project-tiny-context-harness 0.2.85 → 0.6.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 (361) hide show
  1. package/README.md +164 -427
  2. package/assets/README.md +284 -455
  3. package/assets/README.zh-CN.md +200 -123
  4. package/assets/agents/AGENTS_CORE.md +54 -67
  5. package/assets/context_templates/context.toml +3 -0
  6. package/assets/context_templates/global.md +6 -6
  7. package/assets/github/harness.yml +2 -2
  8. package/assets/skills/context_development_engineer/SKILL.md +91 -107
  9. package/assets/skills/context_product_plan/SKILL.md +18 -28
  10. package/assets/skills/context_surface_contract/SKILL.md +35 -38
  11. package/assets/skills/context_uiux_design/SKILL.md +31 -30
  12. package/assets/skills/long-task-workflow/SKILL.md +76 -0
  13. package/assets/skills/long-task-workflow/agents/openai.yaml +4 -0
  14. package/assets/skills/long-task-workflow/references/authority-lifecycle.md +41 -0
  15. package/assets/skills/long-task-workflow/references/contract-authoring.md +63 -0
  16. package/assets/skills/long-task-workflow/references/evidence-design.md +45 -0
  17. package/assets/skills/normal-long-task/SKILL.md +12 -489
  18. package/assets/skills/source-plan-authoring/SKILL.md +467 -0
  19. package/assets/tools/validate_context.py +293 -127
  20. package/dist/cli.js +3 -1
  21. package/dist/commands/check-modularity.js +33 -10
  22. package/dist/commands/composite-campaign.d.ts +1 -0
  23. package/dist/commands/composite-campaign.js +8 -0
  24. package/dist/commands/composite-long-task.d.ts +1 -6
  25. package/dist/commands/composite-long-task.js +7 -163
  26. package/dist/commands/delivery-set.d.ts +1 -0
  27. package/dist/commands/delivery-set.js +8 -0
  28. package/dist/commands/disable.d.ts +1 -0
  29. package/dist/commands/disable.js +15 -0
  30. package/dist/commands/enable.d.ts +1 -0
  31. package/dist/commands/enable.js +14 -0
  32. package/dist/commands/export-context-args.js +13 -4
  33. package/dist/commands/export-context.js +18 -7
  34. package/dist/commands/index.js +42 -30
  35. package/dist/commands/init.js +12 -6
  36. package/dist/commands/long-task-authoring.d.ts +3 -0
  37. package/dist/commands/long-task-authoring.js +92 -0
  38. package/dist/commands/long-task-explain.d.ts +1 -0
  39. package/dist/commands/long-task-explain.js +52 -0
  40. package/dist/commands/long-task.d.ts +1 -0
  41. package/dist/commands/long-task.js +226 -0
  42. package/dist/commands/package-source.js +2 -2
  43. package/dist/commands/upgrade.js +10 -10
  44. package/dist/index.d.ts +11 -1
  45. package/dist/index.js +8 -0
  46. package/dist/lib/config.js +34 -8
  47. package/dist/lib/context-default-footprint.d.ts +16 -0
  48. package/dist/lib/context-default-footprint.js +107 -0
  49. package/dist/lib/context-export.js +105 -41
  50. package/dist/lib/context-graph-snapshot.d.ts +18 -0
  51. package/dist/lib/context-graph-snapshot.js +171 -0
  52. package/dist/lib/context-manifest-schema.d.ts +28 -0
  53. package/dist/lib/context-manifest-schema.js +150 -0
  54. package/dist/lib/context-manifest.js +28 -20
  55. package/dist/lib/context-templates.js +5 -5
  56. package/dist/lib/design-md.js +1 -1
  57. package/dist/lib/doctor.js +54 -1
  58. package/dist/lib/harness-root.js +25 -8
  59. package/dist/lib/init.js +6 -3
  60. package/dist/lib/legacy-managed-scan.js +23 -7
  61. package/dist/lib/legacy-sdlc-migration.js +21 -11
  62. package/dist/lib/long-task-acceptance-reference.d.ts +22 -0
  63. package/dist/lib/long-task-acceptance-reference.js +46 -0
  64. package/dist/lib/long-task-acceptance-shape.d.ts +5 -0
  65. package/dist/lib/long-task-acceptance-shape.js +131 -0
  66. package/dist/lib/long-task-activation-validation.d.ts +21 -0
  67. package/dist/lib/long-task-activation-validation.js +136 -0
  68. package/dist/lib/long-task-artifacts.d.ts +5 -0
  69. package/dist/lib/long-task-artifacts.js +34 -0
  70. package/dist/lib/long-task-assertions-v2.d.ts +22 -0
  71. package/dist/lib/long-task-assertions-v2.js +212 -0
  72. package/dist/lib/long-task-authoring-authority-preview.d.ts +5 -0
  73. package/dist/lib/long-task-authoring-authority-preview.js +85 -0
  74. package/dist/lib/long-task-authoring-preflight-diagnostics.d.ts +8 -0
  75. package/dist/lib/long-task-authoring-preflight-diagnostics.js +179 -0
  76. package/dist/lib/long-task-authoring-preflight-repair-order.d.ts +8 -0
  77. package/dist/lib/long-task-authoring-preflight-repair-order.js +95 -0
  78. package/dist/lib/long-task-authoring-preflight-types.d.ts +46 -0
  79. package/dist/lib/long-task-authoring-preflight-types.js +38 -0
  80. package/dist/lib/long-task-authoring-preflight.d.ts +3 -0
  81. package/dist/lib/long-task-authoring-preflight.js +44 -0
  82. package/dist/lib/long-task-authority-material-diff.d.ts +17 -0
  83. package/dist/lib/long-task-authority-material-diff.js +152 -0
  84. package/dist/lib/long-task-authority-materials.d.ts +7 -0
  85. package/dist/lib/long-task-authority-materials.js +83 -0
  86. package/dist/lib/long-task-authority-policy.d.ts +168 -0
  87. package/dist/lib/long-task-authority-policy.js +181 -0
  88. package/dist/lib/long-task-authority-revision-details.d.ts +19 -0
  89. package/dist/lib/long-task-authority-revision-details.js +192 -0
  90. package/dist/lib/long-task-authority-revision-enforcement.d.ts +3 -0
  91. package/dist/lib/long-task-authority-revision-enforcement.js +41 -0
  92. package/dist/lib/long-task-authority-revision-types.d.ts +50 -0
  93. package/dist/lib/long-task-authority-revision-types.js +1 -0
  94. package/dist/lib/long-task-authority-revision.d.ts +4 -0
  95. package/dist/lib/long-task-authority-revision.js +188 -0
  96. package/dist/lib/long-task-authority-transition-policy.d.ts +62 -0
  97. package/dist/lib/long-task-authority-transition-policy.js +62 -0
  98. package/dist/lib/long-task-authority-types.d.ts +96 -0
  99. package/dist/lib/long-task-authority-types.js +1 -0
  100. package/dist/lib/long-task-authority.d.ts +7 -0
  101. package/dist/lib/long-task-authority.js +142 -0
  102. package/dist/lib/long-task-boundary-check.d.ts +15 -0
  103. package/dist/lib/long-task-boundary-check.js +9 -0
  104. package/dist/lib/long-task-check-evidence-decoder.d.ts +3 -0
  105. package/dist/lib/long-task-check-evidence-decoder.js +74 -0
  106. package/dist/lib/long-task-check-execution-policy.d.ts +18 -0
  107. package/dist/lib/long-task-check-execution-policy.js +36 -0
  108. package/dist/lib/long-task-check-runner.d.ts +2 -0
  109. package/dist/lib/long-task-check-runner.js +181 -0
  110. package/dist/lib/long-task-check-shape.d.ts +2 -0
  111. package/dist/lib/long-task-check-shape.js +136 -0
  112. package/dist/lib/long-task-claim-definitions.d.ts +7 -0
  113. package/dist/lib/long-task-claim-definitions.js +78 -0
  114. package/dist/lib/long-task-claim-proof-policy.d.ts +4 -0
  115. package/dist/lib/long-task-claim-proof-policy.js +57 -0
  116. package/dist/lib/long-task-claims.d.ts +10 -0
  117. package/dist/lib/long-task-claims.js +187 -0
  118. package/dist/lib/long-task-context-authority-topology.d.ts +7 -0
  119. package/dist/lib/long-task-context-authority-topology.js +37 -0
  120. package/dist/lib/long-task-context-authority.d.ts +14 -0
  121. package/dist/lib/long-task-context-authority.js +66 -0
  122. package/dist/lib/long-task-contract-types.d.ts +203 -0
  123. package/dist/lib/long-task-contract-types.js +1 -0
  124. package/dist/lib/long-task-counterfactual-claim-policy.d.ts +10 -0
  125. package/dist/lib/long-task-counterfactual-claim-policy.js +57 -0
  126. package/dist/lib/long-task-counterfactual-sandbox.d.ts +6 -0
  127. package/dist/lib/long-task-counterfactual-sandbox.js +87 -0
  128. package/dist/lib/long-task-counterfactual-types.d.ts +24 -0
  129. package/dist/lib/long-task-counterfactual-types.js +1 -0
  130. package/dist/lib/long-task-delivery-compiler.d.ts +10 -0
  131. package/dist/lib/long-task-delivery-compiler.js +129 -0
  132. package/dist/lib/long-task-delivery-parser.d.ts +13 -0
  133. package/dist/lib/long-task-delivery-parser.js +90 -0
  134. package/dist/lib/long-task-delivery-preflight.d.ts +5 -0
  135. package/dist/lib/long-task-delivery-preflight.js +151 -0
  136. package/dist/lib/long-task-delivery-shape.d.ts +5 -0
  137. package/dist/lib/long-task-delivery-shape.js +5 -0
  138. package/dist/lib/long-task-delivery-types.d.ts +8 -0
  139. package/dist/lib/long-task-delivery-types.js +8 -0
  140. package/dist/lib/long-task-delivery-validation.d.ts +3 -0
  141. package/dist/lib/long-task-delivery-validation.js +175 -0
  142. package/dist/lib/long-task-evidence-adapter-policy.d.ts +4 -0
  143. package/dist/lib/long-task-evidence-adapter-policy.js +15 -0
  144. package/dist/lib/long-task-evidence-adapter-types.d.ts +1 -0
  145. package/dist/lib/long-task-evidence-adapter-types.js +1 -0
  146. package/dist/lib/long-task-evidence-findings.d.ts +5 -0
  147. package/dist/lib/long-task-evidence-findings.js +113 -0
  148. package/dist/lib/long-task-evidence-sensitivity-policy.d.ts +4 -0
  149. package/dist/lib/long-task-evidence-sensitivity-policy.js +98 -0
  150. package/dist/lib/long-task-evidence-v2.d.ts +5 -0
  151. package/dist/lib/long-task-evidence-v2.js +226 -0
  152. package/dist/lib/long-task-explain-acceptance-link.d.ts +46 -0
  153. package/dist/lib/long-task-explain-acceptance-link.js +96 -0
  154. package/dist/lib/long-task-explain-claim-links.d.ts +45 -0
  155. package/dist/lib/long-task-explain-claim-links.js +88 -0
  156. package/dist/lib/long-task-explain-source-links.d.ts +93 -0
  157. package/dist/lib/long-task-explain-source-links.js +51 -0
  158. package/dist/lib/long-task-final-v2.d.ts +2 -0
  159. package/dist/lib/long-task-final-v2.js +124 -0
  160. package/dist/lib/long-task-finding-context.d.ts +3 -0
  161. package/dist/lib/long-task-finding-context.js +63 -0
  162. package/dist/lib/long-task-freshness.d.ts +3 -0
  163. package/dist/lib/long-task-freshness.js +80 -0
  164. package/dist/lib/long-task-hook-install.d.ts +9 -0
  165. package/dist/lib/long-task-hook-install.js +184 -0
  166. package/dist/lib/long-task-hook-preflight.d.ts +7 -0
  167. package/dist/lib/long-task-hook-preflight.js +58 -0
  168. package/dist/lib/long-task-observation-ownership.d.ts +2 -0
  169. package/dist/lib/long-task-observation-ownership.js +22 -0
  170. package/dist/lib/long-task-outcome-parser.d.ts +4 -0
  171. package/dist/lib/long-task-outcome-parser.js +100 -0
  172. package/dist/lib/long-task-paths.d.ts +49 -0
  173. package/dist/lib/long-task-paths.js +418 -0
  174. package/dist/lib/long-task-playwright-counterfactual-policy.d.ts +7 -0
  175. package/dist/lib/long-task-playwright-counterfactual-policy.js +125 -0
  176. package/dist/lib/long-task-playwright-evidence.d.ts +6 -0
  177. package/dist/lib/long-task-playwright-evidence.js +244 -0
  178. package/dist/lib/long-task-product-shape.d.ts +6 -0
  179. package/dist/lib/long-task-product-shape.js +73 -0
  180. package/dist/lib/long-task-progress.d.ts +4 -0
  181. package/dist/lib/long-task-progress.js +114 -0
  182. package/dist/lib/long-task-protected-files.d.ts +1 -0
  183. package/dist/lib/long-task-protected-files.js +30 -0
  184. package/dist/lib/long-task-required-proof-surfaces.d.ts +2 -0
  185. package/dist/lib/long-task-required-proof-surfaces.js +13 -0
  186. package/dist/lib/long-task-requirement-shape.d.ts +2 -0
  187. package/dist/lib/long-task-requirement-shape.js +18 -0
  188. package/dist/lib/long-task-risk-surfaces.d.ts +2 -0
  189. package/dist/lib/long-task-risk-surfaces.js +60 -0
  190. package/dist/lib/long-task-risk-types.d.ts +5 -0
  191. package/dist/lib/long-task-risk-types.js +12 -0
  192. package/dist/lib/long-task-risk.d.ts +9 -0
  193. package/dist/lib/long-task-risk.js +132 -0
  194. package/dist/lib/long-task-root-shape.d.ts +4 -0
  195. package/dist/lib/long-task-root-shape.js +86 -0
  196. package/dist/lib/long-task-runner-environment.d.ts +7 -0
  197. package/dist/lib/long-task-runner-environment.js +57 -0
  198. package/dist/lib/long-task-runner-files.d.ts +3 -0
  199. package/dist/lib/long-task-runner-files.js +39 -0
  200. package/dist/lib/long-task-runner-freeze.d.ts +2 -0
  201. package/dist/lib/long-task-runner-freeze.js +168 -0
  202. package/dist/lib/long-task-runtime-types.d.ts +214 -0
  203. package/dist/lib/long-task-runtime-types.js +1 -0
  204. package/dist/lib/long-task-shape-primitives.d.ts +17 -0
  205. package/dist/lib/long-task-shape-primitives.js +81 -0
  206. package/dist/lib/long-task-source-authority-types.d.ts +13 -0
  207. package/dist/lib/long-task-source-authority-types.js +1 -0
  208. package/dist/lib/long-task-source-claim-validation.d.ts +5 -0
  209. package/dist/lib/long-task-source-claim-validation.js +96 -0
  210. package/dist/lib/long-task-source-continuity.d.ts +4 -0
  211. package/dist/lib/long-task-source-continuity.js +57 -0
  212. package/dist/lib/long-task-source-inventory.d.ts +2 -0
  213. package/dist/lib/long-task-source-inventory.js +21 -0
  214. package/dist/lib/long-task-source-item-parser.d.ts +3 -0
  215. package/dist/lib/long-task-source-item-parser.js +112 -0
  216. package/dist/lib/long-task-source-shape.d.ts +2 -0
  217. package/dist/lib/long-task-source-shape.js +56 -0
  218. package/dist/lib/long-task-source-target-continuity.d.ts +4 -0
  219. package/dist/lib/long-task-source-target-continuity.js +80 -0
  220. package/dist/lib/long-task-source-target-index.d.ts +12 -0
  221. package/dist/lib/long-task-source-target-index.js +76 -0
  222. package/dist/lib/long-task-source-validation.d.ts +3 -0
  223. package/dist/lib/long-task-source-validation.js +46 -0
  224. package/dist/lib/long-task-state.d.ts +91 -0
  225. package/dist/lib/long-task-state.js +611 -0
  226. package/dist/lib/long-task-status-projection.d.ts +21 -0
  227. package/dist/lib/long-task-status-projection.js +116 -0
  228. package/dist/lib/long-task-status-v2.d.ts +37 -0
  229. package/dist/lib/long-task-status-v2.js +306 -0
  230. package/dist/lib/long-task-technical-shape.d.ts +3 -0
  231. package/dist/lib/long-task-technical-shape.js +44 -0
  232. package/dist/lib/long-task-verifier-authority.d.ts +12 -0
  233. package/dist/lib/long-task-verifier-authority.js +47 -0
  234. package/dist/lib/long-task-verifier-identity.d.ts +2 -0
  235. package/dist/lib/long-task-verifier-identity.js +55 -0
  236. package/dist/lib/long-task-verifier-v2.d.ts +13 -0
  237. package/dist/lib/long-task-verifier-v2.js +266 -0
  238. package/dist/lib/long-task-workspace-runtime-types.d.ts +23 -0
  239. package/dist/lib/long-task-workspace-runtime-types.js +1 -0
  240. package/dist/lib/long-task-workspace.d.ts +25 -0
  241. package/dist/lib/long-task-workspace.js +366 -0
  242. package/dist/lib/managed-file.js +20 -5
  243. package/dist/lib/migrations.js +156 -32
  244. package/dist/lib/modularity.d.ts +27 -1
  245. package/dist/lib/modularity.js +499 -23
  246. package/dist/lib/package-json-config.js +14 -5
  247. package/dist/lib/package-source.js +4 -2
  248. package/dist/lib/profiles.d.ts +13 -0
  249. package/dist/lib/profiles.js +66 -0
  250. package/dist/lib/schema-guard.js +4 -2
  251. package/dist/lib/source-files.js +14 -7
  252. package/dist/lib/source-pack-classify.js +91 -19
  253. package/dist/lib/source-pack-config.js +25 -8
  254. package/dist/lib/source-pack-export.js +84 -25
  255. package/dist/lib/source-pack-manifest.js +18 -6
  256. package/dist/lib/source-pack-records.js +35 -11
  257. package/dist/lib/source-pack-render.js +47 -18
  258. package/dist/lib/stable-json.d.ts +2 -0
  259. package/dist/lib/stable-json.js +21 -0
  260. package/dist/lib/strict-codec.d.ts +4 -0
  261. package/dist/lib/strict-codec.js +65 -0
  262. package/dist/lib/sync-engine.js +76 -24
  263. package/dist/lib/types.d.ts +8 -1
  264. package/dist/lib/upgrade.js +4 -3
  265. package/dist/lib/validators.js +218 -191
  266. package/dist/long-task-hook.d.ts +2 -0
  267. package/dist/long-task-hook.js +55 -0
  268. package/dist/schemas/long-task-delivery-v2/long-task-delivery-v2.schema.json +340 -0
  269. package/dist/schemas/long-task-delivery-v2/long-task-outcomes-v2.schema.json +18 -0
  270. package/migrations/README.md +8 -3
  271. package/package.json +17 -6
  272. package/source-mappings.yaml +0 -3
  273. package/assets/protected-harness-baseline.json +0 -20
  274. package/assets/skills/composite-long-task-workflow/SKILL.md +0 -245
  275. package/assets/skills/composite-long-task-workflow/assets/execution-binding.template.md +0 -62
  276. package/assets/skills/composite-long-task-workflow/assets/goal-objective.template.md +0 -17
  277. package/assets/skills/composite-long-task-workflow/references/composite-long-task-workflow-protocol.md +0 -682
  278. package/dist/commands/superpowers.d.ts +0 -1
  279. package/dist/commands/superpowers.js +0 -8
  280. package/dist/lib/composite-long-task-renderer.d.ts +0 -12
  281. package/dist/lib/composite-long-task-renderer.js +0 -109
  282. package/dist/lib/plan-acceptance-artifacts.d.ts +0 -1
  283. package/dist/lib/plan-acceptance-artifacts.js +0 -220
  284. package/dist/lib/plan-acceptance-evidence.d.ts +0 -2
  285. package/dist/lib/plan-acceptance-evidence.js +0 -108
  286. package/dist/lib/plan-acceptance-json.d.ts +0 -15
  287. package/dist/lib/plan-acceptance-json.js +0 -133
  288. package/dist/lib/plan-acceptance-validator.d.ts +0 -2
  289. package/dist/lib/plan-acceptance-validator.js +0 -209
  290. package/dist/lib/plan-contract-validator.d.ts +0 -2
  291. package/dist/lib/plan-contract-validator.js +0 -127
  292. package/dist/lib/plan-validator-common.d.ts +0 -24
  293. package/dist/lib/plan-validator-common.js +0 -196
  294. package/dist/lib/superpowers-task-ac010.d.ts +0 -6
  295. package/dist/lib/superpowers-task-ac010.js +0 -26
  296. package/dist/lib/superpowers-task-assertion-normalizers.d.ts +0 -3
  297. package/dist/lib/superpowers-task-assertion-normalizers.js +0 -74
  298. package/dist/lib/superpowers-task-assertions.d.ts +0 -20
  299. package/dist/lib/superpowers-task-assertions.js +0 -257
  300. package/dist/lib/superpowers-task-attempt.d.ts +0 -4
  301. package/dist/lib/superpowers-task-attempt.js +0 -102
  302. package/dist/lib/superpowers-task-command-run-correlation.d.ts +0 -8
  303. package/dist/lib/superpowers-task-command-run-correlation.js +0 -103
  304. package/dist/lib/superpowers-task-command-specs.d.ts +0 -3
  305. package/dist/lib/superpowers-task-command-specs.js +0 -52
  306. package/dist/lib/superpowers-task-compile-diagnostics.d.ts +0 -5
  307. package/dist/lib/superpowers-task-compile-diagnostics.js +0 -20
  308. package/dist/lib/superpowers-task-compile-guards.d.ts +0 -2
  309. package/dist/lib/superpowers-task-compile-guards.js +0 -66
  310. package/dist/lib/superpowers-task-compile.d.ts +0 -6
  311. package/dist/lib/superpowers-task-compile.js +0 -133
  312. package/dist/lib/superpowers-task-completion-output.d.ts +0 -91
  313. package/dist/lib/superpowers-task-completion-output.js +0 -374
  314. package/dist/lib/superpowers-task-conformance.d.ts +0 -2
  315. package/dist/lib/superpowers-task-conformance.js +0 -24
  316. package/dist/lib/superpowers-task-contradictions.d.ts +0 -6
  317. package/dist/lib/superpowers-task-contradictions.js +0 -126
  318. package/dist/lib/superpowers-task-current-evidence.d.ts +0 -3
  319. package/dist/lib/superpowers-task-current-evidence.js +0 -176
  320. package/dist/lib/superpowers-task-delivery.d.ts +0 -4
  321. package/dist/lib/superpowers-task-delivery.js +0 -96
  322. package/dist/lib/superpowers-task-derive.d.ts +0 -14
  323. package/dist/lib/superpowers-task-derive.js +0 -393
  324. package/dist/lib/superpowers-task-events.d.ts +0 -1
  325. package/dist/lib/superpowers-task-events.js +0 -13
  326. package/dist/lib/superpowers-task-evidence-kernel.d.ts +0 -19
  327. package/dist/lib/superpowers-task-evidence-kernel.js +0 -347
  328. package/dist/lib/superpowers-task-evidence-records.d.ts +0 -2
  329. package/dist/lib/superpowers-task-evidence-records.js +0 -55
  330. package/dist/lib/superpowers-task-evidence.d.ts +0 -10
  331. package/dist/lib/superpowers-task-evidence.js +0 -147
  332. package/dist/lib/superpowers-task-fields.d.ts +0 -22
  333. package/dist/lib/superpowers-task-fields.js +0 -276
  334. package/dist/lib/superpowers-task-final-card.d.ts +0 -3
  335. package/dist/lib/superpowers-task-final-card.js +0 -35
  336. package/dist/lib/superpowers-task-gates.d.ts +0 -12
  337. package/dist/lib/superpowers-task-gates.js +0 -267
  338. package/dist/lib/superpowers-task-harness-drift.d.ts +0 -11
  339. package/dist/lib/superpowers-task-harness-drift.js +0 -90
  340. package/dist/lib/superpowers-task-next-slices.d.ts +0 -1
  341. package/dist/lib/superpowers-task-next-slices.js +0 -12
  342. package/dist/lib/superpowers-task-protected-baseline.d.ts +0 -10
  343. package/dist/lib/superpowers-task-protected-baseline.js +0 -66
  344. package/dist/lib/superpowers-task-source-compile.d.ts +0 -5
  345. package/dist/lib/superpowers-task-source-compile.js +0 -226
  346. package/dist/lib/superpowers-task-source-parser.d.ts +0 -23
  347. package/dist/lib/superpowers-task-source-parser.js +0 -218
  348. package/dist/lib/superpowers-task-state-schema.d.ts +0 -460
  349. package/dist/lib/superpowers-task-state-schema.js +0 -66
  350. package/dist/lib/superpowers-task-state-shape.d.ts +0 -3
  351. package/dist/lib/superpowers-task-state-shape.js +0 -50
  352. package/dist/lib/superpowers-task-state.d.ts +0 -16
  353. package/dist/lib/superpowers-task-state.js +0 -246
  354. package/dist/lib/superpowers-task-status.d.ts +0 -2
  355. package/dist/lib/superpowers-task-status.js +0 -24
  356. package/dist/lib/superpowers-task-under-specified.d.ts +0 -7
  357. package/dist/lib/superpowers-task-under-specified.js +0 -61
  358. package/dist/lib/superpowers-task-unregistered-evidence.d.ts +0 -11
  359. package/dist/lib/superpowers-task-unregistered-evidence.js +0 -72
  360. package/dist/lib/superpowers-task-validator.d.ts +0 -5
  361. package/dist/lib/superpowers-task-validator.js +0 -293
