trinity-method-sdk 2.0.9 → 2.2.0

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 (147) hide show
  1. package/CHANGELOG.md +702 -267
  2. package/README.md +550 -540
  3. package/dist/cli/commands/deploy/agents.js +1 -1
  4. package/dist/cli/commands/deploy/ci-cd.d.ts +4 -3
  5. package/dist/cli/commands/deploy/ci-cd.js +10 -9
  6. package/dist/cli/commands/deploy/claude-setup.js +28 -35
  7. package/dist/cli/commands/deploy/configuration.js +10 -11
  8. package/dist/cli/commands/deploy/directories.js +13 -14
  9. package/dist/cli/commands/deploy/gitignore.js +3 -5
  10. package/dist/cli/commands/deploy/index.d.ts +1 -1
  11. package/dist/cli/commands/deploy/index.js +7 -3
  12. package/dist/cli/commands/deploy/knowledge-base.js +3 -3
  13. package/dist/cli/commands/deploy/pre-flight.js +1 -1
  14. package/dist/cli/commands/deploy/root-files.js +3 -18
  15. package/dist/cli/commands/deploy/sdk-install.js +1 -1
  16. package/dist/cli/commands/deploy/summary.js +3 -3
  17. package/dist/cli/commands/deploy/templates.js +33 -20
  18. package/dist/cli/commands/update/agents.js +1 -1
  19. package/dist/cli/commands/update/backup.js +6 -12
  20. package/dist/cli/commands/update/commands.d.ts +1 -0
  21. package/dist/cli/commands/update/commands.js +18 -45
  22. package/dist/cli/commands/update/knowledge-base.js +2 -2
  23. package/dist/cli/commands/update/pre-flight.js +11 -11
  24. package/dist/cli/commands/update/summary.js +5 -5
  25. package/dist/cli/commands/update/templates.js +35 -13
  26. package/dist/cli/commands/update/verification.js +5 -5
  27. package/dist/cli/commands/update/version.js +1 -1
  28. package/dist/cli/utils/deploy-ci.d.ts +3 -2
  29. package/dist/cli/utils/deploy-ci.js +24 -24
  30. package/dist/cli/utils/deploy-linting.js +101 -6
  31. package/dist/cli/utils/error-classes.d.ts +2 -2
  32. package/dist/cli/utils/linting-tools.js +14 -6
  33. package/dist/cli/utils/template-processor.js +2 -4
  34. package/dist/templates/{claude → .claude}/EMPLOYEE-DIRECTORY.md.template +16 -22
  35. package/dist/templates/{agents → .claude/agents}/aj-team/apo-documentation-specialist.md.template +10 -10
  36. package/dist/templates/{agents → .claude/agents}/aj-team/bas-quality-gate.md.template +13 -15
  37. package/dist/templates/{agents → .claude/agents}/aj-team/bon-dependency-manager.md.template +4 -4
  38. package/dist/templates/{agents → .claude/agents}/aj-team/cap-configuration-specialist.md.template +3 -3
  39. package/dist/templates/{agents → .claude/agents}/aj-team/dra-code-reviewer.md.template +8 -10
  40. package/dist/templates/{agents → .claude/agents}/aj-team/kil-task-executor.md.template +11 -13
  41. package/dist/templates/{agents → .claude/agents}/aj-team/uro-refactoring-specialist.md.template +3 -3
  42. package/dist/templates/{agents → .claude/agents}/audit/juno-auditor.md.template +46 -42
  43. package/dist/templates/{agents → .claude/agents}/deployment/ein-cicd.md.template +59 -164
  44. package/dist/templates/{agents → .claude/agents}/deployment/ino-context.md.template +25 -22
  45. package/dist/templates/{agents → .claude/agents}/deployment/tan-structure.md.template +32 -30
  46. package/dist/templates/{agents → .claude/agents}/deployment/zen-knowledge.md.template +28 -23
  47. package/dist/templates/{agents → .claude/agents}/leadership/aj-maestro.md.template +10 -6
  48. package/dist/templates/{agents → .claude/agents}/leadership/aly-cto.md.template +22 -19
  49. package/dist/templates/{agents → .claude/agents}/planning/eus-decomposer.md.template +8 -4
  50. package/dist/templates/{agents → .claude/agents}/planning/mon-requirements.md.template +8 -4
  51. package/dist/templates/{agents → .claude/agents}/planning/ror-design.md.template +8 -4
  52. package/dist/templates/{agents → .claude/agents}/planning/tra-planner.md.template +10 -4
  53. package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-audit.md.template +15 -15
  54. package/dist/templates/.claude/commands/execution/trinity-breakdown.md.template +535 -0
  55. package/dist/templates/{shared/claude-commands → .claude/commands/execution}/trinity-orchestrate.md.template +48 -48
  56. package/dist/templates/{shared/claude-commands → .claude/commands/infrastructure}/trinity-init.md.template +32 -54
  57. package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-create-investigation.md.template +13 -7
  58. package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-investigate-templates.md.template +19 -15
  59. package/dist/templates/{shared/claude-commands → .claude/commands/investigation}/trinity-plan-investigation.md.template +12 -6
  60. package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-changelog.md.template +9 -8
  61. package/dist/templates/.claude/commands/maintenance/trinity-docs-update.md.template +279 -0
  62. package/dist/templates/.claude/commands/maintenance/trinity-docs.md.template +2828 -0
  63. package/dist/templates/{shared/claude-commands → .claude/commands/maintenance}/trinity-readme.md.template +21 -20
  64. package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-decompose.md.template +6 -4
  65. package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-design.md.template +6 -4
  66. package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-plan.md.template +7 -5
  67. package/dist/templates/{shared/claude-commands → .claude/commands/planning}/trinity-requirements.md.template +6 -4
  68. package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-continue.md.template +30 -24
  69. package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-end.md.template +403 -397
  70. package/dist/templates/{shared/claude-commands → .claude/commands/session}/trinity-start.md.template +9 -4
  71. package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-agents.md.template +11 -8
  72. package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-verify.md.template +56 -57
  73. package/dist/templates/{shared/claude-commands → .claude/commands/utility}/trinity-workorder.md.template +13 -9
  74. package/dist/templates/ci/ci.yml.template +2 -2
  75. package/dist/templates/root/CLAUDE.md.template +9 -9
  76. package/dist/templates/root/linting/nodejs/.husky-pre-commit.template +5 -0
  77. package/dist/templates/source/base-CLAUDE.md.template +310 -310
  78. package/dist/templates/source/flutter-CLAUDE.md.template +593 -593
  79. package/dist/templates/source/nodejs-CLAUDE.md.template +531 -531
  80. package/dist/templates/source/python-CLAUDE.md.template +510 -510
  81. package/dist/templates/source/react-CLAUDE.md.template +513 -513
  82. package/dist/templates/source/rust-CLAUDE.md.template +653 -653
  83. package/dist/templates/trinity/CLAUDE.md.template +14 -14
  84. package/dist/templates/{knowledge-base → trinity/knowledge-base}/AI-DEVELOPMENT-GUIDE.md.template +1 -1
  85. package/dist/templates/{knowledge-base → trinity/knowledge-base}/ARCHITECTURE.md.template +5 -5
  86. package/dist/templates/{knowledge-base → trinity/knowledge-base}/CODING-PRINCIPLES.md.template +1 -1
  87. package/dist/templates/{knowledge-base → trinity/knowledge-base}/DOCUMENTATION-CRITERIA.md.template +1 -1
  88. package/dist/templates/{knowledge-base → trinity/knowledge-base}/ISSUES.md.template +9 -9
  89. package/dist/templates/{knowledge-base → trinity/knowledge-base}/TESTING-PRINCIPLES.md.template +1 -1
  90. package/dist/templates/{knowledge-base → trinity/knowledge-base}/Technical-Debt.md.template +2 -4
  91. package/dist/templates/{knowledge-base → trinity/knowledge-base}/To-do.md.template +2 -2
  92. package/dist/templates/{knowledge-base → trinity/knowledge-base}/Trinity.md.template +6 -6
  93. package/dist/templates/trinity/templates/documentation/api-docs/README.md.template +218 -0
  94. package/dist/templates/trinity/templates/documentation/configuration/documentation-structure.md.template +71 -0
  95. package/dist/templates/trinity/templates/documentation/configuration/env-example-generator.md.template +387 -0
  96. package/dist/templates/trinity/templates/documentation/discovery/api-endpoint-scanner.md.template +343 -0
  97. package/dist/templates/trinity/templates/documentation/discovery/component-discovery.md.template +254 -0
  98. package/dist/templates/trinity/templates/documentation/discovery/env-variable-extraction.md.template +316 -0
  99. package/dist/templates/trinity/templates/documentation/discovery/framework-detection.md.template +205 -0
  100. package/dist/templates/trinity/templates/documentation/guides/api-development.md.template +375 -0
  101. package/dist/templates/trinity/templates/documentation/guides/contributing.md.template +488 -0
  102. package/dist/templates/trinity/templates/documentation/guides/deployment.md.template +565 -0
  103. package/dist/templates/trinity/templates/documentation/guides/getting-started.md.template +118 -0
  104. package/dist/templates/trinity/templates/documentation/mermaid-diagrams/api-endpoint-map.md.template +56 -0
  105. package/dist/templates/trinity/templates/documentation/mermaid-diagrams/component-hierarchy.md.template +60 -0
  106. package/dist/templates/trinity/templates/documentation/mermaid-diagrams/database-er.md.template +49 -0
  107. package/dist/templates/trinity/templates/documentation/mermaid-diagrams/mvc-flow.md.template +41 -0
  108. package/dist/templates/trinity/templates/documentation/processes/error-handling-protocol.md.template +166 -0
  109. package/dist/templates/trinity/templates/documentation/processes/fallback-mechanism.md.template +88 -0
  110. package/dist/templates/trinity/templates/documentation/reports/apo-docs-update-checklist.md.template +343 -0
  111. package/dist/templates/trinity/templates/documentation/reports/juno-docs-update-checklist.md.template +1337 -0
  112. package/dist/templates/trinity/templates/documentation/reports/juno-final-report.md.template +237 -0
  113. package/dist/templates/trinity/templates/documentation/reports/juno-internal-report.md.template +461 -0
  114. package/dist/templates/trinity/templates/documentation/validation/documentation-verification-rules.md.template +379 -0
  115. package/dist/templates/trinity/templates/documentation/validation/juno-quality-gates.md.template +282 -0
  116. package/dist/templates/{investigations → trinity/templates/investigations}/bug.md.template +14 -14
  117. package/dist/templates/{investigations → trinity/templates/investigations}/feature.md.template +14 -14
  118. package/dist/templates/{investigations → trinity/templates/investigations}/performance.md.template +14 -14
  119. package/dist/templates/{investigations → trinity/templates/investigations}/security.md.template +14 -14
  120. package/dist/templates/{investigations → trinity/templates/investigations}/technical.md.template +14 -14
  121. package/dist/templates/{work-orders → trinity/templates/work-orders}/ANALYSIS-TEMPLATE.md.template +10 -13
  122. package/dist/templates/{work-orders → trinity/templates/work-orders}/AUDIT-TEMPLATE.md.template +10 -26
  123. package/dist/templates/{work-orders → trinity/templates/work-orders}/IMPLEMENTATION-TEMPLATE.md.template +10 -26
  124. package/dist/templates/{work-orders → trinity/templates/work-orders}/INVESTIGATION-TEMPLATE.md.template +10 -25
  125. package/dist/templates/{work-orders → trinity/templates/work-orders}/PATTERN-TEMPLATE.md.template +10 -26
  126. package/dist/templates/{work-orders → trinity/templates/work-orders}/VERIFICATION-TEMPLATE.md.template +10 -26
  127. package/package.json +99 -94
  128. package/dist/templates/agents/leadership/aj-cc.md.template +0 -462
  129. package/dist/templates/ci/cd.yml.template +0 -175
  130. package/dist/templates/ci/github-actions.yml +0 -86
  131. package/dist/templates/root/TRINITY.md.template +0 -52
  132. package/dist/templates/shared/claude-commands/trinity-docs.md.template +0 -2577
  133. /package/dist/templates/{linting → root/linting}/flutter/.pre-commit-config.yaml.template +0 -0
  134. /package/dist/templates/{linting → root/linting}/flutter/analysis_options.yaml.template +0 -0
  135. /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-commonjs.json.template +0 -0
  136. /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-esm.json.template +0 -0
  137. /package/dist/templates/{linting → root/linting}/nodejs/.eslintrc-typescript.json.template +0 -0
  138. /package/dist/templates/{linting → root/linting}/nodejs/.pre-commit-config.yaml.template +0 -0
  139. /package/dist/templates/{linting → root/linting}/nodejs/.prettierrc.json.template +0 -0
  140. /package/dist/templates/{linting → root/linting}/python/.flake8.template +0 -0
  141. /package/dist/templates/{linting → root/linting}/python/.pre-commit-config.yaml.template +0 -0
  142. /package/dist/templates/{linting → root/linting}/python/pyproject.toml.template +0 -0
  143. /package/dist/templates/{linting → root/linting}/rust/.pre-commit-config.yaml.template +0 -0
  144. /package/dist/templates/{linting → root/linting}/rust/clippy.toml.template +0 -0
  145. /package/dist/templates/{linting → root/linting}/rust/rustfmt.toml.template +0 -0
  146. /package/dist/templates/{documentation → trinity/templates/documentation}/ROOT-README.md.template +0 -0
  147. /package/dist/templates/{documentation → trinity/templates/documentation}/SUBDIRECTORY-README.md.template +0 -0
