studiograph 1.2.0-beta.9 → 1.2.0

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.
Files changed (226) hide show
  1. package/README.md +13 -18
  2. package/dist/agent/orchestrator.d.ts +56 -0
  3. package/dist/agent/orchestrator.js +167 -22
  4. package/dist/agent/orchestrator.js.map +1 -1
  5. package/dist/agent/prompts/system.md +51 -63
  6. package/dist/agent/skill-loader.js +8 -0
  7. package/dist/agent/skill-loader.js.map +1 -1
  8. package/dist/agent/skills/entity-schema.md +4 -19
  9. package/dist/agent/skills/gather-context.md +1 -1
  10. package/dist/agent/tools/graph-tools.d.ts +41 -1
  11. package/dist/agent/tools/graph-tools.js +133 -57
  12. package/dist/agent/tools/graph-tools.js.map +1 -1
  13. package/dist/agent/tools/ops-tools.js +82 -0
  14. package/dist/agent/tools/ops-tools.js.map +1 -1
  15. package/dist/agent/tools/permission-tools.d.ts +90 -0
  16. package/dist/agent/tools/permission-tools.js +207 -0
  17. package/dist/agent/tools/permission-tools.js.map +1 -0
  18. package/dist/agent/tools/sync-tools.js +2 -2
  19. package/dist/agent/tools/sync-tools.js.map +1 -1
  20. package/dist/auth/github.d.ts +1 -1
  21. package/dist/auth/github.js +21 -13
  22. package/dist/auth/github.js.map +1 -1
  23. package/dist/cli/commands/access.d.ts +11 -0
  24. package/dist/cli/commands/access.js +156 -0
  25. package/dist/cli/commands/access.js.map +1 -0
  26. package/dist/cli/commands/app.js +25 -2
  27. package/dist/cli/commands/app.js.map +1 -1
  28. package/dist/cli/commands/clear.d.ts +5 -0
  29. package/dist/cli/commands/clear.js +36 -0
  30. package/dist/cli/commands/clear.js.map +1 -0
  31. package/dist/cli/commands/clone.js +3 -3
  32. package/dist/cli/commands/clone.js.map +1 -1
  33. package/dist/cli/commands/collection.d.ts +10 -0
  34. package/dist/cli/commands/collection.js +187 -0
  35. package/dist/cli/commands/collection.js.map +1 -0
  36. package/dist/cli/commands/commit.js +2 -1
  37. package/dist/cli/commands/commit.js.map +1 -1
  38. package/dist/cli/commands/config.d.ts +100 -0
  39. package/dist/cli/commands/config.js +1 -1
  40. package/dist/cli/commands/config.js.map +1 -1
  41. package/dist/cli/commands/deploy.js +10 -1
  42. package/dist/cli/commands/deploy.js.map +1 -1
  43. package/dist/cli/commands/index.js +1 -1
  44. package/dist/cli/commands/index.js.map +1 -1
  45. package/dist/cli/commands/init.js +32 -40
  46. package/dist/cli/commands/init.js.map +1 -1
  47. package/dist/cli/commands/join.d.ts +0 -6
  48. package/dist/cli/commands/join.js +26 -111
  49. package/dist/cli/commands/join.js.map +1 -1
  50. package/dist/cli/commands/lint.js +1 -2
  51. package/dist/cli/commands/lint.js.map +1 -1
  52. package/dist/cli/commands/mcp.js +6 -5
  53. package/dist/cli/commands/mcp.js.map +1 -1
  54. package/dist/cli/commands/org.d.ts +10 -0
  55. package/dist/cli/commands/org.js +132 -0
  56. package/dist/cli/commands/org.js.map +1 -0
  57. package/dist/cli/commands/orphans.js +1 -2
  58. package/dist/cli/commands/orphans.js.map +1 -1
  59. package/dist/cli/commands/provision.js +3 -3
  60. package/dist/cli/commands/provision.js.map +1 -1
  61. package/dist/cli/commands/resolve.d.ts +8 -0
  62. package/dist/cli/commands/resolve.js +85 -0
  63. package/dist/cli/commands/resolve.js.map +1 -0
  64. package/dist/cli/commands/serve.js +55 -25
  65. package/dist/cli/commands/serve.js.map +1 -1
  66. package/dist/cli/commands/start.js +22 -205
  67. package/dist/cli/commands/start.js.map +1 -1
  68. package/dist/cli/commands/sync.js +53 -8
  69. package/dist/cli/commands/sync.js.map +1 -1
  70. package/dist/cli/commands/team.d.ts +12 -0
  71. package/dist/cli/commands/team.js +185 -0
  72. package/dist/cli/commands/team.js.map +1 -0
  73. package/dist/cli/index.js +41 -34
  74. package/dist/cli/index.js.map +1 -1
  75. package/dist/cli/scaffolding.d.ts +5 -3
  76. package/dist/cli/scaffolding.js +191 -97
  77. package/dist/cli/scaffolding.js.map +1 -1
  78. package/dist/cli/setup-wizard.js +20 -10
  79. package/dist/cli/setup-wizard.js.map +1 -1
  80. package/dist/cli/sync-review-interactive.js +1 -1
  81. package/dist/cli/sync-review-interactive.js.map +1 -1
  82. package/dist/core/graph.d.ts +5 -10
  83. package/dist/core/graph.js +84 -85
  84. package/dist/core/graph.js.map +1 -1
  85. package/dist/core/migration-runner.d.ts +42 -0
  86. package/dist/core/migration-runner.js +232 -0
  87. package/dist/core/migration-runner.js.map +1 -0
  88. package/dist/core/migration-types.d.ts +101 -0
  89. package/dist/core/migration-types.js +21 -0
  90. package/dist/core/migration-types.js.map +1 -0
  91. package/dist/core/migrations/20260219-formalize-memory-location.d.ts +2 -0
  92. package/dist/core/migrations/20260219-formalize-memory-location.js +35 -0
  93. package/dist/core/migrations/20260219-formalize-memory-location.js.map +1 -0
  94. package/dist/core/migrations/20260220-add-workspace-metadata.d.ts +12 -0
  95. package/dist/core/migrations/20260220-add-workspace-metadata.js +65 -0
  96. package/dist/core/migrations/20260220-add-workspace-metadata.js.map +1 -0
  97. package/dist/core/migrations/20260220-add-workspace-readme.d.ts +11 -0
  98. package/dist/core/migrations/20260220-add-workspace-readme.js +82 -0
  99. package/dist/core/migrations/20260220-add-workspace-readme.js.map +1 -0
  100. package/dist/core/migrations/20260220-migrate-yaml-to-json.d.ts +9 -0
  101. package/dist/core/migrations/20260220-migrate-yaml-to-json.js +64 -0
  102. package/dist/core/migrations/20260220-migrate-yaml-to-json.js.map +1 -0
  103. package/dist/core/migrations/index.d.ts +11 -0
  104. package/dist/core/migrations/index.js +23 -0
  105. package/dist/core/migrations/index.js.map +1 -0
  106. package/dist/core/types.d.ts +19 -34
  107. package/dist/core/types.js +3 -21
  108. package/dist/core/types.js.map +1 -1
  109. package/dist/core/user-config.d.ts +27 -0
  110. package/dist/core/user-config.js +51 -0
  111. package/dist/core/user-config.js.map +1 -1
  112. package/dist/core/validation.d.ts +978 -2182
  113. package/dist/core/validation.js +242 -397
  114. package/dist/core/validation.js.map +1 -1
  115. package/dist/core/workspace-manager.d.ts +32 -31
  116. package/dist/core/workspace-manager.js +171 -186
  117. package/dist/core/workspace-manager.js.map +1 -1
  118. package/dist/core/workspace.d.ts +0 -5
  119. package/dist/core/workspace.js +33 -101
  120. package/dist/core/workspace.js.map +1 -1
  121. package/dist/lib/lib/utils.d.ts +2 -0
  122. package/dist/lib/lib/utils.js +6 -0
  123. package/dist/lib/lib/utils.js.map +1 -0
  124. package/dist/mcp/tools.js +13 -13
  125. package/dist/mcp/tools.js.map +1 -1
  126. package/dist/server/chrome/chrome.css +562 -0
  127. package/dist/server/chrome/chrome.js +540 -0
  128. package/dist/server/index.js +163 -10
  129. package/dist/server/index.js.map +1 -1
  130. package/dist/server/plugin-loader.d.ts +7 -0
  131. package/dist/server/plugin-loader.js +9 -1
  132. package/dist/server/plugin-loader.js.map +1 -1
  133. package/dist/server/routes/chat.d.ts +3 -2
  134. package/dist/server/routes/chat.js +67 -16
  135. package/dist/server/routes/chat.js.map +1 -1
  136. package/dist/server/routes/git-api.d.ts +9 -0
  137. package/dist/server/routes/git-api.js +82 -0
  138. package/dist/server/routes/git-api.js.map +1 -0
  139. package/dist/server/routes/graph-api.d.ts +2 -2
  140. package/dist/server/routes/graph-api.js +267 -3
  141. package/dist/server/routes/graph-api.js.map +1 -1
  142. package/dist/server/routes/permissions-api.d.ts +9 -0
  143. package/dist/server/routes/permissions-api.js +176 -0
  144. package/dist/server/routes/permissions-api.js.map +1 -0
  145. package/dist/server/routes/workspace-api.d.ts +9 -0
  146. package/dist/server/routes/workspace-api.js +283 -0
  147. package/dist/server/routes/workspace-api.js.map +1 -0
  148. package/dist/services/assets/base.d.ts +2 -2
  149. package/dist/services/assets/base.js +4 -4
  150. package/dist/services/assets/base.js.map +1 -1
  151. package/dist/services/assets/index.d.ts +6 -6
  152. package/dist/services/assets/index.js +12 -12
  153. package/dist/services/assets/index.js.map +1 -1
  154. package/dist/services/git.d.ts +35 -0
  155. package/dist/services/git.js +93 -0
  156. package/dist/services/git.js.map +1 -1
  157. package/dist/services/github-provisioner.js +1 -2
  158. package/dist/services/github-provisioner.js.map +1 -1
  159. package/dist/services/github-service.d.ts +99 -0
  160. package/dist/services/github-service.js +310 -0
  161. package/dist/services/github-service.js.map +1 -0
  162. package/dist/services/markdown.js +4 -9
  163. package/dist/services/markdown.js.map +1 -1
  164. package/dist/services/memory-service.d.ts +4 -0
  165. package/dist/services/memory-service.js +13 -1
  166. package/dist/services/memory-service.js.map +1 -1
  167. package/dist/services/sync/commit.d.ts +2 -0
  168. package/dist/services/sync/commit.js +21 -6
  169. package/dist/services/sync/commit.js.map +1 -1
  170. package/dist/services/sync/graphrag-indexer.js +2 -2
  171. package/dist/services/sync/graphrag-indexer.js.map +1 -1
  172. package/dist/utils/git.d.ts +5 -0
  173. package/dist/utils/git.js +10 -0
  174. package/dist/utils/git.js.map +1 -1
  175. package/dist/utils/merge-resolver.d.ts +33 -8
  176. package/dist/utils/merge-resolver.js +157 -55
  177. package/dist/utils/merge-resolver.js.map +1 -1
  178. package/dist/utils/preflight.d.ts +1 -1
  179. package/dist/utils/preflight.js +1 -1
  180. package/dist/web/_app/env.js +1 -0
  181. package/dist/web/_app/immutable/assets/0.CDbX4Cwz.css +1 -0
  182. package/dist/web/_app/immutable/assets/2.DRHi7ABa.css +1 -0
  183. package/dist/web/_app/immutable/assets/3.BJy7pVXi.css +1 -0
  184. package/dist/web/_app/immutable/assets/4.Ad16uh9o.css +1 -0
  185. package/dist/web/_app/immutable/assets/5.BhKgiXd2.css +1 -0
  186. package/dist/web/_app/immutable/assets/6.CeHKR5ZY.css +1 -0
  187. package/dist/web/_app/immutable/assets/AppShell.CXdE5aqF.css +1 -0
  188. package/dist/web/_app/immutable/assets/ChatPanel.RFD5GGYI.css +1 -0
  189. package/dist/web/_app/immutable/assets/editor.CPAf2SRV.css +1 -0
  190. package/dist/web/_app/immutable/chunks/3_5VIr68.js +1 -0
  191. package/dist/web/_app/immutable/chunks/4QY4j-jX.js +1 -0
  192. package/dist/web/_app/immutable/chunks/B0nldqWF.js +23 -0
  193. package/dist/web/_app/immutable/chunks/BB_5th5W.js +3383 -0
  194. package/dist/web/_app/immutable/chunks/BButMJ6M.js +1 -0
  195. package/dist/web/_app/immutable/chunks/BiubvAUI.js +2 -0
  196. package/dist/web/_app/immutable/chunks/CAXuTUkp.js +1 -0
  197. package/dist/web/_app/immutable/chunks/CUzqHQY_.js +1 -0
  198. package/dist/web/_app/immutable/chunks/CYrVHOHA.js +1 -0
  199. package/dist/web/_app/immutable/chunks/CqkleIqs.js +1 -0
  200. package/dist/web/_app/immutable/chunks/DPmdIe6Y.js +1 -0
  201. package/dist/web/_app/immutable/chunks/Dh_H7Owr.js +18 -0
  202. package/dist/web/_app/immutable/chunks/DnlgZ_Tk.js +5 -0
  203. package/dist/web/_app/immutable/chunks/DsERsGWg.js +64 -0
  204. package/dist/web/_app/immutable/chunks/DtVH--hH.js +6 -0
  205. package/dist/web/_app/immutable/chunks/F20aIBpJ.js +1 -0
  206. package/dist/web/_app/immutable/chunks/PPVm8Dsz.js +1 -0
  207. package/dist/web/_app/immutable/chunks/WSUKABI_.js +1 -0
  208. package/dist/web/_app/immutable/chunks/YFT1281h.js +2 -0
  209. package/dist/web/_app/immutable/chunks/aosHekRC.js +1 -0
  210. package/dist/web/_app/immutable/chunks/fwnBoL5x.js +1 -0
  211. package/dist/web/_app/immutable/chunks/hHxe9oXh.js +1 -0
  212. package/dist/web/_app/immutable/chunks/nZKqDQ0w.js +6 -0
  213. package/dist/web/_app/immutable/entry/app.B6Ngvu5P.js +2 -0
  214. package/dist/web/_app/immutable/entry/start.NykKAKQv.js +1 -0
  215. package/dist/web/_app/immutable/nodes/0.DQ5KdeNU.js +1 -0
  216. package/dist/web/_app/immutable/nodes/1.BR6DZ9ov.js +1 -0
  217. package/dist/web/_app/immutable/nodes/2.COSjVZ_C.js +1 -0
  218. package/dist/web/_app/immutable/nodes/3.B9r1XIlO.js +1 -0
  219. package/dist/web/_app/immutable/nodes/4.p-c6hlFf.js +16 -0
  220. package/dist/web/_app/immutable/nodes/5.CPc-Bqal.js +4 -0
  221. package/dist/web/_app/immutable/nodes/6.jJ67YnBc.js +2 -0
  222. package/dist/web/_app/version.json +1 -0
  223. package/dist/web/index.html +43 -0
  224. package/package.json +21 -3
  225. package/dist/agent/skills/bundled/enrich-entities.md +0 -124
  226. package/dist/agent/skills/bundled/gather-context.md +0 -46
