@codewalla_india/openspec 1.3.1 → 1.3.2

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 (333) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +272 -191
  3. package/bin/openspec.js +5 -5
  4. package/dist/cli/index.js +99 -62
  5. package/dist/commands/change.d.ts +0 -2
  6. package/dist/commands/change.js +107 -86
  7. package/dist/commands/config.js +14 -16
  8. package/dist/commands/doctor.js +9 -4
  9. package/dist/commands/feedback.js +79 -30
  10. package/dist/commands/modify.d.ts +26 -0
  11. package/dist/commands/modify.js +147 -0
  12. package/dist/commands/schema.js +170 -91
  13. package/dist/commands/show.js +5 -2
  14. package/dist/commands/spec.js +49 -29
  15. package/dist/commands/store.js +15 -21
  16. package/dist/commands/validate.d.ts +8 -0
  17. package/dist/commands/validate.js +43 -20
  18. package/dist/commands/workflow/index.d.ts +2 -2
  19. package/dist/commands/workflow/index.js +1 -1
  20. package/dist/commands/workflow/instructions.d.ts +6 -26
  21. package/dist/commands/workflow/instructions.js +183 -376
  22. package/dist/commands/workflow/new-change.d.ts +0 -4
  23. package/dist/commands/workflow/new-change.js +10 -28
  24. package/dist/commands/workflow/shared.d.ts +34 -19
  25. package/dist/commands/workflow/shared.js +34 -4
  26. package/dist/commands/workflow/status.js +10 -32
  27. package/dist/commands/workflow/templates.js +15 -5
  28. package/dist/commands/workset.d.ts +2 -2
  29. package/dist/commands/workset.js +19 -22
  30. package/dist/comprehension-quiz/fingerprint.d.ts +39 -0
  31. package/dist/comprehension-quiz/fingerprint.js +84 -0
  32. package/dist/comprehension-quiz/index.d.ts +42 -0
  33. package/dist/comprehension-quiz/index.js +47 -0
  34. package/dist/comprehension-quiz/pass-record.d.ts +44 -0
  35. package/dist/comprehension-quiz/pass-record.js +98 -0
  36. package/dist/comprehension-quiz/providers/anthropic.d.ts +34 -0
  37. package/dist/comprehension-quiz/providers/anthropic.js +53 -0
  38. package/dist/comprehension-quiz/providers/factory.d.ts +44 -0
  39. package/dist/comprehension-quiz/providers/factory.js +174 -0
  40. package/dist/comprehension-quiz/providers/interface.d.ts +59 -0
  41. package/dist/comprehension-quiz/providers/interface.js +63 -0
  42. package/dist/comprehension-quiz/providers/local.d.ts +34 -0
  43. package/dist/comprehension-quiz/providers/local.js +53 -0
  44. package/dist/comprehension-quiz/providers/ollama.d.ts +34 -0
  45. package/dist/comprehension-quiz/providers/ollama.js +53 -0
  46. package/dist/comprehension-quiz/providers/openai.d.ts +34 -0
  47. package/dist/comprehension-quiz/providers/openai.js +53 -0
  48. package/dist/comprehension-quiz/question-generator.d.ts +69 -0
  49. package/dist/comprehension-quiz/question-generator.js +141 -0
  50. package/dist/comprehension-quiz/quiz-executor.d.ts +70 -0
  51. package/dist/comprehension-quiz/quiz-executor.js +165 -0
  52. package/dist/comprehension-quiz/types.d.ts +115 -0
  53. package/dist/comprehension-quiz/types.js +11 -0
  54. package/dist/core/archive.d.ts +14 -1
  55. package/dist/core/archive.js +1350 -190
  56. package/dist/core/artifact-graph/graph.d.ts +28 -9
  57. package/dist/core/artifact-graph/graph.js +94 -43
  58. package/dist/core/artifact-graph/index.d.ts +1 -1
  59. package/dist/core/artifact-graph/index.js +1 -1
  60. package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
  61. package/dist/core/artifact-graph/instruction-loader.js +70 -12
  62. package/dist/core/artifact-graph/outputs.d.ts +1 -0
  63. package/dist/core/artifact-graph/outputs.js +67 -5
  64. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  65. package/dist/core/artifact-graph/resolver.js +69 -15
  66. package/dist/core/artifact-graph/types.js +21 -3
  67. package/dist/core/available-tools.d.ts +2 -2
  68. package/dist/core/available-tools.js +14 -3
  69. package/dist/core/change-metadata/schema.d.ts +2 -0
  70. package/dist/core/change-metadata/schema.js +13 -0
  71. package/dist/core/change-status-policy.d.ts +10 -1
  72. package/dist/core/change-status-policy.js +30 -2
  73. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  74. package/dist/core/command-generation/adapters/amazon-q.js +11 -5
  75. package/dist/core/command-generation/adapters/antigravity.js +6 -5
  76. package/dist/core/command-generation/adapters/auggie.js +7 -6
  77. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  78. package/dist/core/command-generation/adapters/bob.js +11 -10
  79. package/dist/core/command-generation/adapters/claude.d.ts +1 -1
  80. package/dist/core/command-generation/adapters/claude.js +12 -17
  81. package/dist/core/command-generation/adapters/cline.js +5 -5
  82. package/dist/core/command-generation/adapters/codebuddy.js +8 -7
  83. package/dist/core/command-generation/adapters/continue.js +8 -7
  84. package/dist/core/command-generation/adapters/costrict.js +7 -6
  85. package/dist/core/command-generation/adapters/crush.js +9 -9
  86. package/dist/core/command-generation/adapters/cursor.js +8 -8
  87. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  88. package/dist/core/command-generation/adapters/devin.js +36 -0
  89. package/dist/core/command-generation/adapters/factory.js +7 -6
  90. package/dist/core/command-generation/adapters/gemini.js +40 -5
  91. package/dist/core/command-generation/adapters/github-copilot.js +6 -5
  92. package/dist/core/command-generation/adapters/iflow.js +9 -8
  93. package/dist/core/command-generation/adapters/index.d.ts +4 -2
  94. package/dist/core/command-generation/adapters/index.js +4 -2
  95. package/dist/core/command-generation/adapters/junie.js +6 -5
  96. package/dist/core/command-generation/adapters/kilocode.js +1 -1
  97. package/dist/core/command-generation/adapters/kiro.js +6 -5
  98. package/dist/core/command-generation/adapters/lingma.js +9 -9
  99. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
  100. package/dist/core/command-generation/adapters/oh-my-pi.js +42 -0
  101. package/dist/core/command-generation/adapters/opencode.js +6 -8
  102. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  103. package/dist/core/command-generation/adapters/pi.js +7 -10
  104. package/dist/core/command-generation/adapters/qoder.js +9 -9
  105. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  106. package/dist/core/command-generation/adapters/qwen.js +14 -9
  107. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  108. package/dist/core/command-generation/adapters/roocode.js +9 -9
  109. package/dist/core/command-generation/adapters/trae.d.ts +13 -0
  110. package/dist/core/command-generation/adapters/trae.js +28 -0
  111. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  112. package/dist/core/command-generation/adapters/zcode.js +33 -0
  113. package/dist/core/command-generation/generator.d.ts +8 -0
  114. package/dist/core/command-generation/generator.js +15 -1
  115. package/dist/core/command-generation/index.d.ts +1 -1
  116. package/dist/core/command-generation/index.js +1 -1
  117. package/dist/core/command-generation/invocation.d.ts +73 -0
  118. package/dist/core/command-generation/invocation.js +77 -0
  119. package/dist/core/command-generation/registry.js +8 -4
  120. package/dist/core/command-generation/types.d.ts +9 -2
  121. package/dist/core/command-generation/yaml.d.ts +20 -6
  122. package/dist/core/command-generation/yaml.js +31 -21
  123. package/dist/core/command-surface.d.ts +15 -0
  124. package/dist/core/command-surface.js +33 -0
  125. package/dist/core/completions/command-registry.js +16 -61
  126. package/dist/core/completions/generators/bash-generator.js +41 -41
  127. package/dist/core/completions/generators/fish-generator.js +7 -7
  128. package/dist/core/completions/generators/powershell-generator.js +44 -37
  129. package/dist/core/completions/generators/zsh-generator.js +33 -33
  130. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  131. package/dist/core/completions/installers/zsh-installer.js +20 -4
  132. package/dist/core/completions/templates/bash-templates.js +24 -24
  133. package/dist/core/completions/templates/fish-templates.js +38 -38
  134. package/dist/core/completions/templates/powershell-templates.js +28 -28
  135. package/dist/core/completions/templates/zsh-templates.js +39 -39
  136. package/dist/core/config-prompts.d.ts +1 -1
  137. package/dist/core/config-prompts.js +14 -1
  138. package/dist/core/config-schema.d.ts +10 -1
  139. package/dist/core/config-schema.js +67 -1
  140. package/dist/core/config.d.ts +15 -0
  141. package/dist/core/config.js +46 -5
  142. package/dist/core/file-state.js +56 -24
  143. package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
  144. package/dist/core/github-copilot/cloud-agent.js +497 -0
  145. package/dist/core/global-config.d.ts +16 -0
  146. package/dist/core/init.d.ts +58 -0
  147. package/dist/core/init.js +474 -73
  148. package/dist/core/legacy-cleanup.d.ts +59 -0
  149. package/dist/core/legacy-cleanup.js +253 -24
  150. package/dist/core/list.js +23 -16
  151. package/dist/core/migration.d.ts +73 -1
  152. package/dist/core/migration.js +360 -11
  153. package/dist/core/modify/conflict-detector.d.ts +26 -0
  154. package/dist/core/modify/conflict-detector.js +62 -0
  155. package/dist/core/modify/dependency-propagator.d.ts +38 -0
  156. package/dist/core/modify/dependency-propagator.js +103 -0
  157. package/dist/core/modify/history-tracker.d.ts +34 -0
  158. package/dist/core/modify/history-tracker.js +114 -0
  159. package/dist/core/modify/index.d.ts +7 -0
  160. package/dist/core/modify/index.js +7 -0
  161. package/dist/core/onboarding-commands.d.ts +30 -0
  162. package/dist/core/onboarding-commands.js +38 -0
  163. package/dist/core/openspec-root.js +18 -15
  164. package/dist/core/parsers/change-parser.d.ts +17 -2
  165. package/dist/core/parsers/change-parser.js +35 -21
  166. package/dist/core/parsers/code-fence.d.ts +15 -0
  167. package/dist/core/parsers/code-fence.js +49 -0
  168. package/dist/core/parsers/markdown-parser.d.ts +0 -3
  169. package/dist/core/parsers/markdown-parser.js +7 -60
  170. package/dist/core/parsers/requirement-blocks.d.ts +29 -0
  171. package/dist/core/parsers/requirement-blocks.js +150 -31
  172. package/dist/core/parsers/requirement-text.d.ts +48 -0
  173. package/dist/core/parsers/requirement-text.js +98 -0
  174. package/dist/core/parsers/spec-structure.d.ts +1 -1
  175. package/dist/core/parsers/spec-structure.js +20 -30
  176. package/dist/core/profile-sync-drift.d.ts +0 -8
  177. package/dist/core/profile-sync-drift.js +49 -50
  178. package/dist/core/profiles.d.ts +2 -2
  179. package/dist/core/profiles.js +2 -2
  180. package/dist/core/project-config.d.ts +27 -18
  181. package/dist/core/project-config.js +101 -34
  182. package/dist/core/references.js +42 -4
  183. package/dist/core/relationship-health.d.ts +8 -0
  184. package/dist/core/relationship-health.js +13 -0
  185. package/dist/core/root-selection.d.ts +9 -6
  186. package/dist/core/root-selection.js +42 -5
  187. package/dist/core/schemas/base.schema.js +7 -2
  188. package/dist/core/shared/allowed-tools.d.ts +12 -0
  189. package/dist/core/shared/allowed-tools.js +12 -0
  190. package/dist/core/shared/index.d.ts +1 -0
  191. package/dist/core/shared/index.js +1 -0
  192. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  193. package/dist/core/shared/skill-content-equivalence.js +41 -0
  194. package/dist/core/shared/skill-generation.js +17 -13
  195. package/dist/core/shared/skill-paths.d.ts +13 -0
  196. package/dist/core/shared/skill-paths.js +23 -0
  197. package/dist/core/shared/tool-detection.d.ts +27 -7
  198. package/dist/core/shared/tool-detection.js +167 -37
  199. package/dist/core/shared-skill-target.d.ts +16 -0
  200. package/dist/core/shared-skill-target.js +156 -0
  201. package/dist/core/specs-apply.d.ts +80 -33
  202. package/dist/core/specs-apply.js +667 -145
  203. package/dist/core/store/git.d.ts +13 -0
  204. package/dist/core/store/git.js +24 -0
  205. package/dist/core/store/operations.js +20 -0
  206. package/dist/core/templates/skill-templates.d.ts +3 -2
  207. package/dist/core/templates/skill-templates.js +3 -2
  208. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  209. package/dist/core/templates/workflows/apply-change.js +186 -224
  210. package/dist/core/templates/workflows/archive-change.js +387 -260
  211. package/dist/core/templates/workflows/bulk-archive-change.js +655 -475
  212. package/dist/core/templates/workflows/continue-change.js +210 -219
  213. package/dist/core/templates/workflows/explore.js +479 -443
  214. package/dist/core/templates/workflows/feedback.js +97 -97
  215. package/dist/core/templates/workflows/ff-change.js +200 -191
  216. package/dist/core/templates/workflows/modify-change.d.ts +4 -1
  217. package/dist/core/templates/workflows/modify-change.js +237 -115
  218. package/dist/core/templates/workflows/new-change.js +127 -134
  219. package/dist/core/templates/workflows/onboard.js +548 -542
  220. package/dist/core/templates/workflows/propose.js +273 -217
  221. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  222. package/dist/core/templates/workflows/store-selection.js +1 -1
  223. package/dist/core/templates/workflows/sync-specs.js +500 -273
  224. package/dist/core/templates/workflows/update-change.d.ts +10 -0
  225. package/dist/core/templates/workflows/update-change.js +177 -0
  226. package/dist/core/templates/workflows/verify-change.js +324 -326
  227. package/dist/core/update.d.ts +40 -5
  228. package/dist/core/update.js +411 -96
  229. package/dist/core/validation/constants.d.ts +4 -1
  230. package/dist/core/validation/constants.js +4 -1
  231. package/dist/core/validation/plan-validator.d.ts +8 -0
  232. package/dist/core/validation/plan-validator.js +45 -0
  233. package/dist/core/validation/task-numbering.d.ts +16 -0
  234. package/dist/core/validation/task-numbering.js +57 -0
  235. package/dist/core/validation/validator.d.ts +27 -3
  236. package/dist/core/validation/validator.js +337 -48
  237. package/dist/core/version-check.d.ts +152 -0
  238. package/dist/core/version-check.js +731 -0
  239. package/dist/core/view.js +13 -18
  240. package/dist/prompts/searchable-multi-select.js +1 -1
  241. package/dist/telemetry/caller-detection.d.ts +27 -0
  242. package/dist/telemetry/caller-detection.js +85 -0
  243. package/dist/telemetry/caller-detection.test.d.ts +5 -0
  244. package/dist/telemetry/config.d.ts +48 -2
  245. package/dist/telemetry/config.js +113 -11
  246. package/dist/telemetry/config.test.d.ts +5 -0
  247. package/dist/telemetry/deduplication.d.ts +35 -0
  248. package/dist/telemetry/deduplication.js +82 -0
  249. package/dist/telemetry/deduplication.test.d.ts +5 -0
  250. package/dist/telemetry/identity.d.ts +62 -22
  251. package/dist/telemetry/identity.js +147 -102
  252. package/dist/telemetry/index.d.ts +126 -15
  253. package/dist/telemetry/index.js +569 -37
  254. package/dist/telemetry/sanitization.d.ts +40 -0
  255. package/dist/telemetry/sanitization.js +114 -0
  256. package/dist/telemetry/sanitization.test.d.ts +5 -0
  257. package/dist/telemetry/throttling.d.ts +20 -0
  258. package/dist/telemetry/throttling.js +70 -0
  259. package/dist/ui/welcome-screen.d.ts +9 -1
  260. package/dist/ui/welcome-screen.js +91 -38
  261. package/dist/utils/change-metadata.d.ts +43 -0
  262. package/dist/utils/change-metadata.js +123 -7
  263. package/dist/utils/change-utils.d.ts +10 -4
  264. package/dist/utils/change-utils.js +20 -13
  265. package/dist/utils/ci.d.ts +12 -0
  266. package/dist/utils/ci.js +16 -0
  267. package/dist/utils/command-references.d.ts +92 -6
  268. package/dist/utils/command-references.js +180 -7
  269. package/dist/utils/date.d.ts +8 -0
  270. package/dist/utils/date.js +13 -0
  271. package/dist/utils/file-system.d.ts +10 -0
  272. package/dist/utils/file-system.js +70 -0
  273. package/dist/utils/index.d.ts +1 -1
  274. package/dist/utils/index.js +1 -1
  275. package/dist/utils/interactive.d.ts +23 -0
  276. package/dist/utils/interactive.js +32 -0
  277. package/dist/utils/item-discovery.d.ts +19 -0
  278. package/dist/utils/item-discovery.js +30 -48
  279. package/dist/utils/shell-detection.d.ts +1 -1
  280. package/dist/utils/shell-detection.js +64 -11
  281. package/dist/utils/spec-discovery.d.ts +40 -0
  282. package/dist/utils/spec-discovery.js +115 -0
  283. package/dist/utils/task-progress.d.ts +29 -1
  284. package/dist/utils/task-progress.js +109 -15
  285. package/package.json +96 -84
  286. package/schemas/spec-driven/schema.yaml +252 -184
  287. package/schemas/spec-driven/templates/design.md +19 -19
  288. package/schemas/spec-driven/templates/plan-template.md +91 -0
  289. package/schemas/spec-driven/templates/proposal.md +29 -24
  290. package/schemas/spec-driven/templates/spec.md +11 -8
  291. package/schemas/spec-driven/templates/tasks.md +9 -9
  292. package/scripts/postinstall.js +83 -83
  293. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  294. package/dist/core/command-generation/adapters/codex.js +0 -39
  295. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  296. package/dist/core/command-generation/adapters/windsurf.js +0 -38
  297. package/dist/core/comprehension/config.d.ts +0 -20
  298. package/dist/core/comprehension/config.js +0 -23
  299. package/dist/core/comprehension/fingerprint.d.ts +0 -14
  300. package/dist/core/comprehension/fingerprint.js +0 -33
  301. package/dist/core/comprehension/index.d.ts +0 -57
  302. package/dist/core/comprehension/index.js +0 -87
  303. package/dist/core/comprehension/pass-record.d.ts +0 -29
  304. package/dist/core/comprehension/pass-record.js +0 -64
  305. package/dist/core/comprehension/stats.d.ts +0 -35
  306. package/dist/core/comprehension/stats.js +0 -133
  307. package/dist/core/templates/workflows/comprehension-guidance.d.ts +0 -9
  308. package/dist/core/templates/workflows/comprehension-guidance.js +0 -73
  309. package/dist/core/templates/workflows/mcp-guidance.d.ts +0 -13
  310. package/dist/core/templates/workflows/mcp-guidance.js +0 -131
  311. package/dist/core/templates/workflows/user-prompt-guidance.d.ts +0 -16
  312. package/dist/core/templates/workflows/user-prompt-guidance.js +0 -48
  313. package/dist/telemetry/caller.d.ts +0 -5
  314. package/dist/telemetry/caller.js +0 -29
  315. package/dist/telemetry/client.d.ts +0 -27
  316. package/dist/telemetry/client.js +0 -127
  317. package/dist/telemetry/command-context.d.ts +0 -13
  318. package/dist/telemetry/command-context.js +0 -59
  319. package/dist/telemetry/comprehension.d.ts +0 -44
  320. package/dist/telemetry/comprehension.js +0 -105
  321. package/dist/telemetry/content.d.ts +0 -10
  322. package/dist/telemetry/content.js +0 -56
  323. package/dist/telemetry/git-stats.d.ts +0 -12
  324. package/dist/telemetry/git-stats.js +0 -69
  325. package/dist/telemetry/identify-cache.d.ts +0 -7
  326. package/dist/telemetry/identify-cache.js +0 -47
  327. package/dist/telemetry/input.d.ts +0 -17
  328. package/dist/telemetry/input.js +0 -68
  329. package/dist/telemetry/marker.d.ts +0 -37
  330. package/dist/telemetry/marker.js +0 -67
  331. package/dist/telemetry/workflow.d.ts +0 -85
  332. package/dist/telemetry/workflow.js +0 -318
  333. package/schemas/spec-driven/templates/plan.md +0 -19
