@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,420 @@
1
+ #!/usr/bin/env bun
2
+ /** One TypeSafe System One call for an external research decision. Caps are local. */
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { isRecord } from "./hook-input.ts";
7
+ import { readEnv } from "../env.ts";
8
+ import type { Env } from "../env.ts";
9
+
10
+ export interface JevResult {
11
+ code: number;
12
+ text: string;
13
+ }
14
+
15
+ /** The request init this script sends; every field is always set. */
16
+ export interface JevInit {
17
+ method: string;
18
+ headers: Record<string, string>;
19
+ body: string;
20
+ signal: AbortSignal;
21
+ }
22
+
23
+ export type HeadersLike = { get(name: string): string | null } | Record<string, string>;
24
+
25
+ export interface JevResponse {
26
+ status: number;
27
+ json: () => Promise<unknown>;
28
+ headers?: HeadersLike | null;
29
+ }
30
+
31
+ export type JevFetch = (url: string, init: JevInit) => Promise<JevResponse>;
32
+
33
+ export interface JevRunOpts {
34
+ home?: string | undefined;
35
+ env?: Env | undefined;
36
+ fetchImpl?: JevFetch | undefined;
37
+ sleep?: ((ms: number) => Promise<void>) | undefined;
38
+ now?: number | (() => number) | undefined;
39
+ stateText?: unknown;
40
+ questionsText?: unknown;
41
+ }
42
+
43
+ export type JevRun = (opts?: JevRunOpts) => Promise<JevResult>;
44
+
45
+ export interface JevMainOpts extends Omit<JevRunOpts, "stateText" | "questionsText"> {
46
+ run?: JevRun;
47
+ }
48
+
49
+ interface Ledger {
50
+ day: string;
51
+ requests: number;
52
+ input_tokens: number;
53
+ }
54
+
55
+ interface PostResult {
56
+ status: number;
57
+ json: unknown;
58
+ headers: HeadersLike | null | undefined;
59
+ }
60
+
61
+ type Attempt = { fail: JevResult } | { response: PostResult; nowMs: number };
62
+
63
+ type Begun = { busy: true } | { stop: "requests" | "tokens" } | { ok: true; estimate: number };
64
+
65
+ function isErrno(err: unknown, code: string): boolean {
66
+ return isRecord(err) && err.code === code;
67
+ }
68
+
69
+ export const MODEL = "jev-1.13.0";
70
+ export const ENDPOINT = "https://api.typesafe.ai/v1/systemone";
71
+ export const MAX_STATE_CHARS = 64_000;
72
+ export const MAX_QUESTIONS = 8;
73
+ export const MAX_REQUESTS_PER_DAY = 40;
74
+ export const MAX_INPUT_TOKENS_PER_DAY = 1_000_000;
75
+ export const TIMEOUT_MS = 10_000;
76
+ export const MAX_RETRY_WAIT_MS = 2_000;
77
+ export const LOCK_STALE_MS = 10_000;
78
+
79
+ const USAGE = "usage: bun repo jev --available | --state FILE --questions FILE\n";
80
+ const MISSING_KEY = "missing TYPESAFE_API_KEY or ~/.workerstack/jev.json. setup: bun repo setup jev\n";
81
+
82
+ export function jevJsonPath(home: string): string {
83
+ return path.join(home, ".workerstack", "jev.json");
84
+ }
85
+
86
+ export function jevUsagePath(home: string): string {
87
+ return path.join(home, ".workerstack", "jev-usage.json");
88
+ }
89
+
90
+ export function estimateTokens(stateText: unknown, questionsText: unknown): number {
91
+ return Math.ceil((String(stateText).length + String(questionsText).length) / 4);
92
+ }
93
+
94
+ export function loadJevKey({
95
+ env = readEnv(),
96
+ home = os.homedir(),
97
+ }: { env?: Env | undefined; home?: string | undefined } = {}): string {
98
+ const fromEnv = String(env.TYPESAFE_API_KEY || "").trim();
99
+ if (fromEnv) return fromEnv;
100
+ try {
101
+ const parsed: unknown = JSON.parse(fs.readFileSync(jevJsonPath(home), "utf8"));
102
+ return String(isRecord(parsed) && parsed.apiKey ? parsed.apiKey : "").trim();
103
+ } catch {
104
+ return "";
105
+ }
106
+ }
107
+
108
+ export function retryWaitMs(header: unknown, now: number = Date.now()): number | null {
109
+ if (header == null || String(header).trim() === "") return null;
110
+ const raw = String(header).trim();
111
+ if (/^\d+$/.test(raw)) {
112
+ const ms = Number(raw) * 1000;
113
+ return ms <= MAX_RETRY_WAIT_MS ? ms : null;
114
+ }
115
+ const when = Date.parse(raw);
116
+ if (Number.isNaN(when)) return null;
117
+ const ms = when - now;
118
+ if (ms < 0) return 0;
119
+ return ms <= MAX_RETRY_WAIT_MS ? ms : null;
120
+ }
121
+
122
+ function fail(text: string): JevResult {
123
+ return { code: 2, text };
124
+ }
125
+
126
+ function headerGet(headers: HeadersLike | null | undefined, name: string): unknown {
127
+ if (!headers) return null;
128
+ if ("get" in headers && typeof headers.get === "function") return headers.get(name);
129
+ const plain: Record<string, string> = headers as Record<string, string>; // not a Headers object, so a plain map
130
+ return plain[name] ?? null;
131
+ }
132
+
133
+ function readLedger(file: string, day: string): Ledger {
134
+ try {
135
+ const parsed: unknown = JSON.parse(fs.readFileSync(file, "utf8"));
136
+ if (!isRecord(parsed) || parsed.day !== day) return { day, requests: 0, input_tokens: 0 };
137
+ return {
138
+ day,
139
+ requests: Number(parsed.requests) || 0,
140
+ input_tokens: Number(parsed.input_tokens) || 0,
141
+ };
142
+ } catch {
143
+ return { day, requests: 0, input_tokens: 0 };
144
+ }
145
+ }
146
+
147
+ function writeLedger(file: string, row: Ledger): void {
148
+ fs.writeFileSync(file, JSON.stringify(row) + "\n", { mode: 0o600 });
149
+ try {
150
+ fs.chmodSync(file, 0o600);
151
+ } catch {
152
+ /* win */
153
+ }
154
+ }
155
+
156
+ function withLock<T>(home: string, fn: () => T): T | { busy: true } {
157
+ const dir = path.join(home, ".workerstack");
158
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
159
+ const lock = path.join(dir, "jev-usage.lock");
160
+ const start = Date.now();
161
+ for (;;) {
162
+ try {
163
+ fs.mkdirSync(lock);
164
+ break;
165
+ } catch (err) {
166
+ if (!isErrno(err, "EEXIST")) throw err;
167
+ let stale = false;
168
+ try {
169
+ stale = Date.now() - fs.statSync(lock).mtimeMs > LOCK_STALE_MS;
170
+ } catch {
171
+ stale = true;
172
+ }
173
+ if (stale) {
174
+ try {
175
+ fs.rmdirSync(lock);
176
+ } catch {
177
+ /* owner still has it */
178
+ }
179
+ continue;
180
+ }
181
+ if (Date.now() - start > LOCK_STALE_MS) return { busy: true };
182
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 20);
183
+ }
184
+ }
185
+ try {
186
+ return fn();
187
+ } finally {
188
+ try {
189
+ fs.rmdirSync(lock);
190
+ } catch {
191
+ /* already gone */
192
+ }
193
+ }
194
+ }
195
+
196
+ function beginAttempt(home: string, nowMs: number, estimate: number): Begun | { busy: true } {
197
+ return withLock<Begun>(home, () => {
198
+ const file = jevUsagePath(home);
199
+ const day = new Date(nowMs).toISOString().slice(0, 10);
200
+ const cur = readLedger(file, day);
201
+ if (cur.requests >= MAX_REQUESTS_PER_DAY) return { stop: "requests" };
202
+ if (cur.input_tokens >= MAX_INPUT_TOKENS_PER_DAY || cur.input_tokens + estimate > MAX_INPUT_TOKENS_PER_DAY) {
203
+ return { stop: "tokens" };
204
+ }
205
+ const next = {
206
+ day,
207
+ requests: cur.requests + 1,
208
+ input_tokens: cur.input_tokens + estimate,
209
+ };
210
+ writeLedger(file, next);
211
+ return { ok: true, estimate };
212
+ });
213
+ }
214
+
215
+ function settleTokens(home: string, nowMs: number, estimate: number, actual: number): { ok: true } | { busy: true } {
216
+ return withLock(home, () => {
217
+ const file = jevUsagePath(home);
218
+ const day = new Date(nowMs).toISOString().slice(0, 10);
219
+ const cur = readLedger(file, day);
220
+ const input_tokens = Math.max(0, cur.input_tokens - estimate + actual);
221
+ writeLedger(file, { day, requests: cur.requests, input_tokens });
222
+ return { ok: true };
223
+ });
224
+ }
225
+
226
+ function parseState(stateText: string): unknown {
227
+ const trimmed = stateText.trim();
228
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return stateText;
229
+ try {
230
+ // Text that opens with { or [ parses to an object or array, never null.
231
+ return JSON.parse(stateText) as unknown;
232
+ } catch {
233
+ return stateText;
234
+ }
235
+ }
236
+
237
+ function formatAnswers(payload: Record<string, unknown>): string {
238
+ const model = String(payload.model || MODEL);
239
+ const used = Number(isRecord(payload.usage) ? payload.usage.input_tokens : payload.usage);
240
+ const lines = [`${model}. input_tokens=${Number.isFinite(used) ? used : 0}`];
241
+ const answers = isRecord(payload.answers) ? payload.answers : {};
242
+ for (const [id, answer] of Object.entries(answers)) {
243
+ if (lines.length >= 8) break;
244
+ if (!isRecord(answer)) continue;
245
+ if (answer.type === "choice") {
246
+ lines.push(`- ${id} choice=${answer.choice} confidence=${answer.confidence}`);
247
+ } else if (answer.type === "noul") {
248
+ lines.push(`- ${id} noul=${answer.noul}`);
249
+ } else if (answer.type === "score") {
250
+ lines.push(`- ${id} score=${answer.score} confidence=${answer.confidence}`);
251
+ }
252
+ }
253
+ return lines.join("\n") + "\n";
254
+ }
255
+
256
+ async function postOnce(
257
+ fetchImpl: JevFetch,
258
+ key: string,
259
+ state: unknown,
260
+ questions: Record<string, unknown>,
261
+ ): Promise<PostResult> {
262
+ const response = await fetchImpl(ENDPOINT, {
263
+ method: "POST",
264
+ headers: {
265
+ Authorization: `Bearer ${key}`,
266
+ "Content-Type": "application/json",
267
+ },
268
+ body: JSON.stringify({ model: MODEL, state, questions }),
269
+ signal: AbortSignal.timeout(TIMEOUT_MS),
270
+ });
271
+ let json: unknown = null;
272
+ try {
273
+ json = await response.json();
274
+ } catch {
275
+ json = null;
276
+ }
277
+ return { status: response.status, json, headers: response.headers };
278
+ }
279
+
280
+ function stopText(kind: string): string {
281
+ if (kind === "requests") return `daily request cap ${MAX_REQUESTS_PER_DAY}\n`;
282
+ if (kind === "tokens") return `daily input token cap ${MAX_INPUT_TOKENS_PER_DAY}\n`;
283
+ return "jev usage lock busy\n";
284
+ }
285
+
286
+ export function createJevRunner(): JevRun {
287
+ let spent = false;
288
+ return async function runJev(opts: JevRunOpts = {}): Promise<JevResult> {
289
+ if (spent) return fail("process request cap 1\n");
290
+ const home = opts.home || os.homedir();
291
+ const env = opts.env || readEnv();
292
+ // The global fetch returns a Response, which carries every JevResponse field.
293
+ const fetchImpl: JevFetch = opts.fetchImpl || (globalThis.fetch as JevFetch);
294
+ const sleep = opts.sleep || ((ms: number) => new Promise<void>((resolve) => setTimeout(resolve, ms)));
295
+ const nowOpt = opts.now;
296
+ const nowFn: () => number = typeof nowOpt === "function" ? nowOpt : () => nowOpt ?? Date.now();
297
+ const stateText = opts.stateText;
298
+ const questionsText = opts.questionsText;
299
+ if (typeof stateText !== "string" || typeof questionsText !== "string") {
300
+ return fail(USAGE);
301
+ }
302
+ if (stateText.length > MAX_STATE_CHARS) return fail("state exceeds 64000 characters\n");
303
+ let parsedQuestions: unknown;
304
+ try {
305
+ parsedQuestions = JSON.parse(questionsText);
306
+ } catch {
307
+ return fail("questions must be a JSON object\n");
308
+ }
309
+ if (!isRecord(parsedQuestions)) {
310
+ return fail("questions must be a JSON object\n");
311
+ }
312
+ const questions = parsedQuestions;
313
+ const count = Object.keys(questions).length;
314
+ if (count < 1) return fail("questions missing\n");
315
+ if (count > MAX_QUESTIONS) return fail("questions exceed 8\n");
316
+ const key = loadJevKey({ env, home });
317
+ if (!key) return fail(MISSING_KEY);
318
+ const estimate = estimateTokens(stateText, questionsText);
319
+ const state = parseState(stateText);
320
+
321
+ const attempt = async (): Promise<Attempt> => {
322
+ const nowMs = nowFn();
323
+ const begun = beginAttempt(home, nowMs, estimate);
324
+ if ("busy" in begun) return { fail: fail(stopText("lock")) };
325
+ if ("stop" in begun) return { fail: fail(stopText(begun.stop)) };
326
+ spent = true;
327
+ let response: PostResult;
328
+ try {
329
+ response = await postOnce(fetchImpl, key, state, questions);
330
+ } catch {
331
+ return { fail: fail("jev request failed\n") };
332
+ }
333
+ return { response, nowMs };
334
+ };
335
+
336
+ const first = await attempt();
337
+ if ("fail" in first) return first.fail;
338
+ let { response, nowMs } = first;
339
+ if (response.status === 429 || response.status === 529) {
340
+ const wait = retryWaitMs(headerGet(response.headers, "retry-after"), nowMs);
341
+ if (wait != null) {
342
+ await sleep(wait);
343
+ const second = await attempt();
344
+ if ("fail" in second) return second.fail;
345
+ response = second.response;
346
+ nowMs = second.nowMs;
347
+ }
348
+ }
349
+ const body = response.json;
350
+ if (response.status < 200 || response.status >= 300 || !isRecord(body)) {
351
+ return fail("jev request failed\n");
352
+ }
353
+ const actual = Number(isRecord(body.usage) ? body.usage.input_tokens : body.usage);
354
+ if (Number.isFinite(actual) && actual >= 0) settleTokens(home, nowMs, estimate, actual);
355
+ const text = formatAnswers(body);
356
+ if (text.includes(key)) return fail("jev request failed\n");
357
+ return { code: 0, text };
358
+ };
359
+ }
360
+
361
+ export function parseArgv(argv: unknown): { flags: Record<string, string> } {
362
+ const flags: Record<string, string> = {};
363
+ const args: unknown[] = Array.isArray(argv) ? argv : [];
364
+ for (let i = 0; i < args.length; i++) {
365
+ const arg = args[i];
366
+ if (typeof arg !== "string" || !arg.startsWith("--")) continue;
367
+ const eq = arg.indexOf("=");
368
+ if (eq > 2) {
369
+ flags[arg.slice(2, eq)] = arg.slice(eq + 1);
370
+ continue;
371
+ }
372
+ const name = arg.slice(2);
373
+ const next = args[i + 1];
374
+ if (next && !String(next).startsWith("--")) {
375
+ flags[name] = String(next);
376
+ i += 1;
377
+ } else flags[name] = "1";
378
+ }
379
+ return { flags };
380
+ }
381
+
382
+ const runner = createJevRunner();
383
+
384
+ export async function runJev(argv: string[], opts: JevMainOpts = {}): Promise<JevResult> {
385
+ const { flags } = parseArgv(argv);
386
+ if (flags.available) {
387
+ const present = Boolean(loadJevKey({ env: opts.env || readEnv(), home: opts.home || os.homedir() }));
388
+ return { code: 0, text: present ? "yes\n" : "no\n" };
389
+ }
390
+ if (!flags.state || !flags.questions) return fail(USAGE);
391
+ let stateText: string;
392
+ let questionsText: string;
393
+ try {
394
+ stateText = fs.readFileSync(flags.state, "utf8");
395
+ questionsText = fs.readFileSync(flags.questions, "utf8");
396
+ } catch {
397
+ return fail("state or questions file missing\n");
398
+ }
399
+ const run = opts.run || runner;
400
+ return run({
401
+ home: opts.home,
402
+ env: opts.env,
403
+ fetchImpl: opts.fetchImpl,
404
+ sleep: opts.sleep,
405
+ now: opts.now,
406
+ stateText,
407
+ questionsText,
408
+ });
409
+ }
410
+
411
+ export async function main(argv: string[]): Promise<number> {
412
+ try {
413
+ const result = await runJev(argv);
414
+ process.stdout.write(result.text);
415
+ return result.code;
416
+ } catch {
417
+ process.stdout.write("jev request failed\n");
418
+ return 2;
419
+ }
420
+ }