planflow-ai 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/.claude/commands/create-contract.md +468 -0
  2. package/.claude/commands/create-plan.md +512 -0
  3. package/.claude/commands/discovery-plan.md +561 -0
  4. package/.claude/commands/execute-plan.md +682 -0
  5. package/.claude/commands/review-code.md +459 -0
  6. package/.claude/commands/review-pr.md +651 -0
  7. package/.claude/commands/setup.md +1609 -0
  8. package/.claude/commands/write-tests.md +543 -0
  9. package/.claude/rules/core/allowed-patterns.md +175 -0
  10. package/.claude/rules/core/complexity-scoring.md +225 -0
  11. package/.claude/rules/core/forbidden-patterns.md +253 -0
  12. package/.claude/rules/core/project-ledger.md +150 -0
  13. package/.claude/rules/languages/python-patterns.md +6 -0
  14. package/.claude/rules/languages/typescript-patterns.md +7 -0
  15. package/.claude/rules/patterns/contract-patterns.md +332 -0
  16. package/.claude/rules/patterns/discovery-patterns.md +342 -0
  17. package/.claude/rules/patterns/discovery-templates.md +319 -0
  18. package/.claude/rules/patterns/jest-patterns.md +482 -0
  19. package/.claude/rules/patterns/plans-patterns.md +225 -0
  20. package/.claude/rules/patterns/plans-templates.md +227 -0
  21. package/.claude/rules/patterns/pytest-patterns.md +457 -0
  22. package/.claude/rules/patterns/review-code-templates.md +305 -0
  23. package/.claude/rules/patterns/review-pr-patterns.md +360 -0
  24. package/.claude/rules/tools/auth-pr-tool.md +30 -0
  25. package/.claude/rules/tools/interactive-questions-tool.md +235 -0
  26. package/.claude/rules/tools/jest-testing-tool.md +73 -0
  27. package/.claude/rules/tools/plan-mode-tool.md +164 -0
  28. package/.claude/rules/tools/pytest-testing-tool.md +121 -0
  29. package/.claude/rules/tools/reference-expansion-tool.md +326 -0
  30. package/LICENSE +21 -0
  31. package/README.md +167 -0
  32. package/dist/cli/commands/init.d.ts +6 -0
  33. package/dist/cli/commands/init.d.ts.map +1 -0
  34. package/dist/cli/commands/init.js +141 -0
  35. package/dist/cli/commands/init.js.map +1 -0
  36. package/dist/cli/handlers/claude.d.ts +9 -0
  37. package/dist/cli/handlers/claude.d.ts.map +1 -0
  38. package/dist/cli/handlers/claude.js +119 -0
  39. package/dist/cli/handlers/claude.js.map +1 -0
  40. package/dist/cli/handlers/codex.d.ts +9 -0
  41. package/dist/cli/handlers/codex.d.ts.map +1 -0
  42. package/dist/cli/handlers/codex.js +100 -0
  43. package/dist/cli/handlers/codex.js.map +1 -0
  44. package/dist/cli/handlers/cursor.d.ts +9 -0
  45. package/dist/cli/handlers/cursor.d.ts.map +1 -0
  46. package/dist/cli/handlers/cursor.js +60 -0
  47. package/dist/cli/handlers/cursor.js.map +1 -0
  48. package/dist/cli/handlers/openclaw.d.ts +8 -0
  49. package/dist/cli/handlers/openclaw.d.ts.map +1 -0
  50. package/dist/cli/handlers/openclaw.js +34 -0
  51. package/dist/cli/handlers/openclaw.js.map +1 -0
  52. package/dist/cli/handlers/shared.d.ts +9 -0
  53. package/dist/cli/handlers/shared.d.ts.map +1 -0
  54. package/dist/cli/handlers/shared.js +126 -0
  55. package/dist/cli/handlers/shared.js.map +1 -0
  56. package/dist/cli/index.d.ts +8 -0
  57. package/dist/cli/index.d.ts.map +1 -0
  58. package/dist/cli/index.js +43 -0
  59. package/dist/cli/index.js.map +1 -0
  60. package/dist/cli/types.d.ts +26 -0
  61. package/dist/cli/types.d.ts.map +1 -0
  62. package/dist/cli/types.js +5 -0
  63. package/dist/cli/types.js.map +1 -0
  64. package/dist/cli/utils/files.d.ts +37 -0
  65. package/dist/cli/utils/files.d.ts.map +1 -0
  66. package/dist/cli/utils/files.js +115 -0
  67. package/dist/cli/utils/files.js.map +1 -0
  68. package/dist/cli/utils/logger.d.ts +11 -0
  69. package/dist/cli/utils/logger.d.ts.map +1 -0
  70. package/dist/cli/utils/logger.js +34 -0
  71. package/dist/cli/utils/logger.js.map +1 -0
  72. package/dist/cli/utils/prompts.d.ts +10 -0
  73. package/dist/cli/utils/prompts.d.ts.map +1 -0
  74. package/dist/cli/utils/prompts.js +65 -0
  75. package/dist/cli/utils/prompts.js.map +1 -0
  76. package/dist/test/setup.d.ts +5 -0
  77. package/dist/test/setup.d.ts.map +1 -0
  78. package/dist/test/setup.js +7 -0
  79. package/dist/test/setup.js.map +1 -0
  80. package/package.json +63 -0
  81. package/rules/core/_index.mdc +99 -0
  82. package/rules/core/allowed-patterns.mdc +185 -0
  83. package/rules/core/complexity-scoring.mdc +235 -0
  84. package/rules/core/forbidden-patterns.mdc +263 -0
  85. package/rules/core/project-ledger.mdc +155 -0
  86. package/rules/languages/_index.mdc +80 -0
  87. package/rules/languages/python-patterns.mdc +188 -0
  88. package/rules/languages/typescript-patterns.mdc +128 -0
  89. package/rules/patterns/_index.mdc +185 -0
  90. package/rules/patterns/contract-patterns.mdc +344 -0
  91. package/rules/patterns/discovery-patterns.mdc +354 -0
  92. package/rules/patterns/discovery-templates.mdc +329 -0
  93. package/rules/patterns/jest-patterns.mdc +492 -0
  94. package/rules/patterns/plans-patterns.mdc +237 -0
  95. package/rules/patterns/plans-templates.mdc +237 -0
  96. package/rules/patterns/pytest-patterns.mdc +467 -0
  97. package/rules/patterns/review-code-templates.mdc +315 -0
  98. package/rules/patterns/review-pr-patterns.mdc +370 -0
  99. package/rules/skills/_index.mdc +174 -0
  100. package/rules/skills/create-contract-skill.mdc +239 -0
  101. package/rules/skills/create-plan-skill.mdc +271 -0
  102. package/rules/skills/discovery-skill.mdc +295 -0
  103. package/rules/skills/execute-plan-skill.mdc +388 -0
  104. package/rules/skills/review-code-skill.mdc +308 -0
  105. package/rules/skills/review-pr-skill.mdc +496 -0
  106. package/rules/skills/setup-skill.mdc +923 -0
  107. package/rules/skills/write-tests-skill.mdc +294 -0
  108. package/rules/templates/index-template.mdc +126 -0
  109. package/rules/tools/_index.mdc +114 -0
  110. package/rules/tools/auth-pr-tool.mdc +362 -0
  111. package/rules/tools/interactive-questions-tool.mdc +337 -0
  112. package/rules/tools/jest-testing-tool.mdc +96 -0
  113. package/rules/tools/plan-mode-tool.mdc +229 -0
  114. package/rules/tools/pytest-testing-tool.mdc +144 -0
  115. package/rules/tools/reference-expansion-tool.mdc +338 -0
  116. package/skills/plan-flow/SKILL.md +116 -0
  117. package/skills/plan-flow/create-contract/SKILL.md +139 -0
  118. package/skills/plan-flow/create-plan/SKILL.md +93 -0
  119. package/skills/plan-flow/discovery/SKILL.md +85 -0
  120. package/skills/plan-flow/execute-plan/SKILL.md +89 -0
  121. package/skills/plan-flow/ledger/SKILL.md +70 -0
  122. package/skills/plan-flow/review-code/SKILL.md +100 -0
  123. package/skills/plan-flow/review-pr/SKILL.md +122 -0
  124. package/skills/plan-flow/setup/SKILL.md +73 -0
  125. package/skills/plan-flow/write-tests/SKILL.md +115 -0
  126. package/templates/shared/AGENTS.md.template +65 -0
  127. package/templates/shared/CLAUDE.md.template +67 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * File operation utilities for the init command
