{
 "openapi": "3.1.0",
 "info": {
  "title": "GNKG Bridge",
  "version": "2.1.2",
  "description": "Full-access control of Gemini Notebook through the GNKG Chrome extension. Every notebook is a mini knowledge graph."
 },
 "servers": [
  {
   "url": "http://127.0.0.1:7802"
  }
 ],
 "components": {
  "securitySchemes": {
   "token": {
    "type": "apiKey",
    "in": "header",
    "name": "X-Bifrost-Token"
   }
  }
 },
 "security": [],
 "paths": {
  "/api/gn_health": {
   "post": {
    "operationId": "gn_health",
    "summary": "Extension/auth/transport health. Call first.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {},
        "required": []
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_list_notebooks": {
   "post": {
    "operationId": "gn_list_notebooks",
    "summary": "List Gemini Notebook notebooks (most-recently-viewed first) with ids and source counts.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {},
        "required": []
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_create_notebook": {
   "post": {
    "operationId": "gn_create_notebook",
    "summary": "Create a notebook (a new mini knowledge graph).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "title": {
          "type": "string",
          "description": "title"
         }
        },
        "required": [
         "title"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_delete_notebook": {
   "post": {
    "operationId": "gn_delete_notebook",
    "summary": "Delete a notebook permanently (irreversible). Only for notebooks the user asked to delete.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": "notebook id"
         }
        },
        "required": [
         "notebookId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_get_notebook": {
   "post": {
    "operationId": "gn_get_notebook",
    "summary": "Get a notebook with its sources (id, title, kind, wordCount, status).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": "notebook id"
         }
        },
        "required": [
         "notebookId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_add_text_source": {
   "post": {
    "operationId": "gn_add_text_source",
    "summary": "Add a text source (\u2264500k words). Use for bins, notes, transcripts.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "title": {
          "type": "string",
          "description": ""
         },
         "content": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "title",
         "content"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_add_url_source": {
   "post": {
    "operationId": "gn_add_url_source",
    "summary": "Add a web page or YouTube URL as a source.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "url": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "url"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_delete_source": {
   "post": {
    "operationId": "gn_delete_source",
    "summary": "Delete a source.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "sourceId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "sourceId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_refresh_source": {
   "post": {
    "operationId": "gn_refresh_source",
    "summary": "Re-sync a web/Drive source (the legacy B.I.F.R.O.S.T. feed trigger).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "sourceId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "sourceId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_get_source": {
   "post": {
    "operationId": "gn_get_source",
    "summary": "Read a source's indexed full text and AI summary.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "sourceId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "sourceId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_ask": {
   "post": {
    "operationId": "gn_ask",
    "summary": "Ask the notebook a grounded question (uses Gemini Notebook's own retrieval). Optional sourceIds subset.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "question": {
          "type": "string",
          "description": ""
         },
         "sourceIds": {
          "type": "array",
          "items": {
           "type": "string"
          }
         }
        },
        "required": [
         "notebookId",
         "question"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_list_artifacts": {
   "post": {
    "operationId": "gn_list_artifacts",
    "summary": "List Studio artifacts (audio/video/report/slides/infographic/data table/mind map/quiz/flashcards) with status + media URLs.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_create_artifact": {
   "post": {
    "operationId": "gn_create_artifact",
    "summary": "Generate a Studio artifact remotely. kind: audio|video|report|slide_deck|infographic|data_table|mind_map|flashcards|quiz. wait=true polls until done (up to 15 min).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "kind": {
          "type": "string",
          "description": ""
         },
         "sourceIds": {
          "type": "array",
          "items": {
           "type": "string"
          }
         },
         "instructions": {
          "type": "string",
          "description": "focus / stealth prompt"
         },
         "title": {
          "type": "string",
          "description": "report title"
         },
         "wait": {
          "type": "boolean",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "kind"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_wait_artifact": {
   "post": {
    "operationId": "gn_wait_artifact",
    "summary": "Poll an artifact until completed/failed.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "artifactId": {
          "type": "string",
          "description": ""
         },
         "timeoutMs": {
          "type": "number",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "artifactId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_download_artifact": {
   "post": {
    "operationId": "gn_download_artifact",
    "summary": "Download a completed artifact's media via Chrome downloads (TIWY handoff if enabled).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "artifactId": {
          "type": "string",
          "description": ""
         },
         "filename": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "artifactId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_graph": {
   "post": {
    "operationId": "gn_graph",
    "summary": "Knowledge-graph view of a notebook (gnkg-graph-v1 JSON + Mermaid).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/bifrost_plan_bins": {
   "post": {
    "operationId": "bifrost_plan_bins",
    "summary": "Plan B.I.F.R.O.S.T. bins locally: weighted FFD packing at 450k words, pre-chunk >400k, Bin 0 master index preview. files=[{name,text}].",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "files": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "name": {
             "type": "string",
             "description": ""
            },
            "text": {
             "type": "string",
             "description": ""
            }
           },
           "required": [
            "name",
            "text"
           ]
          }
         },
         "project": {
          "type": "string",
          "description": ""
         },
         "directive": {
          "type": "string",
          "description": ""
         },
         "binTarget": {
          "type": "number",
          "description": ""
         }
        },
        "required": [
         "files"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/bifrost_push_bins": {
   "post": {
    "operationId": "bifrost_push_bins",
    "summary": "Pack files and push Bin 0 + bins into a notebook as text sources (waits for each to index). Returns jobId; poll with gn_job.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         },
         "files": {
          "type": "array",
          "items": {
           "type": "object",
           "properties": {
            "name": {
             "type": "string",
             "description": ""
            },
            "text": {
             "type": "string",
             "description": ""
            }
           },
           "required": [
            "name",
            "text"
           ]
          }
         },
         "project": {
          "type": "string",
          "description": ""
         },
         "directive": {
          "type": "string",
          "description": ""
         },
         "binTarget": {
          "type": "number",
          "description": ""
         },
         "skipMasterIndex": {
          "type": "boolean",
          "description": ""
         }
        },
        "required": [
         "notebookId",
         "files"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_job": {
   "post": {
    "operationId": "gn_job",
    "summary": "Get a background job (pushBins) with progress/steps/result.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "jobId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "jobId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_events": {
   "post": {
    "operationId": "gn_events",
    "summary": "Recent extension events (jobs, logs, downloads).",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "limit": {
          "type": "number",
          "description": ""
         }
        },
        "required": []
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_dom_read": {
   "post": {
    "operationId": "gn_dom_read",
    "summary": "Fallback: read the open Gemini Notebook tab's DOM (sources, artifacts, chat) when RPC drifts.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "what": {
          "type": "string",
          "description": "all|sources|artifacts|chat|notebookId"
         }
        },
        "required": []
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/gn_open_notebook": {
   "post": {
    "operationId": "gn_open_notebook",
    "summary": "Open a notebook in a new Chrome tab.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "notebookId": {
          "type": "string",
          "description": ""
         }
        },
        "required": [
         "notebookId"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "ok",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "ok": {
           "type": "boolean"
          },
          "result": {}
         }
        }
       }
      }
     }
    }
   }
  },
  "/health": {
   "get": {
    "operationId": "health",
    "summary": "Bridge + extension health",
    "responses": {
     "200": {
      "description": "ok"
     }
    }
   }
  }
 }
}