prizmkit 1.1.118 → 1.1.120
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/bin/create-prizmkit.js +1 -5
- package/bundled/VERSION.json +3 -3
- package/bundled/dev-pipeline/README.md +41 -38
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +76 -0
- package/bundled/dev-pipeline/prizmkit_runtime/config.py +2 -8
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +2 -4
- package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -1
- package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +3 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +21 -11
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +45 -3
- package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +28 -6
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +60 -102
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -19
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -19
- package/bundled/dev-pipeline/scripts/{init-dev-team.py → init-change-artifact.py} +6 -16
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +364 -76
- package/bundled/dev-pipeline/scripts/utils.py +1 -1
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +7 -9
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +2 -2
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
- package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +6 -7
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +6 -7
- package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +4 -2
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +2 -2
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -2
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +20 -0
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +2 -2
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +204 -141
- package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +16 -10
- package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +2 -13
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +13 -14
- package/bundled/dev-pipeline/tests/test_unified_cli.py +227 -7
- package/bundled/skills/_metadata.json +1 -1
- package/bundled/skills/app-planner/SKILL.md +2 -2
- package/bundled/skills/app-planner/references/architecture-decisions.md +1 -3
- package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +4 -2
- package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +40 -1
- package/bundled/skills/feature-pipeline-launcher/SKILL.md +4 -2
- package/bundled/skills/feature-pipeline-launcher/references/configuration.md +40 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +16 -14
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +9 -9
- package/bundled/skills/prizmkit-implement/SKILL.md +21 -1
- package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +67 -0
- package/bundled/skills/refactor-pipeline-launcher/SKILL.md +4 -2
- package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +40 -1
- package/package.json +1 -1
- package/src/clean.js +12 -8
- package/src/config.js +24 -42
- package/src/index.js +1 -10
- package/src/manifest.js +3 -9
- package/src/metadata.js +0 -26
- package/src/prompts.js +0 -13
- package/src/scaffold.js +76 -201
- package/src/upgrade.js +16 -33
- package/bundled/adapters/claude/agent-adapter.js +0 -96
- package/bundled/adapters/claude/team-adapter.js +0 -183
- package/bundled/adapters/codebuddy/agent-adapter.js +0 -42
- package/bundled/adapters/codebuddy/team-adapter.js +0 -46
- package/bundled/adapters/codex/agent-adapter.js +0 -38
- package/bundled/adapters/codex/team-adapter.js +0 -37
- package/bundled/agents/prizm-dev-team-dev.md +0 -123
- package/bundled/agents/prizm-dev-team-reviewer.md +0 -113
- package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +0 -65
- package/bundled/dev-pipeline/templates/bootstrap-tier1.md +0 -436
- package/bundled/dev-pipeline/templates/bootstrap-tier2.md +0 -510
- package/bundled/team/prizm-dev-team.json +0 -27
package/src/index.js
CHANGED
|
@@ -70,7 +70,6 @@ export async function runScaffold(directory, options) {
|
|
|
70
70
|
platform: options.platform,
|
|
71
71
|
runtime: normalizeRuntime(options.runtime),
|
|
72
72
|
skills: options.skills || 'core',
|
|
73
|
-
team: options.team !== false,
|
|
74
73
|
pipeline: options.pipeline !== false,
|
|
75
74
|
playwrightCli: options.playwrightCli !== false,
|
|
76
75
|
openCli: options.openCli !== false,
|
|
@@ -155,13 +154,7 @@ export async function runScaffold(directory, options) {
|
|
|
155
154
|
});
|
|
156
155
|
}
|
|
157
156
|
|
|
158
|
-
// 3.
|
|
159
|
-
const team = await confirm({
|
|
160
|
-
message: '启用多 Agent 团队模式 (prizm-dev-team)?',
|
|
161
|
-
default: true,
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
// 4. Pipeline
|
|
157
|
+
// 3. Pipeline
|
|
165
158
|
const pipeline = await confirm({
|
|
166
159
|
message: '安装自动化流水线 (dev-pipeline)?',
|
|
167
160
|
default: true,
|
|
@@ -209,7 +202,6 @@ export async function runScaffold(directory, options) {
|
|
|
209
202
|
console.log(` 运行时: ${chalk.cyan(runtimeLabel(runtime))}`);
|
|
210
203
|
console.log(` 平台: ${chalk.cyan(selectedPlatformLabel)}`);
|
|
211
204
|
console.log(` 技能: ${chalk.cyan(suiteLabel)}`);
|
|
212
|
-
console.log(` 团队模式: ${team ? chalk.green('启用') : chalk.gray('禁用')}`);
|
|
213
205
|
console.log(` 流水线: ${pipeline ? chalk.green('启用') : chalk.gray('禁用')}`);
|
|
214
206
|
const browserToolsLabel = [playwrightCli && 'playwright-cli', openCli && 'opencli'].filter(Boolean);
|
|
215
207
|
console.log(` 浏览器工具: ${browserToolsLabel.length ? chalk.green(browserToolsLabel.join(' + ')) : chalk.gray('禁用')}`);
|
|
@@ -234,7 +226,6 @@ export async function runScaffold(directory, options) {
|
|
|
234
226
|
platform,
|
|
235
227
|
runtime,
|
|
236
228
|
skills: skillSuite,
|
|
237
|
-
team,
|
|
238
229
|
pipeline,
|
|
239
230
|
playwrightCli,
|
|
240
231
|
openCli,
|
package/src/manifest.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manifest management for PrizmKit installations.
|
|
3
3
|
*
|
|
4
|
-
* Tracks what was installed (skills,
|
|
4
|
+
* Tracks what was installed (skills, rules, pipeline, extras) so that
|
|
5
5
|
* `upgrade` can diff old vs new and `uninstall` can clean orphaned files.
|
|
6
6
|
*
|
|
7
7
|
* Manifest is written to <projectRoot>/.prizmkit/manifest.json
|
|
@@ -52,10 +52,8 @@ export async function writeManifest(projectRoot, data) {
|
|
|
52
52
|
* @param {string} [params.runtime] - canonical Python runtime id or compatibility alias
|
|
53
53
|
* @param {string} params.suite - skill suite name
|
|
54
54
|
* @param {string[]} params.skills - resolved skill name list
|
|
55
|
-
* @param {string[]} params.agents - agent file names (e.g. ['prizm-dev-team-dev.md'])
|
|
56
55
|
* @param {string[]} params.rules - rule file names (e.g. ['prizm-documentation.md'])
|
|
57
56
|
* @param {string[]} params.pipeline - pipeline file relative paths (or falsy if not installed)
|
|
58
|
-
* @param {boolean} params.team - whether team config was installed
|
|
59
57
|
* @param {string} [params.aiCli] - AI CLI command
|
|
60
58
|
* @param {string} [params.rulesPreset] - rules preset name
|
|
61
59
|
* @param {string[]} [params.payloadPlatforms] - concrete platform payloads installed for platform + aiCli
|
|
@@ -67,10 +65,8 @@ export function buildManifest({
|
|
|
67
65
|
runtime,
|
|
68
66
|
suite,
|
|
69
67
|
skills,
|
|
70
|
-
agents,
|
|
71
68
|
rules,
|
|
72
69
|
pipeline,
|
|
73
|
-
team,
|
|
74
70
|
aiCli,
|
|
75
71
|
rulesPreset,
|
|
76
72
|
extras,
|
|
@@ -88,14 +84,12 @@ export function buildManifest({
|
|
|
88
84
|
runtime: normalizeRuntime(runtime),
|
|
89
85
|
suite,
|
|
90
86
|
options: {
|
|
91
|
-
team: Boolean(team),
|
|
92
87
|
pipeline: Array.isArray(pipeline) ? pipeline.length > 0 : Boolean(pipeline),
|
|
93
88
|
rules: rulesPreset || 'recommended',
|
|
94
89
|
aiCli: aiCli || '',
|
|
95
90
|
},
|
|
96
91
|
files: {
|
|
97
92
|
skills: [...skills],
|
|
98
|
-
agents: [...agents],
|
|
99
93
|
rules: [...rules],
|
|
100
94
|
pipeline: pipeline ? [...pipeline] : [],
|
|
101
95
|
extras: extras ? [...extras] : [],
|
|
@@ -113,7 +107,7 @@ export function buildManifest({
|
|
|
113
107
|
* Diff two manifests and return added/removed items.
|
|
114
108
|
* @param {Object} oldManifest - previous manifest
|
|
115
109
|
* @param {Object} newManifest - new manifest to compare against
|
|
116
|
-
* @returns {Object} { skills: {added, removed},
|
|
110
|
+
* @returns {Object} { skills: {added, removed}, rules: {added, removed}, pipeline: {added, removed}, extras: {added, removed}, legacyAgents: {added, removed} }
|
|
117
111
|
*/
|
|
118
112
|
export function diffManifest(oldManifest, newManifest) {
|
|
119
113
|
function diffArrays(oldArr, newArr) {
|
|
@@ -127,12 +121,12 @@ export function diffManifest(oldManifest, newManifest) {
|
|
|
127
121
|
|
|
128
122
|
return {
|
|
129
123
|
skills: diffArrays(oldManifest?.files?.skills, newManifest?.files?.skills),
|
|
130
|
-
agents: diffArrays(oldManifest?.files?.agents, newManifest?.files?.agents),
|
|
131
124
|
rules: diffArrays(oldManifest?.files?.rules, newManifest?.files?.rules),
|
|
132
125
|
pipeline: diffArrays(
|
|
133
126
|
Array.isArray(oldManifest?.files?.pipeline) ? oldManifest.files.pipeline : [],
|
|
134
127
|
Array.isArray(newManifest?.files?.pipeline) ? newManifest.files.pipeline : [],
|
|
135
128
|
),
|
|
136
129
|
extras: diffArrays(oldManifest?.files?.extras, newManifest?.files?.extras),
|
|
130
|
+
legacyAgents: diffArrays(oldManifest?.files?.agents, []),
|
|
137
131
|
};
|
|
138
132
|
}
|
package/src/metadata.js
CHANGED
|
@@ -94,32 +94,6 @@ export function getSkillCandidatePaths(skillName, skillDef = {}, runtime = 'pyth
|
|
|
94
94
|
return candidates;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
/**
|
|
98
|
-
* 获取 core agents 目录路径
|
|
99
|
-
*/
|
|
100
|
-
export function getAgentsDir() {
|
|
101
|
-
const bundledDir = path.join(getBundledRoot(), 'agents');
|
|
102
|
-
const coreDir = path.join(getFrameworkRoot(), 'core', 'agents');
|
|
103
|
-
|
|
104
|
-
if (fs.pathExistsSync(bundledDir)) return bundledDir;
|
|
105
|
-
if (fs.pathExistsSync(coreDir)) return coreDir;
|
|
106
|
-
|
|
107
|
-
throw new Error('无法找到 Agents 目录。');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* 获取 core team 目录路径
|
|
112
|
-
*/
|
|
113
|
-
export function getTeamDir() {
|
|
114
|
-
const bundledDir = path.join(getBundledRoot(), 'team');
|
|
115
|
-
const coreDir = path.join(getFrameworkRoot(), 'core', 'team');
|
|
116
|
-
|
|
117
|
-
if (fs.pathExistsSync(bundledDir)) return bundledDir;
|
|
118
|
-
if (fs.pathExistsSync(coreDir)) return coreDir;
|
|
119
|
-
|
|
120
|
-
throw new Error('无法找到 Team 目录。');
|
|
121
|
-
}
|
|
122
|
-
|
|
123
97
|
/**
|
|
124
98
|
* 获取 templates 目录路径
|
|
125
99
|
*/
|
package/src/prompts.js
CHANGED
|
@@ -234,19 +234,6 @@ export async function selectExternalSkills(currentSkills, metadata) {
|
|
|
234
234
|
return selectedSkills;
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
/**
|
|
238
|
-
* Confirm team mode setting.
|
|
239
|
-
* @param {boolean} currentValue - current team mode value
|
|
240
|
-
* @returns {Promise<boolean>}
|
|
241
|
-
*/
|
|
242
|
-
export async function confirmTeamMode(currentValue = true) {
|
|
243
|
-
const team = await confirm({
|
|
244
|
-
message: '启用多 Agent 团队模式 (prizm-dev-team)?',
|
|
245
|
-
default: currentValue,
|
|
246
|
-
});
|
|
247
|
-
return team;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
237
|
/**
|
|
251
238
|
* Confirm pipeline setting.
|
|
252
239
|
* @param {boolean} currentValue - current pipeline value
|
package/src/scaffold.js
CHANGED
|
@@ -16,8 +16,6 @@ import { dirname, join } from 'path';
|
|
|
16
16
|
import { execSync } from 'child_process';
|
|
17
17
|
import {
|
|
18
18
|
loadMetadata,
|
|
19
|
-
getAgentsDir,
|
|
20
|
-
getTeamDir,
|
|
21
19
|
getTemplatesDir,
|
|
22
20
|
getPipelineDir,
|
|
23
21
|
getAdaptersDir,
|
|
@@ -82,6 +80,74 @@ const RETIRED_POWERSHELL_RUNTIME_FILES = new Set([
|
|
|
82
80
|
'lib/branch.ps1',
|
|
83
81
|
'lib/heartbeat.ps1',
|
|
84
82
|
]);
|
|
83
|
+
const LEGACY_TEAM_NAME = ['prizm', 'dev', 'team'].join('-');
|
|
84
|
+
const LEGACY_AGENT_BASENAMES = [
|
|
85
|
+
`${LEGACY_TEAM_NAME}-dev`,
|
|
86
|
+
`${LEGACY_TEAM_NAME}-reviewer`,
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
async function removeEmptyDirectory(dirPath) {
|
|
90
|
+
if (!await fs.pathExists(dirPath)) return;
|
|
91
|
+
const entries = await fs.readdir(dirPath);
|
|
92
|
+
if (entries.length === 0) {
|
|
93
|
+
await fs.remove(dirPath);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export async function removeRetiredAgentTeamArtifacts(platform, projectRoot, dryRun) {
|
|
98
|
+
const agentDir = platform === 'claude'
|
|
99
|
+
? path.join(projectRoot, '.claude', 'agents')
|
|
100
|
+
: platform === 'codex'
|
|
101
|
+
? path.join(projectRoot, '.codex', 'agents')
|
|
102
|
+
: path.join(projectRoot, '.codebuddy', 'agents');
|
|
103
|
+
const agentExtensions = platform === 'codex' ? ['.toml', '.md'] : ['.md'];
|
|
104
|
+
|
|
105
|
+
for (const basename of LEGACY_AGENT_BASENAMES) {
|
|
106
|
+
for (const extension of agentExtensions) {
|
|
107
|
+
const filePath = path.join(agentDir, `${basename}${extension}`);
|
|
108
|
+
if (!await fs.pathExists(filePath)) continue;
|
|
109
|
+
if (dryRun) {
|
|
110
|
+
console.log(chalk.gray(` [dry-run] remove retired ${path.relative(projectRoot, filePath)}`));
|
|
111
|
+
} else {
|
|
112
|
+
await fs.remove(filePath);
|
|
113
|
+
console.log(chalk.red(` ✗ removed retired ${path.relative(projectRoot, filePath)}`));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (!dryRun) {
|
|
119
|
+
await removeEmptyDirectory(agentDir);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const teamInfoPath = platform === 'claude'
|
|
123
|
+
? path.join(projectRoot, '.claude', 'team-info.json')
|
|
124
|
+
: platform === 'codex'
|
|
125
|
+
? path.join(projectRoot, '.codex', 'team-info.json')
|
|
126
|
+
: path.join(projectRoot, '.codebuddy', 'team-info.json');
|
|
127
|
+
if (await fs.pathExists(teamInfoPath)) {
|
|
128
|
+
if (dryRun) {
|
|
129
|
+
console.log(chalk.gray(` [dry-run] remove retired ${path.relative(projectRoot, teamInfoPath)}`));
|
|
130
|
+
} else {
|
|
131
|
+
await fs.remove(teamInfoPath);
|
|
132
|
+
console.log(chalk.red(` ✗ removed retired ${path.relative(projectRoot, teamInfoPath)}`));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (platform === 'codebuddy') {
|
|
137
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
138
|
+
if (homeDir) {
|
|
139
|
+
const globalTeamDir = path.join(homeDir, '.codebuddy', 'teams', LEGACY_TEAM_NAME);
|
|
140
|
+
if (await fs.pathExists(globalTeamDir)) {
|
|
141
|
+
if (dryRun) {
|
|
142
|
+
console.log(chalk.gray(' [dry-run] remove retired global CodeBuddy team config'));
|
|
143
|
+
} else {
|
|
144
|
+
await fs.remove(globalTeamDir);
|
|
145
|
+
console.log(chalk.red(' ✗ removed retired global CodeBuddy team config'));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
85
151
|
|
|
86
152
|
// ============================================================
|
|
87
153
|
// Adapter 动态加载
|
|
@@ -282,186 +348,9 @@ export async function installSkills(platform, skills, projectRoot, dryRun, runti
|
|
|
282
348
|
}
|
|
283
349
|
|
|
284
350
|
/**
|
|
285
|
-
*
|
|
286
|
-
|
|
287
|
-
export async function installAgents(platform, projectRoot, dryRun) {
|
|
288
|
-
const agentsDir = getAgentsDir();
|
|
289
|
-
const agentFiles = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
|
|
290
|
-
|
|
291
|
-
// Load Claude agent adapter
|
|
292
|
-
let convertAgentFn;
|
|
293
|
-
if (platform === 'claude') {
|
|
294
|
-
const agentAdapter = await loadAdapter('claude', 'agent-adapter.js');
|
|
295
|
-
convertAgentFn = agentAdapter.convertAgent;
|
|
296
|
-
} else if (platform === 'codex') {
|
|
297
|
-
const agentAdapter = await loadAdapter('codex', 'agent-adapter.js');
|
|
298
|
-
convertAgentFn = agentAdapter.convertAgent;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
for (const file of agentFiles) {
|
|
302
|
-
const content = await fs.readFile(path.join(agentsDir, file), 'utf8');
|
|
303
|
-
|
|
304
|
-
if (platform === 'codebuddy') {
|
|
305
|
-
const targetDir = path.join(projectRoot, '.codebuddy', 'agents');
|
|
306
|
-
if (dryRun) {
|
|
307
|
-
console.log(chalk.gray(` [dry-run] .codebuddy/agents/${file}`));
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
await fs.ensureDir(targetDir);
|
|
311
|
-
await fs.writeFile(path.join(targetDir, file), content);
|
|
312
|
-
console.log(chalk.green(` ✓ .codebuddy/agents/${file}`));
|
|
313
|
-
|
|
314
|
-
} else if (platform === 'claude') {
|
|
315
|
-
const converted = convertAgentFn(content, { model: 'inherit' });
|
|
316
|
-
|
|
317
|
-
const targetDir = path.join(projectRoot, '.claude', 'agents');
|
|
318
|
-
if (dryRun) {
|
|
319
|
-
console.log(chalk.gray(` [dry-run] .claude/agents/${file}`));
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
await fs.ensureDir(targetDir);
|
|
323
|
-
await fs.writeFile(path.join(targetDir, file), converted);
|
|
324
|
-
console.log(chalk.green(` ✓ .claude/agents/${file}`));
|
|
325
|
-
} else if (platform === 'codex') {
|
|
326
|
-
const baseName = path.basename(file, '.md');
|
|
327
|
-
const targetFile = `${baseName}.toml`;
|
|
328
|
-
const converted = convertAgentFn(content, { name: baseName });
|
|
329
|
-
const targetDir = path.join(projectRoot, '.codex', 'agents');
|
|
330
|
-
if (dryRun) {
|
|
331
|
-
console.log(chalk.gray(` [dry-run] .codex/agents/${targetFile}`));
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
await fs.ensureDir(targetDir);
|
|
335
|
-
await fs.writeFile(path.join(targetDir, targetFile), converted);
|
|
336
|
-
await fs.remove(path.join(targetDir, file));
|
|
337
|
-
console.log(chalk.green(` ✓ .codex/agents/${targetFile}`));
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* 安装 Team 配置
|
|
351
|
+
* Legacy platform named-agent and team installation has been retired.
|
|
352
|
+
* Skill-owned references now provide inline reviewer/implementation subagent contracts.
|
|
344
353
|
*/
|
|
345
|
-
export async function installTeamConfig(platform, projectRoot, dryRun) {
|
|
346
|
-
const teamDir = getTeamDir();
|
|
347
|
-
const teamDefPath = path.join(teamDir, 'prizm-dev-team.json');
|
|
348
|
-
|
|
349
|
-
if (!await fs.pathExists(teamDefPath)) {
|
|
350
|
-
console.log(chalk.yellow(' ⚠ 未找到团队配置文件,跳过'));
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
const teamDef = await fs.readJSON(teamDefPath);
|
|
355
|
-
|
|
356
|
-
if (platform === 'codebuddy') {
|
|
357
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
358
|
-
const targetDir = path.join(homeDir, '.codebuddy', 'teams', 'prizm-dev-team');
|
|
359
|
-
|
|
360
|
-
if (dryRun) {
|
|
361
|
-
console.log(chalk.gray(` [dry-run] ~/.codebuddy/teams/prizm-dev-team/`));
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
await fs.ensureDir(path.join(targetDir, 'inboxes'));
|
|
366
|
-
|
|
367
|
-
const config = {
|
|
368
|
-
name: teamDef.name,
|
|
369
|
-
description: teamDef.description,
|
|
370
|
-
createdAt: Date.now(),
|
|
371
|
-
leadAgentId: `${teamDef.lead}@${teamDef.name}`,
|
|
372
|
-
leadSessionId: '',
|
|
373
|
-
members: teamDef.members.map((m, i) => ({
|
|
374
|
-
agentId: `${m.name}@${teamDef.name}`,
|
|
375
|
-
name: m.name,
|
|
376
|
-
agentType: m.agentDefinition || m.name,
|
|
377
|
-
...(m.prompt ? { prompt: m.prompt } : {}),
|
|
378
|
-
joinedAt: Date.now() + i,
|
|
379
|
-
tmuxPaneId: '',
|
|
380
|
-
cwd: '',
|
|
381
|
-
subscriptions: m.subscriptions || [],
|
|
382
|
-
})),
|
|
383
|
-
};
|
|
384
|
-
|
|
385
|
-
await fs.writeFile(path.join(targetDir, 'config.json'), JSON.stringify(config, null, 2));
|
|
386
|
-
|
|
387
|
-
for (const member of teamDef.members) {
|
|
388
|
-
const inboxPath = path.join(targetDir, 'inboxes', `${member.name}.json`);
|
|
389
|
-
if (!await fs.pathExists(inboxPath)) {
|
|
390
|
-
await fs.writeFile(inboxPath, JSON.stringify([], null, 2));
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
console.log(chalk.green(` ✓ ~/.codebuddy/teams/prizm-dev-team/`));
|
|
395
|
-
|
|
396
|
-
} else if (platform === 'claude') {
|
|
397
|
-
const claudeDir = path.join(projectRoot, '.claude');
|
|
398
|
-
|
|
399
|
-
if (dryRun) {
|
|
400
|
-
console.log(chalk.gray(` [dry-run] .claude/team-info.json`));
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
await fs.ensureDir(claudeDir);
|
|
405
|
-
|
|
406
|
-
const teamConfig = {
|
|
407
|
-
name: teamDef.name,
|
|
408
|
-
description: teamDef.description,
|
|
409
|
-
platform: 'claude',
|
|
410
|
-
orchestrationMode: 'subagent',
|
|
411
|
-
agents: teamDef.members
|
|
412
|
-
.filter(m => m.role !== 'lead')
|
|
413
|
-
.map(m => ({
|
|
414
|
-
name: m.name,
|
|
415
|
-
role: m.role,
|
|
416
|
-
agentFile: `.claude/agents/${m.agentDefinition}.md`,
|
|
417
|
-
prompt: m.prompt,
|
|
418
|
-
})),
|
|
419
|
-
upgrade: {
|
|
420
|
-
envVar: 'CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS',
|
|
421
|
-
command: '设置 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 可启用原生 Agent Teams 模式',
|
|
422
|
-
},
|
|
423
|
-
};
|
|
424
|
-
|
|
425
|
-
await fs.writeFile(
|
|
426
|
-
path.join(claudeDir, 'team-info.json'),
|
|
427
|
-
JSON.stringify(teamConfig, null, 2)
|
|
428
|
-
);
|
|
429
|
-
|
|
430
|
-
console.log(chalk.green(` ✓ .claude/team-info.json`));
|
|
431
|
-
} else if (platform === 'codex') {
|
|
432
|
-
const codexDir = path.join(projectRoot, '.codex');
|
|
433
|
-
|
|
434
|
-
if (dryRun) {
|
|
435
|
-
console.log(chalk.gray(` [dry-run] .codex/team-info.json`));
|
|
436
|
-
return;
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
await fs.ensureDir(codexDir);
|
|
440
|
-
|
|
441
|
-
const teamConfig = {
|
|
442
|
-
name: teamDef.name,
|
|
443
|
-
description: teamDef.description,
|
|
444
|
-
platform: 'codex',
|
|
445
|
-
orchestrationMode: 'codex-subagents',
|
|
446
|
-
agents: teamDef.members
|
|
447
|
-
.filter(m => m.role !== 'lead')
|
|
448
|
-
.map(m => ({
|
|
449
|
-
name: m.name,
|
|
450
|
-
role: m.role,
|
|
451
|
-
agentFile: `.codex/agents/${m.agentDefinition}.toml`,
|
|
452
|
-
prompt: m.prompt,
|
|
453
|
-
subscriptions: m.subscriptions || [],
|
|
454
|
-
})),
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
await fs.writeFile(
|
|
458
|
-
path.join(codexDir, 'team-info.json'),
|
|
459
|
-
JSON.stringify(teamConfig, null, 2)
|
|
460
|
-
);
|
|
461
|
-
|
|
462
|
-
console.log(chalk.green(` ✓ .codex/team-info.json`));
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
354
|
|
|
466
355
|
/**
|
|
467
356
|
* 安装平台配置文件(settings/hooks/rules)
|
|
@@ -591,7 +480,7 @@ export async function installSettings(platform, projectRoot, options, dryRun, ru
|
|
|
591
480
|
await fs.ensureDir(path.dirname(configPath));
|
|
592
481
|
const configToml = `# Generated by PrizmKit for Codex CLI project configuration.
|
|
593
482
|
# Keep project guidance in AGENTS.md; repository skills in .agents/skills/;
|
|
594
|
-
# PrizmKit behavioral rules live in .agents/rules
|
|
483
|
+
# PrizmKit behavioral rules live in .agents/rules/.
|
|
595
484
|
|
|
596
485
|
project_doc_fallback_filenames = ["CLAUDE.md", "CODEBUDDY.md"]
|
|
597
486
|
|
|
@@ -1058,7 +947,7 @@ Codex discovers repository skills from \`.agents/skills/\`. When a user or promp
|
|
|
1058
947
|
- Start with \`.agents/skills/prizmkit/SKILL.md\` to see all available PrizmKit skills.
|
|
1059
948
|
- Skill assets and references live inside each \`.agents/skills/<skill>/\` directory.
|
|
1060
949
|
- PrizmKit behavioral rules live in \`.agents/rules/\`; read the relevant Markdown guidance before commit, documentation, or context-loading work.
|
|
1061
|
-
|
|
950
|
+
`
|
|
1062
951
|
);
|
|
1063
952
|
}
|
|
1064
953
|
|
|
@@ -1585,7 +1474,6 @@ export const EXTRAS_REGISTRY = {
|
|
|
1585
1474
|
* @param {string} config.platform - 'codebuddy' | 'claude' | 'codex' | 'all'
|
|
1586
1475
|
* @param {string} [config.runtime] - 'python' (legacy aliases accepted: 'unix' | 'windows')
|
|
1587
1476
|
* @param {string} config.skills - 'core' | 'minimal' | 'recommended:<type>'
|
|
1588
|
-
* @param {boolean} config.team - 是否启用团队模式
|
|
1589
1477
|
* @param {boolean} config.pipeline - 是否安装 dev-pipeline
|
|
1590
1478
|
* @param {string} [config.rules] - Rules preset: 'recommended' | 'minimal' | 'none'
|
|
1591
1479
|
* @param {string} [config.aiCli] - AI CLI 可执行命令(写入 .prizmkit/config.json)
|
|
@@ -1597,7 +1485,7 @@ export const EXTRAS_REGISTRY = {
|
|
|
1597
1485
|
* @param {boolean} config.dryRun - 是否为预览模式
|
|
1598
1486
|
*/
|
|
1599
1487
|
export async function scaffold(config) {
|
|
1600
|
-
const { platform, skills,
|
|
1488
|
+
const { platform, skills, pipeline, rules, aiCli, aiCliLaunch, externalSkills, playwrightCli, openCli, openCliAutoDownload, projectRoot, dryRun } = config;
|
|
1601
1489
|
const runtime = normalizeRuntime(config.runtime);
|
|
1602
1490
|
const launchSelection = resolveAiCliLaunchSelection(aiCli || '', {
|
|
1603
1491
|
aiCliLaunch,
|
|
@@ -1622,21 +1510,13 @@ export async function scaffold(config) {
|
|
|
1622
1510
|
for (const p of payloadPlatforms) {
|
|
1623
1511
|
console.log(chalk.bold(` 正在安装 ${platformLabel(p)} 环境...${platforms.includes(p) ? '' : chalk.gray(' (AI CLI payload)')}\n`));
|
|
1624
1512
|
|
|
1513
|
+
await removeRetiredAgentTeamArtifacts(p, projectRoot, dryRun);
|
|
1514
|
+
|
|
1625
1515
|
// 1. Skills
|
|
1626
1516
|
console.log(chalk.blue(' 技能文件:'));
|
|
1627
1517
|
await installSkills(p, skillList, projectRoot, dryRun, runtime);
|
|
1628
1518
|
|
|
1629
|
-
// 2.
|
|
1630
|
-
console.log(chalk.blue('\n Agent 定义:'));
|
|
1631
|
-
await installAgents(p, projectRoot, dryRun);
|
|
1632
|
-
|
|
1633
|
-
// 3. Team
|
|
1634
|
-
if (team) {
|
|
1635
|
-
console.log(chalk.blue('\n 团队配置:'));
|
|
1636
|
-
await installTeamConfig(p, projectRoot, dryRun);
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
// 4. Settings/Hooks/Rules
|
|
1519
|
+
// 2. Settings/Hooks/Rules
|
|
1640
1520
|
console.log(chalk.blue('\n 平台配置:'));
|
|
1641
1521
|
await installSettings(p, projectRoot, { pipeline, rules }, dryRun, runtime);
|
|
1642
1522
|
|
|
@@ -1747,8 +1627,6 @@ export async function scaffold(config) {
|
|
|
1747
1627
|
|
|
1748
1628
|
// 14. Write installation manifest
|
|
1749
1629
|
if (!dryRun) {
|
|
1750
|
-
const agentsDir = getAgentsDir();
|
|
1751
|
-
const agentFileNames = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
|
|
1752
1630
|
const rulesMeta = await loadRulesMetadata();
|
|
1753
1631
|
const rulesPresetName = rules || 'recommended';
|
|
1754
1632
|
const ruleFileNames = resolveRuleNamesForRuntime(rulesMeta, rulesPresetName, runtime).map(name => `${name}.md`);
|
|
@@ -1759,10 +1637,8 @@ export async function scaffold(config) {
|
|
|
1759
1637
|
runtime,
|
|
1760
1638
|
suite: skills,
|
|
1761
1639
|
skills: skillList,
|
|
1762
|
-
agents: agentFileNames,
|
|
1763
1640
|
rules: ruleFileNames,
|
|
1764
1641
|
pipeline: installedPipelineFiles,
|
|
1765
|
-
team,
|
|
1766
1642
|
aiCli: resolvedAiCli,
|
|
1767
1643
|
rulesPreset: rulesPresetName,
|
|
1768
1644
|
extras: activeExtras,
|
|
@@ -1819,7 +1695,6 @@ export async function scaffold(config) {
|
|
|
1819
1695
|
console.log(chalk.gray(` AI CLI 载荷平台: ${payloadPlatforms.map(platformLabel).join(' + ')}`));
|
|
1820
1696
|
}
|
|
1821
1697
|
console.log(chalk.gray(` 运行时: ${runtimeLabel(runtime)}`));
|
|
1822
|
-
console.log(chalk.gray(` 团队: ${team ? '已启用' : '未启用'}`));
|
|
1823
1698
|
console.log(chalk.gray(` 流水线: ${pipeline ? '已安装' : '未安装'}`));
|
|
1824
1699
|
const browserTools = [playwrightCli && 'playwright-cli', openCli && 'opencli'].filter(Boolean);
|
|
1825
1700
|
console.log(chalk.gray(` 浏览器工具: ${browserTools.length ? '已安装 (' + browserTools.join(' + ') + ')' : '未安装'}`));
|
package/src/upgrade.js
CHANGED
|
@@ -16,23 +16,21 @@ import { confirm } from '@inquirer/prompts';
|
|
|
16
16
|
import { readManifest, writeManifest, buildManifest, diffManifest } from './manifest.js';
|
|
17
17
|
import {
|
|
18
18
|
loadRulesMetadata,
|
|
19
|
-
getAgentsDir,
|
|
20
19
|
} from './metadata.js';
|
|
21
20
|
import {
|
|
22
21
|
installSkills,
|
|
23
|
-
installAgents,
|
|
24
22
|
installSettings,
|
|
25
23
|
installPipeline,
|
|
26
24
|
installPrizmkitScripts,
|
|
27
25
|
installGitHook,
|
|
28
26
|
installGitignore,
|
|
29
27
|
installProjectMemory,
|
|
30
|
-
installTeamConfig,
|
|
31
28
|
resolvePipelineFileList,
|
|
32
29
|
findStaleManagedPipelineFiles,
|
|
33
30
|
removeStaleManagedPipelineFiles,
|
|
34
31
|
resolveRuleNamesForRuntime,
|
|
35
32
|
resolveSkillList,
|
|
33
|
+
removeRetiredAgentTeamArtifacts,
|
|
36
34
|
EXTRAS_REGISTRY,
|
|
37
35
|
} from './scaffold.js';
|
|
38
36
|
import { platformLabel, privateProjectMemoryFiles, resolvePayloadPlatforms } from './platforms.js';
|
|
@@ -222,7 +220,6 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
222
220
|
// 3. Resolve new skill list using old manifest's suite + platform (or defaults)
|
|
223
221
|
const suite = oldManifest?.suite || 'core';
|
|
224
222
|
const runtime = normalizeRuntime(oldManifest?.runtime);
|
|
225
|
-
const team = oldManifest?.options?.team ?? true;
|
|
226
223
|
const pipeline = oldManifest?.options?.pipeline ?? true;
|
|
227
224
|
const rulesPreset = oldManifest?.options?.rules || 'recommended';
|
|
228
225
|
const aiCli = userConfig.ai_cli || oldManifest?.options?.aiCli || '';
|
|
@@ -243,12 +240,9 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
243
240
|
return false;
|
|
244
241
|
}
|
|
245
242
|
};
|
|
246
|
-
const hasClaude = await hasPlatformFiles(path.join(projectRoot, '.claude', 'commands'))
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|| await hasPlatformFiles(path.join(projectRoot, '.codebuddy', 'agents'));
|
|
250
|
-
const hasCodex = await hasPlatformFiles(path.join(projectRoot, '.agents', 'skills'))
|
|
251
|
-
|| await hasPlatformFiles(path.join(projectRoot, '.codex', 'agents'));
|
|
243
|
+
const hasClaude = await hasPlatformFiles(path.join(projectRoot, '.claude', 'commands'));
|
|
244
|
+
const hasCodeBuddy = await hasPlatformFiles(path.join(projectRoot, '.codebuddy', 'skills'));
|
|
245
|
+
const hasCodex = await hasPlatformFiles(path.join(projectRoot, '.agents', 'skills'));
|
|
252
246
|
|
|
253
247
|
const detectedPlatforms = [
|
|
254
248
|
hasCodeBuddy && 'codebuddy',
|
|
@@ -262,8 +256,6 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
262
256
|
}
|
|
263
257
|
|
|
264
258
|
const newSkillList = await resolveSkillList(suite);
|
|
265
|
-
const agentsDir = getAgentsDir();
|
|
266
|
-
const newAgentFiles = (await fs.readdir(agentsDir)).filter(f => f.endsWith('.md'));
|
|
267
259
|
const rulesMeta = await loadRulesMetadata();
|
|
268
260
|
const newRuleFiles = resolveRuleNamesForRuntime(rulesMeta, rulesPreset, runtime).map(name => `${name}.md`);
|
|
269
261
|
|
|
@@ -286,10 +278,8 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
286
278
|
runtime,
|
|
287
279
|
suite,
|
|
288
280
|
skills: newSkillList,
|
|
289
|
-
agents: newAgentFiles,
|
|
290
281
|
rules: newRuleFiles,
|
|
291
282
|
pipeline: newPipelineFiles,
|
|
292
|
-
team,
|
|
293
283
|
aiCli,
|
|
294
284
|
rulesPreset,
|
|
295
285
|
extras: extrasToInstall,
|
|
@@ -301,7 +291,7 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
301
291
|
newManifest.installedAt = oldManifest.installedAt;
|
|
302
292
|
}
|
|
303
293
|
|
|
304
|
-
const diff = oldManifest ? diffManifest(oldManifest, newManifest) : { skills: { added: [], removed: [] },
|
|
294
|
+
const diff = oldManifest ? diffManifest(oldManifest, newManifest) : { skills: { added: [], removed: [] }, rules: { added: [], removed: [] }, pipeline: { added: [], removed: [] }, extras: { added: [], removed: [] }, legacyAgents: { added: [], removed: [] } };
|
|
305
295
|
const removedPipelineSet = new Set(diff.pipeline.removed);
|
|
306
296
|
const staleManagedPipelineFiles = pipeline
|
|
307
297
|
? (await findStaleManagedPipelineFiles(projectRoot, runtime))
|
|
@@ -317,14 +307,13 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
317
307
|
console.log(` Suite: ${suite}`);
|
|
318
308
|
console.log('');
|
|
319
309
|
|
|
320
|
-
const totalAdded = diff.skills.added.length + diff.
|
|
321
|
-
const totalRemoved = diff.skills.removed.length + diff.
|
|
322
|
-
const totalUpdated = newSkillList.length +
|
|
310
|
+
const totalAdded = diff.skills.added.length + diff.rules.added.length + diff.pipeline.added.length + diff.extras.added.length;
|
|
311
|
+
const totalRemoved = diff.skills.removed.length + diff.rules.removed.length + diff.pipeline.removed.length + diff.extras.removed.length + diff.legacyAgents.removed.length + staleManagedPipelineFiles.length;
|
|
312
|
+
const totalUpdated = newSkillList.length + newRuleFiles.length;
|
|
323
313
|
|
|
324
314
|
if (diff.skills.added.length) console.log(chalk.green(` + Skills added: ${diff.skills.added.join(', ')}`));
|
|
325
315
|
if (diff.skills.removed.length) console.log(chalk.red(` - Skills removed: ${diff.skills.removed.join(', ')}`));
|
|
326
|
-
if (diff.
|
|
327
|
-
if (diff.agents.removed.length) console.log(chalk.red(` - Agents removed: ${diff.agents.removed.join(', ')}`));
|
|
316
|
+
if (diff.legacyAgents.removed.length) console.log(chalk.red(` - Legacy agents removed: ${diff.legacyAgents.removed.join(', ')}`));
|
|
328
317
|
if (diff.rules.added.length) console.log(chalk.green(` + Rules added: ${diff.rules.added.join(', ')}`));
|
|
329
318
|
if (diff.rules.removed.length) console.log(chalk.red(` - Rules removed: ${diff.rules.removed.join(', ')}`));
|
|
330
319
|
if (diff.pipeline.added.length) console.log(chalk.green(` + Pipeline files added: ${diff.pipeline.added.length} file(s)`));
|
|
@@ -356,17 +345,19 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
356
345
|
const platforms = payloadPlatforms;
|
|
357
346
|
|
|
358
347
|
// 7a. Remove orphaned files
|
|
359
|
-
if (diff.skills.removed.length || diff.
|
|
348
|
+
if (diff.skills.removed.length || diff.legacyAgents.removed.length || diff.rules.removed.length || diff.pipeline.removed.length || staleManagedPipelineFiles.length) {
|
|
360
349
|
console.log(chalk.bold('\n Removing orphaned files...'));
|
|
361
350
|
for (const p of platforms) {
|
|
362
351
|
if (diff.skills.removed.length) {
|
|
363
352
|
console.log(chalk.blue(`\n Removed skills (${p}):`));
|
|
364
353
|
await removeSkillFiles(p, projectRoot, diff.skills.removed, dryRun);
|
|
365
354
|
}
|
|
366
|
-
if (diff.
|
|
367
|
-
console.log(chalk.blue(`\n Removed agents (${p}):`));
|
|
368
|
-
await removeAgentFiles(p, projectRoot, diff.
|
|
355
|
+
if (diff.legacyAgents.removed.length) {
|
|
356
|
+
console.log(chalk.blue(`\n Removed legacy agents (${p}):`));
|
|
357
|
+
await removeAgentFiles(p, projectRoot, diff.legacyAgents.removed, dryRun);
|
|
369
358
|
}
|
|
359
|
+
console.log(chalk.blue(`\n Removed retired agent/team artifacts (${p}):`));
|
|
360
|
+
await removeRetiredAgentTeamArtifacts(p, projectRoot, dryRun);
|
|
370
361
|
if (diff.rules.removed.length) {
|
|
371
362
|
console.log(chalk.blue(`\n Removed rules (${p}):`));
|
|
372
363
|
await removeRuleFiles(p, projectRoot, diff.rules.removed, dryRun);
|
|
@@ -387,24 +378,16 @@ export async function runUpgrade(directory, options = {}) {
|
|
|
387
378
|
|
|
388
379
|
for (const p of platforms) {
|
|
389
380
|
console.log(chalk.bold(` Installing ${platformLabel(p)} environment...\n`));
|
|
381
|
+
await removeRetiredAgentTeamArtifacts(p, projectRoot, dryRun);
|
|
390
382
|
|
|
391
383
|
// Skills
|
|
392
384
|
console.log(chalk.blue(' Skills:'));
|
|
393
385
|
await installSkills(p, newSkillList, projectRoot, dryRun, runtime);
|
|
394
386
|
|
|
395
|
-
// Agents
|
|
396
|
-
console.log(chalk.blue('\n Agents:'));
|
|
397
|
-
await installAgents(p, projectRoot, dryRun);
|
|
398
|
-
|
|
399
387
|
// Settings/Rules
|
|
400
388
|
console.log(chalk.blue('\n Settings & Rules:'));
|
|
401
389
|
await installSettings(p, projectRoot, { pipeline, rules: rulesPreset }, dryRun, runtime);
|
|
402
390
|
|
|
403
|
-
if (team) {
|
|
404
|
-
console.log(chalk.blue('\n Team Config:'));
|
|
405
|
-
await installTeamConfig(p, projectRoot, dryRun);
|
|
406
|
-
}
|
|
407
|
-
|
|
408
391
|
console.log('');
|
|
409
392
|
}
|
|
410
393
|
|