3
+ */
4
+ import type { CopyOptions, CopyResult } from '../types.js';
5
+ /**
6
+ * Resolves the package root directory by finding the nearest package.json
7
+ * with name "plan-flow" starting from a known internal path.
8
+ *
9
+ * Works with:
10
+ * - Local development (src/cli/utils/)
11
+ * - Built output (dist/cli/utils/)
12
+ * - npx / global install (node_modules/plan-flow/dist/cli/utils/)
13
+ * - Jest/CJS (__dirname available)
14
+ */
15
+ export declare function getPackageRoot(): string;
16
+ /**
17
+ * Recursively copies a directory, preserving structure.
18
+ * Returns a CopyResult with created, skipped, and updated files.
19
+ */
20
+ export declare function copyDir(src: string, dest: string, options: CopyOptions): CopyResult;
21
+ /**
22
+ * Copies a single file with skip/overwrite logic.
23
+ */
24
+ export declare function copyFile(src: string, dest: string, options: CopyOptions): CopyResult;
25
+ /**
26
+ * Creates a directory recursively if it doesn't exist.
27
+ */
28
+ export declare function ensureDir(dir: string): void;
29
+ /**
30
+ * Checks if a file or directory exists.
31
+ */
32
+ export declare function fileExists(filePath: string): boolean;
33
+ /**
34
+ * Formats a file path relative to a base for display.
35
+ */
36
+ export declare function relativePath(filePath: string, base: string): string;
37
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/files.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM3D;;;;;;;;;GASG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAsBvC;AAED;;;GAGG;AACH,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,UAAU,CA8BZ;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,GACnB,UAAU,CAkBZ;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAI3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * File operation utilities for the init command
3
+ */
4
+ import { existsSync, mkdirSync, copyFileSync, readdirSync, readFileSync, statSync, } from 'node:fs';
5
+ import { join, dirname, relative, resolve } from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+ // ESM equivalent of __dirname
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ /**
11
+ * Resolves the package root directory by finding the nearest package.json
12
+ * with name "plan-flow" starting from a known internal path.
13
+ *
14
+ * Works with:
15
+ * - Local development (src/cli/utils/)
16
+ * - Built output (dist/cli/utils/)
17
+ * - npx / global install (node_modules/plan-flow/dist/cli/utils/)
18
+ * - Jest/CJS (__dirname available)
19
+ */
20
+ export function getPackageRoot() {
21
+ // Start from this file's directory and walk up to find package root
22
+ let dir = __dirname;
23
+ for (let i = 0; i < 10; i++) {
24
+ const pkgPath = join(dir, 'package.json');
25
+ if (existsSync(pkgPath)) {
26
+ try {
27
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
28
+ if (pkg.name === 'planflow-ai') {
29
+ return dir;
30
+ }
31
+ }
32
+ catch {
33
+ // Not valid JSON, continue walking up
34
+ }
35
+ }
36
+ const parent = dirname(dir);
37
+ if (parent === dir)
38
+ break; // reached filesystem root
39
+ dir = parent;
40
+ }
41
+ // If we can't find it, fall back to 3 levels up from __dirname
42
+ return resolve(__dirname, '..', '..', '..');
43
+ }
44
+ /**
45
+ * Recursively copies a directory, preserving structure.
46
+ * Returns a CopyResult with created, skipped, and updated files.
47
+ */
48
+ export function copyDir(src, dest, options) {
49
+ const result = { created: [], skipped: [], updated: [] };
50
+ if (!existsSync(src)) {
51
+ return result;
52
+ }
53
+ ensureDir(dest);
54
+ const entries = readdirSync(src);
55
+ for (const entry of entries) {
56
+ const srcPath = join(src, entry);
57
+ const destPath = join(dest, entry);
58
+ const stat = statSync(srcPath);
59
+ if (stat.isDirectory()) {
60
+ const subResult = copyDir(srcPath, destPath, options);
61
+ result.created.push(...subResult.created);
62
+ result.skipped.push(...subResult.skipped);
63
+ result.updated.push(...subResult.updated);
64
+ }
65
+ else {
66
+ const fileResult = copyFile(srcPath, destPath, options);
67
+ result.created.push(...fileResult.created);
68
+ result.skipped.push(...fileResult.skipped);
69
+ result.updated.push(...fileResult.updated);
70
+ }
71
+ }
72
+ return result;
73
+ }
74
+ /**
75
+ * Copies a single file with skip/overwrite logic.
76
+ */
77
+ export function copyFile(src, dest, options) {
78
+ const result = { created: [], skipped: [], updated: [] };
79
+ ensureDir(dirname(dest));
80
+ if (existsSync(dest)) {
81
+ if (options.force) {
82
+ copyFileSync(src, dest);
83
+ result.updated.push(dest);
84
+ }
85
+ else {
86
+ result.skipped.push(dest);
87
+ }
88
+ }
89
+ else {
90
+ copyFileSync(src, dest);
91
+ result.created.push(dest);
92
+ }
93
+ return result;
94
+ }
95
+ /**
96
+ * Creates a directory recursively if it doesn't exist.
97
+ */
98
+ export function ensureDir(dir) {
99
+ if (!existsSync(dir)) {
100
+ mkdirSync(dir, { recursive: true });
101
+ }
102
+ }
103
+ /**
104
+ * Checks if a file or directory exists.
105
+ */
106
+ export function fileExists(filePath) {
107
+ return existsSync(filePath);
108
+ }
109
+ /**
110
+ * Formats a file path relative to a base for display.
111
+ */
112
+ export function relativePath(filePath, base) {
113
+ return relative(base, filePath);
114
+ }
115
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/cli/utils/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Console output with ANSI colors (no external dependencies)
3
+ */
4
+ export declare function success(msg: string): void;
5
+ export declare function warn(msg: string): void;
6
+ export declare function info(msg: string): void;
7
+ export declare function error(msg: string): void;
8
+ export declare function skip(msg: string): void;
9
+ export declare function header(msg: string): void;
10
+ export declare function blank(): void;
11
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEzC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEvC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEtC;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAExC;AAED,wBAAgB,KAAK,IAAI,IAAI,CAE5B"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Console output with ANSI colors (no external dependencies)
3
+ */
4
+ const colors = {
5
+ green: '\x1b[32m',
6
+ yellow: '\x1b[33m',
7
+ blue: '\x1b[34m',
8
+ red: '\x1b[31m',
9
+ gray: '\x1b[90m',
10
+ bold: '\x1b[1m',
11
+ reset: '\x1b[0m',
12
+ };
13
+ export function success(msg) {
14
+ console.log(`${colors.green} +${colors.reset} ${msg}`);
15
+ }
16
+ export function warn(msg) {
17
+ console.log(`${colors.yellow} ~${colors.reset} ${msg}`);
18
+ }
19
+ export function info(msg) {
20
+ console.log(`${colors.blue} i${colors.reset} ${msg}`);
21
+ }
22
+ export function error(msg) {
23
+ console.log(`${colors.red} x${colors.reset} ${msg}`);
24
+ }
25
+ export function skip(msg) {
26
+ console.log(`${colors.gray} -${colors.reset} ${msg}`);
27
+ }
28
+ export function header(msg) {
29
+ console.log(`\n${colors.bold}${msg}${colors.reset}`);
30
+ }
31
+ export function blank() {
32
+ console.log('');
33
+ }
34
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/cli/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,GAAG;IACb,KAAK,EAAE,UAAU;IACjB,MAAM,EAAE,UAAU;IAClB,IAAI,EAAE,UAAU;IAChB,GAAG,EAAE,UAAU;IACf,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,MAAM,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,GAAW;IAChC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,KAAK;IACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Interactive prompts using Node.js readline/promises
3
+ */
4
+ import type { Platform } from '../types.js';
5
+ /**
6
+ * Asks the user which platforms to install for.
7
+ * Returns selected platform names.
8
+ */
9
+ export declare function selectPlatforms(): Promise<Platform[]>;
10
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CA6D3D"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Interactive prompts using Node.js readline/promises
3
+ */
4
+ import { createInterface } from 'node:readline/promises';
5
+ import { stdin, stdout } from 'node:process';
6
+ /**
7
+ * Asks the user which platforms to install for.
8
+ * Returns selected platform names.
9
+ */
10
+ export async function selectPlatforms() {
11
+ const rl = createInterface({ input: stdin, output: stdout });
12
+ try {
13
+ console.log('\nWhich platform(s) would you like to install for?\n');
14
+ console.log(' 1. Claude Code (.claude/commands/ + .claude/rules/)');
15
+ console.log(' 2. Cursor (.cursor/commands/ + .cursor/rules/)');
16
+ console.log(' 3. OpenClaw (skills/plan-flow/)');
17
+ console.log(' 4. Codex CLI (.agents/skills/plan-flow/ + AGENTS.md)');
18
+ console.log(' 5. All of the above');
19
+ console.log('');
20
+ const answer = await rl.question('Enter your choice (1-5, comma-separated): ');
21
+ const choices = answer
22
+ .split(',')
23
+ .map((s) => s.trim())
24
+ .filter(Boolean);
25
+ const platforms = [];
26
+ for (const choice of choices) {
27
+ switch (choice) {
28
+ case '1':
29
+ if (!platforms.includes('claude'))
30
+ platforms.push('claude');
31
+ break;
32
+ case '2':
33
+ if (!platforms.includes('cursor'))
34
+ platforms.push('cursor');
35
+ break;
36
+ case '3':
37
+ if (!platforms.includes('openclaw'))
38
+ platforms.push('openclaw');
39
+ break;
40
+ case '4':
41
+ if (!platforms.includes('codex'))
42
+ platforms.push('codex');
43
+ break;
44
+ case '5':
45
+ return ['claude', 'cursor', 'openclaw', 'codex'];
46
+ default:
47
+ // Try matching platform names directly
48
+ if (['claude', 'cursor', 'openclaw', 'codex'].includes(choice.toLowerCase())) {
49
+ const p = choice.toLowerCase();
50
+ if (!platforms.includes(p))
51
+ platforms.push(p);
52
+ }
53
+ }
54
+ }
55
+ if (platforms.length === 0) {
56
+ console.log('\nNo valid platforms selected. Use --claude, --cursor, --openclaw, or --all flags.');
57
+ process.exit(1);
58
+ }
59
+ return platforms;
60
+ }
61
+ finally {
62
+ rl.close();
63
+ }
64
+ }
65
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/cli/utils/prompts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG7C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAE7D,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC,CAAC;QAE/E,MAAM,OAAO,GAAG,MAAM;aACnB,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QAEnB,MAAM,SAAS,GAAe,EAAE,CAAC;QAEjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,GAAG;oBACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC5D,MAAM;gBACR,KAAK,GAAG;oBACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAAE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC5D,MAAM;gBACR,KAAK,GAAG;oBACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;wBAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAChE,MAAM;gBACR,KAAK,GAAG;oBACN,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;wBAAE,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC1D,MAAM;gBACR,KAAK,GAAG;oBACN,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;gBACnD;oBACE,uCAAuC;oBACvC,IACE,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAChD,MAAM,CAAC,WAAW,EAAc,CACjC,EACD,CAAC;wBACD,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAc,CAAC;wBAC3C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;4BAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChD,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACT,oFAAoF,CACrF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Jest test setup
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Jest test setup
3
+ */
4
+ // Increase timeout for CI environments
5
+ jest.setTimeout(10000);
6
+ export {};
7
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/test/setup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,uCAAuC;AACvC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "planflow-ai",
3
+ "version": "1.0.0",
4
+ "description": "Structured AI-assisted development workflows for discovery, planning, execution, code reviews, and testing",
5
+ "type": "module",
6
+ "main": "dist/cli/index.js",
7
+ "bin": {
8
+ "plan-flow": "./dist/cli/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/cli/index.js",
13
+ "dev": "tsx src/cli/index.ts",
14
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
15
+ "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --watch",
16
+ "test:coverage": "node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
17
+ "lint": "eslint src --ext .ts",
18
+ "lint:fix": "eslint src --ext .ts --fix",
19
+ "format": "prettier --write \"src/**/*.ts\"",
20
+ "format:check": "prettier --check \"src/**/*.ts\"",
21
+ "typecheck": "tsc --noEmit"
22
+ },
23
+ "files": [
24
+ "dist/",
25
+ ".claude/commands/",
26
+ ".claude/rules/",
27
+ "rules/",
28
+ "skills/",
29
+ "templates/",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "keywords": [
34
+ "ai",
35
+ "cursor",
36
+ "claude",
37
+ "openclaw",
38
+ "codex",
39
+ "code-review",
40
+ "planning",
41
+ "development",
42
+ "structured-development",
43
+ "workflow",
44
+ "ai-assisted"
45
+ ],
46
+ "author": "",
47
+ "license": "MIT",
48
+ "dependencies": {
49
+ "commander": "^14.0.3"
50
+ },
51
+ "devDependencies": {
52
+ "@types/jest": "^29.5.14",
53
+ "@types/node": "^22.10.5",
54
+ "jest": "^29.7.0",
55
+ "prettier": "^3.4.2",
56
+ "ts-jest": "^29.2.5",
57
+ "tsx": "^4.7.0",
58
+ "typescript": "^5.9.3"
59
+ },
60
+ "engines": {
61
+ "node": ">=18"
62
+ }
63
+ }
@@ -0,0 +1,99 @@
1
+ ---
2
+ description: "Summary index for core rules - load this to see available references"
3
+ alwaysApply: false
4
+ ---
5
+
6
+ # Core Rules Index
7
+
8
+ ## Overview
9
+
10
+ Core rules define the foundational coding standards that apply across the entire project. These include best practices to follow (allowed patterns), anti-patterns to avoid (forbidden patterns), and complexity scoring for implementation planning.
11
+
12
+ **Total Files**: 4 files, ~833 lines
13
+ **Reference Codes**: COR-AP-1 through COR-LDG-2
14
+
15
+ ---
16
+
17
+ ## Reference Codes
18
+
19
+ ### Allowed Patterns (`allowed-patterns.mdc`)
20
+
21
+ | Code | Description | Source | Lines |
22
+ |------|-------------|--------|-------|
23
+ | COR-AP-1 | Example patterns (Naming, SRP, Errors, Types, Organization) | allowed-patterns.mdc | 45-152 |
24
+ | COR-AP-2 | Template for adding new patterns | allowed-patterns.mdc | 167-186 |
25
+
26
+ ### Forbidden Patterns (`forbidden-patterns.mdc`)
27
+
28
+ | Code | Description | Source | Lines |
29
+ |------|-------------|--------|-------|
30
+ | COR-FP-1 | Example anti-patterns (Magic Numbers, Silent Errors, Ternaries, Mutation, Async) | forbidden-patterns.mdc | 41-230 |
31
+ | COR-FP-2 | Template for adding new anti-patterns | forbidden-patterns.mdc | 245-264 |
32
+
33
+ ### Complexity Scoring (`complexity-scoring.mdc`)
34
+
35
+ | Code | Description | Source | Lines |
36
+ |------|-------------|--------|-------|
37
+ | COR-CS-1 | Complexity scale table (0-10 levels) | complexity-scoring.mdc | 12-21 |
38
+ | COR-CS-2 | Scoring criteria modifiers (+/- points) | complexity-scoring.mdc | 23-51 |
39
+ | COR-CS-3 | Execution strategy and aggregation rules | complexity-scoring.mdc | 53-70 |
40
+ | COR-CS-4 | Common complexity patterns table | complexity-scoring.mdc | 168-185 |
41
+ | COR-CS-5 | Real-world scoring examples | complexity-scoring.mdc | 187-236 |
42
+
43
+ ### Project Ledger (`project-ledger.mdc`)
44
+
45
+ | Code | Description | Source | Lines |
46
+ |------|-------------|--------|-------|
47
+ | COR-LDG-1 | Ledger behavior, entry format, and sections | project-ledger.mdc | 10-110 |
48
+ | COR-LDG-2 | Maintenance rules and plan-flow integration | project-ledger.mdc | 112-155 |
49
+
50
+ ---
51
+
52
+ ## When to Expand
53
+
54
+ | Code | Expand When |
55
+ |------|-------------|
56
+ | COR-AP-1 | Need to see example good patterns for code generation |
57
+ | COR-AP-2 | Adding a new allowed pattern to the project |
58
+ | COR-FP-1 | Need to see anti-patterns to avoid |
59
+ | COR-FP-2 | Adding a new forbidden pattern to the project |
60
+ | COR-CS-1 | Need complexity level definitions |
61
+ | COR-CS-2 | Calculating complexity score for a phase |
62
+ | COR-CS-3 | Determining execution strategy for plan phases |
63
+ | COR-CS-4 | Quick lookup of typical complexity scores |
64
+ | COR-CS-5 | Need detailed scoring examples |
65
+ | COR-LDG-1 | Need ledger behavior and entry guidelines |
66
+ | COR-LDG-2 | Need ledger maintenance and integration rules |
67
+
68
+ ---
69
+
70
+ ## Quick Reference
71
+
72
+ ### Allowed Patterns Summary
73
+ - **Descriptive Naming**: Clear, self-documenting names
74
+ - **Single Responsibility**: One function = one purpose
75
+ - **Error Handling**: Explicit errors with logging
76
+ - **Type Safety**: Leverage TypeScript types
77
+ - **Code Organization**: Consistent folder structure
78
+
79
+ ### Forbidden Patterns Summary
80
+ - **No Magic Numbers**: Use named constants
81
+ - **No Silent Errors**: Always log and handle
82
+ - **No Nested Ternaries**: Use if/else or switch
83
+ - **No Parameter Mutation**: Return new objects/arrays
84
+ - **No Mixed Async**: Use async/await consistently
85
+
86
+ ### Complexity Levels
87
+ - **0-2 Trivial**: Simple, mechanical changes
88
+ - **3-4 Low**: Straightforward implementation
89
+ - **5-6 Medium**: Moderate complexity, some decisions
90
+ - **7-8 High**: Complex, multiple concerns
91
+ - **9-10 Very High**: Requires careful attention
92
+
93
+ ---
94
+
95
+ ## Notes
96
+
97
+ - `allowed-patterns.mdc` and `forbidden-patterns.mdc` have `alwaysApply: true` - they are loaded automatically by Cursor
98
+ - `project-ledger.mdc` has `alwaysApply: true` - maintains persistent project memory
99
+ - `complexity-scoring.mdc` is loaded on-demand when needed for planning
@@ -0,0 +1,185 @@
1
+ ---
2
+ description: "Best practices and recommended patterns that should always be followed"
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Allowed Patterns
7
+
8
+ This file defines **best practices and recommended patterns** for your project. Add patterns that your team agrees upon and wants the AI to follow during code generation.
9
+
10
+ ---
11
+
12
+ ## How to Use This File
13
+
14
+ 1. **Add patterns** that represent your team's coding standards
15
+ 2. **Include examples** showing the correct way to implement each pattern
16
+ 3. **Explain why** each pattern is beneficial
17
+ 4. **Reference tools/rules** if applicable (ESLint, SonarQube, etc.)
18
+
19
+ ---
20
+
21
+ ## Example Pattern Structure
22
+
23
+ ### Pattern Name
24
+
25
+ Brief description of what this pattern accomplishes.
26
+
27
+ ```typescript
28
+ // GOOD - Example of the correct approach
29
+ const example = doThingCorrectly()
30
+
31
+ // Optionally show the contrast
32
+ // BAD - What to avoid (but keep this minimal)
33
+ const badExample = doThingWrong()
34
+ ```
35
+
36
+ **Why**: Explain the benefit of following this pattern.
37
+
38
+ **Guidelines**:
39
+
40
+ - Specific guideline 1
41
+ - Specific guideline 2
42
+
43
+ ---
44
+
45
+ ## Example Patterns
46
+
47
+ ### 1. Descriptive Naming
48
+
49
+ Use clear, descriptive names for functions, variables, and components.
50
+
51
+ ```typescript
52
+ // GOOD - Clear intent
53
+ function calculateOrderTotal(items: OrderItem[]): number
54
+ function fetchUserProfile(userId: string): Promise<User>
55
+ const isAuthenticated = checkAuthStatus()
56
+
57
+ // GOOD - Component names describe what they render
58
+ export const UserProfileCard = () => { ... }
59
+ export const OrderSummaryTable = () => { ... }
60
+ ```
61
+
62
+ **Why**: Improves code readability and makes the codebase self-documenting.
63
+
64
+ ---
65
+
66
+ ### 2. Single Responsibility
67
+
68
+ Each function/component should do one thing well.
69
+
70
+ ```typescript
71
+ // GOOD - Focused function
72
+ function formatCurrency(amount: number): string {
73
+ return new Intl.NumberFormat('en-US', {
74
+ style: 'currency',
75
+ currency: 'USD',
76
+ }).format(amount)
77
+ }
78
+
79
+ // GOOD - Focused component
80
+ const PriceDisplay = ({ amount }: { amount: number }) => (
81
+ <span className="price">{formatCurrency(amount)}</span>
82
+ )
83
+ ```
84
+
85
+ **Why**: Easier to test, maintain, and reuse.
86
+
87
+ ---
88
+
89
+ ### 3. Error Handling
90
+
91
+ Handle errors explicitly with meaningful messages.
92
+
93
+ ```typescript
94
+ // GOOD - Explicit error handling
95
+ async function fetchData(url: string) {
96
+ try {
97
+ const response = await fetch(url)
98
+ if (!response.ok) {
99
+ throw new ApiError(`Request failed: ${response.status}`)
100
+ }
101
+ return response.json()
102
+ } catch (error) {
103
+ logger.error('Failed to fetch data', { url, error })
104
+ throw error
105
+ }
106
+ }
107
+ ```
108
+
109
+ **Why**: Makes debugging easier and provides better user feedback.
110
+
111
+ ---
112
+
113
+ ### 4. Type Safety
114
+
115
+ Leverage TypeScript's type system to catch errors at compile time.
116
+
117
+ ```typescript
118
+ // GOOD - Explicit types for function signatures
119
+ interface User {
120
+ id: string
121
+ name: string
122
+ email: string
123
+ }
124
+
125
+ function createUser(input: CreateUserInput): User {
126
+ // Implementation
127
+ }
128
+
129
+ // GOOD - Use type inference where appropriate
130
+ const users = await fetchUsers() // Type inferred from function return
131
+ ```
132
+
133
+ **Why**: Catches errors before runtime and improves IDE autocomplete.
134
+
135
+ ---
136
+
137
+ ### 5. Consistent Code Organization
138
+
139
+ Follow a consistent structure for files and folders.
140
+
141
+ ```
142
+ src/
143
+ ├── components/ # UI components
144
+ ├── hooks/ # Custom React hooks
145
+ ├── utils/ # Utility functions
146
+ ├── types/ # TypeScript type definitions
147
+ ├── services/ # API and external service integrations
148
+ └── stores/ # State management
149
+ ```
150
+
151
+ **Why**: Makes the codebase navigable and predictable.
152
+
153
+ ---
154
+
155
+ ## Adding Your Patterns
156
+
157
+ When adding new patterns to this file:
158
+
159
+ 1. **Start with the pattern name** as a heading
160
+ 2. **Provide code examples** showing the correct approach
161
+ 3. **Explain the "Why"** - benefits of the pattern
162
+ 4. **Add guidelines** for edge cases or nuances
163
+ 5. **Reference external rules** if applicable (linting, etc.)
164
+
165
+ ---
166
+
167
+ ## Template for New Patterns
168
+
169
+ ```markdown
170
+ ### Pattern Name
171
+
172
+ Brief description of what this pattern accomplishes.
173
+
174
+ \`\`\`typescript
175
+ // GOOD - Example code
176
+ const example = correctApproach()
177
+ \`\`\`
178
+
179
+ **Why**: Explanation of benefits.
180
+
181
+ **Guidelines**:
182
+
183
+ - Guideline 1
184
+ - Guideline 2
185
+ ```