@@ -0,0 +1,85 @@
1
+ /**
2
+ * studiograph resolve — retry conflict resolution for repos stuck mid-rebase.
3
+ *
4
+ * Scans all workspace repos, finds those with an in-progress rebase,
5
+ * and runs the conflict resolver on them.
6
+ */
7
+ import { Command } from 'commander';
8
+ import { log, outro } from '@clack/prompts';
9
+ import { existsSync } from 'fs';
10
+ import { join } from 'path';
11
+ import { Workspace } from '../../core/workspace.js';
12
+ import { isInRebase, gitStashPop } from '../../utils/git.js';
13
+ import { resolveConflicts } from '../../utils/merge-resolver.js';
14
+ export const resolveCommand = new Command('resolve')
15
+ .description('Retry conflict resolution for repos stuck mid-rebase')
16
+ .action(async () => {
17
+ const workspace = new Workspace();
18
+ if (!workspace.isWorkspace()) {
19
+ console.error('❌ Not a Studiograph workspace. Run `studiograph init` first.');
20
+ process.exit(1);
21
+ return;
22
+ }
23
+ const workspaceRoot = workspace.getWorkspacePath();
24
+ // Gather all repo paths
25
+ const repoPaths = [];
26
+ const studioPath = join(workspaceRoot, '.studiograph');
27
+ if (existsSync(studioPath)) {
28
+ repoPaths.push({ name: '.studiograph', path: studioPath });
29
+ }
30
+ const config = await workspace.loadConfig();
31
+ for (const repo of config.repos) {
32
+ const repoPath = join(workspaceRoot, repo.path);
33
+ if (existsSync(repoPath)) {
34
+ repoPaths.push({ name: repo.name, path: repoPath });
35
+ }
36
+ }
37
+ // Find repos mid-rebase
38
+ const rebasingRepos = repoPaths.filter(r => isInRebase(r.path));
39
+ if (rebasingRepos.length === 0) {
40
+ log.info('No collections are mid-rebase. Nothing to resolve.');
41
+ return;
42
+ }
43
+ log.info(`Found ${rebasingRepos.length} collection${rebasingRepos.length === 1 ? '' : 's'} mid-rebase.`);
44
+ let hasFailure = false;
45
+ for (const repo of rebasingRepos) {
46
+ log.info(`\nResolving conflicts in ${repo.name}...`);
47
+ const resolution = await resolveConflicts(repo.path, (msg) => log.info(msg));
48
+ gitStashPop(repo.path);
49
+ if (resolution.success) {
50
+ const count = resolution.resolutions.filter(r => r.resolved).length;
51
+ log.success(`${repo.name}: resolved (${count} conflict${count === 1 ? '' : 's'})`);
52
+ for (const r of resolution.resolutions) {
53
+ if (r.resolved) {
54
+ log.info(` ${r.file} — ${r.summary}`);
55
+ }
56
+ }
57
+ }
58
+ else {
59
+ const failed = resolution.resolutions.filter(r => !r.resolved);
60
+ if (failed.length > 0) {
61
+ log.warn(`${repo.name}: ${failed.length} conflict${failed.length === 1 ? '' : 's'} could not be resolved`);
62
+ for (const r of failed) {
63
+ log.info(` ${r.file} — ${r.summary ?? 'unresolved'}`);
64
+ }
65
+ }
66
+ else {
67
+ log.warn(`${repo.name}: resolution failed (no conflicts found — rebase may need manual intervention)`);
68
+ }
69
+ log.info('');
70
+ log.info(' To resolve manually:');
71
+ log.info(` cd ${repo.path}`);
72
+ log.info(' git status');
73
+ log.info(' # edit conflicted files, then: git add <file> && git rebase --continue');
74
+ hasFailure = true;
75
+ }
76
+ }
77
+ if (hasFailure) {
78
+ outro('⚠️ Some conflicts remain. Resolve them manually, then run `studiograph push`.');
79
+ process.exit(1);
80
+ }
81
+ else {
82
+ outro('All conflicts resolved.');
83
+ }
84
+ });
85
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../../src/cli/commands/resolve.ts"],"names":[],"mappings":"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"}
@@ -16,13 +16,16 @@
16
16
  import { Command } from 'commander';
