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
|
@@ -3,18 +3,147 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Pull and push changes across the workspace:
|
|
5
5
|
* - the .studiograph config repo (if it has a git remote)
|
|
6
|
-
* - each entity
|
|
6
|
+
* - each entity folder that is a git repo with a remote
|
|
7
7
|
*
|
|
8
8
|
* Works with both GitHub remotes and the embedded git server.
|
|
9
9
|
*/
|
|
10
10
|
import { Command } from 'commander';
|
|
11
11
|
import { log, outro, text, password as passwordPrompt } from '@clack/prompts';
|
|
12
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from 'fs';
|
|
12
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
13
13
|
import { join } from 'path';
|
|
14
14
|
import { Workspace } from '../../core/workspace.js';
|
|
15
15
|
import { AuthService } from '../../services/auth-service.js';
|
|
16
16
|
import { ConnectorManager } from '../../mcp/connector-manager.js';
|
|
17
|
-
import {
|
|
17
|
+
import { buildConfigBundle } from '../../core/secrets/bundle.js';
|
|
18
|
+
import { gitClone, gitPull, gitPush, gitPushWithCredentials, gitSetRemote, gitHasRemote } from '../../utils/git.js';
|
|
19
|
+
import { getStudiographToken, setStudiographToken, clearStudiographToken } from '../../core/user-config.js';
|
|
20
|
+
async function resolveRemoteAuth(base, _workspaceRoot, opts) {
|
|
21
|
+
// 1-2. Explicit token or env var
|
|
22
|
+
const explicitToken = opts.token || process.env.STUDIOGRAPH_TOKEN;
|
|
23
|
+
if (explicitToken) {
|
|
24
|
+
const token = explicitToken.trim();
|
|
25
|
+
return {
|
|
26
|
+
httpHeader: { 'Authorization': `Bearer ${token}` },
|
|
27
|
+
gitCredentials: { username: '_token_', password: token },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
// 3. Explicit email/password or env vars
|
|
31
|
+
const email = opts.email || process.env.STUDIOGRAPH_EMAIL;
|
|
32
|
+
const password = opts.password || process.env.STUDIOGRAPH_PASSWORD;
|
|
33
|
+
if (email && password) {
|
|
34
|
+
const httpHeader = await loginForCookie(base, email, password);
|
|
35
|
+
return { httpHeader, gitCredentials: { username: email, password } };
|
|
36
|
+
}
|
|
37
|
+
// 4. Stored per-user token from ~/.studiograph/user.json
|
|
38
|
+
const storedToken = getStudiographToken(base);
|
|
39
|
+
if (storedToken) {
|
|
40
|
+
const httpHeader = { 'Authorization': `Bearer ${storedToken}` };
|
|
41
|
+
// Probe a cheap authenticated endpoint so a revoked / expired / rebuilt-DB
|
|
42
|
+
// token doesn't wedge push/pull. On 401, clear it and fall through to the
|
|
43
|
+
// interactive mint so users can recover without hand-editing user.json.
|
|
44
|
+
const probe = await fetch(`${base}/api/auth/tokens`, { headers: httpHeader }).catch(() => null);
|
|
45
|
+
if (probe?.ok) {
|
|
46
|
+
return { httpHeader, gitCredentials: { username: '_token_', password: storedToken } };
|
|
47
|
+
}
|
|
48
|
+
if (probe?.status === 401) {
|
|
49
|
+
clearStudiographToken(base);
|
|
50
|
+
log.info('Stored CLI token is no longer valid — signing in again.');
|
|
51
|
+
}
|
|
52
|
+
else if (probe) {
|
|
53
|
+
// Non-401 response (5xx, unreachable, etc.) → keep the token, use it;
|
|
54
|
+
// the real request will surface the underlying error.
|
|
55
|
+
return { httpHeader, gitCredentials: { username: '_token_', password: storedToken } };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 5. Interactive prompts — then mint a token for future runs.
|
|
59
|
+
if (!process.stdin.isTTY) {
|
|
60
|
+
throw new Error('No credentials provided and stdin is not a TTY. Use --token, --email + --password, or set STUDIOGRAPH_TOKEN.');
|
|
61
|
+
}
|
|
62
|
+
const emailPrompt = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
|
|
63
|
+
if (typeof emailPrompt === 'symbol') {
|
|
64
|
+
outro('Cancelled');
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
const passPrompt = await passwordPrompt({ message: 'Password:' });
|
|
68
|
+
if (typeof passPrompt === 'symbol') {
|
|
69
|
+
outro('Cancelled');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}
|
|
72
|
+
const emailStr = String(emailPrompt);
|
|
73
|
+
const passStr = String(passPrompt);
|
|
74
|
+
const httpHeader = await loginForCookie(base, emailStr, passStr);
|
|
75
|
+
// Mint a CLI token and save it, so subsequent push/pull runs skip the prompt.
|
|
76
|
+
try {
|
|
77
|
+
const mintRes = await fetch(`${base}/api/auth/tokens`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: { ...httpHeader, 'Content-Type': 'application/json' },
|
|
80
|
+
body: JSON.stringify({ name: `cli-${process.platform}-${Date.now()}` }),
|
|
81
|
+
});
|
|
82
|
+
if (mintRes.ok) {
|
|
83
|
+
const body = await mintRes.json();
|
|
84
|
+
if (body.token) {
|
|
85
|
+
setStudiographToken(base, body.token);
|
|
86
|
+
log.info('Saved personal API token to ~/.studiograph/user.json for future runs');
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch { /* non-fatal — just means next run prompts again */ }
|
|
91
|
+
return { httpHeader, gitCredentials: { username: emailStr, password: passStr } };
|
|
92
|
+
}
|
|
93
|
+
async function loginForCookie(base, email, password) {
|
|
94
|
+
const loginRes = await fetch(`${base}/api/auth/login`, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: { 'Content-Type': 'application/json' },
|
|
97
|
+
body: JSON.stringify({ email, password }),
|
|
98
|
+
});
|
|
99
|
+
if (!loginRes.ok) {
|
|
100
|
+
const body = await loginRes.json().catch(() => ({}));
|
|
101
|
+
throw new Error(`Login failed: ${body.error || loginRes.statusText}`);
|
|
102
|
+
}
|
|
103
|
+
const cookies = loginRes.headers.getSetCookie?.() ?? [];
|
|
104
|
+
const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
|
|
105
|
+
if (!tokenCookie) {
|
|
106
|
+
throw new Error('Login succeeded but no session cookie was returned');
|
|
107
|
+
}
|
|
108
|
+
return { 'Cookie': tokenCookie.split(';')[0] };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Login with email + password and return the raw JWT (extracted from the
|
|
112
|
+
* `__sg_token` cookie). Same endpoint as {@link loginForCookie} but pulls
|
|
113
|
+
* the bare token instead of a Cookie header — needed when callers want to
|
|
114
|
+
* persist the token for reuse (server-auth.json) or pass it as the
|
|
115
|
+
* password in HTTP Basic auth (git-http expects basic-auth, not cookies).
|
|
116
|
+
*/
|
|
117
|
+
async function loginForJwt(base, email, password) {
|
|
118
|
+
const loginRes = await fetch(`${base}/api/auth/login`, {
|
|
119
|
+
method: 'POST',
|
|
120
|
+
headers: { 'Content-Type': 'application/json' },
|
|
121
|
+
body: JSON.stringify({ email, password }),
|
|
122
|
+
});
|
|
123
|
+
if (!loginRes.ok) {
|
|
124
|
+
const body = await loginRes.json().catch(() => ({}));
|
|
125
|
+
throw new Error(`Login failed: ${body.error || loginRes.statusText}`);
|
|
126
|
+
}
|
|
127
|
+
const cookies = loginRes.headers.getSetCookie?.() ?? [];
|
|
128
|
+
const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
|
|
129
|
+
if (!tokenCookie) {
|
|
130
|
+
throw new Error('Login succeeded but no session cookie was returned');
|
|
131
|
+
}
|
|
132
|
+
return tokenCookie.split(';')[0].replace('__sg_token=', '');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Persist a successful login to `<workspace>/.studiograph/server-auth.json`
|
|
136
|
+
* so future runs of the same command don't re-prompt for credentials. Mode
|
|
137
|
+
* 0600 — the JWT is bearer-equivalent. Mirrors the file format `studiograph
|
|
138
|
+
* join` and `studiograph clone` write so any tool that reads
|
|
139
|
+
* server-auth.json sees a consistent shape.
|
|
140
|
+
*/
|
|
141
|
+
function persistServerAuth(workspaceRoot, serverUrl, email, jwtToken) {
|
|
142
|
+
const studiographDir = join(workspaceRoot, '.studiograph');
|
|
143
|
+
if (!existsSync(studiographDir))
|
|
144
|
+
mkdirSync(studiographDir, { recursive: true });
|
|
145
|
+
writeFileSync(join(studiographDir, 'server-auth.json'), JSON.stringify({ serverUrl, email, jwtToken }, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
146
|
+
}
|
|
18
147
|
async function getRepoEntries(workspace, workspaceRoot) {
|
|
19
148
|
const entries = [];
|
|
20
149
|
// The .studiograph config directory is itself a git repo (when GitHub-provisioned)
|
|
@@ -24,8 +153,8 @@ async function getRepoEntries(workspace, workspaceRoot) {
|
|
|
24
153
|
}
|
|
25
154
|
const config = await workspace.loadConfig();
|
|
26
155
|
for (const repo of config.repos) {
|
|
27
|
-
if (repo.
|
|
28
|
-
continue; //
|
|
156
|
+
if (repo.personal)
|
|
157
|
+
continue; // personal repos are local-only
|
|
29
158
|
const repoPath = join(workspaceRoot, repo.path);
|
|
30
159
|
if (!isGitRepo(repoPath) || !gitHasRemote(repoPath))
|
|
31
160
|
continue;
|
|
@@ -42,7 +171,7 @@ function isGitRepo(path) {
|
|
|
42
171
|
function logManualGuidance(entryPath) {
|
|
43
172
|
log.info(` cd ${entryPath} && git pull --rebase`);
|
|
44
173
|
}
|
|
45
|
-
async function pullRemoteConfig(remoteUrl) {
|
|
174
|
+
async function pullRemoteConfig(remoteUrl, includeData = false, authOpts = {}) {
|
|
46
175
|
const workspace = new Workspace();
|
|
47
176
|
if (!workspace.isWorkspace()) {
|
|
48
177
|
console.error('❌ Not a Studiograph workspace. Run `studiograph init` first.');
|
|
@@ -50,72 +179,50 @@ async function pullRemoteConfig(remoteUrl) {
|
|
|
50
179
|
return;
|
|
51
180
|
}
|
|
52
181
|
const base = remoteUrl.replace(/\/+$/, '');
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
process.exit(0);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
const password = await passwordPrompt({ message: 'Password:' });
|
|
61
|
-
if (typeof password === 'symbol') {
|
|
62
|
-
outro('Cancelled');
|
|
63
|
-
process.exit(0);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
// Login to get session token
|
|
67
|
-
log.info('Authenticating...');
|
|
68
|
-
let token;
|
|
182
|
+
const workspaceRoot = workspace.getWorkspacePath();
|
|
183
|
+
const sgDir = join(workspaceRoot, '.studiograph');
|
|
184
|
+
// Resolve authentication (API key, email+password, env vars, or interactive prompts)
|
|
185
|
+
let auth;
|
|
69
186
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
headers: { 'Content-Type': 'application/json' },
|
|
73
|
-
body: JSON.stringify({ email, password }),
|
|
74
|
-
});
|
|
75
|
-
if (!loginRes.ok) {
|
|
76
|
-
const body = await loginRes.json().catch(() => ({}));
|
|
77
|
-
outro(`Login failed: ${body.error || loginRes.statusText}`);
|
|
78
|
-
process.exit(1);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
const cookies = loginRes.headers.getSetCookie?.() ?? [];
|
|
82
|
-
const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
|
|
83
|
-
if (!tokenCookie) {
|
|
84
|
-
outro('Login succeeded but no session cookie was returned');
|
|
85
|
-
process.exit(1);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
token = tokenCookie.split(';')[0];
|
|
187
|
+
log.info('Authenticating...');
|
|
188
|
+
auth = await resolveRemoteAuth(base, workspaceRoot, authOpts);
|
|
89
189
|
}
|
|
90
190
|
catch (err) {
|
|
91
|
-
outro(
|
|
191
|
+
outro(err.message);
|
|
92
192
|
process.exit(1);
|
|
93
193
|
return;
|
|
94
194
|
}
|
|
95
195
|
// Fetch config bundle (fall back to auth seed for older servers)
|
|
96
196
|
log.info('Fetching workspace config...');
|
|
97
|
-
const workspaceRoot = workspace.getWorkspacePath();
|
|
98
|
-
const sgDir = join(workspaceRoot, '.studiograph');
|
|
99
197
|
try {
|
|
100
198
|
const bundleRes = await fetch(`${base}/api/config/bundle`, {
|
|
101
|
-
headers:
|
|
199
|
+
headers: auth.httpHeader,
|
|
102
200
|
});
|
|
103
201
|
if (bundleRes.ok) {
|
|
104
202
|
const bundle = await bundleRes.json();
|
|
105
|
-
// 1. Auth seed
|
|
203
|
+
// 1. Auth seed — remote is authoritative for pull, so overwrite any
|
|
204
|
+
// local-shadow rows (e.g. post-clone setup-wizard credentials that
|
|
205
|
+
// would otherwise shadow the real production password_hash).
|
|
106
206
|
writeFileSync(join(sgDir, 'auth-seed.json'), JSON.stringify(bundle.authSeed, null, 2), 'utf-8');
|
|
107
|
-
|
|
108
|
-
|
|
207
|
+
// AuthService appends `.studiograph` to the path it's given —
|
|
208
|
+
// pass workspace root, not `sgDir`, or we end up with
|
|
209
|
+
// `.studiograph/.studiograph/auth.db` (disjoint from the running server).
|
|
210
|
+
const authService = new AuthService(workspaceRoot);
|
|
211
|
+
authService.applySeed({ mode: 'overwrite' });
|
|
109
212
|
authService.close();
|
|
110
213
|
log.success(`Team: ${bundle.authSeed.users.length} user${bundle.authSeed.users.length === 1 ? '' : 's'}`);
|
|
111
|
-
// 2. Workspace config — merge: keep local-only fields (server_url), update shared fields
|
|
214
|
+
// 2. Workspace config — merge: keep local-only fields (server_url), update shared fields.
|
|
215
|
+
//
|
|
216
|
+
// Phase 9b: route through `workspace.writeConfig()` so this CLI
|
|
217
|
+
// pull path shares the same schema validator + dual-write seam as
|
|
218
|
+
// every other writer.
|
|
112
219
|
if (bundle.workspace) {
|
|
113
220
|
const local = await workspace.loadConfig().catch(() => ({}));
|
|
114
221
|
const merged = { ...local, ...bundle.workspace };
|
|
115
222
|
if (local.server_url)
|
|
116
223
|
merged.server_url = local.server_url;
|
|
117
|
-
|
|
118
|
-
log.success(`Workspace config: ${bundle.workspace.repos?.length ?? 0}
|
|
224
|
+
workspace.writeConfig(merged);
|
|
225
|
+
log.success(`Workspace config: ${bundle.workspace.repos?.length ?? 0} folder${(bundle.workspace.repos?.length ?? 0) === 1 ? '' : 's'}`);
|
|
119
226
|
}
|
|
120
227
|
// 3. ABOUT.md
|
|
121
228
|
if (bundle.about !== null && bundle.about !== undefined) {
|
|
@@ -132,21 +239,33 @@ async function pullRemoteConfig(remoteUrl) {
|
|
|
132
239
|
}
|
|
133
240
|
log.success(`Sources: ${sourceNames.join(', ')}`);
|
|
134
241
|
}
|
|
135
|
-
// 5. Connectors (sanitized — no secrets)
|
|
242
|
+
// 5. Connectors (sanitized — no secrets).
|
|
243
|
+
//
|
|
244
|
+
// Phase 9b: route through `ConnectorManager.saveWorkspaceConfig` so
|
|
245
|
+
// every connector save runs the same schema validator + stripSecrets
|
|
246
|
+
// pass. The bundle is already sanitized server-side; the re-strip
|
|
247
|
+
// is idempotent and preserves the single-seam invariant.
|
|
136
248
|
if (bundle.connectors && bundle.connectors.length > 0) {
|
|
137
|
-
const connectorsDir = join(sgDir, 'connectors');
|
|
138
|
-
mkdirSync(connectorsDir, { recursive: true });
|
|
139
249
|
for (const conn of bundle.connectors) {
|
|
140
|
-
|
|
250
|
+
ConnectorManager.saveWorkspaceConfig(conn, workspaceRoot);
|
|
141
251
|
}
|
|
142
252
|
log.success(`Connectors: ${bundle.connectors.map(c => c.name).join(', ')}`);
|
|
143
253
|
}
|
|
144
|
-
|
|
254
|
+
// Pull workspace data (markdown files) if requested
|
|
255
|
+
if (includeData) {
|
|
256
|
+
try {
|
|
257
|
+
await pullRemoteData(base, auth, workspaceRoot);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
log.error(`Data pull failed: ${err.message}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
outro(`Pulled from ${base}${includeData ? ' (config + data)' : ' (config)'}`);
|
|
145
264
|
}
|
|
146
265
|
else if (bundleRes.status === 404) {
|
|
147
266
|
// Older server — fall back to auth seed only
|
|
148
267
|
log.info('Server does not support config bundle, falling back to auth seed...');
|
|
149
|
-
const seedRes = await fetch(`${base}/api/auth/seed`, { headers:
|
|
268
|
+
const seedRes = await fetch(`${base}/api/auth/seed`, { headers: auth.httpHeader });
|
|
150
269
|
if (!seedRes.ok) {
|
|
151
270
|
const body = await seedRes.json().catch(() => ({}));
|
|
152
271
|
outro(`Failed to fetch seed: ${body.error || seedRes.statusText}`);
|
|
@@ -155,8 +274,9 @@ async function pullRemoteConfig(remoteUrl) {
|
|
|
155
274
|
}
|
|
156
275
|
const seed = await seedRes.json();
|
|
157
276
|
writeFileSync(join(sgDir, 'auth-seed.json'), JSON.stringify(seed, null, 2), 'utf-8');
|
|
158
|
-
|
|
159
|
-
authService
|
|
277
|
+
// AuthService appends `.studiograph` — pass workspace root, not `sgDir`.
|
|
278
|
+
const authService = new AuthService(workspaceRoot);
|
|
279
|
+
authService.applySeed({ mode: 'overwrite' });
|
|
160
280
|
authService.close();
|
|
161
281
|
outro(`Pulled ${seed.users.length} user${seed.users.length === 1 ? '' : 's'} from ${base}`);
|
|
162
282
|
}
|
|
@@ -167,17 +287,147 @@ async function pullRemoteConfig(remoteUrl) {
|
|
|
167
287
|
}
|
|
168
288
|
}
|
|
169
289
|
catch (err) {
|
|
290
|
+
// Phase 9c: surface SchemaViolationError with its redaction-safe
|
|
291
|
+
// message (field path + classification, no values). The error class
|
|
292
|
+
// is detected by name to avoid pulling the schemas module into the
|
|
293
|
+
// CLI bundle import graph just for an instanceof check.
|
|
294
|
+
if (err?.name === 'SchemaViolationError' || err?.code === 'schema_violation') {
|
|
295
|
+
outro(`Schema violation:\n${err.message}`);
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
170
298
|
outro(`Failed: ${err.message}`);
|
|
171
299
|
process.exit(1);
|
|
172
300
|
}
|
|
173
301
|
}
|
|
302
|
+
// ─── Remote data pull (git-based) ───────────────────────────────────────────
|
|
303
|
+
// Clones or pulls each folder from the remote's embedded git HTTP server
|
|
304
|
+
// (/git/:repo). Uses git's native conflict detection — diverged folders
|
|
305
|
+
// are reported, not silently overwritten.
|
|
306
|
+
async function pullRemoteData(base, auth, workspaceRoot) {
|
|
307
|
+
// Reload config — it was just updated by pullRemoteConfig
|
|
308
|
+
const workspace = new Workspace(workspaceRoot);
|
|
309
|
+
const config = await workspace.loadConfig();
|
|
310
|
+
let cloned = 0, updated = 0, upToDate = 0, diverged = 0, errors = 0;
|
|
311
|
+
for (const repo of config.repos) {
|
|
312
|
+
if (repo.personal)
|
|
313
|
+
continue; // personal folders don't sync
|
|
314
|
+
const repoPath = join(workspaceRoot, repo.path);
|
|
315
|
+
const remoteUrl = `${base}/git/${repo.name}`;
|
|
316
|
+
// Clone if missing
|
|
317
|
+
if (!existsSync(join(repoPath, '.git'))) {
|
|
318
|
+
try {
|
|
319
|
+
if (existsSync(repoPath))
|
|
320
|
+
rmSync(repoPath, { recursive: true, force: true });
|
|
321
|
+
mkdirSync(repoPath, { recursive: true });
|
|
322
|
+
gitClone(remoteUrl, repoPath, { silent: true, credentials: auth.gitCredentials });
|
|
323
|
+
log.success(`${repo.name}: cloned`);
|
|
324
|
+
cloned++;
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
log.error(`${repo.name}: clone failed — ${err.message}`);
|
|
328
|
+
errors++;
|
|
329
|
+
}
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
// Ensure remote points at the requested server (may have been cloned elsewhere)
|
|
333
|
+
try {
|
|
334
|
+
gitSetRemote(repoPath, remoteUrl);
|
|
335
|
+
}
|
|
336
|
+
catch { /* non-fatal */ }
|
|
337
|
+
try {
|
|
338
|
+
const result = gitPull(repoPath, { credentials: auth.gitCredentials });
|
|
339
|
+
if (result === 'updated') {
|
|
340
|
+
log.success(`${repo.name}: updated`);
|
|
341
|
+
updated++;
|
|
342
|
+
}
|
|
343
|
+
else if (result === 'up-to-date') {
|
|
344
|
+
upToDate++;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
log.warn(`${repo.name}: diverged — has local commits not on the server`);
|
|
348
|
+
log.info(` cd ${repoPath} && git pull --rebase`);
|
|
349
|
+
diverged++;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
log.error(`${repo.name}: ${err.message}`);
|
|
354
|
+
errors++;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
log.info(`Data: ${cloned} cloned, ${updated} updated, ${upToDate} up to date${diverged ? `, ${diverged} diverged` : ''}${errors ? `, ${errors} failed` : ''}`);
|
|
358
|
+
if (diverged) {
|
|
359
|
+
throw new Error('One or more folders diverged — resolve conflicts and retry');
|
|
360
|
+
}
|
|
361
|
+
if (errors) {
|
|
362
|
+
throw new Error('One or more folders failed to pull');
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// ─── Remote data push (git-based) ───────────────────────────────────────────
|
|
366
|
+
// Pushes each local folder to the remote's embedded git HTTP server.
|
|
367
|
+
// Uses git's native conflict detection — rejected pushes require a pull first.
|
|
368
|
+
async function pushRemoteData(base, auth, workspace, workspaceRoot) {
|
|
369
|
+
const config = await workspace.loadConfig();
|
|
370
|
+
let pushed = 0, nothingToPush = 0, created = 0, rejected = 0, errors = 0;
|
|
371
|
+
for (const repo of config.repos) {
|
|
372
|
+
if (repo.personal)
|
|
373
|
+
continue; // personal folders don't sync to a remote we don't control
|
|
374
|
+
const repoPath = join(workspaceRoot, repo.path);
|
|
375
|
+
if (!existsSync(join(repoPath, '.git'))) {
|
|
376
|
+
log.warn(`${repo.name}: not a git repo — skipping`);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
try {
|
|
380
|
+
// Ensure folder exists on remote (idempotent; 409 means it already exists)
|
|
381
|
+
const status = await ensureServerFolder(base, repo.name, !!repo.personal, auth.httpHeader);
|
|
382
|
+
if (status === 'created') {
|
|
383
|
+
log.info(`${repo.name}: created on server`);
|
|
384
|
+
created++;
|
|
385
|
+
}
|
|
386
|
+
// Point origin at the remote's git server
|
|
387
|
+
gitSetRemote(repoPath, `${base}/git/${repo.name}`);
|
|
388
|
+
// Push with credentials
|
|
389
|
+
const result = gitPushWithCredentials(repoPath, auth.gitCredentials);
|
|
390
|
+
if (result === 'rejected') {
|
|
391
|
+
log.warn(`${repo.name}: push rejected — run \`studiograph pull --remote ${base} --data\` first`);
|
|
392
|
+
rejected++;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
if (result === 'pushed') {
|
|
396
|
+
log.success(`${repo.name}: pushed`);
|
|
397
|
+
pushed++;
|
|
398
|
+
}
|
|
399
|
+
else {
|
|
400
|
+
nothingToPush++;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
catch (err) {
|
|
404
|
+
log.error(`${repo.name}: ${err.message}`);
|
|
405
|
+
errors++;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
log.info(`Data: ${pushed} pushed${created ? `, ${created} created` : ''}, ${nothingToPush} unchanged${rejected ? `, ${rejected} rejected` : ''}${errors ? `, ${errors} failed` : ''}`);
|
|
409
|
+
if (rejected) {
|
|
410
|
+
throw new Error('One or more folders were rejected — pull and retry');
|
|
411
|
+
}
|
|
412
|
+
if (errors) {
|
|
413
|
+
throw new Error('One or more folders failed to push');
|
|
414
|
+
}
|
|
415
|
+
}
|
|
174
416
|
// ─── pull ─────────────────────────────────────────────────────────────────────
|
|
175
417
|
export const pullCommand = new Command('pull')
|
|
176
418
|
.description('Pull latest changes from remote across the workspace')
|
|
177
419
|
.option('--remote <url>', 'Pull config from a remote Studiograph server')
|
|
420
|
+
.option('--data', 'Also pull workspace folder data (markdown files) from the remote server')
|
|
421
|
+
.option('--token <token>', 'Use a personal API token instead of email/password (also reads STUDIOGRAPH_TOKEN)')
|
|
422
|
+
.option('--email <email>', 'Email for non-interactive auth (also reads STUDIOGRAPH_EMAIL)')
|
|
423
|
+
.option('--password <password>', 'Password for non-interactive auth (also reads STUDIOGRAPH_PASSWORD)')
|
|
178
424
|
.action(async (opts) => {
|
|
179
425
|
if (opts.remote) {
|
|
180
|
-
return pullRemoteConfig(opts.remote
|
|
426
|
+
return pullRemoteConfig(opts.remote, opts.data, {
|
|
427
|
+
token: opts.token,
|
|
428
|
+
email: opts.email,
|
|
429
|
+
password: opts.password,
|
|
430
|
+
});
|
|
181
431
|
}
|
|
182
432
|
const workspace = new Workspace();
|
|
183
433
|
if (!workspace.isWorkspace()) {
|
|
@@ -203,13 +453,21 @@ export const pullCommand = new Command('pull')
|
|
|
203
453
|
else if (result === 'up-to-date') {
|
|
204
454
|
log.info('.studiograph: already up to date');
|
|
205
455
|
}
|
|
456
|
+
else {
|
|
457
|
+
// Diverged / any other non-clean state — surface it the same way
|
|
458
|
+
// the folder loop does so the user actually sees the problem
|
|
459
|
+
// instead of walking into a silent no-op.
|
|
460
|
+
log.warn('.studiograph: diverged — has local commits not on the server');
|
|
461
|
+
logManualGuidance(configPath);
|
|
462
|
+
hasConflict = true;
|
|
463
|
+
}
|
|
206
464
|
}
|
|
207
465
|
catch (error) {
|
|
208
466
|
log.error(`.studiograph: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
209
467
|
hasError = true;
|
|
210
468
|
}
|
|
211
469
|
}
|
|
212
|
-
// ── Step 2: reload config — picks up any new
|
|
470
|
+
// ── Step 2: reload config — picks up any new folders added server-side ─
|
|
213
471
|
// Must use a fresh Workspace instance — loadConfig() caches this.config on
|
|
214
472
|
// first call, so the original instance would return stale data after the pull.
|
|
215
473
|
const freshWorkspace = new Workspace(workspaceRoot);
|
|
@@ -220,13 +478,12 @@ export const pullCommand = new Command('pull')
|
|
|
220
478
|
freshWorkspace.writeConfig(config);
|
|
221
479
|
}
|
|
222
480
|
const serverUrl = (config.server_url ?? savedServerUrl)?.replace(/\/+$/, '');
|
|
223
|
-
// ── Step 3: pull or clone each
|
|
481
|
+
// ── Step 3: pull or clone each folder ────────────────────────────────
|
|
224
482
|
// Resolve git credentials for the embedded server:
|
|
225
483
|
// 1. Stored JWT from `studiograph join` — per-user access control (preferred)
|
|
226
|
-
// 2. API
|
|
484
|
+
// 2. Stored personal API token from ~/.studiograph/user.json
|
|
227
485
|
let serverGitCredentials;
|
|
228
486
|
if (serverUrl) {
|
|
229
|
-
// Try stored JWT first (saved by studiograph join)
|
|
230
487
|
const serverAuthPath = join(workspaceRoot, '.studiograph', 'server-auth.json');
|
|
231
488
|
if (existsSync(serverAuthPath)) {
|
|
232
489
|
try {
|
|
@@ -237,29 +494,22 @@ export const pullCommand = new Command('pull')
|
|
|
237
494
|
}
|
|
238
495
|
catch { /* non-fatal */ }
|
|
239
496
|
}
|
|
240
|
-
// Fall back to API key (used by workspace owners who set up with `studiograph serve`)
|
|
241
497
|
if (!serverGitCredentials) {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const seed = JSON.parse(readFileSync(seedPath, 'utf-8'));
|
|
246
|
-
const apiKey = seed.apiKey;
|
|
247
|
-
if (apiKey)
|
|
248
|
-
serverGitCredentials = { username: '_apikey_', password: apiKey };
|
|
249
|
-
}
|
|
498
|
+
const storedToken = getStudiographToken(serverUrl);
|
|
499
|
+
if (storedToken) {
|
|
500
|
+
serverGitCredentials = { username: '_token_', password: storedToken };
|
|
250
501
|
}
|
|
251
|
-
catch { /* non-fatal */ }
|
|
252
502
|
}
|
|
253
503
|
}
|
|
254
504
|
for (const repo of config.repos) {
|
|
255
|
-
if (repo.
|
|
505
|
+
if (repo.personal)
|
|
256
506
|
continue;
|
|
257
507
|
const repoPath = join(workspaceRoot, repo.path);
|
|
258
|
-
// New
|
|
508
|
+
// New folder — directory missing or exists but isn't a git repo (e.g. failed clone)
|
|
259
509
|
if (!isGitRepo(repoPath)) {
|
|
260
510
|
const cloneUrl = serverUrl ? `${serverUrl}/git/${repo.name}` : null;
|
|
261
511
|
if (!cloneUrl) {
|
|
262
|
-
log.warn(`${repo.name}: new
|
|
512
|
+
log.warn(`${repo.name}: new folder has no remote — skipping`);
|
|
263
513
|
continue;
|
|
264
514
|
}
|
|
265
515
|
try {
|
|
@@ -278,7 +528,7 @@ export const pullCommand = new Command('pull')
|
|
|
278
528
|
}
|
|
279
529
|
continue;
|
|
280
530
|
}
|
|
281
|
-
// Existing
|
|
531
|
+
// Existing folder — pull if it has a remote
|
|
282
532
|
if (!isGitRepo(repoPath) || !gitHasRemote(repoPath))
|
|
283
533
|
continue;
|
|
284
534
|
try {
|
|
@@ -300,12 +550,15 @@ export const pullCommand = new Command('pull')
|
|
|
300
550
|
hasError = true;
|
|
301
551
|
}
|
|
302
552
|
}
|
|
303
|
-
// Apply auth seed if it was updated by pulling .studiograph
|
|
553
|
+
// Apply auth seed if it was updated by pulling .studiograph.
|
|
554
|
+
// Overwrite mode: the seed file just came from the remote config repo
|
|
555
|
+
// and is authoritative over any local-shadow rows.
|
|
304
556
|
const seedPath = join(workspaceRoot, '.studiograph', 'auth-seed.json');
|
|
305
557
|
if (existsSync(seedPath)) {
|
|
306
558
|
try {
|
|
307
|
-
|
|
308
|
-
authService
|
|
559
|
+
// AuthService appends `.studiograph` — pass workspace root.
|
|
560
|
+
const authService = new AuthService(workspaceRoot);
|
|
561
|
+
authService.applySeed({ mode: 'overwrite' });
|
|
309
562
|
authService.close();
|
|
310
563
|
}
|
|
311
564
|
catch {
|
|
@@ -317,12 +570,12 @@ export const pullCommand = new Command('pull')
|
|
|
317
570
|
process.exit(1);
|
|
318
571
|
}
|
|
319
572
|
else if (hasError) {
|
|
320
|
-
outro('❌ Pull failed for one or more
|
|
573
|
+
outro('❌ Pull failed for one or more folders.');
|
|
321
574
|
process.exit(1);
|
|
322
575
|
}
|
|
323
576
|
});
|
|
324
577
|
// ─── Remote config push ─────────────────────────────────────────────────────
|
|
325
|
-
async function pushRemoteConfig(remoteUrl) {
|
|
578
|
+
async function pushRemoteConfig(remoteUrl, includeData = false, authOpts = {}) {
|
|
326
579
|
const workspace = new Workspace();
|
|
327
580
|
if (!workspace.isWorkspace()) {
|
|
328
581
|
console.error('❌ Not a Studiograph workspace. Run `studiograph init` first.');
|
|
@@ -332,45 +585,14 @@ async function pushRemoteConfig(remoteUrl) {
|
|
|
332
585
|
const base = remoteUrl.replace(/\/+$/, '');
|
|
333
586
|
const workspaceRoot = workspace.getWorkspacePath();
|
|
334
587
|
const sgDir = join(workspaceRoot, '.studiograph');
|
|
335
|
-
//
|
|
336
|
-
|
|
337
|
-
if (typeof email === 'symbol') {
|
|
338
|
-
outro('Cancelled');
|
|
339
|
-
process.exit(0);
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
342
|
-
const password = await passwordPrompt({ message: 'Password:' });
|
|
343
|
-
if (typeof password === 'symbol') {
|
|
344
|
-
outro('Cancelled');
|
|
345
|
-
process.exit(0);
|
|
346
|
-
return;
|
|
347
|
-
}
|
|
348
|
-
// Login
|
|
349
|
-
log.info('Authenticating...');
|
|
350
|
-
let token;
|
|
588
|
+
// Resolve authentication (API key, email+password, env vars, or interactive prompts)
|
|
589
|
+
let auth;
|
|
351
590
|
try {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
headers: { 'Content-Type': 'application/json' },
|
|
355
|
-
body: JSON.stringify({ email, password }),
|
|
356
|
-
});
|
|
357
|
-
if (!loginRes.ok) {
|
|
358
|
-
const body = await loginRes.json().catch(() => ({}));
|
|
359
|
-
outro(`Login failed: ${body.error || loginRes.statusText}`);
|
|
360
|
-
process.exit(1);
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
const cookies = loginRes.headers.getSetCookie?.() ?? [];
|
|
364
|
-
const tokenCookie = cookies.find(c => c.startsWith('__sg_token='));
|
|
365
|
-
if (!tokenCookie) {
|
|
366
|
-
outro('Login succeeded but no session cookie was returned');
|
|
367
|
-
process.exit(1);
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
token = tokenCookie.split(';')[0];
|
|
591
|
+
log.info('Authenticating...');
|
|
592
|
+
auth = await resolveRemoteAuth(base, workspaceRoot, authOpts);
|
|
371
593
|
}
|
|
372
594
|
catch (err) {
|
|
373
|
-
outro(
|
|
595
|
+
outro(err.message);
|
|
374
596
|
process.exit(1);
|
|
375
597
|
return;
|
|
376
598
|
}
|
|
@@ -402,13 +624,24 @@ async function pushRemoteConfig(remoteUrl) {
|
|
|
402
624
|
}
|
|
403
625
|
// Connectors (workspace-level, already sanitized)
|
|
404
626
|
const connectors = ConnectorManager.loadWorkspaceConfigs(workspaceRoot);
|
|
405
|
-
|
|
627
|
+
// Phase 3: route the bundle through the same sanitizer the server's
|
|
628
|
+
// GET /api/config/bundle endpoint uses. CLI push and server export now
|
|
629
|
+
// produce byte-identical output for the same workspace state — bootstrap
|
|
630
|
+
// class fields (jwtSecret, deprecated apiKey) drop here so the POST
|
|
631
|
+
// endpoint's strict-reject doesn't bounce older client builds.
|
|
632
|
+
const bundle = buildConfigBundle({
|
|
633
|
+
workspace: config,
|
|
634
|
+
about,
|
|
635
|
+
authSeed: (authSeed ?? { users: [] }),
|
|
636
|
+
sources,
|
|
637
|
+
connectors: connectors,
|
|
638
|
+
});
|
|
406
639
|
// Push to remote
|
|
407
640
|
log.info('Pushing config...');
|
|
408
641
|
try {
|
|
409
642
|
const res = await fetch(`${base}/api/config/bundle`, {
|
|
410
643
|
method: 'POST',
|
|
411
|
-
headers: { 'Content-Type': 'application/json'
|
|
644
|
+
headers: { ...auth.httpHeader, 'Content-Type': 'application/json' },
|
|
412
645
|
body: JSON.stringify(bundle),
|
|
413
646
|
});
|
|
414
647
|
if (!res.ok) {
|
|
@@ -423,7 +656,16 @@ async function pushRemoteConfig(remoteUrl) {
|
|
|
423
656
|
log.success(item);
|
|
424
657
|
}
|
|
425
658
|
}
|
|
426
|
-
|
|
659
|
+
// Push workspace data (markdown files) if requested
|
|
660
|
+
if (includeData) {
|
|
661
|
+
try {
|
|
662
|
+
await pushRemoteData(base, auth, workspace, workspaceRoot);
|
|
663
|
+
}
|
|
664
|
+
catch (err) {
|
|
665
|
+
log.error(`Data push failed: ${err.message}`);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
outro(`Pushed to ${base}${includeData ? ' (config + data)' : ' (config)'}`);
|
|
427
669
|
}
|
|
428
670
|
catch (err) {
|
|
429
671
|
outro(`Failed: ${err.message}`);
|
|
@@ -449,27 +691,42 @@ async function serverFetch(serverUrl, path, authHeader) {
|
|
|
449
691
|
}
|
|
450
692
|
return res.json();
|
|
451
693
|
}
|
|
452
|
-
async function
|
|
694
|
+
async function ensureServerFolder(serverUrl, repoName, isPersonal, authHeader) {
|
|
695
|
+
const headers = { 'Content-Type': 'application/json' };
|
|
696
|
+
if (typeof authHeader === 'string') {
|
|
697
|
+
headers['Authorization'] = authHeader;
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
Object.assign(headers, authHeader);
|
|
701
|
+
}
|
|
453
702
|
const res = await fetch(`${serverUrl}/api/repos`, {
|
|
454
703
|
method: 'POST',
|
|
455
|
-
headers
|
|
456
|
-
body: JSON.stringify({ name: repoName, ...(
|
|
704
|
+
headers,
|
|
705
|
+
body: JSON.stringify({ name: repoName, ...(isPersonal ? { personal: true } : {}) }),
|
|
457
706
|
});
|
|
458
707
|
if (res.ok)
|
|
459
708
|
return 'created';
|
|
460
709
|
if (res.status === 409)
|
|
461
710
|
return 'exists'; // already exists
|
|
462
711
|
const body = await res.json().catch(() => ({}));
|
|
463
|
-
throw new Error(body.error || `Failed to create
|
|
712
|
+
throw new Error(body.error || `Failed to create folder "${repoName}": ${res.statusText}`);
|
|
464
713
|
}
|
|
465
714
|
// ─── push ─────────────────────────────────────────────────────────────────────
|
|
466
715
|
export const pushCommand = new Command('push')
|
|
467
716
|
.description('Push local commits to remote across the workspace')
|
|
468
|
-
.argument('[
|
|
717
|
+
.argument('[folder]', 'Push a specific folder (default: all)')
|
|
469
718
|
.option('--remote <url>', 'Push config to a remote Studiograph server')
|
|
470
|
-
.
|
|
719
|
+
.option('--data', 'Also push workspace folder data (markdown files) to the remote server')
|
|
720
|
+
.option('--token <token>', 'Use a personal API token instead of email/password (also reads STUDIOGRAPH_TOKEN)')
|
|
721
|
+
.option('--email <email>', 'Email for non-interactive auth (also reads STUDIOGRAPH_EMAIL)')
|
|
722
|
+
.option('--password <password>', 'Password for non-interactive auth (also reads STUDIOGRAPH_PASSWORD)')
|
|
723
|
+
.action(async (folder, opts) => {
|
|
471
724
|
if (opts.remote) {
|
|
472
|
-
return pushRemoteConfig(opts.remote
|
|
725
|
+
return pushRemoteConfig(opts.remote, opts.data, {
|
|
726
|
+
token: opts.token,
|
|
727
|
+
email: opts.email,
|
|
728
|
+
password: opts.password,
|
|
729
|
+
});
|
|
473
730
|
}
|
|
474
731
|
const workspace = new Workspace();
|
|
475
732
|
if (!workspace.isWorkspace()) {
|
|
@@ -480,12 +737,19 @@ export const pushCommand = new Command('push')
|
|
|
480
737
|
const workspaceRoot = workspace.getWorkspacePath();
|
|
481
738
|
const config = await workspace.loadConfig();
|
|
482
739
|
const serverUrl = config.server_url?.replace(/\/+$/, '');
|
|
483
|
-
// Build list of repos to push
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
740
|
+
// Build list of repos to push. Personal folders are included when
|
|
741
|
+
// pushing to a server — they're per-user, but git-http
|
|
742
|
+
// (canAccessFolder → hasRepoAccess) gates by owner so only the owner
|
|
743
|
+
// ever succeeds. Server-side, personal folders are auto-provisioned
|
|
744
|
+
// on login by auth-api.ts#ensurePrivateFolder, so the per-folder
|
|
745
|
+
// ensureServerFolder() call is skipped for them below (the
|
|
746
|
+
// createSharedFolder path would reject `entries-<number>` as a
|
|
747
|
+
// reserved name even though the folder already exists).
|
|
748
|
+
let repos = config.repos.filter(r => !r.personal || serverUrl);
|
|
749
|
+
if (folder) {
|
|
750
|
+
const match = repos.find(r => r.name === folder);
|
|
487
751
|
if (!match) {
|
|
488
|
-
log.error(`
|
|
752
|
+
log.error(`Folder "${folder}" not found in workspace.`);
|
|
489
753
|
process.exit(1);
|
|
490
754
|
return;
|
|
491
755
|
}
|
|
@@ -496,34 +760,44 @@ export const pushCommand = new Command('push')
|
|
|
496
760
|
// Resolve credentials: JWT (per-user) → API key (admin) → prompt
|
|
497
761
|
let authHeader;
|
|
498
762
|
let gitCredentials;
|
|
499
|
-
// 1. Stored JWT from `studiograph join` (per-user access control)
|
|
763
|
+
// 1. Stored JWT from `studiograph join` (per-user access control).
|
|
764
|
+
//
|
|
765
|
+
// Auth-header format note: the main API auth middleware (server/
|
|
766
|
+
// index.ts:215) accepts Basic only as `email:<password>` — it does
|
|
767
|
+
// NOT accept JWT-as-Basic-password. The git-http handler does
|
|
768
|
+
// (routes/git-http.ts authenticateBasic has explicit branches for
|
|
769
|
+
// `eyJ...` JWTs and `sg_...` tokens). So one stored JWT yields two
|
|
770
|
+
// different headers: `Bearer <jwt>` for API calls (serverFetch,
|
|
771
|
+
// ensureServerFolder) and Basic with JWT-as-password for git push
|
|
772
|
+
// (gitPushWithCredentials → askpass). Same logic for stored API
|
|
773
|
+
// tokens below.
|
|
500
774
|
const pushServerAuthPath = join(workspaceRoot, '.studiograph', 'server-auth.json');
|
|
501
775
|
try {
|
|
502
776
|
if (existsSync(pushServerAuthPath)) {
|
|
503
777
|
const sa = JSON.parse(readFileSync(pushServerAuthPath, 'utf-8'));
|
|
504
778
|
if (sa.email && sa.jwtToken) {
|
|
505
|
-
authHeader =
|
|
779
|
+
authHeader = `Bearer ${sa.jwtToken}`;
|
|
506
780
|
gitCredentials = { username: sa.email, password: sa.jwtToken };
|
|
507
781
|
}
|
|
508
782
|
}
|
|
509
783
|
}
|
|
510
784
|
catch { /* non-fatal */ }
|
|
511
|
-
// 2. API
|
|
512
|
-
if (!authHeader) {
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const pushApiKey = seed.apiKey;
|
|
518
|
-
if (pushApiKey) {
|
|
519
|
-
authHeader = makeBasicAuth('_apikey_', pushApiKey);
|
|
520
|
-
gitCredentials = { username: '_apikey_', password: pushApiKey };
|
|
521
|
-
}
|
|
522
|
-
}
|
|
785
|
+
// 2. Stored personal API token fallback
|
|
786
|
+
if (!authHeader && serverUrl) {
|
|
787
|
+
const storedToken = getStudiographToken(serverUrl);
|
|
788
|
+
if (storedToken) {
|
|
789
|
+
authHeader = `Bearer ${storedToken}`;
|
|
790
|
+
gitCredentials = { username: '_token_', password: storedToken };
|
|
523
791
|
}
|
|
524
|
-
catch { /* non-fatal */ }
|
|
525
792
|
}
|
|
526
|
-
// 3. Interactive credential prompt as last resort
|
|
793
|
+
// 3. Interactive credential prompt as last resort. After successful
|
|
794
|
+
// auth, exchange the password for a JWT and persist it to
|
|
795
|
+
// server-auth.json so the next run skips the prompt entirely.
|
|
796
|
+
// Without this step, every push prompts again — the previous
|
|
797
|
+
// behavior used the typed password as Basic auth ad-hoc and never
|
|
798
|
+
// wrote the file (a real DX papercut surfaced after `studiograph
|
|
799
|
+
// clone` deleted server-auth.json or a Railway restart invalidated
|
|
800
|
+
// the JWT secret).
|
|
527
801
|
if (!authHeader) {
|
|
528
802
|
const email = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
|
|
529
803
|
if (typeof email === 'symbol') {
|
|
@@ -537,8 +811,21 @@ export const pushCommand = new Command('push')
|
|
|
537
811
|
process.exit(0);
|
|
538
812
|
return;
|
|
539
813
|
}
|
|
540
|
-
|
|
541
|
-
|
|
814
|
+
try {
|
|
815
|
+
const jwtToken = await loginForJwt(serverUrl, String(email), String(pass));
|
|
816
|
+
persistServerAuth(workspaceRoot, serverUrl, String(email), jwtToken);
|
|
817
|
+
// Bearer for API calls; Basic with JWT-as-password for git push.
|
|
818
|
+
// See header-format note on the stored-JWT branch above.
|
|
819
|
+
authHeader = `Bearer ${jwtToken}`;
|
|
820
|
+
gitCredentials = { username: String(email), password: jwtToken };
|
|
821
|
+
}
|
|
822
|
+
catch (err) {
|
|
823
|
+
// Surface the underlying auth failure rather than silently
|
|
824
|
+
// falling through with bogus basic-auth that'll fail later.
|
|
825
|
+
outro(`Authentication failed: ${err.message}`);
|
|
826
|
+
process.exit(1);
|
|
827
|
+
return;
|
|
828
|
+
}
|
|
542
829
|
}
|
|
543
830
|
// All three branches above either set credentials or exit — this is a safety guard
|
|
544
831
|
if (!authHeader || !gitCredentials) {
|
|
@@ -546,14 +833,60 @@ export const pushCommand = new Command('push')
|
|
|
546
833
|
process.exit(1);
|
|
547
834
|
return;
|
|
548
835
|
}
|
|
549
|
-
// Validate credentials
|
|
836
|
+
// Validate credentials. If a stored JWT or token has been
|
|
837
|
+
// invalidated (Railway restart that regenerated the JWT secret,
|
|
838
|
+
// server-side token revoke, etc.), fall through to the interactive
|
|
839
|
+
// prompt instead of exiting — typing email+password should always
|
|
840
|
+
// be a viable last resort. We bound the retry to one attempt so
|
|
841
|
+
// bad credentials don't loop forever.
|
|
842
|
+
let validated = false;
|
|
550
843
|
try {
|
|
551
844
|
await serverFetch(serverUrl, '/api/workspace', authHeader);
|
|
845
|
+
validated = true;
|
|
552
846
|
}
|
|
553
847
|
catch (err) {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
848
|
+
// Stored credential failed. Clear it so the next run can't loop
|
|
849
|
+
// on the same stale value, then drop to a fresh prompt below.
|
|
850
|
+
try {
|
|
851
|
+
rmSync(pushServerAuthPath, { force: true });
|
|
852
|
+
}
|
|
853
|
+
catch { /* non-fatal */ }
|
|
854
|
+
}
|
|
855
|
+
if (!validated) {
|
|
856
|
+
log.warn('Stored credentials rejected — re-authenticate.');
|
|
857
|
+
const email = await text({ message: 'Email:', validate: (v) => v.includes('@') ? undefined : 'Enter a valid email' });
|
|
858
|
+
if (typeof email === 'symbol') {
|
|
859
|
+
outro('Cancelled');
|
|
860
|
+
process.exit(0);
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const pass = await passwordPrompt({ message: 'Password:' });
|
|
864
|
+
if (typeof pass === 'symbol') {
|
|
865
|
+
outro('Cancelled');
|
|
866
|
+
process.exit(0);
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
try {
|
|
870
|
+
const jwtToken = await loginForJwt(serverUrl, String(email), String(pass));
|
|
871
|
+
persistServerAuth(workspaceRoot, serverUrl, String(email), jwtToken);
|
|
872
|
+
// Bearer for API calls; Basic with JWT-as-password for git push.
|
|
873
|
+
// See header-format note on the stored-JWT branch above.
|
|
874
|
+
authHeader = `Bearer ${jwtToken}`;
|
|
875
|
+
gitCredentials = { username: String(email), password: jwtToken };
|
|
876
|
+
}
|
|
877
|
+
catch (err) {
|
|
878
|
+
outro(`Authentication failed: ${err.message}`);
|
|
879
|
+
process.exit(1);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
try {
|
|
883
|
+
await serverFetch(serverUrl, '/api/workspace', authHeader);
|
|
884
|
+
}
|
|
885
|
+
catch (err) {
|
|
886
|
+
outro(`Authentication failed: ${err.message}`);
|
|
887
|
+
process.exit(1);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
557
890
|
}
|
|
558
891
|
let hasError = false;
|
|
559
892
|
for (const repo of repos) {
|
|
@@ -562,11 +895,24 @@ export const pushCommand = new Command('push')
|
|
|
562
895
|
log.warn(`${repo.name}: not a git repo, skipping`);
|
|
563
896
|
continue;
|
|
564
897
|
}
|
|
898
|
+
// Personal folders skip the /api/repos POST. Detection has TWO
|
|
899
|
+
// sources because `studiograph clone` strips the `personal: true`
|
|
900
|
+
// flag from cloned workspace.json (alongside r2_config and
|
|
901
|
+
// railway — see memory:studiograph_clone_strips_config). So we
|
|
902
|
+
// also infer from the reserved name pattern: anything matching
|
|
903
|
+
// `entries-<digit>` is owned by the user with that id and was
|
|
904
|
+
// auto-provisioned server-side via auth-api.ts#ensurePrivateFolder
|
|
905
|
+
// on login. The /api/repos path goes through createSharedFolder
|
|
906
|
+
// which rejects this exact pattern; the git push that follows
|
|
907
|
+
// hits git-http directly where canAccessFolder gates by owner.
|
|
908
|
+
const isPersonalByPattern = /^entries-\d+$/.test(repo.name);
|
|
909
|
+
const skipServerFolderEnsure = !!repo.personal || isPersonalByPattern;
|
|
565
910
|
try {
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
911
|
+
if (!skipServerFolderEnsure) {
|
|
912
|
+
const status = await ensureServerFolder(serverUrl, repo.name, false, authHeader);
|
|
913
|
+
if (status === 'created') {
|
|
914
|
+
log.info(`${repo.name}: created on server`);
|
|
915
|
+
}
|
|
570
916
|
}
|
|
571
917
|
// Set origin to server git URL
|
|
572
918
|
gitSetRemote(repoPath, `${serverUrl}/git/${repo.name}`);
|
|
@@ -598,12 +944,12 @@ export const pushCommand = new Command('push')
|
|
|
598
944
|
// Fallback: plain git push for repos that already have remotes
|
|
599
945
|
const entries = await getRepoEntries(workspace, workspaceRoot);
|
|
600
946
|
if (entries.length === 0) {
|
|
601
|
-
log.info('No
|
|
947
|
+
log.info('No folders with remotes to push to. Use `studiograph join` to connect to a server.');
|
|
602
948
|
return;
|
|
603
949
|
}
|
|
604
950
|
let hasError = false;
|
|
605
951
|
for (const entry of entries) {
|
|
606
|
-
if (
|
|
952
|
+
if (folder && entry.name !== folder)
|
|
607
953
|
continue;
|
|
608
954
|
try {
|
|
609
955
|
let result = gitPush(entry.path);
|
|
@@ -625,7 +971,7 @@ export const pushCommand = new Command('push')
|
|
|
625
971
|
}
|
|
626
972
|
}
|
|
627
973
|
if (hasError) {
|
|
628
|
-
outro('Push failed for one or more
|
|
974
|
+
outro('Push failed for one or more folders.');
|
|
629
975
|
process.exit(1);
|
|
630
976
|
}
|
|
631
977
|
});
|