iosm-cli 0.1.2 → 0.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 (103) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +37 -3
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +4 -2
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-profiles.d.ts.map +1 -1
  7. package/dist/core/agent-profiles.js +1 -0
  8. package/dist/core/agent-profiles.js.map +1 -1
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +3 -0
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/blast.d.ts +62 -0
  13. package/dist/core/blast.d.ts.map +1 -0
  14. package/dist/core/blast.js +448 -0
  15. package/dist/core/blast.js.map +1 -0
  16. package/dist/core/contract.d.ts +54 -0
  17. package/dist/core/contract.d.ts.map +1 -0
  18. package/dist/core/contract.js +300 -0
  19. package/dist/core/contract.js.map +1 -0
  20. package/dist/core/sdk.d.ts +3 -3
  21. package/dist/core/sdk.d.ts.map +1 -1
  22. package/dist/core/sdk.js +11 -19
  23. package/dist/core/sdk.js.map +1 -1
  24. package/dist/core/semantic/chunking.d.ts +10 -0
  25. package/dist/core/semantic/chunking.d.ts.map +1 -0
  26. package/dist/core/semantic/chunking.js +82 -0
  27. package/dist/core/semantic/chunking.js.map +1 -0
  28. package/dist/core/semantic/cli.d.ts +23 -0
  29. package/dist/core/semantic/cli.d.ts.map +1 -0
  30. package/dist/core/semantic/cli.js +86 -0
  31. package/dist/core/semantic/cli.js.map +1 -0
  32. package/dist/core/semantic/config.d.ts +8 -0
  33. package/dist/core/semantic/config.d.ts.map +1 -0
  34. package/dist/core/semantic/config.js +266 -0
  35. package/dist/core/semantic/config.js.map +1 -0
  36. package/dist/core/semantic/index-store.d.ts +21 -0
  37. package/dist/core/semantic/index-store.d.ts.map +1 -0
  38. package/dist/core/semantic/index-store.js +73 -0
  39. package/dist/core/semantic/index-store.js.map +1 -0
  40. package/dist/core/semantic/index.d.ts +8 -0
  41. package/dist/core/semantic/index.d.ts.map +1 -0
  42. package/dist/core/semantic/index.js +7 -0
  43. package/dist/core/semantic/index.js.map +1 -0
  44. package/dist/core/semantic/providers.d.ts +22 -0
  45. package/dist/core/semantic/providers.d.ts.map +1 -0
  46. package/dist/core/semantic/providers.js +317 -0
  47. package/dist/core/semantic/providers.js.map +1 -0
  48. package/dist/core/semantic/runtime.d.ts +32 -0
  49. package/dist/core/semantic/runtime.d.ts.map +1 -0
  50. package/dist/core/semantic/runtime.js +510 -0
  51. package/dist/core/semantic/runtime.js.map +1 -0
  52. package/dist/core/semantic/types.d.ts +157 -0
  53. package/dist/core/semantic/types.d.ts.map +1 -0
  54. package/dist/core/semantic/types.js +23 -0
  55. package/dist/core/semantic/types.js.map +1 -0
  56. package/dist/core/shadow-guard.d.ts +30 -0
  57. package/dist/core/shadow-guard.d.ts.map +1 -0
  58. package/dist/core/shadow-guard.js +81 -0
  59. package/dist/core/shadow-guard.js.map +1 -0
  60. package/dist/core/singular.d.ts +73 -0
  61. package/dist/core/singular.d.ts.map +1 -0
  62. package/dist/core/singular.js +413 -0
  63. package/dist/core/singular.js.map +1 -0
  64. package/dist/core/slash-commands.d.ts.map +1 -1
  65. package/dist/core/slash-commands.js +12 -0
  66. package/dist/core/slash-commands.js.map +1 -1
  67. package/dist/core/system-prompt.d.ts.map +1 -1
  68. package/dist/core/system-prompt.js +21 -3
  69. package/dist/core/system-prompt.js.map +1 -1
  70. package/dist/core/tools/ast-grep.js +1 -1
  71. package/dist/core/tools/ast-grep.js.map +1 -1
  72. package/dist/core/tools/comby.js +1 -1
  73. package/dist/core/tools/comby.js.map +1 -1
  74. package/dist/core/tools/index.d.ts +9 -0
  75. package/dist/core/tools/index.d.ts.map +1 -1
  76. package/dist/core/tools/index.js +6 -0
  77. package/dist/core/tools/index.js.map +1 -1
  78. package/dist/core/tools/rg.js +1 -1
  79. package/dist/core/tools/rg.js.map +1 -1
  80. package/dist/core/tools/semantic-search.d.ts +21 -0
  81. package/dist/core/tools/semantic-search.d.ts.map +1 -0
  82. package/dist/core/tools/semantic-search.js +123 -0
  83. package/dist/core/tools/semantic-search.js.map +1 -0
  84. package/dist/index.d.ts +4 -2
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +3 -2
  87. package/dist/index.js.map +1 -1
  88. package/dist/main.d.ts.map +1 -1
  89. package/dist/main.js +124 -0
  90. package/dist/main.js.map +1 -1
  91. package/dist/modes/interactive/components/custom-editor.d.ts +8 -0
  92. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  93. package/dist/modes/interactive/components/custom-editor.js +70 -1
  94. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  95. package/dist/modes/interactive/interactive-mode.d.ts +58 -0
  96. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  97. package/dist/modes/interactive/interactive-mode.js +2067 -104
  98. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  99. package/docs/cli-reference.md +36 -1
  100. package/docs/configuration.md +79 -2
  101. package/docs/getting-started.md +1 -0
  102. package/docs/interactive-mode.md +135 -1
  103. package/package.json +1 -1
