trinity-method-sdk 2.1.0 → 2.2.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.
Files changed (101) hide show
  1. package/CHANGELOG.md +728 -467
  2. package/README.md +550 -539
  3. package/dist/cli/commands/deploy/ci-cd.d.ts +4 -3
  4. package/dist/cli/commands/deploy/ci-cd.js +10 -9
  5. package/dist/cli/commands/deploy/configuration.js +10 -11
  6. package/dist/cli/commands/deploy/directories.js +13 -14
  7. package/dist/cli/commands/deploy/gitignore.js +3 -4
  8. package/dist/cli/commands/deploy/index.d.ts +1 -1
  9. package/dist/cli/commands/deploy/index.js +6 -2
  10. package/dist/cli/commands/deploy/knowledge-base.js +2 -2
  11. package/dist/cli/commands/deploy/pre-flight.js +1 -1
  12. package/dist/cli/commands/deploy/root-files.js +2 -17
  13. package/dist/cli/commands/deploy/summary.js +3 -3
  14. package/dist/cli/commands/deploy/templates.js +5 -5
  15. package/dist/cli/commands/update/backup.js +6 -12
  16. package/dist/cli/commands/update/index.js +15 -1
  17. package/dist/cli/commands/update/knowledge-base.js +1 -1
  18. package/dist/cli/commands/update/migration.d.ts +31 -0
  19. package/dist/cli/commands/update/migration.js +130 -0
  20. package/dist/cli/commands/update/pre-flight.d.ts +7 -2
  21. package/dist/cli/commands/update/pre-flight.js +21 -20
  22. package/dist/cli/commands/update/summary.js +11 -5
  23. package/dist/cli/commands/update/templates.js +1 -1
  24. package/dist/cli/commands/update/types.d.ts +2 -0
  25. package/dist/cli/commands/update/verification.js +5 -5
  26. package/dist/cli/commands/update/version.js +6 -4
  27. package/dist/cli/utils/deploy-ci.d.ts +3 -2
  28. package/dist/cli/utils/deploy-ci.js +24 -24
  29. package/dist/cli/utils/deploy-linting.js +100 -5
  30. package/dist/cli/utils/error-classes.d.ts +2 -2
  31. package/dist/cli/utils/linting-tools.js +14 -6
  32. package/dist/cli/utils/template-processor.js +1 -3
  33. package/dist/templates/.claude/EMPLOYEE-DIRECTORY.md.template +16 -22
  34. package/dist/templates/.claude/agents/aj-team/apo-documentation-specialist.md.template +7 -7
  35. package/dist/templates/.claude/agents/aj-team/bas-quality-gate.md.template +8 -8
  36. package/dist/templates/.claude/agents/aj-team/dra-code-reviewer.md.template +3 -3
  37. package/dist/templates/.claude/agents/aj-team/kil-task-executor.md.template +6 -6
  38. package/dist/templates/.claude/agents/audit/juno-auditor.md.template +39 -40
  39. package/dist/templates/.claude/agents/deployment/ein-cicd.md.template +56 -159
  40. package/dist/templates/.claude/agents/deployment/ino-context.md.template +21 -21
  41. package/dist/templates/.claude/agents/deployment/tan-structure.md.template +28 -29
  42. package/dist/templates/.claude/agents/deployment/zen-knowledge.md.template +22 -23
  43. package/dist/templates/.claude/agents/leadership/aj-maestro.md.template +6 -6
  44. package/dist/templates/.claude/agents/leadership/aly-cto.md.template +17 -18
  45. package/dist/templates/.claude/agents/planning/eus-decomposer.md.template +4 -4
  46. package/dist/templates/.claude/agents/planning/mon-requirements.md.template +4 -4
  47. package/dist/templates/.claude/agents/planning/ror-design.md.template +4 -4
  48. package/dist/templates/.claude/agents/planning/tra-planner.md.template +4 -4
  49. package/dist/templates/.claude/commands/execution/trinity-audit.md.template +9 -9
  50. package/dist/templates/.claude/commands/execution/trinity-breakdown.md.template +535 -0
  51. package/dist/templates/.claude/commands/execution/trinity-orchestrate.md.template +43 -43
  52. package/dist/templates/.claude/commands/infrastructure/trinity-init.md.template +20 -43
  53. package/dist/templates/.claude/commands/investigation/trinity-create-investigation.md.template +5 -5
  54. package/dist/templates/.claude/commands/investigation/trinity-investigate-templates.md.template +10 -10
  55. package/dist/templates/.claude/commands/investigation/trinity-plan-investigation.md.template +1 -1
  56. package/dist/templates/.claude/commands/maintenance/trinity-changelog.md.template +4 -4
  57. package/dist/templates/.claude/commands/maintenance/trinity-docs-update.md.template +10 -10
  58. package/dist/templates/.claude/commands/maintenance/trinity-docs.md.template +62 -62
  59. package/dist/templates/.claude/commands/maintenance/trinity-readme.md.template +16 -16
  60. package/dist/templates/.claude/commands/session/trinity-continue.md.template +22 -22
  61. package/dist/templates/.claude/commands/session/trinity-end.md.template +22 -22
  62. package/dist/templates/.claude/commands/session/trinity-start.md.template +1 -2
  63. package/dist/templates/.claude/commands/utility/trinity-agents.md.template +3 -6
  64. package/dist/templates/.claude/commands/utility/trinity-verify.md.template +48 -54
  65. package/dist/templates/.claude/commands/utility/trinity-workorder.md.template +5 -5
  66. package/dist/templates/ci/ci.yml.template +2 -2
  67. package/dist/templates/root/CLAUDE.md.template +9 -9
  68. package/dist/templates/root/linting/nodejs/.husky-pre-commit.template +5 -0
  69. package/dist/templates/source/base-CLAUDE.md.template +310 -310
  70. package/dist/templates/source/flutter-CLAUDE.md.template +593 -593
  71. package/dist/templates/source/nodejs-CLAUDE.md.template +531 -531
  72. package/dist/templates/source/python-CLAUDE.md.template +510 -510
  73. package/dist/templates/source/react-CLAUDE.md.template +513 -513
  74. package/dist/templates/source/rust-CLAUDE.md.template +653 -653
  75. package/dist/templates/trinity/CLAUDE.md.template +14 -14
  76. package/dist/templates/trinity/knowledge-base/ARCHITECTURE.md.template +4 -4
  77. package/dist/templates/trinity/knowledge-base/ISSUES.md.template +8 -8
  78. package/dist/templates/trinity/knowledge-base/Technical-Debt.md.template +1 -3
  79. package/dist/templates/trinity/knowledge-base/To-do.md.template +1 -1
  80. package/dist/templates/trinity/knowledge-base/Trinity.md.template +5 -5
  81. package/dist/templates/trinity/templates/documentation/configuration/env-example-generator.md.template +1 -1
  82. package/dist/templates/trinity/templates/documentation/processes/error-handling-protocol.md.template +2 -2
  83. package/dist/templates/trinity/templates/documentation/reports/apo-docs-update-checklist.md.template +7 -7
  84. package/dist/templates/trinity/templates/documentation/reports/juno-docs-update-checklist.md.template +4 -4
  85. package/dist/templates/trinity/templates/documentation/reports/juno-internal-report.md.template +10 -10
  86. package/dist/templates/trinity/templates/investigations/bug.md.template +14 -14
  87. package/dist/templates/trinity/templates/investigations/feature.md.template +14 -14
  88. package/dist/templates/trinity/templates/investigations/performance.md.template +14 -14
  89. package/dist/templates/trinity/templates/investigations/security.md.template +14 -14
  90. package/dist/templates/trinity/templates/investigations/technical.md.template +14 -14
  91. package/dist/templates/trinity/templates/work-orders/ANALYSIS-TEMPLATE.md.template +10 -10
  92. package/dist/templates/trinity/templates/work-orders/AUDIT-TEMPLATE.md.template +10 -10
  93. package/dist/templates/trinity/templates/work-orders/IMPLEMENTATION-TEMPLATE.md.template +10 -10
  94. package/dist/templates/trinity/templates/work-orders/INVESTIGATION-TEMPLATE.md.template +10 -10
  95. package/dist/templates/trinity/templates/work-orders/PATTERN-TEMPLATE.md.template +10 -10
  96. package/dist/templates/trinity/templates/work-orders/VERIFICATION-TEMPLATE.md.template +10 -10
  97. package/package.json +99 -94
  98. package/dist/templates/.claude/agents/leadership/aj-cc.md.template +0 -467
  99. package/dist/templates/ci/cd.yml.template +0 -175
  100. package/dist/templates/ci/github-actions.yml +0 -86
  101. package/dist/templates/root/TRINITY.md.template +0 -52
