eser 4.1.50 → 4.1.53

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 (142) hide show
  1. package/chunks/approve-VBXGXWZI.js +2 -0
  2. package/chunks/block-Z4BELXXO.js +2 -0
  3. package/chunks/{build-S4DSRSSR.js → build-4WTOXDXD.js} +1 -1
  4. package/chunks/cancel-HHW2G675.js +2 -0
  5. package/chunks/{changelog-gen-TE6FXELA.js → changelog-gen-JTU6WIYA.js} +1 -1
  6. package/chunks/{chunk-66VSO643.js → chunk-352YGR5O.js} +1 -1
  7. package/chunks/{chunk-BJ45FF6F.js → chunk-4BOZ4A55.js} +1 -1
  8. package/chunks/chunk-5GGWX7CO.js +4 -0
  9. package/chunks/{chunk-NWWXAZFA.js → chunk-5QUEAV4O.js} +26 -26
  10. package/chunks/chunk-5YBG2HOI.js +3 -0
  11. package/chunks/chunk-6F4PFXYY.js +2 -0
  12. package/chunks/{chunk-N6PXARPJ.js → chunk-6HJUPT5Y.js} +1 -1
  13. package/chunks/{chunk-AUDMKDAA.js → chunk-6M64JLJW.js} +1 -1
  14. package/chunks/{chunk-Z2RL2SFY.js → chunk-6WFCBJPF.js} +1 -1
  15. package/chunks/{chunk-ZQ7KN4HT.js → chunk-7L4DDCRL.js} +1 -1
  16. package/chunks/{chunk-TTLUVJIR.js → chunk-7V3IDYYI.js} +1 -1
  17. package/chunks/{chunk-YCI2VITZ.js → chunk-BKWQQUSY.js} +1 -1
  18. package/chunks/{chunk-OSNPAAYT.js → chunk-BZSILAX3.js} +1 -1
  19. package/chunks/{chunk-BNZPRQUS.js → chunk-DGI7M6TL.js} +1 -1
  20. package/chunks/{chunk-TBRDRQQK.js → chunk-DYBJ6UPO.js} +1 -1
  21. package/chunks/{chunk-QRNSYEPI.js → chunk-EJBYYUXZ.js} +1 -1
  22. package/chunks/{chunk-3SBAWBWS.js → chunk-F4QK3J3J.js} +1 -1
  23. package/chunks/{chunk-HV3EYAGF.js → chunk-GQ4WRANA.js} +1 -1
  24. package/chunks/{chunk-4QMRLILJ.js → chunk-H6U2EE7V.js} +1 -1
  25. package/chunks/{chunk-4NNSMDFH.js → chunk-IUORSUN6.js} +1 -1
  26. package/chunks/{chunk-3CE7GA2P.js → chunk-JBUJTUEU.js} +1 -1
  27. package/chunks/chunk-KFVUFHJB.js +6 -0
  28. package/chunks/{chunk-IY3YRKJJ.js → chunk-L6J3BWVP.js} +1 -1
  29. package/chunks/{chunk-PG7KG7NX.js → chunk-LRAHXO3G.js} +1 -1
  30. package/chunks/chunk-NE2J6ISX.js +6 -0
  31. package/chunks/chunk-NQS27P25.js +6 -0
  32. package/chunks/{chunk-2PWSTO7A.js → chunk-NYHMH3N5.js} +1 -1
  33. package/chunks/chunk-ODBJ5KMQ.js +3 -0
  34. package/chunks/chunk-OXP2FOO5.js +2 -0
  35. package/chunks/{chunk-JTSRGXS4.js → chunk-PZUDTTK4.js} +1 -1
  36. package/chunks/{chunk-WJI2X6IA.js → chunk-RLA2Z7XV.js} +1 -1
  37. package/chunks/{chunk-PY6ZNQ4B.js → chunk-RLTTHJ3E.js} +1 -1
  38. package/chunks/{chunk-UYGKTA3C.js → chunk-RSHUTH4K.js} +1 -1
  39. package/chunks/chunk-RUTM4VP7.js +11 -0
  40. package/chunks/{chunk-4XXI5LYN.js → chunk-SKW7N57D.js} +1 -1
  41. package/chunks/{chunk-CE6UVD6F.js → chunk-TJ4VL7T5.js} +1 -1
  42. package/chunks/{chunk-KFSZ6MDH.js → chunk-UTENCUNI.js} +1 -1
  43. package/chunks/{chunk-BESTYZQY.js → chunk-V3KWM26F.js} +1 -1
  44. package/chunks/{chunk-72R6CKNY.js → chunk-VGCEFEFY.js} +1 -1
  45. package/chunks/{chunk-MGNBNMJZ.js → chunk-VJSHVZ7R.js} +1 -1
  46. package/chunks/chunk-YWSOQJ7G.js +5 -0
  47. package/chunks/{chunk-DHNS2KLJ.js → chunk-ZZMU6YO4.js} +1 -1
  48. package/chunks/concern-YFXJJ7DL.js +2 -0
  49. package/chunks/delegate-FVHPWQS7.js +2 -0
  50. package/chunks/{dev-NJVFMPTE.js → dev-UV7J3QTQ.js} +1 -1
  51. package/chunks/diagrams-IC2ADMKS.js +2 -0
  52. package/chunks/diagrams-MRJB73CF.js +2 -0
  53. package/chunks/done-DMKJ27IQ.js +2 -0
  54. package/chunks/followup-XKVSZT2H.js +2 -0
  55. package/chunks/{gh-YLYXDL2X.js → gh-3GMLD6TO.js} +2 -2
  56. package/chunks/{gh-contributors-YFATSPSW.js → gh-contributors-PNU47Y7Q.js} +1 -1
  57. package/chunks/init-ONTNPCSY.js +2 -0
  58. package/chunks/invoke-hook-ZM6UQND6.js +14 -0
  59. package/chunks/learn-SRDLP7B5.js +8 -0
  60. package/chunks/{main-JZTE4B4L.js → main-PQW6MNZM.js} +1 -1
  61. package/chunks/manager-BMNUSWJO.js +7 -0
  62. package/chunks/{mod-MC2WNSB2.js → mod-6LLSLOX6.js} +1 -1
  63. package/chunks/{mod-TUZZQKGZ.js → mod-MKKBIIC4.js} +1 -1
  64. package/chunks/next-FD3EHJW3.js +8 -0
  65. package/chunks/pack-ZQMMSIIP.js +6 -0
  66. package/chunks/{purge-ZQ23VDGR.js → purge-LXL3F3EJ.js} +1 -1
  67. package/chunks/{release-XACZAR6J.js → release-5PXID6GL.js} +2 -2
  68. package/chunks/{release-notes-W6MNV6OT.js → release-notes-3OMBQLOK.js} +1 -1
  69. package/chunks/{release-tag-HSZX6WYU.js → release-tag-2B2CWVMZ.js} +1 -1
  70. package/chunks/reopen-3NA6JI4N.js +2 -0
  71. package/chunks/reset-XITFRWII.js +2 -0
  72. package/chunks/review-UVYK4M4T.js +2 -0
  73. package/chunks/rule-BAO7IP5S.js +7 -0
  74. package/chunks/run-EBKNNOG7.js +4 -0
  75. package/chunks/{serve-3PZ7RBQY.js → serve-T5HR56BZ.js} +1 -1
  76. package/chunks/session-SZYH2UOE.js +2 -0
  77. package/chunks/spec-CPRKQGOX.js +2 -0
  78. package/chunks/status-SRCNQJ4V.js +2 -0
  79. package/chunks/sync-WE6A7KC7.js +2 -0
  80. package/chunks/{system-CP5L6XUP.js → system-6TO2XBOH.js} +1 -1
  81. package/chunks/{system-N5A3SM5G.js → system-RWYI6DJF.js} +1 -1
  82. package/chunks/{validate-bom-EH5Z5TVU.js → validate-bom-YFYXM4ND.js} +1 -1
  83. package/chunks/{validate-case-conflict-XN4KQDSK.js → validate-case-conflict-E7LKQYVM.js} +1 -1
  84. package/chunks/{validate-circular-deps-YZ4DIXIM.js → validate-circular-deps-L4MDRIG3.js} +1 -1
  85. package/chunks/{validate-commit-msg-MXTBUPTC.js → validate-commit-msg-2JQ2W6Y6.js} +1 -1
  86. package/chunks/{validate-docs-BE32R2UM.js → validate-docs-EXDICKDK.js} +1 -1
  87. package/chunks/{validate-filenames-DMZ46CRH.js → validate-eof-UYQI6DYK.js} +1 -1
  88. package/chunks/{validate-export-names-D3QNF6VB.js → validate-export-names-QBYWTK5Q.js} +1 -1
  89. package/chunks/{validate-eof-JPKT2D3D.js → validate-filenames-Z6VSIR2C.js} +1 -1
  90. package/chunks/{validate-json-KG3U4NLK.js → validate-json-2JS2Y4YU.js} +1 -1
  91. package/chunks/validate-large-files-JKQBKNS4.js +2 -0
  92. package/chunks/validate-licenses-7MVLVDZA.js +2 -0
  93. package/chunks/validate-line-endings-KMXN5IUT.js +2 -0
  94. package/chunks/validate-merge-conflict-N7M4OVXI.js +2 -0
  95. package/chunks/{validate-mod-exports-J6KLADGR.js → validate-mod-exports-C7WDH4FK.js} +1 -1
  96. package/chunks/{validate-package-configs-BFCQMBEI.js → validate-package-configs-AYVT55GJ.js} +1 -1
  97. package/chunks/validate-secrets-3PW5GJZD.js +2 -0
  98. package/chunks/validate-shebangs-JACZB7C3.js +2 -0
  99. package/chunks/validate-submodules-SCY4LARV.js +2 -0
  100. package/chunks/validate-symlinks-PDLYFPNE.js +2 -0
  101. package/chunks/{validate-toml-OMUYIHX2.js → validate-toml-NGF5Q27B.js} +1 -1
  102. package/chunks/validate-trailing-whitespace-PDAFNVPQ.js +2 -0
  103. package/chunks/{validate-yaml-VTE42YLF.js → validate-yaml-ILJZJGDG.js} +1 -1
  104. package/chunks/{versions-GXSXTSSG.js → versions-VGXMC5GM.js} +1 -1
  105. package/chunks/{watch-EVUCQISN.js → watch-WBZB2C5P.js} +7 -7
  106. package/chunks/web-GAF33V4M.js +2 -0
  107. package/chunks/wontfix-JBPCNL6S.js +2 -0
  108. package/eser.js +1 -1
  109. package/package.json +1 -1
  110. package/chunks/approve-PXC7FMDI.js +0 -2
  111. package/chunks/block-CSVO3R47.js +0 -2
  112. package/chunks/cancel-AJOYWYV5.js +0 -2
  113. package/chunks/chunk-4TTJVJEI.js +0 -2
  114. package/chunks/chunk-IZUADMIU.js +0 -3
  115. package/chunks/chunk-KNIM3QST.js +0 -10
  116. package/chunks/chunk-QL5FA3P3.js +0 -2
  117. package/chunks/chunk-UTWYRNI6.js +0 -17
  118. package/chunks/concern-DXCLVP5Y.js +0 -2
  119. package/chunks/done-HGZT3ZOT.js +0 -2
  120. package/chunks/init-X6KNS3NC.js +0 -2
  121. package/chunks/invoke-hook-KLJOYZF5.js +0 -12
  122. package/chunks/manager-FMP6PKIR.js +0 -7
  123. package/chunks/next-6K3PS64Z.js +0 -9
  124. package/chunks/pack-YQVWUWCL.js +0 -6
  125. package/chunks/reopen-Z3MPVAGR.js +0 -2
  126. package/chunks/reset-NWO3MNAG.js +0 -2
  127. package/chunks/rule-CH5GMFKE.js +0 -7
  128. package/chunks/run-5YOXFMP2.js +0 -4
  129. package/chunks/session-22XFZLH2.js +0 -2
  130. package/chunks/spec-PWS2UYVL.js +0 -2
  131. package/chunks/status-G5D6BYFF.js +0 -2
  132. package/chunks/sync-URY32B7Y.js +0 -2
  133. package/chunks/validate-large-files-C2ILVCDB.js +0 -2
  134. package/chunks/validate-licenses-P24RTTYG.js +0 -2
  135. package/chunks/validate-line-endings-F65GG2PC.js +0 -2
  136. package/chunks/validate-merge-conflict-PVT6WR2W.js +0 -2
  137. package/chunks/validate-secrets-RBD2KJ3R.js +0 -2
  138. package/chunks/validate-shebangs-L5YR7AGC.js +0 -2
  139. package/chunks/validate-submodules-HD7CSBOG.js +0 -2
  140. package/chunks/validate-symlinks-RPSZMV5Y.js +0 -2
  141. package/chunks/validate-trailing-whitespace-BIG3YYFY.js +0 -2
  142. package/chunks/wontfix-4R2ESAR5.js +0 -2