@@ -0,0 +1,413 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
+ import { basename, join, relative, sep } from "node:path";
3
+ const SCAN_TEXT_EXTENSIONS = new Set([
4
+ ".ts",
5
+ ".tsx",
6
+ ".js",
7
+ ".jsx",
8
+ ".mjs",
9
+ ".cjs",
10
+ ".py",
11
+ ".go",
12
+ ".rs",
13
+ ".java",
14
+ ".json",
15
+ ".yaml",
16
+ ".yml",
17
+ ".toml",
18
+ ".md",
19
+ ".sh",
20
+ ".sql",
21
+ ".html",
22
+ ".css",
23
+ ]);
24
+ const EXCLUDED_DIR_NAMES = new Set([".git", "node_modules", "dist", "build", ".iosm", ".next", "coverage"]);
25
+ const STOP_WORDS = new Set([
26
+ "a",
27
+ "an",
28
+ "the",
29
+ "and",
30
+ "or",
31
+ "for",
32
+ "with",
33
+ "from",
34
+ "into",
35
+ "about",
36
+ "что",
37
+ "как",
38
+ "для",
39
+ "это",
40
+ "надо",
41
+ "нужно",
42
+ "добавить",
43
+ "сделать",
44
+ "функционал",
45
+ "feature",
46
+ "implement",
47
+ "add",
48
+ ]);
49
+ function toPosixPath(value) {
50
+ return value.split(sep).join("/");
51
+ }
52
+ function getExtension(filePath) {
53
+ const normalized = filePath.toLowerCase();
54
+ const index = normalized.lastIndexOf(".");
55
+ return index >= 0 ? normalized.slice(index) : "";
56
+ }
57
+ function nowIso() {
58
+ return new Date().toISOString();
59
+ }
60
+ function buildRunId(date = new Date()) {
61
+ const year = date.getUTCFullYear();
62
+ const month = String(date.getUTCMonth() + 1).padStart(2, "0");
63
+ const day = String(date.getUTCDate()).padStart(2, "0");
64
+ const hours = String(date.getUTCHours()).padStart(2, "0");
65
+ const minutes = String(date.getUTCMinutes()).padStart(2, "0");
66
+ const seconds = String(date.getUTCSeconds()).padStart(2, "0");
67
+ return `${year}-${month}-${day}-${hours}${minutes}${seconds}`;
68
+ }
69
+ function normalizeRequestTokens(request) {
70
+ return request
71
+ .toLowerCase()
72
+ .split(/[^\p{L}\p{N}]+/u)
73
+ .map((token) => token.trim())
74
+ .filter((token) => token.length >= 3 && !STOP_WORDS.has(token));
75
+ }
76
+ function scoreToComplexity(score) {
77
+ if (score >= 4)
78
+ return "high";
79
+ if (score >= 2)
80
+ return "medium";
81
+ return "low";
82
+ }
83
+ function scoreToBlastRadius(score) {
84
+ if (score >= 4)
85
+ return "high";
86
+ if (score >= 2)
87
+ return "medium";
88
+ return "low";
89
+ }
90
+ function defaultSuggestedFiles(matches) {
91
+ if (matches.length > 0)
92
+ return matches.slice(0, 6);
93
+ return ["src/**/*", "test/**/*"];
94
+ }
95
+ export class SingularService {
96
+ constructor(options) {
97
+ this.cwd = options.cwd;
98
+ }
99
+ getAnalysesRoot() {
100
+ return join(this.cwd, ".iosm", "singular");
101
+ }
102
+ getLastRun() {
103
+ const root = this.getAnalysesRoot();
104
+ if (!existsSync(root))
105
+ return undefined;
106
+ const candidates = readdirSync(root, { withFileTypes: true })
107
+ .filter((entry) => entry.isDirectory())
108
+ .map((entry) => entry.name)
109
+ .sort((a, b) => a.localeCompare(b));
110
+ const runId = candidates[candidates.length - 1];
111
+ if (!runId)
112
+ return undefined;
113
+ const runDir = join(root, runId);
114
+ const analysisPath = join(runDir, "analysis.json");
115
+ if (!existsSync(analysisPath))
116
+ return undefined;
117
+ const metaPath = join(runDir, "meta.json");
118
+ let request;
119
+ let recommendation;
120
+ let generatedAt;
121
+ if (existsSync(metaPath)) {
122
+ try {
123
+ const parsed = JSON.parse(readFileSync(metaPath, "utf8"));
124
+ request = typeof parsed.request === "string" ? parsed.request : undefined;
125
+ recommendation =
126
+ parsed.recommendation === "implement_now" ||
127
+ parsed.recommendation === "implement_incrementally" ||
128
+ parsed.recommendation === "defer"
129
+ ? parsed.recommendation
130
+ : undefined;
131
+ generatedAt = typeof parsed.generatedAt === "string" ? parsed.generatedAt : undefined;
132
+ }
133
+ catch {
134
+ // metadata is optional
135
+ }
136
+ }
137
+ return {
138
+ runId,
139
+ analysisPath,
140
+ metaPath: existsSync(metaPath) ? metaPath : undefined,
141
+ request,
142
+ recommendation,
143
+ generatedAt,
144
+ };
145
+ }
146
+ async analyze(options) {
147
+ const request = options.request.trim();
148
+ const contract = options.contract ?? {};
149
+ const autosave = options.autosave !== false;
150
+ const runId = buildRunId();
151
+ const generatedAt = nowIso();
152
+ const scan = this.scanRepository(request);
153
+ const contractSignals = this.collectContractSignals(contract);
154
+ const baselineScore = this.estimateComplexityScore(request, scan.matchedFiles.length, scan.testFiles, contractSignals.length);
155
+ const baselineComplexity = scoreToComplexity(baselineScore);
156
+ const baselineBlastRadius = scoreToBlastRadius(baselineScore + (scan.matchedFiles.length >= 5 ? 1 : 0));
157
+ const recommendation = this.buildRecommendation({
158
+ request,
159
+ baselineComplexity,
160
+ testFiles: scan.testFiles,
161
+ matchedFiles: scan.matchedFiles.length,
162
+ });
163
+ const suggestedFiles = defaultSuggestedFiles(scan.matchedFiles);
164
+ const optionsList = this.buildOptions({
165
+ request,
166
+ baselineComplexity,
167
+ baselineBlastRadius,
168
+ suggestedFiles,
169
+ contractSignals,
170
+ });
171
+ const result = {
172
+ runId,
173
+ request,
174
+ generatedAt,
175
+ scannedFiles: scan.scannedFiles,
176
+ sourceFiles: scan.sourceFiles,
177
+ testFiles: scan.testFiles,
178
+ matchedFiles: scan.matchedFiles,
179
+ baselineComplexity,
180
+ baselineBlastRadius,
181
+ recommendation: recommendation.value,
182
+ recommendationReason: recommendation.reason,
183
+ contractSignals,
184
+ options: optionsList,
185
+ };
186
+ if (autosave) {
187
+ this.saveRunArtifacts(result);
188
+ }
189
+ return result;
190
+ }
191
+ saveAnalysis(result) {
192
+ this.saveRunArtifacts(result);
193
+ }
194
+ saveRunArtifacts(result) {
195
+ const runDir = join(this.getAnalysesRoot(), result.runId);
196
+ mkdirSync(runDir, { recursive: true });
197
+ const analysisPath = join(runDir, "analysis.json");
198
+ const metaPath = join(runDir, "meta.json");
199
+ writeFileSync(analysisPath, `${JSON.stringify(result, null, 2)}\n`, "utf8");
200
+ writeFileSync(metaPath, `${JSON.stringify({
201
+ runId: result.runId,
202
+ generatedAt: result.generatedAt,
203
+ request: result.request,
204
+ recommendation: result.recommendation,
205
+ stageFit: result.stageFit,
206
+ baselineComplexity: result.baselineComplexity,
207
+ baselineBlastRadius: result.baselineBlastRadius,
208
+ }, null, 2)}\n`, "utf8");
209
+ }
210
+ scanRepository(request) {
211
+ const files = this.walkFiles();
212
+ const tokens = normalizeRequestTokens(request);
213
+ const scored = files
214
+ .map((absolutePath) => {
215
+ const relativePath = toPosixPath(relative(this.cwd, absolutePath));
216
+ const normalizedPath = relativePath.toLowerCase();
217
+ const fileName = basename(relativePath).toLowerCase();
218
+ let score = 0;
219
+ for (const token of tokens) {
220
+ if (normalizedPath.includes(token))
221
+ score += 1;
222
+ if (fileName.includes(token))
223
+ score += 2;
224
+ }
225
+ if (/auth|account|profile|cabinet|dashboard|billing|payment/i.test(request) && /auth|user|account|profile|billing|payment|dashboard/i.test(normalizedPath)) {
226
+ score += 1;
227
+ }
228
+ return { relativePath, score };
229
+ })
230
+ .filter((item) => item.score > 0)
231
+ .sort((a, b) => b.score - a.score || a.relativePath.localeCompare(b.relativePath));
232
+ const matchedFiles = scored.slice(0, 10).map((item) => item.relativePath);
233
+ const sourceFiles = files.filter((absolutePath) => {
234
+ const rel = toPosixPath(relative(this.cwd, absolutePath));
235
+ return rel.startsWith("src/") || rel.startsWith("app/") || rel.startsWith("packages/");
236
+ }).length;
237
+ const testFiles = files.filter((absolutePath) => {
238
+ const rel = toPosixPath(relative(this.cwd, absolutePath)).toLowerCase();
239
+ return /(^|\/)(test|tests|__tests__)\//.test(rel) || /\.test\./.test(rel) || /\.spec\./.test(rel);
240
+ }).length;
241
+ return {
242
+ scannedFiles: files.length,
243
+ sourceFiles,
244
+ testFiles,
245
+ matchedFiles,
246
+ };
247
+ }
248
+ walkFiles() {
249
+ const maxFiles = 12_000;
250
+ const stack = [this.cwd];
251
+ const files = [];
252
+ while (stack.length > 0 && files.length < maxFiles) {
253
+ const dir = stack.pop();
254
+ if (!dir)
255
+ break;
256
+ let entries;
257
+ try {
258
+ entries = readdirSync(dir, { withFileTypes: true });
259
+ }
260
+ catch {
261
+ continue;
262
+ }
263
+ for (const entry of entries) {
264
+ const absolutePath = join(dir, entry.name);
265
+ if (entry.isDirectory()) {
266
+ if (EXCLUDED_DIR_NAMES.has(entry.name))
267
+ continue;
268
+ stack.push(absolutePath);
269
+ continue;
270
+ }
271
+ if (!entry.isFile())
272
+ continue;
273
+ if (!SCAN_TEXT_EXTENSIONS.has(getExtension(entry.name)))
274
+ continue;
275
+ try {
276
+ if (statSync(absolutePath).size > 800_000)
277
+ continue;
278
+ }
279
+ catch {
280
+ continue;
281
+ }
282
+ files.push(absolutePath);
283
+ if (files.length >= maxFiles)
284
+ break;
285
+ }
286
+ }
287
+ return files.sort((a, b) => a.localeCompare(b));
288
+ }
289
+ collectContractSignals(contract) {
290
+ const signals = [];
291
+ if (contract.goal)
292
+ signals.push(`goal=${contract.goal}`);
293
+ if ((contract.constraints ?? []).length > 0)
294
+ signals.push(`constraints=${contract.constraints?.length ?? 0}`);
295
+ if ((contract.quality_gates ?? []).length > 0)
296
+ signals.push(`quality_gates=${contract.quality_gates?.length ?? 0}`);
297
+ if ((contract.definition_of_done ?? []).length > 0) {
298
+ signals.push(`definition_of_done=${contract.definition_of_done?.length ?? 0}`);
299
+ }
300
+ if ((contract.non_goals ?? []).length > 0)
301
+ signals.push(`non_goals=${contract.non_goals?.length ?? 0}`);
302
+ if ((contract.risks ?? []).length > 0)
303
+ signals.push(`risks=${contract.risks?.length ?? 0}`);
304
+ return signals.slice(0, 8);
305
+ }
306
+ estimateComplexityScore(request, matchedFiles, testFiles, contractSignalCount) {
307
+ let score = 1;
308
+ const normalized = request.toLowerCase();
309
+ if (request.length > 70)
310
+ score += 1;
311
+ if (matchedFiles >= 5)
312
+ score += 1;
313
+ if (matchedFiles >= 8)
314
+ score += 1;
315
+ if (testFiles === 0)
316
+ score += 1;
317
+ if (contractSignalCount >= 3)
318
+ score += 1;
319
+ if (/(migration|refactor|rewrite|billing|payment|security|permission|rbac|role|distributed|event|queue|microservice|oauth|sso|регресс|миграц|рефактор|безопасност|права|роли)/.test(normalized)) {
320
+ score += 1;
321
+ }
322
+ if (/(asap|urgent|критично|срочно|немедленно)/.test(normalized)) {
323
+ score += 1;
324
+ }
325
+ return Math.min(6, score);
326
+ }
327
+ buildRecommendation(payload) {
328
+ const normalized = payload.request.toLowerCase();
329
+ const urgent = /(asap|urgent|критично|срочно|немедленно)/.test(normalized);
330
+ if (payload.baselineComplexity === "high" && payload.testFiles === 0) {
331
+ return {
332
+ value: "defer",
333
+ reason: "High complexity with no tests in place. Build a safety net and design first.",
334
+ };
335
+ }
336
+ if (payload.baselineComplexity === "high" || payload.matchedFiles >= 7) {
337
+ return {
338
+ value: "implement_incrementally",
339
+ reason: "The change touches multiple areas. Prefer incremental rollout via an MVP slice.",
340
+ };
341
+ }
342
+ if (urgent) {
343
+ return {
344
+ value: "implement_now",
345
+ reason: "The request is urgent and risk appears manageable. Implement now with a constrained scope.",
346
+ };
347
+ }
348
+ return {
349
+ value: "implement_now",
350
+ reason: "Complexity is manageable. Implement now while enforcing quality gates.",
351
+ };
352
+ }
353
+ buildOptions(payload) {
354
+ const compactFiles = payload.suggestedFiles.slice(0, 6);
355
+ const broadFiles = payload.suggestedFiles.length > 0 ? payload.suggestedFiles : ["src/**/*", "test/**/*"];
356
+ const contractGateStep = payload.contractSignals.length > 0
357
+ ? "Validate contract constraints and quality gates before merge."
358
+ : "Define explicit quality gates and Definition of Done before rollout.";
359
+ return [
360
+ {
361
+ id: "1",
362
+ title: "Incremental MVP",
363
+ summary: "Deliver a minimal usable feature slice quickly with measurable outcomes.",
364
+ complexity: payload.baselineComplexity === "high" ? "medium" : payload.baselineComplexity,
365
+ blast_radius: payload.baselineBlastRadius === "high" ? "medium" : payload.baselineBlastRadius,
366
+ suggested_files: compactFiles,
367
+ plan: [
368
+ "Lock the minimum scope and explicitly exclude non-goals.",
369
+ "Implement in 1-2 target areas without cascading refactors.",
370
+ "Add smoke/regression tests for the new flow.",
371
+ contractGateStep,
372
+ ],
373
+ pros: ["Fast time-to-value", "Controlled risk", "Easy rollback"],
374
+ cons: ["Some UX/infrastructure remains for the next phase"],
375
+ when_to_choose: "Choose when you need delivery this sprint with controlled blast radius.",
376
+ },
377
+ {
378
+ id: "2",
379
+ title: "Comprehensive implementation",
380
+ summary: "Ship the full feature with infrastructure, edge cases, and API expansion.",
381
+ complexity: "high",
382
+ blast_radius: "high",
383
+ suggested_files: broadFiles,
384
+ plan: [
385
+ "Design architecture and module boundaries before coding.",
386
+ "Implement domain logic, API/UI layers, and persistence.",
387
+ "Cover behavior with integration and contract tests.",
388
+ "Roll out in stages with feature flags and metrics.",
389
+ ],
390
+ pros: ["Delivers the full capability", "Lower technical debt after release"],
391
+ cons: ["Higher cost and regression risk", "Requires longer review and test cycle"],
392
+ when_to_choose: "Choose when this is a strategic milestone and you can afford larger scope.",
393
+ },
394
+ {
395
+ id: "3",
396
+ title: "Defer implementation",
397
+ summary: "Do not code now; prepare design, risk map, and migration plan first.",
398
+ complexity: "low",
399
+ blast_radius: "low",
400
+ suggested_files: [],
401
+ plan: [
402
+ "Prepare technical design and impacted-area map.",
403
+ "Define readiness criteria and implementation risks.",
404
+ "Resume implementation after dependencies are cleared.",
405
+ ],
406
+ pros: ["Minimal immediate risk", "Clear plan before coding"],
407
+ cons: ["Feature is not delivered in current release window"],
408
+ when_to_choose: "Choose when prerequisites are missing or risk is too high this cycle.",
409
+ },
410
+ ];
411
+ }
412
+ }
413
+ //# sourceMappingURL=singular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"singular.js","sourceRoot":"","sources":["../../src/core/singular.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { basename, join, relative, sep } from \"node:path\";\nimport type { EngineeringContract } from \"./contract.js\";\n\nexport type SingularComplexity = \"low\" | \"medium\" | \"high\";\nexport type SingularBlastRadius = \"low\" | \"medium\" | \"high\";\nexport type SingularRecommendation = \"implement_now\" | \"implement_incrementally\" | \"defer\";\nexport type SingularStageFit = \"needed_now\" | \"optional_now\" | \"later\";\n\nexport interface SingularImpactAnalysis {\n\tcodebase: string;\n\tdelivery: string;\n\trisks: string;\n\toperations: string;\n}\n\nexport interface SingularOption {\n\tid: string;\n\ttitle: string;\n\tsummary: string;\n\tcomplexity: SingularComplexity;\n\tblast_radius: SingularBlastRadius;\n\tsuggested_files: string[];\n\tplan: string[];\n\tpros: string[];\n\tcons: string[];\n\twhen_to_choose?: string;\n}\n\nexport interface SingularAnalysisResult {\n\trunId: string;\n\trequest: string;\n\tgeneratedAt: string;\n\tscannedFiles: number;\n\tsourceFiles: number;\n\ttestFiles: number;\n\tmatchedFiles: string[];\n\tbaselineComplexity: SingularComplexity;\n\tbaselineBlastRadius: SingularBlastRadius;\n\trecommendation: SingularRecommendation;\n\trecommendationReason: string;\n\tstageFit?: SingularStageFit;\n\tstageFitReason?: string;\n\timpactAnalysis?: SingularImpactAnalysis;\n\tcontractSignals: string[];\n\toptions: SingularOption[];\n}\n\nexport interface SingularLastRun {\n\trunId: string;\n\tanalysisPath: string;\n\tmetaPath?: string;\n\trequest?: string;\n\trecommendation?: SingularRecommendation;\n\tgeneratedAt?: string;\n}\n\nexport interface SingularAnalyzeOptions {\n\trequest: string;\n\tcontract?: EngineeringContract;\n\tautosave?: boolean;\n}\n\nexport interface SingularServiceOptions {\n\tcwd: string;\n}\n\nconst SCAN_TEXT_EXTENSIONS = new Set([\n\t\".ts\",\n\t\".tsx\",\n\t\".js\",\n\t\".jsx\",\n\t\".mjs\",\n\t\".cjs\",\n\t\".py\",\n\t\".go\",\n\t\".rs\",\n\t\".java\",\n\t\".json\",\n\t\".yaml\",\n\t\".yml\",\n\t\".toml\",\n\t\".md\",\n\t\".sh\",\n\t\".sql\",\n\t\".html\",\n\t\".css\",\n]);\n\nconst EXCLUDED_DIR_NAMES = new Set([\".git\", \"node_modules\", \"dist\", \"build\", \".iosm\", \".next\", \"coverage\"]);\n\nconst STOP_WORDS = new Set([\n\t\"a\",\n\t\"an\",\n\t\"the\",\n\t\"and\",\n\t\"or\",\n\t\"for\",\n\t\"with\",\n\t\"from\",\n\t\"into\",\n\t\"about\",\n\t\"что\",\n\t\"как\",\n\t\"для\",\n\t\"это\",\n\t\"надо\",\n\t\"нужно\",\n\t\"добавить\",\n\t\"сделать\",\n\t\"функционал\",\n\t\"feature\",\n\t\"implement\",\n\t\"add\",\n]);\n\nfunction toPosixPath(value: string): string {\n\treturn value.split(sep).join(\"/\");\n}\n\nfunction getExtension(filePath: string): string {\n\tconst normalized = filePath.toLowerCase();\n\tconst index = normalized.lastIndexOf(\".\");\n\treturn index >= 0 ? normalized.slice(index) : \"\";\n}\n\nfunction nowIso(): string {\n\treturn new Date().toISOString();\n}\n\nfunction buildRunId(date = new Date()): string {\n\tconst year = date.getUTCFullYear();\n\tconst month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getUTCDate()).padStart(2, \"0\");\n\tconst hours = String(date.getUTCHours()).padStart(2, \"0\");\n\tconst minutes = String(date.getUTCMinutes()).padStart(2, \"0\");\n\tconst seconds = String(date.getUTCSeconds()).padStart(2, \"0\");\n\treturn `${year}-${month}-${day}-${hours}${minutes}${seconds}`;\n}\n\nfunction normalizeRequestTokens(request: string): string[] {\n\treturn request\n\t\t.toLowerCase()\n\t\t.split(/[^\\p{L}\\p{N}]+/u)\n\t\t.map((token) => token.trim())\n\t\t.filter((token) => token.length >= 3 && !STOP_WORDS.has(token));\n}\n\nfunction scoreToComplexity(score: number): SingularComplexity {\n\tif (score >= 4) return \"high\";\n\tif (score >= 2) return \"medium\";\n\treturn \"low\";\n}\n\nfunction scoreToBlastRadius(score: number): SingularBlastRadius {\n\tif (score >= 4) return \"high\";\n\tif (score >= 2) return \"medium\";\n\treturn \"low\";\n}\n\nfunction defaultSuggestedFiles(matches: string[]): string[] {\n\tif (matches.length > 0) return matches.slice(0, 6);\n\treturn [\"src/**/*\", \"test/**/*\"];\n}\n\nexport class SingularService {\n\tprivate readonly cwd: string;\n\n\tconstructor(options: SingularServiceOptions) {\n\t\tthis.cwd = options.cwd;\n\t}\n\n\tgetAnalysesRoot(): string {\n\t\treturn join(this.cwd, \".iosm\", \"singular\");\n\t}\n\n\tgetLastRun(): SingularLastRun | undefined {\n\t\tconst root = this.getAnalysesRoot();\n\t\tif (!existsSync(root)) return undefined;\n\t\tconst candidates = readdirSync(root, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory())\n\t\t\t.map((entry) => entry.name)\n\t\t\t.sort((a, b) => a.localeCompare(b));\n\t\tconst runId = candidates[candidates.length - 1];\n\t\tif (!runId) return undefined;\n\n\t\tconst runDir = join(root, runId);\n\t\tconst analysisPath = join(runDir, \"analysis.json\");\n\t\tif (!existsSync(analysisPath)) return undefined;\n\t\tconst metaPath = join(runDir, \"meta.json\");\n\n\t\tlet request: string | undefined;\n\t\tlet recommendation: SingularRecommendation | undefined;\n\t\tlet generatedAt: string | undefined;\n\t\tif (existsSync(metaPath)) {\n\t\t\ttry {\n\t\t\t\tconst parsed = JSON.parse(readFileSync(metaPath, \"utf8\")) as Record<string, unknown>;\n\t\t\t\trequest = typeof parsed.request === \"string\" ? parsed.request : undefined;\n\t\t\t\trecommendation =\n\t\t\t\t\tparsed.recommendation === \"implement_now\" ||\n\t\t\t\t\tparsed.recommendation === \"implement_incrementally\" ||\n\t\t\t\t\tparsed.recommendation === \"defer\"\n\t\t\t\t\t\t? (parsed.recommendation as SingularRecommendation)\n\t\t\t\t\t\t: undefined;\n\t\t\t\tgeneratedAt = typeof parsed.generatedAt === \"string\" ? parsed.generatedAt : undefined;\n\t\t\t} catch {\n\t\t\t\t// metadata is optional\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\trunId,\n\t\t\tanalysisPath,\n\t\t\tmetaPath: existsSync(metaPath) ? metaPath : undefined,\n\t\t\trequest,\n\t\t\trecommendation,\n\t\t\tgeneratedAt,\n\t\t};\n\t}\n\n\tasync analyze(options: SingularAnalyzeOptions): Promise<SingularAnalysisResult> {\n\t\tconst request = options.request.trim();\n\t\tconst contract = options.contract ?? {};\n\t\tconst autosave = options.autosave !== false;\n\t\tconst runId = buildRunId();\n\t\tconst generatedAt = nowIso();\n\n\t\tconst scan = this.scanRepository(request);\n\t\tconst contractSignals = this.collectContractSignals(contract);\n\t\tconst baselineScore = this.estimateComplexityScore(request, scan.matchedFiles.length, scan.testFiles, contractSignals.length);\n\t\tconst baselineComplexity = scoreToComplexity(baselineScore);\n\t\tconst baselineBlastRadius = scoreToBlastRadius(baselineScore + (scan.matchedFiles.length >= 5 ? 1 : 0));\n\n\t\tconst recommendation = this.buildRecommendation({\n\t\t\trequest,\n\t\t\tbaselineComplexity,\n\t\t\ttestFiles: scan.testFiles,\n\t\t\tmatchedFiles: scan.matchedFiles.length,\n\t\t});\n\n\t\tconst suggestedFiles = defaultSuggestedFiles(scan.matchedFiles);\n\t\tconst optionsList = this.buildOptions({\n\t\t\trequest,\n\t\t\tbaselineComplexity,\n\t\t\tbaselineBlastRadius,\n\t\t\tsuggestedFiles,\n\t\t\tcontractSignals,\n\t\t});\n\n\t\tconst result: SingularAnalysisResult = {\n\t\t\trunId,\n\t\t\trequest,\n\t\t\tgeneratedAt,\n\t\t\tscannedFiles: scan.scannedFiles,\n\t\t\tsourceFiles: scan.sourceFiles,\n\t\t\ttestFiles: scan.testFiles,\n\t\t\tmatchedFiles: scan.matchedFiles,\n\t\t\tbaselineComplexity,\n\t\t\tbaselineBlastRadius,\n\t\t\trecommendation: recommendation.value,\n\t\t\trecommendationReason: recommendation.reason,\n\t\t\tcontractSignals,\n\t\t\toptions: optionsList,\n\t\t};\n\n\t\tif (autosave) {\n\t\t\tthis.saveRunArtifacts(result);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tsaveAnalysis(result: SingularAnalysisResult): void {\n\t\tthis.saveRunArtifacts(result);\n\t}\n\n\tprivate saveRunArtifacts(result: SingularAnalysisResult): void {\n\t\tconst runDir = join(this.getAnalysesRoot(), result.runId);\n\t\tmkdirSync(runDir, { recursive: true });\n\n\t\tconst analysisPath = join(runDir, \"analysis.json\");\n\t\tconst metaPath = join(runDir, \"meta.json\");\n\n\t\twriteFileSync(analysisPath, `${JSON.stringify(result, null, 2)}\\n`, \"utf8\");\n\t\twriteFileSync(\n\t\t\tmetaPath,\n\t\t\t`${JSON.stringify(\n\t\t\t\t{\n\t\t\t\t\trunId: result.runId,\n\t\t\t\t\tgeneratedAt: result.generatedAt,\n\t\t\t\t\trequest: result.request,\n\t\t\t\t\trecommendation: result.recommendation,\n\t\t\t\t\tstageFit: result.stageFit,\n\t\t\t\t\tbaselineComplexity: result.baselineComplexity,\n\t\t\t\t\tbaselineBlastRadius: result.baselineBlastRadius,\n\t\t\t\t},\n\t\t\t\tnull,\n\t\t\t\t2,\n\t\t\t)}\\n`,\n\t\t\t\"utf8\",\n\t\t);\n\t}\n\n\tprivate scanRepository(request: string): {\n\t\tscannedFiles: number;\n\t\tsourceFiles: number;\n\t\ttestFiles: number;\n\t\tmatchedFiles: string[];\n\t} {\n\t\tconst files = this.walkFiles();\n\t\tconst tokens = normalizeRequestTokens(request);\n\t\tconst scored = files\n\t\t\t.map((absolutePath) => {\n\t\t\t\tconst relativePath = toPosixPath(relative(this.cwd, absolutePath));\n\t\t\t\tconst normalizedPath = relativePath.toLowerCase();\n\t\t\t\tconst fileName = basename(relativePath).toLowerCase();\n\n\t\t\t\tlet score = 0;\n\t\t\t\tfor (const token of tokens) {\n\t\t\t\t\tif (normalizedPath.includes(token)) score += 1;\n\t\t\t\t\tif (fileName.includes(token)) score += 2;\n\t\t\t\t}\n\n\t\t\t\tif (/auth|account|profile|cabinet|dashboard|billing|payment/i.test(request) && /auth|user|account|profile|billing|payment|dashboard/i.test(normalizedPath)) {\n\t\t\t\t\tscore += 1;\n\t\t\t\t}\n\n\t\t\t\treturn { relativePath, score };\n\t\t\t})\n\t\t\t.filter((item) => item.score > 0)\n\t\t\t.sort((a, b) => b.score - a.score || a.relativePath.localeCompare(b.relativePath));\n\n\t\tconst matchedFiles = scored.slice(0, 10).map((item) => item.relativePath);\n\t\tconst sourceFiles = files.filter((absolutePath) => {\n\t\t\tconst rel = toPosixPath(relative(this.cwd, absolutePath));\n\t\t\treturn rel.startsWith(\"src/\") || rel.startsWith(\"app/\") || rel.startsWith(\"packages/\");\n\t\t}).length;\n\t\tconst testFiles = files.filter((absolutePath) => {\n\t\t\tconst rel = toPosixPath(relative(this.cwd, absolutePath)).toLowerCase();\n\t\t\treturn /(^|\\/)(test|tests|__tests__)\\//.test(rel) || /\\.test\\./.test(rel) || /\\.spec\\./.test(rel);\n\t\t}).length;\n\n\t\treturn {\n\t\t\tscannedFiles: files.length,\n\t\t\tsourceFiles,\n\t\t\ttestFiles,\n\t\t\tmatchedFiles,\n\t\t};\n\t}\n\n\tprivate walkFiles(): string[] {\n\t\tconst maxFiles = 12_000;\n\t\tconst stack = [this.cwd];\n\t\tconst files: string[] = [];\n\n\t\twhile (stack.length > 0 && files.length < maxFiles) {\n\t\t\tconst dir = stack.pop();\n\t\t\tif (!dir) break;\n\n\t\t\tlet entries;\n\t\t\ttry {\n\t\t\t\tentries = readdirSync(dir, { withFileTypes: true });\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const entry of entries) {\n\t\t\t\tconst absolutePath = join(dir, entry.name);\n\t\t\t\tif (entry.isDirectory()) {\n\t\t\t\t\tif (EXCLUDED_DIR_NAMES.has(entry.name)) continue;\n\t\t\t\t\tstack.push(absolutePath);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!entry.isFile()) continue;\n\t\t\t\tif (!SCAN_TEXT_EXTENSIONS.has(getExtension(entry.name))) continue;\n\t\t\t\ttry {\n\t\t\t\t\tif (statSync(absolutePath).size > 800_000) continue;\n\t\t\t\t} catch {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tfiles.push(absolutePath);\n\t\t\t\tif (files.length >= maxFiles) break;\n\t\t\t}\n\t\t}\n\n\t\treturn files.sort((a, b) => a.localeCompare(b));\n\t}\n\n\tprivate collectContractSignals(contract: EngineeringContract): string[] {\n\t\tconst signals: string[] = [];\n\t\tif (contract.goal) signals.push(`goal=${contract.goal}`);\n\t\tif ((contract.constraints ?? []).length > 0) signals.push(`constraints=${contract.constraints?.length ?? 0}`);\n\t\tif ((contract.quality_gates ?? []).length > 0) signals.push(`quality_gates=${contract.quality_gates?.length ?? 0}`);\n\t\tif ((contract.definition_of_done ?? []).length > 0) {\n\t\t\tsignals.push(`definition_of_done=${contract.definition_of_done?.length ?? 0}`);\n\t\t}\n\t\tif ((contract.non_goals ?? []).length > 0) signals.push(`non_goals=${contract.non_goals?.length ?? 0}`);\n\t\tif ((contract.risks ?? []).length > 0) signals.push(`risks=${contract.risks?.length ?? 0}`);\n\t\treturn signals.slice(0, 8);\n\t}\n\n\tprivate estimateComplexityScore(\n\t\trequest: string,\n\t\tmatchedFiles: number,\n\t\ttestFiles: number,\n\t\tcontractSignalCount: number,\n\t): number {\n\t\tlet score = 1;\n\t\tconst normalized = request.toLowerCase();\n\n\t\tif (request.length > 70) score += 1;\n\t\tif (matchedFiles >= 5) score += 1;\n\t\tif (matchedFiles >= 8) score += 1;\n\t\tif (testFiles === 0) score += 1;\n\t\tif (contractSignalCount >= 3) score += 1;\n\n\t\tif (\n\t\t\t/(migration|refactor|rewrite|billing|payment|security|permission|rbac|role|distributed|event|queue|microservice|oauth|sso|регресс|миграц|рефактор|безопасност|права|роли)/.test(\n\t\t\t\tnormalized,\n\t\t\t)\n\t\t) {\n\t\t\tscore += 1;\n\t\t}\n\n\t\tif (/(asap|urgent|критично|срочно|немедленно)/.test(normalized)) {\n\t\t\tscore += 1;\n\t\t}\n\n\t\treturn Math.min(6, score);\n\t}\n\n\tprivate buildRecommendation(payload: {\n\t\trequest: string;\n\t\tbaselineComplexity: SingularComplexity;\n\t\ttestFiles: number;\n\t\tmatchedFiles: number;\n\t}): { value: SingularRecommendation; reason: string } {\n\t\tconst normalized = payload.request.toLowerCase();\n\t\tconst urgent = /(asap|urgent|критично|срочно|немедленно)/.test(normalized);\n\n\t\tif (payload.baselineComplexity === \"high\" && payload.testFiles === 0) {\n\t\t\treturn {\n\t\t\t\tvalue: \"defer\",\n\t\t\t\treason: \"High complexity with no tests in place. Build a safety net and design first.\",\n\t\t\t};\n\t\t}\n\t\tif (payload.baselineComplexity === \"high\" || payload.matchedFiles >= 7) {\n\t\t\treturn {\n\t\t\t\tvalue: \"implement_incrementally\",\n\t\t\t\treason: \"The change touches multiple areas. Prefer incremental rollout via an MVP slice.\",\n\t\t\t};\n\t\t}\n\t\tif (urgent) {\n\t\t\treturn {\n\t\t\t\tvalue: \"implement_now\",\n\t\t\t\treason: \"The request is urgent and risk appears manageable. Implement now with a constrained scope.\",\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tvalue: \"implement_now\",\n\t\t\treason: \"Complexity is manageable. Implement now while enforcing quality gates.\",\n\t\t};\n\t}\n\n\tprivate buildOptions(payload: {\n\t\trequest: string;\n\t\tbaselineComplexity: SingularComplexity;\n\t\tbaselineBlastRadius: SingularBlastRadius;\n\t\tsuggestedFiles: string[];\n\t\tcontractSignals: string[];\n\t}): SingularOption[] {\n\t\tconst compactFiles = payload.suggestedFiles.slice(0, 6);\n\t\tconst broadFiles = payload.suggestedFiles.length > 0 ? payload.suggestedFiles : [\"src/**/*\", \"test/**/*\"];\n\t\tconst contractGateStep =\n\t\t\tpayload.contractSignals.length > 0\n\t\t\t\t? \"Validate contract constraints and quality gates before merge.\"\n\t\t\t\t: \"Define explicit quality gates and Definition of Done before rollout.\";\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: \"1\",\n\t\t\t\ttitle: \"Incremental MVP\",\n\t\t\t\tsummary: \"Deliver a minimal usable feature slice quickly with measurable outcomes.\",\n\t\t\t\tcomplexity: payload.baselineComplexity === \"high\" ? \"medium\" : payload.baselineComplexity,\n\t\t\t\tblast_radius: payload.baselineBlastRadius === \"high\" ? \"medium\" : payload.baselineBlastRadius,\n\t\t\t\tsuggested_files: compactFiles,\n\t\t\t\tplan: [\n\t\t\t\t\t\"Lock the minimum scope and explicitly exclude non-goals.\",\n\t\t\t\t\t\"Implement in 1-2 target areas without cascading refactors.\",\n\t\t\t\t\t\"Add smoke/regression tests for the new flow.\",\n\t\t\t\t\tcontractGateStep,\n\t\t\t\t],\n\t\t\t\tpros: [\"Fast time-to-value\", \"Controlled risk\", \"Easy rollback\"],\n\t\t\t\tcons: [\"Some UX/infrastructure remains for the next phase\"],\n\t\t\t\twhen_to_choose: \"Choose when you need delivery this sprint with controlled blast radius.\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"2\",\n\t\t\t\ttitle: \"Comprehensive implementation\",\n\t\t\t\tsummary: \"Ship the full feature with infrastructure, edge cases, and API expansion.\",\n\t\t\t\tcomplexity: \"high\",\n\t\t\t\tblast_radius: \"high\",\n\t\t\t\tsuggested_files: broadFiles,\n\t\t\t\tplan: [\n\t\t\t\t\t\"Design architecture and module boundaries before coding.\",\n\t\t\t\t\t\"Implement domain logic, API/UI layers, and persistence.\",\n\t\t\t\t\t\"Cover behavior with integration and contract tests.\",\n\t\t\t\t\t\"Roll out in stages with feature flags and metrics.\",\n\t\t\t\t],\n\t\t\t\tpros: [\"Delivers the full capability\", \"Lower technical debt after release\"],\n\t\t\t\tcons: [\"Higher cost and regression risk\", \"Requires longer review and test cycle\"],\n\t\t\t\twhen_to_choose: \"Choose when this is a strategic milestone and you can afford larger scope.\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: \"3\",\n\t\t\t\ttitle: \"Defer implementation\",\n\t\t\t\tsummary: \"Do not code now; prepare design, risk map, and migration plan first.\",\n\t\t\t\tcomplexity: \"low\",\n\t\t\t\tblast_radius: \"low\",\n\t\t\t\tsuggested_files: [],\n\t\t\t\tplan: [\n\t\t\t\t\t\"Prepare technical design and impacted-area map.\",\n\t\t\t\t\t\"Define readiness criteria and implementation risks.\",\n\t\t\t\t\t\"Resume implementation after dependencies are cleared.\",\n\t\t\t\t],\n\t\t\t\tpros: [\"Minimal immediate risk\", \"Clear plan before coding\"],\n\t\t\t\tcons: [\"Feature is not delivered in current release window\"],\n\t\t\t\twhen_to_choose: \"Choose when prerequisites are missing or risk is too high this cycle.\",\n\t\t\t},\n\t\t];\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,mBAAmB,CAsErE,CAAC"}
1
+ {"version":3,"file":"slash-commands.d.ts","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,CAAC,mBAAmB,CAqFrE,CAAC"}
@@ -31,6 +31,18 @@ export const BUILTIN_SLASH_COMMANDS = [
31
31
  name: "memory",
32
32
  description: "Memory manager: /memory (interactive), /memory <text>, /memory edit <index> <text>, /memory rm <index>",
33
33
  },
