studiograph 1.3.48-next.2 → 1.3.48-next.201
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 +117 -0
- package/dist/agent/agent-pool.js +287 -0
- package/dist/agent/agent-pool.js.map +1 -0
- 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 +113 -22
- package/dist/agent/orchestrator.js +574 -181
- 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 +147 -69
- 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/entity-schema.md +77 -433
- package/dist/agent/skills/interview/entity-templates.md +193 -0
- package/dist/agent/skills/interview/question-domains.md +391 -0
- package/dist/agent/skills/interview/skill.md +204 -0
- package/dist/agent/skills/schema-rules.md +54 -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 +7 -6
- package/dist/agent/tools/fs-tools.js +5 -4
- package/dist/agent/tools/fs-tools.js.map +1 -1
- package/dist/agent/tools/graph-tools.d.ts +21 -58
- package/dist/agent/tools/graph-tools.js +664 -333
- 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 -38
- 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/admin/folder.js +186 -0
- 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/commit.d.ts +1 -1
- package/dist/cli/commands/commit.js +24 -11
- package/dist/cli/commands/commit.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 +2 -2
- 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 +12 -4
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/orphans.js +14 -30
- package/dist/cli/commands/orphans.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 +142 -63
- package/dist/cli/commands/reset.js.map +1 -1
- package/dist/cli/commands/serve.js +218 -24
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +372 -202
- 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 -35
- 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 +33 -52
- package/dist/cli/setup-wizard.js +43 -68
- 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/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 +77 -0
- package/dist/core/embeds.js +147 -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 +53 -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 +140 -0
- package/dist/core/entity-types-catalog.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 +404 -0
- package/dist/core/format-registry.js.map +1 -0
- package/dist/core/graph.d.ts +731 -14
- package/dist/core/graph.js +2202 -315
- 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 +82 -0
- package/dist/core/schema-registry.js +238 -0
- 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 +80 -475
- package/dist/core/types.js +27 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +75 -7
- package/dist/core/user-config.js +155 -7
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +731 -1790
- package/dist/core/validation.js +442 -228
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +89 -12
- package/dist/core/workspace-manager.js +225 -73
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +19 -5
- package/dist/core/workspace.js +69 -35
- 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 +94 -13
- package/dist/mcp/connector-manager.js +283 -62
- package/dist/mcp/connector-manager.js.map +1 -1
- package/dist/mcp/oauth-provider.d.ts +27 -33
- package/dist/mcp/oauth-provider.js +65 -134
- package/dist/mcp/oauth-provider.js.map +1 -1
- package/dist/mcp/oauth-registry.d.ts +62 -0
- package/dist/mcp/oauth-registry.js +85 -0
- package/dist/mcp/oauth-registry.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -3
- package/dist/mcp/server.js +30 -5
- 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/tools.d.ts +35 -2
- package/dist/mcp/tools.js +1361 -112
- 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/asset-index-queue.d.ts +96 -0
- package/dist/server/asset-index-queue.js +191 -0
- package/dist/server/asset-index-queue.js.map +1 -0
- package/dist/server/body-write-coordinator.d.ts +151 -0
- package/dist/server/body-write-coordinator.js +161 -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 +22 -3
- package/dist/server/index.js +622 -198
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/sanitize.d.ts +46 -0
- package/dist/server/middleware/sanitize.js +171 -0
- package/dist/server/middleware/sanitize.js.map +1 -0
- package/dist/server/routes/asset-api.d.ts +31 -0
- package/dist/server/routes/asset-api.js +593 -0
- package/dist/server/routes/asset-api.js.map +1 -0
- 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.d.ts +3 -2
- package/dist/server/routes/auth-api.js +573 -39
- package/dist/server/routes/auth-api.js.map +1 -1
- package/dist/server/routes/capture-api.d.ts +18 -0
- package/dist/server/routes/capture-api.js +257 -0
- package/dist/server/routes/capture-api.js.map +1 -0
- package/dist/server/routes/chat-sessions-api.d.ts +9 -0
- package/dist/server/routes/chat-sessions-api.js +121 -0
- package/dist/server/routes/chat-sessions-api.js.map +1 -0
- package/dist/server/routes/chat.d.ts +12 -1
- package/dist/server/routes/chat.js +318 -88
- 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 +21 -0
- package/dist/server/routes/config-api.js +256 -0
- package/dist/server/routes/config-api.js.map +1 -0
- package/dist/server/routes/connectors-api.d.ts +17 -0
- package/dist/server/routes/connectors-api.js +410 -0
- package/dist/server/routes/connectors-api.js.map +1 -0
- package/dist/server/routes/event-ingest-api.d.ts +15 -0
- package/dist/server/routes/event-ingest-api.js +125 -0
- package/dist/server/routes/event-ingest-api.js.map +1 -0
- package/dist/server/routes/git-http.d.ts +3 -3
- package/dist/server/routes/git-http.js +86 -38
- 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 +1529 -263
- 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 +384 -38
- 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 +22 -6
- 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 -30
- 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/url-api.d.ts +7 -0
- package/dist/server/routes/url-api.js +74 -0
- package/dist/server/routes/url-api.js.map +1 -0
- package/dist/server/routes/views-api.js +75 -7
- 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 +129 -35
- package/dist/server/routes/workspace-api.js.map +1 -1
- package/dist/server/routes/ws.d.ts +2 -1
- package/dist/server/routes/ws.js +68 -16
- 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 -15
- package/dist/server/session-manager.js.map +1 -1
- package/dist/server/ws-hub.d.ts +138 -14
- package/dist/server/ws-hub.js +0 -0
- package/dist/server/ws-hub.js.map +1 -1
- package/dist/server/yjs-manager.d.ts +285 -7
- package/dist/server/yjs-manager.js +907 -36
- 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/asset-caption-service.d.ts +102 -0
- package/dist/services/asset-caption-service.js +184 -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 +207 -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 +92 -0
- package/dist/services/asset-index-sweep.js +258 -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 +30 -0
- package/dist/services/asset-sidecar-service.js +96 -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 +74 -0
- package/dist/services/asset-upload-service.js +244 -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 +118 -1
- package/dist/services/assets/base.js +77 -1
- package/dist/services/assets/base.js.map +1 -1
- package/dist/services/assets/index.d.ts +103 -1
- package/dist/services/assets/index.js +192 -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 +350 -36
- package/dist/services/auth-service.js +1179 -140
- package/dist/services/auth-service.js.map +1 -1
- package/dist/services/bookmark-import-service.d.ts +49 -0
- package/dist/services/bookmark-import-service.js +250 -0
- package/dist/services/bookmark-import-service.js.map +1 -0
- package/dist/services/chat-session-service.d.ts +96 -0
- package/dist/services/chat-session-service.js +316 -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/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 +210 -0
- package/dist/services/entity-mutations.js +377 -0
- package/dist/services/entity-mutations.js.map +1 -0
- package/dist/services/event-processor.d.ts +104 -0
- package/dist/services/event-processor.js +441 -0
- 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 +54 -0
- package/dist/services/git.js +188 -54
- package/dist/services/git.js.map +1 -1
- package/dist/services/graph-maintenance.d.ts +42 -0
- package/dist/services/graph-maintenance.js +143 -0
- package/dist/services/graph-maintenance.js.map +1 -0
- package/dist/services/import-service.d.ts +58 -3
- package/dist/services/import-service.js +316 -100
- 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/memory-service.d.ts +22 -14
- package/dist/services/memory-service.js +53 -35
- package/dist/services/memory-service.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/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 +260 -6
- package/dist/services/vector-service.js +574 -31
- 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.BZHoBJEc.css +2 -0
- package/dist/web/_app/immutable/assets/12.DlIf1mKh.css +1 -0
- package/dist/web/_app/immutable/assets/13.7d-Q37wc.css +1 -0
- package/dist/web/_app/immutable/assets/14.BwBFdc1D.css +1 -0
- package/dist/web/_app/immutable/assets/15.CmLrbzZp.css +1 -0
- package/dist/web/_app/immutable/assets/16.B0GwXar3.css +1 -0
- package/dist/web/_app/immutable/assets/2.C9Vt4JHy.css +1 -0
- package/dist/web/_app/immutable/assets/3.BFvgCYSk.css +1 -0
- package/dist/web/_app/immutable/assets/4.OmdYF47-.css +1 -0
- package/dist/web/_app/immutable/assets/5.C6MySjPq.css +1 -0
- package/dist/web/_app/immutable/assets/BulkActionsBar.Bx7nxMjH.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.DX1oBeF_.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMutationDialogs.D2B7KrRn.css +1 -0
- package/dist/web/_app/immutable/assets/FolderPicker.B5KdvRYl.css +1 -0
- package/dist/web/_app/immutable/assets/GalleryView.CF48FWYQ.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.BqgpZCv5.css +1 -0
- package/dist/web/_app/immutable/assets/Rail.f8lsriOT.css +1 -0
- package/dist/web/_app/immutable/assets/SettingsDialog.DwMus2u2.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.DriOGAKB.css +1 -0
- package/dist/web/_app/immutable/assets/WorkspaceView.u5VdwRR6.css +1 -0
- package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
- package/dist/web/_app/immutable/assets/checkbox.DK0MgYgb.css +1 -0
- package/dist/web/_app/immutable/assets/dist.DDCWxn3B.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.DiLB0G5L.css +1 -0
- package/dist/web/_app/immutable/assets/select.BFL238eD.css +1 -0
- package/dist/web/_app/immutable/assets/sheet.4rY4hpfJ.css +1 -0
- package/dist/web/_app/immutable/chunks/2oYV6q4R.js +2 -0
- package/dist/web/_app/immutable/chunks/4XSri7g0.js +1 -0
- package/dist/web/_app/immutable/chunks/4iaT0dG72.js +1 -0
- package/dist/web/_app/immutable/chunks/5_TKU9QS2.js +1 -0
- package/dist/web/_app/immutable/chunks/8Yh26Z9_2.js +1 -0
- package/dist/web/_app/immutable/chunks/Atl8xKOm.js +2 -0
- package/dist/web/_app/immutable/chunks/B-Z_xZy_.js +4 -0
- package/dist/web/_app/immutable/chunks/B0pk0Lyx.js +1 -0
- package/dist/web/_app/immutable/chunks/B1RnjnNt.js +1 -0
- package/dist/web/_app/immutable/chunks/B2n86UNJ.js +1 -0
- package/dist/web/_app/immutable/chunks/B318GEUB2.js +1 -0
- package/dist/web/_app/immutable/chunks/B6Lt-qaJ.js +1 -0
- package/dist/web/_app/immutable/chunks/B8yrQWxT2.js +1 -0
- package/dist/web/_app/immutable/chunks/BADt8daH.js +2 -0
- package/dist/web/_app/immutable/chunks/BBGt-XQo.js +3 -0
- package/dist/web/_app/immutable/chunks/BDIUHcEz.js +1 -0
- package/dist/web/_app/immutable/chunks/BDSuq3KH.js +1 -0
- package/dist/web/_app/immutable/chunks/BGiLU5VN.js +1 -0
- package/dist/web/_app/immutable/chunks/BJgOZTHR.js +1 -0
- package/dist/web/_app/immutable/chunks/BOSiTh-42.js +1 -0
- package/dist/web/_app/immutable/chunks/BPxcCdjn.js +1 -0
- package/dist/web/_app/immutable/chunks/BVPNAzAK.js +1 -0
- package/dist/web/_app/immutable/chunks/BcOvJgjM.js +1 -0
- package/dist/web/_app/immutable/chunks/BdYQewoD.js +1 -0
- package/dist/web/_app/immutable/chunks/BfCWIy8t.js +8 -0
- package/dist/web/_app/immutable/chunks/BgRT-K6w.js +5 -0
- package/dist/web/_app/immutable/chunks/BibveGGd.js +1 -0
- package/dist/web/_app/immutable/chunks/BmM5VZ4W.js +1 -0
- package/dist/web/_app/immutable/chunks/BnIYzuS1.js +66 -0
- package/dist/web/_app/immutable/chunks/BoDmwOTJ.js +1 -0
- package/dist/web/_app/immutable/chunks/BoglwbZW.js +1 -0
- package/dist/web/_app/immutable/chunks/Bqm_YrIg2.js +23 -0
- package/dist/web/_app/immutable/chunks/BtMRrdc4.js +2 -0
- package/dist/web/_app/immutable/chunks/C-AnzvKr.js +7 -0
- package/dist/web/_app/immutable/chunks/C1Y3tUpz.js +1 -0
- package/dist/web/_app/immutable/chunks/C6VZhhwF.js +1 -0
- package/dist/web/_app/immutable/chunks/C8IMrD4G2.js +3 -0
- package/dist/web/_app/immutable/chunks/CAXXrbj52.js +1 -0
- package/dist/web/_app/immutable/chunks/CB-0u-Pc2.js +1 -0
- package/dist/web/_app/immutable/chunks/CEniyZ1Z2.js +6 -0
- package/dist/web/_app/immutable/chunks/CJhElIkU2.js +1 -0
- package/dist/web/_app/immutable/chunks/CK8tIaYT.js +1 -0
- package/dist/web/_app/immutable/chunks/CM8uYli8.js +1 -0
- package/dist/web/_app/immutable/chunks/CTzjJm_m2.js +1 -0
- package/dist/web/_app/immutable/chunks/CUXqa1nn2.js +1 -0
- package/dist/web/_app/immutable/chunks/CY0iY_WO.js +1 -0
- package/dist/web/_app/immutable/chunks/CbCfNNV_2.js +2692 -0
- package/dist/web/_app/immutable/chunks/CbuGIyDu2.js +22 -0
- package/dist/web/_app/immutable/chunks/CcRGXA-t.js +1 -0
- package/dist/web/_app/immutable/chunks/CcXmQaYs2.js +1 -0
- package/dist/web/_app/immutable/chunks/CcaQuaSt2.js +1 -0
- package/dist/web/_app/immutable/chunks/CoHaBDpN2.js +2 -0
- package/dist/web/_app/immutable/chunks/Cvbd3myc2.js +14 -0
- package/dist/web/_app/immutable/chunks/D20C1thX2.js +1 -0
- package/dist/web/_app/immutable/chunks/D3JoMtWC.js +7 -0
- package/dist/web/_app/immutable/chunks/D3ch71s_.js +1 -0
- package/dist/web/_app/immutable/chunks/D4xXlMEU.js +2 -0
- package/dist/web/_app/immutable/chunks/D5GipQqN2.js +1 -0
- package/dist/web/_app/immutable/chunks/D9TyJuu_.js +1 -0
- package/dist/web/_app/immutable/chunks/DBFijAmG.js +1 -0
- package/dist/web/_app/immutable/chunks/DHLjkH7T.js +1 -0
- package/dist/web/_app/immutable/chunks/DIfdPIt_2.js +1 -0
- package/dist/web/_app/immutable/chunks/DO_sw49q2.js +1 -0
- package/dist/web/_app/immutable/chunks/DP69PpIj.js +1 -0
- package/dist/web/_app/immutable/chunks/DQ3HSZMs.js +2 -0
- package/dist/web/_app/immutable/chunks/DQMWa2t7.js +1 -0
- package/dist/web/_app/immutable/chunks/DT0wzK622.js +1 -0
- package/dist/web/_app/immutable/chunks/DTnEJArL.js +1 -0
- package/dist/web/_app/immutable/chunks/DToS-G202.js +1 -0
- package/dist/web/_app/immutable/chunks/DZcU6mGe2.js +1 -0
- package/dist/web/_app/immutable/chunks/DbslMybD.js +1 -0
- package/dist/web/_app/immutable/chunks/DcGThsSF.js +1 -0
- package/dist/web/_app/immutable/chunks/DcPrzUMJ.js +1 -0
- package/dist/web/_app/immutable/chunks/De0g5qop2.js +1 -0
- package/dist/web/_app/immutable/chunks/DimS8dbZ2.js +1 -0
- package/dist/web/_app/immutable/chunks/DjuqhOjF.js +1 -0
- package/dist/web/_app/immutable/chunks/Dk6sAhpo.js +3 -0
- package/dist/web/_app/immutable/chunks/Dl6cnwyk.js +1 -0
- package/dist/web/_app/immutable/chunks/DnIQzIOz.js +1 -0
- package/dist/web/_app/immutable/chunks/DnXYAo60.js +1 -0
- package/dist/web/_app/immutable/chunks/DnrImJan.js +1 -0
- package/dist/web/_app/immutable/chunks/Dpuq25vu2.js +1 -0
- package/dist/web/_app/immutable/chunks/DrMZDWru.js +1 -0
- package/dist/web/_app/immutable/chunks/DsVOtl0N.js +1 -0
- package/dist/web/_app/immutable/chunks/DuTXsWdP.js +2 -0
- package/dist/web/_app/immutable/chunks/Dw-frCfE.js +1 -0
- package/dist/web/_app/immutable/chunks/Dz34u8Ie2.js +185 -0
- package/dist/web/_app/immutable/chunks/DzcFeQZU2.js +2 -0
- package/dist/web/_app/immutable/chunks/DzrRTvug.js +1 -0
- package/dist/web/_app/immutable/chunks/G5oUVQa92.js +1 -0
- package/dist/web/_app/immutable/chunks/HyhOhoeq2.js +2 -0
- package/dist/web/_app/immutable/chunks/J5nb9xxj.js +1 -0
- package/dist/web/_app/immutable/chunks/JCjEwqH9.js +1 -0
- package/dist/web/_app/immutable/chunks/JN_nsXUm2.js +1 -0
- package/dist/web/_app/immutable/chunks/JS2_GaB1.js +1 -0
- package/dist/web/_app/immutable/chunks/MtI6dyxu.js +1 -0
- package/dist/web/_app/immutable/chunks/N6vnY5Si2.js +1 -0
- package/dist/web/_app/immutable/chunks/PcEbaKam.js +2 -0
- package/dist/web/_app/immutable/chunks/VTYhCLh9.js +2 -0
- package/dist/web/_app/immutable/chunks/Wowi_89k.js +5 -0
- package/dist/web/_app/immutable/chunks/Y_asqJqs2.js +83 -0
- package/dist/web/_app/immutable/chunks/Yhg5Q4MT.js +1 -0
- package/dist/web/_app/immutable/chunks/f_eYccPf2.js +1 -0
- package/dist/web/_app/immutable/chunks/hm_8RsuL.js +1 -0
- package/dist/web/_app/immutable/chunks/iPCkjliu.js +3 -0
- package/dist/web/_app/immutable/chunks/j2AvgZGz.js +1 -0
- package/dist/web/_app/immutable/chunks/kNaey6uv.js +1 -0
- package/dist/web/_app/immutable/chunks/l1761xxj.js +1 -0
- package/dist/web/_app/immutable/chunks/liGRFQqV2.js +184 -0
- package/dist/web/_app/immutable/chunks/lq1kR86d.js +1 -0
- package/dist/web/_app/immutable/chunks/mIykYR4F2.js +1 -0
- package/dist/web/_app/immutable/chunks/rbhlO_t8.js +1 -0
- package/dist/web/_app/immutable/chunks/tJpAwaTl.js +1 -0
- package/dist/web/_app/immutable/chunks/tcegdii0.js +2 -0
- package/dist/web/_app/immutable/chunks/u8G2EUvz2.js +224 -0
- package/dist/web/_app/immutable/chunks/vgsM0KTm2.js +1 -0
- package/dist/web/_app/immutable/chunks/xcGI4fuV.js +1 -0
- package/dist/web/_app/immutable/chunks/xihTtKlq.js +1 -0
- package/dist/web/_app/immutable/chunks/yEYlhV9G2.js +1 -0
- package/dist/web/_app/immutable/entry/app.DSf_XGp8.js +2 -0
- package/dist/web/_app/immutable/entry/start.B7ScfxPc.js +1 -0
- package/dist/web/_app/immutable/nodes/0.BMSOOETY.js +2 -0
- package/dist/web/_app/immutable/nodes/1.B0lBUpHt.js +1 -0
- package/dist/web/_app/immutable/nodes/10.DmDbUH1j.js +1 -0
- package/dist/web/_app/immutable/nodes/11.gwY7gZdR.js +1 -0
- package/dist/web/_app/immutable/nodes/12.BpGHSr2y.js +1 -0
- package/dist/web/_app/immutable/nodes/13.Bf178QF_.js +1 -0
- package/dist/web/_app/immutable/nodes/14.D_x8-nk9.js +1 -0
- package/dist/web/_app/immutable/nodes/15.DY4XeagL.js +1 -0
- package/dist/web/_app/immutable/nodes/16.DPqftx8x.js +77 -0
- package/dist/web/_app/immutable/nodes/2.OM2LGRpi.js +109 -0
- package/dist/web/_app/immutable/nodes/3.e8ZoPCmC.js +6 -0
- package/dist/web/_app/immutable/nodes/4.BdYR1hNQ.js +11 -0
- package/dist/web/_app/immutable/nodes/5.B8sOFna9.js +5 -0
- package/dist/web/_app/immutable/nodes/6.L1BbYsmo.js +1 -0
- package/dist/web/_app/immutable/nodes/7.B7zoemJD.js +1 -0
- package/dist/web/_app/immutable/nodes/8.B1VtnfMK.js +1 -0
- package/dist/web/_app/immutable/nodes/9.BE3VCQzk.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 +58 -19
- package/dist/web/studiograph-logomark.svg +29 -0
- package/package.json +38 -14
- package/dist/agent/skills/enrich-entities.md +0 -136
- package/dist/agent/skills/obsidian-source-setup.md +0 -246
- package/dist/agent/skills/skill-loader.d.ts +0 -48
- package/dist/agent/skills/skill-loader.js +0 -166
- package/dist/agent/skills/skill-loader.js.map +0 -1
- package/dist/agent/skills/sync-configuration.md +0 -119
- package/dist/agent/skills/sync-setup.md +0 -82
- package/dist/agent/tools/sync-tools.d.ts +0 -35
- package/dist/agent/tools/sync-tools.js +0 -992
- package/dist/agent/tools/sync-tools.js.map +0 -1
- package/dist/auth/github.d.ts +0 -56
- package/dist/auth/github.js +0 -169
- package/dist/auth/github.js.map +0 -1
- package/dist/cli/commands/access.d.ts +0 -11
- package/dist/cli/commands/access.js +0 -156
- package/dist/cli/commands/access.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/auth.d.ts +0 -10
- package/dist/cli/commands/auth.js +0 -79
- package/dist/cli/commands/auth.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 +0 -187
- package/dist/cli/commands/collection.js.map +0 -1
- package/dist/cli/commands/enrich.d.ts +0 -11
- package/dist/cli/commands/enrich.js +0 -135
- package/dist/cli/commands/enrich.js.map +0 -1
- package/dist/cli/commands/graphrag.d.ts +0 -12
- package/dist/cli/commands/graphrag.js +0 -122
- package/dist/cli/commands/graphrag.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/members.d.ts +0 -11
- package/dist/cli/commands/members.js +0 -230
- package/dist/cli/commands/members.js.map +0 -1
- package/dist/cli/commands/org.d.ts +0 -10
- package/dist/cli/commands/org.js +0 -132
- package/dist/cli/commands/org.js.map +0 -1
- package/dist/cli/commands/provision.d.ts +0 -8
- package/dist/cli/commands/provision.js +0 -116
- package/dist/cli/commands/provision.js.map +0 -1
- package/dist/cli/commands/resolve.d.ts +0 -8
- package/dist/cli/commands/resolve.js +0 -85
- package/dist/cli/commands/resolve.js.map +0 -1
- package/dist/cli/commands/review.d.ts +0 -19
- package/dist/cli/commands/review.js +0 -128
- package/dist/cli/commands/review.js.map +0 -1
- package/dist/cli/commands/source.d.ts +0 -16
- package/dist/cli/commands/source.js +0 -159
- package/dist/cli/commands/source.js.map +0 -1
- package/dist/cli/commands/start.d.ts +0 -7
- package/dist/cli/commands/start.js +0 -589
- package/dist/cli/commands/start.js.map +0 -1
- package/dist/cli/commands/sync-collection.d.ts +0 -14
- package/dist/cli/commands/sync-collection.js +0 -355
- package/dist/cli/commands/sync-collection.js.map +0 -1
- package/dist/cli/commands/sync-entities.d.ts +0 -13
- package/dist/cli/commands/sync-entities.js +0 -242
- package/dist/cli/commands/sync-entities.js.map +0 -1
- package/dist/cli/commands/team.d.ts +0 -12
- package/dist/cli/commands/team.js +0 -185
- package/dist/cli/commands/team.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 -153
- 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/cli/sync-review-interactive.d.ts +0 -31
- package/dist/cli/sync-review-interactive.js +0 -393
- package/dist/cli/sync-review-interactive.js.map +0 -1
- package/dist/core/migration-runner.d.ts +0 -42
- package/dist/core/migration-runner.js +0 -232
- package/dist/core/migration-runner.js.map +0 -1
- package/dist/core/migration-types.d.ts +0 -101
- package/dist/core/migration-types.js +0 -21
- package/dist/core/migration-types.js.map +0 -1
- package/dist/core/migrations/20260219-formalize-memory-location.d.ts +0 -2
- package/dist/core/migrations/20260219-formalize-memory-location.js +0 -35
- package/dist/core/migrations/20260219-formalize-memory-location.js.map +0 -1
- package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +0 -12
- package/dist/core/migrations/20260220-add-workspace-metadata.js +0 -65
- package/dist/core/migrations/20260220-add-workspace-metadata.js.map +0 -1
- package/dist/core/migrations/20260220-add-workspace-readme.d.ts +0 -11
- package/dist/core/migrations/20260220-add-workspace-readme.js +0 -82
- package/dist/core/migrations/20260220-add-workspace-readme.js.map +0 -1
- package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +0 -9
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js +0 -64
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +0 -1
- package/dist/core/migrations/index.d.ts +0 -11
- package/dist/core/migrations/index.js +0 -23
- package/dist/core/migrations/index.js.map +0 -1
- package/dist/integrations/asana.d.ts +0 -26
- package/dist/integrations/asana.js +0 -78
- package/dist/integrations/asana.js.map +0 -1
- package/dist/integrations/figma-local.d.ts +0 -16
- package/dist/integrations/figma-local.js +0 -10
- package/dist/integrations/figma-local.js.map +0 -1
- package/dist/integrations/figma.d.ts +0 -17
- package/dist/integrations/figma.js +0 -17
- package/dist/integrations/figma.js.map +0 -1
- package/dist/integrations/granola.d.ts +0 -24
- package/dist/integrations/granola.js +0 -60
- package/dist/integrations/granola.js.map +0 -1
- package/dist/integrations/linear.d.ts +0 -14
- package/dist/integrations/linear.js +0 -80
- package/dist/integrations/linear.js.map +0 -1
- package/dist/integrations/paper-local.d.ts +0 -14
- package/dist/integrations/paper-local.js +0 -10
- package/dist/integrations/paper-local.js.map +0 -1
- package/dist/integrations/paper.d.ts +0 -2
- package/dist/integrations/paper.js +0 -10
- package/dist/integrations/paper.js.map +0 -1
- package/dist/integrations/pipedrive.d.ts +0 -26
- package/dist/integrations/pipedrive.js +0 -97
- package/dist/integrations/pipedrive.js.map +0 -1
- package/dist/integrations/registry.d.ts +0 -15
- package/dist/integrations/registry.js +0 -27
- package/dist/integrations/registry.js.map +0 -1
- package/dist/integrations/types.d.ts +0 -38
- package/dist/integrations/types.js +0 -9
- 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/mcp/connectors/asana.d.ts +0 -2
- package/dist/mcp/connectors/asana.js +0 -20
- package/dist/mcp/connectors/asana.js.map +0 -1
- package/dist/mcp/connectors/definitions.d.ts +0 -45
- package/dist/mcp/connectors/definitions.js +0 -32
- package/dist/mcp/connectors/definitions.js.map +0 -1
- package/dist/mcp/connectors/figma.d.ts +0 -5
- package/dist/mcp/connectors/figma.js +0 -21
- package/dist/mcp/connectors/figma.js.map +0 -1
- package/dist/mcp/connectors/gdrive.d.ts +0 -2
- package/dist/mcp/connectors/gdrive.js +0 -20
- package/dist/mcp/connectors/gdrive.js.map +0 -1
- package/dist/mcp/connectors/granola.d.ts +0 -2
- package/dist/mcp/connectors/granola.js +0 -12
- package/dist/mcp/connectors/granola.js.map +0 -1
- package/dist/mcp/connectors/linear.d.ts +0 -2
- package/dist/mcp/connectors/linear.js +0 -19
- package/dist/mcp/connectors/linear.js.map +0 -1
- package/dist/mcp/connectors/obsidian.d.ts +0 -2
- package/dist/mcp/connectors/obsidian.js +0 -19
- package/dist/mcp/connectors/obsidian.js.map +0 -1
- package/dist/mcp/connectors/pipedrive.d.ts +0 -2
- package/dist/mcp/connectors/pipedrive.js +0 -20
- package/dist/mcp/connectors/pipedrive.js.map +0 -1
- package/dist/mcp/connectors/slack.d.ts +0 -2
- package/dist/mcp/connectors/slack.js +0 -21
- package/dist/mcp/connectors/slack.js.map +0 -1
- package/dist/mcp/server-oauth-provider.d.ts +0 -56
- package/dist/mcp/server-oauth-provider.js +0 -142
- package/dist/mcp/server-oauth-provider.js.map +0 -1
- package/dist/server/chrome/chrome.css +0 -691
- package/dist/server/chrome/chrome.js +0 -374
- package/dist/server/collab-authority.d.ts +0 -70
- package/dist/server/collab-authority.js +0 -218
- package/dist/server/collab-authority.js.map +0 -1
- package/dist/server/collab.d.ts +0 -29
- package/dist/server/collab.js +0 -195
- package/dist/server/collab.js.map +0 -1
- 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/collab.d.ts +0 -6
- package/dist/server/routes/collab.js +0 -10
- package/dist/server/routes/collab.js.map +0 -1
- package/dist/server/routes/git-api.d.ts +0 -9
- package/dist/server/routes/git-api.js +0 -82
- package/dist/server/routes/git-api.js.map +0 -1
- package/dist/server/routes/meeting-ingest-api.d.ts +0 -15
- package/dist/server/routes/meeting-ingest-api.js +0 -323
- package/dist/server/routes/meeting-ingest-api.js.map +0 -1
- package/dist/server/routes/sync-api.d.ts +0 -26
- package/dist/server/routes/sync-api.js +0 -814
- package/dist/server/routes/sync-api.js.map +0 -1
- package/dist/server/routes/webhook.d.ts +0 -14
- package/dist/server/routes/webhook.js +0 -102
- package/dist/server/routes/webhook.js.map +0 -1
- package/dist/services/github-provisioner.d.ts +0 -36
- package/dist/services/github-provisioner.js +0 -126
- package/dist/services/github-provisioner.js.map +0 -1
- package/dist/services/github-service.d.ts +0 -99
- package/dist/services/github-service.js +0 -310
- package/dist/services/github-service.js.map +0 -1
- package/dist/services/insights.d.ts +0 -38
- package/dist/services/insights.js +0 -246
- package/dist/services/insights.js.map +0 -1
- package/dist/services/sync/collection-sync.d.ts +0 -60
- package/dist/services/sync/collection-sync.js +0 -509
- package/dist/services/sync/collection-sync.js.map +0 -1
- package/dist/services/sync/commit.d.ts +0 -60
- package/dist/services/sync/commit.js +0 -354
- package/dist/services/sync/commit.js.map +0 -1
- package/dist/services/sync/context-index.d.ts +0 -69
- package/dist/services/sync/context-index.js +0 -280
- package/dist/services/sync/context-index.js.map +0 -1
- package/dist/services/sync/data-fetcher.d.ts +0 -31
- package/dist/services/sync/data-fetcher.js +0 -12
- package/dist/services/sync/data-fetcher.js.map +0 -1
- package/dist/services/sync/derive.d.ts +0 -34
- package/dist/services/sync/derive.js +0 -164
- package/dist/services/sync/derive.js.map +0 -1
- package/dist/services/sync/enrichment-state.d.ts +0 -31
- package/dist/services/sync/enrichment-state.js +0 -63
- package/dist/services/sync/enrichment-state.js.map +0 -1
- package/dist/services/sync/enrichment.d.ts +0 -25
- package/dist/services/sync/enrichment.js +0 -121
- package/dist/services/sync/enrichment.js.map +0 -1
- package/dist/services/sync/entity-refresh.d.ts +0 -30
- package/dist/services/sync/entity-refresh.js +0 -275
- package/dist/services/sync/entity-refresh.js.map +0 -1
- package/dist/services/sync/frontmatter-extractor.d.ts +0 -40
- package/dist/services/sync/frontmatter-extractor.js +0 -279
- package/dist/services/sync/frontmatter-extractor.js.map +0 -1
- package/dist/services/sync/graph-match-state.d.ts +0 -33
- package/dist/services/sync/graph-match-state.js +0 -61
- package/dist/services/sync/graph-match-state.js.map +0 -1
- package/dist/services/sync/graph-match.d.ts +0 -53
- package/dist/services/sync/graph-match.js +0 -316
- package/dist/services/sync/graph-match.js.map +0 -1
- package/dist/services/sync/graphrag-client.d.ts +0 -43
- package/dist/services/sync/graphrag-client.js +0 -94
- package/dist/services/sync/graphrag-client.js.map +0 -1
- package/dist/services/sync/graphrag-config.d.ts +0 -16
- package/dist/services/sync/graphrag-config.js +0 -39
- package/dist/services/sync/graphrag-config.js.map +0 -1
- package/dist/services/sync/graphrag-context.d.ts +0 -14
- package/dist/services/sync/graphrag-context.js +0 -109
- package/dist/services/sync/graphrag-context.js.map +0 -1
- package/dist/services/sync/graphrag-indexer.d.ts +0 -30
- package/dist/services/sync/graphrag-indexer.js +0 -358
- package/dist/services/sync/graphrag-indexer.js.map +0 -1
- package/dist/services/sync/llm.d.ts +0 -32
- package/dist/services/sync/llm.js +0 -115
- package/dist/services/sync/llm.js.map +0 -1
- package/dist/services/sync/mcp-client.d.ts +0 -71
- package/dist/services/sync/mcp-client.js +0 -299
- package/dist/services/sync/mcp-client.js.map +0 -1
- package/dist/services/sync/model-factory.d.ts +0 -13
- package/dist/services/sync/model-factory.js +0 -38
- package/dist/services/sync/model-factory.js.map +0 -1
- package/dist/services/sync/name-quality.d.ts +0 -31
- package/dist/services/sync/name-quality.js +0 -60
- package/dist/services/sync/name-quality.js.map +0 -1
- package/dist/services/sync/output-schemas.d.ts +0 -92
- package/dist/services/sync/output-schemas.js +0 -43
- package/dist/services/sync/output-schemas.js.map +0 -1
- package/dist/services/sync/prompts.d.ts +0 -19
- package/dist/services/sync/prompts.js +0 -128
- package/dist/services/sync/prompts.js.map +0 -1
- package/dist/services/sync/reconciler.d.ts +0 -48
- package/dist/services/sync/reconciler.js +0 -294
- package/dist/services/sync/reconciler.js.map +0 -1
- package/dist/services/sync/rest-client.d.ts +0 -40
- package/dist/services/sync/rest-client.js +0 -100
- package/dist/services/sync/rest-client.js.map +0 -1
- package/dist/services/sync/source-config.d.ts +0 -67
- package/dist/services/sync/source-config.js +0 -304
- package/dist/services/sync/source-config.js.map +0 -1
- package/dist/services/sync/source-definitions/asana.d.ts +0 -14
- package/dist/services/sync/source-definitions/asana.js +0 -42
- package/dist/services/sync/source-definitions/asana.js.map +0 -1
- package/dist/services/sync/source-definitions/definitions.d.ts +0 -8
- package/dist/services/sync/source-definitions/definitions.js +0 -8
- package/dist/services/sync/source-definitions/definitions.js.map +0 -1
- package/dist/services/sync/source-definitions/gdrive.d.ts +0 -16
- package/dist/services/sync/source-definitions/gdrive.js +0 -68
- package/dist/services/sync/source-definitions/gdrive.js.map +0 -1
- package/dist/services/sync/source-definitions/granola.d.ts +0 -2
- package/dist/services/sync/source-definitions/granola.js +0 -21
- package/dist/services/sync/source-definitions/granola.js.map +0 -1
- package/dist/services/sync/source-definitions/linear.d.ts +0 -2
- package/dist/services/sync/source-definitions/linear.js +0 -62
- package/dist/services/sync/source-definitions/linear.js.map +0 -1
- package/dist/services/sync/source-definitions/obsidian.d.ts +0 -2
- package/dist/services/sync/source-definitions/obsidian.js +0 -55
- package/dist/services/sync/source-definitions/obsidian.js.map +0 -1
- package/dist/services/sync/source-definitions/pipedrive.d.ts +0 -2
- package/dist/services/sync/source-definitions/pipedrive.js +0 -43
- package/dist/services/sync/source-definitions/pipedrive.js.map +0 -1
- package/dist/services/sync/staging.d.ts +0 -53
- package/dist/services/sync/staging.js +0 -130
- package/dist/services/sync/staging.js.map +0 -1
- package/dist/services/sync/structured-extractor.d.ts +0 -57
- package/dist/services/sync/structured-extractor.js +0 -584
- package/dist/services/sync/structured-extractor.js.map +0 -1
- package/dist/services/sync/sync-runner.d.ts +0 -32
- package/dist/services/sync/sync-runner.js +0 -195
- package/dist/services/sync/sync-runner.js.map +0 -1
- package/dist/services/sync/sync-state.d.ts +0 -43
- package/dist/services/sync/sync-state.js +0 -154
- package/dist/services/sync/sync-state.js.map +0 -1
- package/dist/services/sync/types.d.ts +0 -381
- package/dist/services/sync/types.js +0 -8
- package/dist/services/sync/types.js.map +0 -1
- package/dist/services/sync/unstructured-extractor.d.ts +0 -27
- package/dist/services/sync/unstructured-extractor.js +0 -185
- package/dist/services/sync/unstructured-extractor.js.map +0 -1
- package/dist/utils/merge-resolver.d.ts +0 -59
- package/dist/utils/merge-resolver.js +0 -303
- package/dist/utils/merge-resolver.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.DdizXOKi.css +0 -1
- package/dist/web/_app/immutable/assets/10.BUrHkYry.css +0 -1
- package/dist/web/_app/immutable/assets/2.n7-yW_Fs.css +0 -1
- package/dist/web/_app/immutable/assets/3.BtaZagnv.css +0 -1
- package/dist/web/_app/immutable/assets/4.DT7X0x5S.css +0 -1
- package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
- package/dist/web/_app/immutable/assets/6.CquhUpOu.css +0 -1
- package/dist/web/_app/immutable/assets/7.CjbDRbuG.css +0 -1
- package/dist/web/_app/immutable/assets/8.S1QdUGNM.css +0 -1
- package/dist/web/_app/immutable/assets/9.CT4xL4K3.css +0 -1
- package/dist/web/_app/immutable/assets/Copy.FS8bdfxr.css +0 -1
- package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
- package/dist/web/_app/immutable/assets/ViewToolbar.D-QW2oKe.css +0 -1
- package/dist/web/_app/immutable/assets/index.D6tMDJWk.css +0 -1
- package/dist/web/_app/immutable/chunks/-iaeBIWN.js +0 -1
- package/dist/web/_app/immutable/chunks/37NdyH6G.js +0 -32
- package/dist/web/_app/immutable/chunks/4Hhzb6pv.js +0 -1
- package/dist/web/_app/immutable/chunks/72bZS3G9.js +0 -1
- package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
- package/dist/web/_app/immutable/chunks/B340SUKR.js +0 -1
- package/dist/web/_app/immutable/chunks/B3Z4_Sps.js +0 -1
- package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
- package/dist/web/_app/immutable/chunks/BPWYOQXG.js +0 -1
- package/dist/web/_app/immutable/chunks/BR77jbfR.js +0 -1
- package/dist/web/_app/immutable/chunks/BS2rFAVq.js +0 -1
- package/dist/web/_app/immutable/chunks/BSsDC_p4.js +0 -1
- package/dist/web/_app/immutable/chunks/BTX2Jr8_.js +0 -1
- package/dist/web/_app/immutable/chunks/Bq_KShUL.js +0 -4
- package/dist/web/_app/immutable/chunks/Bsacq2UX.js +0 -1
- package/dist/web/_app/immutable/chunks/ByunV8un.js +0 -1
- package/dist/web/_app/immutable/chunks/BzPu-Eht.js +0 -1
- package/dist/web/_app/immutable/chunks/C7VoTosa.js +0 -2
- package/dist/web/_app/immutable/chunks/CDV5Q7RN.js +0 -1
- package/dist/web/_app/immutable/chunks/CGc1sIb_.js +0 -1
- package/dist/web/_app/immutable/chunks/CJ8__CWt.js +0 -1
- package/dist/web/_app/immutable/chunks/CJUKmosC.js +0 -5
- package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
- package/dist/web/_app/immutable/chunks/CT6oIU-C.js +0 -1
- package/dist/web/_app/immutable/chunks/CTRxNfZk.js +0 -1
- package/dist/web/_app/immutable/chunks/CWQRQXxy.js +0 -1
- package/dist/web/_app/immutable/chunks/CX87mIM8.js +0 -1
- package/dist/web/_app/immutable/chunks/CXH6iFbA.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/CdeYcEuU.js +0 -1
- package/dist/web/_app/immutable/chunks/CmCtpZ1Y.js +0 -1
- package/dist/web/_app/immutable/chunks/Cpsr8-Xy.js +0 -1
- package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
- package/dist/web/_app/immutable/chunks/CrdV0ttd.js +0 -1
- package/dist/web/_app/immutable/chunks/CscoF-YL.js +0 -18
- package/dist/web/_app/immutable/chunks/Cx4YdFMk.js +0 -1
- package/dist/web/_app/immutable/chunks/D7ZqAKi9.js +0 -3
- package/dist/web/_app/immutable/chunks/DGbA7IXh.js +0 -2
- package/dist/web/_app/immutable/chunks/DTZE-yoq.js +0 -2
- package/dist/web/_app/immutable/chunks/DbbB6Up5.js +0 -1
- package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
- package/dist/web/_app/immutable/chunks/DtM5cEDu.js +0 -1
- package/dist/web/_app/immutable/chunks/Eqahi7_S.js +0 -2
- package/dist/web/_app/immutable/chunks/O9Eb9k00.js +0 -1
- package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
- package/dist/web/_app/immutable/chunks/QF8MAmnc.js +0 -1
- package/dist/web/_app/immutable/chunks/UjzxCpxn.js +0 -1
- package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
- package/dist/web/_app/immutable/chunks/Y90OgS-9.js +0 -1
- package/dist/web/_app/immutable/chunks/cLyZlkXv.js +0 -1
- package/dist/web/_app/immutable/chunks/iDtAARVW.js +0 -2
- package/dist/web/_app/immutable/chunks/oC_W7W7p.js +0 -1
- package/dist/web/_app/immutable/chunks/rJdWIgh-.js +0 -1
- package/dist/web/_app/immutable/chunks/tvOsokaa.js +0 -1
- package/dist/web/_app/immutable/chunks/uLEXaPwE.js +0 -1
- package/dist/web/_app/immutable/chunks/vSaooFHB.js +0 -1
- package/dist/web/_app/immutable/entry/app.BeUKh4sD.js +0 -2
- package/dist/web/_app/immutable/entry/start.CZJnFuQn.js +0 -1
- package/dist/web/_app/immutable/nodes/0.DyF_RsLg.js +0 -2
- package/dist/web/_app/immutable/nodes/1.7iDQmMPh.js +0 -1
- package/dist/web/_app/immutable/nodes/10.Btl8d8HT.js +0 -1
- package/dist/web/_app/immutable/nodes/2.LDRE62jN.js +0 -168
- package/dist/web/_app/immutable/nodes/3.BaW1XB1x.js +0 -1
- package/dist/web/_app/immutable/nodes/4.D0Q8kpkI.js +0 -12
- package/dist/web/_app/immutable/nodes/5.n7j2UG9h.js +0 -4
- package/dist/web/_app/immutable/nodes/6.DQYxR0iy.js +0 -2
- package/dist/web/_app/immutable/nodes/7.BsURvFAp.js +0 -2
- package/dist/web/_app/immutable/nodes/8.CsiErG0p.js +0 -1
- package/dist/web/_app/immutable/nodes/9.CnN6OZgC.js +0 -1
|
@@ -7,11 +7,18 @@
|
|
|
7
7
|
* - Manage wikilinks
|
|
8
8
|
* - Upload assets
|
|
9
9
|
*/
|
|
10
|
-
import { Type as T } from '
|
|
10
|
+
import { Type as T } from 'typebox';
|
|
11
11
|
import { ENTITY_SCHEMAS } from '../../core/validation.js';
|
|
12
|
+
import { describeZodObject } from '../../core/schema-registry.js';
|
|
12
13
|
import { lintWorkspace } from '../../services/lint-service.js';
|
|
13
14
|
import { findOrphans } from '../../services/orphan-service.js';
|
|
14
|
-
import
|
|
15
|
+
import * as access from '../../services/access-control.js';
|
|
16
|
+
import { isCuratedEntityType } from '../../core/entity-types-catalog.js';
|
|
17
|
+
import { getAgentAllowedEntityTypes } from '../prompts/entity-types-section.js';
|
|
18
|
+
import { BridgeError, assertCanChangeUserHandle, validateUserHandleInPayload } from '../../services/user-person-bridge.js';
|
|
19
|
+
import { buildActor, prepareCreatePayload, prepareUpdatePayload, diagnosedUpdate, DroppedAssetError, assertEntityRefs, EntityRefError, UnknownUserRefError, } from '../../services/entity-mutations.js';
|
|
20
|
+
import { listRepoAssets } from '../../services/asset-listing.js';
|
|
21
|
+
import { assetEmbed } from '../../core/embeds.js';
|
|
15
22
|
/**
|
|
16
23
|
* Helper to wrap tool results in AgentToolResult format
|
|
17
24
|
*/
|
|
@@ -31,128 +38,228 @@ function cleanData(data) {
|
|
|
31
38
|
return rest;
|
|
32
39
|
}
|
|
33
40
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
41
|
+
* Undo JSON-string escapes that sometimes leak into content when the LLM
|
|
42
|
+
* serializes markdown as a quoted string instead of raw text. Handles `\n`,
|
|
43
|
+
* `\t`, `\r`, `\"`, `\\` in a single pass so escape sequences aren't
|
|
44
|
+
* re-processed. Also strips stray surrounding quotes from a fully-quoted
|
|
45
|
+
* payload.
|
|
37
46
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (!user)
|
|
52
|
-
return null; // API key / open mode → allow
|
|
53
|
-
if (user.role === 'admin')
|
|
54
|
-
return null;
|
|
55
|
-
return 'This operation requires admin access.';
|
|
47
|
+
function sanitizeLlmContent(content) {
|
|
48
|
+
if (!content)
|
|
49
|
+
return '';
|
|
50
|
+
const unescaped = content.replace(/\\([ntr"\\])/g, (_, c) => {
|
|
51
|
+
if (c === 'n')
|
|
52
|
+
return '\n';
|
|
53
|
+
if (c === 't')
|
|
54
|
+
return '\t';
|
|
55
|
+
if (c === 'r')
|
|
56
|
+
return '\r';
|
|
57
|
+
return c;
|
|
58
|
+
});
|
|
59
|
+
return unescaped.replace(/^"+|"+$/g, '');
|
|
56
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Per-request user context for folder access filtering.
|
|
63
|
+
* When getCurrentUser returns a user, tools filter results to only
|
|
64
|
+
* folders the user is a member of (via folder_access).
|
|
65
|
+
*/
|
|
57
66
|
function getAccessibleRepoNames(workspaceManager, getCurrentUser, authService) {
|
|
58
67
|
const user = getCurrentUser();
|
|
59
68
|
if (!user)
|
|
60
69
|
return null; // API key / open mode → no filtering
|
|
61
70
|
if (!authService)
|
|
62
71
|
return null;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const hidden = allRepos.filter(r => !canSeePrivateRepo(r, user)).map(r => r.name);
|
|
67
|
-
if (hidden.length === 0)
|
|
68
|
-
return null; // No filtering needed
|
|
69
|
-
const visible = new Set(allRepos.filter(r => canSeePrivateRepo(r, user)).map(r => r.name));
|
|
70
|
-
return visible;
|
|
71
|
-
}
|
|
72
|
-
const allowed = authService.getUserCollections(user.id);
|
|
73
|
-
const visible = allRepos.filter(r => canSeePrivateRepo(r, user) && (r.private && r.owner_id === user.id || allowed.includes(r.name)));
|
|
74
|
-
return new Set(visible.map(r => r.name));
|
|
72
|
+
// Delegate to the shared helper so personal-folder restrictions and
|
|
73
|
+
// owner-on-shared-folder semantics apply consistently with the HTTP layer.
|
|
74
|
+
return new Set(access.getAccessibleRepos(user, workspaceManager, authService).map(r => r.name));
|
|
75
75
|
}
|
|
76
76
|
function canAccessRepo(repoName, workspaceManager, getCurrentUser, authService) {
|
|
77
77
|
const user = getCurrentUser();
|
|
78
|
-
const repoConfig = workspaceManager.getRepoConfig(repoName);
|
|
79
|
-
if (!canSeePrivateRepo(repoConfig, user))
|
|
80
|
-
return false;
|
|
81
78
|
if (!user)
|
|
82
79
|
return true;
|
|
83
|
-
if (repoConfig?.private && repoConfig?.owner_id === user.id)
|
|
84
|
-
return true;
|
|
85
|
-
if (user.role === 'admin')
|
|
86
|
-
return true;
|
|
87
80
|
if (!authService)
|
|
88
81
|
return true;
|
|
89
|
-
return
|
|
82
|
+
return access.hasRepoAccess(user, repoName, workspaceManager, authService);
|
|
90
83
|
}
|
|
91
|
-
export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService
|
|
84
|
+
export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService,
|
|
85
|
+
/**
|
|
86
|
+
* Called at the start (`enter`) and end (`leave`) of any mutation tool
|
|
87
|
+
* call. Surfaces the active-agent chip in the sidebar via the WS hub. The
|
|
88
|
+
* orchestrator wires this through to wsHub.handleAgentActivity.
|
|
89
|
+
*/
|
|
90
|
+
onAgentActivity) {
|
|
92
91
|
const getUser = getCurrentUser ?? (() => null);
|
|
93
92
|
const authSvc = authService ?? null;
|
|
93
|
+
/**
|
|
94
|
+
* Resolve the identity to stamp on writes. If the tool call is running on
|
|
95
|
+
* behalf of a real user (chat / quick-capture from the web), credit them
|
|
96
|
+
* by their handle via the shared `buildActor` so MCP and agent surfaces
|
|
97
|
+
* produce byte-identical git authors for the same user. Fall back to the
|
|
98
|
+
* orchestrator-level gitUser for unauthenticated contexts (CLI, tests,
|
|
99
|
+
* server-only automations).
|
|
100
|
+
*/
|
|
101
|
+
function effectiveGitUser() {
|
|
102
|
+
const user = getUser();
|
|
103
|
+
if (user?.handle)
|
|
104
|
+
return buildActor(user);
|
|
105
|
+
return gitUser;
|
|
106
|
+
}
|
|
107
|
+
/** Resolve "private" or "entries" to the current user's actual private folder name. */
|
|
108
|
+
function resolvePrivateRepo(repoName) {
|
|
109
|
+
if (repoName !== 'private' && repoName !== 'entries')
|
|
110
|
+
return repoName;
|
|
111
|
+
const user = getUser();
|
|
112
|
+
if (!user)
|
|
113
|
+
return repoName;
|
|
114
|
+
const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
|
|
115
|
+
return personalRepo?.name ?? repoName;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Eager skills are inlined into every system prompt for everyone with folder
|
|
119
|
+
* access. Creating one in a shared folder requires admin/owner so a rogue
|
|
120
|
+
* member can't bloat everyone's context. Eager skills in the user's own
|
|
121
|
+
* private folder are fine — they only bloat that user's own prompt.
|
|
122
|
+
* Returns an error string or null if the operation is allowed.
|
|
123
|
+
*/
|
|
124
|
+
function checkEagerSkillPermission(entityType, data, repoName) {
|
|
125
|
+
if (entityType !== 'skill')
|
|
126
|
+
return null;
|
|
127
|
+
if (!data || data.loading !== 'eager')
|
|
128
|
+
return null;
|
|
129
|
+
const user = getUser();
|
|
130
|
+
if (!user)
|
|
131
|
+
return null; // non-authenticated contexts (CLI, tests) bypass
|
|
132
|
+
const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
|
|
133
|
+
if (personalRepo && personalRepo.name === repoName)
|
|
134
|
+
return null;
|
|
135
|
+
if (authSvc?.isFolderAdmin(user.id, repoName))
|
|
136
|
+
return null;
|
|
137
|
+
if (user.role === 'owner')
|
|
138
|
+
return null;
|
|
139
|
+
return `Creating an eager skill in a shared folder requires folder admin or workspace owner. Save this skill to your private folder (repo: "private") or set loading to "on-demand".`;
|
|
140
|
+
}
|
|
141
|
+
// Compute the set of entity types the agent is allowed to create in this
|
|
142
|
+
// workspace: the full canonical catalog plus any custom types defined via
|
|
143
|
+
// schema_extensions. The launch-time allowlist was removed — the catalog
|
|
144
|
+
// now grows with the user via the New Entry picker's progressive disclosure.
|
|
145
|
+
const builtinTypeKeys = new Set(Object.keys(ENTITY_SCHEMAS));
|
|
146
|
+
const customWorkspaceTypes = workspaceManager.getSchemaRegistry().getAllTypes()
|
|
147
|
+
.filter(t => !builtinTypeKeys.has(t));
|
|
148
|
+
const agentAllowedTypes = getAgentAllowedEntityTypes(customWorkspaceTypes);
|
|
149
|
+
const agentAllowedTypeSet = new Set(agentAllowedTypes);
|
|
150
|
+
function rejectDisallowedCreateType(entityType) {
|
|
151
|
+
if (agentAllowedTypeSet.has(entityType))
|
|
152
|
+
return null;
|
|
153
|
+
const hint = isCuratedEntityType(entityType)
|
|
154
|
+
? '' // shouldn't happen for any other curated type — they're all allowed
|
|
155
|
+
: ` Allowed types: ${agentAllowedTypes.join(', ')}.`;
|
|
156
|
+
return wrapToolResult({
|
|
157
|
+
success: false,
|
|
158
|
+
error: `Entry type "${entityType}" is not a known canonical or workspace custom type.${hint}`,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
94
161
|
return [
|
|
95
162
|
// Create entity
|
|
96
163
|
{
|
|
97
164
|
name: 'create_entity',
|
|
98
|
-
label: 'Create
|
|
99
|
-
description: 'Create a new
|
|
165
|
+
label: 'Create Entry',
|
|
166
|
+
description: 'Create a new entry in a folder. Always validate required fields before calling. Folder is auto-resolved for app-defined entry types.',
|
|
100
167
|
parameters: T.Object({
|
|
101
|
-
repo: T.Optional(T.String({ description: '
|
|
102
|
-
entityType: T.
|
|
168
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
169
|
+
entityType: T.Union(agentAllowedTypes.map(t => T.Literal(t)), { description: `Entity type. Must be one of: ${agentAllowedTypes.join(', ')}.` }),
|
|
103
170
|
entityId: T.String({ description: 'Unique entity ID in kebab-case' }),
|
|
104
171
|
data: T.Object({}, { description: 'Entity data (YAML frontmatter)', additionalProperties: true }),
|
|
105
172
|
content: T.Optional(T.String({ description: 'Markdown content (optional)' })),
|
|
173
|
+
folder_path: T.Optional(T.String({ description: 'Repo-relative subfolder for the entry (e.g. "clients/acme"). Omit to land at repo root. Parent folders are auto-created.' })),
|
|
106
174
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
|
|
107
175
|
}),
|
|
108
176
|
execute: async (toolCallId, params) => {
|
|
109
177
|
try {
|
|
178
|
+
// Defense in depth: LLMs occasionally pass strings that don't match the
|
|
179
|
+
// enum schema. Runtime check ensures the launch allowlist is enforced
|
|
180
|
+
// even if the schema layer is bypassed.
|
|
181
|
+
const typeRejection = rejectDisallowedCreateType(params.entityType);
|
|
182
|
+
if (typeRejection)
|
|
183
|
+
return typeRejection;
|
|
110
184
|
let repoName = params.repo;
|
|
111
185
|
if (!repoName) {
|
|
112
|
-
|
|
113
|
-
if (!repoName)
|
|
114
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
186
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
115
187
|
}
|
|
188
|
+
repoName = resolvePrivateRepo(repoName);
|
|
116
189
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
117
|
-
return wrapToolResult({ success: false, error: `
|
|
190
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
118
191
|
}
|
|
192
|
+
const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
|
|
193
|
+
if (eagerError)
|
|
194
|
+
return wrapToolResult({ success: false, error: eagerError });
|
|
119
195
|
const graph = workspaceManager.getGraph(repoName);
|
|
120
196
|
// Workspace-level dedup: warn if an entity with this ID already exists elsewhere
|
|
121
197
|
const existing = workspaceManager.findEntityById(params.entityId);
|
|
122
198
|
if (existing && existing.repoName !== repoName) {
|
|
123
|
-
return wrapToolResult({ success: false, error: `An entity with ID "${params.entityId}" already exists in the "${existing.repoName}"
|
|
199
|
+
return wrapToolResult({ success: false, error: `An entity with ID "${params.entityId}" already exists in the "${existing.repoName}" folder (type: ${existing.data?.entity_type}). Use a unique ID or link to the existing entity with [[${params.entityId}]].` });
|
|
124
200
|
}
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
201
|
+
const actor = effectiveGitUser();
|
|
202
|
+
const sanitizedContent = sanitizeLlmContent(params.content);
|
|
203
|
+
// Workspace-wide uniqueness check for `user_handle` on person
|
|
204
|
+
// entities (one user ↔ one person, workspace-wide), plus owner-
|
|
205
|
+
// only authz so a non-owner agent session can't stamp a
|
|
206
|
+
// pre-linked person via generic create_entity.
|
|
207
|
+
if (params.entityType === 'person') {
|
|
208
|
+
try {
|
|
209
|
+
const incoming = params.data ?? {};
|
|
210
|
+
validateUserHandleInPayload(workspaceManager, incoming);
|
|
211
|
+
if (Object.prototype.hasOwnProperty.call(incoming, 'user_handle')) {
|
|
212
|
+
assertCanChangeUserHandle(getUser(), '', incoming.user_handle);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
if (err instanceof BridgeError) {
|
|
217
|
+
return wrapToolResult({ success: false, error: err.message, code: err.code, ...err.details });
|
|
218
|
+
}
|
|
219
|
+
throw err;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Scope ref fields (today: task.assignee → person). Reject a wikilink
|
|
223
|
+
// that resolves to a non-person; forward references are allowed.
|
|
224
|
+
try {
|
|
225
|
+
assertEntityRefs(workspaceManager, params.entityType, params.data ?? {}, authSvc ? { userExists: (id) => !!authSvc.findUserById(Number(id)) } : undefined);
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
if (err instanceof EntityRefError || err instanceof UnknownUserRefError) {
|
|
229
|
+
return wrapToolResult({ success: false, error: err.message, code: err.code, field: err.field });
|
|
230
|
+
}
|
|
231
|
+
throw err;
|
|
232
|
+
}
|
|
233
|
+
const options = prepareCreatePayload({
|
|
138
234
|
entityType: params.entityType,
|
|
139
235
|
entityId: params.entityId,
|
|
140
|
-
data:
|
|
236
|
+
data: params.data ?? {},
|
|
141
237
|
content: sanitizedContent,
|
|
238
|
+
folderPath: params.folder_path,
|
|
142
239
|
commitMessage: params.commitMessage,
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
240
|
+
}, actor);
|
|
241
|
+
// Surface a live "<user>'s agent is acting" chip in the sidebar for
|
|
242
|
+
// the duration of the mutation. `leave` is always emitted via the
|
|
243
|
+
// inner finally so a thrown error doesn't leave the chip stuck.
|
|
244
|
+
onAgentActivity?.('enter', repoName);
|
|
245
|
+
try {
|
|
246
|
+
const entity = await graph.create(options);
|
|
247
|
+
onMutation?.({ action: 'created', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
248
|
+
return wrapToolResult({
|
|
249
|
+
success: true,
|
|
250
|
+
entity: {
|
|
251
|
+
entityId: entity.id,
|
|
252
|
+
entityType: entity.entityType,
|
|
253
|
+
repo: repoName,
|
|
254
|
+
path: entity.path,
|
|
255
|
+
data: cleanData(entity.data),
|
|
256
|
+
},
|
|
257
|
+
message: `Created ${params.entityType}: ${params.entityId} in ${repoName}. Auto-committed — ready to push.`,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
onAgentActivity?.('leave', repoName);
|
|
262
|
+
}
|
|
156
263
|
}
|
|
157
264
|
catch (error) {
|
|
158
265
|
return wrapToolResult({
|
|
@@ -165,31 +272,51 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
165
272
|
// Get entity
|
|
166
273
|
{
|
|
167
274
|
name: 'get_entity',
|
|
168
|
-
label: 'Get
|
|
169
|
-
description: 'Retrieve full
|
|
275
|
+
label: 'Get Entry',
|
|
276
|
+
description: 'Retrieve full entry details. Use repo, entityType, entityId from search/list results. entityType is optional — if omitted it is read from the file.',
|
|
170
277
|
parameters: T.Object({
|
|
171
|
-
repo: T.String({ description: '
|
|
278
|
+
repo: T.String({ description: 'Folder name' }),
|
|
172
279
|
entityType: T.Optional(T.String({ description: 'Entity type (optional — resolved from frontmatter if omitted)' })),
|
|
173
280
|
entityId: T.String({ description: 'Entity ID' }),
|
|
174
281
|
}),
|
|
175
282
|
execute: async (toolCallId, params) => {
|
|
176
283
|
try {
|
|
177
|
-
|
|
178
|
-
|
|
284
|
+
const repo = resolvePrivateRepo(params.repo);
|
|
285
|
+
if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
|
|
286
|
+
return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
|
|
179
287
|
}
|
|
180
|
-
const graph = workspaceManager.getGraph(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
288
|
+
const graph = workspaceManager.getGraph(repo);
|
|
289
|
+
// If the agent passes the wrong entityType (e.g. based on stale
|
|
290
|
+
// search results), graph.get computes the wrong filesystem path
|
|
291
|
+
// and throws. Fall back to getById, which scans all type subdirs
|
|
292
|
+
// under the folder and resolves the actual location.
|
|
293
|
+
let entity;
|
|
294
|
+
if (params.entityType) {
|
|
295
|
+
try {
|
|
296
|
+
entity = graph.get(params.entityType, params.entityId);
|
|
297
|
+
}
|
|
298
|
+
catch {
|
|
299
|
+
entity = graph.getById(params.entityId);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
entity = graph.getById(params.entityId);
|
|
304
|
+
}
|
|
305
|
+
// Prefer the live editor body when a seeded Y.Doc is open. graph.get
|
|
306
|
+
// reads disk, which lags the editor by the autosave debounce — a
|
|
307
|
+
// user's freshly-placed image embed lives in the Y.Doc before it's
|
|
308
|
+
// committed. Returning disk content is what let the agent edit then
|
|
309
|
+
// resend a body missing those embeds, silently dropping images.
|
|
310
|
+
const liveBody = graph.getLiveBody(entity.entityType, entity.id);
|
|
184
311
|
return wrapToolResult({
|
|
185
312
|
success: true,
|
|
186
313
|
entity: {
|
|
187
314
|
entityId: entity.id,
|
|
188
315
|
entityType: entity.entityType,
|
|
189
|
-
repo
|
|
316
|
+
repo,
|
|
190
317
|
path: entity.path,
|
|
191
318
|
data: cleanData(entity.data),
|
|
192
|
-
content: entity.document.content,
|
|
319
|
+
content: liveBody ?? entity.document.content,
|
|
193
320
|
wikilinks: entity.document.wikilinks,
|
|
194
321
|
},
|
|
195
322
|
});
|
|
@@ -205,59 +332,116 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
205
332
|
// Update entity
|
|
206
333
|
{
|
|
207
334
|
name: 'update_entity',
|
|
208
|
-
label: 'Update
|
|
209
|
-
description: 'Update an existing
|
|
335
|
+
label: 'Update Entry',
|
|
336
|
+
description: 'Update an existing entry. Folder is auto-resolved for app-defined types.',
|
|
210
337
|
parameters: T.Object({
|
|
211
|
-
repo: T.Optional(T.String({ description: '
|
|
338
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
212
339
|
entityType: T.String({ description: 'Entity type' }),
|
|
213
340
|
entityId: T.String({ description: 'Entity ID' }),
|
|
214
341
|
data: T.Optional(T.Object({}, { description: 'Updated data fields', additionalProperties: true })),
|
|
215
|
-
content: T.Optional(T.String({ description: 'Updated markdown
|
|
342
|
+
content: T.Optional(T.String({ description: 'Updated markdown body (replaces the entire body)' })),
|
|
216
343
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
|
|
344
|
+
allowImageRemoval: T.Optional(T.Boolean({ description: 'Set true only to deliberately delete image/asset embeds the document currently has; otherwise such a whole-body write is rejected (ASSET_REMOVAL_BLOCKED). Prefer get_entity then patch_entity for small edits.' })),
|
|
217
345
|
}),
|
|
218
346
|
execute: async (toolCallId, params) => {
|
|
219
347
|
try {
|
|
220
348
|
let repoName = params.repo;
|
|
221
349
|
if (!repoName) {
|
|
222
|
-
|
|
223
|
-
if (!repoName)
|
|
224
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
350
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
225
351
|
}
|
|
352
|
+
repoName = resolvePrivateRepo(repoName);
|
|
226
353
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
227
|
-
return wrapToolResult({ success: false, error: `
|
|
354
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
228
355
|
}
|
|
356
|
+
const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
|
|
357
|
+
if (eagerError)
|
|
358
|
+
return wrapToolResult({ success: false, error: eagerError });
|
|
229
359
|
const graph = workspaceManager.getGraph(repoName);
|
|
230
|
-
|
|
231
|
-
const dataWithMeta = params.data
|
|
232
|
-
? {
|
|
233
|
-
...params.data,
|
|
234
|
-
updated_at: new Date().toISOString(),
|
|
235
|
-
updated_by: gitUser.id,
|
|
236
|
-
}
|
|
237
|
-
: undefined;
|
|
238
|
-
// Sanitize double-escaped newlines from LLM JSON output
|
|
360
|
+
const actor = effectiveGitUser();
|
|
239
361
|
const sanitizedContent = params.content !== undefined
|
|
240
|
-
? params.content
|
|
241
|
-
|
|
362
|
+
? sanitizeLlmContent(params.content)
|
|
363
|
+
: params.content;
|
|
364
|
+
// Workspace-wide uniqueness check + owner-only authz for
|
|
365
|
+
// `user_handle` on person entities. Generic update_entity must
|
|
366
|
+
// not be a back door around the ownerOnly() gate on the dedicated
|
|
367
|
+
// link/unlink tools — otherwise a member could ask the agent to
|
|
368
|
+
// "set this person's user_handle to mine" and bypass the gate.
|
|
369
|
+
if (params.entityType === 'person' && params.data) {
|
|
370
|
+
try {
|
|
371
|
+
validateUserHandleInPayload(workspaceManager, params.data, { repo: repoName, entityId: params.entityId });
|
|
372
|
+
if (Object.prototype.hasOwnProperty.call(params.data, 'user_handle')) {
|
|
373
|
+
let currentHandle = '';
|
|
374
|
+
try {
|
|
375
|
+
const current = graph.get('person', params.entityId);
|
|
376
|
+
currentHandle = (current?.data?.user_handle ?? '');
|
|
377
|
+
}
|
|
378
|
+
catch { /* new entity / missing — treat as empty */ }
|
|
379
|
+
assertCanChangeUserHandle(getUser(), currentHandle, params.data.user_handle);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
catch (err) {
|
|
383
|
+
if (err instanceof BridgeError) {
|
|
384
|
+
return wrapToolResult({ success: false, error: err.message, code: err.code, ...err.details });
|
|
385
|
+
}
|
|
386
|
+
throw err;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
// Scope ref fields (today: task.assignee → person). Reject a wikilink
|
|
390
|
+
// that resolves to a non-person; forward references are allowed.
|
|
391
|
+
try {
|
|
392
|
+
assertEntityRefs(workspaceManager, params.entityType, params.data, authSvc ? { userExists: (id) => !!authSvc.findUserById(Number(id)) } : undefined);
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
if (err instanceof EntityRefError || err instanceof UnknownUserRefError) {
|
|
396
|
+
return wrapToolResult({ success: false, error: err.message, code: err.code, field: err.field });
|
|
397
|
+
}
|
|
398
|
+
throw err;
|
|
399
|
+
}
|
|
400
|
+
const options = prepareUpdatePayload({
|
|
242
401
|
entityType: params.entityType,
|
|
243
402
|
entityId: params.entityId,
|
|
244
|
-
data:
|
|
403
|
+
data: params.data,
|
|
245
404
|
content: sanitizedContent,
|
|
246
405
|
commitMessage: params.commitMessage,
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
406
|
+
}, actor);
|
|
407
|
+
onAgentActivity?.('enter', repoName);
|
|
408
|
+
try {
|
|
409
|
+
// Shared diagnosed update (c6ef9297 contract): throws
|
|
410
|
+
// SilentDropError when the caller intended a change that left the
|
|
411
|
+
// file byte-identical, surfaced via the outer catch so the agent
|
|
412
|
+
// isn't misled by a success envelope.
|
|
413
|
+
const { entity, frontmatter_changed, content_changed, noop, broadcast } = await diagnosedUpdate(graph, options, { data: params.data, content: sanitizedContent }, { allowAssetRemoval: params.allowImageRemoval });
|
|
414
|
+
onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
415
|
+
return wrapToolResult({
|
|
416
|
+
success: true,
|
|
417
|
+
entity: {
|
|
418
|
+
entityId: entity.id,
|
|
419
|
+
entityType: entity.entityType,
|
|
420
|
+
repo: repoName,
|
|
421
|
+
data: cleanData(entity.data),
|
|
422
|
+
},
|
|
423
|
+
frontmatter_changed,
|
|
424
|
+
content_changed,
|
|
425
|
+
noop,
|
|
426
|
+
broadcast,
|
|
427
|
+
message: noop
|
|
428
|
+
? `No change to ${params.entityType}: ${params.entityId} — on-disk state already matched.`
|
|
429
|
+
: `Updated ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
finally {
|
|
433
|
+
onAgentActivity?.('leave', repoName);
|
|
434
|
+
}
|
|
259
435
|
}
|
|
260
436
|
catch (error) {
|
|
437
|
+
if (error instanceof DroppedAssetError) {
|
|
438
|
+
return wrapToolResult({
|
|
439
|
+
success: false,
|
|
440
|
+
code: 'ASSET_REMOVAL_BLOCKED',
|
|
441
|
+
droppedAssets: error.dropped,
|
|
442
|
+
error: error.message,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
261
445
|
return wrapToolResult({
|
|
262
446
|
success: false,
|
|
263
447
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
@@ -265,13 +449,157 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
265
449
|
}
|
|
266
450
|
},
|
|
267
451
|
},
|
|
452
|
+
// List assets already uploaded to a folder
|
|
453
|
+
{
|
|
454
|
+
name: 'list_assets',
|
|
455
|
+
label: 'List Assets',
|
|
456
|
+
description: 'List images/files already uploaded to a folder, with a ready-to-paste markdown embed for each. ' +
|
|
457
|
+
'Use this to find an asset a user placed (e.g. a screenshot) so you can embed it into an entry — ' +
|
|
458
|
+
'assets live in storage (R2/local), NOT on the local filesystem, so import_file cannot find them. ' +
|
|
459
|
+
'Each result has an `embed` string: use it verbatim and NEVER write ![[filename]] transclusion syntax ' +
|
|
460
|
+
'(it does not render). Optionally filter by entityType/entityId. This tool only references existing ' +
|
|
461
|
+
'assets — uploads happen via the workspace UI or import_file.',
|
|
462
|
+
parameters: T.Object({
|
|
463
|
+
repo: T.String({ description: 'Folder name' }),
|
|
464
|
+
entityType: T.Optional(T.String({ description: 'Filter to assets owned by entries of this type' })),
|
|
465
|
+
entityId: T.Optional(T.String({ description: 'Filter to assets owned by this entry id' })),
|
|
466
|
+
}),
|
|
467
|
+
execute: async (toolCallId, params) => {
|
|
468
|
+
try {
|
|
469
|
+
const repoName = resolvePrivateRepo(params.repo);
|
|
470
|
+
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
471
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
472
|
+
}
|
|
473
|
+
let assets = await listRepoAssets(repoName, workspaceManager);
|
|
474
|
+
if (params.entityType)
|
|
475
|
+
assets = assets.filter(a => a.entityType === params.entityType);
|
|
476
|
+
if (params.entityId)
|
|
477
|
+
assets = assets.filter(a => a.entityId === params.entityId);
|
|
478
|
+
return wrapToolResult({
|
|
479
|
+
success: true,
|
|
480
|
+
repo: repoName,
|
|
481
|
+
count: assets.length,
|
|
482
|
+
assets: assets.map(a => ({
|
|
483
|
+
asset_id: a.assetId,
|
|
484
|
+
filename: a.filename,
|
|
485
|
+
mime_type: a.contentType,
|
|
486
|
+
entityType: a.entityType,
|
|
487
|
+
entityId: a.entityId,
|
|
488
|
+
entityName: a.entityName,
|
|
489
|
+
url: a.url,
|
|
490
|
+
embed: a.embed,
|
|
491
|
+
})),
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
catch (error) {
|
|
495
|
+
return wrapToolResult({ success: false, error: error instanceof Error ? error.message : 'Unknown error' });
|
|
496
|
+
}
|
|
497
|
+
},
|
|
498
|
+
},
|
|
499
|
+
// Embed an already-uploaded asset into an entry body
|
|
500
|
+
{
|
|
501
|
+
name: 'attach_asset_to_entity',
|
|
502
|
+
label: 'Attach Asset',
|
|
503
|
+
description: 'Embed an already-uploaded asset (from list_assets) into an entry body using its render-safe markdown, ' +
|
|
504
|
+
'without rewriting the whole body. mode "append" adds it at the end; mode "replace_placeholder" swaps dead ' +
|
|
505
|
+
'placeholder text (e.g. an ![[Foo.png]] written earlier) for the working embed. Drop-guarded: rejects with ' +
|
|
506
|
+
'ASSET_REMOVAL_BLOCKED if it would remove other image embeds (append only — replace_placeholder is exempt ' +
|
|
507
|
+
'since the placeholder it removes is the dead reference being fixed).',
|
|
508
|
+
parameters: T.Object({
|
|
509
|
+
repo: T.String({ description: 'Folder name' }),
|
|
510
|
+
entityType: T.String({ description: 'Entity type of the target entry' }),
|
|
511
|
+
entityId: T.String({ description: 'Entity ID of the target entry' }),
|
|
512
|
+
url: T.String({ description: 'Asset url, taken verbatim from list_assets' }),
|
|
513
|
+
alt: T.Optional(T.String({ description: 'Alt text / caption. Defaults to the asset filename.' })),
|
|
514
|
+
mode: T.Optional(T.Union([T.Literal('append'), T.Literal('replace_placeholder')], { description: 'append (default) or replace_placeholder' })),
|
|
515
|
+
placeholder: T.Optional(T.String({ description: 'Required for replace_placeholder: exact text to replace' })),
|
|
516
|
+
expectedCount: T.Optional(T.Number({ description: 'For replace_placeholder: require this many occurrences, else reject' })),
|
|
517
|
+
}),
|
|
518
|
+
execute: async (toolCallId, params) => {
|
|
519
|
+
try {
|
|
520
|
+
const repoName = resolvePrivateRepo(params.repo);
|
|
521
|
+
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
522
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
523
|
+
}
|
|
524
|
+
const url = params.url ?? '';
|
|
525
|
+
if (!url.trim())
|
|
526
|
+
return wrapToolResult({ success: false, error: 'url is required' });
|
|
527
|
+
const mode = params.mode ?? 'append';
|
|
528
|
+
if (mode === 'replace_placeholder' && !params.placeholder) {
|
|
529
|
+
return wrapToolResult({ success: false, error: 'mode "replace_placeholder" requires a non-empty placeholder' });
|
|
530
|
+
}
|
|
531
|
+
const filename = params.alt ?? (url.split('/').pop() || 'asset').split('?')[0];
|
|
532
|
+
const embed = assetEmbed(filename, url);
|
|
533
|
+
const graph = workspaceManager.getGraph(repoName);
|
|
534
|
+
const entity = graph.get(params.entityType, params.entityId);
|
|
535
|
+
const currentBody = graph.getLiveBody(params.entityType, params.entityId) ?? entity.document.content;
|
|
536
|
+
let newBody;
|
|
537
|
+
let occurrences;
|
|
538
|
+
let allowAssetRemoval = false;
|
|
539
|
+
if (mode === 'replace_placeholder') {
|
|
540
|
+
const ph = params.placeholder;
|
|
541
|
+
let count = 0;
|
|
542
|
+
for (let i = currentBody.indexOf(ph); i !== -1; i = currentBody.indexOf(ph, i + ph.length))
|
|
543
|
+
count++;
|
|
544
|
+
if (count === 0) {
|
|
545
|
+
return wrapToolResult({ success: false, code: 'NO_MATCH', error: `placeholder not present in ${params.entityType}/${params.entityId}.` });
|
|
546
|
+
}
|
|
547
|
+
if (params.expectedCount !== undefined && count !== params.expectedCount) {
|
|
548
|
+
return wrapToolResult({ success: false, code: 'AMBIGUOUS_MATCH', occurrences: count, error: `Expected ${params.expectedCount} occurrence(s) of placeholder, found ${count}.` });
|
|
549
|
+
}
|
|
550
|
+
occurrences = count;
|
|
551
|
+
newBody = currentBody.split(ph).join(embed);
|
|
552
|
+
// The placeholder we're removing is itself a recognized embed
|
|
553
|
+
// target; swapping it for the working embed is the whole point.
|
|
554
|
+
allowAssetRemoval = true;
|
|
555
|
+
}
|
|
556
|
+
else {
|
|
557
|
+
if (currentBody.includes(embed)) {
|
|
558
|
+
return wrapToolResult({ success: false, code: 'ALREADY_PRESENT', error: `Asset embed already present in ${params.entityType}/${params.entityId}.` });
|
|
559
|
+
}
|
|
560
|
+
newBody = currentBody.trimEnd() + '\n\n' + embed + '\n';
|
|
561
|
+
}
|
|
562
|
+
const options = prepareUpdatePayload({
|
|
563
|
+
entityType: params.entityType,
|
|
564
|
+
entityId: params.entityId,
|
|
565
|
+
content: newBody,
|
|
566
|
+
}, effectiveGitUser());
|
|
567
|
+
onAgentActivity?.('enter', repoName);
|
|
568
|
+
try {
|
|
569
|
+
const { entity: updated, frontmatter_changed, content_changed, noop, broadcast } = await diagnosedUpdate(graph, options, { content: newBody }, { allowAssetRemoval });
|
|
570
|
+
onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
571
|
+
return wrapToolResult({
|
|
572
|
+
success: true,
|
|
573
|
+
entity: { entityId: updated.id, entityType: updated.entityType, repo: repoName },
|
|
574
|
+
embed,
|
|
575
|
+
mode,
|
|
576
|
+
occurrences,
|
|
577
|
+
frontmatter_changed,
|
|
578
|
+
content_changed,
|
|
579
|
+
noop,
|
|
580
|
+
broadcast,
|
|
581
|
+
message: `Embedded ${filename} into ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
finally {
|
|
585
|
+
onAgentActivity?.('leave', repoName);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
catch (error) {
|
|
589
|
+
if (error instanceof DroppedAssetError) {
|
|
590
|
+
return wrapToolResult({ success: false, code: 'ASSET_REMOVAL_BLOCKED', droppedAssets: error.dropped, error: error.message });
|
|
591
|
+
}
|
|
592
|
+
return wrapToolResult({ success: false, error: error instanceof Error ? error.message : 'Unknown error' });
|
|
593
|
+
}
|
|
594
|
+
},
|
|
595
|
+
},
|
|
268
596
|
// Delete entity
|
|
269
597
|
{
|
|
270
598
|
name: 'delete_entity',
|
|
271
|
-
label: 'Delete
|
|
272
|
-
description: 'Delete an
|
|
599
|
+
label: 'Delete Entry',
|
|
600
|
+
description: 'Delete an entry. Use with caution! Folder is auto-resolved for app-defined types.',
|
|
273
601
|
parameters: T.Object({
|
|
274
|
-
repo: T.Optional(T.String({ description: '
|
|
602
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
275
603
|
entityType: T.String({ description: 'Entity type' }),
|
|
276
604
|
entityId: T.String({ description: 'Entity ID' }),
|
|
277
605
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
|
|
@@ -280,20 +608,39 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
280
608
|
try {
|
|
281
609
|
let repoName = params.repo;
|
|
282
610
|
if (!repoName) {
|
|
283
|
-
|
|
284
|
-
if (!repoName)
|
|
285
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
611
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
286
612
|
}
|
|
613
|
+
repoName = resolvePrivateRepo(repoName);
|
|
287
614
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
288
|
-
return wrapToolResult({ success: false, error: `
|
|
615
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
289
616
|
}
|
|
290
617
|
const graph = workspaceManager.getGraph(repoName);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
618
|
+
// Soft bridge-awareness: deleting a person linked to an auth account
|
|
619
|
+
// orphans that user. Don't block — surface a warning so the agent can
|
|
620
|
+
// tell the user, and the Profile panel catches the orphan after.
|
|
621
|
+
let bridgeWarning;
|
|
622
|
+
if (params.entityType === 'person') {
|
|
623
|
+
try {
|
|
624
|
+
const handle = graph.get('person', params.entityId)?.data?.user_handle;
|
|
625
|
+
if (typeof handle === 'string' && handle.length > 0) {
|
|
626
|
+
bridgeWarning = `Note: this record was linked to the "${handle}" user account. Deleting it unlinks them — their "My Tasks", @mentions, and assignments stop resolving until they link a new record.`;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
catch { /* not found — let graph.delete surface it */ }
|
|
630
|
+
}
|
|
631
|
+
onAgentActivity?.('enter', repoName);
|
|
632
|
+
try {
|
|
633
|
+
await graph.delete(params.entityType, params.entityId, params.commitMessage);
|
|
634
|
+
onMutation?.({ action: 'deleted', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
635
|
+
return wrapToolResult({
|
|
636
|
+
success: true,
|
|
637
|
+
message: `Deleted ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
|
|
638
|
+
...(bridgeWarning ? { warning: bridgeWarning } : {}),
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
finally {
|
|
642
|
+
onAgentActivity?.('leave', repoName);
|
|
643
|
+
}
|
|
297
644
|
}
|
|
298
645
|
catch (error) {
|
|
299
646
|
return wrapToolResult({
|
|
@@ -307,46 +654,94 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
307
654
|
{
|
|
308
655
|
name: 'import_file',
|
|
309
656
|
label: 'Import File',
|
|
310
|
-
description: 'Import a local file as a Studiograph
|
|
657
|
+
description: 'Import a local file as a Studiograph entry. Text formats become typed entries (.md/.txt → note, .csv → dataset). Binary formats become typed entries that embed a free-standing asset: images/opaque files → material, PDF/Word → document, spreadsheets → dataset.',
|
|
311
658
|
parameters: T.Object({
|
|
312
659
|
path: T.String({ description: 'Absolute path or ~/relative path to the file' }),
|
|
313
|
-
|
|
314
|
-
entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension)' })),
|
|
660
|
+
folder: T.String({ description: 'Target folder name' }),
|
|
661
|
+
entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension; ignored for binary imports, which route by kind)' })),
|
|
315
662
|
entityId: T.Optional(T.String({ description: 'Override entity ID (default: from filename)' })),
|
|
316
663
|
}),
|
|
317
664
|
execute: async (toolCallId, params) => {
|
|
318
665
|
try {
|
|
319
|
-
if (!canAccessRepo(params.
|
|
320
|
-
return wrapToolResult({ success: false, error: `
|
|
666
|
+
if (!canAccessRepo(params.folder, workspaceManager, getUser, authSvc)) {
|
|
667
|
+
return wrapToolResult({ success: false, error: `Folder "${params.folder}" not found` });
|
|
321
668
|
}
|
|
322
669
|
const { readFileSync, existsSync } = await import('fs');
|
|
323
|
-
const { resolve } = await import('path');
|
|
670
|
+
const { resolve, basename, sep } = await import('path');
|
|
324
671
|
const { homedir } = await import('os');
|
|
325
672
|
const { importFile, isSupportedFile } = await import('../../services/import-service.js');
|
|
673
|
+
const { isAssetUploadExtension } = await import('../../services/assets/base.js');
|
|
674
|
+
const { importAssetAsEntity } = await import('../../services/asset-import-service.js');
|
|
326
675
|
const filePath = params.path.startsWith('~/')
|
|
327
676
|
? resolve(homedir(), params.path.slice(2))
|
|
328
677
|
: resolve(params.path);
|
|
329
678
|
if (!existsSync(filePath)) {
|
|
330
679
|
return wrapToolResult({ success: false, error: `File not found: ${filePath}` });
|
|
331
680
|
}
|
|
681
|
+
const graph = workspaceManager.getGraph(params.folder);
|
|
682
|
+
const fname = basename(filePath);
|
|
683
|
+
// Path-exfil guard: the agent reads bytes off disk and uploads
|
|
684
|
+
// them as a workspace asset, accessible via /api/assets/* by any
|
|
685
|
+
// folder member. Without an allowlist, an LLM prompt injection in
|
|
686
|
+
// an imported note can ask the agent to grab ~/.ssh/id_rsa, .env
|
|
687
|
+
// files, kubeconfigs, etc. by renaming them to a permitted
|
|
688
|
+
// extension. Restrict to roots a user would plausibly drop files
|
|
689
|
+
// from: the workspace itself, ~/Downloads, ~/Documents.
|
|
690
|
+
const home = homedir();
|
|
691
|
+
const workspaceRoot = graph.getWorkspaceRoot();
|
|
692
|
+
const allowedRoots = [
|
|
693
|
+
workspaceRoot,
|
|
694
|
+
resolve(home, 'Downloads'),
|
|
695
|
+
resolve(home, 'Documents'),
|
|
696
|
+
].filter((r) => Boolean(r)).map(r => r.endsWith(sep) ? r : r + sep);
|
|
697
|
+
const isInAllowedRoot = allowedRoots.some(root => filePath === root.slice(0, -1) || filePath.startsWith(root));
|
|
698
|
+
if (!isInAllowedRoot) {
|
|
699
|
+
return wrapToolResult({
|
|
700
|
+
success: false,
|
|
701
|
+
error: `Path "${filePath}" is outside the import allowlist. Files must live under the workspace, ~/Downloads, or ~/Documents.`,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
// Binary extensions → asset-as-embed import: store a free-standing
|
|
705
|
+
// asset + create the typed entry(ies) that embed it (image→material,
|
|
706
|
+
// doc/pdf→document, xlsx→dataset×N). The text-import path doesn't know
|
|
707
|
+
// how to handle .indd / .pptx / etc. Parity with the web import
|
|
708
|
+
// dispatcher (importAssetAsEntity).
|
|
709
|
+
if (isAssetUploadExtension(fname)) {
|
|
710
|
+
const buffer = readFileSync(filePath);
|
|
711
|
+
const result = await importAssetAsEntity({
|
|
712
|
+
graph,
|
|
713
|
+
filename: fname,
|
|
714
|
+
buffer,
|
|
715
|
+
});
|
|
716
|
+
for (const e of result.entities) {
|
|
717
|
+
onMutation?.({ action: 'created', repo: params.folder, entityType: e.entityType, entityId: e.entityId });
|
|
718
|
+
}
|
|
719
|
+
const first = result.entities[0];
|
|
720
|
+
return wrapToolResult({
|
|
721
|
+
success: true,
|
|
722
|
+
entityType: first?.entityType,
|
|
723
|
+
entityId: first?.entityId,
|
|
724
|
+
assetId: result.assetId,
|
|
725
|
+
entities: result.entities.map(e => ({ entityType: e.entityType, entityId: e.entityId })),
|
|
726
|
+
message: `Imported ${fname} as ${result.entities.map(e => `${e.entityType}/${e.entityId}`).join(', ')} in ${params.folder}`,
|
|
727
|
+
});
|
|
728
|
+
}
|
|
332
729
|
if (!isSupportedFile(filePath)) {
|
|
333
|
-
return wrapToolResult({ success: false, error: `Unsupported file type
|
|
730
|
+
return wrapToolResult({ success: false, error: `Unsupported file type for ${fname}` });
|
|
334
731
|
}
|
|
335
|
-
const graph = workspaceManager.getGraph(params.collection);
|
|
336
732
|
const content = readFileSync(filePath);
|
|
337
|
-
const
|
|
338
|
-
const result = await importFile(graph, basename(filePath), content, {
|
|
733
|
+
const result = await importFile(graph, fname, content, {
|
|
339
734
|
entityType: params.entityType,
|
|
340
735
|
entityId: params.entityId,
|
|
341
736
|
});
|
|
342
737
|
if (result.status === 'created') {
|
|
343
|
-
onMutation?.({ action: 'created', repo: params.
|
|
738
|
+
onMutation?.({ action: 'created', repo: params.folder, entityType: result.entityType, entityId: result.entityId });
|
|
344
739
|
}
|
|
345
740
|
return wrapToolResult({
|
|
346
741
|
success: result.status === 'created',
|
|
347
742
|
...result,
|
|
348
743
|
message: result.status === 'created'
|
|
349
|
-
? `Imported ${
|
|
744
|
+
? `Imported ${fname} as ${result.entityType}/${result.entityId} in ${params.folder}`
|
|
350
745
|
: result.error,
|
|
351
746
|
});
|
|
352
747
|
}
|
|
@@ -361,10 +756,10 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
361
756
|
// Rename entity (change ID)
|
|
362
757
|
{
|
|
363
758
|
name: 'rename_entity',
|
|
364
|
-
label: 'Rename
|
|
365
|
-
description: 'Rename an
|
|
759
|
+
label: 'Rename Entry',
|
|
760
|
+
description: 'Rename an entry by changing its ID. Preserves all data, content, and source_ref. The old ID will no longer exist. Folder is auto-resolved for app-defined types.',
|
|
366
761
|
parameters: T.Object({
|
|
367
|
-
repo: T.Optional(T.String({ description: '
|
|
762
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
368
763
|
entityType: T.String({ description: 'Entity type' }),
|
|
369
764
|
oldId: T.String({ description: 'Current entity ID' }),
|
|
370
765
|
newId: T.String({ description: 'New entity ID (kebab-case)' }),
|
|
@@ -373,12 +768,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
373
768
|
try {
|
|
374
769
|
let repoName = params.repo;
|
|
375
770
|
if (!repoName) {
|
|
376
|
-
|
|
377
|
-
if (!repoName)
|
|
378
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
771
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
379
772
|
}
|
|
773
|
+
repoName = resolvePrivateRepo(repoName);
|
|
380
774
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
381
|
-
return wrapToolResult({ success: false, error: `
|
|
775
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
382
776
|
}
|
|
383
777
|
const graph = workspaceManager.getGraph(repoName);
|
|
384
778
|
const result = await graph.rename(params.entityType, params.oldId, params.newId);
|
|
@@ -398,41 +792,41 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
398
792
|
}
|
|
399
793
|
},
|
|
400
794
|
},
|
|
401
|
-
//
|
|
795
|
+
// Transfer entity across repos (cross-repo move). Distinct from
|
|
796
|
+
// folder-tools' `move_entity`, which relocates within one repo.
|
|
402
797
|
{
|
|
403
|
-
name: '
|
|
404
|
-
label: '
|
|
405
|
-
description: 'Move an
|
|
798
|
+
name: 'transfer_entity',
|
|
799
|
+
label: 'Transfer Entry',
|
|
800
|
+
description: 'Move an entry from one repo to another. Preserves all data, content, and wikilinks. Requires access to both folders. For relocating within the same repo (folder_path change), use move_entity instead.',
|
|
406
801
|
parameters: T.Object({
|
|
407
|
-
sourceRepo: T.String({ description: 'Source
|
|
408
|
-
targetRepo: T.String({ description: 'Target
|
|
802
|
+
sourceRepo: T.String({ description: 'Source repo name' }),
|
|
803
|
+
targetRepo: T.String({ description: 'Target repo name' }),
|
|
409
804
|
entityType: T.String({ description: 'Entity type' }),
|
|
410
805
|
entityId: T.String({ description: 'Entity ID' }),
|
|
411
806
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
|
|
412
807
|
}),
|
|
413
808
|
execute: async (toolCallId, params) => {
|
|
414
809
|
try {
|
|
415
|
-
const denied = adminOnly(getUser);
|
|
416
|
-
if (denied)
|
|
417
|
-
return wrapToolResult({ success: false, error: denied });
|
|
418
810
|
if (!canAccessRepo(params.sourceRepo, workspaceManager, getUser, authSvc)) {
|
|
419
|
-
return wrapToolResult({ success: false, error: `
|
|
811
|
+
return wrapToolResult({ success: false, error: `Folder "${params.sourceRepo}" not found` });
|
|
420
812
|
}
|
|
421
813
|
if (!canAccessRepo(params.targetRepo, workspaceManager, getUser, authSvc)) {
|
|
422
|
-
return wrapToolResult({ success: false, error: `
|
|
814
|
+
return wrapToolResult({ success: false, error: `Folder "${params.targetRepo}" not found` });
|
|
423
815
|
}
|
|
424
816
|
const sourceGraph = workspaceManager.getGraph(params.sourceRepo);
|
|
425
817
|
const targetGraph = workspaceManager.getGraph(params.targetRepo);
|
|
426
818
|
// Read the full entity from source
|
|
427
819
|
const entity = sourceGraph.get(params.entityType, params.entityId);
|
|
428
820
|
// Create in target repo
|
|
821
|
+
const actor = effectiveGitUser();
|
|
429
822
|
const now = new Date().toISOString();
|
|
430
823
|
await targetGraph.create({
|
|
431
824
|
entityType: params.entityType,
|
|
432
825
|
entityId: params.entityId,
|
|
433
|
-
data: { ...entity.data, updated_at: now, updated_by:
|
|
826
|
+
data: { ...entity.data, updated_at: now, updated_by: actor.id },
|
|
434
827
|
content: entity.document.content || '',
|
|
435
828
|
commitMessage: params.commitMessage || `Move ${params.entityType} ${params.entityId} from ${params.sourceRepo} to ${params.targetRepo}`,
|
|
829
|
+
user: actor,
|
|
436
830
|
});
|
|
437
831
|
// Delete from source repo
|
|
438
832
|
await sourceGraph.delete(params.entityType, params.entityId, `Move ${params.entityType} ${params.entityId} to ${params.targetRepo}`);
|
|
@@ -454,12 +848,12 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
454
848
|
// Search entities
|
|
455
849
|
{
|
|
456
850
|
name: 'search_entities',
|
|
457
|
-
label: 'Search
|
|
458
|
-
description: 'Search for
|
|
851
|
+
label: 'Search Entries',
|
|
852
|
+
description: 'Search for entries across folders with filters.',
|
|
459
853
|
parameters: T.Object({
|
|
460
854
|
query: T.Optional(T.String({ description: 'Search query (full-text)' })),
|
|
461
855
|
entityType: T.Optional(T.String({ description: 'Filter by entity type' })),
|
|
462
|
-
repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific
|
|
856
|
+
repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific folders' })),
|
|
463
857
|
visibility: T.Optional(T.Array(T.String(), { description: 'Filter by visibility (public, team, admin, restricted)' })),
|
|
464
858
|
tags: T.Optional(T.Array(T.String(), { description: 'Filter by tags' })),
|
|
465
859
|
dateRange: T.Optional(T.Object({
|
|
@@ -471,9 +865,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
471
865
|
}),
|
|
472
866
|
execute: async (toolCallId, params) => {
|
|
473
867
|
try {
|
|
474
|
-
// Scope search to accessible
|
|
868
|
+
// Scope search to accessible folders
|
|
475
869
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
476
|
-
let repoNames = params.repoNames;
|
|
870
|
+
let repoNames = params.repoNames?.map((r) => resolvePrivateRepo(r));
|
|
477
871
|
if (allowed) {
|
|
478
872
|
repoNames = repoNames
|
|
479
873
|
? repoNames.filter((r) => allowed.has(r))
|
|
@@ -511,8 +905,8 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
511
905
|
// List entities
|
|
512
906
|
{
|
|
513
907
|
name: 'list_entities',
|
|
514
|
-
label: 'List
|
|
515
|
-
description: 'List all
|
|
908
|
+
label: 'List Entries',
|
|
909
|
+
description: 'List all entries of a given type (or all types)',
|
|
516
910
|
parameters: T.Object({
|
|
517
911
|
entityType: T.Optional(T.String({ description: 'Entity type to list (omit for all)' })),
|
|
518
912
|
limit: T.Optional(T.Number({ description: 'Max results' })),
|
|
@@ -520,7 +914,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
520
914
|
execute: async (toolCallId, params) => {
|
|
521
915
|
try {
|
|
522
916
|
let results = workspaceManager.list(params.entityType, params.limit);
|
|
523
|
-
// Filter to accessible
|
|
917
|
+
// Filter to accessible folders
|
|
524
918
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
525
919
|
if (allowed) {
|
|
526
920
|
results = results.filter(r => allowed.has(r.repoName));
|
|
@@ -547,20 +941,21 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
547
941
|
// Get related entities
|
|
548
942
|
{
|
|
549
943
|
name: 'get_related',
|
|
550
|
-
label: 'Get Related
|
|
551
|
-
description: 'Get
|
|
944
|
+
label: 'Get Related Entries',
|
|
945
|
+
description: 'Get entries related to a given entry via wikilinks (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
|
|
552
946
|
parameters: T.Object({
|
|
553
|
-
repo: T.String({ description: '
|
|
947
|
+
repo: T.String({ description: 'Folder name' }),
|
|
554
948
|
entityType: T.String({ description: 'Entity type' }),
|
|
555
949
|
entityId: T.String({ description: 'Entity ID' }),
|
|
556
950
|
}),
|
|
557
951
|
execute: async (toolCallId, params) => {
|
|
558
952
|
try {
|
|
559
|
-
|
|
560
|
-
|
|
953
|
+
const repo = resolvePrivateRepo(params.repo);
|
|
954
|
+
if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
|
|
955
|
+
return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
|
|
561
956
|
}
|
|
562
|
-
let related = workspaceManager.getRelated(
|
|
563
|
-
// Filter cross-
|
|
957
|
+
let related = workspaceManager.getRelated(repo, params.entityType, params.entityId);
|
|
958
|
+
// Filter cross-folder results to accessible repos
|
|
564
959
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
565
960
|
if (allowed) {
|
|
566
961
|
related = related.filter(r => allowed.has(r.repoName));
|
|
@@ -588,19 +983,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
588
983
|
{
|
|
589
984
|
name: 'get_backlinks',
|
|
590
985
|
label: 'Get Backlinks',
|
|
591
|
-
description: 'Get
|
|
986
|
+
description: 'Get entries that link to a given entry (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
|
|
592
987
|
parameters: T.Object({
|
|
593
|
-
repo: T.String({ description: '
|
|
988
|
+
repo: T.String({ description: 'Folder name' }),
|
|
594
989
|
entityType: T.String({ description: 'Entity type' }),
|
|
595
990
|
entityId: T.String({ description: 'Entity ID' }),
|
|
596
991
|
}),
|
|
597
992
|
execute: async (toolCallId, params) => {
|
|
598
993
|
try {
|
|
599
994
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
600
|
-
return wrapToolResult({ success: false, error: `
|
|
995
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
601
996
|
}
|
|
602
997
|
let backlinks = workspaceManager.getBacklinks(params.repo, params.entityType, params.entityId);
|
|
603
|
-
// Filter cross-
|
|
998
|
+
// Filter cross-folder results to accessible repos
|
|
604
999
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
605
1000
|
if (allowed) {
|
|
606
1001
|
backlinks = backlinks.filter(r => allowed.has(r.repoName));
|
|
@@ -628,16 +1023,16 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
628
1023
|
{
|
|
629
1024
|
name: 'validate_wikilinks',
|
|
630
1025
|
label: 'Validate Wikilinks',
|
|
631
|
-
description: 'Validate all wikilinks in an
|
|
1026
|
+
description: 'Validate all wikilinks in an entry (checks same folder and cross-folder)',
|
|
632
1027
|
parameters: T.Object({
|
|
633
|
-
repo: T.String({ description: '
|
|
1028
|
+
repo: T.String({ description: 'Folder name' }),
|
|
634
1029
|
entityType: T.String({ description: 'Entity type' }),
|
|
635
1030
|
entityId: T.String({ description: 'Entity ID' }),
|
|
636
1031
|
}),
|
|
637
1032
|
execute: async (toolCallId, params) => {
|
|
638
1033
|
try {
|
|
639
1034
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
640
|
-
return wrapToolResult({ success: false, error: `
|
|
1035
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
641
1036
|
}
|
|
642
1037
|
const validation = workspaceManager.validateWikilinks(params.repo, params.entityType, params.entityId);
|
|
643
1038
|
return wrapToolResult({
|
|
@@ -672,7 +1067,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
672
1067
|
const summary = workspaceManager.getSummary();
|
|
673
1068
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
674
1069
|
if (allowed) {
|
|
675
|
-
// Filter summary to accessible
|
|
1070
|
+
// Filter summary to accessible folders only
|
|
676
1071
|
const filteredByRepo = {};
|
|
677
1072
|
let filteredTotal = 0;
|
|
678
1073
|
for (const [repo, count] of Object.entries(summary.entitiesByRepo)) {
|
|
@@ -684,19 +1079,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
684
1079
|
return wrapToolResult({
|
|
685
1080
|
success: true,
|
|
686
1081
|
summary: {
|
|
687
|
-
|
|
1082
|
+
totalFolders: allowed.size,
|
|
688
1083
|
totalEntities: filteredTotal,
|
|
689
|
-
|
|
1084
|
+
entitiesByFolder: filteredByRepo,
|
|
690
1085
|
},
|
|
691
1086
|
});
|
|
692
1087
|
}
|
|
693
1088
|
return wrapToolResult({
|
|
694
1089
|
success: true,
|
|
695
1090
|
summary: {
|
|
696
|
-
|
|
1091
|
+
totalFolders: summary.totalRepos,
|
|
697
1092
|
totalEntities: summary.totalEntities,
|
|
698
1093
|
entitiesByType: summary.entitiesByType,
|
|
699
|
-
|
|
1094
|
+
entitiesByFolder: summary.entitiesByRepo,
|
|
700
1095
|
},
|
|
701
1096
|
});
|
|
702
1097
|
}
|
|
@@ -708,15 +1103,15 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
708
1103
|
}
|
|
709
1104
|
},
|
|
710
1105
|
},
|
|
711
|
-
// List
|
|
1106
|
+
// List folders
|
|
712
1107
|
{
|
|
713
1108
|
name: 'list_repos',
|
|
714
|
-
label: 'List
|
|
715
|
-
description: 'List all
|
|
1109
|
+
label: 'List Folders',
|
|
1110
|
+
description: 'List all folders in the workspace',
|
|
716
1111
|
parameters: T.Object({}),
|
|
717
1112
|
execute: async (toolCallId, params) => {
|
|
718
1113
|
try {
|
|
719
|
-
let repos = workspaceManager.
|
|
1114
|
+
let repos = workspaceManager.getContentRepoConfigs();
|
|
720
1115
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
721
1116
|
if (allowed) {
|
|
722
1117
|
repos = repos.filter(r => allowed.has(r.name));
|
|
@@ -724,12 +1119,12 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
724
1119
|
return wrapToolResult({
|
|
725
1120
|
success: true,
|
|
726
1121
|
count: repos.length,
|
|
727
|
-
|
|
1122
|
+
folders: repos.map(r => ({
|
|
728
1123
|
name: r.name,
|
|
729
1124
|
type: r.type,
|
|
730
1125
|
description: r.description,
|
|
731
1126
|
path: r.path,
|
|
732
|
-
|
|
1127
|
+
personal: r.personal || false,
|
|
733
1128
|
})),
|
|
734
1129
|
});
|
|
735
1130
|
}
|
|
@@ -741,40 +1136,35 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
741
1136
|
}
|
|
742
1137
|
},
|
|
743
1138
|
},
|
|
744
|
-
// Create a new
|
|
1139
|
+
// Create a new folder
|
|
745
1140
|
{
|
|
746
|
-
name: '
|
|
747
|
-
label: 'Create
|
|
748
|
-
description: 'Create a new
|
|
1141
|
+
name: 'create_folder',
|
|
1142
|
+
label: 'Create Folder',
|
|
1143
|
+
description: 'Create a new shared folder in the workspace. Folders are git-backed containers for entries. New folders are shared with teammates who have access; the creator is granted admin. Every user already has a personal "My Folder" folder auto-provisioned — do not use this tool to create another one.',
|
|
749
1144
|
parameters: T.Object({
|
|
750
|
-
name: T.String({ description: '
|
|
751
|
-
description: T.Optional(T.String({ description: 'Short description of the
|
|
752
|
-
private: T.Optional(T.Boolean({ description: 'If true, creates a private collection visible only to you' })),
|
|
1145
|
+
name: T.String({ description: 'Folder name in kebab-case (e.g., "client-projects")' }),
|
|
1146
|
+
description: T.Optional(T.String({ description: 'Short description of the folder' })),
|
|
753
1147
|
}),
|
|
754
1148
|
execute: async (toolCallId, params) => {
|
|
755
1149
|
try {
|
|
756
1150
|
const user = getUser();
|
|
757
|
-
// Non-private collections require admin; private collections can be created by anyone
|
|
758
|
-
if (!params.private && user && user.role !== 'admin') {
|
|
759
|
-
return wrapToolResult({ success: false, error: 'Only admins can create collections' });
|
|
760
|
-
}
|
|
761
1151
|
if (!/^[a-z0-9][a-z0-9-]*$/.test(params.name)) {
|
|
762
|
-
return wrapToolResult({ success: false, error: '
|
|
1152
|
+
return wrapToolResult({ success: false, error: 'Folder name must be kebab-case (lowercase letters, numbers, hyphens)' });
|
|
763
1153
|
}
|
|
764
1154
|
const { Workspace } = await import('../../core/workspace.js');
|
|
765
1155
|
const workspace = new Workspace(workspacePath);
|
|
766
1156
|
const repo = await workspace.registerRepo({
|
|
767
1157
|
name: params.name,
|
|
768
1158
|
description: params.description,
|
|
769
|
-
|
|
770
|
-
...(params.private && user ? { owner_id: user.id } : {}),
|
|
1159
|
+
owner_id: user?.id,
|
|
771
1160
|
});
|
|
772
|
-
// Reload workspace manager to pick up the new collection
|
|
773
1161
|
workspaceManager.reloadConfig();
|
|
774
|
-
|
|
1162
|
+
if (user && authSvc)
|
|
1163
|
+
authSvc.grantFolderAccess(user.id, repo.name, 'admin');
|
|
1164
|
+
onMutation?.({ action: 'created', repo: repo.name, entityType: '_folder', entityId: repo.name });
|
|
775
1165
|
return wrapToolResult({
|
|
776
1166
|
success: true,
|
|
777
|
-
|
|
1167
|
+
folder: { name: repo.name, path: repo.path, description: repo.description },
|
|
778
1168
|
});
|
|
779
1169
|
}
|
|
780
1170
|
catch (error) {
|
|
@@ -788,7 +1178,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
788
1178
|
label: 'Query Dataset',
|
|
789
1179
|
description: 'Query rows from a dataset entity with optional filtering',
|
|
790
1180
|
parameters: T.Object({
|
|
791
|
-
repo: T.String({ description: '
|
|
1181
|
+
repo: T.String({ description: 'Folder name' }),
|
|
792
1182
|
entityId: T.String({ description: 'Dataset entity ID' }),
|
|
793
1183
|
filter: T.Optional(T.Object({}, { description: 'Filter conditions (column: value or { gte, lte, contains })', additionalProperties: true })),
|
|
794
1184
|
limit: T.Optional(T.Number({ description: 'Max rows to return' })),
|
|
@@ -796,21 +1186,24 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
796
1186
|
execute: async (toolCallId, params) => {
|
|
797
1187
|
try {
|
|
798
1188
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
799
|
-
return wrapToolResult({ success: false, error: `
|
|
1189
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
800
1190
|
}
|
|
801
1191
|
const graph = workspaceManager.getGraph(params.repo);
|
|
802
|
-
|
|
803
|
-
|
|
1192
|
+
// Validates the entity exists and is a dataset before querying.
|
|
1193
|
+
graph.get('dataset', params.entityId);
|
|
804
1194
|
let rows = graph.getDatasetRows(params.entityId, params.filter);
|
|
805
1195
|
const total = rows.length;
|
|
806
1196
|
if (params.limit && params.limit > 0) {
|
|
807
1197
|
rows = rows.slice(0, params.limit);
|
|
808
1198
|
}
|
|
1199
|
+
// Columns from the header, not the result rows — so a zero-match
|
|
1200
|
+
// filter or header-only dataset still reports the real columns.
|
|
1201
|
+
const columns = graph.getDatasetColumns(params.entityId);
|
|
809
1202
|
return wrapToolResult({
|
|
810
1203
|
success: true,
|
|
811
1204
|
rows,
|
|
812
1205
|
total,
|
|
813
|
-
|
|
1206
|
+
columns,
|
|
814
1207
|
});
|
|
815
1208
|
}
|
|
816
1209
|
catch (error) {
|
|
@@ -827,7 +1220,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
827
1220
|
label: 'Append Rows',
|
|
828
1221
|
description: 'Append rows to a dataset entity',
|
|
829
1222
|
parameters: T.Object({
|
|
830
|
-
repo: T.String({ description: '
|
|
1223
|
+
repo: T.String({ description: 'Folder name' }),
|
|
831
1224
|
entityId: T.String({ description: 'Dataset entity ID' }),
|
|
832
1225
|
rows: T.Array(T.Object({}, { additionalProperties: true }), { description: 'Rows to append' }),
|
|
833
1226
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
|
|
@@ -835,13 +1228,14 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
835
1228
|
execute: async (toolCallId, params) => {
|
|
836
1229
|
try {
|
|
837
1230
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
838
|
-
return wrapToolResult({ success: false, error: `
|
|
1231
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
839
1232
|
}
|
|
840
1233
|
const graph = workspaceManager.getGraph(params.repo);
|
|
841
1234
|
// Get current row count before appending
|
|
842
1235
|
const beforeRows = graph.getDatasetRows(params.entityId);
|
|
843
1236
|
await graph.appendDatasetRows(params.entityId, params.rows, params.commitMessage);
|
|
844
1237
|
const afterRows = graph.getDatasetRows(params.entityId);
|
|
1238
|
+
onMutation?.({ action: 'updated', repo: params.repo, entityType: 'dataset', entityId: params.entityId });
|
|
845
1239
|
return wrapToolResult({
|
|
846
1240
|
success: true,
|
|
847
1241
|
rowsAdded: afterRows.length - beforeRows.length,
|
|
@@ -860,31 +1254,23 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
860
1254
|
// Get entity schema
|
|
861
1255
|
{
|
|
862
1256
|
name: 'get_entity_schema',
|
|
863
|
-
label: 'Get
|
|
864
|
-
description: 'Get the schema
|
|
1257
|
+
label: 'Get Entry Schema',
|
|
1258
|
+
description: 'Get the authoritative schema for an entry type. Returns each field with its type, whether it is optional, the description from the Zod schema, the full enum value list when applicable, and any default. Call this before writing enum-shaped fields (stage, status, category, priority, etc.) — the validator only accepts the values listed under `enum`.',
|
|
865
1259
|
parameters: T.Object({
|
|
866
1260
|
entityType: T.String({ description: 'Entity type' }),
|
|
867
1261
|
}),
|
|
868
1262
|
execute: async (toolCallId, params) => {
|
|
869
1263
|
try {
|
|
870
|
-
const
|
|
871
|
-
|
|
1264
|
+
const registry = workspaceManager.getSchemaRegistry();
|
|
1265
|
+
const knownTypes = new Set(registry.getAllTypes());
|
|
1266
|
+
if (!knownTypes.has(params.entityType)) {
|
|
872
1267
|
return wrapToolResult({
|
|
873
1268
|
success: false,
|
|
874
|
-
error: `Unknown entity type: ${params.entityType}`,
|
|
1269
|
+
error: `Unknown entity type: ${params.entityType}. Known types: ${[...knownTypes].sort().join(', ')}`,
|
|
875
1270
|
});
|
|
876
1271
|
}
|
|
877
|
-
|
|
878
|
-
const
|
|
879
|
-
const fields = {};
|
|
880
|
-
for (const [key, value] of Object.entries(shape)) {
|
|
881
|
-
const field = value;
|
|
882
|
-
fields[key] = {
|
|
883
|
-
type: field._def.typeName || 'unknown',
|
|
884
|
-
optional: field.isOptional() || false,
|
|
885
|
-
description: field._def.description || '',
|
|
886
|
-
};
|
|
887
|
-
}
|
|
1272
|
+
const schema = registry.getSchema(params.entityType);
|
|
1273
|
+
const fields = describeZodObject(schema);
|
|
888
1274
|
return wrapToolResult({
|
|
889
1275
|
success: true,
|
|
890
1276
|
entityType: params.entityType,
|
|
@@ -902,16 +1288,16 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
902
1288
|
// Lint entities
|
|
903
1289
|
{
|
|
904
1290
|
name: 'lint_entities',
|
|
905
|
-
label: 'Lint
|
|
906
|
-
description: 'Check for missing recommended fields across
|
|
1291
|
+
label: 'Lint Entries',
|
|
1292
|
+
description: 'Check for missing recommended fields across entries. Returns incomplete entries with their missing fields. Use to discover entries that need enrichment. Optionally filter by folder or entry type.',
|
|
907
1293
|
parameters: T.Object({
|
|
908
|
-
repo: T.Optional(T.String({ description: 'Optional: limit to specific
|
|
1294
|
+
repo: T.Optional(T.String({ description: 'Optional: limit to specific folder' })),
|
|
909
1295
|
entityType: T.Optional(T.String({ description: 'Optional: limit to specific entity type (e.g. "project", "deal")' })),
|
|
910
1296
|
}),
|
|
911
1297
|
execute: async (toolCallId, params) => {
|
|
912
1298
|
try {
|
|
913
1299
|
if (params.repo && !canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
914
|
-
return wrapToolResult({ success: false, error: `
|
|
1300
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
915
1301
|
}
|
|
916
1302
|
let issues = await lintWorkspace(workspaceManager, {
|
|
917
1303
|
repo: params.repo,
|
|
@@ -957,16 +1343,15 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
957
1343
|
{
|
|
958
1344
|
name: 'find_orphans',
|
|
959
1345
|
label: 'Find Orphans',
|
|
960
|
-
description: 'Find
|
|
1346
|
+
description: 'Find entries with zero inbound wikilink references.',
|
|
961
1347
|
parameters: T.Object({
|
|
962
1348
|
entityTypes: T.Optional(T.Array(T.String(), { description: 'Entity types to check (e.g. ["person", "client"])' })),
|
|
963
1349
|
minAgeDays: T.Optional(T.Number({ description: 'Only flag entities older than N days' })),
|
|
964
|
-
repos: T.Optional(T.Array(T.String(), { description: '
|
|
965
|
-
tombstone: T.Optional(T.Boolean({ description: 'Add orphans to sync-state tombstones' })),
|
|
1350
|
+
repos: T.Optional(T.Array(T.String(), { description: 'Folder names to scan (default: all)' })),
|
|
966
1351
|
}),
|
|
967
1352
|
execute: async (toolCallId, params) => {
|
|
968
1353
|
try {
|
|
969
|
-
// Scope to accessible
|
|
1354
|
+
// Scope to accessible folders
|
|
970
1355
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
971
1356
|
let repos = params.repos;
|
|
972
1357
|
if (allowed) {
|
|
@@ -977,13 +1362,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
977
1362
|
minAgeDays: params.minAgeDays,
|
|
978
1363
|
repos,
|
|
979
1364
|
});
|
|
980
|
-
// Tombstone if requested
|
|
981
|
-
if (params.tombstone && workspacePath && result.orphans.length > 0) {
|
|
982
|
-
const syncState = new SyncStateManager(workspacePath);
|
|
983
|
-
for (const orphan of result.orphans) {
|
|
984
|
-
syncState.addTombstone(orphan.entityId);
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
1365
|
// Group by type for summary
|
|
988
1366
|
const byType = {};
|
|
989
1367
|
for (const o of result.orphans) {
|
|
@@ -993,7 +1371,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
993
1371
|
success: true,
|
|
994
1372
|
totalScanned: result.totalScanned,
|
|
995
1373
|
totalOrphans: result.totalOrphans,
|
|
996
|
-
tombstoned: params.tombstone ? result.totalOrphans : 0,
|
|
997
1374
|
byType,
|
|
998
1375
|
orphans: result.orphans.slice(0, 50), // limit response size
|
|
999
1376
|
});
|
|
@@ -1009,8 +1386,8 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
1009
1386
|
// Highlight entities in graph view
|
|
1010
1387
|
{
|
|
1011
1388
|
name: 'highlight_entities',
|
|
1012
|
-
label: 'Highlight
|
|
1013
|
-
description: 'Highlight specific
|
|
1389
|
+
label: 'Highlight Entries',
|
|
1390
|
+
description: 'Highlight specific entries in the graph view. Pass entry IDs to highlight them (dimming all others). Pass an empty array to clear highlights.',
|
|
1014
1391
|
parameters: T.Object({
|
|
1015
1392
|
entityIds: T.Array(T.String(), { description: 'Entity IDs to highlight in the graph' }),
|
|
1016
1393
|
}),
|
|
@@ -1025,96 +1402,50 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
1025
1402
|
});
|
|
1026
1403
|
},
|
|
1027
1404
|
},
|
|
1028
|
-
//
|
|
1405
|
+
// Mark onboarding complete
|
|
1029
1406
|
{
|
|
1030
|
-
name: '
|
|
1031
|
-
label: '
|
|
1032
|
-
description: '
|
|
1407
|
+
name: 'mark_onboarded',
|
|
1408
|
+
label: 'Mark Onboarded',
|
|
1409
|
+
description: 'Mark the current user as onboarded. Call this when the interview/onboarding flow is complete.',
|
|
1033
1410
|
parameters: T.Object({}),
|
|
1034
|
-
execute: async () => {
|
|
1411
|
+
execute: async (_toolCallId) => {
|
|
1035
1412
|
if (!authSvc)
|
|
1036
1413
|
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1037
1414
|
const userId = getUser()?.id ?? 0;
|
|
1038
|
-
|
|
1039
|
-
return wrapToolResult({
|
|
1415
|
+
authSvc.setOnboarded(userId, true);
|
|
1416
|
+
return wrapToolResult({ success: true, message: 'User marked as onboarded.' });
|
|
1040
1417
|
},
|
|
1041
1418
|
},
|
|
1419
|
+
// Update workspace description (ABOUT.md)
|
|
1042
1420
|
{
|
|
1043
|
-
name: '
|
|
1044
|
-
label: '
|
|
1045
|
-
description: '
|
|
1421
|
+
name: 'update_workspace_about',
|
|
1422
|
+
label: 'Update Workspace Description',
|
|
1423
|
+
description: 'Write or update the workspace description (ABOUT.md). Use this to synthesize a description from the knowledge graph after onboarding, or when asked to sync the workspace description. The content should be a concise narrative covering the organization\'s identity, team, capabilities, and values — written in markdown.',
|
|
1046
1424
|
parameters: T.Object({
|
|
1047
|
-
|
|
1048
|
-
selectedType: T.Optional(T.String({ description: 'Entity type filter (e.g. "task", "project"). Omit for all types.' })),
|
|
1049
|
-
groupBy: T.Optional(T.String({ description: 'Column key to group by (e.g. "status", "priority")' })),
|
|
1425
|
+
content: T.String({ description: 'The full markdown content for the workspace description' }),
|
|
1050
1426
|
}),
|
|
1051
1427
|
execute: async (_toolCallId, params) => {
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
};
|
|
1062
|
-
const view = authSvc.createUserView(userId, params.name, 'list', config);
|
|
1063
|
-
return wrapToolResult({
|
|
1064
|
-
success: true,
|
|
1065
|
-
view: { id: view.id, name: view.name, viewType: view.viewType, config: view.config },
|
|
1066
|
-
message: `Created view "${params.name}". It will appear as a tab in the toolbar.`,
|
|
1067
|
-
});
|
|
1068
|
-
},
|
|
1069
|
-
},
|
|
1070
|
-
{
|
|
1071
|
-
name: 'update_view',
|
|
1072
|
-
label: 'Update View',
|
|
1073
|
-
description: 'Update an existing saved view\'s name or configuration.',
|
|
1074
|
-
parameters: T.Object({
|
|
1075
|
-
id: T.Number({ description: 'View ID' }),
|
|
1076
|
-
name: T.Optional(T.String({ description: 'New view name' })),
|
|
1077
|
-
selectedType: T.Optional(T.String({ description: 'Entity type filter (use "all" to clear)' })),
|
|
1078
|
-
groupBy: T.Optional(T.String({ description: 'Column key to group by (use "none" to clear)' })),
|
|
1079
|
-
}),
|
|
1080
|
-
execute: async (_toolCallId, params) => {
|
|
1081
|
-
if (!authSvc)
|
|
1082
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1083
|
-
const userId = getUser()?.id ?? 0;
|
|
1084
|
-
const existing = authSvc.getUserView(params.id, userId);
|
|
1085
|
-
if (!existing)
|
|
1086
|
-
return wrapToolResult({ success: false, error: `View ${params.id} not found` });
|
|
1087
|
-
const fields = {};
|
|
1088
|
-
if (params.name)
|
|
1089
|
-
fields.name = params.name;
|
|
1090
|
-
if (params.selectedType !== undefined || params.groupBy !== undefined) {
|
|
1091
|
-
const config = { ...existing.config };
|
|
1092
|
-
if (params.selectedType !== undefined)
|
|
1093
|
-
config.selectedType = params.selectedType === 'all' ? null : params.selectedType;
|
|
1094
|
-
if (params.groupBy !== undefined)
|
|
1095
|
-
config.groupBy = params.groupBy === 'none' ? null : params.groupBy;
|
|
1096
|
-
fields.config = config;
|
|
1428
|
+
try {
|
|
1429
|
+
const { Workspace } = await import('../../core/workspace.js');
|
|
1430
|
+
const workspace = new Workspace(workspacePath);
|
|
1431
|
+
workspace.writeAbout(params.content);
|
|
1432
|
+
onMutation?.({ action: 'updated', repo: '_workspace', entityType: '_workspace', entityId: 'about' });
|
|
1433
|
+
return wrapToolResult({ success: true, message: 'Workspace description updated.' });
|
|
1434
|
+
}
|
|
1435
|
+
catch (err) {
|
|
1436
|
+
return wrapToolResult({ success: false, error: err.message || 'Failed to write ABOUT.md' });
|
|
1097
1437
|
}
|
|
1098
|
-
authSvc.updateUserView(params.id, userId, fields);
|
|
1099
|
-
return wrapToolResult({ success: true, message: `Updated view "${existing.name}".` });
|
|
1100
1438
|
},
|
|
1101
1439
|
},
|
|
1440
|
+
// Reset conversation
|
|
1102
1441
|
{
|
|
1103
|
-
name: '
|
|
1104
|
-
label: '
|
|
1105
|
-
description: '
|
|
1106
|
-
parameters: T.Object({
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
if (!authSvc)
|
|
1111
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1112
|
-
const userId = getUser()?.id ?? 0;
|
|
1113
|
-
const existing = authSvc.getUserView(params.id, userId);
|
|
1114
|
-
if (!existing)
|
|
1115
|
-
return wrapToolResult({ success: false, error: `View ${params.id} not found` });
|
|
1116
|
-
authSvc.deleteUserView(params.id, userId);
|
|
1117
|
-
return wrapToolResult({ success: true, message: `Deleted view "${existing.name}".` });
|
|
1442
|
+
name: 'reset_conversation',
|
|
1443
|
+
label: 'Reset Conversation',
|
|
1444
|
+
description: 'Clear the current conversation and start fresh. Use when the user asks to "start over", "reset", "clear the chat", or "new conversation".',
|
|
1445
|
+
parameters: T.Object({}),
|
|
1446
|
+
execute: async (_toolCallId) => {
|
|
1447
|
+
onMutation?.({ action: 'deleted', repo: '_conversation', entityType: '_conversation', entityId: 'reset' });
|
|
1448
|
+
return wrapToolResult({ success: true, message: 'Conversation reset.' });
|
|
1118
1449
|
},
|
|
1119
1450
|
},
|
|
1120
1451
|
];
|