17
17
  import { join } from 'path';
18
18
  import { existsSync } from 'fs';
19
- import { spawnSync } from 'child_process';
19
+ import { exec, spawnSync } from 'child_process';
20
20
  import { Workspace } from '../../core/workspace.js';
21
21
  import { WorkspaceManager } from '../../core/workspace-manager.js';
22
- import { loadUserConfig } from '../../core/user-config.js';
22
+ import { loadUserConfig, resolveApiKey, propagateApiKeyToEnv } from '../../core/user-config.js';
23
+ import { promptLLMSetupIfNeeded } from '../setup-wizard.js';
23
24
  import { runPreflight } from '../../utils/preflight.js';
24
25
  import { createServer } from '../../server/index.js';
25
26
  import { gitClone } from '../../utils/git.js';
27
+ import { box } from 'consola/utils';
28
+ import { header, dimText } from '../colors.js';
26
29
  /**
27
30
  * Pull latest changes for a git repo. Non-fatal — logs warnings on failure.
28
31
  */
@@ -112,9 +115,12 @@ async function bootstrapWorkspace(workspacePath) {
112
115
  }
113
116
  export const serveCommand = new Command('serve')
114
117
  .description('Start the Studiograph HTTP server')
115
- .option('-p, --port <port>', 'Port to listen on', '3000')
118
+ .option('-p, --port <port>', 'Port to listen on', '4800')
116
119
  .option('-H, --host <host>', 'Host to bind to', '0.0.0.0')
