@slope-dev/slope 1.13.2 → 1.15.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 (119) hide show
  1. package/dist/cli/commands/context.d.ts +2 -0
  2. package/dist/cli/commands/context.d.ts.map +1 -0
  3. package/dist/cli/commands/context.js +190 -0
  4. package/dist/cli/commands/context.js.map +1 -0
  5. package/dist/cli/commands/distill.d.ts.map +1 -1
  6. package/dist/cli/commands/distill.js +13 -4
  7. package/dist/cli/commands/distill.js.map +1 -1
  8. package/dist/cli/commands/enrich.d.ts +2 -0
  9. package/dist/cli/commands/enrich.d.ts.map +1 -0
  10. package/dist/cli/commands/enrich.js +140 -0
  11. package/dist/cli/commands/enrich.js.map +1 -0
  12. package/dist/cli/commands/index-cmd.d.ts +2 -0
  13. package/dist/cli/commands/index-cmd.d.ts.map +1 -0
  14. package/dist/cli/commands/index-cmd.js +296 -0
  15. package/dist/cli/commands/index-cmd.js.map +1 -0
  16. package/dist/cli/commands/init.d.ts.map +1 -1
  17. package/dist/cli/commands/init.js +17 -182
  18. package/dist/cli/commands/init.js.map +1 -1
  19. package/dist/cli/commands/initiative.d.ts +2 -0
  20. package/dist/cli/commands/initiative.d.ts.map +1 -0
  21. package/dist/cli/commands/initiative.js +207 -0
  22. package/dist/cli/commands/initiative.js.map +1 -0
  23. package/dist/cli/commands/prep.d.ts +2 -0
  24. package/dist/cli/commands/prep.d.ts.map +1 -0
  25. package/dist/cli/commands/prep.js +94 -0
  26. package/dist/cli/commands/prep.js.map +1 -0
  27. package/dist/cli/commands/roadmap.d.ts.map +1 -1
  28. package/dist/cli/commands/roadmap.js +83 -44
  29. package/dist/cli/commands/roadmap.js.map +1 -1
  30. package/dist/cli/commands/store.js +76 -10
  31. package/dist/cli/commands/store.js.map +1 -1
  32. package/dist/cli/guards/stop-check.d.ts +1 -1
  33. package/dist/cli/guards/stop-check.d.ts.map +1 -1
  34. package/dist/cli/guards/stop-check.js +14 -2
  35. package/dist/cli/guards/stop-check.js.map +1 -1
  36. package/dist/cli/index.js +40 -0
  37. package/dist/cli/index.js.map +1 -1
  38. package/dist/cli/interactive-init.d.ts +19 -0
  39. package/dist/cli/interactive-init.d.ts.map +1 -0
  40. package/dist/cli/interactive-init.js +132 -0
  41. package/dist/cli/interactive-init.js.map +1 -0
  42. package/dist/cli/registry.d.ts.map +1 -1
  43. package/dist/cli/registry.js +6 -0
  44. package/dist/cli/registry.js.map +1 -1
  45. package/dist/core/config.d.ts +6 -0
  46. package/dist/core/config.d.ts.map +1 -1
  47. package/dist/core/config.js.map +1 -1
  48. package/dist/core/context.d.ts +20 -0
  49. package/dist/core/context.d.ts.map +1 -0
  50. package/dist/core/context.js +59 -0
  51. package/dist/core/context.js.map +1 -0
  52. package/dist/core/embedding-client.d.ts +11 -0
  53. package/dist/core/embedding-client.d.ts.map +1 -0
  54. package/dist/core/embedding-client.js +92 -0
  55. package/dist/core/embedding-client.js.map +1 -0
  56. package/dist/core/embedding-store.d.ts +44 -0
  57. package/dist/core/embedding-store.d.ts.map +1 -0
  58. package/dist/core/embedding-store.js +7 -0
  59. package/dist/core/embedding-store.js.map +1 -0
  60. package/dist/core/embedding.d.ts +32 -0
  61. package/dist/core/embedding.d.ts.map +1 -0
  62. package/dist/core/embedding.js +114 -0
  63. package/dist/core/embedding.js.map +1 -0
  64. package/dist/core/enrich.d.ts +76 -0
  65. package/dist/core/enrich.d.ts.map +1 -0
  66. package/dist/core/enrich.js +115 -0
  67. package/dist/core/enrich.js.map +1 -0
  68. package/dist/core/index.d.ts +22 -3
  69. package/dist/core/index.d.ts.map +1 -1
  70. package/dist/core/index.js +20 -2
  71. package/dist/core/index.js.map +1 -1
  72. package/dist/core/initiative.d.ts +72 -0
  73. package/dist/core/initiative.d.ts.map +1 -0
  74. package/dist/core/initiative.js +421 -0
  75. package/dist/core/initiative.js.map +1 -0
  76. package/dist/core/interview-engine.d.ts +34 -0
  77. package/dist/core/interview-engine.d.ts.map +1 -0
  78. package/dist/core/interview-engine.js +195 -0
  79. package/dist/core/interview-engine.js.map +1 -0
  80. package/dist/core/interview-steps.d.ts +27 -0
  81. package/dist/core/interview-steps.d.ts.map +1 -0
  82. package/dist/core/interview-steps.js +157 -0
  83. package/dist/core/interview-steps.js.map +1 -0
  84. package/dist/core/interview.d.ts +20 -0
  85. package/dist/core/interview.d.ts.map +1 -1
  86. package/dist/core/interview.js +61 -34
  87. package/dist/core/interview.js.map +1 -1
  88. package/dist/core/metaphor-preview.d.ts +34 -0
  89. package/dist/core/metaphor-preview.d.ts.map +1 -0
  90. package/dist/core/metaphor-preview.js +94 -0
  91. package/dist/core/metaphor-preview.js.map +1 -0
  92. package/dist/core/prep.d.ts +88 -0
  93. package/dist/core/prep.d.ts.map +1 -0
  94. package/dist/core/prep.js +302 -0
  95. package/dist/core/prep.js.map +1 -0
  96. package/dist/core/roles.d.ts +3 -0
  97. package/dist/core/roles.d.ts.map +1 -1
  98. package/dist/core/roles.js +36 -0
  99. package/dist/core/roles.js.map +1 -1
  100. package/dist/core/store.d.ts +1 -1
  101. package/dist/core/store.d.ts.map +1 -1
  102. package/dist/mcp/index.d.ts.map +1 -1
  103. package/dist/mcp/index.js +55 -7
  104. package/dist/mcp/index.js.map +1 -1
  105. package/dist/mcp/registry.d.ts +1 -1
  106. package/dist/mcp/registry.d.ts.map +1 -1
  107. package/dist/mcp/registry.js +15 -0
  108. package/dist/mcp/registry.js.map +1 -1
  109. package/dist/mcp/sandbox.d.ts.map +1 -1
  110. package/dist/mcp/sandbox.js +12 -1
  111. package/dist/mcp/sandbox.js.map +1 -1
  112. package/dist/store/index.d.ts +26 -1
  113. package/dist/store/index.d.ts.map +1 -1
  114. package/dist/store/index.js +193 -1
  115. package/dist/store/index.js.map +1 -1
  116. package/dist/store-pg/index.d.ts.map +1 -1
  117. package/dist/store-pg/index.js +25 -0
  118. package/dist/store-pg/index.js.map +1 -1
  119. package/package.json +3 -1