@@ -1,11 +1,11 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{c as y}from"./chunk-KNIM3QST.js";import{a as b}from"./chunk-UEMWZOIU.js";import{i as n}from"./chunk-6DBKPC2O.js";var S="<!-- noskills:start -->",g="<!-- noskills:end -->",Y=(e,t,s="npx eser noskills")=>{let o=[S,"## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/rules/`, `.eser/specs/`, or concern files directly.","noskills gives you exactly what you need via JSON output.","","### Protocol","",` ${s} spec <name> next # get current instruction`,` ${s} spec <name> next --answer="your response" # submit result and advance`,"","Every noskills command that operates on a spec MUST include `spec <name>`.","Never omit it. Use `"+s+" spec list` to see available specs.","","### Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" spec <name> next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","### When to call noskills next","",`You MUST call \`${s} next\` in these situations:`,"","1. At the **START** of every conversation (first thing you do)","2. **BEFORE** creating or modifying any file (to verify you have an active task)","3. **AFTER** completing a logical unit of work (to report progress)","4. When you encounter a **DECISION** that affects architecture or scope","5. When you are **UNSURE** what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER make architectural decisions independently \u2014 noskills routes them to the user."];if((t?.allowGit??!1)||o.push("","### Git is read-only","","You MUST NOT run git write commands: commit, add, push, checkout, stash,","reset, merge, rebase, cherry-pick. The user controls git. You control files.","You MAY read from git: log, diff, status, show, blame."),o.push("","### Interactive choices","","When noskills output contains `interactiveOptions`, you MUST present them","using the AskUserQuestion tool. NEVER present options in prose.","","This is not optional. If you ask a question without AskUserQuestion when","interactiveOptions are present, you are violating protocol.","","Pass interactiveOptions as the `options` array in AskUserQuestion.","Use the `commandMap` to resolve the user's selection to a CLI command.","","### Convention discovery","","When you notice a recurring pattern, receive a correction, or discover","a project quirk during any phase:","",'1. Ask: "Should this be a permanent rule?"',`2. If yes: \`${s} rule add "description" --phases=EXECUTING\``,"3. If just this spec: note it and move on","","Corrections are learnings. Capture them as rules so they compound.","Every session should leave the project's rule set slightly better.","Never write to `.eser/rules/` directly.","","### Creating specs","","When the user describes what they want to build, create a spec immediately:",`\`${s} spec new "user's description here"\``,"","The name is auto-generated from the description. Encourage the user to share","as much context as possible \u2014 detailed requirements produce better discovery.","Do NOT ask for a 'short slug' \u2014 just take what the user gives you and create","the spec. A one-liner, meeting notes, task list, or full requirements doc all work.","","### Pre-discovery research","","When starting a new spec, noskills may flag technologies that need","research. Before asking discovery questions, search for current versions","and API status of flagged technologies. Report findings to the user.","Your training data may be outdated \u2014 always verify.","","### Plan-based discovery","","When a spec is created with --from-plan, the first discovery output includes","the plan content. Read it, extract answers for all 6 questions, present them","for user confirmation. The plan is a starting point, not the final answer.","","### Discovery modes","","noskills offers 5 discovery modes selected at the start of each spec:","- full: Standard 6 questions (default)","- validate: Challenge the user's existing plan","- technical-depth: Focus on architecture and integration","- ship-fast: Minimum viable scope","- explore: Think bigger, find opportunities","","### Premise challenge","","After mode selection, challenge 2-4 premises from the spec description.","Present each premise for the user to agree/disagree. Submit as JSON.","","### Alternatives generation","","Before spec draft, propose 2-3 implementation approaches.","User picks one or skips. The selected approach shapes the spec.","","### AI slop prevention","","When implementing UI, avoid these generic AI-generated patterns:","- 3-column grids with icon circles (the most recognizable AI layout)","- Purple gradients, decorative blobs, wavy dividers","- Everything centered, uniform border-radius everywhere",'- Generic hero copy ("Welcome to...", "Unlock the power of...")',"- Cookie-cutter section rhythm","","Every UI element must feel intentional, not generated. If it looks like","every other AI-built site, iterate until it doesn't.","","### Spec splitting","","When noskills suggests splitting a spec, present the options and wait for the","user's decision. Never split a spec without explicit user approval.","","### Decision principle: Explicit > Clever","","You NEVER skip steps, bypass questions, or make assumptions on behalf of the user.","- Discovery questions \u2192 ask the user, don't answer yourself","- Classification \u2192 ask the user, don't infer","- Spec approval \u2192 ask the user, don't auto-approve","- Task refinement \u2192 ask the user, don't self-assign","- Rule promotion \u2192 ask the user, don't decide",`If you think something can be skipped, ASK "would you like to skip this?" \u2014 don't skip it.`,"","### Command execution","","When told to run a noskills command, execute it IMMEDIATELY. Do not explore,","research, read source code, or plan first. The command output contains all the","context you need. Exploring noskills internals wastes tokens and delays the user.","","### JSON output","","noskills returns JSON with a `phase` field and phase-specific instructions.","The `meta` block contains resume context - use it to orient yourself,","especially after compaction or at the start of a new session.","Follow the `instruction` field. Use `transition` commands to advance state.","","### Phase progress","","Every noskills output includes a roadmap showing the current phase.","Display it to the user. At critical transitions (approve, start execution),","noskills shows a gate with an explicit action. Present these prominently.","","### Code quality rules","","These rules apply during spec execution:","- After every file edit, run type-check and lint before reporting success","- Files over 500 LOC: read in chunks, never assume single read = full file","- If search returns few results, re-run narrower \u2014 assume truncation","- Re-read every file before and after editing","- Before refactoring large files, clean dead code first (separate commit)","","### Execution commitment","","Once a spec enters EXECUTING, complete it. Do not suggest mid-execution",'checkpoints, pauses, or "should we stop here?" questions.',"","noskills encourages small, meaningful specs defined during discovery.","If a spec is well-scoped, there is no reason to stop halfway \u2014 half-done","delivers nothing. If it feels too large mid-execution, that means","discovery should have split it. Finish this one, improve the next."),e.length>0){o.push("","### Active Rules","");for(let i of e)o.push(`- ${i}`)}return o.push(g),o.join(`
3
- `)},x=async(e,t,s,o="npx eser noskills")=>{let i=`${e}/CLAUDE.md`,r=Y(t,s,o),a;try{a=await n.fs.readTextFile(i);let c=a.indexOf(S),l=a.indexOf(g);c!==-1&&l!==-1?a=a.slice(0,c)+r+a.slice(l+g.length):a=a.trimEnd()+`
2
+ import{c as y}from"./chunk-RUTM4VP7.js";import{a as b}from"./chunk-UEMWZOIU.js";import{i as n}from"./chunk-6DBKPC2O.js";var x="<!-- noskills:start -->",g="<!-- noskills:end -->",Y=(e,t,s="npx eser noskills")=>{let o=[x,"## noskills orchestrator","","State-driven orchestration. Do NOT read `.eser/` files directly \u2014 noskills provides everything via JSON.","","### Protocol","",` ${s} spec <name> next # get instruction`,` ${s} spec <name> next --answer="response" # submit and advance`,` ${s} spec new "description" # create spec (name auto-generated)`,"","Every spec command MUST include `spec <name>`. Use `"+s+" spec list` for available specs.","","### Core rules","","- Call noskills ONCE per interaction. One question, one answer, one submit.","- Call `next` at: conversation start, before file edits, after completing work, at decisions.","- Never batch-submit. Never answer discovery questions yourself.","- Never skip steps or infer decisions. Ask first. Explicit > Clever.","- NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","- NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Each step has one next step. Just run it.","- Execute noskills commands IMMEDIATELY \u2014 the output has all context needed.","- Display `roadmap` before content. Display `gate` prominently.","","### Interactive choices","","- Use AskUserQuestion for `interactiveOptions`. Use `commandMap` to resolve selections.","- On recurring patterns or corrections: ask 'Permanent rule?' \u2192 `"+s+' rule add "description"`.'];if((t?.allowGit??!1)||o.push("","### Git","","Read-only: log, diff, status, show, blame. No write commands (commit, push, checkout, etc.)."),o.push("","### Discovery","","Modes: full (default), validate, technical-depth, ship-fast, explore.","Pre-scan codebase before questions. Challenge premises. Propose alternatives.","With --from-plan: extract answers, present for user confirmation.","","### Execution","","- Re-read files before and after editing. Files >500 LOC: read in chunks.","- Run type-check + lint after every edit. Never mark AC passed if type-check fails.","- If search returns few results, re-run narrower \u2014 assume truncation.","- Clean dead code before structural refactors on files >300 LOC.","- Complete the spec \u2014 no mid-execution pauses or checkpoints.","- `meta` block has resume context for session start or after compaction."),e.length>0){o.push("","### Active Rules","");for(let i of e)o.push(`- ${i}`)}return o.push(g),o.join(`
3
+ `)},S=async(e,t,s,o="npx eser noskills")=>{let i=`${e}/CLAUDE.md`,r=Y(t,s,o),a;try{a=await n.fs.readTextFile(i);let l=a.indexOf(x),c=a.indexOf(g);l!==-1&&c!==-1?a=a.slice(0,l)+r+a.slice(c+g.length):a=a.trimEnd()+`
4
4
 
5
5
  `+r+`
6
6
  `}catch{a=r+`
7
7
  `}await n.fs.writeTextFile(i,a)};var J=e=>({hooks:{PreToolUse:[{matcher:"Write|Edit|MultiEdit|Bash",hooks:[{type:"command",command:`${e} invoke-hook pre-tool-use`,timeout:5}]}],PostToolUse:[{matcher:"Write|Edit|MultiEdit",hooks:[{type:"command",command:`${e} invoke-hook post-file-write`,timeout:3}]},{matcher:"Bash",hooks:[{type:"command",command:`${e} invoke-hook post-bash`,timeout:3}]}],Stop:[{hooks:[{type:"command",command:`${e} invoke-hook stop`,timeout:10}]}],SessionStart:[{hooks:[{type:"command",command:`${e} invoke-hook session-start`,timeout:5}]}]}}),R=async(e,t="npx eser@latest noskills")=>{let s=`${e}/.claude/settings.json`,o={};try{let a=await n.fs.readTextFile(s);o=JSON.parse(a)}catch{}let i=J(t),r={...o,...i};await n.fs.mkdir(`${e}/.claude`,{recursive:!0}),await n.fs.writeTextFile(s,JSON.stringify(r,null,2)+`
8
- `)};var V=async(e,t)=>{let s=`${e}/.claude/agents`;await n.fs.mkdir(s,{recursive:!0});let o=`---
8
+ `)};var K=async(e,t)=>{let s=`${e}/.claude/agents`;await n.fs.mkdir(s,{recursive:!0});let o=`---
9
9
  name: noskills-executor
10
10
  description: "Executes a single noskills task."
11
11
  tools: Read, Edit, MultiEdit, Write, Bash, Grep, Glob, LS
@@ -31,7 +31,7 @@ When finished, provide a structured JSON summary:
31
31
 
32
32
  Do NOT return raw test output \u2014 summarize it in the verification field.
33
33
  The orchestrator will submit this to \`${t} next --answer\` on your behalf.
34
- `;await n.fs.writeTextFile(`${s}/noskills-executor.md`,o)},K=async(e,t)=>{let s=`${e}/.claude/agents`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-verifier.md`,`---
34
+ `;await n.fs.writeTextFile(`${s}/noskills-executor.md`,o)},q=async(e,t)=>{let s=`${e}/.claude/agents`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-verifier.md`,`---
35
35
  name: noskills-verifier
36
36
  description: "Independently verifies completed task work. Read-only. Never sees the executor's context."
37
37
  tools: Read, Bash, Grep, Glob, LS
@@ -60,52 +60,52 @@ When finished, provide a structured JSON summary:
60
60
  \\\`\\\`\\\`
61
61
 
62
62
  The orchestrator will use this report for the noskills status report.
63
- `)},A={id:"claude-code",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!1,interaction:{hasAskUserTool:!0,optionPresentation:"tool",hasSubAgentDelegation:!0,subAgentMethod:"task"}},async syncRules(e,t){await x(e.root,e.rules,t,e.commandPrefix)},async syncHooks(e,t){await R(e.root,e.commandPrefix)},async syncAgents(e,t){await V(e.root,e.commandPrefix),await K(e.root,e.commandPrefix)}};var T=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.writeTextFile(`${e}/.cursorrules`,o.join(`
64
- `))};var C={id:"cursor",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await T(e.root,e.rules,e.commandPrefix)}};var X=".kiro/steering",O=".kiro/settings",Z=".kiro/agents",ee=".kiro/specs",te="hooks.json",se="mcp.json",oe="noskills-protocol.md",ne="noskills-coaching.md",k="noskills-rules.md",N="conventions.md",ie="noskills-executor.json",re="noskills-verifier.json",ae=(e,t)=>{let s=["---","inclusion: always","---","","# noskills Protocol","","# Generated by noskills \u2014 do not edit manually","","## What is noskills","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/rules/`, `.eser/specs/`, or concern files directly.","noskills gives you exactly what you need via JSON output.","","## Protocol","",` ${e} spec <name> next # get current instruction`,` ${e} spec <name> next --answer="your response" # submit result and advance`,"","Every noskills command that operates on a spec MUST include `spec <name>`.",`Never omit it. Use \`${e} spec list\` to see available specs.`,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+e+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","",`You MUST call \`${e} next\` in these situations:`,"","1. At the **START** of every conversation (first thing you do)","2. **BEFORE** creating or modifying any file (to verify you have an active task)","3. **AFTER** completing a logical unit of work (to report progress)","4. When you encounter a **DECISION** that affects architecture or scope","5. When you are **UNSURE** what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER make architectural decisions independently \u2014 noskills routes them to the user."];return(t?.allowGit??!1)||s.push("","## Git is read-only","","You MUST NOT run git write commands: commit, add, push, checkout, stash,","reset, merge, rebase, cherry-pick. The user controls git. You control files.","You MAY read from git: log, diff, status, show, blame."),s.push("","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","Use the `commandMap` to resolve the user's selection to a CLI command.","","## Decision principle: Explicit > Clever","","You NEVER skip steps, bypass questions, or make assumptions on behalf of the user.","- Discovery questions \u2192 ask the user, don't answer yourself","- Classification \u2192 ask the user, don't infer","- Spec approval \u2192 ask the user, don't auto-approve","- Task refinement \u2192 ask the user, don't self-assign","- Rule promotion \u2192 ask the user, don't decide",`If you think something can be skipped, ASK "would you like to skip this?" \u2014 don't skip it.`,"","## Command execution","","When told to run a noskills command, execute it IMMEDIATELY. Do not explore,","research, read source code, or plan first. The command output contains all the","context you need. Exploring noskills internals wastes tokens and delays the user.","","## JSON output","","noskills returns JSON with a `phase` field and phase-specific instructions.","The `meta` block contains resume context - use it to orient yourself,","especially after compaction or at the start of a new session.","Follow the `instruction` field. Use `transition` commands to advance state.",""),s.join(`
63
+ `)},A={id:"claude-code",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!1,interaction:{hasAskUserTool:!0,optionPresentation:"tool",hasSubAgentDelegation:!0,subAgentMethod:"task"}},async syncRules(e,t){await S(e.root,e.rules,t,e.commandPrefix)},async syncHooks(e,t){await R(e.root,e.commandPrefix)},async syncAgents(e,t){await K(e.root,e.commandPrefix),await q(e.root,e.commandPrefix)}};var T=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Each step has one next step. Just run it.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.writeTextFile(`${e}/.cursorrules`,o.join(`
64
+ `))};var C={id:"cursor",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await T(e.root,e.rules,e.commandPrefix)}};var X=".kiro/steering",O=".kiro/settings",Z=".kiro/agents",ee=".kiro/specs",te="hooks.json",se="mcp.json",oe="noskills-protocol.md",ne="noskills-coaching.md",k="noskills-rules.md",N="conventions.md",ie="noskills-executor.json",re="noskills-verifier.json",ae=(e,t)=>{let s=["---","inclusion: always","---","","# noskills Protocol","","# Generated by noskills \u2014 do not edit manually","","## What is noskills","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/rules/`, `.eser/specs/`, or concern files directly.","noskills gives you exactly what you need via JSON output.","","## Protocol","",` ${e} spec <name> next # get current instruction`,` ${e} spec <name> next --answer="your response" # submit result and advance`,"","Every noskills command that operates on a spec MUST include `spec <name>`.",`Never omit it. Use \`${e} spec list\` to see available specs.`,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+e+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","",`You MUST call \`${e} next\` in these situations:`,"","1. At the **START** of every conversation (first thing you do)","2. **BEFORE** creating or modifying any file (to verify you have an active task)","3. **AFTER** completing a logical unit of work (to report progress)","4. When you encounter a **DECISION** that affects architecture or scope","5. When you are **UNSURE** what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER make architectural decisions independently \u2014 noskills routes them to the user."];return(t?.allowGit??!1)||s.push("","## Git is read-only","","You MUST NOT run git write commands: commit, add, push, checkout, stash,","reset, merge, rebase, cherry-pick. The user controls git. You control files.","You MAY read from git: log, diff, status, show, blame."),s.push("","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","Use the `commandMap` to resolve the user's selection to a CLI command.","","## Decision principle: Explicit > Clever","","You NEVER skip steps, bypass questions, or make assumptions on behalf of the user.","- Discovery questions \u2192 ask the user, don't answer yourself","- Classification \u2192 ask the user, don't infer","- Spec approval \u2192 ask the user, don't auto-approve","- Task refinement \u2192 ask the user, don't self-assign","- Rule promotion \u2192 ask the user, don't decide",`If you think something can be skipped, ASK "would you like to skip this?" \u2014 don't skip it.`,"NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Just run it.","","## Command execution","","When told to run a noskills command, execute it IMMEDIATELY. Do not explore,","research, read source code, or plan first. The command output contains all the","context you need. Exploring noskills internals wastes tokens and delays the user.","","## JSON output","","noskills returns JSON with a `phase` field and phase-specific instructions.","The `meta` block contains resume context - use it to orient yourself,","especially after compaction or at the start of a new session.","Follow the `instruction` field. Use `transition` commands to advance state.",""),s.join(`
65
65
  `)},ce=e=>["---","inclusion: auto","name: noskills-coaching",'description: "Guidance for noskills spec-driven development workflow, including convention discovery and rule promotion"',"---","","# noskills Coaching","","# Generated by noskills \u2014 do not edit manually","","## Convention discovery","","When you discover a pattern, receive a correction, or identify a recurring",'preference from the user, ask: "Should this be a permanent rule for this',`project, or just for this task?" If permanent, run: \`${e} rule add`,'"<description>"`. If just this task, note it and move on.',"Never write to `.eser/rules/` directly.","","## How to promote rules","","When a convention should be permanent, use the noskills CLI to register it:","",` ${e} rule add "<description of the rule>"`,"","This stores the rule in `.eser/rules/` and ensures it is synced to all","coding tools on the next `noskills sync`. Never edit `.eser/rules/` directly.",""].join(`
66
66
  `),le=e=>{let t=["---","inclusion: always","---","","# noskills Rules","","# Generated by noskills \u2014 do not edit manually","","## Active Rules",""];for(let s of e)t.push(`- ${s}`);return t.push(""),t.join(`
67
67
  `)},ue=e=>({hooks:[{_noskills:!0,trigger:"Prompt Submit",action:{type:"Run Command",command:`${e} invoke-hook session-start`},timeout:5e3},{_noskills:!0,trigger:"Pre Tool Use",condition:{toolNames:["write","shell"]},action:{type:"Run Command",command:`${e} invoke-hook pre-tool-use`},timeout:5e3},{_noskills:!0,trigger:"Post Tool Use",condition:{toolNames:["write"]},action:{type:"Run Command",command:`${e} invoke-hook post-file-write`},timeout:3e3},{_noskills:!0,trigger:"Post Tool Use",condition:{toolNames:["shell"]},action:{type:"Run Command",command:`${e} invoke-hook post-bash`},timeout:3e3},{_noskills:!0,trigger:"Agent Stop",action:{type:"Run Command",command:`${e} invoke-hook stop`},timeout:1e4}]}),de=e=>{let t=e.split(/\s+/),s=t[0]??"npx",o=[...t.slice(1),"mcp-serve"];return{mcpServers:{noskills:{command:s,args:o,env:{},autoApprove:["noskills_next","noskills_status"],disabled:!1}}}},pe=e=>({name:"noskills-executor",description:"Executes a single noskills task. Follows spec behavioral rules and reports structured results.",tools:["read","write","glob","grep","shell","delegate"],allowedTools:["read","write","glob","grep","shell","delegate"],resources:["file://.kiro/steering/noskills-protocol.md"],prompt:["You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:","```json",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"], "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"], "verification": {"typeCheck": "pass|fail", "tests": "pass|fail (N passed, M failed)"}}',"```","","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`].join(`
68
68
  `)}),he=()=>({name:"noskills-verifier",description:"Independently verifies completed task work. Read-only. Never sees the executor's context.",tools:["read","glob","grep","shell","use_subagent"],allowedTools:["read","glob","grep","shell"],resources:["file://.kiro/steering/noskills-protocol.md"],prompt:["You are verifying another agent's work. You have NO context about how it was done.","Read the changed files. Run the test suite. Check each acceptance criterion independently.","","For each acceptance criterion:","- PASS: with evidence \u2014 show the grep result, the test output, or the file content that proves it","- FAIL: with specific reason \u2014 what's missing, what's wrong, what doesn't match","","Be skeptical. Don't assume anything works \u2014 verify it yourself.","You CANNOT edit files. Read-only access only.","","## Verification Steps","1. Read each modified file and verify the changes are correct","2. Run type check: `deno check` on modified files","3. Run tests: `deno test` on relevant test files","4. Check each acceptance criterion against actual file contents","","## Report Format","When finished, provide a structured JSON summary:","```json",'{"results": [{"id": "ac-1", "status": "PASS", "evidence": "..."}, {"id": "ac-2", "status": "FAIL", "reason": "..."}]}',"```","","The orchestrator will use this report for the noskills status report."].join(`