120
+ .option('--verbose', 'Show detailed startup info (tools, etc.)')
117
121
  .action(async (opts) => {
122
+ if (opts.verbose)
123
+ process.env.STUDIOGRAPH_VERBOSE = '1';
118
124
  // Bootstrap from STUDIOGRAPH_CONFIG_REPO if repos are not present (e.g. Railway first boot)
119
125
  await bootstrapWorkspace(process.cwd());
120
126
  const workspace = new Workspace();
@@ -128,29 +134,28 @@ export const serveCommand = new Command('serve')
128
134
  return;
129
135
  }
130
136
  const config = await workspace.loadConfig();
131
- // Propagate API key from user config to env (orchestrator reads ANTHROPIC_API_KEY)
132
- const userConfig = loadUserConfig();
133
- if (userConfig.api_key && !process.env.ANTHROPIC_API_KEY) {
134
- process.env.ANTHROPIC_API_KEY = userConfig.api_key;
137
+ // Prompt for model setup if not configured (non-blocking server works without it, but chat won't)
138
+ const isRemote = !!process.env.STUDIOGRAPH_CONFIG_REPO;
139
+ if (!isRemote) {
140
+ await promptLLMSetupIfNeeded();
135
141
  }
142
+ // Propagate API key from user config to env (orchestrator reads provider env vars)
143
+ const userConfig = loadUserConfig();
144
+ propagateApiKeyToEnv(userConfig, config);
145
+ const llmApiKey = resolveApiKey(userConfig, config);
136
146
  // Build GitUser from workspace config
137
147
  const gitUser = {
138
148
  id: 'serve',
139
149
  name: config.team_name || 'Studiograph Server',
140
150
  email: 'noreply@studiograph.local',
141
151
  };
142
- // Admin user for WorkspaceManager (server has full access)
143
- const serverUser = { ...gitUser, role: 'admin' };
144
- const workspaceManager = new WorkspaceManager(process.cwd(), config, gitUser, serverUser);
152
+ const workspaceManager = new WorkspaceManager(process.cwd(), config, gitUser);
145
153
  // Read API keys from environment (semicolon-separated)
146
154
  const apiKeysEnv = process.env.API_KEYS || '';
147
155
  const apiKeys = apiKeysEnv
148
156
  .split(';')
149
157
  .map(k => k.trim())
150
158
  .filter(k => k.length > 0);
151
- if (apiKeys.length === 0) {
152
- console.warn('Warning: No API_KEYS configured — server is open (dev mode)');
153
- }
154
159
  const webhookSecret = process.env.WEBHOOK_SECRET;
155
160
  const port = parseInt(process.env.PORT || opts.port, 10);
156
161
  const host = process.env.HOST || opts.host;
@@ -166,17 +171,42 @@ export const serveCommand = new Command('serve')
166
171
  apiKeys,
167
172
  webhookSecret,
168
173
  });
