tuncss-plan-kit 0.3.0 → 0.5.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 +12 -11
- package/bin/cli.js +12 -137
- package/commands/codex/brainstorm.md +1 -1
- package/commands/codex/changelog.md +1 -1
- package/commands/codex/handoff-plan.md +1 -1
- package/commands/codex/plan-universal.md +1 -1
- package/package.json +1 -3
- package/skills/brainstorm/SKILL.md +132 -132
- package/skills/changelog/SKILL.md +95 -95
- package/skills/plan-universal/SKILL.md +4 -16
- package/templates/instructions-block.md +12 -12
- package/.opencode/plugins/tuncss-plan-kit.js +0 -48
- package/commands/opencode/brainstorm.md +0 -5
- package/commands/opencode/changelog.md +0 -5
- package/commands/opencode/handoff-plan.md +0 -5
- package/commands/opencode/plan-universal.md +0 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# tuncss-plan-kit
|
|
2
2
|
|
|
3
|
-
Four skills for spec-driven development, installable into Claude Code, Codex CLI,
|
|
3
|
+
Four skills for spec-driven development, installable into Claude Code, Codex CLI, and Antigravity:
|
|
4
4
|
|
|
5
5
|
- **`/brainstorm`** — turn an idea into an approved spec (`docs/specs/`)
|
|
6
6
|
- **`/plan-universal`** — turn a spec into an executable plan (`docs/plans/`)
|
|
@@ -23,9 +23,8 @@ The installer auto-detects which platform(s) the project uses and writes the rig
|
|
|
23
23
|
|---|---|
|
|
24
24
|
| `.claude/` or `CLAUDE.md` | Claude Code |
|
|
25
25
|
| `.codex/` | Codex CLI |
|
|
26
|
-
| `.opencode/` | OpenCode |
|
|
27
26
|
| `.agents/` | Antigravity |
|
|
28
|
-
| `AGENTS.md` (alone) | Codex
|
|
27
|
+
| `AGENTS.md` (alone) | Codex and Antigravity (they share `AGENTS.md`) |
|
|
29
28
|
|
|
30
29
|
If nothing is detected, pass an explicit target:
|
|
31
30
|
|
|
@@ -45,10 +44,9 @@ Restart your coding agent after install so it picks up the new skills and slash
|
|
|
45
44
|
|---|---|---|---|
|
|
46
45
|
| Claude Code | `.claude/skills/<n>/SKILL.md` | *(none — skills auto-expose as slash)* | `CLAUDE.md` |
|
|
47
46
|
| Codex CLI | `.agents/skills/<n>/SKILL.md` | `.codex/prompts/<n>.md` | `AGENTS.md` |
|
|
48
|
-
| OpenCode | `.opencode/skills/<n>/SKILL.md` | `.opencode/commands/<n>.md` | `AGENTS.md` |
|
|
49
47
|
| Antigravity | `.agents/skills/<n>/SKILL.md` | *(none — skills auto-expose as slash)* | `AGENTS.md` |
|
|
50
48
|
|
|
51
|
-
Claude Code and Antigravity automatically expose any skill named `foo` as `/foo`, so the kit doesn't write wrapper command files for them. Codex
|
|
49
|
+
Claude Code and Antigravity automatically expose any skill named `foo` as `/foo`, so the kit doesn't write wrapper command files for them. Codex doesn't auto-expose, so wrappers are written there to give you the same `/brainstorm`, `/plan-universal`, `/handoff-plan`, `/changelog` UX everywhere.
|
|
52
50
|
|
|
53
51
|
Antigravity and Codex share `.agents/skills/`, so installing both writes those files once — the second platform reports them as already written.
|
|
54
52
|
|
|
@@ -56,11 +54,9 @@ Note: `agy changelog` is Antigravity's own built-in subcommand for release notes
|
|
|
56
54
|
|
|
57
55
|
With `--global` the same files go to user-wide locations (`~/.claude/`, `~/.agents/`, `~/.codex/`, `~/.gemini/config/`).
|
|
58
56
|
|
|
59
|
-
**OpenCode `--global` is supported via an npm-plugin route**: the kit installs itself into `~/.config/opencode/node_modules/`, registers itself in `~/.config/opencode/opencode.json`'s `plugin` array, and drops command wrappers into `~/.config/opencode/commands/`. After install, restart OpenCode — skills appear in every project. (For Claude and Codex, `--global` is a plain file copy.)
|
|
60
|
-
|
|
61
57
|
**Antigravity `--global` is a plain file copy to `~/.gemini/config/`** — a single location the desktop app, the `agy` CLI, and the IDE all read, so one install covers them all.
|
|
62
58
|
|
|
63
|
-
Project-local is still the default for all
|
|
59
|
+
Project-local is still the default for all three — recommended unless you specifically want the kit available everywhere.
|
|
64
60
|
|
|
65
61
|
## Workflow
|
|
66
62
|
|
|
@@ -74,7 +70,7 @@ You: (review and approve)
|
|
|
74
70
|
You: /plan-universal
|
|
75
71
|
Agent: ↓ writing-plans skill
|
|
76
72
|
writes plan to docs/plans/ with execution contract at the top,
|
|
77
|
-
tasks shaped as Targets /
|
|
73
|
+
tasks shaped as Targets / Implementation Notes /
|
|
78
74
|
Done When / Verification
|
|
79
75
|
|
|
80
76
|
You: do TASK-01
|
|
@@ -100,7 +96,7 @@ Every plan starts with this contract:
|
|
|
100
96
|
> 5. If verification fails, report the failure and stop. Do not attempt fixes outside the task's Targets, and do not write a changelog entry.
|
|
101
97
|
> 6. **Changelog entry:** use the `changelog` skill to append this task's entry to `docs/CHANGELOG.md`. Base it on the actual diff, not on what you set out to do.
|
|
102
98
|
|
|
103
|
-
|
|
99
|
+
Plans carry contracts (types, signatures, commands) and pointers to existing code, not pasted function bodies — the executor writes the code.
|
|
104
100
|
|
|
105
101
|
## Options
|
|
106
102
|
|
|
@@ -110,7 +106,7 @@ npx tuncss-plan-kit init [--target=<list>] [--global] [--force]
|
|
|
110
106
|
|
|
111
107
|
| Flag | Effect |
|
|
112
108
|
|------|--------|
|
|
113
|
-
| `--target=<list>` | Comma-separated. Values: `claude`, `codex`, `
|
|
109
|
+
| `--target=<list>` | Comma-separated. Values: `claude`, `codex`, `antigravity`, `all`. Auto-detected if omitted. |
|
|
114
110
|
| `--global` | Install to user-wide locations instead of the current project. |
|
|
115
111
|
| `--force` | Overwrite existing skill/command files without warning. |
|
|
116
112
|
|
|
@@ -118,6 +114,11 @@ npx tuncss-plan-kit init [--target=<list>] [--global] [--force]
|
|
|
118
114
|
|
|
119
115
|
Existing kits ship dozens of agents and skills you'll never use, but every one of them sits in your context and burns tokens each turn. `tuncss-plan-kit` ships four files that cover the only loop most projects need: design → plan → execute (here or elsewhere) → record. That's it.
|
|
120
116
|
|
|
117
|
+
## A note on OpenCode
|
|
118
|
+
|
|
119
|
+
OpenCode was supported through v0.3.0. It was dropped in v0.4.0 because nobody
|
|
120
|
+
on the team uses it any more. If you need it, pin `tuncss-plan-kit@0.3.0`.
|
|
121
|
+
|
|
121
122
|
## License
|
|
122
123
|
|
|
123
124
|
MIT
|
package/bin/cli.js
CHANGED
|
@@ -3,12 +3,10 @@
|
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import os from "os";
|
|
6
|
-
import { spawnSync } from "child_process";
|
|
7
6
|
import { fileURLToPath } from "url";
|
|
8
7
|
|
|
9
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
9
|
const PKG_ROOT = path.resolve(__dirname, "..");
|
|
11
|
-
const PKG_NAME = "tuncss-plan-kit";
|
|
12
10
|
|
|
13
11
|
const SKILLS = ["brainstorm", "plan-universal", "handoff-plan", "changelog"];
|
|
14
12
|
const COMMANDS = ["brainstorm", "plan-universal", "handoff-plan", "changelog"];
|
|
@@ -45,18 +43,6 @@ const PLATFORMS = {
|
|
|
45
43
|
}),
|
|
46
44
|
commandsSrc: "codex",
|
|
47
45
|
},
|
|
48
|
-
opencode: {
|
|
49
|
-
label: "opencode",
|
|
50
|
-
project: {
|
|
51
|
-
skillsDir: ".opencode/skills",
|
|
52
|
-
commandsDir: ".opencode/commands",
|
|
53
|
-
instructionsFile: "AGENTS.md",
|
|
54
|
-
},
|
|
55
|
-
// Global install for OpenCode uses the npm-plugin route, not file-drop.
|
|
56
|
-
// See installOpenCodeGlobal().
|
|
57
|
-
global: null,
|
|
58
|
-
commandsSrc: "opencode",
|
|
59
|
-
},
|
|
60
46
|
// Antigravity reads .agents/ in a workspace and ~/.gemini/config/ globally.
|
|
61
47
|
// One global location serves all three variants (desktop app, agy CLI, IDE).
|
|
62
48
|
// Like Claude Code, it expands skills into slash commands on its own, so no
|
|
@@ -109,17 +95,14 @@ Usage:
|
|
|
109
95
|
npx tuncss-plan-kit init [--target=<list>] [--global] [--force]
|
|
110
96
|
|
|
111
97
|
Commands:
|
|
112
|
-
init Install the
|
|
113
|
-
into the target platform(s).
|
|
98
|
+
init Install the four skills (brainstorm, plan-universal, handoff-plan,
|
|
99
|
+
changelog) into the target platform(s).
|
|
114
100
|
|
|
115
101
|
Options:
|
|
116
102
|
--target Comma-separated platforms to install for. Supported:
|
|
117
|
-
claude, codex,
|
|
103
|
+
claude, codex, antigravity, all
|
|
118
104
|
If omitted, auto-detects from the current directory.
|
|
119
105
|
--global Install to user-wide locations.
|
|
120
|
-
For OpenCode this uses the npm-plugin route (installs the package
|
|
121
|
-
into ~/.config/opencode/node_modules/ and registers it in
|
|
122
|
-
opencode.json's plugin array).
|
|
123
106
|
--force Overwrite existing skill/command files without warning.
|
|
124
107
|
(Instruction-file marker blocks are always idempotent.)
|
|
125
108
|
|
|
@@ -146,16 +129,12 @@ function detectTargets(cwd) {
|
|
|
146
129
|
found.add("claude");
|
|
147
130
|
}
|
|
148
131
|
if (exists(path.join(cwd, ".codex"))) found.add("codex");
|
|
149
|
-
if (exists(path.join(cwd, ".opencode"))) found.add("opencode");
|
|
150
132
|
// Antigravity discovers .agents/ and reads AGENTS.md as rules. Its project
|
|
151
133
|
// paths are a subset of Codex's, so adding it here costs no extra files.
|
|
152
134
|
if (exists(path.join(cwd, ".agents"))) found.add("antigravity");
|
|
153
135
|
if (exists(path.join(cwd, "AGENTS.md"))) {
|
|
154
136
|
found.add("antigravity");
|
|
155
|
-
if (!found.has("codex")
|
|
156
|
-
found.add("codex");
|
|
157
|
-
found.add("opencode");
|
|
158
|
-
}
|
|
137
|
+
if (!found.has("codex")) found.add("codex");
|
|
159
138
|
}
|
|
160
139
|
return [...found];
|
|
161
140
|
}
|
|
@@ -297,105 +276,6 @@ function installPlatform({ platform, isGlobal, force, baseRoot, sharedState }) {
|
|
|
297
276
|
return lines;
|
|
298
277
|
}
|
|
299
278
|
|
|
300
|
-
function readJsonOrDefault(filePath, fallback) {
|
|
301
|
-
if (!exists(filePath)) return fallback;
|
|
302
|
-
try {
|
|
303
|
-
return JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
304
|
-
} catch {
|
|
305
|
-
return fallback;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
function writeJson(filePath, obj) {
|
|
310
|
-
ensureDir(path.dirname(filePath));
|
|
311
|
-
fs.writeFileSync(filePath, JSON.stringify(obj, null, 2) + "\n");
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
function isRunningFromInstalledPackage() {
|
|
315
|
-
// If our package root contains /node_modules/, we were installed as a dep
|
|
316
|
-
// (e.g. via `npm install -g` or `npx`). Otherwise we're being run from
|
|
317
|
-
// source (dev mode).
|
|
318
|
-
return PKG_ROOT.split(path.sep).includes("node_modules");
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
function dependencySpec() {
|
|
322
|
-
// When running from a published install, use a version range so npm
|
|
323
|
-
// installs from the registry. When running from source (dev), point to
|
|
324
|
-
// our absolute path with file: so changes are picked up without publish.
|
|
325
|
-
if (isRunningFromInstalledPackage()) {
|
|
326
|
-
return `^${readJsonOrDefault(path.join(PKG_ROOT, "package.json"), { version: "0.1.0" }).version || "0.1.0"}`;
|
|
327
|
-
}
|
|
328
|
-
return "file:" + PKG_ROOT.split(path.sep).join("/");
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function installOpenCodeGlobal() {
|
|
332
|
-
const home = os.homedir();
|
|
333
|
-
const ocDir = path.join(home, ".config", "opencode");
|
|
334
|
-
ensureDir(ocDir);
|
|
335
|
-
const lines = [];
|
|
336
|
-
|
|
337
|
-
// 1. package.json — add or update tuncss-plan-kit dependency
|
|
338
|
-
const pkgPath = path.join(ocDir, "package.json");
|
|
339
|
-
const pkg = readJsonOrDefault(pkgPath, {});
|
|
340
|
-
pkg.dependencies = pkg.dependencies || {};
|
|
341
|
-
const spec = dependencySpec();
|
|
342
|
-
const prevSpec = pkg.dependencies[PKG_NAME];
|
|
343
|
-
pkg.dependencies[PKG_NAME] = spec;
|
|
344
|
-
writeJson(pkgPath, pkg);
|
|
345
|
-
lines.push(
|
|
346
|
-
` ${prevSpec === spec ? "·" : prevSpec ? "↻" : "✓"} ${relPath(pkgPath, home)} (dep: ${PKG_NAME}@${spec})`
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
// 2. npm install in ocDir
|
|
350
|
-
// Pass the full command as a single string with shell: true to avoid the
|
|
351
|
-
// Node DEP0190 warning about unescaped args concatenation. Args are all
|
|
352
|
-
// hardcoded here so there's no injection surface.
|
|
353
|
-
const npmBin = process.platform === "win32" ? "npm.cmd" : "npm";
|
|
354
|
-
const npmRes = spawnSync(`${npmBin} install --silent --no-audit --no-fund`, {
|
|
355
|
-
cwd: ocDir,
|
|
356
|
-
stdio: "inherit",
|
|
357
|
-
shell: true,
|
|
358
|
-
});
|
|
359
|
-
if (npmRes.status !== 0) {
|
|
360
|
-
throw new Error(
|
|
361
|
-
`npm install failed in ${ocDir} (exit code ${npmRes.status}). Fix the error above and re-run.`
|
|
362
|
-
);
|
|
363
|
-
}
|
|
364
|
-
lines.push(` ✓ npm install ran in ${relPath(ocDir, home)}`);
|
|
365
|
-
|
|
366
|
-
// 3. command wrappers — file-drop into ~/.config/opencode/commands/
|
|
367
|
-
// (the plugin handles skills via config injection, but command discovery
|
|
368
|
-
// appears to require file-drop)
|
|
369
|
-
const cmdDir = path.join(ocDir, "commands");
|
|
370
|
-
for (const cmd of COMMANDS) {
|
|
371
|
-
const src = path.join(PKG_ROOT, "commands", "opencode", `${cmd}.md`);
|
|
372
|
-
const dest = path.join(cmdDir, `${cmd}.md`);
|
|
373
|
-
const r = copyFile(src, dest, false);
|
|
374
|
-
lines.push(` ${statusTag(r.status)} ${relPath(r.dest, home)}`);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// 4. opencode.json — add plugin reference (idempotent)
|
|
378
|
-
const ocJsonPath = path.join(ocDir, "opencode.json");
|
|
379
|
-
const ocJson = readJsonOrDefault(ocJsonPath, {
|
|
380
|
-
$schema: "https://opencode.ai/config.json",
|
|
381
|
-
});
|
|
382
|
-
ocJson.plugin = ocJson.plugin || [];
|
|
383
|
-
// Normalize to strings only (we don't use the [string, object] tuple form)
|
|
384
|
-
const pluginPath = `~/.config/opencode/node_modules/${PKG_NAME}`;
|
|
385
|
-
const alreadyHas = ocJson.plugin.some(
|
|
386
|
-
(p) => p === pluginPath || (Array.isArray(p) && p[0] === pluginPath)
|
|
387
|
-
);
|
|
388
|
-
if (!alreadyHas) {
|
|
389
|
-
ocJson.plugin.push(pluginPath);
|
|
390
|
-
}
|
|
391
|
-
writeJson(ocJsonPath, ocJson);
|
|
392
|
-
lines.push(
|
|
393
|
-
` ${alreadyHas ? "·" : "✓"} ${relPath(ocJsonPath, home)} (plugin: ${pluginPath})`
|
|
394
|
-
);
|
|
395
|
-
|
|
396
|
-
return lines;
|
|
397
|
-
}
|
|
398
|
-
|
|
399
279
|
function init(args) {
|
|
400
280
|
const cwd = process.cwd();
|
|
401
281
|
|
|
@@ -439,19 +319,14 @@ function init(args) {
|
|
|
439
319
|
|
|
440
320
|
for (const platform of targets) {
|
|
441
321
|
console.log(`[${platform}]`);
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
baseRoot: cwd,
|
|
451
|
-
sharedState,
|
|
452
|
-
});
|
|
453
|
-
for (const l of lines) console.log(l);
|
|
454
|
-
}
|
|
322
|
+
const lines = installPlatform({
|
|
323
|
+
platform,
|
|
324
|
+
isGlobal: args.global,
|
|
325
|
+
force: args.force,
|
|
326
|
+
baseRoot: cwd,
|
|
327
|
+
sharedState,
|
|
328
|
+
});
|
|
329
|
+
for (const l of lines) console.log(l);
|
|
455
330
|
console.log("");
|
|
456
331
|
}
|
|
457
332
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Use the `brainstorm` skill to handle the user's request.
|
|
1
|
+
Use the `brainstorm` skill to handle the user's request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Use the `changelog` skill to handle the user's request.
|
|
1
|
+
Use the `changelog` skill to handle the user's request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Use the `handoff-plan` skill to handle the user's request.
|
|
1
|
+
Use the `handoff-plan` skill to handle the user's request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Use the `plan-universal` skill to handle the user's request.
|
|
1
|
+
Use the `plan-universal` skill to handle the user's request.
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tuncss-plan-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": ".opencode/plugins/tuncss-plan-kit.js",
|
|
6
5
|
"description": "Four-skill kit for spec-driven development: brainstorm an idea into a spec, turn the spec into an executable plan, hand the plan off to another LLM agent, and record what changed.",
|
|
7
6
|
"bin": {
|
|
8
7
|
"tuncss-plan-kit": "bin/cli.js"
|
|
@@ -12,7 +11,6 @@
|
|
|
12
11
|
"skills/",
|
|
13
12
|
"commands/",
|
|
14
13
|
"templates/",
|
|
15
|
-
".opencode/",
|
|
16
14
|
"README.md"
|
|
17
15
|
],
|
|
18
16
|
"keywords": [
|
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: brainstorm
|
|
3
|
-
description: Use before any feature, component, or behavior change. Turns an idea into an approved design before any code is written.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Brainstorming
|
|
7
|
-
|
|
8
|
-
Turn an idea into a design the user approves, then hand off to plan-universal. No code, no scaffolding, no implementation skill until the design is approved.
|
|
9
|
-
|
|
10
|
-
<HARD-GATE>
|
|
11
|
-
Do NOT write code, scaffold, edit files for the feature, or invoke an implementation skill until you have presented a design and the user has approved it. This applies to every project regardless of size.
|
|
12
|
-
</HARD-GATE>
|
|
13
|
-
|
|
14
|
-
## "This is too simple to need a design"
|
|
15
|
-
|
|
16
|
-
It isn't. A todo list, a one-file utility, a config tweak — all go through this. Simple-looking projects are where unexamined assumptions cost the most rework. The design can be three sentences for a trivial change. You still present it, you still get approval.
|
|
17
|
-
|
|
18
|
-
## Checklist
|
|
19
|
-
|
|
20
|
-
Work through these in order. Don't skip ahead.
|
|
21
|
-
|
|
22
|
-
1. Explore project context — relevant files, recent commits, any existing docs
|
|
23
|
-
2. Assess scope — if the request is actually several independent projects, decompose before going deeper
|
|
24
|
-
3. Ask clarifying questions — one per message, multiple-choice when you can
|
|
25
|
-
4. Propose 2-3 approaches — trade-offs and your recommendation
|
|
26
|
-
5. Present the design section by section, getting approval after each
|
|
27
|
-
6. Write the spec to `docs/specs/YYYY-MM-DD-<topic>-design.md`
|
|
28
|
-
7. Self-review the spec — placeholders, contradictions, ambiguity, scope
|
|
29
|
-
8. Wait for the user to review the written spec
|
|
30
|
-
9. Hand off — ask the user to run `/plan-universal` (or implement directly only if trivial; see Hand-off)
|
|
31
|
-
|
|
32
|
-
## Scope assessment
|
|
33
|
-
|
|
34
|
-
Before any clarifying questions, look at the request as a whole. If it describes multiple independent subsystems ("a platform with chat, billing, file storage, and analytics"), don't refine details — that's wasted effort on something that needs to be decomposed first.
|
|
35
|
-
|
|
36
|
-
When the request is too large for a single spec:
|
|
37
|
-
- Name the independent pieces and how they relate
|
|
38
|
-
- Suggest a build order
|
|
39
|
-
- Brainstorm only the first sub-project through this flow
|
|
40
|
-
- Each sub-project gets its own spec → plan → implementation cycle
|
|
41
|
-
|
|
42
|
-
## Asking clarifying questions
|
|
43
|
-
|
|
44
|
-
- One question per message. If a topic needs more, break it into multiple turns.
|
|
45
|
-
- Prefer multiple-choice. Open-ended is fine when the space is genuinely open.
|
|
46
|
-
- Focus on purpose, constraints, and what success looks like.
|
|
47
|
-
- Don't ask about anything you can derive from reading the code.
|
|
48
|
-
|
|
49
|
-
**If the user dumps answers in bulk** (numbered list answering several questions at once, or "just go ahead with X, Y, Z"), do NOT take it as permission to skip the gate. Acknowledge the answers, then ask 1-2 follow-ups on what those answers leave open — trade-offs, edge cases, or the next decision their choices imply ("LocalStorage confirmed — should we handle data clearing or schema versioning?"). Only move to approaches once those are resolved.
|
|
50
|
-
|
|
51
|
-
## Proposing approaches
|
|
52
|
-
|
|
53
|
-
Once you understand the goal, lay out 2-3 ways to solve it. Each gets its trade-offs in plain language. Lead with the one you'd pick and say why. Don't hide your recommendation behind false neutrality — but make it easy for the user to override.
|
|
54
|
-
|
|
55
|
-
## Presenting the design
|
|
56
|
-
|
|
57
|
-
Present in sections. Scale each section to its complexity:
|
|
58
|
-
- A few sentences for something straightforward
|
|
59
|
-
- Up to ~300 words when it's nuanced
|
|
60
|
-
|
|
61
|
-
After each section, ask if it looks right before moving on. Cover what's actually relevant: architecture, components, data flow, error handling, testing. Skip what doesn't apply.
|
|
62
|
-
|
|
63
|
-
If something doesn't fit together, go back and clarify. The point of these gates is to catch confusion before it lands in the spec.
|
|
64
|
-
|
|
65
|
-
## Designing for isolation
|
|
66
|
-
|
|
67
|
-
Break the system into small units that each have one purpose, talk to each other through clear interfaces, and can be understood and tested on their own.
|
|
68
|
-
|
|
69
|
-
For each unit, you should be able to answer:
|
|
70
|
-
- What does it do?
|
|
71
|
-
- How do you use it?
|
|
72
|
-
- What does it depend on?
|
|
73
|
-
|
|
74
|
-
If a consumer has to read the internals to use a unit, the boundary is wrong. If you can't change internals without breaking consumers, the boundary is wrong. Smaller, well-bounded units are also easier to work with later — edits get more reliable when files are focused.
|
|
75
|
-
|
|
76
|
-
## Working inside an existing codebase
|
|
77
|
-
|
|
78
|
-
- Read the surrounding code first. Follow the patterns already there.
|
|
79
|
-
- If existing code in the area has real problems that affect this work (an oversized file, tangled responsibilities, unclear boundaries), include the targeted improvement in the design — the way a careful developer cleans up the room they're working in.
|
|
80
|
-
- Don't bundle unrelated refactoring. Stay on what serves the goal.
|
|
81
|
-
|
|
82
|
-
## YAGNI
|
|
83
|
-
|
|
84
|
-
Cut anything the request doesn't need yet. Future-proofing, config options "just in case", an abstraction for a hypothetical second consumer — all out, unless the user has actually named the second consumer.
|
|
85
|
-
|
|
86
|
-
## Writing the spec
|
|
87
|
-
|
|
88
|
-
After every section is approved, write the spec to `docs/specs/YYYY-MM-DD-<topic>-design.md` (override if the user has set a different location). Create `docs/specs/` if it doesn't exist. Commit the file.
|
|
89
|
-
|
|
90
|
-
The spec is the document a future implementer reads. It captures decisions, not your reasoning trail. Keep it tight.
|
|
91
|
-
|
|
92
|
-
## Spec self-review
|
|
93
|
-
|
|
94
|
-
Re-read with fresh eyes. Fix issues inline; no second review pass.
|
|
95
|
-
|
|
96
|
-
1. **Placeholders** — any "TBD", "TODO", or vague requirement? Resolve them.
|
|
97
|
-
2. **Internal consistency** — do sections contradict each other? Does the architecture match the feature description?
|
|
98
|
-
3. **Scope** — is this still a single implementation plan, or did it grow into something that needs decomposing?
|
|
99
|
-
4. **Ambiguity** — could a requirement be read two different ways? Pick one and make it explicit.
|
|
100
|
-
|
|
101
|
-
## User review gate
|
|
102
|
-
|
|
103
|
-
After your self-review, ask the user to read the written spec:
|
|
104
|
-
|
|
105
|
-
> Spec written and committed to `<path>`. Please review it and let me know if you want changes before we move to the implementation plan.
|
|
106
|
-
|
|
107
|
-
Wait for their response. If they ask for changes, make them and re-run the self-review. Only move on once they approve.
|
|
108
|
-
|
|
109
|
-
## Hand-off
|
|
110
|
-
|
|
111
|
-
After the spec is approved, **do NOT start implementing**. The skill ends here. The next step is `/plan-universal`, which turns the spec into an executable plan with
|
|
112
|
-
|
|
113
|
-
End your final turn with this message to the user (paraphrase, but keep all four parts):
|
|
114
|
-
|
|
115
|
-
> Spec is locked at `<path>`. Want me to write the implementation plan via `/plan-universal`? Or, if this is small enough — one file, no new public API, no schema or migration changes, no new dependency — say "implement directly" and I'll do it now.
|
|
116
|
-
|
|
117
|
-
Then **stop and wait** for the user's choice. Default is `/plan-universal`. Implement directly **only** when:
|
|
118
|
-
- The user explicitly says so (the phrase "implement directly" or equivalent)
|
|
119
|
-
- **AND** the change meets every trivial criterion above
|
|
120
|
-
|
|
121
|
-
If you find yourself thinking "the spec is small, I'll just knock it out" — that's the drift this gate exists to catch. Stop. Hand off.
|
|
122
|
-
|
|
123
|
-
Do not invoke any other skill from this skill.
|
|
124
|
-
|
|
125
|
-
## Key principles
|
|
126
|
-
|
|
127
|
-
- One question at a time
|
|
128
|
-
- Multiple choice when you can
|
|
129
|
-
- YAGNI hard
|
|
130
|
-
- Always explore 2-3 approaches before settling
|
|
131
|
-
- Approve as you go — don't drop a wall of design and ask "thoughts?"
|
|
132
|
-
- Be willing to back up when something doesn't fit
|
|
1
|
+
---
|
|
2
|
+
name: brainstorm
|
|
3
|
+
description: Use before any feature, component, or behavior change. Turns an idea into an approved design before any code is written.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Brainstorming
|
|
7
|
+
|
|
8
|
+
Turn an idea into a design the user approves, then hand off to plan-universal. No code, no scaffolding, no implementation skill until the design is approved.
|
|
9
|
+
|
|
10
|
+
<HARD-GATE>
|
|
11
|
+
Do NOT write code, scaffold, edit files for the feature, or invoke an implementation skill until you have presented a design and the user has approved it. This applies to every project regardless of size.
|
|
12
|
+
</HARD-GATE>
|
|
13
|
+
|
|
14
|
+
## "This is too simple to need a design"
|
|
15
|
+
|
|
16
|
+
It isn't. A todo list, a one-file utility, a config tweak — all go through this. Simple-looking projects are where unexamined assumptions cost the most rework. The design can be three sentences for a trivial change. You still present it, you still get approval.
|
|
17
|
+
|
|
18
|
+
## Checklist
|
|
19
|
+
|
|
20
|
+
Work through these in order. Don't skip ahead.
|
|
21
|
+
|
|
22
|
+
1. Explore project context — relevant files, recent commits, any existing docs
|
|
23
|
+
2. Assess scope — if the request is actually several independent projects, decompose before going deeper
|
|
24
|
+
3. Ask clarifying questions — one per message, multiple-choice when you can
|
|
25
|
+
4. Propose 2-3 approaches — trade-offs and your recommendation
|
|
26
|
+
5. Present the design section by section, getting approval after each
|
|
27
|
+
6. Write the spec to `docs/specs/YYYY-MM-DD-<topic>-design.md`
|
|
28
|
+
7. Self-review the spec — placeholders, contradictions, ambiguity, scope
|
|
29
|
+
8. Wait for the user to review the written spec
|
|
30
|
+
9. Hand off — ask the user to run `/plan-universal` (or implement directly only if trivial; see Hand-off)
|
|
31
|
+
|
|
32
|
+
## Scope assessment
|
|
33
|
+
|
|
34
|
+
Before any clarifying questions, look at the request as a whole. If it describes multiple independent subsystems ("a platform with chat, billing, file storage, and analytics"), don't refine details — that's wasted effort on something that needs to be decomposed first.
|
|
35
|
+
|
|
36
|
+
When the request is too large for a single spec:
|
|
37
|
+
- Name the independent pieces and how they relate
|
|
38
|
+
- Suggest a build order
|
|
39
|
+
- Brainstorm only the first sub-project through this flow
|
|
40
|
+
- Each sub-project gets its own spec → plan → implementation cycle
|
|
41
|
+
|
|
42
|
+
## Asking clarifying questions
|
|
43
|
+
|
|
44
|
+
- One question per message. If a topic needs more, break it into multiple turns.
|
|
45
|
+
- Prefer multiple-choice. Open-ended is fine when the space is genuinely open.
|
|
46
|
+
- Focus on purpose, constraints, and what success looks like.
|
|
47
|
+
- Don't ask about anything you can derive from reading the code.
|
|
48
|
+
|
|
49
|
+
**If the user dumps answers in bulk** (numbered list answering several questions at once, or "just go ahead with X, Y, Z"), do NOT take it as permission to skip the gate. Acknowledge the answers, then ask 1-2 follow-ups on what those answers leave open — trade-offs, edge cases, or the next decision their choices imply ("LocalStorage confirmed — should we handle data clearing or schema versioning?"). Only move to approaches once those are resolved.
|
|
50
|
+
|
|
51
|
+
## Proposing approaches
|
|
52
|
+
|
|
53
|
+
Once you understand the goal, lay out 2-3 ways to solve it. Each gets its trade-offs in plain language. Lead with the one you'd pick and say why. Don't hide your recommendation behind false neutrality — but make it easy for the user to override.
|
|
54
|
+
|
|
55
|
+
## Presenting the design
|
|
56
|
+
|
|
57
|
+
Present in sections. Scale each section to its complexity:
|
|
58
|
+
- A few sentences for something straightforward
|
|
59
|
+
- Up to ~300 words when it's nuanced
|
|
60
|
+
|
|
61
|
+
After each section, ask if it looks right before moving on. Cover what's actually relevant: architecture, components, data flow, error handling, testing. Skip what doesn't apply.
|
|
62
|
+
|
|
63
|
+
If something doesn't fit together, go back and clarify. The point of these gates is to catch confusion before it lands in the spec.
|
|
64
|
+
|
|
65
|
+
## Designing for isolation
|
|
66
|
+
|
|
67
|
+
Break the system into small units that each have one purpose, talk to each other through clear interfaces, and can be understood and tested on their own.
|
|
68
|
+
|
|
69
|
+
For each unit, you should be able to answer:
|
|
70
|
+
- What does it do?
|
|
71
|
+
- How do you use it?
|
|
72
|
+
- What does it depend on?
|
|
73
|
+
|
|
74
|
+
If a consumer has to read the internals to use a unit, the boundary is wrong. If you can't change internals without breaking consumers, the boundary is wrong. Smaller, well-bounded units are also easier to work with later — edits get more reliable when files are focused.
|
|
75
|
+
|
|
76
|
+
## Working inside an existing codebase
|
|
77
|
+
|
|
78
|
+
- Read the surrounding code first. Follow the patterns already there.
|
|
79
|
+
- If existing code in the area has real problems that affect this work (an oversized file, tangled responsibilities, unclear boundaries), include the targeted improvement in the design — the way a careful developer cleans up the room they're working in.
|
|
80
|
+
- Don't bundle unrelated refactoring. Stay on what serves the goal.
|
|
81
|
+
|
|
82
|
+
## YAGNI
|
|
83
|
+
|
|
84
|
+
Cut anything the request doesn't need yet. Future-proofing, config options "just in case", an abstraction for a hypothetical second consumer — all out, unless the user has actually named the second consumer.
|
|
85
|
+
|
|
86
|
+
## Writing the spec
|
|
87
|
+
|
|
88
|
+
After every section is approved, write the spec to `docs/specs/YYYY-MM-DD-<topic>-design.md` (override if the user has set a different location). Create `docs/specs/` if it doesn't exist. Commit the file.
|
|
89
|
+
|
|
90
|
+
The spec is the document a future implementer reads. It captures decisions, not your reasoning trail. Keep it tight.
|
|
91
|
+
|
|
92
|
+
## Spec self-review
|
|
93
|
+
|
|
94
|
+
Re-read with fresh eyes. Fix issues inline; no second review pass.
|
|
95
|
+
|
|
96
|
+
1. **Placeholders** — any "TBD", "TODO", or vague requirement? Resolve them.
|
|
97
|
+
2. **Internal consistency** — do sections contradict each other? Does the architecture match the feature description?
|
|
98
|
+
3. **Scope** — is this still a single implementation plan, or did it grow into something that needs decomposing?
|
|
99
|
+
4. **Ambiguity** — could a requirement be read two different ways? Pick one and make it explicit.
|
|
100
|
+
|
|
101
|
+
## User review gate
|
|
102
|
+
|
|
103
|
+
After your self-review, ask the user to read the written spec:
|
|
104
|
+
|
|
105
|
+
> Spec written and committed to `<path>`. Please review it and let me know if you want changes before we move to the implementation plan.
|
|
106
|
+
|
|
107
|
+
Wait for their response. If they ask for changes, make them and re-run the self-review. Only move on once they approve.
|
|
108
|
+
|
|
109
|
+
## Hand-off
|
|
110
|
+
|
|
111
|
+
After the spec is approved, **do NOT start implementing**. The skill ends here. The next step is `/plan-universal`, which turns the spec into an executable plan with per-task verification.
|
|
112
|
+
|
|
113
|
+
End your final turn with this message to the user (paraphrase, but keep all four parts):
|
|
114
|
+
|
|
115
|
+
> Spec is locked at `<path>`. Want me to write the implementation plan via `/plan-universal`? Or, if this is small enough — one file, no new public API, no schema or migration changes, no new dependency — say "implement directly" and I'll do it now.
|
|
116
|
+
|
|
117
|
+
Then **stop and wait** for the user's choice. Default is `/plan-universal`. Implement directly **only** when:
|
|
118
|
+
- The user explicitly says so (the phrase "implement directly" or equivalent)
|
|
119
|
+
- **AND** the change meets every trivial criterion above
|
|
120
|
+
|
|
121
|
+
If you find yourself thinking "the spec is small, I'll just knock it out" — that's the drift this gate exists to catch. Stop. Hand off.
|
|
122
|
+
|
|
123
|
+
Do not invoke any other skill from this skill.
|
|
124
|
+
|
|
125
|
+
## Key principles
|
|
126
|
+
|
|
127
|
+
- One question at a time
|
|
128
|
+
- Multiple choice when you can
|
|
129
|
+
- YAGNI hard
|
|
130
|
+
- Always explore 2-3 approaches before settling
|
|
131
|
+
- Approve as you go — don't drop a wall of design and ask "thoughts?"
|
|
132
|
+
- Be willing to back up when something doesn't fit
|
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: changelog
|
|
3
|
-
description: Use when a plan task has just been completed, or when the user runs /changelog, to append a short entry describing what actually changed to docs/CHANGELOG.md.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Changelog
|
|
7
|
-
|
|
8
|
-
Append a short, concrete record of what changed to `docs/CHANGELOG.md`. The reader is a teammate who did not do the work and wants to know what is different now. Commit messages already failed at this — do not write another one.
|
|
9
|
-
|
|
10
|
-
**Announce at start:** "Writing the changelog entry."
|
|
11
|
-
|
|
12
|
-
## Two ways in
|
|
13
|
-
|
|
14
|
-
**From a completed plan task.** Rule 6 of the plan's execution contract sends you here once Done When and Verification are satisfied. You have the task id, the task name, and the plan path.
|
|
15
|
-
|
|
16
|
-
**From `/changelog`.** The user invoked it directly for work done outside the plan flow. There is no task id and no plan path.
|
|
17
|
-
|
|
18
|
-
If a task's verification failed, do not write an entry at all. That work is usually not merged, and recording it would put a change that did not happen into the log.
|
|
19
|
-
|
|
20
|
-
## Gather the facts first
|
|
21
|
-
|
|
22
|
-
Run these before writing anything. Never write an entry from memory of what you set out to do — write it from what actually landed.
|
|
23
|
-
|
|
24
|
-
- `git diff` and `git diff --staged` — the real change
|
|
25
|
-
- `git config user.name` — the author name
|
|
26
|
-
|
|
27
|
-
The diff is your source, not your content: it tells you what to write about, and none of it is copied into the entry.
|
|
28
|
-
|
|
29
|
-
If both diffs are empty and nothing was just committed for this work, stop and tell the user there is nothing to record.
|
|
30
|
-
|
|
31
|
-
## How to write the bullets
|
|
32
|
-
|
|
33
|
-
This is the whole skill. Everything else is placement.
|
|
34
|
-
|
|
35
|
-
1. Every bullet names the thing that changed.
|
|
36
|
-
2. If a value changed, give **old → new**.
|
|
37
|
-
3. Banned: any phrasing that does not say what became what. "Improved", "refactored", "fixed issues", "optimized", "cleaned up", "enhanced" — and their equivalents in any language.
|
|
38
|
-
4. One to five bullets per entry. If you need more than five, say so in your report to the user: the task was too large. Write the entry anyway.
|
|
39
|
-
5. Write in the language the repository uses. This skill is in English; the entries it produces are not necessarily.
|
|
40
|
-
|
|
41
|
-
Good:
|
|
42
|
-
- `Read threshold lowered from -60 dB to -80 dB`
|
|
43
|
-
- `Token validation moved out of every handler into a single requireAuth middleware`
|
|
44
|
-
- `Session lifetime cut from 24 hours to 2 hours`
|
|
45
|
-
|
|
46
|
-
Bad:
|
|
47
|
-
- `Improved bluetooth reliability` — what became what?
|
|
48
|
-
- `Refactored auth` — same.
|
|
49
|
-
- `Various fixes` — same.
|
|
50
|
-
|
|
51
|
-
## Entry shape
|
|
52
|
-
|
|
53
|
-
For a plan task:
|
|
54
|
-
|
|
55
|
-
```markdown
|
|
56
|
-
### <task name> — TASK-NN · <author> · [plan](<plan path>)
|
|
57
|
-
- <bullet>
|
|
58
|
-
- <bullet>
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
For off-plan work:
|
|
62
|
-
|
|
63
|
-
```markdown
|
|
64
|
-
### <short name> — off-plan · <author>
|
|
65
|
-
- <bullet>
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The `off-plan` label is written in the repository's language, like the bullets.
|
|
69
|
-
|
|
70
|
-
If `git config user.name` is empty, drop both the author and the `·` that separates it. Never invent a name.
|
|
71
|
-
|
|
72
|
-
## Where it goes
|
|
73
|
-
|
|
74
|
-
The file is `docs/CHANGELOG.md`. Create it if missing, with `# Changelog` as the first line.
|
|
75
|
-
|
|
76
|
-
Entries are grouped under date headings, newest first:
|
|
77
|
-
|
|
78
|
-
```markdown
|
|
79
|
-
# Changelog
|
|
80
|
-
|
|
81
|
-
## 2026-09-04
|
|
82
|
-
|
|
83
|
-
### Auth middleware — TASK-03 · Mustafa TUNÇ · [plan](docs/plans/2026-09-02-auth.md)
|
|
84
|
-
- Token validation moved out of every handler into a single requireAuth middleware
|
|
85
|
-
- Response on an invalid token changed from 200 with an empty body to 401
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Placement rule — follow it exactly, so that three people's agents do not grow the file from three different places:
|
|
89
|
-
|
|
90
|
-
- If today's date heading already exists, append the entry at the end of that section.
|
|
91
|
-
- If it does not, insert a new date heading immediately after the `# Changelog` line.
|
|
92
|
-
|
|
93
|
-
## Do not commit
|
|
94
|
-
|
|
95
|
-
Leave the entry in the working tree next to the change. Whoever commits the work commits the entry with it, so `git log -p docs/CHANGELOG.md` always pairs a line with the change that produced it.
|
|
1
|
+
---
|
|
2
|
+
name: changelog
|
|
3
|
+
description: Use when a plan task has just been completed, or when the user runs /changelog, to append a short entry describing what actually changed to docs/CHANGELOG.md.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Changelog
|
|
7
|
+
|
|
8
|
+
Append a short, concrete record of what changed to `docs/CHANGELOG.md`. The reader is a teammate who did not do the work and wants to know what is different now. Commit messages already failed at this — do not write another one.
|
|
9
|
+
|
|
10
|
+
**Announce at start:** "Writing the changelog entry."
|
|
11
|
+
|
|
12
|
+
## Two ways in
|
|
13
|
+
|
|
14
|
+
**From a completed plan task.** Rule 6 of the plan's execution contract sends you here once Done When and Verification are satisfied. You have the task id, the task name, and the plan path.
|
|
15
|
+
|
|
16
|
+
**From `/changelog`.** The user invoked it directly for work done outside the plan flow. There is no task id and no plan path.
|
|
17
|
+
|
|
18
|
+
If a task's verification failed, do not write an entry at all. That work is usually not merged, and recording it would put a change that did not happen into the log.
|
|
19
|
+
|
|
20
|
+
## Gather the facts first
|
|
21
|
+
|
|
22
|
+
Run these before writing anything. Never write an entry from memory of what you set out to do — write it from what actually landed.
|
|
23
|
+
|
|
24
|
+
- `git diff` and `git diff --staged` — the real change
|
|
25
|
+
- `git config user.name` — the author name
|
|
26
|
+
|
|
27
|
+
The diff is your source, not your content: it tells you what to write about, and none of it is copied into the entry.
|
|
28
|
+
|
|
29
|
+
If both diffs are empty and nothing was just committed for this work, stop and tell the user there is nothing to record.
|
|
30
|
+
|
|
31
|
+
## How to write the bullets
|
|
32
|
+
|
|
33
|
+
This is the whole skill. Everything else is placement.
|
|
34
|
+
|
|
35
|
+
1. Every bullet names the thing that changed.
|
|
36
|
+
2. If a value changed, give **old → new**.
|
|
37
|
+
3. Banned: any phrasing that does not say what became what. "Improved", "refactored", "fixed issues", "optimized", "cleaned up", "enhanced" — and their equivalents in any language.
|
|
38
|
+
4. One to five bullets per entry. If you need more than five, say so in your report to the user: the task was too large. Write the entry anyway.
|
|
39
|
+
5. Write in the language the repository uses. This skill is in English; the entries it produces are not necessarily.
|
|
40
|
+
|
|
41
|
+
Good:
|
|
42
|
+
- `Read threshold lowered from -60 dB to -80 dB`
|
|
43
|
+
- `Token validation moved out of every handler into a single requireAuth middleware`
|
|
44
|
+
- `Session lifetime cut from 24 hours to 2 hours`
|
|
45
|
+
|
|
46
|
+
Bad:
|
|
47
|
+
- `Improved bluetooth reliability` — what became what?
|
|
48
|
+
- `Refactored auth` — same.
|
|
49
|
+
- `Various fixes` — same.
|
|
50
|
+
|
|
51
|
+
## Entry shape
|
|
52
|
+
|
|
53
|
+
For a plan task:
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
### <task name> — TASK-NN · <author> · [plan](<plan path>)
|
|
57
|
+
- <bullet>
|
|
58
|
+
- <bullet>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
For off-plan work:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
### <short name> — off-plan · <author>
|
|
65
|
+
- <bullet>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The `off-plan` label is written in the repository's language, like the bullets.
|
|
69
|
+
|
|
70
|
+
If `git config user.name` is empty, drop both the author and the `·` that separates it. Never invent a name.
|
|
71
|
+
|
|
72
|
+
## Where it goes
|
|
73
|
+
|
|
74
|
+
The file is `docs/CHANGELOG.md`. Create it if missing, with `# Changelog` as the first line.
|
|
75
|
+
|
|
76
|
+
Entries are grouped under date headings, newest first:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
# Changelog
|
|
80
|
+
|
|
81
|
+
## 2026-09-04
|
|
82
|
+
|
|
83
|
+
### Auth middleware — TASK-03 · Mustafa TUNÇ · [plan](docs/plans/2026-09-02-auth.md)
|
|
84
|
+
- Token validation moved out of every handler into a single requireAuth middleware
|
|
85
|
+
- Response on an invalid token changed from 200 with an empty body to 401
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Placement rule — follow it exactly, so that three people's agents do not grow the file from three different places:
|
|
89
|
+
|
|
90
|
+
- If today's date heading already exists, append the entry at the end of that section.
|
|
91
|
+
- If it does not, insert a new date heading immediately after the `# Changelog` line.
|
|
92
|
+
|
|
93
|
+
## Do not commit
|
|
94
|
+
|
|
95
|
+
Leave the entry in the working tree next to the change. Whoever commits the work commits the entry with it, so `git log -p docs/CHANGELOG.md` always pairs a line with the change that produced it.
|
|
@@ -55,17 +55,6 @@ Every plan starts with this header:
|
|
|
55
55
|
---
|
|
56
56
|
````
|
|
57
57
|
|
|
58
|
-
## Model tiers
|
|
59
|
-
|
|
60
|
-
Every task gets a recommended tier. These are the cost/capability brackets for the model that should execute it:
|
|
61
|
-
|
|
62
|
-
- **T1 — Fast:** trivial edits, renames, formatting, single-file boilerplate
|
|
63
|
-
- **T2 — Balanced:** standard feature work in one component, contained logic
|
|
64
|
-
- **T3 — Power:** multi-file changes, non-trivial logic, refactors with consequence
|
|
65
|
-
- **T4 — Reasoning:** architecture decisions, gnarly debugging, cross-cutting design
|
|
66
|
-
|
|
67
|
-
When in doubt, pick the lower tier. Upgrades are cheap; over-spending isn't.
|
|
68
|
-
|
|
69
58
|
## Task structure
|
|
70
59
|
|
|
71
60
|
Every task uses this shape:
|
|
@@ -77,13 +66,12 @@ Every task uses this shape:
|
|
|
77
66
|
- `exact/path/to/file.ts` (create | modify | delete)
|
|
78
67
|
- `exact/path/to/other.ts` (modify)
|
|
79
68
|
|
|
80
|
-
**Model Tier:** T2 <!-- T1 Fast | T2 Balanced | T3 Power | T4 Reasoning -->
|
|
81
|
-
|
|
82
69
|
**Implementation Notes:**
|
|
83
70
|
- What this task does, in plain language
|
|
84
71
|
- Any non-obvious decision and why
|
|
85
|
-
-
|
|
86
|
-
-
|
|
72
|
+
- The contract the executor can't guess: types, function signatures, commands, config keys. Write code bodies only for logic that is genuinely non-obvious (an algorithm, a regex, a query, a tricky edge case) — the executor writes the rest
|
|
73
|
+
- Point to existing code instead of copying it: "follow the handler pattern in `src/routes/users.ts:40`"
|
|
74
|
+
- If a public interface from an earlier task is consumed here, restate its signature only; don't make the reader page back
|
|
87
75
|
|
|
88
76
|
**Done When:**
|
|
89
77
|
- Bullet list of observable outcomes
|
|
@@ -117,7 +105,7 @@ These are **plan failures**. Never write them:
|
|
|
117
105
|
- "Add appropriate error handling" / "validate input" / "handle edge cases" — name the cases
|
|
118
106
|
- "Write tests for the above" without the actual test names and what they assert
|
|
119
107
|
- "Similar to TASK-N" — repeat what's needed; the executor reads tasks out of order
|
|
120
|
-
- Steps that describe *what* without
|
|
108
|
+
- Steps that describe *what* without pointing to *how* — name the existing file to follow, the signature, or the exact command; don't paste whole function bodies the executor can write itself
|
|
121
109
|
- References to types, functions, or files not defined in any task or in the file map
|
|
122
110
|
|
|
123
111
|
## Self-review
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!-- tuncss-plan-kit:start -->
|
|
2
|
-
## Plan Kit
|
|
3
|
-
|
|
4
|
-
This project uses tuncss-plan-kit. Four slash commands are available:
|
|
5
|
-
|
|
6
|
-
- `/brainstorm` — turn an idea into an approved spec (writes to `docs/specs/`)
|
|
7
|
-
- `/plan-universal` — turn a spec into an executable plan (writes to `docs/plans/`)
|
|
8
|
-
- `/handoff-plan` — generate a paste-ready handoff for another LLM agent (writes to `docs/handoffs/`)
|
|
9
|
-
- `/changelog` — record what changed, in plain sentences (writes to `docs/CHANGELOG.md`)
|
|
10
|
-
|
|
11
|
-
Plans contain an execution contract at the top. When asked for a specific task ("do TASK-03"), read only that task's block, stay inside its Targets, write the changelog entry, then stop and report when Done When + Verification are satisfied.
|
|
12
|
-
<!-- tuncss-plan-kit:end -->
|
|
1
|
+
<!-- tuncss-plan-kit:start -->
|
|
2
|
+
## Plan Kit
|
|
3
|
+
|
|
4
|
+
This project uses tuncss-plan-kit. Four slash commands are available:
|
|
5
|
+
|
|
6
|
+
- `/brainstorm` — turn an idea into an approved spec (writes to `docs/specs/`)
|
|
7
|
+
- `/plan-universal` — turn a spec into an executable plan (writes to `docs/plans/`)
|
|
8
|
+
- `/handoff-plan` — generate a paste-ready handoff for another LLM agent (writes to `docs/handoffs/`)
|
|
9
|
+
- `/changelog` — record what changed, in plain sentences (writes to `docs/CHANGELOG.md`)
|
|
10
|
+
|
|
11
|
+
Plans contain an execution contract at the top. When asked for a specific task ("do TASK-03"), read only that task's block, stay inside its Targets, write the changelog entry, then stop and report when Done When + Verification are satisfied.
|
|
12
|
+
<!-- tuncss-plan-kit:end -->
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { fileURLToPath } from "url";
|
|
3
|
-
|
|
4
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
-
const skillsDir = path.resolve(__dirname, "../../skills");
|
|
6
|
-
|
|
7
|
-
// Minimal templates: just pass the user's input through. The skill's
|
|
8
|
-
// `description` frontmatter is what triggers the model to invoke the skill
|
|
9
|
-
// when relevant — we don't force-load it from the wrapper, which would
|
|
10
|
-
// dump the full SKILL.md body into the chat in OpenCode's UI.
|
|
11
|
-
const WRAPPERS = {
|
|
12
|
-
brainstorm: {
|
|
13
|
-
description: "Turn an idea into an approved spec",
|
|
14
|
-
template: "$ARGUMENTS\n",
|
|
15
|
-
},
|
|
16
|
-
"plan-universal": {
|
|
17
|
-
description: "Turn an approved spec into an executable implementation plan",
|
|
18
|
-
template: "$ARGUMENTS\n",
|
|
19
|
-
},
|
|
20
|
-
"handoff-plan": {
|
|
21
|
-
description:
|
|
22
|
-
"Generate a paste-ready handoff message for another LLM agent to execute the plan",
|
|
23
|
-
template: "$ARGUMENTS\n",
|
|
24
|
-
},
|
|
25
|
-
changelog: {
|
|
26
|
-
description: "Record what changed in docs/CHANGELOG.md",
|
|
27
|
-
template: "$ARGUMENTS\n",
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const TuncssPlanKitPlugin = async () => ({
|
|
32
|
-
config: async (config) => {
|
|
33
|
-
config.skills = config.skills || {};
|
|
34
|
-
config.skills.paths = config.skills.paths || [];
|
|
35
|
-
if (!config.skills.paths.includes(skillsDir)) {
|
|
36
|
-
config.skills.paths.push(skillsDir);
|
|
37
|
-
}
|
|
38
|
-
config.command = config.command || {};
|
|
39
|
-
for (const [name, def] of Object.entries(WRAPPERS)) {
|
|
40
|
-
if (!config.command[name]) {
|
|
41
|
-
config.command[name] = {
|
|
42
|
-
template: def.template,
|
|
43
|
-
description: def.description,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
});
|