@workerstack/repo 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +0 -3
  4. package/agents/global-settings/antigravity.json +3 -0
  5. package/agents/global-settings/claude.json +6 -0
  6. package/agents/global-settings/codex.toml +2 -0
  7. package/agents/global-settings/cursor.json +3 -0
  8. package/agents/global-settings/grok.toml +36 -0
  9. package/agents/global-settings/manifest.json +36 -0
  10. package/agents/grok/hooks/orchestrate-parent.json +60 -0
  11. package/agents/grok/hooks/rtk.json +16 -0
  12. package/agents/grok/hooks/rulesync.json +3 -0
  13. package/agents/grok/roles/scout.toml +5 -0
  14. package/agents/hooks.jsonc +67 -0
  15. package/agents/mcp-policy.jsonc +16 -0
  16. package/agents/rules/overview.md +21 -0
  17. package/agents/settings/claude.json +5 -0
  18. package/agents/skills/ask/SKILL.md +13 -0
  19. package/agents/skills/auto/SKILL.md +13 -0
  20. package/agents/skills/away/SKILL.md +19 -0
  21. package/agents/skills/blast-radius/SKILL.md +54 -0
  22. package/agents/skills/bro/SKILL.md +9 -0
  23. package/agents/skills/browser/SKILL.md +16 -0
  24. package/agents/skills/clasp/SKILL.md +11 -0
  25. package/agents/skills/commit/SKILL.md +35 -0
  26. package/agents/skills/commit-and-push/SKILL.md +9 -0
  27. package/agents/skills/commit-push/SKILL.md +59 -0
  28. package/agents/skills/commit-push-deploy/SKILL.md +74 -0
  29. package/agents/skills/commit-push-release/SKILL.md +75 -0
  30. package/agents/skills/correct/SKILL.md +39 -0
  31. package/agents/skills/do/SKILL.md +21 -0
  32. package/agents/skills/explain/SKILL.md +13 -0
  33. package/agents/skills/google-workspace/SKILL.md +12 -0
  34. package/agents/skills/handoff/SKILL.md +81 -0
  35. package/agents/skills/implement-plan/SKILL.md +29 -0
  36. package/agents/skills/implement-roadmap/SKILL.md +27 -0
  37. package/agents/skills/jev/SKILL.md +17 -0
  38. package/agents/skills/listen/SKILL.md +15 -0
  39. package/agents/skills/pickup/SKILL.md +58 -0
  40. package/agents/skills/principle-attack-the-premise/SKILL.md +24 -0
  41. package/agents/skills/principle-boundary-discipline/SKILL.md +38 -0
  42. package/agents/skills/principle-build-the-lever/SKILL.md +28 -0
  43. package/agents/skills/principle-encode-lessons-in-structure/SKILL.md +15 -0
  44. package/agents/skills/principle-exhaust-the-design-space/SKILL.md +12 -0
  45. package/agents/skills/principle-experience-first/SKILL.md +22 -0
  46. package/agents/skills/principle-explain-the-number/SKILL.md +21 -0
  47. package/agents/skills/principle-fix-root-causes/SKILL.md +24 -0
  48. package/agents/skills/principle-foundational-thinking/SKILL.md +25 -0
  49. package/agents/skills/principle-guard-the-context-window/SKILL.md +16 -0
  50. package/agents/skills/principle-laziness-protocol/SKILL.md +13 -0
  51. package/agents/skills/principle-make-operations-idempotent/SKILL.md +25 -0
  52. package/agents/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +18 -0
  53. package/agents/skills/principle-minimize-reader-load/SKILL.md +22 -0
  54. package/agents/skills/principle-model-the-domain/SKILL.md +26 -0
  55. package/agents/skills/principle-never-block-on-the-human/SKILL.md +17 -0
  56. package/agents/skills/principle-outcome-oriented-execution/SKILL.md +25 -0
  57. package/agents/skills/principle-prove-it-works/SKILL.md +25 -0
  58. package/agents/skills/principle-redesign-from-first-principles/SKILL.md +18 -0
  59. package/agents/skills/principle-separate-before-serializing-shared-state/SKILL.md +20 -0
  60. package/agents/skills/principle-sequence-verifiable-units/SKILL.md +22 -0
  61. package/agents/skills/principle-subtract-before-you-add/SKILL.md +21 -0
  62. package/agents/skills/principle-test-behavior-not-implementation/SKILL.md +24 -0
  63. package/agents/skills/principle-type-system-discipline/SKILL.md +17 -0
  64. package/agents/skills/review-plan/SKILL.md +28 -0
  65. package/agents/skills/review-roadmap/SKILL.md +28 -0
  66. package/agents/skills/show-me/SKILL.md +21 -0
  67. package/agents/skills/speak/SKILL.md +15 -0
  68. package/agents/skills/su/SKILL.md +11 -0
  69. package/agents/skills/teach/SKILL.md +25 -0
  70. package/agents/skills/tmp/SKILL.md +54 -0
  71. package/agents/skills/typescript-best-practices/SKILL.md +32 -0
  72. package/agents/skills/typescript-best-practices/references/patterns.md +328 -0
  73. package/agents/skills/unslop/SKILL.md +62 -0
  74. package/agents/skills/write-plan/SKILL.md +33 -0
  75. package/agents/skills/write-roadmap/SKILL.md +66 -0
  76. package/agents/subagents/implementer-deep.md +57 -0
  77. package/agents/subagents/implementer-fast.md +57 -0
  78. package/agents/subagents/orchestrator.md +43 -0
  79. package/agents/subagents/researcher.md +47 -0
  80. package/agents/subagents/scout.md +44 -0
  81. package/bin/repo.ts +4 -0
  82. package/cli/actionlint-default.test.ts +38 -0
  83. package/cli/actionlint-download.test.ts +162 -0
  84. package/cli/actionlint-real.test.ts +33 -0
  85. package/cli/actionlint.constants.ts +43 -0
  86. package/cli/actionlint.test.ts +108 -0
  87. package/cli/actionlint.ts +178 -0
  88. package/cli/bin.test.ts +54 -0
  89. package/cli/bin.ts +40 -0
  90. package/cli/check-changelog.test.ts +40 -0
  91. package/cli/check-changelog.ts +12 -0
  92. package/cli/check-comments.test.ts +157 -0
  93. package/cli/check-comments.ts +123 -0
  94. package/cli/check-env-modules.test.ts +85 -0
  95. package/cli/check-env-modules.ts +56 -0
  96. package/cli/check-magic.test.ts +139 -0
  97. package/cli/check-magic.ts +120 -0
  98. package/cli/check-manifests.constants.ts +4 -0
  99. package/cli/check-manifests.test.ts +210 -0
  100. package/cli/check-manifests.ts +71 -0
  101. package/cli/check-nightly.test.ts +103 -0
  102. package/cli/check-nightly.ts +37 -0
  103. package/cli/check-ratchets-missing.test.ts +46 -0
  104. package/cli/check-ratchets-mutation.test.ts +49 -0
  105. package/cli/check-ratchets.constants.ts +20 -0
  106. package/cli/check-ratchets.test.ts +190 -0
  107. package/cli/check-ratchets.ts +193 -0
  108. package/cli/check-rejections.test.ts +220 -0
  109. package/cli/check-rejections.ts +153 -0
  110. package/cli/check-reports.ts +37 -0
  111. package/cli/check-tsconfig.test.ts +507 -0
  112. package/cli/check-tsconfig.ts +205 -0
  113. package/cli/commands.test.ts +114 -0
  114. package/cli/commands.ts +218 -0
  115. package/cli/commit-changelog.ts +27 -0
  116. package/cli/commit-msg-changelog.test.ts +93 -0
  117. package/cli/commit-msg-range.test.ts +126 -0
  118. package/cli/commit-msg-red-proof.test.ts +147 -0
  119. package/cli/commit-msg-repo.test.ts +153 -0
  120. package/cli/commit-msg.test.ts +101 -0
  121. package/cli/commit-msg.ts +194 -0
  122. package/cli/commit-range.constants.ts +17 -0
  123. package/cli/commit-range.ts +57 -0
  124. package/cli/config-knip.test.ts +70 -0
  125. package/cli/config-nightly.test.ts +84 -0
  126. package/cli/config-tdd.test.ts +46 -0
  127. package/cli/config.test.ts +576 -0
  128. package/cli/config.ts +261 -0
  129. package/cli/conventional.ts +9 -0
  130. package/cli/coverage-config.ts +62 -0
  131. package/cli/coverage.constants.ts +6 -0
  132. package/cli/coverage.test.ts +199 -0
  133. package/cli/coverage.ts +127 -0
  134. package/cli/env.constants.ts +10 -0
  135. package/cli/env.test.ts +56 -0
  136. package/cli/env.ts +72 -0
  137. package/cli/fixtures/base-config.ts +13 -0
  138. package/cli/fixtures/gate-world.ts +48 -0
  139. package/cli/fixtures/knip-run.ts +38 -0
  140. package/cli/fixtures/mutate-fakes.ts +137 -0
  141. package/cli/fixtures/planted-repo.ts +50 -0
  142. package/cli/fixtures/publish-world.ts +71 -0
  143. package/cli/fixtures/red-proof-repo.ts +72 -0
  144. package/cli/fixtures/release-context.ts +15 -0
  145. package/cli/fixtures/release-world.ts +111 -0
  146. package/cli/fixtures/stub-bin.ts +40 -0
  147. package/cli/guard-diagnostics.test.ts +157 -0
  148. package/cli/guard-diagnostics.ts +195 -0
  149. package/cli/init.test.ts +487 -0
  150. package/cli/init.ts +275 -0
  151. package/cli/knip-check-ignores.test.ts +106 -0
  152. package/cli/knip-check-real.test.ts +65 -0
  153. package/cli/knip-check.constants.ts +46 -0
  154. package/cli/knip-check.test.ts +114 -0
  155. package/cli/knip-check.ts +169 -0
  156. package/cli/knip-schema.ts +67 -0
  157. package/cli/known-failures.constants.ts +22 -0
  158. package/cli/known-failures.test.ts +138 -0
  159. package/cli/known-failures.ts +131 -0
  160. package/cli/lint/as-needs-reason.ts +41 -0
  161. package/cli/lint/boundaries.ts +73 -0
  162. package/cli/lint/class-file.ts +39 -0
  163. package/cli/lint/config-file.ts +32 -0
  164. package/cli/lint/entry-file.ts +54 -0
  165. package/cli/lint/env-in-config.ts +66 -0
  166. package/cli/lint/filename-matches-export.ts +63 -0
  167. package/cli/lint/index-file.ts +22 -0
  168. package/cli/lint/index.ts +47 -0
  169. package/cli/lint/is-reason.ts +6 -0
  170. package/cli/lint/manifest.ts +46 -0
  171. package/cli/lint/names.ts +59 -0
  172. package/cli/lint/no-commented-out-code.ts +105 -0
  173. package/cli/lint/no-mock-of-subject.ts +64 -0
  174. package/cli/lint/no-module-side-effects.ts +94 -0
  175. package/cli/lint/no-module-state.ts +58 -0
  176. package/cli/lint/no-side-effect-import.ts +17 -0
  177. package/cli/lint/no-v8-ignore.ts +18 -0
  178. package/cli/lint/script-rules.ts +9 -0
  179. package/cli/lint/skip-on-platform.constants.ts +8 -0
  180. package/cli/lint/skip-on-platform.ts +118 -0
  181. package/cli/lint/todo-needs-id.ts +63 -0
  182. package/cli/lint/types-file.ts +28 -0
  183. package/cli/lint-schema.ts +32 -0
  184. package/cli/magic/fixtures/magic-repo.ts +64 -0
  185. package/cli/magic/magic-hit.ts +2 -0
  186. package/cli/magic/magic-nodes.ts +44 -0
  187. package/cli/magic/magic-numbers.test.ts +99 -0
  188. package/cli/magic/magic-numbers.ts +117 -0
  189. package/cli/magic/magic-strings.test.ts +38 -0
  190. package/cli/magic/magic-strings.ts +81 -0
  191. package/cli/main.test.ts +853 -0
  192. package/cli/main.ts +292 -0
  193. package/cli/mutate-args.ts +79 -0
  194. package/cli/mutate-check.test.ts +147 -0
  195. package/cli/mutate-deps.ts +42 -0
  196. package/cli/mutate-edges.test.ts +150 -0
  197. package/cli/mutate-files.test.ts +100 -0
  198. package/cli/mutate-files.ts +31 -0
  199. package/cli/mutate-floors.test.ts +91 -0
  200. package/cli/mutate-floors.ts +104 -0
  201. package/cli/mutate-real-deps.ts +57 -0
  202. package/cli/mutate-real.test.ts +96 -0
  203. package/cli/mutate-report.ts +96 -0
  204. package/cli/mutate-run.ts +128 -0
  205. package/cli/mutate-shards.ts +64 -0
  206. package/cli/mutate.constants.ts +67 -0
  207. package/cli/mutate.test.ts +182 -0
  208. package/cli/mutate.ts +64 -0
  209. package/cli/nested-vitest-flags.ts +8 -0
  210. package/cli/nightly-config.constants.ts +14 -0
  211. package/cli/nightly-config.ts +62 -0
  212. package/cli/prompt.test.ts +202 -0
  213. package/cli/prompt.ts +1 -0
  214. package/cli/red-proof-edges.test.ts +78 -0
  215. package/cli/red-proof-failures.test.ts +82 -0
  216. package/cli/red-proof-tree.test.ts +157 -0
  217. package/cli/red-proof-verdict.test.ts +44 -0
  218. package/cli/red-proof.constants.ts +14 -0
  219. package/cli/red-proof.ts +202 -0
  220. package/cli/release/changelog-parse.ts +83 -0
  221. package/cli/release/changelog.test.ts +141 -0
  222. package/cli/release/changelog.ts +106 -0
  223. package/cli/release/gate-refusals.test.ts +85 -0
  224. package/cli/release/gate.test.ts +63 -0
  225. package/cli/release/gate.ts +70 -0
  226. package/cli/release/git.ts +66 -0
  227. package/cli/release/github.test.ts +128 -0
  228. package/cli/release/github.ts +46 -0
  229. package/cli/release/list-dir.test.ts +11 -0
  230. package/cli/release/list-dir.ts +6 -0
  231. package/cli/release/main.test.ts +48 -0
  232. package/cli/release/main.ts +51 -0
  233. package/cli/release/manifest.test.ts +24 -0
  234. package/cli/release/manifest.ts +34 -0
  235. package/cli/release/pack.test.ts +107 -0
  236. package/cli/release/pack.ts +76 -0
  237. package/cli/release/plan.ts +127 -0
  238. package/cli/release/publish-run.test.ts +98 -0
  239. package/cli/release/publish.test.ts +127 -0
  240. package/cli/release/publish.ts +125 -0
  241. package/cli/release/refuse.ts +5 -0
  242. package/cli/release/release-messages.constants.ts +96 -0
  243. package/cli/release/release-refusals.test.ts +149 -0
  244. package/cli/release/release.constants.ts +128 -0
  245. package/cli/release/release.test.ts +199 -0
  246. package/cli/release/release.ts +145 -0
  247. package/cli/release/version.test.ts +118 -0
  248. package/cli/release/version.ts +69 -0
  249. package/cli/release/wait.test.ts +101 -0
  250. package/cli/release/wait.ts +95 -0
  251. package/cli/script-diagnostics.test.ts +76 -0
  252. package/cli/script-diagnostics.ts +62 -0
  253. package/cli/scripts/board.ts +519 -0
  254. package/cli/scripts/browser.ts +994 -0
  255. package/cli/scripts/change-set.ts +105 -0
  256. package/cli/scripts/check-globals.ts +199 -0
  257. package/cli/scripts/ci-skips.constants.ts +17 -0
  258. package/cli/scripts/ci-skips.ts +118 -0
  259. package/cli/scripts/ci-wait-run.ts +28 -0
  260. package/cli/scripts/ci-wait.constants.ts +44 -0
  261. package/cli/scripts/ci-wait.ts +175 -0
  262. package/cli/scripts/ci.constants.ts +15 -0
  263. package/cli/scripts/ci.ts +208 -0
  264. package/cli/scripts/clean.ts +363 -0
  265. package/cli/scripts/comments-step.ts +15 -0
  266. package/cli/scripts/doctor.ts +828 -0
  267. package/cli/scripts/emit-agent-shell-tools.ts +91 -0
  268. package/cli/scripts/emit-mcp-policy.ts +402 -0
  269. package/cli/scripts/folder-map.ts +353 -0
  270. package/cli/scripts/gate-fat-tools.ts +1095 -0
  271. package/cli/scripts/gitignore-guard.ts +338 -0
  272. package/cli/scripts/google-workspace.ts +779 -0
  273. package/cli/scripts/hook-command.ts +72 -0
  274. package/cli/scripts/hook-input.ts +178 -0
  275. package/cli/scripts/hook-io.constants.ts +5 -0
  276. package/cli/scripts/hook-io.ts +46 -0
  277. package/cli/scripts/hooks-union.ts +469 -0
  278. package/cli/scripts/interactive.ts +30 -0
  279. package/cli/scripts/jev.ts +420 -0
  280. package/cli/scripts/job.ts +934 -0
  281. package/cli/scripts/jsonc.ts +9 -0
  282. package/cli/scripts/lessons.ts +564 -0
  283. package/cli/scripts/lint-baseline.ts +233 -0
  284. package/cli/scripts/lint-main.ts +24 -0
  285. package/cli/scripts/lint-skips.ts +139 -0
  286. package/cli/scripts/lint.constants.ts +6 -0
  287. package/cli/scripts/lint.ts +142 -0
  288. package/cli/scripts/listen.ts +962 -0
  289. package/cli/scripts/managed-text.ts +47 -0
  290. package/cli/scripts/orchestrate-parent.ts +1155 -0
  291. package/cli/scripts/parse-need.ts +81 -0
  292. package/cli/scripts/persist-handoff.ts +228 -0
  293. package/cli/scripts/persist-implementation.ts +276 -0
  294. package/cli/scripts/persist-plan.ts +888 -0
  295. package/cli/scripts/persist-roadmap.ts +478 -0
  296. package/cli/scripts/persist-tmp.ts +177 -0
  297. package/cli/scripts/persist.ts +54 -0
  298. package/cli/scripts/phase-files.ts +121 -0
  299. package/cli/scripts/prompt.ts +38 -0
  300. package/cli/scripts/purge-global-mcps.ts +313 -0
  301. package/cli/scripts/rejections-step.ts +37 -0
  302. package/cli/scripts/rtk-grok.ts +102 -0
  303. package/cli/scripts/scrub-spawn-prompt.ts +103 -0
  304. package/cli/scripts/scrub-text-lib.ts +58 -0
  305. package/cli/scripts/session-map.ts +69 -0
  306. package/cli/scripts/setup.ts +862 -0
  307. package/cli/scripts/skill-conflicts.ts +82 -0
  308. package/cli/scripts/speak.ts +370 -0
  309. package/cli/scripts/strategy.ts +168 -0
  310. package/cli/scripts/sync-global-settings.ts +316 -0
  311. package/cli/scripts/turn-steps.ts +249 -0
  312. package/cli/scripts/turn.ts +157 -0
  313. package/cli/scripts/typecheck-step.ts +43 -0
  314. package/cli/scripts/vscode-tasks.ts +175 -0
  315. package/cli/scripts/workspace-root.ts +160 -0
  316. package/cli/scripts/worktree.ts +806 -0
  317. package/cli/spawn.test.ts +34 -0
  318. package/cli/spawn.ts +27 -0
  319. package/cli/staged-change.constants.ts +11 -0
  320. package/cli/staged-change.ts +79 -0
  321. package/cli/stryker-preload.test.ts +50 -0
  322. package/cli/stryker-preload.ts +9 -0
  323. package/cli/sync/agents/frontmatter.test.ts +197 -0
  324. package/cli/sync/agents/frontmatter.ts +140 -0
  325. package/cli/sync/agents/hooks.test.ts +517 -0
  326. package/cli/sync/agents/hooks.ts +401 -0
  327. package/cli/sync/agents/rules.test.ts +229 -0
  328. package/cli/sync/agents/rules.ts +84 -0
  329. package/cli/sync/agents/sources.test.ts +375 -0
  330. package/cli/sync/agents/sources.ts +244 -0
  331. package/cli/sync/agents/subagents.test.ts +149 -0
  332. package/cli/sync/agents/subagents.ts +158 -0
  333. package/cli/sync/agents-text.test.ts +31 -0
  334. package/cli/sync/agents-text.ts +36 -0
  335. package/cli/sync/fixtures/copied.README.md +35 -0
  336. package/cli/sync/fixtures/copied.tgz +0 -0
  337. package/cli/sync/fixtures/maps/golden/INDEX.md +22 -0
  338. package/cli/sync/fixtures/maps-ws.tgz +0 -0
  339. package/cli/sync/git-files.test.ts +340 -0
  340. package/cli/sync/git-files.ts +197 -0
  341. package/cli/sync/git-hooks.test.ts +94 -0
  342. package/cli/sync/golden.test.ts +15 -0
  343. package/cli/sync/hooks-mode.test.ts +99 -0
  344. package/cli/sync/hosts.ts +28 -0
  345. package/cli/sync/knip-config.constants.ts +4 -0
  346. package/cli/sync/knip-config.test.ts +147 -0
  347. package/cli/sync/knip-config.ts +108 -0
  348. package/cli/sync/manifest.test.ts +78 -0
  349. package/cli/sync/manifest.ts +60 -0
  350. package/cli/sync/maps.test.ts +304 -0
  351. package/cli/sync/maps.ts +297 -0
  352. package/cli/sync/migrate.test.ts +2000 -0
  353. package/cli/sync/migrate.ts +1104 -0
  354. package/cli/sync/nightly-jobs.test.ts +63 -0
  355. package/cli/sync/nightly.constants.ts +48 -0
  356. package/cli/sync/nightly.test.ts +100 -0
  357. package/cli/sync/nightly.ts +75 -0
  358. package/cli/sync/outputs.test.ts +351 -0
  359. package/cli/sync/outputs.ts +168 -0
  360. package/cli/sync/oxlint-config.test.ts +178 -0
  361. package/cli/sync/oxlint-config.ts +168 -0
  362. package/cli/sync/release-jobs.test.ts +29 -0
  363. package/cli/sync/release-reports.test.ts +31 -0
  364. package/cli/sync/release-workflow.constants.ts +61 -0
  365. package/cli/sync/release-workflow.test.ts +192 -0
  366. package/cli/sync/release-workflow.ts +86 -0
  367. package/cli/sync/release.constants.ts +93 -0
  368. package/cli/sync/release.test.ts +187 -0
  369. package/cli/sync/release.ts +112 -0
  370. package/cli/sync/repo-dir.test.ts +371 -0
  371. package/cli/sync/repo-dir.ts +205 -0
  372. package/cli/sync/standards.constants.ts +8 -0
  373. package/cli/sync/standards.test.ts +206 -0
  374. package/cli/sync/standards.ts +179 -0
  375. package/cli/sync/stock-history.json +2796 -0
  376. package/cli/sync/stock-history.test.ts +66 -0
  377. package/cli/sync/stock-history.ts +84 -0
  378. package/cli/sync/stock.test.ts +47 -0
  379. package/cli/sync/stock.ts +24 -0
  380. package/cli/sync/trees.test.ts +621 -0
  381. package/cli/sync/trees.ts +280 -0
  382. package/cli/sync/validate.test.ts +299 -0
  383. package/cli/sync/validate.ts +402 -0
  384. package/cli/sync/workspace.test.ts +180 -0
  385. package/cli/sync/workspace.ts +138 -0
  386. package/cli/sync/write.test.ts +341 -0
  387. package/cli/sync/write.ts +231 -0
  388. package/cli/sync.test.ts +1495 -0
  389. package/cli/sync.ts +360 -0
  390. package/cli/tdd-scope.test.ts +36 -0
  391. package/cli/tdd-scope.ts +41 -0
  392. package/cli/test-files.ts +16 -0
  393. package/cli/ts-program.ts +69 -0
  394. package/cli/tsconfig.constants.ts +8 -0
  395. package/cli/workerstack-config.types.ts +21 -0
  396. package/dist/cli/env.d.ts +10 -0
  397. package/dist/cli/env.js +64 -0
  398. package/dist/presets/temp-root-env.d.ts +10 -0
  399. package/dist/presets/temp-root-env.js +20 -0
  400. package/dist/presets/temp-root.constants.d.ts +6 -0
  401. package/dist/presets/temp-root.constants.js +6 -0
  402. package/dist/presets/temp-root.d.ts +2 -0
  403. package/dist/presets/temp-root.js +60 -0
  404. package/dist/presets/vitest.constants.d.ts +16 -0
  405. package/dist/presets/vitest.constants.js +16 -0
  406. package/dist/presets/vitest.d.ts +11 -0
  407. package/dist/presets/vitest.js +67 -0
  408. package/dist/presets/workers-plugin.d.ts +10 -0
  409. package/dist/presets/workers-plugin.js +54 -0
  410. package/package.json +141 -4
  411. package/references/INDEX.md +100 -0
  412. package/references/browser.md +66 -0
  413. package/references/cascade.md +15 -0
  414. package/references/clasp.md +21 -0
  415. package/references/cloudflare.md +36 -0
  416. package/references/google-workspace.md +79 -0
  417. package/references/hooks.md +103 -0
  418. package/references/implementation-format.md +119 -0
  419. package/references/jev.md +56 -0
  420. package/references/lessons.md +73 -0
  421. package/references/listen.md +80 -0
  422. package/references/map.md +107 -0
  423. package/references/output.md +47 -0
  424. package/references/plan-format.md +264 -0
  425. package/references/review-loop.md +48 -0
  426. package/references/roadmap-format.md +104 -0
  427. package/references/rtk.md +27 -0
  428. package/references/scope.md +76 -0
  429. package/references/setup.md +42 -0
  430. package/references/speak.md +59 -0
  431. package/tsconfig/base.json +28 -0
  432. package/tsconfig/bun.d.ts +1 -0
  433. package/tsconfig/bun.json +8 -0
  434. package/tsconfig/reset.d.ts +1 -0
  435. package/tsconfig/strict.json +12 -0
  436. package/tsconfig/web.json +7 -0
  437. package/tsconfig/worker.d.ts +1 -0
  438. package/tsconfig/worker.json +8 -0
