@lawaty/lacode 0.5.0 → 0.7.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/CHANGELOG.md +45 -1
- package/README.md +59 -53
- package/dist/agents.js +69 -78
- package/dist/commands.js +90 -63
- package/dist/index.js +118 -194
- package/docs/BENCHMARKS.md +7 -9
- package/docs/CONFIGURATION.md +12 -12
- package/docs/CONTEXT.md +39 -26
- package/docs/INSTALL.md +16 -16
- package/docs/OMNIROUTE.md +12 -25
- package/docs/TUNNEL.md +16 -14
- package/docs/USER-STORIES.md +25 -26
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,8 +9,50 @@ commit as the changelog entry it describes.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.7.0] — standing instructions move to the project AGENTS.md
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **Standing instructions moved to the project root `AGENTS.md`.** The
|
|
17
|
+
`/manager-directive` command and the hidden `manager` agent are gone,
|
|
18
|
+
replaced by `/agent-instructions` and the hidden `instructions` agent. The
|
|
19
|
+
`instructions` agent is the only writer of the project's root `AGENTS.md`;
|
|
20
|
+
every other agent is permission-denied on that path. The plugin no longer
|
|
21
|
+
injects a standing instruction — standing rules now live in `AGENTS.md`
|
|
22
|
+
itself. `ensureManagerFile` is gone.
|
|
23
|
+
|
|
24
|
+
### Removed
|
|
25
|
+
|
|
26
|
+
- `/manager-directive` command
|
|
27
|
+
- `manager` agent
|
|
28
|
+
- `src/lib/manager-directive.ts`
|
|
29
|
+
- `applyInstructions` / `STANDING_INSTRUCTION` / `CURRENT_STATE_RULE` from
|
|
30
|
+
`src/commands.ts`
|
|
31
|
+
- The `ensureManagerFile` call from `src/index.ts`
|
|
32
|
+
|
|
33
|
+
## [0.6.0] — a client-only /pool command, and README corrections
|
|
34
|
+
|
|
35
|
+
### Added
|
|
36
|
+
|
|
37
|
+
- **`/pool <instruction>`** — a client-only command that rewrites this machine's
|
|
38
|
+
pool override, `~/.config/lacode/pool.txt`, from a short instruction. It
|
|
39
|
+
applies the loader's rules (at most 4 distinct slots, weight in (0, 100], line
|
|
40
|
+
order is the rotation), writes the WHOLE file rather than a patch, reports the
|
|
41
|
+
before → after table, and reminds you that nothing hot-reloads.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- README: the count of agent keys deliberately *not* injected was stated as
|
|
46
|
+
three, not the five `docs/CONFIGURATION.md` lists; and the `lacode` CLI section
|
|
47
|
+
was missing `version`, `update`, `receive` and `tunnel setup`.
|
|
48
|
+
`docs/INSTALL.md`'s CLI list gained `version` and `update`. A stale test title
|
|
49
|
+
("three commands") was corrected to match what it asserts.
|
|
50
|
+
|
|
12
51
|
## [0.5.0] — a user-only /manager-directive, instant limit failover, and the longcat preset
|
|
13
52
|
|
|
53
|
+
Released on the npm **`beta`** dist-tag (not `latest`) while the project is
|
|
54
|
+
experimental; `latest` remains 0.4.2.
|
|
55
|
+
|
|
14
56
|
### Added
|
|
15
57
|
|
|
16
58
|
- **`/manager-directive <text>`** — a client-only command that runs a hidden
|
|
@@ -193,7 +235,9 @@ commit as the changelog entry it describes.
|
|
|
193
235
|
|
|
194
236
|
- First published release: pooled subagents over a shared set of models.
|
|
195
237
|
|
|
196
|
-
[Unreleased]: https://github.com/lawaty/lacode/compare/v0.
|
|
238
|
+
[Unreleased]: https://github.com/lawaty/lacode/compare/v0.7.0...HEAD
|
|
239
|
+
[0.7.0]: https://github.com/lawaty/lacode/compare/v0.6.0...v0.7.0
|
|
240
|
+
[0.6.0]: https://github.com/lawaty/lacode/compare/v0.5.0...v0.6.0
|
|
197
241
|
[0.5.0]: https://github.com/lawaty/lacode/compare/v0.4.2...v0.5.0
|
|
198
242
|
[0.4.1]: https://github.com/lawaty/lacode/compare/v0.4.0...v0.4.1
|
|
199
243
|
[0.4.0]: https://github.com/lawaty/lacode/compare/v0.3.0...v0.4.0
|
package/README.md
CHANGED
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
> Ultimate opencode setup for Go users
|
|
4
4
|
|
|
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
|
+
|
|
5
10
|
LaCode is an opencode plugin. It routes delegated work onto a weighted pool of
|
|
6
11
|
cheap models instead of the expensive one, reaps subagents that hang without
|
|
7
12
|
telling anyone, keeps a maintained map of your repository so agents stop
|
|
@@ -128,13 +133,14 @@ option is optional:
|
|
|
128
133
|
|
|
129
134
|
opencode's plugin cache is **write-once**: it resolves `@lawaty/lacode` to an
|
|
130
135
|
exact version once and never re-resolves — not on restart, not with
|
|
131
|
-
`opencode plugin -g -f`, not with a range pin, not with a tagged config spec.
|
|
132
|
-
|
|
133
|
-
version to npm's `latest` (at most
|
|
134
|
-
|
|
135
|
-
binary — no npm or bun required.
|
|
136
|
-
|
|
137
|
-
`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.
|
|
138
144
|
|
|
139
145
|
### Which LaCode is running
|
|
140
146
|
|
|
@@ -149,7 +155,7 @@ lacode version
|
|
|
149
155
|
version 0.4.1
|
|
150
156
|
root /home/you/lacode
|
|
151
157
|
source checkout
|
|
152
|
-
commit
|
|
158
|
+
commit <hash> (dirty)
|
|
153
159
|
dist current
|
|
154
160
|
config /home/you/.config/opencode/opencode.jsonc
|
|
155
161
|
plugin file:///home/you/lacode/dist/index.js
|
|
@@ -158,14 +164,15 @@ this copy yes — opencode loads this copy
|
|
|
158
164
|
|
|
159
165
|
`npm ls -g @lawaty/lacode` answers a different question. It reports the package
|
|
160
166
|
opencode resolves *by name*, which is not necessarily the one running: a config
|
|
161
|
-
may load the plugin by absolute path,
|
|
162
|
-
|
|
163
|
-
|
|
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.
|
|
164
170
|
|
|
165
171
|
`source` distinguishes a git checkout from an npm install, `commit` and the
|
|
166
172
|
dirty flag name what the code was built from, and `dist` is the trap worth
|
|
167
173
|
knowing about — opencode loads `dist/index.js` while you edit and pull `src/`,
|
|
168
|
-
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.
|
|
169
176
|
When it reports `stale`, rebuild with `npm run build`. No network is touched;
|
|
170
177
|
`lacode update --check` is what asks npm whether something newer exists.
|
|
171
178
|
|
|
@@ -178,12 +185,12 @@ only thing that works: naming a variant lets the caller choose the provider
|
|
|
178
185
|
directly, which is exactly what the rotation and the per-slot ceiling exist to
|
|
179
186
|
prevent, so it is refused.
|
|
180
187
|
|
|
181
|
-
|
|
182
|
-
`/lacode-doctor` and `/
|
|
183
|
-
config does not already
|
|
188
|
+
Six commands: `/context-init`, `/context-update`, `/context-review`,
|
|
189
|
+
`/lacode-doctor`, `/agent-instructions` and `/pool`. Everything is added **only
|
|
190
|
+
when your config does not already
|
|
184
191
|
define it** — an agent or command you wrote yourself is left byte-identical,
|
|
185
192
|
never patched or partially merged. `{"enabled": false}` turns the whole thing off
|
|
186
|
-
without leaving a trace. The exact injection list, and the
|
|
193
|
+
without leaving a trace. The exact injection list, and the five keys that are
|
|
187
194
|
deliberately *not* injected, are in
|
|
188
195
|
[docs/CONFIGURATION.md](docs/CONFIGURATION.md#what-gets-injected).
|
|
189
196
|
|
|
@@ -213,54 +220,46 @@ are reading:
|
|
|
213
220
|
/context-update # incremental refresh; accepts a focus, e.g. /context-update src/payments
|
|
214
221
|
/context-review # audit it for staleness, contradictions, duplication and bloat
|
|
215
222
|
/lacode-doctor # check the pool, model resolution and the OmniRoute gateway. Report only
|
|
216
|
-
/
|
|
223
|
+
/agent-instructions # apply a client instruction to the project's AGENTS.md — client-only, see below
|
|
224
|
+
/pool # rewrite the pool slot table in ~/.config/lacode/pool.txt; restart to apply
|
|
217
225
|
```
|
|
218
226
|
|
|
219
227
|
The map is local and untracked — it describes your checkout on your machine, so
|
|
220
228
|
it is not committed and not synced. If it is missing, agents check, find
|
|
221
|
-
nothing and carry on
|
|
229
|
+
nothing and carry on without it. What this buys is tokens not spent
|
|
222
230
|
re-discovering structure; as with everything else here, no savings percentage is
|
|
223
231
|
published, because none has been independently measured. The mechanism, the
|
|
224
232
|
permission rule that makes one writer possible, and what the log lines mean are
|
|
225
233
|
in [docs/CONTEXT.md](docs/CONTEXT.md).
|
|
226
234
|
|
|
227
|
-
##
|
|
235
|
+
## Standing instructions
|
|
228
236
|
|
|
229
|
-
The
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
within that domain it outranks the five generated files and any agent's
|
|
235
|
-
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.
|
|
236
242
|
|
|
237
243
|
The file is per-clone and not committed, so it is yours rather than shared
|
|
238
|
-
team state.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
`/manager-directive <text>` and the `manager` agent applies your instruction to
|
|
258
|
-
`manager.md` — recording it, moving it between sections, rewriting `## Current`,
|
|
259
|
-
whatever you asked — then reports what it changed. It is a normal agent turn, not
|
|
260
|
-
a dead append: tell it what you want and review the result. The `manager` agent
|
|
261
|
-
is the one agent permitted to edit that file, its grant is scoped to
|
|
262
|
-
`manager.md` alone, and no other agent can spawn it — the command is the only
|
|
263
|
-
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.
|
|
264
263
|
|
|
265
264
|
## Cost
|
|
266
265
|
|
|
@@ -333,6 +332,13 @@ must never be able to fail the process that tried to notify you. `lacode forward
|
|
|
333
332
|
HOST -- COMMAND` runs a command on another host over ssh and exits with its
|
|
334
333
|
status.
|
|
335
334
|
|
|
335
|
+
The full CLI is `notify`, `forward`, `doctor`, `version`, `update`, `receive`
|
|
336
|
+
and `tunnel setup`. `version` reports which copy of LaCode is running — and
|
|
337
|
+
whether opencode is loading that same copy — and `update [--check]` refreshes an
|
|
338
|
+
installed one. `receive` is the desktop end of the tunnel (the forced command a
|
|
339
|
+
remote key is restricted to) and `tunnel setup` provisions the key and the
|
|
340
|
+
forward.
|
|
341
|
+
|
|
336
342
|
Configuration, the payload format, the receiver contract and holding the forward
|
|
337
343
|
open are in [docs/TUNNEL.md](docs/TUNNEL.md).
|
|
338
344
|
|
|
@@ -372,7 +378,7 @@ gitignored; `prepack` builds it, so `npm pack` cannot produce a stale tarball.
|
|
|
372
378
|
|
|
373
379
|
The sources are TypeScript and the tests import `src/` directly (node strips the
|
|
374
380
|
types outside `node_modules`, which is exactly where the tests live), so the
|
|
375
|
-
loop
|
|
381
|
+
loop is: edit `src/`, run `npm test`. Only the packaging fixtures build, and
|
|
376
382
|
they call the same `scripts/build.mjs` the tarball does.
|
|
377
383
|
|
|
378
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,60 @@ 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, stop and report that there is nothing to edit.
|
|
751
|
+
Do not create it.
|
|
761
752
|
|
|
762
753
|
# Reporting
|
|
763
754
|
|
|
764
755
|
Report briefly what you changed and where. Do not edit any other file.`,
|
|
765
756
|
permission: {
|
|
766
|
-
// Read is scoped to the one file too: the directive is about
|
|
757
|
+
// Read is scoped to the one file too: the directive is about AGENTS.md, and
|
|
767
758
|
// nothing else is any of this agent's business.
|
|
768
759
|
read: {
|
|
769
760
|
"*": "deny",
|
|
770
|
-
".
|
|
771
|
-
"
|
|
761
|
+
"AGENTS.md": "allow",
|
|
762
|
+
"*/AGENTS.md": "allow"
|
|
772
763
|
},
|
|
773
764
|
glob: "deny",
|
|
774
765
|
grep: "deny",
|
|
775
766
|
list: "deny",
|
|
776
767
|
edit: {
|
|
777
768
|
"*": "deny",
|
|
778
|
-
".
|
|
779
|
-
"
|
|
769
|
+
"AGENTS.md": "allow",
|
|
770
|
+
"*/AGENTS.md": "allow"
|
|
780
771
|
},
|
|
781
772
|
bash: "deny",
|
|
782
773
|
webfetch: "deny",
|
|
@@ -802,7 +793,7 @@ function buildAgentSet() {
|
|
|
802
793
|
set[`${base}-${slot}`] = variant;
|
|
803
794
|
}
|
|
804
795
|
}
|
|
805
|
-
set[
|
|
796
|
+
set[AGENT_INSTRUCTIONS_WRITER] = INSTRUCTIONS_AGENT;
|
|
806
797
|
return set;
|
|
807
798
|
}
|
|
808
799
|
function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
|
|
@@ -822,7 +813,7 @@ function applyAgents(cfg, agents = buildAgentSet(), opts = {}) {
|
|
|
822
813
|
}
|
|
823
814
|
export {
|
|
824
815
|
AGENTS,
|
|
825
|
-
|
|
816
|
+
INSTRUCTIONS_AGENT,
|
|
826
817
|
POOLED_BASES,
|
|
827
818
|
applyAgents,
|
|
828
819
|
buildAgentSet
|