@bastani/atomic 0.6.8 → 0.7.0-1

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 (765) hide show
  1. package/bin/atomic +65 -0
  2. package/package.json +17 -82
  3. package/postinstall.mjs +47 -0
  4. package/.agents/skills/ado-commit/SKILL.md +0 -94
  5. package/.agents/skills/ado-create-pr/SKILL.md +0 -211
  6. package/.agents/skills/advanced-evaluation/SKILL.md +0 -404
  7. package/.agents/skills/advanced-evaluation/references/bias-mitigation.md +0 -288
  8. package/.agents/skills/advanced-evaluation/references/evaluation-pipeline.md +0 -43
  9. package/.agents/skills/advanced-evaluation/references/implementation-patterns.md +0 -315
  10. package/.agents/skills/advanced-evaluation/references/metrics-guide.md +0 -331
  11. package/.agents/skills/advanced-evaluation/scripts/evaluation_example.py +0 -392
  12. package/.agents/skills/ast-grep/SKILL.md +0 -325
  13. package/.agents/skills/ast-grep/references/rule_reference.md +0 -297
  14. package/.agents/skills/bdi-mental-states/SKILL.md +0 -313
  15. package/.agents/skills/bdi-mental-states/references/bdi-ontology-core.md +0 -207
  16. package/.agents/skills/bdi-mental-states/references/framework-integration.md +0 -582
  17. package/.agents/skills/bdi-mental-states/references/rdf-examples.md +0 -315
  18. package/.agents/skills/bdi-mental-states/references/sparql-competency.md +0 -420
  19. package/.agents/skills/bun/SKILL.md +0 -233
  20. package/.agents/skills/context-compression/SKILL.md +0 -274
  21. package/.agents/skills/context-compression/references/evaluation-framework.md +0 -213
  22. package/.agents/skills/context-compression/scripts/compression_evaluator.py +0 -862
  23. package/.agents/skills/context-compression/tests/test_compression_evaluator.py +0 -56
  24. package/.agents/skills/context-degradation/SKILL.md +0 -208
  25. package/.agents/skills/context-degradation/references/patterns.md +0 -314
  26. package/.agents/skills/context-degradation/scripts/degradation_detector.py +0 -614
  27. package/.agents/skills/context-fundamentals/SKILL.md +0 -203
  28. package/.agents/skills/context-fundamentals/references/context-components.md +0 -283
  29. package/.agents/skills/context-fundamentals/scripts/context_manager.py +0 -533
  30. package/.agents/skills/context-optimization/SKILL.md +0 -197
  31. package/.agents/skills/context-optimization/references/optimization_techniques.md +0 -272
  32. package/.agents/skills/context-optimization/scripts/compaction.py +0 -562
  33. package/.agents/skills/create-spec/SKILL.md +0 -249
  34. package/.agents/skills/docx/LICENSE.txt +0 -30
  35. package/.agents/skills/docx/SKILL.md +0 -592
  36. package/.agents/skills/docx/scripts/__init__.py +0 -1
  37. package/.agents/skills/docx/scripts/accept_changes.py +0 -135
  38. package/.agents/skills/docx/scripts/comment.py +0 -318
  39. package/.agents/skills/docx/scripts/office/helpers/__init__.py +0 -0
  40. package/.agents/skills/docx/scripts/office/helpers/merge_runs.py +0 -199
  41. package/.agents/skills/docx/scripts/office/helpers/simplify_redlines.py +0 -197
  42. package/.agents/skills/docx/scripts/office/pack.py +0 -159
  43. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  44. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  45. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  46. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  47. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  48. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  49. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  50. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  51. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  52. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  53. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  54. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  55. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  56. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  57. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  58. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  59. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  60. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  61. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  62. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  63. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  64. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  65. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  66. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  67. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  68. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  69. package/.agents/skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  70. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  71. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  72. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  73. package/.agents/skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  74. package/.agents/skills/docx/scripts/office/schemas/mce/mc.xsd +0 -75
  75. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  76. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  77. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  78. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  79. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  80. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  81. package/.agents/skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  82. package/.agents/skills/docx/scripts/office/soffice.py +0 -183
  83. package/.agents/skills/docx/scripts/office/unpack.py +0 -132
  84. package/.agents/skills/docx/scripts/office/validate.py +0 -111
  85. package/.agents/skills/docx/scripts/office/validators/__init__.py +0 -15
  86. package/.agents/skills/docx/scripts/office/validators/base.py +0 -847
  87. package/.agents/skills/docx/scripts/office/validators/docx.py +0 -446
  88. package/.agents/skills/docx/scripts/office/validators/pptx.py +0 -275
  89. package/.agents/skills/docx/scripts/office/validators/redlining.py +0 -247
  90. package/.agents/skills/docx/scripts/templates/comments.xml +0 -3
  91. package/.agents/skills/docx/scripts/templates/commentsExtended.xml +0 -3
  92. package/.agents/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
  93. package/.agents/skills/docx/scripts/templates/commentsIds.xml +0 -3
  94. package/.agents/skills/docx/scripts/templates/people.xml +0 -3
  95. package/.agents/skills/evaluation/SKILL.md +0 -253
  96. package/.agents/skills/evaluation/references/metrics.md +0 -339
  97. package/.agents/skills/evaluation/scripts/evaluator.py +0 -627
  98. package/.agents/skills/explain-code/SKILL.md +0 -232
  99. package/.agents/skills/filesystem-context/SKILL.md +0 -289
  100. package/.agents/skills/filesystem-context/references/implementation-patterns.md +0 -549
  101. package/.agents/skills/filesystem-context/scripts/filesystem_context.py +0 -425
  102. package/.agents/skills/find-skills/SKILL.md +0 -144
  103. package/.agents/skills/gh-commit/SKILL.md +0 -245
  104. package/.agents/skills/gh-create-pr/SKILL.md +0 -95
  105. package/.agents/skills/hosted-agents/SKILL.md +0 -262
  106. package/.agents/skills/hosted-agents/references/infrastructure-patterns.md +0 -700
  107. package/.agents/skills/hosted-agents/scripts/sandbox_manager.py +0 -590
  108. package/.agents/skills/impeccable/SKILL.md +0 -178
  109. package/.agents/skills/impeccable/agents/openai.yaml +0 -4
  110. package/.agents/skills/impeccable/reference/adapt.md +0 -190
  111. package/.agents/skills/impeccable/reference/animate.md +0 -175
  112. package/.agents/skills/impeccable/reference/audit.md +0 -134
  113. package/.agents/skills/impeccable/reference/bolder.md +0 -113
  114. package/.agents/skills/impeccable/reference/brand.md +0 -114
  115. package/.agents/skills/impeccable/reference/clarify.md +0 -174
  116. package/.agents/skills/impeccable/reference/cognitive-load.md +0 -106
  117. package/.agents/skills/impeccable/reference/color-and-contrast.md +0 -105
  118. package/.agents/skills/impeccable/reference/colorize.md +0 -154
  119. package/.agents/skills/impeccable/reference/craft.md +0 -193
  120. package/.agents/skills/impeccable/reference/critique.md +0 -213
  121. package/.agents/skills/impeccable/reference/delight.md +0 -302
  122. package/.agents/skills/impeccable/reference/distill.md +0 -111
  123. package/.agents/skills/impeccable/reference/document.md +0 -427
  124. package/.agents/skills/impeccable/reference/extract.md +0 -70
  125. package/.agents/skills/impeccable/reference/harden.md +0 -347
  126. package/.agents/skills/impeccable/reference/heuristics-scoring.md +0 -234
  127. package/.agents/skills/impeccable/reference/interaction-design.md +0 -195
  128. package/.agents/skills/impeccable/reference/layout.md +0 -141
  129. package/.agents/skills/impeccable/reference/live.md +0 -594
  130. package/.agents/skills/impeccable/reference/motion-design.md +0 -109
  131. package/.agents/skills/impeccable/reference/onboard.md +0 -234
  132. package/.agents/skills/impeccable/reference/optimize.md +0 -258
  133. package/.agents/skills/impeccable/reference/overdrive.md +0 -130
  134. package/.agents/skills/impeccable/reference/personas.md +0 -178
  135. package/.agents/skills/impeccable/reference/polish.md +0 -232
  136. package/.agents/skills/impeccable/reference/product.md +0 -62
  137. package/.agents/skills/impeccable/reference/quieter.md +0 -99
  138. package/.agents/skills/impeccable/reference/responsive-design.md +0 -114
  139. package/.agents/skills/impeccable/reference/shape.md +0 -151
  140. package/.agents/skills/impeccable/reference/spatial-design.md +0 -100
  141. package/.agents/skills/impeccable/reference/teach.md +0 -156
  142. package/.agents/skills/impeccable/reference/typeset.md +0 -124
  143. package/.agents/skills/impeccable/reference/typography.md +0 -159
  144. package/.agents/skills/impeccable/reference/ux-writing.md +0 -107
  145. package/.agents/skills/impeccable/scripts/cleanup-deprecated.mjs +0 -284
  146. package/.agents/skills/impeccable/scripts/command-metadata.json +0 -94
  147. package/.agents/skills/impeccable/scripts/design-parser.mjs +0 -820
  148. package/.agents/skills/impeccable/scripts/detect-csp.mjs +0 -198
  149. package/.agents/skills/impeccable/scripts/is-generated.mjs +0 -69
  150. package/.agents/skills/impeccable/scripts/live-accept.mjs +0 -595
  151. package/.agents/skills/impeccable/scripts/live-browser.js +0 -4781
  152. package/.agents/skills/impeccable/scripts/live-inject.mjs +0 -445
  153. package/.agents/skills/impeccable/scripts/live-poll.mjs +0 -186
  154. package/.agents/skills/impeccable/scripts/live-server.mjs +0 -694
  155. package/.agents/skills/impeccable/scripts/live-wrap.mjs +0 -571
  156. package/.agents/skills/impeccable/scripts/live.mjs +0 -247
  157. package/.agents/skills/impeccable/scripts/load-context.mjs +0 -141
  158. package/.agents/skills/impeccable/scripts/modern-screenshot.umd.js +0 -14
  159. package/.agents/skills/impeccable/scripts/pin.mjs +0 -214
  160. package/.agents/skills/init/SKILL.md +0 -140
  161. package/.agents/skills/liteparse/SKILL.md +0 -223
  162. package/.agents/skills/memory-systems/SKILL.md +0 -221
  163. package/.agents/skills/memory-systems/references/implementation.md +0 -551
  164. package/.agents/skills/memory-systems/scripts/memory_store.py +0 -616
  165. package/.agents/skills/multi-agent-patterns/SKILL.md +0 -259
  166. package/.agents/skills/multi-agent-patterns/references/frameworks.md +0 -433
  167. package/.agents/skills/multi-agent-patterns/scripts/coordination.py +0 -613
  168. package/.agents/skills/opentui/SKILL.md +0 -202
  169. package/.agents/skills/opentui/references/animation/REFERENCE.md +0 -431
  170. package/.agents/skills/opentui/references/components/REFERENCE.md +0 -144
  171. package/.agents/skills/opentui/references/components/code-diff.md +0 -672
  172. package/.agents/skills/opentui/references/components/containers.md +0 -417
  173. package/.agents/skills/opentui/references/components/inputs.md +0 -531
  174. package/.agents/skills/opentui/references/components/text-display.md +0 -386
  175. package/.agents/skills/opentui/references/core/REFERENCE.md +0 -145
  176. package/.agents/skills/opentui/references/core/api.md +0 -543
  177. package/.agents/skills/opentui/references/core/configuration.md +0 -168
  178. package/.agents/skills/opentui/references/core/gotchas.md +0 -393
  179. package/.agents/skills/opentui/references/core/patterns.md +0 -449
  180. package/.agents/skills/opentui/references/keyboard/REFERENCE.md +0 -617
  181. package/.agents/skills/opentui/references/layout/REFERENCE.md +0 -337
  182. package/.agents/skills/opentui/references/layout/patterns.md +0 -444
  183. package/.agents/skills/opentui/references/react/REFERENCE.md +0 -174
  184. package/.agents/skills/opentui/references/react/api.md +0 -436
  185. package/.agents/skills/opentui/references/react/configuration.md +0 -302
  186. package/.agents/skills/opentui/references/react/gotchas.md +0 -443
  187. package/.agents/skills/opentui/references/react/patterns.md +0 -501
  188. package/.agents/skills/opentui/references/solid/REFERENCE.md +0 -201
  189. package/.agents/skills/opentui/references/solid/api.md +0 -564
  190. package/.agents/skills/opentui/references/solid/configuration.md +0 -316
  191. package/.agents/skills/opentui/references/solid/gotchas.md +0 -427
  192. package/.agents/skills/opentui/references/solid/patterns.md +0 -560
  193. package/.agents/skills/opentui/references/testing/REFERENCE.md +0 -614
  194. package/.agents/skills/pdf/LICENSE.txt +0 -30
  195. package/.agents/skills/pdf/SKILL.md +0 -316
  196. package/.agents/skills/pdf/forms.md +0 -294
  197. package/.agents/skills/pdf/reference.md +0 -612
  198. package/.agents/skills/pdf/scripts/check_bounding_boxes.py +0 -65
  199. package/.agents/skills/pdf/scripts/check_fillable_fields.py +0 -11
  200. package/.agents/skills/pdf/scripts/convert_pdf_to_images.py +0 -33
  201. package/.agents/skills/pdf/scripts/create_validation_image.py +0 -37
  202. package/.agents/skills/pdf/scripts/extract_form_field_info.py +0 -122
  203. package/.agents/skills/pdf/scripts/extract_form_structure.py +0 -115
  204. package/.agents/skills/pdf/scripts/fill_fillable_fields.py +0 -98
  205. package/.agents/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -107
  206. package/.agents/skills/playwright-cli/SKILL.md +0 -390
  207. package/.agents/skills/playwright-cli/references/element-attributes.md +0 -23
  208. package/.agents/skills/playwright-cli/references/playwright-tests.md +0 -39
  209. package/.agents/skills/playwright-cli/references/request-mocking.md +0 -87
  210. package/.agents/skills/playwright-cli/references/running-code.md +0 -241
  211. package/.agents/skills/playwright-cli/references/session-management.md +0 -225
  212. package/.agents/skills/playwright-cli/references/spec-driven-testing.md +0 -305
  213. package/.agents/skills/playwright-cli/references/storage-state.md +0 -275
  214. package/.agents/skills/playwright-cli/references/test-generation.md +0 -134
  215. package/.agents/skills/playwright-cli/references/tracing.md +0 -139
  216. package/.agents/skills/playwright-cli/references/video-recording.md +0 -143
  217. package/.agents/skills/pptx/LICENSE.txt +0 -30
  218. package/.agents/skills/pptx/SKILL.md +0 -234
  219. package/.agents/skills/pptx/editing.md +0 -205
  220. package/.agents/skills/pptx/pptxgenjs.md +0 -420
  221. package/.agents/skills/pptx/scripts/__init__.py +0 -0
  222. package/.agents/skills/pptx/scripts/add_slide.py +0 -195
  223. package/.agents/skills/pptx/scripts/clean.py +0 -286
  224. package/.agents/skills/pptx/scripts/office/helpers/__init__.py +0 -0
  225. package/.agents/skills/pptx/scripts/office/helpers/merge_runs.py +0 -199
  226. package/.agents/skills/pptx/scripts/office/helpers/simplify_redlines.py +0 -197
  227. package/.agents/skills/pptx/scripts/office/pack.py +0 -159
  228. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  229. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  230. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  231. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  232. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  233. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  234. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  235. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  236. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  237. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  238. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  239. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  240. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  241. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  242. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  243. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  244. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  245. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  246. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  247. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  248. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  249. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  250. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  251. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  252. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  253. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  254. package/.agents/skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  255. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  256. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  257. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  258. package/.agents/skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  259. package/.agents/skills/pptx/scripts/office/schemas/mce/mc.xsd +0 -75
  260. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  261. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  262. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  263. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  264. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  265. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  266. package/.agents/skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  267. package/.agents/skills/pptx/scripts/office/soffice.py +0 -183
  268. package/.agents/skills/pptx/scripts/office/unpack.py +0 -132
  269. package/.agents/skills/pptx/scripts/office/validate.py +0 -111
  270. package/.agents/skills/pptx/scripts/office/validators/__init__.py +0 -15
  271. package/.agents/skills/pptx/scripts/office/validators/base.py +0 -847
  272. package/.agents/skills/pptx/scripts/office/validators/docx.py +0 -446
  273. package/.agents/skills/pptx/scripts/office/validators/pptx.py +0 -275
  274. package/.agents/skills/pptx/scripts/office/validators/redlining.py +0 -247
  275. package/.agents/skills/pptx/scripts/thumbnail.py +0 -289
  276. package/.agents/skills/project-development/SKILL.md +0 -293
  277. package/.agents/skills/project-development/references/case-studies.md +0 -388
  278. package/.agents/skills/project-development/references/pipeline-patterns.md +0 -610
  279. package/.agents/skills/project-development/scripts/pipeline_template.py +0 -796
  280. package/.agents/skills/prompt-engineer/SKILL.md +0 -265
  281. package/.agents/skills/prompt-engineer/references/advanced_patterns.md +0 -271
  282. package/.agents/skills/prompt-engineer/references/core_prompting.md +0 -137
  283. package/.agents/skills/prompt-engineer/references/quality_improvement.md +0 -193
  284. package/.agents/skills/research-codebase/SKILL.md +0 -229
  285. package/.agents/skills/ripgrep/SKILL.md +0 -384
  286. package/.agents/skills/skill-creator/LICENSE.txt +0 -202
  287. package/.agents/skills/skill-creator/SKILL.md +0 -487
  288. package/.agents/skills/skill-creator/agents/analyzer.md +0 -274
  289. package/.agents/skills/skill-creator/agents/comparator.md +0 -202
  290. package/.agents/skills/skill-creator/agents/grader.md +0 -223
  291. package/.agents/skills/skill-creator/assets/eval_review.html +0 -146
  292. package/.agents/skills/skill-creator/eval-viewer/generate_review.py +0 -471
  293. package/.agents/skills/skill-creator/eval-viewer/viewer.html +0 -1325
  294. package/.agents/skills/skill-creator/references/schemas.md +0 -430
  295. package/.agents/skills/skill-creator/scripts/__init__.py +0 -0
  296. package/.agents/skills/skill-creator/scripts/aggregate_benchmark.py +0 -401
  297. package/.agents/skills/skill-creator/scripts/generate_report.py +0 -326
  298. package/.agents/skills/skill-creator/scripts/improve_description.py +0 -247
  299. package/.agents/skills/skill-creator/scripts/package_skill.py +0 -136
  300. package/.agents/skills/skill-creator/scripts/quick_validate.py +0 -103
  301. package/.agents/skills/skill-creator/scripts/run_eval.py +0 -310
  302. package/.agents/skills/skill-creator/scripts/run_loop.py +0 -328
  303. package/.agents/skills/skill-creator/scripts/utils.py +0 -47
  304. package/.agents/skills/sl-commit/SKILL.md +0 -53
  305. package/.agents/skills/sl-submit-diff/SKILL.md +0 -57
  306. package/.agents/skills/tdd/SKILL.md +0 -111
  307. package/.agents/skills/tdd/deep-modules.md +0 -33
  308. package/.agents/skills/tdd/interface-design.md +0 -31
  309. package/.agents/skills/tdd/mocking.md +0 -59
  310. package/.agents/skills/tdd/refactoring.md +0 -10
  311. package/.agents/skills/tdd/tests.md +0 -61
  312. package/.agents/skills/tool-design/SKILL.md +0 -273
  313. package/.agents/skills/tool-design/references/architectural_reduction.md +0 -210
  314. package/.agents/skills/tool-design/references/best_practices.md +0 -176
  315. package/.agents/skills/tool-design/scripts/description_generator.py +0 -528
  316. package/.agents/skills/typescript-advanced-types/SKILL.md +0 -720
  317. package/.agents/skills/typescript-expert/SKILL.md +0 -434
  318. package/.agents/skills/typescript-expert/references/tsconfig-strict.json +0 -92
  319. package/.agents/skills/typescript-expert/references/typescript-cheatsheet.md +0 -383
  320. package/.agents/skills/typescript-expert/references/utility-types.ts +0 -335
  321. package/.agents/skills/typescript-expert/scripts/ts_diagnostic.py +0 -203
  322. package/.agents/skills/typescript-react-reviewer/SKILL.md +0 -201
  323. package/.agents/skills/typescript-react-reviewer/references/antipatterns.md +0 -510
  324. package/.agents/skills/typescript-react-reviewer/references/checklist.md +0 -267
  325. package/.agents/skills/typescript-react-reviewer/references/react19-patterns.md +0 -305
  326. package/.agents/skills/workflow-creator/SKILL.md +0 -553
  327. package/.agents/skills/workflow-creator/references/agent-sessions.md +0 -891
  328. package/.agents/skills/workflow-creator/references/agent-setup-recipe.md +0 -266
  329. package/.agents/skills/workflow-creator/references/computation-and-validation.md +0 -201
  330. package/.agents/skills/workflow-creator/references/control-flow.md +0 -470
  331. package/.agents/skills/workflow-creator/references/failure-modes.md +0 -1014
  332. package/.agents/skills/workflow-creator/references/getting-started.md +0 -392
  333. package/.agents/skills/workflow-creator/references/registry-and-validation.md +0 -141
  334. package/.agents/skills/workflow-creator/references/running-workflows.md +0 -418
  335. package/.agents/skills/workflow-creator/references/session-config.md +0 -431
  336. package/.agents/skills/workflow-creator/references/state-and-data-flow.md +0 -356
  337. package/.agents/skills/workflow-creator/references/user-input.md +0 -234
  338. package/.agents/skills/workflow-creator/references/workflow-inputs.md +0 -392
  339. package/.agents/skills/xlsx/LICENSE.txt +0 -30
  340. package/.agents/skills/xlsx/SKILL.md +0 -294
  341. package/.agents/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  342. package/.agents/skills/xlsx/scripts/office/helpers/merge_runs.py +0 -199
  343. package/.agents/skills/xlsx/scripts/office/helpers/simplify_redlines.py +0 -197
  344. package/.agents/skills/xlsx/scripts/office/pack.py +0 -159
  345. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  346. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  347. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  348. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  349. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  350. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  351. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  352. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  353. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  354. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  355. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  356. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  357. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  358. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  359. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  360. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  361. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  362. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  363. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  364. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  365. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  366. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  367. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  368. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  369. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  370. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  371. package/.agents/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  372. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  373. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  374. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  375. package/.agents/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  376. package/.agents/skills/xlsx/scripts/office/schemas/mce/mc.xsd +0 -75
  377. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +0 -560
  378. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +0 -67
  379. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +0 -14
  380. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +0 -20
  381. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +0 -13
  382. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  383. package/.agents/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +0 -8
  384. package/.agents/skills/xlsx/scripts/office/soffice.py +0 -183
  385. package/.agents/skills/xlsx/scripts/office/unpack.py +0 -132
  386. package/.agents/skills/xlsx/scripts/office/validate.py +0 -111
  387. package/.agents/skills/xlsx/scripts/office/validators/__init__.py +0 -15
  388. package/.agents/skills/xlsx/scripts/office/validators/base.py +0 -847
  389. package/.agents/skills/xlsx/scripts/office/validators/docx.py +0 -446
  390. package/.agents/skills/xlsx/scripts/office/validators/pptx.py +0 -275
  391. package/.agents/skills/xlsx/scripts/office/validators/redlining.py +0 -247
  392. package/.agents/skills/xlsx/scripts/recalc.py +0 -184
  393. package/.claude/agents/code-simplifier.md +0 -52
  394. package/.claude/agents/codebase-analyzer.md +0 -166
  395. package/.claude/agents/codebase-locator.md +0 -122
  396. package/.claude/agents/codebase-online-researcher.md +0 -148
  397. package/.claude/agents/codebase-pattern-finder.md +0 -247
  398. package/.claude/agents/codebase-research-analyzer.md +0 -179
  399. package/.claude/agents/codebase-research-locator.md +0 -145
  400. package/.claude/agents/debugger.md +0 -91
  401. package/.claude/agents/orchestrator.md +0 -19
  402. package/.claude/agents/planner.md +0 -295
  403. package/.claude/agents/reviewer.md +0 -98
  404. package/.claude/agents/worker.md +0 -165
  405. package/.claude/settings.json +0 -27
  406. package/.github/agents/code-simplifier.md +0 -52
  407. package/.github/agents/codebase-analyzer.md +0 -166
  408. package/.github/agents/codebase-locator.md +0 -122
  409. package/.github/agents/codebase-online-researcher.md +0 -146
  410. package/.github/agents/codebase-pattern-finder.md +0 -247
  411. package/.github/agents/codebase-research-analyzer.md +0 -179
  412. package/.github/agents/codebase-research-locator.md +0 -145
  413. package/.github/agents/debugger.md +0 -98
  414. package/.github/agents/orchestrator.md +0 -27
  415. package/.github/agents/planner.md +0 -305
  416. package/.github/agents/reviewer.md +0 -95
  417. package/.github/agents/worker.md +0 -237
  418. package/.github/lsp.json +0 -93
  419. package/.mcp.json +0 -20
  420. package/.opencode/agents/code-simplifier.md +0 -62
  421. package/.opencode/agents/codebase-analyzer.md +0 -171
  422. package/.opencode/agents/codebase-locator.md +0 -127
  423. package/.opencode/agents/codebase-online-researcher.md +0 -152
  424. package/.opencode/agents/codebase-pattern-finder.md +0 -252
  425. package/.opencode/agents/codebase-research-analyzer.md +0 -183
  426. package/.opencode/agents/codebase-research-locator.md +0 -149
  427. package/.opencode/agents/debugger.md +0 -99
  428. package/.opencode/agents/orchestrator.md +0 -27
  429. package/.opencode/agents/planner.md +0 -309
  430. package/.opencode/agents/reviewer.md +0 -103
  431. package/.opencode/agents/worker.md +0 -165
  432. package/.opencode/opencode.json +0 -25
  433. package/README.md +0 -1624
  434. package/assets/settings.schema.json +0 -51
  435. package/dist/commands/cli/claude-inflight-hook.d.ts +0 -100
  436. package/dist/commands/cli/claude-inflight-hook.d.ts.map +0 -1
  437. package/dist/commands/cli/claude-stop-hook.d.ts +0 -80
  438. package/dist/commands/cli/claude-stop-hook.d.ts.map +0 -1
  439. package/dist/lib/atomic-temp.d.ts +0 -8
  440. package/dist/lib/atomic-temp.d.ts.map +0 -1
  441. package/dist/lib/path-root-guard.d.ts +0 -4
  442. package/dist/lib/path-root-guard.d.ts.map +0 -1
  443. package/dist/lib/spawn.d.ts +0 -102
  444. package/dist/lib/spawn.d.ts.map +0 -1
  445. package/dist/lib/terminal-env.d.ts +0 -9
  446. package/dist/lib/terminal-env.d.ts.map +0 -1
  447. package/dist/sdk/components/attached-statusline.d.ts +0 -26
  448. package/dist/sdk/components/attached-statusline.d.ts.map +0 -1
  449. package/dist/sdk/components/color-utils.d.ts +0 -4
  450. package/dist/sdk/components/color-utils.d.ts.map +0 -1
  451. package/dist/sdk/components/compact-switcher.d.ts +0 -10
  452. package/dist/sdk/components/compact-switcher.d.ts.map +0 -1
  453. package/dist/sdk/components/connectors.d.ts +0 -16
  454. package/dist/sdk/components/connectors.d.ts.map +0 -1
  455. package/dist/sdk/components/edge.d.ts +0 -4
  456. package/dist/sdk/components/edge.d.ts.map +0 -1
  457. package/dist/sdk/components/error-boundary.d.ts +0 -23
  458. package/dist/sdk/components/error-boundary.d.ts.map +0 -1
  459. package/dist/sdk/components/graph-theme.d.ts +0 -18
  460. package/dist/sdk/components/graph-theme.d.ts.map +0 -1
  461. package/dist/sdk/components/header.d.ts +0 -3
  462. package/dist/sdk/components/header.d.ts.map +0 -1
  463. package/dist/sdk/components/hooks.d.ts +0 -15
  464. package/dist/sdk/components/hooks.d.ts.map +0 -1
  465. package/dist/sdk/components/layout.d.ts +0 -27
  466. package/dist/sdk/components/layout.d.ts.map +0 -1
  467. package/dist/sdk/components/node-card.d.ts +0 -10
  468. package/dist/sdk/components/node-card.d.ts.map +0 -1
  469. package/dist/sdk/components/orchestrator-panel-contexts.d.ts +0 -16
  470. package/dist/sdk/components/orchestrator-panel-contexts.d.ts.map +0 -1
  471. package/dist/sdk/components/orchestrator-panel-store.d.ts +0 -52
  472. package/dist/sdk/components/orchestrator-panel-store.d.ts.map +0 -1
  473. package/dist/sdk/components/orchestrator-panel-types.d.ts +0 -18
  474. package/dist/sdk/components/orchestrator-panel-types.d.ts.map +0 -1
  475. package/dist/sdk/components/orchestrator-panel.d.ts +0 -86
  476. package/dist/sdk/components/orchestrator-panel.d.ts.map +0 -1
  477. package/dist/sdk/components/renderer-background.d.ts +0 -9
  478. package/dist/sdk/components/renderer-background.d.ts.map +0 -1
  479. package/dist/sdk/components/session-graph-panel.d.ts +0 -7
  480. package/dist/sdk/components/session-graph-panel.d.ts.map +0 -1
  481. package/dist/sdk/components/status-helpers.d.ts +0 -6
  482. package/dist/sdk/components/status-helpers.d.ts.map +0 -1
  483. package/dist/sdk/components/statusline.d.ts +0 -5
  484. package/dist/sdk/components/statusline.d.ts.map +0 -1
  485. package/dist/sdk/components/tui-diagnostics.d.ts +0 -56
  486. package/dist/sdk/components/tui-diagnostics.d.ts.map +0 -1
  487. package/dist/sdk/components/workflow-picker-panel.d.ts +0 -126
  488. package/dist/sdk/components/workflow-picker-panel.d.ts.map +0 -1
  489. package/dist/sdk/define-workflow.d.ts +0 -107
  490. package/dist/sdk/define-workflow.d.ts.map +0 -1
  491. package/dist/sdk/errors.d.ts +0 -46
  492. package/dist/sdk/errors.d.ts.map +0 -1
  493. package/dist/sdk/index.d.ts +0 -26
  494. package/dist/sdk/index.d.ts.map +0 -1
  495. package/dist/sdk/primitives/inputs.d.ts +0 -36
  496. package/dist/sdk/primitives/inputs.d.ts.map +0 -1
  497. package/dist/sdk/primitives/metadata.d.ts +0 -40
  498. package/dist/sdk/primitives/metadata.d.ts.map +0 -1
  499. package/dist/sdk/primitives/run.d.ts +0 -57
  500. package/dist/sdk/primitives/run.d.ts.map +0 -1
  501. package/dist/sdk/primitives/sessions.d.ts +0 -128
  502. package/dist/sdk/primitives/sessions.d.ts.map +0 -1
  503. package/dist/sdk/providers/claude.d.ts +0 -392
  504. package/dist/sdk/providers/claude.d.ts.map +0 -1
  505. package/dist/sdk/providers/copilot.d.ts +0 -55
  506. package/dist/sdk/providers/copilot.d.ts.map +0 -1
  507. package/dist/sdk/providers/opencode.d.ts +0 -27
  508. package/dist/sdk/providers/opencode.d.ts.map +0 -1
  509. package/dist/sdk/registry.d.ts +0 -27
  510. package/dist/sdk/registry.d.ts.map +0 -1
  511. package/dist/sdk/runtime/attached-footer.d.ts +0 -31
  512. package/dist/sdk/runtime/attached-footer.d.ts.map +0 -1
  513. package/dist/sdk/runtime/cc-debounce.d.ts +0 -29
  514. package/dist/sdk/runtime/cc-debounce.d.ts.map +0 -1
  515. package/dist/sdk/runtime/executor-env.d.ts +0 -20
  516. package/dist/sdk/runtime/executor-env.d.ts.map +0 -1
  517. package/dist/sdk/runtime/executor.d.ts +0 -265
  518. package/dist/sdk/runtime/executor.d.ts.map +0 -1
  519. package/dist/sdk/runtime/graph-inference.d.ts +0 -35
  520. package/dist/sdk/runtime/graph-inference.d.ts.map +0 -1
  521. package/dist/sdk/runtime/orchestrator-entry.d.ts +0 -26
  522. package/dist/sdk/runtime/orchestrator-entry.d.ts.map +0 -1
  523. package/dist/sdk/runtime/panel.d.ts +0 -9
  524. package/dist/sdk/runtime/panel.d.ts.map +0 -1
  525. package/dist/sdk/runtime/port-discovery.d.ts +0 -71
  526. package/dist/sdk/runtime/port-discovery.d.ts.map +0 -1
  527. package/dist/sdk/runtime/status-writer.d.ts +0 -101
  528. package/dist/sdk/runtime/status-writer.d.ts.map +0 -1
  529. package/dist/sdk/runtime/theme.d.ts +0 -33
  530. package/dist/sdk/runtime/theme.d.ts.map +0 -1
  531. package/dist/sdk/runtime/tmux.d.ts +0 -307
  532. package/dist/sdk/runtime/tmux.d.ts.map +0 -1
  533. package/dist/sdk/runtime/version-compat.d.ts +0 -28
  534. package/dist/sdk/runtime/version-compat.d.ts.map +0 -1
  535. package/dist/sdk/types.d.ts +0 -435
  536. package/dist/sdk/types.d.ts.map +0 -1
  537. package/dist/sdk/worker-shared.d.ts +0 -42
  538. package/dist/sdk/worker-shared.d.ts.map +0 -1
  539. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts +0 -81
  540. package/dist/sdk/workflows/builtin/deep-research-codebase/claude/index.d.ts.map +0 -1
  541. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts +0 -37
  542. package/dist/sdk/workflows/builtin/deep-research-codebase/copilot/index.d.ts.map +0 -1
  543. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts +0 -43
  544. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/batching.d.ts.map +0 -1
  545. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts +0 -14
  546. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.d.ts.map +0 -1
  547. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts +0 -136
  548. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.d.ts.map +0 -1
  549. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts +0 -58
  550. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scout.d.ts.map +0 -1
  551. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.d.ts +0 -43
  552. package/dist/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.d.ts.map +0 -1
  553. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts +0 -37
  554. package/dist/sdk/workflows/builtin/deep-research-codebase/opencode/index.d.ts.map +0 -1
  555. package/dist/sdk/workflows/builtin/open-claude-design/claude/index.d.ts +0 -68
  556. package/dist/sdk/workflows/builtin/open-claude-design/claude/index.d.ts.map +0 -1
  557. package/dist/sdk/workflows/builtin/open-claude-design/copilot/index.d.ts +0 -56
  558. package/dist/sdk/workflows/builtin/open-claude-design/copilot/index.d.ts.map +0 -1
  559. package/dist/sdk/workflows/builtin/open-claude-design/helpers/constants.d.ts +0 -72
  560. package/dist/sdk/workflows/builtin/open-claude-design/helpers/constants.d.ts.map +0 -1
  561. package/dist/sdk/workflows/builtin/open-claude-design/helpers/design-system.d.ts +0 -46
  562. package/dist/sdk/workflows/builtin/open-claude-design/helpers/design-system.d.ts.map +0 -1
  563. package/dist/sdk/workflows/builtin/open-claude-design/helpers/export.d.ts +0 -32
  564. package/dist/sdk/workflows/builtin/open-claude-design/helpers/export.d.ts.map +0 -1
  565. package/dist/sdk/workflows/builtin/open-claude-design/helpers/import.d.ts +0 -33
  566. package/dist/sdk/workflows/builtin/open-claude-design/helpers/import.d.ts.map +0 -1
  567. package/dist/sdk/workflows/builtin/open-claude-design/helpers/prompts.d.ts +0 -106
  568. package/dist/sdk/workflows/builtin/open-claude-design/helpers/prompts.d.ts.map +0 -1
  569. package/dist/sdk/workflows/builtin/open-claude-design/helpers/scan.d.ts +0 -50
  570. package/dist/sdk/workflows/builtin/open-claude-design/helpers/scan.d.ts.map +0 -1
  571. package/dist/sdk/workflows/builtin/open-claude-design/helpers/validation.d.ts +0 -12
  572. package/dist/sdk/workflows/builtin/open-claude-design/helpers/validation.d.ts.map +0 -1
  573. package/dist/sdk/workflows/builtin/open-claude-design/opencode/index.d.ts +0 -58
  574. package/dist/sdk/workflows/builtin/open-claude-design/opencode/index.d.ts.map +0 -1
  575. package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts +0 -37
  576. package/dist/sdk/workflows/builtin/ralph/claude/index.d.ts.map +0 -1
  577. package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts +0 -34
  578. package/dist/sdk/workflows/builtin/ralph/copilot/index.d.ts.map +0 -1
  579. package/dist/sdk/workflows/builtin/ralph/helpers/copilot-reviewer.d.ts +0 -25
  580. package/dist/sdk/workflows/builtin/ralph/helpers/copilot-reviewer.d.ts.map +0 -1
  581. package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts +0 -69
  582. package/dist/sdk/workflows/builtin/ralph/helpers/git.d.ts.map +0 -1
  583. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts +0 -266
  584. package/dist/sdk/workflows/builtin/ralph/helpers/prompts.d.ts.map +0 -1
  585. package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts +0 -24
  586. package/dist/sdk/workflows/builtin/ralph/helpers/review.d.ts.map +0 -1
  587. package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts +0 -33
  588. package/dist/sdk/workflows/builtin/ralph/opencode/index.d.ts.map +0 -1
  589. package/dist/sdk/workflows/index.d.ts +0 -32
  590. package/dist/sdk/workflows/index.d.ts.map +0 -1
  591. package/dist/services/config/additional-instructions.d.ts +0 -67
  592. package/dist/services/config/additional-instructions.d.ts.map +0 -1
  593. package/dist/services/config/atomic-config.d.ts +0 -42
  594. package/dist/services/config/atomic-config.d.ts.map +0 -1
  595. package/dist/services/config/definitions.d.ts +0 -52
  596. package/dist/services/config/definitions.d.ts.map +0 -1
  597. package/dist/services/config/index.d.ts +0 -7
  598. package/dist/services/config/index.d.ts.map +0 -1
  599. package/dist/services/config/scm-sync.d.ts +0 -37
  600. package/dist/services/config/scm-sync.d.ts.map +0 -1
  601. package/dist/services/config/settings-schema.d.ts +0 -2
  602. package/dist/services/config/settings-schema.d.ts.map +0 -1
  603. package/dist/services/system/copy.d.ts +0 -84
  604. package/dist/services/system/copy.d.ts.map +0 -1
  605. package/dist/services/system/detect.d.ts +0 -75
  606. package/dist/services/system/detect.d.ts.map +0 -1
  607. package/dist/theme/colors.d.ts +0 -35
  608. package/dist/theme/colors.d.ts.map +0 -1
  609. package/src/cli.ts +0 -397
  610. package/src/commands/builtin-registry.ts +0 -37
  611. package/src/commands/cli/chat/index.test.ts +0 -252
  612. package/src/commands/cli/chat/index.ts +0 -430
  613. package/src/commands/cli/chat.ts +0 -8
  614. package/src/commands/cli/claude-ask-hook.test.ts +0 -128
  615. package/src/commands/cli/claude-ask-hook.ts +0 -84
  616. package/src/commands/cli/claude-inflight-hook.test.ts +0 -598
  617. package/src/commands/cli/claude-inflight-hook.ts +0 -359
  618. package/src/commands/cli/claude-session-start-hook.ts +0 -61
  619. package/src/commands/cli/claude-stop-hook.test.ts +0 -317
  620. package/src/commands/cli/claude-stop-hook.ts +0 -441
  621. package/src/commands/cli/completions.ts +0 -24
  622. package/src/commands/cli/config.ts +0 -80
  623. package/src/commands/cli/footer.tsx +0 -248
  624. package/src/commands/cli/init/index.ts +0 -41
  625. package/src/commands/cli/init/onboarding.ts +0 -61
  626. package/src/commands/cli/init.ts +0 -8
  627. package/src/commands/cli/management-commands.ts +0 -112
  628. package/src/commands/cli/session.test.ts +0 -830
  629. package/src/commands/cli/session.ts +0 -447
  630. package/src/commands/cli/workflow-command.test.ts +0 -618
  631. package/src/commands/cli/workflow-inputs.test.ts +0 -353
  632. package/src/commands/cli/workflow-inputs.ts +0 -266
  633. package/src/commands/cli/workflow-list.test.ts +0 -235
  634. package/src/commands/cli/workflow-list.ts +0 -0
  635. package/src/commands/cli/workflow-status.test.ts +0 -451
  636. package/src/commands/cli/workflow-status.ts +0 -330
  637. package/src/commands/cli/workflow.ts +0 -196
  638. package/src/completions/bash.ts +0 -102
  639. package/src/completions/fish.ts +0 -136
  640. package/src/completions/index.ts +0 -7
  641. package/src/completions/powershell.ts +0 -195
  642. package/src/completions/zsh.ts +0 -150
  643. package/src/lib/atomic-temp.test.ts +0 -86
  644. package/src/lib/atomic-temp.ts +0 -62
  645. package/src/lib/common-ignore.ts +0 -46
  646. package/src/lib/merge.ts +0 -103
  647. package/src/lib/path-root-guard.ts +0 -38
  648. package/src/lib/spawn.test.ts +0 -109
  649. package/src/lib/spawn.ts +0 -678
  650. package/src/lib/terminal-env.test.ts +0 -343
  651. package/src/lib/terminal-env.ts +0 -100
  652. package/src/scripts/bump-version.ts +0 -94
  653. package/src/scripts/bundle-configs.ts +0 -116
  654. package/src/scripts/clean-dist.test.ts +0 -53
  655. package/src/scripts/clean-dist.ts +0 -37
  656. package/src/scripts/constants-base.ts +0 -14
  657. package/src/scripts/constants.ts +0 -35
  658. package/src/sdk/components/attached-statusline.tsx +0 -86
  659. package/src/sdk/components/color-utils.ts +0 -20
  660. package/src/sdk/components/compact-switcher.tsx +0 -78
  661. package/src/sdk/components/connectors.test.ts +0 -707
  662. package/src/sdk/components/connectors.ts +0 -160
  663. package/src/sdk/components/edge.tsx +0 -13
  664. package/src/sdk/components/error-boundary.tsx +0 -38
  665. package/src/sdk/components/graph-theme.ts +0 -37
  666. package/src/sdk/components/header.tsx +0 -85
  667. package/src/sdk/components/hooks.ts +0 -21
  668. package/src/sdk/components/layout.test.ts +0 -1245
  669. package/src/sdk/components/layout.ts +0 -223
  670. package/src/sdk/components/node-card.tsx +0 -91
  671. package/src/sdk/components/orchestrator-panel-contexts.ts +0 -35
  672. package/src/sdk/components/orchestrator-panel-store.test.ts +0 -847
  673. package/src/sdk/components/orchestrator-panel-store.ts +0 -187
  674. package/src/sdk/components/orchestrator-panel-types.ts +0 -23
  675. package/src/sdk/components/orchestrator-panel.tsx +0 -262
  676. package/src/sdk/components/renderer-background.ts +0 -49
  677. package/src/sdk/components/session-graph-panel.tsx +0 -471
  678. package/src/sdk/components/status-helpers.ts +0 -33
  679. package/src/sdk/components/statusline.tsx +0 -68
  680. package/src/sdk/components/tui-diagnostics.ts +0 -273
  681. package/src/sdk/components/workflow-picker-panel.tsx +0 -1613
  682. package/src/sdk/define-workflow.test.ts +0 -354
  683. package/src/sdk/define-workflow.ts +0 -275
  684. package/src/sdk/errors.test.ts +0 -83
  685. package/src/sdk/errors.ts +0 -77
  686. package/src/sdk/index.test.ts +0 -92
  687. package/src/sdk/index.ts +0 -101
  688. package/src/sdk/primitives/inputs.ts +0 -48
  689. package/src/sdk/primitives/metadata.ts +0 -63
  690. package/src/sdk/primitives/run.ts +0 -81
  691. package/src/sdk/primitives/sessions.test.ts +0 -594
  692. package/src/sdk/primitives/sessions.ts +0 -328
  693. package/src/sdk/providers/claude.ts +0 -1450
  694. package/src/sdk/providers/copilot.test.ts +0 -365
  695. package/src/sdk/providers/copilot.ts +0 -185
  696. package/src/sdk/providers/headless-hil-policy.test.ts +0 -211
  697. package/src/sdk/providers/opencode.ts +0 -88
  698. package/src/sdk/registry.ts +0 -132
  699. package/src/sdk/runtime/attached-footer.ts +0 -155
  700. package/src/sdk/runtime/cc-debounce.ts +0 -104
  701. package/src/sdk/runtime/executor-env.ts +0 -45
  702. package/src/sdk/runtime/executor.test.ts +0 -1321
  703. package/src/sdk/runtime/executor.ts +0 -2136
  704. package/src/sdk/runtime/graph-inference.ts +0 -50
  705. package/src/sdk/runtime/orchestrator-entry.ts +0 -110
  706. package/src/sdk/runtime/panel.tsx +0 -9
  707. package/src/sdk/runtime/port-discovery.test.ts +0 -573
  708. package/src/sdk/runtime/port-discovery.ts +0 -496
  709. package/src/sdk/runtime/status-writer.test.ts +0 -245
  710. package/src/sdk/runtime/status-writer.ts +0 -201
  711. package/src/sdk/runtime/theme.ts +0 -71
  712. package/src/sdk/runtime/tmux.conf +0 -112
  713. package/src/sdk/runtime/tmux.ts +0 -785
  714. package/src/sdk/runtime/version-compat.ts +0 -68
  715. package/src/sdk/types.ts +0 -548
  716. package/src/sdk/worker-shared.test.ts +0 -163
  717. package/src/sdk/worker-shared.ts +0 -155
  718. package/src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts +0 -569
  719. package/src/sdk/workflows/builtin/deep-research-codebase/copilot/index.ts +0 -481
  720. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/batching.ts +0 -65
  721. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/heuristic.ts +0 -24
  722. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/ignore-by-default.d.ts +0 -8
  723. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/prompts.ts +0 -958
  724. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/scout.ts +0 -505
  725. package/src/sdk/workflows/builtin/deep-research-codebase/helpers/scratch.ts +0 -115
  726. package/src/sdk/workflows/builtin/deep-research-codebase/opencode/index.ts +0 -530
  727. package/src/sdk/workflows/builtin/open-claude-design/claude/index.ts +0 -500
  728. package/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts +0 -508
  729. package/src/sdk/workflows/builtin/open-claude-design/helpers/constants.ts +0 -159
  730. package/src/sdk/workflows/builtin/open-claude-design/helpers/design-system.ts +0 -88
  731. package/src/sdk/workflows/builtin/open-claude-design/helpers/export.ts +0 -193
  732. package/src/sdk/workflows/builtin/open-claude-design/helpers/import.ts +0 -52
  733. package/src/sdk/workflows/builtin/open-claude-design/helpers/prompts.ts +0 -1110
  734. package/src/sdk/workflows/builtin/open-claude-design/helpers/scan.ts +0 -117
  735. package/src/sdk/workflows/builtin/open-claude-design/helpers/validation.ts +0 -38
  736. package/src/sdk/workflows/builtin/open-claude-design/opencode/index.ts +0 -610
  737. package/src/sdk/workflows/builtin/ralph/claude/index.ts +0 -272
  738. package/src/sdk/workflows/builtin/ralph/copilot/index.ts +0 -298
  739. package/src/sdk/workflows/builtin/ralph/helpers/copilot-reviewer.ts +0 -105
  740. package/src/sdk/workflows/builtin/ralph/helpers/git.ts +0 -201
  741. package/src/sdk/workflows/builtin/ralph/helpers/prompts.ts +0 -1108
  742. package/src/sdk/workflows/builtin/ralph/helpers/review.ts +0 -33
  743. package/src/sdk/workflows/builtin/ralph/opencode/index.ts +0 -290
  744. package/src/sdk/workflows/index.ts +0 -116
  745. package/src/services/config/additional-instructions.ts +0 -273
  746. package/src/services/config/atomic-config.ts +0 -210
  747. package/src/services/config/atomic-global-config.ts +0 -348
  748. package/src/services/config/config-path.ts +0 -19
  749. package/src/services/config/definitions.ts +0 -125
  750. package/src/services/config/index.ts +0 -7
  751. package/src/services/config/scm-sync.ts +0 -185
  752. package/src/services/config/settings-schema.ts +0 -2
  753. package/src/services/config/settings.ts +0 -144
  754. package/src/services/system/agents.ts +0 -95
  755. package/src/services/system/auth.test.ts +0 -343
  756. package/src/services/system/auth.ts +0 -140
  757. package/src/services/system/auto-sync.ts +0 -128
  758. package/src/services/system/copy.ts +0 -392
  759. package/src/services/system/detect.ts +0 -161
  760. package/src/services/system/file-lock.ts +0 -289
  761. package/src/services/system/install-ui.ts +0 -296
  762. package/src/services/system/skills.ts +0 -58
  763. package/src/theme/colors.ts +0 -96
  764. package/src/theme/logo.ts +0 -123
  765. package/src/version.ts +0 -7
