@matteeh/osq 0.1.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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -0
  3. package/dist/cli/approve.d.ts +6 -0
  4. package/dist/cli/approve.d.ts.map +1 -0
  5. package/dist/cli/approve.js +26 -0
  6. package/dist/cli/approve.js.map +1 -0
  7. package/dist/cli/bin.d.ts +3 -0
  8. package/dist/cli/bin.d.ts.map +1 -0
  9. package/dist/cli/bin.js +5 -0
  10. package/dist/cli/bin.js.map +1 -0
  11. package/dist/cli/index.d.ts +4 -0
  12. package/dist/cli/index.d.ts.map +1 -0
  13. package/dist/cli/index.js +76 -0
  14. package/dist/cli/index.js.map +1 -0
  15. package/dist/cli/init.d.ts +4 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +19 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/cli/new.d.ts +4 -0
  20. package/dist/cli/new.d.ts.map +1 -0
  21. package/dist/cli/new.js +15 -0
  22. package/dist/cli/new.js.map +1 -0
  23. package/dist/cli/report.d.ts +10 -0
  24. package/dist/cli/report.d.ts.map +1 -0
  25. package/dist/cli/report.js +84 -0
  26. package/dist/cli/report.js.map +1 -0
  27. package/dist/cli/setup.d.ts +2 -0
  28. package/dist/cli/setup.d.ts.map +1 -0
  29. package/dist/cli/setup.js +10 -0
  30. package/dist/cli/setup.js.map +1 -0
  31. package/dist/cli/show.d.ts +7 -0
  32. package/dist/cli/show.d.ts.map +1 -0
  33. package/dist/cli/show.js +27 -0
  34. package/dist/cli/show.js.map +1 -0
  35. package/dist/cli/status.d.ts +7 -0
  36. package/dist/cli/status.d.ts.map +1 -0
  37. package/dist/cli/status.js +23 -0
  38. package/dist/cli/status.js.map +1 -0
  39. package/dist/cli/watch.d.ts +9 -0
  40. package/dist/cli/watch.d.ts.map +1 -0
  41. package/dist/cli/watch.js +20 -0
  42. package/dist/cli/watch.js.map +1 -0
  43. package/dist/core/approve.d.ts +11 -0
  44. package/dist/core/approve.d.ts.map +1 -0
  45. package/dist/core/approve.js +52 -0
  46. package/dist/core/approve.js.map +1 -0
  47. package/dist/core/config.d.ts +53 -0
  48. package/dist/core/config.d.ts.map +1 -0
  49. package/dist/core/config.js +124 -0
  50. package/dist/core/config.js.map +1 -0
  51. package/dist/core/hasher.d.ts +4 -0
  52. package/dist/core/hasher.d.ts.map +1 -0
  53. package/dist/core/hasher.js +49 -0
  54. package/dist/core/hasher.js.map +1 -0
  55. package/dist/core/init.d.ts +12 -0
  56. package/dist/core/init.d.ts.map +1 -0
  57. package/dist/core/init.js +151 -0
  58. package/dist/core/init.js.map +1 -0
  59. package/dist/core/linter.d.ts +8 -0
  60. package/dist/core/linter.d.ts.map +1 -0
  61. package/dist/core/linter.js +100 -0
  62. package/dist/core/linter.js.map +1 -0
  63. package/dist/core/lock.d.ts +17 -0
  64. package/dist/core/lock.d.ts.map +1 -0
  65. package/dist/core/lock.js +104 -0
  66. package/dist/core/lock.js.map +1 -0
  67. package/dist/core/logger.d.ts +32 -0
  68. package/dist/core/logger.d.ts.map +1 -0
  69. package/dist/core/logger.js +106 -0
  70. package/dist/core/logger.js.map +1 -0
  71. package/dist/core/new.d.ts +11 -0
  72. package/dist/core/new.d.ts.map +1 -0
  73. package/dist/core/new.js +79 -0
  74. package/dist/core/new.js.map +1 -0
  75. package/dist/core/parser.d.ts +32 -0
  76. package/dist/core/parser.d.ts.map +1 -0
  77. package/dist/core/parser.js +87 -0
  78. package/dist/core/parser.js.map +1 -0
  79. package/dist/core/report.d.ts +54 -0
  80. package/dist/core/report.d.ts.map +1 -0
  81. package/dist/core/report.js +475 -0
  82. package/dist/core/report.js.map +1 -0
  83. package/dist/core/show.d.ts +50 -0
  84. package/dist/core/show.d.ts.map +1 -0
  85. package/dist/core/show.js +374 -0
  86. package/dist/core/show.js.map +1 -0
  87. package/dist/core/state.d.ts +25 -0
  88. package/dist/core/state.d.ts.map +1 -0
  89. package/dist/core/state.js +180 -0
  90. package/dist/core/state.js.map +1 -0
  91. package/dist/core/status.d.ts +10 -0
  92. package/dist/core/status.d.ts.map +1 -0
  93. package/dist/core/status.js +106 -0
  94. package/dist/core/status.js.map +1 -0
  95. package/dist/harness/agy.d.ts +31 -0
  96. package/dist/harness/agy.d.ts.map +1 -0
  97. package/dist/harness/agy.js +251 -0
  98. package/dist/harness/agy.js.map +1 -0
  99. package/dist/harness/index.d.ts +7 -0
  100. package/dist/harness/index.d.ts.map +1 -0
  101. package/dist/harness/index.js +20 -0
  102. package/dist/harness/index.js.map +1 -0
  103. package/dist/harness/mock.d.ts +19 -0
  104. package/dist/harness/mock.d.ts.map +1 -0
  105. package/dist/harness/mock.js +62 -0
  106. package/dist/harness/mock.js.map +1 -0
  107. package/dist/harness/opencode.d.ts +39 -0
  108. package/dist/harness/opencode.d.ts.map +1 -0
  109. package/dist/harness/opencode.js +394 -0
  110. package/dist/harness/opencode.js.map +1 -0
  111. package/dist/harness/process.d.ts +26 -0
  112. package/dist/harness/process.d.ts.map +1 -0
  113. package/dist/harness/process.js +99 -0
  114. package/dist/harness/process.js.map +1 -0
  115. package/dist/harness/stream.d.ts +34 -0
  116. package/dist/harness/stream.d.ts.map +1 -0
  117. package/dist/harness/stream.js +75 -0
  118. package/dist/harness/stream.js.map +1 -0
  119. package/dist/harness/types.d.ts +53 -0
  120. package/dist/harness/types.d.ts.map +1 -0
  121. package/dist/harness/types.js +10 -0
  122. package/dist/harness/types.js.map +1 -0
  123. package/dist/index.d.ts +3 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +2 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/watcher/archiver.d.ts +5 -0
  128. package/dist/watcher/archiver.d.ts.map +1 -0
  129. package/dist/watcher/archiver.js +66 -0
  130. package/dist/watcher/archiver.js.map +1 -0
  131. package/dist/watcher/loop.d.ts +34 -0
  132. package/dist/watcher/loop.d.ts.map +1 -0
  133. package/dist/watcher/loop.js +235 -0
  134. package/dist/watcher/loop.js.map +1 -0
  135. package/dist/watcher/runner.d.ts +70 -0
  136. package/dist/watcher/runner.d.ts.map +1 -0
  137. package/dist/watcher/runner.js +604 -0
  138. package/dist/watcher/runner.js.map +1 -0
  139. package/package.json +66 -0
  140. package/templates/.env.example +3 -0
