devlyn-cli 4.0.1 → 4.2.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 +11 -95
- package/CLAUDE.md +7 -160
- package/LICENSE +21 -0
- package/README.md +83 -114
- package/bin/devlyn.js +330 -472
- package/bin/instruction-templates.json +120 -2
- package/bin/instructions.js +35 -8
- package/config/skills/_shared/adapters/claude.md +8 -85
- package/config/skills/_shared/adapters/codex.md +14 -34
- package/config/skills/_shared/adapters/omp.md +1 -11
- package/config/skills/_shared/codex-monitored.sh +4 -54
- package/config/skills/_shared/engine-doctor.sh +18 -58
- package/config/skills/_shared/engine-preflight.md +15 -47
- package/config/skills/_shared/expected-contract.py +242 -0
- package/config/skills/_shared/expected.schema.json +10 -95
- package/config/skills/_shared/invocation-receipt.py +26 -757
- package/config/skills/_shared/platform-support.py +37 -28
- package/config/skills/_shared/role-config.py +100 -421
- package/config/skills/_shared/runtime-principles.md +17 -93
- package/config/skills/_shared/task-complete.py +490 -285
- package/config/skills/_shared/task-completion.md +235 -0
- package/config/skills/devlyn-engines/SKILL.md +9 -11
- package/config/skills/devlyn-ideate/SKILL.md +57 -107
- package/config/skills/devlyn-ideate/references/elicitation.md +18 -99
- package/config/skills/devlyn-ideate/references/loop.md +110 -0
- package/config/skills/devlyn-ideate/references/package-format.md +128 -0
- package/config/skills/devlyn-ideate/scripts/acceptance.py +795 -0
- package/config/skills/devlyn-ideate/scripts/queue.py +1780 -0
- package/package.json +2 -3
- package/config/commit-conventions.md +0 -28
- package/config/skills/_shared/adapters/README.md +0 -74
- package/config/skills/_shared/adapters/grok.md +0 -100
- package/config/skills/_shared/archive_run.py +0 -969
- package/config/skills/_shared/codex-config.md +0 -81
- package/config/skills/_shared/collect-codex-findings.py +0 -505
- package/config/skills/_shared/finish-gate.py +0 -521
- package/config/skills/_shared/grok-anchor-guard.py +0 -78
- package/config/skills/_shared/judge-output-parser.py +0 -200
- package/config/skills/_shared/judge-role-evidence.py +0 -320
- package/config/skills/_shared/phase-prompt-render.py +0 -183
- package/config/skills/_shared/process-evidence.py +0 -926
- package/config/skills/_shared/resolve-bootstrap.py +0 -1410
- package/config/skills/_shared/resolve-stop-hook.py +0 -359
- package/config/skills/_shared/run-bounded.py +0 -58
- package/config/skills/_shared/spec-verify-check.py +0 -5083
- package/config/skills/_shared/state-phase-write.py +0 -5989
- package/config/skills/_shared/terminal-claim-check.py +0 -777
- package/config/skills/_shared/verify-merge-findings.py +0 -3528
- package/config/skills/devlyn-design-ui/SKILL.md +0 -650
- package/config/skills/devlyn-ideate/references/from-spec-mode.md +0 -61
- package/config/skills/devlyn-ideate/references/project-mode.md +0 -80
- package/config/skills/devlyn-ideate/references/spec-template.md +0 -121
- package/config/skills/devlyn-ideate/references/templates/decision.md +0 -48
- package/config/skills/devlyn-ideate/references/templates/roadmap.md +0 -50
- package/config/skills/devlyn-ideate/references/templates/vision.md +0 -44
- package/config/skills/devlyn-queue/SKILL.md +0 -66
- package/config/skills/devlyn-queue/scripts/append.py +0 -94
- package/config/skills/devlyn-resolve/SKILL.md +0 -379
- package/config/skills/devlyn-resolve/references/free-form-mode.md +0 -71
- package/config/skills/devlyn-resolve/references/outer-loop.md +0 -23
- package/config/skills/devlyn-resolve/references/phases/build-gate.md +0 -75
- package/config/skills/devlyn-resolve/references/phases/cleanup.md +0 -33
- package/config/skills/devlyn-resolve/references/phases/implement.md +0 -44
- package/config/skills/devlyn-resolve/references/phases/plan.md +0 -39
- package/config/skills/devlyn-resolve/references/phases/probe-derive.md +0 -261
- package/config/skills/devlyn-resolve/references/phases/surface-close.md +0 -34
- package/config/skills/devlyn-resolve/references/phases/verify.md +0 -310
- package/config/skills/devlyn-resolve/references/state-schema.md +0 -152
- package/config/skills/devlyn-resolve/references/task-completion.md +0 -160
- package/config/templates/prompt-templates.md +0 -71
- package/config/templates/template-feature.spec.md +0 -255
- package/config/templates/template-product-spec.md +0 -680
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "4.0
|
|
4
|
-
"description": "Loop & harness engineering for AI coding agents (Claude Code, Codex, and any AGENTS.md-driven agent) —
|
|
3
|
+
"version": "4.2.0",
|
|
4
|
+
"description": "Loop & harness engineering for AI coding agents (Claude Code, Codex, and any AGENTS.md-driven agent) — core engineering principles for CLAUDE.md/AGENTS.md and a loop designer that splits one intent into tasks agents drain hands-free",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|
|
7
7
|
"devlyn": "bin/devlyn.js"
|
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
"loop-engineering",
|
|
40
40
|
"agent-orchestration",
|
|
41
41
|
"prompt-engineering",
|
|
42
|
-
"code-review",
|
|
43
42
|
"devlyn",
|
|
44
43
|
"developer-tools",
|
|
45
44
|
"automation",
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# Commit Conventions
|
|
2
|
-
|
|
3
|
-
Use conventional commits: `<type>: <description>` (scope optional: `<type>(<scope>): <description>`)
|
|
4
|
-
|
|
5
|
-
| Type | Use for |
|
|
6
|
-
|------------|------------------------------------------------------|
|
|
7
|
-
| `feat` | New feature |
|
|
8
|
-
| `fix` | Bug fix |
|
|
9
|
-
| `chore` | Routine tasks (deps, non-production changes) |
|
|
10
|
-
| `docs` | Documentation updates |
|
|
11
|
-
| `style` | Code style only (formatting, spacing) |
|
|
12
|
-
| `refactor` | Restructuring (no fix or feature) |
|
|
13
|
-
| `perf` | Performance improvements |
|
|
14
|
-
| `test` | Adding or updating tests |
|
|
15
|
-
| `build` | Build system or dependency changes |
|
|
16
|
-
| `ci` | CI/CD pipeline updates |
|
|
17
|
-
| `revert` | Reverting a previous commit |
|
|
18
|
-
| `temp` | Temporary changes (not for long-term merge) |
|
|
19
|
-
|
|
20
|
-
## Examples
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
feat: add user authentication
|
|
24
|
-
fix: resolve null pointer in auth middleware
|
|
25
|
-
refactor(api): simplify request validation
|
|
26
|
-
docs: update API usage guide
|
|
27
|
-
chore: upgrade next.js to v16.2
|
|
28
|
-
```
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Per-engine prompt adapters
|
|
2
|
-
|
|
3
|
-
This folder is the LLM-specific delta layer. The harness's canonical phase prompts (in each skill's `references/phases/<phase>.md`) stay model-neutral and outcome-first. Each adapter file in this folder is a **small delta header** that gets injected BEFORE the canonical body when the phase runs against that specific engine.
|
|
4
|
-
|
|
5
|
-
## Why adapters exist
|
|
6
|
-
|
|
7
|
-
Anthropic and OpenAI publish official prompt-engineering guides for their flagship models. The two guides converge on outcome-first + decision rules + mechanical validation but **diverge on tactics** (XML structure vs stop-rules format, literal interpretation vs decision-rule phrasing, self-check pattern vs validation-tool primacy). A single canonical prompt can't hit both ceilings.
|
|
8
|
-
|
|
9
|
-
The split:
|
|
10
|
-
- **Canonical body** (in `<skill>/references/phases/`) = the contract: goal, output format, invariants, common-ground rules from both guides.
|
|
11
|
-
- **Adapter header** (here) = the per-engine elaboration: model-specific guidance from that engine's official guide.
|
|
12
|
-
|
|
13
|
-
This is also the load-bearing piece for **multi-LLM evolution**. When Qwen / Gemini / Gemma are added (Mission 2/3), each gets its own adapter file here. The canonical body never moves.
|
|
14
|
-
|
|
15
|
-
## Format
|
|
16
|
-
|
|
17
|
-
Each adapter is a single markdown file named `<engine>.md`, matching the `--engine` selector value (e.g. `claude.md`, `codex.md`). Structure:
|
|
18
|
-
|
|
19
|
-
```markdown
|
|
20
|
-
# <Engine> adapter
|
|
21
|
-
|
|
22
|
-
> Source: <official-prompt-engineering-guide URL>
|
|
23
|
-
|
|
24
|
-
## Identity
|
|
25
|
-
1-2 lines telling the model who it is + which guide governs.
|
|
26
|
-
|
|
27
|
-
## Output discipline
|
|
28
|
-
Verbosity, formatting, length conventions specific to this model.
|
|
29
|
-
|
|
30
|
-
## Tool-use posture
|
|
31
|
-
When to use tools, when to reason, parallel/sequential preferences.
|
|
32
|
-
|
|
33
|
-
## Effort and autonomy
|
|
34
|
-
Optional. Model-specific guidance for effort levels or autonomous-vs-interactive runs when the vendor guide calls this out.
|
|
35
|
-
|
|
36
|
-
## Validation pattern
|
|
37
|
-
How this model verifies its work — mechanical-first vs self-check, etc.
|
|
38
|
-
|
|
39
|
-
## Anti-patterns
|
|
40
|
-
Specific patterns the official guide warns about for this model.
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Keep each section to ≤ 8 lines. Adapters are deltas, not full prompts. If an adapter grows past ~80 lines, the content probably belongs in canonical body.
|
|
44
|
-
|
|
45
|
-
## Role-scoped and non-agentic adapters
|
|
46
|
-
|
|
47
|
-
Adapters may add two more sections beyond the base format:
|
|
48
|
-
|
|
49
|
-
- **`## Role eligibility`** — fixed ASCII fields, one per line: `executor: yes|no`, `pair_judge: yes|no`. Absent section = eligible for both roles (every adapter shipped before iter-0051). Present only when a backend is structurally unable or not certified for a role — e.g. a completion-only local model has no tool/file-edit access, so it declares `executor: no`. `_shared/engine-preflight.md` and `/devlyn-engines` read this section as a structured marker, not prose, so it validates mechanically.
|
|
50
|
-
- **`## Invocation`** — for backends called over an API or CLI backends with non-default invocation contracts: the concrete request shape (endpoint, JSON body, timeout) and the adapter-declared availability probe (`_shared/engine-preflight.md#role-resolution`'s "an adapter may declare a different probe" hook).
|
|
51
|
-
|
|
52
|
-
## When to add a new adapter
|
|
53
|
-
|
|
54
|
-
A new adapter file ships when:
|
|
55
|
-
1. A new LLM is integrated into the pipeline (the engine is now invocable).
|
|
56
|
-
2. An official prompt-engineering guide for that LLM exists (or a vendor-recommended pattern set).
|
|
57
|
-
3. An empirical A/B shows the adapter's specific guidance lifts that model's performance over the canonical body alone.
|
|
58
|
-
|
|
59
|
-
Not all models need adapters. If a model performs well on the canonical body without delta, ship without one.
|
|
60
|
-
|
|
61
|
-
## What NOT to put here
|
|
62
|
-
|
|
63
|
-
- ❌ Universal rules (those go in canonical body or `_shared/runtime-principles.md`).
|
|
64
|
-
- ❌ Iter-history annotations (`*(iter-0020: F4 evidence...)*` style).
|
|
65
|
-
- ❌ Full phase prompts (defeats the decoupling).
|
|
66
|
-
- ❌ Per-task or per-spec content (adapters are model-scope, not task-scope).
|
|
67
|
-
|
|
68
|
-
## Runtime injection
|
|
69
|
-
|
|
70
|
-
A skill's phase invocation prepends the resolved engine's adapter file to the canonical body before sending. Mechanism is left to each skill (a `_shared/adapter-inject.sh` helper may land in a later iter); for now, skills consume the adapter file by direct read at phase-spawn time.
|
|
71
|
-
|
|
72
|
-
## Standing rule
|
|
73
|
-
|
|
74
|
-
Any iter that touches an adapter file MUST cite the corresponding official guide as part of acceptance: "guide section X.Y says Z, this change applies Z." Generic preferences ("feels cleaner") are rejected.
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
# Grok adapter
|
|
2
|
-
|
|
3
|
-
## Role eligibility
|
|
4
|
-
|
|
5
|
-
executor: no
|
|
6
|
-
pair_judge: yes
|
|
7
|
-
|
|
8
|
-
Certification status: the pair-judge seat is wired, reachable, and probe-capable, but not emission-certified; isolation has three independent invariants — tool callability, MCP connection/enumeration, and context injection — and only P-0080-C can certify them; the doctor cannot. Before this change, the shipped recipe connected 65 MCP tools and injected both an MCP reminder and a plugin-skills reminder into the judge's conversation; a durable `pair grok` pin remains gated on follow-up emission registration and the standing seat-fitness rule.
|
|
9
|
-
|
|
10
|
-
## Invocation
|
|
11
|
-
|
|
12
|
-
**Availability probe**: `command -v grok >/dev/null 2>&1`; record
|
|
13
|
-
`grok --version` as evidence. The probe is necessary, not sufficient: auth or
|
|
14
|
-
wrapper failures after it passes are the same fail-closed availability class as
|
|
15
|
-
a failed probe (`BLOCKED:grok-unavailable` for an explicit route; an automatic
|
|
16
|
-
escalation remains a reported solo skip).
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
# $ISO_HOME = ephemeral dir seeded with a copied auth.json + agent_id, and a
|
|
20
|
-
# config.toml containing:
|
|
21
|
-
# [plugins]
|
|
22
|
-
# disabled = ["telegram", "vercel"]
|
|
23
|
-
# enabled = []
|
|
24
|
-
#
|
|
25
|
-
# [skills]
|
|
26
|
-
# ignore = ["~/.agents", "~/.claude", "~/.cursor"]
|
|
27
|
-
# plus $ISO_HOME/hooks/anchor-guard.json. grok reads that file as JSON, not
|
|
28
|
-
# through a shell, so its "command" must carry an ALREADY-EXPANDED path:
|
|
29
|
-
# {"hooks":{"PreToolUse":[{"hooks":[{"type":"command",
|
|
30
|
-
# "command":"python3 /abs/path/to/_shared/grok-anchor-guard.py","timeout":10}]}]}}
|
|
31
|
-
# $NEUTRAL = empty dir outside any git repo
|
|
32
|
-
# $REPO = absolute repo root (redirects MUST be absolute — cwd is $NEUTRAL)
|
|
33
|
-
cd "$NEUTRAL"
|
|
34
|
-
HOME="$NEUTRAL" ZDOTDIR="$NEUTRAL" GROK_HOME="$ISO_HOME" \
|
|
35
|
-
DEVLYN_PROBE_ANCHOR="<the bare anchor, derived exactly as the --allow rule below>" \
|
|
36
|
-
GROK_CLAUDE_MCPS_ENABLED=false GROK_CURSOR_MCPS_ENABLED=false \
|
|
37
|
-
GROK_CLAUDE_SKILLS_ENABLED=false GROK_CURSOR_SKILLS_ENABLED=false \
|
|
38
|
-
GROK_CLAUDE_HOOKS_ENABLED=false GROK_CURSOR_HOOKS_ENABLED=false \
|
|
39
|
-
GROK_CLAUDE_AGENTS_ENABLED=false GROK_CLAUDE_RULES_ENABLED=false \
|
|
40
|
-
GROK_MEMORY=0 \
|
|
41
|
-
python3 "$DEVLYN_SHARED_DIR/run-bounded.py" 600 -- grok -p "<judge prompt>" \
|
|
42
|
-
--permission-mode dontAsk --no-memory \
|
|
43
|
-
--tools "read_file,grep,list_dir,run_terminal_cmd" \
|
|
44
|
-
--disallowed-tools "Agent,use_tool,search_tool" \
|
|
45
|
-
--allow 'Bash(<the bare anchor>)' \
|
|
46
|
-
--reasoning-effort medium \
|
|
47
|
-
--output-format streaming-messages-json \
|
|
48
|
-
> "$REPO/.devlyn/grok-judge.stdout" 2> "$REPO/.devlyn/grok-judge.stderr"
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
Copy `auth.json` into `$ISO_HOME` for every run and seed its `config.toml` with
|
|
52
|
-
the shown `[plugins]` and `[skills] ignore` entries and its
|
|
53
|
-
`hooks/anchor-guard.json` with the shown `PreToolUse` entry. Before launch, create
|
|
54
|
-
`$NEUTRAL/.zshenv` containing `export HOME=<the operator's real home>`.
|
|
55
|
-
Both overrides are needed because grok scans `~/.claude.json` from `$HOME`,
|
|
56
|
-
while zsh reads rc files from `$ZDOTDIR`, which is exported in some environments.
|
|
57
|
-
`$NEUTRAL` and `$ISO_HOME` must be on paths that do not embed a project or repo identifier.
|
|
58
|
-
`--permission-mode plan` is forbidden headless because it silently blocks
|
|
59
|
-
all tools and returns an empty review; `--always-approve` is banned because it
|
|
60
|
-
auto-approves writes. `--tools` and `--disallowed-tools` are headless-only (the
|
|
61
|
-
TUI warns and ignores them); when both are present, the disallow list wins and
|
|
62
|
-
removes tools entirely rather than merely gating execution.
|
|
63
|
-
|
|
64
|
-
Never use `--json-schema` for the pair judge: measured runs degraded the
|
|
65
|
-
tool-use loop (2/3 made zero tool calls and fabricated findings), and a
|
|
66
|
-
`Cancelled` run emitted a PASS-shaped payload after its schema had failed.
|
|
67
|
-
|
|
68
|
-
The judge prompt must name the exact permitted command(s). Derive the prompt
|
|
69
|
-
anchor and allow-list string identically from one source, in this precedence:
|
|
70
|
-
the backticked commands in the spec's `## Verification` bullets;
|
|
71
|
-
otherwise the repo's existing test/CLI runner. If none exists, the probe
|
|
72
|
-
obligation does not arise and a static review is correct for that spec.
|
|
73
|
-
The documented `Bash(<command>)` form matches the exact command or its prefix;
|
|
74
|
-
the trailing ` *` form fails a no-argument command.
|
|
75
|
-
Under `dontAsk`, every allow shape tested for a chained command — including an
|
|
76
|
-
exact full-string rule for the chain — returned `PermissionCancelled`, so the
|
|
77
|
-
mandatory dominance-loss anchor must run unchained with the allow rule scoped
|
|
78
|
-
to that bare anchor.
|
|
79
|
-
|
|
80
|
-
Grok's deny semantics are not Claude-parity: reaching the permission mode's
|
|
81
|
-
auto-deny silently truncates the review at exit 0. On the configured, measured
|
|
82
|
-
path the `PreToolUse` hook above keeps the judge from reaching it — the hook runs
|
|
83
|
-
at step 1, before the rules and before the mode policy, and returns the denial as
|
|
84
|
-
a model-visible `tool_result`.
|
|
85
|
-
It admits the bare anchor and anchor-plus-argv, and vetoes any character that
|
|
86
|
-
could start a second command, so `verify.md`'s bounded input variations survive
|
|
87
|
-
while chaining does not. The hook fails open, so the collector rejection remains
|
|
88
|
-
the fail-closed floor: treat it as `BLOCKED` for
|
|
89
|
-
`verify.pair.emission-contract`, never PASS. After a non-timeout spawn, run:
|
|
90
|
-
|
|
91
|
-
```bash
|
|
92
|
-
python3 "$DEVLYN_SHARED_DIR/collect-codex-findings.py" \
|
|
93
|
-
--devlyn-dir "$REPO/.devlyn" \
|
|
94
|
-
--stdout-file grok-judge.stdout
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
On exit 124, write `.devlyn/verify.pair.timeout.json` with
|
|
98
|
-
`{"engine": "grok", "budget_seconds": 600}` before merge. A budget abort can
|
|
99
|
-
leave the stream truncated before its terminal `result` record; that capture
|
|
100
|
-
stays `TIMEOUT` at merge, never a pair PASS.
|