@@ -0,0 +1,338 @@
1
+ /**
2
+ * Redundant nested `.gitignore` writes (roadmap D4): a nested write is redundant when every literal line it adds
3
+ * is already ignored by the parent `.gitignore` files alone. The gate denies those; everything unclear passes.
4
+ */
5
+ import { spawnSync } from "node:child_process";
6
+ import fs from "node:fs";
7
+ import os from "node:os";
8
+ import path from "node:path";
9
+ import { canonicalPath } from "./workspace-root.ts";
10
+ import { childEnv } from "../env.ts";
11
+
12
+ /** One `.gitignore` write: the file and the literal lines it would add. */
13
+ export interface IgnoreEdit {
14
+ file: string;
15
+ added: string[];
16
+ }
17
+
18
+ /** A tool call's argument bag; the shape varies per host and tool, so every field is read with a guard. */
19
+ type ToolArgs = Record<string, unknown>;
20
+
21
+ /** A shell write of literal text to one file. */
22
+ interface ShellWrite {
23
+ file: string;
24
+ append: boolean;
25
+ text: string | null;
26
+ }
27
+
28
+ /** One word or one `>`, `>>`, `|` operator of a parsed shell line. */
29
+ interface ShellToken {
30
+ word?: string;
31
+ op?: string;
32
+ }
33
+
34
+ /** An added line that a parent `.gitignore` already ignores, with the rule that covers it. */
35
+ export interface RedundantLine {
36
+ line: string;
37
+ rule: string;
38
+ }
39
+
40
+ function isRecord(v: unknown): v is Record<string, unknown> {
41
+ return v !== null && typeof v === "object" && !Array.isArray(v);
42
+ }
43
+
44
+ /** Inherited repo pointers that would aim git at another repo. */
45
+ const GIT_ENV_DROP = ["GIT_DIR", "GIT_WORK_TREE", "GIT_INDEX_FILE", "GIT_COMMON_DIR", "GIT_CEILING_DIRECTORIES"];
46
+ /** An unanchored line is checked one level deeper too, where a top-anchored parent rule stops matching. */
47
+ const PROBE_DIR = ".workerstack-probe";
48
+
49
+ function runGit(git: string, args: string[], cwd: string) {
50
+ const env = childEnv();
51
+ for (const k of GIT_ENV_DROP) delete env[k];
52
+ return spawnSync(git, args, { cwd, env, encoding: "utf8" });
53
+ }
54
+
55
+ function readText(file: string): string {
56
+ try {
57
+ return fs.readFileSync(file, "utf8");
58
+ } catch {
59
+ return "";
60
+ }
61
+ }
62
+
63
+ function linesOf(text: unknown): string[] {
64
+ return String(text).split(/\r?\n/);
65
+ }
66
+
67
+ /** @returns the candidate lines the file does not hold yet, minus blanks and comments */
68
+ function ignoreEdit(file: string, candidates: string[]): IgnoreEdit {
69
+ const have = new Set(linesOf(readText(file)).map((l) => l.trimEnd()));
70
+ const added: string[] = [];
71
+ for (const raw of candidates) {
72
+ const line = raw.trimEnd();
73
+ if (!line || line.startsWith("#") || have.has(line) || added.includes(line)) continue;
74
+ added.push(line);
75
+ }
76
+ return { file, added };
77
+ }
78
+
79
+ /** Apply the host's search/replace to `text`; null when an old string is missing (the host then fails the edit). */
80
+ export function projectEdit(text: string, args: ToolArgs): string | null {
81
+ const edits: unknown[] = Array.isArray(args.edits) ? args.edits : [args];
82
+ let next = text;
83
+ for (const edit of edits) {
84
+ const e: ToolArgs = isRecord(edit) ? edit : {};
85
+ const oldStr = [e.old_string, e.oldString, e.Target].find((v) => typeof v === "string");
86
+ const newStr = [e.new_string, e.newString, e.Replacement].find((v) => typeof v === "string");
87
+ if (typeof oldStr !== "string" || typeof newStr !== "string" || !next.includes(oldStr)) return null;
88
+ next = e.replace_all || e.replaceAll ? next.split(oldStr).join(newStr) : next.replace(oldStr, () => newStr);
89
+ }
90
+ return next;
91
+ }
92
+
93
+ /** The absolute target when `raw` names a `.gitignore`, else null. */
94
+ export function ignoreTarget(raw: unknown, cwd: string, p: typeof path = path): string | null {
95
+ if (typeof raw !== "string" || !raw) return null;
96
+ const abs = canonicalPath(p.resolve(cwd, raw), p);
97
+ return p.basename(abs) === ".gitignore" ? abs : null;
98
+ }
99
+
100
+ /** The edit a Write or search/replace call makes to a `.gitignore` named in one of `fields`. */
101
+ export function writeIgnoreEdits(args: ToolArgs, cwd: string, fields: readonly string[]): IgnoreEdit[] {
102
+ for (const key of fields) {
103
+ const file = ignoreTarget(args[key], cwd);
104
+ if (!file) continue;
105
+ const full = [args.content, args.Content].find((v) => typeof v === "string");
106
+ const next = full ?? projectEdit(readText(file), args);
107
+ return next == null ? [] : [ignoreEdit(file, linesOf(next))];
108
+ }
109
+ return [];
110
+ }
111
+
112
+ /** Each `.gitignore` a Codex patch adds or updates, with its `+` lines. */
113
+ export function patchIgnoreEdits(patch: string, cwd: string): IgnoreEdit[] {
114
+ const sections: { raw: string; plus: string[] }[] = [];
115
+ let cur: { raw: string; plus: string[] } | null = null;
116
+ for (const line of linesOf(patch)) {
117
+ const m = /^\*\*\* (Add File|Update File|Delete File|Move to): (.+)$/.exec(line);
118
+ if (m) {
119
+ if (m[1] === "Move to") {
120
+ if (cur) cur.raw = m[2]!.trim(); // group 2 always matches
121
+ } else {
122
+ cur = m[1] === "Delete File" ? null : { raw: m[2]!.trim(), plus: [] };
123
+ if (cur) sections.push(cur);
124
+ }
125
+ continue;
126
+ }
127
+ if (cur && line.startsWith("+")) cur.plus.push(line.slice(1));
128
+ }
129
+ const out: IgnoreEdit[] = [];
130
+ for (const s of sections) {
131
+ const file = ignoreTarget(s.raw, cwd);
132
+ if (file) out.push(ignoreEdit(file, s.plus));
133
+ }
134
+ return out;
135
+ }
136
+
137
+ const UNSAFE_CHAR = /[;&$`(){}<*?[\]\\#~!]/;
138
+
139
+ /** Words and `>`/`>>`/`|` of one shell line; null on anything a plain parse cannot read literally. */
140
+ function shellTokens(line: string): ShellToken[] | null {
141
+ const out: ShellToken[] = [];
142
+ let word: string | null = null;
143
+ const end = () => {
144
+ if (word != null) out.push({ word });
145
+ word = null;
146
+ };
147
+ for (let i = 0; i < line.length; i++) {
148
+ const ch = line[i]!; // i < line.length
149
+ if (ch === " " || ch === "\t") end();
150
+ else if (ch === ">") {
151
+ end();
152
+ const append = line[i + 1] === ">";
153
+ if (append) i++;
154
+ out.push({ op: append ? ">>" : ">" });
155
+ } else if (ch === "|") {
156
+ if (line[i + 1] === "|") return null;
157
+ end();
158
+ out.push({ op: "|" });
159
+ } else if (ch === "'" || ch === '"') {
160
+ const close = line.indexOf(ch, i + 1);
161
+ if (close === -1) return null;
162
+ const inner = line.slice(i + 1, close);
163
+ if (ch === '"' && /[$`\\]/.test(inner)) return null;
164
+ word = (word ?? "") + inner;
165
+ i = close;
166
+ } else if (UNSAFE_CHAR.test(ch)) return null;
167
+ else word = (word ?? "") + ch;
168
+ }
169
+ end();
170
+ return out;
171
+ }
172
+
173
+ function unescape(s: string): string {
174
+ return s.replace(/\\(.)/g, (_: string, c: string) => (c === "n" ? "\n" : c === "t" ? "\t" : c));
175
+ }
176
+
177
+ /** The text `echo` or `printf` prints, or null when it depends on anything but its literal words. */
178
+ function producedText(words: string[]): string | null {
179
+ const [cmd, ...args] = words;
180
+ if (cmd === "printf") {
181
+ if (args.length !== 1 || /%/.test(args[0]!.replace(/%%/g, ""))) return null;
182
+ return unescape(args[0]!.replace(/%%/g, "%")); // length is 1
183
+ }
184
+ if (cmd !== "echo") return null;
185
+ let newline = true;
186
+ let escapes = false;
187
+ while (/^-[neE]+$/.test(args[0] || "")) {
188
+ const flag = args.shift()!; // the loop test saw args[0]
189
+ if (flag.includes("n")) newline = false;
190
+ if (flag.includes("e")) escapes = true;
191
+ }
192
+ const body = args.join(" ");
193
+ if (!escapes && body.includes("\\")) return null;
194
+ return (escapes ? unescape(body) : body) + (newline ? "\n" : "");
195
+ }
196
+
197
+ /** `tee [-a] FILE [> /dev/null]` at `tokens`; null when the tokens are anything else. */
198
+ function teeTarget(tokens: ShellToken[]): { file: string; append: boolean } | null {
199
+ const t = tokens.slice();
200
+ if (t.shift()?.word !== "tee") return null;
201
+ let append = false;
202
+ if (t[0]?.word === "-a") {
203
+ append = true;
204
+ t.shift();
205
+ }
206
+ const file = t.shift()?.word;
207
+ if (!file) return null;
208
+ if (t.length && !(t.length === 2 && t[0]!.op === ">" && t[1]!.word === "/dev/null")) return null;
209
+ return { file, append };
210
+ }
211
+
212
+ /** One shell write of literal text to one file, in the forms D4 names; null for every other command. */
213
+ function shellIgnoreWrite(command: unknown): ShellWrite | null {
214
+ const lines = String(command).replace(/\s+$/, "").split("\n");
215
+ let head = lines[0]!; // split always yields one element
216
+ let body: string | null = null;
217
+ const doc = /<<(-?)\s*(['"]?)(\w+)\2/.exec(head);
218
+ if (doc) {
219
+ const last = lines.length - 1;
220
+ const strip = (l: string) => (doc[1] ? l.replace(/^\t+/, "") : l);
221
+ if (last < 1 || strip(lines[last]!).trim() !== doc[3]) return null;
222
+ const bodyLines = lines.slice(1, last).map(strip);
223
+ if (!doc[2] && bodyLines.some((l: string) => /[$`\\]/.test(l))) return null;
224
+ body = bodyLines.map((l) => `${l}\n`).join("");
225
+ head = head.slice(0, doc.index) + " " + head.slice(doc.index + doc[0].length);
226
+ } else if (lines.length > 1) return null;
227
+ const tokens = shellTokens(head);
228
+ if (!tokens || !tokens.length) return null;
229
+ const pipe = tokens.findIndex((t) => t.op === "|");
230
+ const redirect = tokens.findIndex((t) => t.op === ">" || t.op === ">>");
231
+ const producer = tokens.slice(0, pipe === -1 ? (redirect === -1 ? tokens.length : redirect) : pipe);
232
+ if (producer.some((t) => t.op)) return null;
233
+ const words = producer.map((t) => t.word /* no operators remain in producer */ as string);
234
+ if (words[0] === "tee") {
235
+ const tee = body == null ? null : teeTarget(tokens);
236
+ return tee && { ...tee, text: body };
237
+ }
238
+ const text = words[0] === "cat" ? (words.length === 1 ? body : null) : body == null ? producedText(words) : null;
239
+ if (text == null) return null;
240
+ if (pipe !== -1) {
241
+ const tee = teeTarget(tokens.slice(pipe + 1));
242
+ return tee && { ...tee, text };
243
+ }
244
+ const rest = tokens.slice(redirect);
245
+ if (redirect === -1 || rest.length !== 2 || !rest[1]?.word) return null;
246
+ return { file: rest[1].word, append: rest[0]?.op === ">>", text };
247
+ }
248
+
249
+ /** The edit a simple shell redirect makes to a `.gitignore`; [] for every other command. */
250
+ export function shellIgnoreEdits(command: unknown, cwd: string): IgnoreEdit[] {
251
+ const w = shellIgnoreWrite(command);
252
+ const file = w && ignoreTarget(w.file, cwd);
253
+ return file ? [ignoreEdit(file, linesOf(w.text))] : [];
254
+ }
255
+
256
+ /** Paths, relative to `top` with `/`, of the `.gitignore` in each directory above the target, from `top` down. */
257
+ export function parentIgnoreFiles(file: string, top: string, p: typeof path = path): string[] {
258
+ const rel = p.relative(p.resolve(top), p.dirname(file));
259
+ if (!rel || rel.startsWith("..") || p.isAbsolute(rel)) return [];
260
+ const parts = rel.split(p.sep);
261
+ return parts.map((_, i) => [...parts.slice(0, i), ".gitignore"].join("/"));
262
+ }
263
+
264
+ function nearestDir(file: string): string {
265
+ let dir = path.dirname(file);
266
+ while (!fs.existsSync(dir) && path.dirname(dir) !== dir) dir = path.dirname(dir);
267
+ return dir;
268
+ }
269
+
270
+ function topOf(file: string, git: string): string | null {
271
+ const r = runGit(git, ["rev-parse", "--show-toplevel"], nearestDir(file));
272
+ return r.status === 0 ? canonicalPath(path.resolve(r.stdout.trim())) : null;
273
+ }
274
+
275
+ /**
276
+ * The added lines of a nested `.gitignore` that its parent `.gitignore` files alone already ignore, each with the
277
+ * covering rule; [] unless every added line is literal and covered.
278
+ * @returns
279
+ */
280
+ export function redundantIgnoreLines(
281
+ target: string,
282
+ added: string[],
283
+ { git = "git" }: { git?: string } = {},
284
+ ): RedundantLine[] {
285
+ const lines = added.map((l) => l.trimEnd()).filter((l) => l && !l.startsWith("#"));
286
+ if (!lines.length || lines.some((l) => l.startsWith("!") || /[*?[\\]/.test(l))) return [];
287
+ const file = canonicalPath(path.resolve(target));
288
+ const top = topOf(file, git);
289
+ const parents = top ? parentIgnoreFiles(file, top) : [];
290
+ if (!top || !parents.length) return [];
291
+ const dir = path.relative(top, path.dirname(file)).split(path.sep).join("/");
292
+ const probes = lines.map((l) => {
293
+ const anchored = l.replace(/\/$/, "").includes("/");
294
+ const body = l.replace(/^\//, "");
295
+ return anchored ? [`${dir}/${body}`] : [`${dir}/${body}`, `${dir}/${PROBE_DIR}/${body}`];
296
+ });
297
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "repo-ignore-"));
298
+ try {
299
+ if (runGit(git, ["init", "-q", "--template="], tmp).status !== 0) return [];
300
+ for (const rel of parents) {
301
+ const src = path.join(top, ...rel.split("/"));
302
+ if (!fs.existsSync(src)) continue;
303
+ const dest = path.join(tmp, ...rel.split("/"));
304
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
305
+ fs.copyFileSync(src, dest);
306
+ }
307
+ const r = runGit(
308
+ git,
309
+ ["-c", "core.excludesFile=", "check-ignore", "--no-index", "-v", "--non-matching", "--", ...probes.flat()],
310
+ tmp,
311
+ );
312
+ if (r.status !== 0 && r.status !== 1) return [];
313
+ const hits = new Map<string, { source: string; n: string; pattern: string }>();
314
+ for (const row of r.stdout.split("\n")) {
315
+ const m = /^(.*?):(\d*):(.*)\t(.*)$/.exec(row);
316
+ if (m && m[1] && !m[3]!.startsWith("!")) hits.set(m[4]!, { source: m[1], n: m[2]!, pattern: m[3]! }); // groups 2-4 always match
317
+ }
318
+ if (!probes.every((ps) => ps.every((q) => hits.has(q)))) return [];
319
+ return lines.map((line, i) => {
320
+ // Every probe is in hits (checked above) and probes has one entry per line.
321
+ const h = hits.get(probes[i]![0]!)!;
322
+ return { line, rule: `${path.join(top, ...h.source.split("/"))}:${h.n} ${h.pattern}` };
323
+ });
324
+ } finally {
325
+ fs.rmSync(tmp, { recursive: true, force: true });
326
+ }
327
+ }
328
+
329
+ /** The deny reason for the first edit whose added lines are all redundant, else null. */
330
+ export function redundantIgnoreReason(edits: IgnoreEdit[]): string | null {
331
+ for (const e of edits) {
332
+ const hits = e.added.length ? redundantIgnoreLines(e.file, e.added) : [];
333
+ if (!hits.length) continue;
334
+ const items = hits.map((h) => `"${h.line}" (ignored by ${h.rule})`).join(", ");
335
+ return `redundant .gitignore lines in ${e.file}: ${items}. Leave them out; the parent rules already ignore them`;
336
+ }
337
+ return null;
338
+ }