@@ -1,17 +0,0 @@
1
- export declare const VALID_EDITORS: readonly ["cursor", "windsurf", "claude"];
2
- export type WorkflowEditor = (typeof VALID_EDITORS)[number];
3
- export declare const MAX_ARTIFACT_BODY_LENGTH = 8000;
4
- export declare function sanitizeTelemetryContent(text: string, maxLength?: number): string;
5
- export declare function sanitizeWorkflowInput(text: string): string;
6
- export declare function readSanitizedFile(filePath: string, maxLength?: number): Promise<string>;
7
- export declare function readWorkflowInputFile(filePath: string): Promise<string>;
8
- export declare function normalizeEditor(value?: string): WorkflowEditor | undefined;
9
- export declare function resolveWorkflowInput(options: {
10
- workflowInput?: string;
11
- workflowInputFile?: string;
12
- }): string | undefined;
13
- export declare function resolveWorkflowInputAsync(options: {
14
- workflowInput?: string;
15
- workflowInputFile?: string;
16
- }): Promise<string | undefined>;
17
- //# sourceMappingURL=input.d.ts.map
@@ -1,68 +0,0 @@
1
- /**
2
- * Workflow input normalization for Codewalla telemetry.
3
- */
4
- import { promises as fs } from 'fs';
5
- export const VALID_EDITORS = ['cursor', 'windsurf', 'claude'];
6
- const MAX_WORKFLOW_INPUT_LENGTH = 2000;
7
- export const MAX_ARTIFACT_BODY_LENGTH = 8000;
8
- const SECRET_PATTERNS = [
9
- /\bsk-[a-zA-Z0-9_-]{8,}\b/g,
10
- /\bghp_[a-zA-Z0-9]{20,}\b/g,
11
- /Bearer\s+[a-zA-Z0-9._-]+/gi,
12
- ];
13
- function redactSecrets(text) {
14
- let sanitized = text.trim();
15
- for (const pattern of SECRET_PATTERNS) {
16
- sanitized = sanitized.replace(pattern, '[redacted]');
17
- }
18
- return sanitized;
19
- }
20
- export function sanitizeTelemetryContent(text, maxLength = MAX_WORKFLOW_INPUT_LENGTH) {
21
- const sanitized = redactSecrets(text);
22
- if (sanitized.length > maxLength) {
23
- return sanitized.slice(0, maxLength);
24
- }
25
- return sanitized;
26
- }
27
- export function sanitizeWorkflowInput(text) {
28
- return sanitizeTelemetryContent(text, MAX_WORKFLOW_INPUT_LENGTH);
29
- }
30
- export async function readSanitizedFile(filePath, maxLength = MAX_ARTIFACT_BODY_LENGTH) {
31
- const content = await fs.readFile(filePath, 'utf-8');
32
- return sanitizeTelemetryContent(content, maxLength);
33
- }
34
- export async function readWorkflowInputFile(filePath) {
35
- const content = await fs.readFile(filePath, 'utf-8');
36
- return sanitizeWorkflowInput(content);
37
- }
38
- export function normalizeEditor(value) {
39
- if (!value) {
40
- return undefined;
41
- }
42
- const normalized = value.trim().toLowerCase();
43
- if (VALID_EDITORS.includes(normalized)) {
44
- return normalized;
45
- }
46
- throw new Error(`Invalid --editor "${value}". Use: ${VALID_EDITORS.join(', ')}.`);
47
- }
48
- export function resolveWorkflowInput(options) {
49
- if (options.workflowInput !== undefined && options.workflowInputFile !== undefined) {
50
- throw new Error('Pass only one of --workflow-input or --workflow-input-file.');
51
- }
52
- if (options.workflowInput !== undefined) {
53
- const sanitized = sanitizeWorkflowInput(options.workflowInput);
54
- return sanitized.length > 0 ? sanitized : undefined;
55
- }
56
- return undefined;
57
- }
58
- export async function resolveWorkflowInputAsync(options) {
59
- if (options.workflowInput !== undefined && options.workflowInputFile !== undefined) {
60
- throw new Error('Pass only one of --workflow-input or --workflow-input-file.');
61
- }
62
- if (options.workflowInputFile !== undefined) {
63
- const sanitized = await readWorkflowInputFile(options.workflowInputFile);
64
- return sanitized.length > 0 ? sanitized : undefined;
65
- }
66
- return resolveWorkflowInput(options);
67
- }
68
- //# sourceMappingURL=input.js.map
@@ -1,37 +0,0 @@
1
- export declare const CHANGE_TELEMETRY_FILENAME = ".openspec-telemetry.yaml";
2
- export type EntryPoint = 'propose' | 'new' | 'ff' | 'manual';
3
- export interface ModifyHistoryEntry {
4
- at: string;
5
- source_artifact: string;
6
- modify_input?: string;
7
- }
8
- export interface ChangeTelemetryMarker {
9
- started_at?: string;
10
- entry_point?: EntryPoint;
11
- workflow_input?: string;
12
- editor?: string;
13
- git_head_at_start?: string;
14
- proposal_ready_at?: string;
15
- proposal_ready_emitted?: boolean;
16
- apply_ready_emitted?: boolean;
17
- artifact_hashes?: Record<string, string>;
18
- artifact_body_cache?: Record<string, string>;
19
- revision_counts?: Record<string, number>;
20
- modify_history?: ModifyHistoryEntry[];
21
- comprehension_attempt_count?: number;
22
- comprehension_failure_count?: number;
23
- comprehension_gate_last_emitted?: {
24
- passed: boolean;
25
- best_score_percent?: number;
26
- };
27
- }
28
- export declare function markerPath(changeDir: string): string;
29
- export declare function readMarker(changeDir: string): Promise<ChangeTelemetryMarker>;
30
- export declare function writeMarker(changeDir: string, marker: ChangeTelemetryMarker): Promise<void>;
31
- export declare function updateMarker(changeDir: string, update: (current: ChangeTelemetryMarker) => ChangeTelemetryMarker): Promise<ChangeTelemetryMarker>;
32
- export declare function hashFileContent(content: string): string;
33
- export declare function hashFileAt(filePath: string): Promise<string | null>;
34
- export declare function durationSince(isoStart: string | undefined): number | undefined;
35
- export declare function durationBetween(isoStart: string | undefined, isoEnd: string | undefined): number | undefined;
36
- export declare function totalRevisions(marker: ChangeTelemetryMarker): number;
37
- //# sourceMappingURL=marker.d.ts.map
@@ -1,67 +0,0 @@
1
- /**
2
- * Change-local telemetry marker (.openspec-telemetry.yaml) for dedupe and durations.
3
- */
4
- import { createHash } from 'crypto';
5
- import { promises as fs } from 'fs';
6
- import path from 'path';
7
- import { parse, stringify } from 'yaml';
8
- export const CHANGE_TELEMETRY_FILENAME = '.openspec-telemetry.yaml';
9
- export function markerPath(changeDir) {
10
- return path.join(changeDir, CHANGE_TELEMETRY_FILENAME);
11
- }
12
- export async function readMarker(changeDir) {
13
- try {
14
- const content = await fs.readFile(markerPath(changeDir), 'utf-8');
15
- return parse(content) ?? {};
16
- }
17
- catch {
18
- return {};
19
- }
20
- }
21
- export async function writeMarker(changeDir, marker) {
22
- await fs.writeFile(markerPath(changeDir), stringify(marker), 'utf-8');
23
- }
24
- export async function updateMarker(changeDir, update) {
25
- const current = await readMarker(changeDir);
26
- const next = update(current);
27
- await writeMarker(changeDir, next);
28
- return next;
29
- }
30
- export function hashFileContent(content) {
31
- return createHash('sha256').update(content).digest('hex').slice(0, 16);
32
- }
33
- export async function hashFileAt(filePath) {
34
- try {
35
- const content = await fs.readFile(filePath, 'utf-8');
36
- return hashFileContent(content);
37
- }
38
- catch {
39
- return null;
40
- }
41
- }
42
- export function durationSince(isoStart) {
43
- if (!isoStart) {
44
- return undefined;
45
- }
46
- const start = Date.parse(isoStart);
47
- if (Number.isNaN(start)) {
48
- return undefined;
49
- }
50
- return Date.now() - start;
51
- }
52
- export function durationBetween(isoStart, isoEnd) {
53
- if (!isoStart || !isoEnd) {
54
- return undefined;
55
- }
56
- const start = Date.parse(isoStart);
57
- const end = Date.parse(isoEnd);
58
- if (Number.isNaN(start) || Number.isNaN(end)) {
59
- return undefined;
60
- }
61
- return end - start;
62
- }
63
- export function totalRevisions(marker) {
64
- const counts = marker.revision_counts ?? {};
65
- return Object.values(counts).reduce((sum, n) => sum + (n ?? 0), 0);
66
- }
67
- //# sourceMappingURL=marker.js.map
@@ -1,85 +0,0 @@
1
- import { type ChangeTelemetryMarker, type EntryPoint } from './marker.js';
2
- export declare function trackWorkflowStarted(params: {
3
- changeDir: string;
4
- changeName: string;
5
- schema: string;
6
- entryPoint: EntryPoint;
7
- storeSelected: boolean;
8
- projectRoot: string;
9
- workflowInput?: string;
10
- description?: string;
11
- goal?: string;
12
- editor?: string;
13
- }): Promise<void>;
14
- export declare function maybeEmitProposalReady(params: {
15
- changeDir: string;
16
- changeName: string;
17
- schema: string;
18
- missingArtifacts: string[];
19
- artifactCount: number;
20
- contextFiles?: Record<string, string[]>;
21
- }): Promise<void>;
22
- export declare function maybeEmitApplyReady(params: {
23
- changeDir: string;
24
- changeName: string;
25
- state: string;
26
- contextFiles?: Record<string, string[]>;
27
- }): Promise<boolean>;
28
- export declare function trackArtifactInstructions(params: {
29
- changeDir: string;
30
- changeName: string;
31
- artifactId: string;
32
- artifactWasDone: boolean;
33
- artifactPaths?: string[];
34
- }): Promise<void>;
35
- export declare function trackArtifactModifyRequested(params: {
36
- changeDir: string;
37
- changeName: string;
38
- schema: string;
39
- sourceArtifactId: string;
40
- downstreamArtifactIds: string[];
41
- artifactsToUpdate: string[];
42
- modifyInput?: string;
43
- editor?: string;
44
- }): Promise<void>;
45
- export declare function trackArtifactContentChanges(params: {
46
- changeDir: string;
47
- changeName: string;
48
- contextFiles: Record<string, string[]>;
49
- }): Promise<void>;
50
- interface SpecDeltaInfo {
51
- capability: string;
52
- counts: {
53
- added: number;
54
- modified: number;
55
- removed: number;
56
- renamed: number;
57
- };
58
- deltaSpecLinesChanged?: number;
59
- }
60
- export declare function trackChangeArchived(params: {
61
- changeDir: string;
62
- changeName: string;
63
- schema: string;
64
- specsUpdated: boolean;
65
- totals?: {
66
- added: number;
67
- modified: number;
68
- removed: number;
69
- renamed: number;
70
- };
71
- tasksComplete: boolean;
72
- specDeltas: SpecDeltaInfo[];
73
- projectRoot: string;
74
- }): Promise<void>;
75
- export declare function buildSpecDeltasFromUpdates(specUpdates: Array<{
76
- source: string;
77
- counts: {
78
- added: number;
79
- modified: number;
80
- removed: number;
81
- renamed: number;
82
- };
83
- }>): Promise<SpecDeltaInfo[]>;
84
- export type { ChangeTelemetryMarker, EntryPoint };
85
- //# sourceMappingURL=workflow.d.ts.map
@@ -1,318 +0,0 @@
1
- /**
2
- * Workflow lifecycle telemetry — propose → archive funnel and artifact revisions.
3
- */
4
- import { promises as fs } from 'fs';
5
- import path from 'path';
6
- import { captureGitHead } from './git-stats.js';
7
- import { durationBetween, durationSince, hashFileAt, readMarker, totalRevisions, updateMarker, } from './marker.js';
8
- import { captureEvent } from './client.js';
9
- import { enrichFromMarker } from './comprehension.js';
10
- import { collectArtifactPathsMap, readPrimaryArtifactBody, readSanitizedFileAt, toChangeRelativePaths, } from './content.js';
11
- import { sanitizeWorkflowInput } from './input.js';
12
- const TRACKED_ARTIFACT_IDS = ['proposal', 'design', 'plan', 'tasks', 'specs'];
13
- export async function trackWorkflowStarted(params) {
14
- const gitHead = await captureGitHead(params.projectRoot);
15
- const startedAt = new Date().toISOString();
16
- const workflowInput = params.workflowInput
17
- ? sanitizeWorkflowInput(params.workflowInput)
18
- : undefined;
19
- const description = params.description
20
- ? sanitizeWorkflowInput(params.description)
21
- : undefined;
22
- const goal = params.goal ? sanitizeWorkflowInput(params.goal) : undefined;
23
- await updateMarker(params.changeDir, (current) => ({
24
- ...current,
25
- started_at: startedAt,
26
- entry_point: params.entryPoint,
27
- ...(workflowInput ? { workflow_input: workflowInput } : {}),
28
- ...(params.editor ? { editor: params.editor } : {}),
29
- ...(gitHead ? { git_head_at_start: gitHead } : {}),
30
- }));
31
- await captureEvent('workflow_started', {
32
- change_name: params.changeName,
33
- schema: params.schema,
34
- entry_point: params.entryPoint,
35
- store_selected: params.storeSelected,
36
- ...(workflowInput ? { workflow_input: workflowInput } : {}),
37
- ...(description ? { description } : {}),
38
- ...(goal ? { goal } : {}),
39
- ...(params.editor ? { editor: params.editor } : {}),
40
- });
41
- }
42
- async function buildArtifactPathsSummary(changeDir, contextFiles) {
43
- const paths = await collectArtifactPathsMap(changeDir, contextFiles);
44
- return Object.keys(paths).length > 0 ? paths : undefined;
45
- }
46
- export async function maybeEmitProposalReady(params) {
47
- if (params.missingArtifacts.length > 0) {
48
- return;
49
- }
50
- const marker = await readMarker(params.changeDir);
51
- if (marker.proposal_ready_emitted) {
52
- return;
53
- }
54
- const proposalReadyAt = new Date().toISOString();
55
- await updateMarker(params.changeDir, (current) => ({
56
- ...current,
57
- proposal_ready_at: proposalReadyAt,
58
- proposal_ready_emitted: true,
59
- }));
60
- const artifactPaths = params.contextFiles
61
- ? await buildArtifactPathsSummary(params.changeDir, params.contextFiles)
62
- : undefined;
63
- const props = await enrichFromMarker(params.changeDir, {
64
- change_name: params.changeName,
65
- schema: params.schema,
66
- artifact_count: params.artifactCount,
67
- duration_since_start_ms: durationSince(marker.started_at),
68
- ...(artifactPaths ? { artifact_paths: artifactPaths } : {}),
69
- });
70
- await captureEvent('change_proposal_ready', props);
71
- }
72
- export async function maybeEmitApplyReady(params) {
73
- if (params.state !== 'ready') {
74
- return false;
75
- }
76
- const marker = await readMarker(params.changeDir);
77
- if (marker.apply_ready_emitted) {
78
- return false;
79
- }
80
- await updateMarker(params.changeDir, (current) => ({
81
- ...current,
82
- apply_ready_emitted: true,
83
- }));
84
- const artifactPaths = params.contextFiles
85
- ? await buildArtifactPathsSummary(params.changeDir, params.contextFiles)
86
- : undefined;
87
- const props = await enrichFromMarker(params.changeDir, {
88
- change_name: params.changeName,
89
- duration_since_start_ms: durationSince(marker.started_at),
90
- ...(artifactPaths ? { artifact_paths: artifactPaths } : {}),
91
- });
92
- await captureEvent('apply_ready', props);
93
- return true;
94
- }
95
- export async function trackArtifactInstructions(params) {
96
- const relativePaths = params.artifactPaths && params.artifactPaths.length > 0
97
- ? toChangeRelativePaths(params.changeDir, params.artifactPaths)
98
- : undefined;
99
- const artifactBody = params.artifactPaths && params.artifactPaths.length > 0
100
- ? await readPrimaryArtifactBody(params.changeDir, params.artifactPaths)
101
- : undefined;
102
- const props = await enrichFromMarker(params.changeDir, {
103
- change_name: params.changeName,
104
- artifact_id: params.artifactId,
105
- artifact_was_done: params.artifactWasDone,
106
- ...(relativePaths ? { artifact_paths: relativePaths } : {}),
107
- ...(artifactBody ? { artifact_body: artifactBody } : {}),
108
- });
109
- await captureEvent('artifact_instructions_requested', props);
110
- if (!params.artifactWasDone) {
111
- return;
112
- }
113
- const marker = await updateMarker(params.changeDir, (current) => {
114
- const revisionCounts = { ...(current.revision_counts ?? {}) };
115
- const next = (revisionCounts[params.artifactId] ?? 0) + 1;
116
- revisionCounts[params.artifactId] = next;
117
- return { ...current, revision_counts: revisionCounts };
118
- });
119
- const revisionNumber = marker.revision_counts?.[params.artifactId] ?? 1;
120
- const revisionProps = await enrichFromMarker(params.changeDir, {
121
- change_name: params.changeName,
122
- artifact_id: params.artifactId,
123
- revision_number: revisionNumber,
124
- });
125
- await captureEvent('artifact_revision_requested', revisionProps);
126
- }
127
- export async function trackArtifactModifyRequested(params) {
128
- const modifyInput = params.modifyInput
129
- ? sanitizeWorkflowInput(params.modifyInput)
130
- : undefined;
131
- const now = new Date().toISOString();
132
- await updateMarker(params.changeDir, (current) => ({
133
- ...current,
134
- modify_history: [
135
- ...(current.modify_history ?? []),
136
- {
137
- at: now,
138
- source_artifact: params.sourceArtifactId,
139
- ...(modifyInput ? { modify_input: modifyInput } : {}),
140
- },
141
- ],
142
- }));
143
- const props = await enrichFromMarker(params.changeDir, {
144
- change_name: params.changeName,
145
- schema: params.schema,
146
- source_artifact_id: params.sourceArtifactId,
147
- downstream_artifact_ids: params.downstreamArtifactIds,
148
- artifacts_to_update: params.artifactsToUpdate,
149
- phase: 'pre_apply',
150
- ...(modifyInput ? { modify_input: modifyInput } : {}),
151
- ...(params.editor ? { editor: params.editor } : {}),
152
- });
153
- await captureEvent('artifact_modify_requested', props);
154
- }
155
- async function hashArtifactFiles(changeDir, contextFiles) {
156
- const hashes = {};
157
- for (const artifactId of TRACKED_ARTIFACT_IDS) {
158
- const paths = contextFiles[artifactId];
159
- if (!paths?.length) {
160
- continue;
161
- }
162
- const parts = [];
163
- for (const filePath of paths) {
164
- const hash = await hashFileAt(filePath);
165
- if (hash) {
166
- parts.push(hash);
167
- }
168
- }
169
- if (parts.length > 0) {
170
- hashes[artifactId] = parts.join(':');
171
- }
172
- }
173
- return hashes;
174
- }
175
- async function refreshArtifactBodyCache(changeDir, contextFiles) {
176
- const cache = {};
177
- for (const artifactId of TRACKED_ARTIFACT_IDS) {
178
- const paths = contextFiles[artifactId];
179
- if (!paths?.length) {
180
- continue;
181
- }
182
- const body = await readPrimaryArtifactBody(changeDir, paths);
183
- if (body) {
184
- cache[artifactId] = body;
185
- }
186
- }
187
- return cache;
188
- }
189
- export async function trackArtifactContentChanges(params) {
190
- const currentHashes = await hashArtifactFiles(params.changeDir, params.contextFiles);
191
- if (Object.keys(currentHashes).length === 0) {
192
- return;
193
- }
194
- const marker = await readMarker(params.changeDir);
195
- const previousHashes = marker.artifact_hashes ?? {};
196
- const previousBodies = marker.artifact_body_cache ?? {};
197
- for (const [artifactId, hash] of Object.entries(currentHashes)) {
198
- const previous = previousHashes[artifactId];
199
- if (previous && previous !== hash) {
200
- const paths = params.contextFiles[artifactId] ?? [];
201
- const bodyAfter = paths[0] ? await readSanitizedFileAt(paths[0]) : undefined;
202
- const bodyBefore = previousBodies[artifactId];
203
- const updated = await updateMarker(params.changeDir, (current) => {
204
- const revisionCounts = { ...(current.revision_counts ?? {}) };
205
- revisionCounts[artifactId] = (revisionCounts[artifactId] ?? 0) + 1;
206
- return { ...current, revision_counts: revisionCounts };
207
- });
208
- const changeProps = await enrichFromMarker(params.changeDir, {
209
- change_name: params.changeName,
210
- artifact_id: artifactId,
211
- change_count: updated.revision_counts?.[artifactId] ?? 1,
212
- artifact_paths: toChangeRelativePaths(params.changeDir, paths),
213
- ...(bodyBefore ? { body_before: bodyBefore } : {}),
214
- ...(bodyAfter ? { body_after: bodyAfter } : {}),
215
- });
216
- await captureEvent('artifact_content_changed', changeProps);
217
- }
218
- }
219
- const bodyCache = await refreshArtifactBodyCache(params.changeDir, params.contextFiles);
220
- await updateMarker(params.changeDir, (current) => ({
221
- ...current,
222
- artifact_hashes: { ...(current.artifact_hashes ?? {}), ...currentHashes },
223
- artifact_body_cache: { ...(current.artifact_body_cache ?? {}), ...bodyCache },
224
- }));
225
- }
226
- async function countDeltaSpecLines(filePath) {
227
- try {
228
- const content = await fs.readFile(filePath, 'utf-8');
229
- return content.split('\n').length;
230
- }
231
- catch {
232
- return undefined;
233
- }
234
- }
235
- export async function trackChangeArchived(params) {
236
- const marker = await readMarker(params.changeDir);
237
- const now = new Date().toISOString();
238
- for (const delta of params.specDeltas) {
239
- await captureEvent('spec_delta_applied', {
240
- change_name: params.changeName,
241
- capability: delta.capability,
242
- requirements_added: delta.counts.added,
243
- requirements_modified: delta.counts.modified,
244
- requirements_removed: delta.counts.removed,
245
- requirements_renamed: delta.counts.renamed,
246
- });
247
- if (delta.deltaSpecLinesChanged !== undefined) {
248
- await captureEvent('spec_delta_lines_changed', {
249
- change_name: params.changeName,
250
- capability: delta.capability,
251
- lines_added: delta.deltaSpecLinesChanged,
252
- lines_removed: 0,
253
- });
254
- }
255
- }
256
- let implementation;
257
- if (marker.git_head_at_start) {
258
- const { diffStatsSince } = await import('./git-stats.js');
259
- const stats = await diffStatsSince(marker.git_head_at_start, params.projectRoot);
260
- if (stats) {
261
- implementation = stats;
262
- await captureEvent('implementation_changed', {
263
- change_name: params.changeName,
264
- files_changed: stats.files_changed,
265
- lines_added: stats.lines_added,
266
- lines_removed: stats.lines_removed,
267
- lines_changed: stats.lines_changed,
268
- spec_capabilities_count: params.specDeltas.length,
269
- });
270
- }
271
- }
272
- const specsSummary = params.specDeltas.map((d) => ({
273
- capability: d.capability,
274
- requirements_added: d.counts.added,
275
- requirements_modified: d.counts.modified,
276
- requirements_removed: d.counts.removed,
277
- requirements_renamed: d.counts.renamed,
278
- delta_spec_lines_changed: d.deltaSpecLinesChanged,
279
- }));
280
- await captureEvent('change_archived', {
281
- change_name: params.changeName,
282
- schema: params.schema,
283
- specs_updated: params.specsUpdated,
284
- tasks_complete: params.tasksComplete,
285
- entry_point: marker.entry_point ?? 'manual',
286
- ...(marker.workflow_input ? { workflow_input: marker.workflow_input } : {}),
287
- ...(marker.editor ? { editor: marker.editor } : {}),
288
- duration_since_start_ms: durationSince(marker.started_at),
289
- duration_proposal_to_ready_ms: durationBetween(marker.started_at, marker.proposal_ready_at),
290
- duration_ready_to_archive_ms: durationBetween(marker.proposal_ready_at, now),
291
- total_revisions: totalRevisions(marker),
292
- revision_counts: marker.revision_counts ?? {},
293
- specs: specsSummary,
294
- ...(implementation ? { implementation } : {}),
295
- ...(params.totals
296
- ? {
297
- requirements_added: params.totals.added,
298
- requirements_modified: params.totals.modified,
299
- requirements_removed: params.totals.removed,
300
- requirements_renamed: params.totals.renamed,
301
- }
302
- : {}),
303
- });
304
- }
305
- export async function buildSpecDeltasFromUpdates(specUpdates) {
306
- const deltas = [];
307
- for (const update of specUpdates) {
308
- const capability = path.basename(path.dirname(update.source));
309
- const deltaSpecLinesChanged = await countDeltaSpecLines(update.source);
310
- deltas.push({
311
- capability,
312
- counts: update.counts,
313
- deltaSpecLinesChanged,
314
- });
315
- }
316
- return deltas;
317
- }
318
- //# sourceMappingURL=workflow.js.map
@@ -1,19 +0,0 @@
1
- ## Code Map
2
-
3
- <!-- files to create/modify/delete -->
4
-
5
- ## Implementation Order
6
-
7
- <!-- sequenced steps at file/module level -->
8
-
9
- ## Test Plan
10
-
11
- <!-- how to verify -->
12
-
13
- ## Risks
14
-
15
- <!-- [Risk] → Mitigation -->
16
-
17
- ## Done Definition
18
-
19
- <!-- objective completion criteria -->