@@ -0,0 +1,54 @@
1
+ import { type OsqConfig } from './config.js';
2
+ export interface SpecMetrics {
3
+ readonly total: number;
4
+ readonly active: number;
5
+ readonly archived: number;
6
+ }
7
+ export interface TaskMetrics {
8
+ readonly total: number;
9
+ readonly done: number;
10
+ readonly dead: number;
11
+ readonly running: number;
12
+ readonly pending: number;
13
+ }
14
+ export interface DurationMetrics {
15
+ readonly totalMs: number;
16
+ readonly totalSeconds: number;
17
+ readonly avgMs: number;
18
+ readonly avgSeconds: number;
19
+ readonly formattedTotal: string;
20
+ readonly formattedAvg: string;
21
+ }
22
+ export interface TokenMetrics {
23
+ readonly input: number;
24
+ readonly cached_input: number;
25
+ readonly output: number;
26
+ readonly reasoning: number;
27
+ readonly total: number;
28
+ readonly cacheSharePercent: number;
29
+ }
30
+ export interface FileChangeMetrics {
31
+ readonly totalChanges: number;
32
+ readonly uniqueCount: number;
33
+ readonly uniqueFiles: readonly string[];
34
+ }
35
+ export interface CostMetrics {
36
+ readonly total: number;
37
+ readonly perSpec: Record<string, number>;
38
+ readonly formattedTotal: string;
39
+ }
40
+ export interface MetricsReport {
41
+ readonly completionRate: number;
42
+ readonly cost?: CostMetrics;
43
+ readonly durations: DurationMetrics;
44
+ readonly failureBreakdown: Record<string, number>;
45
+ readonly fileChanges: FileChangeMetrics;
46
+ readonly specs: SpecMetrics;
47
+ readonly tasks: TaskMetrics;
48
+ readonly tokens: TokenMetrics;
49
+ }
50
+ export declare function formatDuration(ms: number): string;
51
+ export declare function formatCost(total: number): string;
52
+ export declare function getMetricsReport(projectRoot: string, config?: OsqConfig): Promise<MetricsReport>;
53
+ export declare function formatMetricsReport(report: MetricsReport): string;
54
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/core/report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,iBAAiB,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC/B;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAOjD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGhD;AAyED,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,MAAM,EACnB,MAAM,GAAE,SAA0B,GACjC,OAAO,CAAC,aAAa,CAAC,CAyYxB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CA2DjE"}
@@ -0,0 +1,475 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { DEFAULT_CONFIG } from './config.js';
4
+ import { parseFrontmatter } from './parser.js';
5
+ import { compareNumericPrefix, deriveSpecState } from './state.js';
6
+ export function formatDuration(ms) {
7
+ if (ms <= 0)
8
+ return '0s';
9
+ const totalSec = Math.round(ms / 1000);
10
+ if (totalSec < 60)
11
+ return `${totalSec}s`;
12
+ const mins = Math.floor(totalSec / 60);
13
+ const secs = totalSec % 60;
14
+ return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
15
+ }
16
+ export function formatCost(total) {
17
+ const fixed = total >= 0.01 ? total.toFixed(2) : total.toFixed(4);
18
+ return `$${fixed}`;
19
+ }
20
+ const FILE_CHANGE_TOOLS = new Set(['edit', 'write']);
21
+ /**
22
+ * Trims surrounding whitespace and strips a leading `./` so paths written by
23
+ * different harnesses collapse to a single canonical form before deduplication.
24
+ */
25
+ function normalizeFilePath(value) {
26
+ if (typeof value !== 'string')
27
+ return null;
28
+ const trimmed = value.trim();
29
+ if (!trimmed)
30
+ return null;
31
+ const cleaned = trimmed.replace(/^(?:\.\/)+/, '');
32
+ return cleaned || null;
33
+ }
34
+ /**
35
+ * Extracts a file path from a tool or file_changed event payload. The summary
36
+ * field carries the target path for file tools such as edit and write.
37
+ */
38
+ function extractFilePath(data) {
39
+ for (const candidate of [data.summary, data.path, data.filePath, data.file, data.filename]) {
40
+ const filePath = normalizeFilePath(candidate);
41
+ if (filePath !== null)
42
+ return filePath;
43
+ }
44
+ return null;
45
+ }
46
+ async function readArchivedTerminalEvents(specFolderPath) {
47
+ const terminalEvents = new Map();
48
+ const eventsDir = path.join(specFolderPath, '.run', 'events');
49
+ let eventFiles = [];
50
+ try {
51
+ eventFiles = (await fs.readdir(eventsDir))
52
+ .filter((e) => e.endsWith('.jsonl'))
53
+ .sort(compareNumericPrefix);
54
+ }
55
+ catch {
56
+ return terminalEvents;
57
+ }
58
+ for (const eventFile of eventFiles) {
59
+ const fallbackTask = eventFile.replace(/\.jsonl$/, '');
60
+ const content = await fs.readFile(path.join(eventsDir, eventFile), 'utf8').catch(() => '');
61
+ if (!content)
62
+ continue;
63
+ for (const line of content.split('\n')) {
64
+ const trimmed = line.trim();
65
+ if (!trimmed)
66
+ continue;
67
+ try {
68
+ const event = JSON.parse(trimmed);
69
+ if (event.type !== 'done' && event.type !== 'dead')
70
+ continue;
71
+ const task = typeof event.data?.task === 'string' && event.data.task ? event.data.task : fallbackTask;
72
+ const reason = typeof event.data?.reason === 'string' && event.data.reason.trim()
73
+ ? event.data.reason
74
+ : undefined;
75
+ terminalEvents.set(task, { status: event.type, reason });
76
+ }
77
+ catch { }
78
+ }
79
+ }
80
+ return terminalEvents;
81
+ }
82
+ export async function getMetricsReport(projectRoot, config = DEFAULT_CONFIG) {
83
+ const specsDir = path.join(projectRoot, config.paths.specs);
84
+ const archiveDir = path.join(projectRoot, config.paths.archive);
85
+ // 1. Identify active specs
86
+ let activeEntries = [];
87
+ try {
88
+ activeEntries = await fs.readdir(specsDir);
89
+ }
90
+ catch {
91
+ activeEntries = [];
92
+ }
93
+ const archiveRel = path.relative(specsDir, archiveDir);
94
+ const archiveFolder = !archiveRel.startsWith('..') && !path.isAbsolute(archiveRel)
95
+ ? archiveRel.split(path.sep)[0]
96
+ : 'archive';
97
+ const candidateActive = activeEntries.filter((e) => !e.startsWith('_') && !e.startsWith('.') && e !== archiveFolder);
98
+ const activeFolders = [];
99
+ for (const folder of candidateActive) {
100
+ const fullPath = path.join(specsDir, folder);
101
+ const stat = await fs.stat(fullPath).catch(() => null);
102
+ if (stat?.isDirectory()) {
103
+ activeFolders.push(fullPath);
104
+ }
105
+ }
106
+ // 2. Identify archived specs
107
+ let archiveEntries = [];
108
+ try {
109
+ archiveEntries = await fs.readdir(archiveDir);
110
+ }
111
+ catch {
112
+ archiveEntries = [];
113
+ }
114
+ const candidateArchived = archiveEntries.filter((e) => !e.startsWith('_') && !e.startsWith('.'));
115
+ const archivedFolders = [];
116
+ for (const folder of candidateArchived) {
117
+ const fullPath = path.join(archiveDir, folder);
118
+ const stat = await fs.stat(fullPath).catch(() => null);
119
+ if (stat?.isDirectory()) {
120
+ archivedFolders.push(fullPath);
121
+ }
122
+ }
123
+ const allSpecFolders = [...activeFolders, ...archivedFolders];
124
+ let totalTasks = 0;
125
+ let doneTasks = 0;
126
+ let deadTasks = 0;
127
+ let runningTasks = 0;
128
+ let pendingTasks = 0;
129
+ const failureBreakdown = {};
130
+ let totalDurationMs = 0;
131
+ let tasksWithDurationCount = 0;
132
+ let totalInput = 0;
133
+ let totalCachedInput = 0;
134
+ let totalOutput = 0;
135
+ let totalReasoning = 0;
136
+ let totalTokens = 0;
137
+ let totalFileChanges = 0;
138
+ const uniqueFiles = new Set();
139
+ let totalCost = 0;
140
+ const perSpecCost = {};
141
+ const archivedSet = new Set(archivedFolders);
142
+ for (const folderPath of allSpecFolders) {
143
+ const runDir = path.join(folderPath, '.run');
144
+ const tasksDir = path.join(folderPath, 'tasks');
145
+ let taskFiles = [];
146
+ try {
147
+ taskFiles = (await fs.readdir(tasksDir))
148
+ .filter((e) => e.endsWith('.md'))
149
+ .sort(compareNumericPrefix);
150
+ }
151
+ catch {
152
+ taskFiles = [];
153
+ }
154
+ totalTasks += taskFiles.length;
155
+ if (archivedSet.has(folderPath)) {
156
+ // Archived specs are complete. Their task states come from terminal
157
+ // done/dead events when present, then marker files, and finally fall
158
+ // back to done because an archived spec never reports pending work.
159
+ const terminalEvents = await readArchivedTerminalEvents(folderPath);
160
+ for (const taskFile of taskFiles) {
161
+ const taskNumber = taskFile.replace(/\.md$/, '');
162
+ const terminal = terminalEvents.get(taskNumber);
163
+ if (terminal) {
164
+ if (terminal.status === 'done') {
165
+ doneTasks++;
166
+ }
167
+ else {
168
+ deadTasks++;
169
+ }
170
+ continue;
171
+ }
172
+ const donePath = path.join(runDir, 'done', taskNumber);
173
+ const isDone = await fs
174
+ .stat(donePath)
175
+ .then(() => true)
176
+ .catch(() => false);
177
+ if (isDone) {
178
+ doneTasks++;
179
+ continue;
180
+ }
181
+ const deadPath = path.join(runDir, 'dead', `${taskNumber}.md`);
182
+ const deadContent = await fs.readFile(deadPath, 'utf8').catch(() => null);
183
+ if (deadContent !== null) {
184
+ deadTasks++;
185
+ continue;
186
+ }
187
+ doneTasks++;
188
+ }
189
+ }
190
+ else {
191
+ const specState = await deriveSpecState(projectRoot, folderPath);
192
+ for (const task of specState.tasks) {
193
+ switch (task.status) {
194
+ case 'done':
195
+ doneTasks++;
196
+ break;
197
+ case 'dead':
198
+ deadTasks++;
199
+ break;
200
+ case 'running':
201
+ runningTasks++;
202
+ break;
203
+ case 'pending':
204
+ pendingTasks++;
205
+ break;
206
+ }
207
+ }
208
+ }
209
+ // Process events in .run/events/
210
+ const eventsDir = path.join(runDir, 'events');
211
+ let eventFiles = [];
212
+ try {
213
+ eventFiles = (await fs.readdir(eventsDir)).filter((e) => e.endsWith('.jsonl'));
214
+ }
215
+ catch {
216
+ eventFiles = [];
217
+ }
218
+ let specHasDeadEvents = false;
219
+ for (const eventFile of eventFiles) {
220
+ const eventFilePath = path.join(eventsDir, eventFile);
221
+ const fileContent = await fs.readFile(eventFilePath, 'utf8').catch(() => '');
222
+ if (!fileContent)
223
+ continue;
224
+ const lines = fileContent.split('\n');
225
+ let startedTime = null;
226
+ let exitedTime = null;
227
+ let minTime = null;
228
+ let maxTime = null;
229
+ let hasEvents = false;
230
+ for (const line of lines) {
231
+ const trimmed = line.trim();
232
+ if (!trimmed)
233
+ continue;
234
+ try {
235
+ const event = JSON.parse(trimmed);
236
+ hasEvents = true;
237
+ const ts = event.timestamp ? new Date(event.timestamp).getTime() : Number.NaN;
238
+ if (!Number.isNaN(ts)) {
239
+ if (minTime === null || ts < minTime)
240
+ minTime = ts;
241
+ if (maxTime === null || ts > maxTime)
242
+ maxTime = ts;
243
+ if (event.type === 'started' && startedTime === null) {
244
+ startedTime = ts;
245
+ }
246
+ if (event.type === 'exited') {
247
+ exitedTime = ts;
248
+ }
249
+ }
250
+ if (event.type === 'tokens' && event.data) {
251
+ const data = event.data;
252
+ const input = Number(data.input ?? data.input_tokens ?? data.promptTokens ?? data.prompt ?? 0) || 0;
253
+ const output = Number(data.output ??
254
+ data.output_tokens ??
255
+ data.candidateTokens ??
256
+ data.candidate ??
257
+ data.completionTokens ??
258
+ 0) || 0;
259
+ const reasoning = Number(data.reasoningTokens ?? data.reasoning ?? data.thinking_tokens ?? 0) || 0;
260
+ const cacheValue = typeof data.cache === 'number'
261
+ ? data.cache
262
+ : typeof data.cache === 'object' &&
263
+ data.cache !== null &&
264
+ !Array.isArray(data.cache)
265
+ ? data.cache.read
266
+ : undefined;
267
+ const reportedCachedInput = Number(data.cached_input ?? data.cachedTokens ?? data.cache_read_tokens ?? cacheValue ?? 0) || 0;
268
+ const hasReportedCache = data.cachedTokens !== undefined ||
269
+ data.cached_input !== undefined ||
270
+ data.cache_read_tokens !== undefined ||
271
+ cacheValue !== undefined;
272
+ const rawTotal = data.total ?? data.totalTokens;
273
+ const hasReportedTotal = rawTotal !== undefined && rawTotal !== null;
274
+ const reportedTotal = Number(rawTotal) || 0;
275
+ // A harness-reported cache counter is authoritative. The remainder
276
+ // formula (total minus input, output, and reasoning) is a fallback
277
+ // used strictly when the event carries no cache field at all.
278
+ const cachedInput = hasReportedCache
279
+ ? reportedCachedInput
280
+ : hasReportedTotal
281
+ ? Math.max(0, reportedTotal - input - output - reasoning)
282
+ : 0;
283
+ const total = hasReportedTotal
284
+ ? reportedTotal
285
+ : input + cachedInput + output + reasoning;
286
+ totalInput += input;
287
+ totalCachedInput += cachedInput;
288
+ totalOutput += output;
289
+ totalReasoning += reasoning;
290
+ totalTokens += total;
291
+ }
292
+ if (event.data &&
293
+ typeof event.data.cost === 'number' &&
294
+ Number.isFinite(event.data.cost)) {
295
+ const reportedCost = event.data.cost;
296
+ totalCost += reportedCost;
297
+ const specKey = path.basename(folderPath);
298
+ perSpecCost[specKey] = (perSpecCost[specKey] ?? 0) + reportedCost;
299
+ }
300
+ if (event.type === 'dead') {
301
+ specHasDeadEvents = true;
302
+ const reason = typeof event.data?.reason === 'string' && event.data.reason.trim()
303
+ ? event.data.reason.trim()
304
+ : 'unknown';
305
+ failureBreakdown[reason] = (failureBreakdown[reason] || 0) + 1;
306
+ }
307
+ if (event.type === 'tool' && event.data) {
308
+ const tool = event.data.tool;
309
+ if (typeof tool === 'string' && FILE_CHANGE_TOOLS.has(tool.toLowerCase())) {
310
+ totalFileChanges++;
311
+ const filePath = extractFilePath(event.data);
312
+ if (filePath !== null)
313
+ uniqueFiles.add(filePath);
314
+ }
315
+ }
316
+ if (event.type === 'file_changed' && event.data) {
317
+ totalFileChanges++;
318
+ const filePath = extractFilePath(event.data);
319
+ if (filePath !== null)
320
+ uniqueFiles.add(filePath);
321
+ if (Array.isArray(event.data.files)) {
322
+ for (const f of event.data.files) {
323
+ const normalized = normalizeFilePath(f);
324
+ if (normalized !== null)
325
+ uniqueFiles.add(normalized);
326
+ }
327
+ }
328
+ }
329
+ }
330
+ catch { }
331
+ }
332
+ if (hasEvents) {
333
+ let taskDuration = 0;
334
+ if (startedTime !== null && exitedTime !== null && exitedTime >= startedTime) {
335
+ taskDuration = exitedTime - startedTime;
336
+ }
337
+ else if (minTime !== null && maxTime !== null && maxTime > minTime) {
338
+ taskDuration = maxTime - minTime;
339
+ }
340
+ if (taskDuration > 0) {
341
+ totalDurationMs += taskDuration;
342
+ tasksWithDurationCount++;
343
+ }
344
+ }
345
+ }
346
+ // Legacy specs without any dead event in the append-only stream fall back
347
+ // to the current dead markers so historical reasons are still reported.
348
+ if (!specHasDeadEvents) {
349
+ const deadDir = path.join(runDir, 'dead');
350
+ let deadFiles = [];
351
+ try {
352
+ deadFiles = await fs.readdir(deadDir);
353
+ }
354
+ catch {
355
+ deadFiles = [];
356
+ }
357
+ for (const deadFile of deadFiles) {
358
+ if (!deadFile.endsWith('.md'))
359
+ continue;
360
+ const deadContent = await fs.readFile(path.join(deadDir, deadFile), 'utf8').catch(() => '');
361
+ if (!deadContent)
362
+ continue;
363
+ const { data } = parseFrontmatter(deadContent);
364
+ const reason = typeof data.reason === 'string' && data.reason.trim() ? data.reason.trim() : 'unknown';
365
+ failureBreakdown[reason] = (failureBreakdown[reason] || 0) + 1;
366
+ }
367
+ }
368
+ }
369
+ const activeSpecs = activeFolders.length;
370
+ const archivedSpecs = archivedFolders.length;
371
+ const totalSpecs = activeSpecs + archivedSpecs;
372
+ const completionRate = totalTasks > 0 ? Math.round((doneTasks / totalTasks) * 10000) / 100 : 0;
373
+ const avgDurationMs = tasksWithDurationCount > 0 ? Math.round(totalDurationMs / tasksWithDurationCount) : 0;
374
+ const totalSeconds = Math.round(totalDurationMs / 1000);
375
+ const avgSeconds = Math.round(avgDurationMs / 1000);
376
+ const formattedTotal = formatDuration(totalDurationMs);
377
+ const formattedAvg = formatDuration(avgDurationMs);
378
+ const cost = totalCost > 0
379
+ ? {
380
+ total: totalCost,
381
+ perSpec: Object.fromEntries(Object.entries(perSpecCost)
382
+ .filter(([, value]) => value > 0)
383
+ .sort(([a], [b]) => a.localeCompare(b))),
384
+ formattedTotal: formatCost(totalCost),
385
+ }
386
+ : undefined;
387
+ return {
388
+ specs: {
389
+ total: totalSpecs,
390
+ active: activeSpecs,
391
+ archived: archivedSpecs,
392
+ },
393
+ tasks: {
394
+ total: totalTasks,
395
+ done: doneTasks,
396
+ dead: deadTasks,
397
+ running: runningTasks,
398
+ pending: pendingTasks,
399
+ },
400
+ completionRate,
401
+ failureBreakdown,
402
+ durations: {
403
+ totalMs: totalDurationMs,
404
+ totalSeconds,
405
+ avgMs: avgDurationMs,
406
+ avgSeconds,
407
+ formattedTotal,
408
+ formattedAvg,
409
+ },
410
+ tokens: {
411
+ input: totalInput,
412
+ cached_input: totalCachedInput,
413
+ output: totalOutput,
414
+ reasoning: totalReasoning,
415
+ total: totalTokens,
416
+ cacheSharePercent: totalInput + totalCachedInput > 0
417
+ ? Math.round((totalCachedInput / (totalInput + totalCachedInput)) * 1000) / 10
418
+ : 0,
419
+ },
420
+ ...(cost ? { cost } : {}),
421
+ fileChanges: {
422
+ totalChanges: totalFileChanges,
423
+ uniqueFiles: Array.from(uniqueFiles).sort(),
424
+ uniqueCount: uniqueFiles.size,
425
+ },
426
+ };
427
+ }
428
+ export function formatMetricsReport(report) {
429
+ const lines = [];
430
+ lines.push('osq Delivery Metrics Report');
431
+ lines.push('');
432
+ lines.push('Specs Summary:');
433
+ lines.push(` Total specs: ${report.specs.total} (${report.specs.active} active, ${report.specs.archived} archived)`);
434
+ lines.push('');
435
+ lines.push('Tasks & Completion:');
436
+ lines.push(` Total tasks: ${report.tasks.total}`);
437
+ lines.push(` Done: ${report.tasks.done}`);
438
+ lines.push(` Dead: ${report.tasks.dead}`);
439
+ lines.push(` Running: ${report.tasks.running}`);
440
+ lines.push(` Pending: ${report.tasks.pending}`);
441
+ lines.push(` Completion rate: ${report.completionRate}%`);
442
+ lines.push('');
443
+ lines.push('Failure Breakdown:');
444
+ const failureEntries = Object.entries(report.failureBreakdown).sort(([a], [b]) => a.localeCompare(b));
445
+ if (failureEntries.length === 0) {
446
+ lines.push(' (no failures)');
447
+ }
448
+ else {
449
+ for (const [reason, count] of failureEntries) {
450
+ lines.push(` ${reason}: ${count}`);
451
+ }
452
+ }
453
+ lines.push('');
454
+ lines.push('Execution Durations:');
455
+ lines.push(` Total duration: ${report.durations.formattedTotal}`);
456
+ lines.push(` Average duration: ${report.durations.formattedAvg}`);
457
+ lines.push('');
458
+ lines.push('Token Usage:');
459
+ lines.push(` Input: ${report.tokens.input}`);
460
+ lines.push(` Cached input: ${report.tokens.cached_input} (${report.tokens.cacheSharePercent}% cache share)`);
461
+ lines.push(` Output: ${report.tokens.output}`);
462
+ lines.push(` Reasoning: ${report.tokens.reasoning}`);
463
+ lines.push(` Total tokens: ${report.tokens.total}`);
464
+ if (report.cost && report.cost.total > 0) {
465
+ lines.push('');
466
+ lines.push('Cost:');
467
+ lines.push(` Reported cost: ${report.cost.formattedTotal}`);
468
+ }
469
+ lines.push('');
470
+ lines.push('File Changes:');
471
+ lines.push(` Total change events: ${report.fileChanges.totalChanges}`);
472
+ lines.push(` Unique files modified: ${report.fileChanges.uniqueCount}`);
473
+ return lines.join('\n');
474
+ }
475
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/core/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type OsqConfig } from './config.js';
2
+ import { type SpecStatus, type TaskStatus } from './state.js';
3
+ export interface TimelineEvent {
4
+ taskNumber: string;
5
+ type: string;
6
+ timestamp: string;
7
+ data?: Record<string, unknown>;
8
+ }
9
+ export interface TaskDetail {
10
+ taskNumber: string;
11
+ fileName: string;
12
+ title: string;
13
+ status: TaskStatus;
14
+ verify: string;
15
+ scope: string[];
16
+ entry: string[];
17
+ skills: string[];
18
+ acceptance: string[];
19
+ deadReason?: string;
20
+ deadDiagnostic?: string;
21
+ resultContent?: string;
22
+ events: TimelineEvent[];
23
+ }
24
+ export interface SpecDetails {
25
+ id: string;
26
+ folderName: string;
27
+ folderPath: string;
28
+ isArchived: boolean;
29
+ title: string;
30
+ status: SpecStatus;
31
+ approvedHash: string | null;
32
+ dependsOn: string[];
33
+ features: {
34
+ reads: string[];
35
+ writes: string[];
36
+ };
37
+ goal: string;
38
+ contract: string;
39
+ nonGoals: string;
40
+ delta: string;
41
+ tasks: TaskDetail[];
42
+ timeline: TimelineEvent[];
43
+ }
44
+ export declare function resolveSpecFolder(projectRoot: string, idOrPrefix: string, config?: OsqConfig): Promise<{
45
+ folderPath: string;
46
+ isArchived: boolean;
47
+ }>;
48
+ export declare function getSpecDetails(projectRoot: string, specIdOrPrefix: string, config?: OsqConfig): Promise<SpecDetails>;
49
+ export declare function formatSpecDetails(details: SpecDetails): string;
50
+ //# sourceMappingURL=show.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"show.d.ts","sourceRoot":"","sources":["../../src/core/show.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAmB,MAAM,YAAY,CAAC;AAE/E,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;IACF,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAaD,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,SAA0B,GACjC,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAqEtD;AAED,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,EACtB,MAAM,GAAE,SAA0B,GACjC,OAAO,CAAC,WAAW,CAAC,CAqMtB;AAQD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAmG9D"}