169
- await server.listen({ port, host });
170
- console.log(`\nStudiograph server running at http://${host}:${port}`);
171
- console.log('\nRoutes:');
172
- console.log(' GET /api/repos');
173
- console.log(' GET /api/repos/:repo/entities/:type');
174
- console.log(' GET /api/repos/:repo/entities/:type/:id');
175
- console.log(' GET /api/repos/:repo/search');
176
- console.log(' GET /api/search');
177
- console.log(' POST /api/chat');
178
- console.log(' GET /api/chat/stream');
179
- console.log(' POST /webhooks/github');
180
- console.log('\nApp plugins loaded from:', appsDir);
174
+ // Try to listen, auto-incrementing port if in use
175
+ let actualPort = port;
176
+ const maxRetries = 10;
177
+ for (let attempt = 0; attempt < maxRetries; attempt++) {
178
+ try {
179
+ await server.listen({ port: actualPort, host });
180
+ break;
181
+ }
182
+ catch (err) {
183
+ if (err.code === 'EADDRINUSE' && attempt < maxRetries - 1) {
184
+ actualPort++;
185
+ continue;
186
+ }
187
+ console.error(`\nFailed to start server: ${err.message}`);
188
+ process.exit(1);
189
+ }
190
+ }
191
+ const collections = config.repos.length;
192
+ const hasChat = !!llmApiKey;
193
+ const url = `http://localhost:${actualPort}`;
194
+ console.log(box([
195
+ `URL: ${header(url)}`,
196
+ `Collections: ${collections}`,
197
+ `Chat: ${hasChat ? 'enabled' : dimText('disabled (run studiograph config to add an AI model)')}`,
198
+ ].join('\n'), {
199
+ title: `Studiograph — ${config.team_name}`,
200
+ style: { borderColor: 'cyan', padding: 1 },
201
+ }));
202
+ if (actualPort !== port) {
203
+ console.log(dimText(` Port ${port} was in use, using ${actualPort} instead.\n`));
204
+ }
205
+ // Open browser on local dev (not on Railway/remote deployments)
206
+ if (!isRemote) {
207
+ const openUrl = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
208
+ exec(`${openUrl} ${url}`);
209
+ }
210
+ console.log(dimText('Press Ctrl+C to stop the server.\n'));
181
211
  });
