studiograph 1.3.48-next.13 → 1.3.48-next.130
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/agent/agent-pool.d.ts +14 -1
- package/dist/agent/agent-pool.js +37 -12
- package/dist/agent/agent-pool.js.map +1 -1
- package/dist/agent/followups.d.ts +34 -0
- package/dist/agent/followups.js +52 -0
- package/dist/agent/followups.js.map +1 -0
- package/dist/agent/orchestrator.d.ts +29 -2
- package/dist/agent/orchestrator.js +239 -38
- package/dist/agent/orchestrator.js.map +1 -1
- package/dist/agent/prompts/entity-types-section.d.ts +30 -0
- package/dist/agent/prompts/entity-types-section.js +83 -0
- package/dist/agent/prompts/entity-types-section.js.map +1 -0
- package/dist/agent/prompts/system.md +106 -47
- package/dist/agent/skill-loader.d.ts +30 -17
- package/dist/agent/skill-loader.js +63 -30
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/skills/entity-schema.md +79 -343
- package/dist/agent/skills/interview/entity-templates.md +38 -37
- package/dist/agent/skills/interview/question-domains.md +54 -49
- package/dist/agent/skills/interview/skill.md +89 -14
- package/dist/agent/tools/capture-tools.d.ts +31 -0
- package/dist/agent/tools/capture-tools.js +40 -0
- package/dist/agent/tools/capture-tools.js.map +1 -0
- package/dist/agent/tools/folder-tools.d.ts +47 -0
- package/dist/agent/tools/folder-tools.js +249 -0
- package/dist/agent/tools/folder-tools.js.map +1 -0
- package/dist/agent/tools/fs-tools.d.ts +6 -5
- package/dist/agent/tools/fs-tools.js +5 -5
- package/dist/agent/tools/fs-tools.js.map +1 -1
- package/dist/agent/tools/graph-tools.d.ts +25 -72
- package/dist/agent/tools/graph-tools.js +362 -366
- package/dist/agent/tools/graph-tools.js.map +1 -1
- package/dist/agent/tools/history-tools.d.ts +95 -0
- package/dist/agent/tools/history-tools.js +461 -0
- package/dist/agent/tools/history-tools.js.map +1 -0
- package/dist/agent/tools/load-skill.d.ts +6 -5
- package/dist/agent/tools/load-skill.js +3 -3
- package/dist/agent/tools/load-skill.js.map +1 -1
- package/dist/agent/tools/message-tools.d.ts +13 -11
- package/dist/agent/tools/message-tools.js +31 -39
- package/dist/agent/tools/message-tools.js.map +1 -1
- package/dist/agent/tools/ops-tools.d.ts +5 -4
- package/dist/agent/tools/ops-tools.js +99 -212
- package/dist/agent/tools/ops-tools.js.map +1 -1
- package/dist/agent/tools/permission-tools.d.ts +39 -16
- package/dist/agent/tools/permission-tools.js +66 -41
- package/dist/agent/tools/permission-tools.js.map +1 -1
- package/dist/agent/tools/tool-loader.js +5 -4
- package/dist/agent/tools/tool-loader.js.map +1 -1
- package/dist/agent/tools/web-tools.js +58 -9
- package/dist/agent/tools/web-tools.js.map +1 -1
- package/dist/cli/commands/about.d.ts +1 -0
- package/dist/cli/commands/about.js +55 -3
- package/dist/cli/commands/about.js.map +1 -1
- package/dist/cli/commands/audit.d.ts +21 -0
- package/dist/cli/commands/audit.js +174 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/clear.d.ts +5 -0
- package/dist/cli/commands/clear.js +144 -1
- package/dist/cli/commands/clear.js.map +1 -1
- package/dist/cli/commands/clone.d.ts +1 -1
- package/dist/cli/commands/clone.js +47 -12
- package/dist/cli/commands/clone.js.map +1 -1
- package/dist/cli/commands/deploy.js +79 -18
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/folder.d.ts +11 -0
- package/dist/cli/commands/folder.js +186 -0
- package/dist/cli/commands/folder.js.map +1 -0
- package/dist/cli/commands/index.js +2 -2
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.js +16 -14
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/join.d.ts +1 -1
- package/dist/cli/commands/join.js +26 -14
- package/dist/cli/commands/join.js.map +1 -1
- package/dist/cli/commands/mcp.js +12 -4
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/r2.d.ts +3 -0
- package/dist/cli/commands/r2.js +196 -1
- package/dist/cli/commands/r2.js.map +1 -1
- package/dist/cli/commands/redeploy.js +41 -1
- package/dist/cli/commands/redeploy.js.map +1 -1
- package/dist/cli/commands/secrets.d.ts +23 -0
- package/dist/cli/commands/secrets.js +256 -0
- package/dist/cli/commands/secrets.js.map +1 -0
- package/dist/cli/commands/serve.js +143 -24
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/start.js +140 -71
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/sync.d.ts +1 -1
- package/dist/cli/commands/sync.js +509 -163
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/user.js +8 -24
- package/dist/cli/commands/user.js.map +1 -1
- package/dist/cli/index.js +8 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/railway-provisioning.d.ts +53 -0
- package/dist/cli/railway-provisioning.js +85 -0
- package/dist/cli/railway-provisioning.js.map +1 -0
- package/dist/cli/scaffolding.d.ts +4 -2
- package/dist/cli/scaffolding.js +42 -47
- package/dist/cli/scaffolding.js.map +1 -1
- package/dist/cli/setup-wizard.d.ts +30 -49
- package/dist/cli/setup-wizard.js +35 -38
- package/dist/cli/setup-wizard.js.map +1 -1
- package/dist/core/accent-palette.d.ts +22 -0
- package/dist/core/accent-palette.js +47 -0
- package/dist/core/accent-palette.js.map +1 -0
- package/dist/core/entity-body-templates.d.ts +21 -0
- package/dist/core/entity-body-templates.js +48 -0
- package/dist/core/entity-body-templates.js.map +1 -0
- package/dist/core/entity-types-catalog.d.ts +65 -0
- package/dist/core/entity-types-catalog.js +136 -0
- package/dist/core/entity-types-catalog.js.map +1 -0
- package/dist/core/feature-flags.d.ts +22 -0
- package/dist/core/feature-flags.js +15 -0
- package/dist/core/feature-flags.js.map +1 -0
- package/dist/core/features.d.ts +16 -0
- package/dist/core/features.js +48 -0
- package/dist/core/features.js.map +1 -0
- package/dist/core/folder-paths.d.ts +41 -0
- package/dist/core/folder-paths.js +95 -0
- package/dist/core/folder-paths.js.map +1 -0
- package/dist/core/folder-sidecar.d.ts +16 -0
- package/dist/core/folder-sidecar.js +45 -0
- package/dist/core/folder-sidecar.js.map +1 -0
- package/dist/core/graph.d.ts +471 -19
- package/dist/core/graph.js +1411 -284
- package/dist/core/graph.js.map +1 -1
- package/dist/core/schema-registry.js +1 -19
- package/dist/core/schema-registry.js.map +1 -1
- package/dist/core/schemas/connector.d.ts +67 -0
- package/dist/core/schemas/connector.js +100 -0
- package/dist/core/schemas/connector.js.map +1 -0
- package/dist/core/schemas/workspace.d.ts +122 -0
- package/dist/core/schemas/workspace.js +211 -0
- package/dist/core/schemas/workspace.js.map +1 -0
- package/dist/core/secrets/SecretStore.d.ts +77 -0
- package/dist/core/secrets/SecretStore.js +13 -0
- package/dist/core/secrets/SecretStore.js.map +1 -0
- package/dist/core/secrets/SettingsResolver.d.ts +54 -0
- package/dist/core/secrets/SettingsResolver.js +80 -0
- package/dist/core/secrets/SettingsResolver.js.map +1 -0
- package/dist/core/secrets/SettingsStore.d.ts +30 -0
- package/dist/core/secrets/SettingsStore.js +9 -0
- package/dist/core/secrets/SettingsStore.js.map +1 -0
- package/dist/core/secrets/SqliteEncryptedStore.d.ts +78 -0
- package/dist/core/secrets/SqliteEncryptedStore.js +581 -0
- package/dist/core/secrets/SqliteEncryptedStore.js.map +1 -0
- package/dist/core/secrets/audit.d.ts +36 -0
- package/dist/core/secrets/audit.js +60 -0
- package/dist/core/secrets/audit.js.map +1 -0
- package/dist/core/secrets/auth-db-migration.d.ts +129 -0
- package/dist/core/secrets/auth-db-migration.js +653 -0
- package/dist/core/secrets/auth-db-migration.js.map +1 -0
- package/dist/core/secrets/bundle.d.ts +141 -0
- package/dist/core/secrets/bundle.js +435 -0
- package/dist/core/secrets/bundle.js.map +1 -0
- package/dist/core/secrets/dual-write.d.ts +76 -0
- package/dist/core/secrets/dual-write.js +236 -0
- package/dist/core/secrets/dual-write.js.map +1 -0
- package/dist/core/secrets/encryption.d.ts +44 -0
- package/dist/core/secrets/encryption.js +97 -0
- package/dist/core/secrets/encryption.js.map +1 -0
- package/dist/core/secrets/importer.d.ts +94 -0
- package/dist/core/secrets/importer.js +319 -0
- package/dist/core/secrets/importer.js.map +1 -0
- package/dist/core/secrets/index.d.ts +35 -0
- package/dist/core/secrets/index.js +59 -0
- package/dist/core/secrets/index.js.map +1 -0
- package/dist/core/secrets/master-key.d.ts +38 -0
- package/dist/core/secrets/master-key.js +122 -0
- package/dist/core/secrets/master-key.js.map +1 -0
- package/dist/core/secrets/probes/anthropic.d.ts +98 -0
- package/dist/core/secrets/probes/anthropic.js +300 -0
- package/dist/core/secrets/probes/anthropic.js.map +1 -0
- package/dist/core/secrets/probes/brave.d.ts +9 -0
- package/dist/core/secrets/probes/brave.js +15 -0
- package/dist/core/secrets/probes/brave.js.map +1 -0
- package/dist/core/secrets/probes/r2.d.ts +15 -0
- package/dist/core/secrets/probes/r2.js +14 -0
- package/dist/core/secrets/probes/r2.js.map +1 -0
- package/dist/core/secrets/probes/voyage.d.ts +13 -0
- package/dist/core/secrets/probes/voyage.js +52 -0
- package/dist/core/secrets/probes/voyage.js.map +1 -0
- package/dist/core/secrets/read-flip.d.ts +59 -0
- package/dist/core/secrets/read-flip.js +87 -0
- package/dist/core/secrets/read-flip.js.map +1 -0
- package/dist/core/secrets/registry.d.ts +188 -0
- package/dist/core/secrets/registry.js +539 -0
- package/dist/core/secrets/registry.js.map +1 -0
- package/dist/core/types.d.ts +70 -483
- package/dist/core/types.js +6 -3
- package/dist/core/types.js.map +1 -1
- package/dist/core/user-config.d.ts +52 -12
- package/dist/core/user-config.js +119 -14
- package/dist/core/user-config.js.map +1 -1
- package/dist/core/validation.d.ts +603 -1409
- package/dist/core/validation.js +248 -146
- package/dist/core/validation.js.map +1 -1
- package/dist/core/workspace-manager.d.ts +35 -14
- package/dist/core/workspace-manager.js +105 -56
- package/dist/core/workspace-manager.js.map +1 -1
- package/dist/core/workspace.d.ts +19 -5
- package/dist/core/workspace.js +66 -39
- package/dist/core/workspace.js.map +1 -1
- package/dist/mcp/connector-manager.d.ts +16 -1
- package/dist/mcp/connector-manager.js +44 -5
- package/dist/mcp/connector-manager.js.map +1 -1
- package/dist/mcp/server.d.ts +11 -3
- package/dist/mcp/server.js +30 -5
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +27 -2
- package/dist/mcp/tools.js +544 -113
- package/dist/mcp/tools.js.map +1 -1
- package/dist/server/__tests__/helpers/graph-api.d.ts +18 -0
- package/dist/server/__tests__/helpers/graph-api.js +16 -0
- package/dist/server/__tests__/helpers/graph-api.js.map +1 -0
- package/dist/server/commit-audit.d.ts +26 -0
- package/dist/server/commit-audit.js +30 -0
- package/dist/server/commit-audit.js.map +1 -0
- package/dist/server/index.d.ts +14 -3
- package/dist/server/index.js +388 -177
- package/dist/server/index.js.map +1 -1
- package/dist/server/middleware/sanitize.d.ts +46 -0
- package/dist/server/middleware/sanitize.js +171 -0
- package/dist/server/middleware/sanitize.js.map +1 -0
- package/dist/server/routes/asset-api.js +217 -65
- package/dist/server/routes/asset-api.js.map +1 -1
- package/dist/server/routes/audit-api.d.ts +24 -0
- package/dist/server/routes/audit-api.js +117 -0
- package/dist/server/routes/audit-api.js.map +1 -0
- package/dist/server/routes/auth-api.js +220 -44
- package/dist/server/routes/auth-api.js.map +1 -1
- package/dist/server/routes/capture-api.d.ts +10 -3
- package/dist/server/routes/capture-api.js +180 -24
- package/dist/server/routes/capture-api.js.map +1 -1
- package/dist/server/routes/chat.d.ts +4 -1
- package/dist/server/routes/chat.js +178 -46
- package/dist/server/routes/chat.js.map +1 -1
- package/dist/server/routes/config-api.d.ts +21 -0
- package/dist/server/routes/config-api.js +256 -0
- package/dist/server/routes/config-api.js.map +1 -0
- package/dist/server/routes/connectors-api.js +24 -18
- package/dist/server/routes/connectors-api.js.map +1 -1
- package/dist/server/routes/event-ingest-api.d.ts +15 -0
- package/dist/server/routes/event-ingest-api.js +125 -0
- package/dist/server/routes/event-ingest-api.js.map +1 -0
- package/dist/server/routes/features-api.d.ts +19 -0
- package/dist/server/routes/features-api.js +28 -0
- package/dist/server/routes/features-api.js.map +1 -0
- package/dist/server/routes/git-http.d.ts +2 -2
- package/dist/server/routes/git-http.js +69 -34
- package/dist/server/routes/git-http.js.map +1 -1
- package/dist/server/routes/graph-api-access.d.ts +35 -0
- package/dist/server/routes/graph-api-access.js +93 -0
- package/dist/server/routes/graph-api-access.js.map +1 -0
- package/dist/server/routes/graph-api.d.ts +3 -2
- package/dist/server/routes/graph-api.js +1014 -315
- package/dist/server/routes/graph-api.js.map +1 -1
- package/dist/server/routes/health.d.ts +18 -0
- package/dist/server/routes/health.js +74 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/insights-api.js +156 -33
- package/dist/server/routes/insights-api.js.map +1 -1
- package/dist/server/routes/mcp.d.ts +6 -3
- package/dist/server/routes/mcp.js +22 -6
- package/dist/server/routes/mcp.js.map +1 -1
- package/dist/server/routes/messages-api.d.ts +3 -3
- package/dist/server/routes/messages-api.js +308 -120
- package/dist/server/routes/messages-api.js.map +1 -1
- package/dist/server/routes/permissions-api.d.ts +9 -2
- package/dist/server/routes/permissions-api.js +87 -31
- package/dist/server/routes/permissions-api.js.map +1 -1
- package/dist/server/routes/secrets-api.d.ts +36 -0
- package/dist/server/routes/secrets-api.js +303 -0
- package/dist/server/routes/secrets-api.js.map +1 -0
- package/dist/server/routes/settings-api.d.ts +29 -0
- package/dist/server/routes/settings-api.js +177 -0
- package/dist/server/routes/settings-api.js.map +1 -0
- package/dist/server/routes/workspace-api.d.ts +2 -1
- package/dist/server/routes/workspace-api.js +131 -20
- package/dist/server/routes/workspace-api.js.map +1 -1
- package/dist/server/routes/ws.d.ts +3 -2
- package/dist/server/routes/ws.js +68 -18
- package/dist/server/routes/ws.js.map +1 -1
- package/dist/server/session-manager.d.ts +48 -5
- package/dist/server/session-manager.js +175 -11
- package/dist/server/session-manager.js.map +1 -1
- package/dist/server/ws-hub.d.ts +134 -22
- package/dist/server/ws-hub.js +0 -0
- package/dist/server/ws-hub.js.map +1 -1
- package/dist/server/yjs-manager.d.ts +107 -7
- package/dist/server/yjs-manager.js +444 -38
- package/dist/server/yjs-manager.js.map +1 -1
- package/dist/server/yjs-persistence.d.ts +143 -0
- package/dist/server/yjs-persistence.js +543 -0
- package/dist/server/yjs-persistence.js.map +1 -0
- package/dist/server/yjs-text-diff.d.ts +32 -0
- package/dist/server/yjs-text-diff.js +61 -0
- package/dist/server/yjs-text-diff.js.map +1 -0
- package/dist/services/access-control.d.ts +53 -0
- package/dist/services/access-control.js +132 -0
- package/dist/services/access-control.js.map +1 -0
- package/dist/services/asset-upload-service.d.ts +53 -0
- package/dist/services/asset-upload-service.js +200 -0
- package/dist/services/asset-upload-service.js.map +1 -0
- package/dist/services/assets/base.d.ts +38 -0
- package/dist/services/assets/base.js +55 -0
- package/dist/services/assets/base.js.map +1 -1
- package/dist/services/assets/index.d.ts +41 -1
- package/dist/services/assets/index.js +65 -0
- package/dist/services/assets/index.js.map +1 -1
- package/dist/services/assets/local.d.ts +7 -1
- package/dist/services/assets/local.js +83 -0
- package/dist/services/assets/local.js.map +1 -1
- package/dist/services/assets/r2.d.ts +28 -1
- package/dist/services/assets/r2.js +75 -1
- package/dist/services/assets/r2.js.map +1 -1
- package/dist/services/auth-service.d.ts +184 -36
- package/dist/services/auth-service.js +763 -138
- package/dist/services/auth-service.js.map +1 -1
- package/dist/services/briefing.d.ts +1 -1
- package/dist/services/briefing.js +12 -35
- package/dist/services/briefing.js.map +1 -1
- package/dist/services/event-processor.d.ts +104 -0
- package/dist/services/event-processor.js +443 -0
- package/dist/services/event-processor.js.map +1 -0
- package/dist/services/folder-creation.d.ts +33 -0
- package/dist/services/folder-creation.js +103 -0
- package/dist/services/folder-creation.js.map +1 -0
- package/dist/services/git.d.ts +44 -0
- package/dist/services/git.js +162 -55
- package/dist/services/git.js.map +1 -1
- package/dist/services/heartbeat.d.ts +19 -12
- package/dist/services/heartbeat.js +162 -107
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/import-service.d.ts +37 -2
- package/dist/services/import-service.js +222 -123
- package/dist/services/import-service.js.map +1 -1
- package/dist/services/lint-service.js +7 -14
- package/dist/services/lint-service.js.map +1 -1
- package/dist/services/markdown.js +6 -2
- package/dist/services/markdown.js.map +1 -1
- package/dist/services/message-service.d.ts +62 -21
- package/dist/services/message-service.js +160 -43
- package/dist/services/message-service.js.map +1 -1
- package/dist/services/personal-folder.d.ts +40 -0
- package/dist/services/personal-folder.js +101 -0
- package/dist/services/personal-folder.js.map +1 -0
- package/dist/services/vector-service.d.ts +73 -3
- package/dist/services/vector-service.js +106 -7
- package/dist/services/vector-service.js.map +1 -1
- package/dist/services/workspace-access.d.ts +106 -0
- package/dist/services/workspace-access.js +149 -0
- package/dist/services/workspace-access.js.map +1 -0
- package/dist/utils/git.js +3 -3
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/log.d.ts +42 -0
- package/dist/utils/log.js +137 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/preflight.js +2 -2
- package/dist/utils/preflight.js.map +1 -1
- package/dist/utils/version-checker.d.ts +4 -1
- package/dist/utils/version-checker.js +8 -8
- package/dist/utils/version-checker.js.map +1 -1
- package/dist/web/_app/immutable/assets/0.Bp6xXZUi.css +2 -0
- package/dist/web/_app/immutable/assets/11.DlIf1mKh.css +1 -0
- package/dist/web/_app/immutable/assets/12.Dmlt28l2.css +1 -0
- package/dist/web/_app/immutable/assets/13.CmLrbzZp.css +1 -0
- package/dist/web/_app/immutable/assets/2.oo1ac0x_.css +1 -0
- package/dist/web/_app/immutable/assets/3.DJJsQzDb.css +1 -0
- package/dist/web/_app/immutable/assets/4.CZ-fNJ91.css +1 -0
- package/dist/web/_app/immutable/assets/AgentOverlay.BfWESlQU.css +1 -0
- package/dist/web/_app/immutable/assets/AssetManagerModal.ZfasE2L3.css +1 -0
- package/dist/web/_app/immutable/assets/CalendarView.CeNagvyK.css +1 -0
- package/dist/web/_app/immutable/assets/ChatPanel.po0gYtVH.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMembersPanel.Bepw-r0F.css +1 -0
- package/dist/web/_app/immutable/assets/FolderMutationDialogs.BMRF6Z3z.css +1 -0
- package/dist/web/_app/immutable/assets/FolderPicker.B5KdvRYl.css +1 -0
- package/dist/web/_app/immutable/assets/GalleryView.Dy-qQjEc.css +1 -0
- package/dist/web/_app/immutable/assets/GraphView.BHnGIltS.css +1 -0
- package/dist/web/_app/immutable/assets/KanbanView.G3NZ0uHb.css +1 -0
- package/dist/web/_app/immutable/assets/SettingsDialog.tBn8y9DD.css +1 -0
- package/dist/web/_app/immutable/assets/Spinner.UBfl0pab.css +1 -0
- package/dist/web/_app/immutable/assets/TagFilter.DNipjifq.css +1 -0
- package/dist/web/_app/immutable/assets/TagPickerSheet.DJPuqnTg.css +1 -0
- package/dist/web/_app/immutable/assets/WorkspaceView.B9zA92UB.css +1 -0
- package/dist/web/_app/immutable/assets/button.BlLm4Dg1.css +1 -0
- package/dist/web/_app/immutable/assets/dialog.BxVal_19.css +1 -0
- package/dist/web/_app/immutable/assets/dist.B5hGjnfj.css +1 -0
- package/dist/web/_app/immutable/assets/dist.DDCWxn3B.css +1 -0
- package/dist/web/_app/immutable/assets/dropdown-menu.BSsUUQ3o.css +1 -0
- package/dist/web/_app/immutable/assets/entity-row.Bl5FyNCt.css +1 -0
- package/dist/web/_app/immutable/assets/greeting.Bm7lTneV.css +1 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.CvHOgSBP.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-400-normal.DMJ8VG8y.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.CB9ihrfo.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-mono-latin-500-normal.DSY6xOcd.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CZTNEAuW.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-italic.CsGl1sm0.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CDDApCn2.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-400-normal.CYLoc0-x.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.BNK2_mGO.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-italic.DpEwFAQM.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.6ng42L7E.woff2 +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-500-normal.BgVn5rGT.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.Cu4Hd6ag.woff +0 -0
- package/dist/web/_app/immutable/assets/ibm-plex-sans-latin-600-normal.CuJfVYMP.woff2 +0 -0
- package/dist/web/_app/immutable/assets/inline-list.DORLo4xF.css +1 -0
- package/dist/web/_app/immutable/assets/notifications.clodJdp5.css +1 -0
- package/dist/web/_app/immutable/assets/radio-group.GJJRVPUJ.css +1 -0
- package/dist/web/_app/immutable/assets/select.D_AV992j.css +1 -0
- package/dist/web/_app/immutable/chunks/-KAQXGuI2.js +1 -0
- package/dist/web/_app/immutable/chunks/-wzwcH00.js +1 -0
- package/dist/web/_app/immutable/chunks/07l_1Zpm2.js +1 -0
- package/dist/web/_app/immutable/chunks/1i1V0Z172.js +2 -0
- package/dist/web/_app/immutable/chunks/38oWKNzM2.js +6 -0
- package/dist/web/_app/immutable/chunks/54VmiJfH.js +1 -0
- package/dist/web/_app/immutable/chunks/6LRpFvjo.js +185 -0
- package/dist/web/_app/immutable/chunks/9bCTHkeS.js +1 -0
- package/dist/web/_app/immutable/chunks/B-822WnD2.js +22 -0
- package/dist/web/_app/immutable/chunks/B0HUvliX2.js +2 -0
- package/dist/web/_app/immutable/chunks/B12eXGpE.js +1 -0
- package/dist/web/_app/immutable/chunks/B2-Cx5XA.js +1 -0
- package/dist/web/_app/immutable/chunks/B5af0X0p2.js +1 -0
- package/dist/web/_app/immutable/chunks/B6iYNwo72.js +1 -0
- package/dist/web/_app/immutable/chunks/B7EMtoAB.js +1 -0
- package/dist/web/_app/immutable/chunks/B9qBGxh62.js +3 -0
- package/dist/web/_app/immutable/chunks/B9rVXblv.js +1 -0
- package/dist/web/_app/immutable/chunks/BEpMEjHO.js +1 -0
- package/dist/web/_app/immutable/chunks/BErNpj-S2.js +1 -0
- package/dist/web/_app/immutable/chunks/BHBk4zfV.js +1 -0
- package/dist/web/_app/immutable/chunks/BHH-JGNF.js +1 -0
- package/dist/web/_app/immutable/chunks/BNTlsKDJ.js +1 -0
- package/dist/web/_app/immutable/chunks/BOgcXgis2.js +1 -0
- package/dist/web/_app/immutable/chunks/BOyyDrjn2.js +1 -0
- package/dist/web/_app/immutable/chunks/BPR_ufQ0.js +41 -0
- package/dist/web/_app/immutable/chunks/BRcFsc6v.js +5 -0
- package/dist/web/_app/immutable/chunks/BT3KAag_.js +3 -0
- package/dist/web/_app/immutable/chunks/BX2T6xiZ.js +224 -0
- package/dist/web/_app/immutable/chunks/BZnJ8tbJ.js +1 -0
- package/dist/web/_app/immutable/chunks/Ba1Yzb7u.js +1 -0
- package/dist/web/_app/immutable/chunks/BcsvgA3B2.js +1 -0
- package/dist/web/_app/immutable/chunks/BfbS7rGT.js +1 -0
- package/dist/web/_app/immutable/chunks/BgagL41Z.js +1 -0
- package/dist/web/_app/immutable/chunks/Bk-AcswV.js +1 -0
- package/dist/web/_app/immutable/chunks/Bl9Pzopy.js +1 -0
- package/dist/web/_app/immutable/chunks/BmcU05mO.js +1 -0
- package/dist/web/_app/immutable/chunks/Bmgp0jlT.js +1 -0
- package/dist/web/_app/immutable/chunks/BpDONXUo.js +8 -0
- package/dist/web/_app/immutable/chunks/BpTXLx8I2.js +5 -0
- package/dist/web/_app/immutable/chunks/Bq0-jBGC2.js +1 -0
- package/dist/web/_app/immutable/chunks/BqGj0_GS.js +1 -0
- package/dist/web/_app/immutable/chunks/Bsc9K3Pz.js +1 -0
- package/dist/web/_app/immutable/chunks/Bssb691Q.js +1 -0
- package/dist/web/_app/immutable/chunks/BuzQceOn.js +1 -0
- package/dist/web/_app/immutable/chunks/BzeVNab0.js +1 -0
- package/dist/web/_app/immutable/chunks/C-OaypFN.js +1 -0
- package/dist/web/_app/immutable/chunks/C0fjDjvE2.js +1 -0
- package/dist/web/_app/immutable/chunks/C0pTXwEX.js +2 -0
- package/dist/web/_app/immutable/chunks/C3Enww9L2.js +1 -0
- package/dist/web/_app/immutable/chunks/C3oa0Cks.js +1 -0
- package/dist/web/_app/immutable/chunks/C7GIvT8T.js +2 -0
- package/dist/web/_app/immutable/chunks/CC-YWp-f.js +1 -0
- package/dist/web/_app/immutable/chunks/CGdKvXV92.js +1 -0
- package/dist/web/_app/immutable/chunks/CH0siYFL.js +1 -0
- package/dist/web/_app/immutable/chunks/CIc2MMme2.js +1 -0
- package/dist/web/_app/immutable/chunks/CIchr8Tk2.js +1 -0
- package/dist/web/_app/immutable/chunks/CK_yXDQI.js +1 -0
- package/dist/web/_app/immutable/chunks/CLSxJmTj.js +2 -0
- package/dist/web/_app/immutable/chunks/CMhHc1Bq2.js +2 -0
- package/dist/web/_app/immutable/chunks/CNGba6T4.js +1 -0
- package/dist/web/_app/immutable/chunks/CPt2D5aU.js +1 -0
- package/dist/web/_app/immutable/chunks/CQ-2yccd.js +7 -0
- package/dist/web/_app/immutable/chunks/CS6VEwn7.js +1 -0
- package/dist/web/_app/immutable/chunks/CSsDOIrk.js +1 -0
- package/dist/web/_app/immutable/chunks/CVXvEWhv2.js +1 -0
- package/dist/web/_app/immutable/chunks/CaChtuYU2.js +1 -0
- package/dist/web/_app/immutable/chunks/CbiwvM3R2.js +1 -0
- package/dist/web/_app/immutable/chunks/CdCuBMLm.js +156 -0
- package/dist/web/_app/immutable/chunks/CiyqPsJo.js +1 -0
- package/dist/web/_app/immutable/chunks/CjGzUnEF2.js +1 -0
- package/dist/web/_app/immutable/chunks/Cjgbiel7.js +1 -0
- package/dist/web/_app/immutable/chunks/CnqSKqA62.js +1 -0
- package/dist/web/_app/immutable/chunks/CqyqKPuh2.js +1 -0
- package/dist/web/_app/immutable/chunks/CrnX-oFV.js +1 -0
- package/dist/web/_app/immutable/chunks/CsGahE3a.js +1 -0
- package/dist/web/_app/immutable/chunks/Ct3quP0F.js +1 -0
- package/dist/web/_app/immutable/chunks/CtlAYPxw.js +1 -0
- package/dist/web/_app/immutable/chunks/CvZaxjRC.js +1 -0
- package/dist/web/_app/immutable/chunks/CwD4G56R.js +5 -0
- package/dist/web/_app/immutable/chunks/CwROuREs.js +1 -0
- package/dist/web/_app/immutable/chunks/CxalqrMB.js +1 -0
- package/dist/web/_app/immutable/chunks/D7qgUfnr.js +2487 -0
- package/dist/web/_app/immutable/chunks/D9-_Euza2.js +1 -0
- package/dist/web/_app/immutable/chunks/DC69SASj.js +2 -0
- package/dist/web/_app/immutable/chunks/DCCaoKt42.js +1 -0
- package/dist/web/_app/immutable/chunks/DDKweOZr2.js +23 -0
- package/dist/web/_app/immutable/chunks/DEY60osH.js +1 -0
- package/dist/web/_app/immutable/chunks/DG3QZPgI.js +1 -0
- package/dist/web/_app/immutable/chunks/DHepUItL.js +1 -0
- package/dist/web/_app/immutable/chunks/DNtqqgv32.js +1 -0
- package/dist/web/_app/immutable/chunks/DRl7vwNC2.js +184 -0
- package/dist/web/_app/immutable/chunks/DTc5W_V6.js +1 -0
- package/dist/web/_app/immutable/chunks/DaiJs3St.js +1 -0
- package/dist/web/_app/immutable/chunks/DfITyMKh2.js +1 -0
- package/dist/web/_app/immutable/chunks/DhuJRrEX2.js +1 -0
- package/dist/web/_app/immutable/chunks/DiP2EplP.js +3 -0
- package/dist/web/_app/immutable/chunks/DjlDV2JG.js +1 -0
- package/dist/web/_app/immutable/chunks/Dm25ot5x2.js +1 -0
- package/dist/web/_app/immutable/chunks/DpuSt-SO.js +2 -0
- package/dist/web/_app/immutable/chunks/DqOcb9RX2.js +83 -0
- package/dist/web/_app/immutable/chunks/DrbUJCAE.js +1 -0
- package/dist/web/_app/immutable/chunks/Du2-B3c8.js +1 -0
- package/dist/web/_app/immutable/chunks/DwdkE4UD2.js +1 -0
- package/dist/web/_app/immutable/chunks/DxWesPbn.js +1 -0
- package/dist/web/_app/immutable/chunks/DyYZqUV72.js +1 -0
- package/dist/web/_app/immutable/chunks/HfUnhvrv2.js +1 -0
- package/dist/web/_app/immutable/chunks/Je8-BtCk2.js +1 -0
- package/dist/web/_app/immutable/chunks/MSB7eA4_.js +1 -0
- package/dist/web/_app/immutable/chunks/NPe9WyW1.js +1 -0
- package/dist/web/_app/immutable/chunks/O6IzcxXJ.js +2 -0
- package/dist/web/_app/immutable/chunks/SXhc9rJW.js +1 -0
- package/dist/web/_app/immutable/chunks/SbWhkPMt.js +6 -0
- package/dist/web/_app/immutable/chunks/U40J2SnU.js +1 -0
- package/dist/web/_app/immutable/chunks/VS3l21Gu.js +1 -0
- package/dist/web/_app/immutable/chunks/YEPEvlbU2.js +1 -0
- package/dist/web/_app/immutable/chunks/Z7TNRcgK.js +11 -0
- package/dist/web/_app/immutable/chunks/ZCekGjo6.js +5 -0
- package/dist/web/_app/immutable/chunks/_rnxQ655.js +4 -0
- package/dist/web/_app/immutable/chunks/aALpjBW2.js +1 -0
- package/dist/web/_app/immutable/chunks/gNXLhsdy.js +1 -0
- package/dist/web/_app/immutable/chunks/hKSTEN36.js +1 -0
- package/dist/web/_app/immutable/chunks/jZZTbzL5.js +1 -0
- package/dist/web/_app/immutable/chunks/l4FIBKss.js +1 -0
- package/dist/web/_app/immutable/chunks/l_4snZnh2.js +1 -0
- package/dist/web/_app/immutable/chunks/mz-cgRgP.js +3 -0
- package/dist/web/_app/immutable/chunks/qgprkMcL.js +1 -0
- package/dist/web/_app/immutable/chunks/rOisBLC62.js +14 -0
- package/dist/web/_app/immutable/chunks/t08TznXc2.js +1 -0
- package/dist/web/_app/immutable/chunks/t62M88qj.js +1 -0
- package/dist/web/_app/immutable/chunks/uCohGWC42.js +1 -0
- package/dist/web/_app/immutable/chunks/uqxmB78b.js +1 -0
- package/dist/web/_app/immutable/chunks/vJkT0IPN.js +1 -0
- package/dist/web/_app/immutable/chunks/vwTMEIJQ.js +1 -0
- package/dist/web/_app/immutable/chunks/w1FCELam.js +64 -0
- package/dist/web/_app/immutable/chunks/xEzUlKaR2.js +1 -0
- package/dist/web/_app/immutable/chunks/zumDjcgJ.js +1 -0
- package/dist/web/_app/immutable/entry/app.DtdPIxaY.js +2 -0
- package/dist/web/_app/immutable/entry/start.Cqf8YmDj.js +1 -0
- package/dist/web/_app/immutable/nodes/0.CktqlAe7.js +2 -0
- package/dist/web/_app/immutable/nodes/1.Bs7cz_ba.js +1 -0
- package/dist/web/_app/immutable/nodes/10.CAQtOBqO.js +1 -0
- package/dist/web/_app/immutable/nodes/11.l9TQGnJm.js +1 -0
- package/dist/web/_app/immutable/nodes/12.CttDoIpY.js +1 -0
- package/dist/web/_app/immutable/nodes/13.E5fh69kS.js +1 -0
- package/dist/web/_app/immutable/nodes/2.DnLSJfx-.js +106 -0
- package/dist/web/_app/immutable/nodes/3.Bw8R0Jw5.js +2 -0
- package/dist/web/_app/immutable/nodes/4.Cl0HgeTG.js +2 -0
- package/dist/web/_app/immutable/nodes/5.BpIWwWi9.js +1 -0
- package/dist/web/_app/immutable/nodes/6.jpx6ZgOI.js +1 -0
- package/dist/web/_app/immutable/nodes/7.YTFykZQe.js +1 -0
- package/dist/web/_app/immutable/nodes/8.Chy0HNU1.js +1 -0
- package/dist/web/_app/immutable/nodes/9.D10JpFt2.js +1 -0
- package/dist/web/_app/version.json +1 -1
- package/dist/web/favicon-16.png +0 -0
- package/dist/web/favicon-180.png +0 -0
- package/dist/web/favicon-32.png +0 -0
- package/dist/web/favicon-48.png +0 -0
- package/dist/web/favicon-512.png +0 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.svg +8 -0
- package/dist/web/index.html +64 -21
- package/dist/web/studiograph-logomark.svg +29 -0
- package/package.json +28 -14
- package/dist/agent/role-loader.d.ts +0 -24
- package/dist/agent/role-loader.js +0 -67
- package/dist/agent/role-loader.js.map +0 -1
- package/dist/agent/skills/enrich-entities.md +0 -136
- package/dist/agent/skills/obsidian-source-setup.md +0 -246
- package/dist/agent/skills/skill-loader.d.ts +0 -48
- package/dist/agent/skills/skill-loader.js +0 -166
- package/dist/agent/skills/skill-loader.js.map +0 -1
- package/dist/agent/skills/sync-configuration.md +0 -119
- package/dist/agent/skills/sync-setup.md +0 -82
- package/dist/agent/tools/sync-tools.d.ts +0 -35
- package/dist/agent/tools/sync-tools.js +0 -992
- package/dist/agent/tools/sync-tools.js.map +0 -1
- package/dist/auth/github.d.ts +0 -56
- package/dist/auth/github.js +0 -169
- package/dist/auth/github.js.map +0 -1
- package/dist/cli/commands/access.d.ts +0 -11
- package/dist/cli/commands/access.js +0 -156
- package/dist/cli/commands/access.js.map +0 -1
- package/dist/cli/commands/app.d.ts +0 -7
- package/dist/cli/commands/app.js +0 -268
- package/dist/cli/commands/app.js.map +0 -1
- package/dist/cli/commands/auth.d.ts +0 -10
- package/dist/cli/commands/auth.js +0 -79
- package/dist/cli/commands/auth.js.map +0 -1
- package/dist/cli/commands/collection.d.ts +0 -10
- package/dist/cli/commands/collection.js +0 -185
- package/dist/cli/commands/collection.js.map +0 -1
- package/dist/cli/commands/enrich.d.ts +0 -11
- package/dist/cli/commands/enrich.js +0 -135
- package/dist/cli/commands/enrich.js.map +0 -1
- package/dist/cli/commands/graphrag.d.ts +0 -12
- package/dist/cli/commands/graphrag.js +0 -122
- package/dist/cli/commands/graphrag.js.map +0 -1
- package/dist/cli/commands/members.d.ts +0 -11
- package/dist/cli/commands/members.js +0 -230
- package/dist/cli/commands/members.js.map +0 -1
- package/dist/cli/commands/org.d.ts +0 -10
- package/dist/cli/commands/org.js +0 -132
- package/dist/cli/commands/org.js.map +0 -1
- package/dist/cli/commands/provision.d.ts +0 -8
- package/dist/cli/commands/provision.js +0 -116
- package/dist/cli/commands/provision.js.map +0 -1
- package/dist/cli/commands/resolve.d.ts +0 -8
- package/dist/cli/commands/resolve.js +0 -85
- package/dist/cli/commands/resolve.js.map +0 -1
- package/dist/cli/commands/review.d.ts +0 -19
- package/dist/cli/commands/review.js +0 -128
- package/dist/cli/commands/review.js.map +0 -1
- package/dist/cli/commands/source.d.ts +0 -16
- package/dist/cli/commands/source.js +0 -159
- package/dist/cli/commands/source.js.map +0 -1
- package/dist/cli/commands/sync-collection.d.ts +0 -14
- package/dist/cli/commands/sync-collection.js +0 -355
- package/dist/cli/commands/sync-collection.js.map +0 -1
- package/dist/cli/commands/sync-entities.d.ts +0 -13
- package/dist/cli/commands/sync-entities.js +0 -242
- package/dist/cli/commands/sync-entities.js.map +0 -1
- package/dist/cli/commands/team.d.ts +0 -12
- package/dist/cli/commands/team.js +0 -185
- package/dist/cli/commands/team.js.map +0 -1
- package/dist/cli/sync-review-interactive.d.ts +0 -31
- package/dist/cli/sync-review-interactive.js +0 -393
- package/dist/cli/sync-review-interactive.js.map +0 -1
- package/dist/core/migration-runner.d.ts +0 -42
- package/dist/core/migration-runner.js +0 -232
- package/dist/core/migration-runner.js.map +0 -1
- package/dist/core/migration-types.d.ts +0 -101
- package/dist/core/migration-types.js +0 -21
- package/dist/core/migration-types.js.map +0 -1
- package/dist/core/migrations/20260219-formalize-memory-location.d.ts +0 -2
- package/dist/core/migrations/20260219-formalize-memory-location.js +0 -35
- package/dist/core/migrations/20260219-formalize-memory-location.js.map +0 -1
- package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +0 -12
- package/dist/core/migrations/20260220-add-workspace-metadata.js +0 -65
- package/dist/core/migrations/20260220-add-workspace-metadata.js.map +0 -1
- package/dist/core/migrations/20260220-add-workspace-readme.d.ts +0 -11
- package/dist/core/migrations/20260220-add-workspace-readme.js +0 -82
- package/dist/core/migrations/20260220-add-workspace-readme.js.map +0 -1
- package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +0 -9
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js +0 -64
- package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +0 -1
- package/dist/core/migrations/index.d.ts +0 -11
- package/dist/core/migrations/index.js +0 -23
- package/dist/core/migrations/index.js.map +0 -1
- package/dist/integrations/asana.d.ts +0 -26
- package/dist/integrations/asana.js +0 -78
- package/dist/integrations/asana.js.map +0 -1
- package/dist/integrations/figma-local.d.ts +0 -16
- package/dist/integrations/figma-local.js +0 -10
- package/dist/integrations/figma-local.js.map +0 -1
- package/dist/integrations/figma.d.ts +0 -17
- package/dist/integrations/figma.js +0 -17
- package/dist/integrations/figma.js.map +0 -1
- package/dist/integrations/granola.d.ts +0 -24
- package/dist/integrations/granola.js +0 -60
- package/dist/integrations/granola.js.map +0 -1
- package/dist/integrations/linear.d.ts +0 -14
- package/dist/integrations/linear.js +0 -80
- package/dist/integrations/linear.js.map +0 -1
- package/dist/integrations/paper-local.d.ts +0 -14
- package/dist/integrations/paper-local.js +0 -10
- package/dist/integrations/paper-local.js.map +0 -1
- package/dist/integrations/paper.d.ts +0 -2
- package/dist/integrations/paper.js +0 -10
- package/dist/integrations/paper.js.map +0 -1
- package/dist/integrations/pipedrive.d.ts +0 -26
- package/dist/integrations/pipedrive.js +0 -97
- package/dist/integrations/pipedrive.js.map +0 -1
- package/dist/integrations/registry.d.ts +0 -8
- package/dist/integrations/registry.js +0 -7
- package/dist/integrations/registry.js.map +0 -1
- package/dist/integrations/types.d.ts +0 -43
- package/dist/integrations/types.js +0 -5
- package/dist/integrations/types.js.map +0 -1
- package/dist/lib/lib/utils.d.ts +0 -2
- package/dist/lib/lib/utils.js +0 -6
- package/dist/lib/lib/utils.js.map +0 -1
- package/dist/mcp/connectors/asana.d.ts +0 -2
- package/dist/mcp/connectors/asana.js +0 -20
- package/dist/mcp/connectors/asana.js.map +0 -1
- package/dist/mcp/connectors/definitions.d.ts +0 -45
- package/dist/mcp/connectors/definitions.js +0 -32
- package/dist/mcp/connectors/definitions.js.map +0 -1
- package/dist/mcp/connectors/figma.d.ts +0 -5
- package/dist/mcp/connectors/figma.js +0 -21
- package/dist/mcp/connectors/figma.js.map +0 -1
- package/dist/mcp/connectors/gdrive.d.ts +0 -2
- package/dist/mcp/connectors/gdrive.js +0 -20
- package/dist/mcp/connectors/gdrive.js.map +0 -1
- package/dist/mcp/connectors/granola.d.ts +0 -2
- package/dist/mcp/connectors/granola.js +0 -12
- package/dist/mcp/connectors/granola.js.map +0 -1
- package/dist/mcp/connectors/linear.d.ts +0 -2
- package/dist/mcp/connectors/linear.js +0 -19
- package/dist/mcp/connectors/linear.js.map +0 -1
- package/dist/mcp/connectors/obsidian.d.ts +0 -2
- package/dist/mcp/connectors/obsidian.js +0 -19
- package/dist/mcp/connectors/obsidian.js.map +0 -1
- package/dist/mcp/connectors/pipedrive.d.ts +0 -2
- package/dist/mcp/connectors/pipedrive.js +0 -20
- package/dist/mcp/connectors/pipedrive.js.map +0 -1
- package/dist/mcp/connectors/slack.d.ts +0 -2
- package/dist/mcp/connectors/slack.js +0 -21
- package/dist/mcp/connectors/slack.js.map +0 -1
- package/dist/mcp/server-oauth-provider.d.ts +0 -56
- package/dist/mcp/server-oauth-provider.js +0 -142
- package/dist/mcp/server-oauth-provider.js.map +0 -1
- package/dist/server/agents/agent-loader.d.ts +0 -16
- package/dist/server/agents/agent-loader.js +0 -175
- package/dist/server/agents/agent-loader.js.map +0 -1
- package/dist/server/agents/agent-runner.d.ts +0 -33
- package/dist/server/agents/agent-runner.js +0 -187
- package/dist/server/agents/agent-runner.js.map +0 -1
- package/dist/server/agents/agent-runtime.d.ts +0 -39
- package/dist/server/agents/agent-runtime.js +0 -214
- package/dist/server/agents/agent-runtime.js.map +0 -1
- package/dist/server/agents/base-agent.d.ts +0 -30
- package/dist/server/agents/base-agent.js +0 -88
- package/dist/server/agents/base-agent.js.map +0 -1
- package/dist/server/agents/executive-digest.d.ts +0 -16
- package/dist/server/agents/executive-digest.js +0 -115
- package/dist/server/agents/executive-digest.js.map +0 -1
- package/dist/server/agents/graph-steward.d.ts +0 -16
- package/dist/server/agents/graph-steward.js +0 -59
- package/dist/server/agents/graph-steward.js.map +0 -1
- package/dist/server/agents/meeting-followup.d.ts +0 -16
- package/dist/server/agents/meeting-followup.js +0 -88
- package/dist/server/agents/meeting-followup.js.map +0 -1
- package/dist/server/agents/pipeline-monitor.d.ts +0 -15
- package/dist/server/agents/pipeline-monitor.js +0 -86
- package/dist/server/agents/pipeline-monitor.js.map +0 -1
- package/dist/server/agents/types.d.ts +0 -81
- package/dist/server/agents/types.js +0 -41
- package/dist/server/agents/types.js.map +0 -1
- package/dist/server/chrome/chrome.css +0 -691
- package/dist/server/chrome/chrome.js +0 -374
- package/dist/server/collab-authority.d.ts +0 -70
- package/dist/server/collab-authority.js +0 -218
- package/dist/server/collab-authority.js.map +0 -1
- package/dist/server/collab.d.ts +0 -29
- package/dist/server/collab.js +0 -195
- package/dist/server/collab.js.map +0 -1
- package/dist/server/commit-scheduler.d.ts +0 -39
- package/dist/server/commit-scheduler.js +0 -113
- package/dist/server/commit-scheduler.js.map +0 -1
- package/dist/server/plugin-loader.d.ts +0 -53
- package/dist/server/plugin-loader.js +0 -155
- package/dist/server/plugin-loader.js.map +0 -1
- package/dist/server/routes/agents-api.d.ts +0 -10
- package/dist/server/routes/agents-api.js +0 -25
- package/dist/server/routes/agents-api.js.map +0 -1
- package/dist/server/routes/collab.d.ts +0 -6
- package/dist/server/routes/collab.js +0 -10
- package/dist/server/routes/collab.js.map +0 -1
- package/dist/server/routes/git-api.d.ts +0 -9
- package/dist/server/routes/git-api.js +0 -82
- package/dist/server/routes/git-api.js.map +0 -1
- package/dist/server/routes/meeting-ingest-api.d.ts +0 -14
- package/dist/server/routes/meeting-ingest-api.js +0 -98
- package/dist/server/routes/meeting-ingest-api.js.map +0 -1
- package/dist/server/routes/sync-api.d.ts +0 -26
- package/dist/server/routes/sync-api.js +0 -848
- package/dist/server/routes/sync-api.js.map +0 -1
- package/dist/server/routes/webhook.d.ts +0 -14
- package/dist/server/routes/webhook.js +0 -102
- package/dist/server/routes/webhook.js.map +0 -1
- package/dist/services/batch-processor.d.ts +0 -49
- package/dist/services/batch-processor.js +0 -166
- package/dist/services/batch-processor.js.map +0 -1
- package/dist/services/csv-service.d.ts +0 -36
- package/dist/services/csv-service.js +0 -143
- package/dist/services/csv-service.js.map +0 -1
- package/dist/services/github-provisioner.d.ts +0 -36
- package/dist/services/github-provisioner.js +0 -126
- package/dist/services/github-provisioner.js.map +0 -1
- package/dist/services/github-service.d.ts +0 -99
- package/dist/services/github-service.js +0 -310
- package/dist/services/github-service.js.map +0 -1
- package/dist/services/image-import-service.d.ts +0 -24
- package/dist/services/image-import-service.js +0 -108
- package/dist/services/image-import-service.js.map +0 -1
- package/dist/services/insights.d.ts +0 -38
- package/dist/services/insights.js +0 -269
- package/dist/services/insights.js.map +0 -1
- package/dist/services/meeting-processor.d.ts +0 -91
- package/dist/services/meeting-processor.js +0 -331
- package/dist/services/meeting-processor.js.map +0 -1
- package/dist/services/sync/collection-sync.d.ts +0 -60
- package/dist/services/sync/collection-sync.js +0 -509
- package/dist/services/sync/collection-sync.js.map +0 -1
- package/dist/services/sync/commit.d.ts +0 -60
- package/dist/services/sync/commit.js +0 -354
- package/dist/services/sync/commit.js.map +0 -1
- package/dist/services/sync/context-index.d.ts +0 -69
- package/dist/services/sync/context-index.js +0 -280
- package/dist/services/sync/context-index.js.map +0 -1
- package/dist/services/sync/data-fetcher.d.ts +0 -31
- package/dist/services/sync/data-fetcher.js +0 -12
- package/dist/services/sync/data-fetcher.js.map +0 -1
- package/dist/services/sync/derive.d.ts +0 -34
- package/dist/services/sync/derive.js +0 -164
- package/dist/services/sync/derive.js.map +0 -1
- package/dist/services/sync/enrichment-state.d.ts +0 -31
- package/dist/services/sync/enrichment-state.js +0 -63
- package/dist/services/sync/enrichment-state.js.map +0 -1
- package/dist/services/sync/enrichment.d.ts +0 -25
- package/dist/services/sync/enrichment.js +0 -121
- package/dist/services/sync/enrichment.js.map +0 -1
- package/dist/services/sync/entity-refresh.d.ts +0 -30
- package/dist/services/sync/entity-refresh.js +0 -275
- package/dist/services/sync/entity-refresh.js.map +0 -1
- package/dist/services/sync/frontmatter-extractor.d.ts +0 -40
- package/dist/services/sync/frontmatter-extractor.js +0 -279
- package/dist/services/sync/frontmatter-extractor.js.map +0 -1
- package/dist/services/sync/graph-match-state.d.ts +0 -33
- package/dist/services/sync/graph-match-state.js +0 -61
- package/dist/services/sync/graph-match-state.js.map +0 -1
- package/dist/services/sync/graph-match.d.ts +0 -53
- package/dist/services/sync/graph-match.js +0 -316
- package/dist/services/sync/graph-match.js.map +0 -1
- package/dist/services/sync/graphrag-client.d.ts +0 -43
- package/dist/services/sync/graphrag-client.js +0 -94
- package/dist/services/sync/graphrag-client.js.map +0 -1
- package/dist/services/sync/graphrag-config.d.ts +0 -16
- package/dist/services/sync/graphrag-config.js +0 -39
- package/dist/services/sync/graphrag-config.js.map +0 -1
- package/dist/services/sync/graphrag-context.d.ts +0 -14
- package/dist/services/sync/graphrag-context.js +0 -109
- package/dist/services/sync/graphrag-context.js.map +0 -1
- package/dist/services/sync/graphrag-indexer.d.ts +0 -30
- package/dist/services/sync/graphrag-indexer.js +0 -358
- package/dist/services/sync/graphrag-indexer.js.map +0 -1
- package/dist/services/sync/llm.d.ts +0 -32
- package/dist/services/sync/llm.js +0 -115
- package/dist/services/sync/llm.js.map +0 -1
- package/dist/services/sync/mcp-client.d.ts +0 -71
- package/dist/services/sync/mcp-client.js +0 -299
- package/dist/services/sync/mcp-client.js.map +0 -1
- package/dist/services/sync/model-factory.d.ts +0 -13
- package/dist/services/sync/model-factory.js +0 -38
- package/dist/services/sync/model-factory.js.map +0 -1
- package/dist/services/sync/name-quality.d.ts +0 -31
- package/dist/services/sync/name-quality.js +0 -60
- package/dist/services/sync/name-quality.js.map +0 -1
- package/dist/services/sync/output-schemas.d.ts +0 -92
- package/dist/services/sync/output-schemas.js +0 -43
- package/dist/services/sync/output-schemas.js.map +0 -1
- package/dist/services/sync/prompts.d.ts +0 -19
- package/dist/services/sync/prompts.js +0 -128
- package/dist/services/sync/prompts.js.map +0 -1
- package/dist/services/sync/reconciler.d.ts +0 -48
- package/dist/services/sync/reconciler.js +0 -294
- package/dist/services/sync/reconciler.js.map +0 -1
- package/dist/services/sync/rest-client.d.ts +0 -40
- package/dist/services/sync/rest-client.js +0 -100
- package/dist/services/sync/rest-client.js.map +0 -1
- package/dist/services/sync/source-config.d.ts +0 -67
- package/dist/services/sync/source-config.js +0 -304
- package/dist/services/sync/source-config.js.map +0 -1
- package/dist/services/sync/source-definitions/asana.d.ts +0 -14
- package/dist/services/sync/source-definitions/asana.js +0 -42
- package/dist/services/sync/source-definitions/asana.js.map +0 -1
- package/dist/services/sync/source-definitions/definitions.d.ts +0 -8
- package/dist/services/sync/source-definitions/definitions.js +0 -8
- package/dist/services/sync/source-definitions/definitions.js.map +0 -1
- package/dist/services/sync/source-definitions/gdrive.d.ts +0 -16
- package/dist/services/sync/source-definitions/gdrive.js +0 -68
- package/dist/services/sync/source-definitions/gdrive.js.map +0 -1
- package/dist/services/sync/source-definitions/granola.d.ts +0 -2
- package/dist/services/sync/source-definitions/granola.js +0 -21
- package/dist/services/sync/source-definitions/granola.js.map +0 -1
- package/dist/services/sync/source-definitions/linear.d.ts +0 -2
- package/dist/services/sync/source-definitions/linear.js +0 -62
- package/dist/services/sync/source-definitions/linear.js.map +0 -1
- package/dist/services/sync/source-definitions/obsidian.d.ts +0 -2
- package/dist/services/sync/source-definitions/obsidian.js +0 -55
- package/dist/services/sync/source-definitions/obsidian.js.map +0 -1
- package/dist/services/sync/source-definitions/pipedrive.d.ts +0 -2
- package/dist/services/sync/source-definitions/pipedrive.js +0 -43
- package/dist/services/sync/source-definitions/pipedrive.js.map +0 -1
- package/dist/services/sync/staging.d.ts +0 -53
- package/dist/services/sync/staging.js +0 -130
- package/dist/services/sync/staging.js.map +0 -1
- package/dist/services/sync/structured-extractor.d.ts +0 -57
- package/dist/services/sync/structured-extractor.js +0 -584
- package/dist/services/sync/structured-extractor.js.map +0 -1
- package/dist/services/sync/sync-runner.d.ts +0 -32
- package/dist/services/sync/sync-runner.js +0 -195
- package/dist/services/sync/sync-runner.js.map +0 -1
- package/dist/services/sync/sync-state.d.ts +0 -43
- package/dist/services/sync/sync-state.js +0 -154
- package/dist/services/sync/sync-state.js.map +0 -1
- package/dist/services/sync/types.d.ts +0 -381
- package/dist/services/sync/types.js +0 -8
- package/dist/services/sync/types.js.map +0 -1
- package/dist/services/sync/unstructured-extractor.d.ts +0 -27
- package/dist/services/sync/unstructured-extractor.js +0 -185
- package/dist/services/sync/unstructured-extractor.js.map +0 -1
- package/dist/utils/merge-resolver.d.ts +0 -59
- package/dist/utils/merge-resolver.js +0 -303
- package/dist/utils/merge-resolver.js.map +0 -1
- package/dist/utils/workspace-config.d.ts +0 -8
- package/dist/utils/workspace-config.js +0 -22
- package/dist/utils/workspace-config.js.map +0 -1
- package/dist/web/_app/immutable/assets/0.QUqBcyuu.css +0 -1
- package/dist/web/_app/immutable/assets/11.2jzI3cZY.css +0 -1
- package/dist/web/_app/immutable/assets/12.CT4xL4K3.css +0 -1
- package/dist/web/_app/immutable/assets/13.BUrHkYry.css +0 -1
- package/dist/web/_app/immutable/assets/2.5jNm7Pm1.css +0 -1
- package/dist/web/_app/immutable/assets/3.BxdqT7zi.css +0 -1
- package/dist/web/_app/immutable/assets/4.BjPwtpNd.css +0 -1
- package/dist/web/_app/immutable/assets/5.DFeGxLYf.css +0 -1
- package/dist/web/_app/immutable/assets/6.DXZr_rI_.css +0 -1
- package/dist/web/_app/immutable/assets/GraphView.D9ePpZez.css +0 -1
- package/dist/web/_app/immutable/assets/Toaster.rN8r_Hzv.css +0 -1
- package/dist/web/_app/immutable/assets/ViewToolbar.CZjsdjy4.css +0 -1
- package/dist/web/_app/immutable/assets/WorkspaceView.B-1DbivC.css +0 -1
- package/dist/web/_app/immutable/assets/wikilinks.CtSydmQl.css +0 -1
- package/dist/web/_app/immutable/chunks/3--t-YNA.js +0 -1
- package/dist/web/_app/immutable/chunks/5OU-4caN.js +0 -1
- package/dist/web/_app/immutable/chunks/7S2LGqoP.js +0 -2
- package/dist/web/_app/immutable/chunks/B6FUcAv5.js +0 -1
- package/dist/web/_app/immutable/chunks/B9gDgSlp.js +0 -1
- package/dist/web/_app/immutable/chunks/BB_5th5W.js +0 -3383
- package/dist/web/_app/immutable/chunks/BFtIWl5z.js +0 -1
- package/dist/web/_app/immutable/chunks/BHKpz6_7.js +0 -1
- package/dist/web/_app/immutable/chunks/BNfrhBeA.js +0 -1
- package/dist/web/_app/immutable/chunks/BgO5HlCg.js +0 -2
- package/dist/web/_app/immutable/chunks/BqnODQDb.js +0 -1
- package/dist/web/_app/immutable/chunks/BrebtJNG.js +0 -18
- package/dist/web/_app/immutable/chunks/BvIFhEn7.js +0 -2
- package/dist/web/_app/immutable/chunks/BvfdTHv8.js +0 -1
- package/dist/web/_app/immutable/chunks/BxGm65PH.js +0 -1
- package/dist/web/_app/immutable/chunks/BxyxnEKw.js +0 -1
- package/dist/web/_app/immutable/chunks/BygFIGq4.js +0 -1
- package/dist/web/_app/immutable/chunks/Bz0ZjVQE.js +0 -2
- package/dist/web/_app/immutable/chunks/C0LVZhvn.js +0 -1
- package/dist/web/_app/immutable/chunks/CIb_hHMy.js +0 -1
- package/dist/web/_app/immutable/chunks/CNKK6nZb.js +0 -1
- package/dist/web/_app/immutable/chunks/CQ5FjHZK.js +0 -1
- package/dist/web/_app/immutable/chunks/CSVbGg_b.js +0 -5
- package/dist/web/_app/immutable/chunks/CX_61fY8.js +0 -5
- package/dist/web/_app/immutable/chunks/CYrVHOHA.js +0 -1
- package/dist/web/_app/immutable/chunks/CaEaeeKb.js +0 -1
- package/dist/web/_app/immutable/chunks/Ch6e_wpP.js +0 -1
- package/dist/web/_app/immutable/chunks/Ci4zzCVB.js +0 -2
- package/dist/web/_app/immutable/chunks/CknqBVQE.js +0 -1
- package/dist/web/_app/immutable/chunks/Cmfiirqp.js +0 -4
- package/dist/web/_app/immutable/chunks/CqkleIqs.js +0 -1
- package/dist/web/_app/immutable/chunks/CrFpCC6p.js +0 -1
- package/dist/web/_app/immutable/chunks/CxX8hcT6.js +0 -1
- package/dist/web/_app/immutable/chunks/D0T1ps1G.js +0 -1
- package/dist/web/_app/immutable/chunks/D2ZEj9xD.js +0 -1
- package/dist/web/_app/immutable/chunks/D3sy0IkA.js +0 -2
- package/dist/web/_app/immutable/chunks/DFYOFE3o.js +0 -1
- package/dist/web/_app/immutable/chunks/DHWoAC4y.js +0 -1
- package/dist/web/_app/immutable/chunks/DYYBfXU3.js +0 -1
- package/dist/web/_app/immutable/chunks/DiNPRA8T.js +0 -1
- package/dist/web/_app/immutable/chunks/DkjsqHkM.js +0 -1
- package/dist/web/_app/immutable/chunks/DnL9f0lc.js +0 -7
- package/dist/web/_app/immutable/chunks/DpMCynC3.js +0 -1
- package/dist/web/_app/immutable/chunks/DqrybUuA.js +0 -1
- package/dist/web/_app/immutable/chunks/DsnmJJEf.js +0 -1
- package/dist/web/_app/immutable/chunks/KyjzlWRN.js +0 -2
- package/dist/web/_app/immutable/chunks/O9MAeAgV.js +0 -5
- package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +0 -1
- package/dist/web/_app/immutable/chunks/SKSQ4m85.js +0 -2
- package/dist/web/_app/immutable/chunks/WEBTyD-H.js +0 -1
- package/dist/web/_app/immutable/chunks/WSUKABI_.js +0 -1
- package/dist/web/_app/immutable/chunks/bBXT5iJP.js +0 -1
- package/dist/web/_app/immutable/chunks/vxEtkL8z.js +0 -1
- package/dist/web/_app/immutable/chunks/wDIGUaoU.js +0 -3
- package/dist/web/_app/immutable/chunks/xkNhbnff.js +0 -1
- package/dist/web/_app/immutable/chunks/zoVX1Zab.js +0 -1
- package/dist/web/_app/immutable/entry/app.GfE4z2GO.js +0 -2
- package/dist/web/_app/immutable/entry/start.H-LFJK9u.js +0 -1
- package/dist/web/_app/immutable/nodes/0.Bwi7tTNC.js +0 -2
- package/dist/web/_app/immutable/nodes/1.DgNJPEWk.js +0 -1
- package/dist/web/_app/immutable/nodes/10.BW_XCD2O.js +0 -1
- package/dist/web/_app/immutable/nodes/11.DM7RX3Ms.js +0 -1
- package/dist/web/_app/immutable/nodes/12.DKgssZo8.js +0 -1
- package/dist/web/_app/immutable/nodes/13.DCdmTre-.js +0 -1
- package/dist/web/_app/immutable/nodes/2.DOA5QBVG.js +0 -266
- package/dist/web/_app/immutable/nodes/3.bpoHQwAI.js +0 -5
- package/dist/web/_app/immutable/nodes/4.ye0Vy7A1.js +0 -11
- package/dist/web/_app/immutable/nodes/5.rxpnYrx_.js +0 -4
- package/dist/web/_app/immutable/nodes/6.DP8HSxtc.js +0 -1
- package/dist/web/_app/immutable/nodes/7.C1h4Bf-E.js +0 -1
- package/dist/web/_app/immutable/nodes/8.BzmQ7S7Y.js +0 -1
- package/dist/web/_app/immutable/nodes/9.CEakpXpF.js +0 -1
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,107 @@ 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';
|
|
40
|
+
import { registerFeaturesApiRoutes } from './routes/features-api.js';
|
|
35
41
|
import { MessageService } from '../services/message-service.js';
|
|
36
42
|
import { MemoryService } from '../services/memory-service.js';
|
|
37
43
|
import { WsHub } from './ws-hub.js';
|
|
38
44
|
import { registerWsRoute } from './routes/ws.js';
|
|
39
45
|
import { SessionManager } from './session-manager.js';
|
|
40
46
|
import { YjsManager } from './yjs-manager.js';
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
import { YjsPersistence, acquireYjsStateLock } from './yjs-persistence.js';
|
|
48
|
+
import { ensurePersonalFolder } from '../services/personal-folder.js';
|
|
49
|
+
/** Ensure every user has a personal "My Entries" folder + admin access on it (idempotent). */
|
|
50
|
+
async function ensureAllPersonalFolders(authService, workspacePath, workspaceManager) {
|
|
43
51
|
const users = authService.listUsers();
|
|
44
52
|
const workspace = new Workspace(workspacePath);
|
|
45
53
|
for (const user of users) {
|
|
46
|
-
if (workspaceManager.getUserPrivateRepo(user.id))
|
|
47
|
-
continue;
|
|
48
54
|
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();
|
|
55
|
+
await ensurePersonalFolder(workspace, authService, user);
|
|
57
56
|
}
|
|
58
|
-
catch { /*
|
|
57
|
+
catch { /* non-fatal — skip and let the user re-authenticate */ }
|
|
59
58
|
}
|
|
59
|
+
workspaceManager.reloadConfig();
|
|
60
|
+
}
|
|
61
|
+
/** MIME types for static file serving (web UI assets). */
|
|
62
|
+
const MIME_TYPES = {
|
|
63
|
+
'.html': 'text/html',
|
|
64
|
+
'.css': 'text/css',
|
|
65
|
+
'.js': 'application/javascript',
|
|
66
|
+
'.mjs': 'application/javascript',
|
|
67
|
+
'.json': 'application/json',
|
|
68
|
+
'.png': 'image/png',
|
|
69
|
+
'.jpg': 'image/jpeg',
|
|
70
|
+
'.jpeg': 'image/jpeg',
|
|
71
|
+
'.gif': 'image/gif',
|
|
72
|
+
'.svg': 'image/svg+xml',
|
|
73
|
+
'.ico': 'image/x-icon',
|
|
74
|
+
'.woff': 'font/woff',
|
|
75
|
+
'.woff2': 'font/woff2',
|
|
76
|
+
'.ttf': 'font/ttf',
|
|
77
|
+
'.otf': 'font/otf',
|
|
78
|
+
'.webp': 'image/webp',
|
|
79
|
+
'.avif': 'image/avif',
|
|
80
|
+
'.mp4': 'video/mp4',
|
|
81
|
+
'.webm': 'video/webm',
|
|
82
|
+
};
|
|
83
|
+
export function resolveStaticFilePath(webDir, urlPath) {
|
|
84
|
+
let decodedPath;
|
|
85
|
+
try {
|
|
86
|
+
decodedPath = decodeURIComponent(urlPath);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
const filePath = decodedPath === '/' ? '/index.html' : decodedPath;
|
|
92
|
+
const webRoot = resolve(webDir);
|
|
93
|
+
const fullPath = resolve(webRoot, `.${filePath}`);
|
|
94
|
+
if (fullPath !== webRoot && !fullPath.startsWith(webRoot + sep)) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return fullPath;
|
|
98
|
+
}
|
|
99
|
+
function normalizeOrigin(value) {
|
|
100
|
+
if (!value)
|
|
101
|
+
return null;
|
|
102
|
+
try {
|
|
103
|
+
return new URL(value).origin;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export function buildAllowedCorsOrigins(workspaceConfig, port) {
|
|
110
|
+
const rawOrigins = [];
|
|
111
|
+
const envOrigins = process.env.STUDIOGRAPH_CORS_ORIGINS;
|
|
112
|
+
if (envOrigins)
|
|
113
|
+
rawOrigins.push(...envOrigins.split(',').map(o => o.trim()).filter(Boolean));
|
|
114
|
+
const configured = workspaceConfig.cors_origins;
|
|
115
|
+
if (Array.isArray(configured)) {
|
|
116
|
+
rawOrigins.push(...configured.filter((o) => typeof o === 'string'));
|
|
117
|
+
}
|
|
118
|
+
else if (typeof configured === 'string') {
|
|
119
|
+
rawOrigins.push(...configured.split(',').map(o => o.trim()).filter(Boolean));
|
|
120
|
+
}
|
|
121
|
+
const serverUrl = workspaceConfig.server_url;
|
|
122
|
+
if (typeof serverUrl === 'string')
|
|
123
|
+
rawOrigins.push(serverUrl);
|
|
124
|
+
rawOrigins.push(`http://localhost:${port}`, `http://127.0.0.1:${port}`, `http://[::1]:${port}`);
|
|
125
|
+
return new Set(rawOrigins.map(normalizeOrigin).filter((o) => Boolean(o)));
|
|
126
|
+
}
|
|
127
|
+
export function isCorsOriginAllowed(origin, allowedOrigins) {
|
|
128
|
+
if (!origin)
|
|
129
|
+
return true;
|
|
130
|
+
const normalized = normalizeOrigin(origin);
|
|
131
|
+
return Boolean(normalized && allowedOrigins.has(normalized));
|
|
60
132
|
}
|
|
61
133
|
/**
|
|
62
134
|
* Auth middleware — validates JWT cookie or Authorization: Bearer <key> header.
|
|
@@ -64,7 +136,7 @@ async function ensureAllPrivateCollections(authService, workspacePath, workspace
|
|
|
64
136
|
* (except auth endpoints and static assets). When no users exist, everything
|
|
65
137
|
* is open (backward compatible).
|
|
66
138
|
*/
|
|
67
|
-
function createAuthHook(
|
|
139
|
+
function createAuthHook(authService) {
|
|
68
140
|
return async (req, reply) => {
|
|
69
141
|
// Always allow auth endpoints
|
|
70
142
|
if (req.url.startsWith('/api/auth/'))
|
|
@@ -80,27 +152,22 @@ function createAuthHook(apiKeys, authService) {
|
|
|
80
152
|
// WebSocket route handles its own auth
|
|
81
153
|
if (req.url.startsWith('/ws'))
|
|
82
154
|
return;
|
|
83
|
-
// Allow static assets (JS, CSS, fonts, images) — needed for login page
|
|
84
|
-
|
|
155
|
+
// Allow static assets (JS, CSS, fonts, images) — needed for login page.
|
|
156
|
+
// Covers SvelteKit-bundled output under /_app/ and root-level public
|
|
157
|
+
// files (favicon.ico, studiograph-logomark.svg, …) identified by a file
|
|
158
|
+
// extension on a non-API GET.
|
|
159
|
+
if (req.url.startsWith('/_app/'))
|
|
160
|
+
return;
|
|
161
|
+
if (req.method === 'GET' &&
|
|
162
|
+
!req.url.startsWith('/api/') &&
|
|
163
|
+
extname(req.url.split('?')[0]).length > 1)
|
|
85
164
|
return;
|
|
86
165
|
// Allow HTML page requests (SPA routing) — the app handles auth client-side
|
|
87
166
|
if (req.method === 'GET' && req.headers.accept?.includes('text/html'))
|
|
88
167
|
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
|
-
}
|
|
168
|
+
// If no users configured, allow everything (open mode — single-tenant dev)
|
|
169
|
+
if (!authService.hasUsers())
|
|
102
170
|
return;
|
|
103
|
-
}
|
|
104
171
|
// Check JWT cookie (web UI sessions)
|
|
105
172
|
const jwtToken = req.cookies?.['__sg_token'];
|
|
106
173
|
if (jwtToken) {
|
|
@@ -110,11 +177,26 @@ function createAuthHook(apiKeys, authService) {
|
|
|
110
177
|
return;
|
|
111
178
|
}
|
|
112
179
|
}
|
|
113
|
-
// Check Bearer token (API clients, MCP)
|
|
180
|
+
// Check Bearer token (API clients, MCP, CLI): JWT → per-user API token.
|
|
181
|
+
// Both yield a user identity. There is no shared workspace key — every
|
|
182
|
+
// caller must be identifiable so access control can enforce per-folder rules.
|
|
114
183
|
const authHeader = req.headers['authorization'];
|
|
115
184
|
const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : undefined;
|
|
116
|
-
if (bearer
|
|
117
|
-
|
|
185
|
+
if (bearer) {
|
|
186
|
+
const jwtUser = authService.verifyToken(bearer);
|
|
187
|
+
if (jwtUser) {
|
|
188
|
+
req.user = jwtUser;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const tokenMeta = authService.verifyApiTokenWithMeta(bearer);
|
|
192
|
+
if (tokenMeta) {
|
|
193
|
+
req.user = tokenMeta.user;
|
|
194
|
+
// Stash the token's user-set name so downstream surfaces (MCP, agent
|
|
195
|
+
// activity) can label the integration. Absent for cookie/JWT auth.
|
|
196
|
+
req.apiTokenName = tokenMeta.tokenName;
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
118
200
|
// Check Basic Auth (CLI join command)
|
|
119
201
|
if (authHeader?.startsWith('Basic ')) {
|
|
120
202
|
try {
|
|
@@ -133,22 +215,128 @@ function createAuthHook(apiKeys, authService) {
|
|
|
133
215
|
return reply.status(401).send({ error: 'Unauthorized' });
|
|
134
216
|
};
|
|
135
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Phase 11 — preSerialization payload sanitizer.
|
|
220
|
+
*
|
|
221
|
+
* The API has many routes that respond with `{ error: err.message }` from a
|
|
222
|
+
* catch block. Those messages can carry upstream provider errors, git
|
|
223
|
+
* stderr (with embedded credentials), or other free-form text that we
|
|
224
|
+
* don't want surfacing in HTTP responses. Walk the response payload,
|
|
225
|
+
* sanitize any string value at a "message" / "error" / "detail" key,
|
|
226
|
+
* and leave structured fields (status codes, IDs, classification flags)
|
|
227
|
+
* alone.
|
|
228
|
+
*
|
|
229
|
+
* Conservatively, we ONLY redact at keys that conventionally carry
|
|
230
|
+
* free-form text. Arbitrary string fields (entity names, IDs, etc.) are
|
|
231
|
+
* left untouched so we don't garble legitimate content. The Fastify
|
|
232
|
+
* logger sanitization (above) handles log-line redaction independently;
|
|
233
|
+
* this hook focuses on the wire response.
|
|
234
|
+
*/
|
|
235
|
+
const FREEFORM_ERROR_KEYS = new Set(['error', 'message', 'detail', 'stack', 'description', 'error_description']);
|
|
236
|
+
function sanitizeResponsePayload(value) {
|
|
237
|
+
if (typeof value === 'string')
|
|
238
|
+
return sanitize(value);
|
|
239
|
+
if (Array.isArray(value))
|
|
240
|
+
return value.map(sanitizeResponsePayload);
|
|
241
|
+
if (value && typeof value === 'object') {
|
|
242
|
+
const out = {};
|
|
243
|
+
for (const [k, v] of Object.entries(value)) {
|
|
244
|
+
if (FREEFORM_ERROR_KEYS.has(k) && typeof v === 'string') {
|
|
245
|
+
out[k] = sanitize(v);
|
|
246
|
+
}
|
|
247
|
+
else if (v && typeof v === 'object') {
|
|
248
|
+
out[k] = sanitizeResponsePayload(v);
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
out[k] = v;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
return value;
|
|
257
|
+
}
|
|
136
258
|
export async function createServer(config) {
|
|
259
|
+
// Phase 11: every Fastify log line flows through sanitize() before
|
|
260
|
+
// reaching stdout. A thin Writable wrapper passes each chunk through
|
|
261
|
+
// the redactor; pino accepts any `stream` with a `write()` method.
|
|
262
|
+
// STUDIOGRAPH_LOG_RAW=1 disables redaction for local debugging.
|
|
263
|
+
const shouldRedactFastifyLogs = process.env.STUDIOGRAPH_LOG_RAW !== '1' &&
|
|
264
|
+
(process.env.NODE_ENV === 'production' || !!process.env.RAILWAY_ENVIRONMENT);
|
|
265
|
+
const redactingStream = {
|
|
266
|
+
write(chunk) {
|
|
267
|
+
const out = shouldRedactFastifyLogs ? sanitize(chunk) : chunk;
|
|
268
|
+
process.stdout.write(out);
|
|
269
|
+
},
|
|
270
|
+
};
|
|
137
271
|
const fastify = Fastify({
|
|
138
272
|
logger: process.env.STUDIOGRAPH_LOG === '1'
|
|
139
|
-
?
|
|
140
|
-
: { level: 'warn' },
|
|
273
|
+
? { stream: redactingStream }
|
|
274
|
+
: { level: 'warn', stream: redactingStream },
|
|
141
275
|
bodyLimit: 10 * 1024 * 1024, // 10 MB — entities can be large (e.g. meeting transcripts)
|
|
142
276
|
});
|
|
277
|
+
// Phase 11: sanitize uncaught errors before serialization so neither
|
|
278
|
+
// err.message nor err.stack echoes upstream secrets. Stable error
|
|
279
|
+
// codes (err.code) pass through; we only redact freeform text.
|
|
280
|
+
fastify.setErrorHandler((error, _req, reply) => {
|
|
281
|
+
const sanitizedMsg = shouldRedactFastifyLogs ? sanitize(error.message) : error.message;
|
|
282
|
+
const status = error.statusCode ?? 500;
|
|
283
|
+
fastify.log.error({
|
|
284
|
+
err: { message: sanitizedMsg, code: error.code },
|
|
285
|
+
});
|
|
286
|
+
reply.status(status).send({
|
|
287
|
+
statusCode: status,
|
|
288
|
+
code: error.code,
|
|
289
|
+
error: status >= 500 ? 'Internal Server Error' : (error.name || 'Error'),
|
|
290
|
+
message: status >= 500 ? 'An internal error occurred.' : sanitizedMsg,
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
// Phase 11: pre-serialization hook scans every response body for
|
|
294
|
+
// freeform error/message strings and runs them through sanitize().
|
|
295
|
+
// This catches the many `reply.status(4xx).send({ error: err.message })`
|
|
296
|
+
// call sites scattered across the API routes — without this, an
|
|
297
|
+
// upstream provider error or git remote error would echo through to
|
|
298
|
+
// the API consumer with embedded credentials. Stable error codes pass
|
|
299
|
+
// through unchanged. Only kicks in when redaction is enabled.
|
|
300
|
+
if (shouldRedactFastifyLogs) {
|
|
301
|
+
fastify.addHook('preSerialization', async (_req, _reply, payload) => {
|
|
302
|
+
if (!payload || typeof payload !== 'object')
|
|
303
|
+
return payload;
|
|
304
|
+
return sanitizeResponsePayload(payload);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
143
307
|
// CORS
|
|
308
|
+
const allowedCorsOrigins = buildAllowedCorsOrigins(config.workspaceConfig, config.port);
|
|
144
309
|
await fastify.register(cors, {
|
|
145
|
-
origin:
|
|
310
|
+
origin: (origin, cb) => {
|
|
311
|
+
cb(null, isCorsOriginAllowed(origin, allowedCorsOrigins));
|
|
312
|
+
},
|
|
146
313
|
credentials: true,
|
|
147
314
|
});
|
|
148
315
|
// Cookie support for web UI session auth
|
|
149
316
|
await fastify.register(cookie);
|
|
150
|
-
// WebSocket support for real-time notifications
|
|
151
|
-
|
|
317
|
+
// WebSocket support for real-time notifications.
|
|
318
|
+
//
|
|
319
|
+
// perMessageDeflate is enabled here on purpose. Our origin would otherwise
|
|
320
|
+
// leave compression off (ws lib default), but Railway's edge proxy
|
|
321
|
+
// negotiates `permessage-deflate` with the browser anyway and does its own
|
|
322
|
+
// inflate/deflate layer in the middle — which Safari/WebKit mis-decodes,
|
|
323
|
+
// producing truncated buffers and `RangeError: Length out of range of buffer`
|
|
324
|
+
// inside Yjs's varint reader, followed by WS disconnect loops.
|
|
325
|
+
//
|
|
326
|
+
// Negotiating compression at the origin forces end-to-end deflate (Node's
|
|
327
|
+
// zlib ↔ browser) and prevents the proxy from inserting its own layer.
|
|
328
|
+
// `noContextTakeover` on both sides keeps each frame independently
|
|
329
|
+
// decompressible, which avoids cross-frame state bugs that have historically
|
|
330
|
+
// hit Safari.
|
|
331
|
+
await fastify.register(websocket, {
|
|
332
|
+
options: {
|
|
333
|
+
perMessageDeflate: {
|
|
334
|
+
threshold: 1024,
|
|
335
|
+
serverNoContextTakeover: true,
|
|
336
|
+
clientNoContextTakeover: true,
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
});
|
|
152
340
|
// Multipart support for file uploads (images, assets)
|
|
153
341
|
await fastify.register(multipart, { limits: { fileSize: 10 * 1024 * 1024 } });
|
|
154
342
|
fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, (req, body, done) => {
|
|
@@ -169,28 +357,78 @@ export async function createServer(config) {
|
|
|
169
357
|
done(null); // Don't consume the body — the route handler pipes req.raw directly
|
|
170
358
|
});
|
|
171
359
|
}
|
|
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
|
|
360
|
+
// Initialize auth service, WebSocket hub, session manager, and collab server.
|
|
361
|
+
// Phase 8: when the boot path provided master-key options, hand them through
|
|
362
|
+
// so OAuth tokens + per-user secret prefs use the encrypted column path.
|
|
363
|
+
const authService = new AuthService(config.workspacePath, config.authCryptoOptions);
|
|
364
|
+
// Ensure all users have their personal "My Entries" folder
|
|
365
|
+
await ensureAllPersonalFolders(authService, config.workspacePath, config.workspaceManager);
|
|
366
|
+
const { getCurrentVersion } = await import('../utils/version-checker.js');
|
|
367
|
+
const wsHub = new WsHub(getCurrentVersion());
|
|
179
368
|
const messageService = new MessageService(config.workspacePath);
|
|
180
369
|
const sessionManager = new SessionManager(config.workspaceManager, wsHub);
|
|
181
|
-
|
|
370
|
+
// Recover any dirty repos before accepting requests. Replays persisted
|
|
371
|
+
// pending commits from a previous process AND sweeps every working tree
|
|
372
|
+
// for uncommitted state. Catches anything dropped by a crash, OOM, or
|
|
373
|
+
// hard restart. Logs and continues on failure — recovery is best-effort
|
|
374
|
+
// and must never block server startup.
|
|
375
|
+
try {
|
|
376
|
+
await sessionManager.recoverOnBoot();
|
|
377
|
+
}
|
|
378
|
+
catch (err) {
|
|
379
|
+
console.warn('[server] sessionManager.recoverOnBoot failed:', err.message);
|
|
380
|
+
}
|
|
381
|
+
// Persistence layer: durable Y.Doc snapshot store across server restarts.
|
|
382
|
+
// Lives at `<workspace>/.studiograph/yjs-state/` — gitignored binary state
|
|
383
|
+
// separate from the .md files (which remain canonical for git, MCP, agents).
|
|
384
|
+
// See yjs-persistence.ts for the file format and concurrency model.
|
|
385
|
+
const yjsStateDir = join(config.workspacePath, '.studiograph', 'yjs-state');
|
|
386
|
+
// Single-instance lock. Throws if another studiograph server is already
|
|
387
|
+
// running against this workspace. We don't support horizontal scaling today
|
|
388
|
+
// (no shared Yjs pubsub), so the safe default is to fail fast on misuse
|
|
389
|
+
// rather than silently corrupt snapshots via concurrent writers.
|
|
390
|
+
const releaseYjsLock = acquireYjsStateLock(yjsStateDir);
|
|
391
|
+
const yjsPersistence = new YjsPersistence(yjsStateDir);
|
|
392
|
+
const yjsManager = new YjsManager(config.workspaceManager, yjsPersistence);
|
|
393
|
+
// Wire the Yjs persistence layer to follow structural .md mutations.
|
|
394
|
+
// delete / rename / changeType all change a doc's identity (path on disk
|
|
395
|
+
// and its docName), so the snapshot file has to move with it. Without
|
|
396
|
+
// these hooks, snapshots leak (orphaned files for deleted entities) or
|
|
397
|
+
// serve stale state at the new identity (ghost content after a rename).
|
|
398
|
+
config.workspaceManager.setGraphMutationCallbacks({
|
|
399
|
+
onDelete: (repo, entityType, entityId) => yjsPersistence.delete(`${repo}/${entityType}/${entityId}`),
|
|
400
|
+
onRename: (repo, entityType, oldId, newId) => yjsPersistence.rename(`${repo}/${entityType}/${oldId}`, `${repo}/${entityType}/${newId}`),
|
|
401
|
+
onChangeType: (repo, entityId, fromType, toType) => yjsPersistence.rename(`${repo}/${fromType}/${entityId}`, `${repo}/${toType}/${entityId}`),
|
|
402
|
+
// Smart-merge the just-written .md content into the active Y.Doc. Without
|
|
403
|
+
// this, server-side bypass writes (MCP update_entity, agent tools,
|
|
404
|
+
// event processor) get silently overwritten by the next autosave PUT
|
|
405
|
+
// carrying stale Y.Text content. Sync — must complete before any await
|
|
406
|
+
// yields in graph.update so a concurrent autosave can't race in.
|
|
407
|
+
onContentUpdate: (repo, entityType, entityId) => yjsManager.syncDocFromDisk(`${repo}/${entityType}/${entityId}`),
|
|
408
|
+
});
|
|
182
409
|
// Register auth API routes (before the auth hook so they are always accessible)
|
|
183
410
|
await registerAuthApiRoutes(fastify, authService, config.workspacePath, config.workspaceManager, config.workspaceConfig.team_name);
|
|
184
411
|
// Auth hook — applied to all routes
|
|
185
|
-
const authHook = createAuthHook(
|
|
412
|
+
const authHook = createAuthHook(authService);
|
|
186
413
|
fastify.addHook('preHandler', authHook);
|
|
187
414
|
// Register WebSocket route (real-time change notifications + cursor broadcasting)
|
|
188
|
-
await registerWsRoute(fastify, wsHub, authService, yjsManager);
|
|
189
|
-
// Register
|
|
190
|
-
await
|
|
415
|
+
await registerWsRoute(fastify, wsHub, authService, config.workspaceManager, yjsManager);
|
|
416
|
+
// Register feature flags API routes
|
|
417
|
+
await registerFeaturesApiRoutes(fastify);
|
|
418
|
+
// Register graph API routes (with per-folder access filtering)
|
|
419
|
+
await registerGraphApiRoutes(fastify, config.workspaceManager, authService, wsHub, sessionManager, yjsManager);
|
|
191
420
|
// Register workspace API routes (git operations)
|
|
192
|
-
await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser);
|
|
193
|
-
// Register
|
|
421
|
+
await registerWorkspaceApiRoutes(fastify, config.workspaceManager, config.gitUser, authService);
|
|
422
|
+
// Register health endpoints (per-repo dirty status)
|
|
423
|
+
await registerHealthApiRoutes(fastify, config.workspaceManager, sessionManager);
|
|
424
|
+
// Register config + workspace data API routes (for `studiograph push/pull --remote`)
|
|
425
|
+
await registerConfigApiRoutes(fastify, config.workspaceManager, config.workspacePath, authService);
|
|
426
|
+
// Register Phase 7 settings/secrets/audit API routes. Owner-only via
|
|
427
|
+
// isWorkspaceOwner() inside each handler.
|
|
428
|
+
await registerSettingsApiRoutes(fastify, authService);
|
|
429
|
+
await registerSecretsApiRoutes(fastify, authService);
|
|
430
|
+
await registerAuditApiRoutes(fastify, authService);
|
|
431
|
+
// Register permissions API routes (self-hosted folder access)
|
|
194
432
|
await registerPermissionsApiRoutes(fastify, authService, config.workspaceManager, wsHub);
|
|
195
433
|
// Messages API routes registered after agent init (below) so @agent invocation works
|
|
196
434
|
// Register connectors API routes (MCP connector management + OAuth)
|
|
@@ -236,7 +474,21 @@ export async function createServer(config) {
|
|
|
236
474
|
await registerBriefingApiRoutes(fastify, config.workspaceManager, authService, config.workspacePath, wsHub, getToolsForUser);
|
|
237
475
|
// Background briefing refresh — check staleness for online users every heartbeat tick
|
|
238
476
|
{
|
|
239
|
-
|
|
477
|
+
/** Format a Date as YYYY-MM-DD in the given IANA timezone. Falls back to
|
|
478
|
+
* UTC when the timezone is invalid so we never crash on bad input. */
|
|
479
|
+
const localDateIn = (d, tz) => {
|
|
480
|
+
try {
|
|
481
|
+
return new Intl.DateTimeFormat('en-CA', {
|
|
482
|
+
timeZone: tz,
|
|
483
|
+
year: 'numeric',
|
|
484
|
+
month: '2-digit',
|
|
485
|
+
day: '2-digit',
|
|
486
|
+
}).format(d);
|
|
487
|
+
}
|
|
488
|
+
catch {
|
|
489
|
+
return d.toISOString().slice(0, 10);
|
|
490
|
+
}
|
|
491
|
+
};
|
|
240
492
|
const loadWsConfig = () => {
|
|
241
493
|
const cfgPath = join(config.workspacePath, '.studiograph', 'workspace.json');
|
|
242
494
|
if (!existsSync(cfgPath))
|
|
@@ -252,22 +504,26 @@ export async function createServer(config) {
|
|
|
252
504
|
const allRepos = config.workspaceManager.getAllRepoConfigs();
|
|
253
505
|
const user = authService.findUserById(userId);
|
|
254
506
|
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);
|
|
507
|
+
return allRepos.filter(r => !r.personal).map(r => r.name);
|
|
508
|
+
// Folder membership is the sole source of truth — no role-based short-circuit.
|
|
509
|
+
const allowed = new Set(authService.getUserFolders(user.id));
|
|
510
|
+
return allRepos.filter(r => allowed.has(r.name)).map(r => r.name);
|
|
260
511
|
};
|
|
261
|
-
wsHub.setBriefingRefresh((userId) => {
|
|
512
|
+
wsHub.setBriefingRefresh((userId, tz) => {
|
|
262
513
|
const brief = authService.getHomeBrief(userId);
|
|
263
514
|
if (!brief)
|
|
264
515
|
return false;
|
|
265
516
|
// Always regenerate if no briefing text exists yet (migration from old insights system)
|
|
266
517
|
const cached = authService.getCachedBriefing(userId);
|
|
267
|
-
if (!cached.briefingText)
|
|
518
|
+
if (!cached.briefingText || !cached.generatedAt)
|
|
268
519
|
return true;
|
|
269
|
-
|
|
270
|
-
|
|
520
|
+
// Stale when the cached briefing was generated on an earlier calendar
|
|
521
|
+
// date in the user's local timezone. This anchors "daily briefing"
|
|
522
|
+
// to the user's morning rather than a rolling 24h window, and aligns
|
|
523
|
+
// with the chat session's local-calendar-day rollover.
|
|
524
|
+
const cachedLocal = localDateIn(new Date(cached.generatedAt), tz);
|
|
525
|
+
const todayLocal = localDateIn(new Date(), tz);
|
|
526
|
+
return cachedLocal < todayLocal;
|
|
271
527
|
}, async (userId) => {
|
|
272
528
|
const brief = authService.getHomeBrief(userId);
|
|
273
529
|
const repoNames = getReposForUser(userId);
|
|
@@ -283,43 +539,11 @@ export async function createServer(config) {
|
|
|
283
539
|
}
|
|
284
540
|
});
|
|
285
541
|
}
|
|
286
|
-
// Register
|
|
287
|
-
await
|
|
542
|
+
// Register event ingest API (meeting capture from Chrome extension + desktop tray)
|
|
543
|
+
await registerEventIngestRoutes(fastify, config.workspaceManager, authService, wsHub, yjsManager);
|
|
288
544
|
// 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
|
|
545
|
+
await registerMcpRoutes(fastify, config.workspaceManager, authService, wsHub);
|
|
546
|
+
// Initialize memory service and agent — non-fatal so the server can still serve graph API
|
|
323
547
|
const memoryService = new MemoryService();
|
|
324
548
|
let agent = null;
|
|
325
549
|
try {
|
|
@@ -328,13 +552,16 @@ export async function createServer(config) {
|
|
|
328
552
|
workspacePath: config.workspacePath,
|
|
329
553
|
workspaceConfig: config.workspaceConfig,
|
|
330
554
|
gitUser: config.gitUser,
|
|
331
|
-
skillsDirs: appSkillsDirs,
|
|
332
|
-
toolsDirs: appToolsDirs,
|
|
333
555
|
recentMemory,
|
|
334
556
|
workspaceManager: config.workspaceManager,
|
|
335
557
|
messageService,
|
|
558
|
+
// Y.Doc reconciliation now happens at the graph layer via the
|
|
559
|
+
// onContentUpdate callback (see setGraphMutationCallbacks above).
|
|
560
|
+
// Every graph.update() that doesn't explicitly opt out of Yjs sync
|
|
561
|
+
// (skipYjsSync) fires it, so the agent gets it for free without
|
|
562
|
+
// wiring an orchestrator-level hook.
|
|
336
563
|
});
|
|
337
|
-
await registerChatRoutes(fastify, agent, memoryService);
|
|
564
|
+
await registerChatRoutes(fastify, agent, wsHub, authService, memoryService);
|
|
338
565
|
await registerCaptureRoutes(fastify, agent);
|
|
339
566
|
await registerUrlRoutes(fastify);
|
|
340
567
|
}
|
|
@@ -358,63 +585,30 @@ export async function createServer(config) {
|
|
|
358
585
|
let heartbeatService = null;
|
|
359
586
|
try {
|
|
360
587
|
const { HeartbeatService } = await import('../services/heartbeat.js');
|
|
361
|
-
heartbeatService = new HeartbeatService(messageService, config.workspaceManager, wsHub,
|
|
588
|
+
heartbeatService = new HeartbeatService(messageService, config.workspaceManager, wsHub, agent ?? null);
|
|
362
589
|
heartbeatService.start();
|
|
363
590
|
}
|
|
364
591
|
catch (err) {
|
|
365
592
|
fastify.log.warn(`Heartbeat not available: ${err.message}`);
|
|
366
593
|
}
|
|
367
|
-
// Register messages API routes (
|
|
594
|
+
// Register messages API routes (folder-scoped messaging with @agent support)
|
|
368
595
|
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
596
|
// GET /api/workspace — workspace metadata
|
|
390
597
|
fastify.get('/api/workspace', async (_req, reply) => {
|
|
391
598
|
const workspace = new Workspace(config.workspacePath);
|
|
392
599
|
const about = workspace.loadAbout();
|
|
393
|
-
return reply.send({ name: config.workspaceConfig.team_name, about
|
|
600
|
+
return reply.send({ name: config.workspaceConfig.team_name, about });
|
|
394
601
|
});
|
|
395
|
-
// PUT /api/workspace — update workspace identity (
|
|
602
|
+
// PUT /api/workspace — update workspace identity (owner only)
|
|
396
603
|
fastify.put('/api/workspace', async (req, reply) => {
|
|
397
604
|
const user = req.user;
|
|
398
|
-
if (user && !
|
|
399
|
-
return reply.status(403).send({ error: '
|
|
605
|
+
if (user && !isWorkspaceOwner(user.role)) {
|
|
606
|
+
return reply.status(403).send({ error: 'Workspace owner access required' });
|
|
400
607
|
}
|
|
401
|
-
const { name, about
|
|
608
|
+
const { name, about } = req.body ?? {};
|
|
402
609
|
const workspace = new Workspace(config.workspacePath);
|
|
403
|
-
let configChanged = false;
|
|
404
610
|
if (typeof name === 'string' && name.trim()) {
|
|
405
611
|
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
612
|
workspace.writeConfig(config.workspaceConfig);
|
|
419
613
|
}
|
|
420
614
|
if (typeof about === 'string') {
|
|
@@ -422,24 +616,28 @@ export async function createServer(config) {
|
|
|
422
616
|
}
|
|
423
617
|
return reply.send({ success: true });
|
|
424
618
|
});
|
|
425
|
-
// GET /api/workspace/mcp-config — MCP client configuration snippet
|
|
619
|
+
// GET /api/workspace/mcp-config — MCP client configuration snippet.
|
|
620
|
+
// Returns a template with `<your-token-here>` in the Authorization header;
|
|
621
|
+
// the frontend fills it in after the user mints a personal token via
|
|
622
|
+
// POST /api/auth/tokens. We never embed a shared key here because doing so
|
|
623
|
+
// would leak a workspace-wide credential and re-introduce the bug the
|
|
624
|
+
// per-user-token model exists to solve.
|
|
426
625
|
fastify.get('/api/workspace/mcp-config', async (req, reply) => {
|
|
427
626
|
const proto = req.headers['x-forwarded-proto'] === 'https' ? 'https' : (req.protocol ?? 'http');
|
|
428
627
|
const host = req.headers['x-forwarded-host'] || req.headers.host || 'localhost';
|
|
429
628
|
const baseUrl = `${proto}://${host}`;
|
|
430
|
-
const apiKey = authService.getApiKey();
|
|
431
629
|
const mcpConfig = {
|
|
432
630
|
mcpServers: {
|
|
433
631
|
studiograph: {
|
|
434
632
|
type: 'streamable-http',
|
|
435
633
|
url: `${baseUrl}/mcp`,
|
|
436
634
|
headers: {
|
|
437
|
-
Authorization:
|
|
635
|
+
Authorization: 'Bearer <your-token-here>',
|
|
438
636
|
},
|
|
439
637
|
},
|
|
440
638
|
},
|
|
441
639
|
};
|
|
442
|
-
return reply.send({ config: mcpConfig });
|
|
640
|
+
return reply.send({ config: mcpConfig, url: `${baseUrl}/mcp` });
|
|
443
641
|
});
|
|
444
642
|
// DELETE /api/memory — clear all agent memory files
|
|
445
643
|
fastify.delete('/api/memory', async (_req, reply) => {
|
|
@@ -451,19 +649,6 @@ export async function createServer(config) {
|
|
|
451
649
|
const count = agent?.clearSessions() ?? 0;
|
|
452
650
|
return reply.send({ cleared: count });
|
|
453
651
|
});
|
|
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
652
|
// Serve web UI static files from dist/web/ with SPA fallback
|
|
468
653
|
// When running via tsx from source, import.meta.dirname is src/server/ so ../web doesn't exist.
|
|
469
654
|
// Fall back to dist/web/ relative to project root.
|
|
@@ -471,12 +656,34 @@ export async function createServer(config) {
|
|
|
471
656
|
const webDir = existsSync(webDirCandidate) ? webDirCandidate : join(import.meta.dirname, '..', '..', 'dist', 'web');
|
|
472
657
|
if (existsSync(webDir)) {
|
|
473
658
|
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.
|
|
659
|
+
// SPA fallback: if any API route returns a JSON error for a browser GET,
|
|
660
|
+
// serve the SPA instead so client-side routing can handle the URL.
|
|
478
661
|
// Read fresh from disk each time so rebuilds take effect without server restart.
|
|
479
662
|
const readIndexHtml = () => readFileSync(indexPath);
|
|
663
|
+
/**
|
|
664
|
+
* Cache policy for static assets:
|
|
665
|
+
* - `/_app/immutable/*` are content-hashed by SvelteKit, so the URL
|
|
666
|
+
* changes every time the file does — safe to cache forever.
|
|
667
|
+
* - `index.html` (and the SPA fallback) MUST revalidate every load,
|
|
668
|
+
* otherwise stale HTML keeps pointing at expired immutable hashes.
|
|
669
|
+
* - Other root assets (favicons, og images, etc.) get a modest TTL.
|
|
670
|
+
*
|
|
671
|
+
* Without these headers the upstream CDN (Fastly in front of Railway)
|
|
672
|
+
* forwards almost every request to origin, producing multi-second
|
|
673
|
+
* TTFB on cold edges and a 3-5s "black screen" while the SPA bundle
|
|
674
|
+
* loads.
|
|
675
|
+
*/
|
|
676
|
+
function setStaticCacheHeader(reply, urlPath) {
|
|
677
|
+
if (urlPath.startsWith('/_app/immutable/')) {
|
|
678
|
+
reply.header('Cache-Control', 'public, max-age=31536000, immutable');
|
|
679
|
+
}
|
|
680
|
+
else if (urlPath === '/' || urlPath === '/index.html' || !extname(urlPath)) {
|
|
681
|
+
reply.header('Cache-Control', 'no-cache');
|
|
682
|
+
}
|
|
683
|
+
else {
|
|
684
|
+
reply.header('Cache-Control', 'public, max-age=3600');
|
|
685
|
+
}
|
|
686
|
+
}
|
|
480
687
|
fastify.addHook('onSend', async (request, reply, payload) => {
|
|
481
688
|
if (reply.sent)
|
|
482
689
|
return payload;
|
|
@@ -487,23 +694,24 @@ export async function createServer(config) {
|
|
|
487
694
|
typeof ct === 'string' && ct.includes('application/json')) {
|
|
488
695
|
reply.removeHeader('content-length');
|
|
489
696
|
reply.code(200).type('text/html');
|
|
697
|
+
reply.header('Cache-Control', 'no-cache');
|
|
490
698
|
return readIndexHtml();
|
|
491
699
|
}
|
|
492
700
|
return payload;
|
|
493
701
|
});
|
|
494
|
-
// Use setNotFoundHandler so
|
|
702
|
+
// Use setNotFoundHandler so API routes take priority over SPA fallback
|
|
495
703
|
fastify.setNotFoundHandler(async (req, reply) => {
|
|
496
704
|
const urlPath = req.url.split('?')[0];
|
|
497
|
-
const
|
|
498
|
-
|
|
705
|
+
const fullPath = resolveStaticFilePath(webDir, urlPath);
|
|
706
|
+
if (!fullPath) {
|
|
707
|
+
return reply.status(400).send({ error: 'Invalid path' });
|
|
708
|
+
}
|
|
499
709
|
// Serve the file if it exists (and is a file, not directory)
|
|
500
710
|
if (existsSync(fullPath) && statSync(fullPath).isFile()) {
|
|
501
|
-
if (fullPath.includes('..')) {
|
|
502
|
-
return reply.status(400).send({ error: 'Invalid path' });
|
|
503
|
-
}
|
|
504
711
|
const ext = extname(fullPath).toLowerCase();
|
|
505
712
|
const contentType = MIME_TYPES[ext] || 'application/octet-stream';
|
|
506
713
|
reply.type(contentType);
|
|
714
|
+
setStaticCacheHeader(reply, urlPath);
|
|
507
715
|
return reply.send(createReadStream(fullPath));
|
|
508
716
|
}
|
|
509
717
|
// SPA fallback — serve index.html for client-side routing.
|
|
@@ -513,18 +721,21 @@ export async function createServer(config) {
|
|
|
513
721
|
const hasFileExt = extname(urlPath).length > 1;
|
|
514
722
|
if (req.method === 'GET' && !hasFileExt && existsSync(indexPath)) {
|
|
515
723
|
reply.type('text/html');
|
|
724
|
+
reply.header('Cache-Control', 'no-cache');
|
|
516
725
|
return reply.send(createReadStream(indexPath));
|
|
517
726
|
}
|
|
518
727
|
return reply.status(404).send({ error: 'Not found' });
|
|
519
728
|
});
|
|
520
729
|
fastify.log.info('Web UI enabled — serving from dist/web/');
|
|
521
730
|
}
|
|
522
|
-
// Graceful shutdown
|
|
731
|
+
// Graceful shutdown — sessionManager.shutdown() flushes pending commits
|
|
732
|
+
// BEFORE tearing down the timer (the old destroy()-only path could lose
|
|
733
|
+
// dirty sessions if called without an explicit flush).
|
|
523
734
|
fastify.addHook('onClose', async () => {
|
|
524
|
-
await sessionManager.
|
|
525
|
-
|
|
526
|
-
yjsManager.destroy();
|
|
735
|
+
await sessionManager.shutdown();
|
|
736
|
+
await yjsManager.destroy();
|
|
527
737
|
wsHub.destroy();
|
|
738
|
+
releaseYjsLock();
|
|
528
739
|
});
|
|
529
740
|
return fastify;
|
|
530
741
|
}
|