@@ -13,67 +13,40 @@ const COMMAND_CATEGORIES = [
13
13
  'execution',
14
14
  'investigation',
15
15
  'infrastructure',
16
+ 'maintenance',
16
17
  'utility',
17
18
  ];
18
- /**
19
- * Determine command category based on filename
20
- * @param filename - Command file name
21
- * @returns Category name
22
- */
23
- function determineCommandCategory(filename) {
24
- if (filename.includes('start') || filename.includes('continue') || filename.includes('end')) {
25
- return 'session';
26
- }
27
- else if (filename.includes('requirements') ||
28
- filename.includes('design') ||
29
- filename.includes('plan') ||
30
- filename.includes('decompose')) {
31
- return 'planning';
32
- }
33
- else if (filename.includes('orchestrate') ||
34
- filename.includes('audit') ||
35
- filename.includes('changelog') ||
36
- filename.includes('docs') ||
37
- filename.includes('readme')) {
38
- return 'execution';
39
- }
40
- else if (filename.includes('investigation') || filename.includes('investigate')) {
41
- return 'investigation';
42
- }
43
- else if (filename.includes('init')) {
44
- return 'infrastructure';
45
- }
46
- return 'utility';
47
- }
48
19
  /**
49
20
  * Update slash command files from SDK to .claude/commands/
21
+ * Commands are now organized by category in source templates
50
22
  * @param spinner - ora spinner instance for status display
51
23
  * @param stats - update statistics to track progress
52
24
  */