182
212
  //# sourceMappingURL=serve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAmB,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjH,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,SAAS,OAAO,CAAC,QAAgB,EAAE,KAAa;IAC9C,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,EAAE;QACnE,GAAG,EAAE,QAAQ;QACb,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,MAAM;KACd,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YACrD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,mBAAmB,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,kBAAkB,CAAC,aAAqB;IACrD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAC1D,MAAM,WAAW,GAAK,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAE/C,IAAI,CAAC,aAAa;QAAE,OAAO,CAAC,8BAA8B;IAE1D,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,EAAE,CAChC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAEzE,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;IAE3D,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/B,iDAAiD;QACjD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;QAExC,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;QAC/C,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,IAAI,CAAC,IAAI,CAAC,UAAU;oBAAE,SAAS;gBAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACzB,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACN,wCAAwC;oBACxC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC;oBAC1C,IAAI,CAAC;wBACH,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;oBACjD,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAClB,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,oBAAoB,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;oBACxE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,gCAAgC;IAChC,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;IACjD,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,cAAc,CAAC,CAAC;IAEnD,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAC5C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,SAAS;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAS;QAEnC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,IAAI,MAAM,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;KACxD,MAAM,CAAC,mBAAmB,EAAE,iBAAiB,EAAE,SAAS,CAAC;KACzD,MAAM,CAAC,WAAW,EAAE,0CAA0C,CAAC;KAC/D,MAAM,CAAC,KAAK,EAAE,IAAuD,EAAE,EAAE;IACxE,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,GAAG,CAAC;IACxD,4FAA4F;IAC5F,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;IAElC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,oHAAoH,CAAC,CAAC;QACpI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,EAAE,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAExC,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,UAAU,EAAE,CAAC;IAE5C,oGAAoG;IACpG,MAAM,QAAQ,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,sBAAsB,EAAE,CAAC;IACjC,CAAC;IAED,mFAAmF;IACnF,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;IACpC,oBAAoB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEpD,sCAAsC;IACtC,MAAM,OAAO,GAAG;QACd,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,MAAM,CAAC,SAAS,IAAI,oBAAoB;QAC9C,KAAK,EAAE,2BAA2B;KACnC,CAAC;IAEF,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAC3C,OAAO,CAAC,GAAG,EAAE,EACb,MAAM,EACN,OAAO,CACR,CAAC;IAEF,uDAAuD;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;IAC9C,MAAM,OAAO,GAAG,UAAU;SACvB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAE7B,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;IAE3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAChC,gBAAgB;QAChB,aAAa,EAAE,OAAO,CAAC,GAAG,EAAE;QAC5B,eAAe,EAAE,MAAM;QACvB,OAAO;QACP,OAAO;QACP,IAAI;QACJ,IAAI;QACJ,OAAO;QACP,aAAa;KACd,CAAC,CAAC;IAEH,kDAAkD;IAClD,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,MAAM,UAAU,GAAG,EAAE,CAAC;IACtB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM;QACR,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC1D,UAAU,EAAE,CAAC;gBACb,SAAS;YACX,CAAC;YACD,OAAO,CAAC,KAAK,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IACxC,MAAM,OAAO,GAAG,CAAC,CAAC,SAAS,CAAC;IAC5B,MAAM,GAAG,GAAG,oBAAoB,UAAU,EAAE,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAC,GAAG,CACb;QACE,iBAAiB,MAAM,CAAC,GAAG,CAAC,EAAE;QAC9B,iBAAiB,WAAW,EAAE;QAC9B,iBAAiB,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,sDAAsD,CAAC,EAAE;KACzG,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ;QACE,KAAK,EAAE,iBAAiB,MAAM,CAAC,SAAS,EAAE;QAC1C,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE;KAC3C,CACF,CAAC,CAAC;IAEH,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,sBAAsB,UAAU,aAAa,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,gEAAgE;IAChE,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QAC7G,IAAI,CAAC,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC"}
@@ -19,9 +19,10 @@ import { createLoadSkillTool } from '../../agent/tools/load-skill.js';
19
19
  import { loadCustomTools } from '../../agent/tools/tool-loader.js';
20
20
  import { ConnectorManager } from '../../mcp/connector-manager.js';
21
21
  import { buildConnectorRegistry, createConnectorTools } from '../../agent/tools/connector-tools.js';
22
- import { intro, select, text, outro, spinner } from '@clack/prompts';
22
+ import { spinner } from '@clack/prompts';
23
23
  import { runPreflight } from '../../utils/preflight.js';
24
- import { loadUserConfig, saveUserConfig, getAnthropicCredential } from '../../core/user-config.js';
24
+ import { promptLLMSetupIfNeeded } from '../setup-wizard.js';
25
+ import { loadUserConfig, resolveApiKey, resolveProvider, resolveModelId } from '../../core/user-config.js';
25
26
  import { notifyUpdateAvailable } from '../../utils/version-checker.js';
26
27
  import { PluginLoader } from '../../server/plugin-loader.js';
27
28
  import { join, dirname } from 'path';
@@ -35,71 +36,12 @@ import { info, dimText, header, warn, toolRef, renderUserPrompt } from '../color
35
36
  import { box } from 'consola/utils';
36
37
  import ora from 'ora';
37
38
  import { markdownTheme } from '../theme.js';
38
- // Model provider configurations
39
- const MODEL_PROVIDERS = {
40
- anthropic: {
41
- name: 'Anthropic (Claude)',
42
- models: [
43
- { id: 'claude-opus-4-6', name: 'Claude Opus 4.6 (Most Capable)', hint: 'Best reasoning, can be slower' },
44
- { id: 'claude-sonnet-4-5-20250929', name: 'Claude Sonnet 4.5 (Recommended)', hint: 'Great balance of speed and quality' },
45
- { id: 'claude-3-7-sonnet-20250219', name: 'Claude 3.7 Sonnet', hint: 'Faster, good for most tasks' },
46
- { id: 'claude-3-5-haiku-20241022', name: 'Claude 3.5 Haiku', hint: 'Fastest, lightweight tasks' },
47
- ],
48
- requiresApiKey: true,
49
- envVar: 'ANTHROPIC_API_KEY',
50
- },
51
- openai: {
52
- name: 'OpenAI (GPT)',
53
- models: [
54
- { id: 'gpt-4o', name: 'GPT-4o (Recommended)', hint: 'Latest multimodal model' },
55
- { id: 'gpt-4o-mini', name: 'GPT-4o Mini', hint: 'Faster and cheaper' },
56
- { id: 'gpt-4-turbo', name: 'GPT-4 Turbo', hint: 'Previous generation' },
57
- ],
58
- requiresApiKey: true,
59
- envVar: 'OPENAI_API_KEY',
60
- },
61
- google: {
62
- name: 'Google (Gemini)',
63
- models: [
64
- { id: 'gemini-2.0-flash-exp', name: 'Gemini 2.0 Flash (Experimental)', hint: 'Latest experimental model' },
65
- { id: 'gemini-1.5-pro', name: 'Gemini 1.5 Pro', hint: 'Most capable' },
66
- { id: 'gemini-1.5-flash', name: 'Gemini 1.5 Flash', hint: 'Fast and efficient' },
67
- ],
68
- requiresApiKey: true,
69
- envVar: 'GOOGLE_API_KEY',
70
- },
71
- xai: {
72
- name: 'xAI (Grok)',
73
- models: [
74
- { id: 'grok-2-1212', name: 'Grok 2', hint: 'Latest xAI model' },
75
- { id: 'grok-2-vision-1212', name: 'Grok 2 Vision', hint: 'With vision capabilities' },
76
- ],
77
- requiresApiKey: true,
78
- envVar: 'XAI_API_KEY',
79
- },
80
- groq: {
81
- name: 'Groq (Fast Inference)',
82
- models: [
83
- { id: 'llama-3.3-70b-versatile', name: 'Llama 3.3 70B', hint: 'Very fast inference' },
84
- { id: 'mixtral-8x7b-32768', name: 'Mixtral 8x7B', hint: 'Fast and capable' },
85
- ],
86
- requiresApiKey: true,
87
- envVar: 'GROQ_API_KEY',
88
- },
89
- openrouter: {
90
- name: 'OpenRouter (Access to many models)',
91
- models: [
92
- { id: 'anthropic/claude-opus-4-6', name: 'Claude Opus 4.6 (via OpenRouter)', hint: 'Access Claude without Anthropic API' },
93
- { id: 'openai/gpt-4o', name: 'GPT-4o (via OpenRouter)', hint: 'Access OpenAI without direct API' },
94
- { id: 'meta-llama/llama-3.3-70b-instruct', name: 'Llama 3.3 70B', hint: 'Open source model' },
95
- ],
96
- requiresApiKey: true,
97
- envVar: 'OPENROUTER_API_KEY',
98
- },
99
- };
100
39
  export const startCommand = new Command('start')