@@ -1,13 +1,14 @@
1
1
  /**
2
- * CI/CD workflow deployment
2
+ * CI workflow deployment
3
3
  */
4
4
  import type { DeployOptions, Spinner } from './types.js';
5
5
  /**
6
- * Deploy CI/CD workflow templates
6
+ * Deploy CI workflow templates
7
7
  *
8
8
  * @param options - Deploy command options
9
9
  * @param spinner - Spinner instance for status updates
10
+ * @param variables - Template variables for processing
10
11
  * @returns Number of files deployed
11
12
  */
12
- export declare function deployCICD(options: DeployOptions, spinner: Spinner): Promise<number>;
13
+ export declare function deployCICD(options: DeployOptions, spinner: Spinner, variables?: Record<string, string>): Promise<number>;
13
14
  //# sourceMappingURL=ci-cd.d.ts.map
@@ -1,30 +1,31 @@
1
1
  /**
2
- * CI/CD workflow deployment
2
+ * CI workflow deployment
3
3
  */
4
4
  import chalk from 'chalk';
5
5
  import { deployCITemplates } from '../../utils/deploy-ci.js';
6
6
  /**
7
- * Deploy CI/CD workflow templates
7
+ * Deploy CI workflow templates
8
8
  *
9
9
  * @param options - Deploy command options
10
10
  * @param spinner - Spinner instance for status updates
11
+ * @param variables - Template variables for processing
11
12
  * @returns Number of files deployed
12
13
  */