@@ -19,7 +19,7 @@ export async function buildManifest(params) {
19
19
  artifacts: params.artifacts.map((artifact) => artifactReport(artifact)),
20
20
  warnings: params.warnings,
21
21
  omitted: params.omitted,
22
- recommended_upload_sets: params.recommendedUploadSets
22
+ recommended_upload_sets: params.recommendedUploadSets,
23
23
  };
24
24
  return `${JSON.stringify(manifest, null, 2)}\n`;
25
25
  }
@@ -32,7 +32,7 @@ export function artifactReport(artifact) {
32
32
  characters: artifact.content.length,
33
33
  source_count: artifact.sourceCount,
34
34
  source_line_count: artifact.sourceLineCount,
35
- warning_count: artifact.warningCount
35
+ warning_count: artifact.warningCount,
36
36
  };
37
37
  }
38
38
  export async function writeArtifactSet(projectRoot, outputDir, artifacts) {
@@ -55,13 +55,22 @@ export async function pruneTimestampedExports(projectRoot, keepCount) {
55
55
  catch {
56
56
  return;
57
57
  }
58
- const timestampDirs = entries.filter((entry) => /^\d{8}T\d{6}Z$/.test(entry)).sort().reverse();
58
+ const timestampDirs = entries
59
+ .filter((entry) => /^\d{8}T\d{6}Z$/.test(entry))
60
+ .sort()
61
+ .reverse();
59
62
  for (const entry of timestampDirs.slice(keepCount)) {
60
- await fs.rm(path.join(exportsRoot, entry), { recursive: true, force: true });
63
+ await fs.rm(path.join(exportsRoot, entry), {
64
+ recursive: true,
65
+ force: true,
66
+ });
61
67
  }
62
68
  }
63
69
  export function timestampForFile(now) {
64
- return now.toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z");
70
+ return now
71
+ .toISOString()
72
+ .replace(/[-:]/g, "")
73
+ .replace(/\.\d{3}Z$/, "Z");
65
74
  }
66
75
  async function writeArtifacts(projectRoot, outputDir, artifacts) {
67
76
  for (const artifact of artifacts) {
@@ -78,7 +87,10 @@ async function gitInfo(projectRoot) {
78
87
  try {
79
88
  const shaResult = await execFileAsync("git", ["-C", projectRoot, "rev-parse", "HEAD"], { encoding: "utf8" });
80
89
  const dirtyResult = await execFileAsync("git", ["-C", projectRoot, "status", "--porcelain"], { encoding: "utf8" });
81
- return { sha: shaResult.stdout.trim() || null, dirty: dirtyResult.stdout.trim().length > 0 };
90
+ return {
91
+ sha: shaResult.stdout.trim() || null,
92
+ dirty: dirtyResult.stdout.trim().length > 0,
93
+ };
82
94
  }
83
95
  catch {
84
96
  return { sha: null, dirty: false };
@@ -4,7 +4,7 @@ import { promises as fs } from "node:fs";
4
4
  import path from "node:path";
5
5
  import { promisify } from "node:util";
6
6
  import { listFiles, pathExists, readText } from "./fs.js";
7
- import { shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix } from "./source-files.js";
7
+ import { shouldExcludeRelativePath, shouldIncludeCodeFile, toPosix, } from "./source-files.js";
8
8
  import { classifyCodeFile } from "./source-pack-classify.js";
9
9
  import { matchesAny } from "./source-pack-config.js";
10
10
  const execFileAsync = promisify(execFile);
@@ -16,10 +16,13 @@ export async function collectCodeRecords(projectRoot, warnings, options = {}) {
16
16
  const records = [];
17
17
  for (const file of candidates) {
18
18
  const relative = repoRelative(projectRoot, file);
19
- if (!shouldIncludeCodeFile(relative) || matchesAny(relative, options.exclude ?? [])) {
19
+ if (!shouldIncludeCodeFile(relative) ||
20
+ matchesAny(relative, options.exclude ?? [])) {
20
21
  continue;
21
22
  }
22
- if (options.include && options.include.length > 0 && !matchesAny(relative, options.include)) {
23
+ if (options.include &&
24
+ options.include.length > 0 &&
25
+ !matchesAny(relative, options.include)) {
23
26
  continue;
24
27
  }
25
28
  if (!(await isRegularFile(file))) {
@@ -44,26 +47,36 @@ export async function collectCodeRecords(projectRoot, warnings, options = {}) {
44
47
  routes: classification.routes,
45
48
  score: classification.score,
46
49
  bucket: classification.bucket,
47
- bundle: "omitted"
50
+ bundle: "omitted",
48
51
  });
49
52
  }
50
53
  return records.sort((left, right) => left.relative.localeCompare(right.relative));
51
54
  }
52
55
  export async function collectContextArtifacts(projectRoot, warnings, includePatterns) {
53
56
  const files = new Set();
54
- for (const relative of ["AGENTS.md", "README.md", "DESIGN.md", "project_context/global.md", "project_context/architecture.md", "project_context/context.toml"]) {
57
+ for (const relative of [
58
+ "AGENTS.md",
59
+ "README.md",
60
+ "DESIGN.md",
61
+ "project_context/global.md",
62
+ "project_context/architecture.md",
63
+ "project_context/context.toml",
64
+ ]) {
55
65
  await addIfExists(projectRoot, files, warnings, relative, relative.startsWith("project_context/"));
56
66
  }
57
67
  for (const file of await listFiles(path.join(projectRoot, "project_context"))) {
58
68
  const relative = repoRelative(projectRoot, file);
59
- if ((relative.endsWith(".md") || relative.endsWith(".toml")) && !shouldExcludeRelativePath(relative)) {
69
+ if ((relative.endsWith(".md") || relative.endsWith(".toml")) &&
70
+ !shouldExcludeRelativePath(relative)) {
60
71
  files.add(file);
61
72
  }
62
73
  }
63
74
  const artifacts = [];
64
75
  for (const file of [...files].sort((a, b) => repoRelative(projectRoot, a).localeCompare(repoRelative(projectRoot, b)))) {
65
76
  const relative = repoRelative(projectRoot, file);
66
- if (includePatterns && includePatterns.length > 0 && !matchesAny(relative, includePatterns)) {
77
+ if (includePatterns &&
78
+ includePatterns.length > 0 &&
79
+ !matchesAny(relative, includePatterns)) {
67
80
  continue;
68
81
  }
69
82
  const rawContent = await readText(file);
@@ -75,7 +88,7 @@ export async function collectContextArtifacts(projectRoot, warnings, includePatt
75
88
  relative,
76
89
  content: redacted.content,
77
90
  lines: countLines(redacted.content),
78
- characters: redacted.content.length
91
+ characters: redacted.content.length,
79
92
  });
80
93
  }
81
94
  return artifacts;
@@ -103,11 +116,22 @@ async function addIfExists(projectRoot, files, warnings, relative, required) {
103
116
  }
104
117
  async function listGitCandidateFiles(projectRoot) {
105
118
  try {
106
- const result = await execFileAsync("git", ["-C", projectRoot, "ls-files", "--cached", "--others", "--exclude-standard", "-z"], {
119
+ const result = await execFileAsync("git", [
120
+ "-C",
121
+ projectRoot,
122
+ "ls-files",
123
+ "--cached",
124
+ "--others",
125
+ "--exclude-standard",
126
+ "-z",
127
+ ], {
107
128
  encoding: "utf8",
108
- maxBuffer: GIT_LS_MAX_BUFFER
129
+ maxBuffer: GIT_LS_MAX_BUFFER,
109
130
  });
110
- return result.stdout.split("\0").filter(Boolean).map((relative) => path.join(projectRoot, ...toPosix(relative).split("/")));
131
+ return result.stdout
132
+ .split("\0")
133
+ .filter(Boolean)
134
+ .map((relative) => path.join(projectRoot, ...toPosix(relative).split("/")));
111
135
  }
112
136
  catch {
113
137
  return undefined;
@@ -22,7 +22,7 @@ export function renderFullProjectContextArtifact(contexts, warnings, meta) {
22
22
  "## Context Sources",
23
23
  "",
24
24
  ...contexts.map(renderContextArtifact),
25
- ""
25
+ "",
26
26
  ].join("\n");
27
27
  }
28
28
  export function renderCodeIndexArtifact(records, areas, warnings, meta) {
@@ -52,7 +52,11 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
52
52
  "## Context Area Mapping",
53
53
  "",
54
54
  "Inferred buckets below are export routing only; they are not durable architecture or product ownership facts.",
55
- areas.length > 0 ? areas.map((area) => `- ${area.id}: root=${area.root}; context=${area.context}`).join("\n") : "- No Context area mappings found.",
55
+ areas.length > 0
56
+ ? areas
57
+ .map((area) => `- ${area.id}: root=${area.root}; context=${area.context}`)
58
+ .join("\n")
59
+ : "- No Context area mappings found.",
56
60
  "",
57
61
  "## Key Entry Points",
58
62
  "",
@@ -68,7 +72,9 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
68
72
  "",
69
73
  "## CLI / Worker / Script Index",
70
74
  "",
71
- renderRecordList(records.filter((record) => record.tags.includes("cli") || record.tags.includes("worker")).slice(0, 30)),
75
+ renderRecordList(records
76
+ .filter((record) => record.tags.includes("cli") || record.tags.includes("worker"))
77
+ .slice(0, 30)),
72
78
  "",
73
79
  "## Test / Verification Index",
74
80
  "",
@@ -76,12 +82,14 @@ export function renderCodeIndexArtifact(records, areas, warnings, meta) {
76
82
  "",
77
83
  "## Oversized Files",
78
84
  "",
79
- renderRecordList(records.filter((record) => record.tags.includes("oversized")).slice(0, 30)),
85
+ renderRecordList(records
86
+ .filter((record) => record.tags.includes("oversized"))
87
+ .slice(0, 30)),
80
88
  "",
81
89
  "## Source File Index",
82
90
  "",
83
91
  renderSourceFileIndex(records),
84
- ""
92
+ "",
85
93
  ].join("\n");
86
94
  }
87
95
  export function renderBundleArtifact(title, records, contexts, omitted, warnings, meta, policy) {
@@ -109,16 +117,21 @@ export function renderBundleArtifact(title, records, contexts, omitted, warnings
109
117
  "",
110
118
  "## Related Context Paths",
111
119
  "",
112
- contexts.length > 0 ? contexts.map((context) => `- ${context.relative} (${context.lines} lines)`).join("\n") : "- No related Context files selected.",
120
+ contexts.length > 0
121
+ ? contexts
122
+ .map((context) => `- ${context.relative} (${context.lines} lines)`)
123
+ .join("\n")
124
+ : "- No related Context files selected.",
113
125
  "",
114
126
  "## Source Files",
115
127
  "",
116
- records.map(renderSourceRecord).join("\n\n") || "- No source files selected for this bundle.",
128
+ records.map(renderSourceRecord).join("\n\n") ||
129
+ "- No source files selected for this bundle.",
117
130
  "",
118
131
  "## Omitted Files Summary",
119
132
  "",
120
133
  renderOmittedSummary(omitted),
121
- ""
134
+ "",
122
135
  ].join("\n");
123
136
  }
124
137
  export function renderTaskContextArtifact(taskName, contexts, records, verification, omitted, warnings, meta) {
@@ -150,21 +163,31 @@ export function renderTaskContextArtifact(taskName, contexts, records, verificat
150
163
  "",
151
164
  "## Selected Source Files",
152
165
  "",
153
- records.map(renderSourceRecord).join("\n\n") || "- No selected source files matched the task filters.",
166
+ records.map(renderSourceRecord).join("\n\n") ||
167
+ "- No selected source files matched the task filters.",
154
168
  "",
155
169
  "## Verification Entry Points",
156
170
  "",
157
- verification.length > 0 ? verification.map((entry) => `- ${entry}`).join("\n") : "- No profile verification entries selected.",
171
+ verification.length > 0
172
+ ? verification.map((entry) => `- ${entry}`).join("\n")
173
+ : "- No profile verification entries selected.",
158
174
  "",
159
175
  "## Omitted / Support Notes",
160
176
  "",
161
177
  renderOmittedSummary(omitted),
162
- ""
178
+ "",
163
179
  ].join("\n");
164
180
  }
165
181
  function renderContextArtifact(context) {
166
182
  const fence = fenceFor(context.content);
167
- return [`### ${context.relative}`, "", `${fence}markdown`, context.content.trimEnd(), fence, ""].join("\n");
183
+ return [
184
+ `### ${context.relative}`,
185
+ "",
186
+ `${fence}markdown`,
187
+ context.content.trimEnd(),
188
+ fence,
189
+ "",
190
+ ].join("\n");
168
191
  }
169
192
  function renderSourceRecord(record) {
170
193
  const fence = fenceFor(record.content);
@@ -183,7 +206,7 @@ function renderSourceRecord(record) {
183
206
  "",
184
207
  `${fence}${record.language}`,
185
208
  record.content.trimEnd(),
186
- fence
209
+ fence,
187
210
  ].join("\n");
188
211
  }
189
212
  function renderSourceFileIndex(records) {
@@ -193,7 +216,7 @@ function renderSourceFileIndex(records) {
193
216
  return [
194
217
  "| Path | Type | Lines | Characters | SHA256 | Summary | Bundle | Tags |",
195
218
  "|---|---:|---:|---:|---|---|---|---|",
196
- ...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} | ${record.bundle} | ${escapeTableCell(record.tags.join(", "))} |`)
219
+ ...records.map((record) => `| ${escapeTableCell(record.relative)} | ${escapeTableCell(record.language)} | ${record.lines} | ${record.characters} | ${record.sha256.slice(0, 12)} | ${escapeTableCell(record.summary)} | ${record.bundle} | ${escapeTableCell(record.tags.join(", "))} |`),
197
220
  ].join("\n");
198
221
  }
199
222
  function renderRepositoryShape(records) {
@@ -202,10 +225,10 @@ function renderRepositoryShape(records) {
202
225
  const top = record.relative.split("/")[0] || ".";
203
226
  counts.set(top, (counts.get(top) ?? 0) + 1);
204
227
  }
205
- return [...counts.entries()]
228
+ return ([...counts.entries()]
206
229
  .sort((left, right) => right[1] - left[1] || left[0].localeCompare(right[0]))
207
230
  .map(([name, count]) => `- ${name}: ${count} source file(s)`)
208
- .join("\n") || "- No source files matched.";
231
+ .join("\n") || "- No source files matched.");
209
232
  }
210
233
  function renderRecordList(records, includeRoutes = false) {
211
234
  if (records.length === 0) {
@@ -216,13 +239,19 @@ function renderRecordList(records, includeRoutes = false) {
216
239
  .join("\n");
217
240
  }
218
241
  function renderWarningList(warnings) {
219
- return warnings.length > 0 ? warnings.map((warning) => ` - ${warning}`) : [" - none"];
242
+ return warnings.length > 0
243
+ ? warnings.map((warning) => ` - ${warning}`)
244
+ : [" - none"];
220
245
  }
221
246
  function renderOmittedSummary(omitted) {
222
247
  const reasons = Object.entries(omitted.reason_counts)
223
248
  .sort((left, right) => left[0].localeCompare(right[0]))
224
249
  .map(([reason, count]) => ` - ${reason}: ${count}`);
225
- return [`- omitted_source_file_count: ${omitted.source_file_count}`, "- reason_counts:", ...(reasons.length > 0 ? reasons : [" - none: 0"])].join("\n");
250
+ return [
251
+ `- omitted_source_file_count: ${omitted.source_file_count}`,
252
+ "- reason_counts:",
253
+ ...(reasons.length > 0 ? reasons : [" - none: 0"]),
254
+ ].join("\n");
226
255
  }
227
256
  function fenceFor(content) {
228
257
  let fence = "```";
@@ -0,0 +1,2 @@
1
+ export declare function stableJson(value: unknown): string;
2
+ export declare function sha256(value: string): string;
@@ -0,0 +1,21 @@
1
+ import { createHash } from "node:crypto";
2
+ export function stableJson(value) {
3
+ return JSON.stringify(sortJson(value), null, 2);
4
+ }
5
+ export function sha256(value) {
6
+ return createHash("sha256").update(value).digest("hex");
7
+ }
8
+ function sortJson(value) {
9
+ if (Array.isArray(value)) {
10
+ return value.map(sortJson);
11
+ }
12
+ if (!isRecord(value)) {
13
+ return value;
14
+ }
15
+ return Object.fromEntries(Object.keys(value)
16
+ .sort()
17
+ .map((key) => [key, sortJson(value[key])]));
18
+ }
19
+ function isRecord(value) {
20
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
21
+ }
@@ -0,0 +1,4 @@
1
+ export declare function canonicalJson(value: unknown): string;
2
+ export declare function canonicalValueJson(value: unknown): string;
3
+ export declare function sha256Hex(value: string | Uint8Array): string;
4
+ export declare function parseStrictYaml(content: string): unknown;
@@ -0,0 +1,65 @@
1
+ import { createHash } from "node:crypto";
2
+ import YAML, { isAlias, isMap, isPair, isScalar, isSeq, visit, } from "yaml";
3
+ export function canonicalJson(value) {
4
+ return `${JSON.stringify(sortCanonical(value), null, 2)}\n`;
5
+ }
6
+ export function canonicalValueJson(value) {
7
+ return JSON.stringify(sortCanonical(value));
8
+ }
9
+ export function sha256Hex(value) {
10
+ return createHash("sha256").update(value).digest("hex");
11
+ }
12
+ export function parseStrictYaml(content) {
13
+ if (content.charCodeAt(0) === 0xfeff)
14
+ throw new Error("YAML byte-order marks are not allowed");
15
+ if (/^%(?:YAML|TAG)\b/m.test(content))
16
+ throw new Error("YAML directives are not allowed");
17
+ const documents = YAML.parseAllDocuments(content, {
18
+ merge: false,
19
+ schema: "core",
20
+ strict: true,
21
+ stringKeys: true,
22
+ uniqueKeys: true,
23
+ });
24
+ const document = assertSingleDocument(documents);
25
+ if (document.directives.yaml.explicit ||
26
+ Object.keys(document.directives.tags).some((handle) => handle !== "!!"))
27
+ throw new Error("YAML directives are not allowed");
28
+ visit(document, (_key, node) => inspectNode(node));
29
+ return document.toJS({ maxAliasCount: 0 });
30
+ }
31
+ function assertSingleDocument(documents) {
32
+ if (documents.length !== 1)
33
+ throw new Error("YAML must contain exactly one document");
34
+ const document = documents[0];
35
+ const issue = document.errors[0] ?? document.warnings[0];
36
+ if (issue)
37
+ throw new Error(`Invalid YAML: ${issue.message}`);
38
+ return document;
39
+ }
40
+ function inspectNode(node) {
41
+ if (isAlias(node))
42
+ throw new Error("YAML aliases are not allowed");
43
+ const tagged = node;
44
+ if (tagged.anchor)
45
+ throw new Error("YAML anchors are not allowed");
46
+ if (tagged.tag)
47
+ throw new Error("YAML explicit tags are not allowed");
48
+ if (isPair(node) && isScalar(node.key) && node.key.value === "<<")
49
+ throw new Error("YAML merge keys are not allowed");
50
+ if (isMap(node) || isSeq(node) || isScalar(node) || isPair(node))
51
+ return;
52
+ throw new Error("Unsupported YAML node");
53
+ }
54
+ function sortCanonical(value) {
55
+ if (Array.isArray(value))
56
+ return value.map(sortCanonical);
57
+ if (value && typeof value === "object")
58
+ return Object.fromEntries(Object.keys(value)
59
+ .sort()
60
+ .map((key) => [
61
+ key,
62
+ sortCanonical(value[key]),
63
+ ]));
64
+ return value;
65
+ }
@@ -2,15 +2,17 @@ import path from "node:path";
2
2
  import { promises as fs } from "node:fs";
3
3
  import { readConfig } from "./config.js";
4
4
  import { harnessPath, harnessRoot } from "./harness-root.js";
5
- import { copyTree, listFiles, pathExists, readText, writeTextIfChanged } from "./fs.js";
6
- import { AGENTS_BLOCK_MARKERS, GITHUB_WORKFLOW_BLOCK_END, GITHUB_WORKFLOW_BLOCK_MARKERS, GITHUB_WORKFLOW_BLOCK_START, MAKEFILE_BLOCK_END, MAKEFILE_BLOCK_MARKERS, MAKEFILE_BLOCK_START, MANAGED_BLOCK_END, MANAGED_BLOCK_START } from "./managed-file.js";
5
+ import { copyTree, listFiles, pathExists, readText, writeTextIfChanged, } from "./fs.js";
6
+ import { AGENTS_BLOCK_MARKERS, GITHUB_WORKFLOW_BLOCK_END, GITHUB_WORKFLOW_BLOCK_MARKERS, GITHUB_WORKFLOW_BLOCK_START, MAKEFILE_BLOCK_END, MAKEFILE_BLOCK_MARKERS, MAKEFILE_BLOCK_START, MANAGED_BLOCK_END, MANAGED_BLOCK_START, } from "./managed-file.js";
7
7
  import { packageAssetPath } from "./paths.js";
8
8
  import { assertSupportedSchema } from "./schema-guard.js";
9
+ import { installLongTaskHooks, uninstallLongTaskHooks, } from "./long-task-hook-install.js";
10
+ import { enabledManagedSkillNames, isProfileEnabled } from "./profiles.js";
9
11
  export function emptySyncReport() {
10
12
  return {
11
13
  changed: [],
12
14
  skipped: [],
13
- blocked: []
15
+ blocked: [],
14
16
  };
15
17
  }
16
18
  export async function runSync(projectRoot) {
@@ -23,11 +25,17 @@ export async function runSync(projectRoot) {
23
25
  return report;
24
26
  }
25
27
  for (const managedFile of config.managed_files) {
26
- await syncManagedFile(projectRoot, root, managedFile, report);
28
+ await syncManagedFile(projectRoot, root, managedFile, report, config);
29
+ }
30
+ if (isProfileEnabled(config, "long-task")) {
31
+ await installLongTaskHooks(projectRoot, report);
32
+ }
33
+ else {
34
+ await uninstallLongTaskHooks(projectRoot, report);
27
35
  }
28
36
  return report;
29
37
  }
30
- async function syncManagedFile(projectRoot, root, managedFile, report) {
38
+ async function syncManagedFile(projectRoot, root, managedFile, report, config) {
31
39
  const destination = path.join(projectRoot, managedFile.path);
32
40
  if (managedFile.path === "AGENTS.md") {
33
41
  await syncAgentsBlock(destination, root, report);
@@ -38,7 +46,7 @@ async function syncManagedFile(projectRoot, root, managedFile, report) {
38
46
  return;
39
47
  }
40
48
  if (isSkillsManagedPath(managedFile.path, root)) {
41
- await syncSkillsTree(packageAssetPath("skills"), path.join(projectRoot, root, "skills"), report);
49
+ await syncSkillsTree(packageAssetPath("skills"), path.join(projectRoot, root, "skills"), report, enabledManagedSkillNames(config));
42
50
  return;
43
51
  }
44
52
  const managedPath = normalizeManagedPath(managedFile.path);
@@ -47,14 +55,17 @@ async function syncManagedFile(projectRoot, root, managedFile, report) {
47
55
  return;
48
56
  }
49
57
  if (managedPath === harnessPath(root, "ty-context-managed", "context_templates")) {
50
- await syncTree(packageAssetPath("context_templates"), destination, report, { prune: true });
58
+ await syncTree(packageAssetPath("context_templates"), destination, report, {
59
+ prune: true,
60
+ });
51
61
  return;
52
62
  }
53
63
  if (managedPath === harnessPath(root, "ty-context-managed", "policies")) {
54
64
  await syncTree(packageAssetPath("policies"), destination, report);
55
65
  return;
56
66
  }
57
- if (managedPath === harnessPath(root, "ty-context-managed", "make", "ty-context.mk")) {
67
+ if (managedPath ===
68
+ harnessPath(root, "ty-context-managed", "make", "ty-context.mk")) {
58
69
  await syncFile(packageAssetPath("make", "ty-context.mk"), destination, report, "skip-if-missing");
59
70
  return;
60
71
  }
@@ -85,14 +96,16 @@ async function syncAgentsBlock(destination, root, report) {
85
96
  }
86
97
  const core = renderAgentsCore(await readText(corePath), root);
87
98
  const block = `${MANAGED_BLOCK_START}\n${core.trim()}\n${MANAGED_BLOCK_END}`;
88
- const existing = (await pathExists(destination)) ? await readText(destination) : "";
99
+ const existing = (await pathExists(destination))
100
+ ? await readText(destination)
101
+ : "";
89
102
  const next = mergeManagedBlock({
90
103
  existing,
91
104
  block,
92
105
  markers: AGENTS_BLOCK_MARKERS,
93
106
  pathLabel: "AGENTS.md",
94
107
  insert: "append",
95
- report
108
+ report,
96
109
  });
97
110
  if (!next) {
98
111
  return;
@@ -108,14 +121,16 @@ function renderAgentsCore(content, root) {
108
121
  return content.replaceAll(".agent", root).replaceAll(".codex", root);
109
122
  }
110
123
  async function syncMakefileInclude(destination, root, report) {
111
- const existing = (await pathExists(destination)) ? await readText(destination) : "";
124
+ const existing = (await pathExists(destination))
125
+ ? await readText(destination)
126
+ : "";
112
127
  const resetDefaultGoal = shouldResetMakeDefaultGoal(existing);
113
128
  const includePath = `${root.replace(/\\/g, "/")}/ty-context-managed/make/ty-context.mk`;
114
129
  const blockLines = [
115
130
  MAKEFILE_BLOCK_START,
116
131
  "# Included before project targets so project recipes win on name conflicts.",
117
132
  `-include ${includePath}`,
118
- MAKEFILE_BLOCK_END
133
+ MAKEFILE_BLOCK_END,
119
134
  ];
120
135
  if (resetDefaultGoal) {
121
136
  blockLines.splice(3, 0, ".DEFAULT_GOAL :=");
@@ -127,7 +142,7 @@ async function syncMakefileInclude(destination, root, report) {
127
142
  markers: MAKEFILE_BLOCK_MARKERS,
128
143
  pathLabel: "Makefile",
129
144
  insert: "prepend",
130
- report
145
+ report,
131
146
  });
132
147
  if (!next) {
133
148
  return;
@@ -194,9 +209,14 @@ function findManagedBlock(existing, markersList) {
194
209
  matches.push({ markers, startIndex, endIndex });
195
210
  }
196
211
  if (matches.length > 1) {
197
- return { status: "invalid", reason: "conflicting managed block marker namespaces" };
198
- }
199
- return matches[0] ? { status: "found", ...matches[0] } : { status: "missing" };
212
+ return {
213
+ status: "invalid",
214
+ reason: "conflicting managed block marker namespaces",
215
+ };
216
+ }
217
+ return matches[0]
218
+ ? { status: "found", ...matches[0] }
219
+ : { status: "missing" };
200
220
  }
201
221
  async function syncTree(source, destination, report, options = {}) {
202
222
  if (!(await pathExists(source))) {
@@ -224,7 +244,10 @@ async function removeStaleManagedFiles(source, destination) {
224
244
  .map((file) => path.relative(source, file).split(path.sep).join("/")));
225
245
  const removed = [];
226
246
  for (const destinationFile of await listFiles(destination)) {
227
- const relative = path.relative(destination, destinationFile).split(path.sep).join("/");
247
+ const relative = path
248
+ .relative(destination, destinationFile)
249
+ .split(path.sep)
250
+ .join("/");
228
251
  if (sourceFiles.has(relative)) {
229
252
  continue;
230
253
  }
@@ -233,13 +256,18 @@ async function removeStaleManagedFiles(source, destination) {
233
256
  }
234
257
  return removed;
235
258
  }
236
- async function syncSkillsTree(source, destination, report) {
259
+ async function syncSkillsTree(source, destination, report, enabledSkillNames) {
237
260
  if (!(await pathExists(source))) {
238
261
  report.skipped.push(path.basename(destination));
239
262
  return;
240
263
  }
241
264
  const files = await listFiles(source);
242
- const realFiles = files.filter((file) => !file.endsWith(".gitkeep"));
265
+ const allManagedSkillNames = new Set(files
266
+ .map((file) => path.relative(source, file).split(path.sep)[0])
267
+ .filter(Boolean));
268
+ const realFiles = files
269
+ .filter((file) => !file.endsWith(".gitkeep"))
270
+ .filter((file) => enabledSkillNames.has(path.relative(source, file).split(path.sep)[0]));
243
271
  if (realFiles.length === 0) {
244
272
  report.skipped.push(path.basename(destination));
245
273
  return;
@@ -254,6 +282,21 @@ async function syncSkillsTree(source, destination, report) {
254
282
  report.skipped.push(destinationFile);
255
283
  }
256
284
  }
285
+ const managedSkillNames = new Set(realFiles
286
+ .map((file) => path.relative(source, file).split(path.sep)[0])
287
+ .filter(Boolean));
288
+ for (const skillName of managedSkillNames) {
289
+ report.changed.push(...(await removeStaleManagedFiles(path.join(source, skillName), path.join(destination, skillName))));
290
+ }
291
+ for (const skillName of allManagedSkillNames) {
292
+ if (enabledSkillNames.has(skillName))
293
+ continue;
294
+ const disabled = path.join(destination, skillName);
295
+ if (!(await pathExists(disabled)))
296
+ continue;
297
+ await fs.rm(disabled, { recursive: true, force: true });
298
+ report.changed.push(disabled);
299
+ }
257
300
  }
258
301
  async function blockDeprecatedSkillOverrides(projectRoot, root, report) {
259
302
  for (const overrideRoot of skillOverrideRoots(projectRoot, root)) {
@@ -274,12 +317,18 @@ function skillOverrideRoots(projectRoot, root) {
274
317
  return [
275
318
  {
276
319
  absolute: path.join(projectRoot, root, "ty-context-managed", "override_skills"),
277
- relative: path.join(root, "ty-context-managed", "override_skills").split(path.sep).join("/")
320
+ relative: path
321
+ .join(root, "ty-context-managed", "override_skills")
322
+ .split(path.sep)
323
+ .join("/"),
278
324
  },
279
325
  {
280
326
  absolute: path.join(projectRoot, root, "pjsdlc_managed", "override_skills"),
281
- relative: path.join(root, "pjsdlc_managed", "override_skills").split(path.sep).join("/")
282
- }
327
+ relative: path
328
+ .join(root, "pjsdlc_managed", "override_skills")
329
+ .split(path.sep)
330
+ .join("/"),
331
+ },
283
332
  ];
284
333
  }
285
334
  async function syncFile(source, destination, report, missingMode) {
@@ -320,7 +369,9 @@ async function syncGithubWorkflow(source, destination, relativePath, report) {
320
369
  report.blocked.push(`${relativePath}: incomplete managed workflow markers`);
321
370
  return;
322
371
  }
323
- if (markerState === "managed" || normalizeWorkflow(existing) === normalizeWorkflow(stripWorkflowMarkers(sourceContent))) {
372
+ if (markerState === "managed" ||
373
+ normalizeWorkflow(existing) ===
374
+ normalizeWorkflow(stripWorkflowMarkers(sourceContent))) {
324
375
  if (await writeTextIfChanged(destination, sourceContent)) {
325
376
  report.changed.push(relativePath);
326
377
  }
@@ -344,7 +395,8 @@ function workflowMarkerState(content) {
344
395
  function stripWorkflowMarkers(content) {
345
396
  return content
346
397
  .split(/\r?\n/)
347
- .filter((line) => line.trim() !== GITHUB_WORKFLOW_BLOCK_START && line.trim() !== GITHUB_WORKFLOW_BLOCK_END)
398
+ .filter((line) => line.trim() !== GITHUB_WORKFLOW_BLOCK_START &&
399
+ line.trim() !== GITHUB_WORKFLOW_BLOCK_END)
348
400
  .join("\n");
349
401
  }
350
402
  function normalizeWorkflow(content) {
@@ -3,10 +3,14 @@ export interface HarnessConfig {
3
3
  package: string;
4
4
  schema_version: string;
5
5
  };
6
+ profiles: {
7
+ enabled: HarnessProfile[];
8
+ };
6
9
  modularity?: HarnessModularityConfig;
7
10
  managed_files: ManagedFile[];
8
11
  never_overwrite: string[];
9
12
  }
13
+ export type HarnessProfile = "core-portable" | "workflow-default" | "long-task";
10
14
  export interface HarnessModularityConfig {
11
15
  limit?: number;
12
16
  policy?: "scoped_waivers" | "strict_except_generated";
@@ -15,8 +19,11 @@ export interface HarnessModularityConfig {
15
19
  export interface ModularityWaiverConfig {
16
20
  path?: string;
17
21
  category?: string;
22
+ owner?: string;
23
+ introduced_at?: string;
18
24
  reason?: string;
19
- future_split_boundary?: string;
25
+ tracking_issue?: string;
26
+ expiry_condition?: string;
20
27
  }
21
28
  export interface ManagedFile {
22
29
  path: string;