prjct-cli 1.6.11 → 1.6.13
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/CHANGELOG.md +65 -1
- package/core/agentic/prompt-builder.ts +2 -2
- package/core/context-tools/imports-tool.ts +12 -9
- package/core/infrastructure/command-installer.ts +10 -15
- package/core/infrastructure/setup.ts +9 -14
- package/core/services/diff-generator.ts +1 -7
- package/core/services/sync-service.ts +0 -2
- package/core/utils/citations.ts +1 -1
- package/core/utils/version.ts +3 -0
- package/dist/bin/prjct.mjs +26 -36
- package/dist/core/infrastructure/command-installer.js +9 -14
- package/dist/core/infrastructure/setup.js +17 -27
- package/package.json +1 -1
- package/templates/agentic/context-filtering.md +0 -35
- package/templates/agentic/skill-integration.md +0 -59
- package/templates/agentic/subagent-generation.md +0 -54
- package/templates/analysis/bug-severity.md +0 -74
- package/templates/analysis/complexity.md +0 -54
- package/templates/analysis/health.md +0 -66
- package/templates/analysis/intent.md +0 -66
- package/templates/analysis/task-breakdown.md +0 -53
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,76 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.13] - 2026-02-07
|
|
4
|
+
|
|
5
|
+
### Refactoring
|
|
6
|
+
|
|
7
|
+
- remove unused templates and dead code (PRJ-293) (#138)
|
|
8
|
+
- remove unused templates and dead code (PRJ-293)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## [1.6.15] - 2026-02-07
|
|
12
|
+
|
|
13
|
+
### Refactor
|
|
14
|
+
- **Remove unused templates and dead code (PRJ-293)**: Deleted 8 unused template files from `templates/analysis/` (5) and `templates/agentic/` (3) that were never referenced by any code or other templates. Also removed unused type imports flagged by biome's `noUnusedImports` rule from `diff-generator.ts`, `sync-service.ts`, and `citations.ts`. Total: -471 lines removed.
|
|
15
|
+
|
|
16
|
+
### Implementation Details
|
|
17
|
+
Audited all 135 templates by cross-referencing with code that loads them. Carefully distinguished between templates loaded dynamically via `readdir` (checklists, skills — kept) and templates with zero references (analysis prompts, agentic scaffolding — deleted). Unused imports were types imported for re-export where the `export type` statement imports independently from the source module, making the `import type` line redundant.
|
|
18
|
+
|
|
19
|
+
### Learnings
|
|
20
|
+
- Dynamic template loading via `readdir` (in `prompt-builder.ts` and `skill-service.ts`) means simple grep searches can't identify all references — must trace runtime loading patterns to distinguish truly unused templates from dynamically loaded ones
|
|
21
|
+
- TypeScript `export type { X } from 'module'` is a standalone declaration that imports independently — a separate `import type { X }` is only needed if `X` is used in the file body
|
|
22
|
+
|
|
23
|
+
### Test Plan
|
|
24
|
+
|
|
25
|
+
#### For QA
|
|
26
|
+
1. Run `bun run build` — verify build succeeds with no errors
|
|
27
|
+
2. Run `bun run lint` — verify zero biome warnings (especially `noUnusedImports`)
|
|
28
|
+
3. Run `prjct sync` — verify sync still works (deleted templates were unused by sync)
|
|
29
|
+
4. Verify `templates/checklists/*.md` and `templates/skills/*.md` are untouched (dynamically loaded)
|
|
30
|
+
|
|
31
|
+
#### For Users
|
|
32
|
+
**What changed:** Removed 8 unused internal template files and cleaned up dead imports. No user-facing behavior changes.
|
|
33
|
+
**How to use:** No action needed — this is an internal cleanup.
|
|
34
|
+
**Breaking changes:** None.
|
|
35
|
+
|
|
36
|
+
## [1.6.12] - 2026-02-07
|
|
37
|
+
|
|
38
|
+
### Bug Fixes
|
|
39
|
+
|
|
40
|
+
- replace sync I/O in imports-tool hot path (PRJ-290) (#137)
|
|
41
|
+
|
|
42
|
+
## [1.6.14] - 2026-02-07
|
|
43
|
+
|
|
44
|
+
### Bug Fixes
|
|
45
|
+
- **Replace sync I/O in imports-tool hot path (PRJ-290)**: Converted `tryResolve`/`resolveImport`/`extractImports` from sync `require('node:fs')` with `existsSync`+`statSync` to async `fs.stat()` from `node:fs/promises`. Also replaced repeated `getPackageRoot()` calls with the pre-resolved `PACKAGE_ROOT` constant in prompt-builder, command-installer, and setup modules.
|
|
46
|
+
|
|
47
|
+
### Implementation Details
|
|
48
|
+
The `imports-tool.ts` file had an inline `require('node:fs')` call inside `tryResolve()` that used `existsSync` and `statSync` in a loop — a true hot path during import analysis. Converted the entire chain (`tryResolve` → `resolveImport` → `extractImports`) to async, using the already-imported `fs` from `node:fs/promises`. `version.ts` was kept sync intentionally: esbuild CJS output (used for postinstall) doesn't support top-level await, and its I/O runs once at cold start with results cached.
|
|
49
|
+
|
|
50
|
+
### Learnings
|
|
51
|
+
- esbuild CJS format does not support top-level `await` — async module exports require ESM format
|
|
52
|
+
- `version.ts` cold-start I/O is negligible (runs once, cached) vs `imports-tool.ts` which resolves extensions in a loop per import
|
|
53
|
+
- Using pre-resolved `PACKAGE_ROOT` constant avoids repeated sync function calls across modules
|
|
54
|
+
|
|
55
|
+
### Test Plan
|
|
56
|
+
|
|
57
|
+
#### For QA
|
|
58
|
+
1. Run `prjct context imports <file>` — verify import resolution works correctly (resolves `.ts`, `.tsx`, `.js` extensions and `/index.ts` barrel imports)
|
|
59
|
+
2. Run `prjct sync` — verify command-installer and setup find templates via `PACKAGE_ROOT`
|
|
60
|
+
3. Run `bun run build` — verify all 5 build targets compile without errors
|
|
61
|
+
4. Verify no `fs.*Sync()` calls remain in `imports-tool.ts`
|
|
62
|
+
|
|
63
|
+
#### For Users
|
|
64
|
+
**What changed:** Import analysis is now fully async, eliminating sync file system calls in the hot path.
|
|
65
|
+
**How to use:** No changes needed — `prjct context imports` works the same way.
|
|
66
|
+
**Breaking changes:** None.
|
|
67
|
+
|
|
3
68
|
## [1.6.11] - 2026-02-07
|
|
4
69
|
|
|
5
70
|
### Performance
|
|
6
71
|
|
|
7
72
|
- cache provider detection to eliminate redundant shell spawns (PRJ-289) (#136)
|
|
8
73
|
|
|
9
|
-
|
|
10
74
|
## [1.6.13] - 2026-02-07
|
|
11
75
|
|
|
12
76
|
### Improvements
|
|
@@ -27,7 +27,7 @@ import type {
|
|
|
27
27
|
} from '../types'
|
|
28
28
|
import { getErrorMessage, isNotFoundError } from '../types/fs'
|
|
29
29
|
import { fileExists } from '../utils/fs-helpers'
|
|
30
|
-
import {
|
|
30
|
+
import { PACKAGE_ROOT } from '../utils/version'
|
|
31
31
|
|
|
32
32
|
// Re-export types for convenience
|
|
33
33
|
export type {
|
|
@@ -132,7 +132,7 @@ class PromptBuilder {
|
|
|
132
132
|
* These modules extend the base global CLAUDE.md for complex operations
|
|
133
133
|
*/
|
|
134
134
|
async loadModule(moduleName: string): Promise<string | null> {
|
|
135
|
-
const modulePath = path.join(
|
|
135
|
+
const modulePath = path.join(PACKAGE_ROOT, 'templates/global/modules', moduleName)
|
|
136
136
|
return this.getTemplate(modulePath)
|
|
137
137
|
}
|
|
138
138
|
|
|
@@ -178,7 +178,7 @@ export async function analyzeImports(
|
|
|
178
178
|
const patterns = IMPORT_PATTERNS[language] || []
|
|
179
179
|
|
|
180
180
|
// Extract imports
|
|
181
|
-
const imports = extractImports(content, patterns, absolutePath, projectPath)
|
|
181
|
+
const imports = await extractImports(content, patterns, absolutePath, projectPath)
|
|
182
182
|
|
|
183
183
|
// Get reverse imports if requested
|
|
184
184
|
let importedBy: ImportedBy[] = []
|
|
@@ -217,12 +217,12 @@ export async function analyzeImports(
|
|
|
217
217
|
/**
|
|
218
218
|
* Extract imports from file content
|
|
219
219
|
*/
|
|
220
|
-
function extractImports(
|
|
220
|
+
async function extractImports(
|
|
221
221
|
content: string,
|
|
222
222
|
patterns: ImportPattern[],
|
|
223
223
|
absolutePath: string,
|
|
224
224
|
projectPath: string
|
|
225
|
-
): ImportRelation[] {
|
|
225
|
+
): Promise<ImportRelation[]> {
|
|
226
226
|
const imports: ImportRelation[] = []
|
|
227
227
|
const seen = new Set<string>()
|
|
228
228
|
|
|
@@ -254,7 +254,7 @@ function extractImports(
|
|
|
254
254
|
// Resolve internal imports
|
|
255
255
|
let resolved: string | null = null
|
|
256
256
|
if (!isExternal) {
|
|
257
|
-
resolved = resolveImport(source, absolutePath, projectPath)
|
|
257
|
+
resolved = await resolveImport(source, absolutePath, projectPath)
|
|
258
258
|
}
|
|
259
259
|
|
|
260
260
|
imports.push({
|
|
@@ -274,7 +274,11 @@ function extractImports(
|
|
|
274
274
|
/**
|
|
275
275
|
* Resolve a relative import to an absolute path
|
|
276
276
|
*/
|
|
277
|
-
function resolveImport(
|
|
277
|
+
async function resolveImport(
|
|
278
|
+
source: string,
|
|
279
|
+
fromFile: string,
|
|
280
|
+
projectPath: string
|
|
281
|
+
): Promise<string | null> {
|
|
278
282
|
const fileDir = path.dirname(fromFile)
|
|
279
283
|
|
|
280
284
|
// Handle path alias like @/
|
|
@@ -291,15 +295,14 @@ function resolveImport(source: string, fromFile: string, projectPath: string): s
|
|
|
291
295
|
/**
|
|
292
296
|
* Try to resolve a path, adding extensions if needed
|
|
293
297
|
*/
|
|
294
|
-
function tryResolve(basePath: string, projectPath: string): string | null {
|
|
298
|
+
async function tryResolve(basePath: string, projectPath: string): Promise<string | null> {
|
|
295
299
|
const extensions = ['', '.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.js']
|
|
296
300
|
|
|
297
301
|
for (const ext of extensions) {
|
|
298
302
|
const fullPath = basePath + ext
|
|
299
303
|
try {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isFile()) {
|
|
304
|
+
const stat = await fs.stat(fullPath)
|
|
305
|
+
if (stat.isFile()) {
|
|
303
306
|
return path.relative(projectPath, fullPath)
|
|
304
307
|
}
|
|
305
308
|
} catch {}
|
|
@@ -23,7 +23,7 @@ import type {
|
|
|
23
23
|
UninstallResult,
|
|
24
24
|
} from '../types'
|
|
25
25
|
import { getErrorMessage, isNotFoundError } from '../types/fs'
|
|
26
|
-
import {
|
|
26
|
+
import { PACKAGE_ROOT } from '../utils/version'
|
|
27
27
|
|
|
28
28
|
// =============================================================================
|
|
29
29
|
// Module Types
|
|
@@ -51,7 +51,7 @@ interface ModuleConfig {
|
|
|
51
51
|
*/
|
|
52
52
|
async function loadModuleConfig(): Promise<ModuleConfig | null> {
|
|
53
53
|
try {
|
|
54
|
-
const configPath = path.join(
|
|
54
|
+
const configPath = path.join(PACKAGE_ROOT, 'templates/global/modules/module-config.json')
|
|
55
55
|
const content = await fs.readFile(configPath, 'utf-8')
|
|
56
56
|
return JSON.parse(content) as ModuleConfig
|
|
57
57
|
} catch {
|
|
@@ -66,11 +66,11 @@ async function loadModuleConfig(): Promise<ModuleConfig | null> {
|
|
|
66
66
|
*/
|
|
67
67
|
export async function composeGlobalTemplate(profile?: string): Promise<string> {
|
|
68
68
|
const config = await loadModuleConfig()
|
|
69
|
-
const modulesDir = path.join(
|
|
69
|
+
const modulesDir = path.join(PACKAGE_ROOT, 'templates/global/modules')
|
|
70
70
|
|
|
71
71
|
// Fallback to legacy template if config not found
|
|
72
72
|
if (!config) {
|
|
73
|
-
const legacyPath = path.join(
|
|
73
|
+
const legacyPath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
|
|
74
74
|
return fs.readFile(legacyPath, 'utf-8')
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -81,7 +81,7 @@ export async function composeGlobalTemplate(profile?: string): Promise<string> {
|
|
|
81
81
|
// Fallback to default profile
|
|
82
82
|
const defaultProfile = config.profiles[config.default]
|
|
83
83
|
if (!defaultProfile) {
|
|
84
|
-
const legacyPath = path.join(
|
|
84
|
+
const legacyPath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
|
|
85
85
|
return fs.readFile(legacyPath, 'utf-8')
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -130,7 +130,7 @@ export async function getProfileForCommand(command: string): Promise<string> {
|
|
|
130
130
|
export async function installDocs(): Promise<{ success: boolean; error?: string }> {
|
|
131
131
|
try {
|
|
132
132
|
const docsDir = path.join(os.homedir(), '.prjct-cli', 'docs')
|
|
133
|
-
const templateDocsDir = path.join(
|
|
133
|
+
const templateDocsDir = path.join(PACKAGE_ROOT, 'templates/global/docs')
|
|
134
134
|
|
|
135
135
|
// Ensure docs directory exists
|
|
136
136
|
await fs.mkdir(docsDir, { recursive: true })
|
|
@@ -177,12 +177,7 @@ export async function installGlobalConfig(): Promise<GlobalConfigResult> {
|
|
|
177
177
|
await fs.mkdir(activeProvider.configDir, { recursive: true })
|
|
178
178
|
|
|
179
179
|
const globalConfigPath = path.join(activeProvider.configDir, activeProvider.contextFile)
|
|
180
|
-
const templatePath = path.join(
|
|
181
|
-
getPackageRoot(),
|
|
182
|
-
'templates',
|
|
183
|
-
'global',
|
|
184
|
-
activeProvider.contextFile
|
|
185
|
-
)
|
|
180
|
+
const templatePath = path.join(PACKAGE_ROOT, 'templates', 'global', activeProvider.contextFile)
|
|
186
181
|
|
|
187
182
|
// Read template content - use modular composition (PRJ-94)
|
|
188
183
|
let templateContent = ''
|
|
@@ -196,12 +191,12 @@ export async function installGlobalConfig(): Promise<GlobalConfigResult> {
|
|
|
196
191
|
templateContent = await composeGlobalTemplate('standard')
|
|
197
192
|
} catch {
|
|
198
193
|
// Final fallback to legacy template
|
|
199
|
-
const fallbackTemplatePath = path.join(
|
|
194
|
+
const fallbackTemplatePath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
|
|
200
195
|
templateContent = await fs.readFile(fallbackTemplatePath, 'utf-8')
|
|
201
196
|
}
|
|
202
197
|
} else {
|
|
203
198
|
// Fallback for other providers
|
|
204
|
-
const fallbackTemplatePath = path.join(
|
|
199
|
+
const fallbackTemplatePath = path.join(PACKAGE_ROOT, 'templates/global/CLAUDE.md')
|
|
205
200
|
templateContent = await fs.readFile(fallbackTemplatePath, 'utf-8')
|
|
206
201
|
// If it is Gemini, we should rename Claude to Gemini in the fallback content
|
|
207
202
|
if (providerName === 'gemini') {
|
|
@@ -296,7 +291,7 @@ export class CommandInstaller {
|
|
|
296
291
|
|
|
297
292
|
constructor() {
|
|
298
293
|
this.homeDir = os.homedir()
|
|
299
|
-
this.templatesDir = path.join(
|
|
294
|
+
this.templatesDir = path.join(PACKAGE_ROOT, 'templates', 'commands')
|
|
300
295
|
}
|
|
301
296
|
|
|
302
297
|
private async ensureInit(): Promise<void> {
|
|
@@ -28,7 +28,7 @@ import { getErrorMessage, isNotFoundError } from '../types/fs'
|
|
|
28
28
|
import type { AIProviderConfig, AIProviderName } from '../types/provider'
|
|
29
29
|
import { fileExists } from '../utils/fs-helpers'
|
|
30
30
|
import log from '../utils/logger'
|
|
31
|
-
import {
|
|
31
|
+
import { PACKAGE_ROOT, VERSION } from '../utils/version'
|
|
32
32
|
import {
|
|
33
33
|
detectAllProviders,
|
|
34
34
|
detectAntigravity,
|
|
@@ -255,7 +255,7 @@ export async function run(): Promise<SetupResults> {
|
|
|
255
255
|
async function installGeminiRouter(): Promise<boolean> {
|
|
256
256
|
try {
|
|
257
257
|
const geminiCommandsDir = path.join(os.homedir(), '.gemini', 'commands')
|
|
258
|
-
const routerSource = path.join(
|
|
258
|
+
const routerSource = path.join(PACKAGE_ROOT, 'templates', 'commands', 'p.toml')
|
|
259
259
|
const routerDest = path.join(geminiCommandsDir, 'p.toml')
|
|
260
260
|
|
|
261
261
|
// Ensure commands directory exists
|
|
@@ -280,7 +280,7 @@ async function installGeminiGlobalConfig(): Promise<{ success: boolean; action:
|
|
|
280
280
|
try {
|
|
281
281
|
const geminiDir = path.join(os.homedir(), '.gemini')
|
|
282
282
|
const globalConfigPath = path.join(geminiDir, 'GEMINI.md')
|
|
283
|
-
const templatePath = path.join(
|
|
283
|
+
const templatePath = path.join(PACKAGE_ROOT, 'templates', 'global', 'GEMINI.md')
|
|
284
284
|
|
|
285
285
|
// Ensure ~/.gemini directory exists
|
|
286
286
|
await fs.mkdir(geminiDir, { recursive: true })
|
|
@@ -361,7 +361,7 @@ export async function installAntigravitySkill(): Promise<{
|
|
|
361
361
|
const antigravitySkillsDir = path.join(os.homedir(), '.gemini', 'antigravity', 'skills')
|
|
362
362
|
const prjctSkillDir = path.join(antigravitySkillsDir, 'prjct')
|
|
363
363
|
const skillMdPath = path.join(prjctSkillDir, 'SKILL.md')
|
|
364
|
-
const templatePath = path.join(
|
|
364
|
+
const templatePath = path.join(PACKAGE_ROOT, 'templates', 'antigravity', 'SKILL.md')
|
|
365
365
|
|
|
366
366
|
// Ensure skills directory exists
|
|
367
367
|
await fs.mkdir(prjctSkillDir, { recursive: true })
|
|
@@ -431,8 +431,8 @@ export async function installCursorProject(projectRoot: string): Promise<{
|
|
|
431
431
|
|
|
432
432
|
const routerMdcDest = path.join(rulesDir, 'prjct.mdc')
|
|
433
433
|
|
|
434
|
-
const routerMdcSource = path.join(
|
|
435
|
-
const cursorCommandsSource = path.join(
|
|
434
|
+
const routerMdcSource = path.join(PACKAGE_ROOT, 'templates', 'cursor', 'router.mdc')
|
|
435
|
+
const cursorCommandsSource = path.join(PACKAGE_ROOT, 'templates', 'cursor', 'commands')
|
|
436
436
|
|
|
437
437
|
// Ensure directories exist
|
|
438
438
|
await fs.mkdir(rulesDir, { recursive: true })
|
|
@@ -574,13 +574,8 @@ export async function installWindsurfProject(projectRoot: string): Promise<{
|
|
|
574
574
|
|
|
575
575
|
const routerDest = path.join(rulesDir, 'prjct.md')
|
|
576
576
|
|
|
577
|
-
const routerSource = path.join(
|
|
578
|
-
const windsurfWorkflowsSource = path.join(
|
|
579
|
-
getPackageRoot(),
|
|
580
|
-
'templates',
|
|
581
|
-
'windsurf',
|
|
582
|
-
'workflows'
|
|
583
|
-
)
|
|
577
|
+
const routerSource = path.join(PACKAGE_ROOT, 'templates', 'windsurf', 'router.md')
|
|
578
|
+
const windsurfWorkflowsSource = path.join(PACKAGE_ROOT, 'templates', 'windsurf', 'workflows')
|
|
584
579
|
|
|
585
580
|
// Ensure directories exist
|
|
586
581
|
await fs.mkdir(rulesDir, { recursive: true })
|
|
@@ -785,7 +780,7 @@ async function installStatusLine(): Promise<void> {
|
|
|
785
780
|
const prjctConfigPath = path.join(prjctStatusLineDir, 'config.json')
|
|
786
781
|
|
|
787
782
|
// Source assets (from the package)
|
|
788
|
-
const assetsDir = path.join(
|
|
783
|
+
const assetsDir = path.join(PACKAGE_ROOT, 'assets', 'statusline')
|
|
789
784
|
const sourceScript = path.join(assetsDir, 'statusline.sh')
|
|
790
785
|
const sourceThemeDir = path.join(assetsDir, 'themes')
|
|
791
786
|
const sourceLibDir = path.join(assetsDir, 'lib')
|
|
@@ -9,13 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import chalk from 'chalk'
|
|
12
|
-
import type {
|
|
13
|
-
DiffOptions,
|
|
14
|
-
DiffSection,
|
|
15
|
-
ParsedMarkdownSection,
|
|
16
|
-
PreservedInfo,
|
|
17
|
-
SyncDiff,
|
|
18
|
-
} from '../types'
|
|
12
|
+
import type { DiffOptions, ParsedMarkdownSection, SyncDiff } from '../types'
|
|
19
13
|
|
|
20
14
|
export type {
|
|
21
15
|
DiffOptions,
|
|
@@ -33,7 +33,6 @@ import configManager from '../infrastructure/config-manager'
|
|
|
33
33
|
import pathManager from '../infrastructure/path-manager'
|
|
34
34
|
import { metricsStorage } from '../storage/metrics-storage'
|
|
35
35
|
import type {
|
|
36
|
-
AIToolResult,
|
|
37
36
|
GitData,
|
|
38
37
|
ProjectCommands,
|
|
39
38
|
ProjectStats,
|
|
@@ -48,7 +47,6 @@ import { type ContextSources, defaultSources, type SourceInfo } from '../utils/c
|
|
|
48
47
|
import * as dateHelper from '../utils/date-helper'
|
|
49
48
|
import log from '../utils/logger'
|
|
50
49
|
import { ContextFileGenerator } from './context-generator'
|
|
51
|
-
import type { SyncDiff } from './diff-generator'
|
|
52
50
|
import { localStateGenerator } from './local-state-generator'
|
|
53
51
|
import { skillInstaller } from './skill-installer'
|
|
54
52
|
import { StackDetector } from './stack-detector'
|
package/core/utils/citations.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @see PRJ-113
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { ContextSources, SourceInfo
|
|
10
|
+
import type { ContextSources, SourceInfo } from '../types/citations'
|
|
11
11
|
|
|
12
12
|
export type { ContextSources, SourceInfo, SourceType } from '../types/citations'
|
|
13
13
|
|
package/core/utils/version.ts
CHANGED
|
@@ -7,6 +7,9 @@ import { getErrorMessage } from '../types/fs'
|
|
|
7
7
|
*
|
|
8
8
|
* Reads version from package.json dynamically to ensure consistency
|
|
9
9
|
* across the entire application.
|
|
10
|
+
*
|
|
11
|
+
* Uses sync I/O intentionally: runs once at cold start, results cached.
|
|
12
|
+
* CJS build (postinstall) requires sync module-level exports.
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
15
|
interface PackageJson {
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -4309,7 +4309,7 @@ async function analyzeImports(filePath, projectPath = process.cwd(), options = {
|
|
|
4309
4309
|
const ext = path14.extname(filePath).toLowerCase();
|
|
4310
4310
|
const language = EXT_TO_LANG[ext] || "unknown";
|
|
4311
4311
|
const patterns = IMPORT_PATTERNS[language] || [];
|
|
4312
|
-
const imports = extractImports(content, patterns, absolutePath, projectPath);
|
|
4312
|
+
const imports = await extractImports(content, patterns, absolutePath, projectPath);
|
|
4313
4313
|
let importedBy = [];
|
|
4314
4314
|
if (options.reverse) {
|
|
4315
4315
|
importedBy = await findImportedBy(filePath, projectPath);
|
|
@@ -4333,7 +4333,7 @@ async function analyzeImports(filePath, projectPath = process.cwd(), options = {
|
|
|
4333
4333
|
}
|
|
4334
4334
|
};
|
|
4335
4335
|
}
|
|
4336
|
-
function extractImports(content, patterns, absolutePath, projectPath) {
|
|
4336
|
+
async function extractImports(content, patterns, absolutePath, projectPath) {
|
|
4337
4337
|
const imports = [];
|
|
4338
4338
|
const seen = /* @__PURE__ */ new Set();
|
|
4339
4339
|
for (const patternDef of patterns) {
|
|
@@ -4353,7 +4353,7 @@ function extractImports(content, patterns, absolutePath, projectPath) {
|
|
|
4353
4353
|
const isExternal = !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("@/");
|
|
4354
4354
|
let resolved = null;
|
|
4355
4355
|
if (!isExternal) {
|
|
4356
|
-
resolved = resolveImport(source, absolutePath, projectPath);
|
|
4356
|
+
resolved = await resolveImport(source, absolutePath, projectPath);
|
|
4357
4357
|
}
|
|
4358
4358
|
imports.push({
|
|
4359
4359
|
source,
|
|
@@ -4367,7 +4367,7 @@ function extractImports(content, patterns, absolutePath, projectPath) {
|
|
|
4367
4367
|
}
|
|
4368
4368
|
return imports;
|
|
4369
4369
|
}
|
|
4370
|
-
function resolveImport(source, fromFile, projectPath) {
|
|
4370
|
+
async function resolveImport(source, fromFile, projectPath) {
|
|
4371
4371
|
const fileDir = path14.dirname(fromFile);
|
|
4372
4372
|
if (source.startsWith("@/")) {
|
|
4373
4373
|
const aliasPath = path14.join(projectPath, "src", source.slice(2));
|
|
@@ -4376,13 +4376,13 @@ function resolveImport(source, fromFile, projectPath) {
|
|
|
4376
4376
|
const resolved = path14.resolve(fileDir, source);
|
|
4377
4377
|
return tryResolve(resolved, projectPath);
|
|
4378
4378
|
}
|
|
4379
|
-
function tryResolve(basePath, projectPath) {
|
|
4379
|
+
async function tryResolve(basePath, projectPath) {
|
|
4380
4380
|
const extensions = ["", ".ts", ".tsx", ".js", ".jsx", "/index.ts", "/index.js"];
|
|
4381
4381
|
for (const ext of extensions) {
|
|
4382
4382
|
const fullPath = basePath + ext;
|
|
4383
4383
|
try {
|
|
4384
|
-
const
|
|
4385
|
-
if (
|
|
4384
|
+
const stat = await fs14.stat(fullPath);
|
|
4385
|
+
if (stat.isFile()) {
|
|
4386
4386
|
return path14.relative(projectPath, fullPath);
|
|
4387
4387
|
}
|
|
4388
4388
|
} catch {
|
|
@@ -6609,7 +6609,7 @@ import os6 from "node:os";
|
|
|
6609
6609
|
import path19 from "node:path";
|
|
6610
6610
|
async function loadModuleConfig() {
|
|
6611
6611
|
try {
|
|
6612
|
-
const configPath = path19.join(
|
|
6612
|
+
const configPath = path19.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
|
|
6613
6613
|
const content = await fs19.readFile(configPath, "utf-8");
|
|
6614
6614
|
return JSON.parse(content);
|
|
6615
6615
|
} catch {
|
|
@@ -6618,9 +6618,9 @@ async function loadModuleConfig() {
|
|
|
6618
6618
|
}
|
|
6619
6619
|
async function composeGlobalTemplate(profile) {
|
|
6620
6620
|
const config = await loadModuleConfig();
|
|
6621
|
-
const modulesDir = path19.join(
|
|
6621
|
+
const modulesDir = path19.join(PACKAGE_ROOT, "templates/global/modules");
|
|
6622
6622
|
if (!config) {
|
|
6623
|
-
const legacyPath = path19.join(
|
|
6623
|
+
const legacyPath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
6624
6624
|
return fs19.readFile(legacyPath, "utf-8");
|
|
6625
6625
|
}
|
|
6626
6626
|
const profileName = profile || config.default;
|
|
@@ -6628,7 +6628,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
6628
6628
|
if (!selectedProfile) {
|
|
6629
6629
|
const defaultProfile = config.profiles[config.default];
|
|
6630
6630
|
if (!defaultProfile) {
|
|
6631
|
-
const legacyPath = path19.join(
|
|
6631
|
+
const legacyPath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
6632
6632
|
return fs19.readFile(legacyPath, "utf-8");
|
|
6633
6633
|
}
|
|
6634
6634
|
}
|
|
@@ -6653,7 +6653,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
6653
6653
|
async function installDocs() {
|
|
6654
6654
|
try {
|
|
6655
6655
|
const docsDir = path19.join(os6.homedir(), ".prjct-cli", "docs");
|
|
6656
|
-
const templateDocsDir = path19.join(
|
|
6656
|
+
const templateDocsDir = path19.join(PACKAGE_ROOT, "templates/global/docs");
|
|
6657
6657
|
await fs19.mkdir(docsDir, { recursive: true });
|
|
6658
6658
|
const docFiles = await fs19.readdir(templateDocsDir);
|
|
6659
6659
|
for (const file of docFiles) {
|
|
@@ -6684,12 +6684,7 @@ async function installGlobalConfig2() {
|
|
|
6684
6684
|
try {
|
|
6685
6685
|
await fs19.mkdir(activeProvider.configDir, { recursive: true });
|
|
6686
6686
|
const globalConfigPath = path19.join(activeProvider.configDir, activeProvider.contextFile);
|
|
6687
|
-
const templatePath = path19.join(
|
|
6688
|
-
getPackageRoot(),
|
|
6689
|
-
"templates",
|
|
6690
|
-
"global",
|
|
6691
|
-
activeProvider.contextFile
|
|
6692
|
-
);
|
|
6687
|
+
const templatePath = path19.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
|
|
6693
6688
|
let templateContent = "";
|
|
6694
6689
|
try {
|
|
6695
6690
|
templateContent = await fs19.readFile(templatePath, "utf-8");
|
|
@@ -6698,11 +6693,11 @@ async function installGlobalConfig2() {
|
|
|
6698
6693
|
try {
|
|
6699
6694
|
templateContent = await composeGlobalTemplate("standard");
|
|
6700
6695
|
} catch {
|
|
6701
|
-
const fallbackTemplatePath = path19.join(
|
|
6696
|
+
const fallbackTemplatePath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
6702
6697
|
templateContent = await fs19.readFile(fallbackTemplatePath, "utf-8");
|
|
6703
6698
|
}
|
|
6704
6699
|
} else {
|
|
6705
|
-
const fallbackTemplatePath = path19.join(
|
|
6700
|
+
const fallbackTemplatePath = path19.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
6706
6701
|
templateContent = await fs19.readFile(fallbackTemplatePath, "utf-8");
|
|
6707
6702
|
if (providerName === "gemini") {
|
|
6708
6703
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
@@ -6804,7 +6799,7 @@ var init_command_installer = __esm({
|
|
|
6804
6799
|
_initialized = false;
|
|
6805
6800
|
constructor() {
|
|
6806
6801
|
this.homeDir = os6.homedir();
|
|
6807
|
-
this.templatesDir = path19.join(
|
|
6802
|
+
this.templatesDir = path19.join(PACKAGE_ROOT, "templates", "commands");
|
|
6808
6803
|
}
|
|
6809
6804
|
async ensureInit() {
|
|
6810
6805
|
if (this._initialized) return;
|
|
@@ -13851,7 +13846,7 @@ var init_prompt_builder = __esm({
|
|
|
13851
13846
|
* These modules extend the base global CLAUDE.md for complex operations
|
|
13852
13847
|
*/
|
|
13853
13848
|
async loadModule(moduleName) {
|
|
13854
|
-
const modulePath = path28.join(
|
|
13849
|
+
const modulePath = path28.join(PACKAGE_ROOT, "templates/global/modules", moduleName);
|
|
13855
13850
|
return this.getTemplate(modulePath);
|
|
13856
13851
|
}
|
|
13857
13852
|
/**
|
|
@@ -24764,7 +24759,7 @@ async function run() {
|
|
|
24764
24759
|
async function installGeminiRouter() {
|
|
24765
24760
|
try {
|
|
24766
24761
|
const geminiCommandsDir = path53.join(os17.homedir(), ".gemini", "commands");
|
|
24767
|
-
const routerSource = path53.join(
|
|
24762
|
+
const routerSource = path53.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
|
|
24768
24763
|
const routerDest = path53.join(geminiCommandsDir, "p.toml");
|
|
24769
24764
|
await fs48.mkdir(geminiCommandsDir, { recursive: true });
|
|
24770
24765
|
if (await fileExists(routerSource)) {
|
|
@@ -24781,7 +24776,7 @@ async function installGeminiGlobalConfig() {
|
|
|
24781
24776
|
try {
|
|
24782
24777
|
const geminiDir = path53.join(os17.homedir(), ".gemini");
|
|
24783
24778
|
const globalConfigPath = path53.join(geminiDir, "GEMINI.md");
|
|
24784
|
-
const templatePath = path53.join(
|
|
24779
|
+
const templatePath = path53.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
|
|
24785
24780
|
await fs48.mkdir(geminiDir, { recursive: true });
|
|
24786
24781
|
const templateContent = await fs48.readFile(templatePath, "utf-8");
|
|
24787
24782
|
let existingContent = "";
|
|
@@ -24831,7 +24826,7 @@ async function installAntigravitySkill() {
|
|
|
24831
24826
|
const antigravitySkillsDir = path53.join(os17.homedir(), ".gemini", "antigravity", "skills");
|
|
24832
24827
|
const prjctSkillDir = path53.join(antigravitySkillsDir, "prjct");
|
|
24833
24828
|
const skillMdPath = path53.join(prjctSkillDir, "SKILL.md");
|
|
24834
|
-
const templatePath = path53.join(
|
|
24829
|
+
const templatePath = path53.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
|
|
24835
24830
|
await fs48.mkdir(prjctSkillDir, { recursive: true });
|
|
24836
24831
|
const skillExists = await fileExists(skillMdPath);
|
|
24837
24832
|
if (!await fileExists(templatePath)) {
|
|
@@ -24862,8 +24857,8 @@ async function installCursorProject(projectRoot) {
|
|
|
24862
24857
|
const rulesDir = path53.join(cursorDir, "rules");
|
|
24863
24858
|
const commandsDir = path53.join(cursorDir, "commands");
|
|
24864
24859
|
const routerMdcDest = path53.join(rulesDir, "prjct.mdc");
|
|
24865
|
-
const routerMdcSource = path53.join(
|
|
24866
|
-
const cursorCommandsSource = path53.join(
|
|
24860
|
+
const routerMdcSource = path53.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
|
|
24861
|
+
const cursorCommandsSource = path53.join(PACKAGE_ROOT, "templates", "cursor", "commands");
|
|
24867
24862
|
await fs48.mkdir(rulesDir, { recursive: true });
|
|
24868
24863
|
await fs48.mkdir(commandsDir, { recursive: true });
|
|
24869
24864
|
if (await fileExists(routerMdcSource)) {
|
|
@@ -24946,13 +24941,8 @@ async function installWindsurfProject(projectRoot) {
|
|
|
24946
24941
|
const rulesDir = path53.join(windsurfDir, "rules");
|
|
24947
24942
|
const workflowsDir = path53.join(windsurfDir, "workflows");
|
|
24948
24943
|
const routerDest = path53.join(rulesDir, "prjct.md");
|
|
24949
|
-
const routerSource = path53.join(
|
|
24950
|
-
const windsurfWorkflowsSource = path53.join(
|
|
24951
|
-
getPackageRoot(),
|
|
24952
|
-
"templates",
|
|
24953
|
-
"windsurf",
|
|
24954
|
-
"workflows"
|
|
24955
|
-
);
|
|
24944
|
+
const routerSource = path53.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
|
|
24945
|
+
const windsurfWorkflowsSource = path53.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
|
|
24956
24946
|
await fs48.mkdir(rulesDir, { recursive: true });
|
|
24957
24947
|
await fs48.mkdir(workflowsDir, { recursive: true });
|
|
24958
24948
|
if (await fileExists(routerSource)) {
|
|
@@ -25086,7 +25076,7 @@ async function installStatusLine() {
|
|
|
25086
25076
|
const prjctLibDir = path53.join(prjctStatusLineDir, "lib");
|
|
25087
25077
|
const prjctComponentsDir = path53.join(prjctStatusLineDir, "components");
|
|
25088
25078
|
const prjctConfigPath = path53.join(prjctStatusLineDir, "config.json");
|
|
25089
|
-
const assetsDir = path53.join(
|
|
25079
|
+
const assetsDir = path53.join(PACKAGE_ROOT, "assets", "statusline");
|
|
25090
25080
|
const sourceScript = path53.join(assetsDir, "statusline.sh");
|
|
25091
25081
|
const sourceThemeDir = path53.join(assetsDir, "themes");
|
|
25092
25082
|
const sourceLibDir = path53.join(assetsDir, "lib");
|
|
@@ -28716,7 +28706,7 @@ var require_package = __commonJS({
|
|
|
28716
28706
|
"package.json"(exports, module) {
|
|
28717
28707
|
module.exports = {
|
|
28718
28708
|
name: "prjct-cli",
|
|
28719
|
-
version: "1.6.
|
|
28709
|
+
version: "1.6.13",
|
|
28720
28710
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
28721
28711
|
main: "core/index.ts",
|
|
28722
28712
|
bin: {
|
|
@@ -517,7 +517,7 @@ var PACKAGE_ROOT = getPackageRoot();
|
|
|
517
517
|
// core/infrastructure/command-installer.ts
|
|
518
518
|
async function loadModuleConfig() {
|
|
519
519
|
try {
|
|
520
|
-
const configPath = import_node_path4.default.join(
|
|
520
|
+
const configPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
|
|
521
521
|
const content = await import_promises3.default.readFile(configPath, "utf-8");
|
|
522
522
|
return JSON.parse(content);
|
|
523
523
|
} catch {
|
|
@@ -527,9 +527,9 @@ async function loadModuleConfig() {
|
|
|
527
527
|
__name(loadModuleConfig, "loadModuleConfig");
|
|
528
528
|
async function composeGlobalTemplate(profile) {
|
|
529
529
|
const config = await loadModuleConfig();
|
|
530
|
-
const modulesDir = import_node_path4.default.join(
|
|
530
|
+
const modulesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules");
|
|
531
531
|
if (!config) {
|
|
532
|
-
const legacyPath = import_node_path4.default.join(
|
|
532
|
+
const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
533
533
|
return import_promises3.default.readFile(legacyPath, "utf-8");
|
|
534
534
|
}
|
|
535
535
|
const profileName = profile || config.default;
|
|
@@ -537,7 +537,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
537
537
|
if (!selectedProfile) {
|
|
538
538
|
const defaultProfile = config.profiles[config.default];
|
|
539
539
|
if (!defaultProfile) {
|
|
540
|
-
const legacyPath = import_node_path4.default.join(
|
|
540
|
+
const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
541
541
|
return import_promises3.default.readFile(legacyPath, "utf-8");
|
|
542
542
|
}
|
|
543
543
|
}
|
|
@@ -569,7 +569,7 @@ __name(getProfileForCommand, "getProfileForCommand");
|
|
|
569
569
|
async function installDocs() {
|
|
570
570
|
try {
|
|
571
571
|
const docsDir = import_node_path4.default.join(import_node_os3.default.homedir(), ".prjct-cli", "docs");
|
|
572
|
-
const templateDocsDir = import_node_path4.default.join(
|
|
572
|
+
const templateDocsDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/docs");
|
|
573
573
|
await import_promises3.default.mkdir(docsDir, { recursive: true });
|
|
574
574
|
const docFiles = await import_promises3.default.readdir(templateDocsDir);
|
|
575
575
|
for (const file of docFiles) {
|
|
@@ -601,12 +601,7 @@ async function installGlobalConfig() {
|
|
|
601
601
|
try {
|
|
602
602
|
await import_promises3.default.mkdir(activeProvider.configDir, { recursive: true });
|
|
603
603
|
const globalConfigPath = import_node_path4.default.join(activeProvider.configDir, activeProvider.contextFile);
|
|
604
|
-
const templatePath = import_node_path4.default.join(
|
|
605
|
-
getPackageRoot(),
|
|
606
|
-
"templates",
|
|
607
|
-
"global",
|
|
608
|
-
activeProvider.contextFile
|
|
609
|
-
);
|
|
604
|
+
const templatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
|
|
610
605
|
let templateContent = "";
|
|
611
606
|
try {
|
|
612
607
|
templateContent = await import_promises3.default.readFile(templatePath, "utf-8");
|
|
@@ -615,11 +610,11 @@ async function installGlobalConfig() {
|
|
|
615
610
|
try {
|
|
616
611
|
templateContent = await composeGlobalTemplate("standard");
|
|
617
612
|
} catch {
|
|
618
|
-
const fallbackTemplatePath = import_node_path4.default.join(
|
|
613
|
+
const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
619
614
|
templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
|
|
620
615
|
}
|
|
621
616
|
} else {
|
|
622
|
-
const fallbackTemplatePath = import_node_path4.default.join(
|
|
617
|
+
const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
623
618
|
templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
|
|
624
619
|
if (providerName === "gemini") {
|
|
625
620
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
@@ -697,7 +692,7 @@ var CommandInstaller = class {
|
|
|
697
692
|
_initialized = false;
|
|
698
693
|
constructor() {
|
|
699
694
|
this.homeDir = import_node_os3.default.homedir();
|
|
700
|
-
this.templatesDir = import_node_path4.default.join(
|
|
695
|
+
this.templatesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates", "commands");
|
|
701
696
|
}
|
|
702
697
|
async ensureInit() {
|
|
703
698
|
if (this._initialized) return;
|
|
@@ -838,7 +838,7 @@ var import_node_os3 = __toESM(require("node:os"));
|
|
|
838
838
|
var import_node_path4 = __toESM(require("node:path"));
|
|
839
839
|
async function loadModuleConfig() {
|
|
840
840
|
try {
|
|
841
|
-
const configPath = import_node_path4.default.join(
|
|
841
|
+
const configPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules/module-config.json");
|
|
842
842
|
const content = await import_promises3.default.readFile(configPath, "utf-8");
|
|
843
843
|
return JSON.parse(content);
|
|
844
844
|
} catch {
|
|
@@ -848,9 +848,9 @@ async function loadModuleConfig() {
|
|
|
848
848
|
__name(loadModuleConfig, "loadModuleConfig");
|
|
849
849
|
async function composeGlobalTemplate(profile) {
|
|
850
850
|
const config = await loadModuleConfig();
|
|
851
|
-
const modulesDir = import_node_path4.default.join(
|
|
851
|
+
const modulesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/modules");
|
|
852
852
|
if (!config) {
|
|
853
|
-
const legacyPath = import_node_path4.default.join(
|
|
853
|
+
const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
854
854
|
return import_promises3.default.readFile(legacyPath, "utf-8");
|
|
855
855
|
}
|
|
856
856
|
const profileName = profile || config.default;
|
|
@@ -858,7 +858,7 @@ async function composeGlobalTemplate(profile) {
|
|
|
858
858
|
if (!selectedProfile) {
|
|
859
859
|
const defaultProfile = config.profiles[config.default];
|
|
860
860
|
if (!defaultProfile) {
|
|
861
|
-
const legacyPath = import_node_path4.default.join(
|
|
861
|
+
const legacyPath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
862
862
|
return import_promises3.default.readFile(legacyPath, "utf-8");
|
|
863
863
|
}
|
|
864
864
|
}
|
|
@@ -884,7 +884,7 @@ __name(composeGlobalTemplate, "composeGlobalTemplate");
|
|
|
884
884
|
async function installDocs() {
|
|
885
885
|
try {
|
|
886
886
|
const docsDir = import_node_path4.default.join(import_node_os3.default.homedir(), ".prjct-cli", "docs");
|
|
887
|
-
const templateDocsDir = import_node_path4.default.join(
|
|
887
|
+
const templateDocsDir = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/docs");
|
|
888
888
|
await import_promises3.default.mkdir(docsDir, { recursive: true });
|
|
889
889
|
const docFiles = await import_promises3.default.readdir(templateDocsDir);
|
|
890
890
|
for (const file of docFiles) {
|
|
@@ -916,12 +916,7 @@ async function installGlobalConfig() {
|
|
|
916
916
|
try {
|
|
917
917
|
await import_promises3.default.mkdir(activeProvider.configDir, { recursive: true });
|
|
918
918
|
const globalConfigPath = import_node_path4.default.join(activeProvider.configDir, activeProvider.contextFile);
|
|
919
|
-
const templatePath = import_node_path4.default.join(
|
|
920
|
-
getPackageRoot(),
|
|
921
|
-
"templates",
|
|
922
|
-
"global",
|
|
923
|
-
activeProvider.contextFile
|
|
924
|
-
);
|
|
919
|
+
const templatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates", "global", activeProvider.contextFile);
|
|
925
920
|
let templateContent = "";
|
|
926
921
|
try {
|
|
927
922
|
templateContent = await import_promises3.default.readFile(templatePath, "utf-8");
|
|
@@ -930,11 +925,11 @@ async function installGlobalConfig() {
|
|
|
930
925
|
try {
|
|
931
926
|
templateContent = await composeGlobalTemplate("standard");
|
|
932
927
|
} catch {
|
|
933
|
-
const fallbackTemplatePath = import_node_path4.default.join(
|
|
928
|
+
const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
934
929
|
templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
|
|
935
930
|
}
|
|
936
931
|
} else {
|
|
937
|
-
const fallbackTemplatePath = import_node_path4.default.join(
|
|
932
|
+
const fallbackTemplatePath = import_node_path4.default.join(PACKAGE_ROOT, "templates/global/CLAUDE.md");
|
|
938
933
|
templateContent = await import_promises3.default.readFile(fallbackTemplatePath, "utf-8");
|
|
939
934
|
if (providerName === "gemini") {
|
|
940
935
|
templateContent = templateContent.replace(/Claude/g, "Gemini");
|
|
@@ -1012,7 +1007,7 @@ var CommandInstaller = class {
|
|
|
1012
1007
|
_initialized = false;
|
|
1013
1008
|
constructor() {
|
|
1014
1009
|
this.homeDir = import_node_os3.default.homedir();
|
|
1015
|
-
this.templatesDir = import_node_path4.default.join(
|
|
1010
|
+
this.templatesDir = import_node_path4.default.join(PACKAGE_ROOT, "templates", "commands");
|
|
1016
1011
|
}
|
|
1017
1012
|
async ensureInit() {
|
|
1018
1013
|
if (this._initialized) return;
|
|
@@ -1626,7 +1621,7 @@ __name(run, "run");
|
|
|
1626
1621
|
async function installGeminiRouter() {
|
|
1627
1622
|
try {
|
|
1628
1623
|
const geminiCommandsDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini", "commands");
|
|
1629
|
-
const routerSource = import_node_path6.default.join(
|
|
1624
|
+
const routerSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "commands", "p.toml");
|
|
1630
1625
|
const routerDest = import_node_path6.default.join(geminiCommandsDir, "p.toml");
|
|
1631
1626
|
await import_promises5.default.mkdir(geminiCommandsDir, { recursive: true });
|
|
1632
1627
|
if (await fileExists(routerSource)) {
|
|
@@ -1644,7 +1639,7 @@ async function installGeminiGlobalConfig() {
|
|
|
1644
1639
|
try {
|
|
1645
1640
|
const geminiDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini");
|
|
1646
1641
|
const globalConfigPath = import_node_path6.default.join(geminiDir, "GEMINI.md");
|
|
1647
|
-
const templatePath = import_node_path6.default.join(
|
|
1642
|
+
const templatePath = import_node_path6.default.join(PACKAGE_ROOT, "templates", "global", "GEMINI.md");
|
|
1648
1643
|
await import_promises5.default.mkdir(geminiDir, { recursive: true });
|
|
1649
1644
|
const templateContent = await import_promises5.default.readFile(templatePath, "utf-8");
|
|
1650
1645
|
let existingContent = "";
|
|
@@ -1695,7 +1690,7 @@ async function installAntigravitySkill() {
|
|
|
1695
1690
|
const antigravitySkillsDir = import_node_path6.default.join(import_node_os5.default.homedir(), ".gemini", "antigravity", "skills");
|
|
1696
1691
|
const prjctSkillDir = import_node_path6.default.join(antigravitySkillsDir, "prjct");
|
|
1697
1692
|
const skillMdPath = import_node_path6.default.join(prjctSkillDir, "SKILL.md");
|
|
1698
|
-
const templatePath = import_node_path6.default.join(
|
|
1693
|
+
const templatePath = import_node_path6.default.join(PACKAGE_ROOT, "templates", "antigravity", "SKILL.md");
|
|
1699
1694
|
await import_promises5.default.mkdir(prjctSkillDir, { recursive: true });
|
|
1700
1695
|
const skillExists = await fileExists(skillMdPath);
|
|
1701
1696
|
if (!await fileExists(templatePath)) {
|
|
@@ -1728,8 +1723,8 @@ async function installCursorProject(projectRoot) {
|
|
|
1728
1723
|
const rulesDir = import_node_path6.default.join(cursorDir, "rules");
|
|
1729
1724
|
const commandsDir = import_node_path6.default.join(cursorDir, "commands");
|
|
1730
1725
|
const routerMdcDest = import_node_path6.default.join(rulesDir, "prjct.mdc");
|
|
1731
|
-
const routerMdcSource = import_node_path6.default.join(
|
|
1732
|
-
const cursorCommandsSource = import_node_path6.default.join(
|
|
1726
|
+
const routerMdcSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "cursor", "router.mdc");
|
|
1727
|
+
const cursorCommandsSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "cursor", "commands");
|
|
1733
1728
|
await import_promises5.default.mkdir(rulesDir, { recursive: true });
|
|
1734
1729
|
await import_promises5.default.mkdir(commandsDir, { recursive: true });
|
|
1735
1730
|
if (await fileExists(routerMdcSource)) {
|
|
@@ -1816,13 +1811,8 @@ async function installWindsurfProject(projectRoot) {
|
|
|
1816
1811
|
const rulesDir = import_node_path6.default.join(windsurfDir, "rules");
|
|
1817
1812
|
const workflowsDir = import_node_path6.default.join(windsurfDir, "workflows");
|
|
1818
1813
|
const routerDest = import_node_path6.default.join(rulesDir, "prjct.md");
|
|
1819
|
-
const routerSource = import_node_path6.default.join(
|
|
1820
|
-
const windsurfWorkflowsSource = import_node_path6.default.join(
|
|
1821
|
-
getPackageRoot(),
|
|
1822
|
-
"templates",
|
|
1823
|
-
"windsurf",
|
|
1824
|
-
"workflows"
|
|
1825
|
-
);
|
|
1814
|
+
const routerSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "windsurf", "router.md");
|
|
1815
|
+
const windsurfWorkflowsSource = import_node_path6.default.join(PACKAGE_ROOT, "templates", "windsurf", "workflows");
|
|
1826
1816
|
await import_promises5.default.mkdir(rulesDir, { recursive: true });
|
|
1827
1817
|
await import_promises5.default.mkdir(workflowsDir, { recursive: true });
|
|
1828
1818
|
if (await fileExists(routerSource)) {
|
|
@@ -1962,7 +1952,7 @@ async function installStatusLine() {
|
|
|
1962
1952
|
const prjctLibDir = import_node_path6.default.join(prjctStatusLineDir, "lib");
|
|
1963
1953
|
const prjctComponentsDir = import_node_path6.default.join(prjctStatusLineDir, "components");
|
|
1964
1954
|
const prjctConfigPath = import_node_path6.default.join(prjctStatusLineDir, "config.json");
|
|
1965
|
-
const assetsDir = import_node_path6.default.join(
|
|
1955
|
+
const assetsDir = import_node_path6.default.join(PACKAGE_ROOT, "assets", "statusline");
|
|
1966
1956
|
const sourceScript = import_node_path6.default.join(assetsDir, "statusline.sh");
|
|
1967
1957
|
const sourceThemeDir = import_node_path6.default.join(assetsDir, "themes");
|
|
1968
1958
|
const sourceLibDir = import_node_path6.default.join(assetsDir, "lib");
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
allowed-tools: [Glob, Read]
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Context Filtering
|
|
6
|
-
|
|
7
|
-
Determine relevant files for a task.
|
|
8
|
-
|
|
9
|
-
## Process
|
|
10
|
-
|
|
11
|
-
1. **Get real extensions**: Only include what EXISTS in project
|
|
12
|
-
2. **Identify directories**: Based on task, not assumptions
|
|
13
|
-
3. **Filter by task**: What files will be modified?
|
|
14
|
-
4. **Exclude non-relevant**: node_modules, .git, dist, build
|
|
15
|
-
|
|
16
|
-
## Output
|
|
17
|
-
|
|
18
|
-
```json
|
|
19
|
-
{
|
|
20
|
-
"include": {
|
|
21
|
-
"extensions": [".ts", ".tsx"],
|
|
22
|
-
"directories": ["src/", "lib/"]
|
|
23
|
-
},
|
|
24
|
-
"exclude": {
|
|
25
|
-
"directories": ["node_modules/", ".git/", "dist/"]
|
|
26
|
-
},
|
|
27
|
-
"reasoning": "why these patterns"
|
|
28
|
-
}
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Rules
|
|
32
|
-
|
|
33
|
-
- Use REAL extensions (not assumed)
|
|
34
|
-
- Task-specific filtering
|
|
35
|
-
- Efficient - focus on what matters
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# Skill Integration
|
|
2
|
-
|
|
3
|
-
Agents integrate with Claude Code skills from claude-plugins.dev.
|
|
4
|
-
|
|
5
|
-
## Agent → Skill Mapping
|
|
6
|
-
|
|
7
|
-
| Agent | Skill |
|
|
8
|
-
|-------|-------|
|
|
9
|
-
| frontend.md | frontend-design |
|
|
10
|
-
| uxui.md | frontend-design |
|
|
11
|
-
| backend.md | javascript-typescript |
|
|
12
|
-
| testing.md | developer-kit |
|
|
13
|
-
| devops.md | developer-kit |
|
|
14
|
-
| prjct-planner.md | feature-dev |
|
|
15
|
-
| prjct-shipper.md | code-review |
|
|
16
|
-
|
|
17
|
-
## Installation (during `p. sync`)
|
|
18
|
-
|
|
19
|
-
1. Check existing: `ls ~/.claude/skills/*.md`
|
|
20
|
-
2. Search: `https://claude-plugins.dev/skills?q={term}`
|
|
21
|
-
3. Prefer: @anthropics, high downloads
|
|
22
|
-
4. Write to: `~/.claude/skills/{name}.md`
|
|
23
|
-
5. Save mapping: `{globalPath}/config/skills.json`
|
|
24
|
-
|
|
25
|
-
## Agent Frontmatter
|
|
26
|
-
|
|
27
|
-
```yaml
|
|
28
|
-
---
|
|
29
|
-
name: frontend
|
|
30
|
-
description: "Frontend specialist. Use PROACTIVELY."
|
|
31
|
-
tools: Read, Write, Glob, Grep
|
|
32
|
-
skills: [frontend-design]
|
|
33
|
-
---
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Usage
|
|
37
|
-
|
|
38
|
-
**During `p. task`**:
|
|
39
|
-
- Load agent → invoke linked skills
|
|
40
|
-
|
|
41
|
-
**During `p. ship`**:
|
|
42
|
-
- Invoke code-review skill
|
|
43
|
-
|
|
44
|
-
## Key Skills
|
|
45
|
-
|
|
46
|
-
| Skill | Purpose |
|
|
47
|
-
|-------|---------|
|
|
48
|
-
| frontend-design | UI components, anti-AI-slop |
|
|
49
|
-
| javascript-typescript | Node.js, React patterns |
|
|
50
|
-
| python-development | Django, FastAPI patterns |
|
|
51
|
-
| feature-dev | Architecture, planning |
|
|
52
|
-
| code-review | PR review, security |
|
|
53
|
-
| developer-kit | Testing, DevOps |
|
|
54
|
-
|
|
55
|
-
## Troubleshooting
|
|
56
|
-
|
|
57
|
-
- Skill not invoking? Check agent `skills:` frontmatter
|
|
58
|
-
- Wrong skill? Re-run `p. sync`
|
|
59
|
-
- Manual invoke: `/frontend-design`
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
# Sub-Agent Generation
|
|
2
|
-
|
|
3
|
-
Generate project-specific agents based on detected stack.
|
|
4
|
-
|
|
5
|
-
## Output Location
|
|
6
|
-
|
|
7
|
-
`{globalPath}/agents/` (NEVER local project)
|
|
8
|
-
|
|
9
|
-
## Agent Format
|
|
10
|
-
|
|
11
|
-
```markdown
|
|
12
|
-
---
|
|
13
|
-
name: agent-name
|
|
14
|
-
description: When to use. Include "Use PROACTIVELY" for auto-invoke.
|
|
15
|
-
tools: Read, Write, Glob, Grep, Bash
|
|
16
|
-
model: sonnet
|
|
17
|
-
skills: [skill-name]
|
|
18
|
-
---
|
|
19
|
-
Agent prompt...
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Required Workflow Agents
|
|
23
|
-
|
|
24
|
-
| Agent | Purpose | Skill |
|
|
25
|
-
|-------|---------|-------|
|
|
26
|
-
| prjct-workflow.md | Task lifecycle | - |
|
|
27
|
-
| prjct-planner.md | Feature planning | feature-dev |
|
|
28
|
-
| prjct-shipper.md | Git, deploy | code-review |
|
|
29
|
-
|
|
30
|
-
## Domain Agents (based on stack)
|
|
31
|
-
|
|
32
|
-
| If Detected | Generate | Skill |
|
|
33
|
-
|-------------|----------|-------|
|
|
34
|
-
| React, Vue, CSS | frontend.md | frontend-design |
|
|
35
|
-
| Node, Express, API | backend.md | javascript-typescript |
|
|
36
|
-
| PostgreSQL, MongoDB | database.md | - |
|
|
37
|
-
| Docker, CI/CD | devops.md | developer-kit |
|
|
38
|
-
| Jest, Pytest | testing.md | developer-kit |
|
|
39
|
-
| Any UI | uxui.md | frontend-design |
|
|
40
|
-
|
|
41
|
-
## Execution
|
|
42
|
-
|
|
43
|
-
1. Read `{globalPath}/analysis/repo-summary.md`
|
|
44
|
-
2. Create `{globalPath}/agents/` directory
|
|
45
|
-
3. Generate workflow agents (always)
|
|
46
|
-
4. Generate domain agents (based on analysis)
|
|
47
|
-
5. Add skills to frontmatter
|
|
48
|
-
6. Report generated agents
|
|
49
|
-
|
|
50
|
-
## Rules
|
|
51
|
-
|
|
52
|
-
- **ALWAYS** write to `{globalPath}/agents/`
|
|
53
|
-
- **NEVER** write to `.claude/` or `.prjct/`
|
|
54
|
-
- Adapt templates to project context
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: bug-severity
|
|
3
|
-
description: Assess bug severity from description
|
|
4
|
-
allowed-tools: [Read]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Bug Severity Assessment
|
|
8
|
-
|
|
9
|
-
Analyze the bug description to determine its severity and priority.
|
|
10
|
-
|
|
11
|
-
## Input
|
|
12
|
-
- Bug: {{description}}
|
|
13
|
-
- Context (if available)
|
|
14
|
-
|
|
15
|
-
## Severity Levels
|
|
16
|
-
|
|
17
|
-
### CRITICAL
|
|
18
|
-
- System crash or data loss
|
|
19
|
-
- Security vulnerability
|
|
20
|
-
- Blocks all users
|
|
21
|
-
- Production is down
|
|
22
|
-
|
|
23
|
-
### HIGH
|
|
24
|
-
- Major feature broken
|
|
25
|
-
- Significant user impact
|
|
26
|
-
- Workaround difficult
|
|
27
|
-
- Affects many users
|
|
28
|
-
|
|
29
|
-
### MEDIUM
|
|
30
|
-
- Feature partially broken
|
|
31
|
-
- Workaround exists
|
|
32
|
-
- Limited user impact
|
|
33
|
-
- Non-essential functionality
|
|
34
|
-
|
|
35
|
-
### LOW
|
|
36
|
-
- Minor inconvenience
|
|
37
|
-
- Cosmetic issue
|
|
38
|
-
- Edge case only
|
|
39
|
-
- Easy workaround
|
|
40
|
-
|
|
41
|
-
## Analysis Steps
|
|
42
|
-
|
|
43
|
-
1. **Assess Impact**
|
|
44
|
-
- Who is affected?
|
|
45
|
-
- How many users?
|
|
46
|
-
- Is there data loss risk?
|
|
47
|
-
|
|
48
|
-
2. **Check Urgency**
|
|
49
|
-
- Is production affected?
|
|
50
|
-
- Is there a deadline?
|
|
51
|
-
- Are users blocked?
|
|
52
|
-
|
|
53
|
-
3. **Evaluate Workaround**
|
|
54
|
-
- Can users continue working?
|
|
55
|
-
- How hard is the workaround?
|
|
56
|
-
|
|
57
|
-
## Output Format
|
|
58
|
-
|
|
59
|
-
Return JSON:
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"severity": "critical|high|medium|low",
|
|
63
|
-
"priority": 1-4,
|
|
64
|
-
"reasoning": "<brief explanation>",
|
|
65
|
-
"suggestedAction": "<what to do next>"
|
|
66
|
-
}
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Guidelines
|
|
70
|
-
|
|
71
|
-
- Err on the side of higher severity if unsure
|
|
72
|
-
- Security issues are always CRITICAL
|
|
73
|
-
- Data loss is always CRITICAL
|
|
74
|
-
- User-reported = add weight
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: complexity-analysis
|
|
3
|
-
description: Analyze task complexity semantically
|
|
4
|
-
allowed-tools: [Read]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Task Complexity Analysis
|
|
8
|
-
|
|
9
|
-
Analyze the given task description and determine its complexity level.
|
|
10
|
-
|
|
11
|
-
## Input
|
|
12
|
-
- Task: {{task}}
|
|
13
|
-
- Project context (if available)
|
|
14
|
-
|
|
15
|
-
## Analysis Steps
|
|
16
|
-
|
|
17
|
-
1. **Understand the Task**
|
|
18
|
-
- What is being asked?
|
|
19
|
-
- What systems/files are affected?
|
|
20
|
-
- Are there dependencies?
|
|
21
|
-
|
|
22
|
-
2. **Evaluate Scope**
|
|
23
|
-
- Single file change → LOW
|
|
24
|
-
- Multiple files, same module → MEDIUM
|
|
25
|
-
- Cross-module or architectural → HIGH
|
|
26
|
-
|
|
27
|
-
3. **Assess Risk**
|
|
28
|
-
- Read-only or additive → LOW risk
|
|
29
|
-
- Modifying existing logic → MEDIUM risk
|
|
30
|
-
- Refactoring or migration → HIGH risk
|
|
31
|
-
|
|
32
|
-
4. **Consider Dependencies**
|
|
33
|
-
- No external deps → LOW
|
|
34
|
-
- Some integration → MEDIUM
|
|
35
|
-
- Multiple systems → HIGH
|
|
36
|
-
|
|
37
|
-
## Output Format
|
|
38
|
-
|
|
39
|
-
Return JSON:
|
|
40
|
-
```json
|
|
41
|
-
{
|
|
42
|
-
"complexity": "low|medium|high",
|
|
43
|
-
"type": "feature|bugfix|refactor|testing|docs|chore",
|
|
44
|
-
"estimatedHours": <number>,
|
|
45
|
-
"reasoning": "<brief explanation>"
|
|
46
|
-
}
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Guidelines
|
|
50
|
-
|
|
51
|
-
- Be realistic, not optimistic
|
|
52
|
-
- Consider testing time in estimates
|
|
53
|
-
- If unsure, lean toward higher complexity
|
|
54
|
-
- Don't use keyword matching - analyze semantically
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: health-score
|
|
3
|
-
description: Calculate project health score
|
|
4
|
-
allowed-tools: [Read]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Project Health Score
|
|
8
|
-
|
|
9
|
-
Evaluate the project's health based on activity metrics.
|
|
10
|
-
|
|
11
|
-
## Input
|
|
12
|
-
- Active task: {{hasActiveTask}}
|
|
13
|
-
- Queue size: {{queueSize}}
|
|
14
|
-
- Recent ships: {{recentShips}}
|
|
15
|
-
- Ideas count: {{ideasCount}}
|
|
16
|
-
- Days since last ship: {{daysSinceShip}}
|
|
17
|
-
|
|
18
|
-
## Health Factors
|
|
19
|
-
|
|
20
|
-
### Momentum (40%)
|
|
21
|
-
- Active task = good
|
|
22
|
-
- Regular shipping = good
|
|
23
|
-
- Long gaps = concerning
|
|
24
|
-
|
|
25
|
-
### Focus (30%)
|
|
26
|
-
- Queue < 10 = focused
|
|
27
|
-
- Queue 10-20 = busy
|
|
28
|
-
- Queue > 20 = overloaded
|
|
29
|
-
|
|
30
|
-
### Progress (20%)
|
|
31
|
-
- Ships this week > 0 = active
|
|
32
|
-
- Ships this month > 2 = productive
|
|
33
|
-
- No ships in 7+ days = stalled
|
|
34
|
-
|
|
35
|
-
### Planning (10%)
|
|
36
|
-
- Ideas captured = thinking ahead
|
|
37
|
-
- Too many ideas = unfocused
|
|
38
|
-
|
|
39
|
-
## Score Calculation
|
|
40
|
-
|
|
41
|
-
Evaluate each factor and combine:
|
|
42
|
-
|
|
43
|
-
| Score | Label | Meaning |
|
|
44
|
-
|-------|-------|---------|
|
|
45
|
-
| 80-100 | Excellent | High momentum, focused, shipping |
|
|
46
|
-
| 60-79 | Good | Active, some room to improve |
|
|
47
|
-
| 40-59 | Fair | Slowing down, needs attention |
|
|
48
|
-
| 0-39 | Low | Stalled, intervention needed |
|
|
49
|
-
|
|
50
|
-
## Output Format
|
|
51
|
-
|
|
52
|
-
Return JSON:
|
|
53
|
-
```json
|
|
54
|
-
{
|
|
55
|
-
"score": <0-100>,
|
|
56
|
-
"label": "Excellent|Good|Fair|Low",
|
|
57
|
-
"momentum": "<assessment>",
|
|
58
|
-
"suggestions": ["<action 1>", "<action 2>"]
|
|
59
|
-
}
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Guidelines
|
|
63
|
-
|
|
64
|
-
- Be encouraging but honest
|
|
65
|
-
- Suggest specific actions
|
|
66
|
-
- Focus on momentum, not perfection
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: intent-detection
|
|
3
|
-
description: Detect user intent from natural language
|
|
4
|
-
allowed-tools: []
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Intent Detection
|
|
8
|
-
|
|
9
|
-
Analyze user input to determine their intent and map to appropriate action.
|
|
10
|
-
|
|
11
|
-
## Input
|
|
12
|
-
- User message: {{message}}
|
|
13
|
-
|
|
14
|
-
## Intent Categories
|
|
15
|
-
|
|
16
|
-
### Work Intents
|
|
17
|
-
- **start_task**: User wants to begin working on something
|
|
18
|
-
- **complete_task**: User finished current work
|
|
19
|
-
- **ship**: User wants to release/deploy
|
|
20
|
-
- **pause**: User needs to pause current work
|
|
21
|
-
|
|
22
|
-
### Planning Intents
|
|
23
|
-
- **add_feature**: User has a new feature idea
|
|
24
|
-
- **add_idea**: Quick thought to capture
|
|
25
|
-
- **add_bug**: Report a problem
|
|
26
|
-
- **view_queue**: See what's next
|
|
27
|
-
|
|
28
|
-
### Status Intents
|
|
29
|
-
- **check_progress**: View metrics/status
|
|
30
|
-
- **get_recap**: Project overview
|
|
31
|
-
- **get_help**: Need guidance
|
|
32
|
-
|
|
33
|
-
### System Intents
|
|
34
|
-
- **sync**: Update project state
|
|
35
|
-
- **analyze**: Analyze codebase
|
|
36
|
-
- **cleanup**: Clean up files
|
|
37
|
-
|
|
38
|
-
## Analysis
|
|
39
|
-
|
|
40
|
-
Look for semantic meaning, not keywords:
|
|
41
|
-
- "I'm done" → complete_task
|
|
42
|
-
- "Let's ship this" → ship
|
|
43
|
-
- "Quick thought..." → add_idea
|
|
44
|
-
- "What should I do?" → get_help OR view_queue
|
|
45
|
-
|
|
46
|
-
## Output Format
|
|
47
|
-
|
|
48
|
-
Return JSON:
|
|
49
|
-
```json
|
|
50
|
-
{
|
|
51
|
-
"intent": "<intent_name>",
|
|
52
|
-
"confidence": <0.0-1.0>,
|
|
53
|
-
"parameters": {
|
|
54
|
-
"task": "<extracted task if any>",
|
|
55
|
-
"feature": "<extracted feature if any>"
|
|
56
|
-
},
|
|
57
|
-
"suggestedCommand": "/p:<command>"
|
|
58
|
-
}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
## Guidelines
|
|
62
|
-
|
|
63
|
-
- Use semantic understanding, not regex
|
|
64
|
-
- Extract relevant parameters
|
|
65
|
-
- High confidence (>0.8) for clear intents
|
|
66
|
-
- Ask for clarification if < 0.5
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: task-breakdown
|
|
3
|
-
description: Break down a feature into actionable tasks
|
|
4
|
-
allowed-tools: [Read, Glob, Grep]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Feature Task Breakdown
|
|
8
|
-
|
|
9
|
-
Analyze the feature description and break it into concrete, actionable tasks.
|
|
10
|
-
|
|
11
|
-
## Input
|
|
12
|
-
- Feature: {{feature}}
|
|
13
|
-
- Project path: {{projectPath}}
|
|
14
|
-
|
|
15
|
-
## Analysis Steps
|
|
16
|
-
|
|
17
|
-
1. **Understand the Feature**
|
|
18
|
-
- Read related code if paths are obvious
|
|
19
|
-
- Identify affected systems
|
|
20
|
-
- Note existing patterns to follow
|
|
21
|
-
|
|
22
|
-
2. **Identify Components**
|
|
23
|
-
- What new files/modules are needed?
|
|
24
|
-
- What existing code needs modification?
|
|
25
|
-
- What tests are required?
|
|
26
|
-
|
|
27
|
-
3. **Order by Dependencies**
|
|
28
|
-
- Foundation tasks first (models, types, interfaces)
|
|
29
|
-
- Core logic second
|
|
30
|
-
- Integration third
|
|
31
|
-
- Tests and polish last
|
|
32
|
-
|
|
33
|
-
4. **Size Each Task**
|
|
34
|
-
- Each task should be 20-60 minutes
|
|
35
|
-
- If larger, break down further
|
|
36
|
-
- If smaller, combine with related task
|
|
37
|
-
|
|
38
|
-
## Output Format
|
|
39
|
-
|
|
40
|
-
Return a numbered task list:
|
|
41
|
-
```
|
|
42
|
-
1. [20m] Task description - specific action
|
|
43
|
-
2. [30m] Another task - what exactly to do
|
|
44
|
-
3. [45m] Final task - clear deliverable
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Guidelines
|
|
48
|
-
|
|
49
|
-
- Tasks must be specific and actionable
|
|
50
|
-
- Include time estimates in brackets
|
|
51
|
-
- Order matters - dependencies first
|
|
52
|
-
- Don't assume - if unsure, read code first
|
|
53
|
-
- Match project patterns (read existing code)
|