@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,206 @@
1
+ import { BASE_CONFIG } from "../fixtures/base-config.ts";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { parse, type ParseError } from "jsonc-parser";
6
+ import { afterEach, describe, expect, it } from "vitest";
7
+ import { CONFIG_FILE, type LintSkip, type Pack } from "../config.ts";
8
+ import { runSync } from "../sync.ts";
9
+ import type { Output, SyncContext } from "./outputs.ts";
10
+ import { standards } from "./standards.ts";
11
+
12
+ const temps: string[] = [];
13
+ afterEach(() => {
14
+ for (const dir of temps.splice(0)) fs.rmSync(dir, { recursive: true, force: true });
15
+ });
16
+
17
+ function context(packs: Pack[], name = "app", skip: readonly LintSkip[] = []): SyncContext {
18
+ return {
19
+ root: "/repo",
20
+ config: {
21
+ packs,
22
+ agents: { hosts: [], skills: [] },
23
+ ...BASE_CONFIG,
24
+ lint: { skip },
25
+ },
26
+ workspace: { root: "/repo", manifest: { name }, packages: [] },
27
+ read: () => null,
28
+ };
29
+ }
30
+
31
+ const file = (rel: string, tracked: boolean, managed: Output["managed"] = "whole"): Output => ({
32
+ kind: "file",
33
+ path: rel,
34
+ content: "x\n",
35
+ tracked,
36
+ managed,
37
+ });
38
+ const link = (rel: string, tracked: boolean): Output => ({
39
+ kind: "link",
40
+ path: rel,
41
+ target: "../x",
42
+ tracked,
43
+ managed: "whole",
44
+ });
45
+
46
+ function contentOf(outputs: readonly Output[], rel: string): unknown {
47
+ const found = outputs.find((output) => output.path === rel);
48
+ if (found?.kind !== "file") throw new Error(`no file output ${rel}`);
49
+ const errors: ParseError[] = [];
50
+ const value: unknown = parse(found.content, errors, { allowTrailingComma: true });
51
+ if (errors.length > 0) throw new Error(`${rel} does not parse`);
52
+ return value;
53
+ }
54
+
55
+ describe("the standards pass", () => {
56
+ it("writes the oxlint config of the workspace: the repo plugin, and a package bin's override", () => {
57
+ const ctx = context(["standards"]);
58
+ ctx.workspace.packages.push({ dir: "packages/cli", manifest: { bin: "./bin/cli.ts" } });
59
+ const { outputs, errors } = standards(ctx, []);
60
+ expect(errors).toEqual([]);
61
+ const config = contentOf(outputs, ".oxlintrc.json") as { jsPlugins: unknown; overrides: unknown[] };
62
+ expect(config.jsPlugins).toEqual([{ name: "repo", specifier: "@workerstack/repo/lint" }]);
63
+ expect(config.overrides).toContainEqual({
64
+ files: ["packages/cli/bin/cli.ts"],
65
+ rules: { "repo/no-module-side-effects": "off" },
66
+ });
67
+ });
68
+
69
+ it("writes each lint.skip entry as the last override, and refuses a rule the config never runs with no output", () => {
70
+ const reason = "the parsed config cache lives for the process";
71
+ const live = { files: ["src/cache.ts"], rules: ["repo/no-module-state"], reason };
72
+ const { outputs, errors } = standards(context(["standards"], "app", [live]), []);
73
+ expect(errors).toEqual([]);
74
+ const config = contentOf(outputs, ".oxlintrc.json") /* the oxlint config always has overrides */ as {
75
+ overrides: unknown[];
76
+ };
77
+ expect(config.overrides.at(-1)).toEqual({ files: ["src/cache.ts"], rules: { "repo/no-module-state": "off" } });
78
+
79
+ const typo = { ...live, rules: ["repo/no-modul-state"] };
80
+ expect(standards(context(["standards"], "app", [typo]), [])).toEqual({
81
+ outputs: [],
82
+ errors: [
83
+ 'workerstack.config.ts: lint.skip[0].rules: "repo/no-modul-state" is not a rule the generated config runs',
84
+ ],
85
+ });
86
+ });
87
+
88
+ it("writes the oxfmt config: width 120, package.json left unsorted, no trailing commas in JSONC, markdown and fixtures ignored", () => {
89
+ const { outputs } = standards(context(["standards"]), []);
90
+ expect(contentOf(outputs, ".oxfmtrc.jsonc")).toEqual({
91
+ printWidth: 120,
92
+ sortPackageJson: false,
93
+ overrides: [{ files: ["**/*.jsonc"], options: { trailingComma: "none" } }],
94
+ ignorePatterns: [
95
+ "**/*.md",
96
+ "**/fixtures/**",
97
+ "/.gitattributes",
98
+ "/.githooks/commit-msg",
99
+ "/.githooks/pre-commit",
100
+ "/.gitignore",
101
+ "/.oxfmtrc.jsonc",
102
+ "/.oxlintrc.json",
103
+ "/.vscode/settings.json",
104
+ "/knip.json",
105
+ ],
106
+ });
107
+ });
108
+
109
+ it("has oxfmt ignore every planned output of a repo that commits its trees, tracked or not, whole or block, anchored at the root", () => {
110
+ const planned = [
111
+ file("bunfig.toml", true),
112
+ file(".claude/settings.json", true),
113
+ file(".codex/hooks.json", false),
114
+ file("packages/api/references/INDEX.md", true, "block"),
115
+ link(".claude/skills/deploy", true),
116
+ ];
117
+ const { outputs } = standards(context(["agents", "standards"], "@workerstack/repo"), planned);
118
+ expect(contentOf(outputs, ".oxfmtrc.jsonc")).toMatchObject({
119
+ ignorePatterns: [
120
+ "**/*.md",
121
+ "**/fixtures/**",
122
+ "/.claude/settings.json",
123
+ "/.claude/skills/deploy",
124
+ "/.codex/hooks.json",
125
+ "/.gitattributes",
126
+ "/.githooks/commit-msg",
127
+ "/.githooks/pre-commit",
128
+ "/.gitignore",
129
+ "/.oxfmtrc.jsonc",
130
+ "/.oxlintrc.json",
131
+ "/.vscode/settings.json",
132
+ "/bunfig.toml",
133
+ "/knip.json",
134
+ "/packages/api/references/INDEX.md",
135
+ ],
136
+ });
137
+ });
138
+
139
+ it("plans both configs as sync's own, untracked files, the hooks as tracked ones, and nothing without the pack", () => {
140
+ const shapes = standards(context(["standards"]), []).outputs.map(({ kind, path: rel, tracked, managed }) => ({
141
+ kind,
142
+ path: rel,
143
+ tracked,
144
+ managed,
145
+ }));
146
+ expect(shapes).toEqual([
147
+ { kind: "file", path: ".oxlintrc.json", tracked: false, managed: "whole" },
148
+ { kind: "file", path: "knip.json", tracked: false, managed: "whole" },
149
+ { kind: "file", path: ".oxfmtrc.jsonc", tracked: false, managed: "whole" },
150
+ { kind: "file", path: ".githooks/commit-msg", tracked: true, managed: "whole" },
151
+ { kind: "file", path: ".githooks/pre-commit", tracked: true, managed: "whole" },
152
+ ]);
153
+ expect(standards(context(["agents", "docs"]), [file("bunfig.toml", true)])).toEqual({ outputs: [], errors: [] });
154
+ });
155
+ });
156
+
157
+ function repo(packs: string): string {
158
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), "workerstack-standards-"));
159
+ temps.push(root);
160
+ fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "app" }));
161
+ fs.writeFileSync(path.join(root, CONFIG_FILE), `export default { packs: ${packs} }\n`);
162
+ return root;
163
+ }
164
+ const sync = (root: string) => runSync([], { cwd: root, stdout: () => {}, stderr: () => {} }, { generators: [] });
165
+
166
+ describe("repo sync with the standards pack", () => {
167
+ it("writes both configs and has git ignore them, then prunes them once the pack is dropped", async () => {
168
+ const root = repo('["standards"]');
169
+ expect(await sync(root)).toBe(0);
170
+ expect(fs.existsSync(path.join(root, ".oxlintrc.json"))).toBe(true);
171
+ expect(fs.existsSync(path.join(root, ".oxfmtrc.jsonc"))).toBe(true);
172
+ for (const hook of ["pre-commit", "commit-msg"]) {
173
+ expect(fs.statSync(path.join(root, ".githooks", hook)).mode & 0o777).toBe(
174
+ process.platform === "win32" ? 0o666 : 0o755,
175
+ ); // no execute bits on win32
176
+ }
177
+ expect(fs.readFileSync(path.join(root, ".gitignore"), "utf8").split("\n")).toEqual(
178
+ expect.arrayContaining([".oxfmtrc.jsonc", ".oxlintrc.json", ".oxlintrc.unskipped-*.json"]),
179
+ );
180
+
181
+ fs.writeFileSync(path.join(root, CONFIG_FILE), "export default { packs: [] }\n");
182
+ expect(await sync(root)).toBe(0);
183
+ expect(fs.existsSync(path.join(root, ".oxlintrc.json"))).toBe(false);
184
+ expect(fs.existsSync(path.join(root, ".oxfmtrc.jsonc"))).toBe(false);
185
+ expect(fs.existsSync(path.join(root, ".githooks"))).toBe(false);
186
+ expect(fs.readFileSync(path.join(root, ".gitignore"), "utf8")).not.toContain(".ox");
187
+ });
188
+ });
189
+
190
+ describe("repo sync with the standards pack and knip", () => {
191
+ it("writes knip.json with the knip.ignore entries and has git ignore it and its one-run copies, then prunes it", async () => {
192
+ const root = repo('["standards"]');
193
+ const config = `export default { packs: ["standards"], knip: { ignore: [{ file: "src/old.ts", reason: "by name" }] } }\n`;
194
+ fs.writeFileSync(path.join(root, CONFIG_FILE), config);
195
+ expect(await sync(root)).toBe(0);
196
+ expect(JSON.parse(fs.readFileSync(path.join(root, "knip.json"), "utf8"))).toMatchObject({
197
+ workspaces: { ".": { ignoreFiles: ["src/old.ts"] } },
198
+ });
199
+ expect(fs.readFileSync(path.join(root, ".gitignore"), "utf8").split("\n")).toEqual(
200
+ expect.arrayContaining(["knip.json", "knip.unignored-*.json"]),
201
+ );
202
+ fs.writeFileSync(path.join(root, CONFIG_FILE), "export default { packs: [] }\n");
203
+ expect(await sync(root)).toBe(0);
204
+ expect(fs.existsSync(path.join(root, "knip.json"))).toBe(false);
205
+ });
206
+ });
@@ -0,0 +1,179 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { repoBinLookup } from "../scripts/hook-command.ts";
5
+ import { lines } from "../scripts/managed-text.ts";
6
+ import { canonicalPath } from "../scripts/workspace-root.ts";
7
+ import { GIT_FILE_PATHS, type PostPass } from "./git-files.ts";
8
+ import type { Output, SyncContext } from "./outputs.ts";
9
+ import { EXECUTABLE_MODE, INDEX_FIELDS, WINDOWS_PLATFORM } from "./standards.constants.ts";
10
+ import { KNIP_CONFIG_PATH, knipConfig } from "./knip-config.ts";
11
+ import { FIXTURES, OXLINT_CONFIG_PATH, oxlintConfig } from "./oxlint-config.ts";
12
+
13
+ export const OXFMT_CONFIG_PATH = ".oxfmtrc.jsonc";
14
+ /** Where the git hooks live; sync points `core.hooksPath` here. */
15
+ const HOOKS_DIR = ".githooks";
16
+ const HEADER = "# Generated by repo sync. Do not edit.";
17
+ /** Each git hook and the repo command it runs, with the arguments git passes. */
18
+ const GIT_HOOKS = { "commit-msg": 'commit-msg "$1"', "pre-commit": "turn --staged" } as const;
19
+ const HOOK_PATHS = Object.keys(GIT_HOOKS).map((name) => `${HOOKS_DIR}/${name}`);
20
+ /** The line width oxfmt formats to. */
21
+ export const PRINT_WIDTH = 120;
22
+
23
+ /**
24
+ * The oxfmt config: width 120, package.json keys left in their order, JSONC without trailing commas, and no
25
+ * markdown, fixture or sync output touched; each output path is anchored at the root, so it matches that file alone.
26
+ */
27
+ function oxfmtConfig(planned: readonly string[]): string {
28
+ const outputs = [
29
+ ...new Set([...planned, ...GIT_FILE_PATHS, ...HOOK_PATHS, OXLINT_CONFIG_PATH, OXFMT_CONFIG_PATH, KNIP_CONFIG_PATH]),
30
+ ].map((rel) => `/${rel}`);
31
+ const config = {
32
+ printWidth: PRINT_WIDTH,
33
+ sortPackageJson: false,
34
+ // Hand-written JSONC (hooks, MCP policy) is read by parsers that refuse a trailing comma.
35
+ overrides: [{ files: ["**/*.jsonc"], options: { trailingComma: "none" } }],
36
+ ignorePatterns: ["**/*.md", FIXTURES, ...outputs.sort()],
37
+ };
38
+ return `// Generated by repo sync. Do not edit.\n${JSON.stringify(config, null, 2)}\n`;
39
+ }
40
+
41
+ /**
42
+ * The tracked, executable git hooks: each finds the bin from `.`, the worktree top level git runs hooks in, never from
43
+ * an agent's project dir. A hook at either path without the generated header is the user's, so sync refuses it.
44
+ */
45
+ function gitHooks(ctx: SyncContext): { outputs: Output[]; errors: string[] } {
46
+ const outputs: Output[] = [];
47
+ const errors: string[] = [];
48
+ for (const [name, command] of Object.entries(GIT_HOOKS)) {
49
+ const rel = `${HOOKS_DIR}/${name}`;
50
+ const existing = ctx.read(rel);
51
+ if (existing !== null && lines(existing)[1] !== HEADER) {
52
+ errors.push(`${rel} is hand-written; delete it so repo sync can own it`);
53
+ continue;
54
+ }
55
+ const content = `#!/bin/sh\n${HEADER}\n${repoBinLookup(".")}\n"$r" ${command}\n`;
56
+ outputs.push({ kind: "file", path: rel, content, tracked: true, managed: "whole", executable: true });
57
+ }
58
+ return errors.length > 0 ? { outputs: [], errors } : { outputs, errors };
59
+ }
60
+
61
+ /**
62
+ * Under the standards pack, `.oxlintrc.json` (with an override per `lint.skip` entry), `knip.json` (with the
63
+ * `knip.ignore` entries) and `.oxfmtrc.jsonc`, all untracked and sync's own, and the git hooks; a hand-written hook or a skip of a rule the config never runs refuses all.
64
+ * It runs after the generators so oxfmt can ignore every output, and before the git files pass, whose paths it names
65
+ * itself and which marks the hooks generated.
66
+ */
67
+ export const standards: PostPass = (ctx, outputs) => {
68
+ if (!ctx.config.packs.includes("standards")) return { outputs: [], errors: [] };
69
+ const file = (target: string, content: string): Output => ({
70
+ kind: "file",
71
+ path: target,
72
+ content,
73
+ tracked: false,
74
+ managed: "whole",
75
+ });
76
+ const hooks = gitHooks(ctx);
77
+ const oxlint = oxlintConfig(ctx.workspace, ctx.config.lint.skip);
78
+ const errors = [...hooks.errors, ...(oxlint.ok ? [] : oxlint.errors)];
79
+ if (!oxlint.ok || errors.length > 0) return { outputs: [], errors };
80
+ return {
81
+ outputs: [
82
+ file(OXLINT_CONFIG_PATH, oxlint.value),
83
+ file(KNIP_CONFIG_PATH, knipConfig(ctx.workspace, ctx.config.knip.ignore)),
84
+ file(OXFMT_CONFIG_PATH, oxfmtConfig(outputs.map((output) => output.path))),
85
+ ...hooks.outputs,
86
+ ],
87
+ errors: [],
88
+ };
89
+ };
90
+
91
+ /** One git command run at a root, with `input` on its stdin; `status` is null when git could not start. */
92
+ export type GitRun = (
93
+ root: string,
94
+ args: readonly string[],
95
+ input?: string,
96
+ ) => { status: number | null; stdout: string; stderr: string };
97
+
98
+ /** Runs git at `root`; a git that cannot start is a null status with the reason as its stderr. */
99
+ export const runGit: GitRun = (root, args, input) => {
100
+ const result = spawnSync("git", [...args], { cwd: root, encoding: "utf8", input });
101
+ if (result.error) return { status: null, stdout: "", stderr: result.error.message };
102
+ return { status: result.status, stdout: result.stdout, stderr: result.stderr };
103
+ };
104
+
105
+ /** What the hooks path step did, for the summary line, and what it could not do, one line each. */
106
+ export type HooksPathResult = { done: string[]; warnings: string[] };
107
+
108
+ /**
109
+ * Converges `core.hooksPath` on the pack, in a checkout whose top level is `root`: set to the hooks when unset and the
110
+ * pack is on, unset when it is ours and the pack is off, and anything else left. A value pointing elsewhere while the
111
+ * pack is on is reported on every run, never taken over, since the user put it there.
112
+ */
113
+ export function syncHooksPath(root: string, on: boolean, git: GitRun = runGit): HooksPathResult {
114
+ const none: HooksPathResult = { done: [], warnings: [] };
115
+ const top = git(root, ["rev-parse", "--show-toplevel"]);
116
+ if (top.status !== 0 || canonicalPath(top.stdout.trim()) !== canonicalPath(root)) return none;
117
+ const change = (args: string[], what: string): HooksPathResult => {
118
+ const result = git(root, ["config", ...args]);
119
+ return result.status === 0
120
+ ? { done: [what], warnings: [] }
121
+ : { done: [], warnings: [`cannot ${what}: ${result.stderr.trim()}`] };
122
+ };
123
+ const got = git(root, ["config", "--show-scope", "--get", "core.hooksPath"]);
124
+ if (got.status !== 0) return on ? change(["core.hooksPath", HOOKS_DIR], `set core.hooksPath to ${HOOKS_DIR}`) : none;
125
+ const [scope, value] = got.stdout.trim().split("\t") as [string, string];
126
+ if (value !== HOOKS_DIR) return on ? { done: [], warnings: [foreignLine(scope, value)] } : none;
127
+ return on || scope !== "local" ? none : change(["--unset", "core.hooksPath"], "unset core.hooksPath");
128
+ }
129
+
130
+ /** Whether `git ls-files -s` fields are `mode sha stage path`. */
131
+ const isIndexRow = (fields: string[]): fields is [string, string, string, string] => fields.length === INDEX_FIELDS;
132
+
133
+ /** The mode and blob of each path in `git ls-files -s` output, by path; a line of another shape is left out. */
134
+ function indexEntries(listing: string): Map<string, { mode: string; sha: string }> {
135
+ const entries = new Map<string, { mode: string; sha: string }>();
136
+ for (const line of listing.split("\n")) {
137
+ const fields = line.split(/[ \t]/, INDEX_FIELDS);
138
+ if (!isIndexRow(fields)) continue;
139
+ const [mode, sha, , rel] = fields;
140
+ entries.set(rel, { mode, sha });
141
+ }
142
+ return entries;
143
+ }
144
+
145
+ /**
146
+ * On win32 git cannot see an executable bit, so `git add` records the hooks as `100644` and a Unix clone cannot run
147
+ * them. Sets the index mode of each hook sync wrote to `100755` (staging one git does not track yet), in a checkout
148
+ * whose top level is `root`. Elsewhere the file mode carries it and this does nothing.
149
+ */
150
+ export function markHooksExecutable(root: string, platform: string, git: GitRun = runGit): HooksPathResult {
151
+ const none: HooksPathResult = { done: [], warnings: [] };
152
+ if (platform !== WINDOWS_PLATFORM) return none;
153
+ const top = git(root, ["rev-parse", "--show-toplevel"]);
154
+ if (top.status !== 0 || canonicalPath(top.stdout.trim()) !== canonicalPath(root)) return none;
155
+ const listed = git(root, ["ls-files", "-s", "--", ...HOOK_PATHS]);
156
+ if (listed.status !== 0) return none;
157
+ const entries = indexEntries(listed.stdout);
158
+ const todo = HOOK_PATHS.filter(
159
+ (rel) => entries.get(rel)?.mode !== EXECUTABLE_MODE && fs.existsSync(path.join(root, rel)),
160
+ );
161
+ if (todo.length === 0) return none;
162
+ // A tracked hook keeps its staged blob (`--cacheinfo`); `--add` hashes the file as it is now, for one git has not seen.
163
+ const results = todo.map((rel) => {
164
+ const entry = entries.get(rel);
165
+ return entry
166
+ ? git(root, ["update-index", "--cacheinfo", `${EXECUTABLE_MODE},${entry.sha},${rel}`])
167
+ : git(root, ["update-index", "--add", "--chmod=+x", "--", rel]);
168
+ });
169
+ const failed = results.find((result) => result.status !== 0);
170
+ return failed === undefined
171
+ ? { done: [`marked ${todo.join(", ")} executable in the index`], warnings: [] }
172
+ : { done: [], warnings: [`cannot mark the git hooks executable: ${failed.stderr.trim()}`] };
173
+ }
174
+
175
+ /** The line for a `core.hooksPath` that points elsewhere, with the command that unsets it at its scope. */
176
+ function foreignLine(scope: string, value: string): string {
177
+ const flag = scope === "local" ? "" : `--${scope} `;
178
+ return `core.hooksPath is ${value}, so repo's hooks never run; unset it (git config ${flag}--unset core.hooksPath) and sync again`;
179
+ }