@lovrozagar/grunt 0.5.0 → 0.6.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.
Files changed (153) hide show
  1. package/.agents/agents/grunt.md +2 -23
  2. package/.agents/agents/orchestrator.md +5 -45
  3. package/.agents/skills/ask/SKILL.md +11 -0
  4. package/.agents/skills/auto/SKILL.md +13 -0
  5. package/.agents/skills/browser/SKILL.md +4 -7
  6. package/.agents/skills/clasp/SKILL.md +11 -0
  7. package/.agents/skills/commit/SKILL.md +3 -1
  8. package/.agents/skills/commit-push/SKILL.md +2 -0
  9. package/.agents/skills/commit-push-deploy/SKILL.md +2 -0
  10. package/.agents/skills/commit-push-release/SKILL.md +2 -0
  11. package/.agents/skills/explain/SKILL.md +7 -13
  12. package/.agents/skills/google-workspace/SKILL.md +13 -0
  13. package/.agents/skills/handoff/SKILL.md +7 -11
  14. package/.agents/skills/implement-plan/SKILL.md +5 -108
  15. package/.agents/skills/listen/SKILL.md +15 -0
  16. package/.agents/skills/pickup/SKILL.md +6 -12
  17. package/.agents/skills/speak/SKILL.md +13 -0
  18. package/.agents/skills/tmp/SKILL.md +54 -0
  19. package/.agents/skills/write-plan/SKILL.md +5 -74
  20. package/.claude/agents/grunt.md +2 -25
  21. package/.claude/agents/orchestrator.md +12 -45
  22. package/.claude/skills/ask/SKILL.md +11 -0
  23. package/.claude/skills/auto/SKILL.md +13 -0
  24. package/.claude/skills/browser/SKILL.md +4 -7
  25. package/.claude/skills/clasp/SKILL.md +11 -0
  26. package/.claude/skills/commit/SKILL.md +3 -1
  27. package/.claude/skills/commit-push/SKILL.md +2 -0
  28. package/.claude/skills/commit-push-deploy/SKILL.md +2 -0
  29. package/.claude/skills/commit-push-release/SKILL.md +2 -0
  30. package/.claude/skills/explain/SKILL.md +7 -13
  31. package/.claude/skills/google-workspace/SKILL.md +13 -0
  32. package/.claude/skills/handoff/SKILL.md +7 -11
  33. package/.claude/skills/implement-plan/SKILL.md +5 -108
  34. package/.claude/skills/listen/SKILL.md +15 -0
  35. package/.claude/skills/pickup/SKILL.md +6 -12
  36. package/.claude/skills/speak/SKILL.md +13 -0
  37. package/.claude/skills/tmp/SKILL.md +54 -0
  38. package/.claude/skills/write-plan/SKILL.md +5 -74
  39. package/.codex/agents/grunt.toml +2 -25
  40. package/.codex/agents/orchestrator.toml +4 -45
  41. package/.grok/agents/grunt.md +2 -23
  42. package/.grok/agents/orchestrator.md +4 -43
  43. package/.grok/global-settings.toml +1 -3
  44. package/.grok/hooks/orchestrate-parent.js +278 -228
  45. package/.grok/skills/ask/SKILL.md +11 -0
  46. package/.grok/skills/auto/SKILL.md +13 -0
  47. package/.grok/skills/browser/SKILL.md +4 -7
  48. package/.grok/skills/clasp/SKILL.md +11 -0
  49. package/.grok/skills/commit/SKILL.md +3 -1
  50. package/.grok/skills/commit-push/SKILL.md +2 -0
  51. package/.grok/skills/commit-push-deploy/SKILL.md +2 -0
  52. package/.grok/skills/commit-push-release/SKILL.md +2 -0
  53. package/.grok/skills/explain/SKILL.md +7 -13
  54. package/.grok/skills/google-workspace/SKILL.md +13 -0
  55. package/.grok/skills/handoff/SKILL.md +7 -11
  56. package/.grok/skills/implement-plan/SKILL.md +5 -108
  57. package/.grok/skills/listen/SKILL.md +15 -0
  58. package/.grok/skills/pickup/SKILL.md +6 -12
  59. package/.grok/skills/speak/SKILL.md +13 -0
  60. package/.grok/skills/tmp/SKILL.md +54 -0
  61. package/.grok/skills/write-plan/SKILL.md +5 -74
  62. package/.rulesync/hooks.jsonc +1 -1
  63. package/.rulesync/mcp-policy.jsonc +0 -2
  64. package/.rulesync/reference/INDEX.md +30 -17
  65. package/.rulesync/reference/browser.md +13 -6
  66. package/.rulesync/reference/cascade.md +6 -84
  67. package/.rulesync/reference/clasp.md +21 -0
  68. package/.rulesync/reference/google-workspace.md +79 -0
  69. package/.rulesync/reference/hooks.md +7 -9
  70. package/.rulesync/reference/implementation-format.md +113 -0
  71. package/.rulesync/reference/law.md +5 -3
  72. package/.rulesync/reference/listen.md +80 -0
  73. package/.rulesync/reference/map.md +39 -31
  74. package/.rulesync/reference/output.md +3 -41
  75. package/.rulesync/reference/plan-format.md +14 -12
  76. package/.rulesync/reference/refs-map.md +12 -5
  77. package/.rulesync/reference/rtk.md +3 -2
  78. package/.rulesync/reference/scope.md +37 -0
  79. package/.rulesync/reference/setup.md +27 -0
  80. package/.rulesync/reference/skills-map.md +13 -9
  81. package/.rulesync/reference/speak.md +59 -0
  82. package/.rulesync/rules/CLAUDE.md +3 -44
  83. package/.rulesync/rules/overview.md +9 -42
  84. package/.rulesync/skills/ask/SKILL.md +11 -0
  85. package/.rulesync/skills/auto/SKILL.md +11 -0
  86. package/.rulesync/skills/browser/SKILL.md +4 -8
  87. package/.rulesync/skills/clasp/SKILL.md +9 -0
  88. package/.rulesync/skills/commit/SKILL.md +3 -1
  89. package/.rulesync/skills/commit-push/SKILL.md +2 -0
  90. package/.rulesync/skills/commit-push-deploy/SKILL.md +2 -0
  91. package/.rulesync/skills/commit-push-release/SKILL.md +2 -0
  92. package/.rulesync/skills/explain/SKILL.md +7 -14
  93. package/.rulesync/skills/google-workspace/SKILL.md +11 -0
  94. package/.rulesync/skills/handoff/SKILL.md +7 -11
  95. package/.rulesync/skills/implement-plan/SKILL.md +5 -116
  96. package/.rulesync/skills/listen/SKILL.md +13 -0
  97. package/.rulesync/skills/pickup/SKILL.md +6 -12
  98. package/.rulesync/skills/speak/SKILL.md +13 -0
  99. package/.rulesync/skills/tmp/SKILL.md +54 -0
  100. package/.rulesync/skills/write-plan/SKILL.md +5 -80
  101. package/.rulesync/subagents/grunt.md +2 -23
  102. package/.rulesync/subagents/orchestrator.md +14 -54
  103. package/AGENTS.md +9 -42
  104. package/CHANGELOG.md +89 -0
  105. package/CLAUDE.md +1 -44
  106. package/README.md +97 -88
  107. package/cli/grunt.mjs +29 -13
  108. package/cli/grunt.test.ts +62 -20
  109. package/cli/init.mjs +218 -31
  110. package/cli/init.test.ts +669 -46
  111. package/cli/prompt.mjs +8 -0
  112. package/cli/prompt.test.ts +14 -0
  113. package/package.json +13 -1
  114. package/scripts/browser.mjs +98 -5
  115. package/scripts/doctor.mjs +82 -1
  116. package/scripts/emit-gemini.mjs +1 -1
  117. package/scripts/emit-mcp-policy.mjs +1 -1
  118. package/scripts/gate-fat-tools.mjs +223 -173
  119. package/scripts/google-workspace.mjs +713 -0
  120. package/scripts/grunt-job.mjs +453 -69
  121. package/scripts/listen.mjs +829 -0
  122. package/scripts/parse-need.mjs +21 -2
  123. package/scripts/persist-implementation.mjs +278 -0
  124. package/scripts/persist-plan.mjs +17 -2
  125. package/scripts/persist-tmp.mjs +123 -0
  126. package/scripts/scrub-spawn-prompt.mjs +4 -51
  127. package/scripts/setup.mjs +746 -0
  128. package/scripts/speak.mjs +291 -0
  129. package/.agents/agents/implementer.md +0 -32
  130. package/.agents/agents/thinker.md +0 -28
  131. package/.agents/skills/cascade/SKILL.md +0 -26
  132. package/.agents/skills/parent/SKILL.md +0 -6
  133. package/.agents/skills/solo/SKILL.md +0 -23
  134. package/.claude/agents/implementer.md +0 -37
  135. package/.claude/agents/thinker.md +0 -35
  136. package/.claude/skills/cascade/SKILL.md +0 -26
  137. package/.claude/skills/parent/SKILL.md +0 -6
  138. package/.claude/skills/solo/SKILL.md +0 -23
  139. package/.codex/agents/implementer.toml +0 -26
  140. package/.codex/agents/thinker.toml +0 -25
  141. package/.grok/agents/implementer.md +0 -27
  142. package/.grok/agents/thinker.md +0 -26
  143. package/.grok/parent.md +0 -1
  144. package/.grok/roles/implementer.toml +0 -5
  145. package/.grok/roles/thinker.toml +0 -5
  146. package/.grok/skills/cascade/SKILL.md +0 -26
  147. package/.grok/skills/parent/SKILL.md +0 -6
  148. package/.grok/skills/solo/SKILL.md +0 -23
  149. package/.rulesync/skills/cascade/SKILL.md +0 -26
  150. package/.rulesync/skills/parent/SKILL.md +0 -6
  151. package/.rulesync/skills/solo/SKILL.md +0 -23
  152. package/.rulesync/subagents/implementer.md +0 -49
  153. package/.rulesync/subagents/thinker.md +0 -48