69
- `)}),E=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},me=e=>{let s=e.match(/^# Spec:\s*(.+)$/m)?.[1]?.trim()??"Untitled",o=new Map,i=e.split(/^## /m);for(let a of i){let c=a.indexOf(`
70
- `);if(c===-1)continue;let l=a.slice(0,c).trim().toLowerCase(),u=a.slice(c+1).trim();o.set(l,u)}let r=a=>{for(let[c,l]of o)if(c.startsWith(a.toLowerCase()))return l;return""};return{title:s,concerns:r("concerns"),discoveryAnswers:r("discovery answers"),contributorGuide:r("contributor guide"),publicApi:r("public api"),outOfScope:r("out of scope"),tasks:r("tasks"),verification:r("verification")}},fe=e=>{let t=[`# Feature: ${e.title}`,"","## Overview","",e.discoveryAnswers||"(no discovery answers yet)","","## Requirements",""],s=e.discoveryAnswers.split(`
69
+ `)}),E=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},me=e=>{let s=e.match(/^# Spec:\s*(.+)$/m)?.[1]?.trim()??"Untitled",o=new Map,i=e.split(/^## /m);for(let a of i){let l=a.indexOf(`
70
+ `);if(l===-1)continue;let c=a.slice(0,l).trim().toLowerCase(),u=a.slice(l+1).trim();o.set(c,u)}let r=a=>{for(let[l,c]of o)if(l.startsWith(a.toLowerCase()))return c;return""};return{title:s,concerns:r("concerns"),discoveryAnswers:r("discovery answers"),contributorGuide:r("contributor guide"),publicApi:r("public api"),outOfScope:r("out of scope"),tasks:r("tasks"),verification:r("verification")}},fe=e=>{let t=[`# Feature: ${e.title}`,"","## Overview","",e.discoveryAnswers||"(no discovery answers yet)","","## Requirements",""],s=e.discoveryAnswers.split(`
71
71
  `).filter(o=>o.startsWith("### "));if(s.length>0)for(let o of s)t.push(`- ${o.replace(/^###\s*/,"")}`);else e.discoveryAnswers?t.push("- See overview for details"):t.push("- (none yet)");if(t.push("","## Acceptance Criteria",""),e.verification){let o=e.verification.split(`
72
72
  `).filter(i=>i.trim());for(let i of o){let r=i.replace(/^[-*]\s*/,"").trim();r&&t.push(`- [ ] ${r}`)}}else t.push("- [ ] (none yet)");return t.push("","## Out of Scope",""),t.push(e.outOfScope||"(nothing listed)"),t.push(""),t.join(`
73
73
  `)},ye=e=>{let t=[`# Design: ${e.title}`,"","## Architecture",""];return e.discoveryAnswers?t.push(e.discoveryAnswers):t.push("(no architecture decisions yet)"),t.push("","## Concerns",""),e.concerns?t.push(e.concerns):t.push("(no active concerns)"),t.push("","## Decisions",""),e.contributorGuide||e.publicApi?(e.contributorGuide&&t.push("### Contributor Guide","",e.contributorGuide,""),e.publicApi&&t.push("### Public API Surface","",e.publicApi,"")):t.push("(no decisions yet)"),t.push(""),t.join(`
74
74
  `)},ge=e=>{let t=[`# Tasks: ${e.title}`,""];return e.tasks?t.push(e.tasks):t.push("(no tasks yet)"),t.push(""),t.join(`
75
- `)},$={id:"kiro",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!0,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"delegation"}},async syncRules(e,t){let s=`${e.root}/${X}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/${oe}`,ae(e.commandPrefix,t)),await n.fs.writeTextFile(`${s}/${ne}`,ce(e.commandPrefix)),e.rules.length>0?await n.fs.writeTextFile(`${s}/${k}`,le(e.rules)):await E(`${s}/${k}`)&&await n.fs.remove(`${s}/${k}`),await E(`${s}/${N}`)&&await n.fs.remove(`${s}/${N}`)},async syncHooks(e,t){let s=`${e.root}/${O}`,o=`${s}/${te}`;await n.fs.mkdir(s,{recursive:!0});let i=[];try{let l=await n.fs.readTextFile(o),u=JSON.parse(l);Array.isArray(u.hooks)&&(i=u.hooks)}catch{}let r=i.filter(l=>!l._noskills),a=ue(e.commandPrefix),c={hooks:[...r,...a.hooks]};await n.fs.writeTextFile(o,JSON.stringify(c,null,2)+`
75
+ `)},$={id:"kiro",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!0,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"delegation"}},async syncRules(e,t){let s=`${e.root}/${X}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/${oe}`,ae(e.commandPrefix,t)),await n.fs.writeTextFile(`${s}/${ne}`,ce(e.commandPrefix)),e.rules.length>0?await n.fs.writeTextFile(`${s}/${k}`,le(e.rules)):await E(`${s}/${k}`)&&await n.fs.remove(`${s}/${k}`),await E(`${s}/${N}`)&&await n.fs.remove(`${s}/${N}`)},async syncHooks(e,t){let s=`${e.root}/${O}`,o=`${s}/${te}`;await n.fs.mkdir(s,{recursive:!0});let i=[];try{let c=await n.fs.readTextFile(o),u=JSON.parse(c);Array.isArray(u.hooks)&&(i=u.hooks)}catch{}let r=i.filter(c=>!c._noskills),a=ue(e.commandPrefix),l={hooks:[...r,...a.hooks]};await n.fs.writeTextFile(o,JSON.stringify(l,null,2)+`
76
76
  `)},async syncAgents(e,t){let s=`${e.root}/${Z}`;await n.fs.mkdir(s,{recursive:!0});let o=pe(e.commandPrefix);await n.fs.writeTextFile(`${s}/${ie}`,JSON.stringify(o,null,2)+`
77
77
  `);let i=he();await n.fs.writeTextFile(`${s}/${re}`,JSON.stringify(i,null,2)+`
78
- `)},async syncSpecs(e,t){let s;try{s=await n.fs.readTextFile(t)}catch{return}if(s.trim()==="")return;let o=t.split("/"),i=o[o.length-2]??"unknown",r=me(s),a=`${e.root}/${ee}/${i}`;await n.fs.mkdir(a,{recursive:!0}),await n.fs.writeTextFile(`${a}/requirements.md`,fe(r)),await n.fs.writeTextFile(`${a}/design.md`,ye(r)),await n.fs.writeTextFile(`${a}/tasks.md`,ge(r))},async syncMcp(e){let t=`${e.root}/${O}`,s=`${t}/${se}`;await n.fs.mkdir(t,{recursive:!0});let o={mcpServers:{}};try{let a=await n.fs.readTextFile(s),c=JSON.parse(a);c.mcpServers!==void 0&&c.mcpServers!==null&&(o=c)}catch{}let i=de(e.commandPrefix),r={...o,mcpServers:{...o.mcpServers,...i.mcpServers}};await n.fs.writeTextFile(s,JSON.stringify(r,null,2)+`
79
- `)}};var f=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.mkdir(`${e}/.github`,{recursive:!0}),await n.fs.writeTextFile(`${e}/.github/copilot-instructions.md`,o.join(`
80
- `))};var D={id:"copilot",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await f(e.root,e.rules,e.commandPrefix)}};var M=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.writeTextFile(`${e}/.windsurfrules`,o.join(`
81
- `))};var F={id:"windsurf",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await M(e.root,e.rules,e.commandPrefix)}};var Se="AGENTS.md",P="<!-- noskills:start -->",w="<!-- noskills:end -->",xe=(e,t)=>{let s=["## noskills Protocol","","# Generated by noskills \u2014 do not edit manually","","### What is noskills","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/rules/`, `.eser/specs/`, or concern files directly.","noskills gives you exactly what you need via JSON output.","","### Protocol","",` ${e} spec <name> next # get current instruction`,` ${e} spec <name> next --answer="your response" # submit result and advance`,"","Every noskills command that operates on a spec MUST include `spec <name>`.",`Never omit it. Use \`${e} spec list\` to see available specs.`,"","### Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+e+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","### When to call noskills next","",`You MUST call \`${e} next\` in these situations:`,"","1. At the **START** of every conversation (first thing you do)","2. **BEFORE** creating or modifying any file (to verify you have an active task)","3. **AFTER** completing a logical unit of work (to report progress)","4. When you encounter a **DECISION** that affects architecture or scope","5. When you are **UNSURE** what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER make architectural decisions independently \u2014 noskills routes them to the user."];return(t?.allowGit??!1)||s.push("","### Git is read-only","","You MUST NOT run git write commands: commit, add, push, checkout, stash,","reset, merge, rebase, cherry-pick. The user controls git. You control files.","You MAY read from git: log, diff, status, show, blame."),s.push("","### Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","Use the `commandMap` to resolve the user's selection to a CLI command.","","### Decision principle: Explicit > Clever","","You NEVER skip steps, bypass questions, or make assumptions on behalf of the user.","- Discovery questions \u2192 ask the user, don't answer yourself","- Classification \u2192 ask the user, don't infer","- Spec approval \u2192 ask the user, don't auto-approve","- Task refinement \u2192 ask the user, don't self-assign","- Rule promotion \u2192 ask the user, don't decide",`If you think something can be skipped, ASK "would you like to skip this?" \u2014 don't skip it.`,"","### Command execution","","When told to run a noskills command, execute it IMMEDIATELY. Do not explore,","research, read source code, or plan first. The command output contains all the","context you need. Exploring noskills internals wastes tokens and delays the user.","","### JSON output","","noskills returns JSON with a `phase` field and phase-specific instructions.","The `meta` block contains resume context - use it to orient yourself,","especially after compaction or at the start of a new session.","Follow the `instruction` field. Use `transition` commands to advance state.",""),s.join(`
78
+ `)},async syncSpecs(e,t){let s;try{s=await n.fs.readTextFile(t)}catch{return}if(s.trim()==="")return;let o=t.split("/"),i=o[o.length-2]??"unknown",r=me(s),a=`${e.root}/${ee}/${i}`;await n.fs.mkdir(a,{recursive:!0}),await n.fs.writeTextFile(`${a}/requirements.md`,fe(r)),await n.fs.writeTextFile(`${a}/design.md`,ye(r)),await n.fs.writeTextFile(`${a}/tasks.md`,ge(r))},async syncMcp(e){let t=`${e.root}/${O}`,s=`${t}/${se}`;await n.fs.mkdir(t,{recursive:!0});let o={mcpServers:{}};try{let a=await n.fs.readTextFile(s),l=JSON.parse(a);l.mcpServers!==void 0&&l.mcpServers!==null&&(o=l)}catch{}let i=de(e.commandPrefix),r={...o,mcpServers:{...o.mcpServers,...i.mcpServers}};await n.fs.writeTextFile(s,JSON.stringify(r,null,2)+`
79
+ `)}};var f=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Each step has one next step. Just run it.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.mkdir(`${e}/.github`,{recursive:!0}),await n.fs.writeTextFile(`${e}/.github/copilot-instructions.md`,o.join(`
80
+ `))};var D={id:"copilot",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await f(e.root,e.rules,e.commandPrefix)}};var M=async(e,t,s="npx eser noskills")=>{let o=["# Generated by noskills \u2014 do not edit manually","","## noskills orchestrator","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/specs/` or `.eser/rules/` directly. noskills gives you what you need.","",`Run \`${s} next\` to get your current instruction.`,`Submit results with \`${s} next --answer="..."\``,"","## Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+s+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","## When to call noskills next","","1. At the START of every conversation","2. BEFORE creating or modifying any file","3. AFTER completing a logical unit of work","4. When you encounter a DECISION that affects architecture","5. When you are UNSURE what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Each step has one next step. Just run it.","","## Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","","## Execution model","","Execute tasks sequentially in this context. Do not attempt to spawn sub-agents.",""];if(t.length>0){o.push("## Rules","");for(let i of t)o.push(`- ${i}`);o.push("")}await n.fs.writeTextFile(`${e}/.windsurfrules`,o.join(`
81
+ `))};var F={id:"windsurf",capabilities:{rules:!0,hooks:!1,agents:!1,specs:!1,mcp:!1,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!1,subAgentMethod:"none"}},async syncRules(e){await M(e.root,e.rules,e.commandPrefix)}};var xe="AGENTS.md",P="<!-- noskills:start -->",w="<!-- noskills:end -->",Se=(e,t)=>{let s=["## noskills Protocol","","# Generated by noskills \u2014 do not edit manually","","### What is noskills","","This project uses noskills for state-driven orchestration.","Do NOT read `.eser/rules/`, `.eser/specs/`, or concern files directly.","noskills gives you exactly what you need via JSON output.","","### Protocol","",` ${e} spec <name> next # get current instruction`,` ${e} spec <name> next --answer="your response" # submit result and advance`,"","Every noskills command that operates on a spec MUST include `spec <name>`.",`Never omit it. Use \`${e} spec list\` to see available specs.`,"","### Why noskills calls matter","","noskills is not a form to fill out. It is a live state machine that the user","watches in real-time. Every `"+e+" next --answer` call:","","- Updates the spec file on disk (the user sees it change)","- Updates the terminal dashboard if `noskills watch` is running","- Advances the state machine to the next phase","- Records the decision permanently in the project history","","When you batch-submit answers or backfill discovery responses yourself,","the user sees nothing happening \u2014 then suddenly everything jumps forward.","This defeats the purpose.","","Call noskills ONCE per interaction. Ask the user ONE question. Wait for","their answer. Submit it. Ask the next. The user is watching every step.","Do NOT pre-fill answers. Do NOT batch multiple answers. Do NOT answer","discovery questions yourself \u2014 the user's input is the data.","","### When to call noskills next","",`You MUST call \`${e} next\` in these situations:`,"","1. At the **START** of every conversation (first thing you do)","2. **BEFORE** creating or modifying any file (to verify you have an active task)","3. **AFTER** completing a logical unit of work (to report progress)","4. When you encounter a **DECISION** that affects architecture or scope","5. When you are **UNSURE** what to do next","","NEVER proceed with implementation without checking noskills first.","NEVER make architectural decisions independently \u2014 noskills routes them to the user."];return(t?.allowGit??!1)||s.push("","### Git is read-only","","You MUST NOT run git write commands: commit, add, push, checkout, stash,","reset, merge, rebase, cherry-pick. The user controls git. You control files.","You MAY read from git: log, diff, status, show, blame."),s.push("","### Interactive choices","","Present choices as numbered lists. Users select by number.","When interactiveOptions are present in noskills output, present each as a","numbered item with its label and description. Ask the user to pick a number.","Use the `commandMap` to resolve the user's selection to a CLI command.","","### Decision principle: Explicit > Clever","","You NEVER skip steps, bypass questions, or make assumptions on behalf of the user.","- Discovery questions \u2192 ask the user, don't answer yourself","- Classification \u2192 ask the user, don't infer","- Spec approval \u2192 ask the user, don't auto-approve","- Task refinement \u2192 ask the user, don't self-assign","- Rule promotion \u2192 ask the user, don't decide",`If you think something can be skipped, ASK "would you like to skip this?" \u2014 don't skip it.`,"NEVER suggest bypassing or skipping noskills. Discovery is not overhead.","NEVER ask permission to run the next noskills command. After spec new \u2192 run next. After approve \u2192 run next. Just run it.","","### Command execution","","When told to run a noskills command, execute it IMMEDIATELY. Do not explore,","research, read source code, or plan first. The command output contains all the","context you need. Exploring noskills internals wastes tokens and delays the user.","","### JSON output","","noskills returns JSON with a `phase` field and phase-specific instructions.","The `meta` block contains resume context - use it to orient yourself,","especially after compaction or at the start of a new session.","Follow the `instruction` field. Use `transition` commands to advance state.",""),s.join(`
82
82
  `)},Re=e=>["### Convention discovery","","When you discover a pattern, receive a correction, or identify a recurring",'preference from the user, ask: "Should this be a permanent rule for this',`project, or just for this task?" If permanent, run: \`${e} rule add`,'"<description>"`. If just this task, note it and move on.',"Never write to `.eser/rules/` directly.","","### How to promote rules","","When a convention should be permanent, use the noskills CLI to register it:","",` ${e} rule add "<description of the rule>"`,"","This stores the rule in `.eser/rules/` and ensures it is synced to all","coding tools on the next `noskills sync`. Never edit `.eser/rules/` directly.",""].join(`
83
83
  `),Ae=e=>{let t=["### Active Rules",""];for(let s of e)t.push(`- ${s}`);return t.push(""),t.join(`
84
- `)},Te=(e,t,s)=>{let o=[P,xe(t,s),Re(t)];return e.length>0&&o.push(Ae(e)),o.push(w),o.join(`
85
- `)},m=async(e,t)=>{let s=`${e.root}/${Se}`,o=Te(e.rules,e.commandPrefix,t),i;try{i=await n.fs.readTextFile(s);let r=i.indexOf(P),a=i.indexOf(w);r!==-1&&a!==-1?i=i.slice(0,r)+o+i.slice(a+w.length):i=i.trimEnd()+`
84
+ `)},Te=(e,t,s)=>{let o=[P,Se(t,s),Re(t)];return e.length>0&&o.push(Ae(e)),o.push(w),o.join(`
85
+ `)},m=async(e,t)=>{let s=`${e.root}/${xe}`,o=Te(e.rules,e.commandPrefix,t),i;try{i=await n.fs.readTextFile(s);let r=i.indexOf(P),a=i.indexOf(w);r!==-1&&a!==-1?i=i.slice(0,r)+o+i.slice(a+w.length):i=i.trimEnd()+`
86
86
 
87
87
  `+o+`
88
88
  `}catch{i=o+`
89
89
  `}await n.fs.writeTextFile(s,i)};var Ce=".opencode/plugins",Oe=".opencode/agents",Ne=".opencode/skills",Ee="opencode.json",$e=e=>["// Generated by noskills \u2014 do not edit manually",'import { execSync } from "node:child_process";',"","const run = (event: string): void => {"," try {",` execSync(\`${e} invoke-hook \${event}\`, {`,' stdio: "inherit",'," timeout: 10000,"," });"," } catch {"," // Hook failure should not block the session"," }","};","","export default async () => ({",' "session.created": async () => {',' run("session-start");'," },",' "tool.execute.before": async (params: { toolName: string }) => {',' if (["write", "shell"].includes(params.toolName)) {',' run("pre-tool-use");'," }"," },",' "tool.execute.after": async (params: { toolName: string }) => {',' if (params.toolName === "write") {',' run("post-file-write");',' } else if (params.toolName === "shell") {',' run("post-bash");'," }"," },",' "session.deleted": async () => {',' run("stop");'," },","});",""].join(`
90
90
  `),Ie=e=>["---","name: noskills-executor",'description: "Executes a single noskills task. Follows spec behavioral rules and reports structured results."',"tools: read, write, glob, grep, shell, delegate","---","","You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:","```json",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"], "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"], "verification": {"typeCheck": "pass|fail", "tests": "pass|fail (N passed, M failed)"}}',"```","","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`,""].join(`
91
91
  `),De=()=>["---","name: noskills-verifier",`description: "Independently verifies completed task work. Read-only. Never sees the executor's context."`,"tools: read, glob, grep, shell","---","","You are verifying another agent's work. You have NO context about how it was done.","Read the changed files. Run the test suite. Check each acceptance criterion independently.","","For each acceptance criterion:","- PASS: with evidence \u2014 show the grep result, the test output, or the file content that proves it","- FAIL: with specific reason \u2014 what's missing, what's wrong, what doesn't match","","Be skeptical. Don't assume anything works \u2014 verify it yourself.","You CANNOT edit files. Read-only access only.","","## Verification Steps","1. Read each modified file and verify the changes are correct","2. Run type check: `deno check` on modified files","3. Run tests: `deno test` on relevant test files","4. Check each acceptance criterion against actual file contents","","## Report Format","When finished, provide a structured JSON summary:","```json",'{"results": [{"id": "ac-1", "status": "PASS", "evidence": "..."}, {"id": "ac-2", "status": "FAIL", "reason": "..."}]}',"```","","The orchestrator will use this report for the noskills status report.",""].join(`
92
- `),Me=e=>{let s=e.match(/^# Spec:\s*(.+)$/m)?.[1]?.trim()??"Untitled",o=new Map,i=e.split(/^## /m);for(let a of i){let c=a.indexOf(`
93
- `);if(c===-1)continue;let l=a.slice(0,c).trim().toLowerCase(),u=a.slice(c+1).trim();o.set(l,u)}let r=a=>{for(let[c,l]of o)if(c.startsWith(a.toLowerCase()))return l;return""};return{title:s,concerns:r("concerns"),discoveryAnswers:r("discovery answers"),contributorGuide:r("contributor guide"),publicApi:r("public api"),outOfScope:r("out of scope"),tasks:r("tasks"),verification:r("verification")}},Fe=e=>{let t=["---",`name: ${e.title}`,`description: "noskills spec: ${e.title}"`,"---","",`# ${e.title}`,""];return e.discoveryAnswers&&t.push("## Overview","",e.discoveryAnswers,""),e.concerns&&t.push("## Concerns","",e.concerns,""),e.contributorGuide&&t.push("## Contributor Guide","",e.contributorGuide,""),e.publicApi&&t.push("## Public API","",e.publicApi,""),e.outOfScope&&t.push("## Out of Scope","",e.outOfScope,""),e.tasks&&t.push("## Tasks","",e.tasks,""),e.verification&&t.push("## Verification","",e.verification,""),t.join(`
94
- `)},Pe=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},U={id:"opencode",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!0,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"delegation"}},async syncRules(e,t){await m(e,t)},async syncHooks(e,t){let s=`${e.root}/${Ce}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills.ts`,$e(e.commandPrefix))},async syncAgents(e,t){let s=`${e.root}/${Oe}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.md`,Ie(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.md`,De())},async syncSpecs(e,t){let s;try{s=await n.fs.readTextFile(t)}catch{return}if(s.trim()==="")return;let o=t.split("/"),i=o[o.length-2]??"unknown",r=Me(s),a=`${e.root}/${Ne}`;await n.fs.mkdir(a,{recursive:!0}),await n.fs.writeTextFile(`${a}/${i}.md`,Fe(r))},async syncMcp(e){let t=`${e.root}/${Ee}`,s={};if(await Pe(t))try{let c=await n.fs.readTextFile(t);s=JSON.parse(c)}catch{}let o=e.commandPrefix.split(/\s+/),i=o[0]??"npx",r=[...o.slice(1),"mcp-serve"],a={...s,mcp:{...s.mcp,noskills:{type:"local",command:i,args:r}}};await n.fs.writeTextFile(t,JSON.stringify(a,null,2)+`
95
- `)}};var We=".codex",je="hooks.json",_e=".codex/agents",He=".codex/config.toml",Le=e=>({hooks:[{_noskills:!0,event:"SessionStart",command:`${e} invoke-hook session-start`,timeout:5e3},{_noskills:!0,event:"PreToolUse",command:`${e} invoke-hook pre-tool-use`,timeout:5e3},{_noskills:!0,event:"PostToolUse",command:`${e} invoke-hook post-file-write`,timeout:3e3},{_noskills:!0,event:"Stop",command:`${e} invoke-hook stop`,timeout:1e4}]}),Ye=e=>['name = "noskills-executor"','description = "Executes a single noskills task. Follows spec behavioral rules and reports structured results."','developer_instructions = """',["You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"],',' "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"],',' "verification": {"typeCheck": "pass|fail", "tests": "pass|fail"}}',"","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`].join(`
92
+ `),Me=e=>{let s=e.match(/^# Spec:\s*(.+)$/m)?.[1]?.trim()??"Untitled",o=new Map,i=e.split(/^## /m);for(let a of i){let l=a.indexOf(`
93
+ `);if(l===-1)continue;let c=a.slice(0,l).trim().toLowerCase(),u=a.slice(l+1).trim();o.set(c,u)}let r=a=>{for(let[l,c]of o)if(l.startsWith(a.toLowerCase()))return c;return""};return{title:s,concerns:r("concerns"),discoveryAnswers:r("discovery answers"),contributorGuide:r("contributor guide"),publicApi:r("public api"),outOfScope:r("out of scope"),tasks:r("tasks"),verification:r("verification")}},Fe=e=>{let t=["---",`name: ${e.title}`,`description: "noskills spec: ${e.title}"`,"---","",`# ${e.title}`,""];return e.discoveryAnswers&&t.push("## Overview","",e.discoveryAnswers,""),e.concerns&&t.push("## Concerns","",e.concerns,""),e.contributorGuide&&t.push("## Contributor Guide","",e.contributorGuide,""),e.publicApi&&t.push("## Public API","",e.publicApi,""),e.outOfScope&&t.push("## Out of Scope","",e.outOfScope,""),e.tasks&&t.push("## Tasks","",e.tasks,""),e.verification&&t.push("## Verification","",e.verification,""),t.join(`
94
+ `)},Pe=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},_={id:"opencode",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!0,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"delegation"}},async syncRules(e,t){await m(e,t)},async syncHooks(e,t){let s=`${e.root}/${Ce}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills.ts`,$e(e.commandPrefix))},async syncAgents(e,t){let s=`${e.root}/${Oe}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.md`,Ie(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.md`,De())},async syncSpecs(e,t){let s;try{s=await n.fs.readTextFile(t)}catch{return}if(s.trim()==="")return;let o=t.split("/"),i=o[o.length-2]??"unknown",r=Me(s),a=`${e.root}/${Ne}`;await n.fs.mkdir(a,{recursive:!0}),await n.fs.writeTextFile(`${a}/${i}.md`,Fe(r))},async syncMcp(e){let t=`${e.root}/${Ee}`,s={};if(await Pe(t))try{let l=await n.fs.readTextFile(t);s=JSON.parse(l)}catch{}let o=e.commandPrefix.split(/\s+/),i=o[0]??"npx",r=[...o.slice(1),"mcp-serve"],a={...s,mcp:{...s.mcp,noskills:{type:"local",command:i,args:r}}};await n.fs.writeTextFile(t,JSON.stringify(a,null,2)+`
95
+ `)}};var Ue=".codex",je="hooks.json",We=".codex/agents",He=".codex/config.toml",Le=e=>({hooks:[{_noskills:!0,event:"SessionStart",command:`${e} invoke-hook session-start`,timeout:5e3},{_noskills:!0,event:"PreToolUse",command:`${e} invoke-hook pre-tool-use`,timeout:5e3},{_noskills:!0,event:"PostToolUse",command:`${e} invoke-hook post-file-write`,timeout:3e3},{_noskills:!0,event:"Stop",command:`${e} invoke-hook stop`,timeout:1e4}]}),Ye=e=>['name = "noskills-executor"','description = "Executes a single noskills task. Follows spec behavioral rules and reports structured results."','developer_instructions = """',["You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"],',' "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"],',' "verification": {"typeCheck": "pass|fail", "tests": "pass|fail"}}',"","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`].join(`
96
96
  `),'"""',""].join(`
