@azure-id/orc 2.0.2 → 2.1.1
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/CHANGELOG.md +455 -0
- package/README-id.md +52 -23
- package/README.md +36 -20
- package/bin/build-agents.js +205 -206
- package/bin/clear-logs.js +620 -0
- package/bin/cli.js +47417 -46420
- package/bin/fix.js +459 -0
- package/bin/gotcha.js +288 -8
- package/bin/habit.js +1538 -1453
- package/bin/mockrun-catalog.js +3 -0
- package/bin/onboarding-content.js +2 -1
- package/bin/pricing.json +28 -21
- package/bin/trace-write.js +869 -657
- package/bin/verify-contracts.js +5552 -5471
- package/bin/verify-package.js +716 -705
- package/bin/webui/api.js +125 -6
- package/bin/webui/css/panels/hookui.css +79 -0
- package/bin/webui/fixtures/behaviour.js +30 -0
- package/bin/webui/fixtures/extra.js +2036 -2036
- package/bin/webui/fixtures/flow.js +81 -81
- package/bin/webui/fixtures/hookui.js +506 -431
- package/bin/webui/fixtures/index.js +32 -3
- package/bin/webui/fixtures/knowledge.js +2 -2
- package/bin/webui/fixtures/maintenance.js +123 -42
- package/bin/webui/fixtures/rules.js +1007 -1002
- package/bin/webui/fixtures/settings.js +6 -7
- package/bin/webui/fixtures/stats.js +9 -6
- package/bin/webui/fixtures/wait.js +98 -97
- package/bin/webui/i18n/en/behaviour.json +13 -0
- package/bin/webui/i18n/en/hookui.json +290 -194
- package/bin/webui/i18n/en/maintenance.json +71 -52
- package/bin/webui/i18n/en/settings.json +60 -60
- package/bin/webui/i18n/id/behaviour.json +13 -0
- package/bin/webui/i18n/id/hookui.json +290 -194
- package/bin/webui/i18n/id/maintenance.json +71 -52
- package/bin/webui/i18n/id/settings.json +60 -60
- package/bin/webui/js/05-banners.js +181 -172
- package/bin/webui/js/06-edit.js +193 -183
- package/bin/webui/js/panels/behaviour.js +77 -12
- package/bin/webui/js/panels/hookui.js +2196 -1691
- package/bin/webui/js/panels/maintenance.js +336 -235
- package/bin/webui/js/panels/settings.js +726 -719
- package/mock-run/INDEX.md +1 -0
- package/mock-run/a-normal-day.md +2 -2
- package/mock-run/extra-slots.md +177 -177
- package/mock-run/habits.md +1 -1
- package/mock-run/orc-aftermath.md +392 -392
- package/mock-run/orc-budget.md +29 -33
- package/mock-run/orc-cli.md +200 -200
- package/mock-run/orc-explain.md +86 -86
- package/mock-run/orc-extra.md +389 -392
- package/mock-run/orc-fast.md +2 -2
- package/mock-run/orc-fix.md +87 -0
- package/mock-run/orc-pattern.md +112 -112
- package/mock-run/orc-quick.md +146 -146
- package/mock-run/orc.md +4 -4
- package/package.json +1 -1
- package/templates/agents/MODEL-MAPPING.md +176 -173
- package/templates/agents/orc-analyze-mini-sonnet-5-high.md +2 -2
- package/templates/agents/{orc-claude-writer-opus-5-med.md → orc-claude-writer-opus-5-low.md} +4 -4
- package/templates/agents/orc-executor-haiku-4-5.md +1 -1
- package/templates/agents/orc-executor-opus-5-low.md +1 -1
- package/templates/agents/orc-executor-sonnet-4-6-high.md +1 -1
- package/templates/agents/orc-executor-sonnet-4-6-med.md +1 -1
- package/templates/agents/orc-executor-sonnet-5-high.md +2 -2
- package/templates/agents/orc-executor-sonnet-5-low.md +155 -0
- package/templates/agents/orc-executor-sonnet-5-med.md +155 -0
- package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +2 -2
- package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -2
- package/templates/agents/{orc-recon-sonnet-4-6-med.md → orc-recon-sonnet-5-med.md} +4 -4
- package/templates/agents/orc-retro-sonnet-5-high.md +2 -2
- package/templates/agents/{orc-reviewer-opus-5-med.md → orc-reviewer-opus-5-low.md} +4 -4
- package/templates/agents/{orc-wiki-scanner-opus-5-med.md → orc-wiki-scanner-opus-5-low.md} +3 -3
- package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +2 -2
- package/templates/commands/orc-fast.md +10 -10
- package/templates/commands/orc-fix.md +18 -0
- package/templates/commands/orc-wiki.md +64 -64
- package/templates/hooks/README.md +75 -7
- package/templates/hooks/orc-session-hook.js +78 -3
- package/templates/hooks/orc-statusline-render.js +317 -23
- package/templates/hooks/orc-statusline.js +162 -49
- package/templates/hooks/orc-subagent-line.js +23 -5
- package/templates/hooks/orc-weather-fetch.js +123 -0
- package/templates/skills/_shared/extra-dispatch.md +1331 -1331
- package/templates/skills/_shared/gotchas.md +27 -7
- package/templates/skills/_shared/habits.md +2 -2
- package/templates/skills/_shared/opus5-only.md +137 -137
- package/templates/skills/_shared/phases/review.md +2 -2
- package/templates/skills/_shared/phases/trace-verbs.md +17 -3
- package/templates/skills/_shared/phases/trace.md +136 -136
- package/templates/skills/_shared/review-slice.md +28 -1
- package/templates/skills/_shared/wait.md +1 -0
- package/templates/skills/orc/README.md +2 -2
- package/templates/skills/orc/SKILL.md +227 -227
- package/templates/skills/orc/config.md +25 -27
- package/templates/skills/orc/examples/full-run-mock.md +74 -73
- package/templates/skills/orc/references/effort-and-mode.md +222 -222
- package/templates/skills/orc/references/preflight-report.md +3 -3
- package/templates/skills/orc/references/ultra-mode.md +1 -1
- package/templates/skills/orc/schemas/checkpoint.md +122 -122
- package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +3 -3
- package/templates/skills/orc/subskills/orc-review-verify/core.md +1 -1
- package/templates/skills/orc-analyze/SKILL.md +4 -2
- package/templates/skills/orc-claude/SKILL.md +14 -14
- package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -65
- package/templates/skills/orc-diy/SKILL.md +5 -5
- package/templates/skills/orc-fast/SKILL.md +210 -208
- package/templates/skills/orc-fix/SKILL.md +110 -0
- package/templates/skills/orc-grill/SKILL.md +232 -232
- package/templates/skills/orc-grill/references/grill-doc.md +1 -1
- package/templates/skills/orc-mini/SKILL.md +4 -4
- package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -2
- package/templates/skills/orc-quick/README.md +536 -536
- package/templates/skills/orc-quick/SKILL.md +2 -2
- package/templates/skills/orc-quick/references/context-doc.md +145 -145
- package/templates/skills/orc-quick/references/dispatch-gate.md +220 -219
- package/templates/skills/orc-quick/references/gh-mode.md +4 -2
- package/templates/skills/orc-retro/SKILL.md +1 -1
- package/templates/skills/orc-retro/examples/retro-mock.md +16 -16
- package/templates/skills/orc-wiki/README.md +325 -325
- package/templates/skills/orc-wiki/SKILL.md +195 -195
- package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -37
- package/templates/skills/orc-wiki/references/extra.md +2 -2
- package/templates/skills/orc-wiki/references/partial-refresh.md +276 -271
- package/templates/skills/orc-wiki/references/phases/phase-0.md +1 -1
- package/templates/skills/orc-wiki/references/phases/phase-2.md +3 -3
- package/templates/skills/orc-wiki/references/phases/phase-3c.md +3 -2
- package/templates/agents/orc-claude-writer-opus-4-8-high.md +0 -48
- package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +0 -74
package/README.md
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
*Intake → analyze → plan → score → parallel subagents → review → verify → ship.*
|
|
8
8
|
|
|
9
9
|

