ramstack 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -9
- package/agents/ram-agent.md +9 -0
- package/cli/{rstack.mjs → ramstack.mjs} +237 -66
- package/package.json +3 -3
- package/skills/arena/SKILL.md +2 -2
- package/skills/automate-me/README.md +1 -1
- package/skills/automate-me/SKILL.md +2 -2
- package/skills/figure-it-out/SKILL.md +1 -1
- package/skills/interrogate/SKILL.md +1 -1
- package/skills/{poteto-mode → ram-mode}/README.md +4 -4
- package/skills/{poteto-mode → ram-mode}/SKILL.md +6 -6
- package/skills/ram-mode/agents/openai.yaml +5 -0
- package/skills/{poteto-mode → ram-mode}/playbooks/autonomous-run.md +2 -2
- package/skills/{poteto-mode → ram-mode}/references/plan.md +4 -4
- package/skills/{poteto-mode → ram-mode}/scripts/bootstrap.ts +1 -1
- package/skills/{poteto-mode → ram-mode}/scripts/bun.lock +1 -1
- package/skills/{poteto-mode → ram-mode}/scripts/package.json +1 -1
- package/skills/{setup-rstack → setup-ramstack}/README.md +5 -5
- package/skills/{setup-rstack → setup-ramstack}/SKILL.md +9 -9
- package/skills/setup-ramstack/agents/openai.yaml +3 -0
- package/skills/swarm/SKILL.md +1 -1
- package/agents/poteto-agent.md +0 -9
- package/skills/poteto-mode/agents/openai.yaml +0 -5
- package/skills/setup-rstack/agents/openai.yaml +0 -3
- /package/skills/{poteto-mode → ram-mode}/playbooks/authoring-a-skill.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/autopilot-full.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/autopilot-stack.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/babysit.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/bug-fix.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/eval.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/feature.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/hillclimb.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/investigation.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/multi-phase-plan.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/opening-a-pr.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/orchestrate.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/pause-safely.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/perf-issue.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/prototype.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/refactoring.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/runtime-forensics.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/session-pickup.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/shipping.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/trace-forensics.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/visual-parity.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/playbooks/worktree-cleanup.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/references/bugbot-triage.md +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/orch/orch.test.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/orch/orch.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/orch/store.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/cli.test.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/cli.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/fakes.test-helper.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/github.test.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/github.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/policy.test.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/policy.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/render.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/tsconfig.json +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/types.compile.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/types.ts +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/watch-pr/watch-pr +0 -0
- /package/skills/{poteto-mode → ram-mode}/scripts/worktree-audit.sh +0 -0
package/README.md
CHANGED
|
@@ -1,32 +1,46 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ramstack
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ramstack is a set of agent skills for Claude Code, Codex, and [pi](https://github.com/badlogic/pi-mono). It is a port of [pstack](https://github.com/cursor/plugins/tree/main/pstack) by [Lauren Tan](https://x.com/poteto).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
Install the skills into every host on your machine:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx ramstack install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
You need Node.js 18 or newer. The installer detects your hosts, shows the plan, and links the skills after you confirm. Then open a host and run:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
/setup-ramstack
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
That writes the model config. You are ready. To try it on a real task, follow [Your first ramstack task](docs/tutorials/get-started.md). For other install paths (a clone, or a single host), see [How to install ramstack](docs/how-to/install.md).
|
|
6
20
|
|
|
7
21
|
## Tutorials
|
|
8
22
|
|
|
9
23
|
Learn by doing.
|
|
10
24
|
|
|
11
|
-
- [
|
|
25
|
+
- [Your first ramstack task](docs/tutorials/get-started.md)
|
|
12
26
|
|
|
13
27
|
## How-to guides
|
|
14
28
|
|
|
15
29
|
Do a job you already understand.
|
|
16
30
|
|
|
17
|
-
- [How to install
|
|
31
|
+
- [How to install ramstack](docs/how-to/install.md)
|
|
18
32
|
- [How to configure models](docs/how-to/configure-models.md)
|
|
19
|
-
- [How to update
|
|
20
|
-
- [How to uninstall
|
|
33
|
+
- [How to update ramstack](docs/how-to/update.md)
|
|
34
|
+
- [How to uninstall ramstack](docs/how-to/uninstall.md)
|
|
21
35
|
|
|
22
36
|
## Explanation
|
|
23
37
|
|
|
24
38
|
Understand the design.
|
|
25
39
|
|
|
26
|
-
- [About
|
|
40
|
+
- [About ramstack](docs/explanation/about-ramstack.md)
|
|
27
41
|
- [About the pstack port](docs/explanation/about-the-pstack-port.md)
|
|
28
42
|
- [About model routing](docs/explanation/about-model-routing.md)
|
|
29
|
-
- [About
|
|
43
|
+
- [About ram-mode](docs/explanation/about-ram-mode.md)
|
|
30
44
|
|
|
31
45
|
## Reference
|
|
32
46
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ram-agent
|
|
3
|
+
description: Routing target for `/ram-mode` and any request for that style. Resume an existing `ram-agent` for the conversation rather than spawning a sibling. Reads the `ram-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `general-purpose` skips that read and drifts.
|
|
4
|
+
is_background: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Ram subagent
|
|
8
|
+
|
|
9
|
+
You are operating in ram-mode. Read the `ram-mode` skill's `SKILL.md` in full before doing any work, including its inline Principles index. Navigate to a leaf `principle-*` skill whenever you apply that principle.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// The
|
|
2
|
+
// The ramstack installer. Links the skills and agents into host discovery
|
|
3
3
|
// directories, so one install serves every host. Two modes: run from a git
|
|
4
4
|
// clone and links point into the clone (update pulls it); run from the npm
|
|
5
5
|
// package (npx ramstack) and the payload copies to ~/.ramstack first, so the
|
|
@@ -11,10 +11,9 @@ import path from 'node:path';
|
|
|
11
11
|
import { execFileSync } from 'node:child_process';
|
|
12
12
|
import { parseArgs } from 'node:util';
|
|
13
13
|
import { fileURLToPath } from 'node:url';
|
|
14
|
-
import readline from 'node:readline/promises';
|
|
15
14
|
|
|
16
15
|
const REPO = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
17
|
-
const CONFIG_PATH = path.join(REPO, '.
|
|
16
|
+
const CONFIG_PATH = path.join(REPO, '.ramstack', 'config.local.json');
|
|
18
17
|
|
|
19
18
|
// Package mode stores its payload copy and saved choices here, so links
|
|
20
19
|
// never point into the npm cache.
|
|
@@ -37,11 +36,11 @@ const HOSTS = {
|
|
|
37
36
|
const HOST_NAMES = Object.keys(HOSTS);
|
|
38
37
|
const SCOPES = ['global', 'project'];
|
|
39
38
|
|
|
40
|
-
const USAGE = `usage:
|
|
39
|
+
const USAGE = `usage: ramstack [install|update|uninstall] [options]
|
|
41
40
|
|
|
42
41
|
commands
|
|
43
|
-
install Link
|
|
44
|
-
update
|
|
42
|
+
install Link the skills and agents into host directories (default)
|
|
43
|
+
update Fetch new files (git pull or npm package), then link again
|
|
45
44
|
uninstall Remove only the links this installer owns
|
|
46
45
|
|
|
47
46
|
options
|
|
@@ -76,9 +75,10 @@ function fail(message) {
|
|
|
76
75
|
|
|
77
76
|
// ── Wizard ───────────────────────────────────────────────────────────────
|
|
78
77
|
// An interactive run on a terminal gets the wizard treatment: a banner, one
|
|
79
|
-
// stage per step,
|
|
80
|
-
//
|
|
81
|
-
//
|
|
78
|
+
// stage per step, arrow-key selectors (multi-select for hosts), a confirm
|
|
79
|
+
// gate before anything changes, and a closing summary. Project scope uses
|
|
80
|
+
// the current directory. A run with --yes, or without a terminal, keeps the
|
|
81
|
+
// plain tag output and never prompts.
|
|
82
82
|
|
|
83
83
|
const COLOR =
|
|
84
84
|
Boolean(process.stdout.isTTY) && process.env.NO_COLOR === undefined && process.env.TERM !== 'dumb';
|
|
@@ -88,11 +88,188 @@ const C = COLOR
|
|
|
88
88
|
|
|
89
89
|
let stageTotal = 0;
|
|
90
90
|
let stageIndex = 0;
|
|
91
|
-
let
|
|
91
|
+
let wizardIo = false;
|
|
92
|
+
|
|
93
|
+
function restoreTty() {
|
|
94
|
+
if (process.stdin.isTTY && typeof process.stdin.setRawMode === 'function') {
|
|
95
|
+
try {
|
|
96
|
+
process.stdin.setRawMode(false);
|
|
97
|
+
} catch {
|
|
98
|
+
// stdin may already be closed on the way out
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (process.stdout.isTTY) process.stdout.write('\x1b[?25h');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function startWizardIo() {
|
|
105
|
+
process.stdin.setRawMode(true);
|
|
106
|
+
process.stdin.resume();
|
|
107
|
+
process.stdin.setEncoding('utf8');
|
|
108
|
+
wizardIo = true;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function stopWizardIo() {
|
|
112
|
+
if (!wizardIo) return;
|
|
113
|
+
wizardIo = false;
|
|
114
|
+
restoreTty();
|
|
115
|
+
process.stdin.pause();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
process.on('exit', restoreTty);
|
|
119
|
+
|
|
120
|
+
function decodeChunk(data) {
|
|
121
|
+
return typeof data === 'string' ? data : String(data);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function readChunk() {
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
if (process.stdin.readableEnded) {
|
|
127
|
+
resolve('\x04');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const onData = (data) => {
|
|
131
|
+
process.stdin.off('end', onEnd);
|
|
132
|
+
resolve(decodeChunk(data));
|
|
133
|
+
};
|
|
134
|
+
const onEnd = () => {
|
|
135
|
+
process.stdin.off('data', onData);
|
|
136
|
+
resolve('\x04');
|
|
137
|
+
};
|
|
138
|
+
process.stdin.once('data', onData);
|
|
139
|
+
process.stdin.once('end', onEnd);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function readChunkTimeout(ms) {
|
|
144
|
+
return new Promise((resolve) => {
|
|
145
|
+
const timer = setTimeout(() => {
|
|
146
|
+
process.stdin.off('data', onData);
|
|
147
|
+
resolve(null);
|
|
148
|
+
}, ms);
|
|
149
|
+
const onData = (data) => {
|
|
150
|
+
clearTimeout(timer);
|
|
151
|
+
resolve(decodeChunk(data));
|
|
152
|
+
};
|
|
153
|
+
process.stdin.once('data', onData);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async function readKey() {
|
|
158
|
+
let chunk = await readChunk();
|
|
159
|
+
if (chunk === '\x1b' || chunk === '\x1b[' || chunk === '\x1bO') {
|
|
160
|
+
const rest = await readChunkTimeout(30);
|
|
161
|
+
if (rest) chunk += rest;
|
|
162
|
+
}
|
|
163
|
+
if (chunk === '\x1b[A' || chunk === '\x1bOA' || chunk === 'k') return 'up';
|
|
164
|
+
if (chunk === '\x1b[B' || chunk === '\x1bOB' || chunk === 'j') return 'down';
|
|
165
|
+
if (chunk === '\r' || chunk === '\n') return 'enter';
|
|
166
|
+
if (chunk === ' ') return 'space';
|
|
167
|
+
if (chunk === '\x03' || chunk === '\x04' || chunk === '\x1b' || chunk === 'q') return 'cancel';
|
|
168
|
+
return 'other';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function cancelWizard() {
|
|
172
|
+
restoreTty();
|
|
173
|
+
fail('\nerror: cancelled.');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function pause(message) {
|
|
177
|
+
process.stdout.write(` ${C.dim}${message}${C.reset}`);
|
|
178
|
+
for (;;) {
|
|
179
|
+
const key = await readKey();
|
|
180
|
+
if (key === 'enter') break;
|
|
181
|
+
if (key === 'cancel') cancelWizard();
|
|
182
|
+
}
|
|
183
|
+
process.stdout.write('\n');
|
|
184
|
+
}
|
|
92
185
|
|
|
93
|
-
function
|
|
94
|
-
|
|
95
|
-
|
|
186
|
+
async function select({ message, options, multiple = false, initial, emptyError }) {
|
|
187
|
+
const known = new Set(options.map((opt) => opt.value));
|
|
188
|
+
const chosen = new Set();
|
|
189
|
+
if (multiple) {
|
|
190
|
+
for (const value of initial ?? []) {
|
|
191
|
+
if (known.has(value)) chosen.add(value);
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
const start = known.has(initial) ? initial : options[0]?.value;
|
|
195
|
+
if (start !== undefined) chosen.add(start);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
let index = Math.max(
|
|
199
|
+
0,
|
|
200
|
+
options.findIndex((opt) => chosen.has(opt.value)),
|
|
201
|
+
);
|
|
202
|
+
let error = '';
|
|
203
|
+
let rendered = 0;
|
|
204
|
+
process.stdout.write('\x1b[?25l');
|
|
205
|
+
|
|
206
|
+
const paint = () => {
|
|
207
|
+
const help = multiple
|
|
208
|
+
? '↑/↓ move · space toggle · enter confirm'
|
|
209
|
+
: '↑/↓ move · enter choose';
|
|
210
|
+
const rows = [` ${message}`, ` ${C.dim}${help}${C.reset}`, ''];
|
|
211
|
+
const labelWidth = options.some((opt) => opt.hint)
|
|
212
|
+
? Math.max(...options.map((opt) => opt.label.length))
|
|
213
|
+
: 0;
|
|
214
|
+
for (const [i, opt] of options.entries()) {
|
|
215
|
+
const on = chosen.has(opt.value);
|
|
216
|
+
const pointer = i === index ? `${C.blue}❯${C.reset}` : ' ';
|
|
217
|
+
const mark = on ? `${C.green}●${C.reset}` : '○';
|
|
218
|
+
const label = opt.label.padEnd(labelWidth);
|
|
219
|
+
const hint = opt.hint ? ` ${C.dim}${opt.hint}${C.reset}` : '';
|
|
220
|
+
rows.push(` ${pointer} ${multiple ? `${mark} ` : ''}${label}${hint}`);
|
|
221
|
+
}
|
|
222
|
+
if (error) rows.push('', ` ${C.yellow}${error}${C.reset}`);
|
|
223
|
+
const text = rows.join('\n');
|
|
224
|
+
if (rendered > 0) process.stdout.write(`\x1b[${rendered}A\r\x1b[J`);
|
|
225
|
+
process.stdout.write(`${text}\n`);
|
|
226
|
+
rendered = text.split('\n').length;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
const collapse = (summary) => {
|
|
230
|
+
process.stdout.write(`\x1b[${rendered}A\r\x1b[J`);
|
|
231
|
+
process.stdout.write(` ${message} ${C.green}${summary}${C.reset}\n`);
|
|
232
|
+
process.stdout.write('\x1b[?25h');
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
console.log('');
|
|
236
|
+
paint();
|
|
237
|
+
for (;;) {
|
|
238
|
+
const key = await readKey();
|
|
239
|
+
if (key === 'cancel') cancelWizard();
|
|
240
|
+
if (key === 'up') {
|
|
241
|
+
index = (index + options.length - 1) % options.length;
|
|
242
|
+
paint();
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (key === 'down') {
|
|
246
|
+
index = (index + 1) % options.length;
|
|
247
|
+
paint();
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (key === 'space' && multiple) {
|
|
251
|
+
const value = options[index].value;
|
|
252
|
+
if (chosen.has(value)) chosen.delete(value);
|
|
253
|
+
else chosen.add(value);
|
|
254
|
+
error = '';
|
|
255
|
+
paint();
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
if (key === 'enter') {
|
|
259
|
+
if (!multiple) {
|
|
260
|
+
collapse(options[index].label);
|
|
261
|
+
return options[index].value;
|
|
262
|
+
}
|
|
263
|
+
if (chosen.size === 0) {
|
|
264
|
+
error = emptyError ?? 'select at least one option';
|
|
265
|
+
paint();
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
const values = options.filter((opt) => chosen.has(opt.value)).map((opt) => opt.value);
|
|
269
|
+
collapse(values.join(', '));
|
|
270
|
+
return values;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
96
273
|
}
|
|
97
274
|
|
|
98
275
|
async function banner(title) {
|
|
@@ -101,7 +278,7 @@ async function banner(title) {
|
|
|
101
278
|
console.log(`${C.dim} ${stageTotal} stages${C.reset}\n`);
|
|
102
279
|
console.log(`${C.dim} The installer shows each step before it runs. Stop any time with${C.reset}`);
|
|
103
280
|
console.log(`${C.dim} Ctrl-C and re-run later. Saved choices become the defaults.${C.reset}\n`);
|
|
104
|
-
await
|
|
281
|
+
await pause('Ready to start? [Enter]');
|
|
105
282
|
}
|
|
106
283
|
|
|
107
284
|
function stage(name) {
|
|
@@ -115,10 +292,15 @@ function note(message) {
|
|
|
115
292
|
}
|
|
116
293
|
|
|
117
294
|
async function confirm(question) {
|
|
118
|
-
const answer =
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
295
|
+
const answer = await select({
|
|
296
|
+
message: question,
|
|
297
|
+
options: [
|
|
298
|
+
{ value: 'no', label: 'No' },
|
|
299
|
+
{ value: 'yes', label: 'Yes' },
|
|
300
|
+
],
|
|
301
|
+
initial: 'no',
|
|
302
|
+
});
|
|
303
|
+
return answer === 'yes';
|
|
122
304
|
}
|
|
123
305
|
|
|
124
306
|
function finish(headline, notes = []) {
|
|
@@ -162,7 +344,7 @@ function saveConfig(clone, config) {
|
|
|
162
344
|
const file = configPath(clone);
|
|
163
345
|
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
164
346
|
fs.writeFileSync(file, `${JSON.stringify(config, null, 2)}\n`);
|
|
165
|
-
say('save', clone ? '.
|
|
347
|
+
say('save', clone ? '.ramstack/config.local.json' : file);
|
|
166
348
|
}
|
|
167
349
|
|
|
168
350
|
function plan(hosts, base) {
|
|
@@ -317,40 +499,33 @@ function gitPull() {
|
|
|
317
499
|
|
|
318
500
|
async function promptHosts(defaults) {
|
|
319
501
|
const detected = detectHosts();
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
const hosts = parseHosts(list);
|
|
337
|
-
if (hosts.length === 0) fail('error: no hosts selected.');
|
|
338
|
-
return hosts;
|
|
502
|
+
const initial = defaults.filter((name) => HOST_NAMES.includes(name));
|
|
503
|
+
return select({
|
|
504
|
+
message: 'Hosts',
|
|
505
|
+
multiple: true,
|
|
506
|
+
emptyError: 'select at least one host',
|
|
507
|
+
initial: initial.length ? initial : detectedOrAll(),
|
|
508
|
+
options: HOST_NAMES.map((name) => {
|
|
509
|
+
const hit = detected.includes(name);
|
|
510
|
+
const marker = HOSTS[name].marker;
|
|
511
|
+
return {
|
|
512
|
+
value: name,
|
|
513
|
+
label: name,
|
|
514
|
+
hint: hit ? `found ~/${marker}` : `no ~/${marker}`,
|
|
515
|
+
};
|
|
516
|
+
}),
|
|
517
|
+
});
|
|
339
518
|
}
|
|
340
519
|
|
|
341
520
|
async function promptScope(defaultScope) {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
async function promptProjectDir(defaultDir) {
|
|
352
|
-
const answer = (await getRl().question(` Project directory? [${defaultDir}] `)).trim();
|
|
353
|
-
return answer ? path.resolve(answer) : defaultDir;
|
|
521
|
+
return select({
|
|
522
|
+
message: 'Scope',
|
|
523
|
+
initial: defaultScope === 'project' ? 'project' : 'global',
|
|
524
|
+
options: [
|
|
525
|
+
{ value: 'global', label: 'global', hint: 'home directory, all projects' },
|
|
526
|
+
{ value: 'project', label: 'project', hint: `this directory, ${process.cwd()}` },
|
|
527
|
+
],
|
|
528
|
+
});
|
|
354
529
|
}
|
|
355
530
|
|
|
356
531
|
function showPlan(hosts, scope, base, clone) {
|
|
@@ -409,26 +584,23 @@ async function main() {
|
|
|
409
584
|
const saved = readConfig(clone);
|
|
410
585
|
let hosts = values.hosts ? parseHosts(values.hosts) : null;
|
|
411
586
|
let scope = values.scope ? parseScope(values.scope) : null;
|
|
412
|
-
const wizard = !values.yes && process.stdout.isTTY;
|
|
587
|
+
const wizard = !values.yes && process.stdout.isTTY && process.stdin.isTTY;
|
|
413
588
|
|
|
414
589
|
try {
|
|
590
|
+
if (wizard) startWizardIo();
|
|
415
591
|
if (command === 'install') {
|
|
416
592
|
if (wizard) {
|
|
417
593
|
stageTotal = 2 + (hosts ? 0 : 1) + (scope ? 0 : 1);
|
|
418
|
-
await banner('
|
|
594
|
+
await banner('ramstack install');
|
|
419
595
|
if (!hosts) {
|
|
420
596
|
stage('Hosts');
|
|
421
597
|
hosts = await promptHosts(saved?.hosts ?? detectedOrAll());
|
|
422
598
|
}
|
|
423
|
-
let projectDir = values['project-dir'] ?? saved?.projectDir;
|
|
424
599
|
if (!scope) {
|
|
425
600
|
stage('Scope');
|
|
426
601
|
scope = await promptScope(saved?.scope ?? 'global');
|
|
427
|
-
if (scope === 'project' && !values['project-dir']) {
|
|
428
|
-
projectDir = await promptProjectDir(saved?.projectDir ?? process.cwd());
|
|
429
|
-
}
|
|
430
602
|
}
|
|
431
|
-
const base = resolveBase(scope,
|
|
603
|
+
const base = resolveBase(scope, values['project-dir']);
|
|
432
604
|
stage('Review');
|
|
433
605
|
showPlan(hosts, scope, base, clone);
|
|
434
606
|
if (values.force) note('--force is on: a conflicting real file moves to <name>.bak first.');
|
|
@@ -442,13 +614,13 @@ async function main() {
|
|
|
442
614
|
...(counts.skip > 0
|
|
443
615
|
? [`${counts.skip} name(s) skipped. Rename or remove the real files, then run install again.`]
|
|
444
616
|
: []),
|
|
445
|
-
'next: run /setup-
|
|
617
|
+
'next: run /setup-ramstack in each host to configure models',
|
|
446
618
|
]);
|
|
447
619
|
return;
|
|
448
620
|
}
|
|
449
621
|
hosts ??= detectedOrAll();
|
|
450
622
|
scope ??= 'global';
|
|
451
|
-
const base = resolveBase(scope, values['project-dir']
|
|
623
|
+
const base = resolveBase(scope, values['project-dir']);
|
|
452
624
|
if (!clone) syncStore();
|
|
453
625
|
const counts = runLink(hosts, base, values.force, src);
|
|
454
626
|
if (clone) configureGitHooks();
|
|
@@ -457,7 +629,7 @@ async function main() {
|
|
|
457
629
|
if (counts.skip > 0) {
|
|
458
630
|
say('note', `${counts.skip} name(s) skipped. Rename or remove the real files, then run install again.`);
|
|
459
631
|
}
|
|
460
|
-
say('next', 'run /setup-
|
|
632
|
+
say('next', 'run /setup-ramstack in each host to configure models');
|
|
461
633
|
return;
|
|
462
634
|
}
|
|
463
635
|
|
|
@@ -467,7 +639,7 @@ async function main() {
|
|
|
467
639
|
const base = resolveBase(scope, values['project-dir'] ?? saved?.projectDir);
|
|
468
640
|
if (wizard) {
|
|
469
641
|
stageTotal = clone && !values['no-pull'] ? 3 : 2;
|
|
470
|
-
await banner('
|
|
642
|
+
await banner('ramstack update');
|
|
471
643
|
stage('Review');
|
|
472
644
|
showPlan(hosts, scope, base, clone);
|
|
473
645
|
note(
|
|
@@ -507,7 +679,7 @@ async function main() {
|
|
|
507
679
|
const base = resolveBase(scope, values['project-dir'] ?? saved?.projectDir);
|
|
508
680
|
if (wizard) {
|
|
509
681
|
stageTotal = 2;
|
|
510
|
-
await banner('
|
|
682
|
+
await banner('ramstack uninstall');
|
|
511
683
|
stage('Review');
|
|
512
684
|
showPlan(hosts, scope, base, clone);
|
|
513
685
|
note(
|
|
@@ -520,7 +692,7 @@ async function main() {
|
|
|
520
692
|
runUnlink(hosts, base, src);
|
|
521
693
|
finish(`links removed for ${hosts.join(', ')} (${scope})`, [
|
|
522
694
|
clone
|
|
523
|
-
? 'the clone, .
|
|
695
|
+
? 'the clone, .ramstack/config.local.json, and core.hooksPath stay'
|
|
524
696
|
: `the store at ${STORE} stays; delete it to remove the copied skills`,
|
|
525
697
|
]);
|
|
526
698
|
return;
|
|
@@ -528,11 +700,10 @@ async function main() {
|
|
|
528
700
|
runUnlink(hosts, base, src);
|
|
529
701
|
say('done', `links removed for ${hosts.join(', ')} (${scope})`);
|
|
530
702
|
} catch (error) {
|
|
531
|
-
|
|
532
|
-
if (error?.code === 'ABORT_ERR') fail('\nerror: cancelled.');
|
|
703
|
+
restoreTty();
|
|
533
704
|
throw error;
|
|
534
705
|
} finally {
|
|
535
|
-
|
|
706
|
+
stopWizardIo();
|
|
536
707
|
}
|
|
537
708
|
}
|
|
538
709
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ramstack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Agent skills for Claude Code, Codex, and pi",
|
|
5
|
-
"author": "Justin Ramos
|
|
5
|
+
"author": "Justin Ramos",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"skills"
|
|
17
17
|
],
|
|
18
18
|
"bin": {
|
|
19
|
-
"
|
|
19
|
+
"ramstack": "cli/ramstack.mjs"
|
|
20
20
|
},
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=18"
|
package/skills/arena/SKILL.md
CHANGED
|
@@ -25,7 +25,7 @@ The N candidates will receive the same prompt, so the prompt is the contract. Ge
|
|
|
25
25
|
|
|
26
26
|
1. State the artifact each candidate is producing.
|
|
27
27
|
2. Derive the rubric. State what success looks like for *this* task, then turn it into 3-6 concrete gradeable criteria. Concrete: `Adds a --dry-run flag that skips writes`. Vague: `code is correct`. The rubric is the picker's tool in Phase D; candidates only see the task.
|
|
28
|
-
3. Pick the runners. Use `arena runners` from your host's `## <host>` section of `~/.agents/
|
|
28
|
+
3. Pick the runners. Use `arena runners` from your host's `## <host>` section of `~/.agents/ramstack-models.md` when present. Otherwise default to one each on `fable`, `opus`, `sonnet`. Spawn more when the arena covers multiple design directions. Same model N times when the work is generation-bound rather than judgment-sensitive.
|
|
29
29
|
4. Assign output paths. Each candidate writes to its own location (a git worktree where possible, otherwise `/tmp/arena-<slug>/candidate-<n>/`). N candidates writing to the same path is shared mutable state and fails the the **separate-before-serializing-shared-state** principle skill test.
|
|
30
30
|
|
|
31
31
|
## Phase B: Fan out
|
|
@@ -38,7 +38,7 @@ If a candidate fails to produce output, proceed with N-1 and note the dropout in
|
|
|
38
38
|
|
|
39
39
|
## Phase C: Cross-judge
|
|
40
40
|
|
|
41
|
-
After all Phase B candidates complete, choose one model from the `arena cross-judge pool` in your host's `## <host>` section of `~/.agents/
|
|
41
|
+
After all Phase B candidates complete, choose one model from the `arena cross-judge pool` in your host's `## <host>` section of `~/.agents/ramstack-models.md` when present. Otherwise use `fable`, `opus`, `sonnet`. Prefer a different model family from the parent's. Spawn one readonly judge subagent on that model. It sees the rubric and the candidates by path label, scores each criterion, and recommends a base with rationale. It runs in parallel with the parent's reading in Phase D, not with the candidates themselves. Spawning while candidates are still writing means the judge sees partial or empty outputs and reports them as dropouts.
|
|
42
42
|
|
|
43
43
|
## Phase D: Pick a base
|
|
44
44
|
|
|
@@ -14,7 +14,7 @@ A `<handle>-mode/SKILL.md` skill file that encodes your response preferences, de
|
|
|
14
14
|
|
|
15
15
|
## How it works
|
|
16
16
|
|
|
17
|
-
The skill mines recent agent transcripts in parallel slices for recurring patterns, asks you structured questions to fill gaps the mining missed, clusters findings into sections, drafts the skill (using the host's skill-authoring skill when available), and iterates on prose with the `unslop` skill. Patterns need 2+ independent sightings before they get codified. The `
|
|
17
|
+
The skill mines recent agent transcripts in parallel slices for recurring patterns, asks you structured questions to fill gaps the mining missed, clusters findings into sections, drafts the skill (using the host's skill-authoring skill when available), and iterates on prose with the `unslop` skill. Patterns need 2+ independent sightings before they get codified. The `ram-mode` skill serves as the reference shape.
|
|
18
18
|
|
|
19
19
|
## Related
|
|
20
20
|
|
|
@@ -60,7 +60,7 @@ Group the combined signals into sections. Common ones (use only what applies):
|
|
|
60
60
|
- **Process**: git worktrees, commits, PRs, review/merge tooling.
|
|
61
61
|
- **Skills**: skill-authoring habits, fix-the-skill-first, proposing new skills.
|
|
62
62
|
|
|
63
|
-
The **
|
|
63
|
+
The **ram-mode** skill shows the shape. Read it for granularity. Don't copy its content; the user's rules are not the same as ram-mode's.
|
|
64
64
|
|
|
65
65
|
### 4. Draft the skill
|
|
66
66
|
|
|
@@ -104,6 +104,6 @@ Run a description-optimization loop only if the skill's trigger accuracy turns o
|
|
|
104
104
|
|
|
105
105
|
## Reference files
|
|
106
106
|
|
|
107
|
-
- The **
|
|
107
|
+
- The **ram-mode** skill: example of the output shape.
|
|
108
108
|
- The **unslop** skill: prose discipline for every line.
|
|
109
109
|
- The host's skill-authoring skill (when installed): skill authoring process and writing guidelines.
|
|
@@ -12,7 +12,7 @@ Don't reinvent a playbook you already have. A focused single-unit task that matc
|
|
|
12
12
|
|
|
13
13
|
## Start
|
|
14
14
|
|
|
15
|
-
Open a todolist whose first item is to read the Principles section of the **
|
|
15
|
+
Open a todolist whose first item is to read the Principles section of the **ram-mode** skill. Then add the phases below as todos.
|
|
16
16
|
|
|
17
17
|
## Phase A: Frame
|
|
18
18
|
|
|
@@ -33,7 +33,7 @@ Write one clear paragraph. Reviewers challenge whether the work achieves the int
|
|
|
33
33
|
|
|
34
34
|
## Step 3, Spawn Reviewers
|
|
35
35
|
|
|
36
|
-
Launch all reviewers in a single message using the subagent tool. Use the `interrogate reviewers` list from your host's `## <host>` section of `~/.agents/
|
|
36
|
+
Launch all reviewers in a single message using the subagent tool. Use the `interrogate reviewers` list from your host's `## <host>` section of `~/.agents/ramstack-models.md` when present, one reviewer per entry, extending or shrinking the Reviewer A/B/C labels below to the configured entry count; otherwise use the table defaults.
|
|
37
37
|
|
|
38
38
|
| Subagent | Default model |
|
|
39
39
|
|----------|---------------|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Ram mode
|
|
2
2
|
|
|
3
3
|
Opt-in rigor wrapper. Matches a task to a playbook, cites engineering principles, routes bulk work to subagents, and keeps the parent agent in the lead.
|
|
4
4
|
|
|
5
5
|
## When to use
|
|
6
6
|
|
|
7
|
-
- `/
|
|
7
|
+
- `/ram-mode` or "ram-mode"
|
|
8
8
|
- Any task that needs structured rigor: features, bug fixes, investigations, refactoring, shipping
|
|
9
9
|
|
|
10
10
|
## What it produces
|
|
@@ -13,7 +13,7 @@ A todolist driven by the matched playbook's steps, principle citations tied to r
|
|
|
13
13
|
|
|
14
14
|
## How it works
|
|
15
15
|
|
|
16
|
-
The mode matches the task to one of 23 bundled playbooks (feature, bug fix, investigation, refactoring, and others). The playbook's steps become the todolist verbatim. Principles from the index are read as leaf skills and cited only when they change a real choice. Code-writing steps go to `
|
|
16
|
+
The mode matches the task to one of 23 bundled playbooks (feature, bug fix, investigation, refactoring, and others). The playbook's steps become the todolist verbatim. Principles from the index are read as leaf skills and cited only when they change a real choice. Code-writing steps go to `ram-agent` subagents. Review panels use the configured models. The parent reviews every diff and writes its own summary.
|
|
17
17
|
|
|
18
18
|
The mode is opt-in. `disable-model-invocation: true` prevents the host from applying it to prompts that just look similar.
|
|
19
19
|
|
|
@@ -22,5 +22,5 @@ The mode is opt-in. `disable-model-invocation: true` prevents the host from appl
|
|
|
22
22
|
- [SKILL.md](SKILL.md)
|
|
23
23
|
- [playbooks/](playbooks/) (23 playbook files)
|
|
24
24
|
- [references/](references/) (bugbot triage, plan template)
|
|
25
|
-
- [About
|
|
25
|
+
- [About ram-mode](../../docs/explanation/about-ram-mode.md)
|
|
26
26
|
- [Playbooks reference](../../docs/reference/playbooks.md)
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
2
|
+
name: ram-mode
|
|
3
|
+
description: Ram-mode agent style for concise, detailed responses, deliberate subagents, unslopped prose, simple code, and verified work. Use for ram-mode, /ram-mode, or requests to work in this style.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
mode: true
|
|
6
6
|
icon: crown
|
|
7
7
|
color: yellow
|
|
8
|
-
reminder: New task? Playbook match or rigor needed -> apply /
|
|
8
|
+
reminder: New task? Playbook match or rigor needed -> apply /ram-mode. Casual turn or user opts out -> don't.
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
#
|
|
11
|
+
# Ram mode
|
|
12
12
|
|
|
13
13
|
## Non-negotiables
|
|
14
14
|
|
|
@@ -86,9 +86,9 @@ Read the leaf skill in full for any principle you apply. Each entry names when i
|
|
|
86
86
|
|
|
87
87
|
## Subagents
|
|
88
88
|
|
|
89
|
-
**Use `subagent_type: "
|
|
89
|
+
**Use `subagent_type: "ram-agent"` for any subagent you spawn inside a playbook step** (code-writing delegates, ad-hoc helpers). `/ram-mode` and `ram-agent` route through the same wrapper. Routed workflow skills (`how`, `why`, `interrogate`, `reflect`, `swarm`) set their own `subagent_type` for diverse-model review; respect what the skill prescribes, don't override to `ram-agent`.
|
|
90
90
|
|
|
91
|
-
**Defaults for every subagent call.** Run in the background when the host supports it, file pointers not inlined context, explicit model per role (configurable via `/setup-
|
|
91
|
+
**Defaults for every subagent call.** Run in the background when the host supports it, file pointers not inlined context, explicit model per role (configurable via `/setup-ramstack`; defaults `sonnet` for code, `fable` for prose and judgment). Code delegates tier by difficulty. The hardest changes (cross-cutting design, gnarly concurrency, subtle algorithms) go to your strongest judgment model (`fable`) when the task needs judgment or the intent is vague, and to your strongest instruction-following model (`opus`) when the work is a precisely specified sequence of steps to execute to the letter; trivial mechanical edits go to your fast code model. Per-role lines in your host's section of the `/setup-ramstack` config (`~/.agents/ramstack-models.md`) override these defaults and the model choices in the routed skills (`how`, `why`, `arena`, `swarm`, `architect`, `interrogate`, `reflect`); a role with no line keeps its default, and a role line of `inherit-parent` or `auto` runs that role on the parent chat model (omit the subagent `model` param).
|
|
92
92
|
|
|
93
93
|
You own every subagent's work. Review the diff and write your own summary, don't pass through what it said. Interrupt-chained resumes silently drop directives, so fire a fresh subagent with consolidated scope rather than trusting a "done" summary. A second opinion is the same prompt against a different model. Agreement is high-signal.
|
|
94
94
|
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
**You own the exit condition. Define done, then drive to it without stopping.** For "going to bed" / "run until done" / "/loop until X".
|
|
4
4
|
|
|
5
5
|
1. State the exit condition as a checkable predicate before the first iteration (tests green, repro fixed, all N PRs merged, pixel-diff zero). A vague goal stalls; a predicate lets you stop.
|
|
6
|
-
2. Pick the wake mechanism using the host's `/loop` command when it has one (a built-in, not a
|
|
6
|
+
2. Pick the wake mechanism using the host's `/loop` command when it has one (a built-in, not a ramstack skill). An event to watch (CI, a merge, a ref advancing) gets a watcher subagent that wakes you on the event, with a long time-based heartbeat as fallback. No event gets a fixed-interval heartbeat sized to when the result is worth re-checking.
|
|
7
7
|
3. Each iteration makes the smallest change the evidence justifies, verifies it against the predicate, commits if it advanced, discards changes that didn't help. Belt-and-suspenders that "might help" gets reverted, not left to ride.
|
|
8
8
|
Sequence the work via the **sequence-verifiable-units** principle skill, verifying each unit before the next instead of batching checks at the end.
|
|
9
|
-
4. Mid-run discoveries are yours. Address broken skills, related bugs, flaky verifiers, review noise, tooling failures, orphaned follow-ups, and fixable drift yourself via
|
|
9
|
+
4. Mid-run discoveries are yours. Address broken skills, related bugs, flaky verifiers, review noise, tooling failures, orphaned follow-ups, and fixable drift yourself via ram-mode. Put out-of-band fixes in their own PR. Do not park reversible work for the human or use `AskUserQuestion`. Surface only irreversible actions, genuine product or preference calls no experiment can settle, or a real dead end. Keep the predicate as the main drive, and return to it after each side fix.
|
|
10
10
|
5. Checkpoint every iteration via the **show-me-your-work** skill, a row for what changed and whether the predicate moved. A run with no trail can't be audited or resumed.
|
|
11
11
|
6. Stop when the predicate is met. A plateau is not a stop, so keep going and pivot your approach to push past it. Surface a genuine dead end rather than spinning, and never relax the predicate to declare victory.
|
|
12
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Plan
|
|
2
2
|
|
|
3
|
-
Produce a phased implementation plan grounded in the **Principles** section of the `
|
|
3
|
+
Produce a phased implementation plan grounded in the **Principles** section of the `ram-mode` skill. The plan is the deliverable. Do not implement.
|
|
4
4
|
|
|
5
5
|
Open a todolist with one item per step below.
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ Plan when the change spans three or more files, introduces architecture, has com
|
|
|
12
12
|
|
|
13
13
|
## 1. Re-read principles
|
|
14
14
|
|
|
15
|
-
Read the **Principles** section of the `
|
|
15
|
+
Read the **Principles** section of the `ram-mode` skill end to end, and the leaf `principle-*` skills it indexes. The principles govern every plan decision; cross-link them.
|
|
16
16
|
|
|
17
17
|
## 2. Scope and constraints
|
|
18
18
|
|
|
@@ -24,7 +24,7 @@ Resolve what is in scope vs explicitly out, technical or platform constraints, p
|
|
|
24
24
|
|
|
25
25
|
Delegate codebase exploration (the **guard-the-context-window** principle skill).
|
|
26
26
|
|
|
27
|
-
- Prefer `subagent_type: "
|
|
27
|
+
- Prefer `subagent_type: "ram-agent"`. `general-purpose` is the fallback. Never use the built-in `plan` subagent_type; it ignores this skill.
|
|
28
28
|
- Pass `model:` explicitly per the configured roles (defaults `sonnet` for code, `fable` for judgment).
|
|
29
29
|
|
|
30
30
|
Each explorer returns file pointers, conventions, dependencies, test infrastructure, and entry points. No inlined dumps.
|
|
@@ -92,7 +92,7 @@ For bug fixes, the loop is reproduce on the surface, fix, verify on the same sur
|
|
|
92
92
|
|
|
93
93
|
## 6. Implementation guidance
|
|
94
94
|
|
|
95
|
-
In the overview, name which
|
|
95
|
+
In the overview, name which ram-mode non-negotiables the implementer must apply, by name:
|
|
96
96
|
|
|
97
97
|
- the **how** skill over each unfamiliar subsystem before changing it.
|
|
98
98
|
- the **interrogate** skill for adversarial review on contested designs before shipping.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# Setup
|
|
1
|
+
# Setup ramstack
|
|
2
2
|
|
|
3
|
-
Write the current host's section of `~/.agents/
|
|
3
|
+
Write the current host's section of `~/.agents/ramstack-models.md`, the config file that sets a model per role for ramstack skills.
|
|
4
4
|
|
|
5
5
|
## When to use
|
|
6
6
|
|
|
7
|
-
- `/setup-
|
|
8
|
-
- After installing
|
|
7
|
+
- `/setup-ramstack` or "configure ramstack models"
|
|
8
|
+
- After installing ramstack on a new host
|
|
9
9
|
- After model availability changes
|
|
10
10
|
|
|
11
11
|
## What it produces
|
|
12
12
|
|
|
13
|
-
A `## <host>` section in `~/.agents/
|
|
13
|
+
A `## <host>` section in `~/.agents/ramstack-models.md` with one line per role. Other host sections in the file stay unchanged. Creates the file with a header comment if it does not exist.
|
|
14
14
|
|
|
15
15
|
## How it works
|
|
16
16
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: setup-
|
|
3
|
-
description: Configure which models
|
|
2
|
+
name: setup-ramstack
|
|
3
|
+
description: Configure which models ramstack uses per role, for the host you're running in (Claude Code, Codex, or pi). Detects your available models and writes your host's section of the shared config file. Use for /setup-ramstack, "configure ramstack models", or changing ramstack's model choices.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Setup
|
|
6
|
+
# Setup ramstack
|
|
7
7
|
|
|
8
|
-
Write your host's section of `~/.agents/
|
|
8
|
+
Write your host's section of `~/.agents/ramstack-models.md`, a config file that sets ramstack's model per role. The skills read it at run time and fall back to their inline defaults when a section or line is absent, so this is an override layer, not a requirement.
|
|
9
9
|
|
|
10
10
|
The file is shared across hosts on purpose. Model slugs differ per host (`sonnet` means something in Claude Code and nothing in Codex or pi), so the file holds one `## <host>` section per tool, and every skill reads only the section for the host it is running in. Someone who switches between Claude Code, Codex, and pi runs this skill once in each and the tools stop stepping on each other.
|
|
11
11
|
|
|
@@ -25,7 +25,7 @@ If the host has a models API or CLI that lists the user's entitled models, prefe
|
|
|
25
25
|
|
|
26
26
|
### 2. Load current state
|
|
27
27
|
|
|
28
|
-
If `~/.agents/
|
|
28
|
+
If `~/.agents/ramstack-models.md` exists and has a section for this host, read it and treat its values as the current choices. Otherwise start from the defaults in step 5. Never treat another host's section as current state; its slugs are not valid here.
|
|
29
29
|
|
|
30
30
|
### 3. Map and confirm
|
|
31
31
|
|
|
@@ -37,12 +37,12 @@ Every real slug written must be in the detected set; `inherit-parent` and `auto`
|
|
|
37
37
|
|
|
38
38
|
### 5. Write the config
|
|
39
39
|
|
|
40
|
-
Rewrite this host's `## <host>` section of `~/.agents/
|
|
40
|
+
Rewrite this host's `## <host>` section of `~/.agents/ramstack-models.md` with one line per role, using the same labels ram-mode uses. Preserve every other host's section byte for byte; create the file with the header comment below if it doesn't exist. Re-runs stay idempotent by replacing the whole section.
|
|
41
41
|
|
|
42
42
|
Shape, with the Claude Code defaults filled in (another host substitutes its own detected slugs under its own heading, keeping the same roles):
|
|
43
43
|
|
|
44
44
|
```
|
|
45
|
-
#
|
|
45
|
+
# ramstack model configuration. One `## <host>` section per tool; skills read only
|
|
46
46
|
# the section for the host they run in. One line per role. Delete a line (or a
|
|
47
47
|
# section) to fall back to the skill defaults.
|
|
48
48
|
# `inherit-parent` or `auto` as a value: the role runs on the parent chat model
|
|
@@ -74,8 +74,8 @@ The role split follows the upstream design: fast mechanical code goes to the fas
|
|
|
74
74
|
|
|
75
75
|
### 6. Confirm
|
|
76
76
|
|
|
77
|
-
Tell the user which host section was written and that skills read it on their next run. If the file has sections for other hosts, say so; if it doesn't, suggest running `/setup-
|
|
77
|
+
Tell the user which host section was written and that skills read it on their next run. If the file has sections for other hosts, say so; if it doesn't, suggest running `/setup-ramstack` inside each other tool they use so every host gets valid slugs.
|
|
78
78
|
|
|
79
79
|
### 7. Offer a verification skill (optional)
|
|
80
80
|
|
|
81
|
-
Check whether the project has a way to drive the real app for proof (a `verify-*` skill, or an existing harness). If not, offer once: "want a project-local verification skill, so agents can drive the app the way a user does and prove changes work? I can generate one with /create-verification-skill." On yes, invoke `/create-verification-skill` (resolves wherever
|
|
81
|
+
Check whether the project has a way to drive the real app for proof (a `verify-*` skill, or an existing harness). If not, offer once: "want a project-local verification skill, so agents can drive the app the way a user does and prove changes work? I can generate one with /create-verification-skill." On yes, invoke `/create-verification-skill` (resolves wherever ramstack is installed — workspace, user, or plugin). On no, move on without pushing.
|
package/skills/swarm/SKILL.md
CHANGED
|
@@ -22,7 +22,7 @@ Open a todolist with one entry per phase before launching anything.
|
|
|
22
22
|
1. State the done predicate and the artifact or report the swarm must return.
|
|
23
23
|
2. Choose the shape. Partition into slices, race N workers on identical briefs, or mix both. For a race or mixed shape, declare `first pass`, `rank all`, or `best-of` before spawning.
|
|
24
24
|
3. Set N from the user or derive it from the shape. N is total workers, not the cloud concurrency limit.
|
|
25
|
-
4. Pick the worker model from `swarm workers` in your host's `## <host>` section of `~/.agents/
|
|
25
|
+
4. Pick the worker model from `swarm workers` in your host's `## <host>` section of `~/.agents/ramstack-models.md` when present. Otherwise use `sonnet`. For a model race, name each arm's model up front.
|
|
26
26
|
5. Give each worker its own writable output when it writes. Use a worktree, branch, or `/tmp/swarm-<slug>/worker-<n>/`.
|
|
27
27
|
|
|
28
28
|
## Phase B: Fan out
|
package/agents/poteto-agent.md
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: poteto-agent
|
|
3
|
-
description: Routing target for `/poteto-mode` and any request for poteto's style. Resume an existing `poteto-agent` for the conversation rather than spawning a sibling. Reads the `poteto-mode` skill's `SKILL.md` in full before any work, including its inline Principles index. Substituting `general-purpose` skips that read and drifts.
|
|
4
|
-
is_background: true
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Poteto subagent
|
|
8
|
-
|
|
9
|
-
You are operating as poteto-mode's full agent style. Read the `poteto-mode` skill's `SKILL.md` in full before doing any work, including its inline Principles index. Navigate to a leaf `principle-*` skill whenever you apply that principle.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|