prjct-cli 0.18.0 → 0.18.1
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/core/agentic/agent-router.ts +21 -75
- package/package.json +1 -1
- package/templates/commands/sync.md +36 -0
|
@@ -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
|
|
6
|
-
*
|
|
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
|
-
*
|
|
8
|
+
* Agents are dynamically generated by /p:sync based on project tech stack.
|
|
10
9
|
*
|
|
11
10
|
* @module agentic/agent-router
|
|
12
|
-
* @version
|
|
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
|
-
|
|
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.
|
|
47
|
+
this.agentsPath = pathManager.getFilePath(this.projectId!, 'agents', '')
|
|
58
48
|
}
|
|
59
49
|
|
|
60
50
|
/**
|
|
61
|
-
* Load agents from
|
|
51
|
+
* Load all available agents from global storage
|
|
62
52
|
*/
|
|
63
|
-
|
|
64
|
-
agentsPath
|
|
65
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
@@ -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`
|