prizmkit 1.1.119 → 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.
Files changed (62) hide show
  1. package/bin/create-prizmkit.js +1 -5
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/README.md +41 -38
  4. package/bundled/dev-pipeline/assets/skill-subagent-integration.md +76 -0
  5. package/bundled/dev-pipeline/prizmkit_runtime/config.py +2 -8
  6. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +1 -1
  7. package/bundled/dev-pipeline/prizmkit_runtime/platform_detection.py +3 -3
  8. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +45 -3
  9. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +28 -6
  10. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +60 -102
  11. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -19
  12. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -19
  13. package/bundled/dev-pipeline/scripts/{init-dev-team.py → init-change-artifact.py} +6 -16
  14. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +364 -76
  15. package/bundled/dev-pipeline/scripts/utils.py +1 -1
  16. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +2 -2
  17. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +7 -9
  18. package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +2 -2
  19. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
  20. package/bundled/dev-pipeline/templates/sections/critical-paths-agent.md +0 -1
  21. package/bundled/dev-pipeline/templates/sections/critical-paths-full.md +0 -2
  22. package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +8 -1
  23. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +6 -7
  24. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +6 -7
  25. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +4 -2
  26. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +2 -2
  27. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +4 -2
  28. package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +20 -0
  29. package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +2 -2
  30. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +204 -141
  31. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +16 -10
  32. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +2 -13
  33. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +13 -14
  34. package/bundled/dev-pipeline/tests/test_unified_cli.py +205 -6
  35. package/bundled/skills/_metadata.json +1 -1
  36. package/bundled/skills/app-planner/SKILL.md +2 -2
  37. package/bundled/skills/app-planner/references/architecture-decisions.md +1 -3
  38. package/bundled/skills/prizmkit-code-review/SKILL.md +16 -14
  39. package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +9 -9
  40. package/bundled/skills/prizmkit-implement/SKILL.md +21 -1
  41. package/bundled/skills/prizmkit-implement/references/implementation-subagent-procedure.md +67 -0
  42. package/package.json +1 -1
  43. package/src/clean.js +12 -8
  44. package/src/config.js +24 -42
  45. package/src/index.js +1 -10
  46. package/src/manifest.js +3 -9
  47. package/src/metadata.js +0 -26
  48. package/src/prompts.js +0 -13
  49. package/src/scaffold.js +76 -201
  50. package/src/upgrade.js +16 -33
  51. package/bundled/adapters/claude/agent-adapter.js +0 -96
  52. package/bundled/adapters/claude/team-adapter.js +0 -183
  53. package/bundled/adapters/codebuddy/agent-adapter.js +0 -42
  54. package/bundled/adapters/codebuddy/team-adapter.js +0 -46
  55. package/bundled/adapters/codex/agent-adapter.js +0 -38
  56. package/bundled/adapters/codex/team-adapter.js +0 -37
  57. package/bundled/agents/prizm-dev-team-dev.md +0 -123
  58. package/bundled/agents/prizm-dev-team-reviewer.md +0 -113
  59. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +0 -65
  60. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +0 -436
  61. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +0 -510
  62. package/bundled/team/prizm-dev-team.json +0 -27
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
- * 安装 Agent 定义(纯 Copy 模式)
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/; native Codex subagents live in .codex/agents/.
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
- - Native Codex subagents live in \`.codex/agents/*.toml\`; use them when spawning or coordinating subagents.`
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, team, pipeline, rules, aiCli, aiCliLaunch, externalSkills, playwrightCli, openCli, openCliAutoDownload, projectRoot, dryRun } = config;
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. Agents
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
- || await hasPlatformFiles(path.join(projectRoot, '.claude', 'agents'));
248
- const hasCodeBuddy = await hasPlatformFiles(path.join(projectRoot, '.codebuddy', 'skills'))
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: [] }, agents: { added: [], removed: [] }, rules: { added: [], removed: [] }, pipeline: { added: [], removed: [] }, extras: { 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.agents.added.length + diff.rules.added.length + diff.pipeline.added.length + diff.extras.added.length;
321
- const totalRemoved = diff.skills.removed.length + diff.agents.removed.length + diff.rules.removed.length + diff.pipeline.removed.length + diff.extras.removed.length + staleManagedPipelineFiles.length;
322
- const totalUpdated = newSkillList.length + newAgentFiles.length + newRuleFiles.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.agents.added.length) console.log(chalk.green(` + Agents added: ${diff.agents.added.join(', ')}`));
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.agents.removed.length || diff.rules.removed.length || diff.pipeline.removed.length || staleManagedPipelineFiles.length) {
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.agents.removed.length) {
367
- console.log(chalk.blue(`\n Removed agents (${p}):`));
368
- await removeAgentFiles(p, projectRoot, diff.agents.removed, dryRun);
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
 
@@ -1,96 +0,0 @@
1
- /**
2
- * Claude Code Agent Adapter
3
- * Converts core/ agent definitions to .claude/agents/ format.
4
- *
5
- * Key differences from CodeBuddy agents:
6
- * - tools: comma-separated string -> YAML array
7
- * - model: "inherit" -> explicit model name (or kept as "inherit")
8
- * - skills: kept as comma-separated string (Claude Code supports it natively)
9
- * - TaskCreate/Get/Update/List -> Task (single tool)
10
- * - SendMessage -> SendMessage (native Agent Teams communication)
11
- */
12
-
13
- import { parseFrontmatter, buildMarkdown } from '../shared/frontmatter.js';
14
- import { TOOL_MAPPING } from '../shared/constants.js';
15
- import { mkdirSync } from 'node:fs';
16
- import { readFile, writeFile } from 'node:fs/promises';
17
- import path from 'path';
18
-
19
- // Default model for Claude Code agents
20
- const DEFAULT_MODEL = 'claude-sonnet-4-20250514';
21
-
22
- /**
23
- * Convert a core agent definition to Claude Code format.
24
- * @param {string} agentContent - Content of the core agent .md
25
- * @param {Object} options - { model?: string }
26
- * @returns {string} - Claude Code formatted agent .md content
27
- */
28
- export function convertAgent(agentContent, options = {}) {
29
- const { frontmatter, body } = parseFrontmatter(agentContent);
30
-
31
- // Convert tools: comma-separated string -> deduplicated array
32
- let tools = [];
33
- if (frontmatter.tools) {
34
- const rawTools = frontmatter.tools.split(',').map(t => t.trim());
35
- const mapped = rawTools.map(t => {
36
- if (TOOL_MAPPING.hasOwnProperty(t)) {
37
- return TOOL_MAPPING[t];
38
- }
39
- return t;
40
- }).filter(Boolean);
41
- tools = [...new Set(mapped)];
42
- }
43
-
44
- // Body content is used as-is — no injection or transformation needed.
45
- // Claude Code natively supports skills in frontmatter and slash commands in body.
46
- let convertedBody = body;
47
-
48
- // Convert disallowedTools: comma-separated string -> deduplicated array
49
- let disallowedTools = [];
50
- if (frontmatter.disallowedTools) {
51
- const rawDisallowed = frontmatter.disallowedTools.split(',').map(t => t.trim());
52
- const mappedDisallowed = rawDisallowed.map(t => {
53
- if (TOOL_MAPPING.hasOwnProperty(t)) {
54
- return TOOL_MAPPING[t];
55
- }
56
- return t;
57
- }).filter(Boolean);
58
- disallowedTools = [...new Set(mappedDisallowed)];
59
- }
60
-
61
- // Build Claude Code frontmatter
62
- const claudeFrontmatter = {
63
- name: frontmatter.name,
64
- description: frontmatter.description,
65
- tools: tools,
66
- model: options.model || DEFAULT_MODEL,
67
- };
68
-
69
- // Add disallowedTools if present
70
- if (disallowedTools.length > 0) {
71
- claudeFrontmatter.disallowedTools = disallowedTools;
72
- }
73
-
74
- // Preserve skills field if present (Claude Code supports it natively)
75
- if (frontmatter.skills) {
76
- claudeFrontmatter.skills = frontmatter.skills;
77
- }
78
-
79
- return buildMarkdown(claudeFrontmatter, convertedBody);
80
- }
81
-
82
- /**
83
- * Install an agent definition to the target project's .claude/agents/.
84
- * @param {string} corePath - Path to core/agents/<name>.md
85
- * @param {string} targetRoot - Target project root
86
- * @param {Object} options - { model?: string }
87
- */
88
- export async function installAgent(corePath, targetRoot, options = {}) {
89
- const filename = path.basename(corePath);
90
- const targetDir = path.join(targetRoot, '.claude', 'agents');
91
- mkdirSync(targetDir, { recursive: true });
92
-
93
- const content = await readFile(corePath, 'utf8');
94
- const converted = convertAgent(content, options);
95
- await writeFile(path.join(targetDir, filename), converted);
96
- }