@lawaty/lacode 0.6.0 → 0.7.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 +34 -1
- package/README.md +47 -54
- package/dist/agents.js +72 -78
- package/dist/commands.js +11 -63
- package/dist/index.js +91 -194
- package/docs/BENCHMARKS.md +7 -9
- package/docs/CONFIGURATION.md +12 -12
- package/docs/CONTEXT.md +39 -26
- package/docs/INSTALL.md +14 -15
- package/docs/OMNIROUTE.md +12 -25
- package/docs/TUNNEL.md +16 -14
- package/docs/USER-STORIES.md +25 -26
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,37 @@ commit as the changelog entry it describes.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.7.1] — /agent-instructions creates AGENTS.md on first use
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`/agent-instructions` creates `AGENTS.md` on first use.** The hidden
|
|
17
|
+
`instructions` agent now creates the project's root `AGENTS.md` when it does
|
|
18
|
+
not exist, seeded with the instruction you pass, instead of refusing. Nothing
|
|
19
|
+
is created at startup and no placeholder content is written — the file appears
|
|
20
|
+
only when you run the command, and holds only what you asked for.
|
|
21
|
+
|
|
22
|
+
## [0.7.0] — standing instructions move to the project AGENTS.md
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- **Standing instructions moved to the project root `AGENTS.md`.** The
|
|
27
|
+
`/manager-directive` command and the hidden `manager` agent are gone,
|
|
28
|
+
replaced by `/agent-instructions` and the hidden `instructions` agent. The
|
|
29
|
+
`instructions` agent is the only writer of the project's root `AGENTS.md`;
|
|
30
|
+
every other agent is permission-denied on that path. The plugin no longer
|
|
31
|
+
injects a standing instruction — standing rules now live in `AGENTS.md`
|
|
32
|
+
itself. `ensureManagerFile` is gone.
|
|
33
|
+
|
|
34
|
+
### Removed
|
|
35
|
+
|
|
36
|
+
- `/manager-directive` command
|
|
37
|
+
- `manager` agent
|
|
38
|
+
- `src/lib/manager-directive.ts`
|
|
39
|
+
- `applyInstructions` / `STANDING_INSTRUCTION` / `CURRENT_STATE_RULE` from
|
|
40
|
+
`src/commands.ts`
|
|
41
|
+
- The `ensureManagerFile` call from `src/index.ts`
|
|
42
|
+
|
|
12
43
|
## [0.6.0] — a client-only /pool command, and README corrections
|
|
13
44
|
|
|
14
45
|
### Added
|
|
@@ -214,7 +245,9 @@ experimental; `latest` remains 0.4.2.
|
|
|
214
245
|
|
|
215
246
|
- First published release: pooled subagents over a shared set of models.
|
|
216
247
|
|
|
217
|
-
[Unreleased]: https://github.com/lawaty/lacode/compare/v0.
|
|
248
|
+
[Unreleased]: https://github.com/lawaty/lacode/compare/v0.7.1...HEAD
|
|
249
|
+
[0.7.1]: https://github.com/lawaty/lacode/compare/v0.7.0...v0.7.1
|
|
250
|
+
[0.7.0]: https://github.com/lawaty/lacode/compare/v0.6.0...v0.7.0
|
|
218
251
|
[0.6.0]: https://github.com/lawaty/lacode/compare/v0.5.0...v0.6.0
|
|
219
252
|
[0.5.0]: https://github.com/lawaty/lacode/compare/v0.4.2...v0.5.0
|
|
220
253
|
[0.4.1]: https://github.com/lawaty/lacode/compare/v0.4.0...v0.4.1
|
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
> Ultimate opencode setup for Go users
|
|
4
4
|
|
|
5
|
-
> **Beta — experimental, changing fast.**
|
|
6
|
-
>
|
|
7
|
-
>
|
|
8
|
-
>
|
|
5
|
+
> **Beta — experimental, changing fast.** LaCode ships on the npm **`beta`**
|
|
6
|
+
> dist-tag rather than `latest`, so nothing pulls it by accident: install
|
|
7
|
+
> `@lawaty/lacode@beta`, or pin an exact version. Interfaces here can change
|
|
8
|
+
> between releases without a major bump.
|
|
9
9
|
|
|
10
10
|
LaCode is an opencode plugin. It routes delegated work onto a weighted pool of
|
|
11
11
|
cheap models instead of the expensive one, reaps subagents that hang without
|
|
@@ -133,13 +133,14 @@ option is optional:
|
|
|
133
133
|
|
|
134
134
|
opencode's plugin cache is **write-once**: it resolves `@lawaty/lacode` to an
|
|
135
135
|
exact version once and never re-resolves — not on restart, not with
|
|
136
|
-
`opencode plugin -g -f`, not with a range pin, not with a tagged config spec.
|
|
137
|
-
|
|
138
|
-
version to npm's `latest` (at most
|
|
139
|
-
|
|
140
|
-
binary — no npm or bun required.
|
|
141
|
-
|
|
142
|
-
`lacode update` to do it on demand, or
|
|
136
|
+
`opencode plugin -g -f`, not with a range pin, not with a tagged config spec.
|
|
137
|
+
Nothing in the host re-resolves it, so the plugin owns its own currency
|
|
138
|
+
(US-27): at startup LaCode compares its own version to npm's `latest` (at most
|
|
139
|
+
once per ~6h, silent when offline) and, when behind, reinstalls its own cache
|
|
140
|
+
entry in the background using the opencode binary — no npm or bun required.
|
|
141
|
+
The running session keeps its loaded code; the new version takes effect on the
|
|
142
|
+
next start, and the log says so. Run `lacode update` to do it on demand, or
|
|
143
|
+
`lacode update --check` to just report.
|
|
143
144
|
|
|
144
145
|
### Which LaCode is running
|
|
145
146
|
|
|
@@ -154,7 +155,7 @@ lacode version
|
|
|
154
155
|
version 0.4.1
|
|
155
156
|
root /home/you/lacode
|
|
156
157
|
source checkout
|
|
157
|
-
commit
|
|
158
|
+
commit <hash> (dirty)
|
|
158
159
|
dist current
|
|
159
160
|
config /home/you/.config/opencode/opencode.jsonc
|
|
160
161
|
plugin file:///home/you/lacode/dist/index.js
|
|
@@ -163,14 +164,15 @@ this copy yes — opencode loads this copy
|
|
|
163
164
|
|
|
164
165
|
`npm ls -g @lawaty/lacode` answers a different question. It reports the package
|
|
165
166
|
opencode resolves *by name*, which is not necessarily the one running: a config
|
|
166
|
-
may load the plugin by absolute path,
|
|
167
|
-
|
|
168
|
-
|
|
167
|
+
may load the plugin by absolute path, and a global install can sit there
|
|
168
|
+
reporting a version nothing uses. So this command reads your actual `plugin`
|
|
169
|
+
array and says whether it resolves to the copy speaking.
|
|
169
170
|
|
|
170
171
|
`source` distinguishes a git checkout from an npm install, `commit` and the
|
|
171
172
|
dirty flag name what the code was built from, and `dist` is the trap worth
|
|
172
173
|
knowing about — opencode loads `dist/index.js` while you edit and pull `src/`,
|
|
173
|
-
so a `git pull` can leave you running
|
|
174
|
+
so a `git pull` can leave you running a build that differs from the installed
|
|
175
|
+
package, with nothing failing.
|
|
174
176
|
When it reports `stale`, rebuild with `npm run build`. No network is touched;
|
|
175
177
|
`lacode update --check` is what asks npm whether something newer exists.
|
|
176
178
|
|
|
@@ -184,7 +186,7 @@ directly, which is exactly what the rotation and the per-slot ceiling exist to
|
|
|
184
186
|
prevent, so it is refused.
|
|
185
187
|
|
|
186
188
|
Six commands: `/context-init`, `/context-update`, `/context-review`,
|
|
187
|
-
`/lacode-doctor`, `/
|
|
189
|
+
`/lacode-doctor`, `/agent-instructions` and `/pool`. Everything is added **only
|
|
188
190
|
when your config does not already
|
|
189
191
|
define it** — an agent or command you wrote yourself is left byte-identical,
|
|
190
192
|
never patched or partially merged. `{"enabled": false}` turns the whole thing off
|
|
@@ -218,55 +220,46 @@ are reading:
|
|
|
218
220
|
/context-update # incremental refresh; accepts a focus, e.g. /context-update src/payments
|
|
219
221
|
/context-review # audit it for staleness, contradictions, duplication and bloat
|
|
220
222
|
/lacode-doctor # check the pool, model resolution and the OmniRoute gateway. Report only
|
|
221
|
-
/
|
|
223
|
+
/agent-instructions # apply a client instruction to the project's AGENTS.md — client-only, see below
|
|
222
224
|
/pool # rewrite the pool slot table in ~/.config/lacode/pool.txt; restart to apply
|
|
223
225
|
```
|
|
224
226
|
|
|
225
227
|
The map is local and untracked — it describes your checkout on your machine, so
|
|
226
228
|
it is not committed and not synced. If it is missing, agents check, find
|
|
227
|
-
nothing and carry on
|
|
229
|
+
nothing and carry on without it. What this buys is tokens not spent
|
|
228
230
|
re-discovering structure; as with everything else here, no savings percentage is
|
|
229
231
|
published, because none has been independently measured. The mechanism, the
|
|
230
232
|
permission rule that makes one writer possible, and what the log lines mean are
|
|
231
233
|
in [docs/CONTEXT.md](docs/CONTEXT.md).
|
|
232
234
|
|
|
233
|
-
##
|
|
235
|
+
## Standing instructions
|
|
234
236
|
|
|
235
|
-
The
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
within that domain it outranks the five generated files and any agent's
|
|
241
|
-
inference about what matters right now.
|
|
237
|
+
The project's root `AGENTS.md` is your own statement of intent: it records
|
|
238
|
+
what you want worked on and how you want it approached. It says nothing about
|
|
239
|
+
where code lives, so it can never contradict the code, and within that domain
|
|
240
|
+
it outranks the five generated context files and any agent's inference about what
|
|
241
|
+
matters right now.
|
|
242
242
|
|
|
243
243
|
The file is per-clone and not committed, so it is yours rather than shared
|
|
244
|
-
team state.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
`/manager-directive <text>` and the `manager` agent applies your instruction to
|
|
264
|
-
`manager.md` — recording it, moving it between sections, rewriting `## Current`,
|
|
265
|
-
whatever you asked — then reports what it changed. It is a normal agent turn, not
|
|
266
|
-
a dead append: tell it what you want and review the result. The `manager` agent
|
|
267
|
-
is the one agent permitted to edit that file, its grant is scoped to
|
|
268
|
-
`manager.md` alone, and no other agent can spawn it — the command is the only
|
|
269
|
-
route in.
|
|
244
|
+
team state. There is no fixed schema and no prescribed headings — you write
|
|
245
|
+
whatever you like, and every heading you add is treated as direction.
|
|
246
|
+
|
|
247
|
+
Anything you have recorded there is read before work starts, and what you have
|
|
248
|
+
recorded is treated as settled by the agents — not as permission to skip
|
|
249
|
+
reading the code.
|
|
250
|
+
|
|
251
|
+
**Who may write it.** Every agent is explicitly permission-denied from
|
|
252
|
+
touching this path, so no automatic run can ever alter it. The one exception
|
|
253
|
+
is the hidden `instructions` agent, reachable solely through the
|
|
254
|
+
`/agent-instructions` command.
|
|
255
|
+
|
|
256
|
+
**`/agent-instructions` — the one sanctioned write path.** Type
|
|
257
|
+
`/agent-instructions <text>` and the `instructions` agent applies whatever
|
|
258
|
+
instruction you have given to `AGENTS.md`, then reports what it changed. It is
|
|
259
|
+
a normal agent turn, not a dead append: tell it what you want and review the
|
|
260
|
+
result. The `instructions` agent is the one agent permitted to edit that file,
|
|
261
|
+
its grant is scoped to `AGENTS.md` alone, and no other agent can spawn it —
|
|
262
|
+
the command is the only route in.
|
|
270
263
|
|
|
271
264
|
## Cost
|
|
272
265
|
|
|
@@ -385,7 +378,7 @@ gitignored; `prepack` builds it, so `npm pack` cannot produce a stale tarball.
|
|
|
385
378
|
|
|
386
379
|
The sources are TypeScript and the tests import `src/` directly (node strips the
|
|
387
380
|
types outside `node_modules`, which is exactly where the tests live), so the
|
|
388
|
-
loop
|
|
381
|
+
loop is: edit `src/`, run `npm test`. Only the packaging fixtures build, and
|
|
389
382
|
they call the same `scripts/build.mjs` the tarball does.
|
|
390
383
|
|
|
391
384
|
`tests/stories/` holds the story suites and `tests/stories/coverage.test.mjs`
|
package/dist/agents.js
CHANGED
|
@@ -46,8 +46,8 @@ var USER_MODELS_PATH = join2(USER_CONFIG_DIR, "pool.json");
|
|
|
46
46
|
var USER_MODELS_TXT = join2(USER_CONFIG_DIR, "pool.txt");
|
|
47
47
|
var CHILD_MEMORY_MS = 30 * 6e4;
|
|
48
48
|
|
|
49
|
-
// src/lib/
|
|
50
|
-
var
|
|
49
|
+
// src/lib/agent-instructions.ts
|
|
50
|
+
var AGENT_INSTRUCTIONS_WRITER = "instructions";
|
|
51
51
|
|
|
52
52
|
// src/agents.ts
|
|
53
53
|
var POOLED_BASES = ["explore", "implement", "context"];
|
|
@@ -85,14 +85,28 @@ different number.
|
|
|
85
85
|
|
|
86
86
|
The pooled agents are the ONLY route to investigation and implementation. If the
|
|
87
87
|
pool cannot serve a spawn \u2014 every slot cooling or exhausted, spawns repeatedly
|
|
88
|
-
failing, or a runtime message saying no slot is available \u2014 that is a
|
|
89
|
-
|
|
88
|
+
failing, or a runtime message saying no slot is available \u2014 that is not a reason
|
|
89
|
+
to do the work yourself, and not a reason to stop and ask.
|
|
90
|
+
|
|
91
|
+
**Retry.** A refused or cooling slot is transient and costs you nothing but a
|
|
92
|
+
turn. Spawn the bare base again. Do not escalate a \`-N\` variant when a refusal
|
|
93
|
+
names one \u2014 the refusal means the pool has a routing problem, not that you
|
|
94
|
+
picked the wrong number.
|
|
95
|
+
|
|
96
|
+
Retry is always available and never wrong, which is why it is the default. But
|
|
97
|
+
"never wrong" is not "sufficient": looping silently against a pool with every
|
|
98
|
+
model cooling goes nowhere and burns the slot doing it. So separate the two
|
|
99
|
+
failures. **Transient** \u2014 a cooldown, a rate limit, one slot at its ceiling \u2014
|
|
100
|
+
means retry. **Persistent or structural** \u2014 every slot cooling, the same spawn
|
|
101
|
+
failing repeatedly with the same error, a malformed model id \u2014 means stop
|
|
102
|
+
retrying and *report* it: say what failed (slot, model, error) and continue
|
|
103
|
+
with whatever else the task needs, or ask the user. Surface the failure; do not
|
|
104
|
+
spin on it and do not let it end the whole task.
|
|
90
105
|
|
|
91
106
|
**Never fall back to reading, grepping, exploring or implementing on your own.**
|
|
92
|
-
Do not "just quickly" inspect a file because a spawn failed.
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
subagents. A failed spawn is never permission, and silence is not consent.
|
|
107
|
+
Do not "just quickly" inspect a file because a spawn failed. A failed spawn is
|
|
108
|
+
never permission, and silence is not consent \u2014 that part does not change with
|
|
109
|
+
cooldowns, and no amount of retrying grants it.
|
|
96
110
|
|
|
97
111
|
\`edit\`/\`write\`/\`bash\` stay yours for applying and verifying what a subagent
|
|
98
112
|
returned \u2014 never as a substitute for a spawn that could not run.
|
|
@@ -171,7 +185,12 @@ missing). Never paste context file contents into the report.`,
|
|
|
171
185
|
"edit": {
|
|
172
186
|
"*": "allow",
|
|
173
187
|
"*/.opencode/context/**": "deny",
|
|
174
|
-
".opencode/context/**": "deny"
|
|
188
|
+
".opencode/context/**": "deny",
|
|
189
|
+
// AGENTS.md has exactly one writer, the hidden `instructions` agent.
|
|
190
|
+
// opencode resolves a file permission with findLast over the map's own
|
|
191
|
+
// entry order, so this deny has to come AFTER the broad "*" allow above.
|
|
192
|
+
"AGENTS.md": "deny",
|
|
193
|
+
"*/AGENTS.md": "deny"
|
|
175
194
|
},
|
|
176
195
|
"bash": "allow",
|
|
177
196
|
"webfetch": "deny",
|
|
@@ -414,7 +433,11 @@ if the blocker is understanding rather than execution, report that instead.`,
|
|
|
414
433
|
"edit": {
|
|
415
434
|
"*": "allow",
|
|
416
435
|
"*/.opencode/context/**": "deny",
|
|
417
|
-
".opencode/context/**": "deny"
|
|
436
|
+
".opencode/context/**": "deny",
|
|
437
|
+
// AGENTS.md is written by the hidden `instructions` agent alone; LAST
|
|
438
|
+
// match wins, so this deny must sit after the broad allow above.
|
|
439
|
+
"AGENTS.md": "deny",
|
|
440
|
+
"*/AGENTS.md": "deny"
|
|
418
441
|
},
|
|
419
442
|
"bash": "allow",
|
|
420
443
|
"webfetch": "allow",
|
|
@@ -458,29 +481,14 @@ You own exactly these five files and nothing else:
|
|
|
458
481
|
during work that are not already recorded in the project's own decision
|
|
459
482
|
log. Concise; variable length.
|
|
460
483
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
You never create, edit, rename, or delete it \u2014 not at bootstrap, not in an
|
|
470
|
-
update, not in a review, and not when a run of your own concludes the work
|
|
471
|
-
has moved on. The client edits it, or asks a live agent to edit it on
|
|
472
|
-
their explicit instruction. Either way it is their hand, never yours.
|
|
473
|
-
|
|
474
|
-
Read it before you write anything. Its \`## Current\` and \`## Next\`
|
|
475
|
-
sections tell you what is actually being worked on, and \`## Confirmed\`
|
|
476
|
-
tells you which of your facts the client has ratified. A fact you are
|
|
477
|
-
writing that appears under \`## Confirmed\` may be stated plainly, without
|
|
478
|
-
a confidence marker; anything else follows your normal rules \u2014 infer
|
|
479
|
-
carefully, mark uncertainty. Never copy its content into the five files.
|
|
480
|
-
|
|
481
|
-
A missing or empty section is not an instruction. It means the client has
|
|
482
|
-
not said, not that you may assume anything \u2014 proceed exactly as you would
|
|
483
|
-
without the file.
|
|
484
|
+
# Current-state only
|
|
485
|
+
|
|
486
|
+
Every file you write states only the current arrangement and the reason it
|
|
487
|
+
holds, in the present tense. No "used to", "previously", "before this",
|
|
488
|
+
migration notes or deprecation narrative \u2014 history belongs in the project's
|
|
489
|
+
changelog, not in your map. An absence that is true today is a fact worth
|
|
490
|
+
stating, not a removal worth narrating. When a past state is worth keeping,
|
|
491
|
+
record it briefly in \`changelog.md\` instead.
|
|
484
492
|
|
|
485
493
|
Never create, modify, or delete anything outside \`.opencode/context/\`. The
|
|
486
494
|
\`edit\` permission enforces this. Do not attempt to work around it with bash.
|
|
@@ -516,11 +524,6 @@ Then write the five files. For each significant subsystem, give a short
|
|
|
516
524
|
reason. This is the single most valuable thing you produce: where an agent
|
|
517
525
|
should open its editor next.
|
|
518
526
|
|
|
519
|
-
manager.md is created for the client by the plugin, not by you; if it is
|
|
520
|
-
missing anyway, mention once in your final report that they can add it
|
|
521
|
-
themselves to record what is being worked on, what comes next, and what
|
|
522
|
-
they have ratified. Never create it.
|
|
523
|
-
|
|
524
527
|
# Incremental update
|
|
525
528
|
|
|
526
529
|
Trigger: \`.opencode/context/\` exists and work has just been done here.
|
|
@@ -548,14 +551,6 @@ that is already stated in another context file \u2014 one fact has one home, and
|
|
|
548
551
|
the other files link to it. If nothing material changed, make no edits and
|
|
549
552
|
report "no update needed".
|
|
550
553
|
|
|
551
|
-
Before editing, re-read manager.md: its \`## Current\` and \`## Next\`
|
|
552
|
-
sections tell you what the client is actually working on, and its
|
|
553
|
-
\`## Confirmed\` section settles which of your facts are ratified. If what
|
|
554
|
-
you are about to write would place the code somewhere the client never
|
|
555
|
-
described, trust the code, make the edit the code justifies, and report
|
|
556
|
-
the gap in your final message \u2014 never reconcile the two sides silently,
|
|
557
|
-
and never edit manager.md to close it.
|
|
558
|
-
|
|
559
554
|
# Minimal exploration
|
|
560
555
|
|
|
561
556
|
Default shape:
|
|
@@ -650,14 +645,10 @@ Audit the five files for:
|
|
|
650
645
|
- duplicated information \u2014 one canonical place per fact
|
|
651
646
|
- missing canonical entry points for significant subsystems
|
|
652
647
|
- unsupported assumptions \u2014 anything unmarked that you cannot verify
|
|
653
|
-
- manager.md, if present: is \`## Current\` and \`## Next\` still true of
|
|
654
|
-
recent work, is every \`## Confirmed\` entry still true of the code, has
|
|
655
|
-
it outgrown roughly 150 lines \u2014 report findings, but never edit, prune,
|
|
656
|
-
or reorganize it; that is the client's call
|
|
657
648
|
|
|
658
|
-
Fix problems only in the five files you own
|
|
659
|
-
|
|
660
|
-
|
|
649
|
+
Fix problems only in the five files you own. Never modify source code
|
|
650
|
+
during a review. Report what you found, what you fixed, and what you
|
|
651
|
+
could not verify.
|
|
661
652
|
|
|
662
653
|
# Reporting
|
|
663
654
|
|
|
@@ -675,9 +666,7 @@ Finish with a short report:
|
|
|
675
666
|
"edit": {
|
|
676
667
|
"*": "deny",
|
|
677
668
|
"*/.opencode/context/**": "allow",
|
|
678
|
-
".opencode/context/**": "allow"
|
|
679
|
-
"*/.opencode/context/manager.md": "deny",
|
|
680
|
-
".opencode/context/manager.md": "deny"
|
|
669
|
+
".opencode/context/**": "allow"
|
|
681
670
|
},
|
|
682
671
|
"bash": {
|
|
683
672
|
"*": "deny",
|
|
@@ -725,58 +714,63 @@ Finish with a short report:
|
|
|
725
714
|
}
|
|
726
715
|
}
|
|
727
716
|
};
|
|
728
|
-
var
|
|
729
|
-
description: "
|
|
717
|
+
var INSTRUCTIONS_AGENT = {
|
|
718
|
+
description: "Edits the project's AGENTS.md. Run only by the /agent-instructions command; no agent or subagent can spawn it.",
|
|
730
719
|
mode: "subagent",
|
|
731
720
|
hidden: true,
|
|
732
721
|
temperature: 0.1,
|
|
733
722
|
prompt: `# Role
|
|
734
723
|
|
|
735
|
-
You maintain one file and nothing else:
|
|
736
|
-
|
|
737
|
-
other path.
|
|
724
|
+
You maintain one file and nothing else: the project's \`AGENTS.md\`. You are not a
|
|
725
|
+
coding agent and you touch no other path.
|
|
738
726
|
|
|
739
|
-
You are run only by the \`/
|
|
727
|
+
You are run only by the \`/agent-instructions\` command. The client tells you what
|
|
740
728
|
they want recorded or changed in the file; you apply that to the file and report
|
|
741
729
|
what you changed. You have no permission to edit anything else, and you need
|
|
742
730
|
none.
|
|
743
731
|
|
|
744
732
|
# The file
|
|
745
733
|
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
734
|
+
\`AGENTS.md\` is the project's standing instructions \u2014 the rules every agent and
|
|
735
|
+
subagent runs under. opencode loads it into every session automatically, so what
|
|
736
|
+
you write here steers all work in this project. Keep it about how to work:
|
|
737
|
+
conventions, constraints, priorities, things to always do and never do. It says
|
|
738
|
+
nothing about where code lives \u2014 the source and the context map are the authority
|
|
739
|
+
on that.
|
|
750
740
|
|
|
751
741
|
# How to apply a directive
|
|
752
742
|
|
|
753
|
-
- Do what the client asked
|
|
754
|
-
|
|
755
|
-
|
|
743
|
+
- Do what the client asked: add, rewrite, move or remove exactly what they asked
|
|
744
|
+
for. A bare sentence goes under the most fitting existing heading, and you
|
|
745
|
+
create a heading only if none fits.
|
|
756
746
|
- Never invent facts, never record your own inference as the client's, and never
|
|
757
747
|
tidy, reorder or delete content the client did not ask you to touch.
|
|
758
|
-
-
|
|
759
|
-
history.
|
|
748
|
+
- Prefer current-state wording: state how things are, not how they changed.
|
|
760
749
|
- Keep the file concise. If it is growing past roughly 150 lines, say so.
|
|
750
|
+
- If \`AGENTS.md\` does not exist, create it and record the client's instruction in
|
|
751
|
+
it \u2014 that instruction is the file's first content.
|
|
752
|
+
- Do NOT add placeholder comments, empty template headings, or example text;
|
|
753
|
+
write only what the client asked for.
|
|
754
|
+
- Say plainly in your report that you created the file.
|
|
761
755
|
|
|
762
756
|
# Reporting
|
|
763
757
|
|
|
764
758
|
Report briefly what you changed and where. Do not edit any other file.`,
|
|
765
759
|
permission: {
|
|
766
|
-
// Read is scoped to the one file too: the directive is about
|
|
760
|
+
// Read is scoped to the one file too: the directive is about AGENTS.md, and
|
|
767
761
|
// nothing else is any of this agent's business.
|
|
768
762
|
read: {
|
|
769
763
|
"*": "deny",
|
|
770
|
-
".
|
|
771
|
-
"
|
|
764
|
+
"AGENTS.md": "allow",
|
|
765
|
+
"*/AGENTS.md": "allow"
|
|
772
766
|
},
|
|
773
767
|
glob: "deny",
|
|
774
768
|
grep: "deny",
|
|
775
769
|
list: "deny",
|
|
776
770
|
edit: {
|
|
777
771
|
"*": "deny",
|
|
778
|
-
".
|
|
779
|
-
"
|
|
772
|
+
"AGENTS.md": "allow",
|
|
773
|
+
"*/AGENTS.md": "allow"
|
|
780
774
|
},
|
|
781
775
|
bash: "deny",
|
|
782
776
|
webfetch: "deny",
|
|
@@ -802,7 +796,7 @@ function buildAgentSet() {
|
|
|
802
796
|
set[`${base}-${slot}`] = variant;
|
|
803
797
|
}
|
|
804
798
|
}
|
|
805
|
-
set[
|
|
799
|
+
set[AGENT_INSTRUCTIONS_WRITER] = INSTRUCTIONS_AGENT;
|
|
806
800
|
return set;
|
|
807
801
|
}
|
|
808
802
|
function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
|
|
@@ -822,7 +816,7 @@ function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
|
|
|
822
816
|
}
|
|
823
817
|
export {
|
|
824
818
|
AGENTS,
|
|
825
|
-
|
|
819
|
+
INSTRUCTIONS_AGENT,
|
|
826
820
|
POOLED_BASES,
|
|
827
821
|
applyAgents,
|
|
828
822
|
buildAgentSet
|
package/dist/commands.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
// src/lib/
|
|
2
|
-
var
|
|
1
|
+
// src/lib/agent-instructions.ts
|
|
2
|
+
var AGENT_INSTRUCTIONS_COMMAND = "agent-instructions";
|
|
3
|
+
var AGENT_INSTRUCTIONS_WRITER = "instructions";
|
|
3
4
|
|
|
4
5
|
// src/lib/pool.ts
|
|
5
6
|
import { existsSync, mkdirSync, readdirSync, readFileSync as readFileSync2, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
@@ -71,13 +72,7 @@ Remember: write conclusions, not inventories. Link to the project's existing
|
|
|
71
72
|
documentation instead of duplicating it.
|
|
72
73
|
|
|
73
74
|
Report what you created or updated, what you deliberately left out, and
|
|
74
|
-
anything that contradicts the code or existing docs
|
|
75
|
-
|
|
76
|
-
If \`.opencode/context/manager.md\` does not exist, mention in your final
|
|
77
|
-
report that the client can add it themselves \u2014 their own file with
|
|
78
|
-
\`## Current\`, \`## Next\`, \`## Confirmed\` and \`## Instructions\` \u2014 for what
|
|
79
|
-
is being worked on, what comes next, what they have ratified, and standing
|
|
80
|
-
direction. Never create it.`
|
|
75
|
+
anything that contradicts the code or existing docs.`
|
|
81
76
|
},
|
|
82
77
|
"context-update": {
|
|
83
78
|
description: "Incrementally update .opencode/context/ after recent work via the context agent.",
|
|
@@ -108,9 +103,8 @@ timestamp-only edits. If nothing material changed, make no edits and report
|
|
|
108
103
|
subtask: true,
|
|
109
104
|
template: `Context review.
|
|
110
105
|
|
|
111
|
-
Everything outside the five context files is read-only for this run
|
|
112
|
-
|
|
113
|
-
code under any circumstances.
|
|
106
|
+
Everything outside the five context files is read-only for this run. Do not
|
|
107
|
+
modify source code under any circumstances.
|
|
114
108
|
|
|
115
109
|
Audit the five context files for:
|
|
116
110
|
|
|
@@ -123,18 +117,15 @@ Audit the five context files for:
|
|
|
123
117
|
- missing canonical entry points for significant subsystems
|
|
124
118
|
- unsupported assumptions \u2014 anything stated as fact that you cannot verify,
|
|
125
119
|
or that lacks a confidence marker
|
|
126
|
-
- \`manager.md\`, if present: is \`## Current\` and \`## Next\` still true of
|
|
127
|
-
recent work, is every \`## Confirmed\` entry still true of the code, has it
|
|
128
|
-
outgrown roughly 150 lines \u2014 report findings, but never edit it
|
|
129
120
|
|
|
130
121
|
Fix what you find in \`.opencode/context/\` only, then report: findings, fixes,
|
|
131
122
|
and anything you could not verify.`
|
|
132
123
|
},
|
|
133
|
-
|
|
134
|
-
description: "Apply a client instruction to .
|
|
135
|
-
agent:
|
|
124
|
+
[AGENT_INSTRUCTIONS_COMMAND]: {
|
|
125
|
+
description: "Apply a client instruction to the project's AGENTS.md. Client-only \u2014 runs the instructions agent, the only writer of that file.",
|
|
126
|
+
agent: AGENT_INSTRUCTIONS_WRITER,
|
|
136
127
|
subtask: true,
|
|
137
|
-
template: `Apply this instruction to
|
|
128
|
+
template: `Apply this instruction to the project's \`AGENTS.md\`, and edit only that file:
|
|
138
129
|
|
|
139
130
|
$ARGUMENTS
|
|
140
131
|
|
|
@@ -216,50 +207,7 @@ function applyCommands(cfg, commands = COMMANDS) {
|
|
|
216
207
|
}
|
|
217
208
|
return { added, kept };
|
|
218
209
|
}
|
|
219
|
-
var INSTRUCTION_MARKER = "<!-- lacode:context-map-instruction:v1 -->";
|
|
220
|
-
var INSTRUCTION_OPT_OUT = "<!-- lacode:context-map-instruction:off -->";
|
|
221
|
-
var STANDING_INSTRUCTION = `## Repository context map
|
|
222
|
-
|
|
223
|
-
This project may keep a navigation map in \`.opencode/context/\`. Before broad
|
|
224
|
-
exploration, check whether it exists (\`ls .opencode/context\` \u2014 never the \`glob\`
|
|
225
|
-
tool, which skips hidden directories). If \`manager.md\` exists there, read it
|
|
226
|
-
first: it is the client's own statement of intent \u2014 what is being worked on,
|
|
227
|
-
what comes next, \`## Confirmed\` lists what the client has ratified, and
|
|
228
|
-
\`## Instructions\` holds standing managerial directions. It outranks every
|
|
229
|
-
other context file and every inference of yours about what matters right now.
|
|
230
|
-
It says nothing about where code lives, so it cannot contradict the code;
|
|
231
|
-
treat its \`## Confirmed\` entries as settled decisions, not as a licence to
|
|
232
|
-
skip reading the code. Any heading in it is direction, so read the whole
|
|
233
|
-
file rather than only the sections above. The rest of the map remains usable,
|
|
234
|
-
just unratified where \`## Confirmed\` does not cover it. Then read only the
|
|
235
|
-
file relevant to the task \u2014 \`architecture.md\`, \`contexts.md\`,
|
|
236
|
-
\`conventions.md\`, \`workflows.md\`, \`decisions.md\` \u2014 and start from the
|
|
237
|
-
canonical entry points it lists.
|
|
238
|
-
|
|
239
|
-
Source code is authoritative: if the map disagrees with the code,
|
|
240
|
-
trust the code and say so; never edit source to match it.
|
|
241
|
-
Never edit the five context files yourself \u2014 the context agent owns them.
|
|
242
|
-
\`manager.md\` is the client's own file and the context agent is explicitly
|
|
243
|
-
permission-denied from writing it. You may write it only when the client
|
|
244
|
-
explicitly asks you to in this conversation, and then only what they asked
|
|
245
|
-
for; never on your own initiative, and never to "keep it up to date". Say in
|
|
246
|
-
your final report if your work revealed something that belongs to the map, or
|
|
247
|
-
if \`manager.md\` and the code disagree.`;
|
|
248
|
-
function applyInstructions(cfg) {
|
|
249
|
-
const existing = Array.isArray(cfg.instructions) ? cfg.instructions : [];
|
|
250
|
-
const texts = existing.filter((e) => typeof e === "string");
|
|
251
|
-
if (texts.some((e) => e.includes(INSTRUCTION_OPT_OUT))) return { added: false };
|
|
252
|
-
if (texts.some((e) => e.includes(INSTRUCTION_MARKER))) return { added: false };
|
|
253
|
-
cfg.instructions = [...existing, `${INSTRUCTION_MARKER}
|
|
254
|
-
|
|
255
|
-
${STANDING_INSTRUCTION}`];
|
|
256
|
-
return { added: true };
|
|
257
|
-
}
|
|
258
210
|
export {
|
|
259
211
|
COMMANDS,
|
|
260
|
-
|
|
261
|
-
INSTRUCTION_OPT_OUT,
|
|
262
|
-
STANDING_INSTRUCTION,
|
|
263
|
-
applyCommands,
|
|
264
|
-
applyInstructions
|
|
212
|
+
applyCommands
|
|
265
213
|
};
|