@relipa/ai-flow-kit 0.1.8 → 0.1.9

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/scripts/init.js CHANGED
@@ -58,9 +58,58 @@ const AI_TOOL_FILES = {
58
58
  'cursor': '.cursorrules',
59
59
  'gemini': 'GEMINI.md',
60
60
  'copilot': '.github/copilot-instructions.md',
61
+ 'codex': 'AGENTS.md',
61
62
  'generic': '.aiflow/docs/AI_INSTRUCTIONS.md',
62
63
  };
63
64
 
65
+ // Instruction-file layout per tool.
66
+ // 'inline' — the full workflow set is embedded in the tool file (default).
67
+ // 'pointer' — the tool file stays small and links to .aiflow/instructions/ instead.
68
+ //
69
+ // Codex is 'pointer' because it caps the combined AGENTS.md chain at
70
+ // project_doc_max_bytes (32 KiB default) and silently drops whatever exceeds it.
71
+ // The assembled workflow set is ~115 KB, so inlining would truncate it mid-gate.
72
+ const AI_TOOL_LAYOUT = {
73
+ 'codex': 'pointer',
74
+ };
75
+
76
+ /** Return 'inline' or 'pointer' for a tool key. */
77
+ function resolveToolLayout(tool) {
78
+ return AI_TOOL_LAYOUT[tool] || 'inline';
79
+ }
80
+
81
+ // Shared workflow templates copied to .aiflow/instructions/ for pointer-layout tools.
82
+ // Keys are the destination basenames; gate workflow resolves per framework.
83
+ const WORKFLOW_INSTRUCTION_FILES = [
84
+ { dest: 'create-spec-workflow.md', src: 'create-spec-workflow.md' },
85
+ { dest: 'create-testcase-workflow.md', src: 'create-testcase-workflow.md' },
86
+ ];
87
+
88
+ /**
89
+ * Write the full gate/spec/testcase workflows to .aiflow/instructions/ so
90
+ * pointer-layout tools (Codex) can read them on demand instead of having them
91
+ * inlined into an instruction file that would be truncated.
92
+ * Returns the list of project-relative paths written.
93
+ */
94
+ async function writeWorkflowInstructions(projectDir, framework) {
95
+ const destDir = path.join(projectDir, '.aiflow', 'instructions');
96
+ await fs.ensureDir(destDir);
97
+
98
+ const files = [
99
+ { dest: 'gate-workflow.md', src: resolveWorkflowFile(framework) },
100
+ ...WORKFLOW_INSTRUCTION_FILES,
101
+ ];
102
+
103
+ const written = [];
104
+ for (const f of files) {
105
+ const src = path.join(PKG_DIR, 'custom', 'templates', 'shared', f.src);
106
+ if (!(await fs.pathExists(src))) continue;
107
+ await fs.copy(src, path.join(destDir, f.dest), { overwrite: true });
108
+ written.push(`.aiflow/instructions/${f.dest}`);
109
+ }
110
+ return written;
111
+ }
112
+
64
113
  /**
65
114
  * Copy only docs/common/ to .aiflow/docs in the project.
66
115
  * Internal aiflow docs (changelog, architecture…) are never copied out.
@@ -366,10 +415,212 @@ async function setupClaudeCommands(projectDir) {
366
415
  }
367
416
  }
368
417
 
418
+ // ── Codex (OpenAI) support ───────────────────────────────────────
419
+ // Codex reads AGENTS.md + .codex/ from the workspace root. The same files serve
420
+ // all three local surfaces — the Codex IDE extension (VS Code), Codex mode in
421
+ // the ChatGPT desktop app, and the `codex` CLI — because they share CODEX_HOME
422
+ // config, skills and MCP setup.
423
+
424
+ const CODEX_MANAGED_HEADER = '# ai-flow-kit managed — regenerate with `ak sync-skills`';
425
+
426
+ // Codex truncates the combined AGENTS.md chain at project_doc_max_bytes.
427
+ // The 32 KiB default is enough for one pointer block, but a multi-framework
428
+ // project appends one block per framework, so raise it.
429
+ const CODEX_PROJECT_DOC_MAX_BYTES = 131072;
430
+
431
+ /** Serialize a JS string as a TOML basic string. */
432
+ function tomlString(value) {
433
+ return JSON.stringify(String(value));
434
+ }
435
+
436
+ /**
437
+ * Render one [mcp_servers.<id>] table from an .mcp.json server entry.
438
+ * Codex uses the same command/args/env shape as .mcp.json, just in TOML.
439
+ */
440
+ function renderCodexMcpServer(id, cfg) {
441
+ const lines = [`[mcp_servers.${id}]`];
442
+ if (cfg.command) lines.push(`command = ${tomlString(cfg.command)}`);
443
+ if (Array.isArray(cfg.args) && cfg.args.length) {
444
+ lines.push(`args = [${cfg.args.map(tomlString).join(', ')}]`);
445
+ }
446
+ const env = cfg.env && Object.keys(cfg.env).length ? cfg.env : null;
447
+ if (env) {
448
+ const pairs = Object.entries(env).map(([k, v]) => `${k} = ${tomlString(v)}`);
449
+ lines.push(`env = { ${pairs.join(', ')} }`);
450
+ }
451
+ return lines.join('\n');
452
+ }
369
453
 
