studiograph 1.3.48-next.13 → 1.3.48-next.130
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 +7 -7
- package/dist/agent/agent-pool.d.ts +14 -1
- package/dist/agent/agent-pool.js +37 -12
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/followups.d.ts +34 -0
- package/dist/agent/followups.js +52 -0
- package/dist/agent/followups.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +29 -2
- package/dist/agent/orchestrator.js +239 -38
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/entity-types-section.d.ts +30 -0
- package/dist/agent/prompts/entity-types-section.js +83 -0
- package/dist/agent/prompts/entity-types-section.js.map +1 -0
- package/dist/agent/prompts/system.md +106 -47
- 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 +79 -343
- package/dist/agent/skills/interview/entity-templates.md +38 -37
- package/dist/agent/skills/interview/question-domains.md +54 -49
- package/dist/agent/skills/interview/skill.md +89 -14
- package/dist/agent/tools/capture-tools.d.ts +31 -0
- package/dist/agent/tools/capture-tools.js +40 -0
- package/dist/agent/tools/capture-tools.js.map +1 -0
- package/dist/agent/tools/folder-tools.d.ts +47 -0
- package/dist/agent/tools/folder-tools.js +249 -0
- package/dist/agent/tools/folder-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +6 -5
- package/dist/agent/tools/fs-tools.js +5 -5
- package/dist/agent/tools/fs-tools.js.map +1 -1
- package/dist/agent/tools/graph-tools.d.ts +25 -72
- package/dist/agent/tools/graph-tools.js +362 -366
- 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/message-tools.d.ts +13 -11
- package/dist/agent/tools/message-tools.js +31 -39
- package/dist/agent/tools/message-tools.js.map +1 -1
- package/dist/agent/tools/ops-tools.d.ts +5 -4
- package/dist/agent/tools/ops-tools.js +99 -212
- package/dist/agent/tools/ops-tools.js.map +1 -1
- package/dist/agent/tools/permission-tools.d.ts +39 -16
- package/dist/agent/tools/permission-tools.js +66 -41
- 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/audit.d.ts +21 -0
- package/dist/cli/commands/audit.js +174 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/clear.d.ts +5 -0
- package/dist/cli/commands/clear.js +144 -1
- package/dist/cli/commands/clear.js.map +1 -1
- package/dist/cli/commands/clone.d.ts +1 -1
- package/dist/cli/commands/clone.js +47 -12
- package/dist/cli/commands/clone.js.map +1 -1
- package/dist/cli/commands/deploy.js +79 -18
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/folder.d.ts +11 -0
- package/dist/cli/commands/folder.js +186 -0
- package/dist/cli/commands/folder.js.map +1 -0
- package/dist/cli/commands/index.js +2 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.js +16 -14
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.d.ts +1 -1
- package/dist/cli/commands/join.js +26 -14
- package/dist/cli/commands/join.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/r2.d.ts +3 -0
- package/dist/cli/commands/r2.js +196 -1
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/redeploy.js +41 -1
- package/dist/cli/commands/redeploy.js.map +1 -1
- package/dist/cli/commands/secrets.d.ts +23 -0
- package/dist/cli/commands/secrets.js +256 -0
- package/dist/cli/commands/secrets.js.map +1 -0
- package/dist/cli/commands/serve.js +143 -24
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/start.js +140 -71
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +509 -163
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/user.js +8 -24
- package/dist/cli/commands/user.js.map +1 -1
- package/dist/cli/index.js +8 -7
- package/dist/cli/index.js.map +1 -1
- 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/scaffolding.d.ts +4 -2
- package/dist/cli/scaffolding.js +42 -47
- package/dist/cli/scaffolding.js.map +1 -1
- package/dist/cli/setup-wizard.d.ts +30 -49
- package/dist/cli/setup-wizard.js +35 -38
- 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/entity-body-templates.d.ts +21 -0
- package/dist/core/entity-body-templates.js +48 -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 +136 -0
- package/dist/core/entity-types-catalog.js.map +1 -0
- package/dist/core/feature-flags.d.ts +22 -0
- package/dist/core/feature-flags.js +15 -0
- package/dist/core/feature-flags.js.map +1 -0
- package/dist/core/features.d.ts +16 -0
- package/dist/core/features.js +48 -0
- package/dist/core/features.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 +16 -0
- package/dist/core/folder-sidecar.js +45 -0
- package/dist/core/folder-sidecar.js.map +1 -0
- package/dist/core/graph.d.ts +471 -19
- package/dist/core/graph.js +1411 -284
- package/dist/core/graph.js.map +1 -1
- package/dist/core/schema-registry.js +1 -19
- 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 +78 -0
- package/dist/core/secrets/SqliteEncryptedStore.js +581 -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 +76 -0
- package/dist/core/secrets/dual-write.js +236 -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/importer.d.ts +94 -0
- package/dist/core/secrets/importer.js +319 -0
- package/dist/core/secrets/importer.js.map +1 -0
- package/dist/core/secrets/index.d.ts +35 -0
- package/dist/core/secrets/index.js +59 -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/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/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 +539 -0
- package/dist/core/secrets/registry.js.map +1 -0
- package/dist/core/types.d.ts +70 -483
- package/dist/core/types.js +6 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +52 -12
- package/dist/core/user-config.js +119 -14
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +603 -1409
- package/dist/core/validation.js +248 -146
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +35 -14
- package/dist/core/workspace-manager.js +105 -56
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +19 -5
- package/dist/core/workspace.js +66 -39
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +16 -1
- package/dist/mcp/connector-manager.js +44 -5
- package/dist/mcp/connector-manager.js.map +1 -1
- 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/tools.d.ts +27 -2
- package/dist/mcp/tools.js +544 -113
- package/dist/mcp/tools.js.map +1 -1
- package/dist/server/__tests__/helpers/graph-api.d.ts +18 -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/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 +14 -3
- package/dist/server/index.js +388 -177
- 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.js +217 -65
- package/dist/server/routes/asset-api.js.map +1 -1
- package/dist/server/routes/audit-api.d.ts +24 -0
- package/dist/server/routes/audit-api.js +117 -0
- package/dist/server/routes/audit-api.js.map +1 -0
- package/dist/server/routes/auth-api.js +220 -44
- package/dist/server/routes/auth-api.js.map +1 -1
- package/dist/server/routes/capture-api.d.ts +10 -3
- package/dist/server/routes/capture-api.js +180 -24
- package/dist/server/routes/capture-api.js.map +1 -1
- package/dist/server/routes/chat.d.ts +4 -1
- package/dist/server/routes/chat.js +178 -46
- package/dist/server/routes/chat.js.map +1 -1
- 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.js +24 -18
- package/dist/server/routes/connectors-api.js.map +1 -1
- package/dist/server/routes/event-ingest-api.d.ts +15 -0
- package/dist/server/routes/event-ingest-api.js +125 -0
- package/dist/server/routes/event-ingest-api.js.map +1 -0
- package/dist/server/routes/features-api.d.ts +19 -0
- package/dist/server/routes/features-api.js +28 -0
- package/dist/server/routes/features-api.js.map +1 -0
- package/dist/server/routes/git-http.d.ts +2 -2
- package/dist/server/routes/git-http.js +69 -34
- package/dist/server/routes/git-http.js.map +1 -1
- package/dist/server/routes/graph-api-access.d.ts +35 -0
- package/dist/server/routes/graph-api-access.js +93 -0
- package/dist/server/routes/graph-api-access.js.map +1 -0
- package/dist/server/routes/graph-api.d.ts +3 -2
- package/dist/server/routes/graph-api.js +1014 -315
- 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/insights-api.js +156 -33
- package/dist/server/routes/insights-api.js.map +1 -1
- package/dist/server/routes/mcp.d.ts +6 -3
- package/dist/server/routes/mcp.js +22 -6
- package/dist/server/routes/mcp.js.map +1 -1
- package/dist/server/routes/messages-api.d.ts +3 -3
- package/dist/server/routes/messages-api.js +308 -120
- package/dist/server/routes/messages-api.js.map +1 -1
- package/dist/server/routes/permissions-api.d.ts +9 -2
- package/dist/server/routes/permissions-api.js +87 -31
- package/dist/server/routes/permissions-api.js.map +1 -1
- package/dist/server/routes/secrets-api.d.ts +36 -0
- package/dist/server/routes/secrets-api.js +303 -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 +177 -0
- package/dist/server/routes/settings-api.js.map +1 -0
- package/dist/server/routes/workspace-api.d.ts +2 -1
- package/dist/server/routes/workspace-api.js +131 -20
- package/dist/server/routes/workspace-api.js.map +1 -1
- package/dist/server/routes/ws.d.ts +3 -2
- package/dist/server/routes/ws.js +68 -18
- package/dist/server/routes/ws.js.map +1 -1
- package/dist/server/session-manager.d.ts +48 -5
- package/dist/server/session-manager.js +175 -11
- package/dist/server/session-manager.js.map +1 -1
- package/dist/server/ws-hub.d.ts +134 -22
- package/dist/server/ws-hub.js +0 -0
- package/dist/server/ws-hub.js.map +1 -1
- package/dist/server/yjs-manager.d.ts +107 -7
- package/dist/server/yjs-manager.js +444 -38
- package/dist/server/yjs-manager.js.map +1 -1
- package/dist/server/yjs-persistence.d.ts +143 -0
- package/dist/server/yjs-persistence.js +543 -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 +53 -0
- package/dist/services/access-control.js +132 -0
- package/dist/services/access-control.js.map +1 -0
- package/dist/services/asset-upload-service.d.ts +53 -0
- package/dist/services/asset-upload-service.js +200 -0
- package/dist/services/asset-upload-service.js.map +1 -0
- package/dist/services/assets/base.d.ts +38 -0
- package/dist/services/assets/base.js +55 -0
- package/dist/services/assets/base.js.map +1 -1
- package/dist/services/assets/index.d.ts +41 -1
- package/dist/services/assets/index.js +65 -0
- package/dist/services/assets/index.js.map +1 -1
- package/dist/services/assets/local.d.ts +7 -1
- package/dist/services/assets/local.js +83 -0
- package/dist/services/assets/local.js.map +1 -1
- package/dist/services/assets/r2.d.ts +28 -1
- package/dist/services/assets/r2.js +75 -1
- package/dist/services/assets/r2.js.map +1 -1
- package/dist/services/auth-service.d.ts +184 -36
- package/dist/services/auth-service.js +763 -138
- package/dist/services/auth-service.js.map +1 -1
- package/dist/services/briefing.d.ts +1 -1
- package/dist/services/briefing.js +12 -35
- package/dist/services/briefing.js.map +1 -1
- package/dist/services/event-processor.d.ts +104 -0
- package/dist/services/event-processor.js +443 -0
- package/dist/services/event-processor.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 +44 -0
- package/dist/services/git.js +162 -55
- package/dist/services/git.js.map +1 -1
- package/dist/services/heartbeat.d.ts +19 -12
- package/dist/services/heartbeat.js +162 -107
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/import-service.d.ts +37 -2
- package/dist/services/import-service.js +222 -123
- package/dist/services/import-service.js.map +1 -1
- package/dist/services/lint-service.js +7 -14
- package/dist/services/lint-service.js.map +1 -1
- package/dist/services/markdown.js +6 -2
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/message-service.d.ts +62 -21
- package/dist/services/message-service.js +160 -43
- package/dist/services/message-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/vector-service.d.ts +73 -3
- package/dist/services/vector-service.js +106 -7
- package/dist/services/vector-service.js.map +1 -1
- package/dist/services/workspace-access.d.ts +106 -0
- package/dist/services/workspace-access.js +149 -0
- package/dist/services/workspace-access.js.map +1 -0
- package/dist/utils/git.js +3 -3
- 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 +4 -1
- package/dist/utils/version-checker.js +8 -8
- package/dist/utils/version-checker.js.map +1 -1
- package/dist/web/_app/immutable/assets/0.Bp6xXZUi.css +2 -0
- package/dist/web/_app/immutable/assets/11.DlIf1mKh.css +1 -0
- package/dist/web/_app/immutable/assets/12.Dmlt28l2.css +1 -0
- package/dist/web/_app/immutable/assets/13.CmLrbzZp.css +1 -0
- package/dist/web/_app/immutable/assets/2.oo1ac0x_.css +1 -0
- package/dist/web/_app/immutable/assets/3.DJJsQzDb.css +1 -0
- package/dist/web/_app/immutable/assets/4.CZ-fNJ91.css +1 -0
- package/dist/web/_app/immutable/assets/AgentOverlay.BfWESlQU.css +1 -0
- package/dist/web/_app/immutable/assets/AssetManagerModal.ZfasE2L3.css +1 -0
- package/dist/web/_app/immutable/assets/CalendarView.CeNagvyK.css +1 -0
- package/dist/web/_app/immutable/assets/ChatPanel.po0gYtVH.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMembersPanel.Bepw-r0F.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
- package/dist/web/_app/immutable/assets/FolderPicker.B5KdvRYl.css +1 -0
- package/dist/web/_app/immutable/assets/GalleryView.Dy-qQjEc.css +1 -0
- package/dist/web/_app/immutable/assets/GraphView.BHnGIltS.css +1 -0
- package/dist/web/_app/immutable/assets/KanbanView.G3NZ0uHb.css +1 -0
- package/dist/web/_app/immutable/assets/SettingsDialog.tBn8y9DD.css +1 -0
- package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
- package/dist/web/_app/immutable/assets/TagFilter.DNipjifq.css +1 -0
- package/dist/web/_app/immutable/assets/TagPickerSheet.DJPuqnTg.css +1 -0
- package/dist/web/_app/immutable/assets/WorkspaceView.B9zA92UB.css +1 -0
- package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
- package/dist/web/_app/immutable/assets/dialog.BxVal_19.css +1 -0
- package/dist/web/_app/immutable/assets/dist.B5hGjnfj.css +1 -0
- package/dist/web/_app/immutable/assets/dist.DDCWxn3B.css +1 -0
- package/dist/web/_app/immutable/assets/dropdown-menu.BSsUUQ3o.css +1 -0
- package/dist/web/_app/immutable/assets/entity-row.Bl5FyNCt.css +1 -0
- package/dist/web/_app/immutable/assets/greeting.Bm7lTneV.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.DORLo4xF.css +1 -0
- package/dist/web/_app/immutable/assets/notifications.clodJdp5.css +1 -0
- package/dist/web/_app/immutable/assets/radio-group.GJJRVPUJ.css +1 -0
- package/dist/web/_app/immutable/assets/select.D_AV992j.css +1 -0
- package/dist/web/_app/immutable/chunks/-KAQXGuI2.js +1 -0
- package/dist/web/_app/immutable/chunks/-wzwcH00.js +1 -0
- package/dist/web/_app/immutable/chunks/07l_1Zpm2.js +1 -0
- package/dist/web/_app/immutable/chunks/1i1V0Z172.js +2 -0
- package/dist/web/_app/immutable/chunks/38oWKNzM2.js +6 -0
- package/dist/web/_app/immutable/chunks/54VmiJfH.js +1 -0
- package/dist/web/_app/immutable/chunks/6LRpFvjo.js +185 -0
- package/dist/web/_app/immutable/chunks/9bCTHkeS.js +1 -0
- package/dist/web/_app/immutable/chunks/B-822WnD2.js +22 -0
- package/dist/web/_app/immutable/chunks/B0HUvliX2.js +2 -0
- package/dist/web/_app/immutable/chunks/B12eXGpE.js +1 -0
- package/dist/web/_app/immutable/chunks/B2-Cx5XA.js +1 -0
- package/dist/web/_app/immutable/chunks/B5af0X0p2.js +1 -0
- package/dist/web/_app/immutable/chunks/B6iYNwo72.js +1 -0
- package/dist/web/_app/immutable/chunks/B7EMtoAB.js +1 -0
- package/dist/web/_app/immutable/chunks/B9qBGxh62.js +3 -0
- package/dist/web/_app/immutable/chunks/B9rVXblv.js +1 -0
- package/dist/web/_app/immutable/chunks/BEpMEjHO.js +1 -0
- package/dist/web/_app/immutable/chunks/BErNpj-S2.js +1 -0
- package/dist/web/_app/immutable/chunks/BHBk4zfV.js +1 -0
- package/dist/web/_app/immutable/chunks/BHH-JGNF.js +1 -0
- package/dist/web/_app/immutable/chunks/BNTlsKDJ.js +1 -0
- package/dist/web/_app/immutable/chunks/BOgcXgis2.js +1 -0
- package/dist/web/_app/immutable/chunks/BOyyDrjn2.js +1 -0
- package/dist/web/_app/immutable/chunks/BPR_ufQ0.js +41 -0
- package/dist/web/_app/immutable/chunks/BRcFsc6v.js +5 -0
- package/dist/web/_app/immutable/chunks/BT3KAag_.js +3 -0
- package/dist/web/_app/immutable/chunks/BX2T6xiZ.js +224 -0
- package/dist/web/_app/immutable/chunks/BZnJ8tbJ.js +1 -0
- package/dist/web/_app/immutable/chunks/Ba1Yzb7u.js +1 -0
- package/dist/web/_app/immutable/chunks/BcsvgA3B2.js +1 -0
- package/dist/web/_app/immutable/chunks/BfbS7rGT.js +1 -0
- package/dist/web/_app/immutable/chunks/BgagL41Z.js +1 -0
- package/dist/web/_app/immutable/chunks/Bk-AcswV.js +1 -0
- package/dist/web/_app/immutable/chunks/Bl9Pzopy.js +1 -0
- package/dist/web/_app/immutable/chunks/BmcU05mO.js +1 -0
- package/dist/web/_app/immutable/chunks/Bmgp0jlT.js +1 -0
- package/dist/web/_app/immutable/chunks/BpDONXUo.js +8 -0
- package/dist/web/_app/immutable/chunks/BpTXLx8I2.js +5 -0
- package/dist/web/_app/immutable/chunks/Bq0-jBGC2.js +1 -0
- package/dist/web/_app/immutable/chunks/BqGj0_GS.js +1 -0
- package/dist/web/_app/immutable/chunks/Bsc9K3Pz.js +1 -0
- package/dist/web/_app/immutable/chunks/Bssb691Q.js +1 -0
- package/dist/web/_app/immutable/chunks/BuzQceOn.js +1 -0
- package/dist/web/_app/immutable/chunks/BzeVNab0.js +1 -0
- package/dist/web/_app/immutable/chunks/C-OaypFN.js +1 -0
- package/dist/web/_app/immutable/chunks/C0fjDjvE2.js +1 -0
- package/dist/web/_app/immutable/chunks/C0pTXwEX.js +2 -0
- package/dist/web/_app/immutable/chunks/C3Enww9L2.js +1 -0
- package/dist/web/_app/immutable/chunks/C3oa0Cks.js +1 -0
- package/dist/web/_app/immutable/chunks/C7GIvT8T.js +2 -0
- package/dist/web/_app/immutable/chunks/CC-YWp-f.js +1 -0
- package/dist/web/_app/immutable/chunks/CGdKvXV92.js +1 -0
- package/dist/web/_app/immutable/chunks/CH0siYFL.js +1 -0
- package/dist/web/_app/immutable/chunks/CIc2MMme2.js +1 -0
- package/dist/web/_app/immutable/chunks/CIchr8Tk2.js +1 -0
- package/dist/web/_app/immutable/chunks/CK_yXDQI.js +1 -0
- package/dist/web/_app/immutable/chunks/CLSxJmTj.js +2 -0
- package/dist/web/_app/immutable/chunks/CMhHc1Bq2.js +2 -0
- package/dist/web/_app/immutable/chunks/CNGba6T4.js +1 -0
- package/dist/web/_app/immutable/chunks/CPt2D5aU.js +1 -0
- package/dist/web/_app/immutable/chunks/CQ-2yccd.js +7 -0
- package/dist/web/_app/immutable/chunks/CS6VEwn7.js +1 -0
- package/dist/web/_app/immutable/chunks/CSsDOIrk.js +1 -0
- package/dist/web/_app/immutable/chunks/CVXvEWhv2.js +1 -0
- package/dist/web/_app/immutable/chunks/CaChtuYU2.js +1 -0
- package/dist/web/_app/immutable/chunks/CbiwvM3R2.js +1 -0
- package/dist/web/_app/immutable/chunks/CdCuBMLm.js +156 -0
- package/dist/web/_app/immutable/chunks/CiyqPsJo.js +1 -0
- package/dist/web/_app/immutable/chunks/CjGzUnEF2.js +1 -0
- package/dist/web/_app/immutable/chunks/Cjgbiel7.js +1 -0
- package/dist/web/_app/immutable/chunks/CnqSKqA62.js +1 -0
- package/dist/web/_app/immutable/chunks/CqyqKPuh2.js +1 -0
- package/dist/web/_app/immutable/chunks/CrnX-oFV.js +1 -0
- package/dist/web/_app/immutable/chunks/CsGahE3a.js +1 -0
- package/dist/web/_app/immutable/chunks/Ct3quP0F.js +1 -0
- package/dist/web/_app/immutable/chunks/CtlAYPxw.js +1 -0
- package/dist/web/_app/immutable/chunks/CvZaxjRC.js +1 -0
- package/dist/web/_app/immutable/chunks/CwD4G56R.js +5 -0
- package/dist/web/_app/immutable/chunks/CwROuREs.js +1 -0
- package/dist/web/_app/immutable/chunks/CxalqrMB.js +1 -0
- package/dist/web/_app/immutable/chunks/D7qgUfnr.js +2487 -0
- package/dist/web/_app/immutable/chunks/D9-_Euza2.js +1 -0
- package/dist/web/_app/immutable/chunks/DC69SASj.js +2 -0
- package/dist/web/_app/immutable/chunks/DCCaoKt42.js +1 -0
- package/dist/web/_app/immutable/chunks/DDKweOZr2.js +23 -0
- package/dist/web/_app/immutable/chunks/DEY60osH.js +1 -0
- package/dist/web/_app/immutable/chunks/DG3QZPgI.js +1 -0
- package/dist/web/_app/immutable/chunks/DHepUItL.js +1 -0
- package/dist/web/_app/immutable/chunks/DNtqqgv32.js +1 -0
- package/dist/web/_app/immutable/chunks/DRl7vwNC2.js +184 -0
- package/dist/web/_app/immutable/chunks/DTc5W_V6.js +1 -0
- package/dist/web/_app/immutable/chunks/DaiJs3St.js +1 -0
- package/dist/web/_app/immutable/chunks/DfITyMKh2.js +1 -0
- package/dist/web/_app/immutable/chunks/DhuJRrEX2.js +1 -0
- package/dist/web/_app/immutable/chunks/DiP2EplP.js +3 -0
- package/dist/web/_app/immutable/chunks/DjlDV2JG.js +1 -0
- package/dist/web/_app/immutable/chunks/Dm25ot5x2.js +1 -0
- package/dist/web/_app/immutable/chunks/DpuSt-SO.js +2 -0
- package/dist/web/_app/immutable/chunks/DqOcb9RX2.js +83 -0
- package/dist/web/_app/immutable/chunks/DrbUJCAE.js +1 -0
- package/dist/web/_app/immutable/chunks/Du2-B3c8.js +1 -0
- package/dist/web/_app/immutable/chunks/DwdkE4UD2.js +1 -0
- package/dist/web/_app/immutable/chunks/DxWesPbn.js +1 -0
- package/dist/web/_app/immutable/chunks/DyYZqUV72.js +1 -0
- package/dist/web/_app/immutable/chunks/HfUnhvrv2.js +1 -0
- package/dist/web/_app/immutable/chunks/Je8-BtCk2.js +1 -0
- package/dist/web/_app/immutable/chunks/MSB7eA4_.js +1 -0
- package/dist/web/_app/immutable/chunks/NPe9WyW1.js +1 -0
- package/dist/web/_app/immutable/chunks/O6IzcxXJ.js +2 -0
- package/dist/web/_app/immutable/chunks/SXhc9rJW.js +1 -0
- package/dist/web/_app/immutable/chunks/SbWhkPMt.js +6 -0
- package/dist/web/_app/immutable/chunks/U40J2SnU.js +1 -0
- package/dist/web/_app/immutable/chunks/VS3l21Gu.js +1 -0
- package/dist/web/_app/immutable/chunks/YEPEvlbU2.js +1 -0
- package/dist/web/_app/immutable/chunks/Z7TNRcgK.js +11 -0
- package/dist/web/_app/immutable/chunks/ZCekGjo6.js +5 -0
- package/dist/web/_app/immutable/chunks/_rnxQ655.js +4 -0
- package/dist/web/_app/immutable/chunks/aALpjBW2.js +1 -0
- package/dist/web/_app/immutable/chunks/gNXLhsdy.js +1 -0
- package/dist/web/_app/immutable/chunks/hKSTEN36.js +1 -0
- package/dist/web/_app/immutable/chunks/jZZTbzL5.js +1 -0
- package/dist/web/_app/immutable/chunks/l4FIBKss.js +1 -0
- package/dist/web/_app/immutable/chunks/l_4snZnh2.js +1 -0
- package/dist/web/_app/immutable/chunks/mz-cgRgP.js +3 -0
- package/dist/web/_app/immutable/chunks/qgprkMcL.js +1 -0
- package/dist/web/_app/immutable/chunks/rOisBLC62.js +14 -0
- package/dist/web/_app/immutable/chunks/t08TznXc2.js +1 -0
- package/dist/web/_app/immutable/chunks/t62M88qj.js +1 -0
- package/dist/web/_app/immutable/chunks/uCohGWC42.js +1 -0
- package/dist/web/_app/immutable/chunks/uqxmB78b.js +1 -0
- package/dist/web/_app/immutable/chunks/vJkT0IPN.js +1 -0
- package/dist/web/_app/immutable/chunks/vwTMEIJQ.js +1 -0
- package/dist/web/_app/immutable/chunks/w1FCELam.js +64 -0
- package/dist/web/_app/immutable/chunks/xEzUlKaR2.js +1 -0
- package/dist/web/_app/immutable/chunks/zumDjcgJ.js +1 -0
- package/dist/web/_app/immutable/entry/app.DtdPIxaY.js +2 -0
- package/dist/web/_app/immutable/entry/start.Cqf8YmDj.js +1 -0
- package/dist/web/_app/immutable/nodes/0.CktqlAe7.js +2 -0
- package/dist/web/_app/immutable/nodes/1.Bs7cz_ba.js +1 -0
- package/dist/web/_app/immutable/nodes/10.CAQtOBqO.js +1 -0
- package/dist/web/_app/immutable/nodes/11.l9TQGnJm.js +1 -0
- package/dist/web/_app/immutable/nodes/12.CttDoIpY.js +1 -0
- package/dist/web/_app/immutable/nodes/13.E5fh69kS.js +1 -0
- package/dist/web/_app/immutable/nodes/2.DnLSJfx-.js +106 -0
- package/dist/web/_app/immutable/nodes/3.Bw8R0Jw5.js +2 -0
- package/dist/web/_app/immutable/nodes/4.Cl0HgeTG.js +2 -0
- package/dist/web/_app/immutable/nodes/5.BpIWwWi9.js +1 -0
- package/dist/web/_app/immutable/nodes/6.jpx6ZgOI.js +1 -0
- package/dist/web/_app/immutable/nodes/7.YTFykZQe.js +1 -0
- package/dist/web/_app/immutable/nodes/8.Chy0HNU1.js +1 -0
- package/dist/web/_app/immutable/nodes/9.D10JpFt2.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 +64 -21
- package/dist/web/studiograph-logomark.svg +29 -0
- package/package.json +28 -14
- package/dist/agent/role-loader.d.ts +0 -24
- package/dist/agent/role-loader.js +0 -67
- package/dist/agent/role-loader.js.map +0 -1
- 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/collection.d.ts +0 -10
- package/dist/cli/commands/collection.js +0 -185
- 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/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/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/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 -8
- package/dist/integrations/registry.js +0 -7
- package/dist/integrations/registry.js.map +0 -1
- package/dist/integrations/types.d.ts +0 -43
- package/dist/integrations/types.js +0 -5
- package/dist/integrations/types.js.map +0 -1
- package/dist/lib/lib/utils.d.ts +0 -2
- package/dist/lib/lib/utils.js +0 -6
- package/dist/lib/lib/utils.js.map +0 -1
- package/dist/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/agents/agent-loader.d.ts +0 -16
- package/dist/server/agents/agent-loader.js +0 -175
- package/dist/server/agents/agent-loader.js.map +0 -1
- package/dist/server/agents/agent-runner.d.ts +0 -33
- package/dist/server/agents/agent-runner.js +0 -187
- package/dist/server/agents/agent-runner.js.map +0 -1
- package/dist/server/agents/agent-runtime.d.ts +0 -39
- package/dist/server/agents/agent-runtime.js +0 -214
- package/dist/server/agents/agent-runtime.js.map +0 -1
- package/dist/server/agents/base-agent.d.ts +0 -30
- package/dist/server/agents/base-agent.js +0 -88
- package/dist/server/agents/base-agent.js.map +0 -1
- package/dist/server/agents/executive-digest.d.ts +0 -16
- package/dist/server/agents/executive-digest.js +0 -115
- package/dist/server/agents/executive-digest.js.map +0 -1
- package/dist/server/agents/graph-steward.d.ts +0 -16
- package/dist/server/agents/graph-steward.js +0 -59
- package/dist/server/agents/graph-steward.js.map +0 -1
- package/dist/server/agents/meeting-followup.d.ts +0 -16
- package/dist/server/agents/meeting-followup.js +0 -88
- package/dist/server/agents/meeting-followup.js.map +0 -1
- package/dist/server/agents/pipeline-monitor.d.ts +0 -15
- package/dist/server/agents/pipeline-monitor.js +0 -86
- package/dist/server/agents/pipeline-monitor.js.map +0 -1
- package/dist/server/agents/types.d.ts +0 -81
- package/dist/server/agents/types.js +0 -41
- package/dist/server/agents/types.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/agents-api.d.ts +0 -10
- package/dist/server/routes/agents-api.js +0 -25
- package/dist/server/routes/agents-api.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 -14
- package/dist/server/routes/meeting-ingest-api.js +0 -98
- 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 -848
- 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/batch-processor.d.ts +0 -49
- package/dist/services/batch-processor.js +0 -166
- package/dist/services/batch-processor.js.map +0 -1
- package/dist/services/csv-service.d.ts +0 -36
- package/dist/services/csv-service.js +0 -143
- package/dist/services/csv-service.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/image-import-service.d.ts +0 -24
- package/dist/services/image-import-service.js +0 -108
- package/dist/services/image-import-service.js.map +0 -1
- package/dist/services/insights.d.ts +0 -38
- package/dist/services/insights.js +0 -269
- package/dist/services/insights.js.map +0 -1
- package/dist/services/meeting-processor.d.ts +0 -91
- package/dist/services/meeting-processor.js +0 -331
- package/dist/services/meeting-processor.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.QUqBcyuu.css +0 -1
- package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
- package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
- package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
- package/dist/web/_app/immutable/assets/2.5jNm7Pm1.css +0 -1
- package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
- package/dist/web/_app/immutable/assets/4.BjPwtpNd.css +0 -1
- package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
- package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
- package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
- package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
- package/dist/web/_app/immutable/assets/ViewToolbar.CZjsdjy4.css +0 -1
- package/dist/web/_app/immutable/assets/WorkspaceView.B-1DbivC.css +0 -1
- package/dist/web/_app/immutable/assets/wikilinks.CtSydmQl.css +0 -1
- package/dist/web/_app/immutable/chunks/3--t-YNA.js +0 -1
- package/dist/web/_app/immutable/chunks/5OU-4caN.js +0 -1
- package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
- package/dist/web/_app/immutable/chunks/B6FUcAv5.js +0 -1
- package/dist/web/_app/immutable/chunks/B9gDgSlp.js +0 -1
- package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
- package/dist/web/_app/immutable/chunks/BFtIWl5z.js +0 -1
- package/dist/web/_app/immutable/chunks/BHKpz6_7.js +0 -1
- package/dist/web/_app/immutable/chunks/BNfrhBeA.js +0 -1
- package/dist/web/_app/immutable/chunks/BgO5HlCg.js +0 -2
- package/dist/web/_app/immutable/chunks/BqnODQDb.js +0 -1
- package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
- package/dist/web/_app/immutable/chunks/BvIFhEn7.js +0 -2
- package/dist/web/_app/immutable/chunks/BvfdTHv8.js +0 -1
- package/dist/web/_app/immutable/chunks/BxGm65PH.js +0 -1
- package/dist/web/_app/immutable/chunks/BxyxnEKw.js +0 -1
- package/dist/web/_app/immutable/chunks/BygFIGq4.js +0 -1
- package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
- package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
- package/dist/web/_app/immutable/chunks/CIb_hHMy.js +0 -1
- package/dist/web/_app/immutable/chunks/CNKK6nZb.js +0 -1
- package/dist/web/_app/immutable/chunks/CQ5FjHZK.js +0 -1
- package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
- 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/CaEaeeKb.js +0 -1
- package/dist/web/_app/immutable/chunks/Ch6e_wpP.js +0 -1
- package/dist/web/_app/immutable/chunks/Ci4zzCVB.js +0 -2
- package/dist/web/_app/immutable/chunks/CknqBVQE.js +0 -1
- package/dist/web/_app/immutable/chunks/Cmfiirqp.js +0 -4
- package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
- package/dist/web/_app/immutable/chunks/CrFpCC6p.js +0 -1
- package/dist/web/_app/immutable/chunks/CxX8hcT6.js +0 -1
- package/dist/web/_app/immutable/chunks/D0T1ps1G.js +0 -1
- package/dist/web/_app/immutable/chunks/D2ZEj9xD.js +0 -1
- package/dist/web/_app/immutable/chunks/D3sy0IkA.js +0 -2
- package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
- package/dist/web/_app/immutable/chunks/DHWoAC4y.js +0 -1
- package/dist/web/_app/immutable/chunks/DYYBfXU3.js +0 -1
- package/dist/web/_app/immutable/chunks/DiNPRA8T.js +0 -1
- package/dist/web/_app/immutable/chunks/DkjsqHkM.js +0 -1
- package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
- package/dist/web/_app/immutable/chunks/DpMCynC3.js +0 -1
- package/dist/web/_app/immutable/chunks/DqrybUuA.js +0 -1
- package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
- package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
- package/dist/web/_app/immutable/chunks/O9MAeAgV.js +0 -5
- package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
- package/dist/web/_app/immutable/chunks/SKSQ4m85.js +0 -2
- package/dist/web/_app/immutable/chunks/WEBTyD-H.js +0 -1
- package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
- package/dist/web/_app/immutable/chunks/bBXT5iJP.js +0 -1
- package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
- package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
- package/dist/web/_app/immutable/chunks/xkNhbnff.js +0 -1
- package/dist/web/_app/immutable/chunks/zoVX1Zab.js +0 -1
- package/dist/web/_app/immutable/entry/app.GfE4z2GO.js +0 -2
- package/dist/web/_app/immutable/entry/start.H-LFJK9u.js +0 -1
- package/dist/web/_app/immutable/nodes/0.Bwi7tTNC.js +0 -2
- package/dist/web/_app/immutable/nodes/1.DgNJPEWk.js +0 -1
- package/dist/web/_app/immutable/nodes/10.BW_XCD2O.js +0 -1
- package/dist/web/_app/immutable/nodes/11.DM7RX3Ms.js +0 -1
- package/dist/web/_app/immutable/nodes/12.DKgssZo8.js +0 -1
- package/dist/web/_app/immutable/nodes/13.DCdmTre-.js +0 -1
- package/dist/web/_app/immutable/nodes/2.DOA5QBVG.js +0 -266
- package/dist/web/_app/immutable/nodes/3.bpoHQwAI.js +0 -5
- package/dist/web/_app/immutable/nodes/4.ye0Vy7A1.js +0 -11
- package/dist/web/_app/immutable/nodes/5.rxpnYrx_.js +0 -4
- package/dist/web/_app/immutable/nodes/6.DP8HSxtc.js +0 -1
- package/dist/web/_app/immutable/nodes/7.C1h4Bf-E.js +0 -1
- package/dist/web/_app/immutable/nodes/8.BzmQ7S7Y.js +0 -1
- package/dist/web/_app/immutable/nodes/9.CEakpXpF.js +0 -1
|
@@ -7,11 +7,13 @@
|
|
|
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
12
|
import { lintWorkspace } from '../../services/lint-service.js';
|
|
13
13
|
import { findOrphans } from '../../services/orphan-service.js';
|
|
14
|
-
import
|
|
14
|
+
import * as access from '../../services/access-control.js';
|
|
15
|
+
import { isCuratedEntityType } from '../../core/entity-types-catalog.js';
|
|
16
|
+
import { getAgentAllowedEntityTypes } from '../prompts/entity-types-section.js';
|
|
15
17
|
/**
|
|
16
18
|
* Helper to wrap tool results in AgentToolResult format
|
|
17
19
|
*/
|
|
@@ -31,139 +33,229 @@ function cleanData(data) {
|
|
|
31
33
|
return rest;
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
36
|
+
* Undo JSON-string escapes that sometimes leak into content when the LLM
|
|
37
|
+
* serializes markdown as a quoted string instead of raw text. Handles `\n`,
|
|
38
|
+
* `\t`, `\r`, `\"`, `\\` in a single pass so escape sequences aren't
|
|
39
|
+
* re-processed. Also strips stray surrounding quotes from a fully-quoted
|
|
40
|
+
* payload.
|
|
37
41
|
*/
|
|
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 (isAdminOrOwner(user.role))
|
|
54
|
-
return null;
|
|
55
|
-
return 'This operation requires admin access.';
|
|
42
|
+
function sanitizeLlmContent(content) {
|
|
43
|
+
if (!content)
|
|
44
|
+
return '';
|
|
45
|
+
const unescaped = content.replace(/\\([ntr"\\])/g, (_, c) => {
|
|
46
|
+
if (c === 'n')
|
|
47
|
+
return '\n';
|
|
48
|
+
if (c === 't')
|
|
49
|
+
return '\t';
|
|
50
|
+
if (c === 'r')
|
|
51
|
+
return '\r';
|
|
52
|
+
return c;
|
|
53
|
+
});
|
|
54
|
+
return unescaped.replace(/^"+|"+$/g, '');
|
|
56
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Per-request user context for folder access filtering.
|
|
58
|
+
* When getCurrentUser returns a user, tools filter results to only
|
|
59
|
+
* folders the user is a member of (via folder_access).
|
|
60
|
+
*/
|
|
57
61
|
function getAccessibleRepoNames(workspaceManager, getCurrentUser, authService) {
|
|
58
62
|
const user = getCurrentUser();
|
|
59
63
|
if (!user)
|
|
60
64
|
return null; // API key / open mode → no filtering
|
|
61
65
|
if (!authService)
|
|
62
66
|
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));
|
|
67
|
+
// Delegate to the shared helper so personal-folder restrictions and
|
|
68
|
+
// owner-on-shared-folder semantics apply consistently with the HTTP layer.
|
|
69
|
+
return new Set(access.getAccessibleRepos(user, workspaceManager, authService).map(r => r.name));
|
|
75
70
|
}
|
|
76
71
|
function canAccessRepo(repoName, workspaceManager, getCurrentUser, authService) {
|
|
77
72
|
const user = getCurrentUser();
|
|
78
|
-
const repoConfig = workspaceManager.getRepoConfig(repoName);
|
|
79
|
-
if (!canSeePrivateRepo(repoConfig, user))
|
|
80
|
-
return false;
|
|
81
73
|
if (!user)
|
|
82
74
|
return true;
|
|
83
|
-
if (repoConfig?.private && repoConfig?.owner_id === user.id)
|
|
84
|
-
return true;
|
|
85
|
-
if (isAdminOrOwner(user.role))
|
|
86
|
-
return true;
|
|
87
75
|
if (!authService)
|
|
88
76
|
return true;
|
|
89
|
-
return
|
|
77
|
+
return access.hasRepoAccess(user, repoName, workspaceManager, authService);
|
|
90
78
|
}
|
|
91
|
-
export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService
|
|
79
|
+
export function createGraphTools(workspaceManager, gitUser, workspacePath, onHighlight, onMutation, getCurrentUser, authService,
|
|
80
|
+
/**
|
|
81
|
+
* Called after an entity's content is written to disk (create/update), so
|
|
82
|
+
* callers can push the new content into any active Y.Doc. Without this,
|
|
83
|
+
* agent edits bypass live editors and cause CRDT duplication on resync.
|
|
84
|
+
*/
|
|
85
|
+
onContentSync,
|
|
86
|
+
/**
|
|
87
|
+
* Called at the start (`enter`) and end (`leave`) of any mutation tool
|
|
88
|
+
* call. Surfaces the active-agent chip in the sidebar via the WS hub. The
|
|
89
|
+
* orchestrator wires this through to wsHub.handleAgentActivity.
|
|
90
|
+
*/
|
|
91
|
+
onAgentActivity) {
|
|
92
92
|
const getUser = getCurrentUser ?? (() => null);
|
|
93
93
|
const authSvc = authService ?? null;
|
|
94
|
-
/**
|
|
94
|
+
/**
|
|
95
|
+
* Resolve the identity to stamp on writes. If the tool call is running on
|
|
96
|
+
* behalf of a real user (chat / quick-capture from the web), credit them
|
|
97
|
+
* by their handle — a stable email-free slug. The fake-domain email keeps
|
|
98
|
+
* git commit metadata well-formed without putting real addresses into
|
|
99
|
+
* workspace history. Fall back to the orchestrator-level gitUser for
|
|
100
|
+
* unauthenticated contexts (CLI, tests, server-only automations).
|
|
101
|
+
*/
|
|
102
|
+
function effectiveGitUser() {
|
|
103
|
+
const user = getUser();
|
|
104
|
+
if (user?.handle) {
|
|
105
|
+
return {
|
|
106
|
+
id: user.handle,
|
|
107
|
+
name: user.displayName ?? user.handle,
|
|
108
|
+
email: `${user.handle}@studiograph.local`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return gitUser;
|
|
112
|
+
}
|
|
113
|
+
/** Resolve "private" or "entries" to the current user's actual private folder name. */
|
|
95
114
|
function resolvePrivateRepo(repoName) {
|
|
96
115
|
if (repoName !== 'private' && repoName !== 'entries')
|
|
97
116
|
return repoName;
|
|
98
117
|
const user = getUser();
|
|
99
118
|
if (!user)
|
|
100
119
|
return repoName;
|
|
101
|
-
const
|
|
102
|
-
return
|
|
120
|
+
const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
|
|
121
|
+
return personalRepo?.name ?? repoName;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Eager skills are inlined into every system prompt for everyone with folder
|
|
125
|
+
* access. Creating one in a shared folder requires admin/owner so a rogue
|
|
126
|
+
* member can't bloat everyone's context. Eager skills in the user's own
|
|
127
|
+
* private folder are fine — they only bloat that user's own prompt.
|
|
128
|
+
* Returns an error string or null if the operation is allowed.
|
|
129
|
+
*/
|
|
130
|
+
function checkEagerSkillPermission(entityType, data, repoName) {
|
|
131
|
+
if (entityType !== 'skill')
|
|
132
|
+
return null;
|
|
133
|
+
if (!data || data.loading !== 'eager')
|
|
134
|
+
return null;
|
|
135
|
+
const user = getUser();
|
|
136
|
+
if (!user)
|
|
137
|
+
return null; // non-authenticated contexts (CLI, tests) bypass
|
|
138
|
+
const personalRepo = workspaceManager.getUserPersonalRepo(user.id);
|
|
139
|
+
if (personalRepo && personalRepo.name === repoName)
|
|
140
|
+
return null;
|
|
141
|
+
if (authSvc?.isFolderAdmin(user.id, repoName))
|
|
142
|
+
return null;
|
|
143
|
+
if (user.role === 'owner')
|
|
144
|
+
return null;
|
|
145
|
+
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".`;
|
|
146
|
+
}
|
|
147
|
+
// Compute the set of entity types the agent is allowed to create in this
|
|
148
|
+
// workspace: the full canonical catalog plus any custom types defined via
|
|
149
|
+
// schema_extensions. The launch-time allowlist was removed — the catalog
|
|
150
|
+
// now grows with the user via the New Entry picker's progressive disclosure.
|
|
151
|
+
const builtinTypeKeys = new Set(Object.keys(ENTITY_SCHEMAS));
|
|
152
|
+
const customWorkspaceTypes = workspaceManager.getSchemaRegistry().getAllTypes()
|
|
153
|
+
.filter(t => !builtinTypeKeys.has(t));
|
|
154
|
+
const agentAllowedTypes = getAgentAllowedEntityTypes(customWorkspaceTypes);
|
|
155
|
+
const agentAllowedTypeSet = new Set(agentAllowedTypes);
|
|
156
|
+
function rejectDisallowedCreateType(entityType) {
|
|
157
|
+
if (agentAllowedTypeSet.has(entityType))
|
|
158
|
+
return null;
|
|
159
|
+
if (entityType === 'asset') {
|
|
160
|
+
// The schema enum already excludes `asset` (see
|
|
161
|
+
// getAgentAllowedEntityTypes). This is the runtime defense-in-depth
|
|
162
|
+
// path for clients that bypass the enum.
|
|
163
|
+
return wrapToolResult({
|
|
164
|
+
success: false,
|
|
165
|
+
error: 'Asset entries cannot be created via create_entity — they require a binary blob plus a sidecar text file. Use the import_file tool with a local file path, or have the user upload via the workspace import dialog.',
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
const hint = isCuratedEntityType(entityType)
|
|
169
|
+
? '' // shouldn't happen for any other curated type — they're all allowed
|
|
170
|
+
: ` Allowed types: ${agentAllowedTypes.join(', ')}.`;
|
|
171
|
+
return wrapToolResult({
|
|
172
|
+
success: false,
|
|
173
|
+
error: `Entry type "${entityType}" is not a known canonical or workspace custom type.${hint}`,
|
|
174
|
+
});
|
|
103
175
|
}
|
|
104
176
|
return [
|
|
105
177
|
// Create entity
|
|
106
178
|
{
|
|
107
179
|
name: 'create_entity',
|
|
108
180
|
label: 'Create Entry',
|
|
109
|
-
description: 'Create a new entry in a
|
|
181
|
+
description: 'Create a new entry in a folder. Always validate required fields before calling. Folder is auto-resolved for app-defined entry types.',
|
|
110
182
|
parameters: T.Object({
|
|
111
|
-
repo: T.Optional(T.String({ description: '
|
|
112
|
-
entityType: T.
|
|
183
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
184
|
+
entityType: T.Union(agentAllowedTypes.map(t => T.Literal(t)), { description: `Entity type. Must be one of: ${agentAllowedTypes.join(', ')}.` }),
|
|
113
185
|
entityId: T.String({ description: 'Unique entity ID in kebab-case' }),
|
|
114
186
|
data: T.Object({}, { description: 'Entity data (YAML frontmatter)', additionalProperties: true }),
|
|
115
187
|
content: T.Optional(T.String({ description: 'Markdown content (optional)' })),
|
|
188
|
+
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.' })),
|
|
116
189
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
|
|
117
190
|
}),
|
|
118
191
|
execute: async (toolCallId, params) => {
|
|
119
192
|
try {
|
|
193
|
+
// Defense in depth: LLMs occasionally pass strings that don't match the
|
|
194
|
+
// enum schema. Runtime check ensures the launch allowlist is enforced
|
|
195
|
+
// even if the schema layer is bypassed.
|
|
196
|
+
const typeRejection = rejectDisallowedCreateType(params.entityType);
|
|
197
|
+
if (typeRejection)
|
|
198
|
+
return typeRejection;
|
|
120
199
|
let repoName = params.repo;
|
|
121
200
|
if (!repoName) {
|
|
122
|
-
|
|
123
|
-
if (!repoName)
|
|
124
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
201
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
125
202
|
}
|
|
126
203
|
repoName = resolvePrivateRepo(repoName);
|
|
127
204
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
128
|
-
return wrapToolResult({ success: false, error: `
|
|
205
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
129
206
|
}
|
|
207
|
+
const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
|
|
208
|
+
if (eagerError)
|
|
209
|
+
return wrapToolResult({ success: false, error: eagerError });
|
|
130
210
|
const graph = workspaceManager.getGraph(repoName);
|
|
131
211
|
// Workspace-level dedup: warn if an entity with this ID already exists elsewhere
|
|
132
212
|
const existing = workspaceManager.findEntityById(params.entityId);
|
|
133
213
|
if (existing && existing.repoName !== repoName) {
|
|
134
|
-
return wrapToolResult({ success: false, error: `An entity with ID "${params.entityId}" already exists in the "${existing.repoName}"
|
|
214
|
+
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}]].` });
|
|
135
215
|
}
|
|
136
216
|
// Add timestamps and user info
|
|
217
|
+
const actor = effectiveGitUser();
|
|
137
218
|
const now = new Date().toISOString();
|
|
138
219
|
const dataWithMeta = {
|
|
139
220
|
...params.data,
|
|
140
221
|
entity_id: params.entityId,
|
|
141
222
|
created_at: now,
|
|
142
223
|
updated_at: now,
|
|
143
|
-
created_by:
|
|
144
|
-
updated_by:
|
|
224
|
+
created_by: actor.id,
|
|
225
|
+
updated_by: actor.id,
|
|
145
226
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
227
|
+
const sanitizedContent = sanitizeLlmContent(params.content);
|
|
228
|
+
// Surface a live "<user>'s agent is acting" chip in the sidebar for
|
|
229
|
+
// the duration of the mutation. `leave` is always emitted via the
|
|
230
|
+
// inner finally so a thrown error doesn't leave the chip stuck.
|
|
231
|
+
onAgentActivity?.('enter', repoName);
|
|
232
|
+
try {
|
|
233
|
+
const entity = await graph.create({
|
|
234
|
+
entityType: params.entityType,
|
|
235
|
+
entityId: params.entityId,
|
|
236
|
+
data: dataWithMeta,
|
|
237
|
+
content: sanitizedContent,
|
|
238
|
+
commitMessage: params.commitMessage,
|
|
239
|
+
user: actor,
|
|
240
|
+
folderPath: params.folder_path,
|
|
241
|
+
});
|
|
242
|
+
onContentSync?.(repoName, params.entityType, params.entityId);
|
|
243
|
+
onMutation?.({ action: 'created', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
244
|
+
return wrapToolResult({
|
|
245
|
+
success: true,
|
|
246
|
+
entity: {
|
|
247
|
+
entityId: entity.id,
|
|
248
|
+
entityType: entity.entityType,
|
|
249
|
+
repo: repoName,
|
|
250
|
+
path: entity.path,
|
|
251
|
+
data: cleanData(entity.data),
|
|
252
|
+
},
|
|
253
|
+
message: `Created ${params.entityType}: ${params.entityId} in ${repoName}. Auto-committed — ready to push.`,
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
onAgentActivity?.('leave', repoName);
|
|
258
|
+
}
|
|
167
259
|
}
|
|
168
260
|
catch (error) {
|
|
169
261
|
return wrapToolResult({
|
|
@@ -179,7 +271,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
179
271
|
label: 'Get Entry',
|
|
180
272
|
description: 'Retrieve full entry details. Use repo, entityType, entityId from search/list results. entityType is optional — if omitted it is read from the file.',
|
|
181
273
|
parameters: T.Object({
|
|
182
|
-
repo: T.String({ description: '
|
|
274
|
+
repo: T.String({ description: 'Folder name' }),
|
|
183
275
|
entityType: T.Optional(T.String({ description: 'Entity type (optional — resolved from frontmatter if omitted)' })),
|
|
184
276
|
entityId: T.String({ description: 'Entity ID' }),
|
|
185
277
|
}),
|
|
@@ -187,12 +279,25 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
187
279
|
try {
|
|
188
280
|
const repo = resolvePrivateRepo(params.repo);
|
|
189
281
|
if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
|
|
190
|
-
return wrapToolResult({ success: false, error: `
|
|
282
|
+
return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
|
|
191
283
|
}
|
|
192
284
|
const graph = workspaceManager.getGraph(repo);
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
285
|
+
// If the agent passes the wrong entityType (e.g. based on stale
|
|
286
|
+
// search results), graph.get computes the wrong filesystem path
|
|
287
|
+
// and throws. Fall back to getById, which scans all type subdirs
|
|
288
|
+
// under the folder and resolves the actual location.
|
|
289
|
+
let entity;
|
|
290
|
+
if (params.entityType) {
|
|
291
|
+
try {
|
|
292
|
+
entity = graph.get(params.entityType, params.entityId);
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
entity = graph.getById(params.entityId);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
entity = graph.getById(params.entityId);
|
|
300
|
+
}
|
|
196
301
|
return wrapToolResult({
|
|
197
302
|
success: true,
|
|
198
303
|
entity: {
|
|
@@ -218,9 +323,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
218
323
|
{
|
|
219
324
|
name: 'update_entity',
|
|
220
325
|
label: 'Update Entry',
|
|
221
|
-
description: 'Update an existing entry.
|
|
326
|
+
description: 'Update an existing entry. Folder is auto-resolved for app-defined types.',
|
|
222
327
|
parameters: T.Object({
|
|
223
|
-
repo: T.Optional(T.String({ description: '
|
|
328
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
224
329
|
entityType: T.String({ description: 'Entity type' }),
|
|
225
330
|
entityId: T.String({ description: 'Entity ID' }),
|
|
226
331
|
data: T.Optional(T.Object({}, { description: 'Updated data fields', additionalProperties: true })),
|
|
@@ -231,44 +336,58 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
231
336
|
try {
|
|
232
337
|
let repoName = params.repo;
|
|
233
338
|
if (!repoName) {
|
|
234
|
-
|
|
235
|
-
if (!repoName)
|
|
236
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
339
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
237
340
|
}
|
|
238
341
|
repoName = resolvePrivateRepo(repoName);
|
|
239
342
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
240
|
-
return wrapToolResult({ success: false, error: `
|
|
343
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
241
344
|
}
|
|
345
|
+
const eagerError = checkEagerSkillPermission(params.entityType, params.data, repoName);
|
|
346
|
+
if (eagerError)
|
|
347
|
+
return wrapToolResult({ success: false, error: eagerError });
|
|
242
348
|
const graph = workspaceManager.getGraph(repoName);
|
|
243
349
|
// Add update metadata
|
|
350
|
+
const actor = effectiveGitUser();
|
|
244
351
|
const dataWithMeta = params.data
|
|
245
352
|
? {
|
|
246
353
|
...params.data,
|
|
247
354
|
updated_at: new Date().toISOString(),
|
|
248
|
-
updated_by:
|
|
355
|
+
updated_by: actor.id,
|
|
249
356
|
}
|
|
250
357
|
: undefined;
|
|
251
|
-
// Sanitize LLM JSON output: double-escaped newlines and stray quotes
|
|
252
358
|
const sanitizedContent = params.content !== undefined
|
|
253
|
-
? params.content
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
359
|
+
? sanitizeLlmContent(params.content)
|
|
360
|
+
: params.content;
|
|
361
|
+
onAgentActivity?.('enter', repoName);
|
|
362
|
+
try {
|
|
363
|
+
const entity = await graph.update({
|
|
364
|
+
entityType: params.entityType,
|
|
365
|
+
entityId: params.entityId,
|
|
366
|
+
data: dataWithMeta,
|
|
367
|
+
content: sanitizedContent,
|
|
368
|
+
commitMessage: params.commitMessage,
|
|
369
|
+
user: actor,
|
|
370
|
+
});
|
|
371
|
+
// Only sync Y.Doc when the body was actually rewritten. Pure
|
|
372
|
+
// metadata edits don't touch content and shouldn't thrash.
|
|
373
|
+
if (sanitizedContent !== undefined) {
|
|
374
|
+
onContentSync?.(repoName, params.entityType, params.entityId);
|
|
375
|
+
}
|
|
376
|
+
onMutation?.({ action: 'updated', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
377
|
+
return wrapToolResult({
|
|
378
|
+
success: true,
|
|
379
|
+
entity: {
|
|
380
|
+
entityId: entity.id,
|
|
381
|
+
entityType: entity.entityType,
|
|
382
|
+
repo: repoName,
|
|
383
|
+
data: cleanData(entity.data),
|
|
384
|
+
},
|
|
385
|
+
message: `Updated ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
finally {
|
|
389
|
+
onAgentActivity?.('leave', repoName);
|
|
390
|
+
}
|
|
272
391
|
}
|
|
273
392
|
catch (error) {
|
|
274
393
|
return wrapToolResult({
|
|
@@ -282,9 +401,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
282
401
|
{
|
|
283
402
|
name: 'delete_entity',
|
|
284
403
|
label: 'Delete Entry',
|
|
285
|
-
description: 'Delete an entry. Use with caution!
|
|
404
|
+
description: 'Delete an entry. Use with caution! Folder is auto-resolved for app-defined types.',
|
|
286
405
|
parameters: T.Object({
|
|
287
|
-
repo: T.Optional(T.String({ description: '
|
|
406
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
288
407
|
entityType: T.String({ description: 'Entity type' }),
|
|
289
408
|
entityId: T.String({ description: 'Entity ID' }),
|
|
290
409
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
|
|
@@ -293,21 +412,25 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
293
412
|
try {
|
|
294
413
|
let repoName = params.repo;
|
|
295
414
|
if (!repoName) {
|
|
296
|
-
|
|
297
|
-
if (!repoName)
|
|
298
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
415
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
299
416
|
}
|
|
300
417
|
repoName = resolvePrivateRepo(repoName);
|
|
301
418
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
302
|
-
return wrapToolResult({ success: false, error: `
|
|
419
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
303
420
|
}
|
|
304
421
|
const graph = workspaceManager.getGraph(repoName);
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
422
|
+
onAgentActivity?.('enter', repoName);
|
|
423
|
+
try {
|
|
424
|
+
await graph.delete(params.entityType, params.entityId, params.commitMessage);
|
|
425
|
+
onMutation?.({ action: 'deleted', repo: repoName, entityType: params.entityType, entityId: params.entityId });
|
|
426
|
+
return wrapToolResult({
|
|
427
|
+
success: true,
|
|
428
|
+
message: `Deleted ${params.entityType}: ${params.entityId}. Auto-committed — ready to push.`,
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
finally {
|
|
432
|
+
onAgentActivity?.('leave', repoName);
|
|
433
|
+
}
|
|
311
434
|
}
|
|
312
435
|
catch (error) {
|
|
313
436
|
return wrapToolResult({
|
|
@@ -321,46 +444,93 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
321
444
|
{
|
|
322
445
|
name: 'import_file',
|
|
323
446
|
label: 'Import File',
|
|
324
|
-
description: 'Import a local file as a Studiograph entry.
|
|
447
|
+
description: 'Import a local file as a Studiograph entry. Text formats become typed entries (.md/.txt → note, .csv → dataset). Binary formats (PDF, images, design files, video, audio, archives) become asset entries.',
|
|
325
448
|
parameters: T.Object({
|
|
326
449
|
path: T.String({ description: 'Absolute path or ~/relative path to the file' }),
|
|
327
|
-
|
|
328
|
-
entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension)' })),
|
|
450
|
+
folder: T.String({ description: 'Target folder name' }),
|
|
451
|
+
entityType: T.Optional(T.String({ description: 'Override entity type (default: auto-detect from extension; ignored for asset uploads)' })),
|
|
329
452
|
entityId: T.Optional(T.String({ description: 'Override entity ID (default: from filename)' })),
|
|
330
453
|
}),
|
|
331
454
|
execute: async (toolCallId, params) => {
|
|
332
455
|
try {
|
|
333
|
-
if (!canAccessRepo(params.
|
|
334
|
-
return wrapToolResult({ success: false, error: `
|
|
456
|
+
if (!canAccessRepo(params.folder, workspaceManager, getUser, authSvc)) {
|
|
457
|
+
return wrapToolResult({ success: false, error: `Folder "${params.folder}" not found` });
|
|
335
458
|
}
|
|
336
459
|
const { readFileSync, existsSync } = await import('fs');
|
|
337
|
-
const { resolve } = await import('path');
|
|
460
|
+
const { resolve, basename, sep } = await import('path');
|
|
338
461
|
const { homedir } = await import('os');
|
|
339
462
|
const { importFile, isSupportedFile } = await import('../../services/import-service.js');
|
|
463
|
+
const { isAssetUploadExtension } = await import('../../services/assets/base.js');
|
|
464
|
+
const { uploadAsset } = await import('../../services/asset-upload-service.js');
|
|
340
465
|
const filePath = params.path.startsWith('~/')
|
|
341
466
|
? resolve(homedir(), params.path.slice(2))
|
|
342
467
|
: resolve(params.path);
|
|
343
468
|
if (!existsSync(filePath)) {
|
|
344
469
|
return wrapToolResult({ success: false, error: `File not found: ${filePath}` });
|
|
345
470
|
}
|
|
471
|
+
const graph = workspaceManager.getGraph(params.folder);
|
|
472
|
+
const fname = basename(filePath);
|
|
473
|
+
// Path-exfil guard: the agent reads bytes off disk and uploads
|
|
474
|
+
// them as a workspace asset, accessible via /api/assets/* by any
|
|
475
|
+
// folder member. Without an allowlist, an LLM prompt injection in
|
|
476
|
+
// an imported note can ask the agent to grab ~/.ssh/id_rsa, .env
|
|
477
|
+
// files, kubeconfigs, etc. by renaming them to a permitted
|
|
478
|
+
// extension. Restrict to roots a user would plausibly drop files
|
|
479
|
+
// from: the workspace itself, ~/Downloads, ~/Documents.
|
|
480
|
+
const home = homedir();
|
|
481
|
+
const workspaceRoot = graph.getWorkspaceRoot();
|
|
482
|
+
const allowedRoots = [
|
|
483
|
+
workspaceRoot,
|
|
484
|
+
resolve(home, 'Downloads'),
|
|
485
|
+
resolve(home, 'Documents'),
|
|
486
|
+
].filter((r) => Boolean(r)).map(r => r.endsWith(sep) ? r : r + sep);
|
|
487
|
+
const isInAllowedRoot = allowedRoots.some(root => filePath === root.slice(0, -1) || filePath.startsWith(root));
|
|
488
|
+
if (!isInAllowedRoot) {
|
|
489
|
+
return wrapToolResult({
|
|
490
|
+
success: false,
|
|
491
|
+
error: `Path "${filePath}" is outside the import allowlist. Files must live under the workspace, ~/Downloads, or ~/Documents.`,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
// Binary extensions → asset wrapper. The text-import path doesn't
|
|
495
|
+
// know how to handle .indd / .pptx / etc. and would either reject
|
|
496
|
+
// them or (for .pdf) mistakenly land them as a `note` entity with
|
|
497
|
+
// extracted body text. Route to uploadAsset for parity with the
|
|
498
|
+
// web import dispatcher.
|
|
499
|
+
if (isAssetUploadExtension(fname)) {
|
|
500
|
+
const buffer = readFileSync(filePath);
|
|
501
|
+
const result = await uploadAsset({
|
|
502
|
+
graph,
|
|
503
|
+
filename: fname,
|
|
504
|
+
buffer,
|
|
505
|
+
workspacePath: graph.getWorkspaceRoot(),
|
|
506
|
+
});
|
|
507
|
+
onMutation?.({ action: 'created', repo: params.folder, entityType: 'asset', entityId: result.entityId });
|
|
508
|
+
return wrapToolResult({
|
|
509
|
+
success: true,
|
|
510
|
+
entityType: 'asset',
|
|
511
|
+
entityId: result.entityId,
|
|
512
|
+
asset_kind: result.asset_kind,
|
|
513
|
+
asset_size: result.asset_size,
|
|
514
|
+
pages: result.pages,
|
|
515
|
+
message: `Imported ${fname} as asset/${result.entityId} in ${params.folder}`,
|
|
516
|
+
});
|
|
517
|
+
}
|
|
346
518
|
if (!isSupportedFile(filePath)) {
|
|
347
|
-
return wrapToolResult({ success: false, error: `Unsupported file type
|
|
519
|
+
return wrapToolResult({ success: false, error: `Unsupported file type for ${fname}` });
|
|
348
520
|
}
|
|
349
|
-
const graph = workspaceManager.getGraph(params.collection);
|
|
350
521
|
const content = readFileSync(filePath);
|
|
351
|
-
const
|
|
352
|
-
const result = await importFile(graph, basename(filePath), content, {
|
|
522
|
+
const result = await importFile(graph, fname, content, {
|
|
353
523
|
entityType: params.entityType,
|
|
354
524
|
entityId: params.entityId,
|
|
355
525
|
});
|
|
356
526
|
if (result.status === 'created') {
|
|
357
|
-
onMutation?.({ action: 'created', repo: params.
|
|
527
|
+
onMutation?.({ action: 'created', repo: params.folder, entityType: result.entityType, entityId: result.entityId });
|
|
358
528
|
}
|
|
359
529
|
return wrapToolResult({
|
|
360
530
|
success: result.status === 'created',
|
|
361
531
|
...result,
|
|
362
532
|
message: result.status === 'created'
|
|
363
|
-
? `Imported ${
|
|
533
|
+
? `Imported ${fname} as ${result.entityType}/${result.entityId} in ${params.folder}`
|
|
364
534
|
: result.error,
|
|
365
535
|
});
|
|
366
536
|
}
|
|
@@ -376,9 +546,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
376
546
|
{
|
|
377
547
|
name: 'rename_entity',
|
|
378
548
|
label: 'Rename Entry',
|
|
379
|
-
description: 'Rename an entry by changing its ID. Preserves all data, content, and source_ref. The old ID will no longer exist.
|
|
549
|
+
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.',
|
|
380
550
|
parameters: T.Object({
|
|
381
|
-
repo: T.Optional(T.String({ description: '
|
|
551
|
+
repo: T.Optional(T.String({ description: 'Folder name (auto-resolved for app entity types)' })),
|
|
382
552
|
entityType: T.String({ description: 'Entity type' }),
|
|
383
553
|
oldId: T.String({ description: 'Current entity ID' }),
|
|
384
554
|
newId: T.String({ description: 'New entity ID (kebab-case)' }),
|
|
@@ -387,13 +557,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
387
557
|
try {
|
|
388
558
|
let repoName = params.repo;
|
|
389
559
|
if (!repoName) {
|
|
390
|
-
|
|
391
|
-
if (!repoName)
|
|
392
|
-
return wrapToolResult({ success: false, error: `repo is required — could not auto-resolve repo for type "${params.entityType}"` });
|
|
560
|
+
return wrapToolResult({ success: false, error: `repo is required — must specify which folder to use for type "${params.entityType}"` });
|
|
393
561
|
}
|
|
394
562
|
repoName = resolvePrivateRepo(repoName);
|
|
395
563
|
if (!canAccessRepo(repoName, workspaceManager, getUser, authSvc)) {
|
|
396
|
-
return wrapToolResult({ success: false, error: `
|
|
564
|
+
return wrapToolResult({ success: false, error: `Folder "${repoName}" not found` });
|
|
397
565
|
}
|
|
398
566
|
const graph = workspaceManager.getGraph(repoName);
|
|
399
567
|
const result = await graph.rename(params.entityType, params.oldId, params.newId);
|
|
@@ -413,41 +581,41 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
413
581
|
}
|
|
414
582
|
},
|
|
415
583
|
},
|
|
416
|
-
//
|
|
584
|
+
// Transfer entity across repos (cross-repo move). Distinct from
|
|
585
|
+
// folder-tools' `move_entity`, which relocates within one repo.
|
|
417
586
|
{
|
|
418
|
-
name: '
|
|
419
|
-
label: '
|
|
420
|
-
description: 'Move an entry from one
|
|
587
|
+
name: 'transfer_entity',
|
|
588
|
+
label: 'Transfer Entry',
|
|
589
|
+
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.',
|
|
421
590
|
parameters: T.Object({
|
|
422
|
-
sourceRepo: T.String({ description: 'Source
|
|
423
|
-
targetRepo: T.String({ description: 'Target
|
|
591
|
+
sourceRepo: T.String({ description: 'Source repo name' }),
|
|
592
|
+
targetRepo: T.String({ description: 'Target repo name' }),
|
|
424
593
|
entityType: T.String({ description: 'Entity type' }),
|
|
425
594
|
entityId: T.String({ description: 'Entity ID' }),
|
|
426
595
|
commitMessage: T.Optional(T.String({ description: 'Custom commit message (optional)' })),
|
|
427
596
|
}),
|
|
428
597
|
execute: async (toolCallId, params) => {
|
|
429
598
|
try {
|
|
430
|
-
const denied = adminOnly(getUser);
|
|
431
|
-
if (denied)
|
|
432
|
-
return wrapToolResult({ success: false, error: denied });
|
|
433
599
|
if (!canAccessRepo(params.sourceRepo, workspaceManager, getUser, authSvc)) {
|
|
434
|
-
return wrapToolResult({ success: false, error: `
|
|
600
|
+
return wrapToolResult({ success: false, error: `Folder "${params.sourceRepo}" not found` });
|
|
435
601
|
}
|
|
436
602
|
if (!canAccessRepo(params.targetRepo, workspaceManager, getUser, authSvc)) {
|
|
437
|
-
return wrapToolResult({ success: false, error: `
|
|
603
|
+
return wrapToolResult({ success: false, error: `Folder "${params.targetRepo}" not found` });
|
|
438
604
|
}
|
|
439
605
|
const sourceGraph = workspaceManager.getGraph(params.sourceRepo);
|
|
440
606
|
const targetGraph = workspaceManager.getGraph(params.targetRepo);
|
|
441
607
|
// Read the full entity from source
|
|
442
608
|
const entity = sourceGraph.get(params.entityType, params.entityId);
|
|
443
609
|
// Create in target repo
|
|
610
|
+
const actor = effectiveGitUser();
|
|
444
611
|
const now = new Date().toISOString();
|
|
445
612
|
await targetGraph.create({
|
|
446
613
|
entityType: params.entityType,
|
|
447
614
|
entityId: params.entityId,
|
|
448
|
-
data: { ...entity.data, updated_at: now, updated_by:
|
|
615
|
+
data: { ...entity.data, updated_at: now, updated_by: actor.id },
|
|
449
616
|
content: entity.document.content || '',
|
|
450
617
|
commitMessage: params.commitMessage || `Move ${params.entityType} ${params.entityId} from ${params.sourceRepo} to ${params.targetRepo}`,
|
|
618
|
+
user: actor,
|
|
451
619
|
});
|
|
452
620
|
// Delete from source repo
|
|
453
621
|
await sourceGraph.delete(params.entityType, params.entityId, `Move ${params.entityType} ${params.entityId} to ${params.targetRepo}`);
|
|
@@ -470,11 +638,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
470
638
|
{
|
|
471
639
|
name: 'search_entities',
|
|
472
640
|
label: 'Search Entries',
|
|
473
|
-
description: 'Search for entries across
|
|
641
|
+
description: 'Search for entries across folders with filters.',
|
|
474
642
|
parameters: T.Object({
|
|
475
643
|
query: T.Optional(T.String({ description: 'Search query (full-text)' })),
|
|
476
644
|
entityType: T.Optional(T.String({ description: 'Filter by entity type' })),
|
|
477
|
-
repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific
|
|
645
|
+
repoNames: T.Optional(T.Array(T.String(), { description: 'Limit to specific folders' })),
|
|
478
646
|
visibility: T.Optional(T.Array(T.String(), { description: 'Filter by visibility (public, team, admin, restricted)' })),
|
|
479
647
|
tags: T.Optional(T.Array(T.String(), { description: 'Filter by tags' })),
|
|
480
648
|
dateRange: T.Optional(T.Object({
|
|
@@ -486,7 +654,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
486
654
|
}),
|
|
487
655
|
execute: async (toolCallId, params) => {
|
|
488
656
|
try {
|
|
489
|
-
// Scope search to accessible
|
|
657
|
+
// Scope search to accessible folders
|
|
490
658
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
491
659
|
let repoNames = params.repoNames?.map((r) => resolvePrivateRepo(r));
|
|
492
660
|
if (allowed) {
|
|
@@ -535,7 +703,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
535
703
|
execute: async (toolCallId, params) => {
|
|
536
704
|
try {
|
|
537
705
|
let results = workspaceManager.list(params.entityType, params.limit);
|
|
538
|
-
// Filter to accessible
|
|
706
|
+
// Filter to accessible folders
|
|
539
707
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
540
708
|
if (allowed) {
|
|
541
709
|
results = results.filter(r => allowed.has(r.repoName));
|
|
@@ -563,9 +731,9 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
563
731
|
{
|
|
564
732
|
name: 'get_related',
|
|
565
733
|
label: 'Get Related Entries',
|
|
566
|
-
description: 'Get entries related to a given entry via wikilinks (cross-
|
|
734
|
+
description: 'Get entries related to a given entry via wikilinks (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
|
|
567
735
|
parameters: T.Object({
|
|
568
|
-
repo: T.String({ description: '
|
|
736
|
+
repo: T.String({ description: 'Folder name' }),
|
|
569
737
|
entityType: T.String({ description: 'Entity type' }),
|
|
570
738
|
entityId: T.String({ description: 'Entity ID' }),
|
|
571
739
|
}),
|
|
@@ -573,10 +741,10 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
573
741
|
try {
|
|
574
742
|
const repo = resolvePrivateRepo(params.repo);
|
|
575
743
|
if (!canAccessRepo(repo, workspaceManager, getUser, authSvc)) {
|
|
576
|
-
return wrapToolResult({ success: false, error: `
|
|
744
|
+
return wrapToolResult({ success: false, error: `Folder "${repo}" not found` });
|
|
577
745
|
}
|
|
578
746
|
let related = workspaceManager.getRelated(repo, params.entityType, params.entityId);
|
|
579
|
-
// Filter cross-
|
|
747
|
+
// Filter cross-folder results to accessible repos
|
|
580
748
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
581
749
|
if (allowed) {
|
|
582
750
|
related = related.filter(r => allowed.has(r.repoName));
|
|
@@ -604,19 +772,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
604
772
|
{
|
|
605
773
|
name: 'get_backlinks',
|
|
606
774
|
label: 'Get Backlinks',
|
|
607
|
-
description: 'Get entries that link to a given entry (cross-
|
|
775
|
+
description: 'Get entries that link to a given entry (cross-folder supported). Pass repo, entityType, entityId from search/list results.',
|
|
608
776
|
parameters: T.Object({
|
|
609
|
-
repo: T.String({ description: '
|
|
777
|
+
repo: T.String({ description: 'Folder name' }),
|
|
610
778
|
entityType: T.String({ description: 'Entity type' }),
|
|
611
779
|
entityId: T.String({ description: 'Entity ID' }),
|
|
612
780
|
}),
|
|
613
781
|
execute: async (toolCallId, params) => {
|
|
614
782
|
try {
|
|
615
783
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
616
|
-
return wrapToolResult({ success: false, error: `
|
|
784
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
617
785
|
}
|
|
618
786
|
let backlinks = workspaceManager.getBacklinks(params.repo, params.entityType, params.entityId);
|
|
619
|
-
// Filter cross-
|
|
787
|
+
// Filter cross-folder results to accessible repos
|
|
620
788
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
621
789
|
if (allowed) {
|
|
622
790
|
backlinks = backlinks.filter(r => allowed.has(r.repoName));
|
|
@@ -644,16 +812,16 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
644
812
|
{
|
|
645
813
|
name: 'validate_wikilinks',
|
|
646
814
|
label: 'Validate Wikilinks',
|
|
647
|
-
description: 'Validate all wikilinks in an entry (checks same
|
|
815
|
+
description: 'Validate all wikilinks in an entry (checks same folder and cross-folder)',
|
|
648
816
|
parameters: T.Object({
|
|
649
|
-
repo: T.String({ description: '
|
|
817
|
+
repo: T.String({ description: 'Folder name' }),
|
|
650
818
|
entityType: T.String({ description: 'Entity type' }),
|
|
651
819
|
entityId: T.String({ description: 'Entity ID' }),
|
|
652
820
|
}),
|
|
653
821
|
execute: async (toolCallId, params) => {
|
|
654
822
|
try {
|
|
655
823
|
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
656
|
-
return wrapToolResult({ success: false, error: `
|
|
824
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
657
825
|
}
|
|
658
826
|
const validation = workspaceManager.validateWikilinks(params.repo, params.entityType, params.entityId);
|
|
659
827
|
return wrapToolResult({
|
|
@@ -688,7 +856,7 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
688
856
|
const summary = workspaceManager.getSummary();
|
|
689
857
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
690
858
|
if (allowed) {
|
|
691
|
-
// Filter summary to accessible
|
|
859
|
+
// Filter summary to accessible folders only
|
|
692
860
|
const filteredByRepo = {};
|
|
693
861
|
let filteredTotal = 0;
|
|
694
862
|
for (const [repo, count] of Object.entries(summary.entitiesByRepo)) {
|
|
@@ -700,19 +868,19 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
700
868
|
return wrapToolResult({
|
|
701
869
|
success: true,
|
|
702
870
|
summary: {
|
|
703
|
-
|
|
871
|
+
totalFolders: allowed.size,
|
|
704
872
|
totalEntities: filteredTotal,
|
|
705
|
-
|
|
873
|
+
entitiesByFolder: filteredByRepo,
|
|
706
874
|
},
|
|
707
875
|
});
|
|
708
876
|
}
|
|
709
877
|
return wrapToolResult({
|
|
710
878
|
success: true,
|
|
711
879
|
summary: {
|
|
712
|
-
|
|
880
|
+
totalFolders: summary.totalRepos,
|
|
713
881
|
totalEntities: summary.totalEntities,
|
|
714
882
|
entitiesByType: summary.entitiesByType,
|
|
715
|
-
|
|
883
|
+
entitiesByFolder: summary.entitiesByRepo,
|
|
716
884
|
},
|
|
717
885
|
});
|
|
718
886
|
}
|
|
@@ -724,11 +892,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
724
892
|
}
|
|
725
893
|
},
|
|
726
894
|
},
|
|
727
|
-
// List
|
|
895
|
+
// List folders
|
|
728
896
|
{
|
|
729
897
|
name: 'list_repos',
|
|
730
|
-
label: 'List
|
|
731
|
-
description: 'List all
|
|
898
|
+
label: 'List Folders',
|
|
899
|
+
description: 'List all folders in the workspace',
|
|
732
900
|
parameters: T.Object({}),
|
|
733
901
|
execute: async (toolCallId, params) => {
|
|
734
902
|
try {
|
|
@@ -740,12 +908,12 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
740
908
|
return wrapToolResult({
|
|
741
909
|
success: true,
|
|
742
910
|
count: repos.length,
|
|
743
|
-
|
|
911
|
+
folders: repos.map(r => ({
|
|
744
912
|
name: r.name,
|
|
745
913
|
type: r.type,
|
|
746
914
|
description: r.description,
|
|
747
915
|
path: r.path,
|
|
748
|
-
|
|
916
|
+
personal: r.personal || false,
|
|
749
917
|
})),
|
|
750
918
|
});
|
|
751
919
|
}
|
|
@@ -757,40 +925,35 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
757
925
|
}
|
|
758
926
|
},
|
|
759
927
|
},
|
|
760
|
-
// Create a new
|
|
928
|
+
// Create a new folder
|
|
761
929
|
{
|
|
762
|
-
name: '
|
|
763
|
-
label: 'Create
|
|
764
|
-
description: 'Create a new
|
|
930
|
+
name: 'create_folder',
|
|
931
|
+
label: 'Create Folder',
|
|
932
|
+
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 Entries" folder auto-provisioned — do not use this tool to create another one.',
|
|
765
933
|
parameters: T.Object({
|
|
766
|
-
name: T.String({ description: '
|
|
767
|
-
description: T.Optional(T.String({ description: 'Short description of the
|
|
768
|
-
private: T.Optional(T.Boolean({ description: 'If true, creates a private collection visible only to you' })),
|
|
934
|
+
name: T.String({ description: 'Folder name in kebab-case (e.g., "client-projects")' }),
|
|
935
|
+
description: T.Optional(T.String({ description: 'Short description of the folder' })),
|
|
769
936
|
}),
|
|
770
937
|
execute: async (toolCallId, params) => {
|
|
771
938
|
try {
|
|
772
939
|
const user = getUser();
|
|
773
|
-
// Non-private collections require admin; private collections can be created by anyone
|
|
774
|
-
if (!params.private && user && !isAdminOrOwner(user.role)) {
|
|
775
|
-
return wrapToolResult({ success: false, error: 'Only admins can create collections' });
|
|
776
|
-
}
|
|
777
940
|
if (!/^[a-z0-9][a-z0-9-]*$/.test(params.name)) {
|
|
778
|
-
return wrapToolResult({ success: false, error: '
|
|
941
|
+
return wrapToolResult({ success: false, error: 'Folder name must be kebab-case (lowercase letters, numbers, hyphens)' });
|
|
779
942
|
}
|
|
780
943
|
const { Workspace } = await import('../../core/workspace.js');
|
|
781
944
|
const workspace = new Workspace(workspacePath);
|
|
782
945
|
const repo = await workspace.registerRepo({
|
|
783
946
|
name: params.name,
|
|
784
947
|
description: params.description,
|
|
785
|
-
|
|
786
|
-
...(params.private && user ? { owner_id: user.id } : {}),
|
|
948
|
+
owner_id: user?.id,
|
|
787
949
|
});
|
|
788
|
-
// Reload workspace manager to pick up the new collection
|
|
789
950
|
workspaceManager.reloadConfig();
|
|
790
|
-
|
|
951
|
+
if (user && authSvc)
|
|
952
|
+
authSvc.grantFolderAccess(user.id, repo.name, 'admin');
|
|
953
|
+
onMutation?.({ action: 'created', repo: repo.name, entityType: '_folder', entityId: repo.name });
|
|
791
954
|
return wrapToolResult({
|
|
792
955
|
success: true,
|
|
793
|
-
|
|
956
|
+
folder: { name: repo.name, path: repo.path, description: repo.description },
|
|
794
957
|
});
|
|
795
958
|
}
|
|
796
959
|
catch (error) {
|
|
@@ -798,81 +961,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
798
961
|
}
|
|
799
962
|
},
|
|
800
963
|
},
|
|
801
|
-
// Query dataset rows
|
|
802
|
-
{
|
|
803
|
-
name: 'query_dataset',
|
|
804
|
-
label: 'Query Dataset',
|
|
805
|
-
description: 'Query rows from a dataset entity with optional filtering',
|
|
806
|
-
parameters: T.Object({
|
|
807
|
-
repo: T.String({ description: 'Collection name' }),
|
|
808
|
-
entityId: T.String({ description: 'Dataset entity ID' }),
|
|
809
|
-
filter: T.Optional(T.Object({}, { description: 'Filter conditions (column: value or { gte, lte, contains })', additionalProperties: true })),
|
|
810
|
-
limit: T.Optional(T.Number({ description: 'Max rows to return' })),
|
|
811
|
-
}),
|
|
812
|
-
execute: async (toolCallId, params) => {
|
|
813
|
-
try {
|
|
814
|
-
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
815
|
-
return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
|
|
816
|
-
}
|
|
817
|
-
const graph = workspaceManager.getGraph(params.repo);
|
|
818
|
-
const entity = graph.get('dataset', params.entityId);
|
|
819
|
-
const schema = entity.data.schema;
|
|
820
|
-
let rows = graph.getDatasetRows(params.entityId, params.filter);
|
|
821
|
-
const total = rows.length;
|
|
822
|
-
if (params.limit && params.limit > 0) {
|
|
823
|
-
rows = rows.slice(0, params.limit);
|
|
824
|
-
}
|
|
825
|
-
return wrapToolResult({
|
|
826
|
-
success: true,
|
|
827
|
-
rows,
|
|
828
|
-
total,
|
|
829
|
-
schema,
|
|
830
|
-
});
|
|
831
|
-
}
|
|
832
|
-
catch (error) {
|
|
833
|
-
return wrapToolResult({
|
|
834
|
-
success: false,
|
|
835
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
},
|
|
839
|
-
},
|
|
840
|
-
// Append rows to dataset
|
|
841
|
-
{
|
|
842
|
-
name: 'append_rows',
|
|
843
|
-
label: 'Append Rows',
|
|
844
|
-
description: 'Append rows to a dataset entity',
|
|
845
|
-
parameters: T.Object({
|
|
846
|
-
repo: T.String({ description: 'Collection name' }),
|
|
847
|
-
entityId: T.String({ description: 'Dataset entity ID' }),
|
|
848
|
-
rows: T.Array(T.Object({}, { additionalProperties: true }), { description: 'Rows to append' }),
|
|
849
|
-
commitMessage: T.Optional(T.String({ description: 'Custom commit message' })),
|
|
850
|
-
}),
|
|
851
|
-
execute: async (toolCallId, params) => {
|
|
852
|
-
try {
|
|
853
|
-
if (!canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
854
|
-
return wrapToolResult({ success: false, error: `Collection "${params.repo}" not found` });
|
|
855
|
-
}
|
|
856
|
-
const graph = workspaceManager.getGraph(params.repo);
|
|
857
|
-
// Get current row count before appending
|
|
858
|
-
const beforeRows = graph.getDatasetRows(params.entityId);
|
|
859
|
-
await graph.appendDatasetRows(params.entityId, params.rows, params.commitMessage);
|
|
860
|
-
const afterRows = graph.getDatasetRows(params.entityId);
|
|
861
|
-
return wrapToolResult({
|
|
862
|
-
success: true,
|
|
863
|
-
rowsAdded: afterRows.length - beforeRows.length,
|
|
864
|
-
totalRows: afterRows.length,
|
|
865
|
-
message: `Appended ${afterRows.length - beforeRows.length} row(s) to dataset: ${params.entityId}`,
|
|
866
|
-
});
|
|
867
|
-
}
|
|
868
|
-
catch (error) {
|
|
869
|
-
return wrapToolResult({
|
|
870
|
-
success: false,
|
|
871
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
},
|
|
875
|
-
},
|
|
876
964
|
// Get entity schema
|
|
877
965
|
{
|
|
878
966
|
name: 'get_entity_schema',
|
|
@@ -919,15 +1007,15 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
919
1007
|
{
|
|
920
1008
|
name: 'lint_entities',
|
|
921
1009
|
label: 'Lint Entries',
|
|
922
|
-
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
|
|
1010
|
+
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.',
|
|
923
1011
|
parameters: T.Object({
|
|
924
|
-
repo: T.Optional(T.String({ description: 'Optional: limit to specific
|
|
1012
|
+
repo: T.Optional(T.String({ description: 'Optional: limit to specific folder' })),
|
|
925
1013
|
entityType: T.Optional(T.String({ description: 'Optional: limit to specific entity type (e.g. "project", "deal")' })),
|
|
926
1014
|
}),
|
|
927
1015
|
execute: async (toolCallId, params) => {
|
|
928
1016
|
try {
|
|
929
1017
|
if (params.repo && !canAccessRepo(params.repo, workspaceManager, getUser, authSvc)) {
|
|
930
|
-
return wrapToolResult({ success: false, error: `
|
|
1018
|
+
return wrapToolResult({ success: false, error: `Folder "${params.repo}" not found` });
|
|
931
1019
|
}
|
|
932
1020
|
let issues = await lintWorkspace(workspaceManager, {
|
|
933
1021
|
repo: params.repo,
|
|
@@ -977,11 +1065,11 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
977
1065
|
parameters: T.Object({
|
|
978
1066
|
entityTypes: T.Optional(T.Array(T.String(), { description: 'Entity types to check (e.g. ["person", "client"])' })),
|
|
979
1067
|
minAgeDays: T.Optional(T.Number({ description: 'Only flag entities older than N days' })),
|
|
980
|
-
repos: T.Optional(T.Array(T.String(), { description: '
|
|
1068
|
+
repos: T.Optional(T.Array(T.String(), { description: 'Folder names to scan (default: all)' })),
|
|
981
1069
|
}),
|
|
982
1070
|
execute: async (toolCallId, params) => {
|
|
983
1071
|
try {
|
|
984
|
-
// Scope to accessible
|
|
1072
|
+
// Scope to accessible folders
|
|
985
1073
|
const allowed = getAccessibleRepoNames(workspaceManager, getUser, authSvc);
|
|
986
1074
|
let repos = params.repos;
|
|
987
1075
|
if (allowed) {
|
|
@@ -1032,98 +1120,6 @@ export function createGraphTools(workspaceManager, gitUser, workspacePath, onHig
|
|
|
1032
1120
|
});
|
|
1033
1121
|
},
|
|
1034
1122
|
},
|
|
1035
|
-
// ── View Management Tools ──
|
|
1036
|
-
{
|
|
1037
|
-
name: 'list_views',
|
|
1038
|
-
label: 'List Views',
|
|
1039
|
-
description: 'List the current user\'s saved views.',
|
|
1040
|
-
parameters: T.Object({}),
|
|
1041
|
-
execute: async () => {
|
|
1042
|
-
if (!authSvc)
|
|
1043
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1044
|
-
const userId = getUser()?.id ?? 0;
|
|
1045
|
-
const views = authSvc.getUserViews(userId);
|
|
1046
|
-
return wrapToolResult({ views });
|
|
1047
|
-
},
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
name: 'create_view',
|
|
1051
|
-
label: 'Create View',
|
|
1052
|
-
description: 'Create a new saved view for the current user. Views appear as tabs in the toolbar.',
|
|
1053
|
-
parameters: T.Object({
|
|
1054
|
-
name: T.String({ description: 'View name (e.g. "My Tasks", "Open Projects")' }),
|
|
1055
|
-
selectedType: T.Optional(T.String({ description: 'Entity type filter (e.g. "task", "project"). Omit for all types.' })),
|
|
1056
|
-
groupBy: T.Optional(T.String({ description: 'Column key to group by (e.g. "status", "priority")' })),
|
|
1057
|
-
}),
|
|
1058
|
-
execute: async (_toolCallId, params) => {
|
|
1059
|
-
if (!authSvc)
|
|
1060
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1061
|
-
const userId = getUser()?.id ?? 0;
|
|
1062
|
-
const config = {
|
|
1063
|
-
selectedType: params.selectedType ?? null,
|
|
1064
|
-
groupBy: params.groupBy ?? null,
|
|
1065
|
-
sortKey: 'name',
|
|
1066
|
-
sortAsc: true,
|
|
1067
|
-
filters: { text: {}, enum: {}, date: {} },
|
|
1068
|
-
};
|
|
1069
|
-
const view = authSvc.createUserView(userId, params.name, 'list', config);
|
|
1070
|
-
return wrapToolResult({
|
|
1071
|
-
success: true,
|
|
1072
|
-
view: { id: view.id, name: view.name, viewType: view.viewType, config: view.config },
|
|
1073
|
-
message: `Created view "${params.name}". It will appear as a tab in the toolbar.`,
|
|
1074
|
-
});
|
|
1075
|
-
},
|
|
1076
|
-
},
|
|
1077
|
-
{
|
|
1078
|
-
name: 'update_view',
|
|
1079
|
-
label: 'Update View',
|
|
1080
|
-
description: 'Update an existing saved view\'s name or configuration.',
|
|
1081
|
-
parameters: T.Object({
|
|
1082
|
-
id: T.Number({ description: 'View ID' }),
|
|
1083
|
-
name: T.Optional(T.String({ description: 'New view name' })),
|
|
1084
|
-
selectedType: T.Optional(T.String({ description: 'Entity type filter (use "all" to clear)' })),
|
|
1085
|
-
groupBy: T.Optional(T.String({ description: 'Column key to group by (use "none" to clear)' })),
|
|
1086
|
-
}),
|
|
1087
|
-
execute: async (_toolCallId, params) => {
|
|
1088
|
-
if (!authSvc)
|
|
1089
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1090
|
-
const userId = getUser()?.id ?? 0;
|
|
1091
|
-
const existing = authSvc.getUserView(params.id, userId);
|
|
1092
|
-
if (!existing)
|
|
1093
|
-
return wrapToolResult({ success: false, error: `View ${params.id} not found` });
|
|
1094
|
-
const fields = {};
|
|
1095
|
-
if (params.name)
|
|
1096
|
-
fields.name = params.name;
|
|
1097
|
-
if (params.selectedType !== undefined || params.groupBy !== undefined) {
|
|
1098
|
-
const config = { ...existing.config };
|
|
1099
|
-
if (params.selectedType !== undefined)
|
|
1100
|
-
config.selectedType = params.selectedType === 'all' ? null : params.selectedType;
|
|
1101
|
-
if (params.groupBy !== undefined)
|
|
1102
|
-
config.groupBy = params.groupBy === 'none' ? null : params.groupBy;
|
|
1103
|
-
fields.config = config;
|
|
1104
|
-
}
|
|
1105
|
-
authSvc.updateUserView(params.id, userId, fields);
|
|
1106
|
-
return wrapToolResult({ success: true, message: `Updated view "${existing.name}".` });
|
|
1107
|
-
},
|
|
1108
|
-
},
|
|
1109
|
-
{
|
|
1110
|
-
name: 'delete_view',
|
|
1111
|
-
label: 'Delete View',
|
|
1112
|
-
description: 'Delete a saved view.',
|
|
1113
|
-
parameters: T.Object({
|
|
1114
|
-
id: T.Number({ description: 'View ID to delete' }),
|
|
1115
|
-
}),
|
|
1116
|
-
execute: async (_toolCallId, params) => {
|
|
1117
|
-
if (!authSvc)
|
|
1118
|
-
return wrapToolResult({ success: false, error: 'Auth service not available' });
|
|
1119
|
-
const userId = getUser()?.id ?? 0;
|
|
1120
|
-
const existing = authSvc.getUserView(params.id, userId);
|
|
1121
|
-
if (!existing)
|
|
1122
|
-
return wrapToolResult({ success: false, error: `View ${params.id} not found` });
|
|
1123
|
-
authSvc.deleteUserView(params.id, userId);
|
|
1124
|
-
return wrapToolResult({ success: true, message: `Deleted view "${existing.name}".` });
|
|
1125
|
-
},
|
|
1126
|
-
},
|
|
1127
1123
|
// Mark onboarding complete
|
|
1128
1124
|
{
|
|
1129
1125
|
name: 'mark_onboarded',
|