prjct-cli 0.18.0 → 0.18.2

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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.18.2] - 2025-12-15
4
+
5
+ ### Fix: Agents Write to Global Storage
6
+
7
+ Fixed critical bug where sub-agents were being written to project's local `.claude/agents/` directory instead of global storage.
8
+
9
+ - **Bug**: `/p:sync` created agents in `{projectPath}/.claude/agents/` polluting local projects
10
+ - **Fix**: Agents now correctly write to `~/.prjct-cli/projects/{projectId}/agents/`
11
+
12
+ **Files Modified:**
13
+ - `templates/commands/sync.md` - Changed all agent paths from `{cwd}/.claude/agents/` to `{globalPath}/agents/`
14
+ - `templates/agentic/subagent-generation.md` - Updated paths and added critical rules
15
+
3
16
  ## [0.16.0] - 2025-12-15
4
17
 
5
18
  ### Dead Code Cleanup
@@ -2,14 +2,13 @@
2
2
  * Agent Router
3
3
  * Orchestrates agent loading and context building for Claude delegation.
4
4
  *
5
- * Loads agents from two locations:
6
- * 1. {projectPath}/.claude/agents/ - Claude Code sub-agents (PRIMARY, per-project)
7
- * 2. ~/.prjct-cli/projects/{id}/agents/ - Legacy agents (fallback)
5
+ * Loads agents from global storage:
6
+ * ~/.prjct-cli/projects/{id}/agents/
8
7
  *
9
- * Claude Code sub-agents are prioritized as they're more specific to the project.
8
+ * Agents are dynamically generated by /p:sync based on project tech stack.
10
9
  *
11
10
  * @module agentic/agent-router
12
- * @version 3.0.0
11
+ * @version 4.0.0
13
12
  */
14
13
 
15
14
  import fs from 'fs/promises'
@@ -20,7 +19,6 @@ import pathManager from '../infrastructure/path-manager'
20
19
  interface Agent {
21
20
  name: string
22
21
  content: string
23
- source: 'claude-code' | 'legacy'
24
22
  }
25
23
 