370
- async function generateSkillRegistry(projectDir) {
454
+ /**
455
+ * Write .codex/config.toml — project-scoped Codex config mirroring .mcp.json.
456
+ *
457
+ * The file is fully kit-managed: it is only written when absent or when it still
458
+ * carries our header. A hand-edited config is left alone and the generated
459
+ * version is saved to .aiflow/reference/ for the developer to merge.
460
+ */
461
+ async function setupCodexConfig(projectDir) {
462
+ const configPath = path.join(projectDir, '.codex', 'config.toml');
463
+
464
+ const mcpPath = path.join(projectDir, '.mcp.json');
465
+ let servers = {};
466
+ if (await fs.pathExists(mcpPath)) {
467
+ const mcp = await fs.readJson(mcpPath).catch(() => ({}));
468
+ servers = mcp.mcpServers || {};
469
+ }
470
+
471
+ const sections = [
472
+ CODEX_MANAGED_HEADER,
473
+ '# Project-scoped Codex config. Applies to the Codex IDE extension,',
474
+ '# Codex mode in the ChatGPT desktop app, and the `codex` CLI.',
475
+ '',
476
+ '# AGENTS.md is assembled per framework and can exceed the 32 KiB default.',
477
+ `project_doc_max_bytes = ${CODEX_PROJECT_DOC_MAX_BYTES}`,
478
+ ];
479
+
480
+ const serverIds = Object.keys(servers);
481
+ for (const id of serverIds) {
482
+ sections.push('', renderCodexMcpServer(id, servers[id]));
483
+ }
484
+ const content = sections.join('\n') + '\n';
485
+
486
+ if (await fs.pathExists(configPath)) {
487
+ const existing = await fs.readFile(configPath, 'utf-8');
488
+ if (!existing.includes(CODEX_MANAGED_HEADER)) {
489
+ const refPath = path.join(projectDir, '.aiflow', 'reference', 'codex-config.toml');
490
+ await fs.ensureDir(path.dirname(refPath));
491
+ await fs.writeFile(refPath, content);
492
+ console.log(chalk.yellow(' ⚠ .codex/config.toml exists and is hand-managed — left untouched.'));
493
+ console.log(chalk.gray(' Generated version saved to .aiflow/reference/codex-config.toml — merge manually.'));
494
+ return { written: false, servers: serverIds };
495
+ }
496
+ }
497
+
498
+ await fs.ensureDir(path.dirname(configPath));
499
+ await fs.writeFile(configPath, content);
500
+ const mcpNote = serverIds.length ? ` (MCP: ${serverIds.join(', ')})` : '';
501
+ console.log(chalk.green(`✓ Codex config written → .codex/config.toml${mcpNote}`));
502
+ return { written: true, servers: serverIds };
503
+ }
504
+
505
+ /**
506
+ * Mirror the kit's skills into .codex/skills/ and add the four entry-point
507
+ * skills that wrap the shared workflows.
508
+ *
509
+ * Codex discovers project skills as any directory under .codex/skills containing
510
+ * a SKILL.md with name/description frontmatter — the same layout .claude/skills
511
+ * already uses, so the canonical copy is reused verbatim.
512
+ */
513
+ async function setupCodexSkills(projectDir) {
514
+ const claudeSkills = path.join(projectDir, '.claude', 'skills');
515
+ const codexSkills = path.join(projectDir, '.codex', 'skills');
516
+
517
+ if (!(await fs.pathExists(claudeSkills))) {
518
+ console.log(chalk.yellow(' ! .claude/skills not found — Codex skills not installed.'));
519
+ return;
520
+ }
521
+
522
+ await fs.emptyDir(codexSkills);
523
+ await fs.copy(claudeSkills, codexSkills, { overwrite: true });
524
+ const count = (await fs.readdir(codexSkills)).length;
525
+ console.log(chalk.green(`✓ Mirrored ${count} skills → .codex/skills/`));
526
+
527
+ // Entry-point skills. Small workflows are inlined; the two large ones point at
528
+ // .aiflow/instructions/ so skill metadata scanning stays cheap.
529
+ const entryPoints = [
530
+ {
531
+ name: 'ak-coding',
532
+ description: 'Start or resume the DEV 5-Gate coding workflow for the ticket loaded by `ak use`. Trigger when the developer says start / Gate 1 / analyze ticket, or when a ticket was loaded while this session was already open. Do not trigger for BA spec or QA testcase work.',
533
+ src: 'coding-workflow.md',
534
+ },
535
+ {
536
+ name: 'ak-ask',
537
+ description: 'Answer a question about ai-flow-kit itself — install, roles, folder structure, CLI commands, memory draft/submit, troubleshooting. Trigger on an AKQ:/[AKQ]: prefix or a kit-usage question, even with no ticket loaded. Do not trigger for the developer\'s actual ticket work.',
538
+ src: 'ak-ask-workflow.md',
539
+ },
540
+ {
541
+ name: 'ak-create-spec',
542
+ description: 'BA 4-Gate Spec Creation Workflow — turn a raw requirement (Jira/Backlog/file) into a complete UC Spec: Gate 1 analysis & Q&A, Gate 2 Q&A loop until Confirmed, Gate 3 HTML/CSS prototype, Gate 4 full UC Spec. Trigger for BA spec work, not for coding or testcases.',
543
+ pointer: '.aiflow/instructions/create-spec-workflow.md',
544
+ subSkills: '.codex/skills/ba-skills/',
545
+ },
546
+ {
547
+ name: 'ak-create-testcase',
548
+ description: 'QA 4-Gate TestCase Creation Workflow — turn a requirement or spec (SRS/Backlog/Jira/Spec file) into an execution-ready test case set: Gate 1 requirement & risk analysis, Gate 2 scenarios, Gate 3 detailed cases, Gate 4 review & optimization. Trigger for QA testcase work, not for coding or BA specs.',
549
+ pointer: '.aiflow/instructions/create-testcase-workflow.md',
550
+ subSkills: '.codex/skills/test-skills/',
551
+ },
552
+ ];
553
+
554
+ for (const ep of entryPoints) {
555
+ let body;
556
+ if (ep.pointer) {
557
+ body = [
558
+ `Read \`${ep.pointer}\` **in full**, then follow it exactly, gate by gate.`,
559
+ '',
560
+ 'That file is the authoritative workflow — do not work from a summary of it and',
561
+ 'do not skip, shorten, or merge gates. Sub-skills it references live in',
562
+ `\`${ep.subSkills}\`.`,
563
+ '',
564
+ 'Before starting, read `.aiflow/context/current.json` for ticket context if it exists.',
565
+ ].join('\n');
566
+ } else {
567
+ const src = path.join(PKG_DIR, 'custom', 'templates', 'shared', ep.src);
568
+ if (!(await fs.pathExists(src))) continue;
569
+ body = await fs.readFile(src, 'utf-8');
570
+ }
571
+
572
+ const skillDir = path.join(codexSkills, ep.name);
573
+ await fs.ensureDir(skillDir);
574
+ const content = `---\nname: ${ep.name}\ndescription: ${ep.description}\n---\n\n${body}`;
575
+ await fs.writeFile(path.join(skillDir, 'SKILL.md'), content);
576
+ }
577
+ console.log(chalk.green(`✓ Installed ${entryPoints.length} Codex entry-point skills (${entryPoints.map(e => e.name).join(', ')})`));
578
+ }
579
+
580
+ /**
581
+ * Full Codex setup: skill mirror + project config.
582
+ * Safe to call unconditionally — no-ops when 'codex' is not a selected AI tool.
583
+ */
584
+ async function setupCodex(projectDir, selectedTools) {
585
+ if (!selectedTools || !selectedTools.includes('codex')) return;
586
+ await setupCodexSkills(projectDir);
587
+ await setupCodexConfig(projectDir);
588
+ }
589
+
590
+ /**
591
+ * Build the markdown skill registry table.
592
+ * Skills are always read from .claude/skills (the canonical copy). `skillsRoot`
593
+ * only rewrites the paths written into the table, so Codex can be pointed at its
594
+ * own .codex/skills mirror.
595
+ */
596
+ /**
597
+ * Compact skill list for pointer-layout tools.
598
+ *
599
+ * Codex indexes .codex/skills/ itself — every SKILL.md's name and description are
600
+ * already in its skill index — so restating the full registry table in AGENTS.md
601
+ * would burn ~11 KB of the doc budget on every turn for nothing. Names only, so a
602
+ * workflow's "INVOKE: <skill>" step still resolves to a known path.
603
+ */
604
+ async function generateSkillNameList(projectDir, skillsRoot = '.codex/skills') {
371
605
  const skillsDir = path.join(projectDir, '.claude', 'skills');
372
-
606
+ if (!(await fs.pathExists(skillsDir))) return '';
607
+
608
+ const names = [];
609
+ for (const folder of await fs.readdir(skillsDir)) {
610
+ if (await fs.pathExists(path.join(skillsDir, folder, 'SKILL.md'))) names.push(folder);
611
+ }
612
+ if (!names.length) return '';
613
+
614
+ let out = `## Available skills\n\n`;
615
+ out += `Codex indexes these automatically from \`${skillsRoot}/\`. When a workflow step says `;
616
+ out += `**INVOKE:** \`<name>\`, read \`${skillsRoot}/<name>/SKILL.md\` in full and follow it:\n\n`;
617
+ out += names.sort().map(n => `\`${n}\``).join(' · ') + '\n';
618
+ return out;
619
+ }
620
+
621
+ async function generateSkillRegistry(projectDir, skillsRoot = '.claude/skills') {
622
+ const skillsDir = path.join(projectDir, '.claude', 'skills');
623
+
373
624
  if (!(await fs.pathExists(skillsDir))) return '';
374
625
 
375
626
  let registry = `## AI Skill Registry (Superpowers)\n\n`;
@@ -393,8 +644,8 @@ async function generateSkillRegistry(projectDir) {
393
644
  description = lines[0] ? lines[0].trim() : 'No description available';
394
645
  }
395
646
 
396
- // Path relative to project root
397
- const relPath = path.relative(projectDir, skillFile).replace(/\\/g, '/');
647
+ // Path relative to project root, re-rooted for the target tool
648
+ const relPath = `${skillsRoot}/${folder}/SKILL.md`;
398
649
  registry += `| **${folder}** | ${description} | \`${relPath}\` |\n`;
399
650
  }
400
651
  }
