devlyn-cli 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +5 -1
- package/CLAUDE.md +8 -4
- package/README.md +15 -3
- package/bin/devlyn.js +3 -1
- package/config/skills/_shared/task-complete.py +1169 -0
- package/config/skills/devlyn:ideate/SKILL.md +2 -2
- package/config/skills/devlyn:ideate/references/spec-template.md +5 -5
- package/config/skills/devlyn:queue/SKILL.md +3 -3
- package/config/skills/devlyn:resolve/SKILL.md +6 -2
- package/config/skills/devlyn:resolve/references/free-form-mode.md +1 -0
- package/config/skills/devlyn:resolve/references/outer-loop.md +10 -2
- package/config/skills/devlyn:resolve/references/task-completion.md +117 -0
- package/package.json +1 -1
- package/scripts/lint-skills.sh +4 -1
package/AGENTS.md
CHANGED
|
@@ -38,7 +38,11 @@ Each skill's `SKILL.md` is the source of truth for flags and workflow. Do not du
|
|
|
38
38
|
|
|
39
39
|
Engine roles: orchestrator = whichever CLI the user opened (this contract is symmetric with CLAUDE.md. If you are Codex orchestrating `/devlyn:resolve`, the phase machinery is mandatory regardless of task size; if you will not run it, say so explicitly and stop — do not silently degrade to ad-hoc execution); legacy executor (with optional separate worker/primary/pair profiles) uses the canonical skill's orchestrator-supported default, overridable per run with `--engine <name>` or durably via machine-local `.devlyn/engines.json` `{"executor": "<name>", "pair_judge_priority": ["<name>", ...]}`; PLAN is orchestrator-fixed and never inherits `--engine` or the executor pin; pair judge = first available OTHER engine, default for VERIFY whenever available; risk probes remain conditional and --no-pair opts out. Pins fail closed (`BLOCKED:<engine>-unavailable` / `BLOCKED:invalid-engine-config`); new engines plug in by shipping `_shared/adapters/<name>.md`. `/devlyn:engines` (no args) shows the role table + detected engines; `executor <name>` / `pair <name>,...` / `clear` manage the pins. The executor pin binds the orchestrator in plain conversation too, not only inside a skill run: when you would implement directly and executor is pinned to a non-default engine, route that work through the pin — via `/devlyn:resolve` (reads it at PHASE 0) or by delegating to that engine; no pin / no file → use the canonical skill's orchestrator-supported default. The pair-judge pin stays pipeline-scoped. `/devlyn:engines role` configures explicit engine/model/effort for supported worker and judge routes; `/devlyn:resolve --role-config <path>` overrides roles for one run. Canonical skills define precedence, evidence and unsupported-route errors; absent profiles preserve existing defaults.
|
|
40
40
|
|
|
41
|
-
Conversational
|
|
41
|
+
Conversational entry: Before writes, inspect requested files and relevant callers/tests. Default to direct execution only for clear, local, reversible, low-risk work with a decisive existing or small task-specific acceptance check. Preserve requested behavior, scope, explicit constraints and the executor pin; make scoped edits, run required checks, review the final diff, and report changes with evidence. One concise route/check explanation suffices; ordinary direct work needs no spec, pipeline state, phase workers or extra approval. For direct/full/queue work, the outer owner reads `references/task-completion.md` relative to the installed `devlyn:resolve` skill's directory: prospective task-branch ownership (linked worktree optional), scoped commit acceptance, then PR/merge and recoverable owned-resource cleanup after required archive/queue commits. Local-only/no-push wins; delivery pending/failure stays separate from product verification.
|
|
42
|
+
|
|
43
|
+
Use full `/devlyn:resolve` for material ambiguity, subsystem/design work, security/auth/payment/persistence/concurrency/public-API-contract changes, or inconclusive inspection/checks. Counts of lines, files or words alone do not establish low risk. Explicit resolve (even small), formal spec workflows and queue drains retain all canonical phases, independent verification, pins and failure handling. If new risk appears mid-edit, preserve the delta in the full run's scope/evidence; do not hide it in a new baseline or reconfirm existing authorization.
|
|
44
|
+
|
|
45
|
+
Full-route handoff + loop engineering: the orchestrating model — not the user — invokes the skills. `/devlyn:queue` fronts the intent queue (`docs/specs/queue.md`): no args = status, `add <intent>`, `drain` = serial unattended drain per the contract below. Large agreed work is written to `docs/specs/<id>/spec.md` (always a spec file — the user's reviewed contract; free-form large assumes-and-logs instead of halting, zero-scope-signal goals still halt to ideate), summarized once for user review, then run hands-free via `--spec`. Outer loop per task: before the first full run, commit the scoped queue-item delta (when applicable) and linked spec bundle; findings-backed verdicts (NEEDS_WORK, verify/build-gate exhaustion) get a committed spec amendment before re-run, max 3 iterations; infrastructure / invalid-input / engine-availability / implement-empty BLOCKED verdicts surface immediately. Unattended queue drain (`docs/specs/queue.md`, strictly serial): assumptions may only take scope-narrowing, reversible, non-user-visible defaults — material ambiguity marks the item `[F] needs-review`; commit every terminal `[x]` / `[F]` transition before advancing. The canonical commit order is `config/skills/devlyn:resolve/references/outer-loop.md`.
|
|
42
46
|
|
|
43
47
|
## Subtractive-First Editing
|
|
44
48
|
|
package/CLAUDE.md
CHANGED
|
@@ -49,16 +49,20 @@ Each skill's `SKILL.md` is the source of truth for its flags and workflow — do
|
|
|
49
49
|
|
|
50
50
|
**The executor pin binds the orchestrator in plain conversation too, not only inside a skill run.** When you would do implementation work directly and executor is pinned to a non-default engine, route that work through the pin — run it via `/devlyn:resolve` (which reads the pin at PHASE 0), or delegate to that engine. No pin / no `.devlyn/engines.json` → use the canonical skill's orchestrator-supported default. The pair-judge pin stays pipeline-scoped. `/devlyn:engines role` configures explicit engine/model/effort for supported worker and judge routes; `/devlyn:resolve --role-config <path>` overrides roles for one run. Canonical skills define precedence, evidence and unsupported-route errors; absent profiles preserve existing defaults.
|
|
51
51
|
|
|
52
|
-
### Conversational
|
|
52
|
+
### Conversational entry + full-route handoff
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Before writes, inspect requested files and relevant callers/tests. Default to direct execution only for clear, local, reversible, low-risk work with a decisive existing or small task-specific acceptance check. Preserve requested behavior, scope, explicit constraints and the executor pin; make scoped edits, run required checks, review the final diff, and report changes with evidence. One concise route/check explanation suffices; ordinary direct work needs no spec, pipeline state, phase workers or extra approval. For direct/full/queue work, the outer owner reads `references/task-completion.md` relative to the installed `devlyn:resolve` skill's directory: prospective task-branch ownership (linked worktree optional), scoped commit acceptance, then PR/merge and recoverable owned-resource cleanup after required archive/queue commits. Local-only/no-push wins; delivery pending/failure stays separate from product verification.
|
|
55
|
+
|
|
56
|
+
Use full `/devlyn:resolve` for material ambiguity, subsystem/design work, security/auth/payment/persistence/concurrency/public-API-contract changes, or inconclusive inspection/checks. Counts of lines, files or words alone do not establish low risk. Explicit resolve (even small), formal spec workflows and queue drains retain all canonical phases, independent verification, pins and failure handling. If new risk appears mid-edit, preserve the delta in the full run's scope/evidence; do not hide it in a new baseline or reconfirm existing authorization.
|
|
57
|
+
|
|
58
|
+
The user does not invoke skills manually; the orchestrating model does. Large tasks agreed in conversation:
|
|
55
59
|
|
|
56
60
|
1. Write the agreed contract to `docs/specs/<id>/spec.md` (+ `spec.expected.json` when mechanical verifications exist). Always a spec file for large work — a written spec is the user's reviewed contract; free-form large now assumes-and-logs instead of halting (zero-scope-signal goals still halt to ideate).
|
|
57
61
|
2. Present a one-screen plan-contract summary — the user's single review checkpoint, BEFORE the pipeline starts.
|
|
58
62
|
3. On go-ahead, commit the scoped queue-item delta (when applicable) and linked spec bundle, then invoke `/devlyn:resolve --spec <path>` hands-free to completion.
|
|
59
|
-
4. **Per-task outer loop**: read the terminal verdict.
|
|
63
|
+
4. **Per-task outer loop**: read the terminal verdict. Successful normal-run archive → outer-owner completion per the canonical task-completion reference, after any terminal queue commit. Verdicts backed by spec/verification findings (NEEDS_WORK, verify/build-gate exhaustion) → adjudicate the findings, amend the spec (recorded in the spec file; spec stays read-only inside a run), commit that scoped amendment, then re-invoke — at most 3 outer iterations, then surface with the findings trail. Infrastructure, invalid-input, engine-availability, and implement-empty BLOCKED verdicts are not spec-amendable: surface immediately. Every iteration re-enters through committed durable artifacts (spec, findings, run archive), never conversation memory.
|
|
60
64
|
|
|
61
|
-
**Intent queue (unattended drain)**: the user stacks intents in `docs/specs/queue.md` (ordered checklist; `/devlyn:queue` is the front-end — no args shows status, `add <intent>` appends, `drain` starts the serial drain). Drain strictly serially — per item: spec it, commit the scoped owner baseline, run the outer loop, mark `[x]` done or `[F]` blocked with reason, commit that terminal transition, then
|
|
65
|
+
**Intent queue (unattended drain)**: the user stacks intents in `docs/specs/queue.md` (ordered checklist; `/devlyn:queue` is the front-end — no args shows status, `add <intent>` appends, `drain` starts the serial drain). Drain strictly serially — per item: spec it, commit the scoped owner baseline, run the outer loop, mark `[x]` done or `[F]` blocked with reason, commit that terminal transition, then complete eligible delivery once. Retain PR/pending workspaces; unavailable separate safe placement stops the drain with remaining items pending. A product-blocked item otherwise never halts the queue. The queue entry is the user's go-ahead, so assume-and-log replaces the interactive checkpoint — but unattended assumptions may only take scope-narrowing, reversible, non-user-visible defaults. Material ambiguity (user-visible behavior, data/state semantics, new files/scripts/flags, implementation surface) → mark `[F] needs-review`, commit it, and move on. End the drain with a per-item product verdict, separate delivery status/URL/resume and assumptions report. The canonical commit order is `config/skills/devlyn:resolve/references/outer-loop.md`.
|
|
62
66
|
|
|
63
67
|
## Subtractive-first editing — perfection = nothing left to remove
|
|
64
68
|
<!-- runtime-principles:section=subtractive-first:begin -->
|
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ If devlyn-cli saved you time, [give it a star](https://github.com/fysoul17/devly
|
|
|
27
27
|
npx devlyn-cli
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
That's it. The installer opens with a single **agent selector** — pick any combination of **Claude Code**, **Codex CLI**, **oh-my-pi (omp)**, **Pi**, or **Grok Build CLI**, and devlyn installs into every one you choose in a single pass. Claude Code and any agent already present on your machine are pre-checked, so the common case is just Enter. Skill-capable agents receive the `devlyn:resolve`, `devlyn:ideate`, and `devlyn:design-ui` skills — plus the `devlyn:engines` and `devlyn:queue` utilities — in the directory each one loads from: Codex → `~/.codex/skills/`, Grok → `~/.grok/skills/`, while **omp and Pi share `~/.agents/skills/`** — the cross-agent standard both read — so the bundle is written there once, not duplicated per agent. In Codex / omp / Pi, invoke them as skills (`$devlyn:resolve`, `$devlyn:ideate`, `$devlyn:design-ui`); in Claude Code and Grok Build CLI they're slash commands (`/devlyn:resolve`).
|
|
30
|
+
That's it. The installer opens with a single **agent selector** — pick any combination of **Claude Code**, **Codex CLI**, **oh-my-pi (omp)**, **Pi**, or **Grok Build CLI**, and devlyn installs into every one you choose in a single pass. Claude Code and any agent already present on your machine are pre-checked, so the common case is just Enter. Skill-capable agents receive the `devlyn:resolve`, `devlyn:ideate`, and `devlyn:design-ui` skills — plus the `devlyn:engines` and `devlyn:queue` utilities — in the directory each one loads from: Codex → `~/.codex/skills/`, Grok → `~/.grok/skills/`, while **omp and Pi share `~/.agents/skills/`** — the cross-agent standard both read — so the bundle is written there once, not duplicated per agent. In Codex / omp / Pi, invoke them as skills (`$devlyn:resolve`, `$devlyn:ideate`, `$devlyn:design-ui`); in Claude Code and Grok Build CLI they're slash commands (`/devlyn:resolve`). Rerunning refreshes skills for selected agents, preserves existing AGENTS.md without legacy managed markers (legacy appended blocks are still cleaned up), and replaces CLAUDE.md when Claude Code is selected. Use the bundled AGENTS.md template path printed by the installer to compare and merge relevant shared runtime instructions into your preserved AGENTS.md, retaining your content and keeping engine-specific instructions distinct. (`npx devlyn-cli -y` installs the Claude core non-interactively; `npx devlyn-cli agents <cli>` adds one agent later.)
|
|
31
31
|
|
|
32
32
|
---
|
|
33
33
|
|
|
@@ -62,7 +62,7 @@ Skip ideate entirely if you have a spec or just want to describe the work — `/
|
|
|
62
62
|
|
|
63
63
|
### Step 2 — Resolve with `/devlyn:resolve`
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Before writes, inspect requested files and relevant callers/tests. Clear, local, reversible, low-risk conversational edits with a decisive acceptance check run directly, honoring scope, constraints and executor pins; finish required checks and diff review, then accept the scoped commit for owner completion below. Material ambiguity, subsystem/design work, security/auth/payment/persistence/concurrency/public-API-contract changes or no decisive check use full `/devlyn:resolve`. Explicit resolve (including small tasks), formal specs and queue drains keep the full workflow below. Pass a spec, a free-form goal, or a diff to verify.
|
|
66
66
|
|
|
67
67
|
```
|
|
68
68
|
/devlyn:resolve "fix the login bug" # free-form
|
|
@@ -97,9 +97,21 @@ golden fixture, risk-probe, or pair-evidence candidate must also include
|
|
|
97
97
|
difference from rejected or solo-saturated controls such as `S2`-`S6`; without
|
|
98
98
|
that, `/devlyn:resolve` stops with `BLOCKED:solo-ceiling-avoidance-required`.
|
|
99
99
|
|
|
100
|
+
Accepted tasks default to owner completion: scoped commit → push → PR → normal
|
|
101
|
+
protected merge → recoverable cleanup of prospectively owned resources. Set
|
|
102
|
+
`git config --local devlyn.completionMode pr` to stop at a PR, or `auto` to restore
|
|
103
|
+
the default; `task-complete.py complete --mode auto|pr` overrides one task.
|
|
104
|
+
Local-only/no-push instructions take precedence. Linked worktrees are optional;
|
|
105
|
+
existing branches cannot be adopted. Full runs require successful archive before
|
|
106
|
+
delivery; direct tasks use their actual checks and root acceptance. Verify-only
|
|
107
|
+
never publishes. Pending checks or unsupported merge policy retain resources and
|
|
108
|
+
report a receipt-based resume command separately from product verification.
|
|
109
|
+
See [task completion](config/skills/devlyn:resolve/references/task-completion.md)
|
|
110
|
+
for allocation, acceptance, writer cessation and recovery.
|
|
111
|
+
|
|
100
112
|
### Queue multiple intents for unattended drain — `/devlyn:queue`
|
|
101
113
|
|
|
102
|
-
Stack tasks to run back-to-back without supervision. `/devlyn:queue add "<intent>"` appends to `docs/specs/queue.md` (an ordered checklist); `/devlyn:queue drain` runs each item serially — spec it, run the resolve outer loop,
|
|
114
|
+
Stack tasks to run back-to-back without supervision. `/devlyn:queue add "<intent>"` appends to `docs/specs/queue.md` (an ordered checklist); `/devlyn:queue drain` runs each item serially — spec it, run the resolve outer loop, commit `[x]` done or `[F]` blocked with a reason, then complete eligible delivery once. Product verdict and delivery status are separate. A blocked product otherwise never halts the queue; pending delivery retains its branch, and the next item requires separate safe placement. Unattended runs only take scope-narrowing, reversible defaults — anything user-visible or ambiguous is marked `[F] needs-review` for you to adjudicate afterward. `/devlyn:queue` with no args shows status.
|
|
103
115
|
|
|
104
116
|
### Engine roles — auto-detected, pinnable with `/devlyn:engines`
|
|
105
117
|
|
package/bin/devlyn.js
CHANGED
|
@@ -690,14 +690,16 @@ function installInstructionsForCLI(cliKey) {
|
|
|
690
690
|
if (!cli || !cli.baseInstructionsFile) return false;
|
|
691
691
|
|
|
692
692
|
const destFile = path.join(process.cwd(), cli.instructionsFile);
|
|
693
|
+
const baseInstructionsSrc = path.join(__dirname, '..', cli.baseInstructionsFile);
|
|
693
694
|
let content = null;
|
|
694
695
|
if (fs.existsSync(destFile)) {
|
|
695
696
|
const current = fs.readFileSync(destFile, 'utf8');
|
|
696
697
|
if (current.includes(DEVLYN_AGENTS_MARKER)) {
|
|
697
698
|
content = stripManagedBlock(current) + '\n';
|
|
699
|
+
} else {
|
|
700
|
+
log(` → Preserved existing ${cli.instructionsFile}. Compare with the bundled template at ${baseInstructionsSrc} and merge relevant instructions.`, 'dim');
|
|
698
701
|
}
|
|
699
702
|
} else {
|
|
700
|
-
const baseInstructionsSrc = path.join(__dirname, '..', cli.baseInstructionsFile);
|
|
701
703
|
if (fs.existsSync(baseInstructionsSrc)) {
|
|
702
704
|
content = fs.readFileSync(baseInstructionsSrc, 'utf8');
|
|
703
705
|
}
|