noskills 4.1.27 → 4.1.30

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 (67) hide show
  1. package/README.md +659 -2
  2. package/chunks/approve-5N5LJ2WQ.js +1 -0
  3. package/chunks/{ask-Q7AVFBH5.js → ask-TR4ZPBU5.js} +1 -1
  4. package/chunks/block-WWW3MXHP.js +1 -0
  5. package/chunks/{browser-XCMD2IZQ.js → browser-JYFQKVFU.js} +1 -1
  6. package/chunks/bun-KVGAHBUF.js +1 -0
  7. package/chunks/chunk-4IFPLK7L.js +39 -0
  8. package/chunks/chunk-5ORUHRWF.js +3 -0
  9. package/chunks/{chunk-FEWVQ5CW.js → chunk-6C2MLMD6.js} +2 -2
  10. package/chunks/chunk-6QFROYLO.js +1 -0
  11. package/chunks/chunk-7ADGJB4H.js +2 -0
  12. package/chunks/chunk-AB4ZUDV6.js +1 -0
  13. package/chunks/{chunk-N4POD6ZW.js → chunk-AT7V3AKV.js} +1 -1
  14. package/chunks/chunk-HLQNHWXS.js +1 -0
  15. package/chunks/{chunk-FPO2JRU3.js → chunk-HS6FTDDW.js} +1 -1
  16. package/chunks/chunk-I6ISQXVP.js +1 -0
  17. package/chunks/chunk-KBNVVXFC.js +3 -0
  18. package/chunks/chunk-LBOCIPVF.js +1 -0
  19. package/chunks/{chunk-TNKUKNM4.js → chunk-LZSLKXJE.js} +1 -1
  20. package/chunks/chunk-M2ZPJN26.js +1 -0
  21. package/chunks/chunk-OJUA2UZK.js +144 -0
  22. package/chunks/chunk-QEEZKZXM.js +12 -0
  23. package/chunks/{chunk-RAI7PS2P.js → chunk-RVIPYZ7F.js} +1 -1
  24. package/chunks/chunk-TGA7MX5P.js +4 -0
  25. package/chunks/chunk-UXRWSNVZ.js +1 -0
  26. package/chunks/{chunk-SG4G3OOO.js → chunk-WV3HK5WR.js} +1 -1
  27. package/chunks/{claude-code-AFPWU2BS.js → claude-code-3XV3QOZJ.js} +1 -1
  28. package/chunks/concern-P4L2VWAE.js +1 -0
  29. package/chunks/{deno-H6NPLC5O.js → deno-5VR3ZY4Z.js} +1 -1
  30. package/chunks/done-IBA3FUE5.js +1 -0
  31. package/chunks/init-HS26Q2YL.js +1 -0
  32. package/chunks/invoke-hook-JZBFLW46.js +9 -0
  33. package/chunks/{kiro-WSWAMBP2.js → kiro-IXVNKPRT.js} +1 -1
  34. package/chunks/list-UT3MSC6R.js +1 -0
  35. package/chunks/mod-LUIKS5KC.js +1 -0
  36. package/chunks/next-ZZAZ6ZVW.js +3 -0
  37. package/chunks/node-MZTU6BAB.js +1 -0
  38. package/chunks/{ollama-ZD3BKKDE.js → ollama-K4QCYLVL.js} +1 -1
  39. package/chunks/{opencode-TJR46E7H.js → opencode-QBVD5FAD.js} +1 -1
  40. package/chunks/purge-FBZME5ZJ.js +4 -0
  41. package/chunks/reset-VZO7YXM6.js +1 -0
  42. package/chunks/rule-4D2CRBI4.js +2 -0
  43. package/chunks/run-LEX6S5D7.js +3 -0
  44. package/chunks/spec-RTBL43T7.js +1 -0
  45. package/chunks/status-B4YAFCOQ.js +1 -0
  46. package/chunks/sync-XMUP5YHZ.js +1 -0
  47. package/chunks/watch-7DNXJAAQ.js +8 -0
  48. package/chunks/{workerd-LKKH32SO.js → workerd-QUMEG65S.js} +1 -1
  49. package/noskills.js +1 -1
  50. package/package.json +1 -1
  51. package/chunks/approve-JJTQKJU6.js +0 -1
  52. package/chunks/block-4I5XBXK7.js +0 -1
  53. package/chunks/bun-YFFBDKUJ.js +0 -1
  54. package/chunks/chunk-BK2BDHKB.js +0 -1
  55. package/chunks/chunk-JYJTZEC4.js +0 -32
  56. package/chunks/chunk-LXVBR775.js +0 -1
  57. package/chunks/chunk-NGURBONB.js +0 -6
  58. package/chunks/chunk-PQQKC72V.js +0 -10
  59. package/chunks/init-QCOPTDGO.js +0 -1
  60. package/chunks/list-UVJ2Q5KF.js +0 -1
  61. package/chunks/next-DNJGG34Q.js +0 -3
  62. package/chunks/node-SMAAGOR3.js +0 -1
  63. package/chunks/reset-WLKKKEUZ.js +0 -1
  64. package/chunks/rule-3VERAMM3.js +0 -2
  65. package/chunks/spec-P6YE224I.js +0 -1
  66. package/chunks/status-CJMMUOTY.js +0 -1
  67. package/chunks/sync-BZ3Z5YQP.js +0 -1