@@ -0,0 +1,296 @@
1
+ // slope index — Semantic embedding index management
2
+ // Subcommands: (default) incremental, --full, --status, --prune
3
+ import { execSync, execFileSync } from 'node:child_process';
4
+ import { readFileSync } from 'node:fs';
5
+ import { loadConfig } from '../../core/config.js';
6
+ import { chunkFile, shouldSkipFile } from '../../core/embedding.js';
7
+ import { embedBatch } from '../../core/embedding-client.js';
8
+ import { hasEmbeddingSupport } from '../../core/embedding-store.js';
9
+ import { SqliteSlopeStore } from '../../store/index.js';
10
+ function exec(cmd, cwd) {
11
+ try {
12
+ return execSync(cmd, { cwd, encoding: 'utf8', timeout: 30000 }).trim();
13
+ }
14
+ catch {
15
+ return '';
16
+ }
17
+ }
18
+ function parseArgs(args) {
19
+ return {
20
+ full: args.includes('--full'),
21
+ status: args.includes('--status'),
22
+ prune: args.includes('--prune'),
23
+ json: args.includes('--json'),
24
+ };
25
+ }
26
+ function resolveEmbeddingConfig(config) {
27
+ const emb = config.embedding;
28
+ if (!emb) {
29
+ throw new Error('No embedding config found in .slope/config.json.\n' +
30
+ 'Add an "embedding" section with endpoint, model, and dimensions.\n' +
31
+ 'Example:\n "embedding": {\n "endpoint": "http://localhost:11434/v1/embeddings",\n "model": "nomic-embed-text",\n "dimensions": 768\n }');
32
+ }
33
+ return {
34
+ endpoint: emb.endpoint,
35
+ model: emb.model,
36
+ dimensions: emb.dimensions,
37
+ apiKey: emb.apiKey,
38
+ };
39
+ }
40
+ function getSourceFiles(cwd) {
41
+ const output = exec('git ls-files', cwd);
42
+ if (!output)
43
+ return [];
44
+ return output.split('\n').filter(f => !shouldSkipFile(f));
45
+ }
46
+ function getChangedFiles(lastSha, cwd) {
47
+ // Validate SHA to prevent shell injection (use execFileSync for safety)
48
+ if (!/^[0-9a-f]{4,40}$/i.test(lastSha))
49
+ return [];
50
+ try {
51
+ const output = execFileSync('git', ['diff', '--name-only', `${lastSha}..HEAD`], {
52
+ cwd, encoding: 'utf8', timeout: 30000,
53
+ }).trim();
54
+ if (!output)
55
+ return [];
56
+ return output.split('\n').filter(f => !shouldSkipFile(f));
57
+ }
58
+ catch {
59
+ return [];
60
+ }
61
+ }
62
+ function getHeadSha(cwd) {
63
+ return exec('git rev-parse HEAD', cwd);
64
+ }
65
+ export async function indexCommand(args) {
66
+ const cwd = process.cwd();
67
+ const config = loadConfig(cwd);
68
+ const flags = parseArgs(args);
69
+ if (args.includes('--help') || args.includes('-h')) {
70
+ printUsage();
71
+ return;
72
+ }
73
+ // Resolve store
74
+ const storePath = config.store_path ?? '.slope/slope.db';
75
+ const store = new SqliteSlopeStore(`${cwd}/${storePath}`);
76
+ try {
77
+ if (!hasEmbeddingSupport(store)) {
78
+ console.error('Error: Store does not support embeddings.');
79
+ process.exit(1);
80
+ }
81
+ if (flags.status) {
82
+ await showStatus(store, flags.json);
83
+ return;
84
+ }
85
+ const embConfig = resolveEmbeddingConfig(config);
86
+ if (flags.prune) {
87
+ await pruneIndex(store, cwd);
88
+ return;
89
+ }
90
+ if (flags.full) {
91
+ await fullIndex(store, embConfig, cwd);
92
+ }
93
+ else {
94
+ await incrementalIndex(store, embConfig, cwd);
95
+ }
96
+ }
97
+ finally {
98
+ store.close();
99
+ }
100
+ }
101
+ async function showStatus(store, json) {
102
+ const stats = await store.getEmbeddingStats();
103
+ if (json) {
104
+ console.log(JSON.stringify({
105
+ fileCount: stats.fileCount,
106
+ chunkCount: stats.chunkCount,
107
+ model: stats.model,
108
+ dimensions: stats.dimensions,
109
+ lastIndexedAt: stats.lastIndexedAt,
110
+ lastSha: stats.lastIndexedSha,
111
+ }));
112
+ return;
113
+ }
114
+ if (stats.chunkCount === 0) {
115
+ console.log('\nSemantic index: empty');
116
+ console.log(' Run `slope index` to build the index.\n');
117
+ return;
118
+ }
119
+ console.log('\nSemantic Index Status');
120
+ console.log(` Files: ${stats.fileCount}`);
121
+ console.log(` Chunks: ${stats.chunkCount}`);
122
+ console.log(` Model: ${stats.model ?? 'unknown'}`);
123
+ console.log(` Dimensions: ${stats.dimensions ?? 'unknown'}`);
124
+ console.log(` Last SHA: ${stats.lastIndexedSha ?? 'unknown'}`);
125
+ console.log(` Indexed at: ${stats.lastIndexedAt ?? 'unknown'}`);
126
+ console.log('');
127
+ }
128
+ async function fullIndex(store, embConfig, cwd) {
129
+ console.log('Rebuilding semantic index (full)...');
130
+ console.log(` Model: ${embConfig.model} (${embConfig.dimensions} dims)`);
131
+ // Drop and recreate vec table with configured dimensions
132
+ store.clearAllEmbeddings();
133
+ store.recreateVecTable(embConfig.dimensions);
134
+ const files = getSourceFiles(cwd);
135
+ console.log(` Source files: ${files.length}`);
136
+ const allChunks = [];
137
+ for (const file of files) {
138
+ try {
139
+ const content = readFileSync(`${cwd}/${file}`, 'utf8');
140
+ const chunks = chunkFile(file, content);
141
+ allChunks.push(...chunks);
142
+ }
143
+ catch {
144
+ // Skip unreadable files
145
+ }
146
+ }
147
+ console.log(` Total chunks: ${allChunks.length}`);
148
+ if (allChunks.length === 0) {
149
+ console.log(' No chunks to index.\n');
150
+ return;
151
+ }
152
+ const headSha = getHeadSha(cwd);
153
+ const start = Date.now();
154
+ // Embed in batches with progress
155
+ const batchSize = 32;
156
+ let indexed = 0;
157
+ for (let i = 0; i < allChunks.length; i += batchSize) {
158
+ const batch = allChunks.slice(i, i + batchSize);
159
+ const results = await embedBatch(batch, embConfig, batchSize);
160
+ const entries = results.map(r => ({
161
+ filePath: r.filePath,
162
+ chunkIndex: r.chunkIndex,
163
+ chunkText: r.chunkText,
164
+ gitSha: headSha,
165
+ model: embConfig.model,
166
+ vector: r.vector,
167
+ }));
168
+ await store.saveEmbeddings(entries);
169
+ indexed += batch.length;
170
+ const pct = Math.round((indexed / allChunks.length) * 100);
171
+ process.stdout.write(`\r Indexing... ${indexed}/${allChunks.length} chunks (${pct}%)`);
172
+ }
173
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
174
+ console.log(`\n \u2713 Index rebuilt (${files.length} files, ${allChunks.length} chunks, ${elapsed}s)`);
175
+ await store.setIndexMeta(headSha, embConfig.model, embConfig.dimensions);
176
+ console.log('');
177
+ }
178
+ async function incrementalIndex(store, embConfig, cwd) {
179
+ const meta = await store.getIndexMeta();
180
+ const headSha = getHeadSha(cwd);
181
+ // First-time: do full index
182
+ if (!meta) {
183
+ await fullIndex(store, embConfig, cwd);
184
+ return;
185
+ }
186
+ // Dimension mismatch check
187
+ if (meta.dimensions !== embConfig.dimensions) {
188
+ console.error(`Error: Index built with ${meta.dimensions} dims but config specifies ${embConfig.dimensions}. ` +
189
+ 'Run: slope index --full');
190
+ process.exit(1);
191
+ }
192
+ // Already up to date
193
+ if (meta.sha === headSha) {
194
+ console.log('Semantic index is up to date.\n');
195
+ return;
196
+ }
197
+ console.log('Updating semantic index...');
198
+ console.log(` Model: ${embConfig.model} (${embConfig.dimensions} dims)`);
199
+ // Find changed files
200
+ const changedFiles = getChangedFiles(meta.sha, cwd);
201
+ if (changedFiles.length === 0) {
202
+ console.log(' No file changes detected.');
203
+ await store.setIndexMeta(headSha, embConfig.model, embConfig.dimensions);
204
+ console.log(` \u2713 Index updated (SHA: ${headSha.slice(0, 8)})\n`);
205
+ return;
206
+ }
207
+ // Detect deleted files
208
+ const currentFiles = new Set(getSourceFiles(cwd));
209
+ const indexedFiles = await store.getIndexedFiles();
210
+ const deletedFiles = indexedFiles
211
+ .map(f => f.filePath)
212
+ .filter(f => !currentFiles.has(f));
213
+ // Remove deleted files
214
+ for (const file of deletedFiles) {
215
+ await store.deleteEmbeddingsByFile(file);
216
+ }
217
+ // Chunk changed files
218
+ const allChunks = [];
219
+ const validChangedFiles = changedFiles.filter(f => currentFiles.has(f));
220
+ for (const file of validChangedFiles) {
221
+ // Remove old embeddings for this file
222
+ await store.deleteEmbeddingsByFile(file);
223
+ try {
224
+ const content = readFileSync(`${cwd}/${file}`, 'utf8');
225
+ const chunks = chunkFile(file, content);
226
+ allChunks.push(...chunks);
227
+ }
228
+ catch {
229
+ // Skip unreadable files
230
+ }
231
+ }
232
+ console.log(` Changed files: ${validChangedFiles.length} (${allChunks.length} chunks)`);
233
+ if (deletedFiles.length > 0) {
234
+ console.log(` Deleted files: ${deletedFiles.length}`);
235
+ }
236
+ if (allChunks.length > 0) {
237
+ const start = Date.now();
238
+ const results = await embedBatch(allChunks, embConfig);
239
+ const entries = results.map(r => ({
240
+ filePath: r.filePath,
241
+ chunkIndex: r.chunkIndex,
242
+ chunkText: r.chunkText,
243
+ gitSha: headSha,
244
+ model: embConfig.model,
245
+ vector: r.vector,
246
+ }));
247
+ await store.saveEmbeddings(entries);
248
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
249
+ console.log(` \u2713 Index updated (${validChangedFiles.length} files, ${allChunks.length} chunks, ${elapsed}s)`);
250
+ }
251
+ else {
252
+ console.log(' \u2713 Index updated (removals only)');
253
+ }
254
+ await store.setIndexMeta(headSha, embConfig.model, embConfig.dimensions);
255
+ console.log('');
256
+ }
257
+ async function pruneIndex(store, cwd) {
258
+ console.log('Pruning semantic index...');
259
+ const currentFiles = new Set(getSourceFiles(cwd));
260
+ const indexedFiles = await store.getIndexedFiles();
261
+ const orphans = indexedFiles
262
+ .map(f => f.filePath)
263
+ .filter(f => !currentFiles.has(f));
264
+ // Deduplicate
265
+ const uniqueOrphans = [...new Set(orphans)];
266
+ if (uniqueOrphans.length === 0) {
267
+ console.log(' No orphaned embeddings found.\n');
268
+ return;
269
+ }
270
+ for (const file of uniqueOrphans) {
271
+ await store.deleteEmbeddingsByFile(file);
272
+ }
273
+ console.log(` \u2713 Pruned ${uniqueOrphans.length} file(s)\n`);
274
+ }
275
+ function printUsage() {
276
+ console.log(`
277
+ slope index — Semantic embedding index management
278
+
279
+ Usage:
280
+ slope index Incremental index (changed files only)
281
+ slope index --full Full reindex (drop + rebuild)
282
+ slope index --status Show index stats
283
+ slope index --status --json Show index stats as JSON
284
+ slope index --prune Remove embeddings for deleted files
285
+
286
+ Requires "embedding" section in .slope/config.json:
287
+ {
288
+ "embedding": {
289
+ "endpoint": "http://localhost:11434/v1/embeddings",
290
+ "model": "nomic-embed-text",
291
+ "dimensions": 768
292
+ }
293
+ }
294
+ `);
295
+ }
296
+ //# sourceMappingURL=index-cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-cmd.js","sourceRoot":"","sources":["../../../src/cli/commands/index-cmd.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AACvC,OAAO,iCAAiC,CAAC;AACzC,OAAO,8BAA8B,CAAC;AACtC,OAAO,gCAAgC,CAAC;AA0FxC,mFAAmF;AACnF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAElD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAiBtE;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAa3D;AA2bD,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAiDnE;AAsND,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmG/D"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,OAAO,oCAAoC,CAAC;AAC5C,OAAO,+BAA+B,CAAC;AACvC,OAAO,iCAAiC,CAAC;AACzC,OAAO,8BAA8B,CAAC;AACtC,OAAO,gCAAgC,CAAC;AA0FxC,mFAAmF;AACnF,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,UAAU,CAAC;AAElD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAiBtE;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAa3D;AA2bD,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAiDnE;AAyBD,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmG/D"}
@@ -4,8 +4,6 @@ import { fileURLToPath } from 'node:url';
4
4
  import { createConfig } from '../config.js';
