studiograph 1.3.48-next.13 → 1.3.48-next.131
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 +27 -1
- package/dist/agent/agent-pool.js +55 -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 +251 -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 +82 -23
- 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 +49 -0
- package/dist/core/secrets/index.js +74 -0
- package/dist/core/secrets/index.js.map +1 -0
- package/dist/core/secrets/master-key.d.ts +38 -0
- package/dist/core/secrets/master-key.js +122 -0
- package/dist/core/secrets/master-key.js.map +1 -0
- package/dist/core/secrets/probes/anthropic.d.ts +98 -0
- package/dist/core/secrets/probes/anthropic.js +300 -0
- package/dist/core/secrets/probes/anthropic.js.map +1 -0
- package/dist/core/secrets/probes/brave.d.ts +9 -0
- package/dist/core/secrets/probes/brave.js +15 -0
- package/dist/core/secrets/probes/brave.js.map +1 -0
- package/dist/core/secrets/probes/r2.d.ts +15 -0
- package/dist/core/secrets/probes/r2.js +14 -0
- package/dist/core/secrets/probes/r2.js.map +1 -0
- package/dist/core/secrets/probes/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 +531 -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 +385 -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 +308 -0
- package/dist/server/routes/secrets-api.js.map +1 -0
- package/dist/server/routes/settings-api.d.ts +29 -0
- package/dist/server/routes/settings-api.js +180 -0
- package/dist/server/routes/settings-api.js.map +1 -0
- package/dist/server/routes/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/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/7R0Rp3Mz.js +1 -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/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/B7L4gmPR.js +2 -0
- package/dist/web/_app/immutable/chunks/B9qBGxh62.js +3 -0
- package/dist/web/_app/immutable/chunks/BDJYj9yi.js +2 -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/BKe5wPiN.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/BiUh0Sik.js +1 -0
- package/dist/web/_app/immutable/chunks/Biajc_oU.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/BmgyOoEp.js +1 -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/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/CIchr8Tk2.js +1 -0
- package/dist/web/_app/immutable/chunks/CK_yXDQI.js +1 -0
- package/dist/web/_app/immutable/chunks/CLPtMig0.js +1 -0
- package/dist/web/_app/immutable/chunks/CLSxJmTj.js +2 -0
- package/dist/web/_app/immutable/chunks/CPQNcHIB.js +3 -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/CSGIGrrK.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/CfqjDDMu.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/ClNEskRf.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/CsXIliss.js +1 -0
- package/dist/web/_app/immutable/chunks/Ct3quP0F.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/CxalqrMB.js +1 -0
- package/dist/web/_app/immutable/chunks/D1Ap3evT2.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/DCCaoKt42.js +1 -0
- package/dist/web/_app/immutable/chunks/DDKweOZr2.js +23 -0
- package/dist/web/_app/immutable/chunks/DHeU-hHI2.js +2 -0
- package/dist/web/_app/immutable/chunks/DHepUItL.js +1 -0
- package/dist/web/_app/immutable/chunks/DL_KbCKq.js +8 -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/DZetJu9k2.js +1 -0
- package/dist/web/_app/immutable/chunks/DaiJs3St.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/Dm25ot5x2.js +1 -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/Dt4HY2cT2.js +2 -0
- package/dist/web/_app/immutable/chunks/DtGUCMv8.js +6 -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/LAN53VbP2.js +5 -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/TuBvdkhV2.js +1 -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/dTXrX5Bw.js +2 -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/q6R6T-lK.js +1 -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/vwTMEIJQ.js +1 -0
- package/dist/web/_app/immutable/chunks/w1FCELam.js +64 -0
- package/dist/web/_app/immutable/chunks/zmjgin7A.js +1 -0
- package/dist/web/_app/immutable/chunks/zumDjcgJ.js +1 -0
- package/dist/web/_app/immutable/entry/app.B3JEO5sy.js +2 -0
- package/dist/web/_app/immutable/entry/start.Dk84vnrL.js +1 -0
- package/dist/web/_app/immutable/nodes/0.BKLFgYTV.js +2 -0
- package/dist/web/_app/immutable/nodes/1.Djf_1kN1.js +1 -0
- package/dist/web/_app/immutable/nodes/10.De6eGWLx.js +1 -0
- package/dist/web/_app/immutable/nodes/11.CDsfSRTw.js +1 -0
- package/dist/web/_app/immutable/nodes/12.BeKkKpkY.js +1 -0
- package/dist/web/_app/immutable/nodes/13.BcI8xwSy.js +1 -0
- package/dist/web/_app/immutable/nodes/2.ZMZ-QAZ7.js +106 -0
- package/dist/web/_app/immutable/nodes/3.C1ZiAfle.js +2 -0
- package/dist/web/_app/immutable/nodes/4.Chmqy9KF.js +2 -0
- package/dist/web/_app/immutable/nodes/5.Bpvr_Vcq.js +1 -0
- package/dist/web/_app/immutable/nodes/6.BHa_gOs3.js +1 -0
- package/dist/web/_app/immutable/nodes/7.D0hg4Eap.js +1 -0
- package/dist/web/_app/immutable/nodes/8.3ZUUxJqR.js +1 -0
- package/dist/web/_app/immutable/nodes/9.Ducy-oqR.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
package/dist/server/index.js
CHANGED
|
@@ -4,20 +4,21 @@
|
|
|
4
4
|
* Hosts:
|
|
5
5
|
* - Graph API (read-only REST over WorkspaceManager)
|
|
6
6
|
* - Agent chat via POST /api/chat and SSE GET /api/chat/stream
|
|
7
|
-
* -
|
|
7
|
+
* - Static web UI (SvelteKit build) with SPA fallback
|
|
8
8
|
*/
|
|
9
9
|
import Fastify from 'fastify';
|
|
10
10
|
import cookie from '@fastify/cookie';
|
|
11
11
|
import cors from '@fastify/cors';
|
|
12
12
|
import websocket from '@fastify/websocket';
|
|
13
|
+
import { sanitize } from './middleware/sanitize.js';
|
|
13
14
|
import { existsSync, readFileSync, createReadStream, statSync } from 'fs';
|
|
14
|
-
import { join, extname } from 'path';
|
|
15
|
+
import { join, extname, resolve, sep } from 'path';
|
|
15
16
|
import { Workspace } from '../core/workspace.js';
|
|
16
17
|
import { AgentOrchestrator } from '../agent/orchestrator.js';
|
|
17
|
-
import { PluginLoader, MIME_TYPES } from './plugin-loader.js';
|
|
18
18
|
import { registerGraphApiRoutes } from './routes/graph-api.js';
|
|
19
19
|
import { registerChatRoutes } from './routes/chat.js';
|
|
20
20
|
import { registerWorkspaceApiRoutes } from './routes/workspace-api.js';
|
|
21
|
+
import { registerHealthApiRoutes } from './routes/health.js';
|
|
21
22
|
import { registerPermissionsApiRoutes } from './routes/permissions-api.js';
|
|
22
23
|
import { registerAuthApiRoutes } from './routes/auth-api.js';
|
|
23
24
|
import { registerGitHttpRoutes } from './routes/git-http.js';
|
|
@@ -27,36 +28,106 @@ import { registerMcpRoutes } from './routes/mcp.js';
|
|
|
27
28
|
import { registerConnectorsApiRoutes } from './routes/connectors-api.js';
|
|
28
29
|
import { registerAssetApiRoutes } from './routes/asset-api.js';
|
|
29
30
|
import multipart from '@fastify/multipart';
|
|
30
|
-
import {
|
|
31
|
+
import { registerEventIngestRoutes } from './routes/event-ingest-api.js';
|
|
31
32
|
import { registerCaptureRoutes } from './routes/capture-api.js';
|
|
32
33
|
import { registerUrlRoutes } from './routes/url-api.js';
|
|
33
34
|
import { registerMessagesApiRoutes } from './routes/messages-api.js';
|
|
34
|
-
import {
|
|
35
|
+
import { registerConfigApiRoutes } from './routes/config-api.js';
|
|
36
|
+
import { registerSettingsApiRoutes } from './routes/settings-api.js';
|
|
37
|
+
import { registerSecretsApiRoutes } from './routes/secrets-api.js';
|
|
38
|
+
import { registerAuditApiRoutes } from './routes/audit-api.js';
|
|
39
|
+
import { AuthService, isWorkspaceOwner } from '../services/auth-service.js';
|
|
35
40
|
import { MessageService } from '../services/message-service.js';
|
|
36
41
|
import { MemoryService } from '../services/memory-service.js';
|
|
37
42
|
import { WsHub } from './ws-hub.js';
|
|
38
43
|
import { registerWsRoute } from './routes/ws.js';
|
|
39
44
|
import { SessionManager } from './session-manager.js';
|
|
40
45
|
import { YjsManager } from './yjs-manager.js';
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
import { YjsPersistence, acquireYjsStateLock } from './yjs-persistence.js';
|
|
47
|
+
import { ensurePersonalFolder } from '../services/personal-folder.js';
|
|
48
|
+
/** Ensure every user has a personal "My Entries" folder + admin access on it (idempotent). */
|
|
49
|
+
async function ensureAllPersonalFolders(authService, workspacePath, workspaceManager) {
|
|
43
50
|
const users = authService.listUsers();
|
|
44
51
|
const workspace = new Workspace(workspacePath);
|
|
45
52
|
for (const user of users) {
|
|
46
|
-
if (workspaceManager.getUserPrivateRepo(user.id))
|
|
47
|
-
continue;
|
|
48
53
|
try {
|
|
49
|
-
await workspace
|
|
50
|
-
name: `entries-${user.id}`,
|
|
51
|
-
display_name: 'My Entries',
|
|
52
|
-
description: `Private entries for ${user.displayName}`,
|
|
53
|
-
private: true,
|
|
54
|
-
owner_id: user.id,
|
|
55
|
-
});
|
|
56
|
-
workspaceManager.reloadConfig();
|
|
54
|
+
await ensurePersonalFolder(workspace, authService, user);
|
|
57
55
|
}
|
|
58
|
-
catch { /*
|
|
56
|
+
catch { /* non-fatal — skip and let the user re-authenticate */ }
|
|
59
57
|
}
|
|
58
|
+
workspaceManager.reloadConfig();
|
|
59
|
+
}
|
|
60
|
+
/** MIME types for static file serving (web UI assets). */
|
|
61
|
+
const MIME_TYPES = {
|
|
62
|
+
'.html': 'text/html',
|
|
63
|
+
'.css': 'text/css',
|
|
64
|
+
'.js': 'application/javascript',
|
|
65
|
+
'.mjs': 'application/javascript',
|
|
66
|
+
'.json': 'application/json',
|
|
67
|
+
'.png': 'image/png',
|
|
68
|
+
'.jpg': 'image/jpeg',
|
|
69
|
+
'.jpeg': 'image/jpeg',
|
|
70
|
+
'.gif': 'image/gif',
|
|
71
|
+
'.svg': 'image/svg+xml',
|
|
72
|
+
'.ico': 'image/x-icon',
|
|
73
|
+
'.woff': 'font/woff',
|
|
74
|
+
'.woff2': 'font/woff2',
|
|
75
|
+
'.ttf': 'font/ttf',
|
|
76
|
+
'.otf': 'font/otf',
|
|
77
|
+
'.webp': 'image/webp',
|
|
78
|
+
'.avif': 'image/avif',
|
|
79
|
+
'.mp4': 'video/mp4',
|
|
80
|
+
'.webm': 'video/webm',
|
|
81
|
+
};
|
|
82
|
+
export function resolveStaticFilePath(webDir, urlPath) {
|
|
83
|
+
let decodedPath;
|
|
84
|
+
try {
|
|
85
|
+
decodedPath = decodeURIComponent(urlPath);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const filePath = decodedPath === '/' ? '/index.html' : decodedPath;
|
|
91
|
+
const webRoot = resolve(webDir);
|
|
92
|
+
const fullPath = resolve(webRoot, `.${filePath}`);
|
|
93
|
+
if (fullPath !== webRoot && !fullPath.startsWith(webRoot + sep)) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return fullPath;
|
|
97
|
+
}
|
|
98
|
+
function normalizeOrigin(value) {
|
|
99
|
+
if (!value)
|
|
100
|
+
return null;
|
|
101
|
+
try {
|
|
102
|
+
return new URL(value).origin;
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export function buildAllowedCorsOrigins(workspaceConfig, port) {
|
|
109
|
+
const rawOrigins = [];
|
|
110
|
+
const envOrigins = process.env.STUDIOGRAPH_CORS_ORIGINS;
|
|
111
|
+
if (envOrigins)
|
|
112
|
+
rawOrigins.push(...envOrigins.split(',').map(o => o.trim()).filter(Boolean));
|
|
113
|
+
const configured = workspaceConfig.cors_origins;
|
|
114
|
+
if (Array.isArray(configured)) {
|
|
115
|
+
rawOrigins.push(...configured.filter((o) => typeof o === 'string'));
|
|
116
|
+
}
|
|
117
|
+
else if (typeof configured === 'string') {
|
|
118
|
+
rawOrigins.push(...configured.split(',').map(o => o.trim()).filter(Boolean));
|
|
119
|
+
}
|
|
120
|
+
const serverUrl = workspaceConfig.server_url;
|
|
121
|
+
if (typeof serverUrl === 'string')
|
|
122
|
+
rawOrigins.push(serverUrl);
|
|
123
|
+
rawOrigins.push(`http://localhost:${port}`, `http://127.0.0.1:${port}`, `http://[::1]:${port}`);
|
|
124
|
+
return new Set(rawOrigins.map(normalizeOrigin).filter((o) => Boolean(o)));
|
|
125
|
+
}
|
|
126
|
+
export function isCorsOriginAllowed(origin, allowedOrigins) {
|
|
127
|
+
if (!origin)
|
|
128
|
+
return true;
|
|
129
|
+
const normalized = normalizeOrigin(origin);
|
|
130
|
+
return Boolean(normalized && allowedOrigins.has(normalized));
|
|
60
131
|
}
|
|
61
132
|
/**
|
|
62
133
|
* Auth middleware — validates JWT cookie or Authorization: Bearer <key> header.
|
|
@@ -64,7 +135,7 @@ async function ensureAllPrivateCollections(authService, workspacePath, workspace
|
|
|
64
135
|
* (except auth endpoints and static assets). When no users exist, everything
|
|
65
136
|
* is open (backward compatible).
|
|
66
137
|
*/
|
|
67
|
-
function createAuthHook(
|
|
138
|
+
function createAuthHook(authService) {
|
|
68
139
|
return async (req, reply) => {
|
|
69
140
|
// Always allow auth endpoints
|
|
70
141
|
if (req.url.startsWith('/api/auth/'))
|
|
@@ -80,27 +151,22 @@ function createAuthHook(apiKeys, authService) {
|
|
|
80
151
|
// WebSocket route handles its own auth
|
|
81
152
|
if (req.url.startsWith('/ws'))
|
|
82
153
|
return;
|
|
83
|
-
// Allow static assets (JS, CSS, fonts, images) — needed for login page
|
|
84
|
-
|
|
154
|
+
// Allow static assets (JS, CSS, fonts, images) — needed for login page.
|
|
155
|
+
// Covers SvelteKit-bundled output under /_app/ and root-level public
|
|
156
|
+
// files (favicon.ico, studiograph-logomark.svg, …) identified by a file
|
|
157
|
+
// extension on a non-API GET.
|
|
158
|
+
if (req.url.startsWith('/_app/'))
|
|
159
|
+
return;
|
|
160
|
+
if (req.method === 'GET' &&
|
|
161
|
+
!req.url.startsWith('/api/') &&
|
|
162
|
+
extname(req.url.split('?')[0]).length > 1)
|
|
85
163
|
return;
|
|
86
164
|
// Allow HTML page requests (SPA routing) — the app handles auth client-side
|
|
87
165
|
if (req.method === 'GET' && req.headers.accept?.includes('text/html'))
|
|
88
166
|
return;
|
|
89
|
-
// If no users configured, allow everything (open mode)
|
|
90
|
-
if (!authService.hasUsers())
|
|
91
|
-
// Still check API keys for programmatic routes if configured
|
|
92
|
-
if (apiKeys.length > 0) {
|
|
93
|
-
const authHeader = req.headers['authorization'];
|
|
94
|
-
const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
|
|
95
|
-
if (bearer && apiKeys.includes(bearer))
|
|
96
|
-
return;
|
|
97
|
-
// For non-API routes (i.e. browser requests), allow without auth
|
|
98
|
-
if (!req.url.startsWith('/api/') || req.url.startsWith('/api/auth/'))
|
|
99
|
-
return;
|
|
100
|
-
// For API routes without a bearer token, allow if no users exist
|
|
101
|
-
}
|
|
167
|
+
// If no users configured, allow everything (open mode — single-tenant dev)
|
|
168
|
+
if (!authService.hasUsers())
|
|
102
169
|
return;
|
|
103
|
-
}
|
|
104
170
|
// Check JWT cookie (web UI sessions)
|
|
105
171
|
const jwtToken = req.cookies?.['__sg_token'];
|
|
106
172
|
if (jwtToken) {
|
|
@@ -110,11 +176,26 @@ function createAuthHook(apiKeys, authService) {
|
|
|
110
176
|
return;
|
|
111
177
|
}
|
|
112
178
|
}
|
|
113
|
-
// Check Bearer token (API clients, MCP)
|
|
179
|
+
// Check Bearer token (API clients, MCP, CLI): JWT → per-user API token.
|
|
180
|
+
// Both yield a user identity. There is no shared workspace key — every
|
|
181
|
+
// caller must be identifiable so access control can enforce per-folder rules.
|
|
114
182
|
const authHeader = req.headers['authorization'];
|
|
115
183
|
const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
|
|
116
|
-
if (bearer
|
|
117
|
-
|
|
184
|
+
if (bearer) {
|
|
185
|
+
const jwtUser = authService.verifyToken(bearer);
|
|
186
|
+
if (jwtUser) {
|
|
187
|
+
req.user = jwtUser;
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const tokenMeta = authService.verifyApiTokenWithMeta(bearer);
|
|
191
|
+
if (tokenMeta) {
|
|
192
|
+
req.user = tokenMeta.user;
|
|
193
|
+
// Stash the token's user-set name so downstream surfaces (MCP, agent
|
|
194
|
+
// activity) can label the integration. Absent for cookie/JWT auth.
|
|
195
|
+
req.apiTokenName = tokenMeta.tokenName;
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
118
199
|
// Check Basic Auth (CLI join command)
|
|
119
200
|
if (authHeader?.startsWith('Basic ')) {
|
|
120
201
|
try {
|
|
@@ -133,22 +214,128 @@ function createAuthHook(apiKeys, authService) {
|
|
|
133
214
|
return reply.status(401).send({ error: 'Unauthorized' });
|
|
134
215
|
};
|
|
135
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Phase 11 — preSerialization payload sanitizer.
|
|
219
|
+
*
|
|
220
|
+
* The API has many routes that respond with `{ error: err.message }` from a
|
|
221
|
+
* catch block. Those messages can carry upstream provider errors, git
|
|
222
|
+
* stderr (with embedded credentials), or other free-form text that we
|
|
223
|
+
* don't want surfacing in HTTP responses. Walk the response payload,
|
|
224
|
+
* sanitize any string value at a "message" / "error" / "detail" key,
|
|
225
|
+
* and leave structured fields (status codes, IDs, classification flags)
|
|
226
|
+
* alone.
|
|
227
|
+
*
|
|
228
|
+
* Conservatively, we ONLY redact at keys that conventionally carry
|
|
229
|
+
* free-form text. Arbitrary string fields (entity names, IDs, etc.) are
|
|
230
|
+
* left untouched so we don't garble legitimate content. The Fastify
|
|
231
|
+
* logger sanitization (above) handles log-line redaction independently;
|
|
232
|
+
* this hook focuses on the wire response.
|
|
233
|
+
*/
|
|
234
|
+
const FREEFORM_ERROR_KEYS = new Set(['error', 'message', 'detail', 'stack', 'description', 'error_description']);
|
|
235
|
+
function sanitizeResponsePayload(value) {
|
|
236
|
+
if (typeof value === 'string')
|
|
237
|
+
return sanitize(value);
|
|
238
|
+
if (Array.isArray(value))
|
|
239
|
+
return value.map(sanitizeResponsePayload);
|
|
240
|
+
if (value && typeof value === 'object') {
|
|
241
|
+
const out = {};
|
|
242
|
+
for (const [k, v] of Object.entries(value)) {
|
|
243
|
+
if (FREEFORM_ERROR_KEYS.has(k) && typeof v === 'string') {
|
|
244
|
+
out[k] = sanitize(v);
|
|
245
|
+
}
|
|
246
|
+
else if (v && typeof v === 'object') {
|
|
247
|
+
out[k] = sanitizeResponsePayload(v);
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
out[k] = v;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
136
257
|
export async function createServer(config) {
|
|
258
|
+
// Phase 11: every Fastify log line flows through sanitize() before
|
|
259
|
+
// reaching stdout. A thin Writable wrapper passes each chunk through
|
|
260
|
+
// the redactor; pino accepts any `stream` with a `write()` method.
|
|
261
|
+
// STUDIOGRAPH_LOG_RAW=1 disables redaction for local debugging.
|
|
262
|
+
const shouldRedactFastifyLogs = process.env.STUDIOGRAPH_LOG_RAW !== '1' &&
|
|
263
|
+
(process.env.NODE_ENV === 'production' || !!process.env.RAILWAY_ENVIRONMENT);
|
|
264
|
+
const redactingStream = {
|
|
265
|
+
write(chunk) {
|
|
266
|
+
const out = shouldRedactFastifyLogs ? sanitize(chunk) : chunk;
|
|
267
|
+
process.stdout.write(out);
|
|
268
|
+
},
|
|
269
|
+
};
|
|
137
270
|
const fastify = Fastify({
|
|
138
271
|
logger: process.env.STUDIOGRAPH_LOG === '1'
|
|
139
|
-
?
|
|
140
|
-
: { level: 'warn' },
|
|
272
|
+
? { stream: redactingStream }
|
|
273
|
+
: { level: 'warn', stream: redactingStream },
|
|
141
274
|
bodyLimit: 10 * 1024 * 1024, // 10 MB — entities can be large (e.g. meeting transcripts)
|
|
142
275
|
});
|
|
276
|
+
// Phase 11: sanitize uncaught errors before serialization so neither
|
|
277
|
+
// err.message nor err.stack echoes upstream secrets. Stable error
|
|
278
|
+
// codes (err.code) pass through; we only redact freeform text.
|
|
279
|
+
fastify.setErrorHandler((error, _req, reply) => {
|
|
280
|
+
const sanitizedMsg = shouldRedactFastifyLogs ? sanitize(error.message) : error.message;
|
|
281
|
+
const status = error.statusCode ?? 500;
|
|
282
|
+
fastify.log.error({
|
|
283
|
+
err: { message: sanitizedMsg, code: error.code },
|
|
284
|
+
});
|
|
285
|
+
reply.status(status).send({
|
|
286
|
+
statusCode: status,
|
|
287
|
+
code: error.code,
|
|
288
|
+
error: status >= 500 ? 'Internal Server Error' : (error.name || 'Error'),
|
|
289
|
+
message: status >= 500 ? 'An internal error occurred.' : sanitizedMsg,
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
// Phase 11: pre-serialization hook scans every response body for
|
|
293
|
+
// freeform error/message strings and runs them through sanitize().
|
|
294
|
+
// This catches the many `reply.status(4xx).send({ error: err.message })`
|
|
295
|
+
// call sites scattered across the API routes — without this, an
|
|
296
|
+
// upstream provider error or git remote error would echo through to
|
|
297
|
+
// the API consumer with embedded credentials. Stable error codes pass
|
|
298
|
+
// through unchanged. Only kicks in when redaction is enabled.
|
|
299
|
+
if (shouldRedactFastifyLogs) {
|
|
300
|
+
fastify.addHook('preSerialization', async (_req, _reply, payload) => {
|
|
301
|
+
if (!payload || typeof payload !== 'object')
|
|
302
|
+
return payload;
|
|
303
|
+
return sanitizeResponsePayload(payload);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
143
306
|
// CORS
|
|
307
|
+
const allowedCorsOrigins = buildAllowedCorsOrigins(config.workspaceConfig, config.port);
|
|
144
308
|
await fastify.register(cors, {
|
|
145
|
-
origin:
|
|
309
|
+
origin: (origin, cb) => {
|
|
310
|
+
cb(null, isCorsOriginAllowed(origin, allowedCorsOrigins));
|
|
311
|
+
},
|
|
146
312
|
credentials: true,
|
|
147
313
|
});
|
|
148
314
|
// Cookie support for web UI session auth
|
|
149
315
|
await fastify.register(cookie);
|
|
150
|
-
// WebSocket support for real-time notifications
|
|
151
|
-
|
|
316
|
+
// WebSocket support for real-time notifications.
|
|
317
|
+
//
|
|
318
|
+
// perMessageDeflate is enabled here on purpose. Our origin would otherwise
|
|
319
|
+
// leave compression off (ws lib default), but Railway's edge proxy
|
|
320
|
+
// negotiates `permessage-deflate` with the browser anyway and does its own
|
|
321
|
+
// inflate/deflate layer in the middle — which Safari/WebKit mis-decodes,
|
|
322
|
+
// producing truncated buffers and `RangeError: Length out of range of buffer`
|
|
323
|
+
// inside Yjs's varint reader, followed by WS disconnect loops.
|
|
324
|
+
//
|
|
325
|
+
// Negotiating compression at the origin forces end-to-end deflate (Node's
|
|
326
|
+
// zlib ↔ browser) and prevents the proxy from inserting its own layer.
|
|
327
|
+
// `noContextTakeover` on both sides keeps each frame independently
|
|
328
|
+
// decompressible, which avoids cross-frame state bugs that have historically
|
|
329
|
+
// hit Safari.
|
|
330
|
+
await fastify.register(websocket, {
|
|
331
|
+
options: {
|
|
332
|
+
perMessageDeflate: {
|
|
333
|
+
threshold: 1024,
|
|
334
|
+
serverNoContextTakeover: true,
|
|
335
|
+
clientNoContextTakeover: true,
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
});
|
|
152
339
|
// Multipart support for file uploads (images, assets)
|
|
153
340
|
await fastify.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
|
|
154
341
|
fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, (req, body, done) => {
|
|
@@ -169,28 +356,76 @@ export async function createServer(config) {
|
|
|
169
356
|
done(null); // Don't consume the body — the route handler pipes req.raw directly
|
|
170
357
|
});
|
|
171
358
|
}
|
|
172
|
-
// Initialize auth service, WebSocket hub, session manager, and collab server
|
|
173
|
-
|
|
174
|
-
//
|
|
175
|
-
authService.
|
|
176
|
-
// Ensure all users have their
|
|
177
|
-
await
|
|
178
|
-
const
|
|
359
|
+
// Initialize auth service, WebSocket hub, session manager, and collab server.
|
|
360
|
+
// Phase 8: when the boot path provided master-key options, hand them through
|
|
361
|
+
// so OAuth tokens + per-user secret prefs use the encrypted column path.
|
|
362
|
+
const authService = new AuthService(config.workspacePath, config.authCryptoOptions);
|
|
363
|
+
// Ensure all users have their personal "My Entries" folder
|
|
364
|
+
await ensureAllPersonalFolders(authService, config.workspacePath, config.workspaceManager);
|
|
365
|
+
const { getCurrentVersion } = await import('../utils/version-checker.js');
|
|
366
|
+
const wsHub = new WsHub(getCurrentVersion());
|
|
179
367
|
const messageService = new MessageService(config.workspacePath);
|
|
180
368
|
const sessionManager = new SessionManager(config.workspaceManager, wsHub);
|
|
181
|
-
|
|
369
|
+
// Recover any dirty repos before accepting requests. Replays persisted
|
|
370
|
+
// pending commits from a previous process AND sweeps every working tree
|
|
371
|
+
// for uncommitted state. Catches anything dropped by a crash, OOM, or
|
|
372
|
+
// hard restart. Logs and continues on failure — recovery is best-effort
|
|
373
|
+
// and must never block server startup.
|
|
374
|
+
try {
|
|
375
|
+
await sessionManager.recoverOnBoot();
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
console.warn('[server] sessionManager.recoverOnBoot failed:', err.message);
|
|
379
|
+
}
|
|
380
|
+
// Persistence layer: durable Y.Doc snapshot store across server restarts.
|
|
381
|
+
// Lives at `<workspace>/.studiograph/yjs-state/` — gitignored binary state
|
|
382
|
+
// separate from the .md files (which remain canonical for git, MCP, agents).
|
|
383
|
+
// See yjs-persistence.ts for the file format and concurrency model.
|
|
384
|
+
const yjsStateDir = join(config.workspacePath, '.studiograph', 'yjs-state');
|
|
385
|
+
// Single-instance lock. Throws if another studiograph server is already
|
|
386
|
+
// running against this workspace. We don't support horizontal scaling today
|
|
387
|
+
// (no shared Yjs pubsub), so the safe default is to fail fast on misuse
|
|
388
|
+
// rather than silently corrupt snapshots via concurrent writers.
|
|
389
|
+
const releaseYjsLock = acquireYjsStateLock(yjsStateDir);
|
|
390
|
+
const yjsPersistence = new YjsPersistence(yjsStateDir);
|
|
391
|
+
const yjsManager = new YjsManager(config.workspaceManager, yjsPersistence);
|
|
392
|
+
// Wire the Yjs persistence layer to follow structural .md mutations.
|
|
393
|
+
// delete / rename / changeType all change a doc's identity (path on disk
|
|
394
|
+
// and its docName), so the snapshot file has to move with it. Without
|
|
395
|
+
// these hooks, snapshots leak (orphaned files for deleted entities) or
|
|
396
|
+
// serve stale state at the new identity (ghost content after a rename).
|
|
397
|
+
config.workspaceManager.setGraphMutationCallbacks({
|
|
398
|
+
onDelete: (repo, entityType, entityId) => yjsPersistence.delete(`${repo}/${entityType}/${entityId}`),
|
|
399
|
+
onRename: (repo, entityType, oldId, newId) => yjsPersistence.rename(`${repo}/${entityType}/${oldId}`, `${repo}/${entityType}/${newId}`),
|
|
400
|
+
onChangeType: (repo, entityId, fromType, toType) => yjsPersistence.rename(`${repo}/${fromType}/${entityId}`, `${repo}/${toType}/${entityId}`),
|
|
401
|
+
// Smart-merge the just-written .md content into the active Y.Doc. Without
|
|
402
|
+
// this, server-side bypass writes (MCP update_entity, agent tools,
|
|
403
|
+
// event processor) get silently overwritten by the next autosave PUT
|
|
404
|
+
// carrying stale Y.Text content. Sync — must complete before any await
|
|
405
|
+
// yields in graph.update so a concurrent autosave can't race in.
|
|
406
|
+
onContentUpdate: (repo, entityType, entityId) => yjsManager.syncDocFromDisk(`${repo}/${entityType}/${entityId}`),
|
|
407
|
+
});
|
|
182
408
|
// Register auth API routes (before the auth hook so they are always accessible)
|
|
183
409
|
await registerAuthApiRoutes(fastify, authService, config.workspacePath, config.workspaceManager, config.workspaceConfig.team_name);
|
|
184
410
|
// Auth hook — applied to all routes
|
|
185
|
-
const authHook = createAuthHook(
|
|
411
|
+
const authHook = createAuthHook(authService);
|
|
186
412
|
fastify.addHook('preHandler', authHook);
|
|
187
413
|
// Register WebSocket route (real-time change notifications + cursor broadcasting)
|
|
188
|
-
await registerWsRoute(fastify, wsHub, authService, yjsManager);
|
|
189
|
-
// Register graph API routes (with per-
|
|
190
|
-
await registerGraphApiRoutes(fastify, config.workspaceManager, authService, wsHub, sessionManager);
|
|
414
|
+
await registerWsRoute(fastify, wsHub, authService, config.workspaceManager, yjsManager);
|
|
415
|
+
// Register graph API routes (with per-folder access filtering)
|
|
416
|
+
await registerGraphApiRoutes(fastify, config.workspaceManager, authService, wsHub, sessionManager, yjsManager);
|
|
191
417
|
// Register workspace API routes (git operations)
|
|
192
|
-
await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser);
|
|
193
|
-
// Register
|
|
418
|
+
await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser, authService);
|
|
419
|
+
// Register health endpoints (per-repo dirty status)
|
|
420
|
+
await registerHealthApiRoutes(fastify, config.workspaceManager, sessionManager);
|
|
421
|
+
// Register config + workspace data API routes (for `studiograph push/pull --remote`)
|
|
422
|
+
await registerConfigApiRoutes(fastify, config.workspaceManager, config.workspacePath, authService);
|
|
423
|
+
// Register Phase 7 settings/secrets/audit API routes. Owner-only via
|
|
424
|
+
// isWorkspaceOwner() inside each handler.
|
|
425
|
+
await registerSettingsApiRoutes(fastify, authService);
|
|
426
|
+
await registerSecretsApiRoutes(fastify, authService);
|
|
427
|
+
await registerAuditApiRoutes(fastify, authService);
|
|
428
|
+
// Register permissions API routes (self-hosted folder access)
|
|
194
429
|
await registerPermissionsApiRoutes(fastify, authService, config.workspaceManager, wsHub);
|
|
195
430
|
// Messages API routes registered after agent init (below) so @agent invocation works
|
|
196
431
|
// Register connectors API routes (MCP connector management + OAuth)
|
|
@@ -236,7 +471,21 @@ export async function createServer(config) {
|
|
|
236
471
|
await registerBriefingApiRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub, getToolsForUser);
|
|
237
472
|
// Background briefing refresh — check staleness for online users every heartbeat tick
|
|
238
473
|
{
|
|
239
|
-
|
|
474
|
+
/** Format a Date as YYYY-MM-DD in the given IANA timezone. Falls back to
|
|
475
|
+
* UTC when the timezone is invalid so we never crash on bad input. */
|
|
476
|
+
const localDateIn = (d, tz) => {
|
|
477
|
+
try {
|
|
478
|
+
return new Intl.DateTimeFormat('en-CA', {
|
|
479
|
+
timeZone: tz,
|
|
480
|
+
year: 'numeric',
|
|
481
|
+
month: '2-digit',
|
|
482
|
+
day: '2-digit',
|
|
483
|
+
}).format(d);
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
return d.toISOString().slice(0, 10);
|
|
487
|
+
}
|
|
488
|
+
};
|
|
240
489
|
const loadWsConfig = () => {
|
|
241
490
|
const cfgPath = join(config.workspacePath, '.studiograph', 'workspace.json');
|
|
242
491
|
if (!existsSync(cfgPath))
|
|
@@ -252,22 +501,26 @@ export async function createServer(config) {
|
|
|
252
501
|
const allRepos = config.workspaceManager.getAllRepoConfigs();
|
|
253
502
|
const user = authService.findUserById(userId);
|
|
254
503
|
if (!user)
|
|
255
|
-
return allRepos.filter(r => !r.
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return allRepos.filter(r => (r.private && r.owner_id === user.id) || allowed.has(r.name)).map(r => r.name);
|
|
504
|
+
return allRepos.filter(r => !r.personal).map(r => r.name);
|
|
505
|
+
// Folder membership is the sole source of truth — no role-based short-circuit.
|
|
506
|
+
const allowed = new Set(authService.getUserFolders(user.id));
|
|
507
|
+
return allRepos.filter(r => allowed.has(r.name)).map(r => r.name);
|
|
260
508
|
};
|
|
261
|
-
wsHub.setBriefingRefresh((userId) => {
|
|
509
|
+
wsHub.setBriefingRefresh((userId, tz) => {
|
|
262
510
|
const brief = authService.getHomeBrief(userId);
|
|
263
511
|
if (!brief)
|
|
264
512
|
return false;
|
|
265
513
|
// Always regenerate if no briefing text exists yet (migration from old insights system)
|
|
266
514
|
const cached = authService.getCachedBriefing(userId);
|
|
267
|
-
if (!cached.briefingText)
|
|
515
|
+
if (!cached.briefingText || !cached.generatedAt)
|
|
268
516
|
return true;
|
|
269
|
-
|
|
270
|
-
|
|
517
|
+
// Stale when the cached briefing was generated on an earlier calendar
|
|
518
|
+
// date in the user's local timezone. This anchors "daily briefing"
|
|
519
|
+
// to the user's morning rather than a rolling 24h window, and aligns
|
|
520
|
+
// with the chat session's local-calendar-day rollover.
|
|
521
|
+
const cachedLocal = localDateIn(new Date(cached.generatedAt), tz);
|
|
522
|
+
const todayLocal = localDateIn(new Date(), tz);
|
|
523
|
+
return cachedLocal < todayLocal;
|
|
271
524
|
}, async (userId) => {
|
|
272
525
|
const brief = authService.getHomeBrief(userId);
|
|
273
526
|
const repoNames = getReposForUser(userId);
|
|
@@ -283,43 +536,11 @@ export async function createServer(config) {
|
|
|
283
536
|
}
|
|
284
537
|
});
|
|
285
538
|
}
|
|
286
|
-
// Register
|
|
287
|
-
await
|
|
539
|
+
// Register event ingest API (meeting capture from Chrome extension + desktop tray)
|
|
540
|
+
await registerEventIngestRoutes(fastify, config.workspaceManager, authService, wsHub, yjsManager);
|
|
288
541
|
// Register MCP Streamable HTTP endpoint
|
|
289
|
-
await registerMcpRoutes(fastify, config.workspaceManager, authService);
|
|
290
|
-
//
|
|
291
|
-
const chromeDir = join(import.meta.dirname, 'chrome');
|
|
292
|
-
if (existsSync(chromeDir)) {
|
|
293
|
-
const CHROME_MIME = { '.js': 'application/javascript', '.css': 'text/css' };
|
|
294
|
-
fastify.get('/api/chrome/:file', async (req, reply) => {
|
|
295
|
-
const file = req.params.file;
|
|
296
|
-
if (file.includes('..') || file.includes('/')) {
|
|
297
|
-
return reply.status(400).send({ error: 'Invalid path' });
|
|
298
|
-
}
|
|
299
|
-
const filePath = join(chromeDir, file);
|
|
300
|
-
if (!existsSync(filePath) || !statSync(filePath).isFile()) {
|
|
301
|
-
return reply.status(404).send({ error: 'Not found' });
|
|
302
|
-
}
|
|
303
|
-
const ext = extname(filePath).toLowerCase();
|
|
304
|
-
reply.type(CHROME_MIME[ext] || 'application/octet-stream');
|
|
305
|
-
reply.header('Cache-Control', 'public, max-age=300');
|
|
306
|
-
return reply.send(createReadStream(filePath));
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
// Discover installed apps and collect their skill/tool dirs
|
|
310
|
-
const loader = new PluginLoader();
|
|
311
|
-
const manifests = loader.loadApps(config.appsDir);
|
|
312
|
-
const appSkillsDirs = [];
|
|
313
|
-
const appToolsDirs = [];
|
|
314
|
-
for (const manifest of manifests) {
|
|
315
|
-
const skillsDir = loader.getSkillsDir(config.appsDir, manifest);
|
|
316
|
-
if (skillsDir)
|
|
317
|
-
appSkillsDirs.push(skillsDir);
|
|
318
|
-
const toolsDir = loader.getToolsDir(config.appsDir, manifest);
|
|
319
|
-
if (toolsDir)
|
|
320
|
-
appToolsDirs.push(toolsDir);
|
|
321
|
-
}
|
|
322
|
-
// Initialize memory service and agent — non-fatal so the server can still serve graph API and apps
|
|
542
|
+
await registerMcpRoutes(fastify, config.workspaceManager, authService, wsHub);
|
|
543
|
+
// Initialize memory service and agent — non-fatal so the server can still serve graph API
|
|
323
544
|
const memoryService = new MemoryService();
|
|
324
545
|
let agent = null;
|
|
325
546
|
try {
|
|
@@ -328,13 +549,16 @@ export async function createServer(config) {
|
|
|
328
549
|
workspacePath: config.workspacePath,
|
|
329
550
|
workspaceConfig: config.workspaceConfig,
|
|
330
551
|
gitUser: config.gitUser,
|
|
331
|
-
skillsDirs: appSkillsDirs,
|
|
332
|
-
toolsDirs: appToolsDirs,
|
|
333
552
|
recentMemory,
|
|
334
553
|
workspaceManager: config.workspaceManager,
|
|
335
554
|
messageService,
|
|
555
|
+
// Y.Doc reconciliation now happens at the graph layer via the
|
|
556
|
+
// onContentUpdate callback (see setGraphMutationCallbacks above).
|
|
557
|
+
// Every graph.update() that doesn't explicitly opt out of Yjs sync
|
|
558
|
+
// (skipYjsSync) fires it, so the agent gets it for free without
|
|
559
|
+
// wiring an orchestrator-level hook.
|
|
336
560
|
});
|
|
337
|
-
await registerChatRoutes(fastify, agent, memoryService);
|
|
561
|
+
await registerChatRoutes(fastify, agent, wsHub, authService, memoryService);
|
|
338
562
|
await registerCaptureRoutes(fastify, agent);
|
|
339
563
|
await registerUrlRoutes(fastify);
|
|
340
564
|
}
|
|
@@ -358,63 +582,30 @@ export async function createServer(config) {
|
|
|
358
582
|
let heartbeatService = null;
|
|
359
583
|
try {
|
|
360
584
|
const { HeartbeatService } = await import('../services/heartbeat.js');
|
|
361
|
-
heartbeatService = new HeartbeatService(messageService, config.workspaceManager, wsHub,
|
|
585
|
+
heartbeatService = new HeartbeatService(messageService, config.workspaceManager, wsHub, agent ?? null);
|
|
362
586
|
heartbeatService.start();
|
|
363
587
|
}
|
|
364
588
|
catch (err) {
|
|
365
589
|
fastify.log.warn(`Heartbeat not available: ${err.message}`);
|
|
366
590
|
}
|
|
367
|
-
// Register messages API routes (
|
|
591
|
+
// Register messages API routes (folder-scoped messaging with @agent support)
|
|
368
592
|
await registerMessagesApiRoutes(fastify, messageService, authService, wsHub, config.workspaceManager, agent, heartbeatService);
|
|
369
|
-
// GET /api/apps — list installed app manifests with resolved entity type names
|
|
370
|
-
const resolvedApps = manifests.map(m => {
|
|
371
|
-
let entityTypes = [];
|
|
372
|
-
try {
|
|
373
|
-
const etPath = join(config.appsDir, m.name, m.entityTypes);
|
|
374
|
-
if (existsSync(etPath)) {
|
|
375
|
-
const raw = JSON.parse(readFileSync(etPath, 'utf-8'));
|
|
376
|
-
if (Array.isArray(raw)) {
|
|
377
|
-
entityTypes = raw.map((item) => item.name).filter(Boolean);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
catch {
|
|
382
|
-
// gracefully degrade — return empty array
|
|
383
|
-
}
|
|
384
|
-
return { name: m.name, version: m.version, description: m.description, mountPath: m.mountPath, entityTypes };
|
|
385
|
-
});
|
|
386
|
-
fastify.get('/api/apps', async (_req, reply) => {
|
|
387
|
-
return reply.send(resolvedApps);
|
|
388
|
-
});
|
|
389
593
|
// GET /api/workspace — workspace metadata
|
|
390
594
|
fastify.get('/api/workspace', async (_req, reply) => {
|
|
391
595
|
const workspace = new Workspace(config.workspacePath);
|
|
392
596
|
const about = workspace.loadAbout();
|
|
393
|
-
return reply.send({ name: config.workspaceConfig.team_name, about
|
|
597
|
+
return reply.send({ name: config.workspaceConfig.team_name, about });
|
|
394
598
|
});
|
|
395
|
-
// PUT /api/workspace — update workspace identity (
|
|
599
|
+
// PUT /api/workspace — update workspace identity (owner only)
|
|
396
600
|
fastify.put('/api/workspace', async (req, reply) => {
|
|
397
601
|
const user = req.user;
|
|
398
|
-
if (user && !
|
|
399
|
-
return reply.status(403).send({ error: '
|
|
602
|
+
if (user && !isWorkspaceOwner(user.role)) {
|
|
603
|
+
return reply.status(403).send({ error: 'Workspace owner access required' });
|
|
400
604
|
}
|
|
401
|
-
const { name, about
|
|
605
|
+
const { name, about } = req.body ?? {};
|
|
402
606
|
const workspace = new Workspace(config.workspacePath);
|
|
403
|
-
let configChanged = false;
|
|
404
607
|
if (typeof name === 'string' && name.trim()) {
|
|
405
608
|
config.workspaceConfig.team_name = name.trim();
|
|
406
|
-
configChanged = true;
|
|
407
|
-
}
|
|
408
|
-
if (accent_color !== undefined) {
|
|
409
|
-
if (accent_color === null) {
|
|
410
|
-
delete config.workspaceConfig.accent_color;
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
config.workspaceConfig.accent_color = accent_color;
|
|
414
|
-
}
|
|
415
|
-
configChanged = true;
|
|
416
|
-
}
|
|
417
|
-
if (configChanged) {
|
|
418
609
|
workspace.writeConfig(config.workspaceConfig);
|
|
419
610
|
}
|
|
420
611
|
if (typeof about === 'string') {
|
|
@@ -422,24 +613,28 @@ export async function createServer(config) {
|
|
|
422
613
|
}
|
|
423
614
|
return reply.send({ success: true });
|
|
424
615
|
});
|
|
425
|
-
// GET /api/workspace/mcp-config — MCP client configuration snippet
|
|
616
|
+
// GET /api/workspace/mcp-config — MCP client configuration snippet.
|
|
617
|
+
// Returns a template with `<your-token-here>` in the Authorization header;
|
|
618
|
+
// the frontend fills it in after the user mints a personal token via
|
|
619
|
+
// POST /api/auth/tokens. We never embed a shared key here because doing so
|
|
620
|
+
// would leak a workspace-wide credential and re-introduce the bug the
|
|
621
|
+
// per-user-token model exists to solve.
|
|
426
622
|
fastify.get('/api/workspace/mcp-config', async (req, reply) => {
|
|
427
623
|
const proto = req.headers['x-forwarded-proto'] === 'https' ? 'https' : (req.protocol ?? 'http');
|
|
428
624
|
const host = req.headers['x-forwarded-host'] || req.headers.host || 'localhost';
|
|
429
625
|
const baseUrl = `${proto}://${host}`;
|
|
430
|
-
const apiKey = authService.getApiKey();
|
|
431
626
|
const mcpConfig = {
|
|
432
627
|
mcpServers: {
|
|
433
628
|
studiograph: {
|
|
434
629
|
type: 'streamable-http',
|
|
435
630
|
url: `${baseUrl}/mcp`,
|
|
436
631
|
headers: {
|
|
437
|
-
Authorization:
|
|
632
|
+
Authorization: 'Bearer <your-token-here>',
|
|
438
633
|
},
|
|
439
634
|
},
|
|
440
635
|
},
|
|
441
636
|
};
|
|
442
|
-
return reply.send({ config: mcpConfig });
|
|
637
|
+
return reply.send({ config: mcpConfig, url: `${baseUrl}/mcp` });
|
|
443
638
|
});
|
|
444
639
|
// DELETE /api/memory — clear all agent memory files
|
|
445
640
|
fastify.delete('/api/memory', async (_req, reply) => {
|
|
@@ -451,19 +646,6 @@ export async function createServer(config) {
|
|
|
451
646
|
const count = agent?.clearSessions() ?? 0;
|
|
452
647
|
return reply.send({ cleared: count });
|
|
453
648
|
});
|
|
454
|
-
// Mount app plugins
|
|
455
|
-
for (const manifest of manifests) {
|
|
456
|
-
try {
|
|
457
|
-
await loader.mountPlugin(fastify, manifest, config.appsDir, {
|
|
458
|
-
workspaceManager: config.workspaceManager,
|
|
459
|
-
gitUser: config.gitUser,
|
|
460
|
-
});
|
|
461
|
-
fastify.log.info(`Mounted app "${manifest.name}" at ${manifest.mountPath}`);
|
|
462
|
-
}
|
|
463
|
-
catch (err) {
|
|
464
|
-
fastify.log.error(err, `Failed to mount app "${manifest.name}"`);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
649
|
// Serve web UI static files from dist/web/ with SPA fallback
|
|
468
650
|
// When running via tsx from source, import.meta.dirname is src/server/ so ../web doesn't exist.
|
|
469
651
|
// Fall back to dist/web/ relative to project root.
|
|
@@ -471,12 +653,34 @@ export async function createServer(config) {
|
|
|
471
653
|
const webDir = existsSync(webDirCandidate) ? webDirCandidate : join(import.meta.dirname, '..', '..', 'dist', 'web');
|
|
472
654
|
if (existsSync(webDir)) {
|
|
473
655
|
const indexPath = join(webDir, 'index.html');
|
|
474
|
-
// SPA fallback
|
|
475
|
-
//
|
|
476
|
-
// refreshes a URL like /documents/document/doc-123 — the app's greedy route
|
|
477
|
-
// catches it but fails because the params don't match its expectations.
|
|
656
|
+
// SPA fallback: if any API route returns a JSON error for a browser GET,
|
|
657
|
+
// serve the SPA instead so client-side routing can handle the URL.
|
|
478
658
|
// Read fresh from disk each time so rebuilds take effect without server restart.
|
|
479
659
|
const readIndexHtml = () => readFileSync(indexPath);
|
|
660
|
+
/**
|
|
661
|
+
* Cache policy for static assets:
|
|
662
|
+
* - `/_app/immutable/*` are content-hashed by SvelteKit, so the URL
|
|
663
|
+
* changes every time the file does — safe to cache forever.
|
|
664
|
+
* - `index.html` (and the SPA fallback) MUST revalidate every load,
|
|
665
|
+
* otherwise stale HTML keeps pointing at expired immutable hashes.
|
|
666
|
+
* - Other root assets (favicons, og images, etc.) get a modest TTL.
|
|
667
|
+
*
|
|
668
|
+
* Without these headers the upstream CDN (Fastly in front of Railway)
|
|
669
|
+
* forwards almost every request to origin, producing multi-second
|
|
670
|
+
* TTFB on cold edges and a 3-5s "black screen" while the SPA bundle
|
|
671
|
+
* loads.
|
|
672
|
+
*/
|
|
673
|
+
function setStaticCacheHeader(reply, urlPath) {
|
|
674
|
+
if (urlPath.startsWith('/_app/immutable/')) {
|
|
675
|
+
reply.header('Cache-Control', 'public, max-age=31536000, immutable');
|
|
676
|
+
}
|
|
677
|
+
else if (urlPath === '/' || urlPath === '/index.html' || !extname(urlPath)) {
|
|
678
|
+
reply.header('Cache-Control', 'no-cache');
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
reply.header('Cache-Control', 'public, max-age=3600');
|
|
682
|
+
}
|
|
683
|
+
}
|
|
480
684
|
fastify.addHook('onSend', async (request, reply, payload) => {
|
|
481
685
|
if (reply.sent)
|
|
482
686
|
return payload;
|
|
@@ -487,23 +691,24 @@ export async function createServer(config) {
|
|
|
487
691
|
typeof ct === 'string' && ct.includes('application/json')) {
|
|
488
692
|
reply.removeHeader('content-length');
|
|
489
693
|
reply.code(200).type('text/html');
|
|
694
|
+
reply.header('Cache-Control', 'no-cache');
|
|
490
695
|
return readIndexHtml();
|
|
491
696
|
}
|
|
492
697
|
return payload;
|
|
493
698
|
});
|
|
494
|
-
// Use setNotFoundHandler so
|
|
699
|
+
// Use setNotFoundHandler so API routes take priority over SPA fallback
|
|
495
700
|
fastify.setNotFoundHandler(async (req, reply) => {
|
|
496
701
|
const urlPath = req.url.split('?')[0];
|
|
497
|
-
const
|
|
498
|
-
|
|
702
|
+
const fullPath = resolveStaticFilePath(webDir, urlPath);
|
|
703
|
+
if (!fullPath) {
|
|
704
|
+
return reply.status(400).send({ error: 'Invalid path' });
|
|
705
|
+
}
|
|
499
706
|
// Serve the file if it exists (and is a file, not directory)
|
|
500
707
|
if (existsSync(fullPath) && statSync(fullPath).isFile()) {
|
|
501
|
-
if (fullPath.includes('..')) {
|
|
502
|
-
return reply.status(400).send({ error: 'Invalid path' });
|
|
503
|
-
}
|
|
504
708
|
const ext = extname(fullPath).toLowerCase();
|
|
505
709
|
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
506
710
|
reply.type(contentType);
|
|
711
|
+
setStaticCacheHeader(reply, urlPath);
|
|
507
712
|
return reply.send(createReadStream(fullPath));
|
|
508
713
|
}
|
|
509
714
|
// SPA fallback — serve index.html for client-side routing.
|
|
@@ -513,18 +718,21 @@ export async function createServer(config) {
|
|
|
513
718
|
const hasFileExt = extname(urlPath).length > 1;
|
|
514
719
|
if (req.method === 'GET' && !hasFileExt && existsSync(indexPath)) {
|
|
515
720
|
reply.type('text/html');
|
|
721
|
+
reply.header('Cache-Control', 'no-cache');
|
|
516
722
|
return reply.send(createReadStream(indexPath));
|
|
517
723
|
}
|
|
518
724
|
return reply.status(404).send({ error: 'Not found' });
|
|
519
725
|
});
|
|
520
726
|
fastify.log.info('Web UI enabled — serving from dist/web/');
|
|
521
727
|
}
|
|
522
|
-
// Graceful shutdown
|
|
728
|
+
// Graceful shutdown — sessionManager.shutdown() flushes pending commits
|
|
729
|
+
// BEFORE tearing down the timer (the old destroy()-only path could lose
|
|
730
|
+
// dirty sessions if called without an explicit flush).
|
|
523
731
|
fastify.addHook('onClose', async () => {
|
|
524
|
-
await sessionManager.
|
|
525
|
-
|
|
526
|
-
yjsManager.destroy();
|
|
732
|
+
await sessionManager.shutdown();
|
|
733
|
+
await yjsManager.destroy();
|
|
527
734
|
wsHub.destroy();
|
|
735
|
+
releaseYjsLock();
|
|
528
736
|
});
|
|
529
737
|
return fastify;
|
|
530
738
|
}
|