97
97
  `),Ge=()=>['name = "noskills-verifier"',`description = "Independently verifies completed task work. Read-only. Never sees the executor's context."`,'developer_instructions = """',["You are verifying another agent's work. You have NO context about how it was done.","Read the changed files. Run the test suite. Check each acceptance criterion independently.","","For each acceptance criterion:","- PASS: with evidence \u2014 show the grep result, the test output, or the file content that proves it","- FAIL: with specific reason \u2014 what's missing, what's wrong, what doesn't match","","Be skeptical. Don't assume anything works \u2014 verify it yourself.","You CANNOT edit files. Read-only access only.","","## Verification Steps","1. Read each modified file and verify the changes are correct","2. Run type check: `deno check` on modified files","3. Run tests: `deno test` on relevant test files","4. Check each acceptance criterion against actual file contents","","## Report Format","When finished, provide a structured JSON summary:",'{"results": [{"id": "ac-1", "status": "PASS", "evidence": "..."},',' {"id": "ac-2", "status": "FAIL", "reason": "..."}]}',"","The orchestrator will use this report for the noskills status report."].join(`
98
98
  `),'"""',""].join(`
99
99
  `),Je=e=>{let t=e.split(/\s+/),s=t[0]??"npx",o=[...t.slice(1),"mcp-serve"].map(i=>`"${i}"`).join(", ");return`[mcp_servers.noskills]
100
100
  command = "${s}"
101
101
  args = [${o}]