5
5
  import { saveHooksConfig } from '../hooks-config.js';
6
6
  import { resolveMetaphor } from '../metaphor.js';
7
- import { listMetaphors } from '../../core/metaphor.js';
8
- import { saveVision } from '../../core/vision.js';
9
7
  import { generateProjectContext, generateSprintChecklist, generateCommitDiscipline, generateReviewLoop, generateCodebaseContextRule, generateCursorSprintChecklist, generateCursorCommitDiscipline, generateCursorReviewLoop, generateCursorCodebaseContextRule, generateCursorrules, generateAgentsMd, generateOpenCodePlugin, generateGenericChecklist, } from '../template-generator.js';
10
8
  import { getAdapter, ADAPTER_PRIORITY } from '../../core/harness.js';
11
9
  // Side-effect imports: ensure all adapters are registered for detectPlatforms()
@@ -589,189 +587,26 @@ export function printInstallSummary(providers) {
589
587
  console.log(' slope hook add --level=full — install all guidance hooks');
590
588
  console.log('');
591
589
  }
592
- async function runInteractiveInit(cwd, args) {
593
- const { createInterface } = await import('node:readline');
594
- const { initFromInterview } = await import('../../core/interview.js');
595
- const rl = createInterface({ input: process.stdin, output: process.stdout });
596
- const ask = (question) => new Promise(resolve => rl.question(question, answer => resolve(answer.trim())));
590
+ async function runInteractiveInit(cwd, _args) {
591
+ // Check for TTY @clack/prompts requires an interactive terminal
592
+ if (!process.stdin.isTTY) {
593
+ console.error('Error: Interactive init requires a TTY (terminal).');
594
+ console.error('Use flag-based init instead: slope init --claude-code --metaphor=golf');
595
+ process.exit(1);
596
+ }
597
597
  try {
598
- const projectName = await ask('Project name: ');
599
- if (!projectName) {
600
- console.error('Project name is required');
598
+ const { runInteractiveCli } = await import('../interactive-init.js');
599
+ await runInteractiveCli(cwd);
600
+ }
601
+ catch (err) {
602
+ // Handle ERR_USE_AFTER_CLOSE from readline teardown
603
+ const code = err?.code;
604
+ if (code === 'ERR_USE_AFTER_CLOSE') {
605
+ console.error('\nInit cancelled (input stream closed).');
606
+ console.error('Use flag-based init instead: slope init --claude-code --metaphor=golf');
601
607
  process.exit(1);
602
608
  }
603
- const repoUrl = await ask('GitHub repo URL (optional): ') || undefined;
604
- // Build metaphor selection menu dynamically
605
- // Ensure built-in metaphors are loaded
606
- await import('../../core/metaphors/index.js');
607
- const allMetaphors = listMetaphors();
608
- const builtinIds = ['golf', 'tennis', 'baseball', 'gaming', 'dnd', 'matrix', 'agile'];
609
- const builtins = builtinIds
610
- .map(id => allMetaphors.find(m => m.id === id))
611
- .filter((m) => m !== undefined);
612
- const customs = allMetaphors.filter(m => !builtinIds.includes(m.id));
613
- const menuItems = [...builtins, ...customs];
614
- console.log('\nChoose a metaphor (display theme for SLOPE output):\n');
615
- menuItems.forEach((m, i) => {
616
- const tag = builtinIds.includes(m.id) ? '' : ' [custom]';
617
- console.log(` ${i + 1}) ${m.id.padEnd(12)} — ${m.description}${tag}`);
618
- });
619
- const customIdx = menuItems.length + 1;
620
- console.log(` ${customIdx}) ${'custom'.padEnd(12)} — Describe a theme and your AI agent will generate it`);
621
- const metaphorChoice = await ask(`\nChoose [1]: `);
622
- let metaphor;
623
- let customTheme;
624
- if (!metaphorChoice) {
625
- metaphor = 'golf';
626
- }
627
- else {
628
- const choiceNum = parseInt(metaphorChoice, 10);
629
- if (choiceNum >= 1 && choiceNum <= menuItems.length) {
630
- metaphor = menuItems[choiceNum - 1].id;
631
- }
632
- else if (choiceNum === customIdx) {
633
- customTheme = await ask('Describe your metaphor theme (e.g., "cooking", "Formula 1", "space exploration"): ');
634
- metaphor = 'golf'; // temporary default until agent generates
635
- }
636
- else {
637
- // Try as a raw ID
638
- const found = allMetaphors.find(m => m.id === metaphorChoice);
639
- metaphor = found ? found.id : 'golf';
640
- }
641
- }
642
- const sprintStr = await ask('Current sprint number [1]: ');
643
- const currentSprint = sprintStr ? parseInt(sprintStr, 10) : undefined;
644
- const teamStr = await ask('Team members (slug:name, comma-separated, optional): ');
645
- let teamMembers;
646
- if (teamStr) {
647
- teamMembers = {};
648
- for (const pair of teamStr.split(',')) {
649
- const [slug, ...nameParts] = pair.trim().split(':');
650
- if (slug && nameParts.length > 0) {
651
- teamMembers[slug.trim()] = nameParts.join(':').trim();
652
- }
653
- }
654
- }
655
- const visionPurpose = await ask('Project vision / purpose (optional): ') || undefined;
656
- let visionPriorities = [];
657
- if (visionPurpose) {
658
- const priStr = await ask('Priorities (comma-separated, optional): ');
659
- if (priStr) {
660
- visionPriorities = priStr.split(',').map(s => s.trim()).filter(Boolean);
661
- }
662
- }
663
- const vision = visionPurpose || undefined;
664
- // Run smart analysis if --smart flag is present
665
- let smartConfig = {};
666
- if (args.includes('--smart')) {
667
- console.log('\nRunning repo analysis...\n');
668
- const { runAnalyzers, saveRepoProfile } = await import('../../core/analyzers/index.js');
669
- const { estimateComplexity } = await import('../../core/analyzers/complexity.js');
670
- const { analyzeBacklog } = await import('../../core/analyzers/backlog.js');
671
- const { generateConfig } = await import('../../core/generators/config.js');
672
- const { generateFirstSprint } = await import('../../core/generators/first-sprint.js');
673
- const { generateCommonIssues } = await import('../../core/generators/common-issues.js');
674
- const profile = await runAnalyzers({ cwd });
675
- saveRepoProfile(profile, cwd);
676
- const complexity = estimateComplexity(profile);
677
- const backlog = await analyzeBacklog(cwd);
678
- const genConfig = generateConfig(profile);
679
- const genSprint = generateFirstSprint(profile, complexity, backlog);
680
- const genIssues = generateCommonIssues(profile, backlog);
681
- // Use generated values as defaults (user input overrides)
682
- smartConfig = {
683
- projectName: genConfig.projectName,
684
- techStack: genConfig.techStack,
685
- sprintCadence: genConfig.sprintCadence,
686
- team: genConfig.team,
687
- };
688
- // Store generated artifacts for writing after init
689
- smartConfig.roadmap = genSprint.roadmap;
690
- smartConfig.commonIssues = genIssues;
691
- const stackParts = [profile.stack.primaryLanguage || 'unknown'];
692
- if (profile.stack.packageManager)
693
- stackParts.push(profile.stack.packageManager);
694
- if (profile.stack.runtime)
695
- stackParts.push(profile.stack.runtime);
696
- if (profile.stack.frameworks.length > 0)
697
- stackParts.push(profile.stack.frameworks.slice(0, 3).join(', '));
698
- const moduleInfo = profile.structure.modules.length > 0
699
- ? `, ${profile.structure.modules.length} modules`
700
- : '';
701
- console.log('Smart Analysis Complete:');
702
- console.log(` Stack: ${stackParts.join(', ')}`);
703
- console.log(` Structure: ${profile.structure.sourceFiles} source files, ${profile.structure.testFiles} test files${moduleInfo}`);
704
- console.log(` Complexity: par ${complexity.estimatedPar}, slope ${complexity.estimatedSlope}${complexity.slopeFactors.length > 0 ? ` (${complexity.slopeFactors.join(', ')})` : ''}`);
705
- console.log(` Backlog: ${backlog.todos.length} TODOs across ${Object.keys(backlog.todosByModule).length} modules`);
706
- console.log(` Suggested: ${genSprint.sprint.tickets.length} tickets for Sprint 1\n`);
707
- }
708
- console.log('\nInitializing SLOPE project...\n');
709
- const result = await initFromInterview(cwd, {
710
- projectName: projectName || smartConfig.projectName || 'my-project',
711
- repoUrl,
712
- metaphor,
713
- currentSprint,
714
- teamMembers: teamMembers ?? smartConfig.team,
715
- techStack: smartConfig.techStack,
716
- sprintCadence: smartConfig.sprintCadence,
717
- vision,
718
- });
719
- console.log(` Config: ${result.configPath}`);
720
- for (const f of result.filesCreated.slice(1)) {
721
- console.log(` Created: ${f}`);
722
- }
723
- // Print custom metaphor request for agent pickup
724
- if (customTheme) {
725
- console.log(`\n Custom metaphor requested: "${customTheme}"`);
726
- console.log(' Your AI agent can generate it with: search({ module: \'metaphor\' })');
727
- console.log(' Then call saveCustomMetaphor() with the generated definition.');
728
- }
729
- // Overwrite with smart-generated artifacts if available
730
- if (smartConfig.roadmap) {
731
- const roadmapPath = join(cwd, 'docs', 'backlog', 'roadmap.json');
732
- mkdirSync(join(cwd, 'docs', 'backlog'), { recursive: true });
733
- writeFileSync(roadmapPath, JSON.stringify(smartConfig.roadmap, null, 2) + '\n');
734
- console.log(` Updated: ${roadmapPath} (from smart analysis)`);
735
- }
736
- if (smartConfig.commonIssues) {
737
- const issuesPath = join(cwd, '.slope', 'common-issues.json');
738
- writeFileSync(issuesPath, JSON.stringify(smartConfig.commonIssues, null, 2) + '\n');
739
- console.log(` Updated: ${issuesPath} (from smart analysis)`);
740
- }
741
- // Save vision document if purpose was provided
742
- if (visionPurpose) {
743
- const now = new Date().toISOString();
744
- const visionDoc = {
745
- purpose: visionPurpose,
746
- priorities: visionPriorities,
747
- createdAt: now,
748
- updatedAt: now,
749
- };
750
- saveVision(visionDoc, cwd);
751
- console.log(` Created .slope/vision.json`);
752
- }
753
- // Handle store setup (infrastructure concern — CLI only)
754
- const storeArg = args.find(a => a.startsWith('--store='));
755
- const storeType = storeArg?.slice('--store='.length) ?? 'sqlite';
756
- if (storeType === 'sqlite') {
757
- const dbPath = join(cwd, '.slope', 'slope.db');
758
- if (!existsSync(dbPath)) {
759
- try {
760
- const { createStore } = await import('../../store/index.js');
761
- const store = createStore({ storePath: '.slope/slope.db', cwd });
762
- store.close();
763
- console.log(` Created ${dbPath}`);
764
- }
765
- catch (err) {
766
- console.error(` Warning: Could not create SQLite store: ${err.message}`);
767
- }
768
- }
769
- }
770
- // Continue with provider installation
771
- return;
772
- }
773
- finally {
774
- rl.close();
609
+ throw err;
775
610
  }
776
611
  }
777
612
  export async function initCommand(args) {