create-issflow 1.8.1 → 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 +60 -52
- 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 +30 -31
- package/template/{.claude → .issflow}/templates/automation/Dockerfile +1 -1
- package/template/{.claude → .issflow}/templates/automation/feature-docker.js +2 -2
- package/template/.claude/README.md +0 -33
- /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).',
|
|
@@ -204,23 +210,23 @@ function agentsMd() {
|
|
|
204
210
|
'This repo runs the **iStartSoftFlow** agentic dev workflow.', '',
|
|
205
211
|
'**Primary entry (this file).** The complete, tool-agnostic methodology — loop,',
|
|
206
212
|
'roles, procedures, rituals, hard rules — lives in ONE place. Read before acting:', '',
|
|
207
|
-
'> **`.
|
|
208
|
-
'The portable kit lives in **`.
|
|
209
|
-
'
|
|
210
|
-
'Do not restate METHODOLOGY rules elsewhere (anti-drift).', '',
|
|
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).', '',
|
|
211
217
|
'## The loop', '',
|
|
212
218
|
'design-research → grill ×2 → plan → (propose/design if quoted) → implement →',
|
|
213
219
|
'test → deploy — one VERTICAL SLICE per phase. Phase 0 (infra) only when',
|
|
214
220
|
'infra is self-managed.', '',
|
|
215
|
-
'## Roles — `.
|
|
221
|
+
'## Roles — `.issflow/agents/`', '',
|
|
216
222
|
'planner · researcher · implementer · test-author · debugger · e2e-runner · synthesizer', '',
|
|
217
|
-
'## Procedures — `.
|
|
223
|
+
'## Procedures — `.issflow/commands/` (run as `/name`)', '',
|
|
218
224
|
'**Default:** `/overview` · `/feature` · `/quick`', '',
|
|
219
225
|
'**Advanced:** `/propose` · `/design` · `/support` · `/phase` · `/sprint` · `/goal` ·',
|
|
220
226
|
'`/ui-audit` · `/qa-audit` · `/security-audit` · `/release` · `/uat` ·',
|
|
221
227
|
'`/change-request` · `/replan` · `/synthesize` · `/runbook` · `/store-wisdom` ·',
|
|
222
228
|
'`/log-issue` · `/log-decision` · `/unstuck`', '',
|
|
223
|
-
'## Skills — `.
|
|
229
|
+
'## Skills — `.issflow/skills/` (loaded on demand)', '',
|
|
224
230
|
'caveman · grill-me · karpathy-guidelines · ux-design · security · code-standards ·',
|
|
225
231
|
'support-triage', '',
|
|
226
232
|
'## Autonomy', '',
|
|
@@ -246,10 +252,12 @@ function claudeMd() {
|
|
|
246
252
|
'@AGENTS.md', '',
|
|
247
253
|
'Claude Code auto-loads **this filename only**. The import above is the real',
|
|
248
254
|
'entry (`AGENTS.md` → METHODOLOGY). Do NOT restate rules here.', '',
|
|
249
|
-
'## Host wiring
|
|
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`).',
|
|
250
258
|
'- **SessionStart** injects git state + `docs/STATE.md` + open `docs/ISSUES.md`.',
|
|
251
259
|
'- **PreCompact** + **SubagentStop** rituals run automatically.',
|
|
252
|
-
'-
|
|
260
|
+
'- Edit the kit in `.issflow/`, then re-run `create-issflow --tool=claude` to refresh the mirror.', '',
|
|
253
261
|
].join('\n');
|
|
254
262
|
}
|
|
255
263
|
|
|
@@ -259,7 +267,7 @@ function flowConfig() {
|
|
|
259
267
|
window: 0,
|
|
260
268
|
warnPct: 60,
|
|
261
269
|
gatePct: 78,
|
|
262
|
-
_note: 'Context-budget watchdog (.
|
|
270
|
+
_note: 'Context-budget watchdog (.issflow/hooks/context-guard.js, PreToolUse hook). '
|
|
263
271
|
+ 'window 0 = auto-detect from the model id (200000 for standard models). '
|
|
264
272
|
+ 'Some 1M-context models report their id WITHOUT a [1m] tag, so auto-detect '
|
|
265
273
|
+ 'assumes 200000 and may false-gate around 156k — if you run a 1M model, set '
|
|
@@ -281,7 +289,7 @@ function flowConfig() {
|
|
|
281
289
|
|
|
282
290
|
function main() {
|
|
283
291
|
if (HELP) { printHelp(); return; }
|
|
284
|
-
if (!fs.existsSync(path.join(TPL, '.
|
|
292
|
+
if (!fs.existsSync(path.join(TPL, '.issflow'))) {
|
|
285
293
|
console.error('create-issflow: embedded template/ missing. From source run: npm run build');
|
|
286
294
|
process.exit(1);
|
|
287
295
|
}
|
|
@@ -289,14 +297,14 @@ function main() {
|
|
|
289
297
|
const TOOL = pickTool();
|
|
290
298
|
const targets = TOOL === 'all' ? Object.keys(TOOLS).filter(t => t !== 'all') : [TOOL];
|
|
291
299
|
|
|
292
|
-
// 1. portable kit tree (.
|
|
293
|
-
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'))) {
|
|
294
302
|
const rel = path.relative(TPL, src);
|
|
295
303
|
writeFile(rel, fs.readFileSync(src, 'utf8'));
|
|
296
304
|
}
|
|
297
305
|
|
|
298
306
|
// 1b. integrity: confirm the methodology resolved on disk (load-bearing sentinel).
|
|
299
|
-
const methPath = path.join(CWD, '.
|
|
307
|
+
const methPath = path.join(CWD, '.issflow', 'istartsoft-flow', 'METHODOLOGY.md');
|
|
300
308
|
const SENTINEL = 'ISTARTSOFTFLOW-AGENTS-SENTINEL-v2.0';
|
|
301
309
|
if (!DRY && (!fs.existsSync(methPath) || !fs.readFileSync(methPath, 'utf8').includes(SENTINEL))) {
|
|
302
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).`);
|
|
@@ -309,7 +317,7 @@ function main() {
|
|
|
309
317
|
for (const t of targets) ADAPTERS[t]();
|
|
310
318
|
|
|
311
319
|
// 3b. headless feature lane (opt-in): materialize the automation templates.
|
|
312
|
-
const autoDir = path.join(TPL, '.
|
|
320
|
+
const autoDir = path.join(TPL, '.issflow', 'templates', 'automation');
|
|
313
321
|
if (CI) {
|
|
314
322
|
writeFile(path.join('.github', 'workflows', 'issflow-feature.yml'), fs.readFileSync(path.join(autoDir, 'issflow-feature.yml'), 'utf8'));
|
|
315
323
|
writeFile(path.join('.github', 'workflows', 'issflow-goal.yml'), fs.readFileSync(path.join(autoDir, 'issflow-goal.yml'), 'utf8'));
|
|
@@ -319,13 +327,13 @@ function main() {
|
|
|
319
327
|
writeFile(path.join('scripts', 'feature-docker.js'), fs.readFileSync(path.join(autoDir, 'feature-docker.js'), 'utf8'), { exec: true });
|
|
320
328
|
}
|
|
321
329
|
|
|
322
|
-
// 4. .gitignore: track the workflow dirs if .
|
|
330
|
+
// 4. .gitignore: track the workflow dirs if .issflow/* is ignored
|
|
323
331
|
const gi = path.join(CWD, '.gitignore');
|
|
324
332
|
if (fs.existsSync(gi)) {
|
|
325
333
|
const txt = fs.readFileSync(gi, 'utf8');
|
|
326
|
-
if (/^\.
|
|
327
|
-
const block = '\n# iStartSoftFlow workflow — track as project config\n!.
|
|
328
|
-
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');
|
|
329
337
|
if (!DRY) fs.appendFileSync(gi, block);
|
|
330
338
|
}
|
|
331
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,11 +1,10 @@
|
|
|
1
1
|
# iStartSoftFlow — portable agent methodology (single source of truth)
|
|
2
2
|
|
|
3
|
-
> **The iStartSoft execution loop.** Lives under `.
|
|
4
|
-
> part of the **portable kit
|
|
5
|
-
>
|
|
6
|
-
>
|
|
7
|
-
>
|
|
8
|
-
> here; they do NOT replace this file.
|
|
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).
|
|
9
8
|
>
|
|
10
9
|
> The kit is **stack-agnostic and tool-agnostic**: it pins a *process*, not a
|
|
11
10
|
> *stack*. Declare your stack (language, framework, infra, auth, test + E2E
|
|
@@ -171,7 +170,7 @@ documented feature branch out, near-100% hands-off. Humans remain at exactly thr
|
|
|
171
170
|
points: **approve the doc** (entry) · **UAT** (`/uat` against the generated
|
|
172
171
|
TEST-PLAN) · **merge**. Production deploy is never in this lane (`/release` owns it).
|
|
173
172
|
|
|
174
|
-
Pipeline (canonical body in `.
|
|
173
|
+
Pipeline (canonical body in `.issflow/commands/feature.md`):
|
|
175
174
|
spec completion → adversarial doc-review → mini-plan → contract surface probe →
|
|
176
175
|
build loop (the `/phase` machinery, feature-scoped) → review & harden → manual
|
|
177
176
|
test plan → docs + token stamp + summary → memory queue → delivery.
|
|
@@ -182,13 +181,13 @@ Three layers make "hands-off" real — each uses the mechanism suited to its job
|
|
|
182
181
|
through the standard roles under AUTO; the circuit breaker, rules 11/12, and
|
|
183
182
|
blind TDD apply unchanged.
|
|
184
183
|
2. **Must-happen-every-time → a lifecycle hook.** `docs/features/<slug>/GATES.md`
|
|
185
|
-
is the run's gate checklist; the `Stop` hook (`.
|
|
184
|
+
is the run's gate checklist; the `Stop` hook (`.issflow/hooks/feature-gate.js`)
|
|
186
185
|
BLOCKS session end while the feature is `(active)` in STATE with unchecked
|
|
187
186
|
gates — and it verifies ARTIFACTS, not ticks: a checked `test-plan` /
|
|
188
187
|
`mini-plan` / `contract-probe` / `token-stamp` / `summary` / `memory-queued`
|
|
189
188
|
gate whose deliverable is missing on disk blocks too (also re-checked in the
|
|
190
189
|
`(done)` state). A prompt can be ignored; the hook cannot. Rule 13 gets the
|
|
191
|
-
same treatment: the `PreToolUse` plan gate (`.
|
|
190
|
+
same treatment: the `PreToolUse` plan gate (`.issflow/hooks/plan-gate.js`)
|
|
192
191
|
denies source Edit/Write while `docs/PLAN.md` reads `> Approval: PENDING`
|
|
193
192
|
(docs/kit paths stay writable; an active feature lane is exempt — its doc
|
|
194
193
|
approval is its own scoped gate). Hosts without lifecycle hooks run these as
|
|
@@ -196,14 +195,14 @@ Three layers make "hands-off" real — each uses the mechanism suited to its job
|
|
|
196
195
|
3. **No-human-at-the-keyboard → a headless runner.** `ISSFLOW_HEADLESS=1` tells the
|
|
197
196
|
lane no human is present: every hard-stop degrades to a `BLOCKED.md` report +
|
|
198
197
|
clean exit — never a guess. Two shipped runners (`create-issflow --ci|--docker`,
|
|
199
|
-
sources in `.
|
|
198
|
+
sources in `.issflow/templates/automation/`):
|
|
200
199
|
- **GitHub Actions** — label an issue `feature:approved` (or dispatch with a doc
|
|
201
200
|
path); the workflow runs the lane on an ephemeral runner.
|
|
202
201
|
- **Docker** — `node scripts/feature-docker.js <FEATURE.md>` builds
|
|
203
202
|
`Dockerfile.issflow` and runs the lane in an unprivileged container with the
|
|
204
203
|
repo mounted; the container is the sandbox that makes a skip-permissions run
|
|
205
204
|
acceptable. Works for any host that ships a headless CLI. The runner image
|
|
206
|
-
MUST contain Node ≥ 18 — the lifecycle hooks are `node .
|
|
205
|
+
MUST contain Node ≥ 18 — the lifecycle hooks are `node .issflow/hooks/*.js`,
|
|
207
206
|
and without node they die silently (no session context, no feature gate).
|
|
208
207
|
The shipped image is Node-based and the wrapper preflights `node` before
|
|
209
208
|
every run, including bring-your-own images (`ISSFLOW_IMAGE=<name>`).
|
|
@@ -256,7 +255,7 @@ the planning phase when a project needs that rigor, then drive delivery here.
|
|
|
256
255
|
## Roles (fresh-context workers)
|
|
257
256
|
|
|
258
257
|
Each role is a fresh-context worker mapped to a named Claude Code subagent in
|
|
259
|
-
`.
|
|
258
|
+
`.issflow/agents/*.md`. A worker dumps its noise to a file and returns only a
|
|
260
259
|
terse summary + path. Workers cannot address the user — only the orchestrator
|
|
261
260
|
can. Escalation is at most two hops.
|
|
262
261
|
|
|
@@ -284,7 +283,7 @@ can. Escalation is at most two hops.
|
|
|
284
283
|
|
|
285
284
|
The orchestrator ROUTES. It does not implement or debug.
|
|
286
285
|
|
|
287
|
-
**Model routing (per-role tiers).** Each role's `.
|
|
286
|
+
**Model routing (per-role tiers).** Each role's `.issflow/agents/<role>.md` pins a
|
|
288
287
|
`model:` tier suited to its work, so the RIGHT model runs each task by default:
|
|
289
288
|
|
|
290
289
|
| Role | `model:` | Why |
|
|
@@ -302,7 +301,7 @@ support run everything on the session model (graceful degrade).
|
|
|
302
301
|
|
|
303
302
|
## Procedures (the slash-command set)
|
|
304
303
|
|
|
305
|
-
Named procedures, each with a canonical body in `.
|
|
304
|
+
Named procedures, each with a canonical body in `.issflow/commands/<name>.md`.
|
|
306
305
|
|
|
307
306
|
**Lane routing — which entry point for which job:**
|
|
308
307
|
|
|
@@ -334,7 +333,7 @@ surface or need its own acceptance criteria? -> `/feature`. Otherwise `/quick`.
|
|
|
334
333
|
one APPROVED Feature doc → spec completion → adversarial doc-review → mini-plan
|
|
335
334
|
→ contract probe → build loop → review & harden → manual test plan →
|
|
336
335
|
docs/stamps/memory → delivery. `new` scaffolds the doc from
|
|
337
|
-
`.
|
|
336
|
+
`.issflow/templates/FEATURE-template.md`; `from-story` transforms a BMAD/iSSM
|
|
338
337
|
story into a PENDING doc (approval stays human). Gate checklist in
|
|
339
338
|
`docs/features/<slug>/GATES.md`, enforced by the `Stop` hook with artifact
|
|
340
339
|
verification. Headless-capable (CI / Docker, `ISSFLOW_HEADLESS=1`). See "Feature lane".
|
|
@@ -407,7 +406,7 @@ At the start of every session, before any other work, surface:
|
|
|
407
406
|
surface its goal + burndown from `docs/sprints/sprint-<n>.md`.
|
|
408
407
|
3. open items in `docs/ISSUES.md`.
|
|
409
408
|
4. `docs/research/INDEX.md` (research map) + infra/auth status.
|
|
410
|
-
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`
|
|
411
410
|
exists.
|
|
412
411
|
6. a one-line reminder of the hard rules below.
|
|
413
412
|
|
|
@@ -611,7 +610,7 @@ fail the other.
|
|
|
611
610
|
|
|
612
611
|
## Shared KB (optional)
|
|
613
612
|
|
|
614
|
-
If `.
|
|
613
|
+
If `.issflow/kb-config.json` exists, the SESSION-OPEN ritual pulls the KB and loads
|
|
615
614
|
a snapshot to `docs/.kb-snapshot.md`. The researcher checks the snapshot (step 0)
|
|
616
615
|
before any web search. Run `store-wisdom` to promote resolved issues + research to
|
|
617
616
|
the KB. The kit works normally without a KB.
|
|
@@ -624,10 +623,10 @@ the KB. The kit works normally without a KB.
|
|
|
624
623
|
- `docs/PROPOSAL.md` — scope + phase breakdown + effort/cost totals + assumptions
|
|
625
624
|
+ sign-off. Versioned; client-safe commercial baseline (no rate / contingency %).
|
|
626
625
|
- `docs/proposal.html` — the client-facing proposal, rendered from PROPOSAL.md via
|
|
627
|
-
`.
|
|
626
|
+
`.issflow/templates/proposal.html`, in the project language; print-ready (PDF).
|
|
628
627
|
- `docs/UX-PACK.md` · `docs/ARCHITECTURE.md` — pre-build design/arch frames
|
|
629
|
-
(rule 15); templates under `.
|
|
630
|
-
- `.
|
|
628
|
+
(rule 15); templates under `.issflow/templates/`.
|
|
629
|
+
- `.issflow/templates/` — document templates (proposal.html, UX-PACK, ARCHITECTURE,
|
|
631
630
|
CR, FEATURE, …) the commands render into `docs/`.
|
|
632
631
|
- `docs/CHANGES.md` — change-order log (append-only): each scope change with its
|
|
633
632
|
impact, effort/cost delta, new total, and approval status. The commercial audit trail.
|
|
@@ -645,14 +644,14 @@ the KB. The kit works normally without a KB.
|
|
|
645
644
|
`BLOCKED.md` (headless blocker reports).
|
|
646
645
|
- `docs/WISDOM-QUEUE.md` — auto-appended wisdom candidates from feature runs;
|
|
647
646
|
`/store-wisdom` reads it before pushing to the shared KB (push stays human).
|
|
648
|
-
- `.
|
|
647
|
+
- `.issflow/templates/automation/` — headless-runner sources (GitHub Actions ·
|
|
649
648
|
Dockerfile · docker wrapper), materialized by `create-issflow --ci` /
|
|
650
649
|
`--docker` as `.github/workflows/issflow-feature.yml` +
|
|
651
650
|
`.github/workflows/issflow-goal.yml` (cron-ready, disarmed by default) ·
|
|
652
651
|
`Dockerfile.issflow` · `scripts/feature-docker.js`.
|
|
653
652
|
- `docs/GOALS.md` — the goal layer's state: one `## G<n>` block per goal
|
|
654
653
|
(Done-when · Budget · `Approved:` line · progress ticks). Maintained by `/goal`.
|
|
655
|
-
- `.
|
|
654
|
+
- `.issflow/templates/FEATURE-template.md` — the Feature-doc form `/feature new`
|
|
656
655
|
scaffolds (Approval/Automation headers + spec sections).
|
|
657
656
|
- `docs/STATE.md` — current position. Small. Rewritten, not appended. Includes
|
|
658
657
|
`plan:`, `design:`, `architecture:` gate pointers (approved · PENDING · n/a).
|
|
@@ -686,20 +685,20 @@ the KB. The kit works normally without a KB.
|
|
|
686
685
|
- `tests/phase-<n>/` — phase-local test suites.
|
|
687
686
|
- `tests/regression/` — cross-phase contract tests (the regression corpus). Run by
|
|
688
687
|
`scripts/regression.sh` (default mock; `--real` runs the real corpus).
|
|
689
|
-
- `.
|
|
688
|
+
- `.issflow/skills/ux-design/` — the UX cookbook + wireframe baseline (read on
|
|
690
689
|
demand for any UI work).
|
|
691
|
-
- `.
|
|
690
|
+
- `.issflow/skills/security/` — the Secure SDLC cookbook + threat-modeling /
|
|
692
691
|
secure-coding / pentest / standards references (read on demand for security work).
|
|
693
|
-
- `.
|
|
692
|
+
- `.issflow/skills/code-standards/` — naming-per-language + architecture cookbook
|
|
694
693
|
(read on demand for any coding / scaffolding / structure decision).
|
|
695
|
-
- `.
|
|
694
|
+
- `.issflow/kb-config.json` — shared KB path + remote (optional).
|
|
696
695
|
- `docs/.kb-snapshot.md` — KB INDEX loaded this session (auto-generated, gitignored).
|
|
697
696
|
|
|
698
697
|
-----
|
|
699
698
|
|
|
700
699
|
## Capability matrix (which host gets what)
|
|
701
700
|
|
|
702
|
-
Single-source kit: **`.
|
|
701
|
+
Single-source kit: **`.issflow/` tree** (portable) + **this file** (rules) + root
|
|
703
702
|
**`AGENTS.md`** (open-standard entry). `create-issflow --tool=<host>` (omit =
|
|
704
703
|
all) writes adapters; unsupported features degrade to model-run rituals, never
|
|
705
704
|
silently vanish. Assets are the same everywhere — only the *wiring* differs.
|
|
@@ -707,11 +706,11 @@ silently vanish. Assets are the same everywhere — only the *wiring* differs.
|
|
|
707
706
|
| Host | Entry file | Commands | Subagents | Lifecycle hooks | Shared KB |
|
|
708
707
|
|------|-----------|----------|-----------|-----------------|-----------|
|
|
709
708
|
| **Any AGENTS.md host** | `AGENTS.md` | read as reference | model-run | model-run | yes |
|
|
710
|
-
| **Codex CLI** | `AGENTS.md` (native) | `.
|
|
711
|
-
| **Cursor** | `.cursor/rules/` + `AGENTS.md` | `.cursor/commands/` | reads `.
|
|
712
|
-
| **Gemini CLI** | `GEMINI.md` + `AGENTS.md` | `.
|
|
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 |
|
|
713
712
|
| **Aider** | `.aider.conf.yml` → `AGENTS.md` | read as reference | model-run | model-run | yes |
|
|
714
|
-
| **Claude Code** | `CLAUDE.md` (`@AGENTS.md`) + `.claude/` | `.claude/commands/` | native | SessionStart · PreToolUse (context watchdog + plan gate) · PreCompact · SubagentStop · Stop | 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 |
|
|
715
714
|
|
|
716
715
|
"model-run" = the host can't automate the ritual, so the model performs it by hand
|
|
717
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
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# `.claude/` — portable iStartSoftFlow kit
|
|
2
|
-
|
|
3
|
-
This directory is the **portable workflow kit** installed into every project.
|
|
4
|
-
Content is **tool-agnostic**. The folder name `.claude/` is a **host convention**
|
|
5
|
-
(Claude Code and several other agents load commands/agents/hooks from this path).
|
|
6
|
-
It is **not** “Claude-only product branding.”
|
|
7
|
-
|
|
8
|
-
**Human entry points (repo root):**
|
|
9
|
-
|
|
10
|
-
| File | Role |
|
|
11
|
-
|------|------|
|
|
12
|
-
| `AGENTS.md` | Open-standard primary entry — indexes this kit |
|
|
13
|
-
| `CLAUDE.md` | Thin shim (`@AGENTS.md`) — only because Claude Code auto-loads that filename |
|
|
14
|
-
|
|
15
|
-
**Single source of truth for rules:** [`istartsoft-flow/METHODOLOGY.md`](./istartsoft-flow/METHODOLOGY.md)
|
|
16
|
-
|
|
17
|
-
## Layout
|
|
18
|
-
|
|
19
|
-
| Path | What |
|
|
20
|
-
|------|------|
|
|
21
|
-
| `agents/` | Fresh-context workers (planner, researcher, implementer, …) |
|
|
22
|
-
| `commands/` | Procedures — Default: `/overview` `/feature` `/quick`; Advanced: `/propose` `/design` `/support` … |
|
|
23
|
-
| `skills/` | On-demand cookbooks (ux-design, security, support-triage, …) |
|
|
24
|
-
| `hooks/` | Lifecycle enforcement (context, plan gate, feature gate, …) |
|
|
25
|
-
| `istartsoft-flow/` | METHODOLOGY.md — every hard rule lives here once |
|
|
26
|
-
| `templates/` | Proposal / UX pack / architecture / CR / FEATURE / automation |
|
|
27
|
-
| `settings.json` | Host hook wiring (when using Claude Code adapter) |
|
|
28
|
-
| `flow-config.json` | Context watchdog + sprint knobs (optional overrides) |
|
|
29
|
-
|
|
30
|
-
Do **not** duplicate METHODOLOGY rules into other files (anti-drift).
|
|
31
|
-
Do **not** put personal rate cards or salary numbers in this kit.
|
|
32
|
-
|
|
33
|
-
Installer: `npx create-issflow` (omit `--tool` = all adapters).
|
|
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
|