26
24
  interface AssignmentContext {
@@ -38,15 +36,7 @@ interface AssignmentContext {
38
36
  class AgentRouter {
39
37
  projectId: string | null = null
40
38
  projectPath: string | null = null
41
- legacyAgentsPath: string | null = null
42
-
43
- /**
44
- * Get path to Claude Code sub-agents directory
45
- */
46
- getClaudeCodeAgentsPath(): string | null {
47
- if (!this.projectPath) return null
48
- return path.join(this.projectPath, '.claude', 'agents')
49
- }
39
+ agentsPath: string | null = null
50
40
 
51
41
  /**
52
42
  * Initialize router with project context
@@ -54,25 +44,24 @@ class AgentRouter {
54
44
  async initialize(projectPath: string): Promise<void> {
55
45
  this.projectId = await configManager.getProjectId(projectPath)
56
46
  this.projectPath = projectPath
57
- this.legacyAgentsPath = pathManager.getFilePath(this.projectId!, 'agents', '')
47
+ this.agentsPath = pathManager.getFilePath(this.projectId!, 'agents', '')
58
48
  }
59
49
 
60
50
  /**
61
- * Load agents from a specific directory
51
+ * Load all available agents from global storage
62
52
  */
63
- private async loadAgentsFromPath(
64
- agentsPath: string,
65
- source: 'claude-code' | 'legacy'
66
- ): Promise<Agent[]> {
53
+ async loadAvailableAgents(): Promise<Agent[]> {
54
+ if (!this.agentsPath) return []
55
+
67
56
  try {
68
- const files = await fs.readdir(agentsPath)
57
+ const files = await fs.readdir(this.agentsPath)
69
58
  const agents: Agent[] = []
70
59
 
71
60
  for (const file of files) {
72
61
  if (file.endsWith('.md')) {
73
62
  const name = file.replace('.md', '')
74
- const content = await fs.readFile(path.join(agentsPath, file), 'utf-8')
75
- agents.push({ name, content, source })
63
+ const content = await fs.readFile(path.join(this.agentsPath, file), 'utf-8')
64
+ agents.push({ name, content })
76
65
  }
77
66
  }
78
67
 
@@ -82,33 +71,6 @@ class AgentRouter {
82
71
  }
83
72
  }
84
73
 
85
- /**
86
- * Load all available agents from both Claude Code and legacy locations
87
- * Claude Code sub-agents take priority over legacy agents with same name
88
- */
89
- async loadAvailableAgents(): Promise<Agent[]> {
90
- const agentMap = new Map<string, Agent>()
91
-
92
- // Load legacy agents first (lower priority)
93
- if (this.legacyAgentsPath) {
94
- const legacyAgents = await this.loadAgentsFromPath(this.legacyAgentsPath, 'legacy')
95
- for (const agent of legacyAgents) {
96
- agentMap.set(agent.name, agent)
97
- }
98
- }
99
-
100
- // Load Claude Code sub-agents (higher priority - overwrites legacy)
101
- const claudeCodePath = this.getClaudeCodeAgentsPath()
102
- if (claudeCodePath) {
103
- const claudeCodeAgents = await this.loadAgentsFromPath(claudeCodePath, 'claude-code')
104
- for (const agent of claudeCodeAgents) {
105
- agentMap.set(agent.name, agent)
106
- }
107
- }
108
-
109
- return Array.from(agentMap.values())
110
- }
111
-
112
74
  /**
113
75
  * Get list of available agent names
114
76
  */
@@ -118,34 +80,18 @@ class AgentRouter {
118
80
  }
119
81
 
120
82
  /**
121
- * Load a specific agent by name
122
- * Checks Claude Code sub-agents first, then falls back to legacy
83
+ * Load a specific agent by name from global storage
123
84
  */
124
85
  async loadAgent(name: string): Promise<Agent | null> {
125
- // Try Claude Code sub-agents first (higher priority)
126
- const claudeCodePath = this.getClaudeCodeAgentsPath()
127
- if (claudeCodePath) {
128
- try {
129
- const filePath = path.join(claudeCodePath, `${name}.md`)
130
- const content = await fs.readFile(filePath, 'utf-8')
131
- return { name, content, source: 'claude-code' }
132
- } catch {
133
- // Not found in Claude Code path, try legacy
134
- }
135
- }
86
+ if (!this.agentsPath) return null
136
87
 
137
- // Fall back to legacy agents
138
- if (this.legacyAgentsPath) {
139
- try {
140
- const filePath = path.join(this.legacyAgentsPath, `${name}.md`)
141
- const content = await fs.readFile(filePath, 'utf-8')
142
- return { name, content, source: 'legacy' }
143
- } catch {
144
- // Not found
145
- }
88
+ try {
89
+ const filePath = path.join(this.agentsPath, `${name}.md`)
90
+ const content = await fs.readFile(filePath, 'utf-8')
91
+ return { name, content }
92
+ } catch {
93
+ return null
146
94
  }
147
-
148
- return null
149
95
  }
150
96
 
151
97
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prjct-cli",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
4
4
  "description": "Built for Claude - Ship fast, track progress, stay focused. Developer momentum tool for indie hackers.",
5
5
  "main": "core/index.ts",
6
6
  "bin": {
@@ -11,7 +11,7 @@ You have access to:
11
11
 
12
12
  ## Output Location
13
13
 
14
- Write sub-agents to: `{projectPath}/.claude/agents/`
14
+ Write sub-agents to: `{globalPath}/agents/` (global storage, NOT local project)
15
15
 
16
16
  ## Sub-Agent Format (Claude Code)
17
17
 
@@ -70,29 +70,29 @@ Each generated agent should include:
70
70
 
71
71
  1. **Read Analysis**
72
72
  ```
73
- Read("{projectPath}/.prjct-cli/projects/{projectId}/analysis/repo-summary.md")
73
+ Read("{globalPath}/analysis/repo-summary.md")
74
74
  ```
75
75
 
76
76
  2. **Create Directory**
77
77
  ```
78
- Bash("mkdir -p {projectPath}/.claude/agents")
78
+ Bash("mkdir -p {globalPath}/agents")
79
79
  ```
80
80
 
81
81
  3. **Generate Workflow Agents** (always)
82
82
  - Read template from `templates/subagents/workflow/prjct-workflow.md`
83
83
  - Adapt with project context
84
- - Write to `{projectPath}/.claude/agents/prjct-workflow.md`
84
+ - Write to `{globalPath}/agents/prjct-workflow.md`
85
85
  - Repeat for prjct-planner.md and prjct-shipper.md
86
86
 
87
87
  4. **Generate Domain Agents** (based on analysis)
88
88
  - For each detected technology stack:
89
89
  - Read corresponding template from `templates/subagents/domain/`
90
90
  - Adapt with project-specific details
91
- - Write to `{projectPath}/.claude/agents/`
91
+ - Write to `{globalPath}/agents/`
92
92
 
93
93
  5. **Report Generated Agents**
94
94
  ```
95
- Generated sub-agents in .claude/agents/:
95
+ Generated sub-agents in {globalPath}/agents/:
96
96
  - prjct-workflow.md (workflow)
97
97
  - prjct-planner.md (workflow)
98
98
  - prjct-shipper.md (workflow)
@@ -102,6 +102,8 @@ Each generated agent should include:
102
102
 
103
103
  ## Critical Rules
104
104
 
105
+ - **NEVER write agents to local project directories** (`.claude/`, `.prjct/`)
106
+ - **ALWAYS write agents to `{globalPath}/agents/`** (global storage)
105
107
  - NEVER hardcode technology detection in TypeScript
106
108
  - ALWAYS read and analyze repo-summary.md
107
109
  - ADAPT templates to project context
@@ -54,6 +54,42 @@ Git Analysis → Storage (JSON) → Context (MD) → Project Metadata
54
54
 
55
55
  ---
56
56
 
57
+ ## Step 0: Migration Check (Legacy Projects)
58
+
59
+ CHECK: Does `.prjct/prjct.config.json` exist?
60
+
61
+ IF file exists:
62
+ READ: `.prjct/prjct.config.json`
63
+ CHECK: Does `projectId` exist and is it a valid UUID?
64
+
65
+ IF projectId is missing OR not a UUID:
66
+ MIGRATE to UUID:
67
+ 1. Generate new UUID: `{newProjectId}`
68
+ 2. Create global structure: `~/.prjct-cli/projects/{newProjectId}/`
69
+ 3. Create subdirectories: storage/, context/, agents/, memory/, analysis/
70
+ 4. IF legacy data exists in `.prjct/`:
71
+ - Migrate core/now.md → storage/state.json
72
+ - Migrate planning/ideas.md → storage/ideas.json
73
+ - Migrate progress/shipped.md → storage/shipped.json
74
+ 5. Update `.prjct/prjct.config.json` with new `projectId`
75
+ OUTPUT: "🔄 Migrated to UUID format: {newProjectId}"
76
+
77
+ IF file not found:
78
+ CHECK: Does `.prjct/` directory exist? (legacy project without config)
79
+
80
+ IF `.prjct/` exists:
81
+ MIGRATE:
82
+ 1. Generate new UUID: `{newProjectId}`
83
+ 2. Create `.prjct/prjct.config.json` with `projectId`
84
+ 3. Create global structure
85
+ 4. Migrate legacy data
86
+ OUTPUT: "🔄 Migrated legacy project to UUID: {newProjectId}"
87
+ ELSE:
88
+ OUTPUT: "No prjct project. Run /p:init first."
89
+ STOP
90
+
91
+ ---
92
+
57
93
  ## Step 1: Read Config
58
94
 
59
95
  READ: `.prjct/prjct.config.json`
@@ -338,12 +374,12 @@ WRITE: `{globalPath}/project.json`
338
374
 
339
375
  ## Step 7: Generate Claude Code Sub-Agents (AGENTIC)
340
376
 
341
- Generate sub-agents for Claude Code in the PROJECT's `.claude/agents/` directory.
377
+ Generate sub-agents for Claude Code in the GLOBAL storage `{globalPath}/agents/` directory.
342
378
 
343
379
  ### 7.1 Create Directory
344
380
 
345
381
  ```bash
346
- mkdir -p {cwd}/.claude/agents
382
+ mkdir -p {globalPath}/agents
347
383
  ```
348
384
 
349
385
  ### 7.2 Read Generation Instructions
@@ -362,17 +398,17 @@ These 3 agents are ALWAYS created for every prjct project:
362
398
  **prjct-workflow.md** - Handles: /p:now, /p:done, /p:next, /p:pause, /p:resume
363
399
  READ template: `templates/subagents/workflow/prjct-workflow.md`
364
400
  ADAPT with: projectId, projectPath
365
- WRITE to: `{cwd}/.claude/agents/prjct-workflow.md`
401
+ WRITE to: `{globalPath}/agents/prjct-workflow.md`
366
402
 
367
403
  **prjct-planner.md** - Handles: /p:feature, /p:idea, /p:spec, /p:bug
368
404
  READ template: `templates/subagents/workflow/prjct-planner.md`
369
405
  ADAPT with: projectId, projectPath
370
- WRITE to: `{cwd}/.claude/agents/prjct-planner.md`
406
+ WRITE to: `{globalPath}/agents/prjct-planner.md`
371
407
 
372
408
  **prjct-shipper.md** - Handles: /p:ship
373
409
  READ template: `templates/subagents/workflow/prjct-shipper.md`
374
410
  ADAPT with: projectId, projectPath, detected test/lint commands
375
- WRITE to: `{cwd}/.claude/agents/prjct-shipper.md`
411
+ WRITE to: `{globalPath}/agents/prjct-shipper.md`
376
412
 
377
413
  ### 7.4 Generate Domain Agents (Based on Stack)
378
414
 
@@ -389,7 +425,7 @@ Analyze `{techStack}` from Step 3 and generate ONLY relevant domain agents:
389
425
  For EACH detected stack:
390
426
  1. READ template from `templates/subagents/domain/{name}.md`
391
427
  2. ADAPT description with detected frameworks (e.g., "React specialist" not just "frontend")
392
- 3. WRITE to `{cwd}/.claude/agents/{name}.md`
428
+ 3. WRITE to `{globalPath}/agents/{name}.md`
393
429
 
394
430
  ### 7.5 Report Generated Agents
395
431
 
@@ -537,7 +573,7 @@ Next: /p:now to start a new task
537
573
  │ └── events.jsonl
538
574
  └── project.json # Metadata
539
575
 
540
- {cwd}/.claude/agents/ # Claude Code Sub-Agents (PER PROJECT)
576
+ # Sub-Agents are in {globalPath}/agents/ (NOT in project .claude/)
541
577
  ├── prjct-workflow.md # /p:now, /p:done, /p:next
542
578
  ├── prjct-planner.md # /p:feature, /p:idea, /p:spec
543
579
  ├── prjct-shipper.md # /p:ship