@planu/cli 1.12.0 → 1.13.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/dist/config/ai-tool-registry.json +71 -0
- package/dist/config/autopilot-config.json +21 -0
- package/dist/config/competitive-catalog.json +83 -0
- package/dist/config/license-plans.json +17 -1
- package/dist/engine/agent-registry/lifecycle-manager.d.ts +8 -0
- package/dist/engine/agent-registry/lifecycle-manager.d.ts.map +1 -0
- package/dist/engine/agent-registry/lifecycle-manager.js +81 -0
- package/dist/engine/agent-registry/lifecycle-manager.js.map +1 -0
- package/dist/engine/agent-registry/role-catalog.d.ts +17 -0
- package/dist/engine/agent-registry/role-catalog.d.ts.map +1 -0
- package/dist/engine/agent-registry/role-catalog.js +55 -0
- package/dist/engine/agent-registry/role-catalog.js.map +1 -0
- package/dist/engine/autopilot/action-executor.d.ts +18 -0
- package/dist/engine/autopilot/action-executor.d.ts.map +1 -0
- package/dist/engine/autopilot/action-executor.js +91 -0
- package/dist/engine/autopilot/action-executor.js.map +1 -0
- package/dist/engine/autopilot/event-bus.d.ts +8 -0
- package/dist/engine/autopilot/event-bus.d.ts.map +1 -0
- package/dist/engine/autopilot/event-bus.js +28 -0
- package/dist/engine/autopilot/event-bus.js.map +1 -0
- package/dist/engine/autopilot/trigger-rules.d.ts +3 -0
- package/dist/engine/autopilot/trigger-rules.d.ts.map +1 -0
- package/dist/engine/autopilot/trigger-rules.js +125 -0
- package/dist/engine/autopilot/trigger-rules.js.map +1 -0
- package/dist/engine/competitive/gap-analyzer.d.ts +12 -0
- package/dist/engine/competitive/gap-analyzer.d.ts.map +1 -0
- package/dist/engine/competitive/gap-analyzer.js +214 -0
- package/dist/engine/competitive/gap-analyzer.js.map +1 -0
- package/dist/engine/hook-generator/ai-hook-templates.d.ts +8 -0
- package/dist/engine/hook-generator/ai-hook-templates.d.ts.map +1 -0
- package/dist/engine/hook-generator/ai-hook-templates.js +43 -0
- package/dist/engine/hook-generator/ai-hook-templates.js.map +1 -0
- package/dist/engine/hook-generator/hook-merger.d.ts +13 -0
- package/dist/engine/hook-generator/hook-merger.d.ts.map +1 -0
- package/dist/engine/hook-generator/hook-merger.js +148 -0
- package/dist/engine/hook-generator/hook-merger.js.map +1 -0
- package/dist/engine/hook-generator/stack-hook-templates.d.ts +10 -0
- package/dist/engine/hook-generator/stack-hook-templates.d.ts.map +1 -0
- package/dist/engine/hook-generator/stack-hook-templates.js +105 -0
- package/dist/engine/hook-generator/stack-hook-templates.js.map +1 -0
- package/dist/engine/project-dna/ai-tool-detector.d.ts +12 -0
- package/dist/engine/project-dna/ai-tool-detector.d.ts.map +1 -0
- package/dist/engine/project-dna/ai-tool-detector.js +103 -0
- package/dist/engine/project-dna/ai-tool-detector.js.map +1 -0
- package/dist/engine/project-dna/rules-generator.d.ts +18 -0
- package/dist/engine/project-dna/rules-generator.d.ts.map +1 -0
- package/dist/engine/project-dna/rules-generator.js +193 -0
- package/dist/engine/project-dna/rules-generator.js.map +1 -0
- package/dist/engine/project-dna/stack-detector.d.ts +24 -0
- package/dist/engine/project-dna/stack-detector.d.ts.map +1 -0
- package/dist/engine/project-dna/stack-detector.js +309 -0
- package/dist/engine/project-dna/stack-detector.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/agent-registry-store.d.ts +11 -0
- package/dist/storage/agent-registry-store.d.ts.map +1 -0
- package/dist/storage/agent-registry-store.js +45 -0
- package/dist/storage/agent-registry-store.js.map +1 -0
- package/dist/tools/competitive-handlers.d.ts +30 -0
- package/dist/tools/competitive-handlers.d.ts.map +1 -0
- package/dist/tools/competitive-handlers.js +155 -0
- package/dist/tools/competitive-handlers.js.map +1 -0
- package/dist/tools/create-spec/post-creation.d.ts +1 -1
- package/dist/tools/create-spec/post-creation.d.ts.map +1 -1
- package/dist/tools/create-spec/post-creation.js +13 -1
- package/dist/tools/create-spec/post-creation.js.map +1 -1
- package/dist/tools/create-spec.js +1 -1
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/hook-generator-handler.d.ts +8 -0
- package/dist/tools/hook-generator-handler.d.ts.map +1 -0
- package/dist/tools/hook-generator-handler.js +154 -0
- package/dist/tools/hook-generator-handler.js.map +1 -0
- package/dist/tools/project-dna-handler.d.ts +34 -0
- package/dist/tools/project-dna-handler.d.ts.map +1 -0
- package/dist/tools/project-dna-handler.js +261 -0
- package/dist/tools/project-dna-handler.js.map +1 -0
- package/dist/tools/register-agent-registry.d.ts +5 -0
- package/dist/tools/register-agent-registry.d.ts.map +1 -0
- package/dist/tools/register-agent-registry.js +254 -0
- package/dist/tools/register-agent-registry.js.map +1 -0
- package/dist/tools/register-autopilot.d.ts +3 -0
- package/dist/tools/register-autopilot.d.ts.map +1 -0
- package/dist/tools/register-autopilot.js +78 -0
- package/dist/tools/register-autopilot.js.map +1 -0
- package/dist/tools/register-competitive.d.ts +3 -0
- package/dist/tools/register-competitive.d.ts.map +1 -0
- package/dist/tools/register-competitive.js +88 -0
- package/dist/tools/register-competitive.js.map +1 -0
- package/dist/tools/register-hook-generator.d.ts +3 -0
- package/dist/tools/register-hook-generator.d.ts.map +1 -0
- package/dist/tools/register-hook-generator.js +96 -0
- package/dist/tools/register-hook-generator.js.map +1 -0
- package/dist/tools/register-project-dna.d.ts +3 -0
- package/dist/tools/register-project-dna.d.ts.map +1 -0
- package/dist/tools/register-project-dna.js +43 -0
- package/dist/tools/register-project-dna.js.map +1 -0
- package/dist/tools/update-status/side-effects.d.ts.map +1 -1
- package/dist/tools/update-status/side-effects.js +32 -0
- package/dist/tools/update-status/side-effects.js.map +1 -1
- package/dist/types/agent-registry.d.ts +53 -0
- package/dist/types/agent-registry.d.ts.map +1 -0
- package/dist/types/agent-registry.js +2 -0
- package/dist/types/agent-registry.js.map +1 -0
- package/dist/types/autopilot.d.ts +36 -0
- package/dist/types/autopilot.d.ts.map +1 -0
- package/dist/types/autopilot.js +3 -0
- package/dist/types/autopilot.js.map +1 -0
- package/dist/types/competitive.d.ts +41 -0
- package/dist/types/competitive.d.ts.map +1 -0
- package/dist/types/competitive.js +3 -0
- package/dist/types/competitive.js.map +1 -0
- package/dist/types/hook-generator.d.ts +49 -0
- package/dist/types/hook-generator.d.ts.map +1 -0
- package/dist/types/hook-generator.js +3 -0
- package/dist/types/hook-generator.js.map +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/project-dna.d.ts +46 -0
- package/dist/types/project-dna.d.ts.map +1 -0
- package/dist/types/project-dna.js +4 -0
- package/dist/types/project-dna.js.map +1 -0
- package/package.json +1 -1
- package/src/config/ai-tool-registry.json +71 -0
- package/src/config/autopilot-config.json +21 -0
- package/src/config/competitive-catalog.json +83 -0
- package/src/config/license-plans.json +17 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// engine/hook-generator/stack-hook-templates.ts — Git hook templates per stack (SPEC-416)
|
|
2
|
+
// ---------------------------------------------------------------------------
|
|
3
|
+
// Marker helpers — used by hook-merger for idempotent injection
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
export function markerStart(id) {
|
|
6
|
+
return `# <!-- planu:generated:${id} -->`;
|
|
7
|
+
}
|
|
8
|
+
export function markerEnd(id) {
|
|
9
|
+
return `# <!-- /planu:generated:${id} -->`;
|
|
10
|
+
}
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Templates
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
export const STACK_HOOK_TEMPLATES = {
|
|
15
|
+
typescript: [
|
|
16
|
+
{
|
|
17
|
+
id: 'typescript-typecheck',
|
|
18
|
+
phase: 'pre-commit',
|
|
19
|
+
stack: 'typescript',
|
|
20
|
+
content: 'pnpm typecheck || exit 1',
|
|
21
|
+
description: 'TypeScript type checking',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
eslint: [
|
|
25
|
+
{
|
|
26
|
+
id: 'eslint-fix',
|
|
27
|
+
phase: 'pre-commit',
|
|
28
|
+
stack: 'eslint',
|
|
29
|
+
content: 'pnpm lint --fix || exit 1',
|
|
30
|
+
description: 'ESLint auto-fix',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
prettier: [
|
|
34
|
+
{
|
|
35
|
+
id: 'prettier-format',
|
|
36
|
+
phase: 'pre-commit',
|
|
37
|
+
stack: 'prettier',
|
|
38
|
+
content: 'pnpm format || exit 1',
|
|
39
|
+
description: 'Prettier formatting',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
vitest: [
|
|
43
|
+
{
|
|
44
|
+
id: 'vitest-coverage',
|
|
45
|
+
phase: 'pre-push',
|
|
46
|
+
stack: 'vitest',
|
|
47
|
+
content: 'pnpm test:coverage || exit 1',
|
|
48
|
+
description: 'Vitest coverage threshold check',
|
|
49
|
+
},
|
|
50
|
+
],
|
|
51
|
+
jest: [
|
|
52
|
+
{
|
|
53
|
+
id: 'jest-coverage',
|
|
54
|
+
phase: 'pre-push',
|
|
55
|
+
stack: 'jest',
|
|
56
|
+
content: 'pnpm test --coverage || exit 1',
|
|
57
|
+
description: 'Jest coverage check',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
python: [
|
|
61
|
+
{
|
|
62
|
+
id: 'python-ruff',
|
|
63
|
+
phase: 'pre-commit',
|
|
64
|
+
stack: 'python',
|
|
65
|
+
content: 'ruff check --fix . || exit 1',
|
|
66
|
+
description: 'Python ruff linting',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
go: [
|
|
70
|
+
{
|
|
71
|
+
id: 'go-vet',
|
|
72
|
+
phase: 'pre-commit',
|
|
73
|
+
stack: 'go',
|
|
74
|
+
content: 'go vet ./... || exit 1',
|
|
75
|
+
description: 'Go vet check',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
commitlint: [
|
|
79
|
+
{
|
|
80
|
+
id: 'commitlint',
|
|
81
|
+
phase: 'commit-msg',
|
|
82
|
+
stack: 'commitlint',
|
|
83
|
+
content: 'npx --no -- commitlint --edit "$1" || exit 1',
|
|
84
|
+
description: 'Conventional commits validation',
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
};
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Public helper
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
/**
|
|
92
|
+
* Returns all HookSection entries matching the requested stack tokens.
|
|
93
|
+
* Unknown tokens are silently skipped.
|
|
94
|
+
*/
|
|
95
|
+
export function getHookSectionsForStack(stack) {
|
|
96
|
+
const sections = [];
|
|
97
|
+
for (const token of stack) {
|
|
98
|
+
const templates = STACK_HOOK_TEMPLATES[token];
|
|
99
|
+
if (templates !== undefined) {
|
|
100
|
+
sections.push(...templates);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return sections;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=stack-hook-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-hook-templates.js","sourceRoot":"","sources":["../../../src/engine/hook-generator/stack-hook-templates.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAI1F,8EAA8E;AAC9E,gEAAgE;AAChE,8EAA8E;AAE9E,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,0BAA0B,EAAE,MAAM,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAU;IAClC,OAAO,2BAA2B,EAAE,MAAM,CAAC;AAC7C,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,CAAC,MAAM,oBAAoB,GAAkC;IACjE,UAAU,EAAE;QACV;YACE,EAAE,EAAE,sBAAsB;YAC1B,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,0BAA0B;YACnC,WAAW,EAAE,0BAA0B;SACxC;KACF;IACD,MAAM,EAAE;QACN;YACE,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,2BAA2B;YACpC,WAAW,EAAE,iBAAiB;SAC/B;KACF;IACD,QAAQ,EAAE;QACR;YACE,EAAE,EAAE,iBAAiB;YACrB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,uBAAuB;YAChC,WAAW,EAAE,qBAAqB;SACnC;KACF;IACD,MAAM,EAAE;QACN;YACE,EAAE,EAAE,iBAAiB;YACrB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,8BAA8B;YACvC,WAAW,EAAE,iCAAiC;SAC/C;KACF;IACD,IAAI,EAAE;QACJ;YACE,EAAE,EAAE,eAAe;YACnB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,gCAAgC;YACzC,WAAW,EAAE,qBAAqB;SACnC;KACF;IACD,MAAM,EAAE;QACN;YACE,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,QAAQ;YACf,OAAO,EAAE,8BAA8B;YACvC,WAAW,EAAE,qBAAqB;SACnC;KACF;IACD,EAAE,EAAE;QACF;YACE,EAAE,EAAE,QAAQ;YACZ,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,wBAAwB;YACjC,WAAW,EAAE,cAAc;SAC5B;KACF;IACD,UAAU,EAAE;QACV;YACE,EAAE,EAAE,YAAY;YAChB,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,8CAA8C;YACvD,WAAW,EAAE,iCAAiC;SAC/C;KACF;CACF,CAAC;AAEF,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAe;IACrD,MAAM,QAAQ,GAAkB,EAAE,CAAC;IACnC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC9C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AIToolId, AIToolProfile } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detects which AI tool is active by checking detection files in priority order.
|
|
4
|
+
* Returns 'unknown' if no known AI tool is detected.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectAITool(projectPath: string): Promise<AIToolId>;
|
|
7
|
+
/**
|
|
8
|
+
* Loads the full AI tool profile from the registry for a given tool ID.
|
|
9
|
+
* Returns an 'unknown' profile if the tool ID is not found.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadAIToolProfile(toolId: AIToolId): Promise<AIToolProfile>;
|
|
12
|
+
//# sourceMappingURL=ai-tool-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tool-detector.d.ts","sourceRoot":"","sources":["../../../src/engine/project-dna/ai-tool-detector.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqFpE;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAazE;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC,CAoBhF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Planu — project-dna/ai-tool-detector.ts
|
|
2
|
+
// Detects which AI tool is active in a project by checking detection files.
|
|
3
|
+
import { access, readFile } from 'node:fs/promises';
|
|
4
|
+
import { join, dirname } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
const REGISTRY_PATH = join(dirname(fileURLToPath(import.meta.url)), '../../config/ai-tool-registry.json');
|
|
7
|
+
let cachedRegistry = null;
|
|
8
|
+
async function loadRegistry() {
|
|
9
|
+
if (cachedRegistry !== null) {
|
|
10
|
+
return cachedRegistry;
|
|
11
|
+
}
|
|
12
|
+
const raw = await readFile(REGISTRY_PATH, 'utf-8');
|
|
13
|
+
cachedRegistry = JSON.parse(raw);
|
|
14
|
+
return cachedRegistry;
|
|
15
|
+
}
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Detection order (priority: highest first)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const DETECTION_ORDER = [
|
|
20
|
+
'claude',
|
|
21
|
+
'cursor',
|
|
22
|
+
'windsurf',
|
|
23
|
+
'gemini',
|
|
24
|
+
'kiro',
|
|
25
|
+
'cline',
|
|
26
|
+
'copilot',
|
|
27
|
+
'aider',
|
|
28
|
+
];
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Helpers
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
async function pathExists(filePath) {
|
|
33
|
+
try {
|
|
34
|
+
await access(filePath);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function anyDetectionFileExists(projectPath, detectionFiles) {
|
|
42
|
+
for (const f of detectionFiles) {
|
|
43
|
+
if (await pathExists(join(projectPath, f))) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Public API
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
/**
|
|
53
|
+
* Detects which AI tool is active by checking detection files in priority order.
|
|
54
|
+
* Returns 'unknown' if no known AI tool is detected.
|
|
55
|
+
*/
|
|
56
|
+
export async function detectAITool(projectPath) {
|
|
57
|
+
const registry = await loadRegistry();
|
|
58
|
+
for (const toolId of DETECTION_ORDER) {
|
|
59
|
+
const entry = registry.tools[toolId];
|
|
60
|
+
if (entry === undefined) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (await anyDetectionFileExists(projectPath, entry.detectionFiles)) {
|
|
64
|
+
return toolId;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return 'unknown';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Loads the full AI tool profile from the registry for a given tool ID.
|
|
71
|
+
* Returns an 'unknown' profile if the tool ID is not found.
|
|
72
|
+
*/
|
|
73
|
+
export async function loadAIToolProfile(toolId) {
|
|
74
|
+
if (toolId === 'unknown') {
|
|
75
|
+
return buildUnknownProfile();
|
|
76
|
+
}
|
|
77
|
+
const registry = await loadRegistry();
|
|
78
|
+
const entry = registry.tools[toolId];
|
|
79
|
+
if (entry === undefined) {
|
|
80
|
+
return buildUnknownProfile();
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
id: toolId,
|
|
84
|
+
name: entry.name,
|
|
85
|
+
detectionFiles: entry.detectionFiles,
|
|
86
|
+
rulesDir: entry.rulesDir,
|
|
87
|
+
rulesFile: entry.rulesFile,
|
|
88
|
+
rulesFormat: entry.rulesFormat,
|
|
89
|
+
docsUrl: entry.docsUrl,
|
|
90
|
+
configFile: entry.configFile,
|
|
91
|
+
frontmatterRequired: entry.frontmatterRequired,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function buildUnknownProfile() {
|
|
95
|
+
return {
|
|
96
|
+
id: 'unknown',
|
|
97
|
+
name: 'Unknown AI Tool',
|
|
98
|
+
detectionFiles: [],
|
|
99
|
+
rulesFormat: 'markdown',
|
|
100
|
+
docsUrl: '',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ai-tool-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tool-detector.js","sourceRoot":"","sources":["../../../src/engine/project-dna/ai-tool-detector.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,4EAA4E;AAC5E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AA0BzC,MAAM,aAAa,GAAG,IAAI,CACxB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,oCAAoC,CACrC,CAAC;AAEF,IAAI,cAAc,GAAwB,IAAI,CAAC;AAE/C,KAAK,UAAU,YAAY;IACzB,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,cAAc,CAAC;IACxB,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACnD,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACjD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E,MAAM,eAAe,GAAe;IAClC,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,MAAM;IACN,OAAO;IACP,SAAS;IACT,OAAO;CACR,CAAC;AAEF,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,WAAmB,EACnB,cAAwB;IAExB,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,IAAI,MAAM,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB;IACpD,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IAEtC,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QACD,IAAI,MAAM,sBAAsB,CAAC,WAAW,EAAE,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YACpE,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAgB;IACtD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,mBAAmB,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO;QACL,EAAE,EAAE,MAAM;QACV,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAA2C;QAC9D,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;KAC/C,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB;IAC1B,OAAO;QACL,EAAE,EAAE,SAAS;QACb,IAAI,EAAE,iBAAiB;QACvB,cAAc,EAAE,EAAE;QAClB,WAAW,EAAE,UAAU;QACvB,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProjectDNA, AIToolProfile } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a rules file for a given stack token formatted for the AI tool.
|
|
4
|
+
* Returns null if no rule template exists for the given stack token.
|
|
5
|
+
*/
|
|
6
|
+
export declare function generateRulesForStack(dna: ProjectDNA, stackToken: string): Promise<{
|
|
7
|
+
filePath: string;
|
|
8
|
+
content: string;
|
|
9
|
+
} | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Formats rule content according to the AI tool's expected format.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatRuleForAI(ruleContent: string, profile: AIToolProfile, stackToken: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Returns the list of stack tokens that have rule templates available.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getSupportedStackTokens(): string[];
|
|
18
|
+
//# sourceMappingURL=rules-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-generator.d.ts","sourceRoot":"","sources":["../../../src/engine/project-dna/rules-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAoJtE;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,UAAU,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAevD;AAED;;GAEG;AAEH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,aAAa,EACtB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAsBjB;AAwBD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAElD"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Rule templates (hardcoded — project conventions, not fetched)
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
const RULE_TEMPLATES = {
|
|
5
|
+
supabase: `# Supabase Patterns
|
|
6
|
+
- Always use { data, error } destructuring — never .then()
|
|
7
|
+
- Check error before using data: if (error) throw error
|
|
8
|
+
- Never expose service role key in client code
|
|
9
|
+
- Use RLS policies as primary auth layer
|
|
10
|
+
- Prefer supabase.auth.getUser() over getSession() for server-side`,
|
|
11
|
+
typescript: `# TypeScript Strict Patterns
|
|
12
|
+
- Use import type for type-only imports
|
|
13
|
+
- Prefer unknown over any
|
|
14
|
+
- Always declare return types explicitly
|
|
15
|
+
- Use noUncheckedIndexedAccess — array[i] is T | undefined`,
|
|
16
|
+
nextjs: `# Next.js App Router Patterns
|
|
17
|
+
- Prefer Server Components by default, Client Components only when needed
|
|
18
|
+
- Use server actions for mutations (not API routes)
|
|
19
|
+
- Call revalidatePath() after mutations
|
|
20
|
+
- Never use useEffect for data fetching — use async Server Components`,
|
|
21
|
+
vitest: `# Vitest Testing Patterns
|
|
22
|
+
- Use vi.mock() at module level, not inside tests
|
|
23
|
+
- Use vi.clearAllMocks() in beforeEach
|
|
24
|
+
- Prefer mockReturnValue for sync, mockResolvedValue for async
|
|
25
|
+
- Group with describe, test cases with it()`,
|
|
26
|
+
react: `# React Patterns
|
|
27
|
+
- Prefer functional components with hooks over class components
|
|
28
|
+
- Use React.memo() for expensive pure components
|
|
29
|
+
- Avoid prop drilling — use Context or state management
|
|
30
|
+
- Keep components small and single-responsibility`,
|
|
31
|
+
prisma: `# Prisma Patterns
|
|
32
|
+
- Always handle Prisma errors — catch PrismaClientKnownRequestError
|
|
33
|
+
- Use transactions for multi-step writes
|
|
34
|
+
- Never expose raw database IDs — use UUIDs or slugs
|
|
35
|
+
- Run prisma generate after schema changes`,
|
|
36
|
+
zod: `# Zod Validation Patterns
|
|
37
|
+
- Parse at boundaries — never trust external input without validation
|
|
38
|
+
- Use z.infer<typeof schema> for derived types
|
|
39
|
+
- Prefer .safeParse() over .parse() for user input
|
|
40
|
+
- Add .describe() on all fields used in LLM/MCP contexts`,
|
|
41
|
+
stripe: `# Stripe Patterns
|
|
42
|
+
- Never trust client-side amount — always verify on server
|
|
43
|
+
- Use webhook events for fulfillment — not redirect callbacks
|
|
44
|
+
- Store Stripe customer IDs, never raw card data
|
|
45
|
+
- Test with test mode keys, never live keys in development`,
|
|
46
|
+
jest: `# Jest Testing Patterns
|
|
47
|
+
- Use jest.mock() at module level
|
|
48
|
+
- Use beforeEach/afterEach for setup and cleanup
|
|
49
|
+
- Prefer mockResolvedValue for async mocks
|
|
50
|
+
- Use describe blocks to group related tests`,
|
|
51
|
+
fastapi: `# FastAPI Patterns
|
|
52
|
+
- Use Pydantic models for request/response validation
|
|
53
|
+
- Prefer async endpoints for I/O bound operations
|
|
54
|
+
- Use dependency injection for database sessions
|
|
55
|
+
- Add response_model to all endpoints`,
|
|
56
|
+
django: `# Django Patterns
|
|
57
|
+
- Use select_related/prefetch_related to avoid N+1 queries
|
|
58
|
+
- Keep views thin — move logic to services or managers
|
|
59
|
+
- Use Django forms or serializers for input validation
|
|
60
|
+
- Always use CSRF protection for state-changing endpoints`,
|
|
61
|
+
flask: `# Flask Patterns
|
|
62
|
+
- Use application factory pattern for testability
|
|
63
|
+
- Use blueprints to organize routes by domain
|
|
64
|
+
- Validate all input with marshmallow or wtforms
|
|
65
|
+
- Use Flask-SQLAlchemy for ORM integration`,
|
|
66
|
+
gin: `# Gin (Go) Patterns
|
|
67
|
+
- Use context cancellation — respect ctx.Done()
|
|
68
|
+
- Bind request data with ShouldBind — check errors
|
|
69
|
+
- Use middleware for cross-cutting concerns (auth, logging)
|
|
70
|
+
- Return consistent error responses with gin.H{}`,
|
|
71
|
+
axum: `# Axum (Rust) Patterns
|
|
72
|
+
- Use extractors for request parsing — never raw body
|
|
73
|
+
- Return impl IntoResponse for handler flexibility
|
|
74
|
+
- Use AppState for shared dependencies
|
|
75
|
+
- Propagate errors with ? and map_err`,
|
|
76
|
+
tailwind: `# Tailwind CSS Patterns
|
|
77
|
+
- Use semantic class groupings — layout, spacing, typography
|
|
78
|
+
- Extract repeated patterns to components, not @apply
|
|
79
|
+
- Use responsive prefixes consistently (sm/md/lg/xl)
|
|
80
|
+
- Avoid arbitrary values — prefer design tokens`,
|
|
81
|
+
};
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Glob patterns by stack token
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
const GLOB_PATTERNS = {
|
|
86
|
+
supabase: ['**/*.ts', '**/*.tsx'],
|
|
87
|
+
typescript: ['**/*.ts', '**/*.tsx'],
|
|
88
|
+
nextjs: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
89
|
+
vitest: ['**/*.test.ts', '**/*.spec.ts', '**/*.test.tsx'],
|
|
90
|
+
react: ['**/*.tsx', '**/*.jsx'],
|
|
91
|
+
prisma: ['prisma/**', '**/*.ts'],
|
|
92
|
+
zod: ['**/*.ts', '**/*.tsx'],
|
|
93
|
+
stripe: ['**/*.ts', '**/*.tsx'],
|
|
94
|
+
jest: ['**/*.test.ts', '**/*.test.js', '**/*.spec.ts'],
|
|
95
|
+
fastapi: ['**/*.py'],
|
|
96
|
+
django: ['**/*.py'],
|
|
97
|
+
flask: ['**/*.py'],
|
|
98
|
+
gin: ['**/*.go'],
|
|
99
|
+
axum: ['**/*.rs'],
|
|
100
|
+
tailwind: ['**/*.tsx', '**/*.jsx', '**/*.html'],
|
|
101
|
+
};
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Format helpers
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
function buildMdcFrontmatter(stackToken, globs) {
|
|
106
|
+
const globsJson = JSON.stringify(globs);
|
|
107
|
+
const description = `${capitalize(stackToken)} patterns for this project`;
|
|
108
|
+
return `---\ndescription: ${description}\nalwaysApply: false\nglobs: ${globsJson}\n---\n\n`;
|
|
109
|
+
}
|
|
110
|
+
function capitalize(s) {
|
|
111
|
+
if (s.length === 0) {
|
|
112
|
+
return s;
|
|
113
|
+
}
|
|
114
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
115
|
+
}
|
|
116
|
+
function buildAppendMarkers(stackToken, content) {
|
|
117
|
+
const marker = `<!-- planu:${stackToken} -->`;
|
|
118
|
+
const endMarker = `<!-- /planu:${stackToken} -->`;
|
|
119
|
+
return `\n${marker}\n${content}\n${endMarker}\n`;
|
|
120
|
+
}
|
|
121
|
+
// ---------------------------------------------------------------------------
|
|
122
|
+
// Public API
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
/**
|
|
125
|
+
* Generates a rules file for a given stack token formatted for the AI tool.
|
|
126
|
+
* Returns null if no rule template exists for the given stack token.
|
|
127
|
+
*/
|
|
128
|
+
export async function generateRulesForStack(dna, stackToken) {
|
|
129
|
+
const template = RULE_TEMPLATES[stackToken];
|
|
130
|
+
if (template === undefined) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
const { aiToolProfile } = dna;
|
|
134
|
+
const content = await formatRuleForAI(template, aiToolProfile, stackToken);
|
|
135
|
+
const filePath = resolveFilePath(aiToolProfile, stackToken);
|
|
136
|
+
if (filePath === null) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
return { filePath, content };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Formats rule content according to the AI tool's expected format.
|
|
143
|
+
*/
|
|
144
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
145
|
+
export async function formatRuleForAI(ruleContent, profile, stackToken) {
|
|
146
|
+
switch (profile.rulesFormat) {
|
|
147
|
+
case 'mdc': {
|
|
148
|
+
const globs = GLOB_PATTERNS[stackToken] ?? ['**/*.ts'];
|
|
149
|
+
return buildMdcFrontmatter(stackToken, globs) + ruleContent;
|
|
150
|
+
}
|
|
151
|
+
case 'markdown-append': {
|
|
152
|
+
return buildAppendMarkers(stackToken, ruleContent);
|
|
153
|
+
}
|
|
154
|
+
case 'yaml': {
|
|
155
|
+
// For aider: wrap content as a YAML comment block
|
|
156
|
+
const lines = ruleContent
|
|
157
|
+
.split('\n')
|
|
158
|
+
.map((l) => `# ${l}`)
|
|
159
|
+
.join('\n');
|
|
160
|
+
return `\n# === Planu: ${capitalize(stackToken)} Patterns ===\n${lines}\n`;
|
|
161
|
+
}
|
|
162
|
+
case 'markdown':
|
|
163
|
+
default: {
|
|
164
|
+
return ruleContent + '\n';
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Resolves the file path where the rule should be written for a given AI tool.
|
|
170
|
+
*/
|
|
171
|
+
function resolveFilePath(profile, stackToken) {
|
|
172
|
+
if (profile.rulesFormat === 'mdc' && profile.rulesDir !== undefined) {
|
|
173
|
+
return `${profile.rulesDir}${stackToken}.mdc`;
|
|
174
|
+
}
|
|
175
|
+
if (profile.rulesFormat === 'markdown' && profile.rulesDir !== undefined) {
|
|
176
|
+
return `${profile.rulesDir}${stackToken}.md`;
|
|
177
|
+
}
|
|
178
|
+
if ((profile.rulesFormat === 'markdown-append' || profile.rulesFormat === 'yaml') &&
|
|
179
|
+
profile.rulesFile !== undefined) {
|
|
180
|
+
return profile.rulesFile;
|
|
181
|
+
}
|
|
182
|
+
if (profile.rulesFormat === 'markdown' && profile.configFile !== undefined) {
|
|
183
|
+
return profile.configFile;
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Returns the list of stack tokens that have rule templates available.
|
|
189
|
+
*/
|
|
190
|
+
export function getSupportedStackTokens() {
|
|
191
|
+
return Object.keys(RULE_TEMPLATES);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=rules-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules-generator.js","sourceRoot":"","sources":["../../../src/engine/project-dna/rules-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects the technology stack by reading common manifest files.
|
|
3
|
+
* Returns normalized stack tokens (e.g. 'nextjs', 'supabase', 'vitest').
|
|
4
|
+
*/
|
|
5
|
+
export declare function detectStack(projectPath: string): Promise<string[]>;
|
|
6
|
+
type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'pip' | 'cargo' | 'go' | 'unknown';
|
|
7
|
+
/**
|
|
8
|
+
* Detects the package manager by checking lock files and manifests.
|
|
9
|
+
*/
|
|
10
|
+
export declare function detectPackageManager(projectPath: string): Promise<PackageManager>;
|
|
11
|
+
/**
|
|
12
|
+
* Detects the primary testing framework based on stack tokens and config files.
|
|
13
|
+
*/
|
|
14
|
+
export declare function detectTestingFramework(projectPath: string, stack: string[]): Promise<string | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Detects the primary linter based on config files and stack tokens.
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectLinter(projectPath: string, stack: string[]): Promise<string | undefined>;
|
|
19
|
+
/**
|
|
20
|
+
* Detects the primary code formatter based on config files and stack tokens.
|
|
21
|
+
*/
|
|
22
|
+
export declare function detectFormatter(projectPath: string, stack: string[]): Promise<string | undefined>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=stack-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../../src/engine/project-dna/stack-detector.ts"],"names":[],"mappings":"AA8BA;;;GAGG;AACH,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAWxE;AAmKD,KAAK,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3F;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAsBvF;AAMD;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe7B;AAMD;;GAEG;AACH,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+B7B;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAwB7B"}
|