create-issflow 1.8.0 → 1.9.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 +5 -5
- package/bin/cli.js +80 -77
- package/package.json +1 -1
- package/template/.issflow/README.md +36 -0
- package/template/{.claude → .issflow}/commands/change-request.md +1 -1
- package/template/{.claude → .issflow}/commands/design.md +2 -2
- package/template/{.claude → .issflow}/commands/feature.md +2 -2
- package/template/{.claude → .issflow}/commands/propose.md +1 -1
- package/template/{.claude → .issflow}/commands/security-audit.md +1 -1
- package/template/{.claude → .issflow}/commands/store-wisdom.md +3 -3
- package/template/{.claude → .issflow}/commands/ui-audit.md +1 -1
- package/template/.issflow/flow-config.json +12 -0
- package/template/{.claude → .issflow}/hooks/context-guard.js +2 -2
- package/template/{.claude → .issflow}/hooks/lib/ctx.js +1 -1
- package/template/{.claude → .issflow}/hooks/plan-gate.js +1 -1
- package/template/{.claude → .issflow}/hooks/session-start.js +2 -2
- package/template/{.claude → .issflow}/istartsoft-flow/METHODOLOGY.md +48 -44
- package/template/{.claude → .issflow}/templates/automation/Dockerfile +1 -1
- package/template/{.claude → .issflow}/templates/automation/feature-docker.js +2 -2
- /package/template/{.claude → .issflow}/agents/debugger.md +0 -0
- /package/template/{.claude → .issflow}/agents/e2e-runner.md +0 -0
- /package/template/{.claude → .issflow}/agents/implementer.md +0 -0
- /package/template/{.claude → .issflow}/agents/planner.md +0 -0
- /package/template/{.claude → .issflow}/agents/researcher.md +0 -0
- /package/template/{.claude → .issflow}/agents/synthesizer.md +0 -0
- /package/template/{.claude → .issflow}/agents/test-author.md +0 -0
- /package/template/{.claude → .issflow}/commands/goal.md +0 -0
- /package/template/{.claude → .issflow}/commands/log-decision.md +0 -0
- /package/template/{.claude → .issflow}/commands/log-issue.md +0 -0
- /package/template/{.claude → .issflow}/commands/overview.md +0 -0
- /package/template/{.claude → .issflow}/commands/phase.md +0 -0
- /package/template/{.claude → .issflow}/commands/qa-audit.md +0 -0
- /package/template/{.claude → .issflow}/commands/quick.md +0 -0
- /package/template/{.claude → .issflow}/commands/release.md +0 -0
- /package/template/{.claude → .issflow}/commands/replan.md +0 -0
- /package/template/{.claude → .issflow}/commands/runbook.md +0 -0
- /package/template/{.claude → .issflow}/commands/sprint.md +0 -0
- /package/template/{.claude → .issflow}/commands/support.md +0 -0
- /package/template/{.claude → .issflow}/commands/synthesize.md +0 -0
- /package/template/{.claude → .issflow}/commands/uat.md +0 -0
- /package/template/{.claude → .issflow}/commands/unstuck.md +0 -0
- /package/template/{.claude → .issflow}/hooks/feature-gate.js +0 -0
- /package/template/{.claude → .issflow}/hooks/pre-compact.js +0 -0
- /package/template/{.claude → .issflow}/hooks/subagent-stop.js +0 -0
- /package/template/{.claude → .issflow}/skills/caveman/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/code-standards/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/code-standards/references/architecture.md +0 -0
- /package/template/{.claude → .issflow}/skills/code-standards/references/naming.md +0 -0
- /package/template/{.claude → .issflow}/skills/grill-me/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/karpathy-guidelines/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/security/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/security/references/pentest-checklist.md +0 -0
- /package/template/{.claude → .issflow}/skills/security/references/secure-coding.md +0 -0
- /package/template/{.claude → .issflow}/skills/security/references/standards.md +0 -0
- /package/template/{.claude → .issflow}/skills/security/references/threat-modeling.md +0 -0
- /package/template/{.claude → .issflow}/skills/support-triage/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/ux-design/SKILL.md +0 -0
- /package/template/{.claude → .issflow}/skills/ux-design/references/wireframe-template.md +0 -0
- /package/template/{.claude → .issflow}/templates/ARCHITECTURE-template.md +0 -0
- /package/template/{.claude → .issflow}/templates/CR-template.md +0 -0
- /package/template/{.claude → .issflow}/templates/FEATURE-template.md +0 -0
- /package/template/{.claude → .issflow}/templates/UX-PACK-template.md +0 -0
- /package/template/{.claude → .issflow}/templates/automation/issflow-feature.yml +0 -0
- /package/template/{.claude → .issflow}/templates/automation/issflow-goal.yml +0 -0
- /package/template/{.claude → .issflow}/templates/proposal.html +0 -0
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ Flags:
|
|
|
28
28
|
|
|
29
29
|
## What it installs
|
|
30
30
|
|
|
31
|
-
The portable kit (every tool) in `<project>/.
|
|
31
|
+
The portable kit (every tool) in `<project>/.issflow/`:
|
|
32
32
|
|
|
33
33
|
- `agents/` — planner · researcher · implementer · test-author · debugger · e2e-runner · synthesizer
|
|
34
34
|
- `commands/` — `/overview` `/feature` `/goal` `/propose` `/phase` `/sprint` `/ui-audit` `/qa-audit` `/security-audit` `/release` `/uat` `/change-request` `/replan` `/quick` `/synthesize` `/runbook` `/store-wisdom` `/log-issue` `/log-decision` `/unstuck`
|
|
@@ -44,10 +44,10 @@ Plus a root **`AGENTS.md`** (open standard — primary entry) and the per-tool a
|
|
|
44
44
|
| `cursor` | `.cursor/rules/` + `.cursor/commands/` + `.cursor/hooks.json` |
|
|
45
45
|
| `gemini` | `GEMINI.md` pointer |
|
|
46
46
|
| `aider` | `.aider.conf.yml` that loads the methodology |
|
|
47
|
-
| `claude` | thin `CLAUDE.md` (`@AGENTS.md`) + merges hooks into `.claude/settings.json` |
|
|
47
|
+
| `claude` | thin `CLAUDE.md` (`@AGENTS.md`) + `.claude/` kit mirror + merges hooks into `.claude/settings.json` (hooks run from `.issflow/`) |
|
|
48
48
|
| `all` | every adapter above |
|
|
49
49
|
|
|
50
|
-
It also un-ignores the workflow dirs in `.gitignore` if `.
|
|
50
|
+
It also un-ignores the workflow dirs in `.gitignore` if `.issflow/*` was ignored.
|
|
51
51
|
|
|
52
52
|
## Loop
|
|
53
53
|
|
|
@@ -58,10 +58,10 @@ PRD / architecture / stories (e.g. BMAD / iSSM).
|
|
|
58
58
|
|
|
59
59
|
## Maintainers
|
|
60
60
|
|
|
61
|
-
The kit lives in the repo's `.
|
|
61
|
+
The kit lives in the repo's `.issflow/`. After editing it, run `npm run build`
|
|
62
62
|
(pure Node — cmd / PowerShell / sh) to refresh `template/`, then `npm version patch`
|
|
63
63
|
and `npm publish`. `prepublishOnly` rebuilds `template/` on publish automatically.
|
|
64
64
|
|
|
65
65
|
Everything is cross-platform: the installer and `build.js` are pure Node, and the
|
|
66
|
-
lifecycle hooks are Node scripts (`node .
|
|
66
|
+
lifecycle hooks are Node scripts (`node .issflow/hooks/*.js`) — no bash/jq/python,
|
|
67
67
|
so the kit runs the same on macOS, Windows, and Linux.
|
package/bin/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// current project. Pure Node, zero deps, cross-platform, NON-DESTRUCTIVE:
|
|
4
4
|
// never overwrites an existing file — on conflict it writes `<file>.issflow-new`.
|
|
5
5
|
//
|
|
6
|
-
// Tool-agnostic: the portable kit lives in `.
|
|
6
|
+
// Tool-agnostic: the portable kit lives in `.issflow/` and the methodology is the
|
|
7
7
|
// single source of truth. `--tool=<name>` writes the right adapter so the same
|
|
8
8
|
// kit drives Claude Code, Codex, Cursor, Gemini CLI, Aider, or any AGENTS.md tool.
|
|
9
9
|
'use strict';
|
|
@@ -23,7 +23,7 @@ const toolArg = (argv.find(a => a.startsWith('--tool=')) || '').split('=')[1];
|
|
|
23
23
|
const TOOLS = {
|
|
24
24
|
claude: 'Claude Code (Anthropic) — full: subagents, lifecycle hooks, skills',
|
|
25
25
|
codex: 'OpenAI Codex CLI — AGENTS.md native; subagents/skills as readable files',
|
|
26
|
-
cursor: 'Cursor — .cursor/rules + commands + hooks;
|
|
26
|
+
cursor: 'Cursor — .cursor/rules + commands + hooks; kit stays in .issflow/ (no .claude/)',
|
|
27
27
|
gemini: 'Google Gemini CLI — GEMINI.md pointer; commands/skills as readable files',
|
|
28
28
|
aider: 'Aider — .aider.conf.yml loads the methodology as conventions',
|
|
29
29
|
all: 'Write every adapter above (mixed-team repo)',
|
|
@@ -50,10 +50,10 @@ Flags:
|
|
|
50
50
|
--force overwrite existing kit files (default keeps yours -> <file>.issflow-new)
|
|
51
51
|
-h, --help this message
|
|
52
52
|
|
|
53
|
-
Every tool installs the portable kit in .
|
|
54
|
-
standard
|
|
55
|
-
|
|
56
|
-
shim
|
|
53
|
+
Every tool installs the portable kit in .issflow/ + a root AGENTS.md (open
|
|
54
|
+
standard). Methodology: .issflow/istartsoft-flow/METHODOLOGY.md.
|
|
55
|
+
Claude Code ONLY (--tool=claude|all) also gets a .claude/ mirror + CLAUDE.md
|
|
56
|
+
shim — other tools do not create .claude/.`);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
// Typo / alias map → canonical TOOLS key
|
|
@@ -98,33 +98,38 @@ function walk(dir) {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
function copyTemplateCommands(destDir) {
|
|
101
|
-
const cmdDir = path.join(TPL, '.
|
|
101
|
+
const cmdDir = path.join(TPL, '.issflow', 'commands');
|
|
102
102
|
if (!fs.existsSync(cmdDir)) return;
|
|
103
103
|
for (const f of fs.readdirSync(cmdDir)) writeFile(path.join(destDir, f), fs.readFileSync(path.join(cmdDir, f), 'utf8'));
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/** Claude Code loads commands/agents/skills from `.claude/`. Mirror the
|
|
107
|
+
* portable `.issflow/` kit there (Claude adapter only — Cursor never gets this). */
|
|
108
|
+
function materializeClaudeMirror() {
|
|
109
|
+
const kitTpl = path.join(TPL, '.issflow');
|
|
110
|
+
for (const src of walk(kitTpl)) {
|
|
111
|
+
const rel = path.relative(kitTpl, src);
|
|
112
|
+
writeFile(path.join('.claude', rel), fs.readFileSync(src, 'utf8'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
106
116
|
// ---- adapters (keep the methodology single-source — these POINT at it) ------
|
|
107
117
|
|
|
108
118
|
function adapterClaude() {
|
|
109
|
-
// Claude Code
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
// load). A one-line `@AGENTS.md` import gives Claude Code the full baseline
|
|
113
|
-
// while keeping ONE source of truth — no rule is restated here (anti-drift).
|
|
119
|
+
// Claude Code: needs CLAUDE.md auto-load + native `.claude/` tree for
|
|
120
|
+
// commands/agents/skills discovery. Portable SoT remains `.issflow/`;
|
|
121
|
+
// hooks execute from `.issflow/` (single source).
|
|
114
122
|
const c0 = conflicts;
|
|
115
123
|
writeFile('CLAUDE.md', claudeMd());
|
|
116
124
|
if (conflicts > c0) warnings.push('claude: you already keep a CLAUDE.md — ours was written as CLAUDE.md.issflow-new. Add a line `@AGENTS.md` to your CLAUDE.md so the methodology auto-loads.');
|
|
117
|
-
|
|
118
|
-
// Shipped default window:0 = auto-detect; flow-config.json lives at .claude root,
|
|
119
|
-
// outside build.js's copied DIRS, so the installer writes it here.
|
|
120
|
-
writeFile('.claude/flow-config.json', flowConfig());
|
|
125
|
+
materializeClaudeMirror();
|
|
121
126
|
const HOOKS = {
|
|
122
|
-
SessionStart: [{ matcher: 'startup|clear|compact', hooks: [{ type: 'command', command: 'node .
|
|
123
|
-
PreToolUse: [{ matcher: '*', hooks: [{ type: 'command', command: 'node .
|
|
124
|
-
{ matcher: 'Edit|Write|MultiEdit|NotebookEdit', hooks: [{ type: 'command', command: 'node .
|
|
125
|
-
PreCompact: [{ matcher: 'auto|manual', hooks: [{ type: 'command', command: 'node .
|
|
126
|
-
SubagentStop: [{ hooks: [{ type: 'command', command: 'node .
|
|
127
|
-
Stop: [{ hooks: [{ type: 'command', command: 'node .
|
|
127
|
+
SessionStart: [{ matcher: 'startup|clear|compact', hooks: [{ type: 'command', command: 'node .issflow/hooks/session-start.js' }] }],
|
|
128
|
+
PreToolUse: [{ matcher: '*', hooks: [{ type: 'command', command: 'node .issflow/hooks/context-guard.js' }] },
|
|
129
|
+
{ matcher: 'Edit|Write|MultiEdit|NotebookEdit', hooks: [{ type: 'command', command: 'node .issflow/hooks/plan-gate.js' }] }],
|
|
130
|
+
PreCompact: [{ matcher: 'auto|manual', hooks: [{ type: 'command', command: 'node .issflow/hooks/pre-compact.js' }] }],
|
|
131
|
+
SubagentStop: [{ hooks: [{ type: 'command', command: 'node .issflow/hooks/subagent-stop.js' }] }],
|
|
132
|
+
Stop: [{ hooks: [{ type: 'command', command: 'node .issflow/hooks/feature-gate.js' }] }],
|
|
128
133
|
};
|
|
129
134
|
const sp = path.join(CWD, '.claude', 'settings.json');
|
|
130
135
|
let settings = {};
|
|
@@ -135,27 +140,28 @@ function adapterClaude() {
|
|
|
135
140
|
for (const k of Object.keys(HOOKS)) if (!settings.hooks[k]) { settings.hooks[k] = HOOKS[k]; added.push(k); }
|
|
136
141
|
if (added.length) { log(` + .claude/settings.json hooks: ${added.join(', ')}`); if (!DRY) { fs.mkdirSync(path.dirname(sp), { recursive: true }); fs.writeFileSync(sp, JSON.stringify(settings, null, 2) + '\n'); } }
|
|
137
142
|
else log(' = .claude/settings.json hooks already present');
|
|
143
|
+
warnings.push('claude: portable SoT is .issflow/ — .claude/ is a host mirror; refresh with create-issflow --tool=claude after kit edits.');
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
function adapterCodex() {
|
|
141
|
-
warnings.push('codex: AGENTS.md is read natively. Lifecycle hooks unsupported (rituals model-run); subagents in .
|
|
147
|
+
warnings.push('codex: AGENTS.md is read natively. Lifecycle hooks unsupported (rituals model-run); subagents in .issflow/agents/ are read as reference, not isolated contexts.');
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
function adapterCursor() {
|
|
145
151
|
writeFile('.cursor/rules/istartsoftflow.mdc', [
|
|
146
152
|
'---', 'description: iStartSoftFlow workflow — always apply', 'alwaysApply: true', '---', '',
|
|
147
153
|
'Run the **iStartSoftFlow** workflow. The full, single-source methodology is',
|
|
148
|
-
'`.
|
|
149
|
-
'`.
|
|
150
|
-
'(mirror of `.
|
|
154
|
+
'`.issflow/istartsoft-flow/METHODOLOGY.md` — read it before acting. Roles live in',
|
|
155
|
+
'`.issflow/agents/` (Cursor reads them natively); procedures in `.cursor/commands/`',
|
|
156
|
+
'(mirror of `.issflow/commands/`). Caveman ULTRA mode; apply the `karpathy-guidelines`',
|
|
151
157
|
'and `ux-design` skills. See `AGENTS.md` for the role/command/skill map.', '',
|
|
152
158
|
].join('\n'));
|
|
153
159
|
copyTemplateCommands('.cursor/commands');
|
|
154
160
|
writeFile('.cursor/hooks.json', JSON.stringify({
|
|
155
161
|
version: 1,
|
|
156
162
|
hooks: {
|
|
157
|
-
sessionStart: [{ command: 'node .
|
|
158
|
-
subagentStop: [{ command: 'node .
|
|
163
|
+
sessionStart: [{ command: 'node .issflow/hooks/session-start.js' }],
|
|
164
|
+
subagentStop: [{ command: 'node .issflow/hooks/subagent-stop.js' }],
|
|
159
165
|
},
|
|
160
166
|
}, null, 2) + '\n');
|
|
161
167
|
warnings.push('cursor: PreCompact has no Cursor equivalent (snapshot ritual degrades to model-run); verify hooks.json against cursor.com/docs/hooks — the schema evolves.');
|
|
@@ -166,9 +172,9 @@ function adapterGemini() {
|
|
|
166
172
|
'# GEMINI.md — iStartSoftFlow', '',
|
|
167
173
|
'This repo runs the **iStartSoftFlow** agentic dev workflow. The complete,',
|
|
168
174
|
'tool-agnostic methodology (the single source of truth) lives in',
|
|
169
|
-
'`.
|
|
170
|
-
'`.
|
|
171
|
-
'skills in `.
|
|
175
|
+
'`.issflow/istartsoft-flow/METHODOLOGY.md` — read it before acting. Roles are in',
|
|
176
|
+
'`.issflow/agents/`, procedures in `.issflow/commands/` (run their bodies as prompts),',
|
|
177
|
+
'skills in `.issflow/skills/` (read on demand). See `AGENTS.md` for the full map.', '',
|
|
172
178
|
'Lifecycle hooks do not auto-fire in Gemini CLI — run the SESSION-OPEN ritual',
|
|
173
179
|
'(git state, docs/STATE.md, docs/ISSUES.md) yourself at the start of each session.', '',
|
|
174
180
|
].join('\n'));
|
|
@@ -181,7 +187,7 @@ function adapterAider() {
|
|
|
181
187
|
'# Aider has no lifecycle hooks/subagents; the workflow degrades to model-run rituals.',
|
|
182
188
|
'read:',
|
|
183
189
|
' - AGENTS.md',
|
|
184
|
-
' - .
|
|
190
|
+
' - .issflow/istartsoft-flow/METHODOLOGY.md',
|
|
185
191
|
'',
|
|
186
192
|
].join('\n'));
|
|
187
193
|
warnings.push('aider: hooks + named subagents unsupported — the loop runs as a single-agent, model-driven workflow.');
|
|
@@ -191,7 +197,7 @@ const ADAPTERS = { claude: adapterClaude, codex: adapterCodex, cursor: adapterCu
|
|
|
191
197
|
|
|
192
198
|
const NEXT_STEPS = {
|
|
193
199
|
claude: 'Open Claude Code — CLAUDE.md (@AGENTS.md) loads the methodology and the SessionStart hook fires automatically. Run /overview to bootstrap.',
|
|
194
|
-
codex: 'Open Codex CLI — it reads AGENTS.md. Start by running the /overview procedure (.
|
|
200
|
+
codex: 'Open Codex CLI — it reads AGENTS.md. Start by running the /overview procedure (.issflow/commands/overview.md).',
|
|
195
201
|
cursor: 'Open Cursor — the rule applies automatically. Run the /overview command to bootstrap.',
|
|
196
202
|
gemini: 'Open Gemini CLI — it reads GEMINI.md. Run the SESSION-OPEN ritual, then the overview procedure.',
|
|
197
203
|
aider: 'Run aider — it loads AGENTS.md + METHODOLOGY.md. Drive the loop manually (overview -> phase).',
|
|
@@ -201,22 +207,28 @@ const NEXT_STEPS = {
|
|
|
201
207
|
function agentsMd() {
|
|
202
208
|
return [
|
|
203
209
|
'# AGENTS.md — iStartSoftFlow', '',
|
|
204
|
-
'This repo runs the **iStartSoftFlow** agentic dev workflow.
|
|
205
|
-
'tool-agnostic methodology —
|
|
206
|
-
'rules — lives in ONE
|
|
207
|
-
'> **`.
|
|
208
|
-
'
|
|
210
|
+
'This repo runs the **iStartSoftFlow** agentic dev workflow.', '',
|
|
211
|
+
'**Primary entry (this file).** The complete, tool-agnostic methodology — loop,',
|
|
212
|
+
'roles, procedures, rituals, hard rules — lives in ONE place. Read before acting:', '',
|
|
213
|
+
'> **`.issflow/istartsoft-flow/METHODOLOGY.md`** ← single source of truth.', '',
|
|
214
|
+
'The portable kit lives in **`.issflow/`** (commands, agents, hooks, skills,',
|
|
215
|
+
'methodology — see `.issflow/README.md`). Host adapters (`.cursor/`, `CLAUDE.md`,',
|
|
216
|
+
'…) point at it. Do not restate METHODOLOGY rules elsewhere (anti-drift).', '',
|
|
209
217
|
'## The loop', '',
|
|
210
|
-
'design-research → grill ×2 → plan →
|
|
211
|
-
'SLICE per phase. Phase 0 (infra)
|
|
212
|
-
'
|
|
218
|
+
'design-research → grill ×2 → plan → (propose/design if quoted) → implement →',
|
|
219
|
+
'test → deploy — one VERTICAL SLICE per phase. Phase 0 (infra) only when',
|
|
220
|
+
'infra is self-managed.', '',
|
|
221
|
+
'## Roles — `.issflow/agents/`', '',
|
|
213
222
|
'planner · researcher · implementer · test-author · debugger · e2e-runner · synthesizer', '',
|
|
214
|
-
'## Procedures — `.
|
|
215
|
-
'
|
|
216
|
-
'
|
|
217
|
-
'
|
|
218
|
-
'
|
|
219
|
-
'
|
|
223
|
+
'## Procedures — `.issflow/commands/` (run as `/name`)', '',
|
|
224
|
+
'**Default:** `/overview` · `/feature` · `/quick`', '',
|
|
225
|
+
'**Advanced:** `/propose` · `/design` · `/support` · `/phase` · `/sprint` · `/goal` ·',
|
|
226
|
+
'`/ui-audit` · `/qa-audit` · `/security-audit` · `/release` · `/uat` ·',
|
|
227
|
+
'`/change-request` · `/replan` · `/synthesize` · `/runbook` · `/store-wisdom` ·',
|
|
228
|
+
'`/log-issue` · `/log-decision` · `/unstuck`', '',
|
|
229
|
+
'## Skills — `.issflow/skills/` (loaded on demand)', '',
|
|
230
|
+
'caveman · grill-me · karpathy-guidelines · ux-design · security · code-standards ·',
|
|
231
|
+
'support-triage', '',
|
|
220
232
|
'## Autonomy', '',
|
|
221
233
|
'Planning (`/overview` grill + plan approval) always asks — that input is cheap.',
|
|
222
234
|
'**AUTO (default)** governs the DEV loop: follow the plan, decide + log + continue,',
|
|
@@ -225,16 +237,8 @@ function agentsMd() {
|
|
|
225
237
|
'mid-flow. **GUIDED** asks at each fork in dev too. Declare the mode in',
|
|
226
238
|
'`docs/OVERVIEW.md`. See METHODOLOGY → Autonomy.', '',
|
|
227
239
|
'## Hard-rule index (full text in METHODOLOGY.md)', '',
|
|
228
|
-
'1
|
|
229
|
-
'
|
|
230
|
-
'green · 6 blind tests (RED-first) · 7 programmatic E2E auth · 8 log-decision on arch',
|
|
231
|
-
'change · 9 UI conforms to the `ux-design` cookbook + wireframe frame · 10 no-rationalization ·',
|
|
232
|
-
'11 Secure SDLC: threat-model → secure coding → SAST/SCA/secrets each phase → pentest',
|
|
233
|
-
'gate + security review before deploy (`security` skill) · 12 code-standards gate:',
|
|
234
|
-
'lint/format clean + naming per language idiom + declared architecture (`code-standards`) ·',
|
|
235
|
-
'13 PLAN-APPROVAL gate: no phase/sprint starts until `docs/PLAN.md` is human-approved ·',
|
|
236
|
-
'14 UNDERSTAND-FIRST gate: brief back any new free-text task and wait for confirm',
|
|
237
|
-
'before executing (an approved PLAN/FEATURE/CR/goal is the recorded confirmation).', '',
|
|
240
|
+
'1–12 as in METHODOLOGY · 13 PLAN-APPROVAL · 14 UNDERSTAND-FIRST ·',
|
|
241
|
+
'15 DESIGN + ARCHITECTURE gates (after proposal, before `/phase`; internal may n/a).', '',
|
|
238
242
|
'## Your stack', '',
|
|
239
243
|
'Declare your stack (language, framework, infra, auth, test + E2E runner,',
|
|
240
244
|
'planning source) once in `docs/OVERVIEW.md`. Every rule references *your declared',
|
|
@@ -244,17 +248,16 @@ function agentsMd() {
|
|
|
244
248
|
|
|
245
249
|
function claudeMd() {
|
|
246
250
|
return [
|
|
247
|
-
'# CLAUDE.md —
|
|
251
|
+
'# CLAUDE.md — host shim for Claude Code', '',
|
|
248
252
|
'@AGENTS.md', '',
|
|
249
|
-
'
|
|
250
|
-
'
|
|
251
|
-
'
|
|
252
|
-
'
|
|
253
|
-
'- **
|
|
254
|
-
'
|
|
255
|
-
'- **PreCompact** + **SubagentStop**
|
|
256
|
-
'-
|
|
257
|
-
' native subagents.', '',
|
|
253
|
+
'Claude Code auto-loads **this filename only**. The import above is the real',
|
|
254
|
+
'entry (`AGENTS.md` → METHODOLOGY). Do NOT restate rules here.', '',
|
|
255
|
+
'## Host wiring', '',
|
|
256
|
+
'- **`.claude/`** is a mirror of `.issflow/` for command/agent/skill discovery.',
|
|
257
|
+
'- **Hooks** run from `.issflow/hooks/` (see `.claude/settings.json`).',
|
|
258
|
+
'- **SessionStart** injects git state + `docs/STATE.md` + open `docs/ISSUES.md`.',
|
|
259
|
+
'- **PreCompact** + **SubagentStop** rituals run automatically.',
|
|
260
|
+
'- Edit the kit in `.issflow/`, then re-run `create-issflow --tool=claude` to refresh the mirror.', '',
|
|
258
261
|
].join('\n');
|
|
259
262
|
}
|
|
260
263
|
|
|
@@ -264,7 +267,7 @@ function flowConfig() {
|
|
|
264
267
|
window: 0,
|
|
265
268
|
warnPct: 60,
|
|
266
269
|
gatePct: 78,
|
|
267
|
-
_note: 'Context-budget watchdog (.
|
|
270
|
+
_note: 'Context-budget watchdog (.issflow/hooks/context-guard.js, PreToolUse hook). '
|
|
268
271
|
+ 'window 0 = auto-detect from the model id (200000 for standard models). '
|
|
269
272
|
+ 'Some 1M-context models report their id WITHOUT a [1m] tag, so auto-detect '
|
|
270
273
|
+ 'assumes 200000 and may false-gate around 156k — if you run a 1M model, set '
|
|
@@ -286,7 +289,7 @@ function flowConfig() {
|
|
|
286
289
|
|
|
287
290
|
function main() {
|
|
288
291
|
if (HELP) { printHelp(); return; }
|
|
289
|
-
if (!fs.existsSync(path.join(TPL, '.
|
|
292
|
+
if (!fs.existsSync(path.join(TPL, '.issflow'))) {
|
|
290
293
|
console.error('create-issflow: embedded template/ missing. From source run: npm run build');
|
|
291
294
|
process.exit(1);
|
|
292
295
|
}
|
|
@@ -294,14 +297,14 @@ function main() {
|
|
|
294
297
|
const TOOL = pickTool();
|
|
295
298
|
const targets = TOOL === 'all' ? Object.keys(TOOLS).filter(t => t !== 'all') : [TOOL];
|
|
296
299
|
|
|
297
|
-
// 1. portable kit tree (.
|
|
298
|
-
for (const src of walk(path.join(TPL, '.
|
|
300
|
+
// 1. portable kit tree (.issflow/) — every tool gets it.
|
|
301
|
+
for (const src of walk(path.join(TPL, '.issflow'))) {
|
|
299
302
|
const rel = path.relative(TPL, src);
|
|
300
303
|
writeFile(rel, fs.readFileSync(src, 'utf8'));
|
|
301
304
|
}
|
|
302
305
|
|
|
303
306
|
// 1b. integrity: confirm the methodology resolved on disk (load-bearing sentinel).
|
|
304
|
-
const methPath = path.join(CWD, '.
|
|
307
|
+
const methPath = path.join(CWD, '.issflow', 'istartsoft-flow', 'METHODOLOGY.md');
|
|
305
308
|
const SENTINEL = 'ISTARTSOFTFLOW-AGENTS-SENTINEL-v2.0';
|
|
306
309
|
if (!DRY && (!fs.existsSync(methPath) || !fs.readFileSync(methPath, 'utf8').includes(SENTINEL))) {
|
|
307
310
|
warnings.push(`integrity: ${SENTINEL} not found in installed METHODOLOGY.md — the kit may be incomplete; re-run create-issflow (or npm run build from source).`);
|
|
@@ -314,7 +317,7 @@ function main() {
|
|
|
314
317
|
for (const t of targets) ADAPTERS[t]();
|
|
315
318
|
|
|
316
319
|
// 3b. headless feature lane (opt-in): materialize the automation templates.
|
|
317
|
-
const autoDir = path.join(TPL, '.
|
|
320
|
+
const autoDir = path.join(TPL, '.issflow', 'templates', 'automation');
|
|
318
321
|
if (CI) {
|
|
319
322
|
writeFile(path.join('.github', 'workflows', 'issflow-feature.yml'), fs.readFileSync(path.join(autoDir, 'issflow-feature.yml'), 'utf8'));
|
|
320
323
|
writeFile(path.join('.github', 'workflows', 'issflow-goal.yml'), fs.readFileSync(path.join(autoDir, 'issflow-goal.yml'), 'utf8'));
|
|
@@ -324,13 +327,13 @@ function main() {
|
|
|
324
327
|
writeFile(path.join('scripts', 'feature-docker.js'), fs.readFileSync(path.join(autoDir, 'feature-docker.js'), 'utf8'), { exec: true });
|
|
325
328
|
}
|
|
326
329
|
|
|
327
|
-
// 4. .gitignore: track the workflow dirs if .
|
|
330
|
+
// 4. .gitignore: track the workflow dirs if .issflow/* is ignored
|
|
328
331
|
const gi = path.join(CWD, '.gitignore');
|
|
329
332
|
if (fs.existsSync(gi)) {
|
|
330
333
|
const txt = fs.readFileSync(gi, 'utf8');
|
|
331
|
-
if (/^\.
|
|
332
|
-
const block = '\n# iStartSoftFlow workflow — track as project config\n!.
|
|
333
|
-
log(' + .gitignore: un-ignore .
|
|
334
|
+
if (/^\.issflow\/\*\s*$/m.test(txt) && !txt.includes('!.issflow/agents/')) {
|
|
335
|
+
const block = '\n# iStartSoftFlow workflow — track as project config\n!.issflow/agents/\n!.issflow/commands/\n!.issflow/skills/\n!.issflow/hooks/\n!.issflow/istartsoft-flow/\n';
|
|
336
|
+
log(' + .gitignore: un-ignore .issflow workflow dirs');
|
|
334
337
|
if (!DRY) fs.appendFileSync(gi, block);
|
|
335
338
|
}
|
|
336
339
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-issflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Scaffold the iStartSoftFlow AI-coding workflow into a project. Stack-agnostic, tool-agnostic (Claude Code, Codex, Cursor, Gemini, Aider), non-destructive.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-issflow": "bin/cli.js"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# `.issflow/` — portable iStartSoftFlow kit
|
|
2
|
+
|
|
3
|
+
This directory is the **portable workflow kit** (tool-agnostic). Every
|
|
4
|
+
`--tool=` install gets this tree. Host-specific adapters live **outside** it
|
|
5
|
+
(`.cursor/`, `CLAUDE.md` + `.claude/` mirror, `GEMINI.md`, …).
|
|
6
|
+
|
|
7
|
+
**Human entry (repo root):** `AGENTS.md` → indexes this kit.
|
|
8
|
+
|
|
9
|
+
**Rules SoT:** [`istartsoft-flow/METHODOLOGY.md`](./istartsoft-flow/METHODOLOGY.md)
|
|
10
|
+
|
|
11
|
+
## Layout
|
|
12
|
+
|
|
13
|
+
| Path | What |
|
|
14
|
+
|------|------|
|
|
15
|
+
| `agents/` | Fresh-context workers (planner, researcher, implementer, …) |
|
|
16
|
+
| `commands/` | Procedures — Default: `/overview` `/feature` `/quick`; Advanced: `/propose` `/design` `/support` … |
|
|
17
|
+
| `skills/` | On-demand cookbooks (ux-design, security, support-triage, …) |
|
|
18
|
+
| `hooks/` | Lifecycle enforcement scripts |
|
|
19
|
+
| `istartsoft-flow/` | METHODOLOGY.md — every hard rule lives here once |
|
|
20
|
+
| `templates/` | Proposal / UX pack / architecture / CR / FEATURE / automation |
|
|
21
|
+
|
|
22
|
+
## Claude Code only
|
|
23
|
+
|
|
24
|
+
Anthropic’s Claude Code loads commands/agents/skills from **`.claude/`**. When you
|
|
25
|
+
install `--tool=claude` (or `all`), the installer also **mirrors** this kit into
|
|
26
|
+
`.claude/` plus a root `CLAUDE.md` shim (`@AGENTS.md`). Cursor / Codex / Gemini /
|
|
27
|
+
Aider installs do **not** create `.claude/`.
|
|
28
|
+
|
|
29
|
+
Edit the kit in **`.issflow/`**, then re-run `create-issflow --tool=claude` (with
|
|
30
|
+
`--force` if needed) to refresh the Claude mirror. Hooks run from `.issflow/`
|
|
31
|
+
(single source); Claude settings point there.
|
|
32
|
+
|
|
33
|
+
Do **not** duplicate METHODOLOGY rules into other files (anti-drift).
|
|
34
|
+
Do **not** put personal rate cards in this kit.
|
|
35
|
+
|
|
36
|
+
Installer: `npx create-issflow` (omit `--tool` = all adapters).
|
|
@@ -68,7 +68,7 @@ contingency %.
|
|
|
68
68
|
CR-<n> | <date> | <change> | impact: <phases> | effort Δ: <±days> |
|
|
69
69
|
cost Δ: <±amount> | new total: <amount> | status: proposed
|
|
70
70
|
```
|
|
71
|
-
2. Fill `.
|
|
71
|
+
2. Fill `.issflow/templates/CR-template.md` → `docs/changes/CR-<n>.md` (detail:
|
|
72
72
|
classification, impact, Δ cost, warranty vs billable, status). Keep the detail
|
|
73
73
|
file client-safe on money fields (totals only).
|
|
74
74
|
|
|
@@ -25,7 +25,7 @@ Target: `$ARGUMENTS` → `ux` | `arch` | `both` (default **both**).
|
|
|
25
25
|
|
|
26
26
|
## STEP 1 — UX PACK (if ux|both)
|
|
27
27
|
1. Apply `ux-design` skill (authoring mode): wireframe baseline + cookbook direction.
|
|
28
|
-
2. Scaffold or update `docs/UX-PACK.md` from `.
|
|
28
|
+
2. Scaffold or update `docs/UX-PACK.md` from `.issflow/templates/UX-PACK-template.md`.
|
|
29
29
|
3. Fill flows, screen inventory, tokens/frame, a11y notes from OVERVIEW + PLAN.
|
|
30
30
|
4. SHOW me UX-PACK.md. **STOP for approval.**
|
|
31
31
|
5. On approve: stamp `> Approval: approved <date> v<n>`; set `design: approved <date>`
|
|
@@ -35,7 +35,7 @@ Target: `$ARGUMENTS` → `ux` | `arch` | `both` (default **both**).
|
|
|
35
35
|
## STEP 2 — ARCHITECTURE (if arch|both)
|
|
36
36
|
1. Dispatch `researcher` (DESIGN) only if open unknowns remain; else use OVERVIEW.
|
|
37
37
|
2. Scaffold or update `docs/ARCHITECTURE.md` from
|
|
38
|
-
`.
|
|
38
|
+
`.issflow/templates/ARCHITECTURE-template.md`.
|
|
39
39
|
3. Apply `code-standards` architecture guidance; security trust boundaries via
|
|
40
40
|
`security` skill when relevant.
|
|
41
41
|
4. SHOW me ARCHITECTURE.md. **STOP for approval.**
|
|
@@ -14,7 +14,7 @@ Target doc: $ARGUMENTS (default: the single `docs/features/*/FEATURE.md` whose
|
|
|
14
14
|
## ENTRY MODES (before the pipeline)
|
|
15
15
|
|
|
16
16
|
- **`/feature new <name>`** — scaffold only. Copy
|
|
17
|
-
`.
|
|
17
|
+
`.issflow/templates/FEATURE-template.md` to `docs/features/<kebab-name>/FEATURE.md`,
|
|
18
18
|
fill `<feature name>`, then STOP: the human writes the spec and flips
|
|
19
19
|
`> Approval:` to APPROVED. Never auto-approve; never continue into the pipeline.
|
|
20
20
|
- **`/feature from-story <key>`** — planning-stack bridge. If a story MCP is
|
|
@@ -50,7 +50,7 @@ b. APPROVAL GATE (the ONE human gate at entry): the Feature doc must carry a hea
|
|
|
50
50
|
> Automation: <none | push | push+pr>
|
|
51
51
|
```
|
|
52
52
|
Missing/PENDING -> HARD-STOP: a human approves the DOC, not the run (need a doc?
|
|
53
|
-
`/feature new <name>` scaffolds `.
|
|
53
|
+
`/feature new <name>` scaffolds `.issflow/templates/FEATURE-template.md`). Doc approval
|
|
54
54
|
is the rule-13 sign-off *scoped to this doc only* — the mini-plan it produces
|
|
55
55
|
inherits approval as long as it stays inside the doc's stated scope.
|
|
56
56
|
|
|
@@ -90,7 +90,7 @@ change-orders re-price against.
|
|
|
90
90
|
the client PROPOSAL.md / HTML). PROPOSAL.md itself stays client-safe so it can
|
|
91
91
|
be shared.
|
|
92
92
|
|
|
93
|
-
2. RENDER a client-facing `docs/proposal.html` from `.
|
|
93
|
+
2. RENDER a client-facing `docs/proposal.html` from `.issflow/templates/proposal.html`:
|
|
94
94
|
copy it, replace every `{{PLACEHOLDER}}`, and fill the CONTENT in the declared
|
|
95
95
|
language (the section labels are already bilingual TH / EN). It must fit ONE A4
|
|
96
96
|
page — be terse (≈ 3–6 phase rows, ≈ 4 assumptions, short scope items); trim before
|
|
@@ -15,7 +15,7 @@ Security = "is it SAFE?" — a different axis from QA ("does it work?") and UI
|
|
|
15
15
|
("does it look right?"). Passing those never implies this.
|
|
16
16
|
|
|
17
17
|
## PRE-FLIGHT
|
|
18
|
-
Read the rubric: `.
|
|
18
|
+
Read the rubric: `.issflow/skills/security/SKILL.md` (the Secure SDLC cookbook) and
|
|
19
19
|
its `references/` (OWASP Top 10 / ASVS / WSTG / ISO 27001 / SLSA). The cookbook IS the
|
|
20
20
|
checklist — audit against it; don't invent criteria.
|
|
21
21
|
|
|
@@ -11,15 +11,15 @@ Only resolved issues and completed research qualify. Open issues do NOT.
|
|
|
11
11
|
|
|
12
12
|
## PRE-FLIGHT
|
|
13
13
|
|
|
14
|
-
1. Read `.
|
|
15
|
-
- Not found -> STOP. Tell me: "KB not configured. Create `.
|
|
14
|
+
1. Read `.issflow/kb-config.json`.
|
|
15
|
+
- Not found -> STOP. Tell me: "KB not configured. Create `.issflow/kb-config.json`
|
|
16
16
|
with `kb_path` + `kb_remote` pointing at the shared KB repo, then retry /store-wisdom."
|
|
17
17
|
- Found -> extract `kb_path` and `kb_remote`.
|
|
18
18
|
|
|
19
19
|
2. Expand `kb_path` (resolve `~` to home directory).
|
|
20
20
|
Verify the path exists and is a git repo (`git -C <path> status`).
|
|
21
21
|
- Fails -> STOP. Tell me the path is broken and to fix `kb_path` in
|
|
22
|
-
`.
|
|
22
|
+
`.issflow/kb-config.json`.
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
@@ -11,7 +11,7 @@ scores the product, and surfaces drift that accumulated across changes. Run befo
|
|
|
11
11
|
release, after big UI work, or on request.
|
|
12
12
|
|
|
13
13
|
## PRE-FLIGHT
|
|
14
|
-
Read the rubric: `.
|
|
14
|
+
Read the rubric: `.issflow/skills/ux-design/SKILL.md` (the cookbook) and
|
|
15
15
|
`references/wireframe-template.md` (the frame). The cookbook IS the checklist —
|
|
16
16
|
do not invent new criteria; audit against it.
|
|
17
17
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"context": {
|
|
3
|
+
"window": 1000000,
|
|
4
|
+
"warnPct": 60,
|
|
5
|
+
"gatePct": 78,
|
|
6
|
+
"_note": "window = this session's real context window. THIS repo runs Opus 4.8 [1m] but the transcript records model id as 'claude-opus-4-8' (no [1m] tag), so auto-detect (window:0) would wrongly assume 200000 and false-gate around 156k. Set it explicitly here. Kit template default stays 200000 — override per your model. warnPct = soft non-blocking nudge. gatePct = hard PreToolUse block on NEW build work (Edit/Write to SOURCE files). Checkpoint paths (docs/**, STATE/ISSUES/snapshots) and all Bash (git) are never blocked; Task delegation is never gated (a subagent isolates noise and shrinks orchestrator context)."
|
|
7
|
+
},
|
|
8
|
+
"sprint": {
|
|
9
|
+
"defaultCapacity": 8,
|
|
10
|
+
"_note": "Sprint layer (/sprint). defaultCapacity = points committed to the FIRST sprint before any velocity history exists; later sprints size to the rolling completed-velocity average. Optional — /sprint falls back to 8 if this block is absent."
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -27,7 +27,7 @@ process.stdin.on('end', () => {
|
|
|
27
27
|
function run(evt) {
|
|
28
28
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || evt.cwd || '.';
|
|
29
29
|
let ctx;
|
|
30
|
-
try { ctx = require(path.join(projectDir, '.
|
|
30
|
+
try { ctx = require(path.join(projectDir, '.issflow/hooks/lib/ctx.js')); } catch (_) { return silent(); }
|
|
31
31
|
const cfg = ctx.loadConfig(projectDir);
|
|
32
32
|
const warn = cfg.warnPct || 60;
|
|
33
33
|
const gate = cfg.gatePct || 78;
|
|
@@ -89,7 +89,7 @@ function gateReason(u, gate) {
|
|
|
89
89
|
' 2) /synthesize (อัด handoff docs — subagent นี้ไม่ถูก block)',
|
|
90
90
|
' 3) /clear (session ใหม่ บางลง)',
|
|
91
91
|
'build ต่อหลัง clear. กลาง irreversible op? ใช้ Bash ปิดให้จบก่อน clear.',
|
|
92
|
-
'ปลดล็อกชั่วคราว: เพิ่ม gatePct ใน .
|
|
92
|
+
'ปลดล็อกชั่วคราว: เพิ่ม gatePct ใน .issflow/flow-config.json.',
|
|
93
93
|
].join('\n');
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -21,7 +21,7 @@ function inferWindow(model) {
|
|
|
21
21
|
// Read project flow config; returns the `context` block or {}.
|
|
22
22
|
function loadConfig(projectDir) {
|
|
23
23
|
try {
|
|
24
|
-
const cfg = JSON.parse(fs.readFileSync(projectDir + '/.
|
|
24
|
+
const cfg = JSON.parse(fs.readFileSync(projectDir + '/.issflow/flow-config.json', 'utf8'));
|
|
25
25
|
return (cfg && cfg.context) || {};
|
|
26
26
|
} catch (_) { return {}; }
|
|
27
27
|
}
|
|
@@ -50,7 +50,7 @@ function run(evt) {
|
|
|
50
50
|
|
|
51
51
|
// writable while PENDING: planning + docs + kit + repo meta — never product source.
|
|
52
52
|
const ALLOW = [
|
|
53
|
-
/^docs\//, /^\.claude\//, /^\.cursor\//, /^\.github\//, /^\.aider/, /^\.git/,
|
|
53
|
+
/^docs\//, /^\.issflow\//, /^\.claude\//, /^\.cursor\//, /^\.github\//, /^\.aider/, /^\.git/,
|
|
54
54
|
/^(README|AGENTS|CLAUDE|GEMINI|CHANGELOG|LICENSE)[^/]*$/i, /^[^/]+\.md$/,
|
|
55
55
|
];
|
|
56
56
|
if (ALLOW.some((re) => re.test(rel))) return silent();
|
|
@@ -90,7 +90,7 @@ if (idx !== null) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// 3d. shared KB — pull latest + load snapshot
|
|
93
|
-
const KB_CONFIG = '.
|
|
93
|
+
const KB_CONFIG = '.issflow/kb-config.json';
|
|
94
94
|
let kbActive = false;
|
|
95
95
|
if (exists(KB_CONFIG)) {
|
|
96
96
|
let cfg = {}; try { cfg = JSON.parse(read(KB_CONFIG) || '{}'); } catch (_) {}
|
|
@@ -126,7 +126,7 @@ if (exists(KB_CONFIG)) {
|
|
|
126
126
|
kbActive = true;
|
|
127
127
|
} else {
|
|
128
128
|
emit('## Shared KB: configured but path not found (' + (cfg.kb_path || '') + ')');
|
|
129
|
-
emit('Fix kb_path in .
|
|
129
|
+
emit('Fix kb_path in .issflow/kb-config.json (or re-run: npx create-issflow).');
|
|
130
130
|
emit('');
|
|
131
131
|
}
|
|
132
132
|
}
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
# iStartSoftFlow — portable agent methodology (single source of truth)
|
|
2
2
|
|
|
3
|
-
> **The iStartSoft execution loop.**
|
|
4
|
-
>
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
>
|
|
8
|
-
>
|
|
9
|
-
>
|
|
10
|
-
>
|
|
11
|
-
>
|
|
12
|
-
>
|
|
13
|
-
>
|
|
3
|
+
> **The iStartSoft execution loop.** Lives under `.issflow/istartsoft-flow/` as
|
|
4
|
+
> part of the **portable kit** (tool-agnostic SoT). Primary human entry is root
|
|
5
|
+
> **`AGENTS.md`** (open standard). `CLAUDE.md` / `GEMINI.md` / `.cursor/` / … are
|
|
6
|
+
> thin host adapters that point here; they do NOT replace this file. Claude Code
|
|
7
|
+
> also gets a `.claude/` **mirror** of this kit (host discovery only).
|
|
8
|
+
>
|
|
9
|
+
> The kit is **stack-agnostic and tool-agnostic**: it pins a *process*, not a
|
|
10
|
+
> *stack*. Declare your stack (language, framework, infra, auth, test + E2E
|
|
11
|
+
> runner, planning source) once in `docs/OVERVIEW.md`; every rule below
|
|
12
|
+
> references *your declared stack* and hardcodes none. If infra is **managed**
|
|
13
|
+
> (a PaaS + a managed datastore), Phase 0 (infra) is N/A and phases begin at the
|
|
14
|
+
> first vertical slice; otherwise Phase 0 provisions infra first. Planning source
|
|
15
|
+
> of truth stays in your PRD / architecture / stories (e.g. BMAD / iSSM);
|
|
16
|
+
> iStartSoftFlow is the execution loop layered on top.
|
|
14
17
|
|
|
15
18
|
<!-- ISTARTSOFTFLOW-AGENTS-SENTINEL-v2.0 -->
|
|
16
19
|
> **SENTINEL.** The HTML comment above (`ISTARTSOFTFLOW-AGENTS-SENTINEL-v2.0`) is a
|
|
@@ -23,10 +26,11 @@
|
|
|
23
26
|
> open `AGENTS.md` standard, get the full methodology from here.
|
|
24
27
|
|
|
25
28
|
> **Anti-drift invariant (load-bearing).** Every rule lives in exactly ONE place:
|
|
26
|
-
> this file. `CLAUDE.md`
|
|
27
|
-
>
|
|
28
|
-
>
|
|
29
|
-
> architectural defect, not a
|
|
29
|
+
> this file. Host entry files (`AGENTS.md`, `CLAUDE.md`, `GEMINI.md`, …) restate
|
|
30
|
+
> NO rule — they only index this file and wire host-native mechanisms
|
|
31
|
+
> ("mechanism X performs ritual Y automatically"). A rule and its automation may
|
|
32
|
+
> never contradict. Duplication between files is an architectural defect, not a
|
|
33
|
+
> convenience.
|
|
30
34
|
|
|
31
35
|
Caveman ULTRA mode always on. Apply the `karpathy-guidelines` skill (engineering
|
|
32
36
|
discipline) on every coding and debugging task. Apply the `ux-design` skill (the UX
|
|
@@ -166,7 +170,7 @@ documented feature branch out, near-100% hands-off. Humans remain at exactly thr
|
|
|
166
170
|
points: **approve the doc** (entry) · **UAT** (`/uat` against the generated
|
|
167
171
|
TEST-PLAN) · **merge**. Production deploy is never in this lane (`/release` owns it).
|
|
168
172
|
|
|
169
|
-
Pipeline (canonical body in `.
|
|
173
|
+
Pipeline (canonical body in `.issflow/commands/feature.md`):
|
|
170
174
|
spec completion → adversarial doc-review → mini-plan → contract surface probe →
|
|
171
175
|
build loop (the `/phase` machinery, feature-scoped) → review & harden → manual
|
|
172
176
|
test plan → docs + token stamp + summary → memory queue → delivery.
|
|
@@ -177,13 +181,13 @@ Three layers make "hands-off" real — each uses the mechanism suited to its job
|
|
|
177
181
|
through the standard roles under AUTO; the circuit breaker, rules 11/12, and
|
|
178
182
|
blind TDD apply unchanged.
|
|
179
183
|
2. **Must-happen-every-time → a lifecycle hook.** `docs/features/<slug>/GATES.md`
|
|
180
|
-
is the run's gate checklist; the `Stop` hook (`.
|
|
184
|
+
is the run's gate checklist; the `Stop` hook (`.issflow/hooks/feature-gate.js`)
|
|
181
185
|
BLOCKS session end while the feature is `(active)` in STATE with unchecked
|
|
182
186
|
gates — and it verifies ARTIFACTS, not ticks: a checked `test-plan` /
|
|
183
187
|
`mini-plan` / `contract-probe` / `token-stamp` / `summary` / `memory-queued`
|
|
184
188
|
gate whose deliverable is missing on disk blocks too (also re-checked in the
|
|
185
189
|
`(done)` state). A prompt can be ignored; the hook cannot. Rule 13 gets the
|
|
186
|
-
same treatment: the `PreToolUse` plan gate (`.
|
|
190
|
+
same treatment: the `PreToolUse` plan gate (`.issflow/hooks/plan-gate.js`)
|
|
187
191
|
denies source Edit/Write while `docs/PLAN.md` reads `> Approval: PENDING`
|
|
188
192
|
(docs/kit paths stay writable; an active feature lane is exempt — its doc
|
|
189
193
|
approval is its own scoped gate). Hosts without lifecycle hooks run these as
|
|
@@ -191,14 +195,14 @@ Three layers make "hands-off" real — each uses the mechanism suited to its job
|
|
|
191
195
|
3. **No-human-at-the-keyboard → a headless runner.** `ISSFLOW_HEADLESS=1` tells the
|
|
192
196
|
lane no human is present: every hard-stop degrades to a `BLOCKED.md` report +
|
|
193
197
|
clean exit — never a guess. Two shipped runners (`create-issflow --ci|--docker`,
|
|
194
|
-
sources in `.
|
|
198
|
+
sources in `.issflow/templates/automation/`):
|
|
195
199
|
- **GitHub Actions** — label an issue `feature:approved` (or dispatch with a doc
|
|
196
200
|
path); the workflow runs the lane on an ephemeral runner.
|
|
197
201
|
- **Docker** — `node scripts/feature-docker.js <FEATURE.md>` builds
|
|
198
202
|
`Dockerfile.issflow` and runs the lane in an unprivileged container with the
|
|
199
203
|
repo mounted; the container is the sandbox that makes a skip-permissions run
|
|
200
204
|
acceptable. Works for any host that ships a headless CLI. The runner image
|
|
201
|
-
MUST contain Node ≥ 18 — the lifecycle hooks are `node .
|
|
205
|
+
MUST contain Node ≥ 18 — the lifecycle hooks are `node .issflow/hooks/*.js`,
|
|
202
206
|
and without node they die silently (no session context, no feature gate).
|
|
203
207
|
The shipped image is Node-based and the wrapper preflights `node` before
|
|
204
208
|
every run, including bring-your-own images (`ISSFLOW_IMAGE=<name>`).
|
|
@@ -251,7 +255,7 @@ the planning phase when a project needs that rigor, then drive delivery here.
|
|
|
251
255
|
## Roles (fresh-context workers)
|
|
252
256
|
|
|
253
257
|
Each role is a fresh-context worker mapped to a named Claude Code subagent in
|
|
254
|
-
`.
|
|
258
|
+
`.issflow/agents/*.md`. A worker dumps its noise to a file and returns only a
|
|
255
259
|
terse summary + path. Workers cannot address the user — only the orchestrator
|
|
256
260
|
can. Escalation is at most two hops.
|
|
257
261
|
|
|
@@ -279,7 +283,7 @@ can. Escalation is at most two hops.
|
|
|
279
283
|
|
|
280
284
|
The orchestrator ROUTES. It does not implement or debug.
|
|
281
285
|
|
|
282
|
-
**Model routing (per-role tiers).** Each role's `.
|
|
286
|
+
**Model routing (per-role tiers).** Each role's `.issflow/agents/<role>.md` pins a
|
|
283
287
|
`model:` tier suited to its work, so the RIGHT model runs each task by default:
|
|
284
288
|
|
|
285
289
|
| Role | `model:` | Why |
|
|
@@ -297,7 +301,7 @@ support run everything on the session model (graceful degrade).
|
|
|
297
301
|
|
|
298
302
|
## Procedures (the slash-command set)
|
|
299
303
|
|
|
300
|
-
Named procedures, each with a canonical body in `.
|
|
304
|
+
Named procedures, each with a canonical body in `.issflow/commands/<name>.md`.
|
|
301
305
|
|
|
302
306
|
**Lane routing — which entry point for which job:**
|
|
303
307
|
|
|
@@ -329,7 +333,7 @@ surface or need its own acceptance criteria? -> `/feature`. Otherwise `/quick`.
|
|
|
329
333
|
one APPROVED Feature doc → spec completion → adversarial doc-review → mini-plan
|
|
330
334
|
→ contract probe → build loop → review & harden → manual test plan →
|
|
331
335
|
docs/stamps/memory → delivery. `new` scaffolds the doc from
|
|
332
|
-
`.
|
|
336
|
+
`.issflow/templates/FEATURE-template.md`; `from-story` transforms a BMAD/iSSM
|
|
333
337
|
story into a PENDING doc (approval stays human). Gate checklist in
|
|
334
338
|
`docs/features/<slug>/GATES.md`, enforced by the `Stop` hook with artifact
|
|
335
339
|
verification. Headless-capable (CI / Docker, `ISSFLOW_HEADLESS=1`). See "Feature lane".
|
|
@@ -402,7 +406,7 @@ At the start of every session, before any other work, surface:
|
|
|
402
406
|
surface its goal + burndown from `docs/sprints/sprint-<n>.md`.
|
|
403
407
|
3. open items in `docs/ISSUES.md`.
|
|
404
408
|
4. `docs/research/INDEX.md` (research map) + infra/auth status.
|
|
405
|
-
5. shared KB: pull latest + load `docs/.kb-snapshot.md` if `.
|
|
409
|
+
5. shared KB: pull latest + load `docs/.kb-snapshot.md` if `.issflow/kb-config.json`
|
|
406
410
|
exists.
|
|
407
411
|
6. a one-line reminder of the hard rules below.
|
|
408
412
|
|
|
@@ -606,7 +610,7 @@ fail the other.
|
|
|
606
610
|
|
|
607
611
|
## Shared KB (optional)
|
|
608
612
|
|
|
609
|
-
If `.
|
|
613
|
+
If `.issflow/kb-config.json` exists, the SESSION-OPEN ritual pulls the KB and loads
|
|
610
614
|
a snapshot to `docs/.kb-snapshot.md`. The researcher checks the snapshot (step 0)
|
|
611
615
|
before any web search. Run `store-wisdom` to promote resolved issues + research to
|
|
612
616
|
the KB. The kit works normally without a KB.
|
|
@@ -619,10 +623,10 @@ the KB. The kit works normally without a KB.
|
|
|
619
623
|
- `docs/PROPOSAL.md` — scope + phase breakdown + effort/cost totals + assumptions
|
|
620
624
|
+ sign-off. Versioned; client-safe commercial baseline (no rate / contingency %).
|
|
621
625
|
- `docs/proposal.html` — the client-facing proposal, rendered from PROPOSAL.md via
|
|
622
|
-
`.
|
|
626
|
+
`.issflow/templates/proposal.html`, in the project language; print-ready (PDF).
|
|
623
627
|
- `docs/UX-PACK.md` · `docs/ARCHITECTURE.md` — pre-build design/arch frames
|
|
624
|
-
(rule 15); templates under `.
|
|
625
|
-
- `.
|
|
628
|
+
(rule 15); templates under `.issflow/templates/`.
|
|
629
|
+
- `.issflow/templates/` — document templates (proposal.html, UX-PACK, ARCHITECTURE,
|
|
626
630
|
CR, FEATURE, …) the commands render into `docs/`.
|
|
627
631
|
- `docs/CHANGES.md` — change-order log (append-only): each scope change with its
|
|
628
632
|
impact, effort/cost delta, new total, and approval status. The commercial audit trail.
|
|
@@ -640,14 +644,14 @@ the KB. The kit works normally without a KB.
|
|
|
640
644
|
`BLOCKED.md` (headless blocker reports).
|
|
641
645
|
- `docs/WISDOM-QUEUE.md` — auto-appended wisdom candidates from feature runs;
|
|
642
646
|
`/store-wisdom` reads it before pushing to the shared KB (push stays human).
|
|
643
|
-
- `.
|
|
647
|
+
- `.issflow/templates/automation/` — headless-runner sources (GitHub Actions ·
|
|
644
648
|
Dockerfile · docker wrapper), materialized by `create-issflow --ci` /
|
|
645
649
|
`--docker` as `.github/workflows/issflow-feature.yml` +
|
|
646
650
|
`.github/workflows/issflow-goal.yml` (cron-ready, disarmed by default) ·
|
|
647
651
|
`Dockerfile.issflow` · `scripts/feature-docker.js`.
|
|
648
652
|
- `docs/GOALS.md` — the goal layer's state: one `## G<n>` block per goal
|
|
649
653
|
(Done-when · Budget · `Approved:` line · progress ticks). Maintained by `/goal`.
|
|
650
|
-
- `.
|
|
654
|
+
- `.issflow/templates/FEATURE-template.md` — the Feature-doc form `/feature new`
|
|
651
655
|
scaffolds (Approval/Automation headers + spec sections).
|
|
652
656
|
- `docs/STATE.md` — current position. Small. Rewritten, not appended. Includes
|
|
653
657
|
`plan:`, `design:`, `architecture:` gate pointers (approved · PENDING · n/a).
|
|
@@ -681,32 +685,32 @@ the KB. The kit works normally without a KB.
|
|
|
681
685
|
- `tests/phase-<n>/` — phase-local test suites.
|
|
682
686
|
- `tests/regression/` — cross-phase contract tests (the regression corpus). Run by
|
|
683
687
|
`scripts/regression.sh` (default mock; `--real` runs the real corpus).
|
|
684
|
-
- `.
|
|
688
|
+
- `.issflow/skills/ux-design/` — the UX cookbook + wireframe baseline (read on
|
|
685
689
|
demand for any UI work).
|
|
686
|
-
- `.
|
|
690
|
+
- `.issflow/skills/security/` — the Secure SDLC cookbook + threat-modeling /
|
|
687
691
|
secure-coding / pentest / standards references (read on demand for security work).
|
|
688
|
-
- `.
|
|
692
|
+
- `.issflow/skills/code-standards/` — naming-per-language + architecture cookbook
|
|
689
693
|
(read on demand for any coding / scaffolding / structure decision).
|
|
690
|
-
- `.
|
|
694
|
+
- `.issflow/kb-config.json` — shared KB path + remote (optional).
|
|
691
695
|
- `docs/.kb-snapshot.md` — KB INDEX loaded this session (auto-generated, gitignored).
|
|
692
696
|
|
|
693
697
|
-----
|
|
694
698
|
|
|
695
699
|
## Capability matrix (which host gets what)
|
|
696
700
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
the same everywhere — only the *wiring* differs.
|
|
701
|
+
Single-source kit: **`.issflow/` tree** (portable) + **this file** (rules) + root
|
|
702
|
+
**`AGENTS.md`** (open-standard entry). `create-issflow --tool=<host>` (omit =
|
|
703
|
+
all) writes adapters; unsupported features degrade to model-run rituals, never
|
|
704
|
+
silently vanish. Assets are the same everywhere — only the *wiring* differs.
|
|
701
705
|
|
|
702
706
|
| Host | Entry file | Commands | Subagents | Lifecycle hooks | Shared KB |
|
|
703
707
|
|------|-----------|----------|-----------|-----------------|-----------|
|
|
704
|
-
| **Claude Code** (reference) | `CLAUDE.md` (`@AGENTS.md`) + `.claude/` | `.claude/commands/` | native | SessionStart · PreToolUse (context watchdog + rule-13 plan gate) · PreCompact · SubagentStop · Stop (feature gate) | yes |
|
|
705
|
-
| **Codex CLI** | `AGENTS.md` (native) | `.claude/commands/` (read as prompts) | read as reference | model-run | yes |
|
|
706
|
-
| **Cursor** | `.cursor/rules/` + `AGENTS.md` | `.cursor/commands/` | reads `.claude/agents/` | `.cursor/hooks.json` (sessionStart · subagentStop) | yes |
|
|
707
|
-
| **Gemini CLI** | `GEMINI.md` + `AGENTS.md` | `.claude/commands/` (read as prompts) | read as reference | model-run | yes |
|
|
708
|
-
| **Aider** | `.aider.conf.yml` → `AGENTS.md` | read as reference | model-run | model-run | yes |
|
|
709
708
|
| **Any AGENTS.md host** | `AGENTS.md` | read as reference | model-run | model-run | yes |
|
|
709
|
+
| **Codex CLI** | `AGENTS.md` (native) | `.issflow/commands/` (read as prompts) | read as reference | model-run | yes |
|
|
710
|
+
| **Cursor** | `.cursor/rules/` + `AGENTS.md` | `.cursor/commands/` | reads `.issflow/agents/` | `.cursor/hooks.json` (sessionStart · subagentStop) | yes |
|
|
711
|
+
| **Gemini CLI** | `GEMINI.md` + `AGENTS.md` | `.issflow/commands/` (read as prompts) | read as reference | model-run | yes |
|
|
712
|
+
| **Aider** | `.aider.conf.yml` → `AGENTS.md` | read as reference | model-run | model-run | yes |
|
|
713
|
+
| **Claude Code** | `CLAUDE.md` (`@AGENTS.md`) + `.claude/` mirror | `.claude/commands/` (mirror of `.issflow/`) | native | SessionStart · PreToolUse (context watchdog + plan gate) · PreCompact · SubagentStop · Stop — hooks run from `.issflow/` | yes |
|
|
710
714
|
|
|
711
715
|
"model-run" = the host can't automate the ritual, so the model performs it by hand
|
|
712
716
|
(SESSION-OPEN at the top of each session; the COMPRESS snapshot before a reset).
|
|
@@ -18,7 +18,7 @@ RUN apt-get update \
|
|
|
18
18
|
&& rm -rf /var/lib/apt/lists/* \
|
|
19
19
|
&& npm install -g @anthropic-ai/claude-code
|
|
20
20
|
|
|
21
|
-
# sanity: the kit's lifecycle hooks are `node .
|
|
21
|
+
# sanity: the kit's lifecycle hooks are `node .issflow/hooks/*.js` — a runner
|
|
22
22
|
# image WITHOUT node runs claude fine but every hook silently dies (no
|
|
23
23
|
# session-start context, no feature gate). Fail the build, not the run.
|
|
24
24
|
RUN node --version && claude --version
|
|
@@ -34,7 +34,7 @@ const run = (cmd, args, opts = {}) => spawnSync(cmd, args, { stdio: 'inherit', .
|
|
|
34
34
|
if (!doc) die('usage: node scripts/feature-docker.js <path/to/FEATURE.md> [--rebuild] [--worktree]');
|
|
35
35
|
const repo = process.cwd();
|
|
36
36
|
if (!fs.existsSync(path.join(repo, doc))) die(`Feature doc not found: ${doc} (run from the repo root)`);
|
|
37
|
-
if (!fs.existsSync(path.join(repo, '.
|
|
37
|
+
if (!fs.existsSync(path.join(repo, '.issflow', 'commands', 'feature.md'))) die('no .issflow/commands/feature.md here — run from a repo with the kit installed');
|
|
38
38
|
if (!process.env.ANTHROPIC_API_KEY) die('ANTHROPIC_API_KEY is not set');
|
|
39
39
|
|
|
40
40
|
const dockerOk = spawnSync('docker', ['version'], { stdio: 'ignore' });
|
|
@@ -44,7 +44,7 @@ const haveImage = spawnSync('docker', ['image', 'inspect', IMAGE], { stdio: 'ign
|
|
|
44
44
|
if (!haveImage || rebuild) {
|
|
45
45
|
const df = fs.existsSync(path.join(repo, 'Dockerfile.issflow'))
|
|
46
46
|
? 'Dockerfile.issflow'
|
|
47
|
-
: path.join('.
|
|
47
|
+
: path.join('.issflow', 'templates', 'automation', 'Dockerfile');
|
|
48
48
|
console.log(`feature-docker: building ${IMAGE} from ${df} …`);
|
|
49
49
|
if (run('docker', ['build', '-t', IMAGE, '-f', df, '.']).status !== 0) die('image build failed');
|
|
50
50
|
}
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|