studiograph 1.3.48-next.21 → 1.3.48-next.210
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -16
- package/dist/agent/agent-pool.d.ts +87 -3
- package/dist/agent/agent-pool.js +188 -15
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/followups.d.ts +34 -0
- package/dist/agent/followups.js +52 -0
- package/dist/agent/followups.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +101 -4
- package/dist/agent/orchestrator.js +464 -66
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/entity-types-section.d.ts +34 -0
- package/dist/agent/prompts/entity-types-section.js +76 -0
- package/dist/agent/prompts/entity-types-section.js.map +1 -0
- package/dist/agent/prompts/system.md +112 -54
- package/dist/agent/skill-loader.d.ts +30 -17
- package/dist/agent/skill-loader.js +63 -30
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/skills/artifact-canvas/skill.md +152 -0
- package/dist/agent/skills/entity-schema.md +75 -431
- package/dist/agent/skills/interview/entity-templates.md +38 -37
- package/dist/agent/skills/interview/question-domains.md +54 -49
- package/dist/agent/skills/interview/skill.md +84 -16
- package/dist/agent/skills/schema-rules.md +28 -28
- package/dist/agent/tools/artifact-tools.d.ts +124 -0
- package/dist/agent/tools/artifact-tools.js +207 -0
- package/dist/agent/tools/artifact-tools.js.map +1 -0
- package/dist/agent/tools/capture-tools.d.ts +31 -0
- package/dist/agent/tools/capture-tools.js +40 -0
- package/dist/agent/tools/capture-tools.js.map +1 -0
- package/dist/agent/tools/folder-tools.d.ts +47 -0
- package/dist/agent/tools/folder-tools.js +249 -0
- package/dist/agent/tools/folder-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +6 -5
- package/dist/agent/tools/fs-tools.js +5 -5
- package/dist/agent/tools/fs-tools.js.map +1 -1
- package/dist/agent/tools/graph-tools.d.ts +48 -72
- package/dist/agent/tools/graph-tools.js +852 -329
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/history-tools.d.ts +95 -0
- package/dist/agent/tools/history-tools.js +461 -0
- package/dist/agent/tools/history-tools.js.map +1 -0
- package/dist/agent/tools/load-skill.d.ts +6 -5
- package/dist/agent/tools/load-skill.js +3 -3
- package/dist/agent/tools/load-skill.js.map +1 -1
- package/dist/agent/tools/ops-tools.d.ts +5 -4
- package/dist/agent/tools/ops-tools.js +130 -236
- package/dist/agent/tools/ops-tools.js.map +1 -1
- package/dist/agent/tools/permission-tools.d.ts +87 -17
- package/dist/agent/tools/permission-tools.js +233 -43
- package/dist/agent/tools/permission-tools.js.map +1 -1
- package/dist/agent/tools/tool-loader.js +5 -4
- package/dist/agent/tools/tool-loader.js.map +1 -1
- package/dist/agent/tools/web-tools.js +58 -9
- package/dist/agent/tools/web-tools.js.map +1 -1
- package/dist/cli/commands/about.d.ts +1 -0
- package/dist/cli/commands/about.js +55 -3
- package/dist/cli/commands/about.js.map +1 -1
- package/dist/cli/commands/admin/audit-workspace.d.ts +23 -0
- package/dist/cli/commands/admin/audit-workspace.js +133 -0
- package/dist/cli/commands/admin/audit-workspace.js.map +1 -0
- package/dist/cli/commands/admin/audit.d.ts +21 -0
- package/dist/cli/commands/admin/audit.js +174 -0
- package/dist/cli/commands/admin/audit.js.map +1 -0
- package/dist/cli/commands/admin/backup.d.ts +54 -0
- package/dist/cli/commands/admin/backup.js +207 -0
- package/dist/cli/commands/admin/backup.js.map +1 -0
- package/dist/cli/commands/admin/folder.d.ts +11 -0
- package/dist/cli/commands/{collection.js → admin/folder.js} +33 -32
- package/dist/cli/commands/admin/folder.js.map +1 -0
- package/dist/cli/commands/admin/index.d.ts +16 -0
- package/dist/cli/commands/admin/index.js +46 -0
- package/dist/cli/commands/admin/index.js.map +1 -0
- package/dist/cli/commands/admin/migrate-assets.d.ts +53 -0
- package/dist/cli/commands/admin/migrate-assets.js +184 -0
- package/dist/cli/commands/admin/migrate-assets.js.map +1 -0
- package/dist/cli/commands/admin/migrate.d.ts +56 -0
- package/dist/cli/commands/admin/migrate.js +263 -0
- package/dist/cli/commands/admin/migrate.js.map +1 -0
- package/dist/cli/commands/admin/restore.d.ts +24 -0
- package/dist/cli/commands/admin/restore.js +228 -0
- package/dist/cli/commands/admin/restore.js.map +1 -0
- package/dist/cli/commands/admin/secrets.d.ts +23 -0
- package/dist/cli/commands/admin/secrets.js +256 -0
- package/dist/cli/commands/admin/secrets.js.map +1 -0
- package/dist/cli/commands/admin/settings.d.ts +28 -0
- package/dist/cli/commands/admin/settings.js +284 -0
- package/dist/cli/commands/admin/settings.js.map +1 -0
- package/dist/cli/commands/admin/token.d.ts +42 -0
- package/dist/cli/commands/admin/token.js +126 -0
- package/dist/cli/commands/admin/token.js.map +1 -0
- package/dist/cli/commands/admin/transfer-ownership.d.ts +15 -0
- package/dist/cli/commands/admin/transfer-ownership.js +106 -0
- package/dist/cli/commands/admin/transfer-ownership.js.map +1 -0
- package/dist/cli/commands/admin/user.d.ts +11 -0
- package/dist/cli/commands/admin/user.js +187 -0
- package/dist/cli/commands/admin/user.js.map +1 -0
- package/dist/cli/commands/clone.d.ts +25 -3
- package/dist/cli/commands/clone.js +142 -36
- package/dist/cli/commands/clone.js.map +1 -1
- package/dist/cli/commands/config.d.ts +23 -107
- package/dist/cli/commands/config.js +52 -260
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/connector.d.ts +10 -13
- package/dist/cli/commands/connector.js +16 -58
- package/dist/cli/commands/connector.js.map +1 -1
- package/dist/cli/commands/deploy.js +215 -68
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/index.js +5 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.js +10 -30
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mcp.js +54 -6
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/r2.d.ts +3 -0
- package/dist/cli/commands/r2.js +223 -204
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/redeploy.js +65 -12
- package/dist/cli/commands/redeploy.js.map +1 -1
- package/dist/cli/commands/reset.d.ts +22 -6
- package/dist/cli/commands/reset.js +132 -34
- package/dist/cli/commands/reset.js.map +1 -1
- package/dist/cli/commands/serve.js +231 -26
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +237 -227
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/crypto-bundle.d.ts +39 -0
- package/dist/cli/crypto-bundle.js +94 -0
- package/dist/cli/crypto-bundle.js.map +1 -0
- package/dist/cli/index.js +24 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/railway-pin.d.ts +68 -0
- package/dist/cli/railway-pin.js +96 -0
- package/dist/cli/railway-pin.js.map +1 -0
- package/dist/cli/railway-provisioning.d.ts +53 -0
- package/dist/cli/railway-provisioning.js +85 -0
- package/dist/cli/railway-provisioning.js.map +1 -0
- package/dist/cli/setup-wizard.d.ts +30 -49
- package/dist/cli/setup-wizard.js +39 -40
- package/dist/cli/setup-wizard.js.map +1 -1
- package/dist/core/accent-palette.d.ts +22 -0
- package/dist/core/accent-palette.js +47 -0
- package/dist/core/accent-palette.js.map +1 -0
- package/dist/core/artifact-asset-urls.d.ts +51 -0
- package/dist/core/artifact-asset-urls.js +79 -0
- package/dist/core/artifact-asset-urls.js.map +1 -0
- package/dist/core/artifact-bundle.d.ts +69 -0
- package/dist/core/artifact-bundle.js +305 -0
- package/dist/core/artifact-bundle.js.map +1 -0
- package/dist/core/artifact-escape.d.ts +5 -0
- package/dist/core/artifact-escape.js +26 -0
- package/dist/core/artifact-escape.js.map +1 -0
- package/dist/core/artifact-export.d.ts +17 -0
- package/dist/core/artifact-export.js +529 -0
- package/dist/core/artifact-export.js.map +1 -0
- package/dist/core/cell-anchor.d.ts +29 -0
- package/dist/core/cell-anchor.js +53 -0
- package/dist/core/cell-anchor.js.map +1 -0
- package/dist/core/comment-anchor.d.ts +41 -0
- package/dist/core/comment-anchor.js +147 -0
- package/dist/core/comment-anchor.js.map +1 -0
- package/dist/core/commit-messages.d.ts +57 -0
- package/dist/core/commit-messages.js +85 -0
- package/dist/core/commit-messages.js.map +1 -0
- package/dist/core/embeds.d.ts +96 -0
- package/dist/core/embeds.js +187 -0
- package/dist/core/embeds.js.map +1 -0
- package/dist/core/entity-body-templates.d.ts +21 -0
- package/dist/core/entity-body-templates.js +67 -0
- package/dist/core/entity-body-templates.js.map +1 -0
- package/dist/core/entity-types-catalog.d.ts +65 -0
- package/dist/core/entity-types-catalog.js +142 -0
- package/dist/core/entity-types-catalog.js.map +1 -0
- package/dist/core/field-library.d.ts +62 -0
- package/dist/core/field-library.js +129 -0
- package/dist/core/field-library.js.map +1 -0
- package/dist/core/folder-paths.d.ts +41 -0
- package/dist/core/folder-paths.js +95 -0
- package/dist/core/folder-paths.js.map +1 -0
- package/dist/core/folder-sidecar.d.ts +36 -0
- package/dist/core/folder-sidecar.js +91 -0
- package/dist/core/folder-sidecar.js.map +1 -0
- package/dist/core/format-registry.d.ts +170 -0
- package/dist/core/format-registry.js +412 -0
- package/dist/core/format-registry.js.map +1 -0
- package/dist/core/graph.d.ts +773 -14
- package/dist/core/graph.js +2269 -308
- package/dist/core/graph.js.map +1 -1
- package/dist/core/history-diff.d.ts +35 -0
- package/dist/core/history-diff.js +114 -0
- package/dist/core/history-diff.js.map +1 -0
- package/dist/core/refs.d.ts +41 -0
- package/dist/core/refs.js +80 -0
- package/dist/core/refs.js.map +1 -0
- package/dist/core/schema-registry.d.ts +66 -0
- package/dist/core/schema-registry.js +198 -37
- package/dist/core/schema-registry.js.map +1 -1
- package/dist/core/schemas/connector.d.ts +67 -0
- package/dist/core/schemas/connector.js +100 -0
- package/dist/core/schemas/connector.js.map +1 -0
- package/dist/core/schemas/workspace.d.ts +122 -0
- package/dist/core/schemas/workspace.js +211 -0
- package/dist/core/schemas/workspace.js.map +1 -0
- package/dist/core/secrets/SecretStore.d.ts +77 -0
- package/dist/core/secrets/SecretStore.js +13 -0
- package/dist/core/secrets/SecretStore.js.map +1 -0
- package/dist/core/secrets/SettingsResolver.d.ts +54 -0
- package/dist/core/secrets/SettingsResolver.js +80 -0
- package/dist/core/secrets/SettingsResolver.js.map +1 -0
- package/dist/core/secrets/SettingsStore.d.ts +30 -0
- package/dist/core/secrets/SettingsStore.js +9 -0
- package/dist/core/secrets/SettingsStore.js.map +1 -0
- package/dist/core/secrets/SqliteEncryptedStore.d.ts +90 -0
- package/dist/core/secrets/SqliteEncryptedStore.js +598 -0
- package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
- package/dist/core/secrets/audit.d.ts +36 -0
- package/dist/core/secrets/audit.js +60 -0
- package/dist/core/secrets/audit.js.map +1 -0
- package/dist/core/secrets/auth-db-migration.d.ts +129 -0
- package/dist/core/secrets/auth-db-migration.js +653 -0
- package/dist/core/secrets/auth-db-migration.js.map +1 -0
- package/dist/core/secrets/bundle.d.ts +141 -0
- package/dist/core/secrets/bundle.js +435 -0
- package/dist/core/secrets/bundle.js.map +1 -0
- package/dist/core/secrets/dual-write.d.ts +81 -0
- package/dist/core/secrets/dual-write.js +247 -0
- package/dist/core/secrets/dual-write.js.map +1 -0
- package/dist/core/secrets/encryption.d.ts +44 -0
- package/dist/core/secrets/encryption.js +97 -0
- package/dist/core/secrets/encryption.js.map +1 -0
- package/dist/core/secrets/index.d.ts +49 -0
- package/dist/core/secrets/index.js +74 -0
- package/dist/core/secrets/index.js.map +1 -0
- package/dist/core/secrets/master-key.d.ts +38 -0
- package/dist/core/secrets/master-key.js +122 -0
- package/dist/core/secrets/master-key.js.map +1 -0
- package/dist/core/secrets/probes/anthropic.d.ts +98 -0
- package/dist/core/secrets/probes/anthropic.js +300 -0
- package/dist/core/secrets/probes/anthropic.js.map +1 -0
- package/dist/core/secrets/probes/brave.d.ts +9 -0
- package/dist/core/secrets/probes/brave.js +15 -0
- package/dist/core/secrets/probes/brave.js.map +1 -0
- package/dist/core/secrets/probes/r2.d.ts +15 -0
- package/dist/core/secrets/probes/r2.js +14 -0
- package/dist/core/secrets/probes/r2.js.map +1 -0
- package/dist/core/secrets/probes/tavily.d.ts +18 -0
- package/dist/core/secrets/probes/tavily.js +58 -0
- package/dist/core/secrets/probes/tavily.js.map +1 -0
- package/dist/core/secrets/probes/voyage.d.ts +13 -0
- package/dist/core/secrets/probes/voyage.js +52 -0
- package/dist/core/secrets/probes/voyage.js.map +1 -0
- package/dist/core/secrets/r2-structural-migration.d.ts +39 -0
- package/dist/core/secrets/r2-structural-migration.js +109 -0
- package/dist/core/secrets/r2-structural-migration.js.map +1 -0
- package/dist/core/secrets/read-flip.d.ts +59 -0
- package/dist/core/secrets/read-flip.js +87 -0
- package/dist/core/secrets/read-flip.js.map +1 -0
- package/dist/core/secrets/registry.d.ts +188 -0
- package/dist/core/secrets/registry.js +616 -0
- package/dist/core/secrets/registry.js.map +1 -0
- package/dist/core/types.d.ts +77 -483
- package/dist/core/types.js +25 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +75 -12
- package/dist/core/user-config.js +155 -14
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +786 -1373
- package/dist/core/validation.js +458 -147
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +87 -14
- package/dist/core/workspace-manager.js +222 -94
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +19 -5
- package/dist/core/workspace.js +67 -39
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/comment-virtual-entity.d.ts +36 -0
- package/dist/mcp/comment-virtual-entity.js +71 -0
- package/dist/mcp/comment-virtual-entity.js.map +1 -0
- package/dist/mcp/connector-manager.d.ts +72 -2
- package/dist/mcp/connector-manager.js +211 -32
- package/dist/mcp/connector-manager.js.map +1 -1
- package/dist/mcp/oauth-provider.d.ts +0 -5
- package/dist/mcp/oauth-provider.js +10 -22
- package/dist/mcp/oauth-provider.js.map +1 -1
- package/dist/mcp/oauth-registry.d.ts +46 -8
- package/dist/mcp/oauth-registry.js +52 -13
- package/dist/mcp/oauth-registry.js.map +1 -1
- package/dist/mcp/server-discovery.d.ts +73 -0
- package/dist/mcp/server-discovery.js +164 -0
- package/dist/mcp/server-discovery.js.map +1 -0
- package/dist/mcp/server.d.ts +24 -3
- package/dist/mcp/server.js +53 -10
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/state-signer.d.ts +62 -0
- package/dist/mcp/state-signer.js +205 -0
- package/dist/mcp/state-signer.js.map +1 -0
- package/dist/mcp/stdio-proxy.d.ts +67 -0
- package/dist/mcp/stdio-proxy.js +149 -0
- package/dist/mcp/stdio-proxy.js.map +1 -0
- package/dist/mcp/tools.d.ts +65 -2
- package/dist/mcp/tools.js +1772 -124
- package/dist/mcp/tools.js.map +1 -1
- package/dist/server/__tests__/helpers/graph-api.d.ts +16 -0
- package/dist/server/__tests__/helpers/graph-api.js +16 -0
- package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
- package/dist/server/artifact-asset-mint.d.ts +41 -0
- package/dist/server/artifact-asset-mint.js +59 -0
- package/dist/server/artifact-asset-mint.js.map +1 -0
- package/dist/server/asset-index-queue.d.ts +98 -0
- package/dist/server/asset-index-queue.js +193 -0
- package/dist/server/asset-index-queue.js.map +1 -0
- package/dist/server/body-write-coordinator.d.ts +161 -0
- package/dist/server/body-write-coordinator.js +182 -0
- package/dist/server/body-write-coordinator.js.map +1 -0
- package/dist/server/cloud-billing-flow.d.ts +32 -0
- package/dist/server/cloud-billing-flow.js +75 -0
- package/dist/server/cloud-billing-flow.js.map +1 -0
- package/dist/server/commit-audit.d.ts +26 -0
- package/dist/server/commit-audit.js +30 -0
- package/dist/server/commit-audit.js.map +1 -0
- package/dist/server/index.d.ts +29 -3
- package/dist/server/index.js +657 -269
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/sanitize.d.ts +46 -0
- package/dist/server/middleware/sanitize.js +182 -0
- package/dist/server/middleware/sanitize.js.map +1 -0
- package/dist/server/routes/artifact-export-api.d.ts +11 -0
- package/dist/server/routes/artifact-export-api.js +159 -0
- package/dist/server/routes/artifact-export-api.js.map +1 -0
- package/dist/server/routes/asset-api.d.ts +76 -1
- package/dist/server/routes/asset-api.js +761 -61
- package/dist/server/routes/asset-api.js.map +1 -1
- package/dist/server/routes/audit-api.d.ts +24 -0
- package/dist/server/routes/audit-api.js +117 -0
- package/dist/server/routes/audit-api.js.map +1 -0
- package/dist/server/routes/auth-api.js +532 -63
- package/dist/server/routes/auth-api.js.map +1 -1
- package/dist/server/routes/capture-api.d.ts +10 -3
- package/dist/server/routes/capture-api.js +213 -25
- package/dist/server/routes/capture-api.js.map +1 -1
- package/dist/server/routes/chat-sessions-api.d.ts +13 -0
- package/dist/server/routes/chat-sessions-api.js +455 -0
- package/dist/server/routes/chat-sessions-api.js.map +1 -0
- package/dist/server/routes/chat.d.ts +35 -1
- package/dist/server/routes/chat.js +699 -54
- package/dist/server/routes/chat.js.map +1 -1
- package/dist/server/routes/comments-api.d.ts +15 -0
- package/dist/server/routes/comments-api.js +444 -0
- package/dist/server/routes/comments-api.js.map +1 -0
- package/dist/server/routes/config-api.d.ts +3 -2
- package/dist/server/routes/config-api.js +179 -49
- package/dist/server/routes/config-api.js.map +1 -1
- package/dist/server/routes/connectors-api.js +177 -42
- package/dist/server/routes/connectors-api.js.map +1 -1
- package/dist/server/routes/event-ingest-api.d.ts +15 -0
- package/dist/server/routes/{meeting-ingest-api.js → event-ingest-api.js} +35 -20
- package/dist/server/routes/event-ingest-api.js.map +1 -0
- package/dist/server/routes/field-library-api.d.ts +28 -0
- package/dist/server/routes/field-library-api.js +126 -0
- package/dist/server/routes/field-library-api.js.map +1 -0
- package/dist/server/routes/git-http.d.ts +2 -2
- package/dist/server/routes/git-http.js +86 -39
- package/dist/server/routes/git-http.js.map +1 -1
- package/dist/server/routes/graph-api-access.d.ts +57 -0
- package/dist/server/routes/graph-api-access.js +112 -0
- package/dist/server/routes/graph-api-access.js.map +1 -0
- package/dist/server/routes/graph-api.d.ts +1 -1
- package/dist/server/routes/graph-api.js +1455 -325
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/health.d.ts +18 -0
- package/dist/server/routes/health.js +74 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/import-batch.d.ts +24 -0
- package/dist/server/routes/import-batch.js +33 -0
- package/dist/server/routes/import-batch.js.map +1 -0
- package/dist/server/routes/insights-api.d.ts +9 -2
- package/dist/server/routes/insights-api.js +355 -61
- package/dist/server/routes/insights-api.js.map +1 -1
- package/dist/server/routes/mcp.d.ts +7 -3
- package/dist/server/routes/mcp.js +24 -8
- package/dist/server/routes/mcp.js.map +1 -1
- package/dist/server/routes/oauth-api.d.ts +67 -0
- package/dist/server/routes/oauth-api.js +421 -0
- package/dist/server/routes/oauth-api.js.map +1 -0
- package/dist/server/routes/permissions-api.d.ts +9 -2
- package/dist/server/routes/permissions-api.js +87 -31
- package/dist/server/routes/permissions-api.js.map +1 -1
- package/dist/server/routes/r2-api.d.ts +25 -0
- package/dist/server/routes/r2-api.js +276 -0
- package/dist/server/routes/r2-api.js.map +1 -0
- package/dist/server/routes/secrets-api.d.ts +36 -0
- package/dist/server/routes/secrets-api.js +308 -0
- package/dist/server/routes/secrets-api.js.map +1 -0
- package/dist/server/routes/settings-api.d.ts +29 -0
- package/dist/server/routes/settings-api.js +180 -0
- package/dist/server/routes/settings-api.js.map +1 -0
- package/dist/server/routes/share-api.d.ts +32 -0
- package/dist/server/routes/share-api.js +234 -0
- package/dist/server/routes/share-api.js.map +1 -0
- package/dist/server/routes/views-api.js +51 -0
- package/dist/server/routes/views-api.js.map +1 -1
- package/dist/server/routes/workspace-api.d.ts +2 -1
- package/dist/server/routes/workspace-api.js +142 -23
- package/dist/server/routes/workspace-api.js.map +1 -1
- package/dist/server/routes/ws.d.ts +3 -2
- package/dist/server/routes/ws.js +68 -17
- package/dist/server/routes/ws.js.map +1 -1
- package/dist/server/session-manager.d.ts +48 -5
- package/dist/server/session-manager.js +182 -14
- package/dist/server/session-manager.js.map +1 -1
- package/dist/server/ws-hub.d.ts +124 -37
- package/dist/server/ws-hub.js +0 -0
- package/dist/server/ws-hub.js.map +1 -1
- package/dist/server/yjs-manager.d.ts +278 -7
- package/dist/server/yjs-manager.js +830 -38
- package/dist/server/yjs-manager.js.map +1 -1
- package/dist/server/yjs-persistence.d.ts +165 -0
- package/dist/server/yjs-persistence.js +557 -0
- package/dist/server/yjs-persistence.js.map +1 -0
- package/dist/server/yjs-text-diff.d.ts +32 -0
- package/dist/server/yjs-text-diff.js +61 -0
- package/dist/server/yjs-text-diff.js.map +1 -0
- package/dist/services/access-control.d.ts +73 -0
- package/dist/services/access-control.js +165 -0
- package/dist/services/access-control.js.map +1 -0
- package/dist/services/artifact-asset-token.d.ts +69 -0
- package/dist/services/artifact-asset-token.js +94 -0
- package/dist/services/artifact-asset-token.js.map +1 -0
- package/dist/services/artifact-library-sources.d.ts +3 -0
- package/dist/services/artifact-library-sources.js +44 -0
- package/dist/services/artifact-library-sources.js.map +1 -0
- package/dist/services/artifact-render-export.d.ts +97 -0
- package/dist/services/artifact-render-export.js +467 -0
- package/dist/services/artifact-render-export.js.map +1 -0
- package/dist/services/asset-caption-service.d.ts +103 -0
- package/dist/services/asset-caption-service.js +186 -0
- package/dist/services/asset-caption-service.js.map +1 -0
- package/dist/services/asset-delete-authz.d.ts +31 -0
- package/dist/services/asset-delete-authz.js +61 -0
- package/dist/services/asset-delete-authz.js.map +1 -0
- package/dist/services/asset-finalize-service.d.ts +58 -0
- package/dist/services/asset-finalize-service.js +216 -0
- package/dist/services/asset-finalize-service.js.map +1 -0
- package/dist/services/asset-import-service.d.ts +111 -0
- package/dist/services/asset-import-service.js +394 -0
- package/dist/services/asset-import-service.js.map +1 -0
- package/dist/services/asset-index-sweep.d.ts +95 -0
- package/dist/services/asset-index-sweep.js +249 -0
- package/dist/services/asset-index-sweep.js.map +1 -0
- package/dist/services/asset-lifecycle-check.d.ts +22 -0
- package/dist/services/asset-lifecycle-check.js +80 -0
- package/dist/services/asset-lifecycle-check.js.map +1 -0
- package/dist/services/asset-listing.d.ts +72 -0
- package/dist/services/asset-listing.js +321 -0
- package/dist/services/asset-listing.js.map +1 -0
- package/dist/services/asset-presign-service.d.ts +68 -0
- package/dist/services/asset-presign-service.js +124 -0
- package/dist/services/asset-presign-service.js.map +1 -0
- package/dist/services/asset-sidecar-service.d.ts +28 -0
- package/dist/services/asset-sidecar-service.js +79 -0
- package/dist/services/asset-sidecar-service.js.map +1 -0
- package/dist/services/asset-upload-errors.d.ts +41 -0
- package/dist/services/asset-upload-errors.js +45 -0
- package/dist/services/asset-upload-errors.js.map +1 -0
- package/dist/services/asset-upload-service.d.ts +56 -0
- package/dist/services/asset-upload-service.js +200 -0
- package/dist/services/asset-upload-service.js.map +1 -0
- package/dist/services/asset-upload-token.d.ts +58 -0
- package/dist/services/asset-upload-token.js +75 -0
- package/dist/services/asset-upload-token.js.map +1 -0
- package/dist/services/assets/asset-index-service.d.ts +127 -0
- package/dist/services/assets/asset-index-service.js +227 -0
- package/dist/services/assets/asset-index-service.js.map +1 -0
- package/dist/services/assets/base.d.ts +128 -2
- package/dist/services/assets/base.js +98 -1
- package/dist/services/assets/base.js.map +1 -1
- package/dist/services/assets/index.d.ts +114 -1
- package/dist/services/assets/index.js +221 -0
- package/dist/services/assets/index.js.map +1 -1
- package/dist/services/assets/local.d.ts +16 -1
- package/dist/services/assets/local.js +110 -1
- package/dist/services/assets/local.js.map +1 -1
- package/dist/services/assets/r2-sync.d.ts +88 -0
- package/dist/services/assets/r2-sync.js +412 -0
- package/dist/services/assets/r2-sync.js.map +1 -0
- package/dist/services/assets/r2.d.ts +87 -1
- package/dist/services/assets/r2.js +203 -1
- package/dist/services/assets/r2.js.map +1 -1
- package/dist/services/auth-service.d.ts +312 -45
- package/dist/services/auth-service.js +1011 -195
- package/dist/services/auth-service.js.map +1 -1
- package/dist/services/chat-session-service.d.ts +188 -0
- package/dist/services/chat-session-service.js +512 -0
- package/dist/services/chat-session-service.js.map +1 -0
- package/dist/services/cloud-inference-billing.d.ts +64 -0
- package/dist/services/cloud-inference-billing.js +313 -0
- package/dist/services/cloud-inference-billing.js.map +1 -0
- package/dist/services/comment-service.d.ts +97 -0
- package/dist/services/comment-service.js +341 -0
- package/dist/services/comment-service.js.map +1 -0
- package/dist/services/comment-virtual-entity.d.ts +36 -0
- package/dist/services/comment-virtual-entity.js +71 -0
- package/dist/services/comment-virtual-entity.js.map +1 -0
- package/dist/services/convert-service.d.ts +64 -0
- package/dist/services/convert-service.js +68 -0
- package/dist/services/convert-service.js.map +1 -0
- package/dist/services/csv-service.d.ts +22 -17
- package/dist/services/csv-service.js +55 -92
- package/dist/services/csv-service.js.map +1 -1
- package/dist/services/entity-mutations.d.ts +213 -0
- package/dist/services/entity-mutations.js +380 -0
- package/dist/services/entity-mutations.js.map +1 -0
- package/dist/services/{meeting-processor.d.ts → event-processor.d.ts} +15 -8
- package/dist/services/{meeting-processor.js → event-processor.js} +124 -65
- package/dist/services/event-processor.js.map +1 -0
- package/dist/services/extract/docx.d.ts +1 -0
- package/dist/services/extract/docx.js +233 -0
- package/dist/services/extract/docx.js.map +1 -0
- package/dist/services/extract/index.d.ts +9 -0
- package/dist/services/extract/index.js +10 -0
- package/dist/services/extract/index.js.map +1 -0
- package/dist/services/extract/pdf.d.ts +13 -0
- package/dist/services/extract/pdf.js +69 -0
- package/dist/services/extract/pdf.js.map +1 -0
- package/dist/services/folder-creation.d.ts +33 -0
- package/dist/services/folder-creation.js +103 -0
- package/dist/services/folder-creation.js.map +1 -0
- package/dist/services/git.d.ts +58 -0
- package/dist/services/git.js +194 -55
- package/dist/services/git.js.map +1 -1
- package/dist/services/graph-maintenance.js +4 -4
- package/dist/services/graph-maintenance.js.map +1 -1
- package/dist/services/import-service.d.ts +51 -2
- package/dist/services/import-service.js +254 -107
- package/dist/services/import-service.js.map +1 -1
- package/dist/services/lint-service.js +10 -17
- package/dist/services/lint-service.js.map +1 -1
- package/dist/services/markdown.d.ts +12 -1
- package/dist/services/markdown.js +77 -9
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/mention-detector.d.ts +23 -0
- package/dist/services/mention-detector.js +47 -0
- package/dist/services/mention-detector.js.map +1 -0
- package/dist/services/model-capabilities.d.ts +41 -0
- package/dist/services/model-capabilities.js +107 -0
- package/dist/services/model-capabilities.js.map +1 -0
- package/dist/services/notification-broadcast.d.ts +32 -0
- package/dist/services/notification-broadcast.js +38 -0
- package/dist/services/notification-broadcast.js.map +1 -0
- package/dist/services/notification-service.d.ts +41 -0
- package/dist/services/notification-service.js +100 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/oauth-server-store.d.ts +147 -0
- package/dist/services/oauth-server-store.js +319 -0
- package/dist/services/oauth-server-store.js.map +1 -0
- package/dist/services/orphan-service.js +2 -2
- package/dist/services/orphan-service.js.map +1 -1
- package/dist/services/personal-folder.d.ts +40 -0
- package/dist/services/personal-folder.js +101 -0
- package/dist/services/personal-folder.js.map +1 -0
- package/dist/services/scratch-asset-promote.d.ts +57 -0
- package/dist/services/scratch-asset-promote.js +95 -0
- package/dist/services/scratch-asset-promote.js.map +1 -0
- package/dist/services/scratch-attachment-service.d.ts +196 -0
- package/dist/services/scratch-attachment-service.js +347 -0
- package/dist/services/scratch-attachment-service.js.map +1 -0
- package/dist/services/share-link-service.d.ts +57 -0
- package/dist/services/share-link-service.js +142 -0
- package/dist/services/share-link-service.js.map +1 -0
- package/dist/services/user-person-bridge.d.ts +136 -0
- package/dist/services/user-person-bridge.js +340 -0
- package/dist/services/user-person-bridge.js.map +1 -0
- package/dist/services/vector-service.d.ts +282 -5
- package/dist/services/vector-service.js +585 -29
- package/dist/services/vector-service.js.map +1 -1
- package/dist/services/workspace-access.d.ts +108 -0
- package/dist/services/workspace-access.js +149 -0
- package/dist/services/workspace-access.js.map +1 -0
- package/dist/services/workspace-assets-folder.d.ts +46 -0
- package/dist/services/workspace-assets-folder.js +75 -0
- package/dist/services/workspace-assets-folder.js.map +1 -0
- package/dist/utils/git.d.ts +17 -2
- package/dist/utils/git.js +23 -7
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/log.d.ts +42 -0
- package/dist/utils/log.js +137 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/preflight.js +2 -2
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +12 -19
- package/dist/utils/version-checker.js +14 -104
- package/dist/utils/version-checker.js.map +1 -1
- package/dist/web/_app/immutable/assets/0.Bs_z3Z86.css +2 -0
- package/dist/web/_app/immutable/assets/12.DlIf1mKh.css +1 -0
- package/dist/web/_app/immutable/assets/14.7d-Q37wc.css +1 -0
- package/dist/web/_app/immutable/assets/15.BwBFdc1D.css +1 -0
- package/dist/web/_app/immutable/assets/16.CmLrbzZp.css +1 -0
- package/dist/web/_app/immutable/assets/17.DcuK5ZVm.css +1 -0
- package/dist/web/_app/immutable/assets/2.DATnR31c.css +1 -0
- package/dist/web/_app/immutable/assets/3.Cz4H8n_O.css +1 -0
- package/dist/web/_app/immutable/assets/4.aDHteTDy.css +1 -0
- package/dist/web/_app/immutable/assets/6.CF1i5Bon.css +1 -0
- package/dist/web/_app/immutable/assets/ArtifactEntityView.C4ooklFD.css +1 -0
- package/dist/web/_app/immutable/assets/AssetLibraryPicker.BOFW0MvF.css +1 -0
- package/dist/web/_app/immutable/assets/BulkActionsBar.cmKvHzRK.css +1 -0
- package/dist/web/_app/immutable/assets/CalendarView.lBCvS3X5.css +1 -0
- package/dist/web/_app/immutable/assets/CodeMirrorEditor.D6hf2pNJ.css +1 -0
- package/dist/web/_app/immutable/assets/CopyField.DVGZtw4U.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMembersPanel.kiYnDFHu.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
- package/dist/web/_app/immutable/assets/FolderPicker.Cp46GHe2.css +1 -0
- package/dist/web/_app/immutable/assets/GalleryView.WBGxxUQc.css +1 -0
- package/dist/web/_app/immutable/assets/GraphView.BJtGL9py.css +1 -0
- package/dist/web/_app/immutable/assets/KanbanView.BOaI5KFL.css +1 -0
- package/dist/web/_app/immutable/assets/Link.vV0ne105.css +1 -0
- package/dist/web/_app/immutable/assets/Markdown.BZnsSOSf.css +1 -0
- package/dist/web/_app/immutable/assets/Rail.ilusFgD4.css +1 -0
- package/dist/web/_app/immutable/assets/SettingsDialog.D7-BO6S_.css +1 -0
- package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
- package/dist/web/_app/immutable/assets/StopFilledAlt.fNlDN65D.css +1 -0
- package/dist/web/_app/immutable/assets/TimelineView.xAZBJhHw.css +1 -0
- package/dist/web/_app/immutable/assets/WorkspaceView.C8ErUJAY.css +1 -0
- package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
- package/dist/web/_app/immutable/assets/history-summary.LpmHXasl.css +1 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
- package/dist/web/_app/immutable/assets/inline-list.cqga56xT.css +1 -0
- package/dist/web/_app/immutable/assets/list-columns.BgnafZ4K.css +1 -0
- package/dist/web/_app/immutable/assets/realtime.DDCWxn3B.css +1 -0
- package/dist/web/_app/immutable/assets/select.B90KUqR4.css +1 -0
- package/dist/web/_app/immutable/assets/sheet.RF9RBmml.css +1 -0
- package/dist/web/_app/immutable/chunks/22qYtvr82.js +1 -0
- package/dist/web/_app/immutable/chunks/3anKjXOb.js +1 -0
- package/dist/web/_app/immutable/chunks/6S9WOky52.js +1 -0
- package/dist/web/_app/immutable/chunks/7xJ91z7d.js +2 -0
- package/dist/web/_app/immutable/chunks/9K8VREGP.js +1 -0
- package/dist/web/_app/immutable/chunks/B-TGZnCt2.js +1 -0
- package/dist/web/_app/immutable/chunks/B-n5q6ku.js +1 -0
- package/dist/web/_app/immutable/chunks/B0p2fSEV2.js +1 -0
- package/dist/web/_app/immutable/chunks/B2oi87jG.js +2 -0
- package/dist/web/_app/immutable/chunks/B4DG5QOL.js +1 -0
- package/dist/web/_app/immutable/chunks/B6Lt-qaJ.js +1 -0
- package/dist/web/_app/immutable/chunks/B6qeIQZz.js +2 -0
- package/dist/web/_app/immutable/chunks/B9KfEsQw2.js +1 -0
- package/dist/web/_app/immutable/chunks/B9VRF5aH2.js +1 -0
- package/dist/web/_app/immutable/chunks/BCQQzpbj.js +1 -0
- package/dist/web/_app/immutable/chunks/BF0vIqH9.js +1 -0
- package/dist/web/_app/immutable/chunks/BFp1K70l.js +8 -0
- package/dist/web/_app/immutable/chunks/BFr7Funh.js +1 -0
- package/dist/web/_app/immutable/chunks/BFx32D20.js +2 -0
- package/dist/web/_app/immutable/chunks/BLs1h0Rh2.js +1 -0
- package/dist/web/_app/immutable/chunks/BPzV_xOS2.js +1 -0
- package/dist/web/_app/immutable/chunks/BRvMjAzW.js +2 -0
- package/dist/web/_app/immutable/chunks/BV-iCKqa.js +1 -0
- package/dist/web/_app/immutable/chunks/BZi3uKF4.js +1 -0
- package/dist/web/_app/immutable/chunks/B_PyL87x.js +2 -0
- package/dist/web/_app/immutable/chunks/BbfHGU9n2.js +1 -0
- package/dist/web/_app/immutable/chunks/Bbqu2-5G2.js +1 -0
- package/dist/web/_app/immutable/chunks/BdWZJpmv.js +2 -0
- package/dist/web/_app/immutable/chunks/BfnFtsiY.js +1 -0
- package/dist/web/_app/immutable/chunks/BlgjVmFM2.js +14 -0
- package/dist/web/_app/immutable/chunks/BmgXvmIG.js +5 -0
- package/dist/web/_app/immutable/chunks/BpCG9m962.js +1 -0
- package/dist/web/_app/immutable/chunks/BrveeylZ.js +1 -0
- package/dist/web/_app/immutable/chunks/BsW72fyR2.js +1 -0
- package/dist/web/_app/immutable/chunks/Bti_XKwx.js +2692 -0
- package/dist/web/_app/immutable/chunks/BuhW5Fr0.js +689 -0
- package/dist/web/_app/immutable/chunks/Bx74EEyn2.js +1 -0
- package/dist/web/_app/immutable/chunks/BxPN0T61.js +1 -0
- package/dist/web/_app/immutable/chunks/Bxk27YWG.js +1 -0
- package/dist/web/_app/immutable/chunks/Bz9lrgGs.js +1 -0
- package/dist/web/_app/immutable/chunks/BzaxZ6j12.js +1 -0
- package/dist/web/_app/immutable/chunks/C1B4xDs0.js +1 -0
- package/dist/web/_app/immutable/chunks/C1trcC8M.js +7 -0
- package/dist/web/_app/immutable/chunks/C3F_NMTk.js +3 -0
- package/dist/web/_app/immutable/chunks/C4PZmGUQ.js +2 -0
- package/dist/web/_app/immutable/chunks/C6wYiSz8.js +1 -0
- package/dist/web/_app/immutable/chunks/C70saxIl.js +1 -0
- package/dist/web/_app/immutable/chunks/C9tvkk7Y2.js +22 -0
- package/dist/web/_app/immutable/chunks/CE1XZ5DE.js +1 -0
- package/dist/web/_app/immutable/chunks/CEahbtnP.js +1 -0
- package/dist/web/_app/immutable/chunks/CGkd0a-c2.js +2 -0
- package/dist/web/_app/immutable/chunks/CIoNEHQ82.js +184 -0
- package/dist/web/_app/immutable/chunks/CK4z74w5.js +1 -0
- package/dist/web/_app/immutable/chunks/COo3HgCZ.js +1 -0
- package/dist/web/_app/immutable/chunks/CP8_U450.js +1 -0
- package/dist/web/_app/immutable/chunks/CQ1eQ93t2.js +6 -0
- package/dist/web/_app/immutable/chunks/CQyBDccA.js +1 -0
- package/dist/web/_app/immutable/chunks/CUFQMEBn2.js +1 -0
- package/dist/web/_app/immutable/chunks/CV5OSCJc.js +1 -0
- package/dist/web/_app/immutable/chunks/CYEYDNwO2.js +1 -0
- package/dist/web/_app/immutable/chunks/CZgFaimi2.js +83 -0
- package/dist/web/_app/immutable/chunks/CZqvCTCv.js +1 -0
- package/dist/web/_app/immutable/chunks/CcWaWbrI2.js +1 -0
- package/dist/web/_app/immutable/chunks/CdtzRVZK.js +1 -0
- package/dist/web/_app/immutable/chunks/CfYG72Hc.js +1 -0
- package/dist/web/_app/immutable/chunks/Cg-ND0cl.js +1 -0
- package/dist/web/_app/immutable/chunks/Ch1kmm3J2.js +1 -0
- package/dist/web/_app/immutable/chunks/CjiMLTwX2.js +1 -0
- package/dist/web/_app/immutable/chunks/CkoeSJ8K.js +6 -0
- package/dist/web/_app/immutable/chunks/Cp87MaaW.js +1 -0
- package/dist/web/_app/immutable/chunks/Cqm5wAin.js +1 -0
- package/dist/web/_app/immutable/chunks/Ct1uesdW.js +2 -0
- package/dist/web/_app/immutable/chunks/CuYPXpWU.js +1 -0
- package/dist/web/_app/immutable/chunks/Cuq8J2Td.js +1 -0
- package/dist/web/_app/immutable/chunks/CvSEodTA.js +1 -0
- package/dist/web/_app/immutable/chunks/CvqqrTrj.js +1 -0
- package/dist/web/_app/immutable/chunks/CzXdOgVl2.js +7 -0
- package/dist/web/_app/immutable/chunks/D0W7c6Sg.js +185 -0
- package/dist/web/_app/immutable/chunks/D0rBhnqB2.js +1 -0
- package/dist/web/_app/immutable/chunks/D1-GZSN1.js +1 -0
- package/dist/web/_app/immutable/chunks/D1BLcNJ7.js +1 -0
- package/dist/web/_app/immutable/chunks/D1yvtriI.js +1 -0
- package/dist/web/_app/immutable/chunks/D25NMRpl.js +1 -0
- package/dist/web/_app/immutable/chunks/D3F675fu2.js +2 -0
- package/dist/web/_app/immutable/chunks/D4UrtGC1.js +1 -0
- package/dist/web/_app/immutable/chunks/D8wZ2xul.js +4 -0
- package/dist/web/_app/immutable/chunks/DA3HEX3X.js +1 -0
- package/dist/web/_app/immutable/chunks/DE2TCESD2.js +1 -0
- package/dist/web/_app/immutable/chunks/DN-gIRdd2.js +1 -0
- package/dist/web/_app/immutable/chunks/DPUVu0T0.js +1 -0
- package/dist/web/_app/immutable/chunks/DPcejqKZ.js +1 -0
- package/dist/web/_app/immutable/chunks/DQMWa2t7.js +1 -0
- package/dist/web/_app/immutable/chunks/DRPMJ-3M.js +2 -0
- package/dist/web/_app/immutable/chunks/DRPnwQAm.js +1 -0
- package/dist/web/_app/immutable/chunks/DXmfl4Hq2.js +1 -0
- package/dist/web/_app/immutable/chunks/DXsFrDer2.js +1 -0
- package/dist/web/_app/immutable/chunks/DYc5KW3F.js +1 -0
- package/dist/web/_app/immutable/chunks/DcPrzUMJ.js +1 -0
- package/dist/web/_app/immutable/chunks/DdQVGKgM.js +1 -0
- package/dist/web/_app/immutable/chunks/DiFfW--R2.js +2 -0
- package/dist/web/_app/immutable/chunks/DjIqa1_y.js +2 -0
- package/dist/web/_app/immutable/chunks/Dl63IUnH2.js +224 -0
- package/dist/web/_app/immutable/chunks/DmFdD6zT.js +1 -0
- package/dist/web/_app/immutable/chunks/Dn3R8S-U.js +1 -0
- package/dist/web/_app/immutable/chunks/DpNr1GQ2.js +1 -0
- package/dist/web/_app/immutable/chunks/DsFEd8vL2.js +1 -0
- package/dist/web/_app/immutable/chunks/DuxziNnw.js +1 -0
- package/dist/web/_app/immutable/chunks/FuiJnZG0.js +1 -0
- package/dist/web/_app/immutable/chunks/Izkulod7.js +1 -0
- package/dist/web/_app/immutable/chunks/LYL8znYR2.js +23 -0
- package/dist/web/_app/immutable/chunks/ON7Gta0d.js +1 -0
- package/dist/web/_app/immutable/chunks/PhN6tXuJ2.js +1 -0
- package/dist/web/_app/immutable/chunks/PyLyCpuL.js +1 -0
- package/dist/web/_app/immutable/chunks/RG7IUVLn2.js +2 -0
- package/dist/web/_app/immutable/chunks/RK4gCWN0.js +2 -0
- package/dist/web/_app/immutable/chunks/SnzlL4ZV.js +1 -0
- package/dist/web/_app/immutable/chunks/XcWejFm_.js +5 -0
- package/dist/web/_app/immutable/chunks/Xkp5hSA1.js +1 -0
- package/dist/web/_app/immutable/chunks/al_nidE9.js +1 -0
- package/dist/web/_app/immutable/chunks/e50-izZO2.js +1 -0
- package/dist/web/_app/immutable/chunks/golz20La2.js +2 -0
- package/dist/web/_app/immutable/chunks/hG-QCarB.js +1 -0
- package/dist/web/_app/immutable/chunks/kNaey6uv.js +1 -0
- package/dist/web/_app/immutable/chunks/nXReuy-5.js +3 -0
- package/dist/web/_app/immutable/chunks/o61aZZFZ2.js +66 -0
- package/dist/web/_app/immutable/chunks/qwr5boV8.js +1 -0
- package/dist/web/_app/immutable/chunks/rjjyuGhb.js +1 -0
- package/dist/web/_app/immutable/chunks/uBgoVlsx.js +3 -0
- package/dist/web/_app/immutable/chunks/xY0c-UfG.js +3 -0
- package/dist/web/_app/immutable/chunks/xeNvx4Bl2.js +1 -0
- package/dist/web/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/dist/web/_app/immutable/entry/app.dqA31fjy.js +2 -0
- package/dist/web/_app/immutable/entry/start.BB1XrAea.js +1 -0
- package/dist/web/_app/immutable/nodes/0.dALEQAnu.js +2 -0
- package/dist/web/_app/immutable/nodes/1.aFU32Ukj.js +1 -0
- package/dist/web/_app/immutable/nodes/10.C2wB-OnW.js +1 -0
- package/dist/web/_app/immutable/nodes/11.CI3a8Rj5.js +1 -0
- package/dist/web/_app/immutable/nodes/12.CsTvsKzB.js +1 -0
- package/dist/web/_app/immutable/nodes/13.CYrHXCA8.js +1 -0
- package/dist/web/_app/immutable/nodes/14.B31HrQ26.js +1 -0
- package/dist/web/_app/immutable/nodes/15.DxgnZ61h.js +1 -0
- package/dist/web/_app/immutable/nodes/16.DAP8cwVb.js +1 -0
- package/dist/web/_app/immutable/nodes/17.CmwXtCDY.js +77 -0
- package/dist/web/_app/immutable/nodes/2.BuGXEIlN.js +122 -0
- package/dist/web/_app/immutable/nodes/3.CmhZJWHE.js +6 -0
- package/dist/web/_app/immutable/nodes/4.BRfoPTm-.js +11 -0
- package/dist/web/_app/immutable/nodes/5.C7gPuZM_.js +1 -0
- package/dist/web/_app/immutable/nodes/6.qKODVbya.js +6 -0
- package/dist/web/_app/immutable/nodes/7.BZO37zAJ.js +1 -0
- package/dist/web/_app/immutable/nodes/8.xF_Dd1BO.js +1 -0
- package/dist/web/_app/immutable/nodes/9.Bow4UyKV.js +1 -0
- package/dist/web/_app/version.json +1 -1
- package/dist/web/favicon-16.png +0 -0
- package/dist/web/favicon-180.png +0 -0
- package/dist/web/favicon-32.png +0 -0
- package/dist/web/favicon-48.png +0 -0
- package/dist/web/favicon-512.png +0 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.svg +8 -0
- package/dist/web/index.html +56 -21
- package/dist/web/studiograph-logomark.svg +29 -0
- package/package.json +35 -14
- package/dist/agent/skills/enrich-entities.md +0 -136
- package/dist/agent/skills/sync-configuration.md +0 -119
- package/dist/agent/skills/sync-setup.md +0 -82
- package/dist/agent/tools/message-tools.d.ts +0 -42
- package/dist/agent/tools/message-tools.js +0 -106
- package/dist/agent/tools/message-tools.js.map +0 -1
- package/dist/cli/commands/app.d.ts +0 -7
- package/dist/cli/commands/app.js +0 -268
- package/dist/cli/commands/app.js.map +0 -1
- package/dist/cli/commands/clear.d.ts +0 -5
- package/dist/cli/commands/clear.js +0 -36
- package/dist/cli/commands/clear.js.map +0 -1
- package/dist/cli/commands/collection.d.ts +0 -10
- package/dist/cli/commands/collection.js.map +0 -1
- package/dist/cli/commands/join.d.ts +0 -9
- package/dist/cli/commands/join.js +0 -255
- package/dist/cli/commands/join.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -7
- package/dist/cli/commands/start.js +0 -584
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/update.d.ts +0 -8
- package/dist/cli/commands/update.js +0 -155
- package/dist/cli/commands/update.js.map +0 -1
- package/dist/cli/commands/user.d.ts +0 -7
- package/dist/cli/commands/user.js +0 -175
- package/dist/cli/commands/user.js.map +0 -1
- package/dist/cli/scaffolding.d.ts +0 -12
- package/dist/cli/scaffolding.js +0 -397
- package/dist/cli/scaffolding.js.map +0 -1
- package/dist/integrations/registry.d.ts +0 -8
- package/dist/integrations/registry.js +0 -7
- package/dist/integrations/registry.js.map +0 -1
- package/dist/integrations/types.d.ts +0 -43
- package/dist/integrations/types.js +0 -5
- package/dist/integrations/types.js.map +0 -1
- package/dist/lib/lib/utils.d.ts +0 -2
- package/dist/lib/lib/utils.js +0 -6
- package/dist/lib/lib/utils.js.map +0 -1
- package/dist/server/chrome/chrome.css +0 -691
- package/dist/server/chrome/chrome.js +0 -374
- package/dist/server/commit-scheduler.d.ts +0 -39
- package/dist/server/commit-scheduler.js +0 -113
- package/dist/server/commit-scheduler.js.map +0 -1
- package/dist/server/plugin-loader.d.ts +0 -53
- package/dist/server/plugin-loader.js +0 -155
- package/dist/server/plugin-loader.js.map +0 -1
- package/dist/server/routes/meeting-ingest-api.d.ts +0 -14
- package/dist/server/routes/meeting-ingest-api.js.map +0 -1
- package/dist/server/routes/messages-api.d.ts +0 -15
- package/dist/server/routes/messages-api.js +0 -385
- package/dist/server/routes/messages-api.js.map +0 -1
- package/dist/services/batch-processor.d.ts +0 -49
- package/dist/services/batch-processor.js +0 -166
- package/dist/services/batch-processor.js.map +0 -1
- package/dist/services/briefing.d.ts +0 -26
- package/dist/services/briefing.js +0 -230
- package/dist/services/briefing.js.map +0 -1
- package/dist/services/heartbeat.d.ts +0 -28
- package/dist/services/heartbeat.js +0 -183
- package/dist/services/heartbeat.js.map +0 -1
- package/dist/services/image-import-service.d.ts +0 -24
- package/dist/services/image-import-service.js +0 -108
- package/dist/services/image-import-service.js.map +0 -1
- package/dist/services/insights.d.ts +0 -38
- package/dist/services/insights.js +0 -269
- package/dist/services/insights.js.map +0 -1
- package/dist/services/meeting-processor.js.map +0 -1
- package/dist/services/message-service.d.ts +0 -68
- package/dist/services/message-service.js +0 -220
- package/dist/services/message-service.js.map +0 -1
- package/dist/utils/workspace-config.d.ts +0 -8
- package/dist/utils/workspace-config.js +0 -22
- package/dist/utils/workspace-config.js.map +0 -1
- package/dist/web/_app/immutable/assets/0.uPSqtsC5.css +0 -1
- package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
- package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
- package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
- package/dist/web/_app/immutable/assets/2.DpQWr6q6.css +0 -1
- package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
- package/dist/web/_app/immutable/assets/4.DdNqjd0T.css +0 -1
- package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
- package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
- package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
- package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
- package/dist/web/_app/immutable/assets/ViewToolbar.BWE03S64.css +0 -1
- package/dist/web/_app/immutable/assets/WorkspaceView.CgGDi_Zb.css +0 -1
- package/dist/web/_app/immutable/assets/wikilinks.CzMBkUMB.css +0 -1
- package/dist/web/_app/immutable/chunks/-jG4Obyh.js +0 -4
- package/dist/web/_app/immutable/chunks/2nrc8f_O.js +0 -1
- package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
- package/dist/web/_app/immutable/chunks/8Q3ZJIYu.js +0 -1
- package/dist/web/_app/immutable/chunks/B8ydT5xX.js +0 -2
- package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
- package/dist/web/_app/immutable/chunks/BEn6N5c2.js +0 -1
- package/dist/web/_app/immutable/chunks/BFNNbCAM.js +0 -1
- package/dist/web/_app/immutable/chunks/BFZZEUd5.js +0 -1
- package/dist/web/_app/immutable/chunks/BGk8kfOE.js +0 -2
- package/dist/web/_app/immutable/chunks/BIBCr278.js +0 -1
- package/dist/web/_app/immutable/chunks/BPCkkwqe.js +0 -1
- package/dist/web/_app/immutable/chunks/BhlvzGQx.js +0 -1
- package/dist/web/_app/immutable/chunks/BlMknQeF.js +0 -1
- package/dist/web/_app/immutable/chunks/BpjqrlCg.js +0 -1
- package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
- package/dist/web/_app/immutable/chunks/ByBZ7JIT.js +0 -1
- package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
- package/dist/web/_app/immutable/chunks/BzJTZOK2.js +0 -1
- package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
- package/dist/web/_app/immutable/chunks/C3uBrOS5.js +0 -1
- package/dist/web/_app/immutable/chunks/C8R1sDpW.js +0 -1
- package/dist/web/_app/immutable/chunks/CDRHrs0g.js +0 -1
- package/dist/web/_app/immutable/chunks/CN5_py1I.js +0 -1
- package/dist/web/_app/immutable/chunks/CPne482a.js +0 -1
- package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
- package/dist/web/_app/immutable/chunks/CWyU-seV.js +0 -1
- package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
- package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
- package/dist/web/_app/immutable/chunks/ChsiIm-E.js +0 -1
- package/dist/web/_app/immutable/chunks/CojKppbh.js +0 -1
- package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
- package/dist/web/_app/immutable/chunks/CtYLtD7K.js +0 -1
- package/dist/web/_app/immutable/chunks/D-HDy5qS.js +0 -1
- package/dist/web/_app/immutable/chunks/D5aIYSkd.js +0 -1
- package/dist/web/_app/immutable/chunks/DBBXARVf.js +0 -1
- package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
- package/dist/web/_app/immutable/chunks/DKaafS50.js +0 -1
- package/dist/web/_app/immutable/chunks/DUMOo1Pn.js +0 -1
- package/dist/web/_app/immutable/chunks/DWX9f6AF.js +0 -1
- package/dist/web/_app/immutable/chunks/DY8-EONP.js +0 -1
- package/dist/web/_app/immutable/chunks/DkoHPElM.js +0 -1
- package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
- package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
- package/dist/web/_app/immutable/chunks/DujahU3W.js +0 -1
- package/dist/web/_app/immutable/chunks/FBn-ES5k.js +0 -1
- package/dist/web/_app/immutable/chunks/HQpwSOb3.js +0 -1
- package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
- package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
- package/dist/web/_app/immutable/chunks/UwYfmrPx.js +0 -2
- package/dist/web/_app/immutable/chunks/W25ZVI8L.js +0 -2
- package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
- package/dist/web/_app/immutable/chunks/XjsuEnNE.js +0 -5
- package/dist/web/_app/immutable/chunks/ZD6ARAtb.js +0 -1
- package/dist/web/_app/immutable/chunks/pBTf4stg.js +0 -2
- package/dist/web/_app/immutable/chunks/rGIarcnp.js +0 -1
- package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
- package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
- package/dist/web/_app/immutable/entry/app.ZHiTM8WS.js +0 -2
- package/dist/web/_app/immutable/entry/start.C9-FfAVc.js +0 -1
- package/dist/web/_app/immutable/nodes/0.D92Orz8k.js +0 -2
- package/dist/web/_app/immutable/nodes/1.BMdyglM_.js +0 -1
- package/dist/web/_app/immutable/nodes/10.BilVDHSL.js +0 -1
- package/dist/web/_app/immutable/nodes/11.CS9E0Hic.js +0 -1
- package/dist/web/_app/immutable/nodes/12.D3BOxYzG.js +0 -1
- package/dist/web/_app/immutable/nodes/13.CClMKYtN.js +0 -1
- package/dist/web/_app/immutable/nodes/2.C8KKElPL.js +0 -267
- package/dist/web/_app/immutable/nodes/3.C5n5uiWU.js +0 -5
- package/dist/web/_app/immutable/nodes/4.DcGVvgiL.js +0 -11
- package/dist/web/_app/immutable/nodes/5.DxIjnFQO.js +0 -4
- package/dist/web/_app/immutable/nodes/6.lkh6kKLj.js +0 -1
- package/dist/web/_app/immutable/nodes/7.Bg7SbfhA.js +0 -1
- package/dist/web/_app/immutable/nodes/8.DcXWCNBE.js +0 -1
- package/dist/web/_app/immutable/nodes/9.Cefi8Jfm.js +0 -1
|
@@ -18,22 +18,185 @@
|
|
|
18
18
|
import { join } from 'path';
|
|
19
19
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
20
20
|
import * as lancedb from '@lancedb/lancedb';
|
|
21
|
+
import { embeddedAssetIds } from '../core/embeds.js';
|
|
22
|
+
import { isCaptionableImage } from './assets/base.js';
|
|
23
|
+
import { tryResolve } from '../core/secrets/read-flip.js';
|
|
21
24
|
const VOYAGE_API_URL = 'https://api.voyageai.com/v1/embeddings';
|
|
22
25
|
const VOYAGE_MODEL = 'voyage-3';
|
|
23
26
|
const VECTOR_DIM = 1024;
|
|
24
27
|
const TABLE_NAME = 'entities';
|
|
28
|
+
/**
|
|
29
|
+
* Dedicated LanceDB table for an asset's MUTABLE index state (decision A1).
|
|
30
|
+
*
|
|
31
|
+
* Why a separate table, not columns on `entities` and not asset frontmatter:
|
|
32
|
+
* - Frontmatter is immutable + git-committed; writing `index_status` there
|
|
33
|
+
* would fire one async git commit per asset and defeat the import batching.
|
|
34
|
+
* (The immutable `indexable` flag DOES live in frontmatter — see P3a.)
|
|
35
|
+
* - New columns on the shared `entities` table force a schema migration on
|
|
36
|
+
* every existing row. A side table is additive and touches only assets.
|
|
37
|
+
*/
|
|
38
|
+
const INDEX_STATE_TABLE = 'asset_index_state';
|
|
39
|
+
/**
|
|
40
|
+
* Derivation-logic version. BUMP this when caption/extraction output changes so
|
|
41
|
+
* the boot sweep RE-derives every asset (Codex migration rule: a row at a stale
|
|
42
|
+
* version is re-derived, never treated as "done"). Legacy assets have NO row at
|
|
43
|
+
* all — also re-derived, never skipped.
|
|
44
|
+
*/
|
|
45
|
+
export const ASSET_INDEX_VERSION = 1;
|
|
25
46
|
export class VectorService {
|
|
26
47
|
dbPath;
|
|
27
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Legacy fallback key passed via constructor for tests or for early-
|
|
50
|
+
* boot code paths that run before the secrets store is initialized.
|
|
51
|
+
* Live calls prefer `tryResolve('voyage.api_key')` so values written
|
|
52
|
+
* to the store via the UI / CLI take effect without a restart.
|
|
53
|
+
*/
|
|
54
|
+
fallbackVoyageApiKey;
|
|
28
55
|
db;
|
|
29
56
|
table;
|
|
57
|
+
/** Lazily-opened side table for mutable asset index state (A1). */
|
|
58
|
+
stateTable;
|
|
59
|
+
stateInitialized = false;
|
|
30
60
|
lastIndexedPath;
|
|
31
61
|
initialized = false;
|
|
62
|
+
// ── Single-flight guards (one in-flight init per resource) ──
|
|
63
|
+
// `init()` and `initStateTable()` both open the LanceDB connection and can be
|
|
64
|
+
// invoked concurrently (boot incremental reindex via upsert() races the
|
|
65
|
+
// fire-and-forget asset sweep via getAllIndexStates()). Without
|
|
66
|
+
// single-flighting, both would pass their boolean guard before either await
|
|
67
|
+
// resolved, double-connect, and double-`createTable` → "table already exists"
|
|
68
|
+
// / CommitConflict. Each promise is created once and awaited by all callers.
|
|
69
|
+
dbPromise;
|
|
70
|
+
initPromise;
|
|
71
|
+
stateInitPromise;
|
|
72
|
+
// ── Write serialization ──
|
|
73
|
+
// LanceDB uses optimistic concurrency: two `mergeInsert(...).execute()` (or
|
|
74
|
+
// delete) calls racing on the SAME table throw a CommitConflict and one loses.
|
|
75
|
+
// This singleton VectorService is shared by foreground entity writes
|
|
76
|
+
// (graph.ts fire-and-forget upsert/delete) AND the live asset-index drain
|
|
77
|
+
// (re-upsert after writing a caption sidecar). Without serialization those two
|
|
78
|
+
// sources can collide on the `entities` table — and the drain would record the
|
|
79
|
+
// loser as a terminal `failed` index state. `withWrite()` chains every mutating
|
|
80
|
+
// op onto a single per-instance promise so they run one at a time, in order.
|
|
81
|
+
writeChain = Promise.resolve();
|
|
82
|
+
/**
|
|
83
|
+
* Fired exactly once per asset, when `ensureInitialAssetIndexState` seeds a
|
|
84
|
+
* fresh `pending` row — i.e. an indexable IMAGE assets.db row that needs
|
|
85
|
+
* captioning. The asset-creation paths (graph.uploadAsset for import +
|
|
86
|
+
* manager/editor uploads, asset-finalize-service for presign) call
|
|
87
|
+
* ensureInitialAssetIndexState after writing the assets.db row, so the live
|
|
88
|
+
* caption drain registers here instead of being wired at each call site. It
|
|
89
|
+
* fires only for images and only on the first seed (a re-seed early-returns),
|
|
90
|
+
* so it can't loop the drain.
|
|
91
|
+
*/
|
|
92
|
+
onAssetPendingCb;
|
|
93
|
+
/**
|
|
94
|
+
* Workspace-global asset ownership index (assets.db). Injected by the
|
|
95
|
+
* WorkspaceManager so `upsert` can resolve the captions of images an entry
|
|
96
|
+
* embeds (`resolveEmbeddedCaptions`) and fold them into the entry's search
|
|
97
|
+
* text. Optional — tests / early-boot paths run without it (no caption fold).
|
|
98
|
+
*/
|
|
99
|
+
assetIndex;
|
|
100
|
+
// ── Operator-visible health (surfaced via /api/health/dirty) ──
|
|
101
|
+
// Tracked here, not at the call sites, because every fire-and-forget
|
|
102
|
+
// upsert/delete in graph.ts catches its own promise to avoid blocking
|
|
103
|
+
// writes — the operator needs a single rolled-up signal instead of
|
|
104
|
+
// grepping logs for `[vector] index failed`.
|
|
105
|
+
failureCount = 0;
|
|
106
|
+
inFlight = 0;
|
|
107
|
+
lastFailureAt = null;
|
|
108
|
+
lastFailure = null;
|
|
32
109
|
constructor(dbPath, voyageApiKey) {
|
|
33
110
|
this.dbPath = dbPath;
|
|
34
|
-
this.
|
|
111
|
+
this.fallbackVoyageApiKey = voyageApiKey;
|
|
35
112
|
this.lastIndexedPath = join(dbPath, 'last-indexed.json');
|
|
36
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Resolve the Voyage API key fresh on each call: store > constructor
|
|
116
|
+
* fallback. Lets the operator flip the key via UI / CLI without a
|
|
117
|
+
* server restart.
|
|
118
|
+
*/
|
|
119
|
+
get voyageApiKey() {
|
|
120
|
+
const fromStore = tryResolve('voyage.api_key');
|
|
121
|
+
return fromStore ?? this.fallbackVoyageApiKey;
|
|
122
|
+
}
|
|
123
|
+
/** Begin tracking an in-flight op. Pair with `recordSuccess`/`recordFailure`. */
|
|
124
|
+
beginOp() { this.inFlight++; }
|
|
125
|
+
recordSuccess() {
|
|
126
|
+
if (this.inFlight > 0)
|
|
127
|
+
this.inFlight--;
|
|
128
|
+
}
|
|
129
|
+
recordFailure(op, entity, err) {
|
|
130
|
+
if (this.inFlight > 0)
|
|
131
|
+
this.inFlight--;
|
|
132
|
+
this.failureCount++;
|
|
133
|
+
this.lastFailureAt = new Date().toISOString();
|
|
134
|
+
this.lastFailure = {
|
|
135
|
+
op,
|
|
136
|
+
entity,
|
|
137
|
+
error: err instanceof Error ? err.message : String(err),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Snapshot for /api/health. Healthy = the last op succeeded (or none have
|
|
142
|
+
* run yet) AND there is no abnormal in-flight backlog. The failure count
|
|
143
|
+
* is informational; a single transient Voyage 503 shouldn't permanently
|
|
144
|
+
* mark the service unhealthy, but operators can see the trend.
|
|
145
|
+
*/
|
|
146
|
+
getHealth() {
|
|
147
|
+
return {
|
|
148
|
+
healthy: this.lastFailure === null,
|
|
149
|
+
failureCount: this.failureCount,
|
|
150
|
+
inFlight: this.inFlight,
|
|
151
|
+
lastFailureAt: this.lastFailureAt,
|
|
152
|
+
lastFailure: this.lastFailure,
|
|
153
|
+
embeddingsEnabled: !!this.voyageApiKey,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** Inject the workspace-global asset ownership index (assets.db). Lets
|
|
157
|
+
* `upsert` fold embedded-image captions into an entry's search text. */
|
|
158
|
+
setAssetIndex(index) {
|
|
159
|
+
this.assetIndex = index;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The captions of every immutable-keyed image an entry embeds, joined for
|
|
163
|
+
* folding into the entry's FTS/embedding text (asset-as-embed, decision D2).
|
|
164
|
+
*
|
|
165
|
+
* The caption + OCR text is derived once per image and stored in
|
|
166
|
+
* `assets.db.caption`, keyed by the immutable assetId (NOT in a sidecar or
|
|
167
|
+
* the body). An entry becomes findable by an embedded image's visual content
|
|
168
|
+
* by reading those captions back here — for the `material` body embed, the
|
|
169
|
+
* `reference` thumbnail, a note body image, etc. Each captioned image's text
|
|
170
|
+
* is read from the single assets.db row, so the same image embedded by N
|
|
171
|
+
* entries enriches all N without duplicating the stored caption.
|
|
172
|
+
*
|
|
173
|
+
* Forward-only (entry → the assets IT embeds) — no reverse index, no
|
|
174
|
+
* cross-repo ownership claim. Best-effort: returns undefined without an index
|
|
175
|
+
* or when nothing embedded is captioned.
|
|
176
|
+
*/
|
|
177
|
+
resolveEmbeddedCaptions(entity) {
|
|
178
|
+
const index = this.assetIndex;
|
|
179
|
+
if (!index)
|
|
180
|
+
return undefined;
|
|
181
|
+
// `embeddedAssetIds` (core/embeds.ts) is the SHARED definition of "which
|
|
182
|
+
// assets does this entry embed" — body + string frontmatter, immutable-key
|
|
183
|
+
// urls only — also used by the sweep's embedder re-index, so the two never
|
|
184
|
+
// disagree on coverage. It applies a cheap substring pre-check, so a no-asset
|
|
185
|
+
// entry costs no regex.
|
|
186
|
+
const ids = embeddedAssetIds(entity.document?.content ?? '', entity.data);
|
|
187
|
+
if (ids.size === 0)
|
|
188
|
+
return undefined;
|
|
189
|
+
const captions = [];
|
|
190
|
+
for (const id of ids) {
|
|
191
|
+
try {
|
|
192
|
+
const caption = index.get(id)?.caption?.trim();
|
|
193
|
+
if (caption)
|
|
194
|
+
captions.push(caption);
|
|
195
|
+
}
|
|
196
|
+
catch { /* best-effort: a lookup failure must not fail the index */ }
|
|
197
|
+
}
|
|
198
|
+
return captions.length ? captions.join('\n') : undefined;
|
|
199
|
+
}
|
|
37
200
|
/**
|
|
38
201
|
* Open/create the LanceDB table and ensure the FTS index exists.
|
|
39
202
|
* Call once before using the service.
|
|
@@ -41,11 +204,44 @@ export class VectorService {
|
|
|
41
204
|
async init() {
|
|
42
205
|
if (this.initialized)
|
|
43
206
|
return;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
207
|
+
// Single-flight: concurrent callers share one in-flight init.
|
|
208
|
+
if (!this.initPromise)
|
|
209
|
+
this.initPromise = this.doInit();
|
|
210
|
+
await this.initPromise;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Run a mutating LanceDB op under the per-instance write lock so concurrent
|
|
214
|
+
* writers (foreground entity writes vs. the asset-index drain) can't collide
|
|
215
|
+
* on a shared table's optimistic-concurrency commit. Ops run strictly in the
|
|
216
|
+
* order `withWrite` is called; a throwing op rejects to ITS caller without
|
|
217
|
+
* poisoning the chain for the next writer.
|
|
218
|
+
*/
|
|
219
|
+
withWrite(fn) {
|
|
220
|
+
const run = this.writeChain.then(fn, fn);
|
|
221
|
+
// Keep the chain alive regardless of this op's outcome (swallow on the
|
|
222
|
+
// chain copy only; the real result/throw still goes to the caller).
|
|
223
|
+
this.writeChain = run.then(() => undefined, () => undefined);
|
|
224
|
+
return run;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Open (once) the shared LanceDB connection. Both `init()` and
|
|
228
|
+
* `initStateTable()` go through this so they never race to assign `this.db`.
|
|
229
|
+
*/
|
|
230
|
+
async ensureDb() {
|
|
231
|
+
if (this.db)
|
|
232
|
+
return this.db;
|
|
233
|
+
if (!this.dbPromise) {
|
|
234
|
+
mkdirSync(this.dbPath, { recursive: true });
|
|
235
|
+
this.dbPromise = lancedb.connect(this.dbPath);
|
|
236
|
+
}
|
|
237
|
+
this.db = await this.dbPromise;
|
|
238
|
+
return this.db;
|
|
239
|
+
}
|
|
240
|
+
async doInit() {
|
|
241
|
+
const db = await this.ensureDb();
|
|
242
|
+
const tableNames = await db.tableNames();
|
|
47
243
|
if (tableNames.includes(TABLE_NAME)) {
|
|
48
|
-
this.table = await
|
|
244
|
+
this.table = await db.openTable(TABLE_NAME);
|
|
49
245
|
}
|
|
50
246
|
else {
|
|
51
247
|
// Create table with a seed record (LanceDB infers schema from first batch)
|
|
@@ -58,7 +254,7 @@ export class VectorService {
|
|
|
58
254
|
vector: new Array(VECTOR_DIM).fill(0),
|
|
59
255
|
updated_at: new Date().toISOString(),
|
|
60
256
|
};
|
|
61
|
-
this.table = await
|
|
257
|
+
this.table = await db.createTable(TABLE_NAME, [seed]);
|
|
62
258
|
// Create FTS index on text column
|
|
63
259
|
await this.table.createIndex('text', {
|
|
64
260
|
config: lancedb.Index.fts(),
|
|
@@ -68,6 +264,156 @@ export class VectorService {
|
|
|
68
264
|
}
|
|
69
265
|
this.initialized = true;
|
|
70
266
|
}
|
|
267
|
+
// ─── Asset index state (mutable, LanceDB-only; keyed by assetId) ─────────────
|
|
268
|
+
/**
|
|
269
|
+
* Open/create the side table for asset index state. Independent of `init()`
|
|
270
|
+
* so state-only callers (and tests) don't pay for the entities table. Lazy
|
|
271
|
+
* because most workspaces never need it until the first asset is indexed.
|
|
272
|
+
*/
|
|
273
|
+
async initStateTable() {
|
|
274
|
+
if (this.stateInitialized)
|
|
275
|
+
return;
|
|
276
|
+
// Single-flight: concurrent state readers/writers share one in-flight init,
|
|
277
|
+
// so two callers can't both take the createTable branch (which would throw
|
|
278
|
+
// "table already exists" on the loser).
|
|
279
|
+
if (!this.stateInitPromise)
|
|
280
|
+
this.stateInitPromise = this.doInitStateTable();
|
|
281
|
+
await this.stateInitPromise;
|
|
282
|
+
}
|
|
283
|
+
async doInitStateTable() {
|
|
284
|
+
const db = await this.ensureDb();
|
|
285
|
+
const names = await db.tableNames();
|
|
286
|
+
if (names.includes(INDEX_STATE_TABLE)) {
|
|
287
|
+
this.stateTable = await db.openTable(INDEX_STATE_TABLE);
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
const seed = {
|
|
291
|
+
id: '__seed__', repo: '', entity_id: '', index_status: 'pending',
|
|
292
|
+
indexed_at: '', index_version: 0, reason: '',
|
|
293
|
+
};
|
|
294
|
+
this.stateTable = await db.createTable(INDEX_STATE_TABLE, [seed]);
|
|
295
|
+
await this.stateTable.delete(`id = '__seed__'`);
|
|
296
|
+
}
|
|
297
|
+
this.stateInitialized = true;
|
|
298
|
+
}
|
|
299
|
+
toState(r) {
|
|
300
|
+
return {
|
|
301
|
+
assetId: r.entity_id, // legacy column name; holds the immutable UUID
|
|
302
|
+
repo: r.repo,
|
|
303
|
+
status: r.index_status,
|
|
304
|
+
indexedAt: r.indexed_at,
|
|
305
|
+
version: r.index_version,
|
|
306
|
+
reason: r.reason,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Read the `text` actually indexed for one entity (the value `buildEntityText`
|
|
311
|
+
* produced — markdown body plus, for assets, the extracted sidecar). Null when
|
|
312
|
+
* no row exists. This is the searchable content of record, independent of FTS
|
|
313
|
+
* index freshness, so it's the deterministic way to assert "the asset's body
|
|
314
|
+
* reached the index" (e.g. the docx stub-upsert-race regression test).
|
|
315
|
+
*/
|
|
316
|
+
async getIndexedText(repo, entityType, entityId) {
|
|
317
|
+
await this.init();
|
|
318
|
+
const id = `${repo}/${entityType}/${entityId}`.replace(/'/g, "''");
|
|
319
|
+
const rows = await this.table.query().where(`id = '${id}'`).limit(1).toArray();
|
|
320
|
+
const row = rows.find((r) => r.id !== '__seed__');
|
|
321
|
+
return row ? row.text : null;
|
|
322
|
+
}
|
|
323
|
+
/** Read one asset's index state, or null when no row exists (never-derived). */
|
|
324
|
+
async getIndexState(assetId) {
|
|
325
|
+
await this.initStateTable();
|
|
326
|
+
const id = assetId.replace(/'/g, "''");
|
|
327
|
+
const rows = await this.stateTable.query().where(`id = '${id}'`).limit(1).toArray();
|
|
328
|
+
const row = rows.find((r) => r.id !== '__seed__');
|
|
329
|
+
return row ? this.toState(row) : null;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Load every index-state row into a Map keyed by assetId. The boot sweep uses
|
|
333
|
+
* this to decide, per image asset, whether a row is missing (never-derived),
|
|
334
|
+
* stale (old version), or unfinished (pending) — without re-deriving the
|
|
335
|
+
* whole set (PERF1).
|
|
336
|
+
*/
|
|
337
|
+
async getAllIndexStates() {
|
|
338
|
+
await this.initStateTable();
|
|
339
|
+
const rows = await this.stateTable.query().toArray();
|
|
340
|
+
const map = new Map();
|
|
341
|
+
for (const r of rows) {
|
|
342
|
+
if (r.id === '__seed__')
|
|
343
|
+
continue;
|
|
344
|
+
// Key by the authoritative PK `id` (== assetId for current rows), matching
|
|
345
|
+
// getIndexState/setIndexState. Legacy entity-keyed rows from the old
|
|
346
|
+
// pipeline have `id = '<repo>/<entityId>'`, which can never equal a UUID
|
|
347
|
+
// assetId, so they stay inert here (the sweep looks up by assetId) rather
|
|
348
|
+
// than being mistaken for a current row via their bare `entity_id`.
|
|
349
|
+
map.set(r.id, this.toState(r));
|
|
350
|
+
}
|
|
351
|
+
return map;
|
|
352
|
+
}
|
|
353
|
+
/** Upsert an asset's index state. Stamps `indexed_at` + current version unless overridden. */
|
|
354
|
+
async setIndexState(assetId, status, opts = {}) {
|
|
355
|
+
await this.initStateTable();
|
|
356
|
+
const record = {
|
|
357
|
+
id: assetId,
|
|
358
|
+
repo: opts.repo ?? '',
|
|
359
|
+
entity_id: assetId,
|
|
360
|
+
index_status: status,
|
|
361
|
+
indexed_at: opts.indexedAt ?? new Date().toISOString(),
|
|
362
|
+
index_version: opts.version ?? ASSET_INDEX_VERSION,
|
|
363
|
+
reason: opts.reason ?? '',
|
|
364
|
+
};
|
|
365
|
+
await this.withWrite(() => this.stateTable
|
|
366
|
+
.mergeInsert('id')
|
|
367
|
+
.whenMatchedUpdateAll()
|
|
368
|
+
.whenNotMatchedInsertAll()
|
|
369
|
+
.execute([record]));
|
|
370
|
+
}
|
|
371
|
+
/** Drop an asset's index-state row (e.g. when the asset is deleted). */
|
|
372
|
+
async deleteIndexState(assetId) {
|
|
373
|
+
await this.initStateTable();
|
|
374
|
+
const id = assetId.replace(/'/g, "''");
|
|
375
|
+
await this.withWrite(() => this.stateTable.delete(`id = '${id}'`));
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Register the single sink for "a new indexable image needs captioning."
|
|
379
|
+
* The live caption drain (AssetIndexQueue) registers here; the chokepoint
|
|
380
|
+
* fires from `ensureInitialAssetIndexState`, covering every image-upload path
|
|
381
|
+
* at once. Replaces per-call-site enqueue wiring.
|
|
382
|
+
*/
|
|
383
|
+
setOnAssetPending(cb) {
|
|
384
|
+
this.onAssetPendingCb = cb;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Seed the initial index state for a freshly-stored IMAGE asset, IF it has no
|
|
388
|
+
* row yet, and notify the live caption drain. Called by the asset-creation
|
|
389
|
+
* paths (graph.uploadAsset, asset-finalize-service) after the assets.db row
|
|
390
|
+
* is written — keyed by the immutable assetId, never an entity.
|
|
391
|
+
*
|
|
392
|
+
* State *transitions* (full/failed) are owned by the caption sweep; this only
|
|
393
|
+
* establishes the `pending` starting point + fires the drain. Only raster
|
|
394
|
+
* images are captioned: SVG stays transitional (sanitize-html not wired);
|
|
395
|
+
* documents/opaque binaries carry no caption. A re-seed (row already exists)
|
|
396
|
+
* early-returns so the drain can't loop. Best-effort: a state-write failure
|
|
397
|
+
* must not fail the upload.
|
|
398
|
+
*/
|
|
399
|
+
async ensureInitialAssetIndexState(assetId, opts) {
|
|
400
|
+
if (!isCaptionableImage(opts.mediaType, opts.filename))
|
|
401
|
+
return;
|
|
402
|
+
try {
|
|
403
|
+
const existing = await this.getIndexState(assetId);
|
|
404
|
+
if (existing)
|
|
405
|
+
return;
|
|
406
|
+
await this.setIndexState(assetId, 'pending', { repo: opts.repo });
|
|
407
|
+
try {
|
|
408
|
+
this.onAssetPendingCb?.(assetId);
|
|
409
|
+
}
|
|
410
|
+
catch { /* non-fatal */ }
|
|
411
|
+
}
|
|
412
|
+
catch (err) {
|
|
413
|
+
// eslint-disable-next-line no-console
|
|
414
|
+
console.warn(`[vector] asset index-state seed failed for ${assetId}: ${err instanceof Error ? err.message : err}`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
71
417
|
/**
|
|
72
418
|
* Index or re-index a single entity.
|
|
73
419
|
* Safe to call on create, update, or as part of bulk indexing.
|
|
@@ -75,7 +421,7 @@ export class VectorService {
|
|
|
75
421
|
async upsert(repoName, entity) {
|
|
76
422
|
await this.init();
|
|
77
423
|
const id = `${repoName}/${entity.entityType}/${entity.id}`;
|
|
78
|
-
const text = buildEntityText(entity);
|
|
424
|
+
const text = buildEntityText(entity, this.resolveEmbeddedCaptions(entity));
|
|
79
425
|
const vector = this.voyageApiKey
|
|
80
426
|
? await this.generateEmbedding(text)
|
|
81
427
|
: null;
|
|
@@ -89,24 +435,29 @@ export class VectorService {
|
|
|
89
435
|
vector: vector ?? new Array(VECTOR_DIM).fill(0),
|
|
90
436
|
updated_at: new Date().toISOString(),
|
|
91
437
|
};
|
|
92
|
-
await this.table
|
|
438
|
+
await this.withWrite(() => this.table
|
|
93
439
|
.mergeInsert('id')
|
|
94
440
|
.whenMatchedUpdateAll()
|
|
95
441
|
.whenNotMatchedInsertAll()
|
|
96
|
-
.execute([record]);
|
|
442
|
+
.execute([record]));
|
|
97
443
|
}
|
|
98
444
|
/**
|
|
99
445
|
* Bulk upsert — used by `studiograph index`. Batches Voyage API calls.
|
|
100
446
|
*/
|
|
101
|
-
async upsertMany(repoName, entities) {
|
|
447
|
+
async upsertMany(repoName, entities, opts = {}) {
|
|
102
448
|
await this.init();
|
|
103
449
|
if (entities.length === 0)
|
|
104
450
|
return;
|
|
105
|
-
const texts = entities.map(e => buildEntityText(e));
|
|
451
|
+
const texts = entities.map(e => buildEntityText(e, this.resolveEmbeddedCaptions(e)));
|
|
106
452
|
// Batch embeddings (Voyage supports up to 128 per request)
|
|
107
453
|
let vectors = new Array(entities.length).fill(null);
|
|
108
454
|
if (this.voyageApiKey) {
|
|
109
|
-
vectors = await this.generateEmbeddingsBatch(texts);
|
|
455
|
+
vectors = await this.generateEmbeddingsBatch(texts, opts.onProgress);
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
// No embedding step — report the whole batch as "done" once so
|
|
459
|
+
// progress UIs that wait on at least one callback don't sit at 0%.
|
|
460
|
+
opts.onProgress?.(entities.length, entities.length);
|
|
110
461
|
}
|
|
111
462
|
const records = entities.map((entity, i) => ({
|
|
112
463
|
id: `${repoName}/${entity.entityType}/${entity.id}`,
|
|
@@ -117,11 +468,11 @@ export class VectorService {
|
|
|
117
468
|
vector: vectors[i] ?? new Array(VECTOR_DIM).fill(0),
|
|
118
469
|
updated_at: new Date().toISOString(),
|
|
119
470
|
}));
|
|
120
|
-
await this.table
|
|
471
|
+
await this.withWrite(() => this.table
|
|
121
472
|
.mergeInsert('id')
|
|
122
473
|
.whenMatchedUpdateAll()
|
|
123
474
|
.whenNotMatchedInsertAll()
|
|
124
|
-
.execute(records);
|
|
475
|
+
.execute(records));
|
|
125
476
|
}
|
|
126
477
|
/**
|
|
127
478
|
* Remove an entity from the index.
|
|
@@ -129,7 +480,48 @@ export class VectorService {
|
|
|
129
480
|
async delete(repoName, entityType, entityId) {
|
|
130
481
|
await this.init();
|
|
131
482
|
const id = `${repoName}/${entityType}/${entityId}`;
|
|
132
|
-
await this.table.delete(`id = '${id.replace(/'/g, "''")}'`);
|
|
483
|
+
await this.withWrite(() => this.table.delete(`id = '${id.replace(/'/g, "''")}'`));
|
|
484
|
+
// No asset index-state reap here: under asset-as-embed the caption state is
|
|
485
|
+
// keyed by the immutable assetId and survives deletion of any entry that
|
|
486
|
+
// merely embeds the asset. The state row is reaped only when the asset
|
|
487
|
+
// itself is deleted (graph.deleteAssetById → vectorService.deleteIndexState).
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Remove an entity by `(repo, id)` alone, without needing its type.
|
|
491
|
+
*
|
|
492
|
+
* Used by the serve-boot incremental indexer: when git diff reports a
|
|
493
|
+
* deletion, the file is gone from disk so its type can't be resolved
|
|
494
|
+
* from frontmatter. The vector store has a discrete `entity_id` column
|
|
495
|
+
* so we can match on `repo + entity_id` without falling back to a LIKE
|
|
496
|
+
* pattern on the synthetic id.
|
|
497
|
+
*
|
|
498
|
+
* Safe across type renames: a single id that legitimately had two type
|
|
499
|
+
* rows (e.g. type changed mid-edit and both old + new still exist) gets
|
|
500
|
+
* both wiped — which is the right behavior for incremental rebuild
|
|
501
|
+
* since the next upsert recreates the current type's row.
|
|
502
|
+
*/
|
|
503
|
+
async deleteByRepoAndId(repoName, entityId) {
|
|
504
|
+
await this.init();
|
|
505
|
+
const r = repoName.replace(/'/g, "''");
|
|
506
|
+
const e = entityId.replace(/'/g, "''");
|
|
507
|
+
await this.withWrite(() => this.table.delete(`repo = '${r}' AND entity_id = '${e}'`));
|
|
508
|
+
// No asset index-state reap here either — see delete(): asset state is
|
|
509
|
+
// assetId-keyed and decoupled from the entry's lifecycle.
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Best-effort `deleteIndexState` for the asset-delete path: the blob/index
|
|
513
|
+
* delete is the authoritative op, so a failure to reap the state row must not
|
|
514
|
+
* turn a successful asset delete into a thrown error. Called by
|
|
515
|
+
* graph.deleteAssetById.
|
|
516
|
+
*/
|
|
517
|
+
async deleteIndexStateSafe(assetId) {
|
|
518
|
+
try {
|
|
519
|
+
await this.deleteIndexState(assetId);
|
|
520
|
+
}
|
|
521
|
+
catch (err) {
|
|
522
|
+
// eslint-disable-next-line no-console
|
|
523
|
+
console.warn(`[vector] index-state cleanup failed for ${assetId}: ${err instanceof Error ? err.message : err}`);
|
|
524
|
+
}
|
|
133
525
|
}
|
|
134
526
|
/**
|
|
135
527
|
* Search the index.
|
|
@@ -140,22 +532,35 @@ export class VectorService {
|
|
|
140
532
|
const limit = options.limit ?? 10;
|
|
141
533
|
try {
|
|
142
534
|
let rows;
|
|
535
|
+
// Repo scoping is a PRE-filter pushed into the query, not a post-filter on
|
|
536
|
+
// the result page. Filtering after `.limit()` silently drops a scoped
|
|
537
|
+
// repo's matches whenever the global top-K is dominated by other repos —
|
|
538
|
+
// e.g. a `repos:['studiograph']` search returning nothing while the same
|
|
539
|
+
// query unscoped ranks a studiograph doc #1. `where` applies BEFORE the
|
|
540
|
+
// limit so the K results are already within scope.
|
|
541
|
+
const repoWhere = options.repos && options.repos.length > 0
|
|
542
|
+
? options.repos.map(r => `repo = '${r.replace(/'/g, "''")}'`).join(' OR ')
|
|
543
|
+
: null;
|
|
143
544
|
if (this.voyageApiKey) {
|
|
144
545
|
// Tier 2: hybrid search
|
|
145
546
|
const queryVector = await this.generateEmbedding(query);
|
|
146
|
-
|
|
147
|
-
|
|
547
|
+
let q = this.table.search(queryVector);
|
|
548
|
+
if (repoWhere)
|
|
549
|
+
q = q.where(repoWhere);
|
|
550
|
+
rows = await q
|
|
148
551
|
.limit(limit * 2) // fetch extra for re-ranking
|
|
149
552
|
.toArray();
|
|
150
553
|
}
|
|
151
554
|
else {
|
|
152
555
|
// Tier 1: FTS only
|
|
153
|
-
|
|
154
|
-
|
|
556
|
+
let q = this.table.search(query, 'text');
|
|
557
|
+
if (repoWhere)
|
|
558
|
+
q = q.where(repoWhere);
|
|
559
|
+
rows = await q
|
|
155
560
|
.limit(limit)
|
|
156
561
|
.toArray();
|
|
157
562
|
}
|
|
158
|
-
|
|
563
|
+
const results = rows
|
|
159
564
|
.filter((r) => r.id !== '__seed__' && r.entity_id !== '')
|
|
160
565
|
.map((r, i) => ({
|
|
161
566
|
repoName: r.repo,
|
|
@@ -163,9 +568,6 @@ export class VectorService {
|
|
|
163
568
|
entityId: r.entity_id,
|
|
164
569
|
score: r._distance != null ? 1 / (1 + r._distance) : 1 - i * 0.01,
|
|
165
570
|
}));
|
|
166
|
-
if (options.repos && options.repos.length > 0) {
|
|
167
|
-
results = results.filter(r => options.repos.includes(r.repoName));
|
|
168
|
-
}
|
|
169
571
|
return results.slice(0, limit);
|
|
170
572
|
}
|
|
171
573
|
catch {
|
|
@@ -188,9 +590,13 @@ export class VectorService {
|
|
|
188
590
|
}
|
|
189
591
|
}
|
|
190
592
|
/**
|
|
191
|
-
* Record the
|
|
593
|
+
* Record the last index time for a repo.
|
|
594
|
+
*
|
|
595
|
+
* Production callers omit `isoTimestamp` and the current time is used.
|
|
596
|
+
* Tests pass an explicit ISO timestamp so they can rewind the clock and
|
|
597
|
+
* assert the git-log `--since` window picks up the right commits.
|
|
192
598
|
*/
|
|
193
|
-
setLastIndexedTime(repoName) {
|
|
599
|
+
setLastIndexedTime(repoName, isoTimestamp) {
|
|
194
600
|
mkdirSync(this.dbPath, { recursive: true });
|
|
195
601
|
let data = {};
|
|
196
602
|
if (existsSync(this.lastIndexedPath)) {
|
|
@@ -199,7 +605,7 @@ export class VectorService {
|
|
|
199
605
|
}
|
|
200
606
|
catch { /* ignore */ }
|
|
201
607
|
}
|
|
202
|
-
data[repoName] = new Date().toISOString();
|
|
608
|
+
data[repoName] = isoTimestamp ?? new Date().toISOString();
|
|
203
609
|
writeFileSync(this.lastIndexedPath, JSON.stringify(data, null, 2) + '\n');
|
|
204
610
|
}
|
|
205
611
|
/** Whether Voyage AI embeddings are enabled (Tier 2). */
|
|
@@ -211,10 +617,11 @@ export class VectorService {
|
|
|
211
617
|
const results = await this.generateEmbeddingsBatch([text]);
|
|
212
618
|
return results[0] ?? new Array(VECTOR_DIM).fill(0);
|
|
213
619
|
}
|
|
214
|
-
async generateEmbeddingsBatch(texts) {
|
|
620
|
+
async generateEmbeddingsBatch(texts, onProgress) {
|
|
215
621
|
// Voyage supports up to 128 inputs per request
|
|
216
622
|
const BATCH_SIZE = 128;
|
|
217
623
|
const all = [];
|
|
624
|
+
const total = texts.length;
|
|
218
625
|
for (let i = 0; i < texts.length; i += BATCH_SIZE) {
|
|
219
626
|
const batch = texts.slice(i, i + BATCH_SIZE);
|
|
220
627
|
const response = await fetch(VOYAGE_API_URL, {
|
|
@@ -231,6 +638,7 @@ export class VectorService {
|
|
|
231
638
|
}
|
|
232
639
|
const json = await response.json();
|
|
233
640
|
all.push(...json.data.map(d => d.embedding));
|
|
641
|
+
onProgress?.(all.length, total);
|
|
234
642
|
}
|
|
235
643
|
return all;
|
|
236
644
|
}
|
|
@@ -246,10 +654,15 @@ export class VectorService {
|
|
|
246
654
|
export async function reindexWorkspace(workspacePath, repos, onProgress) {
|
|
247
655
|
const { loadUserConfig } = await import('../core/user-config.js');
|
|
248
656
|
const { BaseGraphManager } = await import('../core/graph.js');
|
|
657
|
+
const { AssetIndexService } = await import('./assets/asset-index-service.js');
|
|
249
658
|
const { homedir } = await import('os');
|
|
250
659
|
const userConfig = loadUserConfig();
|
|
251
660
|
const dbPath = userConfig.vector_db_path || join(homedir(), '.studiograph', 'vector');
|
|
252
661
|
const vectorService = new VectorService(dbPath, userConfig.voyage_api_key);
|
|
662
|
+
// Wire the assets.db handle so a cold reindex still folds embedded-image
|
|
663
|
+
// captions into entry search text (otherwise it would overwrite the server's
|
|
664
|
+
// caption-folded rows with caption-less ones).
|
|
665
|
+
vectorService.setAssetIndex(new AssetIndexService(workspacePath));
|
|
253
666
|
await vectorService.init();
|
|
254
667
|
const log = onProgress ?? (() => { });
|
|
255
668
|
let total = 0;
|
|
@@ -277,13 +690,151 @@ export async function reindexWorkspace(workspacePath, repos, onProgress) {
|
|
|
277
690
|
}
|
|
278
691
|
return total;
|
|
279
692
|
}
|
|
693
|
+
export async function incrementalReindexWorkspace(workspaceManager, repos, workspacePath, opts = {}) {
|
|
694
|
+
const vectorService = workspaceManager.vectorService;
|
|
695
|
+
if (!vectorService) {
|
|
696
|
+
return { total: 0, fresh: false };
|
|
697
|
+
}
|
|
698
|
+
const log = opts.log ?? (() => { });
|
|
699
|
+
const { execFileSync } = await import('child_process');
|
|
700
|
+
let total = 0;
|
|
701
|
+
let anyFreshRepo = false;
|
|
702
|
+
const staleEntities = [];
|
|
703
|
+
// Pre-pass: figure out the total first-time entity count so the
|
|
704
|
+
// progress callback has a stable denominator. Cheap — `graph.list()`
|
|
705
|
+
// doesn't re-read files, it returns the in-memory graph state the
|
|
706
|
+
// workspace manager already maintains.
|
|
707
|
+
let firstTimeTotal = 0;
|
|
708
|
+
if (opts.onFirstTimeProgress) {
|
|
709
|
+
for (const repo of repos) {
|
|
710
|
+
if (vectorService.getLastIndexedTime(repo.name))
|
|
711
|
+
continue;
|
|
712
|
+
try {
|
|
713
|
+
firstTimeTotal += workspaceManager.getGraph(repo.name).list().length;
|
|
714
|
+
}
|
|
715
|
+
catch {
|
|
716
|
+
// tolerate per-repo failure; the real loop below will log it
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
let firstTimeDone = 0;
|
|
721
|
+
for (const repo of repos) {
|
|
722
|
+
const lastIndexed = vectorService.getLastIndexedTime(repo.name);
|
|
723
|
+
// Per-repo first-time index. Catches three cases:
|
|
724
|
+
// 1. Very first `serve` boot (every repo missing a timestamp).
|
|
725
|
+
// 2. New folder added between serve boots (existing workspace +
|
|
726
|
+
// new repo with no timestamp). Pre-fix this was skipped here
|
|
727
|
+
// and never indexed unless the operator ran a full reindex.
|
|
728
|
+
// 3. Vector DB rebuilt from scratch but workspace has existing
|
|
729
|
+
// folders.
|
|
730
|
+
if (!lastIndexed) {
|
|
731
|
+
try {
|
|
732
|
+
const graph = workspaceManager.getGraph(repo.name);
|
|
733
|
+
const entities = graph.list();
|
|
734
|
+
if (entities.length > 0) {
|
|
735
|
+
await vectorService.upsertMany(repo.name, entities, {
|
|
736
|
+
onProgress: (batchDone) => {
|
|
737
|
+
opts.onFirstTimeProgress?.(firstTimeDone + batchDone, firstTimeTotal);
|
|
738
|
+
},
|
|
739
|
+
});
|
|
740
|
+
firstTimeDone += entities.length;
|
|
741
|
+
total += entities.length;
|
|
742
|
+
}
|
|
743
|
+
vectorService.setLastIndexedTime(repo.name);
|
|
744
|
+
anyFreshRepo = true;
|
|
745
|
+
}
|
|
746
|
+
catch (err) {
|
|
747
|
+
log(`failed to index ${repo.name}: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
748
|
+
}
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
// Established repo — diff git log since the last index timestamp and
|
|
752
|
+
// collect a list of stale (repo, id) tuples to upsert / delete below.
|
|
753
|
+
const repoPath = join(workspacePath, repo.path);
|
|
754
|
+
if (!existsSync(repoPath))
|
|
755
|
+
continue;
|
|
756
|
+
try {
|
|
757
|
+
const output = execFileSync('git', ['log', `--since=${lastIndexed}`, '--name-status', '--format=', '--', '*.md'], { cwd: repoPath, encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
758
|
+
if (!output)
|
|
759
|
+
continue;
|
|
760
|
+
for (const line of output.split('\n')) {
|
|
761
|
+
// Accept any markdown path. Layouts in the wild:
|
|
762
|
+
// - flat: `entity-id.md`
|
|
763
|
+
// - typed: `<type>/entity-id.md`
|
|
764
|
+
// - nested: `folder/sub/entity-id.md`
|
|
765
|
+
// STU-131 normalized on flat for new entities; older typed layouts
|
|
766
|
+
// and arbitrary nested folders still appear in mixed repos. Entity
|
|
767
|
+
// type lives in frontmatter (resolved via graph.getById for
|
|
768
|
+
// upserts; not needed for deletes since we now match by `(repo,
|
|
769
|
+
// entity_id)` columns). Pre-fix this regex required exactly one
|
|
770
|
+
// slash with a `\w+` type segment and missed all three layouts,
|
|
771
|
+
// plus hyphenated types like `case-study`.
|
|
772
|
+
const m = line.match(/^([AMD])\s+(.+\.md)$/);
|
|
773
|
+
if (!m)
|
|
774
|
+
continue;
|
|
775
|
+
const [, status, path] = m;
|
|
776
|
+
// basename minus `.md`. Entity IDs are unique within a repo.
|
|
777
|
+
const id = path.split('/').pop().replace(/\.md$/, '');
|
|
778
|
+
if (!id)
|
|
779
|
+
continue;
|
|
780
|
+
staleEntities.push({ repoName: repo.name, entityId: id, deleted: status === 'D' });
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
catch (err) {
|
|
784
|
+
log(`failed to diff ${repo.name}: ${err instanceof Error ? err.message : 'unknown'}`);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (staleEntities.length === 0) {
|
|
788
|
+
// Nothing changed via git diff. If we did first-time work above, that
|
|
789
|
+
// counts as a fresh run; otherwise this was a no-op incremental boot.
|
|
790
|
+
return { total, fresh: anyFreshRepo };
|
|
791
|
+
}
|
|
792
|
+
// Dedupe: if an entity appears multiple times (e.g. M then D), the last
|
|
793
|
+
// entry wins. Order matters — git log is newest-first by default, so we
|
|
794
|
+
// reverse before reducing to get the newest state per (repo, id).
|
|
795
|
+
const seen = new Map();
|
|
796
|
+
for (const item of staleEntities.slice().reverse()) {
|
|
797
|
+
seen.set(`${item.repoName}/${item.entityId}`, item);
|
|
798
|
+
}
|
|
799
|
+
for (const item of seen.values()) {
|
|
800
|
+
try {
|
|
801
|
+
if (item.deleted) {
|
|
802
|
+
// Delete by (repo, id) — type isn't recoverable from a deleted file.
|
|
803
|
+
// The new column-based matcher in vectorService handles it without
|
|
804
|
+
// a frontmatter lookup.
|
|
805
|
+
await vectorService.deleteByRepoAndId(item.repoName, item.entityId);
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
const graph = workspaceManager.getGraph(item.repoName);
|
|
809
|
+
const entity = graph.getById(item.entityId);
|
|
810
|
+
await vectorService.upsert(item.repoName, entity);
|
|
811
|
+
total++;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
catch {
|
|
815
|
+
// Entity may have been deleted then re-created; safe to skip.
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
// Stamp every repo we touched. Empty-diff repos already had a timestamp
|
|
819
|
+
// (we skipped the rebuild path) — re-stamping is cheap and keeps the
|
|
820
|
+
// "since" window tight for the next boot.
|
|
821
|
+
for (const repo of repos) {
|
|
822
|
+
vectorService.setLastIndexedTime(repo.name);
|
|
823
|
+
}
|
|
824
|
+
return { total, fresh: anyFreshRepo };
|
|
825
|
+
}
|
|
280
826
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
281
827
|
/**
|
|
282
828
|
* Build a text representation of an entity for FTS/embedding.
|
|
283
829
|
* Combines entity type, key frontmatter fields, and markdown body.
|
|
830
|
+
*
|
|
831
|
+
* `extraText` is appended after the body — used by VectorService to
|
|
832
|
+
* fold PDF sidecar text into asset-entity embeddings. Kept as a plain
|
|
833
|
+
* string parameter (not file IO) so this stays pure and unit-testable.
|
|
834
|
+
*
|
|
284
835
|
* Exported for testing.
|
|
285
836
|
*/
|
|
286
|
-
export function buildEntityText(entity) {
|
|
837
|
+
export function buildEntityText(entity, extraText) {
|
|
287
838
|
const parts = [];
|
|
288
839
|
// Entity type and ID as context
|
|
289
840
|
parts.push(`${entity.entityType}: ${entity.data.name || entity.id}`);
|
|
@@ -317,6 +868,11 @@ export function buildEntityText(entity) {
|
|
|
317
868
|
if (plainText)
|
|
318
869
|
parts.push(plainText);
|
|
319
870
|
}
|
|
871
|
+
if (extraText) {
|
|
872
|
+
const trimmed = extraText.trim();
|
|
873
|
+
if (trimmed)
|
|
874
|
+
parts.push(trimmed);
|
|
875
|
+
}
|
|
320
876
|
return parts.join('\n');
|
|
321
877
|
}
|
|
322
878
|
//# sourceMappingURL=vector-service.js.map
|