@@ -1,1450 +0,0 @@
1
- /**
2
- * Claude Code query abstraction.
3
- *
4
- * Sends a prompt to an interactive Claude Code session running in a tmux pane
5
- * using `tmux send-keys -l --` (literal text) + `C-m` (raw carriage return).
6
- * Verifies delivery by polling `capture-pane` and retries if needed.
7
- *
8
- * This is NOT headless — Claude runs as a full interactive TUI in the pane.
9
- * We're automating keyboard input and reading pane output.
10
- *
11
- * Reliability hardened from oh-my-codex's sendToWorker implementation:
12
- * - Pre-send readiness wait with exponential backoff
13
- * - CLI-specific submit plan (Claude: 1 C-m per round)
14
- * - Per-round capture verification (6 rounds)
15
- * - Adaptive retry with C-u clear + retype
16
- * - Post-submit active-task detection
17
- * - File-based idle detection via session JSONL watching
18
- */
19
-
20
- import {
21
- getSessionMessages,
22
- query as sdkQuery,
23
- type SessionMessage,
24
- type SDKUserMessage,
25
- type Options as SDKOptions,
26
- } from "@anthropic-ai/claude-agent-sdk";
27
- import { respawnPane } from "../runtime/tmux.ts";
28
- import { escBash } from "../runtime/executor.ts";
29
- import { watch, unlink, mkdir, writeFile } from "node:fs/promises";
30
- import { existsSync, writeFileSync } from "node:fs";
31
- import { join } from "node:path";
32
- import { randomUUID } from "node:crypto";
33
- import { claudeHookDirs } from "../../commands/cli/claude-stop-hook.ts";
34
- import {
35
- clearInflightTracking,
36
- waitForInflightDrained,
37
- } from "../../commands/cli/claude-inflight-hook.ts";
38
- import { resolveAdditionalInstructionsContent } from "../../services/config/additional-instructions.ts";
39
- import {
40
- atomicContentTempPath,
41
- atomicTempPath,
42
- withAtomicTempEnv,
43
- } from "../../lib/atomic-temp.ts";
44
-
45
- // ---------------------------------------------------------------------------
46
- // Session tracking — ensures createClaudeSession is called before claudeQuery
47
- // ---------------------------------------------------------------------------
48
-
49
- /** Per-pane state for Claude sessions. */
50
- interface PaneState {
51
- /**
52
- * Claude Code's session ID. Pre-generated via `crypto.randomUUID()` in
53
- * `createClaudeSession` and passed to `claude --session-id <UUID>` on the
54
- * first query, so we know the JSONL filename without polling.
55
- */
56
- claudeSessionId: string;
57
- /** Whether the `claude` CLI has been spawned in this pane yet. */
58
- claudeStarted: boolean;
59
- /** CLI flags to pass to `claude` when it is spawned on the first query. */
60
- chatFlags: string[];
61
- }
62
-
63
- const initializedPanes = new Map<string, PaneState>();
64
-
65
- /**
66
- * Remove a pane from the initialized map and signal the currently-blocked
67
- * Stop hook that the session is over, so Claude stops promptly instead of
68
- * waiting out the hook's safety timeout.
69
- *
70
- * Called by the runtime when a Claude stage is being torn down. Idempotent.
71
- *
72
- * After writing the release marker, this waits for the per-session in-flight
73
- * marker dir (`~/.atomic/claude-inflight/<session_id>/`) to drain. The
74
- * marker dir is populated by the SubagentStart/Stop and TaskCreated/Completed
75
- * hooks registered in {@link WORKFLOW_HOOK_SETTINGS}. This wait is the
76
- * synchronization barrier that prevents the executor from advancing to the
77
- * next stage while the previous stage's backgrounded subagents/tasks still
78
- * hold FDs/PTYs on the atomic tmux server — the failure mode that surfaced
79
- * intermittently as `tmux respawn-pane: fork failed: Device not configured`.
80
- *
81
- * The wait has its own bounded timeout (default 30 minutes) so a wedged
82
- * subagent can't permanently block the workflow; the in-hook stale-sweep
83
- * (~2 hours TTL) is the ultimate safety net.
84
- */
85
- export async function clearClaudeSession(paneId: string): Promise<void> {
86
- const state = initializedPanes.get(paneId);
87
- if (state) {
88
- try {
89
- await releaseClaudeSession(state.claudeSessionId);
90
- } catch {
91
- // Best-effort — if release fails the hook will still exit on its
92
- // own safety timeout.
93
- }
94
- // Wait for in-flight subagents/tasks to finish before letting the
95
- // executor advance. Resolves immediately when the dir is empty/missing
96
- // (the common case, including any stage that didn't spawn subagents).
97
- try {
98
- await waitForInflightDrained(state.claudeSessionId);
99
- } catch {
100
- // Best-effort — the wait swallows internal errors and resolves on
101
- // timeout. A throw here would only happen on a path bug.
102
- }
103
- try {
104
- await unlinkAtomicPidFile(state.claudeSessionId);
105
- } catch {
106
- // Best-effort — stale pid file is inert; the next session writes a
107
- // fresh one under its own UUID.
108
- }
109
- try {
110
- await clearStaleReadyMarker(state.claudeSessionId);
111
- } catch {
112
- // Best-effort — stale ready marker is inert; the next session writes
113
- // a fresh one under its own UUID and clears any prior leftover in
114
- // `claudeQuery` before respawn.
115
- }
116
- try {
117
- await clearInflightTracking(state.claudeSessionId);
118
- } catch {
119
- // Best-effort — leftover marker files are reaped by the next session's
120
- // stale-sweep, and the .session-roots/ entries are tiny.
121
- }
122
- }
123
- initializedPanes.delete(paneId);
124
- }
125
-
126
- /** Default CLI flags passed to the `claude` command. */
127
- const DEFAULT_CHAT_FLAGS = [
128
- "--allow-dangerously-skip-permissions",
129
- "--dangerously-skip-permissions",
130
- ];
131
-
132
- /**
133
- * Build the shell command Claude Code runs from an injected workflow hook.
134
- *
135
- * - **Published install** (`import.meta.dir` under `node_modules`): resolve
136
- * `atomic` via the user's PATH. That's the binary they installed, and
137
- * relying on PATH is robust across shells and platforms.
138
- * - **Dev** (source checkout): re-invoke THIS repo's `src/cli.ts` using the
139
- * same Bun runtime that's executing us, so edits to the hook logic are
140
- * picked up without rebuilding or re-linking. Mirrors the
141
- * `spawnAttachedFooter` pattern in `src/sdk/runtime/executor.ts:293-303`.
142
- *
143
- * The dev-detection heuristic (`node_modules` in `import.meta.dir`) is the
144
- * same one used by `src/services/system/auto-sync.ts:50`.
145
- */
146
- function buildWorkflowHookCommand(subcommand: string, extraArgs: readonly string[] = []): string {
147
- if (import.meta.dir.includes("node_modules")) {
148
- return ["atomic", subcommand, ...extraArgs].join(" ");
149
- }
150
- const runtime = process.execPath;
151
- const cliPath = join(import.meta.dir, "..", "..", "cli.ts");
152
- if (process.platform === "win32") {
153
- const script = [
154
- quotePwshLiteral(runtime),
155
- quotePwshLiteral(cliPath),
156
- quotePwshLiteral(subcommand),
157
- ...extraArgs.map(quotePwshLiteral),
158
- ].join(" ");
159
- const encoded = Buffer.from(`& ${script}`, "utf16le").toString("base64");
160
- return `pwsh -NoProfile -EncodedCommand ${encoded}`;
161
- }
162
- return [
163
- `"${escBash(runtime)}"`,
164
- `"${escBash(cliPath)}"`,
165
- subcommand,
166
- ...extraArgs,
167
- ].join(" ");
168
- }
169
-
170
- function quotePwshLiteral(s: string): string {
171
- return `'${s
172
- .replace(/\x00/g, "")
173
- .replace(/[\n\r]+/g, " ")
174
- .replace(/'/g, "''")}'`;
175
- }
176
-
177
- /**
178
- * Effectively-unbounded timeout (in seconds) for the Stop hook command.
179
- *
180
- * Claude Code's Stop hook process runs three phases sequentially — the
181
- * initial Stop hooks, then TaskCompleted hooks (per in-progress task owned
182
- * by the teammate), then TeammateIdle hooks — and the per-hook `timeout`
183
- * applies to the entire lifecycle. Under Claude Code's default (10 min),
184
- * a turn that leaves tasks in-progress (e.g. via the TaskList/TodoWrite
185
- * tool) can blow the budget and get killed, which also severs our
186
- * `_claude-stop-hook`'s queue/release poll and strands the workflow.
187
- *
188
- * ~24 days — the max safe `setTimeout` value (2^31 - 1 ms) expressed in
189
- * seconds — removes the timeout in practical terms. `waitForIdle`'s
190
- * marker-file watch still fires as soon as our initial hook writes the
191
- * marker, so the workflow proceeds on real hook completion, not on timer
192
- * expiry.
193
- */
194
- const STOP_HOOK_TIMEOUT_SECONDS = 2_147_483;
195
-
196
- /**
197
- * Effectively-unbounded ms ceiling for `waitForReadyMarker`. Mirrors
198
- * {@link STOP_HOOK_TIMEOUT_SECONDS} but expressed in ms for `setTimeout`.
199
- *
200
- * The SessionStart hook fires well under a second on a working spawn, so in
201
- * practice this timer never expires. It only protects against failure modes
202
- * where the hook will never fire at all (claude binary missing, hook
203
- * command not resolvable, settings JSON rejected), where a clear error
204
- * beats a hung pane.
205
- */
206
- const READY_HOOK_TIMEOUT_MS = 2_147_483_000;
207
-
208
- /**
209
- * Inline settings injected via `claude --settings <json>` on every workflow
210
- * spawn. Registers the workflow-owned hooks without relying on
211
- * `.claude/settings.json` — so the hooks fire only for workflow-spawned
212
- * Claude sessions, not when a user runs `claude` manually.
213
- *
214
- * Registered hooks:
215
- * - `Stop`: deliver queued follow-up prompts via `{decision:"block"}` and
216
- * write an idle-marker file that `waitForIdle` watches. `timeout` is
217
- * set to {@link STOP_HOOK_TIMEOUT_SECONDS} so the hook survives long
218
- * TaskCompleted/TeammateIdle phases — see the constant's docstring.
219
- * - `PreToolUse` matched on `AskUserQuestion`: write
220
- * `~/.atomic/claude-hil/<session_id>` so `watchHILMarker` can fire
221
- * `onHIL(true)` — the node card flips to the blue "awaiting_input" pulse.
222
- * - `PostToolUse` / `PostToolUseFailure` matched on `AskUserQuestion`:
223
- * remove the HIL marker. Claude Code fires exactly one of these per
224
- * tool invocation (PostToolUse on success, PostToolUseFailure in the
225
- * catch path — see `src/services/tools/toolExecution.ts` in the CLI
226
- * source), so registering the same command on both guarantees the
227
- * marker clears regardless of which completion path the tool takes.
228
- * - `SubagentStart` / `SubagentStop`: maintain a per-root-session marker
229
- * dir under `~/.atomic/claude-inflight/<root>/` so the Stop hook and
230
- * `clearClaudeSession` can both gate on subagent completion before
231
- * letting the stage advance. Without this gate, a stage that spawned
232
- * `run_in_background: true` subagents would tear down its pane while
233
- * children still hold FDs/PTYs on the atomic tmux server, intermittently
234
- * surfacing as `tmux respawn-pane: fork failed: Device not configured`
235
- * when the next stage tried to spawn.
236
- * - `TeammateIdle`: same gating applied at agent-team teammate idle.
237
- * Unlike Stop, this fires when a teammate (potentially a different
238
- * `session_id` from the stage's root) goes idle, so we route it to a
239
- * focused `_claude-inflight-hook wait` mode that only awaits in-flight
240
- * drain — no claude-stop marker write (that would confuse `waitForIdle`)
241
- * and no queue/release polling (those are keyed on the stage's root).
242
- *
243
- * Built once at module load. Contains no single quotes (JSON syntax doesn't
244
- * produce them and paths rarely do), so POSIX single-quoting at the spawn
245
- * site is sufficient shell escaping.
246
- */
247
- const WORKFLOW_HOOK_SETTINGS = JSON.stringify({
248
- hooks: {
249
- SessionStart: [
250
- {
251
- matcher: "startup",
252
- hooks: [
253
- {
254
- type: "command",
255
- command: buildWorkflowHookCommand("_claude-session-start-hook"),
256
- },
257
- ],
258
- },
259
- ],
260
- Stop: [
261
- {
262
- hooks: [
263
- {
264
- type: "command",
265
- command: buildWorkflowHookCommand("_claude-stop-hook"),
266
- timeout: STOP_HOOK_TIMEOUT_SECONDS,
267
- },
268
- ],
269
- },
270
- ],
271
- PreToolUse: [
272
- {
273
- matcher: "AskUserQuestion",
274
- hooks: [
275
- {
276
- type: "command",
277
- command: buildWorkflowHookCommand("_claude-ask-hook", ["enter"]),
278
- },
279
- ],
280
- },
281
- ],
282
- PostToolUse: [
283
- {
284
- matcher: "AskUserQuestion",
285
- hooks: [
286
- {
287
- type: "command",
288
- command: buildWorkflowHookCommand("_claude-ask-hook", ["exit"]),
289
- },
290
- ],
291
- },
292
- ],
293
- PostToolUseFailure: [
294
- {
295
- matcher: "AskUserQuestion",
296
- hooks: [
297
- {
298
- type: "command",
299
- command: buildWorkflowHookCommand("_claude-ask-hook", ["exit"]),
300
- },
301
- ],
302
- },
303
- ],
304
- // SubagentStart/SubagentStop fire per Agent-tool dispatch (no matcher)
305
- // and route to a single subcommand that touches/removes one marker file
306
- // per `agent_id`. The handler is bulletproof — any error exits 0
307
- // silently — so a hook failure can't kill the stage.
308
- SubagentStart: [
309
- {
310
- hooks: [
311
- {
312
- type: "command",
313
- command: buildWorkflowHookCommand("_claude-inflight-hook", ["start"]),
314
- },
315
- ],
316
- },
317
- ],
318
- SubagentStop: [
319
- {
320
- hooks: [
321
- {
322
- type: "command",
323
- command: buildWorkflowHookCommand("_claude-inflight-hook", ["stop"]),
324
- },
325
- ],
326
- },
327
- ],
328
- // TeammateIdle gets a focused `wait` mode (gates on in-flight drain,
329
- // nothing else) — see the WORKFLOW_HOOK_SETTINGS docstring for why this
330
- // doesn't reuse the Stop hook handler. Timeout matches Stop's so the
331
- // wait can run for as long as the workflow holds onto teammates.
332
- TeammateIdle: [
333
- {
334
- hooks: [
335
- {
336
- type: "command",
337
- command: buildWorkflowHookCommand("_claude-inflight-hook", ["wait"]),
338
- timeout: STOP_HOOK_TIMEOUT_SECONDS,
339
- },
340
- ],
341
- },
342
- ],
343
- },
344
- });
345
-
346
- // ---------------------------------------------------------------------------
347
- // createClaudeSession
348
- // ---------------------------------------------------------------------------
349
-
350
- export interface ClaudeSessionOptions {
351
- /** tmux pane ID where Claude should be started */
352
- paneId: string;
353
- /** CLI flags to pass to the `claude` command (default: ["--allow-dangerously-skip-permissions", "--dangerously-skip-permissions"]) */
354
- chatFlags?: string[];
355
- }
356
-
357
- /**
358
- * Initialize per-pane Claude state. Does NOT spawn the `claude` CLI — the
359
- * pane is left as a bare shell. The CLI is spawned lazily on the first
360
- * `claudeQuery()` call, with the prompt baked into the spawn command:
361
- *
362
- * claude [chatFlags] --session-id <UUID> 'Read the prompt in <tmpfile>'
363
- *
364
- * Pre-generating the session UUID here lets the first query pass it to the
365
- * CLI, so we know the JSONL filename up front and can skip discovery polling.
366
- *
367
- * Must be called before any `claudeQuery()` calls targeting the same pane.
368
- *
369
- * @example
370
- * ```typescript
371
- * import { createClaudeSession, claudeQuery } from "@bastani/atomic/workflows";
372
- *
373
- * await createClaudeSession({ paneId: ctx.paneId });
374
- * await claudeQuery({ paneId: ctx.paneId, prompt: "Describe this project" });
375
- * ```
376
- *
377
- * @example
378
- * ```typescript
379
- * // With custom flags
380
- * await createClaudeSession({
381
- * paneId: ctx.paneId,
382
- * chatFlags: ["--model", "opus", "--dangerously-skip-permissions"],
383
- * });
384
- * ```
385
- */
386
- export async function createClaudeSession(options: ClaudeSessionOptions): Promise<string> {
387
- const { paneId, chatFlags = DEFAULT_CHAT_FLAGS } = options;
388
-
389
- const claudeSessionId = randomUUID();
390
- initializedPanes.set(paneId, {
391
- claudeSessionId,
392
- claudeStarted: false,
393
- chatFlags,
394
- });
395
-
396
- // Write our PID so the Stop hook can detect an orphaned session if we
397
- // crash/get SIGKILL'd without running teardown. Best-effort; failures just
398
- // mean the hook falls back to waiting out Claude's own hook timeout.
399
- await writeAtomicPidFile(claudeSessionId);
400
-
401
- return claudeSessionId;
402
- }
403
-
404
- /**
405
- * Build the short, single-line natural-language prompt we send to Claude
406
- * (either as spawn argv or as a follow-up message). Claude's first action
407
- * is then a Read tool call against `promptFile` — which sidesteps shell
408
- * escaping, ARG_MAX, and tmux paste-buffer flakiness for large prompts.
409
- *
410
- * The session dir and filename are slug-based (`prompt-<N>.txt` under
411
- * `~/.atomic/sessions/...`), so they never contain shell-special characters.
412
- */
413
- function readPromptInstruction(promptFile: string): string {
414
- return `Read ${promptFile} and follow the instructions inside.`;
415
- }
416
-
417
- /**
418
- * Spawn `claude` in the pane with the prompt baked in via the Read tool.
419
- *
420
- * The prompt is already written to `promptFile` by the caller. The spawn
421
- * argv is `'Read the prompt in <path>'`, so Claude's first action is a Read
422
- * tool call against that file.
423
- */
424
- async function spawnClaudeWithPrompt(
425
- paneId: string,
426
- promptFile: string,
427
- chatFlags: string[],
428
- sessionId: string,
429
- ): Promise<void> {
430
- const settingsPath = workflowHookSettingsPath();
431
- const argvPrompt = `"${escBash(readPromptInstruction(promptFile))}"`;
432
- const cmd = [
433
- "claude",
434
- ...chatFlags,
435
- // Workflow-owned hooks. Placed AFTER chatFlags so commander's last-wins
436
- // semantics shadow any user-provided --settings, making this
437
- // non-overridable by `.atomic/settings.json` chatFlags overrides. Passing
438
- // a path avoids Claude Code's content-hashed /tmp/claude-settings*.json.
439
- "--settings",
440
- `"${escBash(settingsPath)}"`,
441
- "--session-id",
442
- sessionId,
443
- argvPrompt,
444
- ].join(" ");
445
-
446
- // Replace the pane's shell with `claude` directly. tmux execs the command
447
- // itself, so there's no shell line editor to race with — the previous
448
- // approach keystroked into a zsh that hadn't finished ZLE init yet, and
449
- // zsh's TCSAFLUSH during startup would discard the buffered `\r`, leaving
450
- // the command typed at the prompt but never submitted.
451
- respawnPane(paneId, cmd);
452
-
453
- // Positive readiness signal: wait for Claude's SessionStart hook (matcher
454
- // `startup`) to write `~/.atomic/claude-ready/<session_id>`. This fires
455
- // before Claude writes the JSONL transcript, so it beats the old
456
- // transcript-file race and is deterministic.
457
- await waitForReadyMarker(sessionId);
458
- }
459
-
460
- function workflowHookSettingsPath(): string {
461
- const path = atomicContentTempPath(
462
- "claude-settings-atomic",
463
- ".json",
464
- WORKFLOW_HOOK_SETTINGS,
465
- );
466
- writeFileSync(path, WORKFLOW_HOOK_SETTINGS, {
467
- encoding: "utf-8",
468
- mode: 0o600,
469
- });
470
- return path;
471
- }
472
-
473
- /**
474
- * Wait for the SessionStart hook's ready marker at
475
- * `~/.atomic/claude-ready/<session_id>`.
476
- *
477
- * `atomic _claude-session-start-hook` is registered in
478
- * {@link WORKFLOW_HOOK_SETTINGS} with matcher `startup`; the Claude CLI
479
- * dispatches it during spawn, before the first API call and before the JSONL
480
- * transcript is created. Waiting on the resulting marker file gives us a
481
- * positive "Claude is alive" signal instead of racing the transcript writer.
482
- *
483
- * The timeout only fires on catastrophic startup failure (bad binary, exec
484
- * error) — under load, Claude's own session bootstrap runs well under the
485
- * limit because SessionStart is dispatched early in the startup sequence.
486
- */
487
- async function waitForReadyMarker(sessionId: string): Promise<void> {
488
- const { ready: readyDir } = claudeHookDirs();
489
- await mkdir(readyDir, { recursive: true });
490
- const target = join(readyDir, sessionId);
491
-
492
- if (existsSync(target)) return;
493
-
494
- const ac = new AbortController();
495
- const timeout = setTimeout(() => ac.abort(), READY_HOOK_TIMEOUT_MS);
496
-
497
- try {
498
- await Promise.race([
499
- // fs.watch — instant OS-native notification when the hook writes the file
500
- (async (): Promise<void> => {
501
- try {
502
- for await (const _event of watch(readyDir, { signal: ac.signal })) {
503
- // Trust disk state, not event.filename (Linux can deliver
504
- // unexpected basenames under tmp+rename writes).
505
- if (existsSync(target)) return;
506
- }
507
- } catch (e: unknown) {
508
- if (e instanceof Error && e.name === "AbortError") throw e;
509
- }
510
- return new Promise<void>(() => {});
511
- })(),
512
-
513
- // Polling fallback — catches dropped inotify/FSEvent notifications
514
- (async (): Promise<void> => {
515
- while (!ac.signal.aborted) {
516
- if (existsSync(target)) return;
517
- await Bun.sleep(250);
518
- }
519
- throw new DOMException("Aborted", "AbortError");
520
- })(),
521
- ]);
522
- } catch (e: unknown) {
523
- if (e instanceof DOMException && e.name === "AbortError") {
524
- throw new Error(
525
- `Timed out waiting for Claude SessionStart hook to signal readiness ` +
526
- `at ${target}. Verify the \`claude\` command started successfully.`,
527
- );
528
- }
529
- throw e;
530
- } finally {
531
- clearTimeout(timeout);
532
- ac.abort();
533
- }
534
- }
535
-
536
- // ---------------------------------------------------------------------------
537
- // HIL detection helpers
538
- // ---------------------------------------------------------------------------
539
-
540
- /**
541
- * Returns true when the most recent assistant message in the transcript
542
- * ended with `stop_reason: "tool_use"` — i.e. the agent stopped the current
543
- * API response to call a tool but has not yet produced its post-tool answer.
544
- *
545
- * Claude Code's Stop hook fires each time Claude "finishes responding",
546
- * which includes intermediate tool-use responses in a multi-step agent
547
- * loop (not just the final `end_turn`). If we return from `waitForIdle`
548
- * on the first Stop event, we capture the transcript mid-loop — the
549
- * final assistant text block is still being generated and won't be on
550
- * disk yet, so `inbox.md` drops the actual answer.
551
- *
552
- * We keep watching until we see an assistant message with a terminal
553
- * stop_reason (`end_turn`, `max_tokens`, `stop_sequence`, `refusal`),
554
- * which is the real end of the turn.
555
- *
556
- * Exported as `_isMidAgentLoop` for unit testing.
557
- */
558
- export function _isMidAgentLoop(messages: SessionMessage[]): boolean {
559
- for (let i = messages.length - 1; i >= 0; i--) {
560
- const msg = messages[i];
561
- if (msg?.type !== "assistant") continue;
562
- const inner = msg.message as { stop_reason?: unknown } | null;
563
- const stopReason = inner?.stop_reason;
564
- return stopReason === "tool_use";
565
- }
566
- // No assistant message yet — treat as mid-loop so we wait for one.
567
- return true;
568
- }
569
-
570
- /**
571
- * Watch `~/.atomic/claude-hil/` for this session's marker file and fire
572
- * `onHIL(true|false)` on create/unlink. Returns when `signal` is aborted.
573
- *
574
- * The marker is written by the `_claude-ask-hook enter` subcommand from
575
- * Claude Code's `PreToolUse` hook (matched on `AskUserQuestion`) and removed
576
- * by `_claude-ask-hook exit` from `PostToolUse` / `PostToolUseFailure`. That
577
- * makes the signal deterministic and independent of Claude Code's batched
578
- * JSONL flush timing, which used to hide the HIL window entirely when
579
- * tool_use and tool_result landed in the same file write.
580
- *
581
- * @internal Exported for tests.
582
- */
583
- export async function watchHILMarker(
584
- claudeSessionId: string,
585
- onHIL: (waiting: boolean) => void,
586
- signal: AbortSignal,
587
- ): Promise<void> {
588
- const { hil: dir } = claudeHookDirs();
589
- const target = join(dir, claudeSessionId);
590
-
591
- await mkdir(dir, { recursive: true });
592
-
593
- let wasHIL = false;
594
- const emit = (isHIL: boolean): void => {
595
- if (isHIL !== wasHIL) {
596
- onHIL(isHIL);
597
- wasHIL = isHIL;
598
- }
599
- };
600
-
601
- // Attach the watcher BEFORE the initial existsSync so any event that fires
602
- // during the check is buffered by the iterator instead of being dropped.
603
- const watcher = watch(dir, { signal });
604
-
605
- // Polling fallback: Bun/inotify can drop events under heavy fs load, which
606
- // would leave the UI stuck on (or off) the blue "awaiting_input" pulse.
607
- // A cheap periodic existsSync guarantees eventual consistency. `emit` is
608
- // guarded by `wasHIL` so the interval is idempotent w.r.t. the watcher.
609
- const poll = setInterval(() => emit(existsSync(target)), 250);
610
-
611
- // Initial existsSync: handles resumed sessions whose PreToolUse marker was
612
- // already on disk before the watcher attached.
613
- if (existsSync(target)) emit(true);
614
-
615
- try {
616
- for await (const _event of watcher) {
617
- // Don't trust event.filename — Bun/Linux deliver inconsistent basenames
618
- // across OSes and write patterns. Disk existence is authoritative.
619
- emit(existsSync(target));
620
- }
621
- } catch (e: unknown) {
622
- if (!(e instanceof Error && e.name === "AbortError")) {
623
- throw e;
624
- }
625
- } finally {
626
- clearInterval(poll);
627
- }
628
- }
629
-
630
- // ---------------------------------------------------------------------------
631
- // Helpers
632
- // ---------------------------------------------------------------------------
633
-
634
- /**
635
- * Path of the directory where the claude-stop-hook writes marker files.
636
- * Each Claude turn creates `~/.atomic/claude-stop/<session_id>` which
637
- * triggers the `fs.watch` event in `waitForIdle`.
638
- *
639
- * @internal Exported for unit tests.
640
- */
641
- export function markerDir(): string {
642
- return claudeHookDirs().marker;
643
- }
644
-
645
- /**
646
- * Return the marker file path for a given Claude session ID.
647
- *
648
- * @internal Exported for unit tests.
649
- */
650
- export function markerPath(claudeSessionId: string): string {
651
- return join(markerDir(), claudeSessionId);
652
- }
653
-
654
- /**
655
- * Directory where the workflow runtime writes queued follow-up prompts that
656
- * `atomic _claude-stop-hook` picks up and feeds back to Claude as
657
- * `{decision:"block", reason:<prompt>}`. @internal Exported for unit tests.
658
- */
659
- export function queueDir(): string {
660
- return claudeHookDirs().queue;
661
- }
662
-
663
- /** Return the queue file path for a given Claude session ID. @internal */
664
- export function queuePath(claudeSessionId: string): string {
665
- return join(queueDir(), claudeSessionId);
666
- }
667
-
668
- /**
669
- * Directory where the runtime writes session-release signals. When the Stop
670
- * hook sees `~/.atomic/claude-release/<session_id>` it exits 0 without
671
- * emitting a block decision — the signal used by `clearClaudeSession` to
672
- * tell Claude it's safe to actually stop. @internal Exported for unit tests.
673
- */
674
- export function releaseDir(): string {
675
- return claudeHookDirs().release;
676
- }
677
-
678
- /** Return the release file path for a given Claude session ID. @internal */
679
- export function releasePath(claudeSessionId: string): string {
680
- return join(releaseDir(), claudeSessionId);
681
- }
682
-
683
- /**
684
- * Ensure the marker directory exists and remove any stale marker left from a
685
- * previous turn of this session. Call this BEFORE submitting the prompt so
686
- * the subsequent `waitForIdle` watch loop doesn't fire on a stale file.
687
- *
688
- * Ignores ENOENT on `unlink` — the file simply doesn't exist yet.
689
- */
690
- async function clearStaleMarker(claudeSessionId: string): Promise<void> {
691
- await mkdir(markerDir(), { recursive: true });
692
- try {
693
- await unlink(markerPath(claudeSessionId));
694
- } catch (e: unknown) {
695
- // ENOENT is expected — ignore it; rethrow anything else
696
- if (!(e instanceof Error && "code" in e && (e as NodeJS.ErrnoException).code === "ENOENT")) {
697
- throw e;
698
- }
699
- }
700
- }
701
-
702
- /**
703
- * Ensure the queue directory exists and remove any stale entry from a prior
704
- * turn so the Stop hook doesn't race on it. Ignores ENOENT.
705
- */
706
- async function clearStaleQueue(claudeSessionId: string): Promise<void> {
707
- await mkdir(queueDir(), { recursive: true });
708
- try {
709
- await unlink(queuePath(claudeSessionId));
710
- } catch (e: unknown) {
711
- if (!(e instanceof Error && "code" in e && (e as NodeJS.ErrnoException).code === "ENOENT")) {
712
- throw e;
713
- }
714
- }
715
- }
716
-
717
- /**
718
- * Remove a stale HIL marker left over from a prior turn (e.g. the ask-hook
719
- * process was SIGKILL'd between PreToolUse and PostToolUse). Without this,
720
- * `watchHILMarker`'s initial `existsSync` would spuriously fire `onHIL(true)`
721
- * at the start of a fresh turn. Ignores ENOENT.
722
- */
723
- async function clearStaleHILMarker(claudeSessionId: string): Promise<void> {
724
- const { hil } = claudeHookDirs();
725
- await mkdir(hil, { recursive: true });
726
- try {
727
- await unlink(join(hil, claudeSessionId));
728
- } catch (e: unknown) {
729
- if (!(e instanceof Error && "code" in e && (e as NodeJS.ErrnoException).code === "ENOENT")) {
730
- throw e;
731
- }
732
- }
733
- }
734
-
735
- /**
736
- * Remove a stale ready marker from a prior session that reused this UUID (in
737
- * practice impossible — UUIDs are fresh per session — but cheap insurance so
738
- * `waitForReadyMarker`'s initial existsSync can't false-positive on anything
739
- * we left behind). Ignores ENOENT.
740
- */
741
- async function clearStaleReadyMarker(claudeSessionId: string): Promise<void> {
742
- const { ready } = claudeHookDirs();
743
- await mkdir(ready, { recursive: true });
744
- try {
745
- await unlink(join(ready, claudeSessionId));
746
- } catch (e: unknown) {
747
- if (!(e instanceof Error && "code" in e && (e as NodeJS.ErrnoException).code === "ENOENT")) {
748
- throw e;
749
- }
750
- }
751
- }
752
-
753
- /**
754
- * Write the next prompt to the session queue file. The currently-running
755
- * Stop hook process (blocked on poll from the previous turn) picks it up,
756
- * emits `{decision:"block", reason:<prompt>}` on stdout, and Claude feeds
757
- * it back as the next user message — no tmux keystrokes required.
758
- */
759
- async function enqueuePrompt(claudeSessionId: string, prompt: string): Promise<void> {
760
- await mkdir(queueDir(), { recursive: true });
761
- await writeFile(queuePath(claudeSessionId), prompt, "utf-8");
762
- }
763
-
764
- /**
765
- * Signal the Stop hook's blocking wait that this session is done. Called
766
- * during session teardown so the final hook invocation exits 0 promptly.
767
- * Safe to call more than once.
768
- */
769
- export async function releaseClaudeSession(claudeSessionId: string): Promise<void> {
770
- await mkdir(releaseDir(), { recursive: true });
771
- await writeFile(releasePath(claudeSessionId), "");
772
- }
773
-
774
- /** @internal */
775
- function pidDir(): string {
776
- return claudeHookDirs().pid;
777
- }
778
-
779
- /** @internal */
780
- function pidFilePath(claudeSessionId: string): string {
781
- return join(pidDir(), claudeSessionId);
782
- }
783
-
784
- /**
785
- * Write `process.pid` to `~/.atomic/claude-pid/<session_id>` so the Stop hook
786
- * can use it as a liveness signal. If atomic is SIGKILL'd (no chance to run
787
- * `clearClaudeSession`), the hook detects the dead PID via `process.kill(..,0)`
788
- * and self-exits instead of parking Claude for the full 24-day timeout.
789
- */
790
- async function writeAtomicPidFile(claudeSessionId: string): Promise<void> {
791
- await mkdir(pidDir(), { recursive: true });
792
- await writeFile(pidFilePath(claudeSessionId), String(process.pid), "utf-8");
793
- }
794
-
795
- /** Remove the pid file for a session. Idempotent — ENOENT is swallowed. */
796
- async function unlinkAtomicPidFile(claudeSessionId: string): Promise<void> {
797
- try {
798
- await unlink(pidFilePath(claudeSessionId));
799
- } catch (e: unknown) {
800
- if (!(e instanceof Error && "code" in e && (e as NodeJS.ErrnoException).code === "ENOENT")) {
801
- throw e;
802
- }
803
- }
804
- }
805
-
806
- // ---------------------------------------------------------------------------
807
- // Idle detection via marker file watch
808
- // ---------------------------------------------------------------------------
809
-
810
- /**
811
- * Wait for the Claude session to become idle using `fs.watch` on the
812
- * `~/.atomic/claude-stop/` marker directory.
813
- *
814
- * When Claude finishes a turn, the `atomic _claude-stop-hook` Stop hook writes
815
- * `~/.atomic/claude-stop/<session_id>`. The write triggers an OS-native
816
- * `fs.watch` event on the parent directory — far more reliable than polling
817
- * tmux pane glyphs, which vary between Claude Code versions.
818
- *
819
- * This function is strictly about *idle detection*. HIL is detected separately
820
- * by {@link watchHILMarker}; the Stop hook does not fire while
821
- * `AskUserQuestion` is pending (the agent loop blocks on deferred tools), so
822
- * mixing the two would silently miss the HIL window.
823
- *
824
- * Algorithm:
825
- * 1. Attach the directory watcher, then check for the marker file on disk —
826
- * this closes the race where the Stop hook fires between prompt submission
827
- * and watcher attach.
828
- * 2. On any event, re-check the marker file on disk (we intentionally do NOT
829
- * filter by `event.filename`, because on Linux a write can deliver multiple
830
- * events with varying filenames and editor tools may race us).
831
- * 3. Read the session transcript via `getSessionMessages` and slice messages
832
- * from `transcriptBeforeCount`.
833
- * 4. Clean up the `fs.watch` watcher on any exit path via AbortController.
834
- *
835
- * @param claudeSessionId - Claude's session UUID (used to identify marker file)
836
- * @param transcriptBeforeCount - number of messages in transcript before this turn
837
- */
838
- /**
839
- * @internal Exported for unit tests.
840
- */
841
- export async function waitForIdle(
842
- claudeSessionId: string,
843
- transcriptBeforeCount: number,
844
- ): Promise<SessionMessage[]> {
845
-
846
- const dir = markerDir();
847
- const sessionId = claudeSessionId;
848
- const target = markerPath(sessionId);
849
- const ac = new AbortController();
850
-
851
- // Process a marker that has appeared on disk. Returns a tuple:
852
- // [resolved, result] — when resolved=true, waitForIdle should return.
853
- const readMessages = async (): Promise<SessionMessage[] | null> => {
854
- try {
855
- return await getSessionMessages(sessionId, {
856
- dir: process.cwd(),
857
- includeSystemMessages: true,
858
- });
859
- } catch {
860
- return null;
861
- }
862
- };
863
-
864
- const handleMarker = async (): Promise<[boolean, SessionMessage[]]> => {
865
- let msgs = await readMessages();
866
- if (msgs === null) {
867
- // Transcript read failed — keep watching; the next event will retry.
868
- return [false, []];
869
- }
870
-
871
- // The Stop hook fires only once per agent loop completion (when there
872
- // are no more tool_use blocks to resolve — see Claude Code's
873
- // `src/query/stopHooks.ts` / `query.ts`: `if (!needsFollowUp)`). But
874
- // Claude Code writes to the JSONL transcript asynchronously via
875
- // `enqueueWrite()` with a batched ~100ms flush, so the final
876
- // `assistant[text]` message can still be in the page-cache when our
877
- // marker watcher fires. Reading the transcript at that moment races
878
- // the writer and returns a prefix ending at `user[tool_result]`.
879
- //
880
- // Because no further marker events are coming, we can't just "keep
881
- // watching the marker dir". Instead, poll the transcript file directly
882
- // until it either settles on a terminal stop_reason or the poll budget
883
- // expires. The budget covers Claude Code's flush interval plus headroom
884
- // for slow disks and buffered `fs/promises` writes.
885
- if (_isMidAgentLoop(msgs)) {
886
- const pollIntervalMs = 50;
887
- const pollBudgetMs = 3_000;
888
- const start = Date.now();
889
- while (_isMidAgentLoop(msgs) && Date.now() - start < pollBudgetMs) {
890
- await Bun.sleep(pollIntervalMs);
891
- const next = await readMessages();
892
- if (next) msgs = next;
893
- }
894
- // Whether we recovered or ran out of budget, fall through — returning
895
- // what we have beats hanging forever if the writer really did drop a
896
- // message (e.g. max-tokens collapse, abort mid-stream).
897
- }
898
-
899
- const sliced = msgs.length > transcriptBeforeCount
900
- ? msgs.slice(transcriptBeforeCount)
901
- : [];
902
- return [true, sliced];
903
- };
904
-
905
- try {
906
- // Attach the watcher FIRST; fs.watch returns an iterable whose underlying
907
- // inotify/FSEvent subscription is live from this point on.
908
- const watcher = watch(dir, { signal: ac.signal });
909
-
910
- // Close the race: if the Stop hook fired between clearStaleMarker() and
911
- // the watcher attach above, the marker is already on disk and no further
912
- // events will be emitted. Handle it synchronously.
913
- if (existsSync(target)) {
914
- const [done, result] = await handleMarker();
915
- if (done) {
916
- ac.abort();
917
- return result;
918
- }
919
- }
920
-
921
- for await (const _event of watcher) {
922
- // We don't trust event.filename — on Linux, a tmp+rename write emits
923
- // events with the `.tmp` basename, and other files in the marker dir
924
- // can race us. The marker file's existence on disk is authoritative.
925
- if (!existsSync(target)) continue;
926
-
927
- const [done, result] = await handleMarker();
928
- if (done) {
929
- ac.abort();
930
- return result;
931
- }
932
- }
933
- } catch (e: unknown) {
934
- // AbortError is expected when we call ac.abort() to stop watching.
935
- if (!(e instanceof Error && e.name === "AbortError")) {
936
- throw e;
937
- }
938
- }
939
-
940
- return [];
941
- }
942
-
943
- // ---------------------------------------------------------------------------
944
- // claudeQuery
945
- // ---------------------------------------------------------------------------
946
-
947
- export interface ClaudeQueryOptions {
948
- /** tmux pane ID where Claude is running */
949
- paneId: string;
950
- /** The prompt to send */
951
- prompt: string;
952
- /**
953
- * Called when the agent's human-in-the-loop state changes.
954
- * `waiting=true` → AskUserQuestion is pending (agent blocked on user input).
955
- * `waiting=false` → AskUserQuestion was resolved (agent resumed processing).
956
- */
957
- onHIL?: (waiting: boolean) => void;
958
- }
959
-
960
- /**
961
- * Extract text content from assistant messages in a transcript slice.
962
- *
963
- * Walks messages from `afterIndex` forward, pulls `TextBlock.text` from each
964
- * assistant message's content array, and joins them. The `message` payload is
965
- * `unknown` in the SDK type so we do runtime narrowing.
966
- *
967
- * Exported so workflow authors can extract text from `SessionMessage[]`
968
- * returned by `s.session.query()`.
969
- */
970
- export function extractAssistantText(
971
- msgs: ReadonlyArray<{ type: string; message: unknown }>,
972
- afterIndex: number,
973
- ): string {
974
- const parts: string[] = [];
975
- for (let i = afterIndex; i < msgs.length; i++) {
976
- const msg = msgs[i];
977
- if (!msg || msg.type !== "assistant") continue;
978
- const m = msg.message;
979
- if (!m || typeof m !== "object") continue;
980
- const content = (m as Record<string, unknown>).content;
981
- if (!Array.isArray(content)) continue;
982
- for (const block of content) {
983
- if (
984
- block &&
985
- typeof block === "object" &&
986
- (block as Record<string, unknown>).type === "text"
987
- ) {
988
- parts.push(String((block as Record<string, unknown>).text ?? ""));
989
- }
990
- }
991
- }
992
- return parts.join("\n");
993
- }
994
-
995
- /**
996
- * Send a prompt to a Claude Code interactive session running in a tmux pane.
997
- *
998
- * First query and follow-up queries use different delivery channels:
999
- *
1000
- * - **First query**: stages the prompt in a tmp file and spawns
1001
- * `claude --session-id <UUID> 'Read the prompt in <path>'` into the
1002
- * empty pane. Claude's first action is a Read tool call, which
1003
- * sidesteps ARG_MAX on the spawn argv.
1004
- *
1005
- * - **Follow-up query**: writes the prompt to
1006
- * `~/.atomic/claude-queue/<session_id>`. The Stop hook from the
1007
- * previous turn is blocked in a poll loop there; it reads the queue
1008
- * entry and emits `{"decision":"block","reason":<prompt>}` on stdout,
1009
- * which Claude Code feeds back as the next user message. No tmux
1010
- * keystrokes, no paste-buffer dance, no pane-state polling — the
1011
- * whole delivery rides Claude's own continuation API.
1012
- *
1013
- * Both paths converge on `waitForIdle`, which watches the Stop-hook marker
1014
- * file for this session and returns the transcript slice for the turn.
1015
- *
1016
- * @example
1017
- * ```typescript
1018
- * import { claudeQuery } from "@bastani/atomic/workflows";
1019
- *
1020
- * const result = await claudeQuery({
1021
- * paneId: ctx.paneId,
1022
- * prompt: "Describe this project",
1023
- * });
1024
- * ctx.log(result.output);
1025
- * ```
1026
- */
1027
- export async function claudeQuery(options: ClaudeQueryOptions): Promise<SessionMessage[]> {
1028
- const { paneId, prompt, onHIL } = options;
1029
-
1030
- const paneState = initializedPanes.get(paneId);
1031
- if (!paneState) {
1032
- throw new Error(
1033
- "claudeQuery() called without a prior createClaudeSession() for this pane. " +
1034
- "Call createClaudeSession({ paneId }) first to start the Claude CLI.",
1035
- );
1036
- }
1037
-
1038
- const dir = process.cwd();
1039
- const claudeSessionId = paneState.claudeSessionId;
1040
-
1041
- // Clear stale marker AND stale queue entry before submitting so the
1042
- // Stop-hook for the previous turn (if any) cannot race this one. The HIL
1043
- // marker is cleared too so a crashed ask-hook process from turn N-1 can't
1044
- // make `watchHILMarker`'s initial existsSync spuriously fire onHIL(true).
1045
- await clearStaleMarker(claudeSessionId);
1046
- await clearStaleQueue(claudeSessionId);
1047
- await clearStaleHILMarker(claudeSessionId);
1048
- await clearStaleReadyMarker(claudeSessionId);
1049
-
1050
- let transcriptBeforeCount = 0;
1051
- let spawnPromptFile: string | undefined;
1052
-
1053
- try {
1054
- if (paneState.claudeStarted) {
1055
- // Follow-up query: snapshot the transcript length so waitForIdle can
1056
- // slice out the messages produced by THIS turn, then enqueue the
1057
- // prompt for the Stop hook to pick up.
1058
- try {
1059
- const msgs = await getSessionMessages(claudeSessionId, {
1060
- dir,
1061
- includeSystemMessages: true,
1062
- });
1063
- transcriptBeforeCount = msgs.length;
1064
- } catch {
1065
- // Best-effort — 0 means we scan all messages (correct, slightly less efficient)
1066
- }
1067
-
1068
- await enqueuePrompt(claudeSessionId, prompt);
1069
- } else {
1070
- // First query: spawn claude with the prompt baked into argv via the
1071
- // Read-tool indirection. The tmp file only has to live long enough
1072
- // for Claude's first Read tool call, so we delete it once waitForIdle
1073
- // returns (the turn is complete by then).
1074
- spawnPromptFile = atomicTempPath(
1075
- "atomic-claude-prompt",
1076
- ".txt",
1077
- `${claudeSessionId}-${randomUUID()}`,
1078
- );
1079
- writeFileSync(spawnPromptFile, prompt, {
1080
- encoding: "utf-8",
1081
- mode: 0o600,
1082
- });
1083
-
1084
- await spawnClaudeWithPrompt(
1085
- paneId,
1086
- spawnPromptFile,
1087
- paneState.chatFlags,
1088
- claudeSessionId,
1089
- );
1090
- paneState.claudeStarted = true;
1091
- }
1092
-
1093
- // HIL detection runs in parallel with idle detection. The
1094
- // PreToolUse/PostToolUse/PostToolUseFailure hooks on `AskUserQuestion`
1095
- // write/remove `~/.atomic/claude-hil/<session_id>`; we watch that dir
1096
- // for create/unlink events so HIL state is deterministic and immune to
1097
- // Claude Code's batched JSONL flush timing.
1098
- const hilAc = new AbortController();
1099
- if (onHIL) {
1100
- void watchHILMarker(claudeSessionId, onHIL, hilAc.signal).catch(() => {
1101
- // Best-effort — never fail the query over HIL detection.
1102
- });
1103
- }
1104
-
1105
- try {
1106
- return await waitForIdle(claudeSessionId, transcriptBeforeCount);
1107
- } finally {
1108
- hilAc.abort();
1109
- // Safety: waitForIdle only returns at true turn-idle. If the ask-hook
1110
- // process crashed mid-turn and left the marker on disk, the UI could
1111
- // be stuck on awaiting_input. `resumeSession` in the panel store is
1112
- // idempotent (no-op when the session isn't in awaiting_input), so
1113
- // this is always safe.
1114
- onHIL?.(false);
1115
- }
1116
- } finally {
1117
- if (spawnPromptFile) {
1118
- try {
1119
- await unlink(spawnPromptFile);
1120
- } catch {
1121
- // ENOENT / already removed is fine.
1122
- }
1123
- }
1124
- }
1125
- }
1126
-
1127
- // ---------------------------------------------------------------------------
1128
- // Synthetic wrappers — uniform s.client / s.session API for Claude stages
1129
- // ---------------------------------------------------------------------------
1130
-
1131
- /**
1132
- * Merge two `disallowedTools` lists, preserving caller entries and appending
1133
- * any extras that aren't already present. Exported for unit testing.
1134
- */
1135
- export function mergeDisallowedTools(
1136
- existing: string[] | undefined,
1137
- extras: string[],
1138
- ): string[] {
1139
- const merged = [...(existing ?? [])];
1140
- for (const tool of extras) {
1141
- if (!merged.includes(tool)) merged.push(tool);
1142
- }
1143
- return merged;
1144
- }
1145
-
1146
- /**
1147
- * Fold the atomic-managed additional instructions into a caller's
1148
- * `systemPrompt` value. Behavior, in order of precedence:
1149
- *
1150
- * - **No caller value** → return a `claude_code` preset with our content
1151
- * in `append`. Preserves the SDK's full Claude Code persona.
1152
- * - **Caller passed a preset object** → concatenate our content onto the
1153
- * existing `append` (newline-separated when both are present).
1154
- * - **Caller passed a custom string or array** → leave it alone. The
1155
- * caller has explicitly opted into a custom prompt, and silently
1156
- * prepending the persona-style preset text would break that contract.
1157
- *
1158
- * Exported for unit testing.
1159
- */
1160
- export function mergeSystemPromptAppend(
1161
- existing: SDKOptions["systemPrompt"],
1162
- extra: string,
1163
- ): SDKOptions["systemPrompt"] {
1164
- if (!extra) return existing;
1165
- if (existing === undefined) {
1166
- return { type: "preset", preset: "claude_code", append: extra };
1167
- }
1168
- if (typeof existing === "object" && !Array.isArray(existing) && existing.type === "preset") {
1169
- const prevAppend = existing.append ?? "";
1170
- const merged = prevAppend ? `${prevAppend}\n\n${extra}` : extra;
1171
- return { ...existing, append: merged };
1172
- }
1173
- return existing;
1174
- }
1175
-
1176
- /**
1177
- * Synthetic client wrapper for Claude stages.
1178
- * Auto-starts the Claude CLI in the tmux pane during `start()`.
1179
- */
1180
- export class ClaudeClientWrapper {
1181
- readonly paneId: string;
1182
- private readonly opts: { chatFlags?: string[] };
1183
-
1184
- constructor(
1185
- paneId: string,
1186
- opts: { chatFlags?: string[] } = {},
1187
- ) {
1188
- this.paneId = paneId;
1189
- this.opts = opts;
1190
- }
1191
-
1192
- /**
1193
- * Start the Claude CLI in the tmux pane. Returns the Claude session UUID
1194
- * so the caller can pass it to `ClaudeSessionWrapper` (and thus expose it
1195
- * as `s.sessionId` to workflows). This is the UUID used by Claude Code to
1196
- * name its JSONL transcript file and to key the Stop-hook marker — workflows
1197
- * pass it to `s.save(s.sessionId)` so the save path reads the correct
1198
- * transcript even when many Claude sessions run in parallel.
1199
- */
1200
- async start(): Promise<string> {
1201
- return await createClaudeSession({
1202
- paneId: this.paneId,
1203
- chatFlags: this.opts.chatFlags,
1204
- });
1205
- }
1206
-
1207
- /** Noop — cleanup is handled by the runtime via `clearClaudeSession`. */
1208
- async stop(): Promise<void> {}
1209
- }
1210
-
1211
- /**
1212
- * Synthetic session wrapper for Claude stages.
1213
- * Wraps `claudeQuery()` so users call `s.session.query(prompt)`.
1214
- */
1215
- export class ClaudeSessionWrapper {
1216
- readonly paneId: string;
1217
- readonly sessionId: string;
1218
- private readonly onHIL: ((waiting: boolean) => void) | undefined;
1219
-
1220
- constructor(
1221
- paneId: string,
1222
- sessionId: string,
1223
- onHIL?: (waiting: boolean) => void,
1224
- ) {
1225
- this.paneId = paneId;
1226
- this.sessionId = sessionId;
1227
- this.onHIL = onHIL;
1228
- }
1229
-
1230
- /**
1231
- * Send a prompt to Claude and wait for the response.
1232
- *
1233
- * The `_options` parameter exists for signature compatibility with
1234
- * {@link HeadlessClaudeSessionWrapper#query} (which forwards SDK options
1235
- * like `agent`, `permissionMode`, etc. to the Agent SDK). In the
1236
- * interactive pane path these options don't apply — we're driving the
1237
- * `claude` CLI binary, not the SDK — so they are silently ignored.
1238
- */
1239
- async query(
1240
- prompt: string,
1241
- _options?: Partial<SDKOptions>,
1242
- ): Promise<SessionMessage[]> {
1243
- return claudeQuery({
1244
- paneId: this.paneId,
1245
- prompt,
1246
- onHIL: this.onHIL,
1247
- });
1248
- }
1249
-
1250
- /**
1251
- * Structured output is only produced by the Agent SDK's `result` message,
1252
- * which interactive stages don't consume (they drive the `claude` CLI via
1253
- * tmux, not the SDK). Always `undefined` here — pair `outputFormat` with a
1254
- * headless stage to read {@link HeadlessClaudeSessionWrapper#lastStructuredOutput}.
1255
- */
1256
- get lastStructuredOutput(): unknown {
1257
- return undefined;
1258
- }
1259
-
1260
- /** Noop — for API symmetry with CopilotSession.disconnect(). */
1261
- async disconnect(): Promise<void> {}
1262
- }
1263
-
1264
- // ---------------------------------------------------------------------------
1265
- // Headless wrappers — use the Agent SDK directly (no tmux pane)
1266
- // ---------------------------------------------------------------------------
1267
-
1268
- /**
1269
- * Headless client wrapper for Claude stages. No tmux pane — noop start/stop.
1270
- * Used when `options.headless` is true in `ctx.stage()`.
1271
- */
1272
- export class HeadlessClaudeClientWrapper {
1273
- /**
1274
- * Headless Claude stages don't pre-allocate a session — each `query()` call
1275
- * to {@link HeadlessClaudeSessionWrapper} spawns a fresh Agent SDK run that
1276
- * emits its own `session_id`. We still return an empty string here so the
1277
- * method signature matches {@link ClaudeClientWrapper#start}.
1278
- */
1279
- async start(): Promise<string> {
1280
- return "";
1281
- }
1282
- async stop(): Promise<void> {}
1283
- }
1284
-
1285
- /**
1286
- * Resolve the `claude` CLI binary for headless SDK queries.
1287
- *
1288
- * Pins the SDK to the same binary interactive stages already spawn via tmux
1289
- * (`AGENT_CONFIG.claude.cmd` on PATH), bypassing
1290
- * `@anthropic-ai/claude-agent-sdk`'s built-in resolver. That resolver probes
1291
- * optional native packages in a fixed order — on Linux it tries
1292
- * `linux-${arch}-musl` before `linux-${arch}` and returns whichever
1293
- * `require.resolve` finds first — so on a glibc host where both optional
1294
- * packages got installed (Bun installs every optionalDependency by default)
1295
- * it picks the musl binary, which can't exec because its dynamic linker
1296
- * (`/lib/ld-musl-*.so.1`) is absent. The SDK surfaces the resulting ENOENT
1297
- * as a misleading "Claude Code native binary not found" error.
1298
- *
1299
- * `chatCommand` and `workflowCommand` already fail fast when `claude` isn't
1300
- * on PATH (see `isCommandInstalled` in each), so in practice this lookup
1301
- * always succeeds. The throw here is a belt-and-suspenders guard that
1302
- * prefers a clear failure over silently falling back to the SDK's resolver.
1303
- */
1304
- export function resolveHeadlessClaudeBin(): string {
1305
- // Pass PATH explicitly — the 1-arg form of Bun.which caches the value
1306
- // captured at process start, which makes the lookup insensitive to later
1307
- // env mutations (and un-exercisable from tests that tweak `process.env.PATH`).
1308
- const onPath = Bun.which("claude", { PATH: process.env.PATH ?? "" });
1309
- if (!onPath) {
1310
- throw new Error(
1311
- "`claude` CLI not found on PATH. Install Claude Code via the native " +
1312
- "installer (https://docs.claude.com/en/docs/claude-code/overview) " +
1313
- "and retry.",
1314
- );
1315
- }
1316
- return onPath;
1317
- }
1318
-
1319
- /**
1320
- * Headless session wrapper for Claude stages. Uses the Agent SDK's `query()`
1321
- * directly instead of tmux pane operations. Implements the same `query()`
1322
- * interface as {@link ClaudeSessionWrapper} so workflow callbacks work
1323
- * identically for headless and interactive stages.
1324
- *
1325
- * The `query()` method accepts the full Agent SDK parameter types —
1326
- * `prompt` can be a plain string or an `AsyncIterable<SDKUserMessage>`
1327
- * for multi-turn streaming, and `options` passes through SDK-level
1328
- * configuration (abort controllers, allowed tools, agents, etc.).
1329
- */
1330
- export class HeadlessClaudeSessionWrapper {
1331
- readonly paneId = "";
1332
- /**
1333
- * Project root the workflow is operating against. Used to resolve
1334
- * project-scoped config (e.g. `additional-instructions`) against the
1335
- * workflow's actual root rather than `process.cwd()`, which can drift
1336
- * when workflows are invoked programmatically or from a subdirectory.
1337
- */
1338
- private readonly _projectRoot: string;
1339
- /**
1340
- * The Claude session UUID of the most recently completed `query()`. Exposed
1341
- * via `s.sessionId` so workflows can pass it to `s.save(s.sessionId)` and
1342
- * have the save path read the correct transcript, even when several headless
1343
- * Claude stages run in parallel (each call gets its own SDK-assigned UUID).
1344
- */
1345
- private _lastSessionId: string = "";
1346
-
1347
- constructor(projectRoot: string) {
1348
- this._projectRoot = projectRoot;
1349
- }
1350
- /**
1351
- * Validated structured output captured from the most recent `query()`'s
1352
- * `result` message. Populated only when callers pass
1353
- * `options.outputFormat = { type: "json_schema", schema }` and the SDK
1354
- * produced a `subtype: "success"` result with `structured_output` attached.
1355
- * Remains `undefined` on plain text runs or when the SDK fails validation
1356
- * (`error_max_structured_output_retries`).
1357
- */
1358
- private _lastStructuredOutput: unknown = undefined;
1359
-
1360
- get sessionId(): string {
1361
- return this._lastSessionId;
1362
- }
1363
-
1364
- get lastStructuredOutput(): unknown {
1365
- return this._lastStructuredOutput;
1366
- }
1367
-
1368
- async query(
1369
- prompt: string | AsyncIterable<SDKUserMessage>,
1370
- options?: Partial<SDKOptions>,
1371
- ): Promise<SessionMessage[]> {
1372
- // Auto-deny the `AskUserQuestion` tool in headless runs. Without this, the
1373
- // agent can call it and the SDK query will sit blocked forever since no
1374
- // human is attached to answer.
1375
- const sdkOpts = options ?? {};
1376
- const additional = await resolveAdditionalInstructionsContent(this._projectRoot);
1377
- const headlessSdkOpts: Partial<SDKOptions> = {
1378
- ...sdkOpts,
1379
- pathToClaudeCodeExecutable:
1380
- sdkOpts.pathToClaudeCodeExecutable ?? resolveHeadlessClaudeBin(),
1381
- disallowedTools: mergeDisallowedTools(sdkOpts.disallowedTools, [
1382
- "AskUserQuestion",
1383
- ]),
1384
- ...(additional
1385
- ? { systemPrompt: mergeSystemPromptAppend(sdkOpts.systemPrompt, additional) }
1386
- : {}),
1387
- };
1388
-
1389
- let sdkSessionId = "";
1390
- let structuredOutput: unknown = undefined;
1391
- try {
1392
- await withAtomicTempEnv(async () => {
1393
- for await (const msg of sdkQuery({ prompt, options: headlessSdkOpts })) {
1394
- if (msg.type === "result") {
1395
- const record = msg as Record<string, unknown>;
1396
- sdkSessionId = String(record.session_id ?? "");
1397
- if (record.subtype === "success" && "structured_output" in record) {
1398
- structuredOutput = record.structured_output;
1399
- }
1400
- }
1401
- }
1402
- });
1403
- } catch (err) {
1404
- const detail = err instanceof Error ? err.message : String(err);
1405
- throw new Error(`Claude SDK query failed: ${detail}`);
1406
- }
1407
- if (!sdkSessionId) {
1408
- throw new Error(
1409
- "Claude SDK query completed without a `result` message — " +
1410
- "likely a stream idle timeout, aborted request, or upstream API error. " +
1411
- "Set CLAUDE_ENABLE_STREAM_WATCHDOG=1 (and tune CLAUDE_STREAM_IDLE_TIMEOUT_MS / " +
1412
- "API_TIMEOUT_MS) so the CLI surfaces a concrete failure instead of exiting silently.",
1413
- );
1414
- }
1415
- this._lastSessionId = sdkSessionId;
1416
- this._lastStructuredOutput = structuredOutput;
1417
- return getSessionMessages(sdkSessionId, { dir: process.cwd() });
1418
- }
1419
-
1420
- async disconnect(): Promise<void> {}
1421
- }
1422
-
1423
- // ---------------------------------------------------------------------------
1424
- // Static source validation
1425
- // ---------------------------------------------------------------------------
1426
-
1427
- import { createProviderValidator } from "../types.ts";
1428
-
1429
- /**
1430
- * Validate a Claude workflow source file for common mistakes.
1431
- *
1432
- * Warns on direct usage of createClaudeSession/claudeQuery — the runtime
1433
- * now handles init/cleanup automatically via s.client and s.session.
1434
- */
1435
- export const validateClaudeWorkflow = createProviderValidator([
1436
- {
1437
- pattern: /\bcreateClaudeSession\b/,
1438
- rule: "claude/manual-session",
1439
- message:
1440
- "Manual createClaudeSession() call detected. The runtime auto-starts the Claude CLI — " +
1441
- "use s.session.query() instead of claudeQuery(). Pass chatFlags via the second arg to ctx.stage().",
1442
- },
1443
- {
1444
- pattern: /\bclaudeQuery\b/,
1445
- rule: "claude/manual-query",
1446
- message:
1447
- "Direct claudeQuery() call detected. Use s.session.query(prompt) instead — " +
1448
- "it wraps claudeQuery with the correct paneId.",
1449
- },
1450
- ]);