@@ -432,11 +683,51 @@ async function setupFramework(projectDir, framework, multi = false, selectedTool
432
683
  const workflowContent = [gateWorkflowContent, createSpecContent, createTestcaseContent].filter(Boolean).join('\n\n---\n\n');
433
684
 
434
685
  const separator = `\n\n---\n\n`;
435
- const skillRegistry = await generateSkillRegistry(projectDir);
686
+ const skillRegistry = await generateSkillRegistry(projectDir);
687
+ const codexSkillList = await generateSkillNameList(projectDir, '.codex/skills');
436
688
 
437
689
  const markerStart = '<!-- aiflow-kit-start -->';
438
690
  const markerEnd = '<!-- aiflow-kit-end -->';
439
691
 
692
+ // Pointer-layout tools need the workflows on disk instead of inlined.
693
+ const needsPointer = selectedTools.some(t => resolveToolLayout(t) === 'pointer');
694
+ const instructionPaths = needsPointer
695
+ ? await writeWorkflowInstructions(projectDir, framework)
696
+ : [];
697
+
698
+ /**
699
+ * Assemble the marker block for one tool.
700
+ * 'inline' tools get the whole workflow set embedded; 'pointer' tools get a
701
+ * short "installed workflow files" list and read the workflows from disk.
702
+ */
703
+ async function buildToolBlock(tool, blockMarkerStart, blockMarkerEnd) {
704
+ const pointer = resolveToolLayout(tool) === 'pointer';
705
+ let body = '';
706
+
707
+ const toolTemplatePath = path.join(PKG_DIR, 'custom', 'templates', 'tools', `${tool}.md`);
708
+ if (await fs.pathExists(toolTemplatePath)) {
709
+ body += await fs.readFile(toolTemplatePath, 'utf-8') + '\n\n';
710
+ }
711
+
712
+ if (frameworkContent) body += frameworkContent + '\n\n';
713
+
714
+ const registry = pointer ? codexSkillList : skillRegistry;
715
+ if (registry) body += registry + '\n\n';
716
+
717
+ if (pointer) {
718
+ if (instructionPaths.length) {
719
+ body += `## Installed workflow files\n\n`;
720
+ body += `Generated for framework \`${framework}\` by ai-flow-kit v${PKG_VERSION}. `;
721
+ body += `Read the relevant file in full before starting a gate:\n\n`;
722
+ body += instructionPaths.map(p => `- \`${p}\``).join('\n') + '\n\n';
723
+ }
724
+ } else if (workflowContent) {
725
+ body += workflowContent + '\n\n';
726
+ }
727
+
728
+ return `${blockMarkerStart}\n${body.trim()}\n${blockMarkerEnd}`;
729
+ }
730
+
440
731
  const written = [];
441
732
  const skipped = [];
442
733
 
@@ -472,15 +763,7 @@ async function setupFramework(projectDir, framework, multi = false, selectedTool
472
763
  await fs.ensureDir(path.dirname(targetPath));
473
764
 
474
765
  // Build content for this tool
475
- let finalContent = '';
476
- const toolTemplatePath = path.join(PKG_DIR, 'custom', 'templates', 'tools', `${tool}.md`);
477
- if (await fs.pathExists(toolTemplatePath)) {
478
- finalContent += await fs.readFile(toolTemplatePath, 'utf-8') + '\n\n';
479
- }
480
- finalContent += frameworkContent + '\n\n';
481
- if (skillRegistry) finalContent += skillRegistry + '\n\n';
482
- if (workflowContent) finalContent += workflowContent + '\n\n';
483
- finalContent = `${markerStart}\n${finalContent.trim()}\n${markerEnd}`;
766
+ const finalContent = await buildToolBlock(tool, markerStart, markerEnd);
484
767
 
485
768
  // Backup existing file before overwriting
486
769
  if (await fs.pathExists(targetPath)) {
@@ -513,27 +796,13 @@ async function setupFramework(projectDir, framework, multi = false, selectedTool
513
796
 
514
797
  await fs.ensureDir(path.dirname(targetPath));
515
798
 
516
- let finalContent = '';
799
+ // Multi-framework projects get one self-contained, per-framework marker block
800
+ // per tool file so re-running init/update can find-and-replace each framework's
801
+ // block in place instead of blindly appending it again on every run.
802
+ const blockMarkerStart = multi ? `<!-- aiflow-kit-start:${framework} -->` : markerStart;
803
+ const blockMarkerEnd = multi ? `<!-- aiflow-kit-end:${framework} -->` : markerEnd;
517
804
 
518
- const toolTemplatePath = path.join(PKG_DIR, 'custom', 'templates', 'tools', `${tool}.md`);
519
- if (await fs.pathExists(toolTemplatePath)) {
520
- finalContent += await fs.readFile(toolTemplatePath, 'utf-8') + '\n\n';
521
- }
522
-
523
- // Include framework conventions for single-framework projects
524
- if (!multi && frameworkContent) {
525
- finalContent += frameworkContent + '\n\n';
526
- }
527
-
528
- if (skillRegistry) {
529
- finalContent += skillRegistry + '\n\n';
530
- }
531
-
532
- if (workflowContent) {
533
- finalContent += workflowContent + '\n\n';
534
- }
535
-
536
- finalContent = `${markerStart}\n${finalContent.trim()}\n${markerEnd}`;
805
+ const finalContent = await buildToolBlock(tool, blockMarkerStart, blockMarkerEnd);
537
806
 
538
807
  const fileExists = await fs.pathExists(targetPath);
539
808
 
@@ -593,7 +862,15 @@ async function setupFramework(projectDir, framework, multi = false, selectedTool
593
862
  }
594
863
  } else {
595
864
  if (fileExists) {
596
- await fs.appendFile(targetPath, separator + frameworkContent);
865
+ const existingContent = await fs.readFile(targetPath, 'utf-8');
866
+ const hasBlock = existingContent.includes(blockMarkerStart) && existingContent.includes(blockMarkerEnd);
867
+ if (hasBlock) {
868
+ const regex = new RegExp(`${blockMarkerStart}[\\s\\S]*?${blockMarkerEnd}`, 'g');
869
+ const updatedContent = existingContent.replace(regex, finalContent);
870
+ await fs.writeFile(targetPath, updatedContent);
871
+ } else {
872
+ await fs.appendFile(targetPath, separator + finalContent);
873
+ }
597
874
  } else {
598
875
  await fs.writeFile(targetPath, finalContent);
599
876
  }
@@ -802,6 +1079,8 @@ async function ensureAiflowGitignored(projectDir) {
802
1079
  '.mcp.json',
803
1080
  'CLAUDE.md',
804
1081
  'GEMINI.md',
1082
+ 'AGENTS.md',
1083
+ '.codex/',
805
1084
  '.cursorrules',
806
1085
  '.github/copilot-instructions.md'
807
1086
  ];
@@ -1185,6 +1464,11 @@ async function init(options) {
1185
1464
  // ── Optional: GitNexus code intelligence ─────────────────────
1186
1465
  await maybeSetupGitNexus(projectDir, options.withGitnexus || false, options.wait || false);
1187
1466
 
1467
+ // ── Codex assets ─────────────────────────────────────────────
1468
+ // After adapters + GitNexus: .codex/config.toml mirrors .mcp.json, so it
1469
+ // has to be written once every MCP server is registered.
1470
+ await setupCodex(projectDir, selectedTools);
1471
+
1188
1472
  // ── Ensure all aiflow files are gitignored ───────────────────
1189
1473
  await ensureAiflowGitignored(projectDir);
1190
1474
 
@@ -1201,6 +1485,9 @@ async function init(options) {
1201
1485
 
1202
1486
  console.log(` ${chalk.green('claude')} ${chalk.gray('← Claude Code CLI (recommended)')}`);
1203
1487
  console.log(` ${chalk.green('Cursor / Gemini')} ${chalk.gray('← Instructions in .cursorrules / GEMINI.md')}`);
1488
+ if (selectedTools.includes('codex')) {
1489
+ console.log(` ${chalk.green('Codex')} ${chalk.gray('← AGENTS.md + .codex/ (VS Code extension, ChatGPT desktop app, codex CLI)')}`);
1490
+ }
1204
1491
  console.log(chalk.blue('─'.repeat(62)));
1205
1492
  console.log(chalk.gray(` Full guide: ${chalk.green('aiflow guide')} | Commands: ${chalk.green('aiflow guide --commands')}`));
1206
1493
  console.log(chalk.blue('─'.repeat(62)) + '\n');
@@ -1211,6 +1498,15 @@ async function init(options) {
1211
1498
 
1212
1499
  module.exports = init;
1213
1500
  module.exports.AI_TOOL_FILES = AI_TOOL_FILES;
1501
+ module.exports.AI_TOOL_LAYOUT = AI_TOOL_LAYOUT;
1502
+ module.exports.resolveToolLayout = resolveToolLayout;
1503
+ module.exports.writeWorkflowInstructions = writeWorkflowInstructions;
1504
+ module.exports.setupCodex = setupCodex;
1505
+ module.exports.setupCodexSkills = setupCodexSkills;
1506
+ module.exports.setupCodexConfig = setupCodexConfig;
1507
+ module.exports.renderCodexMcpServer = renderCodexMcpServer;
1508
+ module.exports.generateSkillNameList = generateSkillNameList;
1509
+ module.exports.CODEX_PROJECT_DOC_MAX_BYTES = CODEX_PROJECT_DOC_MAX_BYTES;
1214
1510
  module.exports.detectRtk = detectRtk;
1215
1511
  module.exports.isRtkHookConfigured = isRtkHookConfigured;
1216
1512
  module.exports.isGitNexusConfigured = isGitNexusConfigured;
package/scripts/prompt.js CHANGED
@@ -51,8 +51,7 @@ Only runs after Gate 2 APPROVED.
51
51
  **INVOKE:** \`review-plan\` skill
52
52
  1. \`superpowers:verification-before-completion\` — all tests PASS (including old tests)
53
53
  2. \`impact-analysis\` skill — fix doesn't cause new bugs elsewhere
54
- 3. Tick \`custom/rules/review-checklist.md\`
55
- 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
54
+ 3. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
56
55
  - Display: "GATE 4: type APPROVED or BUG: [description]"
57
56
  - Coding bug → fix → repeat Gate 4
58
57
  - Requirement bug → back to Gate 1
@@ -103,8 +102,7 @@ Only runs after Gate 2 APPROVED.
103
102
  **INVOKE:** \`review-plan\` skill
104
103
  1. \`superpowers:verification-before-completion\` — all tests PASS
105
104
  2. \`impact-analysis\` skill — no regressions
106
- 3. Tick \`custom/rules/review-checklist.md\`
107
- 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
105
+ 3. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
108
106
  - Display: "GATE 4: type APPROVED or BUG: [description]"
109
107
  - Coding bug → fix → repeat Gate 4
110
108
  - Requirement bug → back to Gate 1
@@ -181,8 +179,7 @@ Only runs after Gate 2 APPROVED.
181
179
  **INVOKE:** \`review-plan\` skill
182
180
  1. \`superpowers:verification-before-completion\` — all tests PASS
183
181
  2. \`impact-analysis\` skill — verify no regressions
184
- 3. Tick \`custom/rules/review-checklist.md\`
185
- 4. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
182
+ 3. Create \`AK-Docs/04.Coding/04.Reviews/[functionId]/[ticketId].md\`
186
183
  - Display: "GATE 4: type APPROVED or BUG: [description]"
187
184
 
188
185
  ### GATE 5 — Peer Review & Done