34
+ {
35
+ name: "semantic",
36
+ description: "Semantic search manager: /semantic (interactive UI), /semantic setup|auto-index|status|index|rebuild|query <text> [--top-k N]",
37
+ },
38
+ {
39
+ name: "contract",
40
+ description: "Engineering contract manager: /contract (interactive field editor), /contract show|edit|clear --scope <project|session>",
41
+ },
42
+ {
43
+ name: "singular",
44
+ description: "Feature feasibility analyzer: /singular <request> (builds implementation options and recommendations)",
45
+ },
34
46
  { name: "settings", description: "Open settings menu" },
35
47
  {
36
48
  name: "permissions",
@@ -1 +1 @@
1
- {"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["export type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport type SlashCommandLocation = \"user\" | \"project\" | \"path\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tlocation?: SlashCommandLocation;\n\tpath?: string;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"init\", description: \"Initialize iosm.yaml and .iosm scaffold in current (or target) directory\" },\n\t{\n\t\tname: \"iosm\",\n\t\tdescription: \"Run IOSM auto-improvement loop: /iosm [target-index] [--max-iterations N] [--force-init]\",\n\t},\n\t{\n\t\tname: \"orchestrate\",\n\t\tdescription:\n\t\t\t\"Run orchestrated subagents: /orchestrate (--parallel|--sequential) --agents N [--max-parallel N] [--profile <name>|--profiles p1,p2] [--cwd p1,p2] [--locks l1,l2] [--worktree] [--depends 2>1,3>2] <task>\",\n\t},\n\t{\n\t\tname: \"agents\",\n\t\tdescription:\n\t\t\t\"Interactive agent menu: browse/use/create/edit/delete custom agents and inspect source precedence from .iosm/agents\",\n\t},\n\t{ name: \"subagent-runs\", description: \"List recent subagent runs from .iosm/subagents/runs\" },\n\t{\n\t\tname: \"subagent-resume\",\n\t\tdescription: \"Resume from prior subagent output: /subagent-resume [run-id] [extra instructions] (picker when omitted)\",\n\t},\n\t{ name: \"team-runs\", description: \"List recent team orchestration runs from .iosm/subagents/teams\" },\n\t{ name: \"team-status\", description: \"Show a team run status: /team-status [team-run-id] (picker when omitted)\" },\n\t{ name: \"cycle-list\", description: \"List IOSM cycles\" },\n\t{ name: \"cycle-plan\", description: \"Plan a new IOSM cycle: /cycle-plan [--id <id>] [--force] <goal...>\" },\n\t{ name: \"cycle-status\", description: \"Show IOSM cycle completeness and gates: /cycle-status [cycle-id]\" },\n\t{ name: \"cycle-report\", description: \"Show IOSM cycle report JSON: /cycle-report [cycle-id]\" },\n\t{\n\t\tname: \"mcp\",\n\t\tdescription:\n\t\t\t\"MCP server manager: /mcp (interactive UI), /mcp add <name> ..., /mcp list, /mcp tools [name], /mcp enable|disable|remove <name>\",\n\t},\n\t{\n\t\tname: \"memory\",\n\t\tdescription:\n\t\t\t\"Memory manager: /memory (interactive), /memory <text>, /memory edit <index> <text>, /memory rm <index>\",\n\t},\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{\n\t\tname: \"permissions\",\n\t\tdescription:\n\t\t\t\"Permission controls: /permissions (interactive menu) or /permissions [ask|auto|yolo|status|hooks] and /permissions [allow|deny] [list|add|remove] <tool:match>\",\n\t},\n\t{ name: \"yolo\", description: \"Toggle permission prompts: /yolo [on|off|status]\" },\n\t{ name: \"model\", description: \"Select model (provider-first selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for Ctrl+P cycling\" },\n\t{ name: \"export\", description: \"Export session to HTML file: /export [output-path] (wizard when omitted)\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{\n\t\tname: \"doctor\",\n\t\tdescription: \"Run runtime diagnostics (model/auth/MCP/CLI tools/hooks/paths) with optional interactive fixes\",\n\t},\n\t{ name: \"checkpoint\", description: \"Create/list checkpoints for safe rollback\" },\n\t{ name: \"rollback\", description: \"Rollback session tree to a checkpoint (picker when omitted)\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous message\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"login\", description: \"Authenticate with provider (OAuth incl. Qwen + OpenRouter API key)\" },\n\t{ name: \"auth\", description: \"Alias for /login\" },\n\t{ name: \"logout\", description: \"Remove saved provider credentials (OAuth/API key)\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"clear\", description: \"Alias for /new\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"reload\", description: \"Reload extensions, skills, prompts, and themes\" },\n\t{ name: \"quit\", description: \"Quit iosm\" },\n];\n"]}
1
+ {"version":3,"file":"slash-commands.js","sourceRoot":"","sources":["../../src/core/slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["export type SlashCommandSource = \"extension\" | \"prompt\" | \"skill\";\n\nexport type SlashCommandLocation = \"user\" | \"project\" | \"path\";\n\nexport interface SlashCommandInfo {\n\tname: string;\n\tdescription?: string;\n\tsource: SlashCommandSource;\n\tlocation?: SlashCommandLocation;\n\tpath?: string;\n}\n\nexport interface BuiltinSlashCommand {\n\tname: string;\n\tdescription: string;\n}\n\nexport const BUILTIN_SLASH_COMMANDS: ReadonlyArray<BuiltinSlashCommand> = [\n\t{ name: \"init\", description: \"Initialize iosm.yaml and .iosm scaffold in current (or target) directory\" },\n\t{\n\t\tname: \"iosm\",\n\t\tdescription: \"Run IOSM auto-improvement loop: /iosm [target-index] [--max-iterations N] [--force-init]\",\n\t},\n\t{\n\t\tname: \"orchestrate\",\n\t\tdescription:\n\t\t\t\"Run orchestrated subagents: /orchestrate (--parallel|--sequential) --agents N [--max-parallel N] [--profile <name>|--profiles p1,p2] [--cwd p1,p2] [--locks l1,l2] [--worktree] [--depends 2>1,3>2] <task>\",\n\t},\n\t{\n\t\tname: \"agents\",\n\t\tdescription:\n\t\t\t\"Interactive agent menu: browse/use/create/edit/delete custom agents and inspect source precedence from .iosm/agents\",\n\t},\n\t{ name: \"subagent-runs\", description: \"List recent subagent runs from .iosm/subagents/runs\" },\n\t{\n\t\tname: \"subagent-resume\",\n\t\tdescription: \"Resume from prior subagent output: /subagent-resume [run-id] [extra instructions] (picker when omitted)\",\n\t},\n\t{ name: \"team-runs\", description: \"List recent team orchestration runs from .iosm/subagents/teams\" },\n\t{ name: \"team-status\", description: \"Show a team run status: /team-status [team-run-id] (picker when omitted)\" },\n\t{ name: \"cycle-list\", description: \"List IOSM cycles\" },\n\t{ name: \"cycle-plan\", description: \"Plan a new IOSM cycle: /cycle-plan [--id <id>] [--force] <goal...>\" },\n\t{ name: \"cycle-status\", description: \"Show IOSM cycle completeness and gates: /cycle-status [cycle-id]\" },\n\t{ name: \"cycle-report\", description: \"Show IOSM cycle report JSON: /cycle-report [cycle-id]\" },\n\t{\n\t\tname: \"mcp\",\n\t\tdescription:\n\t\t\t\"MCP server manager: /mcp (interactive UI), /mcp add <name> ..., /mcp list, /mcp tools [name], /mcp enable|disable|remove <name>\",\n\t},\n\t{\n\t\tname: \"memory\",\n\t\tdescription:\n\t\t\t\"Memory manager: /memory (interactive), /memory <text>, /memory edit <index> <text>, /memory rm <index>\",\n\t},\n\t{\n\t\tname: \"semantic\",\n\t\tdescription:\n\t\t\t\"Semantic search manager: /semantic (interactive UI), /semantic setup|auto-index|status|index|rebuild|query <text> [--top-k N]\",\n\t},\n\t{\n\t\tname: \"contract\",\n\t\tdescription:\n\t\t\t\"Engineering contract manager: /contract (interactive field editor), /contract show|edit|clear --scope <project|session>\",\n\t},\n\t{\n\t\tname: \"singular\",\n\t\tdescription:\n\t\t\t\"Feature feasibility analyzer: /singular <request> (builds implementation options and recommendations)\",\n\t},\n\t{ name: \"settings\", description: \"Open settings menu\" },\n\t{\n\t\tname: \"permissions\",\n\t\tdescription:\n\t\t\t\"Permission controls: /permissions (interactive menu) or /permissions [ask|auto|yolo|status|hooks] and /permissions [allow|deny] [list|add|remove] <tool:match>\",\n\t},\n\t{ name: \"yolo\", description: \"Toggle permission prompts: /yolo [on|off|status]\" },\n\t{ name: \"model\", description: \"Select model (provider-first selector UI)\" },\n\t{ name: \"scoped-models\", description: \"Enable/disable models for Ctrl+P cycling\" },\n\t{ name: \"export\", description: \"Export session to HTML file: /export [output-path] (wizard when omitted)\" },\n\t{ name: \"share\", description: \"Share session as a secret GitHub gist\" },\n\t{ name: \"copy\", description: \"Copy last agent message to clipboard\" },\n\t{ name: \"name\", description: \"Set session display name\" },\n\t{ name: \"session\", description: \"Show session info and stats\" },\n\t{\n\t\tname: \"doctor\",\n\t\tdescription: \"Run runtime diagnostics (model/auth/MCP/CLI tools/hooks/paths) with optional interactive fixes\",\n\t},\n\t{ name: \"checkpoint\", description: \"Create/list checkpoints for safe rollback\" },\n\t{ name: \"rollback\", description: \"Rollback session tree to a checkpoint (picker when omitted)\" },\n\t{ name: \"changelog\", description: \"Show changelog entries\" },\n\t{ name: \"hotkeys\", description: \"Show all keyboard shortcuts\" },\n\t{ name: \"fork\", description: \"Create a new fork from a previous message\" },\n\t{ name: \"tree\", description: \"Navigate session tree (switch branches)\" },\n\t{ name: \"login\", description: \"Authenticate with provider (OAuth incl. Qwen + OpenRouter API key)\" },\n\t{ name: \"auth\", description: \"Alias for /login\" },\n\t{ name: \"logout\", description: \"Remove saved provider credentials (OAuth/API key)\" },\n\t{ name: \"new\", description: \"Start a new session\" },\n\t{ name: \"clear\", description: \"Alias for /new\" },\n\t{ name: \"compact\", description: \"Manually compact the session context\" },\n\t{ name: \"resume\", description: \"Resume a different session\" },\n\t{ name: \"reload\", description: \"Reload extensions, skills, prompts, and themes\" },\n\t{ name: \"quit\", description: \"Quit iosm\" },\n];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAsBhE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAoPhF"}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AA0BhE,MAAM,WAAW,wBAAwB;IACxC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yBAAyB;IACzB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAuRhF"}
@@ -12,14 +12,15 @@ const toolDescriptions = {
12
12
  grep: "Search file contents for patterns (respects .gitignore)",
13
13
  find: "Find files by glob pattern (respects .gitignore)",
14
14
  ls: "List directory contents",
15
- rg: "Run ripgrep directly for advanced regex search",
15
+ rg: "Run ripgrep directly for advanced regex search (prefer explicit path args, e.g. -n pattern .)",
16
16
  fd: "Run fd directly for fast file discovery",
17
- ast_grep: "Run ast-grep for AST/syntax-aware structural code search",
18
- comby: "Run comby for structural pattern search/rewrite previews (no in-place edits)",
17
+ ast_grep: "Run ast-grep for AST/syntax-aware structural code search (prefer run --pattern; retry with scan/-p on older versions)",
18
+ comby: "Run comby for structural pattern search/rewrite previews (prefer explicit -matcher; no in-place edits)",
19
19
  jq: "Run jq for JSON querying/transformation",
20
20
  yq: "Run yq for YAML/JSON/TOML querying/transformation",
21
21
  semgrep: "Run semgrep for structural/static security checks",
22
22
  sed: "Run sed for stream editing/extraction previews (no in-place edits)",
23
+ semantic_search: "Semantic embeddings search over the project index (actions: status, index, rebuild, query)",
23
24
  task: "Run a specialized subagent (supports profile, cwd, lock_key for optional write serialization, run_id/task_id, model override, background mode for detached runs, and agent=<custom name from .iosm/agents>)",
24
25
  };
25
26
  /** Build the system prompt with tools, guidelines, and context */
@@ -102,6 +103,7 @@ export function buildSystemPrompt(options = {}) {
102
103
  const hasYq = tools.includes("yq");
103
104
  const hasSemgrep = tools.includes("semgrep");
104
105
  const hasSed = tools.includes("sed");
106
+ const hasSemanticSearch = tools.includes("semantic_search");
105
107
  const hasRead = tools.includes("read");
106
108
  // File exploration guidelines
107
109
  if (hasBash && !hasGrep && !hasFind && !hasLs && !hasRg && !hasFd) {
@@ -110,6 +112,9 @@ export function buildSystemPrompt(options = {}) {
110
112
  else if (hasBash && (hasGrep || hasFind || hasLs || hasRg || hasFd)) {
111
113
  addGuideline("Prefer grep/find/ls/rg/fd tools over bash for codebase exploration (faster and less noisy)");
112
114
  }
115
+ if (hasRg || hasFd || hasAstGrep || hasComby || hasJq || hasYq || hasSemgrep || hasSed || hasSemanticSearch) {
116
+ addGuideline("Route work to specialized tools first: rg/fd (search/discovery), semantic_search (concept-level retrieval), ast_grep/comby (structural code queries), jq/yq (data/config transforms), semgrep (risk scans), sed (stream extraction)");
117
+ }
113
118
  if (hasAstGrep || hasComby) {
114
119
  addGuideline("Use ast_grep/comby for syntax-aware structural queries before falling back to broad regex");
115
120
  }
@@ -125,6 +130,17 @@ export function buildSystemPrompt(options = {}) {
125
130
  if (hasSed) {
126
131
  addGuideline("Use sed for preview/extraction workflows only; perform final file edits with edit/write");
127
132
  }
133
+ if (hasSemanticSearch) {
134
+ addGuideline("Use semantic_search for intent/meaning queries that are hard to express with regex; use rg/ast_grep for exact symbol and syntax matches");
135
+ addGuideline("semantic_search query can auto-refresh stale indexes when semantic auto-index is enabled (default); if disabled or if provider/chunk/filter changes require it, run semantic_search index/rebuild explicitly");
136
+ }
137
+ if (hasRg || hasAstGrep || hasComby) {
138
+ addGuideline("For rg/ast_grep/comby, pass explicit target paths to avoid cwd ambiguity; if syntax errors occur (especially ast_grep), retry once with version-compatible command forms before concluding no matches");
139
+ }
140
+ if (hasBash &&
141
+ (hasRg || hasFd || hasAstGrep || hasComby || hasJq || hasYq || hasSemgrep || hasSed || hasSemanticSearch)) {
142
+ addGuideline("If a required CLI tool is missing, install it first when permitted (rg/fd can be auto-managed; others via brew/apt/pipx/npm), then continue with that tool instead of broad bash fallback. For semantic_search, configure provider/index first via /semantic setup.");
143
+ }
128
144
  // Read before edit guideline
129
145
  if (hasRead && hasEdit) {
130
146
  addGuideline("Use read to examine files before editing. You must use this tool instead of cat or sed.");
@@ -150,6 +166,8 @@ export function buildSystemPrompt(options = {}) {
150
166
  addGuideline("Do not claim success without evidence; if you could not verify, say so explicitly");
151
167
  addGuideline("Complete the requested task end-to-end when possible instead of stopping at analysis");
152
168
  addGuideline("For code review requests, lead with findings and risks before summaries");
169
+ addGuideline("When an active engineering contract is present in context, treat its constraints, quality gates, and definition_of_done as execution requirements unless user overrides them.");
170
+ addGuideline("For major feature forks, run a /singular feasibility pass before coding to compare implementation options.");
153
171
  for (const guideline of promptGuidelines ?? []) {
154
172
  const normalized = guideline.trim();
155
173
  if (normalized.length > 0) {