@swarmdo/cli 1.50.0 → 1.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +6 -3
  2. package/dist/src/agent-bridge/bridge.d.ts +104 -0
  3. package/dist/src/agent-bridge/bridge.d.ts.map +1 -0
  4. package/dist/src/agent-bridge/bridge.js +133 -0
  5. package/dist/src/agent-bridge/bridge.js.map +1 -0
  6. package/dist/src/command-usage/usage.d.ts +74 -0
  7. package/dist/src/command-usage/usage.d.ts.map +1 -0
  8. package/dist/src/command-usage/usage.js +161 -0
  9. package/dist/src/command-usage/usage.js.map +1 -0
  10. package/dist/src/commands/agent.d.ts.map +1 -1
  11. package/dist/src/commands/agent.js +133 -1
  12. package/dist/src/commands/agent.js.map +1 -1
  13. package/dist/src/commands/commands.d.ts +19 -0
  14. package/dist/src/commands/commands.d.ts.map +1 -0
  15. package/dist/src/commands/commands.js +107 -0
  16. package/dist/src/commands/commands.js.map +1 -0
  17. package/dist/src/commands/index.d.ts.map +1 -1
  18. package/dist/src/commands/index.js +11 -3
  19. package/dist/src/commands/index.js.map +1 -1
  20. package/dist/src/commands/standup.d.ts +18 -0
  21. package/dist/src/commands/standup.d.ts.map +1 -0
  22. package/dist/src/commands/standup.js +116 -0
  23. package/dist/src/commands/standup.js.map +1 -0
  24. package/dist/src/commands/swarm.d.ts.map +1 -1
  25. package/dist/src/commands/swarm.js +29 -0
  26. package/dist/src/commands/swarm.js.map +1 -1
  27. package/dist/src/commands/usage.d.ts.map +1 -1
  28. package/dist/src/commands/usage.js +57 -1
  29. package/dist/src/commands/usage.js.map +1 -1
  30. package/dist/src/comms/store.d.ts +11 -1
  31. package/dist/src/comms/store.d.ts.map +1 -1
  32. package/dist/src/comms/store.js +16 -2
  33. package/dist/src/comms/store.js.map +1 -1
  34. package/dist/src/init/helpers-generator.d.ts.map +1 -1
  35. package/dist/src/init/helpers-generator.js +41 -1
  36. package/dist/src/init/helpers-generator.js.map +1 -1
  37. package/dist/src/init/statusline-generator.d.ts.map +1 -1
  38. package/dist/src/init/statusline-generator.js +9 -2
  39. package/dist/src/init/statusline-generator.js.map +1 -1
  40. package/dist/src/integrations/integrations.d.ts.map +1 -1
  41. package/dist/src/integrations/integrations.js +19 -8
  42. package/dist/src/integrations/integrations.js.map +1 -1
  43. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  44. package/dist/src/mcp-tools/agent-tools.js +166 -0
  45. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  46. package/dist/src/mcp-tools/comms-tools.js +4 -4
  47. package/dist/src/mcp-tools/comms-tools.js.map +1 -1
  48. package/dist/src/mcp-tools/swarm-tools.d.ts +33 -0
  49. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  50. package/dist/src/mcp-tools/swarm-tools.js +73 -38
  51. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  52. package/dist/src/standup/standup.d.ts +83 -0
  53. package/dist/src/standup/standup.d.ts.map +1 -0
  54. package/dist/src/standup/standup.js +157 -0
  55. package/dist/src/standup/standup.js.map +1 -0
  56. package/dist/src/usage/transcript-friction.d.ts +77 -0
  57. package/dist/src/usage/transcript-friction.d.ts.map +1 -0
  58. package/dist/src/usage/transcript-friction.js +151 -0
  59. package/dist/src/usage/transcript-friction.js.map +1 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/package.json +1 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * standup.ts — "what did I do?" recall from git history, weekend-aware.