101
40
  .description('Start the Studiograph agent chat interface')
102
- .action(async () => {
41
+ .option('--verbose', 'Show detailed startup info (tools, etc.)')
42
+ .action(async (opts) => {
43
+ if (opts.verbose)
44
+ process.env.STUDIOGRAPH_VERBOSE = '1';
103
45
  const workspace = new Workspace();
104
46
  // Check if workspace is initialized
105
47
  if (!workspace.isWorkspace()) {
@@ -111,135 +53,26 @@ export const startCommand = new Command('start')
111
53
  process.exit(1);
112
54
  return;
113
55
  }
114
- // Load workspace config and user config
56
+ // Load workspace config
115
57
  const config = await workspace.loadConfig();
116
58
  const repos = await workspace.getRepos();
59
+ // Model setup — shared wizard handles first-time prompts and "already configured" message
60
+ await promptLLMSetupIfNeeded();
61
+ // Re-read user config (wizard may have updated it)
117
62
  const userConfig = loadUserConfig();
118
- // Check if model is configured — user config takes precedence over workspace config
119
- let modelProvider = userConfig.model_provider || config.model_provider;
120
- let modelId = userConfig.model_id || config.model_id;
121
- // API key: user config (oauth token or api key) → workspace.json → env var (resolved below)
122
- let apiKey = getAnthropicCredential(userConfig) || config.api_key;
123
- if (!modelProvider || !modelId) {
124
- // First-time setup
125
- intro('🎨 Studiograph Setup');
126
- console.log('Let\'s configure your AI model.\n');
127
- // Select provider
128
- const providerChoice = await select({
129
- message: 'Which AI provider would you like to use?',
130
- options: [
131
- { value: 'anthropic', label: 'Anthropic (Claude)', hint: 'Recommended - Best reasoning' },
132
- { value: 'openai', label: 'OpenAI (GPT)', hint: 'Popular, widely used' },
133
- { value: 'google', label: 'Google (Gemini)', hint: 'Free tier available' },
134
- { value: 'xai', label: 'xAI (Grok)', hint: 'Real-time knowledge' },
135
- { value: 'groq', label: 'Groq', hint: 'Fastest inference' },
136
- { value: 'openrouter', label: 'OpenRouter', hint: 'Access many models with one API key' },
137
- ],
138
- });
139
- if (typeof providerChoice === 'symbol') {
140
- outro('Cancelled');
141
- process.exit(0);
142
- }
143
- modelProvider = providerChoice;
144
- const provider = MODEL_PROVIDERS[modelProvider];
145
- // Select model
146
- const modelChoice = await select({
147
- message: `Which ${provider.name} model?`,
148
- options: provider.models.map(m => ({
149
- value: m.id,
150
- label: m.name,
151
- hint: m.hint,
152
- })),
153
- });
154
- if (typeof modelChoice === 'symbol') {
155
- outro('Cancelled');
156
- process.exit(0);
157
- }
158
- modelId = modelChoice;
159
- // Get API key if required
160
- if (provider.requiresApiKey && !apiKey) {
161
- // Check environment variable first
162
- const envKey = process.env[provider.envVar];
163
- if (envKey) {
164
- console.log(`✓ Using ${provider.envVar} from environment\n`);
165
- apiKey = envKey;
166
- }
167
- else if (modelProvider === 'anthropic') {
168
- // Anthropic requires API key from console.anthropic.com
169
- const keyInput = await text({
170
- message: 'Enter your Anthropic API key:',
171
- placeholder: 'sk-ant-api03-...',
172
- validate: (value) => {
173
- if (!value || value.length < 10)
174
- return 'API key seems too short';
175
- },
176
- });
177
- if (typeof keyInput !== 'string') {
178
- outro('Cancelled');
179
- process.exit(0);
180
- }
181
- apiKey = keyInput;
182
- const s = spinner();
183
- s.start('Saving configuration...');
184
- workspace.setModelConfig(modelProvider, modelId, apiKey);
185
- s.stop('Configuration saved ✓');
186
- outro(`Model configured: ${provider.name} - ${modelId}\n`);
187
- }
188
- else {
189
- const keyInput = await text({
190
- message: `Enter your ${provider.name} API key:`,
191
- placeholder: 'sk-...',
192
- validate: (value) => {
193
- if (!value || value.length < 10)
194
- return 'API key seems too short';
195
- },
196
- });
197
- if (typeof keyInput !== 'string') {
198
- outro('Cancelled');
199
- process.exit(0);
200
- }
201
- apiKey = keyInput;
202
- const s = spinner();
203
- s.start('Saving configuration...');
204
- workspace.setModelConfig(modelProvider, modelId, apiKey);
205
- s.stop('Configuration saved ✓');
206
- outro(`Model configured: ${provider.name} - ${modelId}\n`);
207
- }
208
- }
209
- else {
210
- // Save configuration (non-Anthropic or key already available)
211
- const s = spinner();
212
- s.start('Saving configuration...');
213
- workspace.setModelConfig(modelProvider, modelId, apiKey);
214
- s.stop('Configuration saved ✓');
215
- outro(`Model configured: ${provider.name} - ${modelId}\n`);
216
- }
217
- }
218
- // Validate we have all required config
219
- if (!modelProvider || !modelId) {
220
- console.error('❌ Model configuration incomplete');
63
+ const modelProvider = resolveProvider(userConfig, config);
64
+ const modelId = resolveModelId(userConfig, config);
65
+ const apiKey = resolveApiKey(userConfig, config);
66
+ if (!apiKey) {
67
+ console.error('❌ No API key configured. Run `studiograph config` to set one up.');
221
68
  process.exit(1);
222
69
  }
223
- // Check if we need API key for this provider
224
- const provider = MODEL_PROVIDERS[modelProvider];
225
- if (provider?.requiresApiKey && !apiKey) {
226
- const envKey = process.env[provider.envVar];
227
- if (envKey) {
228
- apiKey = envKey;
229
- }
230
- else {
231
- console.error(`❌ API key required for ${provider.name}`);
232
- console.error(` Set ${provider.envVar} environment variable or run setup again`);
233
- process.exit(1);
234
- }
235
- }
236
70
  // Initialize memory service
237
71
  const memoryService = new MemoryService();
238
72
  const recentMemory = memoryService.loadRecentMemory();
239
73
  // Initialize workspace manager
240
74
  const gitUser = { id: 'cli-user', name: config.team_name, email: 'noreply@studiograph.local' };
241
- const cliUser = { id: 'cli-user', name: config.team_name, email: 'noreply@studiograph.local', role: 'admin' };
242
- const workspaceManager = new WorkspaceManager(process.cwd(), config, gitUser, cliUser);
75
+ const workspaceManager = new WorkspaceManager(process.cwd(), config, gitUser);
243
76
  // Discover app-bundled skill and tool directories
244
77
  const appsDir = join(process.cwd(), '.studiograph', 'apps');
245
78
  const loader = new PluginLoader();
@@ -309,10 +142,15 @@ export const startCommand = new Command('start')
309
142
  await initSearchIndex(workspaceManager, config.repos, process.cwd());
310
143
  const totalTools = agent.state.tools.length;
311
144
  const memoryDays = memoryService.listMemoryFiles().length;
145
+ const hasSemanticSearch = !!loadUserConfig().voyage_api_key;
146
+ const searchStatus = hasSemanticSearch
147
+ ? 'semantic'
148
+ : `keyword ${dimText('(run studiograph config to enable semantic search)')}`;
312
149
  console.log(box([
313
150
  `Model: ${header(modelProvider + '/' + modelId)}`,
314
151
  `Tools: ${totalTools} registered${connectorSummary ? ` (${connectorSummary})` : ''}`,
315
152
  `Memory: ${memoryDays} day${memoryDays === 1 ? '' : 's'} loaded`,
153
+ `Search: ${searchStatus}`,
316
154
  ].join('\n'), {
317
155
  title: `Studiograph — ${config.team_name}`,
318
156
  style: { borderColor: 'cyan', padding: 1 },
@@ -579,27 +417,6 @@ async function initSearchIndex(workspaceManager, repos, workspacePath) {
579
417
  // First-run: no repos have been indexed yet
580
418
  const isFirstRun = repos.every(r => !vectorService.getLastIndexedTime(r.name));
581
419
  if (isFirstRun) {
582
- // Prompt for Voyage AI key (optional)
583
- if (!userConfig.voyage_api_key) {
584
- const choice = await select({
585
- message: 'Enable semantic search? (optional)',
586
- options: [
587
- { value: 'skip', label: 'Skip — use FTS keyword search', hint: 'No setup required' },
588
- { value: 'voyage', label: 'Enable semantic search', hint: 'Voyage AI key required' },
589
- ],
590
- });
591
- if (choice === 'voyage' && typeof choice === 'string') {
592
- const keyInput = await text({
593
- message: 'Enter your Voyage AI API key:',
594
- placeholder: 'pa-...',
595
- validate: (v) => (!v || v.length < 10 ? 'Key seems too short' : undefined),
596
- });
597
- if (typeof keyInput === 'string') {
598
- userConfig.voyage_api_key = keyInput;
599
- saveUserConfig(userConfig);
600
- }
601
- }
602
- }
603
420
  // Full index on first run
604
421
  const s = spinner();
605
422
  s.start('Indexing workspace for search...');