53
25
  export async function updateCommands(spinner, stats) {
54
26
  spinner.start('Updating slash commands...');
55
27
  const sdkPath = await getSDKPath();
56
- const commandsTemplatePath = path.join(sdkPath, 'dist/templates/shared/claude-commands');
28
+ const commandsTemplatePath = path.join(sdkPath, 'dist/templates/.claude/commands');
57
29
  if (!(await fs.pathExists(commandsTemplatePath))) {
58
30
  spinner.warn('Commands template path not found, skipping');
59
31
  return;
60
32
  }
61
- // Create command category directories
33
+ // Iterate through each category directory
62
34
  for (const category of COMMAND_CATEGORIES) {
35
+ const sourceCategoryPath = path.join(commandsTemplatePath, category);
63
36
  const targetCategoryPath = path.join('.claude/commands', category);
64
- await fs.ensureDir(targetCategoryPath);
65
- }
66
- // Copy all command files
67
- const commandFiles = await fs.readdir(commandsTemplatePath);
68
- for (const file of commandFiles) {
69
- if (file.endsWith('.md.template')) {
70
- const sourcePath = path.join(commandsTemplatePath, file);
71
- const category = determineCommandCategory(file);
72
- // Remove .template extension for deployed file
73
- const deployedFileName = file.replace('.template', '');
74
- const targetPath = path.join('.claude/commands', category, deployedFileName);
75
- await fs.copy(sourcePath, targetPath, { overwrite: true });
76
- stats.commandsUpdated++;
37
+ if (await fs.pathExists(sourceCategoryPath)) {
38
+ await fs.ensureDir(targetCategoryPath);
39
+ const commandFiles = await fs.readdir(sourceCategoryPath);
40
+ for (const file of commandFiles) {
41
+ if (file.endsWith('.md.template')) {
42
+ const sourcePath = path.join(sourceCategoryPath, file);
43
+ // Remove .template extension for deployed file
44
+ const deployedFileName = file.replace('.template', '');
45
+ const targetPath = path.join(targetCategoryPath, deployedFileName);
46
+ await fs.copy(sourcePath, targetPath, { overwrite: true });
47
+ stats.commandsUpdated++;
48
+ }
49
+ }
77
50
  }
78
51
  }
79
52
  spinner.succeed(`Slash commands updated (${stats.commandsUpdated} files)`);
@@ -22,13 +22,13 @@ const SDK_MANAGED_KB_FILES = [
22
22
  export async function updateKnowledgeBase(spinner, stats) {
23
23
  spinner.start('Updating knowledge base...');
24
24
  const sdkPath = await getSDKPath();
25
- const kbTemplatePath = path.join(sdkPath, 'dist/templates/knowledge-base');
25
+ const kbTemplatePath = path.join(sdkPath, 'dist/templates/trinity/knowledge-base');
26
26
  for (const templateFile of SDK_MANAGED_KB_FILES) {
27
27
  const sourcePath = path.join(kbTemplatePath, templateFile);
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
  }
@@ -12,26 +12,26 @@ import { UpdateError } from '../../utils/error-classes.js';
12
12
  */
13
13
  export async function runUpdatePreflightChecks(spinner) {
14
14
  spinner.start('Running pre-flight checks...');
15
- // Check trinity directory exists
16
- const trinityExists = await fs.pathExists('trinity');
17
- if (!trinityExists) {
18
- spinner.fail('Trinity Method not deployed');
19
- const { displayInfo } = await import('../../utils/errors.js');
20
- displayInfo('Use: trinity deploy to install');
21
- throw new UpdateError('Trinity Method not deployed in this project', {
22
- reason: 'trinity_directory_missing',
23
- });
24
- }
25
15
  // Check .claude directory exists
26
16
  const claudeExists = await fs.pathExists('.claude');
27
17
  if (!claudeExists) {
28
18
  spinner.fail('.claude directory not found');
29
19
  const { displayInfo } = await import('../../utils/errors.js');
30
- displayInfo('Trinity deployment appears incomplete');
20
+ displayInfo('Use: trinity deploy to install');
31
21
  throw new UpdateError('.claude directory not found', {
32
22
  reason: 'claude_directory_missing',
33
23
  });
34
24
  }
25
+ // Check .claude/trinity directory exists
26
+ const trinityExists = await fs.pathExists('.claude/trinity');
27
+ if (!trinityExists) {
28
+ spinner.fail('Trinity Method not deployed');
29
+ const { displayInfo } = await import('../../utils/errors.js');
30
+ displayInfo('Trinity deployment appears incomplete');
31
+ throw new UpdateError('Trinity Method not deployed in this project', {
32
+ reason: 'trinity_directory_missing',
33
+ });
34
+ }
35
35
  spinner.succeed('Pre-flight checks passed');
36
36
  }
37
37
  //# sourceMappingURL=pre-flight.js.map
@@ -32,15 +32,15 @@ export function displayDryRunPreview(oldVersion, newVersion) {
32
32
  console.log(chalk.white(' Would update:'));
33
33
  console.log(chalk.gray(` • 18 agent files in .claude/agents/`));
34
34
  console.log(chalk.gray(` • 16 slash commands in .claude/commands/`));
35
- console.log(chalk.gray(` • 6 work order templates in trinity/templates/`));
35
+ console.log(chalk.gray(` • 6 work order templates in .claude/trinity/templates/`));
36
36
  console.log(chalk.gray(` • Knowledge base files (Trinity.md, CODING-PRINCIPLES.md, etc.)`));
37
37
  console.log(chalk.gray(` • Version file: ${oldVersion} → ${newVersion}`));
38
38
  console.log('');
39
39
  console.log(chalk.white(' Would preserve:'));
40
- console.log(chalk.gray(` • trinity/knowledge-base/ARCHITECTURE.md`));
41
- console.log(chalk.gray(` • trinity/knowledge-base/To-do.md`));
42
- console.log(chalk.gray(` • trinity/knowledge-base/ISSUES.md`));
43
- console.log(chalk.gray(` • trinity/knowledge-base/Technical-Debt.md`));
40
+ console.log(chalk.gray(` • .claude/trinity/knowledge-base/ARCHITECTURE.md`));
41
+ console.log(chalk.gray(` • .claude/trinity/knowledge-base/To-do.md`));
42
+ console.log(chalk.gray(` • .claude/trinity/knowledge-base/ISSUES.md`));
43
+ console.log(chalk.gray(` • .claude/trinity/knowledge-base/Technical-Debt.md`));
44
44
  console.log('');
45
45
  console.log(chalk.blue('💡 Run without --dry-run to perform update\n'));
46
46
  }
@@ -8,6 +8,38 @@ import path from 'path';
8
8
  import { getSDKPath } from './utils.js';
9
9
  /** Template directories to update */
10
10
  const TEMPLATE_DIRS = ['work-orders', 'documentation', 'investigations'];
11
+ /**
12
+ * Recursively copy files from source to target directory
13
+ * @param sourcePath - source directory path
14
+ * @param targetPath - target directory path
15
+ * @param stats - update statistics to track progress
16
+ */
17
+ async function copyTemplatesRecursively(sourcePath, targetPath, stats) {
18
+ const entries = await fs.readdir(sourcePath, { withFileTypes: true });
19
+ for (const entry of entries) {
20
+ const sourceFile = path.join(sourcePath, entry.name);
21
+ const targetFile = path.join(targetPath, entry.name);
22
+ if (entry.isDirectory()) {
23
+ // Recursively copy subdirectories
24
+ await fs.ensureDir(targetFile);
25
+ await copyTemplatesRecursively(sourceFile, targetFile, stats);
26
+ }
27
+ else if (entry.isFile()) {
28
+ // Copy template files (.md.template files get .template stripped)
29
+ if (entry.name.endsWith('.md.template')) {
30
+ const deployedFileName = entry.name.replace('.template', '');
31
+ const targetFilePath = path.join(targetPath, deployedFileName);
32
+ await fs.copy(sourceFile, targetFilePath, { overwrite: true });
33
+ stats.templatesUpdated++;
34
+ }
35
+ // Copy plain .md files (e.g., Mermaid diagram templates)
36
+ else if (entry.name.endsWith('.md')) {
37
+ await fs.copy(sourceFile, targetFile, { overwrite: true });
38
+ stats.templatesUpdated++;
39
+ }
40
+ }
41
+ }
42
+ }
11
43
  /**
12
44
  * Update template files from SDK to trinity/templates/
13
45
  * @param spinner - ora spinner instance for status display
@@ -16,23 +48,13 @@ const TEMPLATE_DIRS = ['work-orders', 'documentation', 'investigations'];
16
48
  export async function updateTemplates(spinner, stats) {
17
49
  spinner.start('Updating templates...');
18
50
  const sdkPath = await getSDKPath();
19
- const sdkTemplatesPath = path.join(sdkPath, 'dist/templates');
51
+ const sdkTemplatesPath = path.join(sdkPath, 'dist/templates/trinity/templates');
20
52
  for (const templateDir of TEMPLATE_DIRS) {
21
53
  const sourcePath = path.join(sdkTemplatesPath, templateDir);
22
- const targetPath = path.join('trinity/templates', templateDir);
54
+ const targetPath = path.join('.claude/trinity/templates', templateDir);
23
55
  if (await fs.pathExists(sourcePath)) {
24
56
  await fs.ensureDir(targetPath);
25
- const files = await fs.readdir(sourcePath);
26
- // Copy each file individually, stripping .template extension
27
- for (const file of files) {
28
- if (file.endsWith('.md.template')) {
29
- const sourceFile = path.join(sourcePath, file);
30
- const deployedFileName = file.replace('.template', '');
31
- const targetFile = path.join(targetPath, deployedFileName);
32
- await fs.copy(sourceFile, targetFile, { overwrite: true });
33
- stats.templatesUpdated++;
34
- }
35
- }
57
+ await copyTemplatesRecursively(sourcePath, targetPath, stats);
36
58
  }
37
59
  }
38
60
  spinner.succeed(`Templates updated (${stats.templatesUpdated} files)`);
@@ -7,13 +7,13 @@ import fs from 'fs-extra';
7
7
  import { validatePath } from '../../utils/validate-path.js';
8
8
  /** Verification checks to run after update */
9
9
  const VERIFICATION_CHECKS = [
10
- { path: 'trinity/VERSION', desc: 'Version file' },
10
+ { path: '.claude/trinity/VERSION', desc: 'Version file' },
11
11
  { path: '.claude/agents/leadership', desc: 'Leadership agents' },
12
12
  { path: '.claude/agents/planning', desc: 'Planning agents' },
13
13
  { path: '.claude/agents/aj-team', desc: 'AJ team agents' },
14
14
  { path: '.claude/commands', desc: 'Slash commands' },
15
- { path: 'trinity/templates', desc: 'Work order templates' },
16
- { path: 'trinity/knowledge-base/Trinity.md', desc: 'Trinity knowledge base' },
15
+ { path: '.claude/trinity/templates', desc: 'Work order templates' },
16
+ { path: '.claude/trinity/knowledge-base/Trinity.md', desc: 'Trinity knowledge base' },
17
17
  ];
18
18
  /**
19
19
  * Verify update deployment is successful
@@ -31,7 +31,7 @@ export async function verifyUpdateDeployment(spinner, expectedVersion) {
31
31
  }
32
32
  }
33
33
  // Verify version was actually updated
34
- const versionPath = 'trinity/VERSION';
34
+ const versionPath = '.claude/trinity/VERSION';
35
35
  const updatedVersion = (await fs.readFile(versionPath, 'utf8')).trim();
36
36
  if (updatedVersion !== expectedVersion) {
37
37
  spinner.fail('Version file not updated correctly');
@@ -47,7 +47,7 @@ export async function verifyUpdateDeployment(spinner, expectedVersion) {
47
47
  export async function updateVersionFile(spinner, version) {
48
48
  spinner.start('Updating version file...');
49
49
  // Validate destination path for security
50
- const destPath = validatePath('trinity/VERSION');
50
+ const destPath = validatePath('.claude/trinity/VERSION');
51
51
  await fs.writeFile(destPath, version);
52
52
  spinner.succeed('Version file updated');
53
53
  }
@@ -14,7 +14,7 @@ import { getPackageJsonPath } from '../../utils/get-sdk-path.js';
14
14
  export async function detectInstalledSDKVersion(spinner) {
15
15
  spinner.start('Checking versions...');
16
16
  // Read current version from trinity/VERSION
17
- const versionPath = 'trinity/VERSION';
17
+ const versionPath = '.claude/trinity/VERSION';
18
18
  let currentVersion = '0.0.0';
19
19
  if (await fs.pathExists(versionPath)) {
20
20
  currentVersion = (await fs.readFile(versionPath, 'utf8')).trim();
@@ -12,11 +12,12 @@ interface CIDeployOptions {
12
12
  force?: boolean;
13
13
  }
14
14
  /**
15
- * Deploy CI/CD workflow templates based on detected Git platform
15
+ * Deploy CI workflow templates based on detected Git platform
16
16
  *
17
17
  * @param options - Deployment options
18
+ * @param variables - Template variables for processing
18
19
  * @returns Deployment results with statistics
19
20
  */
20
- export declare function deployCITemplates(options?: CIDeployOptions): Promise<CIDeploymentStats>;
21
+ export declare function deployCITemplates(options?: CIDeployOptions, variables?: Record<string, string>): Promise<CIDeploymentStats>;
21
22
  export {};
22
23
  //# sourceMappingURL=deploy-ci.d.ts.map
@@ -3,6 +3,7 @@ import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
4
  import { dirname } from 'path';
5
5
  import { validatePath } from './validate-path.js';
6
+ import { processTemplate } from './template-processor.js';
6
7
  const __filename = fileURLToPath(import.meta.url);
7
8
  const __dirname = dirname(__filename);
8
9
  /**
@@ -20,7 +21,7 @@ async function deployGitLabCI(templatesPath, options, stats) {
20
21
  const content = await fs.readFile(gitlabTemplate, 'utf8');
21
22
  const gitlabCIExists = await fs.pathExists('.gitlab-ci.yml');
22
23
  if (gitlabCIExists && !options.force) {
23
- stats.skipped.push('.gitlab-ci.yml (already exists)');
24
+ stats.skipped.push('.gitlab-ci.yml (already exists, use --force to overwrite)');
24
25
  return;
25
26
  }
26
27
  // Validate destination path for security
@@ -34,12 +35,13 @@ async function deployGitLabCI(templatesPath, options, stats) {
34
35
  }
35
36
  }
36
37
  /**
37
- * Deploy CI/CD workflow templates based on detected Git platform
38
+ * Deploy CI workflow templates based on detected Git platform
38
39
  *
39
40
  * @param options - Deployment options
41
+ * @param variables - Template variables for processing
40
42
  * @returns Deployment results with statistics
41
43
  */
42
- export async function deployCITemplates(options = {}) {
44
+ export async function deployCITemplates(options = {}, variables = {}) {
43
45
  const stats = {
44
46
  deployed: [],
45
47
  skipped: [],
@@ -49,33 +51,31 @@ export async function deployCITemplates(options = {}) {
49
51
  // Detect Git platform
50
52
  const platform = await detectGitPlatform();
51
53
  const templatesPath = path.join(__dirname, '../../templates/ci');
52
- // GitHub Actions - Deploy both CI and CD workflows
54
+ // GitHub Actions - Deploy CI workflow
53
55
  if (platform === 'github' || platform === 'unknown') {
54
56
  try {
55
57
  await fs.ensureDir('.github/workflows');
56
58
  // Deploy CI workflow
57
59
  const ciTemplate = path.join(templatesPath, 'ci.yml.template');
58
60
  if (await fs.pathExists(ciTemplate)) {
59
- const content = await fs.readFile(ciTemplate, 'utf8');
60
- // Validate destination path for security
61
- const destPath = validatePath('.github/workflows/ci.yml');
62
- await fs.writeFile(destPath, content);
63
- stats.deployed.push('.github/workflows/ci.yml');
64
- }
65
- // Deploy CD workflow
66
- const cdTemplate = path.join(templatesPath, 'cd.yml.template');
67
- if (await fs.pathExists(cdTemplate)) {
68
- const content = await fs.readFile(cdTemplate, 'utf8');
69
- // Validate destination path for security
70
- const destPath = validatePath('.github/workflows/cd.yml');
71
- await fs.writeFile(destPath, content);
72
- stats.deployed.push('.github/workflows/cd.yml');
61
+ const ciExists = await fs.pathExists('.github/workflows/ci.yml');
62
+ if (ciExists && !options.force) {
63
+ stats.skipped.push('.github/workflows/ci.yml (already exists, use --force to overwrite)');
64
+ }
65
+ else {
66
+ const content = await fs.readFile(ciTemplate, 'utf8');
67
+ const processed = processTemplate(content, variables);
68
+ // Validate destination path for security
69
+ const destPath = validatePath('.github/workflows/ci.yml');
70
+ await fs.writeFile(destPath, processed);
71
+ stats.deployed.push('.github/workflows/ci.yml');
72
+ }
73
73
  }
74
74
  }
75
75
  catch (error) {
76
76
  const { getErrorMessage } = await import('./errors.js');
77
77
  stats.errors.push({
78
- file: '.github/workflows/ci.yml or cd.yml',
78
+ file: '.github/workflows/ci.yml',
79
79
  error: getErrorMessage(error),
80
80
  });
81
81
  }
@@ -84,22 +84,22 @@ export async function deployCITemplates(options = {}) {
84
84
  if (platform === 'gitlab') {
85
85
  await deployGitLabCI(templatesPath, options, stats);
86
86
  }
87
- // Generic template (always deploy to trinity/templates/ci)
87
+ // Generic template (always deploy to .claude/trinity/templates/ci)
88
88
  try {
89
- await fs.ensureDir('trinity/templates/ci');
89
+ await fs.ensureDir('.claude/trinity/templates/ci');
90
90
  const genericTemplate = path.join(templatesPath, 'generic-ci.yml');
91
91
  if (await fs.pathExists(genericTemplate)) {
92
92
  const content = await fs.readFile(genericTemplate, 'utf8');
93
93
  // Validate destination path for security
94
- const destPath = validatePath('trinity/templates/ci/generic-ci.yml');
94
+ const destPath = validatePath('.claude/trinity/templates/ci/generic-ci.yml');
95
95
  await fs.writeFile(destPath, content);
96
- stats.deployed.push('trinity/templates/ci/generic-ci.yml');
96
+ stats.deployed.push('.claude/trinity/templates/ci/generic-ci.yml');
97
97
  }
98
98
  }
99
99
  catch (error) {
100
100
  const { getErrorMessage } = await import('./errors.js');
101
101
  stats.errors.push({
102
- file: 'trinity/templates/ci/generic-ci.yml',
102
+ file: '.claude/trinity/templates/ci/generic-ci.yml',
103
103
  error: getErrorMessage(error),
104
104
  });
105
105
  }
@@ -1,10 +1,11 @@
1
1
  import fs from 'fs-extra';
2
2
  import path from 'path';
3
+ import chalk from 'chalk';
3
4
  import { processTemplate } from './template-processor.js';
4
5
  import { validatePath } from './validate-path.js';
5
6
  export async function deployLintingTool(tool, stack, templatesPath, variables) {
6
7
  const frameworkDir = getFrameworkDirectory(stack.framework);
7
- const templateDir = path.join(templatesPath, 'linting', frameworkDir);
8
+ const templateDir = path.join(templatesPath, 'root/linting', frameworkDir);
8
9
  switch (tool.id) {
9
10
  case 'eslint':
10
11
  case 'eslint-typescript': // Alias for eslint with TypeScript (backward compatibility)
@@ -14,7 +15,7 @@ export async function deployLintingTool(tool, stack, templatesPath, variables) {
14
15
  await deployPrettier(tool, templateDir, variables);
15
16
  break;
16
17
  case 'precommit':
17
- await deployPreCommit(tool, templateDir, variables);
18
+ await deployPreCommit(tool, stack, templateDir, variables);
18
19
  break;
19
20
  case 'typescript-eslint':
20
21
  await deployTypeScriptESLint(tool, stack, templateDir, variables);
@@ -46,7 +47,22 @@ function getFrameworkDirectory(framework) {
46
47
  };
47
48
  return frameworkMap[framework] || 'nodejs';
48
49
  }
49
- async function deployESLint(tool, stack, templateDir, variables) {
50
+ async function deployESLint(_tool, stack, templateDir, variables) {
51
+ // Skip if ESLint config already exists
52
+ const eslintConfigs = [
53
+ '.eslintrc.json',
54
+ '.eslintrc.js',
55
+ '.eslintrc.cjs',
56
+ '.eslintrc.yml',
57
+ 'eslint.config.js',
58
+ 'eslint.config.mjs',
59
+ ];
60
+ for (const config of eslintConfigs) {
61
+ if (await fs.pathExists(config)) {
62
+ console.warn(chalk.yellow(` Skipped: .eslintrc.json (${config} already exists, use --force to overwrite)`));
63
+ return;
64
+ }
65
+ }
50
66
  let templateFile;
51
67
  if (stack.language === 'TypeScript') {
52
68
  templateFile = '.eslintrc-typescript.json.template';
@@ -64,7 +80,22 @@ async function deployESLint(tool, stack, templateDir, variables) {
64
80
  const destPath = validatePath('.eslintrc.json');
65
81
  await fs.writeFile(destPath, processed);
66
82
  }
67
- async function deployPrettier(tool, templateDir, variables) {
83
+ async function deployPrettier(_tool, templateDir, variables) {
84
+ // Skip if Prettier config already exists
85
+ const prettierConfigs = [
86
+ '.prettierrc.json',
87
+ '.prettierrc',
88
+ '.prettierrc.js',
89
+ '.prettierrc.cjs',
90
+ '.prettierrc.yml',
91
+ 'prettier.config.js',
92
+ ];
93
+ for (const config of prettierConfigs) {
94
+ if (await fs.pathExists(config)) {
95
+ console.warn(chalk.yellow(` Skipped: .prettierrc.json (${config} already exists, use --force to overwrite)`));
96
+ return;
97
+ }
98
+ }
68
99
  const templatePath = path.join(templateDir, '.prettierrc.json.template');
69
100
  const content = await fs.readFile(templatePath, 'utf8');
70
101
  const processed = processTemplate(content, variables);
@@ -72,7 +103,71 @@ async function deployPrettier(tool, templateDir, variables) {
72
103
  const destPath = validatePath('.prettierrc.json');
73
104
  await fs.writeFile(destPath, processed);
74
105
  }
75
- async function deployPreCommit(tool, templateDir, variables) {
106
+ async function deployPreCommit(tool, stack, templateDir, variables) {
107
+ // Skip if existing pre-commit setup detected
108
+ if (await hasExistingPreCommitSetup()) {
109
+ console.warn(chalk.yellow(' Existing pre-commit configuration detected, skipping deployment'));
110
+ return;
111
+ }
112
+ const framework = stack.framework;
113
+ if (framework === 'Node.js' || framework === 'React' || framework === 'Next.js') {
114
+ await deployHuskyPreCommit(tool, templateDir, variables);
115
+ }
116
+ else {
117
+ await deployPythonPreCommit(tool, templateDir, variables);
118
+ }
119
+ }
120
+ async function hasExistingPreCommitSetup() {
121
+ // Check for .husky/ directory
122
+ if (await fs.pathExists('.husky')) {
123
+ return true;
124
+ }
125
+ // Check for .pre-commit-config.yaml
126
+ if (await fs.pathExists('.pre-commit-config.yaml')) {
127
+ return true;
128
+ }
129
+ // Check package.json for husky or lint-staged
130
+ if (await fs.pathExists('package.json')) {
131
+ const pkg = await fs.readJson('package.json');
132
+ const allDeps = {
133
+ ...pkg.dependencies,
134
+ ...pkg.devDependencies,
135
+ };
136
+ if (allDeps.husky || allDeps['lint-staged']) {
137
+ return true;
138
+ }
139
+ }
140
+ return false;
141
+ }
142
+ async function deployHuskyPreCommit(_tool, templateDir, variables) {
143
+ // Create .husky directory
144
+ await fs.ensureDir('.husky');
145
+ // Deploy pre-commit hook from template
146
+ const templatePath = path.join(templateDir, '.husky-pre-commit.template');
147
+ const content = await fs.readFile(templatePath, 'utf8');
148
+ const processed = processTemplate(content, variables);
149
+ const destPath = validatePath('.husky/pre-commit');
150
+ await fs.writeFile(destPath, processed, { mode: 0o755 });
151
+ // Add lint-staged config to package.json
152
+ await addLintStagedConfig();
153
+ }
154
+ async function addLintStagedConfig() {
155
+ const packageJsonPath = 'package.json';
156
+ if (!(await fs.pathExists(packageJsonPath))) {
157
+ return;
158
+ }
159
+ const pkg = await fs.readJson(packageJsonPath);
160
+ if (pkg['lint-staged']) {
161
+ return; // Already has lint-staged config
162
+ }
163
+ pkg['lint-staged'] = {
164
+ '*.{ts,tsx}': ['eslint --fix', 'prettier --write'],
165
+ '*.{js,jsx}': ['eslint --fix', 'prettier --write'],
166
+ '*.{json,md,yml,yaml}': ['prettier --write'],
167
+ };
168
+ await fs.writeJson(packageJsonPath, pkg, { spaces: 2 });
169
+ }
170
+ async function deployPythonPreCommit(_tool, templateDir, variables) {
76
171
  const templatePath = path.join(templateDir, '.pre-commit-config.yaml.template');
77
172
  const content = await fs.readFile(templatePath, 'utf8');
78
173
  const processed = processTemplate(content, variables);
@@ -116,7 +211,7 @@ async function deployPythonTool(tool, templateDir, variables) {
116
211
  await fs.writeFile(destPath, processed);
117
212
  }
118
213
  }
119
- async function deployDartAnalyzer(tool, templateDir, variables) {
214
+ async function deployDartAnalyzer(_tool, templateDir, variables) {
120
215
  const templatePath = path.join(templateDir, 'analysis_options.yaml.template');
121
216
  const content = await fs.readFile(templatePath, 'utf8');
122
217
  const processed = processTemplate(content, variables);
@@ -10,7 +10,7 @@
10
10
  export declare class TrinityCLIError extends Error {
11
11
  readonly code: string;
12
12
  readonly exitCode: number;
13
- readonly context?: Record<string, unknown>;
13
+ readonly context?: Record<string, unknown> | undefined;
14
14
  /**
15
15
  * Create a Trinity CLI error
16
16
  * @param message - Human-readable error message
@@ -18,7 +18,7 @@ export declare class TrinityCLIError extends Error {
18
18
  * @param exitCode - Process exit code (default: 1)
19
19
  * @param context - Additional context for debugging
20
20
  */
21
- constructor(message: string, code: string, exitCode?: number, context?: Record<string, unknown>);
21
+ constructor(message: string, code: string, exitCode?: number, context?: Record<string, unknown> | undefined);
22
22
  /**
23
23
  * Format error for user display
24
24
  * @returns Formatted error message with code
@@ -27,10 +27,14 @@ export const lintingTools = {
27
27
  {
28
28
  id: 'precommit',
29
29
  name: 'Pre-commit hooks',
30
- description: 'Git hooks for code quality',
31
- file: '.pre-commit-config.yaml',
30
+ description: 'Git hooks for code quality (husky + lint-staged)',
31
+ file: '.husky/pre-commit',
32
32
  recommended: true,
33
- dependencies: [],
33
+ dependencies: ['husky@^9.1.7', 'lint-staged@^16.2.0'],
34
+ scripts: {
35
+ prepare: 'husky',
36
+ },
37
+ postInstall: 'npm install',
34
38
  },
35
39
  {
36
40
  id: 'typescript-eslint',
@@ -69,10 +73,14 @@ export const lintingTools = {
69
73
  {
70
74
  id: 'precommit',
71
75
  name: 'Pre-commit hooks',
72
- description: 'Git hooks for code quality',
73
- file: '.pre-commit-config.yaml',
76
+ description: 'Git hooks for code quality (husky + lint-staged)',
77
+ file: '.husky/pre-commit',
74
78
  recommended: true,
75
- dependencies: [],
79
+ dependencies: ['husky@^9.1.7', 'lint-staged@^16.2.0'],
80
+ scripts: {
81
+ prepare: 'husky',
82
+ },
83
+ postInstall: 'npm install',
76
84
  },
77
85
  {
78
86
  id: 'typescript-eslint',
@@ -24,14 +24,12 @@ const VARIABLE_RESOLVERS = {
24
24
  DEPLOYMENT_TIMESTAMP: (v) => toString(v.DEPLOYMENT_TIMESTAMP || v.timestamp) || new Date().toISOString(),
25
25
  LANGUAGE: (v) => toString(v.LANGUAGE || v.language) || 'Unknown',
26
26
  PACKAGE_MANAGER: (v) => toString(v.PACKAGE_MANAGER || v.packageManager) || 'npm',
27
- TRINITY_VERSION: (v) => toString(v.TRINITY_VERSION) || '2.0.9',
27
+ TRINITY_VERSION: (v) => toString(v.TRINITY_VERSION) || '2.1.0',
28
28
  TECHNOLOGY_STACK: (v) => toString(v.TECHNOLOGY_STACK || v.TECH_STACK || v.techStack) || 'Unknown',
29
29
  PRIMARY_FRAMEWORK: (v) => toString(v.PRIMARY_FRAMEWORK || v.FRAMEWORK || v.framework) || 'Generic',
30
30
  CURRENT_DATE: (v) => toString(v.CURRENT_DATE) || new Date().toISOString().split('T')[0],
31
31
  PROJECT_VAR_NAME: (v) => resolveProjectVarName(v),
32
- TRINITY_HOME: (v) => toString(v.TRINITY_HOME) ||
33
- process.env.TRINITY_HOME ||
34
- 'C:/Users/lukaf/Desktop/Dev Work/trinity-method',
32
+ TRINITY_HOME: (v) => toString(v.TRINITY_HOME) || process.env.TRINITY_HOME || process.cwd(),
35
33
  };
36
34
  export function processTemplate(content, variables) {
37
35
  let processed = content;