3
+ *
4
+ * Ports the signature behavior of git-standup: list the commits since your last
5
+ * WORKING day, so on Monday you reach back to Friday (not merely yesterday).
6
+ * Power users juggling many repos + AI-agent sessions use it to re-orient at the
7
+ * start of a session and to answer the standup question in one command.
8
+ *
9
+ * Pure + deterministic: the grouping core takes the raw `git log --numstat`
10
+ * dump (control-char delimited, subject included) and a reference Date, and
11
+ * folds it into per-day buckets. No LLM, no network — the git subprocess lives
12
+ * in ../commands/standup.ts, so this module is fully fixture-testable.
13
+ * `resolveRenamePath` is reused from hotspots so renamed files fold correctly.
14
+ *
15
+ * Expected log format (control-char delimited):
16
+ * <SOH>%H<US>%aN<US>%aI<US>%s ← one header line per commit (subject last)
17
+ * <added>\t<deleted>\t<path> ← one numstat line per file ('-' = binary)
18
+ */
19
+ export interface StandupCommit {
20
+ hash: string;
21
+ author: string;
22
+ /** epoch milliseconds, parsed from the ISO author date */
23
+ date: number;
24
+ subject: string;
25
+ /** insertions summed across the commit's files (binary counts as 0) */
26
+ added: number;
27
+ /** deletions summed across the commit's files */
28
+ deleted: number;
29
+ /** count of files touched by the commit */
30
+ files: number;
31
+ }
32
+ export interface DayBucket {
33
+ /** local calendar day, `YYYY-MM-DD` */
34
+ day: string;
35
+ /** commits on this day, newest first */
36
+ commits: StandupCommit[];
37
+ /** day totals */
38
+ added: number;
39
+ deleted: number;
40
+ files: number;
41
+ }
42
+ /**
43
+ * How many days back to the last WORKING day (Mon–Fri), given a day-of-week
44
+ * (0=Sun..6=Sat). Weekend-aware, matching git-standup's signature behavior:
45
+ * Monday (1) → 3 (reach back to Friday)
46
+ * Sunday (0) → 2 (reach back to Friday)
47
+ * any other → 1 (yesterday)
48
+ * Pure integer core — no Date, no timezone. Out-of-range inputs are normalized
49
+ * into 0..6 so callers can pass raw arithmetic safely.
50
+ */
51
+ export declare function daysToLastWorkingDay(dayOfWeek: number): number;
52
+ /**
53
+ * The default weekend-aware window for a reference date. Reads the LOCAL
54
+ * day-of-week — a user's "last working day" is local to them. Pure w.r.t. the
55
+ * injected Date.
56
+ */
57
+ export declare function sinceLastWorkingDay(refDate: Date): {
58
+ sinceDays: number;
59
+ };
60
+ /** Parse the control-char-delimited standup log dump into commits. Pure. */
61
+ export declare function parseStandupLog(raw: string): StandupCommit[];
62
+ /**
63
+ * Local `YYYY-MM-DD` for an epoch-ms instant. Uses LOCAL calendar components so
64
+ * the day matches the user's wall clock; round-trips with local-constructed
65
+ * dates regardless of the runner timezone. Pure.
66
+ */
67
+ export declare function dayKey(ms: number): string;
68
+ /**
69
+ * Fold commits into per-day buckets — newest day first, and newest commit first
70
+ * within a day. Day boundaries are LOCAL. Pure (Array.sort is stable, so
71
+ * same-timestamp commits keep git-log order).
72
+ */
73
+ export declare function groupByDay(commits: StandupCommit[]): DayBucket[];
74
+ /** Weekday name for a `YYYY-MM-DD` day key (local). '' if unparseable. Pure. */
75
+ export declare function weekdayOf(day: string): string;
76
+ /**
77
+ * Human-readable standup: a heading per day (weekday + date + counts) followed
78
+ * by each commit's abbreviated hash and subject, then a totals footer. Pure.
79
+ */
80
+ export declare function formatStandup(buckets: DayBucket[], opts?: {
81
+ abbrev?: number;
82
+ }): string;
83
+ //# sourceMappingURL=standup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standup.d.ts","sourceRoot":"","sources":["../../../src/standup/standup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAOH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,IAAI,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAExE;AAED,4EAA4E;AAC5E,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CAmC5D;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMzC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,SAAS,EAAE,CAkBhE;AAID,gFAAgF;AAChF,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAkB1F"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * standup.ts — "what did I do?" recall from git history, weekend-aware.
3
+ *
4
+ * Ports the signature behavior of git-standup: list the commits since your last
5
+ * WORKING day, so on Monday you reach back to Friday (not merely yesterday).
6
+ * Power users juggling many repos + AI-agent sessions use it to re-orient at the
7
+ * start of a session and to answer the standup question in one command.
8
+ *
9
+ * Pure + deterministic: the grouping core takes the raw `git log --numstat`
10
+ * dump (control-char delimited, subject included) and a reference Date, and
11
+ * folds it into per-day buckets. No LLM, no network — the git subprocess lives
12
+ * in ../commands/standup.ts, so this module is fully fixture-testable.
13
+ * `resolveRenamePath` is reused from hotspots so renamed files fold correctly.
14
+ *
15
+ * Expected log format (control-char delimited):
16
+ * <SOH>%H<US>%aN<US>%aI<US>%s ← one header line per commit (subject last)
17
+ * <added>\t<deleted>\t<path> ← one numstat line per file ('-' = binary)
18
+ */
19
+ import { resolveRenamePath } from '../hotspots/hotspots.js';
20
+ const SOH = '\x01'; // start-of-commit marker (git --format=format:%x01...)
21
+ const US = '\x1f'; // field separator (%x1f)
22
+ /**
23
+ * How many days back to the last WORKING day (Mon–Fri), given a day-of-week
24
+ * (0=Sun..6=Sat). Weekend-aware, matching git-standup's signature behavior:
25
+ * Monday (1) → 3 (reach back to Friday)
26
+ * Sunday (0) → 2 (reach back to Friday)
27
+ * any other → 1 (yesterday)
28
+ * Pure integer core — no Date, no timezone. Out-of-range inputs are normalized
29
+ * into 0..6 so callers can pass raw arithmetic safely.
30
+ */
31
+ export function daysToLastWorkingDay(dayOfWeek) {
32
+ const d = ((Math.trunc(dayOfWeek) % 7) + 7) % 7;
33
+ if (d === 1)
34
+ return 3; // Monday → Friday
35
+ if (d === 0)
36
+ return 2; // Sunday → Friday
37
+ return 1; // yesterday
38
+ }
39
+ /**
40
+ * The default weekend-aware window for a reference date. Reads the LOCAL
41
+ * day-of-week — a user's "last working day" is local to them. Pure w.r.t. the
42
+ * injected Date.
43
+ */
44
+ export function sinceLastWorkingDay(refDate) {
45
+ return { sinceDays: daysToLastWorkingDay(refDate.getDay()) };
46
+ }
47
+ /** Parse the control-char-delimited standup log dump into commits. Pure. */
48
+ export function parseStandupLog(raw) {
49
+ const commits = [];
50
+ let cur = null;
51
+ for (const line of raw.split('\n')) {
52
+ if (line === '')
53
+ continue;
54
+ if (line.startsWith(SOH)) {
55
+ const parts = line.slice(1).split(US);
56
+ const t = Date.parse(parts[2] ?? '');
57
+ cur = {
58
+ hash: parts[0] ?? '',
59
+ author: parts[1] ?? '',
60
+ date: Number.isNaN(t) ? 0 : t,
61
+ // subject is the last field; rejoin defensively in case it ever held a US.
62
+ subject: parts.slice(3).join(US),
63
+ added: 0,
64
+ deleted: 0,
65
+ files: 0,
66
+ };
67
+ commits.push(cur);
68
+ continue;
69
+ }
70
+ if (!cur)
71
+ continue;
72
+ // numstat: added<TAB>deleted<TAB>path ('-' means binary → count as 0)
73
+ const tab1 = line.indexOf('\t');
74
+ const tab2 = line.indexOf('\t', tab1 + 1);
75
+ if (tab1 < 0 || tab2 < 0)
76
+ continue;
77
+ const a = line.slice(0, tab1);
78
+ const d = line.slice(tab1 + 1, tab2);
79
+ const path = resolveRenamePath(line.slice(tab2 + 1));
80
+ if (!path)
81
+ continue;
82
+ cur.added += a === '-' ? 0 : parseInt(a, 10) || 0;
83
+ cur.deleted += d === '-' ? 0 : parseInt(d, 10) || 0;
84
+ cur.files += 1;
85
+ }
86
+ return commits;
87
+ }
88
+ /**
89
+ * Local `YYYY-MM-DD` for an epoch-ms instant. Uses LOCAL calendar components so
90
+ * the day matches the user's wall clock; round-trips with local-constructed
91
+ * dates regardless of the runner timezone. Pure.
92
+ */
93
+ export function dayKey(ms) {
94
+ const d = new Date(ms);
95
+ const y = d.getFullYear();
96
+ const m = String(d.getMonth() + 1).padStart(2, '0');
97
+ const day = String(d.getDate()).padStart(2, '0');
98
+ return `${y}-${m}-${day}`;
99
+ }
100
+ /**
101
+ * Fold commits into per-day buckets — newest day first, and newest commit first
102
+ * within a day. Day boundaries are LOCAL. Pure (Array.sort is stable, so
103
+ * same-timestamp commits keep git-log order).
104
+ */
105
+ export function groupByDay(commits) {
106
+ const map = new Map();
107
+ for (const c of commits) {
108
+ const key = dayKey(c.date);
109
+ let b = map.get(key);
110
+ if (!b) {
111
+ b = { day: key, commits: [], added: 0, deleted: 0, files: 0 };
112
+ map.set(key, b);
113
+ }
114
+ b.commits.push(c);
115
+ b.added += c.added;
116
+ b.deleted += c.deleted;
117
+ b.files += c.files;
118
+ }
119
+ const buckets = [...map.values()];
120
+ for (const b of buckets)
121
+ b.commits.sort((x, y) => y.date - x.date); // newest first
122
+ buckets.sort((x, y) => (x.day < y.day ? 1 : x.day > y.day ? -1 : 0)); // newest day first
123
+ return buckets;
124
+ }
125
+ const WEEKDAY = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
126
+ /** Weekday name for a `YYYY-MM-DD` day key (local). '' if unparseable. Pure. */
127
+ export function weekdayOf(day) {
128
+ const [y, m, d] = day.split('-').map(Number);
129
+ if (!y || !m || !d)
130
+ return '';
131
+ return WEEKDAY[new Date(y, m - 1, d).getDay()] ?? '';
132
+ }
133
+ /**
134
+ * Human-readable standup: a heading per day (weekday + date + counts) followed
135
+ * by each commit's abbreviated hash and subject, then a totals footer. Pure.
136
+ */
137
+ export function formatStandup(buckets, opts = {}) {
138
+ if (buckets.length === 0)
139
+ return 'no commits in the window — nothing to report';
140
+ const abbrev = opts.abbrev ?? 9;
141
+ const totalCommits = buckets.reduce((n, b) => n + b.commits.length, 0);
142
+ const lines = [];
143
+ for (const b of buckets) {
144
+ const wd = weekdayOf(b.day);
145
+ const plural = b.commits.length === 1 ? '' : 's';
146
+ lines.push(`${wd ? wd + ', ' : ''}${b.day} — ${b.commits.length} commit${plural}, +${b.added}/-${b.deleted}`);
147
+ for (const c of b.commits) {
148
+ lines.push(` ${c.hash.slice(0, abbrev)} ${c.subject}`);
149
+ }
150
+ lines.push('');
151
+ }
152
+ const dp = buckets.length === 1 ? '' : 's';
153
+ const cp = totalCommits === 1 ? '' : 's';
154
+ lines.push(`${totalCommits} commit${cp} across ${buckets.length} day${dp}`);
155
+ return lines.join('\n');
156
+ }
157
+ //# sourceMappingURL=standup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standup.js","sourceRoot":"","sources":["../../../src/standup/standup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * transcript-friction.ts — interruption + error-category analytics over the same
3
+ * Claude Code transcripts the `usage` command already reads. `usage errors`
4
+ * answers "which tools fail"; this answers "where does Claude waste my turns" —
5
+ * how often you interrupt it (ESC mid-turn), which tool was running when you did,
6
+ * and what KIND of errors dominate (NotFound/Permission/Timeout/Network/Syntax).
7
+ * The interruption axis + human-meaningful error categories are the sniffly
8
+ * (chiphuyen, 1.2k★) headline signals `usage errors` left on the table (#102).
9
+ *
10
+ * The fold is pure and unit-tested; only collectFriction touches the filesystem.
11
+ * Reuses blockText / ParsedLine (transcript-errors) + the transcript plumbing.
12
+ */
13
+ import { type ParsedLine } from './transcript-errors.js';
14
+ export type ErrorCategory = 'NotFound' | 'Permission' | 'Timeout' | 'Network' | 'Syntax' | 'Other';
15
+ export declare const ERROR_CATEGORIES: ErrorCategory[];
16
+ export interface ToolInterruptions {
17
+ /** tool name that was running when interrupted, or '(idle)' when none was */
18
+ tool: string;
19
+ interruptions: number;
20
+ }
21
+ export interface CategoryShare {
22
+ category: ErrorCategory;
23
+ count: number;
24
+ /** count / totalErrors, 0..1 (0 when no errors) */
25
+ share: number;
26
+ }
27
+ export interface FrictionReport {
28
+ interruptions: number;
29
+ assistantTurns: number;
30
+ /** interruptions / assistantTurns, 0 when no turns (never divides by zero) */
31
+ interruptionRate: number;
32
+ byTool: ToolInterruptions[];
33
+ categories: CategoryShare[];
34
+ totalErrors: number;
35
+ filesScanned: number;
36
+ }
37
+ /** Bucket used when an interruption happened outside any running tool. */
38
+ export declare const IDLE_CONTEXT = "(idle)";
39
+ /**
40
+ * Does a user-role text block read as an ESC interruption sentinel? Matches the
41
+ * whole family at the START of the text (real transcripts show "[Request
42
+ * interrupted by user]", "… for tool use]", "…]", and bare "Request
43
+ * interrupted") — anchored so an incidental mid-sentence mention doesn't count.
44
+ */
45
+ export declare function isInterruptionText(text: string): boolean;
46
+ /**
47
+ * Map a tool-error message to a human-meaningful category. Order matters:
48
+ * specific buckets come before the broad Syntax catch so e.g. "no such file"
49
+ * lands in NotFound, not Syntax. Everything unmatched is Other. Pure.
50
+ */
51
+ export declare function classifyError(raw: string): ErrorCategory;
52
+ export interface FrictionAccum {
53
+ interruptions: number;
54
+ assistantTurns: number;
55
+ byTool: Map<string, number>;
56
+ categories: Map<ErrorCategory, number>;
57
+ totalErrors: number;
58
+ /** open tool_use id → name; cleared on its result, or on an interruption */
59
+ openTools: Map<string, string>;
60
+ /** most recent tool_use name (open or already-resolved); reset per turn on an
61
+ * interruption. Used to attribute a "…for tool use]" sentinel even after the
62
+ * interrupted tool's (often synthetic) result already landed. */
63
+ lastToolName: string | null;
64
+ }
65
+ export declare function newFrictionAccum(): FrictionAccum;
66
+ /** Fold one parsed transcript line into the accumulator. Pure (no fs). */
67
+ export declare function foldFriction(acc: FrictionAccum, line: ParsedLine): void;
68
+ export declare function finalizeFriction(acc: FrictionAccum, filesScanned: number): FrictionReport;
69
+ export interface CollectFrictionOptions {
70
+ dirs?: string[];
71
+ since?: string;
72
+ until?: string;
73
+ }
74
+ /** Walk transcripts and produce the friction report. Malformed lines and
75
+ * unreadable files are skipped, never fatal (same discipline as collectUsage). */
76
+ export declare function collectFriction(opts?: CollectFrictionOptions): FrictionReport;
77
+ //# sourceMappingURL=transcript-friction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-friction.d.ts","sourceRoot":"","sources":["../../../src/usage/transcript-friction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpE,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AACnG,eAAO,MAAM,gBAAgB,EAAE,aAAa,EAAwE,CAAC;AAErH,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;CACvB;AACD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAID,0EAA0E;AAC1E,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAQxD;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,EAAE,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;qEAEiE;IACjE,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAiCvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAgBzF;AAED,MAAM,WAAW,sBAAsB;IAAG,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAAE;AAE5F;kFACkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,GAAE,sBAA2B,GAAG,cAAc,CAoCjF"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * transcript-friction.ts — interruption + error-category analytics over the same
3
+ * Claude Code transcripts the `usage` command already reads. `usage errors`
4
+ * answers "which tools fail"; this answers "where does Claude waste my turns" —
5
+ * how often you interrupt it (ESC mid-turn), which tool was running when you did,
6
+ * and what KIND of errors dominate (NotFound/Permission/Timeout/Network/Syntax).
7
+ * The interruption axis + human-meaningful error categories are the sniffly
8
+ * (chiphuyen, 1.2k★) headline signals `usage errors` left on the table (#102).
9
+ *
10
+ * The fold is pure and unit-tested; only collectFriction touches the filesystem.
11
+ * Reuses blockText / ParsedLine (transcript-errors) + the transcript plumbing.
12
+ */
13
+ import * as fs from 'node:fs';
14
+ import { defaultClaudeProjectDirs, findTranscriptFiles, normalizeDateBound } from './transcript-usage.js';
15
+ import { blockText } from './transcript-errors.js';
16
+ export const ERROR_CATEGORIES = ['NotFound', 'Permission', 'Timeout', 'Network', 'Syntax', 'Other'];
17
+ /** Bucket used when an interruption happened outside any running tool. */
18
+ export const IDLE_CONTEXT = '(idle)';
19
+ /**
20
+ * Does a user-role text block read as an ESC interruption sentinel? Matches the
21
+ * whole family at the START of the text (real transcripts show "[Request
22
+ * interrupted by user]", "… for tool use]", "…]", and bare "Request
23
+ * interrupted") — anchored so an incidental mid-sentence mention doesn't count.
24
+ */
25
+ export function isInterruptionText(text) {
26
+ return /^\s*\[?\s*request interrupted/i.test(text);
27
+ }
28
+ /**
29
+ * Map a tool-error message to a human-meaningful category. Order matters:
30
+ * specific buckets come before the broad Syntax catch so e.g. "no such file"
31
+ * lands in NotFound, not Syntax. Everything unmatched is Other. Pure.
32
+ */
33
+ export function classifyError(raw) {
34
+ const s = raw.toLowerCase();
35
+ if (/\bnot found\b|no such file|enoent|does not exist|cannot find|doesn'?t exist|\b404\b/.test(s))
36
+ return 'NotFound';
37
+ if (/permission denied|\beacces\b|\beperm\b|not permitted|unauthori[sz]ed|forbidden|\b403\b/.test(s))
38
+ return 'Permission';
39
+ if (/timed ?out|\betimedout\b|timeout|deadline exceeded/.test(s))
40
+ return 'Timeout';
41
+ if (/econnrefused|econnreset|enotfound|network|socket hang|getaddrinfo|fetch failed|\bdns\b/.test(s))
42
+ return 'Network';
43
+ if (/syntax|parse error|unexpected token|invalid |compil|typeerror|referenceerror|cannot read propert/.test(s))
44
+ return 'Syntax';
45
+ return 'Other';
46
+ }
47
+ export function newFrictionAccum() {
48
+ return { interruptions: 0, assistantTurns: 0, byTool: new Map(), categories: new Map(), totalErrors: 0, openTools: new Map(), lastToolName: null };
49
+ }
50
+ /** Fold one parsed transcript line into the accumulator. Pure (no fs). */
51
+ export function foldFriction(acc, line) {
52
+ const role = line.message?.role;
53
+ if (role === 'assistant')
54
+ acc.assistantTurns++;
55
+ const content = line.message?.content;
56
+ if (!Array.isArray(content))
57
+ return;
58
+ for (const b of content) {
59
+ if (!b || typeof b !== 'object')
60
+ continue;
61
+ if (b.type === 'tool_use' && b.id && b.name) {
62
+ acc.openTools.set(b.id, b.name);
63
+ acc.lastToolName = b.name;
64
+ }
65
+ else if (b.type === 'tool_result') {
66
+ if (b.tool_use_id)
67
+ acc.openTools.delete(b.tool_use_id);
68
+ if (b.is_error) {
69
+ acc.totalErrors++;
70
+ const cat = classifyError(blockText(b.content));
71
+ acc.categories.set(cat, (acc.categories.get(cat) ?? 0) + 1);
72
+ }
73
+ }
74
+ else if (b.type === 'text' && role === 'user' && typeof b.text === 'string' && isInterruptionText(b.text)) {
75
+ acc.interruptions++;
76
+ // Attribute to: a still-open tool (interrupted mid-execution) → else, when
77
+ // the sentinel says "for tool use", the last tool used even if its
78
+ // (synthetic) result already landed → else idle.
79
+ const open = [...acc.openTools.values()];
80
+ const tool = open.length > 0
81
+ ? open[open.length - 1]
82
+ : /for tool use/i.test(b.text) && acc.lastToolName
83
+ ? acc.lastToolName
84
+ : IDLE_CONTEXT;
85
+ acc.byTool.set(tool, (acc.byTool.get(tool) ?? 0) + 1);
86
+ acc.openTools.clear(); // an interrupt ends the pending turn
87
+ acc.lastToolName = null;
88
+ }
89
+ }
90
+ }
91
+ export function finalizeFriction(acc, filesScanned) {
92
+ const byTool = [...acc.byTool.entries()]
93
+ .map(([tool, interruptions]) => ({ tool, interruptions }))
94
+ .sort((a, b) => b.interruptions - a.interruptions || a.tool.localeCompare(b.tool));
95
+ const categories = [...acc.categories.entries()]
96
+ .map(([category, count]) => ({ category, count, share: acc.totalErrors > 0 ? count / acc.totalErrors : 0 }))
97
+ .sort((a, b) => b.count - a.count || a.category.localeCompare(b.category));
98
+ return {
99
+ interruptions: acc.interruptions,
100
+ assistantTurns: acc.assistantTurns,
101
+ interruptionRate: acc.assistantTurns > 0 ? acc.interruptions / acc.assistantTurns : 0,
102
+ byTool,
103
+ categories,
104
+ totalErrors: acc.totalErrors,
105
+ filesScanned,
106
+ };
107
+ }
108
+ /** Walk transcripts and produce the friction report. Malformed lines and
109
+ * unreadable files are skipped, never fatal (same discipline as collectUsage). */
110
+ export function collectFriction(opts = {}) {
111
+ const dirs = opts.dirs && opts.dirs.length > 0 ? opts.dirs : defaultClaudeProjectDirs();
112
+ const since = normalizeDateBound(opts.since);
113
+ const until = normalizeDateBound(opts.until);
114
+ const acc = newFrictionAccum();
115
+ let filesScanned = 0;
116
+ for (const dir of dirs) {
117
+ for (const { file } of findTranscriptFiles(dir)) {
118
+ filesScanned++;
119
+ let content;
120
+ try {
121
+ content = fs.readFileSync(file, 'utf8');
122
+ }
123
+ catch {
124
+ continue;
125
+ }
126
+ for (const raw of content.split('\n')) {
127
+ if (!raw.trim())
128
+ continue;
129
+ let line;
130
+ try {
131
+ line = JSON.parse(raw);
132
+ }
133
+ catch {
134
+ continue;
135
+ }
136
+ if (since || until) {
137
+ const day = line.timestamp ? line.timestamp.slice(0, 10) : '';
138
+ if (day) {
139
+ if (since && day < since)
140
+ continue;
141
+ if (until && day > until)
142
+ continue;
143
+ }
144
+ }
145
+ foldFriction(acc, line);
146
+ }
147
+ }
148
+ }
149
+ return finalizeFriction(acc, filesScanned);
150
+ }
151
+ //# sourceMappingURL=transcript-friction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-friction.js","sourceRoot":"","sources":["../../../src/usage/transcript-friction.ts"],"names":[],"mappings":"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"}