timsquad 2.0.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 (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +347 -0
  3. package/bin/tsq.js +6 -0
  4. package/dist/commands/feedback.d.ts +3 -0
  5. package/dist/commands/feedback.d.ts.map +1 -0
  6. package/dist/commands/feedback.js +142 -0
  7. package/dist/commands/feedback.js.map +1 -0
  8. package/dist/commands/full.d.ts +3 -0
  9. package/dist/commands/full.d.ts.map +1 -0
  10. package/dist/commands/full.js +87 -0
  11. package/dist/commands/full.js.map +1 -0
  12. package/dist/commands/git/commit.d.ts +3 -0
  13. package/dist/commands/git/commit.d.ts.map +1 -0
  14. package/dist/commands/git/commit.js +88 -0
  15. package/dist/commands/git/commit.js.map +1 -0
  16. package/dist/commands/git/index.d.ts +5 -0
  17. package/dist/commands/git/index.d.ts.map +1 -0
  18. package/dist/commands/git/index.js +5 -0
  19. package/dist/commands/git/index.js.map +1 -0
  20. package/dist/commands/git/pr.d.ts +3 -0
  21. package/dist/commands/git/pr.d.ts.map +1 -0
  22. package/dist/commands/git/pr.js +138 -0
  23. package/dist/commands/git/pr.js.map +1 -0
  24. package/dist/commands/git/release.d.ts +3 -0
  25. package/dist/commands/git/release.d.ts.map +1 -0
  26. package/dist/commands/git/release.js +158 -0
  27. package/dist/commands/git/release.js.map +1 -0
  28. package/dist/commands/git/sync.d.ts +3 -0
  29. package/dist/commands/git/sync.d.ts.map +1 -0
  30. package/dist/commands/git/sync.js +132 -0
  31. package/dist/commands/git/sync.js.map +1 -0
  32. package/dist/commands/init.d.ts +3 -0
  33. package/dist/commands/init.d.ts.map +1 -0
  34. package/dist/commands/init.js +150 -0
  35. package/dist/commands/init.js.map +1 -0
  36. package/dist/commands/log.d.ts +3 -0
  37. package/dist/commands/log.d.ts.map +1 -0
  38. package/dist/commands/log.js +271 -0
  39. package/dist/commands/log.js.map +1 -0
  40. package/dist/commands/metrics.d.ts +3 -0
  41. package/dist/commands/metrics.d.ts.map +1 -0
  42. package/dist/commands/metrics.js +299 -0
  43. package/dist/commands/metrics.js.map +1 -0
  44. package/dist/commands/quick.d.ts +3 -0
  45. package/dist/commands/quick.d.ts.map +1 -0
  46. package/dist/commands/quick.js +136 -0
  47. package/dist/commands/quick.js.map +1 -0
  48. package/dist/commands/retro.d.ts +3 -0
  49. package/dist/commands/retro.d.ts.map +1 -0
  50. package/dist/commands/retro.js +280 -0
  51. package/dist/commands/retro.js.map +1 -0
  52. package/dist/commands/status.d.ts +3 -0
  53. package/dist/commands/status.d.ts.map +1 -0
  54. package/dist/commands/status.js +127 -0
  55. package/dist/commands/status.js.map +1 -0
  56. package/dist/commands/watch.d.ts +3 -0
  57. package/dist/commands/watch.d.ts.map +1 -0
  58. package/dist/commands/watch.js +213 -0
  59. package/dist/commands/watch.js.map +1 -0
  60. package/dist/index.d.ts +3 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +50 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/lib/config.d.ts +34 -0
  65. package/dist/lib/config.d.ts.map +1 -0
  66. package/dist/lib/config.js +108 -0
  67. package/dist/lib/config.js.map +1 -0
  68. package/dist/lib/project.d.ts +47 -0
  69. package/dist/lib/project.d.ts.map +1 -0
  70. package/dist/lib/project.js +191 -0
  71. package/dist/lib/project.js.map +1 -0
  72. package/dist/lib/template.d.ts +33 -0
  73. package/dist/lib/template.d.ts.map +1 -0
  74. package/dist/lib/template.js +151 -0
  75. package/dist/lib/template.js.map +1 -0
  76. package/dist/types/config.d.ts +75 -0
  77. package/dist/types/config.d.ts.map +1 -0
  78. package/dist/types/config.js +66 -0
  79. package/dist/types/config.js.map +1 -0
  80. package/dist/types/feedback.d.ts +59 -0
  81. package/dist/types/feedback.d.ts.map +1 -0
  82. package/dist/types/feedback.js +26 -0
  83. package/dist/types/feedback.js.map +1 -0
  84. package/dist/types/index.d.ts +4 -0
  85. package/dist/types/index.d.ts.map +1 -0
  86. package/dist/types/index.js +5 -0
  87. package/dist/types/index.js.map +1 -0
  88. package/dist/types/project.d.ts +89 -0
  89. package/dist/types/project.d.ts.map +1 -0
  90. package/dist/types/project.js +44 -0
  91. package/dist/types/project.js.map +1 -0
  92. package/dist/utils/colors.d.ts +30 -0
  93. package/dist/utils/colors.d.ts.map +1 -0
  94. package/dist/utils/colors.js +54 -0
  95. package/dist/utils/colors.js.map +1 -0
  96. package/dist/utils/date.d.ts +25 -0
  97. package/dist/utils/date.d.ts.map +1 -0
  98. package/dist/utils/date.js +65 -0
  99. package/dist/utils/date.js.map +1 -0
  100. package/dist/utils/fs.d.ts +49 -0
  101. package/dist/utils/fs.d.ts.map +1 -0
  102. package/dist/utils/fs.js +84 -0
  103. package/dist/utils/fs.js.map +1 -0
  104. package/dist/utils/prompts.d.ts +31 -0
  105. package/dist/utils/prompts.d.ts.map +1 -0
  106. package/dist/utils/prompts.js +95 -0
  107. package/dist/utils/prompts.js.map +1 -0
  108. package/dist/utils/yaml.d.ts +21 -0
  109. package/dist/utils/yaml.d.ts.map +1 -0
  110. package/dist/utils/yaml.js +40 -0
  111. package/dist/utils/yaml.js.map +1 -0
  112. package/package.json +71 -0
  113. package/templates/common/CLAUDE.md.template +254 -0
  114. package/templates/common/claude/agents/tsq-dba.md +290 -0
  115. package/templates/common/claude/agents/tsq-designer.md +304 -0
  116. package/templates/common/claude/agents/tsq-developer.md +118 -0
  117. package/templates/common/claude/agents/tsq-planner.md +90 -0
  118. package/templates/common/claude/agents/tsq-prompter.md +336 -0
  119. package/templates/common/claude/agents/tsq-qa.md +134 -0
  120. package/templates/common/claude/agents/tsq-retro.md +168 -0
  121. package/templates/common/claude/agents/tsq-security.md +190 -0
  122. package/templates/common/claude/skills/architecture/SKILL.md +123 -0
  123. package/templates/common/claude/skills/backend/node/SKILL.md +1015 -0
  124. package/templates/common/claude/skills/coding/SKILL.md +171 -0
  125. package/templates/common/claude/skills/database/prisma/SKILL.md +357 -0
  126. package/templates/common/claude/skills/frontend/nextjs/SKILL.md +279 -0
  127. package/templates/common/claude/skills/frontend/react/SKILL.md +1729 -0
  128. package/templates/common/claude/skills/methodology/bdd/SKILL.md +234 -0
  129. package/templates/common/claude/skills/methodology/ddd/SKILL.md +311 -0
  130. package/templates/common/claude/skills/methodology/tdd/SKILL.md +512 -0
  131. package/templates/common/claude/skills/planning/SKILL.md +90 -0
  132. package/templates/common/claude/skills/security/SKILL.md +234 -0
  133. package/templates/common/claude/skills/testing/SKILL.md +146 -0
  134. package/templates/common/claude/skills/typescript/SKILL.md +435 -0
  135. package/templates/common/config.template.yaml +131 -0
  136. package/templates/common/timsquad/architectures/clean/ARCHITECTURE.md +49 -0
  137. package/templates/common/timsquad/architectures/clean/backend.xml +210 -0
  138. package/templates/common/timsquad/architectures/clean/frontend.xml +148 -0
  139. package/templates/common/timsquad/architectures/fsd/ARCHITECTURE.md +67 -0
  140. package/templates/common/timsquad/architectures/fsd/frontend.xml +288 -0
  141. package/templates/common/timsquad/architectures/hexagonal/ARCHITECTURE.md +60 -0
  142. package/templates/common/timsquad/architectures/hexagonal/backend.xml +300 -0
  143. package/templates/common/timsquad/constraints/competency-framework.xml +501 -0
  144. package/templates/common/timsquad/constraints/ssot-schema.xml +433 -0
  145. package/templates/common/timsquad/feedback/feedback-router.sh +341 -0
  146. package/templates/common/timsquad/feedback/routing-rules.yaml +352 -0
  147. package/templates/common/timsquad/generators/data-design.xml +290 -0
  148. package/templates/common/timsquad/generators/prd.xml +280 -0
  149. package/templates/common/timsquad/generators/requirements.xml +220 -0
  150. package/templates/common/timsquad/generators/service-spec.xml +266 -0
  151. package/templates/common/timsquad/logs/_example.md +81 -0
  152. package/templates/common/timsquad/logs/_template.md +46 -0
  153. package/templates/common/timsquad/patterns/cqrs.xml +127 -0
  154. package/templates/common/timsquad/patterns/event-sourcing.xml +85 -0
  155. package/templates/common/timsquad/patterns/repository.xml +64 -0
  156. package/templates/common/timsquad/process/state-machine.xml +343 -0
  157. package/templates/common/timsquad/process/validation-rules.xml +308 -0
  158. package/templates/common/timsquad/process/workflow-base.xml +202 -0
  159. package/templates/common/timsquad/retrospective/cycle-report.template.md +205 -0
  160. package/templates/common/timsquad/retrospective/metrics/metrics-schema.json +203 -0
  161. package/templates/common/timsquad/retrospective/patterns/failure-patterns.md +199 -0
  162. package/templates/common/timsquad/retrospective/patterns/success-patterns.md +262 -0
  163. package/templates/common/timsquad/retrospective/retrospective-config.xml +294 -0
  164. package/templates/common/timsquad/retrospective/retrospective-state.xml +210 -0
  165. package/templates/common/timsquad/ssot/adr/ADR-000-template.md +121 -0
  166. package/templates/common/timsquad/ssot/adr/ADR-001-example.md +115 -0
  167. package/templates/common/timsquad/ssot/data-design.template.md +132 -0
  168. package/templates/common/timsquad/ssot/deployment-spec.template.md +384 -0
  169. package/templates/common/timsquad/ssot/env-config.template.md +346 -0
  170. package/templates/common/timsquad/ssot/error-codes.template.md +114 -0
  171. package/templates/common/timsquad/ssot/functional-spec.template.md +185 -0
  172. package/templates/common/timsquad/ssot/glossary.template.md +148 -0
  173. package/templates/common/timsquad/ssot/integration-spec.template.md +391 -0
  174. package/templates/common/timsquad/ssot/planning.template.md +94 -0
  175. package/templates/common/timsquad/ssot/prd.template.md +102 -0
  176. package/templates/common/timsquad/ssot/requirements.template.md +117 -0
  177. package/templates/common/timsquad/ssot/security-spec.template.md +309 -0
  178. package/templates/common/timsquad/ssot/service-spec.template.md +194 -0
  179. package/templates/common/timsquad/ssot/test-spec.template.md +264 -0
  180. package/templates/common/timsquad/ssot/ui-ux-spec.template.md +262 -0
  181. package/templates/common/timsquad/state/workspace.xml +217 -0
@@ -0,0 +1,280 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+ import { colors, printHeader, printError, printSuccess, printKeyValue } from '../utils/colors.js';
4
+ import { findProjectRoot } from '../lib/project.js';
5
+ import { exists, writeFile, listFiles } from '../utils/fs.js';
6
+ import { getTimestamp } from '../utils/date.js';
7
+ export function registerRetroCommand(program) {
8
+ const retroCmd = program
9
+ .command('retro')
10
+ .description('Retrospective learning system');
11
+ // tsq retro start
12
+ retroCmd
13
+ .command('start')
14
+ .description('Start a new retrospective cycle')
15
+ .action(async () => {
16
+ try {
17
+ await startRetro();
18
+ }
19
+ catch (error) {
20
+ printError(error.message);
21
+ process.exit(1);
22
+ }
23
+ });
24
+ // tsq retro collect
25
+ retroCmd
26
+ .command('collect')
27
+ .description('Collect logs and metrics')
28
+ .action(async () => {
29
+ try {
30
+ await collectRetro();
31
+ }
32
+ catch (error) {
33
+ printError(error.message);
34
+ process.exit(1);
35
+ }
36
+ });
37
+ // tsq retro analyze
38
+ retroCmd
39
+ .command('analyze')
40
+ .description('Analyze patterns (requires Claude)')
41
+ .action(async () => {
42
+ try {
43
+ await analyzeRetro();
44
+ }
45
+ catch (error) {
46
+ printError(error.message);
47
+ process.exit(1);
48
+ }
49
+ });
50
+ // tsq retro report
51
+ retroCmd
52
+ .command('report')
53
+ .description('Generate retrospective report')
54
+ .action(async () => {
55
+ try {
56
+ await generateReport();
57
+ }
58
+ catch (error) {
59
+ printError(error.message);
60
+ process.exit(1);
61
+ }
62
+ });
63
+ // tsq retro apply
64
+ retroCmd
65
+ .command('apply')
66
+ .description('Apply improvements')
67
+ .action(async () => {
68
+ try {
69
+ await applyImprovements();
70
+ }
71
+ catch (error) {
72
+ printError(error.message);
73
+ process.exit(1);
74
+ }
75
+ });
76
+ // tsq retro status
77
+ retroCmd
78
+ .command('status')
79
+ .description('Show retrospective status')
80
+ .action(async () => {
81
+ try {
82
+ await showRetroStatus();
83
+ }
84
+ catch (error) {
85
+ printError(error.message);
86
+ process.exit(1);
87
+ }
88
+ });
89
+ }
90
+ async function getRetroState(projectRoot) {
91
+ const statePath = path.join(projectRoot, '.timsquad', 'retrospective', 'state.json');
92
+ if (!await exists(statePath)) {
93
+ return { currentCycle: 0, status: 'idle' };
94
+ }
95
+ return fs.readJson(statePath);
96
+ }
97
+ async function saveRetroState(projectRoot, state) {
98
+ const statePath = path.join(projectRoot, '.timsquad', 'retrospective', 'state.json');
99
+ await fs.ensureDir(path.dirname(statePath));
100
+ await fs.writeJson(statePath, state, { spaces: 2 });
101
+ }
102
+ async function startRetro() {
103
+ const projectRoot = await findProjectRoot();
104
+ if (!projectRoot) {
105
+ throw new Error('Not a TimSquad project');
106
+ }
107
+ const state = await getRetroState(projectRoot);
108
+ if (state.status !== 'idle') {
109
+ throw new Error(`Retrospective cycle ${state.currentCycle} is already in progress (${state.status})`);
110
+ }
111
+ state.currentCycle += 1;
112
+ state.status = 'collecting';
113
+ state.startedAt = getTimestamp();
114
+ await saveRetroState(projectRoot, state);
115
+ printSuccess(`Started retrospective cycle ${state.currentCycle}`);
116
+ console.log(colors.dim('\nNext: Run "tsq retro collect" to collect metrics'));
117
+ }
118
+ async function collectRetro() {
119
+ const projectRoot = await findProjectRoot();
120
+ if (!projectRoot) {
121
+ throw new Error('Not a TimSquad project');
122
+ }
123
+ const state = await getRetroState(projectRoot);
124
+ if (state.status !== 'collecting') {
125
+ throw new Error('No active retrospective. Run "tsq retro start" first');
126
+ }
127
+ printHeader(`Collecting Metrics - Cycle ${state.currentCycle}`);
128
+ // Collect log stats
129
+ const logsDir = path.join(projectRoot, '.timsquad', 'logs');
130
+ const logFiles = await listFiles('*.md', logsDir);
131
+ const recentLogs = logFiles.filter(f => !f.startsWith('_'));
132
+ // Count by agent
133
+ const agentStats = {};
134
+ for (const file of recentLogs) {
135
+ const match = file.match(/-([a-z]+)\.md$/);
136
+ if (match) {
137
+ const agent = match[1];
138
+ agentStats[agent] = (agentStats[agent] || 0) + 1;
139
+ }
140
+ }
141
+ // Create metrics JSON
142
+ const metrics = {
143
+ cycle: state.currentCycle,
144
+ collectedAt: getTimestamp(),
145
+ raw_data: {
146
+ log_files: recentLogs.length,
147
+ agents: agentStats,
148
+ },
149
+ summary: {
150
+ total_logs: recentLogs.length,
151
+ agents_active: Object.keys(agentStats).length,
152
+ },
153
+ };
154
+ const metricsPath = path.join(projectRoot, '.timsquad', 'retrospective', 'metrics', `cycle-${state.currentCycle}.json`);
155
+ await fs.ensureDir(path.dirname(metricsPath));
156
+ await fs.writeJson(metricsPath, metrics, { spaces: 2 });
157
+ state.status = 'analyzing';
158
+ state.collectedAt = getTimestamp();
159
+ await saveRetroState(projectRoot, state);
160
+ printSuccess('Metrics collected');
161
+ printKeyValue('Log files', String(recentLogs.length));
162
+ printKeyValue('Active agents', String(Object.keys(agentStats).length));
163
+ console.log(colors.dim('\nNext: Run "tsq retro analyze" to analyze patterns'));
164
+ }
165
+ async function analyzeRetro() {
166
+ const projectRoot = await findProjectRoot();
167
+ if (!projectRoot) {
168
+ throw new Error('Not a TimSquad project');
169
+ }
170
+ const state = await getRetroState(projectRoot);
171
+ if (state.status !== 'analyzing') {
172
+ throw new Error('Collect metrics first. Run "tsq retro collect"');
173
+ }
174
+ console.log(colors.warning('\n⚠ Pattern analysis requires Claude integration'));
175
+ console.log(colors.dim(' This feature will analyze logs and suggest improvements'));
176
+ console.log(colors.dim(' For now, marking as analyzed for manual review\n'));
177
+ state.status = 'reporting';
178
+ state.analyzedAt = getTimestamp();
179
+ await saveRetroState(projectRoot, state);
180
+ printSuccess('Analysis phase completed (manual review mode)');
181
+ console.log(colors.dim('\nNext: Run "tsq retro report" to generate report'));
182
+ }
183
+ async function generateReport() {
184
+ const projectRoot = await findProjectRoot();
185
+ if (!projectRoot) {
186
+ throw new Error('Not a TimSquad project');
187
+ }
188
+ const state = await getRetroState(projectRoot);
189
+ if (state.status !== 'reporting') {
190
+ throw new Error('Analyze patterns first. Run "tsq retro analyze"');
191
+ }
192
+ // Load metrics
193
+ const metricsPath = path.join(projectRoot, '.timsquad', 'retrospective', 'metrics', `cycle-${state.currentCycle}.json`);
194
+ const metrics = await fs.readJson(metricsPath);
195
+ // Generate report
196
+ const report = `# Cycle ${state.currentCycle} Retrospective Report
197
+
198
+ ## Period
199
+ - Started: ${state.startedAt}
200
+ - Collected: ${state.collectedAt}
201
+ - Generated: ${getTimestamp()}
202
+
203
+ ## Metrics Summary
204
+
205
+ | Metric | Value |
206
+ |--------|-------|
207
+ | Total Logs | ${metrics.summary.total_logs} |
208
+ | Active Agents | ${metrics.summary.agents_active} |
209
+
210
+ ## Agent Activity
211
+
212
+ ${Object.entries(metrics.raw_data.agents).map(([agent, count]) => `- ${agent}: ${count} logs`).join('\n')}
213
+
214
+ ## Patterns Identified
215
+
216
+ ### Success Patterns
217
+ _Manual review required_
218
+
219
+ ### Failure Patterns
220
+ _Manual review required_
221
+
222
+ ## Improvement Suggestions
223
+ _Manual review required_
224
+
225
+ ## Next Cycle Goals
226
+ - [ ] Review and update SSOT documents
227
+ - [ ] Address identified patterns
228
+ - [ ] Apply approved improvements
229
+
230
+ ---
231
+ Generated by TimSquad v2.0.0
232
+ `;
233
+ const reportPath = path.join(projectRoot, '.timsquad', 'retrospective', 'cycles', `cycle-${state.currentCycle}.md`);
234
+ await fs.ensureDir(path.dirname(reportPath));
235
+ await writeFile(reportPath, report);
236
+ state.status = 'applying';
237
+ await saveRetroState(projectRoot, state);
238
+ printSuccess(`Report generated: cycle-${state.currentCycle}.md`);
239
+ console.log(colors.path(` ${reportPath}`));
240
+ console.log(colors.dim('\nNext: Review report and run "tsq retro apply" to complete'));
241
+ }
242
+ async function applyImprovements() {
243
+ const projectRoot = await findProjectRoot();
244
+ if (!projectRoot) {
245
+ throw new Error('Not a TimSquad project');
246
+ }
247
+ const state = await getRetroState(projectRoot);
248
+ if (state.status !== 'applying') {
249
+ throw new Error('Generate report first. Run "tsq retro report"');
250
+ }
251
+ console.log(colors.warning('\n⚠ Improvement application requires manual review'));
252
+ console.log(colors.dim(' 1. Review the generated report'));
253
+ console.log(colors.dim(' 2. Update templates/prompts as needed'));
254
+ console.log(colors.dim(' 3. This cycle will be marked as complete\n'));
255
+ state.status = 'idle';
256
+ await saveRetroState(projectRoot, state);
257
+ printSuccess(`Retrospective cycle ${state.currentCycle} completed!`);
258
+ }
259
+ async function showRetroStatus() {
260
+ const projectRoot = await findProjectRoot();
261
+ if (!projectRoot) {
262
+ throw new Error('Not a TimSquad project');
263
+ }
264
+ const state = await getRetroState(projectRoot);
265
+ printHeader('Retrospective Status');
266
+ printKeyValue('Current Cycle', String(state.currentCycle));
267
+ printKeyValue('Status', state.status);
268
+ if (state.startedAt) {
269
+ printKeyValue('Started', state.startedAt.split('T')[0]);
270
+ }
271
+ // List completed cycles
272
+ const cyclesDir = path.join(projectRoot, '.timsquad', 'retrospective', 'cycles');
273
+ if (await exists(cyclesDir)) {
274
+ const cycles = await listFiles('cycle-*.md', cyclesDir);
275
+ if (cycles.length > 0) {
276
+ console.log(colors.dim(`\nCompleted cycles: ${cycles.length}`));
277
+ }
278
+ }
279
+ }
280
+ //# sourceMappingURL=retro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retro.js","sourceRoot":"","sources":["../../src/commands/retro.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStatusCommand(program: Command): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgB5D"}
@@ -0,0 +1,127 @@
1
+ import { colors, printHeader, printError, printKeyValue } from '../utils/colors.js';
2
+ import { findProjectRoot, getProjectStatus } from '../lib/project.js';
3
+ import { PROJECT_TYPE_DESCRIPTIONS, PROJECT_LEVEL_DESCRIPTIONS } from '../types/project.js';
4
+ export function registerStatusCommand(program) {
5
+ program
6
+ .command('status')
7
+ .description('Show project status')
8
+ .option('-a, --all', 'Show all details')
9
+ .option('-s, --ssot', 'Show SSOT status only')
10
+ .option('-p, --phase', 'Show phase status only')
11
+ .option('-m, --metrics', 'Show metrics only')
12
+ .action(async (options) => {
13
+ try {
14
+ await runStatus(options);
15
+ }
16
+ catch (error) {
17
+ printError(error.message);
18
+ process.exit(1);
19
+ }
20
+ });
21
+ }
22
+ async function runStatus(options) {
23
+ // Find project root
24
+ const projectRoot = await findProjectRoot();
25
+ if (!projectRoot) {
26
+ throw new Error('Not a TimSquad project. Run "tsq init" first.');
27
+ }
28
+ // Get full status
29
+ const status = await getProjectStatus(projectRoot);
30
+ // Show based on options
31
+ if (options.ssot) {
32
+ showSSOTStatus(status);
33
+ }
34
+ else if (options.phase) {
35
+ showPhaseStatus(status);
36
+ }
37
+ else if (options.metrics) {
38
+ showMetrics(status);
39
+ }
40
+ else {
41
+ // Show all or default
42
+ showFullStatus(status, options.all);
43
+ }
44
+ }
45
+ function showFullStatus(status, showAll = false) {
46
+ printHeader('TimSquad Project Status');
47
+ // Project info
48
+ console.log(colors.subheader('Project'));
49
+ printKeyValue('Name', status.project.name);
50
+ printKeyValue('Type', `${status.project.type} (${PROJECT_TYPE_DESCRIPTIONS[status.project.type]})`);
51
+ printKeyValue('Level', `${status.project.level} (${PROJECT_LEVEL_DESCRIPTIONS[status.project.level]})`);
52
+ console.log('');
53
+ // Phase
54
+ showPhaseStatus(status);
55
+ // SSOT
56
+ showSSOTStatus(status);
57
+ // Agents
58
+ if (showAll || status.agents.length > 0) {
59
+ console.log(colors.subheader('Agents'));
60
+ if (status.agents.length === 0) {
61
+ console.log(colors.dim(' No agents configured'));
62
+ }
63
+ else {
64
+ status.agents.forEach(agent => {
65
+ const modelColor = agent.model === 'opus' ? colors.primary : colors.dim;
66
+ console.log(` ${colors.agent(agent.name)} ${modelColor(`(${agent.model})`)}`);
67
+ });
68
+ }
69
+ console.log('');
70
+ }
71
+ // Logs
72
+ if (showAll || status.logs.total > 0) {
73
+ console.log(colors.subheader('Logs'));
74
+ printKeyValue('Total', String(status.logs.total));
75
+ if (status.logs.recent.length > 0) {
76
+ console.log(colors.dim(' Recent:'));
77
+ status.logs.recent.forEach(log => {
78
+ console.log(` ${colors.path(log)}`);
79
+ });
80
+ }
81
+ console.log('');
82
+ }
83
+ // Retrospective
84
+ if (showAll) {
85
+ showMetrics(status);
86
+ }
87
+ }
88
+ function showPhaseStatus(status) {
89
+ console.log(colors.subheader('Phase'));
90
+ const { phase } = status;
91
+ const progressBar = createProgressBar(phase.progress);
92
+ printKeyValue('Current', colors.phase(phase.current));
93
+ printKeyValue('Started', phase.startedAt.split('T')[0]);
94
+ console.log(` ${colors.label('Progress:')} ${progressBar} ${phase.progress}%`);
95
+ console.log('');
96
+ }
97
+ function showSSOTStatus(status) {
98
+ console.log(colors.subheader('SSOT Documents'));
99
+ const required = status.ssot.filter(d => d.required);
100
+ const optional = status.ssot.filter(d => !d.required);
101
+ const filledCount = required.filter(d => d.filled).length;
102
+ console.log(` Required: ${colors.success(String(filledCount))}/${required.length}`);
103
+ // Show required documents
104
+ required.forEach(doc => {
105
+ const icon = doc.filled ? colors.success('✓') : colors.warning('○');
106
+ const name = doc.filled ? colors.value(doc.name) : colors.dim(doc.name);
107
+ console.log(` ${icon} ${name}`);
108
+ });
109
+ if (optional.length > 0) {
110
+ const optionalFilled = optional.filter(d => d.filled).length;
111
+ console.log(` Optional: ${optionalFilled}/${optional.length}`);
112
+ }
113
+ console.log('');
114
+ }
115
+ function showMetrics(status) {
116
+ console.log(colors.subheader('Retrospective'));
117
+ printKeyValue('Completed Cycles', String(status.retrospective.cycles));
118
+ printKeyValue('Success Patterns', String(status.retrospective.patterns.success));
119
+ printKeyValue('Failure Patterns', String(status.retrospective.patterns.failure));
120
+ console.log('');
121
+ }
122
+ function createProgressBar(progress, width = 20) {
123
+ const filled = Math.round((progress / 100) * width);
124
+ const empty = width - filled;
125
+ return colors.success('█'.repeat(filled)) + colors.dim('░'.repeat(empty));
126
+ }
127
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerWatchCommand(program: Command): void;
3
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2C3D"}
@@ -0,0 +1,213 @@
1
+ import path from 'path';
2
+ import chokidar from 'chokidar';
3
+ import { colors, printHeader, printError, printSuccess, printKeyValue } from '../utils/colors.js';
4
+ import { findProjectRoot } from '../lib/project.js';
5
+ import { exists, writeFile, readFile } from '../utils/fs.js';
6
+ import { getTimestamp } from '../utils/date.js';
7
+ export function registerWatchCommand(program) {
8
+ const watchCmd = program
9
+ .command('watch')
10
+ .description('SSOT file watcher');
11
+ // tsq watch start
12
+ watchCmd
13
+ .command('start')
14
+ .description('Start watching SSOT files')
15
+ .action(async () => {
16
+ try {
17
+ await startWatch();
18
+ }
19
+ catch (error) {
20
+ printError(error.message);
21
+ process.exit(1);
22
+ }
23
+ });
24
+ // tsq watch stop
25
+ watchCmd
26
+ .command('stop')
27
+ .description('Stop watching')
28
+ .action(async () => {
29
+ try {
30
+ await stopWatch();
31
+ }
32
+ catch (error) {
33
+ printError(error.message);
34
+ process.exit(1);
35
+ }
36
+ });
37
+ // tsq watch status
38
+ watchCmd
39
+ .command('status')
40
+ .description('Show watch status')
41
+ .action(async () => {
42
+ try {
43
+ await showWatchStatus();
44
+ }
45
+ catch (error) {
46
+ printError(error.message);
47
+ process.exit(1);
48
+ }
49
+ });
50
+ }
51
+ async function getWatchState(projectRoot) {
52
+ const statePath = path.join(projectRoot, '.timsquad', 'state', 'watch-state.json');
53
+ if (!await exists(statePath)) {
54
+ return {
55
+ running: false,
56
+ watchedPaths: [],
57
+ changeCount: 0,
58
+ };
59
+ }
60
+ try {
61
+ const content = await readFile(statePath);
62
+ return JSON.parse(content);
63
+ }
64
+ catch {
65
+ return {
66
+ running: false,
67
+ watchedPaths: [],
68
+ changeCount: 0,
69
+ };
70
+ }
71
+ }
72
+ async function saveWatchState(projectRoot, state) {
73
+ const statePath = path.join(projectRoot, '.timsquad', 'state', 'watch-state.json');
74
+ await writeFile(statePath, JSON.stringify(state, null, 2));
75
+ }
76
+ async function startWatch() {
77
+ const projectRoot = await findProjectRoot();
78
+ if (!projectRoot) {
79
+ throw new Error('Not a TimSquad project');
80
+ }
81
+ const state = await getWatchState(projectRoot);
82
+ if (state.running) {
83
+ console.log(colors.warning('Watch already running'));
84
+ console.log(colors.dim(`Started at: ${state.startedAt}`));
85
+ return;
86
+ }
87
+ printHeader('SSOT File Watcher');
88
+ const ssotDir = path.join(projectRoot, '.timsquad', 'ssot');
89
+ const watchPaths = [
90
+ path.join(ssotDir, '**/*.md'),
91
+ path.join(ssotDir, '**/*.yaml'),
92
+ ];
93
+ console.log(colors.subheader('Watching:'));
94
+ console.log(colors.path(` ${ssotDir}`));
95
+ console.log('');
96
+ // Initialize watcher
97
+ const watcher = chokidar.watch(watchPaths, {
98
+ persistent: true,
99
+ ignoreInitial: true,
100
+ awaitWriteFinish: {
101
+ stabilityThreshold: 500,
102
+ pollInterval: 100,
103
+ },
104
+ });
105
+ let changeCount = 0;
106
+ const changeLog = [];
107
+ watcher
108
+ .on('change', (filePath) => {
109
+ changeCount++;
110
+ const relativePath = path.relative(projectRoot, filePath);
111
+ const timestamp = getTimestamp();
112
+ const logEntry = `[${timestamp}] Modified: ${relativePath}`;
113
+ console.log(colors.warning(`📝 ${logEntry}`));
114
+ changeLog.push(logEntry);
115
+ // Log to file
116
+ logChange(projectRoot, 'modified', relativePath);
117
+ })
118
+ .on('add', (filePath) => {
119
+ changeCount++;
120
+ const relativePath = path.relative(projectRoot, filePath);
121
+ const timestamp = getTimestamp();
122
+ const logEntry = `[${timestamp}] Added: ${relativePath}`;
123
+ console.log(colors.success(`➕ ${logEntry}`));
124
+ changeLog.push(logEntry);
125
+ logChange(projectRoot, 'added', relativePath);
126
+ })
127
+ .on('unlink', (filePath) => {
128
+ changeCount++;
129
+ const relativePath = path.relative(projectRoot, filePath);
130
+ const timestamp = getTimestamp();
131
+ const logEntry = `[${timestamp}] Deleted: ${relativePath}`;
132
+ console.log(colors.error(`➖ ${logEntry}`));
133
+ changeLog.push(logEntry);
134
+ logChange(projectRoot, 'deleted', relativePath);
135
+ })
136
+ .on('error', (error) => {
137
+ printError(`Watcher error: ${error.message}`);
138
+ });
139
+ // Update state
140
+ state.running = true;
141
+ state.startedAt = getTimestamp();
142
+ state.watchedPaths = watchPaths;
143
+ state.changeCount = 0;
144
+ await saveWatchState(projectRoot, state);
145
+ printSuccess('Watcher started');
146
+ console.log(colors.dim('\nPress Ctrl+C to stop'));
147
+ console.log(colors.dim('Or run: tsq watch stop'));
148
+ // Handle process termination
149
+ const cleanup = async () => {
150
+ console.log(colors.dim('\n\nStopping watcher...'));
151
+ await watcher.close();
152
+ state.running = false;
153
+ state.changeCount = changeCount;
154
+ await saveWatchState(projectRoot, state);
155
+ printSuccess(`Watcher stopped. ${changeCount} changes detected.`);
156
+ process.exit(0);
157
+ };
158
+ process.on('SIGINT', cleanup);
159
+ process.on('SIGTERM', cleanup);
160
+ }
161
+ async function stopWatch() {
162
+ const projectRoot = await findProjectRoot();
163
+ if (!projectRoot) {
164
+ throw new Error('Not a TimSquad project');
165
+ }
166
+ const state = await getWatchState(projectRoot);
167
+ if (!state.running) {
168
+ console.log(colors.dim('No watcher running'));
169
+ return;
170
+ }
171
+ // Mark as stopped (actual process should handle cleanup)
172
+ state.running = false;
173
+ await saveWatchState(projectRoot, state);
174
+ printSuccess('Watcher marked as stopped');
175
+ console.log(colors.dim('If the process is still running, press Ctrl+C'));
176
+ }
177
+ async function showWatchStatus() {
178
+ const projectRoot = await findProjectRoot();
179
+ if (!projectRoot) {
180
+ throw new Error('Not a TimSquad project');
181
+ }
182
+ const state = await getWatchState(projectRoot);
183
+ printHeader('Watch Status');
184
+ printKeyValue('Status', state.running ? 'Running' : 'Stopped');
185
+ if (state.startedAt) {
186
+ printKeyValue('Started at', state.startedAt);
187
+ }
188
+ printKeyValue('Changes detected', String(state.changeCount));
189
+ if (state.watchedPaths.length > 0) {
190
+ console.log(colors.subheader('\nWatched paths:'));
191
+ state.watchedPaths.forEach(p => {
192
+ console.log(colors.dim(` ${p}`));
193
+ });
194
+ }
195
+ }
196
+ async function logChange(projectRoot, action, filePath) {
197
+ const logDir = path.join(projectRoot, '.timsquad', 'logs');
198
+ const logFile = path.join(logDir, 'ssot-changes.log');
199
+ const timestamp = getTimestamp();
200
+ const logEntry = `${timestamp} | ${action.toUpperCase().padEnd(8)} | ${filePath}\n`;
201
+ try {
202
+ let content = '';
203
+ if (await exists(logFile)) {
204
+ content = await readFile(logFile);
205
+ }
206
+ content += logEntry;
207
+ await writeFile(logFile, content);
208
+ }
209
+ catch {
210
+ // Ignore logging errors
211
+ }
212
+ }
213
+ //# sourceMappingURL=watch.js.map