102
- `},qe=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},W={id:"codex",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"spawn"}},async syncRules(e,t){await m(e,t)},async syncHooks(e,t){let s=`${e.root}/${We}`,o=`${s}/${je}`;await n.fs.mkdir(s,{recursive:!0});let i=[];try{let l=await n.fs.readTextFile(o),u=JSON.parse(l);Array.isArray(u.hooks)&&(i=u.hooks)}catch{}let r=i.filter(l=>!l._noskills),a=Le(e.commandPrefix),c={hooks:[...r,...a.hooks]};await n.fs.writeTextFile(o,JSON.stringify(c,null,2)+`
103
- `)},async syncAgents(e,t){let s=`${e.root}/${_e}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.toml`,Ye(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.toml`,Ge())},async syncMcp(e){let t=`${e.root}/${He}`;await n.fs.mkdir(`${e.root}/.codex`,{recursive:!0});let s="";if(await qe(t))try{s=await n.fs.readTextFile(t)}catch{}let o=s.replace(/\[mcp_servers\.noskills\][\s\S]*?(?=\[|$)/,"").trimEnd(),i=Je(e.commandPrefix),r=o+(o.length>0?`
102
+ `},Ve=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},U={id:"codex",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"spawn"}},async syncRules(e,t){await m(e,t)},async syncHooks(e,t){let s=`${e.root}/${Ue}`,o=`${s}/${je}`;await n.fs.mkdir(s,{recursive:!0});let i=[];try{let c=await n.fs.readTextFile(o),u=JSON.parse(c);Array.isArray(u.hooks)&&(i=u.hooks)}catch{}let r=i.filter(c=>!c._noskills),a=Le(e.commandPrefix),l={hooks:[...r,...a.hooks]};await n.fs.writeTextFile(o,JSON.stringify(l,null,2)+`
103
+ `)},async syncAgents(e,t){let s=`${e.root}/${We}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.toml`,Ye(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.toml`,Ge())},async syncMcp(e){let t=`${e.root}/${He}`;await n.fs.mkdir(`${e.root}/.codex`,{recursive:!0});let s="";if(await Ve(t))try{s=await n.fs.readTextFile(t)}catch{}let o=s.replace(/\[mcp_servers\.noskills\][\s\S]*?(?=\[|$)/,"").trimEnd(),i=Je(e.commandPrefix),r=o+(o.length>0?`
104
104
 
105
- `:"")+i;await n.fs.writeTextFile(t,r)}};var Ke=".github/hooks",Be="noskills.json",ze=".github/agents",Qe=".copilot",Xe="mcp.json",Ze=e=>({version:1,hooks:{"noskills:sessionStart":{_noskills:!0,command:["bash","-c",`${e} invoke-hook session-start`],timeoutSec:5},"noskills:preToolUse":{_noskills:!0,command:["bash","-c",`${e} invoke-hook pre-tool-use`],timeoutSec:5},"noskills:postToolUse":{_noskills:!0,command:["bash","-c",`${e} invoke-hook post-file-write`],timeoutSec:3},"noskills:agentStop":{_noskills:!0,command:["bash","-c",`${e} invoke-hook stop`],timeoutSec:10}}}),et=e=>["---","name: noskills-executor",'description: "Executes a single noskills task. Follows spec behavioral rules and reports structured results."',"tools:"," - read"," - write"," - glob"," - grep"," - shell","---","","You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:","```json",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"], "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"], "verification": {"typeCheck": "pass|fail", "tests": "pass|fail (N passed, M failed)"}}',"```","","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`,""].join(`
105
+ `:"")+i;await n.fs.writeTextFile(t,r)}};var qe=".github/hooks",Be="noskills.json",ze=".github/agents",Qe=".copilot",Xe="mcp.json",Ze=e=>({version:1,hooks:{"noskills:sessionStart":{_noskills:!0,command:["bash","-c",`${e} invoke-hook session-start`],timeoutSec:5},"noskills:preToolUse":{_noskills:!0,command:["bash","-c",`${e} invoke-hook pre-tool-use`],timeoutSec:5},"noskills:postToolUse":{_noskills:!0,command:["bash","-c",`${e} invoke-hook post-file-write`],timeoutSec:3},"noskills:agentStop":{_noskills:!0,command:["bash","-c",`${e} invoke-hook stop`],timeoutSec:10}}}),et=e=>["---","name: noskills-executor",'description: "Executes a single noskills task. Follows spec behavioral rules and reports structured results."',"tools:"," - read"," - write"," - glob"," - grep"," - shell","---","","You are executing a single task from a noskills spec.","Your ONLY job is to complete the task described in the prompt.","Follow all behavioral rules provided in the prompt.","Do NOT start new tasks, explore unrelated code, or make architectural decisions.","If the task is too vague to execute, say so immediately.","","## Self-Verification","After completing the task, you MUST verify your own work before reporting:","1. Run type check: `deno check` on all modified files","2. Run test suite: `deno test` on the relevant test files","3. If type check or tests fail, fix the issues before reporting","","## Reporting","When finished, provide a structured JSON summary:","```json",'{"completed": ["<item IDs done>"], "remaining": ["<item IDs not done>"], "blocked": ["<item IDs needing decisions>"], "filesModified": ["<paths>"], "verification": {"typeCheck": "pass|fail", "tests": "pass|fail (N passed, M failed)"}}',"```","","Do NOT return raw test output \u2014 summarize it in the verification field.",`The orchestrator will submit this to \`${e} next --answer\` on your behalf.`,""].join(`
106
106
  `),tt=()=>["---","name: noskills-verifier",`description: "Independently verifies completed task work. Read-only. Never sees the executor's context."`,"tools:"," - read"," - glob"," - grep"," - shell","---","","You are verifying another agent's work. You have NO context about how it was done.","Read the changed files. Run the test suite. Check each acceptance criterion independently.","","For each acceptance criterion:","- PASS: with evidence \u2014 show the grep result, the test output, or the file content that proves it","- FAIL: with specific reason \u2014 what's missing, what's wrong, what doesn't match","","Be skeptical. Don't assume anything works \u2014 verify it yourself.","You CANNOT edit files. Read-only access only.","","## Verification Steps","1. Read each modified file and verify the changes are correct","2. Run type check: `deno check` on modified files","3. Run tests: `deno test` on relevant test files","4. Check each acceptance criterion against actual file contents","","## Report Format","When finished, provide a structured JSON summary:","```json",'{"results": [{"id": "ac-1", "status": "PASS", "evidence": "..."}, {"id": "ac-2", "status": "FAIL", "reason": "..."}]}',"```","","The orchestrator will use this report for the noskills status report.",""].join(`
107
- `),st=e=>{let t=e.split(/\s+/),s=t[0]??"npx",o=[...t.slice(1),"mcp-serve"];return{mcpServers:{noskills:{type:"local",command:s,args:o,tools:["*"]}}}},ot=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},j={id:"copilot-cli",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"fleet"}},async syncRules(e,t){await m(e,t),await f(e.root,e.rules,e.commandPrefix)},async syncHooks(e,t){let s=`${e.root}/${Ke}`,o=`${s}/${Be}`;await n.fs.mkdir(s,{recursive:!0});let i={};try{let l=await n.fs.readTextFile(o),u=JSON.parse(l);u.hooks!==void 0&&u.hooks!==null&&(i=u.hooks)}catch{}let r={};for(let[l,u]of Object.entries(i))u._noskills||(r[l]=u);let a=Ze(e.commandPrefix),c={version:1,hooks:{...r,...a.hooks}};await n.fs.writeTextFile(o,JSON.stringify(c,null,2)+`
108
- `)},async syncAgents(e,t){let s=`${e.root}/${ze}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.agent.md`,et(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.agent.md`,tt())},async syncMcp(e){let t=`${e.root}/${Qe}`,s=`${t}/${Xe}`;await n.fs.mkdir(t,{recursive:!0});let o={mcpServers:{}};if(await ot(s))try{let a=await n.fs.readTextFile(s),c=JSON.parse(a);c.mcpServers!==void 0&&c.mcpServers!==null&&(o=c)}catch{}let i=st(e.commandPrefix),r={...o,mcpServers:{...o.mcpServers,...i.mcpServers}};await n.fs.writeTextFile(s,JSON.stringify(r,null,2)+`
107
+ `),st=e=>{let t=e.split(/\s+/),s=t[0]??"npx",o=[...t.slice(1),"mcp-serve"];return{mcpServers:{noskills:{type:"local",command:s,args:o,tools:["*"]}}}},ot=async e=>{try{return await n.fs.stat(e),!0}catch{return!1}},j={id:"copilot-cli",capabilities:{rules:!0,hooks:!0,agents:!0,specs:!1,mcp:!0,interaction:{hasAskUserTool:!1,optionPresentation:"prose",hasSubAgentDelegation:!0,subAgentMethod:"fleet"}},async syncRules(e,t){await m(e,t),await f(e.root,e.rules,e.commandPrefix)},async syncHooks(e,t){let s=`${e.root}/${qe}`,o=`${s}/${Be}`;await n.fs.mkdir(s,{recursive:!0});let i={};try{let c=await n.fs.readTextFile(o),u=JSON.parse(c);u.hooks!==void 0&&u.hooks!==null&&(i=u.hooks)}catch{}let r={};for(let[c,u]of Object.entries(i))u._noskills||(r[c]=u);let a=Ze(e.commandPrefix),l={version:1,hooks:{...r,...a.hooks}};await n.fs.writeTextFile(o,JSON.stringify(l,null,2)+`
108
+ `)},async syncAgents(e,t){let s=`${e.root}/${ze}`;await n.fs.mkdir(s,{recursive:!0}),await n.fs.writeTextFile(`${s}/noskills-executor.agent.md`,et(e.commandPrefix)),await n.fs.writeTextFile(`${s}/noskills-verifier.agent.md`,tt())},async syncMcp(e){let t=`${e.root}/${Qe}`,s=`${t}/${Xe}`;await n.fs.mkdir(t,{recursive:!0});let o={mcpServers:{}};if(await ot(s))try{let a=await n.fs.readTextFile(s),l=JSON.parse(a);l.mcpServers!==void 0&&l.mcpServers!==null&&(o=l)}catch{}let i=st(e.commandPrefix),r={...o,mcpServers:{...o.mcpServers,...i.mcpServers}};await n.fs.writeTextFile(s,JSON.stringify(r,null,2)+`
109
109
  `)}};var it=e=>{let t=e.trim();if(!t.startsWith("---"))return{meta:{},body:t};let s=t.indexOf("---",3);if(s===-1)return{meta:{},body:t};let o=t.slice(3,s).trim(),i=t.slice(s+3).trim(),r={};for(let a of o.split(`
110
- `)){let c=a.indexOf(":");if(c===-1)continue;let l=a.slice(0,c).trim(),u=a.slice(c+1).trim();if(u.startsWith("[")&&u.endsWith("]")){let d=u.slice(1,-1).split(",").map(p=>p.trim().replace(/^["']|["']$/g,"")).filter(p=>p.length>0);r[l]=d}else r[l]=u.replace(/^["']|["']$/g,"")}return{meta:r,body:i}},rt=async e=>{let t=`${e}/${y.rulesDir}`,s=[];try{for await(let o of n.fs.readDir(t))if(o.isFile&&(o.name.endsWith(".md")||o.name.endsWith(".txt"))){let i=await n.fs.readTextFile(`${t}/${o.name}`),{meta:r,body:a}=it(i),c=a.split(`
111
- `)[0]??a;s.push({text:c,phases:Array.isArray(r.phases)?r.phases:void 0,appliesTo:Array.isArray(r.applies_to)?r.applies_to:void 0})}}catch{}return s},ft=(e,t,s)=>e.filter(o=>!(o.phases!==void 0&&o.phases.length>0&&!o.phases.includes(t)||o.appliesTo!==void 0&&o.appliesTo.length>0&&s!==void 0&&s.length>0&&!o.appliesTo.some(r=>{let a=r.startsWith("*.")?r.slice(1):null;return a!==null?s.some(c=>c.endsWith(a)):s.some(c=>c.includes(r.replace(/\*/g,"")))}))).map(o=>o.text),at=async e=>(await rt(e)).map(s=>s.text),H=[A,C,$,D,F,U,W,j],_={hasAskUserTool:!0,optionPresentation:"tool",hasSubAgentDelegation:!0,subAgentMethod:"task"},yt=e=>{let t=e[0];return t===void 0?_:H.find(o=>o.id===t)?.capabilities.interaction??_},gt=async(e,t,s)=>{let o=await at(e),i=[],r={allowGit:s?.allowGit??!1},a=s?.command??"npx eser@latest noskills";b(a);for(let c of t){let l=H.find(d=>d.id===c);if(l===void 0)continue;let u={root:e,rules:o,commandPrefix:a};if(await l.syncRules(u,r),l.capabilities.hooks&&l.syncHooks!==void 0&&await l.syncHooks(u,r),l.capabilities.agents&&l.syncAgents!==void 0&&await l.syncAgents(u,r),l.capabilities.specs&&l.syncSpecs!==void 0){let d=`${e}/${y.specsDir}`;try{for await(let p of n.fs.readDir(d))if(p.isDirectory){let L=`${d}/${p.name}/spec.md`;await l.syncSpecs(u,L)}}catch{}}l.capabilities.mcp&&l.syncMcp!==void 0&&await l.syncMcp(u),i.push(c)}return t.includes("claude-code")&&i.push("hooks"),i};export{rt as a,ft as b,at as c,yt as d,gt as e};
110
+ `)){let l=a.indexOf(":");if(l===-1)continue;let c=a.slice(0,l).trim(),u=a.slice(l+1).trim();if(u.startsWith("[")&&u.endsWith("]")){let d=u.slice(1,-1).split(",").map(p=>p.trim().replace(/^["']|["']$/g,"")).filter(p=>p.length>0);r[c]=d}else r[c]=u.replace(/^["']|["']$/g,"")}return{meta:r,body:i}},rt=async e=>{let t=`${e}/${y.rulesDir}`,s=[];try{for await(let o of n.fs.readDir(t))if(o.isFile&&(o.name.endsWith(".md")||o.name.endsWith(".txt"))){let i=await n.fs.readTextFile(`${t}/${o.name}`),{meta:r,body:a}=it(i),l=a.split(`
111
+ `)[0]??a;s.push({text:l,phases:Array.isArray(r.phases)?r.phases:void 0,appliesTo:Array.isArray(r.applies_to)?r.applies_to:void 0})}}catch{}return s};var at=async e=>(await rt(e)).map(s=>s.text),yt=(e,t)=>{let s=[],o=0;for(let i of e)i.phases!==void 0&&i.phases.length>0&&!i.phases.includes(t)||(i.appliesTo!==void 0&&i.appliesTo.length>0?o++:s.push(i.text));return{tier1:s,tier2Count:o}},ct=(e,t)=>{let s=t.startsWith("*.")?t.slice(1):null;return s!==null?e.endsWith(s):e.includes(t.replace(/\*/g,""))},gt=(e,t,s)=>e.filter(o=>o.phases!==void 0&&o.phases.length>0&&!o.phases.includes(t)||o.appliesTo===void 0||o.appliesTo.length===0?!1:o.appliesTo.some(i=>ct(s,i))).map(o=>o.text),H=[A,C,$,D,F,_,U,j],W={hasAskUserTool:!0,optionPresentation:"tool",hasSubAgentDelegation:!0,subAgentMethod:"task"},kt=e=>{let t=e[0];return t===void 0?W:H.find(o=>o.id===t)?.capabilities.interaction??W},wt=async(e,t,s)=>{let o=await at(e),i=[],r={allowGit:s?.allowGit??!1},a=s?.command??"npx eser@latest noskills";b(a);for(let l of t){let c=H.find(d=>d.id===l);if(c===void 0)continue;let u={root:e,rules:o,commandPrefix:a};if(await c.syncRules(u,r),c.capabilities.hooks&&c.syncHooks!==void 0&&await c.syncHooks(u,r),c.capabilities.agents&&c.syncAgents!==void 0&&await c.syncAgents(u,r),c.capabilities.specs&&c.syncSpecs!==void 0){let d=`${e}/${y.specsDir}`;try{for await(let p of n.fs.readDir(d))if(p.isDirectory){let L=`${d}/${p.name}/spec.md`;await c.syncSpecs(u,L)}}catch{}}c.capabilities.mcp&&c.syncMcp!==void 0&&await c.syncMcp(u),i.push(l)}return t.includes("claude-code")&&i.push("hooks"),i};export{rt as a,at as b,yt as c,gt as d,kt as e,wt as f};
@@ -0,0 +1,3 @@
1
+ import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
+ import{i as c}from"./chunk-6DBKPC2O.js";var p=r=>r.split(`
3
+ `).map(e=>e.replace(/^[-*]\s+/,"").trim()).filter(e=>e.length>0&&!e.startsWith("#")),g=async(r,e)=>{let l=[],t=(e.startsWith(r)?e.slice(r.length+1):e).split("/");t.pop();for(let s=t.length;s>=0;s--){let n=`${s===0?r:`${r}/${t.slice(0,s).join("/")}`}/.folder-rules.md`,a=s===0?".":t.slice(0,s).join("/");try{let d=await c.fs.readTextFile(n),u=p(d);for(let f of u)l.push({folder:a,rule:f})}catch{}}return l},F=async(r,e)=>{let l=new Set,i=[];for(let t of e){let s=await g(r,t);for(let o of s){let n=`${o.folder}::${o.rule}`;l.has(n)||(l.add(n),i.push(o))}}return i};export{F as a};
@@ -0,0 +1,2 @@
1
+ import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
+ import{c as s}from"./chunk-IUORSUN6.js";var o=[{id:"status_quo",text:"What does the user do today without this feature?",concerns:["product:status_quo","eng:replace_scope","qa:regression_risk"]},{id:"ambition",text:"Describe the 1-star and 10-star versions.",concerns:["product:scope_direction","eng:complexity_tier","qa:test_depth"]},{id:"reversibility",text:"Does this change involve an irreversible decision?",concerns:["product:one_way_door","eng:migration_strategy","qa:verification_stringency"]},{id:"user_impact",text:"Does this change affect existing users' behavior?",concerns:["product:breaking_change","eng:backward_compat","qa:regression_tests"]},{id:"verification",text:"How do you verify this works correctly?",concerns:["product:success_metric","eng:test_strategy","qa:acceptance_criteria"]},{id:"scope_boundary",text:"What should this feature NOT do?",concerns:["product:focus","eng:out_of_scope","qa:negative_tests"]}],a=[{questionId:"verification",text:"What tests should be written? (unit, integration, e2e \u2014 be specific about what behavior to test)"},{questionId:"verification",text:"What documentation needs updating? (README, API docs, CHANGELOG, inline comments)"}],d=n=>o.map(e=>{let t=a.filter(i=>i.questionId===e.id),r=s(n,e.id);return{...e,extras:[...t,...r]}});var u=n=>{let e=new Set(n.map(t=>t.questionId));return o.every(t=>e.has(t.id))};export{o as a,d as b,u as c};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as i}from"./chunk-MGNBNMJZ.js";import{j as a}from"./chunk-6DBKPC2O.js";var s=i({name:"validate-symlinks",description:"Detect broken symlinks",canFix:!1,stacks:[],defaults:{},async checkAll(n){let o=[];for(let t of n)if(t.isSymlink)try{await a.runtime.fs.stat(t.path)}catch{o.push({path:t.path,message:"broken symlink \u2014 target not found"})}return o}}),l=s.run,c=s.validator,m=s.main;export{s as a,l as b,c,m as d};
2
+ import{a as i}from"./chunk-VJSHVZ7R.js";import{j as a}from"./chunk-6DBKPC2O.js";var s=i({name:"validate-symlinks",description:"Detect broken symlinks",canFix:!1,stacks:[],defaults:{},async checkAll(n){let o=[];for(let t of n)if(t.isSymlink)try{await a.runtime.fs.stat(t.path)}catch{o.push({path:t.path,message:"broken symlink \u2014 target not found"})}return o}}),l=s.run,c=s.validator,m=s.main;export{s as a,l as b,c,m as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as C,c as E}from"./chunk-VXVW4UNH.js";import{a as k}from"./chunk-LFNUSULJ.js";import{b as x}from"./chunk-JTSRGXS4.js";import{f as h}from"./chunk-P2MUEKFT.js";import{b as i,f as d,g as f,h as u,i as g}from"./chunk-YVN2NZL4.js";import{g as n}from"./chunk-FFWPJP7A.js";import{j as c}from"./chunk-6DBKPC2O.js";var l=x(),b=t=>{let e=new Set,r=/export\s+\*\s+from\s+["']([^"']+)["']/g,a=/export\s+\{[^}]*\}\s+from\s+["']([^"']+)["']/g,o=/export\s+type\s+\{[^}]*\}\s+from\s+["']([^"']+)["']/g;for(let s of t.matchAll(r))s[1]!==void 0&&e.add(s[1]);for(let s of t.matchAll(a))s[1]!==void 0&&e.add(s[1]);for(let s of t.matchAll(o))s[1]!==void 0&&e.add(s[1]);return e},y=t=>{let e=t.startsWith("./")?t.slice(2):t;return e.endsWith(".ts")&&(e=e.slice(0,-3)),e},O=t=>!(t==="mod.ts"||t.endsWith("_test.ts")||t.endsWith("_bench.ts")||t.startsWith("_")||t.includes("/")),P=async(t={})=>{let{root:e=".",failFast:r=!1}=t,a=await C(e),o=[];for(let s of a){let v=c.runtime.path.join(s.path,"mod.ts"),m;try{m=await c.runtime.fs.readTextFile(v)}catch{continue}let M=b(m),w=new Set([...M].map(p=>y(p))),A=await E(s.path);for(let p of A){let R=c.runtime.path.basename(p);if(!O(R))continue;let F=y(p);if(!w.has(F)&&(o.push({packageName:s.name,file:p}),r))return{isComplete:!1,missingExports:o,packagesChecked:a.length}}}return{isComplete:o.length===0,missingExports:o,packagesChecked:a.length}},W=t=>h.fromPromise(()=>P(t)),_=t=>n.ok({root:"."}),z=t=>{if(n.isFail(t))return l.writeln(d("\u2717"),i(" "+String(t.error))),n.fail({exitCode:1});let{value:e}=t;if(l.writeln(g("\u2139"),i(` Checked ${e.packagesChecked} packages.`)),!e.isComplete){l.writeln(d("\u2717"),i(` Found ${e.missingExports.length} missing exports:`));for(let r of e.missingExports)l.writeln(u("\u26A0"),i(` ${r.packageName}: ${r.file}`));return n.fail({exitCode:1})}return l.writeln(f("\u2713"),i(" All mod.ts exports are complete.")),n.ok(void 0)},S=k.createTrigger({handler:W,adaptInput:_,adaptOutput:z}),N=async t=>await S({command:"validate-mod-exports",args:[],flags:{}});export{P as a,W as b,S as c,N as d};
2
+ import{a as C,c as E}from"./chunk-VXVW4UNH.js";import{a as k}from"./chunk-LFNUSULJ.js";import{b as x}from"./chunk-PZUDTTK4.js";import{f as h}from"./chunk-P2MUEKFT.js";import{b as i,f as d,g as f,h as u,i as g}from"./chunk-YVN2NZL4.js";import{g as n}from"./chunk-FFWPJP7A.js";import{j as c}from"./chunk-6DBKPC2O.js";var l=x(),b=t=>{let e=new Set,r=/export\s+\*\s+from\s+["']([^"']+)["']/g,a=/export\s+\{[^}]*\}\s+from\s+["']([^"']+)["']/g,o=/export\s+type\s+\{[^}]*\}\s+from\s+["']([^"']+)["']/g;for(let s of t.matchAll(r))s[1]!==void 0&&e.add(s[1]);for(let s of t.matchAll(a))s[1]!==void 0&&e.add(s[1]);for(let s of t.matchAll(o))s[1]!==void 0&&e.add(s[1]);return e},y=t=>{let e=t.startsWith("./")?t.slice(2):t;return e.endsWith(".ts")&&(e=e.slice(0,-3)),e},O=t=>!(t==="mod.ts"||t.endsWith("_test.ts")||t.endsWith("_bench.ts")||t.startsWith("_")||t.includes("/")),P=async(t={})=>{let{root:e=".",failFast:r=!1}=t,a=await C(e),o=[];for(let s of a){let v=c.runtime.path.join(s.path,"mod.ts"),m;try{m=await c.runtime.fs.readTextFile(v)}catch{continue}let M=b(m),w=new Set([...M].map(p=>y(p))),A=await E(s.path);for(let p of A){let R=c.runtime.path.basename(p);if(!O(R))continue;let F=y(p);if(!w.has(F)&&(o.push({packageName:s.name,file:p}),r))return{isComplete:!1,missingExports:o,packagesChecked:a.length}}}return{isComplete:o.length===0,missingExports:o,packagesChecked:a.length}},W=t=>h.fromPromise(()=>P(t)),_=t=>n.ok({root:"."}),z=t=>{if(n.isFail(t))return l.writeln(d("\u2717"),i(" "+String(t.error))),n.fail({exitCode:1});let{value:e}=t;if(l.writeln(g("\u2139"),i(` Checked ${e.packagesChecked} packages.`)),!e.isComplete){l.writeln(d("\u2717"),i(` Found ${e.missingExports.length} missing exports:`));for(let r of e.missingExports)l.writeln(u("\u26A0"),i(` ${r.packageName}: ${r.file}`));return n.fail({exitCode:1})}return l.writeln(f("\u2713"),i(" All mod.ts exports are complete.")),n.ok(void 0)},S=k.createTrigger({handler:W,adaptInput:_,adaptOutput:z}),N=async t=>await S({command:"validate-mod-exports",args:[],flags:{}});export{P as a,W as b,S as c,N as d};
@@ -1,4 +1,4 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{b as y}from"./chunk-IZUADMIU.js";import{c as d}from"./chunk-KNIM3QST.js";import{i as h}from"./chunk-6DBKPC2O.js";var S=p=>{let n=p.split(/\n/).flatMap(t=>t.trim().length>0?[t.trim()]:[]);return n.length>1?n:p.split(/\.(?=\s+[A-Z])|;\s+/).map(t=>t.trim()).filter(t=>t.length>5)},A=(p,n=[])=>{let t=[],c=p.find(r=>r.questionId==="ambition");if(c!==void 0){let r=c.answer,a=r.match(/10[- ]?star[:\s]+(.+?)(?:\n|$)/is),l=r.match(/5[- ]?star[:\s]+(.+?)(?:\n|$)/is),o=(a!==null?a[1].trim():l!==null?l[1].trim():r.replace(/1[- ]?star[:\s]+[^.]*\.\s*/i,"").trim()).replace(/^(the|a|an|with|plus|also)\s+/i,"").replace(/^(the\s+)?(target|goal|objective)[:\s]+/i,"").trim();o.length>0&&(o=o.charAt(0).toUpperCase()+o.slice(1)),o=o.replace(/[.\u2026]+$/,"").trim(),o.length>140&&(o=o.slice(0,137)+"..."),o.length>3&&t.push(o)}let i=p.find(r=>r.questionId==="verification");if(i!==void 0){let r=i.answer.split(/\n/).map(a=>a.replace(/^\s*[-\u2022*]\s*/,"").trim()).filter(a=>a.length>0);for(let a of r)t.push(a)}for(let r of n){let a=r.choice.toLowerCase();if(a.includes("accepted")||a.includes("add to scope")){let l=r.question.replace(/^should\s+(we|i)\s+/i,"").replace(/\?+$/,"").trim(),e=l.charAt(0).toUpperCase()+l.slice(1);t.push(e)}}return t.length===0&&t.push("_Tasks need to be defined before execution. Add tasks manually or run discovery with more detail._"),t.push("Write or update tests for all new and changed behavior"),t.push("Update documentation for all public-facing changes (README, API docs, CHANGELOG)"),t},C=(p,n)=>{let t={};if(n===null){for(let c of p.specSections)t[c]=!1;return t}for(let c of p.specSections){let i=c.toLowerCase();i.includes("design")||i.includes("mobile")||i.includes("layout")||i.includes("interaction")?t[c]=n.involvesWebUI:i.includes("contributor")||i.includes("public api")||i.includes("api surface")?t[c]=n.involvesPublicAPI:i.includes("migration")||i.includes("deprecation")||i.includes("backward")||i.includes("compatibility")?t[c]=n.involvesMigration:i.includes("audit")||i.includes("access control")||i.includes("data handling")?t[c]=n.involvesDataHandling:t[c]=!0}return t},b=(p,n,t,c,i,r,a,l)=>{let e=[];e.push(`# Spec: ${p}`),e.push(""),e.push("## Status: draft"),e.push(""),t.length>0&&(e.push(`## Concerns: ${t.map(s=>s.id).join(", ")}`),e.push("")),e.push("## Discovery Answers"),e.push("");for(let s of n){if(e.push(`### ${s.questionId}`),e.push(""),e.push(s.answer),"user"in s&&s.user!=="Unknown User"){let u=s;e.push(""),e.push(`_-- ${u.user}_`)}e.push("")}for(let s of t)if(s.specSections.length>0){let u=C(s,i??null);for(let w of s.specSections)u[w]!==!1&&(e.push(`## ${w} (${s.id})`),e.push(""),e.push("_To be addressed during execution._"),e.push(""))}if(c.length>0){e.push("## Decisions"),e.push(""),e.push("| # | Decision | Choice | Promoted |"),e.push("|---|----------|--------|----------|");for(let s=0;s<c.length;s++){let u=c[s];e.push(`| ${s+1} | ${u.question} | ${u.choice} | ${u.promoted?"yes":"no"} |`)}e.push("")}let o=n.find(s=>s.questionId==="scope_boundary");if(o!==void 0){e.push("## Out of Scope"),e.push("");let s=S(o.answer);for(let u of s)e.push(`- ${u}`);e.push("")}let f=A(n,c);e.push("## Tasks"),e.push("");for(let s=0;s<f.length;s++)e.push(`- [ ] task-${s+1}: ${f[s]}`);e.push("");let m=n.find(s=>s.questionId==="verification");if(e.push("## Verification"),e.push(""),m!==void 0){let s=S(m.answer);for(let u of s)e.push(`- ${u}`)}else e.push("_To be defined._");e.push("");let g=r??[];if(g.length>0){e.push("## Custom Acceptance Criteria"),e.push("");for(let s of g)e.push(`- ${s.text} _-- ${s.user}, ${s.addedInPhase}_`);e.push("")}let $=(a??[]).filter(s=>!s.text.startsWith("[TASK] "));if($.length>0){e.push("## Notes"),e.push("");for(let s of $)e.push(`- ${s.text} _-- ${s.user}, ${s.phase}_`);e.push("")}let v=l??[];if(v.length>0){e.push("## Transition History"),e.push(""),e.push("| From | To | User | Timestamp | Reason |"),e.push("|------|----|------|-----------|--------|");for(let s of v)e.push(`| ${s.from} | ${s.to} | ${s.user} | ${s.timestamp} | ${s.reason??"-"} |`);e.push("")}return e.join(`
2
+ import{b as y}from"./chunk-ODBJ5KMQ.js";import{c as d}from"./chunk-RUTM4VP7.js";import{i as h}from"./chunk-6DBKPC2O.js";var S=p=>{let n=p.split(/\n/).flatMap(t=>t.trim().length>0?[t.trim()]:[]);return n.length>1?n:p.split(/\.(?=\s+[A-Z])|;\s+/).map(t=>t.trim()).filter(t=>t.length>5)},A=(p,n=[])=>{let t=[],c=p.find(r=>r.questionId==="ambition");if(c!==void 0){let r=c.answer,a=r.match(/10[- ]?star[:\s]+(.+?)(?:\n|$)/is),l=r.match(/5[- ]?star[:\s]+(.+?)(?:\n|$)/is),o=(a!==null?a[1].trim():l!==null?l[1].trim():r.replace(/1[- ]?star[:\s]+[^.]*\.\s*/i,"").trim()).replace(/^(the|a|an|with|plus|also)\s+/i,"").replace(/^(the\s+)?(target|goal|objective)[:\s]+/i,"").trim();o.length>0&&(o=o.charAt(0).toUpperCase()+o.slice(1)),o=o.replace(/[.\u2026]+$/,"").trim(),o.length>140&&(o=o.slice(0,137)+"..."),o.length>3&&t.push(o)}let i=p.find(r=>r.questionId==="verification");if(i!==void 0){let r=i.answer.split(/\n/).map(a=>a.replace(/^\s*[-\u2022*]\s*/,"").trim()).filter(a=>a.length>0);for(let a of r)t.push(a)}for(let r of n){let a=r.choice.toLowerCase();if(a.includes("accepted")||a.includes("add to scope")){let l=r.question.replace(/^should\s+(we|i)\s+/i,"").replace(/\?+$/,"").trim(),e=l.charAt(0).toUpperCase()+l.slice(1);t.push(e)}}return t.length===0&&t.push("_Tasks need to be defined before execution. Add tasks manually or run discovery with more detail._"),t.push("Write or update tests for all new and changed behavior"),t.push("Update documentation for all public-facing changes (README, API docs, CHANGELOG)"),t},C=(p,n)=>{let t={};if(n===null){for(let c of p.specSections)t[c]=!1;return t}for(let c of p.specSections){let i=c.toLowerCase();i.includes("design")||i.includes("mobile")||i.includes("layout")||i.includes("interaction")?t[c]=n.involvesWebUI:i.includes("contributor")||i.includes("public api")||i.includes("api surface")?t[c]=n.involvesPublicAPI:i.includes("migration")||i.includes("deprecation")||i.includes("backward")||i.includes("compatibility")?t[c]=n.involvesMigration:i.includes("audit")||i.includes("access control")||i.includes("data handling")?t[c]=n.involvesDataHandling:t[c]=!0}return t},b=(p,n,t,c,i,r,a,l)=>{let e=[];e.push(`# Spec: ${p}`),e.push(""),e.push("## Status: draft"),e.push(""),t.length>0&&(e.push(`## Concerns: ${t.map(s=>s.id).join(", ")}`),e.push("")),e.push("## Discovery Answers"),e.push("");for(let s of n){if(e.push(`### ${s.questionId}`),e.push(""),e.push(s.answer),"user"in s&&s.user!=="Unknown User"){let u=s;e.push(""),e.push(`_-- ${u.user}_`)}e.push("")}for(let s of t)if(s.specSections.length>0){let u=C(s,i??null);for(let w of s.specSections)u[w]!==!1&&(e.push(`## ${w} (${s.id})`),e.push(""),e.push("_To be addressed during execution._"),e.push(""))}if(c.length>0){e.push("## Decisions"),e.push(""),e.push("| # | Decision | Choice | Promoted |"),e.push("|---|----------|--------|----------|");for(let s=0;s<c.length;s++){let u=c[s];e.push(`| ${s+1} | ${u.question} | ${u.choice} | ${u.promoted?"yes":"no"} |`)}e.push("")}let o=n.find(s=>s.questionId==="scope_boundary");if(o!==void 0){e.push("## Out of Scope"),e.push("");let s=S(o.answer);for(let u of s)e.push(`- ${u}`);e.push("")}let f=A(n,c);e.push("## Tasks"),e.push("");for(let s=0;s<f.length;s++)e.push(`- [ ] task-${s+1}: ${f[s]}`);e.push("");let m=n.find(s=>s.questionId==="verification");if(e.push("## Verification"),e.push(""),m!==void 0){let s=S(m.answer);for(let u of s)e.push(`- ${u}`)}else e.push("_To be defined._");e.push("");let g=r??[];if(g.length>0){e.push("## Custom Acceptance Criteria"),e.push("");for(let s of g)e.push(`- ${s.text} _-- ${s.user}, ${s.addedInPhase}_`);e.push("")}let $=(a??[]).filter(s=>!s.text.startsWith("[TASK] "));if($.length>0){e.push("## Notes"),e.push("");for(let s of $)e.push(`- ${s.text} _-- ${s.user}, ${s.phase}_`);e.push("")}let v=l??[];if(v.length>0){e.push("## Transition History"),e.push(""),e.push("| From | To | User | Timestamp | Reason |"),e.push("|------|----|------|-----------|--------|");for(let s of v)e.push(`| ${s.from} | ${s.to} | ${s.user} | ${s.timestamp} | ${s.reason??"-"} |`);e.push("")}return e.join(`
3
3
  `)};var _=async(p,n,t)=>{if(n.spec===null)throw new Error("No active spec");let c=`${p}/${d.specDir(n.spec)}`,i=`${p}/${d.specFile(n.spec)}`;await h.fs.mkdir(c,{recursive:!0});let r=b(n.spec,n.discovery.answers,t,n.decisions,n.classification,n.customACs,n.specNotes,n.transitionHistory);await h.fs.writeTextFile(i,r);let a=y(n.spec,r),l=`${c}/progress.json`,e={spec:n.spec,status:"draft",tasks:a.tasks.map(o=>({id:o.id,title:o.title,status:"pending"})),decisions:n.decisions.map(o=>({question:o.question,choice:o.choice,promoted:o.promoted})),debt:[],updatedAt:new Date().toISOString()};return await h.fs.writeTextFile(l,JSON.stringify(e,null,2)+`
4
4
  `),i};export{_ as a};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as o}from"./chunk-MGNBNMJZ.js";import{a as l}from"./chunk-2XNFZXHY.js";import{e as n}from"./chunk-5WJ6AUNY.js";var i=n(l(),1);var a=o({name:"validate-yaml",description:"Validate YAML syntax",canFix:!1,stacks:[],defaults:{},extensions:["yml","yaml"],checkFile(e,r){if(r===void 0)return[];try{return i.parse(r),[]}catch(t){let s=t instanceof Error?t.message:"invalid YAML";return[{path:e.path,message:s}]}}}),d=a.run,u=a.validator,f=a.main;export{a,d as b,u as c,f as d};
2
+ import{a as o}from"./chunk-VJSHVZ7R.js";import{a as l}from"./chunk-2XNFZXHY.js";import{e as n}from"./chunk-5WJ6AUNY.js";var i=n(l(),1);var a=o({name:"validate-yaml",description:"Validate YAML syntax",canFix:!1,stacks:[],defaults:{},extensions:["yml","yaml"],checkFile(e,r){if(r===void 0)return[];try{return i.parse(r),[]}catch(t){let s=t instanceof Error?t.message:"invalid YAML";return[{path:e.path,message:s}]}}}),d=a.run,u=a.validator,f=a.main;export{a,d as b,u as c,f as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as r}from"./chunk-MGNBNMJZ.js";var a="\uFEFF",i=r({name:"validate-bom",description:"Remove UTF-8 byte order markers",canFix:!0,stacks:[],defaults:{},checkFile(e,t){return t===void 0?[]:t.startsWith(a)?[{path:e.path,message:"file has UTF-8 BOM"}]:[]},fixFile(e,t){if(!t.startsWith(a))return;let o=t.slice(1);return{path:e.path,oldContent:t,newContent:o}}}),u=i.run,d=i.validator,m=i.main;export{i as a,u as b,d as c,m as d};
2
+ import{a as r}from"./chunk-VJSHVZ7R.js";var a="\uFEFF",i=r({name:"validate-bom",description:"Remove UTF-8 byte order markers",canFix:!0,stacks:[],defaults:{},checkFile(e,t){return t===void 0?[]:t.startsWith(a)?[{path:e.path,message:"file has UTF-8 BOM"}]:[]},fixFile(e,t){if(!t.startsWith(a))return;let o=t.slice(1);return{path:e.path,oldContent:t,newContent:o}}}),u=i.run,d=i.validator,m=i.main;export{i as a,u as b,d as c,m as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as r}from"./chunk-P7WCO724.js";import{a as i}from"./chunk-MGNBNMJZ.js";var t=i({name:"validate-toml",description:"Validate TOML syntax",canFix:!1,stacks:[],defaults:{},extensions:["toml"],checkFile(e,o){if(o===void 0)return[];try{return r(o),[]}catch(a){let s=a instanceof Error?a.message:"invalid TOML";return[{path:e.path,message:s}]}}}),p=t.run,d=t.validator,u=t.main;export{t as a,p as b,d as c,u as d};
2
+ import{a as r}from"./chunk-P7WCO724.js";import{a as i}from"./chunk-VJSHVZ7R.js";var t=i({name:"validate-toml",description:"Validate TOML syntax",canFix:!1,stacks:[],defaults:{},extensions:["toml"],checkFile(e,o){if(o===void 0)return[];try{return r(o),[]}catch(a){let s=a instanceof Error?a.message:"invalid TOML";return[{path:e.path,message:s}]}}}),p=t.run,d=t.validator,u=t.main;export{t as a,p as b,d as c,u as d};
@@ -1,4 +1,4 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as t}from"./chunk-MGNBNMJZ.js";var n=t({name:"validate-line-endings",description:"Normalize line endings to LF",canFix:!0,stacks:[],defaults:{},checkFile(i,e){return e===void 0?[]:e.includes("\r")?[{path:i.path,message:"file contains CRLF or CR line endings"}]:[]},fixFile(i,e){let r=e.replace(/\r\n/g,`
2
+ import{a as t}from"./chunk-VJSHVZ7R.js";var n=t({name:"validate-line-endings",description:"Normalize line endings to LF",canFix:!0,stacks:[],defaults:{},checkFile(i,e){return e===void 0?[]:e.includes("\r")?[{path:i.path,message:"file contains CRLF or CR line endings"}]:[]},fixFile(i,e){let r=e.replace(/\r\n/g,`
3
3
  `).replace(/\r/g,`
4
4
  `);if(r!==e)return{path:i.path,oldContent:e,newContent:r}}}),s=n.run,d=n.validator,p=n.main;export{n as a,s as b,d as c,p as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- var r={name:"@eser/cli",version:"4.1.50",type:"module",exports:"./main.ts",bin:{eser:"./bin.ts"},dependencies:{"@eser/ai":"workspace:*","@eser/codebase":"workspace:*","@eser/kit":"workspace:*","@eser/noskills":"workspace:*","@eser/laroux-server":"workspace:*","@eser/workflows":"workspace:*","@eser/functions":"workspace:*","@eser/logging":"workspace:*","@eser/shell":"workspace:*","@eser/standards":"workspace:*","@std/cli":"npm:@jsr/std__cli@^1.0.25","@std/fmt":"npm:@jsr/std__fmt@^1.0.8"},devDependencies:{"@std/assert":"npm:@jsr/std__assert@^1.0.16",esbuild:"^0.27.3"},optionalDependencies:{"@eserstack/ajan-darwin-arm64":"^4.1.47","@eserstack/ajan-darwin-x64":"^4.1.47","@eserstack/ajan-linux-arm64":"^4.1.47","@eserstack/ajan-linux-x64":"^4.1.47","@eserstack/ajan-win32-x64":"^4.1.47","@eserstack/ajan-wasm":"^4.1.47"}};export{r as a};
2
+ var r={name:"@eser/cli",version:"4.1.53",type:"module",exports:"./main.ts",bin:{eser:"./bin.ts"},dependencies:{"@eser/ai":"workspace:*","@eser/codebase":"workspace:*","@eser/kit":"workspace:*","@eser/noskills":"workspace:*","@eser/laroux-server":"workspace:*","@eser/workflows":"workspace:*","@eser/functions":"workspace:*","@eser/logging":"workspace:*","@eser/shell":"workspace:*","@eser/standards":"workspace:*","@std/cli":"npm:@jsr/std__cli@^1.0.25","@std/fmt":"npm:@jsr/std__fmt@^1.0.8"},devDependencies:{"@std/assert":"npm:@jsr/std__assert@^1.0.16",esbuild:"^0.27.3"},optionalDependencies:{"@eserstack/ajan-darwin-arm64":"^4.1.47","@eserstack/ajan-darwin-x64":"^4.1.47","@eserstack/ajan-linux-arm64":"^4.1.47","@eserstack/ajan-linux-x64":"^4.1.47","@eserstack/ajan-win32-x64":"^4.1.47","@eserstack/ajan-wasm":"^4.1.47"}};export{r as a};
@@ -1,4 +1,4 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as E,b as A,c as I}from"./chunk-VXVW4UNH.js";import{a as w}from"./chunk-LFNUSULJ.js";import{b as v}from"./chunk-JTSRGXS4.js";import{f as D}from"./chunk-P2MUEKFT.js";import{b as l,f as g,g as k,h as C,i as h}from"./chunk-YVN2NZL4.js";import{g as a}from"./chunk-FFWPJP7A.js";import{j as b}from"./chunk-6DBKPC2O.js";var u=v(),O=/\/\*\*\s*([\s\S]*?)\s*\*\//g,R=/export\s+(const|function|class|type|interface)\s+(\w+)/g,$=/@example/,S=s=>{let n=[],i;for(R.lastIndex=0;(i=R.exec(s))!==null;){let e=i.index,t=i[2];if(t===void 0)continue;let c=s.substring(0,e).split(`
2
+ import{a as E,b as A,c as I}from"./chunk-VXVW4UNH.js";import{a as w}from"./chunk-LFNUSULJ.js";import{b as v}from"./chunk-PZUDTTK4.js";import{f as D}from"./chunk-P2MUEKFT.js";import{b as l,f as g,g as k,h as C,i as h}from"./chunk-YVN2NZL4.js";import{g as a}from"./chunk-FFWPJP7A.js";import{j as b}from"./chunk-6DBKPC2O.js";var u=v(),O=/\/\*\*\s*([\s\S]*?)\s*\*\//g,R=/export\s+(const|function|class|type|interface)\s+(\w+)/g,$=/@example/,S=s=>{let n=[],i;for(R.lastIndex=0;(i=R.exec(s))!==null;){let e=i.index,t=i[2];if(t===void 0)continue;let c=s.substring(0,e).split(`
3
3
  `).length,p=null,m=[...s.substring(0,e).matchAll(O)];if(m.length>0){let r=m[m.length-1];if(r!==void 0){let d=(r.index??0)+r[0].length,f=s.substring(d,e);/^\s*$/.test(f)&&(p=r[1]??null)}}n.push({jsdoc:p,symbolName:t,line:c})}return n},_=(s,n,i)=>{let e=[];if(s===null)return e.push("missing-description"),e;let t=s.split(`
4
4
  `)[0]?.trim();return(!t||t.startsWith("@"))&&e.push("empty-description"),i&&!$.test(s)&&e.push("missing-example"),e},F=async(s={})=>{let{root:n=".",requireExamples:i=!1}=s,e=await E(n),t=[],o=0,c=0;for(let p of e){let y=await I(p.path);for(let m of y){let r=A(m,p.path),d;try{d=await b.runtime.fs.readTextFile(r)}catch{continue}o++;let f=S(d);for(let{jsdoc:T,symbolName:x,line:P}of f){c++;let M=_(T,x,i);for(let N of M)t.push({file:r,symbol:x,issue:N,line:P})}}}return{isValid:t.length===0,issues:t,filesChecked:o,symbolsChecked:c}},J=s=>{switch(s){case"missing-description":return"Missing JSDoc documentation";case"missing-param":return"Missing @param documentation";case"missing-returns":return"Missing @returns documentation";case"missing-example":return"Missing @example";case"empty-description":return"Empty description"}},j=s=>D.fromPromise(()=>F(s)),V=s=>a.ok({root:"."}),q=s=>{if(a.isFail(s))return u.writeln(g("\u2717"),l(" "+String(s.error))),a.fail({exitCode:1});let{value:n}=s;if(u.writeln(h("\u2139"),l(` Checked ${n.filesChecked} files, ${n.symbolsChecked} symbols.`)),!n.isValid){u.writeln(g("\u2717"),l(` Found ${n.issues.length} documentation issues:`));let i=new Map;for(let e of n.issues){let t=i.get(e.file)??[];t.push(e),i.set(e.file,t)}for(let[e,t]of i){u.writeln(C("\u26A0"),l(" "+e));for(let o of t){let c=o.line!==void 0?`:${o.line}`:"";u.writeln(h("\u2139"),l(` ${o.symbol}${c}: ${J(o.issue)}`))}}return a.fail({exitCode:1})}return u.writeln(k("\u2713"),l(" All documentation is valid.")),a.ok(void 0)},B=w.createTrigger({handler:j,adaptInput:V,adaptOutput:q}),Q=async s=>await B({command:"validate-docs",args:[],flags:{}});export{F as a,j as b,B as c,Q as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as i}from"./chunk-MGNBNMJZ.js";import{i as t}from"./chunk-6DBKPC2O.js";var s=i({name:"validate-submodules",description:"Detect new git submodules",canFix:!1,stacks:[],defaults:{},async checkAll(n,a){let o=t.path.join(a.root,".gitmodules");if(!await t.fs.exists(o))return[];let e=((await t.fs.readTextFile(o)).match(/\[submodule\s/g)??[]).length;return e>0?[{path:o,message:`found ${e} submodule(s) \u2014 submodules are not allowed`}]:[]}}),p=s.run,f=s.validator,x=s.main;export{s as a,p as b,f as c,x as d};
2
+ import{a as i}from"./chunk-VJSHVZ7R.js";import{i as t}from"./chunk-6DBKPC2O.js";var s=i({name:"validate-submodules",description:"Detect new git submodules",canFix:!1,stacks:[],defaults:{},async checkAll(n,a){let o=t.path.join(a.root,".gitmodules");if(!await t.fs.exists(o))return[];let e=((await t.fs.readTextFile(o)).match(/\[submodule\s/g)??[]).length;return e>0?[{path:o,message:`found ${e} submodule(s) \u2014 submodules are not allowed`}]:[]}}),p=s.run,f=s.validator,x=s.main;export{s as a,p as b,f as c,x as d};
@@ -1,4 +1,4 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{b as w}from"./chunk-JTSRGXS4.js";import{b as r,f as n,g as h}from"./chunk-YVN2NZL4.js";import{a as y}from"./chunk-MG65QJY6.js";import{g as i}from"./chunk-FFWPJP7A.js";import{j as v}from"./chunk-6DBKPC2O.js";var m=w(),x=["ci","chore","docs","feat","fix","perf","refactor","revert","test"],C=/^(\w+)(?:\(([^)]+)\))?!?:\s{1,5}.+$/,M=(p,e={})=>{let o=e.allowAsterisk??!0,a=e.allowMultipleScopes??!0,c=e.forceScope??!1,f=new Set(e.types??x),s=[],l=p.split(`
2
+ import{b as w}from"./chunk-PZUDTTK4.js";import{b as r,f as n,g as h}from"./chunk-YVN2NZL4.js";import{a as y}from"./chunk-MG65QJY6.js";import{g as i}from"./chunk-FFWPJP7A.js";import{j as v}from"./chunk-6DBKPC2O.js";var m=w(),x=["ci","chore","docs","feat","fix","perf","refactor","revert","test"],C=/^(\w+)(?:\(([^)]+)\))?!?:\s{1,5}.+$/,M=(p,e={})=>{let o=e.allowAsterisk??!0,a=e.allowMultipleScopes??!0,c=e.forceScope??!1,f=new Set(e.types??x),s=[],l=p.split(`
3
3
  `)[0]?.trim()??"";if(l==="")return{valid:!1,issues:["commit message is empty"]};if(l.startsWith("Merge "))return{valid:!0,issues:[]};let d=l.match(C);if(d===null)return s.push(`invalid format: expected "type(scope): message", got: "${l}"`),{valid:!1,issues:s};let g=d[1].toLowerCase(),t=d[2];return f.has(g)||s.push(`invalid type "${g}". Must be one of: ${[...f].join(", ")}`),c&&(t===void 0||t.trim()==="")&&s.push("scope is required: use type(scope): message"),t!==void 0&&t.trim()!==""&&(t==="*"&&!o&&s.push('wildcard scope "*" is not allowed (allowAsterisk is false)'),t.includes(",")&&(a?t.split(",").map(u=>u.trim()).filter(u=>u==="").length>0&&s.push("invalid scope: each comma-separated scope must be non-empty"):s.push("multiple scopes are not allowed (allowMultipleScopes is false)"))),{valid:s.length===0,issues:s}},_=async p=>{let e=y(p??[],{string:["message"],boolean:["help"],alias:{h:"help",m:"message"}});if(e.help)return console.log(`eser codebase validate-commit-msg \u2014 Validate conventional commit format
4
4
  `),console.log("Usage:"),console.log(" eser codebase validate-commit-msg <commit-msg-file>"),console.log(" eser codebase validate-commit-msg --message 'feat(x): msg'"),i.ok(void 0);let o;if(e.message!==void 0)o=e.message;else if(e._.length>0)try{o=await v.runtime.fs.readTextFile(String(e._[0]))}catch{return m.writeln(n("\u2717"),r(` cannot read commit message file: ${e._[0]}`)),i.fail({exitCode:1})}else return m.writeln(n("\u2717"),r(" no commit message provided")),i.fail({exitCode:1});let a=M(o);if(a.valid)return m.writeln(h("\u2713"),r(" commit message is valid")),i.ok(void 0);for(let c of a.issues)m.writeln(n("\u2717"),r(" "+c));return i.fail({exitCode:1})};export{M as a,_ as b};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as l}from"./chunk-MGNBNMJZ.js";var p=new Set(["con","prn","aux","nul","com1","com2","com3","com4","com5","com6","com7","com8","com9","lpt1","lpt2","lpt3","lpt4","lpt5","lpt6","lpt7","lpt8","lpt9"]),E=/^[a-z0-9_./[\]@-]+$/,u=/^[a-z0-9./[\]@-]+$/,g=[".claude/",".github/",".git/","CLAUDE.md","AGENTS.md","CHANGELOG.md","Makefile","Dockerfile","LICENSE","README.md","VERSION"],d=(o,s)=>{for(let e of s)if(e.includes("*")){let a=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]+");if(new RegExp(a).test(o))return!0}else if(o.includes(e)||o.endsWith(e))return!0;return!1},c=l({name:"validate-filenames",description:"Enforce filename conventions (kebab-case / snake_case)",canFix:!1,stacks:[],defaults:{},checkAll(o,s){let e=[],a=s.rules,f=s.exclude??g;for(let t of o){if(d(t.path,f))continue;let i=t.name,m=i.replace(/\.[^.]+$/,"");if(p.has(m.toLowerCase())){e.push({path:t.path,message:`Windows-reserved filename: ${i}`});continue}if(a!==void 0){let r=!1;for(let n of a)if(n.directory==="*"||t.path.includes(n.directory)){if(n.exclude!==void 0&&d(t.path,n.exclude)){r=!0;break}(n.convention==="snake_case"?E:u).test(i)||e.push({path:t.path,message:`filename must be ${n.convention}`}),r=!0;break}if(r)continue}u.test(i)||e.push({path:t.path,message:"filename must be kebab-case"})}return e}}),S=c.run,k=c.validator,v=c.main;export{c as a,S as b,k as c,v as d};
2
+ import{a as l}from"./chunk-VJSHVZ7R.js";var p=new Set(["con","prn","aux","nul","com1","com2","com3","com4","com5","com6","com7","com8","com9","lpt1","lpt2","lpt3","lpt4","lpt5","lpt6","lpt7","lpt8","lpt9"]),E=/^[a-z0-9_./[\]@-]+$/,u=/^[a-z0-9./[\]@-]+$/,g=[".claude/",".github/",".git/","CLAUDE.md","AGENTS.md","CHANGELOG.md","Makefile","Dockerfile","LICENSE","README.md","VERSION"],d=(o,s)=>{for(let e of s)if(e.includes("*")){let a=e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,"[^/]+");if(new RegExp(a).test(o))return!0}else if(o.includes(e)||o.endsWith(e))return!0;return!1},c=l({name:"validate-filenames",description:"Enforce filename conventions (kebab-case / snake_case)",canFix:!1,stacks:[],defaults:{},checkAll(o,s){let e=[],a=s.rules,f=s.exclude??g;for(let t of o){if(d(t.path,f))continue;let i=t.name,m=i.replace(/\.[^.]+$/,"");if(p.has(m.toLowerCase())){e.push({path:t.path,message:`Windows-reserved filename: ${i}`});continue}if(a!==void 0){let r=!1;for(let n of a)if(n.directory==="*"||t.path.includes(n.directory)){if(n.exclude!==void 0&&d(t.path,n.exclude)){r=!0;break}(n.convention==="snake_case"?E:u).test(i)||e.push({path:t.path,message:`filename must be ${n.convention}`}),r=!0;break}if(r)continue}u.test(i)||e.push({path:t.path,message:"filename must be kebab-case"})}return e}}),S=c.run,k=c.validator,v=c.main;export{c as a,S as b,k as c,v as d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as n}from"./chunk-MGNBNMJZ.js";var e=n({name:"validate-case-conflict",description:"Detect filenames that differ only by case",canFix:!1,stacks:[],defaults:{},checkAll(r){let o=new Map,s=[];for(let t of r){let a=t.path.toLowerCase(),i=o.get(a);i!==void 0?s.push({path:t.path,message:`case conflict with "${i}"`}):o.set(a,t.path)}return s}}),f=e.run,m=e.validator,d=e.main;export{e as a,f as b,m as c,d};
2
+ import{a as n}from"./chunk-VJSHVZ7R.js";var e=n({name:"validate-case-conflict",description:"Detect filenames that differ only by case",canFix:!1,stacks:[],defaults:{},checkAll(r){let o=new Map,s=[];for(let t of r){let a=t.path.toLowerCase(),i=o.get(a);i!==void 0?s.push({path:t.path,message:`case conflict with "${i}"`}):o.set(a,t.path)}return s}}),f=e.run,m=e.validator,d=e.main;export{e as a,f as b,m as c,d};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- var s={id:"open-source",name:"Open Source",description:"Community-driven, inclusive, well-documented. Prioritize contributor experience, avoid exclusionary patterns, default to permissive choices.",extras:[{questionId:"status_quo",text:"Is this workaround common in the community?"},{questionId:"user_impact",text:"Does this make contribution harder?"}],specSections:["Contributor Guide","Public API Surface"],reminders:["Endpoint should be documented in API docs","Consider contributor experience for new patterns","Default to permissive, well-documented choices","New features and API changes must be documented so contributors can discover and use them"],acceptanceCriteria:["Public API documented","Changes reflected in README or relevant docs","No exclusionary patterns introduced"]};var r={id:"beautiful-product",name:"Beautiful Product",description:"Design and UX are first-class. Agent critiques UI/UX like a passionate designer. Empty states, error states, loading states, mobile layout \u2014 nothing ships unspecified.",extras:[{questionId:"status_quo",text:"How painful is the current experience?"},{questionId:"status_quo",text:"What does the current UI look like? Rate it 0-10 on design intentionality."},{questionId:"ambition",text:"In the 10-star version, what does the user feel?"},{questionId:"ambition",text:"What would a 10/10 design look like for this feature? Describe the emotional response you want from users."},{questionId:"ambition",text:"What makes this UI NOT look AI-generated? Name specific design decisions that differentiate it from generic templates."},{questionId:"verification",text:"How will you verify design quality? Will you review empty states, loading states, error states, and edge cases (long text, zero results, slow connection)?"}],specSections:["Design States (empty, loading, error, success)","Mobile Layout","Interaction Design"],reminders:["Loading state and error state must be designed, not placeholder","No AI slop \u2014 every UI element is intentional","Empty states need clear CTAs with examples","Rate each UI change 0-10 on design intentionality before marking task complete. If below 7, iterate.","Check all interaction states: loading, empty, error, success, partial. Missing states are bugs, not TODOs.","Edge case check: what happens with 47-character names? Zero results? Network failure mid-action?","AI SLOP BLACKLIST \u2014 reject these patterns in any UI implementation: (1) Purple/violet gradient backgrounds (2) 3-column feature grid with icon-in-circle + bold title + 2-line description (3) Icons in colored circles as decoration (4) Everything centered (text-align: center on all elements) (5) Uniform bubbly border-radius on every element (6) Decorative blobs, floating circles, wavy SVG dividers (7) Emoji as design elements in headings or bullets (8) Colored left-border on cards (9) Generic hero copy ('Welcome to X', 'Unlock the power of...') (10) Cookie-cutter section rhythm (hero \u2192 3 features \u2192 testimonials \u2192 pricing). If the implementation matches any of these patterns, reject it and ask for a redesign with specific, intentional alternatives."],acceptanceCriteria:["All UI states designed (empty, loading, error, success)","Mobile layout considered","No placeholder or skeleton UI left unfinished","All UI states specified and implemented: loading, empty, error, success, partial","No placeholder text in shipped UI \u2014 every empty state has warmth, a primary action, and context","Design rated 7+ on intentionality by the spec author"]};var a={id:"long-lived",name:"Long-Lived",description:"Built to last. Stability, maintainability, and backward compatibility matter. Every shortcut needs justification. Favor boring technology.",extras:[{questionId:"reversibility",text:"Will this decision still be correct in 2 years?"},{questionId:"verification",text:"Is documentation (README, CHANGELOG, API docs) up to date with this change?"},{questionId:"scope_boundary",text:"What technical debt would this introduce?"}],specSections:["Migration & Deprecation","Backward Compatibility"],reminders:["Favor boring technology over shiny new tools","Every shortcut needs explicit justification","Consider maintenance burden for new dependencies","If this task changes public behavior, API, CLI flags, or configuration \u2014 update README and relevant docs in the SAME task. Documentation is not a follow-up."],acceptanceCriteria:["Backward compatibility preserved","Migration path documented if breaking","No unnecessary new dependencies","Documentation updated for any public-facing change"]};var c={id:"move-fast",name:"Move Fast",description:"Optimize for shipping speed. Acceptable trade-offs on polish. Good enough is good enough. Reduce ceremony.",extras:[{questionId:"scope_boundary",text:"Which polish items can be deferred to v2?"},{questionId:"ambition",text:"What is the minimum viable 5-star version?"}],specSections:["v1 vs v2 Scope"],reminders:["Good enough is good enough \u2014 ship it","Reduce ceremony, optimize for feedback speed","Mark polish items for v2 explicitly"],acceptanceCriteria:["Core functionality works","v2 items explicitly deferred"]};var d={id:"compliance",name:"Compliance",description:"Audit trails, access controls, data handling rules. Every change is traceable. Verification is mandatory, not optional.",extras:[{questionId:"reversibility",text:"Is the audit trail preserved on rollback?"},{questionId:"verification",text:"Is there an audit/traceability requirement?"}],specSections:["Audit Trail","Access Control","Data Handling"],reminders:["Every state change must be traceable","Verification is mandatory, not optional","Document data handling and retention policies"],acceptanceCriteria:["Audit trail added for state changes","Access control verified","Data handling documented"]};var l={id:"learning-project",name:"Learning Project",description:"Experimentation is the goal. Encourage trying new patterns, don't punish dead ends. Document learnings over polish.",extras:[{questionId:"ambition",text:"What do you want to learn from building this?"},{questionId:"scope_boundary",text:"What experiments are explicitly allowed?"}],specSections:["Learning Goals","Experiment Log"],reminders:["Document learnings, not just outcomes","Dead ends are acceptable \u2014 document why","Try new patterns freely, polish later"],acceptanceCriteria:["Learnings documented","Experiment outcomes recorded"]};var u=[s,r,a,c,d,l];var N=()=>Promise.resolve(u),T=(n,t)=>{let e=[];for(let i of n)for(let o of i.extras)o.questionId===t&&e.push(o);return e},W=n=>{let t=[];for(let e of n)for(let i of e.reminders)t.push(`${e.id}: ${i}`);return t},M=n=>{let t=[],e=n.map(i=>i.id);return e.includes("move-fast")&&e.includes("compliance")&&t.push({between:["move-fast","compliance"],issue:"Speed vs traceability \u2014 shortcuts may violate audit requirements."}),e.includes("move-fast")&&e.includes("long-lived")&&t.push({between:["move-fast","long-lived"],issue:"Shipping speed vs maintainability \u2014 tech debt decisions need human approval."}),e.includes("beautiful-product")&&e.includes("move-fast")&&t.push({between:["beautiful-product","move-fast"],issue:"Design polish vs speed \u2014 which UI states can be deferred?"}),t};export{u as a,N as b,T as c,W as d,M as e};
2
+ var l={id:"open-source",name:"Open Source",description:"Community-driven, inclusive, well-documented. Prioritize contributor experience, avoid exclusionary patterns, default to permissive choices.",extras:[{questionId:"status_quo",text:"Is this workaround common in the community?"},{questionId:"user_impact",text:"Does this make contribution harder?"}],specSections:["Contributor Guide","Public API Surface"],reminders:["Endpoint should be documented in API docs","Consider contributor experience for new patterns","Default to permissive, well-documented choices","New features and API changes must be documented so contributors can discover and use them"],acceptanceCriteria:["Public API documented","Changes reflected in README or relevant docs","No exclusionary patterns introduced"]};var u={id:"beautiful-product",name:"Beautiful Product",description:"Design and UX are first-class. Agent critiques UI/UX like a passionate designer. Empty states, error states, loading states, mobile layout \u2014 nothing ships unspecified.",extras:[{questionId:"status_quo",text:"How painful is the current experience?"},{questionId:"status_quo",text:"What does the current UI look like? Rate it 0-10 on design intentionality."},{questionId:"ambition",text:"In the 10-star version, what does the user feel?"},{questionId:"ambition",text:"What would a 10/10 design look like for this feature? Describe the emotional response you want from users."},{questionId:"ambition",text:"What makes this UI NOT look AI-generated? Name specific design decisions that differentiate it from generic templates."},{questionId:"verification",text:"How will you verify design quality? Will you review empty states, loading states, error states, and edge cases (long text, zero results, slow connection)?"}],specSections:["Design States (empty, loading, error, success)","Mobile Layout","Interaction Design"],reminders:["Loading state and error state must be designed, not placeholder","No AI slop \u2014 every UI element is intentional","Empty states need clear CTAs with examples","Rate each UI change 0-10 on design intentionality before marking task complete. If below 7, iterate.","Check all interaction states: loading, empty, error, success, partial. Missing states are bugs, not TODOs.","Edge case check: what happens with 47-character names? Zero results? Network failure mid-action?","AI SLOP BLACKLIST \u2014 reject these patterns in any UI implementation: (1) Purple/violet gradient backgrounds (2) 3-column feature grid with icon-in-circle + bold title + 2-line description (3) Icons in colored circles as decoration (4) Everything centered (text-align: center on all elements) (5) Uniform bubbly border-radius on every element (6) Decorative blobs, floating circles, wavy SVG dividers (7) Emoji as design elements in headings or bullets (8) Colored left-border on cards (9) Generic hero copy ('Welcome to X', 'Unlock the power of...') (10) Cookie-cutter section rhythm (hero \u2192 3 features \u2192 testimonials \u2192 pricing). If the implementation matches any of these patterns, reject it and ask for a redesign with specific, intentional alternatives."],acceptanceCriteria:["All UI states designed (empty, loading, error, success)","Mobile layout considered","No placeholder or skeleton UI left unfinished","All UI states specified and implemented: loading, empty, error, success, partial","No placeholder text in shipped UI \u2014 every empty state has warmth, a primary action, and context","Design rated 7+ on intentionality by the spec author"]};var m={id:"long-lived",name:"Long-Lived",description:"Built to last. Stability, maintainability, and backward compatibility matter. Every shortcut needs justification. Favor boring technology.",extras:[{questionId:"reversibility",text:"Will this decision still be correct in 2 years?"},{questionId:"verification",text:"Is documentation (README, CHANGELOG, API docs) up to date with this change?"},{questionId:"scope_boundary",text:"What technical debt would this introduce?"}],specSections:["Migration & Deprecation","Backward Compatibility"],reminders:["Favor boring technology over shiny new tools","Every shortcut needs explicit justification","Consider maintenance burden for new dependencies","If this task changes public behavior, API, CLI flags, or configuration \u2014 update README and relevant docs in the SAME task. Documentation is not a follow-up."],acceptanceCriteria:["Backward compatibility preserved","Migration path documented if breaking","No unnecessary new dependencies","Documentation updated for any public-facing change"]};var p={id:"move-fast",name:"Move Fast",description:"Optimize for shipping speed. Acceptable trade-offs on polish. Good enough is good enough. Reduce ceremony.",extras:[{questionId:"scope_boundary",text:"Which polish items can be deferred to v2?"},{questionId:"ambition",text:"What is the minimum viable 5-star version?"}],specSections:["v1 vs v2 Scope"],reminders:["Good enough is good enough \u2014 ship it","Reduce ceremony, optimize for feedback speed","Mark polish items for v2 explicitly"],acceptanceCriteria:["Core functionality works","v2 items explicitly deferred"]};var h={id:"compliance",name:"Compliance",description:"Audit trails, access controls, data handling rules. Every change is traceable. Verification is mandatory, not optional.",extras:[{questionId:"reversibility",text:"Is the audit trail preserved on rollback?"},{questionId:"verification",text:"Is there an audit/traceability requirement?"}],specSections:["Audit Trail","Access Control","Data Handling"],reminders:["Every state change must be traceable","Verification is mandatory, not optional","Document data handling and retention policies"],acceptanceCriteria:["Audit trail added for state changes","Access control verified","Data handling documented"]};var f={id:"learning-project",name:"Learning Project",description:"Experimentation is the goal. Encourage trying new patterns, don't punish dead ends. Document learnings over polish.",extras:[{questionId:"ambition",text:"What do you want to learn from building this?"},{questionId:"scope_boundary",text:"What experiments are explicitly allowed?"}],specSections:["Learning Goals","Experiment Log"],reminders:["Document learnings, not just outcomes","Dead ends are acceptable \u2014 document why","Try new patterns freely, polish later"],acceptanceCriteria:["Learnings documented","Experiment outcomes recorded"]};var g=[l,u,m,p,h,f];var O=()=>Promise.resolve(g),_=(o,e)=>{let n=[];for(let i of o)for(let s of i.extras)s.questionId===e&&n.push(s);return n},$=(o,e)=>{let n=[];for(let i of o)for(let s of i.reminders){if(e!=null){let t=s.toLowerCase();if((t.includes("slop")||t.includes("ui element")||t.includes("design intentionality")||t.includes("interaction states")||t.includes("edge case check")||t.includes("loading state"))&&!e.involvesWebUI||(t.includes("api doc")||t.includes("endpoint should be"))&&!e.involvesPublicAPI)continue}n.push(`${i.id}: ${s}`)}return n},y=o=>{let e=o.toLowerCase();return e.includes("slop")||e.includes("ui element")||e.includes("design intentionality")||e.includes("interaction states")||e.includes("edge case check")||e.includes("loading state")||e.includes("api doc")||e.includes("endpoint should be")||e.includes("migration")||e.includes("rollback")},G=o=>{let e=[],n=[];for(let i of o)for(let s of i.reminders){let t=`${i.id}: ${s}`;y(s)?n.push(t):e.push(t)}return{tier1:e,tier2:n}},B=(o,e,n)=>{let i=e.includes(".")?`.${e.split(".").pop()}`:"",s=[".tsx",".jsx",".html",".css",".svelte",".vue"].includes(i),t=[".ts",".go",".py",".rs"].includes(i),c=[];for(let d of o)for(let a of d.reminders){if(!y(a))continue;let r=a.toLowerCase();(r.includes("slop")||r.includes("ui element")||r.includes("design intentionality")||r.includes("interaction states")||r.includes("edge case check")||r.includes("loading state"))&&!s||(r.includes("api doc")||r.includes("endpoint should be"))&&(!t||!n?.involvesPublicAPI)||c.push(`${d.id}: ${a}`)}return c},z=o=>{let e=[],n=o.map(i=>i.id);return n.includes("move-fast")&&n.includes("compliance")&&e.push({between:["move-fast","compliance"],issue:"Speed vs traceability \u2014 shortcuts may violate audit requirements."}),n.includes("move-fast")&&n.includes("long-lived")&&e.push({between:["move-fast","long-lived"],issue:"Shipping speed vs maintainability \u2014 tech debt decisions need human approval."}),n.includes("beautiful-product")&&n.includes("move-fast")&&e.push({between:["beautiful-product","move-fast"],issue:"Design polish vs speed \u2014 which UI states can be deferred?"}),e};export{g as a,O as b,_ as c,$ as d,G as e,B as f,z as g};
@@ -1,2 +1,2 @@
1
1
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
2
- import{a as E}from"./chunk-VXVW4UNH.js";import{a as y}from"./chunk-LFNUSULJ.js";import{b as C}from"./chunk-JTSRGXS4.js";import{f as v}from"./chunk-P2MUEKFT.js";import{b as i,f as m,g as x,h as k,i as g}from"./chunk-YVN2NZL4.js";import{g as p}from"./chunk-FFWPJP7A.js";import{j as h}from"./chunk-6DBKPC2O.js";var l=C(),d=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]+/g,"-").toLowerCase(),f=(e,o=[])=>{let s=e.split("/").filter(r=>r.length>0);for(let r of s){let t=r.startsWith(".")?r.slice(1):r;if(t.length===0)continue;let a=h.runtime.path.extname(t);if(a.length>0&&(t=t.slice(0,-a.length)),t.length!==0&&!o.includes(t)&&!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(t))return!1}return!0},N=async(e={})=>{let{root:o=".",ignoreWords:s=[]}=e,r=await E(o),t=[];for(let a of r){let n=a.config.exports?.value;if(n!=null){if(typeof n=="string"){f(n,s)||t.push({packageName:a.name,exportPath:n,suggestion:d(n)});continue}if(n!==null&&typeof n=="object")for(let[u,c]of Object.entries(n))f(u,s)||t.push({packageName:a.name,exportPath:u,suggestion:d(u)}),typeof c=="string"&&!f(c,s)&&t.push({packageName:a.name,exportPath:c,suggestion:d(c)})}}return{isValid:t.length===0,violations:t,packagesChecked:r.length}},w=e=>v.fromPromise(()=>N(e)),b=e=>p.ok({root:"."}),A=e=>{if(p.isFail(e))return l.writeln(m("\u2717"),i(" "+String(e.error))),p.fail({exitCode:1});let{value:o}=e;if(l.writeln(g("\u2139"),i(` Checked ${o.packagesChecked} packages.`)),!o.isValid){l.writeln(m("\u2717"),i(` Found ${o.violations.length} naming violations:`));for(let s of o.violations)l.writeln(k("\u26A0"),i(" "+s.packageName)),l.writeln(g("\u2139"),i(` Export: ${s.exportPath}`)),l.writeln(g("\u2139"),i(` Suggestion: ${s.suggestion}`));return p.fail({exitCode:1})}return l.writeln(x("\u2713"),i(" All export names follow conventions.")),p.ok(void 0)},P=y.createTrigger({handler:w,adaptInput:b,adaptOutput:A}),W=async e=>await P({command:"validate-export-names",args:[],flags:{}});export{N as a,w as b,P as c,W as d};
2
+ import{a as E}from"./chunk-VXVW4UNH.js";import{a as y}from"./chunk-LFNUSULJ.js";import{b as C}from"./chunk-PZUDTTK4.js";import{f as v}from"./chunk-P2MUEKFT.js";import{b as i,f as m,g as x,h as k,i as g}from"./chunk-YVN2NZL4.js";import{g as p}from"./chunk-FFWPJP7A.js";import{j as h}from"./chunk-6DBKPC2O.js";var l=C(),d=e=>e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[_\s]+/g,"-").toLowerCase(),f=(e,o=[])=>{let s=e.split("/").filter(r=>r.length>0);for(let r of s){let t=r.startsWith(".")?r.slice(1):r;if(t.length===0)continue;let a=h.runtime.path.extname(t);if(a.length>0&&(t=t.slice(0,-a.length)),t.length!==0&&!o.includes(t)&&!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(t))return!1}return!0},N=async(e={})=>{let{root:o=".",ignoreWords:s=[]}=e,r=await E(o),t=[];for(let a of r){let n=a.config.exports?.value;if(n!=null){if(typeof n=="string"){f(n,s)||t.push({packageName:a.name,exportPath:n,suggestion:d(n)});continue}if(n!==null&&typeof n=="object")for(let[u,c]of Object.entries(n))f(u,s)||t.push({packageName:a.name,exportPath:u,suggestion:d(u)}),typeof c=="string"&&!f(c,s)&&t.push({packageName:a.name,exportPath:c,suggestion:d(c)})}}return{isValid:t.length===0,violations:t,packagesChecked:r.length}},w=e=>v.fromPromise(()=>N(e)),b=e=>p.ok({root:"."}),A=e=>{if(p.isFail(e))return l.writeln(m("\u2717"),i(" "+String(e.error))),p.fail({exitCode:1});let{value:o}=e;if(l.writeln(g("\u2139"),i(` Checked ${o.packagesChecked} packages.`)),!o.isValid){l.writeln(m("\u2717"),i(` Found ${o.violations.length} naming violations:`));for(let s of o.violations)l.writeln(k("\u26A0"),i(" "+s.packageName)),l.writeln(g("\u2139"),i(` Export: ${s.exportPath}`)),l.writeln(g("\u2139"),i(` Suggestion: ${s.suggestion}`));return p.fail({exitCode:1})}return l.writeln(x("\u2713"),i(" All export names follow conventions.")),p.ok(void 0)},P=y.createTrigger({handler:w,adaptInput:b,adaptOutput:A}),W=async e=>await P({command:"validate-export-names",args:[],flags:{}});export{N as a,w as b,P as c,W as d};