|
|
10
|
-

|
|
11
11
|

|
|
12
12
|

|
|
13
13
|

|
|
14
14
|

|
|
15
15
|

|
|
16
16
|
|
|
17
|
-
**Latest: v2.
|
|
17
|
+
**Latest: v2.1.1** · updated 02-10-2026 · [full changelog](CHANGELOG.md)
|
|
18
18
|
|
|
19
19
|
**On npm: [`@azure-id/orc`](https://www.npmjs.com/package/@azure-id/orc)** — `npm i -g @azure-id/orc`
|
|
20
20
|
|
|
@@ -255,6 +255,7 @@ ORC have terminal hook to see: Context Window %, 5 Hour usage %, Weekly usage %
|
|
|
255
255
|
| **`/orc-fast`** | The fastest lane. Needs a fresh wiki **and** a cached code pattern; then it skips the analyst and planner entirely. A missing prerequisite falls back to `/orc-mini` — the chat never stops. | [see it](mock-run/orc-fast.md) |
|
|
256
256
|
| **`/orc-quick`** | Ask for anything: a fix, a question, a defect hunt, a dependency bump, PR comments. Look → ask once → do. **It always asks which agent to dispatch**, and no setting can change that. A defect is **reproduced red before it is fixed**. | [see it](mock-run/orc-quick.md) |
|
|
257
257
|
| **`/orc-wait`** | Wall-clock pause without losing the run. You see the window is nearly full, type `/orc-wait 30`, and ORC hands the run back to disk, waits in detached hops that **cost zero tokens**, and picks up where it stopped. Three modes decide how much finishes first: `safe` · `soft` (forces the checkpoint) · `hard` (fastest, can lose an in-flight return). `/orc-wait block <reason>` tells it not to stop you at all. | — |
|
|
258
|
+
| **`/orc-fix`** | Fix one thing after a review: a Sonar issue, a red CI, a bug someone found. Inside a paused run it only **records** the fix (one observation and one `FIX` line in that run's trace), so the review that missed it is counted. With no run open, it fixes like `/orc-quick` and asks which agent to use. | [see it](mock-run/orc-fix.md) |
|
|
258
259
|
| **`/orc-diy`** | Your own lane, composed in the terminal with `orc diy` and compiled. Unconfigured or stale → it refuses and offers plain `/orc`. | [see it](mock-run/orc-diy.md) |
|
|
259
260
|
|
|
260
261
|
### Work out what to build
|
|
@@ -617,8 +618,18 @@ fixed published formula turns them into a number. A cited risk forces a floor of
|
|
|
617
618
|
70. The score maps through a published table to a **named, model-pinned agent**,
|
|
618
619
|
so what ran is inspectable rather than requested in prose.
|
|
619
620
|
|
|
621
|
+
The default table (since v2.1.0):
|
|
622
|
+
|
|
623
|
+
| Score | Agent | Model · effort |
|
|
624
|
+
|---|---|---|
|
|
625
|
+
| `[0,21)` | `orc-executor-sonnet-5-low` | Sonnet 5 · low |
|
|
626
|
+
| `[21,31)` | `orc-executor-sonnet-5-med` | Sonnet 5 · medium |
|
|
627
|
+
| `[31,41)` | `orc-executor-sonnet-5-high` | Sonnet 5 · high |
|
|
628
|
+
| `[41,90)` | `orc-executor-opus-5-low` | Opus 5.5 · low |
|
|
629
|
+
| `[90,100]` | `orc-executor-opus-5-med` | Opus 5.5 · medium |
|
|
630
|
+
|
|
620
631
|
> **The rule that catches everyone:** a subagent's model can never be higher than
|
|
621
|
-
> your main session's.
|
|
632
|
+
> your main session's. Every band from score 41 needs an Opus 5.5 main session.
|
|
622
633
|
|
|
623
634
|
**Full detail — the bands, `opus5_only`, and the tier guard `orc init` installs:
|
|
624
635
|
[guides/model-selection.md](guides/model-selection.md).**
|
|
@@ -649,13 +660,13 @@ clobbers. `orc ui` ▸ Settings edits the same keys through the same validators.
|
|
|
649
660
|
|
|
650
661
|
```
|
|
651
662
|
templates/
|
|
652
|
-
├── skills/
|
|
663
|
+
├── skills/ 34 skill folders, 41 SKILL.md files (a lane may ship subskills) —
|
|
653
664
|
│ the lanes above, plus the ones with no command of their own:
|
|
654
665
|
│ context-combiner, orc-advisor, orc-judge, orc-analyze-mini,
|
|
655
666
|
│ and _shared/ (cross-lane contract prose)
|
|
656
|
-
├── commands/
|
|
667
|
+
├── commands/ 33 slash commands
|
|
657
668
|
├── hooks/ effort guard (PreToolUse) · statusline warning · behavior trace
|
|
658
|
-
└── agents/
|
|
669
|
+
└── agents/ 50 model-pinned subagents + MODEL-MAPPING.md
|
|
659
670
|
bin/cli.js installer, config editor, flow composer, run-state reader, and
|
|
660
671
|
the deterministic half of every lane. Every read speaks --json
|
|
661
672
|
bin/graph*.js the code graph: store, extraction, resolution + its cache and
|
|
@@ -730,25 +741,30 @@ a current audit: [EVAL-REPORT.md](EVAL-REPORT.md).
|
|
|
730
741
|
**Full history: [CHANGELOG.md](CHANGELOG.md)** — or `orc changelog`, which prints
|
|
731
742
|
only what is newer than the version you have.
|
|
732
743
|
|
|
733
|
-
### v2.
|
|
734
|
-
|
|
735
|
-
**A patch from the live evals.** Habits now really work in a live run, and the reviewer
|
|
736
|
-
always gets its card:
|
|
744
|
+
### v2.1.1 — the quick and fast lanes move to Sonnet 5 _(2026-10-02)_
|
|
737
745
|
|
|
738
|
-
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
-
|
|
742
|
-
|
|
743
|
-
-
|
|
744
|
-
|
|
745
|
-
- **The
|
|
746
|
+
- **`/orc-quick` offers Sonnet 5 medium and Opus 5.5 low.** For code:
|
|
747
|
+
`orc-executor-sonnet-5-med` or `orc-executor-opus-5-low`. For a question:
|
|
748
|
+
`orc-recon-sonnet-5-med` or `orc-recon-opus-5-low`.
|
|
749
|
+
- **`/orc-fast` uses `orc-executor-sonnet-5-med`** (it used Sonnet 4.6 high). Run it
|
|
750
|
+
from a Sonnet 5 or Opus main session.
|
|
751
|
+
- **`/orc` examples and the "cheap subagent" rule name Sonnet 5.** Sonnet 4.6 stays
|
|
752
|
+
only for the graph noter, the scout, `orc diy` choices and opt-in names.
|
|
753
|
+
- **The recon agent has a new name:** `orc-recon-sonnet-4-6-med` →
|
|
754
|
+
`orc-recon-sonnet-5-med`.
|
|
755
|
+
- **`orc extra`:** the `quick-executor` slot uses `orc-executor-sonnet-5-med`. The
|
|
756
|
+
`extra_fallback_agent` options show `orc-executor-sonnet-5-high` (not Sonnet 4.6).
|
|
746
757
|
|
|
747
|
-
**What you have to do:** `orc update`.
|
|
758
|
+
**What you have to do:** `orc update --prune`. If a script names
|
|
759
|
+
`orc-recon-sonnet-4-6-med`, change it to `orc-recon-sonnet-5-med`.
|
|
748
760
|
|
|
749
761
|
<details>
|
|
750
|
-
<summary><strong>Earlier releases</strong> —
|
|
762
|
+
<summary><strong>Earlier releases</strong> — 128 of them, titles only. Full text in <a href="CHANGELOG.md">CHANGELOG.md</a>.</summary>
|
|
751
763
|
|
|
764
|
+
- **v2.1.0** — the review counts, the score table moves up, and old logs can go · _2026-10-02_
|
|
765
|
+
- **v2.0.4** — design the status line to the last cell · _2026-09-30_
|
|
766
|
+
- **v2.0.3** — the status line you designed is the status line you see · _2026-09-30_
|
|
767
|
+
- **v2.0.2** — the lanes record what you answered, and the reviewer always gets the card · _2026-09-28_
|
|
752
768
|
- **v2.0.1** — the trace keeps the gate name, and the lanes find the habits rule · _2026-09-27_
|
|
753
769
|
- **v2.0.0** — the coding lanes remember what you fixed and how you work · _2026-09-27_
|
|
754
770
|
- **v1.9.2** — the code graph gets its own tab, and Opus 5 becomes Opus 5.5 · _2026-09-23_
|
package/bin/build-agents.js
CHANGED
|
@@ -1,206 +1,205 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
/**
|
|
4
|
-
* Agent generator. Two sets, one rule: a file that differs from its siblings
|
|
5
|
-
* ONLY in frontmatter and the "You are … (<model>, <effort>)" line is GENERATED.
|
|
6
|
-
*
|
|
7
|
-
* 1. The 10 executors — agents-src/executor.template.md × VARIANTS
|
|
8
|
-
* (name/model/effort + score band).
|
|
9
|
-
* 2. The 8 model-twin pairs (v2.0.0 T15) — agents-src/twins/<family>.template.md
|
|
10
|
-
* × TWINS (name/model/effort/description + the `who` line). One body per
|
|
11
|
-
* family: before T15 each pair was two hand-kept copies that nothing
|
|
12
|
-
* checked against each other.
|
|
13
|
-
*
|
|
14
|
-
* Edit the template (or the table), run `npm run build:agents`, and every copy
|
|
15
|
-
* is stamped out identically. A model change is still a RENAME: a new row, not
|
|
16
|
-
* an edited one.
|
|
17
|
-
*
|
|
18
|
-
* Modes:
|
|
19
|
-
* node bin/build-agents.js write both sets into templates/agents/
|
|
20
|
-
* node bin/build-agents.js --check fail if any generated file drifted from
|
|
21
|
-
* its template (runs in `npm run verify`
|
|
22
|
-
* and prepack — a hand-edit to a generated
|
|
23
|
-
* agent file fails the build)
|
|
24
|
-
*/
|
|
25
|
-
const fs = require("fs");
|
|
26
|
-
const path = require("path");
|
|
27
|
-
|
|
28
|
-
const ROOT = path.join(__dirname, "..");
|
|
29
|
-
const TEMPLATE = path.join(ROOT, "agents-src", "executor.template.md");
|
|
30
|
-
const OUT_DIR = path.join(ROOT, "templates", "agents");
|
|
31
|
-
|
|
32
|
-
// Score→model bands mirror templates/agents/MODEL-MAPPING.md and the single
|
|
33
|
-
// score→model table in skills/orc/config.md (documented drift — change
|
|
34
|
-
// together). `effort: null` = a model with NO effort ladder (haiku): the
|
|
35
|
-
// generator omits the `effort:` frontmatter line entirely.
|
|
36
|
-
//
|
|
37
|
-
// v1.0.0 W4 — the table
|
|
38
|
-
// TWO, not three.
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
{ name: "orc-executor-opus-5-
|
|
48
|
-
{ name: "orc-executor-
|
|
49
|
-
{ name: "orc-executor-sonnet-
|
|
50
|
-
{ name: "orc-executor-sonnet-
|
|
51
|
-
{ name: "orc-executor-
|
|
52
|
-
// NAMED BY NO BAND since v1.0.0 W4 (D14) — kept on disk, dispatched
|
|
53
|
-
// user names one explicitly.
|
|
54
|
-
{ name: "orc-executor-
|
|
55
|
-
{ name: "orc-executor-
|
|
56
|
-
{ name: "orc-executor-
|
|
57
|
-
{ name: "orc-executor-opus-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.replace(/\{\{
|
|
132
|
-
.replace(/\{\{
|
|
133
|
-
.replace(/\{\{
|
|
134
|
-
.replace(/\{\{
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
.replace(/\{\{
|
|
141
|
-
.replace(/\{\{
|
|
142
|
-
.replace(/\{\{
|
|
143
|
-
.replace(/\{\{
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
`
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (require.main === module) main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Agent generator. Two sets, one rule: a file that differs from its siblings
|
|
5
|
+
* ONLY in frontmatter and the "You are … (<model>, <effort>)" line is GENERATED.
|
|
6
|
+
*
|
|
7
|
+
* 1. The 10 executors — agents-src/executor.template.md × VARIANTS
|
|
8
|
+
* (name/model/effort + score band).
|
|
9
|
+
* 2. The 8 model-twin pairs (v2.0.0 T15) — agents-src/twins/<family>.template.md
|
|
10
|
+
* × TWINS (name/model/effort/description + the `who` line). One body per
|
|
11
|
+
* family: before T15 each pair was two hand-kept copies that nothing
|
|
12
|
+
* checked against each other.
|
|
13
|
+
*
|
|
14
|
+
* Edit the template (or the table), run `npm run build:agents`, and every copy
|
|
15
|
+
* is stamped out identically. A model change is still a RENAME: a new row, not
|
|
16
|
+
* an edited one.
|
|
17
|
+
*
|
|
18
|
+
* Modes:
|
|
19
|
+
* node bin/build-agents.js write both sets into templates/agents/
|
|
20
|
+
* node bin/build-agents.js --check fail if any generated file drifted from
|
|
21
|
+
* its template (runs in `npm run verify`
|
|
22
|
+
* and prepack — a hand-edit to a generated
|
|
23
|
+
* agent file fails the build)
|
|
24
|
+
*/
|
|
25
|
+
const fs = require("fs");
|
|
26
|
+
const path = require("path");
|
|
27
|
+
|
|
28
|
+
const ROOT = path.join(__dirname, "..");
|
|
29
|
+
const TEMPLATE = path.join(ROOT, "agents-src", "executor.template.md");
|
|
30
|
+
const OUT_DIR = path.join(ROOT, "templates", "agents");
|
|
31
|
+
|
|
32
|
+
// Score→model bands mirror templates/agents/MODEL-MAPPING.md and the single
|
|
33
|
+
// score→model table in skills/orc/config.md (documented drift — change
|
|
34
|
+
// together). `effort: null` = a model with NO effort ladder (haiku): the
|
|
35
|
+
// generator omits the `effort:` frontmatter line entirely.
|
|
36
|
+
//
|
|
37
|
+
// v1.0.0 W4 — the table was SIX bands, not eight, and the `opus5_only` ladder is
|
|
38
|
+
// TWO, not three. v2.1.0 made the table FIVE bands (Sonnet 5 low/med/high, then
|
|
39
|
+
// Opus 5.5 low/med). Seven of these agents are named by NO default row:
|
|
40
|
+
// names them, and they ship anyway (D14). They stay reachable through
|
|
41
|
+
// `rubric_bands_override`, `orc diy` `fixed_executor` and `extra_fallback_agent`,
|
|
42
|
+
// and deleting a generated file that no row happens to name today would be a
|
|
43
|
+
// rename-shaped migration for what is only a table change. Their `band` string
|
|
44
|
+
// says so rather than naming a range that no longer exists — a band label that
|
|
45
|
+
// lies is worse than one that admits it is unreachable by default.
|
|
46
|
+
const VARIANTS = [
|
|
47
|
+
{ name: "orc-executor-opus-5-med", model: "claude-opus-5-5", effort: "medium", band: "highest-complexity [90,100]" },
|
|
48
|
+
{ name: "orc-executor-opus-5-low", model: "claude-opus-5-5", effort: "low", band: "upper-complexity [41,90)" },
|
|
49
|
+
{ name: "orc-executor-sonnet-5-high", model: "claude-sonnet-5-5", effort: "high", band: "mid-complexity [31,41)" },
|
|
50
|
+
{ name: "orc-executor-sonnet-5-med", model: "claude-sonnet-5-5", effort: "medium", band: "low-complexity [21,31)" },
|
|
51
|
+
{ name: "orc-executor-sonnet-5-low", model: "claude-sonnet-5-5", effort: "low", band: "lowest-complexity [0,21)" },
|
|
52
|
+
// NAMED BY NO BAND since v1.0.0 W4 / v2.1.0 (D14) — kept on disk, dispatched
|
|
53
|
+
// only when a user names one explicitly.
|
|
54
|
+
{ name: "orc-executor-sonnet-4-6-high", model: "claude-sonnet-4-6", effort: "high", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
55
|
+
{ name: "orc-executor-sonnet-4-6-med", model: "claude-sonnet-4-6", effort: "medium", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
56
|
+
{ name: "orc-executor-haiku-4-5", model: "claude-haiku-4-5", effort: null, band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
57
|
+
{ name: "orc-executor-opus-5-high", model: "claude-opus-5-5", effort: "high", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
58
|
+
{ name: "orc-executor-opus-4-8-high", model: "claude-opus-4-8", effort: "high", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
59
|
+
{ name: "orc-executor-opus-4-7-high", model: "claude-opus-4-7", effort: "high", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
60
|
+
{ name: "orc-executor-opus-4-7-med", model: "claude-opus-4-7", effort: "medium", band: "none (opt-in only, see MODEL-MAPPING.md)" },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
// v2.0.0 T15 — the model twins. Each family is one template under
|
|
64
|
+
// agents-src/twins/; a row fills five placeholders: {{NAME}}, {{MODEL}},
|
|
65
|
+
// {{EFFORT}}, {{DESC}} (the one-line frontmatter description) and {{WHO}} (the
|
|
66
|
+
// "(Sonnet 5, high)" part of the "You are …" line — absent for a family whose
|
|
67
|
+
// body never names its own model). The pair is a runtime choice (`opus5_only`,
|
|
68
|
+
// the recon gate, the wiki tier ladder), so both halves always ship.
|
|
69
|
+
const TWIN_DIR = path.join(ROOT, "agents-src", "twins");
|
|
70
|
+
const TWINS = [
|
|
71
|
+
{ family: "analyze-mini", variants: [
|
|
72
|
+
{ name: "orc-analyze-mini-sonnet-5-high", model: "claude-sonnet-5-5", effort: "high", who: "Sonnet 5, high",
|
|
73
|
+
desc: "ORC mini System Analyst — claude-sonnet-5-5, high effort. Dispatched by /orc-mini and /orc-analyze-mini at analysis: single pass, no deep mode, no scouts." },
|
|
74
|
+
{ name: "orc-analyze-mini-opus-5-med", model: "claude-opus-5-5", effort: "medium", who: "Opus 5.5, medium",
|
|
75
|
+
desc: "ORC mini System Analyst — claude-opus-5-5, medium effort. Dispatched by /orc-mini and /orc-analyze-mini, instead of orc-analyze-mini-sonnet-5-high when `opus5_only: true`." },
|
|
76
|
+
] },
|
|
77
|
+
{ family: "planner-mini", variants: [
|
|
78
|
+
{ name: "orc-planner-mini-sonnet-5-high", model: "claude-sonnet-5-5", effort: "high", who: "Sonnet 5, high",
|
|
79
|
+
desc: "ORC mini Requirement Planner — claude-sonnet-5-5, high effort. Dispatched by /orc-mini at planning." },
|
|
80
|
+
{ name: "orc-planner-mini-opus-5-med", model: "claude-opus-5-5", effort: "medium", who: "Opus 5.5, medium",
|
|
81
|
+
desc: "ORC mini Requirement Planner — claude-opus-5-5, medium effort. Dispatched by /orc-mini at planning, instead of orc-planner-mini-sonnet-5-high when `opus5_only: true`." },
|
|
82
|
+
] },
|
|
83
|
+
{ family: "pattern-codifier", variants: [
|
|
84
|
+
{ name: "orc-pattern-codifier-sonnet-5-high", model: "claude-sonnet-5-5", effort: "high",
|
|
85
|
+
desc: "ORC Pattern Codifier — claude-sonnet-5-5, high effort. Dispatched by orc-pattern (lazy /orc miss, eager orc-wiki, or manual /orc-pattern) for ONE language." },
|
|
86
|
+
{ name: "orc-pattern-codifier-opus-5-med", model: "claude-opus-5-5", effort: "medium",
|
|
87
|
+
desc: "ORC Pattern Codifier — claude-opus-5-5, medium effort. Dispatched by orc-pattern, instead of orc-pattern-codifier-sonnet-5-high when `opus5_only: true`." },
|
|
88
|
+
] },
|
|
89
|
+
{ family: "recon", variants: [
|
|
90
|
+
{ name: "orc-recon-sonnet-5-med", model: "claude-sonnet-5-5", effort: "medium", who: "Sonnet 5, medium",
|
|
91
|
+
desc: "ORC Recon — claude-sonnet-5-5, medium effort. Dispatched by /orc-quick at the dispatch gate, for a read-only question. It never edits." },
|
|
92
|
+
{ name: "orc-recon-opus-5-low", model: "claude-opus-5-5", effort: "low", who: "Opus 5.5, low",
|
|
93
|
+
desc: "ORC Recon — claude-opus-5-5, low effort. Dispatched by /orc-quick at the dispatch gate, for a WIDE or SUBTLE read-only question. It never edits." },
|
|
94
|
+
] },
|
|
95
|
+
{ family: "retro", variants: [
|
|
96
|
+
{ name: "orc-retro-sonnet-5-high", model: "claude-sonnet-5-5", effort: "high", who: "Sonnet 5, high",
|
|
97
|
+
desc: "ORC Retro miner — claude-sonnet-5-5, high effort. Dispatched by /orc-retro to mine the behavior traces. Read-only, report-only." },
|
|
98
|
+
{ name: "orc-retro-opus-5-med", model: "claude-opus-5-5", effort: "medium", who: "Opus 5.5, medium",
|
|
99
|
+
desc: "ORC Retro miner — claude-opus-5-5, medium effort. Dispatched by /orc-retro, instead of orc-retro-sonnet-5-high when `opus5_only: true`. Read-only." },
|
|
100
|
+
] },
|
|
101
|
+
{ family: "scout", variants: [
|
|
102
|
+
{ name: "orc-scout-sonnet-4-6-high", model: "claude-sonnet-4-6", effort: "high", who: "Sonnet 4.6, high",
|
|
103
|
+
desc: "ORC Code Scout — claude-sonnet-4-6, high effort. Dispatched by orc in the analyst's DEEP mode (≤max_scouts in parallel), ONE coverage area each." },
|
|
104
|
+
{ name: "orc-scout-opus-5-low", model: "claude-opus-5-5", effort: "low", who: "Opus 5.5, low",
|
|
105
|
+
desc: "ORC Code Scout — claude-opus-5-5, low effort. Dispatched by orc in the analyst's DEEP mode, instead of orc-scout-sonnet-4-6-high when `opus5_only: true`." },
|
|
106
|
+
] },
|
|
107
|
+
{ family: "claude-writer", variants: [
|
|
108
|
+
{ name: "orc-claude-writer-opus-5-low", model: "claude-opus-5-5", effort: "low", who: "Opus 5.5, low",
|
|
109
|
+
desc: "ORC CLAUDE.md Writer — claude-opus-5-5, low effort. Dispatched by /orc-claude to create, update or refresh the repo-root CLAUDE.md." },
|
|
110
|
+
] },
|
|
111
|
+
{ family: "wiki-scanner", variants: [
|
|
112
|
+
{ name: "orc-wiki-scanner-opus-5-low", model: "claude-opus-5-5", effort: "low",
|
|
113
|
+
desc: "ORC Wiki Scanner — claude-opus-5-5, low effort. Dispatched by orc-wiki per scan-task (DEEP tier), ONE coverage area each." },
|
|
114
|
+
] },
|
|
115
|
+
];
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
// Line endings are NOT content here: .gitattributes stores these files with LF
|
|
119
|
+
// and checks them out native, so a Windows worktree is CRLF and a Linux one LF.
|
|
120
|
+
// The injected frontmatter line therefore borrows the TEMPLATE's own ending, and
|
|
121
|
+
// --check compares LF-normalized text — otherwise the guard fails on Windows for
|
|
122
|
+
// a difference git itself does not record.
|
|
123
|
+
const eolOf = (s) => (/\r\n/.test(s) ? "\r\n" : "\n");
|
|
124
|
+
const lf = (s) => s.replace(/\r\n/g, "\n");
|
|
125
|
+
|
|
126
|
+
function render(template, v) {
|
|
127
|
+
const effortDesc = v.effort ? `, ${v.effort} effort` : " (no effort ladder)";
|
|
128
|
+
const effortFm = v.effort ? `effort: ${v.effort}${eolOf(template)}` : "";
|
|
129
|
+
return template
|
|
130
|
+
.replace(/\{\{NAME\}\}/g, v.name)
|
|
131
|
+
.replace(/\{\{MODEL\}\}/g, v.model)
|
|
132
|
+
.replace(/\{\{EFFORT_DESC\}\}/g, effortDesc)
|
|
133
|
+
.replace(/\{\{EFFORT_FM\}\}/g, effortFm)
|
|
134
|
+
.replace(/\{\{BAND\}\}/g, v.band);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function renderTwin(template, v) {
|
|
138
|
+
return template
|
|
139
|
+
.replace(/\{\{NAME\}\}/g, v.name)
|
|
140
|
+
.replace(/\{\{MODEL\}\}/g, v.model)
|
|
141
|
+
.replace(/\{\{EFFORT\}\}/g, v.effort)
|
|
142
|
+
.replace(/\{\{DESC\}\}/g, v.desc)
|
|
143
|
+
.replace(/\{\{WHO\}\}/g, v.who || "");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Every [template, row, renderer] the generator owns, executors first.
|
|
147
|
+
function jobs() {
|
|
148
|
+
const template = fs.readFileSync(TEMPLATE, "utf8");
|
|
149
|
+
if (/\{\{(?!NAME|MODEL|EFFORT_DESC|EFFORT_FM|BAND)\w/.test(template)) {
|
|
150
|
+
console.error("❌ build-agents: unknown {{placeholder}} in executor.template.md");
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
const out = VARIANTS.map((v) => ({ v, out: render(template, v), src: "agents-src/executor.template.md" }));
|
|
154
|
+
for (const fam of TWINS) {
|
|
155
|
+
const src = "agents-src/twins/" + fam.family + ".template.md";
|
|
156
|
+
const t = fs.readFileSync(path.join(TWIN_DIR, fam.family + ".template.md"), "utf8");
|
|
157
|
+
if (/\{\{(?!(?:NAME|MODEL|EFFORT|DESC|WHO)\}\})\w/.test(t)) {
|
|
158
|
+
console.error("❌ build-agents: unknown {{placeholder}} in " + src);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
if (/\{\{WHO\}\}/.test(t) !==fam.variants.every((v) => v.who)) {
|
|
162
|
+
console.error("❌ build-agents: " + src + " and its TWINS rows disagree about {{WHO}}");
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
for (const v of fam.variants) out.push({ v, out: renderTwin(t, v), src });
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function main() {
|
|
171
|
+
const checkMode = process.argv.includes("--check");
|
|
172
|
+
const all = jobs();
|
|
173
|
+
let drifted = 0;
|
|
174
|
+
for (const { v, out, src } of all) {
|
|
175
|
+
const dest = path.join(OUT_DIR, v.name + ".md");
|
|
176
|
+
if (checkMode) {
|
|
177
|
+
const current = fs.existsSync(dest) ? fs.readFileSync(dest, "utf8") : null;
|
|
178
|
+
if (current === null || lf(current) !== lf(out)) {
|
|
179
|
+
drifted++;
|
|
180
|
+
console.error(
|
|
181
|
+
`❌ generated agent drifted: templates/agents/${v.name}.md\n` +
|
|
182
|
+
` This agent is GENERATED — edit ${src}\n` +
|
|
183
|
+
` (or the VARIANTS / TWINS table in bin/build-agents.js) and run: npm run build:agents`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
fs.writeFileSync(dest, out);
|
|
188
|
+
console.log(` gen templates/agents/${v.name}.md`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (checkMode) {
|
|
193
|
+
if (drifted) process.exit(1);
|
|
194
|
+
const twins = all.length - VARIANTS.length;
|
|
195
|
+
console.log(
|
|
196
|
+
`✅ ORC executor agents OK — ${VARIANTS.length} files match the template; ${twins} model twins match agents-src/twins/.`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Required by test/payload.test.js, which checks the line-ending rule above
|
|
202
|
+
// without writing to templates/agents/.
|
|
203
|
+
module.exports = { VARIANTS, TWINS, render, renderTwin, lf, eolOf };
|
|
204
|
+
|
|
205
|
+
if (require.main === module) main();
|