forge-workflow 0.0.10 → 0.1.0-beta.3

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 (468) hide show
  1. package/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
  2. package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
  3. package/.cursor/rules/permissions-guidance.mdc +2 -2
  4. package/.forge/hooks/check-tdd.js +82 -5
  5. package/.forge/hooks/forge-native-hook.js +431 -0
  6. package/.forge/protected-paths.yaml +157 -0
  7. package/AGENTS.md +151 -61
  8. package/CHANGELOG.md +709 -0
  9. package/CLAUDE.md +9 -118
  10. package/QUICKSTART.md +175 -0
  11. package/README.md +275 -365
  12. package/bin/forge-cmd.js +120 -9
  13. package/bin/forge-preflight.js +26 -5
  14. package/bin/forge.js +532 -489
  15. package/docs/INDEX.md +93 -0
  16. package/docs/PROJECT_DESIGN.md +685 -0
  17. package/docs/architecture/index.md +66 -0
  18. package/docs/architecture/notes/README.md +35 -0
  19. package/docs/architecture/subsystems/README.md +46 -0
  20. package/docs/forge/TOOLCHAIN.md +670 -0
  21. package/docs/forge/VALIDATION.md +82 -0
  22. package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
  23. package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
  24. package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
  25. package/docs/guides/GREPTILE_SETUP.md +46 -0
  26. package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
  27. package/docs/guides/MIGRATION.md +56 -0
  28. package/docs/guides/SETUP.md +121 -0
  29. package/docs/guides/SUPPORT.md +190 -0
  30. package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
  31. package/docs/guides/memory-backends.md +183 -0
  32. package/docs/reference/ADAPTERS.md +128 -0
  33. package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
  34. package/docs/reference/COMMANDS.md +214 -0
  35. package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
  36. package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
  37. package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
  38. package/docs/reference/HERMES_INTEGRATION.md +118 -0
  39. package/docs/reference/INSIGHTS_RECAP.md +63 -0
  40. package/docs/reference/INSTALL.md +164 -0
  41. package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
  42. package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
  43. package/docs/reference/RELEASE.md +68 -0
  44. package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
  45. package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
  46. package/docs/reference/SKILLS.md +35 -0
  47. package/docs/reference/STATUS_BOARD.md +80 -0
  48. package/docs/reference/TEMPLATES.md +106 -0
  49. package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
  50. package/docs/reference/VALIDATION.md +82 -0
  51. package/docs/reference/agent-permissions.md +169 -0
  52. package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
  53. package/docs/reference/control-plane-guarantees.md +125 -0
  54. package/docs/reference/dependency-chain.md +331 -0
  55. package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
  56. package/docs/reference/forge-kernel-schema.md +72 -0
  57. package/docs/reference/kernel-conflict-evaluators.md +27 -0
  58. package/docs/reference/patch-md-format.md +77 -0
  59. package/docs/reference/protected-state-surfaces.md +59 -0
  60. package/docs/reference/shepherd.md +155 -0
  61. package/docs/reference/superpowers-analysis.md +320 -0
  62. package/docs/reference/superpowers-integration-options.md +404 -0
  63. package/docs/reference/test-environment.md +519 -0
  64. package/docs/reference/upgrade-safety.md +59 -0
  65. package/lefthook.yml +18 -0
  66. package/lib/activation/ensure-forge-home.js +135 -0
  67. package/lib/adapter-cli.js +307 -0
  68. package/lib/adapters/beads-issue-adapter.js +127 -0
  69. package/lib/adapters/beads-kernel-compat.js +1109 -0
  70. package/lib/adapters/greptile-review-adapter.js +141 -0
  71. package/lib/adapters/kernel-issue-adapter.js +101 -0
  72. package/lib/adapters/pr-state-adapter.js +484 -0
  73. package/lib/adoption-profiles.js +139 -0
  74. package/lib/agents/README.md +2 -6
  75. package/lib/agents/claude.plugin.json +3 -8
  76. package/lib/agents/codex.plugin.json +9 -1
  77. package/lib/agents/cursor.plugin.json +2 -6
  78. package/lib/agents/hermes.plugin.json +22 -0
  79. package/lib/agents-config.js +39 -1236
  80. package/lib/audit-evidence.js +282 -0
  81. package/lib/beads-detect.js +60 -0
  82. package/lib/beads-nudge.js +91 -0
  83. package/lib/beads-setup.js +121 -0
  84. package/lib/beads-sync-scaffold.js +25 -101
  85. package/lib/codex-skills.js +51 -1
  86. package/lib/commands/_aliases.js +248 -0
  87. package/lib/commands/_issue.js +780 -77
  88. package/lib/commands/_manifest.js +93 -0
  89. package/lib/commands/_registry.js +99 -34
  90. package/lib/commands/_resolve-command-opts.js +230 -0
  91. package/lib/commands/_serve-security.js +270 -0
  92. package/lib/commands/adapter.js +12 -0
  93. package/lib/commands/add.js +118 -0
  94. package/lib/commands/audit.js +70 -0
  95. package/lib/commands/blocked.js +5 -0
  96. package/lib/commands/board.js +64 -0
  97. package/lib/commands/claim.js +21 -2
  98. package/lib/commands/claims.js +7 -0
  99. package/lib/commands/clean.js +485 -75
  100. package/lib/commands/close.js +2 -2
  101. package/lib/commands/comment.js +5 -0
  102. package/lib/commands/control.js +148 -0
  103. package/lib/commands/create.js +2 -2
  104. package/lib/commands/dev.js +185 -7
  105. package/lib/commands/doc-gate.js +336 -0
  106. package/lib/commands/doctor.js +156 -0
  107. package/lib/commands/explain.js +15 -0
  108. package/lib/commands/export.js +237 -0
  109. package/lib/commands/gate.js +209 -0
  110. package/lib/commands/hooks.js +377 -0
  111. package/lib/commands/inbox.js +118 -0
  112. package/lib/commands/init.js +604 -0
  113. package/lib/commands/insights.js +79 -0
  114. package/lib/commands/issue.js +12 -1
  115. package/lib/commands/issues.js +17 -0
  116. package/lib/commands/lint.js +5 -0
  117. package/lib/commands/list.js +2 -2
  118. package/lib/commands/memory.js +81 -0
  119. package/lib/commands/merge.js +312 -0
  120. package/lib/commands/migrate.js +362 -0
  121. package/lib/commands/new.js +12 -0
  122. package/lib/commands/options.js +241 -0
  123. package/lib/commands/orient.js +13 -0
  124. package/lib/commands/orphans.js +5 -0
  125. package/lib/commands/patch.js +67 -0
  126. package/lib/commands/plan.js +481 -29
  127. package/lib/commands/pr.js +88 -0
  128. package/lib/commands/preflight.js +211 -0
  129. package/lib/commands/prime.js +13 -0
  130. package/lib/commands/push.js +135 -2
  131. package/lib/commands/ready.js +2 -2
  132. package/lib/commands/recall.js +171 -0
  133. package/lib/commands/recap.js +75 -0
  134. package/lib/commands/recommend.js +0 -1
  135. package/lib/commands/release.js +104 -0
  136. package/lib/commands/remember.js +140 -0
  137. package/lib/commands/role.js +99 -0
  138. package/lib/commands/serve.js +581 -0
  139. package/lib/commands/setup.js +900 -971
  140. package/lib/commands/shepherd.js +501 -0
  141. package/lib/commands/ship.js +59 -1
  142. package/lib/commands/show.js +2 -2
  143. package/lib/commands/stage.js +192 -0
  144. package/lib/commands/stale.js +5 -0
  145. package/lib/commands/status.js +158 -21
  146. package/lib/commands/sync.js +34 -46
  147. package/lib/commands/team.js +4 -1
  148. package/lib/commands/test.js +43 -27
  149. package/lib/commands/update.js +2 -2
  150. package/lib/commands/upgrade.js +47 -0
  151. package/lib/commands/validate.js +43 -18
  152. package/lib/commands/worktree.js +362 -99
  153. package/lib/config-writer.js +202 -0
  154. package/lib/control-plane.js +236 -0
  155. package/lib/core/runtime-graph.js +977 -0
  156. package/lib/dep-guard/keyword-ripple.js +2 -2
  157. package/lib/deprecated-sync-cleanup.js +362 -0
  158. package/lib/detect-agent.js +2 -28
  159. package/lib/detect-worktree.js +35 -9
  160. package/lib/doc-gate/declaration.js +177 -0
  161. package/lib/doc-gate/detect.js +289 -0
  162. package/lib/doc-gate/gate.js +375 -0
  163. package/lib/doc-gate/okf-config.js +128 -0
  164. package/lib/doc-gate/okf.js +429 -0
  165. package/lib/docs-command.js +1161 -6
  166. package/lib/forge-issues.js +382 -11
  167. package/lib/forge-lock.js +262 -0
  168. package/lib/gate-events.js +192 -0
  169. package/lib/global-flags.js +104 -0
  170. package/lib/greptile-match.js +7 -63
  171. package/lib/grounding/context-events.js +230 -0
  172. package/lib/grounding/read-first.js +112 -0
  173. package/lib/harness-capability-matrix.js +380 -0
  174. package/lib/hook-global-installer.js +347 -0
  175. package/lib/hook-renderer.js +541 -0
  176. package/lib/inbox.js +391 -0
  177. package/lib/insights.js +397 -0
  178. package/lib/issue-adapter.js +156 -0
  179. package/lib/issue-backend.js +145 -0
  180. package/lib/issue-render.js +220 -0
  181. package/lib/kernel/backing-issue.js +311 -0
  182. package/lib/kernel/broker.js +1218 -0
  183. package/lib/kernel/cli-broker-factory.js +130 -0
  184. package/lib/kernel/conflict-signal.js +82 -0
  185. package/lib/kernel/evaluators.js +195 -0
  186. package/lib/kernel/fs-class.js +495 -0
  187. package/lib/kernel/issue-command-contract.js +559 -0
  188. package/lib/kernel/issue-id-resolver.js +186 -0
  189. package/lib/kernel/lease-enforcer.js +158 -0
  190. package/lib/kernel/migrations.js +333 -0
  191. package/lib/kernel/owned-kernel.js +43 -0
  192. package/lib/kernel/planning-buckets-schema.js +109 -0
  193. package/lib/kernel/projection-jsonl-writer.js +450 -0
  194. package/lib/kernel/readiness-model.js +329 -0
  195. package/lib/kernel/schema.js +356 -0
  196. package/lib/kernel/sqlite-driver.js +2540 -0
  197. package/lib/kernel/taxonomy-validator.js +394 -0
  198. package/lib/lefthook-check.js +3 -2
  199. package/lib/lefthook-wiring.js +413 -0
  200. package/lib/mcp-config-renderer.js +288 -0
  201. package/lib/memory/graphiti-mcp.js +106 -0
  202. package/lib/memory/router.js +387 -0
  203. package/lib/memory/typed-api.js +102 -0
  204. package/lib/memory-digest.js +195 -0
  205. package/lib/merge-rules.js +395 -0
  206. package/lib/migrate-dry-run.js +466 -0
  207. package/lib/orientation.js +863 -0
  208. package/lib/package-manager-remediation.js +103 -0
  209. package/lib/package-root.js +381 -0
  210. package/lib/patch-intent.js +890 -0
  211. package/lib/plugin-catalog.js +3 -4
  212. package/lib/plugin-manager.js +0 -5
  213. package/lib/pr-bundle.js +186 -0
  214. package/lib/pr-monitor/auto-actions.js +175 -0
  215. package/lib/pr-monitor/differ.js +195 -0
  216. package/lib/pr-monitor/digest.js +206 -0
  217. package/lib/pr-monitor/events.js +0 -0
  218. package/lib/pr-monitor/gather.js +124 -0
  219. package/lib/pr-monitor/journal.js +299 -0
  220. package/lib/pr-monitor/monitor.js +146 -0
  221. package/lib/pr-monitor/render-sticky.js +192 -0
  222. package/lib/pr-monitor/upsert-sticky.js +169 -0
  223. package/lib/pr-monitor/watch-lifecycle.js +95 -0
  224. package/lib/pr-monitor/watch.js +247 -0
  225. package/lib/pr-pull.js +1314 -0
  226. package/lib/pr-shepherd.js +494 -0
  227. package/lib/pr-state-validator.js +59 -0
  228. package/lib/preflight/gates.js +237 -0
  229. package/lib/preflight/runner.js +116 -0
  230. package/lib/project-discovery.js +0 -53
  231. package/lib/project-memory.js +99 -497
  232. package/lib/protected-path-manifest.js +281 -0
  233. package/lib/protected-state-surfaces.js +387 -0
  234. package/lib/release-readiness.js +2105 -0
  235. package/lib/reset.js +59 -45
  236. package/lib/review-adapter.js +68 -0
  237. package/lib/rules-sync.js +260 -0
  238. package/lib/runtime-health.js +241 -20
  239. package/lib/safety-config-renderer.js +268 -0
  240. package/lib/setup-action-log.js +1 -7
  241. package/lib/setup.js +27 -65
  242. package/lib/shell-utils.js +76 -6
  243. package/lib/skills-sync.js +330 -0
  244. package/lib/smart-status/scoring.js +17 -3
  245. package/lib/status/beads-snapshot.js +45 -2
  246. package/lib/status/presenter.js +169 -18
  247. package/lib/status/snapshot.js +186 -0
  248. package/lib/sync-backend.js +202 -0
  249. package/lib/untrusted-content.js +52 -0
  250. package/lib/upgrade-safety.js +251 -0
  251. package/lib/workflow/enforce-stage.js +351 -45
  252. package/lib/workflow/stage-transition.js +115 -0
  253. package/lib/workflow/stages.js +30 -6
  254. package/lib/workflow/state-manager.js +11 -22
  255. package/lib/workflow/state.js +23 -1
  256. package/lib/workflow-profiles.js +17 -5
  257. package/package.json +37 -35
  258. package/rules/documentation.md +19 -0
  259. package/rules/kernel-tracking.md +26 -0
  260. package/rules/security.md +22 -0
  261. package/rules/tdd.md +20 -0
  262. package/rules/workflow.md +27 -0
  263. package/scripts/auto-backing-issue.js +47 -0
  264. package/scripts/beads-context.sh +81 -57
  265. package/scripts/beads-upgrade-smoke.sh +24 -3
  266. package/scripts/bootstrap-windows-tools.sh +78 -0
  267. package/scripts/branch-protection.js +2 -3
  268. package/scripts/check-agents.js +34 -137
  269. package/scripts/commitlint.js +3 -1
  270. package/scripts/conflict-detect.sh +3 -0
  271. package/scripts/dep-guard.sh +22 -3
  272. package/scripts/file-index.sh +3 -0
  273. package/scripts/forge-team/lib/claim.sh +34 -18
  274. package/scripts/forge-team/lib/dashboard.sh +61 -86
  275. package/scripts/forge-team/lib/epic.sh +99 -263
  276. package/scripts/forge-team/lib/hooks.sh +26 -28
  277. package/scripts/forge-team/lib/identity.sh +4 -4
  278. package/scripts/forge-team/lib/sync-github.sh +49 -84
  279. package/scripts/forge-team/lib/verify.sh +93 -83
  280. package/scripts/forge-team/lib/workload.sh +41 -65
  281. package/scripts/forge-team/tests/claim.test.sh +25 -19
  282. package/scripts/forge-team/tests/dashboard.test.sh +31 -46
  283. package/scripts/forge-team/tests/epic.test.sh +52 -71
  284. package/scripts/forge-team/tests/hooks.test.sh +38 -50
  285. package/scripts/forge-team/tests/identity.test.sh +3 -3
  286. package/scripts/forge-team/tests/integration.test.sh +44 -66
  287. package/scripts/forge-team/tests/sync-github.test.sh +50 -83
  288. package/scripts/forge-team/tests/verify.test.sh +37 -46
  289. package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
  290. package/scripts/forge-team/tests/workload.test.sh +32 -66
  291. package/scripts/gen-command-manifest.js +153 -0
  292. package/scripts/gen-embedded-assets.mjs +129 -0
  293. package/scripts/install.ps1 +139 -0
  294. package/scripts/install.sh +268 -0
  295. package/scripts/lib/release-asset.mjs +84 -0
  296. package/scripts/parity-check.mjs +145 -0
  297. package/scripts/parity-check.test.mjs +58 -0
  298. package/scripts/pin-agentic-workflow-images.js +112 -0
  299. package/scripts/pr-auto-actions.js +93 -0
  300. package/scripts/pr-coordinator.sh +3 -0
  301. package/scripts/pr-verdict-label.js +50 -0
  302. package/scripts/preflight-sonar.eslint.config.mjs +44 -0
  303. package/scripts/preflight.sh +21 -94
  304. package/scripts/protected-state-check.js +104 -0
  305. package/scripts/smart-status.sh +60 -57
  306. package/scripts/spikes/config-race-bench.js +111 -0
  307. package/scripts/spikes/harness-capability-matrix.js +13 -0
  308. package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
  309. package/scripts/spikes/protected-path-manifest.js +20 -0
  310. package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
  311. package/scripts/sync-agent-skills.js +62 -0
  312. package/scripts/sync-utils.sh +3 -0
  313. package/scripts/test-ci-shard.js +13 -6
  314. package/scripts/test.js +95 -12
  315. package/skills/claim-safety/SKILL.md +102 -0
  316. package/skills/claim-safety/evals/evals.json +46 -0
  317. package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
  318. package/skills/dev/evals/evals.json +50 -0
  319. package/skills/hermes-forge/SKILL.md +185 -0
  320. package/skills/hermes-forge/evals/evals.json +46 -0
  321. package/skills/issue-basics/SKILL.md +111 -0
  322. package/skills/issue-basics/evals/evals.json +46 -0
  323. package/skills/kernel/SKILL.md +166 -0
  324. package/skills/kernel/evals/evals.json +50 -0
  325. package/skills/memory/SKILL.md +102 -0
  326. package/skills/parallel-deep-research/SKILL.md +14 -11
  327. package/skills/parallel-deep-research/evals/evals.json +11 -27
  328. package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
  329. package/skills/plan/evals/evals.json +42 -0
  330. package/skills/research/SKILL.md +195 -0
  331. package/skills/research/evals/evals.json +42 -0
  332. package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
  333. package/skills/review/evals/evals.json +42 -0
  334. package/skills/rollback/SKILL.md +110 -0
  335. package/skills/rollback/evals/evals.json +46 -0
  336. package/skills/rollback/references/methods.md +204 -0
  337. package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
  338. package/skills/shepherd/SKILL.md +66 -0
  339. package/skills/shepherd/evals/evals.json +42 -0
  340. package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
  341. package/skills/ship/evals/evals.json +42 -0
  342. package/skills/smith/SKILL.md +142 -0
  343. package/skills/smith/evals/evals.json +46 -0
  344. package/skills/smith/references/autonomy-and-gates.md +94 -0
  345. package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
  346. package/skills/sonarcloud/evals/evals.json +46 -0
  347. package/skills/sonarcloud-analysis/SKILL.md +18 -13
  348. package/skills/sonarcloud-analysis/evals/evals.json +11 -15
  349. package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
  350. package/skills/status/evals/evals.json +50 -0
  351. package/skills/triage-ready/SKILL.md +121 -0
  352. package/skills/triage-ready/evals/evals.json +42 -0
  353. package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
  354. package/skills/validate/evals/evals.json +42 -0
  355. package/skills/verify/SKILL.md +299 -0
  356. package/skills/verify/evals/evals.json +50 -0
  357. package/.claude/commands/dev.md +0 -345
  358. package/.claude/commands/plan.md +0 -566
  359. package/.claude/commands/premerge.md +0 -186
  360. package/.claude/commands/research.md +0 -42
  361. package/.claude/commands/review.md +0 -451
  362. package/.claude/commands/rollback.md +0 -721
  363. package/.claude/commands/ship.md +0 -213
  364. package/.claude/commands/sonarcloud.md +0 -152
  365. package/.claude/commands/status.md +0 -90
  366. package/.claude/commands/validate.md +0 -288
  367. package/.claude/commands/verify.md +0 -269
  368. package/.claude/rules/workflow.md +0 -121
  369. package/.cline/workflows/dev.md +0 -342
  370. package/.cline/workflows/plan.md +0 -563
  371. package/.cline/workflows/premerge.md +0 -183
  372. package/.cline/workflows/research.md +0 -39
  373. package/.cline/workflows/review.md +0 -448
  374. package/.cline/workflows/rollback.md +0 -718
  375. package/.cline/workflows/ship.md +0 -210
  376. package/.cline/workflows/sonarcloud.md +0 -146
  377. package/.cline/workflows/status.md +0 -87
  378. package/.cline/workflows/validate.md +0 -285
  379. package/.cline/workflows/verify.md +0 -266
  380. package/.codex/config.toml +0 -11
  381. package/.codex/skills/dev/SKILL.md +0 -345
  382. package/.codex/skills/plan/SKILL.md +0 -566
  383. package/.codex/skills/premerge/SKILL.md +0 -186
  384. package/.codex/skills/research/SKILL.md +0 -42
  385. package/.codex/skills/review/SKILL.md +0 -451
  386. package/.codex/skills/rollback/SKILL.md +0 -721
  387. package/.codex/skills/ship/SKILL.md +0 -213
  388. package/.codex/skills/sonarcloud/SKILL.md +0 -149
  389. package/.codex/skills/status/SKILL.md +0 -90
  390. package/.codex/skills/validate/SKILL.md +0 -288
  391. package/.codex/skills/verify/SKILL.md +0 -269
  392. package/.cursor/commands/dev.md +0 -342
  393. package/.cursor/commands/plan.md +0 -563
  394. package/.cursor/commands/premerge.md +0 -183
  395. package/.cursor/commands/research.md +0 -39
  396. package/.cursor/commands/review.md +0 -448
  397. package/.cursor/commands/ship.md +0 -210
  398. package/.cursor/commands/sonarcloud.md +0 -146
  399. package/.cursor/commands/status.md +0 -87
  400. package/.cursor/commands/validate.md +0 -285
  401. package/.cursor/commands/verify.md +0 -266
  402. package/.cursorrules +0 -149
  403. package/.github/prompts/premerge.prompt.md +0 -188
  404. package/.github/prompts/research.prompt.md +0 -44
  405. package/.github/prompts/rollback.prompt.md +0 -723
  406. package/.github/prompts/verify.prompt.md +0 -271
  407. package/.github/workflows/beads-to-github.yml +0 -89
  408. package/.github/workflows/github-to-beads.yml +0 -100
  409. package/.kilocode/workflows/dev.md +0 -346
  410. package/.kilocode/workflows/plan.md +0 -567
  411. package/.kilocode/workflows/premerge.md +0 -187
  412. package/.kilocode/workflows/research.md +0 -43
  413. package/.kilocode/workflows/review.md +0 -452
  414. package/.kilocode/workflows/rollback.md +0 -722
  415. package/.kilocode/workflows/ship.md +0 -214
  416. package/.kilocode/workflows/sonarcloud.md +0 -150
  417. package/.kilocode/workflows/status.md +0 -91
  418. package/.kilocode/workflows/validate.md +0 -289
  419. package/.kilocode/workflows/verify.md +0 -270
  420. package/.opencode/commands/dev.md +0 -345
  421. package/.opencode/commands/plan.md +0 -566
  422. package/.opencode/commands/premerge.md +0 -186
  423. package/.opencode/commands/research.md +0 -42
  424. package/.opencode/commands/review.md +0 -451
  425. package/.opencode/commands/rollback.md +0 -721
  426. package/.opencode/commands/ship.md +0 -213
  427. package/.opencode/commands/sonarcloud.md +0 -149
  428. package/.opencode/commands/status.md +0 -90
  429. package/.opencode/commands/validate.md +0 -288
  430. package/.opencode/commands/verify.md +0 -269
  431. package/.roo/commands/dev.md +0 -346
  432. package/.roo/commands/plan.md +0 -567
  433. package/.roo/commands/premerge.md +0 -187
  434. package/.roo/commands/research.md +0 -43
  435. package/.roo/commands/review.md +0 -452
  436. package/.roo/commands/rollback.md +0 -722
  437. package/.roo/commands/ship.md +0 -214
  438. package/.roo/commands/sonarcloud.md +0 -150
  439. package/.roo/commands/status.md +0 -91
  440. package/.roo/commands/validate.md +0 -289
  441. package/.roo/commands/verify.md +0 -270
  442. package/docs/BEADS_GITHUB_SYNC.md +0 -281
  443. package/docs/GREPTILE_SETUP.md +0 -400
  444. package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
  445. package/docs/SETUP.md +0 -663
  446. package/docs/VALIDATION.md +0 -363
  447. package/lib/agents/cline.plugin.json +0 -29
  448. package/lib/agents/copilot.plugin.json +0 -24
  449. package/lib/agents/kilocode.plugin.json +0 -22
  450. package/lib/agents/opencode.plugin.json +0 -23
  451. package/lib/agents/roo.plugin.json +0 -30
  452. package/lib/beads-bootstrap.js +0 -225
  453. package/lib/beads-health-check.js +0 -188
  454. package/lib/commands/commands-reset.js +0 -147
  455. package/opencode.json +0 -67
  456. package/scripts/beads-context.test.js +0 -584
  457. package/scripts/github-beads-sync/comment.mjs +0 -64
  458. package/scripts/github-beads-sync/config.mjs +0 -148
  459. package/scripts/github-beads-sync/github-api.mjs +0 -131
  460. package/scripts/github-beads-sync/index.mjs +0 -356
  461. package/scripts/github-beads-sync/label-mapper.mjs +0 -54
  462. package/scripts/github-beads-sync/mapping.mjs +0 -132
  463. package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
  464. package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
  465. package/scripts/github-beads-sync/run-bd.mjs +0 -161
  466. package/scripts/github-beads-sync/sanitize.mjs +0 -121
  467. package/scripts/github-beads-sync.config.json +0 -26
  468. package/scripts/sync-commands.js +0 -600