package/README.md CHANGED
@@ -1,3 +1,660 @@
1
- # noskills
1
+ # [@eser/noskills](./)
2
2
 
3
- Not disclosed yet.
3
+ State-machine orchestrator for AI coding agents. Instead of loading skills into
4
+ context and hoping the agent picks the right one, noskills pushes exactly the
5
+ right instruction at the right time — the agent never decides what to do next,
6
+ the state machine does.
7
+
8
+ ## Why
9
+
10
+ AI coding agents have a context rot problem. The more skills, rules, and
11
+ conventions you load upfront, the worse the agent performs — its context window
12
+ fills with instructions it doesn't need yet, and it forgets the ones it does.
13
+
14
+ Skills are a "pull" model: the agent decides which skill to load. This creates
15
+ two failure modes — picking the wrong skill (wasted context) and needing
16
+ meta-knowledge to pick the right one (more context to waste).
17
+
18
+ noskills is a "push" model:
19
+
20
+ ```
21
+ Agent <- stdout (JSON) <- noskills CLI <- filesystem (state + concerns + rules)
22
+ ```
23
+
24
+ The agent calls `noskills next`, gets exactly what it needs for the current
25
+ phase, acts on it, and calls `noskills next` again. No skill selection, no
26
+ context pollution, no forgetting.
27
+
28
+ ## The Mental Model
29
+
30
+ ```
31
+ .cursorrules -> .cursor/rules/*.mdc -> eser/rules + skills -> noskills
32
+ (1 file) (modular, 1 tool) (portable, curated) (state-driven)
33
+ ```
34
+
35
+ Each generation solved one bottleneck and discovered the next:
36
+
37
+ 1. **`.cursorrules`** — single file, single tool. Couldn't split, couldn't
38
+ scale, couldn't travel across tools.
39
+ 2. **`.cursor/rules/*.mdc`** — modular, but still locked to Cursor.
40
+ 3. **`eser/rules` + `eser-rules-manager`** — created as a portable,
41
+ tool-agnostic instruction system. This **predated** Anthropic's Skills spec.
42
+ When Skills arrived, eser/rules was adapted into skills format — validating
43
+ the ecosystem was heading where eser/rules had already gone.
44
+ 4. **noskills** — Skills brought new limits: context rot as skills accumulated,
45
+ agents making wrong skill choices, manual sync across tools. noskills drops
46
+ skills entirely in favor of state-driven context injection.
47
+
48
+ The `eser/rules` repository
49
+ ([github.com/eser/rules](https://github.com/eser/rules)) is now archived. Its
50
+ ideas live on in noskills, refined under
51
+ [github.com/eser/stack](https://github.com/eser/stack).
52
+
53
+ This is the **SW3** (Software Cubed) philosophy: build, discover limits, evolve,
54
+ share. noskills will discover its own limits too — and when it does, the next
55
+ step will emerge. If you want to discover those limits together, jump on board.
56
+
57
+ The name mirrors the SQL -> NoSQL shift: skills define everything upfront,
58
+ noskills determines what's needed at runtime.
59
+
60
+ ## Quick Start
61
+
62
+ ### With an agent (Claude Code, Cursor, etc.)
63
+
64
+ ```bash
65
+ eser noskills init # Scaffold .eser/, detect tools
66
+ eser noskills concern add open-source # Activate concerns
67
+ eser noskills spec new "photo upload" # Start spec -> DISCOVERY
68
+ # Agent takes over: calls noskills next, answers questions,
69
+ # builds to spec, reports progress. You approve transitions.
70
+ ```
71
+
72
+ After `init`, your CLAUDE.md (or .cursorrules, etc.) tells the agent to call
73
+ `noskills next` at every step. The agent follows the JSON output. You never need
74
+ to prompt-engineer the agent's behavior — noskills handles that.
75
+
76
+ ### Without an agent (agentless CLI mode)
77
+
78
+ ```bash
79
+ eser noskills init
80
+ eser noskills concern add beautiful-product
81
+ eser noskills spec new "photo upload"
82
+ eser noskills next -o text # Shows Q1 in plain text
83
+ eser noskills next --answer="users drag files manually" -o text
84
+ eser noskills next -o text # Shows Q2
85
+ # ... answer all 6 questions ...
86
+ eser noskills approve
87
+ eser noskills next --answer="start" -o text # Begin execution
88
+ eser noskills next --answer="task-1 done" -o text
89
+ # noskills asks for status report against acceptance criteria
90
+ eser noskills next --answer='{"completed":["endpoint works"],"remaining":["error UI"]}' -o text
91
+ # debt carries forward to next iteration
92
+ eser noskills status -o markdown
93
+ ```
94
+
95
+ The entire lifecycle works without any agent. noskills is the orchestrator —
96
+ agents and humans are both consumers.
97
+
98
+ Both CLI and agent write to the same state. You can start discovery via CLI
99
+ (answering questions in the terminal), close the terminal, open an agent session
100
+ later, and the agent picks up from the last answered question. Or start with an
101
+ agent and finish via CLI. noskills doesn't care who's driving — it checks state
102
+ and continues from wherever it left off.
103
+
104
+ ### Autonomous execution (Ralph loop)
105
+
106
+ ```bash
107
+ eser noskills run # Spawns fresh claude -p per iteration
108
+ eser noskills run --unattended # Stops at BLOCKED, logs to file
109
+ eser noskills run --max-iterations=20 # Safety valve
110
+ eser noskills run --max-turns=15 # Turns per agent process
111
+ ```
112
+
113
+ Each iteration is a fresh `claude -p` process with zero context accumulation.
114
+ State persists in `.eser/.state/state.json` between iterations. The Stop hook
115
+ snapshots git state automatically. Verification backpressure prevents advancing
116
+ past broken tests. When `autoCommit: true` in `manifest.yml`, the `noskills run`
117
+ CLI loop handles git commits between iterations — the agent never touches git.
118
+ Git write operations are the CLI's responsibility, never the agent's.
119
+
120
+ ### Live monitoring
121
+
122
+ While an agent works, open another terminal:
123
+
124
+ ```bash
125
+ eser noskills watch # Live terminal dashboard
126
+ eser noskills watch -o json # JSON lines per state change (pipeable)
127
+ eser noskills watch -o markdown # Markdown per update
128
+ ```
129
+
130
+ The dashboard shows: active spec, phase, progress bar, iteration count, time
131
+ since last update, outstanding debt items, files changed this iteration, concern
132
+ list, and context warning. Entirely filesystem-driven — watches `.eser/.state/`
133
+ for changes. Zero LLM tokens. Exits automatically when phase reaches DONE.
134
+
135
+ ## How It Works
136
+
137
+ ### The State Machine
138
+
139
+ Every spec follows a deterministic phase flow:
140
+
141
+ ```
142
+ IDLE -> DISCOVERY -> SPEC_DRAFT -> SPEC_APPROVED -> EXECUTING <-> BLOCKED
143
+ ^ |
144
+ +------------------------- DONE <-----------------------+
145
+ ```
146
+
147
+ | Phase | What happens |
148
+ | ----------------- | ---------------------------------------------------------------------- |
149
+ | **IDLE** | No active spec. Start one with `noskills spec new "..."` |
150
+ | **DISCOVERY** | 6 blended questions probe product, engineering, and QA simultaneously |
151
+ | **SPEC_DRAFT** | Spec generated from discovery answers. Human reviews |
152
+ | **SPEC_APPROVED** | Spec approved, waiting to start. A deliberate "ready but not yet" gate |
153
+ | **EXECUTING** | Agent works through the spec. Reports progress each iteration |
154
+ | **BLOCKED** | Agent hit a decision it can't make alone. Human resolves |
155
+ | **DONE** | Spec complete. Summary with iteration count and decisions |
156
+
157
+ ### Phase Transition Protocol
158
+
159
+ Every phase transition follows the same structured cycle:
160
+
161
+ ```
162
+ Human input -> Agent A evaluates -> Agent B validates (optional) -> Human approves -> Next phase
163
+ ```
164
+
165
+ This is universal — DISCOVERY -> SPEC_DRAFT, SPEC_DRAFT -> SPEC_APPROVED,
166
+ BLOCKED -> EXECUTING, every transition. The human always has final say.
167
+
168
+ Agent B validation is opt-in per command (`noskills next --validate`) or as a
169
+ project default in `manifest.yml`. When validation is active, noskills spawns
170
+ Agent B via the Agent Bridge with completely isolated context — Agent B never
171
+ sees Agent A's conversation history. This is real generator/judge separation,
172
+ not role-played.
173
+
174
+ ### The JSON Output
175
+
176
+ Every `noskills next` call returns a structured JSON payload:
177
+
178
+ ```jsonc
179
+ {
180
+ "phase": "EXECUTING",
181
+ "instruction": "Execute the current task. When done, report progress.",
182
+ "task": {
183
+ "id": "task-2",
184
+ "title": "Add photo upload endpoint with validation",
185
+ "totalTasks": 5,
186
+ "completedTasks": 1
187
+ },
188
+ "meta": {
189
+ "protocol": "Run `eser noskills next --answer=\"...\"` to submit results and advance",
190
+ "spec": "photo-upload",
191
+ "branch": null,
192
+ "iteration": 3,
193
+ "lastProgress": "implemented auth module",
194
+ "activeConcerns": ["open-source", "beautiful-product"],
195
+ "resumeHint": "Executing \"photo-upload\", iteration 3. Last progress: implemented auth module. Continue with the current task."
196
+ },
197
+ "behavioral": {
198
+ "rules": [
199
+ "NEVER run git write commands. Git is read-only for agents.",
200
+ "Do not explore the codebase beyond what the current task requires.",
201
+ "Do not refactor, improve, or modify code outside this task's scope.",
202
+ "Complete the task, then report progress. The user handles git."
203
+ ],
204
+ "tone": "Direct. No preamble. Start coding immediately."
205
+ },
206
+ "context": {
207
+ "rules": ["Use Deno for all TypeScript"],
208
+ "concernReminders": [
209
+ "open-source: Endpoint should be documented in API docs",
210
+ "beautiful-product: Loading and error states must be designed, not placeholder"
211
+ ]
212
+ },
213
+ "transition": {
214
+ "onComplete": "eser noskills next --answer=\"...\"",
215
+ "onBlocked": "eser noskills block \"reason\"",
216
+ "iteration": 3
217
+ }
218
+ }
219
+ ```
220
+
221
+ The `meta.resumeHint` is designed for cold starts — a fresh agent (or human)
222
+ reading the output for the first time can orient themselves without any prior
223
+ context. On stale sessions (>5 min since last call), a `protocolGuide` block
224
+ appears explaining what noskills is and how phases work.
225
+
226
+ When concerns conflict, the output includes a tension block:
227
+
228
+ ```jsonc
229
+ {
230
+ "phase": "EXECUTING",
231
+ "concernTensions": [{
232
+ "between": ["move-fast", "compliance"],
233
+ "issue": "Skipping audit log saves ~2h but violates compliance concern."
234
+ }]
235
+ }
236
+ ```
237
+
238
+ Tensions require human resolution — noskills never auto-resolves them.
239
+
240
+ ### Output Formats
241
+
242
+ ```bash
243
+ noskills next # JSON (default, for agents and pipes)
244
+ noskills next -o json # Explicit JSON
245
+ noskills next -o markdown # Human-readable with headings and checklists
246
+ noskills next -o text # Plain text, no formatting
247
+ noskills status -o json # Structured status for scripts
248
+ ```
249
+
250
+ ### Behavioral Guardrails
251
+
252
+ Every `noskills next` output includes a `behavioral` block with phase-specific
253
+ rules. These tell the agent HOW to behave, not just WHAT to do:
254
+
255
+ | Phase | Behavioral tone | Key rules |
256
+ | ---------- | ------------------------------ | ------------------------------------------------------------ |
257
+ | DISCOVERY | "You are a messenger" | Don't rephrase questions, relay answers verbatim, don't code |
258
+ | SPEC_DRAFT | "The user is reviewing" | Don't modify the spec, don't start coding |
259
+ | EXECUTING | "Start coding immediately" | Don't explore beyond scope, don't refactor, timebox reading |
260
+ | BLOCKED | "Brief. Decision time." | Present decision as-is, don't suggest preferences |
261
+ | DONE | "Celebrate briefly, then stop" | Don't start new work |
262
+
263
+ **Git is read-only** for agents (configurable via `allowGit: true` in manifest).
264
+ Agents may read (`git log`, `git diff`, `git status`) but never write
265
+ (`git commit`, `git push`, `git checkout`). This is enforced at three levels:
266
+ behavioral rules, CLAUDE.md instruction, and PreToolUse hook.
267
+
268
+ When the agent's iteration count exceeds `maxIterationsBeforeRestart` (default
269
+ 15), an `urgency` message warns that context is degrading and recommends a fresh
270
+ session.
271
+
272
+ **Convention discovery:** When the agent identifies a recurring pattern,
273
+ receives a correction from the user, or discovers a preference during work, the
274
+ behavioral rules instruct it to ask: _"Should this be a permanent rule for this
275
+ project, or just for this task?"_ If permanent, the agent runs
276
+ `noskills rule add`. If just this task, it notes and moves on. The agent never
277
+ writes to `.eser/rules/` directly — noskills handles file creation and sync.
278
+
279
+ ### Concerns — The Project's DNA
280
+
281
+ Concerns define what your project IS. They stack on top of each other and affect
282
+ discovery questions, spec sections, execution reminders, and acceptance
283
+ criteria:
284
+
285
+ | Concern | Effect |
286
+ | --------------------- | --------------------------------------------------------------------- |
287
+ | **open-source** | Prioritize contributor experience, default to permissive choices |
288
+ | **beautiful-product** | Every UI state specified — empty, loading, error, success. No AI slop |
289
+ | **long-lived** | Favor boring technology, every shortcut needs justification |
290
+ | **move-fast** | Good enough is good enough, defer polish to v2 |
291
+ | **compliance** | Every state change must be traceable, verification is mandatory |
292
+ | **learning-project** | Experimentation encouraged, document learnings over polish |
293
+
294
+ Concerns inject:
295
+
296
+ - **Discovery extras** — sub-questions per concern per question
297
+ - **Spec sections** — e.g., beautiful-product adds "Design States (empty,
298
+ loading, error, success)"
299
+ - **Execution reminders** — per-iteration context hints
300
+ - **Acceptance criteria** — checked during status reports before task is
301
+ accepted
302
+
303
+ When concerns conflict (e.g., move-fast + compliance), noskills surfaces the
304
+ tension to the human rather than resolving it silently.
305
+
306
+ ### Decision Lifecycle
307
+
308
+ When an agent encounters a decision during any phase:
309
+
310
+ 1. Agent reports it needs a decision (via `noskills block` or within `next`
311
+ output).
312
+ 2. noskills routes the decision to the human.
313
+ 3. Human answers.
314
+ 4. noskills asks: _"Should this be a permanent rule for this project, or just
315
+ for this spec?"_
316
+ 5. If permanent -> `noskills rule add` is called internally -> writes to
317
+ `.eser/rules/` -> triggers sync.
318
+ 6. If just this spec -> recorded in the spec's decisions table only.
319
+
320
+ This creates an organic growth loop: as you build specs, your rule set evolves.
321
+ New team members and AI agents automatically inherit accumulated decisions.
322
+ One-time decisions stay scoped to their spec — they never leak into other specs.
323
+
324
+ The spec file tracks decisions:
325
+
326
+ ```markdown
327
+ ## Decisions
328
+
329
+ | # | Decision | Choice | Type |
330
+ | - | ------------------ | ------------- | --------------- |
331
+ | 1 | Validation library | Zod | rule (promoted) |
332
+ | 2 | Image API provider | OpenAI Vision | one-time |
333
+ ```
334
+
335
+ ### Verification Backpressure
336
+
337
+ When the agent reports a task complete, noskills doesn't take its word for it.
338
+
339
+ 1. **Automated verification** runs first (configurable via `verifyCommand` in
340
+ manifest, e.g., `"deno test"`). If tests fail, the task is rejected and the
341
+ failure output is returned as the next instruction.
342
+
343
+ 2. **Status report** requested against acceptance criteria — items from the spec
344
+ plus concern-injected criteria (e.g., "All UI states designed" from
345
+ beautiful-product). The agent checks off what's done and reports what
346
+ remains.
347
+
348
+ 3. **Debt carry-forward** — remaining items persist across iterations as debt.
349
+ Every subsequent `noskills next` output includes the debt with "Address these
350
+ BEFORE starting new work." Debt is never silently removed — only an explicit
351
+ status report listing items as completed clears them. If debt items remain
352
+ unaddressed for 3+ iterations, noskills escalates — the debt block gains an
353
+ urgency field warning that these items have been outstanding for N iterations
354
+ and must be addressed before any new work.
355
+
356
+ 4. **Context clearing** — when debt is zero and verification passes, noskills
357
+ emits a `clearContext` action telling the agent to `/clear` for fresh context
358
+ on the next task. A `pendingClear` flag blocks all file edits until the agent
359
+ complies.
360
+
361
+ ### Scoped Folder Rules
362
+
363
+ In monorepos, different packages have different constraints. Drop a
364
+ `.folder-rules.md` in any directory with markdown bullet rules:
365
+
366
+ ```markdown
367
+ - Generated CLAUDE.md must preserve existing content outside noskills:start/end
368
+ markers
369
+ - All command references must use dynamic noskillsCmd prefix
370
+ - Sync output must be idempotent
371
+ - Hook scripts must be self-contained
372
+ ```
373
+
374
+ When the agent modifies files in that directory (tracked via the post-file-write
375
+ hook log), noskills adds those rules to the acceptance criteria during status
376
+ reports:
377
+
378
+ ```
379
+ (folder: pkg/@eser/noskills/sync) Sync output must be idempotent
380
+ (folder: pkg/@eser/noskills/sync) Hook scripts must be self-contained
381
+ ```
382
+
383
+ Rules stack upward — `.folder-rules.md` files in parent directories also apply,
384
+ like CSS specificity. A rule at `pkg/` applies to all files under `pkg/`, while
385
+ a rule at `pkg/@eser/streams/` applies only to that package. Zero token cost —
386
+ derived from filesystem, not LLM.
387
+
388
+ ### Discovery Questions
389
+
390
+ Six questions, each probing product + engineering + QA at once:
391
+
392
+ 1. **What does the user do today without this feature?**
393
+ 2. **Describe the 1-star and 10-star versions.**
394
+ 3. **Does this change involve an irreversible decision?**
395
+ 4. **Does this change affect existing users' behavior?**
396
+ 5. **How do you verify this works correctly?**
397
+ 6. **What should this feature NOT do?**
398
+
399
+ Active concerns inject sub-questions. For example, with `open-source` active,
400
+ question 1 also asks: _"Is this workaround common in the community?"_
401
+
402
+ ### Spec Classification
403
+
404
+ After discovery answers are submitted, noskills asks the user to classify the
405
+ spec along four boolean axes:
406
+
407
+ | Flag | What it controls |
408
+ | ---------------------- | ------------------------------------------------------- |
409
+ | `involvesUI` | UI state sections from beautiful-product concern |
410
+ | `involvesPublicAPI` | API documentation sections from open-source concern |
411
+ | `involvesMigration` | Migration checklist sections from compliance/long-lived |
412
+ | `involvesDataHandling` | Data safety sections from compliance concern |
413
+
414
+ Classification determines which concern sections appear in the generated spec.
415
+ Irrelevant sections are skipped entirely — a backend API change won't get UI
416
+ state checklists, and a CSS tweak won't get migration warnings. This replaces
417
+ keyword-based guessing with explicit user input.
418
+
419
+ The classification is submitted as JSON via `noskills next`:
420
+
421
+ ```bash
422
+ noskills next --answer='{"involvesUI":true,"involvesPublicAPI":false,"involvesMigration":false,"involvesDataHandling":false}'
423
+ ```
424
+
425
+ ### Hooks — Zero-Token Bookkeeping
426
+
427
+ noskills installs Claude Code hooks that handle state bookkeeping without
428
+ spending LLM tokens:
429
+
430
+ | Hook | Event | What it does |
431
+ | ------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------- |
432
+ | **pre-tool-use** | PreToolUse | Blocks file edits outside EXECUTING phase. Blocks git write commands. Blocks edits when pendingClear is set. |
433
+ | **stop** | Stop | Increments iteration counter, snapshots `git diff` into state, checks restart threshold. The Ralph loop's heartbeat. |
434
+ | **post-file-write** | PostToolUse | Logs modified file paths to `.eser/.state/files-changed.jsonl` |
435
+ | **post-bash** | PostToolUse | Logs noskills CLI invocations for observability |
436
+
437
+ Hooks are CLI subcommands (`noskills invoke-hook <name>`), not generated script
438
+ files. This avoids ESM/CJS issues — the same Deno entry point handles
439
+ everything.
440
+
441
+ The agent is completely unaware hooks exist. Hooks derive progress from
442
+ filesystem and git state — the agent doesn't waste tokens summarizing what it
443
+ did.
444
+
445
+ ### Tool Sync — One Source of Truth
446
+
447
+ noskills generates instruction files for every AI tool your team uses:
448
+
449
+ ```
450
+ .eser/ (single source of truth)
451
+ +-- noskills sync
452
+ |-- -> CLAUDE.md (Claude Code)
453
+ |-- -> .cursorrules (Cursor)
454
+ |-- -> .kiro/steering/ (Kiro)
455
+ |-- -> .github/copilot-instructions.md (GitHub Copilot)
456
+ +-- -> .windsurfrules (Windsurf)
457
+ ```
458
+
459
+ Write your rules once in `.eser/rules/`, run `noskills sync`, and every tool
460
+ gets the same instructions in its native format.
461
+
462
+ Generated CLAUDE.md includes:
463
+
464
+ - Protocol instructions with 5 concrete trigger points
465
+ - Git read-only section (unless `allowGit: true`)
466
+ - Active rules
467
+ - JSON output explanation
468
+
469
+ ### Spec Management
470
+
471
+ ```bash
472
+ # Create with auto-generated slug
473
+ noskills spec new "photo upload feature"
474
+ # -> .eser/specs/photo-upload-feature/spec.md
475
+
476
+ # Create with explicit name
477
+ noskills spec new --name=SPC0001 "photo upload feature"
478
+ # -> .eser/specs/SPC0001/spec.md
479
+
480
+ # List all specs with status
481
+ noskills spec list
482
+ # . photo-upload-feature EXECUTING iteration 3
483
+ # fix-login-bug SPEC_DRAFT
484
+ # SPC0001 DONE
485
+
486
+ # Switch between specs (preserves state)
487
+ noskills spec switch fix-login-bug
488
+ # Active spec: fix-login-bug (SPEC_DRAFT)
489
+
490
+ # JSON output for scripts
491
+ noskills spec list -o json
492
+ ```
493
+
494
+ Multiple specs can exist at different stages. Switching away from an EXECUTING
495
+ spec preserves everything — iteration, debt, verification result, progress.
496
+ Switching back resumes exactly where it left off.
497
+
498
+ ## CLI Reference
499
+
500
+ ```bash
501
+ # Via eser CLI
502
+ eser noskills <command>
503
+
504
+ # Standalone
505
+ deno run --allow-all jsr:@eser/noskills <command>
506
+
507
+ # Alias
508
+ eser nos <command>
509
+ ```
510
+
511
+ ### Commands
512
+
513
+ | Command | Description |
514
+ | ----------------------------- | ------------------------------------------------------------------ |
515
+ | `init` | Scaffold `.eser/`, detect project traits, install hooks |
516
+ | `status [-o format]` | Show current phase, spec name, progress, debt |
517
+ | `spec new "..." [--name=N]` | Start a new spec, enter DISCOVERY |
518
+ | `spec list [-o format]` | List all specs with phase info |
519
+ | `spec switch <name>` | Switch active spec (preserves state) |
520
+ | `next [-o format]` | Get instruction for current phase |
521
+ | `next --answer="..." [-o f]` | Submit answer and advance state |
522
+ | `approve` | Approve spec draft -> SPEC_APPROVED |
523
+ | `done` | Complete execution -> DONE |
524
+ | `block "reason"` | Mark execution as blocked |
525
+ | `reset` | Reset current spec to IDLE |
526
+ | `run [--unattended]` | Autonomous execution loop (Ralph loop) |
527
+ | `watch [-o format]` | Live dashboard monitoring agent progress |
528
+ | `concern add/remove/list` | Manage active concerns |
529
+ | `rule add/list/promote` | Manage permanent rules |
530
+ | `sync` | Regenerate tool-specific instruction files + hooks |
531
+ | `purge [--force]` | Remove all noskills content (specs, rules, concerns, hooks, state) |
532
+
533
+ ### Output Formats
534
+
535
+ All commands that produce output support `-o` / `--output`:
536
+
537
+ | Format | Flag | Use case |
538
+ | -------- | ------------------- | ---------------------- |
539
+ | JSON | `-o json` (default) | Agents, pipes, scripts |
540
+ | Markdown | `-o markdown` | Human reading |
541
+ | Text | `-o text` | Simple terminal output |
542
+
543
+ ## Configuration
544
+
545
+ noskills config lives inside `.eser/manifest.yml` as a `noskills:` section:
546
+
547
+ ```yaml
548
+ noskills:
549
+ command: "eser noskills" # auto-detected during init
550
+ concerns:
551
+ - open-source
552
+ - beautiful-product
553
+ tools:
554
+ - claude-code
555
+ - cursor
556
+ providers:
557
+ - anthropic
558
+ project:
559
+ languages: [typescript]
560
+ frameworks: [react]
561
+ ci: [github-actions]
562
+ testRunner: deno
563
+ maxIterationsBeforeRestart: 15
564
+ verifyCommand: "deno test" # runs before accepting task completion
565
+ allowGit: false # true = agents can run git write commands
566
+ ```
567
+
568
+ During `init`, noskills detects how it was invoked (via `@eser/standards`
569
+ runtime) and stores it as `command`. All generated output — `CLAUDE.md`
570
+ instructions, hook remediation messages, behavioral rules, transition hints —
571
+ uses this prefix. Users who invoke via `deno run`, `npx`, homebrew, or global
572
+ install all get correct command references.
573
+
574
+ **Tools vs Providers:**
575
+
576
+ - **Tools** = the IDE or agent environment (`claude-code`, `cursor`, `kiro`,
577
+ `copilot`, `windsurf`). Affects which sync output files are generated.
578
+ - **Providers** = AI model access methods (`anthropic`, `openai`, `ollama`,
579
+ `claude-code` CLI). Used by the Agent Bridge for validation and
580
+ `noskills run`.
581
+
582
+ ## Directory Structure
583
+
584
+ ```
585
+ .eser/ # unified toolchain directory
586
+ |-- manifest.yml # workflows, scripts, AND noskills config
587
+ |-- concerns/ # Concern definitions (built-in + custom)
588
+ | |-- 001-open-source.json
589
+ | |-- 002-beautiful-product.json
590
+ | +-- ... # Numeric prefixes control ordering
591
+ |-- rules/ # Permanent rules (*.md, *.txt)
592
+ |-- specs/
593
+ | +-- photo-upload/
594
+ | +-- spec.md # Generated spec from discovery
595
+ |-- workflows/
596
+ |-- .state/ # git-ignored (runtime only)
597
+ | |-- state.json # Current phase, answers, progress, active spec
598
+ | |-- specs/ # Per-spec state snapshots
599
+ | | |-- photo-upload.json
600
+ | | +-- fix-login-bug.json
601
+ | |-- files-changed.jsonl # File modification log (from hooks)
602
+ | +-- noskills-calls.jsonl # CLI invocation log (from hooks)
603
+ +-- .gitignore # Excludes .state/
604
+ ```
605
+
606
+ Configuration and specs are git-tracked for PR review. Runtime state is
607
+ gitignored — each agent session reads fresh state from the filesystem.
608
+
609
+ ## Library API
610
+
611
+ ```typescript
612
+ import * as noskills from "@eser/noskills/mod";
613
+
614
+ // State machine
615
+ const state = noskills.machine.startSpec(
616
+ noskills.createInitialState(),
617
+ "my-feature",
618
+ "spec/my-feature",
619
+ );
620
+
621
+ // Questions with concern extras
622
+ const qs = noskills.questions.getQuestionsWithExtras(activeConcerns);
623
+
624
+ // Compile instruction for current phase
625
+ const output = noskills.compiler.compile(state, activeConcerns, rules, config);
626
+
627
+ // Concern tension detection
628
+ const tensions = noskills.concerns.detectTensions(activeConcerns);
629
+
630
+ // Output formatting
631
+ const text = noskills.formatter.format(output, "markdown");
632
+ ```
633
+
634
+ ## Agent Bridge
635
+
636
+ noskills can call AI agents for validation via a fallback chain:
637
+
638
+ 1. **@eser/ai** — Programmatic API call (cross-model, configurable)
639
+ 2. **Claude CLI** — Spawns `claude -p "..."` locally (zero additional cost)
640
+ 3. **Manual** — Returns null, caller handles human review
641
+
642
+ ## Init Detection
643
+
644
+ `noskills init` auto-detects:
645
+
646
+ - **Languages** — TypeScript, Go, Rust, Python (from config files)
647
+ - **Frameworks** — React, Vue, Svelte, Next.js, Express, Hono (from
648
+ package.json)
649
+ - **CI** — GitHub Actions, GitLab CI, Jenkins, CircleCI
650
+ - **Test runner** — Deno, Vitest, Jest, Playwright
651
+ - **Coding tools** — Claude Code, Cursor, Kiro, Copilot, Windsurf (from existing
652
+ config files in repo)
653
+
654
+ Detected coding tools are auto-synced on init, including hook installation for
655
+ Claude Code. Invocation method is auto-detected and stored in `manifest.yml` as
656
+ `noskills.command` — all output references use this prefix.
657
+
658
+ ## License
659
+
660
+ Apache-2.0
@@ -0,0 +1 @@
1
+ import{a as C}from"./chunk-5ORUHRWF.js";import"./chunk-7ADGJB4H.js";import{a as P,d as R}from"./chunk-KBNVVXFC.js";import{e as y}from"./chunk-HLQNHWXS.js";import{a as p}from"./chunk-UXRWSNVZ.js";import{e as h,f as S,k as g,o as v}from"./chunk-OJUA2UZK.js";import{c as n,d as c,f as l,g as m,k as d,o as f,q as u,r as w}from"./chunk-4IFPLK7L.js";import{a as i}from"./chunk-2N4GTHXQ.js";import{a as o}from"./chunk-HS6FTDDW.js";import"./chunk-WV3HK5WR.js";import"./chunk-FDZP7B5Y.js";import"./chunk-ACQUINWH.js";import"./chunk-DXB73IDG.js";var $=async E=>{let r=f({renderer:w.ansi(),sink:u.stdout()}),s=o.process.cwd(),e=await h(s),a=await g(s);if(e.phase==="SPEC_DRAFT"){if(e.classification===null&&e.spec!==null){let A=(await v(s)).filter(D=>a?.concerns.includes(D.id)??!1);try{await C(s,e,A)}catch{}}let t=y(e);await S(s,t),t.spec!==null&&(await P(s,t.spec,"approved"),await R(s,t.spec,"approved")),r.writeln(m("\u2714")," Spec approved. Phase: ",d("SPEC_APPROVED")),r.writeln("When ready, run ",n(`${p('next --answer="start"',a)}`)," to begin execution.")}else e.phase==="DISCOVERY"&&e.discovery.completed?(r.writeln(c("Discovery complete. Spec draft already generated.")),r.writeln("Review the spec and run ",n(p("approve",a))," again when in SPEC_DRAFT phase.")):r.writeln(l(`Cannot approve in phase: ${e.phase}`));return await r.close(),i(void 0)};export{$ as main};