13
- export async function deployCICD(options, spinner) {
14
+ export async function deployCICD(options, spinner, variables = {}) {
14
15
  if (!options.ciDeploy) {
15
16
  return 0;
16
17
  }
17
- spinner.start('Deploying CI/CD workflow templates...');
18
+ spinner.start('Deploying CI workflow templates...');
18
19
  try {
19
- const ciStats = await deployCITemplates(options);
20
+ const ciStats = await deployCITemplates(options, variables);
20
21
  if (ciStats.deployed.length > 0) {
21
- spinner.succeed(`CI/CD templates deployed (${ciStats.deployed.length} files)`);
22
+ spinner.succeed(`CI templates deployed (${ciStats.deployed.length} files)`);
22
23
  ciStats.deployed.forEach((file) => {
23
24
  console.log(chalk.white(` ✓ ${file}`));
24
25
  });
25
26
  }
26
27
  else {
27
- spinner.info('No CI/CD templates deployed');
28
+ spinner.info('No CI templates deployed');
28
29
  }
29
30
  if (ciStats.skipped.length > 0) {
30
31
  console.log(chalk.yellow(' Skipped:'));
@@ -33,7 +34,7 @@ export async function deployCICD(options, spinner) {
33
34
  });
34
35
  }
35
36
  if (ciStats.errors.length > 0) {
36
- spinner.warn('Some CI/CD templates failed to deploy');
37
+ spinner.warn('Some CI templates failed to deploy');
37
38
  ciStats.errors.forEach((err) => {
38
39
  console.log(chalk.red(` ✗ ${err.file || 'Error'}: ${err.error}`));
39
40
  });
@@ -41,7 +42,7 @@ export async function deployCICD(options, spinner) {
41
42
  return ciStats.deployed.length;
42
43
  }
43
44
  catch (error) {
44
- spinner.fail('CI/CD template deployment failed');
45
+ spinner.fail('CI template deployment failed');
45
46
  const { displayWarning, getErrorMessage } = await import('../../utils/errors.js');
46
47
  displayWarning(getErrorMessage(error));
47
48
  return 0;
@@ -66,7 +66,7 @@ async function promptLintingChoice(stack) {
66
66
  {
67
67
  type: 'confirm',
68
68
  name: 'setupLinting',
69
- message: 'Setup linting configuration? (y/n)',
69
+ message: 'Setup linting configuration?',
70
70
  default: true,
71
71
  },
72
72
  ]);
@@ -82,7 +82,6 @@ async function promptLintingChoice(stack) {
82
82
  */
83
83
  async function configureRecommendedLinting(stack) {
84
84
  const tools = getRecommendedTools(stack.framework, stack.language);
85
- console.log(chalk.green('\n✔ Setup linting configuration?'), 'Recommended\n');
86
85
  const dependencies = getDependenciesForTools(tools);
87
86
  const scripts = getScriptsForTools(tools);
88
87
  displayLintingConfig(tools, dependencies, scripts);
@@ -111,35 +110,35 @@ async function detectGitPlatform() {
111
110
  * Display CI/CD configuration summary
112
111
  */
113
112
  function displayCICDConfig(platform) {
114
- console.log(chalk.green('\n✔ Deploy CI/CD workflow templates?'), 'Yes');
113
+ console.log(chalk.green('\n✔ Deploy CI workflow templates?'), 'yes');
115
114
  if (platform !== 'unknown') {
116
115
  console.log(chalk.cyan(`📦 Detected platform: ${platform}\n`));
117
116
  console.log(chalk.white(' Will configure:'));
118
117
  if (platform === 'GitHub Actions') {
119
- console.log(chalk.white(' ✓ .github/workflows/trinity-ci.yml'));
118
+ console.log(chalk.white(' ✓ .github/workflows/ci.yml'));
120
119
  }
121
120
  else if (platform === 'GitLab CI') {
122
121
  console.log(chalk.white(' ✓ .gitlab-ci.yml'));
123
122
  }
124
- console.log(chalk.white(' ✓ trinity/templates/ci/generic-ci.yml (reference)'));
123
+ console.log(chalk.white(' ✓ .claude/trinity/templates/ci/generic-ci.yml (reference)'));
125
124
  }
126
125
  else {
127
126
  console.log(chalk.cyan('\n📦 Will configure:\n'));
128
- console.log(chalk.white(' ✓ .github/workflows/trinity-ci.yml (GitHub Actions)'));
129
- console.log(chalk.white(' ✓ trinity/templates/ci/generic-ci.yml (reference)'));
127
+ console.log(chalk.white(' ✓ .github/workflows/ci.yml (GitHub Actions)'));
128
+ console.log(chalk.white(' ✓ .claude/trinity/templates/ci/generic-ci.yml (reference)'));
130
129
  }
131
130
  }
132
131
  /**
133
132
  * Prompt for CI/CD setup
134
133
  */
135
134
  async function promptCICDSetup() {
136
- console.log(chalk.cyan('\n⚙️ Optional: CI/CD Automation\n'));
137
- console.log(chalk.white('Trinity can setup automated testing workflows for your CI/CD platform.\n'));
135
+ console.log(chalk.cyan('\n⚙️ Optional: CI Automation\n'));
136
+ console.log(chalk.white('Trinity can setup automated testing workflows for your CI platform.\n'));
138
137
  const ciChoice = await inquirer.prompt([
139
138
  {
140
139
  type: 'confirm',
141
140
  name: 'setupCI',
142
- message: 'Deploy CI/CD workflow templates?',
141
+ message: 'Deploy CI workflow templates?',
143
142
  default: true,
144
143
  },
145
144
  ]);
@@ -149,7 +148,7 @@ async function promptCICDSetup() {
149
148
  return true;
150
149
  }
151
150
  else {
152
- console.log(chalk.gray('\n✔ Deploy CI/CD workflow templates?'), 'Skip\n');
151
+ console.log(chalk.gray('\n✔ Deploy CI workflow templates?'), 'Skip\n');
153
152
  return false;
154
153
  }
155
154
  }
@@ -11,20 +11,19 @@ import fs from 'fs-extra';
11
11
  export async function createDirectories(spinner) {
12
12
  spinner.start('Creating Trinity Method structure...');
13
13
  let directoriesCreated = 0;
14
- // Trinity core directories
15
- await fs.ensureDir('trinity/knowledge-base');
16
- await fs.ensureDir('trinity/sessions');
17
- await fs.ensureDir('trinity/investigations');
18
- await fs.ensureDir('trinity/patterns');
19
- await fs.ensureDir('trinity/work-orders');
20
- await fs.ensureDir('trinity/templates');
21
- await fs.ensureDir('trinity/reports');
22
- await fs.ensureDir('trinity/investigations/plans');
23
- await fs.ensureDir('trinity/archive/work-orders');
24
- await fs.ensureDir('trinity/archive/investigations');
25
- await fs.ensureDir('trinity/archive/reports');
26
- await fs.ensureDir('trinity/archive/sessions');
27
- directoriesCreated += 12;
14
+ // Trinity core directories (inside .claude/)
15
+ await fs.ensureDir('.claude/trinity/knowledge-base');
16
+ await fs.ensureDir('.claude/trinity/sessions');
17
+ await fs.ensureDir('.claude/trinity/investigations');
18
+ await fs.ensureDir('.claude/trinity/work-orders');
19
+ await fs.ensureDir('.claude/trinity/templates');
20
+ await fs.ensureDir('.claude/trinity/reports');
21
+ await fs.ensureDir('.claude/trinity/investigations/plans');
22
+ await fs.ensureDir('.claude/trinity/archive/work-orders');
23
+ await fs.ensureDir('.claude/trinity/archive/investigations');
24
+ await fs.ensureDir('.claude/trinity/archive/reports');
25
+ await fs.ensureDir('.claude/trinity/archive/sessions');
26
+ directoriesCreated += 11;
28
27
  // Claude Code directories
29
28
  await fs.ensureDir('.claude/agents/leadership');
30
29
  await fs.ensureDir('.claude/agents/deployment');
@@ -18,14 +18,13 @@ export async function updateGitignore(spinner) {
18
18
  if (await fs.pathExists(gitignorePath)) {
19
19
  gitignoreContent = await fs.readFile(gitignorePath, 'utf8');
20
20
  }
21
- // Trinity files to ignore
21
+ // Trinity files to ignore (archive and templates are ephemeral/generated)
22
22
  const trinityIgnores = [
23
23
  '',
24
24
  '# Trinity Method SDK',
25
- '.claude/',
26
- 'trinity/',
25
+ '.claude/trinity/archive/',
26
+ '.claude/trinity/templates/',
27
27
  '*CLAUDE.md',
28
- 'TRINITY.md',
29
28
  ];
30
29
  // Check if Trinity section already exists
31
30
  if (!gitignoreContent.includes('# Trinity Method SDK')) {
@@ -13,7 +13,7 @@
13
13
  * Manual setup is error-prone and inconsistent. Developers forget folders, skip quality tools, or
14
14
  * misconfigure agents. This command orchestrates TAN (structure), ZEN (documentation), INO (context),
15
15
  * and EIN (CI/CD) to deploy battle-tested Trinity infrastructure in minutes. Every project gets same
16
- * high-quality foundation: 19 agents, 20 commands, quality gates, and documentation architecture.
16
+ * high-quality foundation: 18 agents, 20 commands, quality gates, and documentation architecture.
17
17
  *
18
18
  * @example
19
19
  * ```bash
@@ -13,7 +13,7 @@
13
13
  * Manual setup is error-prone and inconsistent. Developers forget folders, skip quality tools, or
14
14
  * misconfigure agents. This command orchestrates TAN (structure), ZEN (documentation), INO (context),
15
15
  * and EIN (CI/CD) to deploy battle-tested Trinity infrastructure in minutes. Every project gets same
16
- * high-quality foundation: 19 agents, 20 commands, quality gates, and documentation architecture.
16
+ * high-quality foundation: 18 agents, 20 commands, quality gates, and documentation architecture.
17
17
  *
18
18
  * @example
19
19
  * ```bash
@@ -75,6 +75,10 @@ export async function deploy(options) {
75
75
  spinner.succeed(`Detected: ${stack.framework} (${stack.language}) - Source: ${stack.sourceDir}`);
76
76
  // STEP 3: Interactive configuration (or use defaults with --yes)
77
77
  const config = await promptConfiguration(options, stack);
78
+ // Bridge interactive CI/CD selection to deployment flag
79
+ if (config.enableCICD) {
80
+ options.ciDeploy = true;
81
+ }
78
82
  // STEP 3.5: Collect codebase metrics
79
83
  let metrics;
80
84
  if (!options.skipAudit) {
@@ -126,7 +130,7 @@ export async function deploy(options) {
126
130
  const templatesDeployed = await deployTemplates(templatesPath, variables, spinner);
127
131
  progress.templatesDeployed = templatesDeployed;
128
132
  // STEP 11: Deploy CI/CD workflow templates (if enabled)
129
- const cicdFiles = await deployCICD(options, spinner);
133
+ const cicdFiles = await deployCICD(options, spinner, variables);
130
134
  progress.rootFilesDeployed += cicdFiles;
131
135
  // STEP 11.5: Update .gitignore
132
136
  const gitignoreUpdated = await updateGitignore(spinner);
@@ -35,7 +35,7 @@ export async function deployKnowledgeBase(templatesPath, variables, stack, metri
35
35
  const content = await fs.readFile(templatePath, 'utf8');
36
36
  const processed = processTemplate(content, variables);
37
37
  // Validate destination path for security
38
- const destPath = validatePath(`trinity/knowledge-base/${template}`);
38
+ const destPath = validatePath(`.claude/trinity/knowledge-base/${template}`);
39
39
  await fs.writeFile(destPath, processed);
40
40
  filesDeployed++;
41
41
  }
@@ -44,7 +44,7 @@ export async function deployKnowledgeBase(templatesPath, variables, stack, metri
44
44
  // Enrich knowledge base with project metrics
45
45
  try {
46
46
  spinner.start('Enriching knowledge base with project metrics...');
47
- const archPath = 'trinity/knowledge-base/ARCHITECTURE.md';
47
+ const archPath = '.claude/trinity/knowledge-base/ARCHITECTURE.md';
48
48
  if (await fs.pathExists(archPath)) {
49
49
  let archContent = await fs.readFile(archPath, 'utf8');
50
50
  // Replace common placeholders with actual data
@@ -13,7 +13,7 @@ import chalk from 'chalk';
13
13
  export async function checkPreFlight(options, spinner) {
14
14
  spinner.start('Running pre-flight checks...');
15
15
  // Check if Trinity is already deployed
16
- const trinityExists = await fs.pathExists('trinity');
16
+ const trinityExists = await fs.pathExists('.claude/trinity');
17
17
  if (trinityExists && !options.force) {
18
18
  spinner.fail();
19
19
  console.log(chalk.yellow('\nTrinity Method is already deployed in this project.'));
@@ -6,20 +6,6 @@ import path from 'path';
6
6
  import chalk from 'chalk';
7
7
  import { processTemplate } from '../../utils/template-processor.js';
8
8
  import { validatePath } from '../../utils/validate-path.js';
9
- /**
10
- * Deploy TRINITY.md root file
11
- */
12
- async function deployTrinityMarkdown(templatesPath, variables) {
13
- const trinityRootTemplate = path.join(templatesPath, 'root', 'TRINITY.md.template');
14
- if (await fs.pathExists(trinityRootTemplate)) {
15
- const content = await fs.readFile(trinityRootTemplate, 'utf8');
16
- const processed = processTemplate(content, variables);
17
- const destPath = validatePath('TRINITY.md');
18
- await fs.writeFile(destPath, processed);
19
- return 1;
20
- }
21
- return 0;
22
- }
23
9
  /**
24
10
  * Deploy root CLAUDE.md file
25
11
  */
@@ -38,7 +24,7 @@ async function deployRootClaudeMarkdown(templatesPath, variables) {
38
24
  * Deploy VERSION file
39
25
  */
40
26
  async function deployVersionFile(pkgVersion) {
41
- const versionPath = validatePath('trinity/VERSION');
27
+ const versionPath = validatePath('.claude/trinity/VERSION');
42
28
  await fs.writeFile(versionPath, pkgVersion || '2.1.0');
43
29
  return 1;
44
30
  }
@@ -51,7 +37,7 @@ async function deployTrinityClaudeMarkdown(templatesPath, variables, spinner) {
51
37
  if (await fs.pathExists(trinityCLAUDETemplate)) {
52
38
  const content = await fs.readFile(trinityCLAUDETemplate, 'utf8');
53
39
  const processed = processTemplate(content, variables);
54
- const destPath = validatePath('trinity/CLAUDE.md');
40
+ const destPath = validatePath('.claude/trinity/CLAUDE.md');
55
41
  await fs.writeFile(destPath, processed);
56
42
  spinner.succeed('Trinity CLAUDE.md deployed');
57
43
  return 1;
@@ -163,7 +149,6 @@ export async function deployRootFiles(templatesPath, variables, stack, pkgVersio
163
149
  let filesDeployed = 0;
164
150
  // Deploy root files
165
151
  spinner.start('Creating root files...');
166
- filesDeployed += await deployTrinityMarkdown(templatesPath, variables);
167
152
  filesDeployed += await deployRootClaudeMarkdown(templatesPath, variables);
168
153
  filesDeployed += await deployVersionFile(pkgVersion);
169
154
  spinner.succeed('Root files created');
@@ -6,7 +6,7 @@ import chalk from 'chalk';
6
6
  /**
7
7
  * Display deployment statistics section
8
8
  */
9
- function displayStatistics(stats, stack, claudeMdCount, claudeMdSummary) {
9
+ function displayStatistics(stats, _stack, claudeMdCount, claudeMdSummary) {
10
10
  console.log(chalk.cyan('📊 Deployment Statistics (v2.0):\n'));
11
11
  console.log(chalk.white(` Directories Created: ${stats.directories || 17}`));
12
12
  console.log(chalk.white(` Agents Deployed: ${stats.agentsDeployed} (v2.0: 2 leadership + 4 planning + 7 execution + 4 deployment + 1 audit)`));
@@ -88,8 +88,8 @@ function displayNextSteps(options, stack) {
88
88
  step++;
89
89
  }
90
90
  // Standard next steps
91
- console.log(chalk.white(` ${step}. Review trinity/knowledge-base/ARCHITECTURE.md`));
92
- console.log(chalk.white(` ${step + 1}. Update trinity/knowledge-base/To-do.md`));
91
+ console.log(chalk.white(` ${step}. Review .claude/trinity/knowledge-base/ARCHITECTURE.md`));
92
+ console.log(chalk.white(` ${step + 1}. Update .claude/trinity/knowledge-base/To-do.md`));
93
93
  console.log(chalk.white(` ${step + 2}. Open Claude Code and start your first Trinity session`));
94
94
  console.log(chalk.white(` ${step + 3}. Agents will be automatically invoked as needed\n`));
95
95
  // Test linting command (if applicable)
@@ -25,7 +25,7 @@ export async function deployTemplates(templatesPath, variables, spinner) {
25
25
  'PATTERN-TEMPLATE.md.template',
26
26
  'VERIFICATION-TEMPLATE.md.template',
27
27
  ];
28
- await fs.ensureDir('trinity/templates/work-orders');
28
+ await fs.ensureDir('.claude/trinity/templates/work-orders');
29
29
  for (const template of woTemplates) {
30
30
  const templatePath = path.join(templatesPath, 'trinity/templates/work-orders', template);
31
31
  if (await fs.pathExists(templatePath)) {
@@ -33,7 +33,7 @@ export async function deployTemplates(templatesPath, variables, spinner) {
33
33
  const processed = processTemplate(content, variables);
34
34
  const deployedName = template.replace('.template', '');
35
35
  // Validate destination path for security
36
- const destPath = validatePath(`trinity/templates/work-orders/${deployedName}`);
36
+ const destPath = validatePath(`.claude/trinity/templates/work-orders/${deployedName}`);
37
37
  await fs.writeFile(destPath, processed);
38
38
  templatesDeployed++;
39
39
  }
@@ -48,7 +48,7 @@ export async function deployTemplates(templatesPath, variables, spinner) {
48
48
  'security.md.template',
49
49
  'technical.md.template',
50
50
  ];
51
- await fs.ensureDir('trinity/templates/investigations');
51
+ await fs.ensureDir('.claude/trinity/templates/investigations');
52
52
  for (const template of investigationTemplates) {
53
53
  const templatePath = path.join(templatesPath, 'trinity/templates/investigations', template);
54
54
  if (await fs.pathExists(templatePath)) {
@@ -56,7 +56,7 @@ export async function deployTemplates(templatesPath, variables, spinner) {
56
56
  const processed = processTemplate(content, variables);
57
57
  const deployedName = template.replace('.template', '');
58
58
  // Validate destination path for security
59
- const destPath = validatePath(`trinity/templates/investigations/${deployedName}`);
59
+ const destPath = validatePath(`.claude/trinity/templates/investigations/${deployedName}`);
60
60
  await fs.writeFile(destPath, processed);
61
61
  templatesDeployed++;
62
62
  }
@@ -65,7 +65,7 @@ export async function deployTemplates(templatesPath, variables, spinner) {
65
65
  // Deploy documentation templates (all 28 templates including subdirectories)
66
66
  spinner.start('Deploying documentation templates...');
67
67
  const docSourcePath = path.join(templatesPath, 'trinity/templates/documentation');
68
- const docDestPath = 'trinity/templates/documentation';
68
+ const docDestPath = '.claude/trinity/templates/documentation';
69
69
  await fs.ensureDir(docDestPath);
70
70
  // Recursively copy all documentation templates, removing .template extension
71
71
  async function copyDocTemplates(sourcePath, destPath) {
@@ -7,10 +7,10 @@ import fs from 'fs-extra';
7
7
  import path from 'path';
8
8
  /** User-managed files that need backup */
9
9
  const USER_FILES = [
10
- 'trinity/knowledge-base/ARCHITECTURE.md',
11
- 'trinity/knowledge-base/To-do.md',
12
- 'trinity/knowledge-base/ISSUES.md',
13
- 'trinity/knowledge-base/Technical-Debt.md',
10
+ '.claude/trinity/knowledge-base/ARCHITECTURE.md',
11
+ '.claude/trinity/knowledge-base/To-do.md',
12
+ '.claude/trinity/knowledge-base/ISSUES.md',
13
+ '.claude/trinity/knowledge-base/Technical-Debt.md',
14
14
  ];
15
15
  /**
16
16
  * Create backup of Trinity Method files before update
@@ -28,8 +28,7 @@ export async function createUpdateBackup(spinner) {
28
28
  await fs.copy(file, backupPath);
29
29
  }
30
30
  }
31
- // Backup entire trinity and .claude dirs for rollback safety
32
- await fs.copy('trinity', path.join(backupDir, 'trinity'));
31
+ // Backup entire .claude dir for rollback safety (includes .claude/trinity/)
33
32
  await fs.copy('.claude', path.join(backupDir, '.claude'));
34
33
  spinner.succeed('Backup created');
35
34
  return backupDir;
@@ -60,12 +59,7 @@ export async function rollbackFromBackup(backupDir) {
60
59
  }
61
60
  const rollbackSpinner = await import('ora').then((m) => m.default('Restoring from backup...').start());
62
61
  try {
63
- // Restore trinity directory
64
- if (await fs.pathExists(path.join(backupDir, 'trinity'))) {
65
- await fs.remove('trinity');
66
- await fs.copy(path.join(backupDir, 'trinity'), 'trinity');
67
- }
68
- // Restore .claude directory
62
+ // Restore .claude directory (includes .claude/trinity/)
69
63
  if (await fs.pathExists(path.join(backupDir, '.claude'))) {
70
64
  await fs.remove('.claude');
71
65
  await fs.copy(path.join(backupDir, '.claude'), '.claude');
@@ -10,6 +10,7 @@ import chalk from 'chalk';
10
10
  import inquirer from 'inquirer';
11
11
  import { runUpdatePreflightChecks } from './pre-flight.js';
12
12
  import { detectInstalledSDKVersion } from './version.js';
13
+ import { detectLegacyDeployment, migrateLegacyDeployment, updateGitignoreForMigration, } from './migration.js';
13
14
  import { createUpdateBackup, restoreUserContent, rollbackFromBackup, cleanupBackup, } from './backup.js';
14
15
  import { updateAgents } from './agents.js';
15
16
  import { updateCommands } from './commands.js';
@@ -34,10 +35,23 @@ export async function update(options) {
34
35
  knowledgeBaseUpdated: 0,
35
36
  commandsUpdated: 0,
36
37
  filesUpdated: 0,
38
+ legacyMigrated: false,
39
+ gitignoreUpdated: false,
37
40
  };
38
41
  try {
39
42
  // STEP 1: Pre-flight checks
40
- await runUpdatePreflightChecks(spinner);
43
+ const preflight = await runUpdatePreflightChecks(spinner);
44
+ // STEP 1.5: Legacy migration (pre-2.2.0 trinity/ → .claude/trinity/)
45
+ if (preflight.needsLegacyMigration) {
46
+ const legacyInfo = await detectLegacyDeployment(spinner);
47
+ if (legacyInfo.isLegacy) {
48
+ await migrateLegacyDeployment(spinner);
49
+ stats.legacyMigrated = true;
50
+ }
51
+ }
52
+ // STEP 1.7: Update .gitignore patterns
53
+ const gitignoreChanged = await updateGitignoreForMigration(spinner);
54
+ stats.gitignoreUpdated = gitignoreChanged;
41
55
  // STEP 2: Version check
42
56
  const versionInfo = await detectInstalledSDKVersion(spinner);
43
57
  if (versionInfo.isUpToDate && !options.force) {
@@ -28,7 +28,7 @@ export async function updateKnowledgeBase(spinner, stats) {
28
28
  if (await fs.pathExists(sourcePath)) {
29
29
  // Remove .template extension for target
30
30
  const targetFile = templateFile.replace('.template', '');
31
- const targetPath = path.join('trinity/knowledge-base', targetFile);
31
+ const targetPath = path.join('.claude/trinity/knowledge-base', targetFile);
32
32
  await fs.copy(sourcePath, targetPath, { overwrite: true });
33
33
  stats.knowledgeBaseUpdated++;
34
34
  }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Update Migration Module
3
+ * Handles legacy deployment detection and migration from pre-2.2.0 structure
4
+ * @module cli/commands/update/migration
5
+ */
6
+ import { Ora } from 'ora';
7
+ export interface LegacyInfo {
8
+ isLegacy: boolean;
9
+ legacyVersion: string | null;
10
+ }
11
+ /**
12
+ * Detect if the project has a legacy (pre-2.2.0) Trinity deployment
13
+ * Legacy deployments use `trinity/` at root instead of `.claude/trinity/`
14
+ * @param spinner - ora spinner instance for status display
15
+ * @returns Legacy deployment info
16
+ */
17
+ export declare function detectLegacyDeployment(spinner: Ora): Promise<LegacyInfo>;
18
+ /**
19
+ * Migrate legacy Trinity deployment from `trinity/` to `.claude/trinity/`
20
+ * Preserves user-managed knowledge base files during migration
21
+ * @param spinner - ora spinner instance for status display
22
+ */
23
+ export declare function migrateLegacyDeployment(spinner: Ora): Promise<void>;
24
+ /**
25
+ * Update .gitignore to replace old Trinity patterns with current ones
26
+ * Safe to run on any deployment — idempotent
27
+ * @param spinner - ora spinner instance for status display
28
+ * @returns True if gitignore was updated
29
+ */
30
+ export declare function updateGitignoreForMigration(spinner: Ora): Promise<boolean>;
31
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Update Migration Module
3
+ * Handles legacy deployment detection and migration from pre-2.2.0 structure
4
+ * @module cli/commands/update/migration
5
+ */
6
+ import fs from 'fs-extra';
7
+ import path from 'path';
8
+ import { validatePath } from '../../utils/validate-path.js';
9
+ /** Old gitignore patterns from pre-2.2.0 deployments */
10
+ const OLD_GITIGNORE_PATTERNS = ['trinity/', '*CLAUDE.md', 'TRINITY.md'];
11
+ /** Current gitignore patterns */
12
+ const CURRENT_GITIGNORE_PATTERNS = [
13
+ '.claude/trinity/archive/',
14
+ '.claude/trinity/templates/',
15
+ '*CLAUDE.md',
16
+ ];
17
+ /**
18
+ * Detect if the project has a legacy (pre-2.2.0) Trinity deployment
19
+ * Legacy deployments use `trinity/` at root instead of `.claude/trinity/`
20
+ * @param spinner - ora spinner instance for status display
21
+ * @returns Legacy deployment info
22
+ */
23
+ export async function detectLegacyDeployment(spinner) {
24
+ spinner.start('Checking for legacy deployment...');
25
+ const hasLegacyDir = await fs.pathExists('trinity');
26
+ const hasLegacyVersion = await fs.pathExists('trinity/VERSION');
27
+ if (!hasLegacyDir) {
28
+ spinner.info('No legacy deployment detected');
29
+ return { isLegacy: false, legacyVersion: null };
30
+ }
31
+ let legacyVersion = null;
32
+ if (hasLegacyVersion) {
33
+ legacyVersion = (await fs.readFile('trinity/VERSION', 'utf8')).trim();
34
+ }
35
+ spinner.warn(`Legacy deployment detected (v${legacyVersion || 'unknown'})`);
36
+ return { isLegacy: true, legacyVersion };
37
+ }
38
+ /**
39
+ * Migrate legacy Trinity deployment from `trinity/` to `.claude/trinity/`
40
+ * Preserves user-managed knowledge base files during migration
41
+ * @param spinner - ora spinner instance for status display
42
+ */
43
+ export async function migrateLegacyDeployment(spinner) {
44
+ spinner.start('Migrating legacy deployment to .claude/trinity/...');
45
+ // Create new directory structure
46
+ await fs.ensureDir('.claude/trinity');
47
+ await fs.ensureDir('.claude/agents/leadership');
48
+ await fs.ensureDir('.claude/agents/deployment');
49
+ await fs.ensureDir('.claude/agents/audit');
50
+ await fs.ensureDir('.claude/agents/planning');
51
+ await fs.ensureDir('.claude/agents/aj-team');
52
+ await fs.ensureDir('.claude/commands');
53
+ // Move trinity/ contents to .claude/trinity/
54
+ const trinityContents = await fs.readdir('trinity');
55
+ for (const item of trinityContents) {
56
+ const srcPath = path.join('trinity', item);
57
+ const destPath = path.join('.claude/trinity', item);
58
+ // Don't overwrite if destination already exists (prefer new structure)
59
+ if (!(await fs.pathExists(destPath))) {
60
+ await fs.copy(srcPath, destPath);
61
+ }
62
+ }
63
+ // Remove old trinity/ directory
64
+ await fs.remove('trinity');
65
+ spinner.succeed('Legacy deployment migrated to .claude/trinity/');
66
+ }
67
+ /**
68
+ * Update .gitignore to replace old Trinity patterns with current ones
69
+ * Safe to run on any deployment — idempotent
70
+ * @param spinner - ora spinner instance for status display
71
+ * @returns True if gitignore was updated
72
+ */
73
+ export async function updateGitignoreForMigration(spinner) {
74
+ spinner.start('Updating .gitignore patterns...');
75
+ const gitignorePath = '.gitignore';
76
+ if (!(await fs.pathExists(gitignorePath))) {
77
+ spinner.info('No .gitignore found, skipping');
78
+ return false;
79
+ }
80
+ let content = await fs.readFile(gitignorePath, 'utf8');
81
+ const originalContent = content;
82
+ if (content.includes('# Trinity Method SDK')) {
83
+ // Remove the existing Trinity section entirely
84
+ const lines = content.split('\n');
85
+ const filteredLines = [];
86
+ let inTrinitySection = false;
87
+ for (const line of lines) {
88
+ if (line.trim() === '# Trinity Method SDK') {
89
+ inTrinitySection = true;
90
+ continue;
91
+ }
92
+ // End of Trinity section: next comment or blank line after non-Trinity content
93
+ if (inTrinitySection) {
94
+ const trimmed = line.trim();
95
+ // Still in Trinity section if line is empty, or matches known patterns
96
+ if (trimmed === '' ||
97
+ trimmed === 'trinity/' ||
98
+ trimmed === '*CLAUDE.md' ||
99
+ trimmed === 'TRINITY.md' ||
100
+ trimmed === '.claude/trinity/archive/' ||
101
+ trimmed === '.claude/trinity/templates/') {
102
+ continue;
103
+ }
104
+ // Non-Trinity line — we've left the section
105
+ inTrinitySection = false;
106
+ }
107
+ filteredLines.push(line);
108
+ }
109
+ content = filteredLines.join('\n');
110
+ }
111
+ // Remove any standalone old patterns that might exist outside the section
112
+ for (const pattern of OLD_GITIGNORE_PATTERNS) {
113
+ const regex = new RegExp(`^${pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\s*$`, 'gm');
114
+ content = content.replace(regex, '');
115
+ }
116
+ // Clean up multiple blank lines
117
+ content = content.replace(/\n{3,}/g, '\n\n').trim();
118
+ // Append current Trinity section
119
+ const trinitySection = ['', '# Trinity Method SDK', ...CURRENT_GITIGNORE_PATTERNS].join('\n');
120
+ content = `${content}\n${trinitySection}\n`;
121
+ if (content === originalContent) {
122
+ spinner.info('.gitignore already up to date');
123
+ return false;
124
+ }
125
+ const validatedPath = validatePath(gitignorePath);
126
+ await fs.writeFile(validatedPath, content);
127
+ spinner.succeed('.gitignore patterns updated');
128
+ return true;
129
+ }
130
+ //# sourceMappingURL=migration.js.map
@@ -4,10 +4,15 @@
4
4
  * @module cli/commands/update/pre-flight
5
5
  */
6
6
  import { Ora } from 'ora';
7
+ export interface PreflightResult {
8
+ needsLegacyMigration: boolean;
9
+ }
7
10
  /**
8
11
  * Run pre-flight checks to ensure Trinity Method is deployed
12
+ * Detects both current (.claude/trinity/) and legacy (trinity/) layouts
9
13
  * @param spinner - ora spinner instance for status display
10
- * @throws {UpdateError} If pre-flight checks fail
14
+ * @returns Pre-flight result with migration flags
15
+ * @throws {UpdateError} If no Trinity deployment found at all
11
16
  */
12
- export declare function runUpdatePreflightChecks(spinner: Ora): Promise<void>;
17
+ export declare function runUpdatePreflightChecks(spinner: Ora): Promise<PreflightResult>;
13
18
  //# sourceMappingURL=pre-flight.d.ts.map