@@ -0,0 +1,291 @@
1
+ #!/usr/bin/env node
2
+ /** Text-to-speech (output only). Providers: elevenlabs, openai. */
3
+ import { spawnSync } from "node:child_process";
4
+ import fs from "node:fs";
5
+ import os from "node:os";
6
+ import path from "node:path";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
8
+
9
+ export const DEFAULT_ELEVEN_VOICE = "JBFqnCBsd6RMkjVDRZzb";
10
+ export const DEFAULT_ELEVEN_MODEL = "eleven_multilingual_v2";
11
+ export const DEFAULT_OPENAI_VOICE = "coral";
12
+ export const DEFAULT_OPENAI_MODEL = "gpt-4o-mini-tts";
13
+ export const OPENAI_VOICES = [
14
+ "alloy",
15
+ "ash",
16
+ "ballad",
17
+ "coral",
18
+ "echo",
19
+ "fable",
20
+ "nova",
21
+ "onyx",
22
+ "sage",
23
+ "shimmer",
24
+ ];
25
+ export const USAGE =
26
+ "usage: speak whoami | voices | say --text T [--provider elevenlabs|openai] [--voice ID] [--out path] [--play]";
27
+ const ELEVEN_API = "https://api.elevenlabs.io/v1";
28
+ const OPENAI_API = "https://api.openai.com/v1";
29
+ export const SETUP = "node scripts/setup.mjs speak";
30
+ export const NEED_KEY =
31
+ "missing ELEVENLABS_API_KEY or OPENAI_API_KEY (or ~/.grunt/speak.json). setup: node scripts/setup.mjs speak";
32
+ export const NEED_ELEVEN =
33
+ "missing ELEVENLABS_API_KEY (or ~/.grunt/speak.json elevenlabs.apiKey). setup: node scripts/setup.mjs speak";
34
+ export const NEED_OPENAI =
35
+ "missing OPENAI_API_KEY (or ~/.grunt/speak.json openai.apiKey). setup: node scripts/setup.mjs speak";
36
+
37
+ export function formatHttpError(status, body, provider) {
38
+ const n = Number(status);
39
+ const raw = String(body || "");
40
+ if (/missing_permissions/i.test(raw)) {
41
+ return `${provider} key present but missing permission (${n || status}). setup: ${SETUP}`;
42
+ }
43
+ const auth =
44
+ n === 401 ||
45
+ n === 403 ||
46
+ /unauthorized|invalid.?api.?key|authentication/i.test(raw);
47
+ if (auth) {
48
+ return `${provider} key missing or rejected (${n || status}). setup: ${SETUP}`;
49
+ }
50
+ return `${status} ${raw.slice(0, 200)}`.trim();
51
+ }
52
+
53
+ export function parseArgv(argv) {
54
+ const out = { _: [], flags: {} };
55
+ const args = Array.isArray(argv) ? argv : [];
56
+ for (let i = 0; i < args.length; i++) {
57
+ const a = args[i];
58
+ if (a === "--") {
59
+ out._.push(...args.slice(i + 1));
60
+ break;
61
+ }
62
+ if (a.startsWith("--") && a.length > 2) {
63
+ const key = a.slice(2);
64
+ const nxt = args[i + 1];
65
+ if (nxt && !nxt.startsWith("--")) {
66
+ out.flags[key] = nxt;
67
+ i += 1;
68
+ } else out.flags[key] = "1";
69
+ } else out._.push(a);
70
+ }
71
+ return out;
72
+ }
73
+
74
+ function readJson(p) {
75
+ try {
76
+ const j = JSON.parse(fs.readFileSync(p, "utf8"));
77
+ if (j && typeof j === "object" && !Array.isArray(j)) return j;
78
+ } catch {
79
+ /* none */
80
+ }
81
+ return {};
82
+ }
83
+
84
+ function str(v, fallback = "") {
85
+ const s = String(v ?? "").trim();
86
+ return s || fallback;
87
+ }
88
+
89
+ export function loadCfg({ env = process.env, home = os.homedir() } = {}) {
90
+ const filePath = path.join(home, ".grunt", "speak.json");
91
+ const file = readJson(filePath);
92
+ const eleven = file.elevenlabs && typeof file.elevenlabs === "object" ? file.elevenlabs : {};
93
+ const openai = file.openai && typeof file.openai === "object" ? file.openai : {};
94
+ return {
95
+ filePath,
96
+ providerPref: str(env.SPEAK_PROVIDER || file.provider).toLowerCase(),
97
+ elevenlabs: {
98
+ apiKey: str(env.ELEVENLABS_API_KEY || eleven.apiKey || file.apiKey),
99
+ voiceId: str(env.ELEVENLABS_VOICE_ID || eleven.voiceId || file.voiceId, DEFAULT_ELEVEN_VOICE),
100
+ modelId: str(env.ELEVENLABS_MODEL_ID || eleven.modelId || file.modelId, DEFAULT_ELEVEN_MODEL),
101
+ },
102
+ openai: {
103
+ apiKey: str(env.OPENAI_API_KEY || openai.apiKey),
104
+ voice: str(env.OPENAI_TTS_VOICE || openai.voice, DEFAULT_OPENAI_VOICE),
105
+ model: str(env.OPENAI_TTS_MODEL || openai.model, DEFAULT_OPENAI_MODEL),
106
+ },
107
+ };
108
+ }
109
+
110
+ export function resolveProvider(cfg, flagProvider) {
111
+ const want = str(flagProvider || (cfg && cfg.providerPref)).toLowerCase();
112
+ if (want && want !== "elevenlabs" && want !== "openai") {
113
+ throw new Error("provider must be elevenlabs or openai");
114
+ }
115
+ if (want === "elevenlabs") {
116
+ if (!cfg?.elevenlabs?.apiKey) throw new Error(NEED_ELEVEN);
117
+ return "elevenlabs";
118
+ }
119
+ if (want === "openai") {
120
+ if (!cfg?.openai?.apiKey) throw new Error(NEED_OPENAI);
121
+ return "openai";
122
+ }
123
+ if (cfg?.elevenlabs?.apiKey) return "elevenlabs";
124
+ if (cfg?.openai?.apiKey) return "openai";
125
+ throw new Error(NEED_KEY);
126
+ }
127
+
128
+ async function apiFetch(url, { method = "GET", headers, body, raw, fetchFn } = {}) {
129
+ const fn = fetchFn || globalThis.fetch;
130
+ if (typeof fn !== "function") throw new Error("fetch is not available");
131
+ const res = await fn(url, {
132
+ method,
133
+ headers,
134
+ body: body ? JSON.stringify(body) : undefined,
135
+ });
136
+ if (!res || !res.ok) {
137
+ const status = res && res.status != null ? res.status : "err";
138
+ let t = "";
139
+ try {
140
+ t = res && typeof res.text === "function" ? await res.text() : "";
141
+ } catch {
142
+ /* none */
143
+ }
144
+ const provider = String(url || "").includes("elevenlabs") ? "elevenlabs" : "openai";
145
+ throw new Error(formatHttpError(status, t, provider));
146
+ }
147
+ if (raw) {
148
+ if (typeof res.arrayBuffer === "function") return Buffer.from(await res.arrayBuffer());
149
+ if (Buffer.isBuffer(res.body)) return res.body;
150
+ return Buffer.from(res.body || []);
151
+ }
152
+ if (typeof res.json === "function") return res.json();
153
+ return {};
154
+ }
155
+
156
+ export async function whoami({ provider, cfg, fetchFn } = {}) {
157
+ const p = resolveProvider(cfg, provider);
158
+ if (p === "elevenlabs") {
159
+ try {
160
+ const u = await apiFetch(`${ELEVEN_API}/user`, {
161
+ headers: { "xi-api-key": cfg.elevenlabs.apiKey },
162
+ fetchFn,
163
+ });
164
+ const email = u && u.email ? u.email : "ok";
165
+ const tier = u && u.subscription && u.subscription.tier ? u.subscription.tier : "-";
166
+ return `elevenlabs ${email} tier=${tier}`;
167
+ } catch (e) {
168
+ const msg = String(e && e.message ? e.message : e);
169
+ if (/missing permission/i.test(msg)) {
170
+ return "elevenlabs ok (scoped key; whoami needs user_read). voices/say still work";
171
+ }
172
+ throw e;
173
+ }
174
+ }
175
+ await apiFetch(`${OPENAI_API}/models`, {
176
+ headers: { Authorization: `Bearer ${cfg.openai.apiKey}` },
177
+ fetchFn,
178
+ });
179
+ return "openai ok";
180
+ }
181
+
182
+ export async function voices({ provider, cfg, fetchFn } = {}) {
183
+ const p = resolveProvider(cfg, provider);
184
+ if (p === "openai") return OPENAI_VOICES.join("\n");
185
+ const j = await apiFetch(`${ELEVEN_API}/voices`, {
186
+ headers: { "xi-api-key": cfg.elevenlabs.apiKey },
187
+ fetchFn,
188
+ });
189
+ const list = Array.isArray(j?.voices) ? j.voices : [];
190
+ return list.map((v) => `${v.voice_id} ${v.name}`).join("\n");
191
+ }
192
+
193
+ function playPath(dest) {
194
+ const bin = process.platform === "darwin" ? "afplay" : "ffplay";
195
+ const args = process.platform === "darwin" ? [dest] : ["-nodisp", "-autoexit", dest];
196
+ spawnSync(bin, args, { stdio: "ignore" });
197
+ }
198
+
199
+ export async function say({
200
+ text,
201
+ voice,
202
+ out,
203
+ play,
204
+ provider,
205
+ cfg,
206
+ cwd = process.cwd(),
207
+ fetchFn,
208
+ } = {}) {
209
+ if (!str(text)) throw new Error("say needs --text");
210
+ const p = resolveProvider(cfg, provider);
211
+ let buf;
212
+ if (p === "elevenlabs") {
213
+ const id = str(voice, cfg.elevenlabs.voiceId);
214
+ buf = await apiFetch(
215
+ `${ELEVEN_API}/text-to-speech/${encodeURIComponent(id)}?output_format=mp3_44100_128`,
216
+ {
217
+ method: "POST",
218
+ headers: {
219
+ "xi-api-key": cfg.elevenlabs.apiKey,
220
+ "Content-Type": "application/json",
221
+ },
222
+ body: { text: str(text), model_id: cfg.elevenlabs.modelId },
223
+ raw: true,
224
+ fetchFn,
225
+ },
226
+ );
227
+ } else {
228
+ const v = str(voice, cfg.openai.voice);
229
+ buf = await apiFetch(`${OPENAI_API}/audio/speech`, {
230
+ method: "POST",
231
+ headers: {
232
+ Authorization: `Bearer ${cfg.openai.apiKey}`,
233
+ "Content-Type": "application/json",
234
+ },
235
+ body: { model: cfg.openai.model, input: str(text), voice: v },
236
+ raw: true,
237
+ fetchFn,
238
+ });
239
+ }
240
+ const dest = str(out) || path.join(cwd, ".tmp/grunt/speak", `say-${Date.now()}.mp3`);
241
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
242
+ fs.writeFileSync(dest, buf);
243
+ if (play === true || play === "true" || play === "1") playPath(dest);
244
+ return dest;
245
+ }
246
+
247
+ export async function main(argv = process.argv.slice(2), opts = {}) {
248
+ const { _, flags } = parseArgv(argv);
249
+ const env = opts.env || process.env;
250
+ const home = opts.home || os.homedir();
251
+ const cwd = opts.cwd || process.cwd();
252
+ const fetchFn = opts.fetchFn || globalThis.fetch;
253
+ const log = opts.log || console;
254
+ const cfg = loadCfg({ env, home });
255
+ const verb = String(_[0] || "").toLowerCase();
256
+ try {
257
+ if (verb === "whoami") {
258
+ log.log(await whoami({ provider: flags.provider, cfg, fetchFn }));
259
+ return 0;
260
+ }
261
+ if (verb === "voices") {
262
+ log.log(await voices({ provider: flags.provider, cfg, fetchFn }));
263
+ return 0;
264
+ }
265
+ if (verb === "say") {
266
+ const dest = await say({
267
+ text: flags.text,
268
+ voice: flags.voice,
269
+ out: flags.out,
270
+ play: flags.play,
271
+ provider: flags.provider,
272
+ cfg,
273
+ cwd,
274
+ fetchFn,
275
+ });
276
+ log.log(dest);
277
+ return 0;
278
+ }
279
+ log.error(USAGE);
280
+ return 1;
281
+ } catch (e) {
282
+ log.error(String(e && e.message ? e.message : e));
283
+ return 1;
284
+ }
285
+ }
286
+
287
+ const thisFile = fileURLToPath(import.meta.url);
288
+ const invoked = process.argv[1] ? path.resolve(process.argv[1]) : "";
289
+ if (invoked === thisFile || import.meta.url === pathToFileURL(invoked).href) {
290
+ main().then((code) => process.exit(code));
291
+ }
@@ -1,32 +0,0 @@
1
- ---
2
- name: implementer
3
- description: Write already-defined solution. Never plan/advise. Never how/why/explain judgment. Never spawn.
4
- tools:
5
- - view_file
6
- - grep_search
7
- - run_command
8
- - replace_file_content
9
- mainAgent: false
10
- subagent: true
11
- model: pro
12
- commandExecutionPolicy: eager
13
- inheritMcp: false
14
- ---
15
- Voice: `.rulesync/reference/output.md` — must follow.
16
-
17
- Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan/advise (thinker agent). Never how/why/explain judgment.
18
- After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
19
- DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
20
- Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
21
- Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
22
- TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
23
- Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
24
- Findings first line = output.md recap. Completed = past verbs + abs paths. Remainder/blocker = noun + one recommended X then ask. Body after first line OK.
25
-
26
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
27
-
28
- ```
29
- need: [{"job":"search","query":"..."}]
30
- ```
31
-
32
- After each leaf: flip that `[ ]`→`[x]` in the plan file (box only). Do not “do all of plan 2”.
@@ -1,28 +0,0 @@
1
- ---
2
- name: thinker
3
- description: Plan/deep reason/advise/recommend/how/why/explain. Imperative. Read-only. Never spawn. No bash.
4
- tools:
5
- - view_file
6
- mainAgent: false
7
- subagent: true
8
- model: pro
9
- commandExecutionPolicy: eager
10
- inheritMcp: false
11
- ---
12
- Voice: `.rulesync/reference/output.md` — must follow.
13
-
14
- Plan/advise/recommend/how/why/explain. Deep reason. Never spawn. Never implement (implementer agent). Never run for simple tool usage (grunt agent).
15
- Read-only. No bash. Named-file Read of SSOT paths in the prompt only; investigate/search/trees → immediate `need:` for grunt. Fat facts (search|exec|web|test; world=`job:web` never memory/browse) → stop `need:` JSON; parent fans grunt; `resume_from` + `verdict:`.
16
- Return the spec/plan. Flag edge cases/pitfalls.
17
- First line = recap. Recap **must** be `{decided}. {how-capsule}. {why-clause}`. Why-clause = rejected alt + constraint (not dump not “because”). Labels optional (`Why:` / em-dash OK); do not mandate `## Why`. Body may expand How/Why/edges — not parent-echoed. Advice ≠ completed product work. `need:` JSON still JSON-only (no why mix).
18
- Advise leftover: numbered pick each on own line after recap:
19
- 1. Implementer with verbal plan
20
- 2. Implementer with file plan
21
- 3. Tweak
22
- Parent matches leftover. Thinker does not spawn. `ok`/`yes`/`y`/`continue` ≠ implement.
23
-
24
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
25
-
26
- ```
27
- need: [{"job":"search","query":"..."}]
28
- ```
@@ -1,26 +0,0 @@
1
- ---
2
- name: cascade
3
- description: >
4
- Session mode. /cascade exits solo and restores the grunt cascade for this
5
- session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
- /explain this IS a mode: it persists until /solo or session end. Not a sticky
7
- second mode — exit solo / restore cascade.
8
- ---
9
- Exit solo / restore cascade. Not a sticky second mode.
10
-
11
- Session mode, not one-turn. Persists until `/solo` or session end.
12
-
13
- This session: cascade restored. You are the parent orchestrator.
14
-
15
- - Spawn grunt|implementer|thinker.
16
- - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
- - Spawn-first rule. `need:`/`verdict:` grammar.
18
- - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
-
20
- Fat-tool caps stay on — token guards, not cascade.
21
-
22
- Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
-
24
- `/explain` is voice-only not spawn-escape. After unlink first token = spawn.
25
-
26
- After `/solo`, or when spawn/recap/need|verdict must resume.
@@ -1,6 +0,0 @@
1
- ---
2
- name: parent
3
- description: |
4
- One-turn parent-orchestrator escape. Use for /parent. Not a session mode.
5
- ---
6
- One-turn. Not a mode. Only `/solo` escapes spawn workflow. First token = spawn grunt|implementer|thinker. Never parent Read/Bash. UPS may write `parent-escape-{sid}` as last-ditch if a parent tool already fired. Do not treat stamp as license to probe. Do not instruct Read/Bash. After this reply: spawn-only. Protocol: `.rulesync/reference/cascade.md`. Do not paste. Do not parent-Read it.
@@ -1,23 +0,0 @@
1
- ---
2
- name: solo
3
- description: >
4
- Session mode. /solo disables the grunt cascade for this session — one normal
5
- agent, no spawn, no orchestrator. /cascade restores it. Unlike /parent and
6
- /explain this IS a mode: it persists until /cascade or session end.
7
- ---
8
- Session mode, not one-turn. Persists until `/cascade` or session end.
9
-
10
- This session: cascade suspended. You are one normal agent.
11
-
12
- - Do not spawn. No grunt|implementer|thinker.
13
- - No recap tags. Do not recap `[orchestrator]:`. Answer the user directly.
14
- - No spawn-first rule. No `need:`/`verdict:` grammar.
15
- - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
16
-
17
- Fat-tool caps stay on — token guards, not cascade.
18
-
19
- Claude/Codex/Grok: `/solo` via submit hook writes `.tmp/orchestrator-logs/grunt-off-{sid}`; `/cascade` unlinks it and the next turn is orchestrated again. Agents/Antigravity: instruction-only (this skill body); cannot create stamp via `/solo`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
20
-
21
- This is the only session-wide spawn-workflow escape. /explain /parent /handoff /pickup /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
22
-
23
- Spawn-escape only. Not advisory/design routing.
@@ -1,37 +0,0 @@
1
- ---
2
- name: implementer
3
- description: >-
4
- Write already-defined solution. Never plan/advise. Never how/why/explain
5
- judgment. Never spawn.
6
- model: sonnet
7
- tools:
8
- - Read
9
- - Edit
10
- - Write
11
- - Bash
12
- - Grep
13
- - Glob
14
- - WebSearch
15
- disallowedTools:
16
- - Agent
17
- permissionMode: bypassPermissions
18
- effort: medium
19
- ---
20
- Voice: `.rulesync/reference/output.md` — must follow.
21
-
22
- Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan/advise (thinker agent). Never how/why/explain judgment.
23
- After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
24
- DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
25
- Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
26
- Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
27
- TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
28
- Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
29
- Findings first line = output.md recap. Completed = past verbs + abs paths. Remainder/blocker = noun + one recommended X then ask. Body after first line OK.
30
-
31
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
32
-
33
- ```
34
- need: [{"job":"search","query":"..."}]
35
- ```
36
-
37
- After each leaf: flip that `[ ]`→`[x]` in the plan file (box only). Do not “do all of plan 2”.
@@ -1,35 +0,0 @@
1
- ---
2
- name: thinker
3
- description: >-
4
- Plan/deep reason/advise/recommend/how/why/explain. Imperative. Read-only.
5
- Never spawn. No bash.
6
- model: opus
7
- tools:
8
- - Read
9
- disallowedTools:
10
- - Agent
11
- - Write
12
- - Edit
13
- - Bash
14
- - Grep
15
- - Glob
16
- permissionMode: bypassPermissions
17
- effort: high
18
- ---
19
- Voice: `.rulesync/reference/output.md` — must follow.
20
-
21
- Plan/advise/recommend/how/why/explain. Deep reason. Never spawn. Never implement (implementer agent). Never run for simple tool usage (grunt agent).
22
- Read-only. No bash. Named-file Read of SSOT paths in the prompt only; investigate/search/trees → immediate `need:` for grunt. Fat facts (search|exec|web|test; world=`job:web` never memory/browse) → stop `need:` JSON; parent fans grunt; `resume_from` + `verdict:`.
23
- Return the spec/plan. Flag edge cases/pitfalls.
24
- First line = recap. Recap **must** be `{decided}. {how-capsule}. {why-clause}`. Why-clause = rejected alt + constraint (not dump not “because”). Labels optional (`Why:` / em-dash OK); do not mandate `## Why`. Body may expand How/Why/edges — not parent-echoed. Advice ≠ completed product work. `need:` JSON still JSON-only (no why mix).
25
- Advise leftover: numbered pick each on own line after recap:
26
- 1. Implementer with verbal plan
27
- 2. Implementer with file plan
28
- 3. Tweak
29
- Parent matches leftover. Thinker does not spawn. `ok`/`yes`/`y`/`continue` ≠ implement.
30
-
31
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
32
-
33
- ```
34
- need: [{"job":"search","query":"..."}]
35
- ```
@@ -1,26 +0,0 @@
1
- ---
2
- name: cascade
3
- description: >
4
- Session mode. /cascade exits solo and restores the grunt cascade for this
5
- session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
- /explain this IS a mode: it persists until /solo or session end. Not a sticky
7
- second mode — exit solo / restore cascade.
8
- ---
9
- Exit solo / restore cascade. Not a sticky second mode.
10
-
11
- Session mode, not one-turn. Persists until `/solo` or session end.
12
-
13
- This session: cascade restored. You are the parent orchestrator.
14
-
15
- - Spawn grunt|implementer|thinker.
16
- - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
- - Spawn-first rule. `need:`/`verdict:` grammar.
18
- - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
-
20
- Fat-tool caps stay on — token guards, not cascade.
21
-
22
- Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
-
24
- `/explain` is voice-only not spawn-escape. After unlink first token = spawn.
25
-
26
- After `/solo`, or when spawn/recap/need|verdict must resume.
@@ -1,6 +0,0 @@
1
- ---
2
- name: parent
3
- description: |
4
- One-turn parent-orchestrator escape. Use for /parent. Not a session mode.
5
- ---
6
- One-turn. Not a mode. Only `/solo` escapes spawn workflow. First token = spawn grunt|implementer|thinker. Never parent Read/Bash. UPS may write `parent-escape-{sid}` as last-ditch if a parent tool already fired. Do not treat stamp as license to probe. Do not instruct Read/Bash. After this reply: spawn-only. Protocol: `.rulesync/reference/cascade.md`. Do not paste. Do not parent-Read it.
@@ -1,23 +0,0 @@
1
- ---
2
- name: solo
3
- description: >
4
- Session mode. /solo disables the grunt cascade for this session — one normal
5
- agent, no spawn, no orchestrator. /cascade restores it. Unlike /parent and
6
- /explain this IS a mode: it persists until /cascade or session end.
7
- ---
8
- Session mode, not one-turn. Persists until `/cascade` or session end.
9
-
10
- This session: cascade suspended. You are one normal agent.
11
-
12
- - Do not spawn. No grunt|implementer|thinker.
13
- - No recap tags. Do not recap `[orchestrator]:`. Answer the user directly.
14
- - No spawn-first rule. No `need:`/`verdict:` grammar.
15
- - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
16
-
17
- Fat-tool caps stay on — token guards, not cascade.
18
-
19
- Claude/Codex/Grok: `/solo` via submit hook writes `.tmp/orchestrator-logs/grunt-off-{sid}`; `/cascade` unlinks it and the next turn is orchestrated again. Agents/Antigravity: instruction-only (this skill body); cannot create stamp via `/solo`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
20
-
21
- This is the only session-wide spawn-workflow escape. /explain /parent /handoff /pickup /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
22
-
23
- Spawn-escape only. Not advisory/design routing.
@@ -1,26 +0,0 @@
1
- name = "implementer"
2
- description = "Write already-defined solution. Never plan/advise. Never how/why/explain judgment. Never spawn."
3
- model = "gpt-5.4"
4
- model_reasoning_effort = "medium"
5
- sandbox_mode = "danger-full-access"
6
- approval_policy = "never"
7
- developer_instructions = '''
8
- Voice: `.rulesync/reference/output.md` — must follow.
9
-
10
- Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan/advise (thinker agent). Never how/why/explain judgment.
11
- After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
12
- DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
13
- Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
14
- Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
15
- TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
16
- Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
17
- Findings first line = output.md recap. Completed = past verbs + abs paths. Remainder/blocker = noun + one recommended X then ask. Body after first line OK.
18
-
19
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
20
-
21
- ```
22
- need: [{"job":"search","query":"..."}]
23
- ```
24
-
25
- After each leaf: flip that `[ ]`→`[x]` in the plan file (box only). Do not “do all of plan 2”.
26
- '''
@@ -1,25 +0,0 @@
1
- name = "thinker"
2
- description = "Plan/deep reason/advise/recommend/how/why/explain. Imperative. Read-only. Never spawn. No bash."
3
- model = "gpt-5.4"
4
- model_reasoning_effort = "high"
5
- sandbox_mode = "danger-full-access"
6
- approval_policy = "never"
7
- developer_instructions = '''
8
- Voice: `.rulesync/reference/output.md` — must follow.
9
-
10
- Plan/advise/recommend/how/why/explain. Deep reason. Never spawn. Never implement (implementer agent). Never run for simple tool usage (grunt agent).
11
- Read-only. No bash. Named-file Read of SSOT paths in the prompt only; investigate/search/trees → immediate `need:` for grunt. Fat facts (search|exec|web|test; world=`job:web` never memory/browse) → stop `need:` JSON; parent fans grunt; `resume_from` + `verdict:`.
12
- Return the spec/plan. Flag edge cases/pitfalls.
13
- First line = recap. Recap **must** be `{decided}. {how-capsule}. {why-clause}`. Why-clause = rejected alt + constraint (not dump not “because”). Labels optional (`Why:` / em-dash OK); do not mandate `## Why`. Body may expand How/Why/edges — not parent-echoed. Advice ≠ completed product work. `need:` JSON still JSON-only (no why mix).
14
- Advise leftover: numbered pick each on own line after recap:
15
- 1. Implementer with verbal plan
16
- 2. Implementer with file plan
17
- 3. Tweak
18
- Parent matches leftover. Thinker does not spawn. `ok`/`yes`/`y`/`continue` ≠ implement.
19
-
20
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
21
-
22
- ```
23
- need: [{"job":"search","query":"..."}]
24
- ```
25
- '''
@@ -1,27 +0,0 @@
1
- ---
2
- name: implementer
3
- description: Write already-defined solution. Never plan/advise. Never how/why/explain judgment. Never spawn.
4
- model: grok-4.6
5
- permission_mode: bypassPermissions
6
- agents_md: false
7
- mcpInheritance: none
8
- tools: read_file, grep, list_dir, write, search_replace, run_terminal_command, web_search, todo_write
9
- ---
10
- Voice: `.rulesync/reference/output.md` — must follow.
11
-
12
- Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan/advise (thinker agent). Never how/why/explain judgment.
13
- After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
14
- DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
15
- Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
16
- Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
17
- TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
18
- Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
19
- Findings first line = output.md recap. Completed = past verbs + abs paths. Remainder/blocker = noun + one recommended X then ask. Body after first line OK.
20
-
21
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
22
-
23
- ```
24
- need: [{"job":"search","query":"..."}]
25
- ```
26
-
27
- After each leaf: flip that `[ ]`→`[x]` in the plan file (box only). Do not “do all of plan 2”.
@@ -1,26 +0,0 @@
1
- ---
2
- name: thinker
3
- description: Plan/deep reason/advise/recommend/how/why/explain. Imperative. Read-only. Never spawn. No bash.
4
- model: grok-4.6
5
- agents_md: false
6
- mcpInheritance: none
7
- permission_mode: bypassPermissions
8
- tools: read_file
9
- ---
10
- Voice: `.rulesync/reference/output.md` — must follow.
11
-
12
- Plan/advise/recommend/how/why/explain. Deep reason. Never spawn. Never implement (implementer agent). Never run for simple tool usage (grunt agent).
13
- Read-only. No bash. Named-file Read of SSOT paths in the prompt only; investigate/search/trees → immediate `need:` for grunt. Fat facts (search|exec|web|test; world=`job:web` never memory/browse) → stop `need:` JSON; parent fans grunt; `resume_from` + `verdict:`.
14
- Return the spec/plan. Flag edge cases/pitfalls.
15
- First line = recap. Recap **must** be `{decided}. {how-capsule}. {why-clause}`. Why-clause = rejected alt + constraint (not dump not “because”). Labels optional (`Why:` / em-dash OK); do not mandate `## Why`. Body may expand How/Why/edges — not parent-echoed. Advice ≠ completed product work. `need:` JSON still JSON-only (no why mix).
16
- Advise leftover: numbered pick each on own line after recap:
17
- 1. Implementer with verbal plan
18
- 2. Implementer with file plan
19
- 3. Tweak
20
- Parent matches leftover. Thinker does not spawn. `ok`/`yes`/`y`/`continue` ≠ implement.
21
-
22
- Fat dump → stop on this JSON only (≤4/batch; no serial known-parallel):
23
-
24
- ```
25
- need: [{"job":"search","query":"..."}]
26
- ```
package/.grok/parent.md DELETED
@@ -1 +0,0 @@
1
- SSOT: `.grok/agents/orchestrator.md` (`[agent] name = "orchestrator"`).
@@ -1,5 +0,0 @@
1
- description = "Medium reasoning role"
2
- default_capability_mode = "all"
3
- reasoning_effort = "medium"
4
- model = "grok-4.6"
5
- default_fork_context = false