@@ -1,132 +0,0 @@
1
- /**
2
- * CRUD module for .github/beads-mapping.json
3
- *
4
- * Maps GitHub issue numbers (string keys) to Beads issue IDs.
5
- * Format: { "42": "forge-abc", "7": "forge-xyz" }
6
- *
7
- * @module mapping
8
- */
9
-
10
- import fs from 'node:fs';
11
- import path from 'node:path';
12
- import { createRequire } from 'node:module';
13
-
14
- const require = createRequire(import.meta.url);
15
- const { createLinkStore, resolveCanonicalLink, upsertCanonicalLink } = require('../../lib/issue-sync/link-store.js');
16
- const { bridgeLegacyLinkHints } = require('../../lib/issue-sync/legacy-link-bridge.js');
17
-
18
- /**
19
- * Reads the mapping file and returns parsed JSON.
20
- * Returns {} if the file does not exist.
21
- * Throws with a helpful message if JSON is invalid.
22
- *
23
- * @param {string} mappingPath - Absolute path to the mapping JSON file
24
- * @returns {Record<string, string>} The mapping object
25
- */
26
- export function readMapping(mappingPath) {
27
- if (!fs.existsSync(mappingPath)) {
28
- return {};
29
- }
30
- const raw = fs.readFileSync(mappingPath, 'utf8');
31
- try {
32
- return JSON.parse(raw);
33
- } catch (err) {
34
- throw new Error(`Failed to parse mapping file at ${mappingPath}: ${err.message}`, { cause: err });
35
- }
36
- }
37
-
38
- /**
39
- * Writes the mapping object to disk as JSON with 2-space indent.
40
- * Atomic: writes to a temp file then renames.
41
- * Creates parent directories if they do not exist.
42
- *
43
- * @param {string} mappingPath - Absolute path to the mapping JSON file
44
- * @param {Record<string, string>} data - The mapping object to write
45
- */
46
- export function writeMapping(mappingPath, data) {
47
- const dir = path.dirname(mappingPath);
48
- fs.mkdirSync(dir, { recursive: true });
49
-
50
- const tmpPath = mappingPath + '.tmp';
51
- const content = JSON.stringify(data, null, 2) + '\n';
52
- fs.writeFileSync(tmpPath, content, 'utf8');
53
- fs.renameSync(tmpPath, mappingPath);
54
- }
55
-
56
- /**
57
- * Returns the Beads ID for a given GitHub issue number, or null if not found.
58
- * Coerces numeric issueNumber to string for lookup.
59
- *
60
- * @param {string} mappingPath - Absolute path to the mapping JSON file
61
- * @param {string|number} issueNumber - The GitHub issue number
62
- * @returns {string|null} The Beads ID or null
63
- */
64
- export function getBeadsId(mappingPath, issueNumber) {
65
- const data = readMapping(mappingPath);
66
- const key = String(issueNumber);
67
- return data[key] ?? null;
68
- }
69
-
70
- /**
71
- * Adds or updates a mapping entry. Reads existing data, merges, and writes back.
72
- * Preserves all existing entries.
73
- *
74
- * @param {string} mappingPath - Absolute path to the mapping JSON file
75
- * @param {string|number} issueNumber - The GitHub issue number
76
- * @param {string} beadsId - The Beads issue ID
77
- */
78
- export function setBeadsId(mappingPath, issueNumber, beadsId) {
79
- const data = readMapping(mappingPath);
80
- const key = String(issueNumber);
81
- data[key] = beadsId;
82
- writeMapping(mappingPath, data);
83
- }
84
-
85
- /**
86
- * Loads a canonical link store seeded from the legacy mapping file plus any
87
- * optional migration hints.
88
- *
89
- * @param {string} mappingPath - Path to the legacy mapping file
90
- * @param {object} [legacyHints] - Additional migration hints to bridge
91
- * @returns {ReturnType<typeof createLinkStore>}
92
- */
93
- export function loadCanonicalLinkStore(mappingPath, legacyHints = {}) {
94
- const store = createLinkStore();
95
- const mapping = readMapping(mappingPath);
96
- bridgeLegacyLinkHints({ ...legacyHints, mapping }, { store });
97
- return store;
98
- }
99
-
100
- /**
101
- * Resolves the canonical link record for a GitHub lookup using the legacy
102
- * mapping file only as a bridge input.
103
- *
104
- * @param {string} mappingPath - Path to the legacy mapping file
105
- * @param {object} lookup - Canonical lookup values
106
- * @param {object} [legacyHints] - Additional migration hints to bridge
107
- * @returns {object|null}
108
- */
109
- export function resolveCanonicalBeadsLink(mappingPath, lookup = {}, legacyHints = {}) {
110
- const store = loadCanonicalLinkStore(mappingPath, legacyHints);
111
- return resolveCanonicalLink(store, lookup);
112
- }
113
-
114
- /**
115
- * Upserts a canonical link and mirrors it into the legacy mapping file for
116
- * compatibility during migration.
117
- *
118
- * @param {string} mappingPath - Path to the legacy mapping file
119
- * @param {object} link - Canonical link record
120
- * @param {object} [legacyHints] - Additional migration hints to bridge
121
- * @returns {object}
122
- */
123
- export function upsertCanonicalBeadsLink(mappingPath, link, legacyHints = {}) {
124
- const store = loadCanonicalLinkStore(mappingPath, legacyHints);
125
- const canonical = upsertCanonicalLink(store, link);
126
-
127
- if (canonical?.github?.number != null && canonical.forgeIssueId) {
128
- setBeadsId(mappingPath, canonical.github.number, canonical.forgeIssueId);
129
- }
130
-
131
- return canonical;
132
- }
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * CLI entry point for Beads → GitHub reverse sync.
4
- * Usage: node reverse-sync-cli.mjs <old-snapshot-jsonl-path> <new-snapshot-jsonl-path>
5
- *
6
- * @module scripts/github-beads-sync/reverse-sync-cli
7
- */
8
-
9
- import { readFileSync } from 'node:fs';
10
- import { handleBeadsClosed } from './reverse-sync.mjs';
11
-
12
- const oldPath = process.argv[2];
13
- const newPath = process.argv[3];
14
-
15
- if (!oldPath || !newPath) {
16
- console.error('Usage: node reverse-sync-cli.mjs <old-snapshot-jsonl-path> <new-snapshot-jsonl-path>');
17
- process.exit(1);
18
- }
19
-
20
- const oldContent = readFileSync(oldPath, 'utf-8');
21
- const newContent = readFileSync(newPath, 'utf-8');
22
-
23
- const result = handleBeadsClosed(oldContent, newContent);
24
- console.log(JSON.stringify(result, null, 2));
25
-
26
- if (result.errors.length > 0) {
27
- console.error(`${result.errors.length} issue(s) failed to close on GitHub`);
28
- process.exit(1);
29
- }
30
-
31
- console.log(`Closed ${result.closed.length} GitHub issue(s), skipped ${result.skipped.length}`);
@@ -1,162 +0,0 @@
1
- /**
2
- * Reverse sync: Beads → GitHub.
3
- * When a Beads issue is closed (via git push updating exported issue snapshots),
4
- * close the linked GitHub issue.
5
- *
6
- * @module scripts/github-beads-sync/reverse-sync
7
- */
8
-
9
- import { execFileSync } from 'node:child_process';
10
-
11
- /**
12
- * Parse JSONL lines into an array of objects, skipping empty/malformed lines.
13
- * @param {string[]} lines - Array of JSONL strings
14
- * @returns {Array<{id: string, status: string, description?: string}>}
15
- */
16
- function parseJsonlLines(lines) {
17
- const results = [];
18
- for (const line of lines) {
19
- const trimmed = line.trim();
20
- if (!trimmed) continue;
21
- try {
22
- const obj = JSON.parse(trimmed);
23
- if (obj && obj.id) results.push(obj);
24
- } catch (_err) {
25
- // Skip malformed lines
26
- }
27
- }
28
- return results;
29
- }
30
-
31
- function extractCanonicalGitHubLink(issue = {}) {
32
- const github = issue.github ?? {};
33
- if (typeof github.url === 'string' && github.url.length > 0) {
34
- const match = github.url.match(
35
- /https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/,
36
- );
37
- if (match) {
38
- return {
39
- owner: match[1],
40
- repo: match[2],
41
- issueNumber: parseInt(match[3], 10),
42
- };
43
- }
44
- }
45
- return null;
46
- }
47
-
48
- function extractPreferredGitHubLink(issue = {}) {
49
- return extractCanonicalGitHubLink(issue) ?? extractGitHubUrl(issue.description);
50
- }
51
-
52
- /**
53
- * Detect Beads issues that transitioned to "closed" status.
54
- * Only detects transitions: issue must exist in oldLines as non-closed,
55
- * and appear in newLines as "closed".
56
- *
57
- * @param {string[]} oldLines - JSONL lines from a previous exported issue snapshot
58
- * @param {string[]} newLines - JSONL lines from a current exported issue snapshot
59
- * @returns {Array<{id: string, description: string}>} Issues that transitioned to closed
60
- */
61
- export function detectClosedIssues(oldLines, newLines) {
62
- const oldMap = new Map();
63
- for (const issue of parseJsonlLines(oldLines)) {
64
- oldMap.set(issue.id, issue.status);
65
- }
66
-
67
- const closed = [];
68
- for (const issue of parseJsonlLines(newLines)) {
69
- if (issue.status !== 'closed') continue;
70
- const oldStatus = oldMap.get(issue.id);
71
- // Must have existed before and not been closed already
72
- if (oldStatus == null || oldStatus === 'closed') continue;
73
- closed.push({ id: issue.id, description: issue.description || '' });
74
- }
75
- return closed;
76
- }
77
-
78
- /**
79
- * Extract GitHub owner, repo, and issue number from a description string
80
- * containing a GitHub issue URL.
81
- *
82
- * @param {string|null|undefined} description - Text that may contain a GitHub issue URL
83
- * @returns {{owner: string, repo: string, issueNumber: number}|null}
84
- */
85
- export function extractGitHubUrl(description) {
86
- if (!description) return null;
87
- const match = description.match(
88
- /https:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/,
89
- );
90
- if (!match) return null;
91
- return {
92
- owner: match[1],
93
- repo: match[2],
94
- issueNumber: parseInt(match[3], 10),
95
- };
96
- }
97
-
98
- /**
99
- * Close a GitHub issue using the `gh api` CLI.
100
- * Uses execFileSync with array args (no shell).
101
- *
102
- * @param {string} owner - Repository owner
103
- * @param {string} repo - Repository name
104
- * @param {number|string} issueNumber - Issue number
105
- */
106
- export function closeGitHubIssue(owner, repo, issueNumber) {
107
- execFileSync('gh', [
108
- 'api',
109
- `repos/${owner}/${repo}/issues/${issueNumber}`,
110
- '-X', 'PATCH',
111
- '-f', 'state=closed',
112
- ], { encoding: 'utf-8' });
113
- }
114
-
115
- /**
116
- * Handle Beads-to-GitHub reverse sync.
117
- * Detects issues that transitioned to closed in exported issue snapshot JSONL
118
- * and closes the linked GitHub issues.
119
- *
120
- * @param {string} oldContent - Previous exported issue snapshot content
121
- * @param {string} newContent - Current exported issue snapshot content
122
- * @param {object} [deps] - Dependency injection
123
- * @param {Function} [deps.closeGitHubIssue] - Override for testing
124
- * @returns {{closed: Array, skipped: Array, errors: Array}}
125
- */
126
- export function handleBeadsClosed(oldContent, newContent, deps = {}) {
127
- const closeFn = deps.closeGitHubIssue ?? closeGitHubIssue;
128
-
129
- const oldLines = oldContent.split('\n');
130
- const newLines = newContent.split('\n');
131
-
132
- const transitions = detectClosedIssues(oldLines, newLines);
133
- const latestIssues = new Map(
134
- parseJsonlLines(newLines).map((issue) => [issue.id, issue]),
135
- );
136
-
137
- const closed = [];
138
- const skipped = [];
139
- const errors = [];
140
-
141
- for (const issue of transitions) {
142
- const parsed = extractPreferredGitHubLink(latestIssues.get(issue.id) ?? issue);
143
- if (!parsed) {
144
- skipped.push({ beadsId: issue.id, reason: 'no GitHub URL' });
145
- continue;
146
- }
147
-
148
- try {
149
- closeFn(parsed.owner, parsed.repo, parsed.issueNumber);
150
- closed.push({
151
- beadsId: issue.id,
152
- owner: parsed.owner,
153
- repo: parsed.repo,
154
- issueNumber: parsed.issueNumber,
155
- });
156
- } catch (err) {
157
- errors.push({ beadsId: issue.id, error: err.message });
158
- }
159
- }
160
-
161
- return { closed, skipped, errors };
162
- }
@@ -1,161 +0,0 @@
1
- /**
2
- * @module run-bd
3
- * @description Wrapper around the `bd` (Beads) CLI for GitHub-Beads sync.
4
- *
5
- * Exports pure arg-building and output-parsing functions (unit-testable),
6
- * plus thin exec wrappers that shell out to the real `bd` binary.
7
- */
8
-
9
- import { execFileSync } from 'node:child_process';
10
-
11
- const EXEC_OPTS = { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] };
12
-
13
- // ---------------------------------------------------------------------------
14
- // Arg builders (pure)
15
- // ---------------------------------------------------------------------------
16
-
17
- /**
18
- * Build args array for `bd create`.
19
- * Omits flags whose values are null or undefined.
20
- * @param {object} opts
21
- * @param {string} opts.title
22
- * @param {string} [opts.type]
23
- * @param {number|string} [opts.priority]
24
- * @param {string} [opts.assignee]
25
- * @param {string} [opts.description]
26
- * @param {string} [opts.externalRef]
27
- * @returns {string[]}
28
- */
29
- export function buildCreateArgs({ title, type, priority, assignee, description, externalRef } = {}) {
30
- const args = ['create', '--title', title];
31
-
32
- if (type != null) args.push('--type', type);
33
- if (priority != null) args.push('--priority', String(priority));
34
- if (assignee != null) args.push('--assignee', assignee);
35
- if (description != null) args.push('--description', description);
36
- if (externalRef != null) args.push('--external-ref', externalRef);
37
-
38
- return args;
39
- }
40
-
41
- /**
42
- * Build args array for `bd close`.
43
- * @param {string} beadsId
44
- * @param {string} [reason]
45
- * @returns {string[]}
46
- */
47
- export function buildCloseArgs(beadsId, reason) {
48
- const args = ['close', beadsId];
49
- if (reason != null) args.push('--reason', reason);
50
- return args;
51
- }
52
-
53
- /**
54
- * Build args array for `bd show`.
55
- * @param {string} beadsId
56
- * @returns {string[]}
57
- */
58
- export function buildShowArgs(beadsId) {
59
- return ['show', beadsId, '--json'];
60
- }
61
-
62
- /**
63
- * Build args array for `bd search`.
64
- * @param {string} query
65
- * @returns {string[]}
66
- */
67
- export function buildSearchArgs(query) {
68
- return ['search', query];
69
- }
70
-
71
- // ---------------------------------------------------------------------------
72
- // Output parsers (pure)
73
- // ---------------------------------------------------------------------------
74
-
75
- /**
76
- * Extract beads ID from `bd create` stdout.
77
- * Expects pattern: "Created issue: forge-xxxx"
78
- * @param {string} stdout
79
- * @returns {string|null}
80
- */
81
- export function parseCreateOutput(stdout) {
82
- // Match forge-xxx with optional dotted sub-IDs (e.g. forge-m1n8.6, forge-dq8j.1).
83
- // \w in JS doesn't include '.', so the dotted sub-ID group is explicit.
84
- const match = stdout.match(/Created issue:\s+(forge-[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*)/);
85
- if (match) return match[1];
86
- // Fallback: loose match for any forge-prefixed ID anywhere in output
87
- const fallback = stdout.match(/(forge-[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*)/);
88
- return fallback ? fallback[1] : null;
89
- }
90
-
91
- /**
92
- * Extract status from `bd show --json` stdout.
93
- * Parses JSON output for reliable status extraction.
94
- * @param {string} stdout - JSON output from `bd show --json`
95
- * @returns {string|null} Lowercase status or null
96
- */
97
- export function parseShowOutput(stdout) {
98
- try {
99
- const data = JSON.parse(stdout);
100
- const issue = Array.isArray(data) ? data[0] : data;
101
- return issue?.status ? issue.status.toLowerCase() : null;
102
- } catch (_err) {
103
- return null;
104
- }
105
- }
106
-
107
- // ---------------------------------------------------------------------------
108
- // Exec wrappers (side-effectful — not unit-tested)
109
- // ---------------------------------------------------------------------------
110
-
111
- /**
112
- * Run `bd create` and return the parsed beads ID.
113
- * @param {object} opts - Same as buildCreateArgs
114
- * @returns {string|null} The created beads ID, or null if parsing failed
115
- */
116
- export function bdCreate(opts) {
117
- try {
118
- const stdout = execFileSync('bd', buildCreateArgs(opts), EXEC_OPTS);
119
- const id = parseCreateOutput(stdout);
120
- if (!id) {
121
- console.error('bd create succeeded but ID not parsed. stdout:', stdout);
122
- }
123
- return id;
124
- } catch (err) {
125
- console.error('bd create failed:', err.stderr?.toString() || err.message);
126
- return null;
127
- }
128
- }
129
-
130
- /**
131
- * Run `bd close`.
132
- * @param {string} beadsId
133
- * @param {string} [reason]
134
- */
135
- export function bdClose(beadsId, reason) {
136
- execFileSync('bd', buildCloseArgs(beadsId, reason), EXEC_OPTS);
137
- }
138
-
139
- /**
140
- * Run `bd show` and return the parsed status.
141
- * Returns null if bd exits non-zero (e.g., deleted issue, corrupted .beads/).
142
- * @param {string} beadsId
143
- * @returns {string|null} Lowercase status or null
144
- */
145
- export function bdShow(beadsId) {
146
- try {
147
- const stdout = execFileSync('bd', buildShowArgs(beadsId), EXEC_OPTS);
148
- return parseShowOutput(stdout);
149
- } catch (_err) {
150
- return null;
151
- }
152
- }
153
-
154
- /**
155
- * Run `bd search` and return raw stdout.
156
- * @param {string} query
157
- * @returns {string}
158
- */
159
- export function bdSearch(query) {
160
- return execFileSync('bd', buildSearchArgs(query), EXEC_OPTS);
161
- }
@@ -1,121 +0,0 @@
1
- /**
2
- * Input sanitizer for GitHub issue data before passing to bd CLI.
3
- * Strips shell metacharacters, GitHub Actions interpolation, and control chars.
4
- * @module sanitize
5
- */
6
-
7
- /** Shell metacharacters to strip from titles and bodies */
8
- const SHELL_META_RE = /[;|&$`()<>\r\n]/g;
9
-
10
- /** GitHub Actions interpolation pattern: ${{ ... }} */
11
- const INTERPOLATION_RE = /\$\{\{[^}]*\}\}/g;
12
-
13
- /** Control characters (C0 range, excluding normal whitespace) */
14
- // eslint-disable-next-line no-control-regex
15
- const CONTROL_CHARS_RE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
16
-
17
- /** Label: only allow alphanumeric, dot, underscore, hyphen */
18
- const LABEL_INVALID_RE = /[^a-zA-Z0-9._-]/g;
19
-
20
- /**
21
- * Sanitize a general text field (shared logic for title/body).
22
- * @param {string} input - Raw input string
23
- * @param {number} maxLen - Maximum allowed length
24
- * @param {string} fieldName - Name for warning messages
25
- * @returns {{ sanitized: string, warnings: string[] }}
26
- */
27
- function sanitizeText(input, maxLen, fieldName) {
28
- const warnings = [];
29
- let text = String(input ?? '');
30
-
31
- // Strip GitHub Actions interpolation patterns
32
- // Use local regex to avoid stateful /g lastIndex bug with .test()
33
- const interpolationReLocal = /\$\{\{[^}]*\}\}/g;
34
- if (interpolationReLocal.test(text)) {
35
- warnings.push(`${fieldName}: stripped GitHub Actions interpolation pattern(s)`);
36
- }
37
- text = text.replace(INTERPOLATION_RE, '');
38
-
39
- // Strip shell metacharacters
40
- const metaMatches = text.match(SHELL_META_RE);
41
- if (metaMatches) {
42
- const unique = [...new Set(metaMatches)];
43
- warnings.push(`${fieldName}: stripped shell metacharacters: ${unique.join(' ')}`);
44
- }
45
- text = text.replace(SHELL_META_RE, '');
46
-
47
- // Strip control characters
48
- // eslint-disable-next-line no-control-regex
49
- const controlCharsReLocal = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g;
50
- if (controlCharsReLocal.test(text)) {
51
- warnings.push(`${fieldName}: stripped control characters`);
52
- }
53
- text = text.replace(CONTROL_CHARS_RE, '');
54
-
55
- // Trim whitespace
56
- text = text.trim();
57
-
58
- // Truncate
59
- if (text.length > maxLen) {
60
- warnings.push(`${fieldName}: truncated from ${text.length} to ${maxLen} chars`);
61
- text = text.slice(0, maxLen);
62
- }
63
-
64
- // Empty check
65
- if (text.length === 0) {
66
- warnings.push(`${fieldName}: empty after sanitization`);
67
- text = '(empty)';
68
- }
69
-
70
- return { sanitized: text, warnings };
71
- }
72
-
73
- /**
74
- * Sanitize an issue title for bd CLI args.
75
- * @param {string} title - Raw GitHub issue title
76
- * @returns {{ sanitized: string, warnings: string[] }}
77
- */
78
- export function sanitizeTitle(title) {
79
- return sanitizeText(title, 256, 'title');
80
- }
81
-
82
- /**
83
- * Sanitize an issue body for the description field.
84
- * @param {string} body - Raw GitHub issue body
85
- * @returns {{ sanitized: string, warnings: string[] }}
86
- */
87
- export function sanitizeBody(body) {
88
- return sanitizeText(body, 1024, 'body');
89
- }
90
-
91
- /**
92
- * Sanitize a single label string.
93
- * Only allows [a-zA-Z0-9._-], max 64 chars.
94
- * @param {string} label - Raw GitHub label name
95
- * @returns {{ sanitized: string, warnings: string[] }}
96
- */
97
- export function sanitizeLabel(label) {
98
- const warnings = [];
99
- let text = String(label ?? '').trim();
100
-
101
- // Strip invalid characters
102
- const invalidMatches = text.match(LABEL_INVALID_RE);
103
- if (invalidMatches) {
104
- warnings.push(`label: stripped invalid characters: ${[...new Set(invalidMatches)].join(' ')}`);
105
- text = text.replace(LABEL_INVALID_RE, '');
106
- }
107
-
108
- // Truncate
109
- if (text.length > 64) {
110
- warnings.push(`label: truncated from ${text.length} to 64 chars`);
111
- text = text.slice(0, 64);
112
- }
113
-
114
- // Empty check
115
- if (text.length === 0) {
116
- warnings.push('label: empty after sanitization');
117
- text = '(empty)';
118
- }
119
-
120
- return { sanitized: text, warnings };
121
- }
@@ -1,26 +0,0 @@
1
- {
2
- "labelToType": {
3
- "bug": "bug",
4
- "enhancement": "feature",
5
- "documentation": "task",
6
- "question": "task"
7
- },
8
- "labelToPriority": {
9
- "P0": 0,
10
- "critical": 0,
11
- "P1": 1,
12
- "high": 1,
13
- "P2": 2,
14
- "medium": 2,
15
- "P3": 3,
16
- "low": 3,
17
- "P4": 4,
18
- "backlog": 4
19
- },
20
- "defaultType": "task",
21
- "defaultPriority": 2,
22
- "mapAssignee": true,
23
- "publicRepoGate": "none",
24
- "gateLabelName": "beads-track",
25
- "gateAssociations": ["MEMBER", "COLLABORATOR", "OWNER"]
26
- }