@agentdeck/shared 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/action-fold.d.ts +71 -0
  2. package/dist/action-fold.d.ts.map +1 -0
  3. package/dist/action-fold.js +93 -0
  4. package/dist/action-fold.js.map +1 -0
  5. package/dist/apme-graph.d.ts +6 -2
  6. package/dist/apme-graph.d.ts.map +1 -1
  7. package/dist/apme-graph.js +3 -1
  8. package/dist/apme-graph.js.map +1 -1
  9. package/dist/claude-permission-rules.d.ts +181 -0
  10. package/dist/claude-permission-rules.d.ts.map +1 -0
  11. package/dist/claude-permission-rules.js +495 -0
  12. package/dist/claude-permission-rules.js.map +1 -0
  13. package/dist/connection-status.d.ts +11 -2
  14. package/dist/connection-status.d.ts.map +1 -1
  15. package/dist/connection-status.js +11 -2
  16. package/dist/connection-status.js.map +1 -1
  17. package/dist/d200h-layout.d.ts +4 -0
  18. package/dist/d200h-layout.d.ts.map +1 -1
  19. package/dist/d200h-layout.js +30 -10
  20. package/dist/d200h-layout.js.map +1 -1
  21. package/dist/esp32-boards.d.ts.map +1 -1
  22. package/dist/esp32-boards.js +34 -0
  23. package/dist/esp32-boards.js.map +1 -1
  24. package/dist/eval-schema.d.ts +74 -3
  25. package/dist/eval-schema.d.ts.map +1 -1
  26. package/dist/eval-schema.js +23 -0
  27. package/dist/eval-schema.js.map +1 -1
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +3 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/pairing-code.d.ts +69 -0
  33. package/dist/pairing-code.d.ts.map +1 -1
  34. package/dist/pairing-code.js +138 -0
  35. package/dist/pairing-code.js.map +1 -1
  36. package/dist/protocol.d.ts +63 -0
  37. package/dist/protocol.d.ts.map +1 -1
  38. package/dist/protocol.js +2 -0
  39. package/dist/protocol.js.map +1 -1
  40. package/dist/sample.d.ts +48 -2
  41. package/dist/sample.d.ts.map +1 -1
  42. package/dist/session-utils.d.ts.map +1 -1
  43. package/dist/session-utils.js +11 -2
  44. package/dist/session-utils.js.map +1 -1
  45. package/dist/subagent-activity.d.ts.map +1 -1
  46. package/dist/subagent-activity.js +16 -1
  47. package/dist/subagent-activity.js.map +1 -1
  48. package/dist/task-title.d.ts +51 -0
  49. package/dist/task-title.d.ts.map +1 -0
  50. package/dist/task-title.js +111 -0
  51. package/dist/task-title.js.map +1 -0
  52. package/dist/timeline-task-display.d.ts +8 -4
  53. package/dist/timeline-task-display.d.ts.map +1 -1
  54. package/dist/timeline-task-display.js +9 -3
  55. package/dist/timeline-task-display.js.map +1 -1
  56. package/package.json +2 -2
@@ -0,0 +1,71 @@
1
+ /**
2
+ * action-fold.ts — the SINGLE source of truth for folding a task's tool
3
+ * activity into one summary line: `Edit×9 Read×24 Bash×11 +2 · 3 files`.
4
+ *
5
+ * A task detail used to enumerate turns and steps; a list row has no room for
6
+ * that, and a bare total ("44 tools") says nothing about the SHAPE of the
7
+ * work. The fold is a pure projection over per-tool counts the store already
8
+ * holds (sample_events kind='tool' grouped by tool_name) — no schema change,
9
+ * no new collection.
10
+ *
11
+ * Consumers (keep in the same commit):
12
+ * - GET /apme/tasks response `actionFold` field (bridge/src/apme/http.ts)
13
+ */
14
+ export interface ActionFoldInput {
15
+ /** Per-tool call counts, any order. Names are the raw tool names the agent
16
+ * reported (`Read`, `Bash`, `mcp__server__tool`). */
17
+ tools: ReadonlyArray<{
18
+ name: string;
19
+ count: number;
20
+ }>;
21
+ /** Distinct files the task touched (modified + created), when known. */
22
+ filesTouched?: number | null;
23
+ }
24
+ /** How many named tools the fold shows before collapsing the rest to `+N`.
25
+ * Four keeps the line inside one row beside its chips at the dashboard's
26
+ * default width. */
27
+ export declare const ACTION_FOLD_MAX_TOOLS = 4;
28
+ /** `mcp__claude-in-chrome__navigate` → `navigate`: the server prefix is
29
+ * provenance, not shape, and at row width it would crowd out every other
30
+ * tool. Non-MCP names pass through unchanged. */
31
+ export declare function foldToolName(name: string): string;
32
+ /** Tool names that DISPATCH another agent (fan-out). Measured on the real
33
+ * store 2026-08-28: `Agent` (Claude Code subagent tool, 126 calls), `Task`
34
+ * (its pre-rename spelling), `task` (OpenCode's), `Workflow` (multi-agent
35
+ * orchestration — counted as ONE dispatch per call even though it fans out
36
+ * internally, because parent-side hooks see only the call). TaskCreate /
37
+ * TaskUpdate and friends are todo bookkeeping, not dispatch. */
38
+ export declare const DISPATCH_TOOL_NAMES: ReadonlySet<string>;
39
+ /** Tool names that MESSAGE another agent (peer/teammate traffic). */
40
+ export declare const MESSAGING_TOOL_NAMES: ReadonlySet<string>;
41
+ export interface AgentCoordinationSummary {
42
+ /** Subagent/workflow dispatch calls in this task. */
43
+ dispatches: number;
44
+ /** Agent-to-agent messages sent from this task. */
45
+ messages: number;
46
+ }
47
+ /**
48
+ * Count the coordination shape of a task from its per-tool counts: how often
49
+ * it fanned out to other agents and how often it messaged them. Returns null
50
+ * when the task did neither, so a plain single-agent task renders no
51
+ * coordination chip at all. Matches on RAW tool names (before `foldToolName`),
52
+ * since the dispatch/messaging sets are exact names, not display shapes.
53
+ */
54
+ export declare function agentCoordinationSummary(tools: ReadonlyArray<{
55
+ name: string;
56
+ count: number;
57
+ }>): AgentCoordinationSummary | null;
58
+ /**
59
+ * Fold tool counts into the summary line. Returns null when there is nothing
60
+ * to say (no tools and no files) — callers render nothing rather than an
61
+ * empty string, matching the retain-on-absent display rules elsewhere.
62
+ *
63
+ * Determinism: ties sort by name so the same task always folds to the same
64
+ * line (renderer output is used as identity in dedup paths — see the
65
+ * session-slot renderer rule in CLAUDE.md). The tie-break is a plain
66
+ * code-unit compare, NOT localeCompare: localeCompare's order depends on the
67
+ * host locale (and case-folds, so `Bash` vs `apply` flips), which both breaks
68
+ * determinism across machines and cannot be mirrored by Swift's `<`.
69
+ */
70
+ export declare function foldActionCounts(input: ActionFoldInput): string | null;
71
+ //# sourceMappingURL=action-fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-fold.d.ts","sourceRoot":"","sources":["../src/action-fold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,eAAe;IAC9B;0DACsD;IACtD,KAAK,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtD,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;qBAEqB;AACrB,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC;;kDAEkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKjD;AAED;;;;;iEAKiE;AACjE,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAAkD,CAAC;AAEvG,qEAAqE;AACrE,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAA4B,CAAC;AAElF,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,aAAa,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACpD,wBAAwB,GAAG,IAAI,CAUjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAkBtE"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * action-fold.ts — the SINGLE source of truth for folding a task's tool
3
+ * activity into one summary line: `Edit×9 Read×24 Bash×11 +2 · 3 files`.
4
+ *
5
+ * A task detail used to enumerate turns and steps; a list row has no room for
6
+ * that, and a bare total ("44 tools") says nothing about the SHAPE of the
7
+ * work. The fold is a pure projection over per-tool counts the store already
8
+ * holds (sample_events kind='tool' grouped by tool_name) — no schema change,
9
+ * no new collection.
10
+ *
11
+ * Consumers (keep in the same commit):
12
+ * - GET /apme/tasks response `actionFold` field (bridge/src/apme/http.ts)
13
+ */
14
+ /** How many named tools the fold shows before collapsing the rest to `+N`.
15
+ * Four keeps the line inside one row beside its chips at the dashboard's
16
+ * default width. */
17
+ export const ACTION_FOLD_MAX_TOOLS = 4;
18
+ /** `mcp__claude-in-chrome__navigate` → `navigate`: the server prefix is
19
+ * provenance, not shape, and at row width it would crowd out every other
20
+ * tool. Non-MCP names pass through unchanged. */
21
+ export function foldToolName(name) {
22
+ const trimmed = name.trim();
23
+ if (!trimmed.toLowerCase().startsWith('mcp__'))
24
+ return trimmed;
25
+ const segments = trimmed.split('__').filter((s) => s.length > 0);
26
+ return segments.length > 0 ? segments[segments.length - 1] : trimmed;
27
+ }
28
+ /** Tool names that DISPATCH another agent (fan-out). Measured on the real
29
+ * store 2026-08-28: `Agent` (Claude Code subagent tool, 126 calls), `Task`
30
+ * (its pre-rename spelling), `task` (OpenCode's), `Workflow` (multi-agent
31
+ * orchestration — counted as ONE dispatch per call even though it fans out
32
+ * internally, because parent-side hooks see only the call). TaskCreate /
33
+ * TaskUpdate and friends are todo bookkeeping, not dispatch. */
34
+ export const DISPATCH_TOOL_NAMES = new Set(['Agent', 'Task', 'task', 'Workflow']);
35
+ /** Tool names that MESSAGE another agent (peer/teammate traffic). */
36
+ export const MESSAGING_TOOL_NAMES = new Set(['SendMessage']);
37
+ /**
38
+ * Count the coordination shape of a task from its per-tool counts: how often
39
+ * it fanned out to other agents and how often it messaged them. Returns null
40
+ * when the task did neither, so a plain single-agent task renders no
41
+ * coordination chip at all. Matches on RAW tool names (before `foldToolName`),
42
+ * since the dispatch/messaging sets are exact names, not display shapes.
43
+ */
44
+ export function agentCoordinationSummary(tools) {
45
+ let dispatches = 0;
46
+ let messages = 0;
47
+ for (const t of tools) {
48
+ if (!(t.count > 0))
49
+ continue;
50
+ if (DISPATCH_TOOL_NAMES.has(t.name.trim()))
51
+ dispatches += t.count;
52
+ if (MESSAGING_TOOL_NAMES.has(t.name.trim()))
53
+ messages += t.count;
54
+ }
55
+ if (dispatches === 0 && messages === 0)
56
+ return null;
57
+ return { dispatches, messages };
58
+ }
59
+ /**
60
+ * Fold tool counts into the summary line. Returns null when there is nothing
61
+ * to say (no tools and no files) — callers render nothing rather than an
62
+ * empty string, matching the retain-on-absent display rules elsewhere.
63
+ *
64
+ * Determinism: ties sort by name so the same task always folds to the same
65
+ * line (renderer output is used as identity in dedup paths — see the
66
+ * session-slot renderer rule in CLAUDE.md). The tie-break is a plain
67
+ * code-unit compare, NOT localeCompare: localeCompare's order depends on the
68
+ * host locale (and case-folds, so `Bash` vs `apply` flips), which both breaks
69
+ * determinism across machines and cannot be mirrored by Swift's `<`.
70
+ */
71
+ export function foldActionCounts(input) {
72
+ const merged = new Map();
73
+ for (const t of input.tools) {
74
+ const name = foldToolName(t.name);
75
+ if (!name || !(t.count > 0))
76
+ continue;
77
+ merged.set(name, (merged.get(name) ?? 0) + t.count);
78
+ }
79
+ const sorted = [...merged.entries()].sort((a, b) => (b[1] - a[1]) || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
80
+ const parts = [];
81
+ if (sorted.length > 0) {
82
+ const shown = sorted.slice(0, ACTION_FOLD_MAX_TOOLS);
83
+ const rest = sorted.length - shown.length;
84
+ parts.push(shown.map(([name, count]) => `${name}×${count}`).join(' ') + (rest > 0 ? ` +${rest}` : ''));
85
+ }
86
+ const files = input.filesTouched ?? 0;
87
+ if (files > 0)
88
+ parts.push(`${files} file${files === 1 ? '' : 's'}`);
89
+ if (parts.length === 0)
90
+ return null;
91
+ return parts.join(' · ');
92
+ }
93
+ //# sourceMappingURL=action-fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-fold.js","sourceRoot":"","sources":["../src/action-fold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAUH;;qBAEqB;AACrB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAEvC;;kDAEkD;AAClD,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjE,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,OAAO,CAAC;AACxE,CAAC;AAED;;;;;iEAKiE;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAEvG,qEAAqE;AACrE,MAAM,CAAC,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;AASlF;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CACtC,KAAqD;IAErD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAAE,SAAS;QAC7B,IAAI,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAAE,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC;QAClE,IAAI,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAAE,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC;IACnE,CAAC;IACD,IAAI,UAAU,KAAK,CAAC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACrD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAAE,SAAS;QACtC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACtD,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/G,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;IACtC,IAAI,KAAK,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;IACpE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
@@ -18,7 +18,8 @@
18
18
  * session held 127 runs). Now `runs.parent_run_id`.
19
19
  *
20
20
  * What is still denormalized, and is therefore DERIVED here rather than read:
21
- * session, project, model, agent, tool and file are string columns, not rows.
21
+ * session, project, model, agent, tool, subagent and file are string/payload
22
+ * identities, not rows.
22
23
  * They are exactly the interesting hubs — they connect work units that share no
23
24
  * ancestor — so this projection materializes them as nodes. That is a deliberate
24
25
  * choice: they are cheap to derive, they change meaning as the schema evolves,
@@ -33,7 +34,7 @@
33
34
  * can be reshaped without a migration.
34
35
  */
35
36
  /** Node kinds. Containment nodes mirror rows; entity nodes are derived hubs. */
36
- export type ApmeGraphNodeKind = 'run' | 'task' | 'turn' | 'session' | 'project' | 'model' | 'agent' | 'tool' | 'file';
37
+ export type ApmeGraphNodeKind = 'run' | 'task' | 'turn' | 'session' | 'project' | 'model' | 'agent' | 'tool' | 'subagent' | 'file';
37
38
  export type ApmeGraphEdgeKind =
38
39
  /** Containment: run→task, task→turn. */
39
40
  'contains'
@@ -43,6 +44,8 @@ export type ApmeGraphEdgeKind =
43
44
  | 'produced'
44
45
  /** turn→tool, task→tool — the turn invoked this tool. */
45
46
  | 'used'
47
+ /** task/turn→subagent — the parent delegated part of this work. */
48
+ | 'delegated'
46
49
  /** turn→file, task→file — the turn read or wrote this path. */
47
50
  | 'touched';
48
51
  export interface ApmeGraphNode {
@@ -97,6 +100,7 @@ export declare const apmeGraphNodeId: {
97
100
  readonly model: (id: string) => string;
98
101
  readonly agent: (t: string) => string;
99
102
  readonly tool: (name: string) => string;
103
+ readonly subagent: (id: string) => string;
100
104
  readonly file: (path: string) => string;
101
105
  };
102
106
  //# sourceMappingURL=apme-graph.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apme-graph.d.ts","sourceRoot":"","sources":["../src/apme-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAEzB,KAAK,GACL,MAAM,GACN,MAAM,GAEN,SAAS,GACT,SAAS,GACT,OAAO,GACP,OAAO,GACP,MAAM,GACN,MAAM,CAAC;AAEX,MAAM,MAAM,iBAAiB;AAC3B,wCAAwC;AACtC,UAAU;AACZ,iEAAiE;GAC/D,WAAW;AACb,sDAAsD;GACpD,UAAU;AACZ,yDAAyD;GACvD,MAAM;AACR,+DAA+D;GAC7D,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB;2DACuD;IACvD,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,0EAA0E;QAC1E,cAAc,EAAE,MAAM,CAAC;QACvB,qEAAqE;QACrE,YAAY,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yEAAyE;AACzE,eAAO,MAAM,eAAe;uBAChB,MAAM;wBACL,MAAM;wBACN,MAAM;2BACH,MAAM;6BACJ,MAAM;yBACV,MAAM;wBACP,MAAM;0BACJ,MAAM;0BACN,MAAM;CACX,CAAC"}
1
+ {"version":3,"file":"apme-graph.d.ts","sourceRoot":"","sources":["../src/apme-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GAEzB,KAAK,GACL,MAAM,GACN,MAAM,GAEN,SAAS,GACT,SAAS,GACT,OAAO,GACP,OAAO,GACP,MAAM,GACN,UAAU,GACV,MAAM,CAAC;AAEX,MAAM,MAAM,iBAAiB;AAC3B,wCAAwC;AACtC,UAAU;AACZ,iEAAiE;GAC/D,WAAW;AACb,sDAAsD;GACpD,UAAU;AACZ,yDAAyD;GACvD,MAAM;AACR,mEAAmE;GACjE,WAAW;AACb,+DAA+D;GAC7D,SAAS,CAAC;AAEd,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB;2DACuD;IACvD,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,0EAA0E;QAC1E,cAAc,EAAE,MAAM,CAAC;QACvB,qEAAqE;QACrE,YAAY,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;CACH;AAED,MAAM,WAAW,iBAAkB,SAAQ,cAAc;IACvD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,yEAAyE;AACzE,eAAO,MAAM,eAAe;uBAChB,MAAM;wBACL,MAAM;wBACN,MAAM;2BACH,MAAM;6BACJ,MAAM;yBACV,MAAM;wBACP,MAAM;0BACJ,MAAM;4BACJ,MAAM;0BACR,MAAM;CACX,CAAC"}
@@ -18,7 +18,8 @@
18
18
  * session held 127 runs). Now `runs.parent_run_id`.
19
19
  *
20
20
  * What is still denormalized, and is therefore DERIVED here rather than read:
21
- * session, project, model, agent, tool and file are string columns, not rows.
21
+ * session, project, model, agent, tool, subagent and file are string/payload
22
+ * identities, not rows.
22
23
  * They are exactly the interesting hubs — they connect work units that share no
23
24
  * ancestor — so this projection materializes them as nodes. That is a deliberate
24
25
  * choice: they are cheap to derive, they change meaning as the schema evolves,
@@ -42,6 +43,7 @@ export const apmeGraphNodeId = {
42
43
  model: (id) => `model:${id}`,
43
44
  agent: (t) => `agent:${t}`,
44
45
  tool: (name) => `tool:${name}`,
46
+ subagent: (id) => `subagent:${id}`,
45
47
  file: (path) => `file:${path}`,
46
48
  };
47
49
  //# sourceMappingURL=apme-graph.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"apme-graph.js","sourceRoot":"","sources":["../src/apme-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAuEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,GAAG,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE;IAChC,IAAI,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;IAClC,IAAI,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;IAClC,OAAO,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE;IACxC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE;IAC5C,KAAK,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE;IACpC,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE;IAClC,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE;IACtC,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE;CAC9B,CAAC"}
1
+ {"version":3,"file":"apme-graph.js","sourceRoot":"","sources":["../src/apme-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA0EH,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,GAAG,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE;IAChC,IAAI,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;IAClC,IAAI,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;IAClC,OAAO,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,WAAW,EAAE,EAAE;IACxC,OAAO,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,WAAW,IAAI,EAAE;IAC5C,KAAK,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,SAAS,EAAE,EAAE;IACpC,KAAK,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE;IAClC,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE;IACtC,QAAQ,EAAE,CAAC,EAAU,EAAE,EAAE,CAAC,YAAY,EAAE,EAAE;IAC1C,IAAI,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,IAAI,EAAE;CAC9B,CAAC"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Claude Code permission prediction — the single source of truth for "would
3
+ * Claude Code actually prompt the user for this tool call?".
4
+ *
5
+ * Both daemons hold an observed session's PreToolUse for a device decision
6
+ * ONLY when this module predicts a genuine prompt. A false hold costs the user
7
+ * twice: the deck shows PERM for a decision Claude never asked for, and the
8
+ * hook response is held for the whole timeout (25 s) before Claude's own
9
+ * allow rule lets the call through. Measured 2026-09-05: two `acceptEdits`
10
+ * worker sessions whose every `curl`/`mkdir` was allowlisted by
11
+ * `Bash(curl *)` / `Bash(mkdir *)` were held on every batch, because the
12
+ * predictor understood only the legacy `Bash(curl:*)` spelling — 67 of the
13
+ * 73 Bash rules in the user's settings were in the space form and matched
14
+ * nothing. The Swift daemon carried the same defect as a hand mirror, which
15
+ * is why the matcher now lives here and is GENERATED into Swift
16
+ * (`pnpm generate-claude-permission-rules`), with behavior pinned by
17
+ * `shared/claude-permission-vectors.json` that both suites replay.
18
+ *
19
+ * Rule semantics follow the Claude Code permissions reference
20
+ * (https://code.claude.com/docs/en/permissions):
21
+ * - `Bash`, `Bash(*)` → every Bash call
22
+ * - `Bash(npm run build)` → the exact command
23
+ * - `Bash(npm run *)` → `*` matches any text INCLUDING spaces; a rule
24
+ * whose only wildcard is a trailing ` *` also
25
+ * matches the bare command (`ls *` ⇒ `ls`)
26
+ * - `Bash(ls:*)` → legacy end-only spelling; the docs now define
27
+ * it as `Bash(ls *)`, older builds read it as a
28
+ * raw prefix (`npm run test:*` ⇒ `npm run
29
+ * test:watch`), so it matches under EITHER —
30
+ * over-matching only ever costs a missed hold
31
+ * - `Bash(git * main)` → wildcards anywhere
32
+ * - compound commands split on `&&` `||` `;` `|` `|&` `&` and newlines, and
33
+ * EVERY subcommand must be covered for Claude to skip the prompt
34
+ * - a built-in read-only set (`ls`, `cat`, `git status`, …) never prompts in
35
+ * any mode, and `acceptEdits` additionally auto-approves the filesystem
36
+ * commands `mkdir touch rm rmdir mv cp sed`
37
+ * - `timeout`/`nice`/`nohup`/… wrappers and leading `VAR=value` assignments
38
+ * are stripped before matching
39
+ *
40
+ * Every uncertainty resolves toward "don't hold": a missed hold means the user
41
+ * answers in the terminal exactly as before, while a false hold nags them with
42
+ * a prompt Claude never showed and stalls the agent for the hold timeout.
43
+ */
44
+ /** Values Claude Code writes into a hook payload's `permission_mode`. */
45
+ export declare const CLAUDE_PERMISSION_MODES: readonly ["default", "acceptEdits", "plan", "auto", "dontAsk", "bypassPermissions"];
46
+ export type ClaudePermissionMode = typeof CLAUDE_PERMISSION_MODES[number];
47
+ /** Tools that never trigger a permission prompt — holding them can only ever
48
+ * be a false positive. Kept intentionally tight (unknown tools are excluded
49
+ * by the prompt-prone check, not this list). */
50
+ export declare const NEVER_PROMPT_TOOLS: ReadonlySet<string>;
51
+ /** Tools that DO prompt in default/acceptEdits mode unless allowlisted.
52
+ * Anything outside this set (including every mcp__* tool, whose per-server
53
+ * trust state we cannot see) is never held. */
54
+ export declare const PROMPT_PRONE_TOOLS: ReadonlySet<string>;
55
+ /** Edit-family tools that Claude auto-approves in `acceptEdits` mode. */
56
+ export declare const EDIT_FAMILY_TOOLS: ReadonlySet<string>;
57
+ /**
58
+ * Should the daemon consider HOLDING a PreToolUse at all, given the session's
59
+ * `permission_mode`? Claude's PreToolUse hook fires for EVERY tool call
60
+ * regardless of mode, so gate only in modes where Claude could still surface
61
+ * its own prompt.
62
+ *
63
+ * - `bypassPermissions` / `dontAsk` → never prompts → no
64
+ * - `auto` → the classifier decides outside the settings files; the rule
65
+ * predictor cannot see it, so every unlisted call would
66
+ * false-hold. The rare genuine prompt still arrives as a
67
+ * Notification `permission_prompt` → no
68
+ * - `plan` → tools don't execute (classifier or read-only only) → no
69
+ * - `acceptEdits` → edits + filesystem commands auto-approved, other
70
+ * Bash still prompts → non-edit tools
71
+ * - `default` / unknown → Claude may prompt → yes
72
+ *
73
+ * Unknown/absent mode is treated as `default` to preserve behavior on older
74
+ * Claude versions that don't send the field.
75
+ */
76
+ export declare function shouldGatePreToolUse(permissionMode: string | undefined, tool: string): boolean;
77
+ /** Bash programs Claude Code runs without a prompt in every mode (the
78
+ * documented built-in read-only set plus its obviously read-only kin). Being
79
+ * generous here is the SAFE direction: an entry that Claude actually prompts
80
+ * for costs a missed hold, never a false one. */
81
+ export declare const READ_ONLY_BASH_COMMANDS: readonly string[];
82
+ /** `git <subcommand>` forms that are read-only regardless of arguments. */
83
+ export declare const READ_ONLY_GIT_SUBCOMMANDS: readonly string[];
84
+ /** `git <subcommand>` forms that are read-only only when they carry no
85
+ * arguments or only these flags (`git branch` lists; `git branch x` writes). */
86
+ export declare const READ_ONLY_GIT_LISTING_SUBCOMMANDS: Readonly<Record<string, readonly string[]>>;
87
+ /** Filesystem commands `acceptEdits` mode auto-approves (in-scope paths). */
88
+ export declare const ACCEPT_EDITS_FS_COMMANDS: readonly string[];
89
+ /** Strip leading `VAR=value` assignments and process wrappers so `LANG=C
90
+ * timeout 30 npm test` is matched as `npm test`. Returns the stripped
91
+ * command text (tokens re-joined by single spaces). */
92
+ export declare function stripCommandWrappers(segment: string): string;
93
+ /**
94
+ * Split a compound command on shell operators, quote-aware. Returns `null`
95
+ * when the split is not trustworthy — a heredoc, command substitution, an
96
+ * unbalanced quote, or an operator with nothing after it — in which case
97
+ * Claude Code itself does not split either.
98
+ */
99
+ export declare function splitCompoundCommand(command: string): string[] | null;
100
+ /**
101
+ * Does one Bash rule spec match one command text? Implements the documented
102
+ * wildcard rules: `*` matches any text including spaces; a trailing ` *` that
103
+ * is the rule's only wildcard also matches the bare command; the legacy `:*`
104
+ * suffix is an alias for ` *`; no wildcard means exact match.
105
+ */
106
+ export declare function bashRuleMatches(spec: string, command: string): boolean;
107
+ /** `*`-only glob over code points. Iterative two-pointer form so a rule with
108
+ * several wildcards cannot go exponential on a long command. */
109
+ export declare function globMatch(pattern: string, text: string): boolean;
110
+ export interface ParsedPermissionRule {
111
+ tool: string;
112
+ spec?: string;
113
+ }
114
+ /** `Tool` or `Tool(spec)` → parts; anything else → null. */
115
+ export declare function parsePermissionRule(rule: string): ParsedPermissionRule | null;
116
+ /** Rules merged from every settings file Claude reads for a cwd. `null`
117
+ * ("unknown") when any existing file failed to parse — the daemon can no
118
+ * longer trust its picture of the allowlist and must hold nothing. */
119
+ export interface MergedPermissionRules {
120
+ allow: string[];
121
+ deny: string[];
122
+ ask: string[];
123
+ }
124
+ /** Loose match (allow/deny direction): a tool-name match with ANY spec counts
125
+ * for tools whose spec grammar we do not replicate (paths, domains); Bash
126
+ * specs are compared precisely against the (wrapper-stripped) segment. */
127
+ export declare function ruleMatchesLoose(rule: ParsedPermissionRule, tool: string, segment: string | undefined): boolean;
128
+ /** Strict match (ask direction): only patterns we can evaluate exactly, since
129
+ * an ask match CAUSES a hold. */
130
+ export declare function ruleMatchesStrict(rule: ParsedPermissionRule, tool: string, segment: string | undefined): boolean;
131
+ /**
132
+ * Is this one (already split) segment in Claude Code's built-in read-only set,
133
+ * so it runs without a prompt in every mode?
134
+ */
135
+ export declare function isBuiltinReadOnlyCommand(segment: string): boolean;
136
+ /** Is this segment one of the filesystem commands `acceptEdits` auto-approves? */
137
+ export declare function isAcceptEditsFsCommand(segment: string): boolean;
138
+ export type PermissionRuleVerdict = 'allow' | 'deny' | 'ask' | 'none' | 'unknown';
139
+ /**
140
+ * Predict Claude's permission-RULE verdict for one tool call (rules only; the
141
+ * mode and built-in sets are applied by `predictPreToolUseHold`).
142
+ * 'deny' → a deny rule may match: Claude auto-denies — don't hold
143
+ * 'allow' → allow rules cover every subcommand — don't hold
144
+ * 'ask' → an ask rule definitely matches — hold-eligible
145
+ * 'none' → no rule decides — default behavior for the tool applies
146
+ * 'unknown' → settings unreadable — don't hold
147
+ */
148
+ export declare function evaluatePermissionRules(tool: string, command: string | undefined, rules: MergedPermissionRules | null, opts?: {
149
+ permissionMode?: string;
150
+ }): PermissionRuleVerdict;
151
+ export interface PreToolUseHoldInput {
152
+ tool: string;
153
+ toolInput?: Record<string, unknown> | undefined;
154
+ permissionMode?: string | undefined;
155
+ /** Merged rules, or `null` when unreadable. */
156
+ rules: MergedPermissionRules | null;
157
+ }
158
+ export interface PreToolUseHoldPrediction {
159
+ hold: boolean;
160
+ reason: string;
161
+ }
162
+ /**
163
+ * The stateless half of the device-approval gate: given the tool, its input,
164
+ * the session's mode and the merged rules, would Claude Code genuinely prompt?
165
+ * The daemons layer session state on top (connected clients, one held gate
166
+ * per session, learned auto-approvals).
167
+ */
168
+ export declare function predictPreToolUseHold(input: PreToolUseHoldInput): PreToolUseHoldPrediction;
169
+ /** Bash signature = first two command tokens (the granularity of Claude's own
170
+ * "always allow `git push`"-style session approvals); other tools = tool name. */
171
+ export declare function gateSignature(tool: string, toolInput: Record<string, unknown> | undefined): string;
172
+ /**
173
+ * How long after an undecided gate release a PostToolUse still teaches the
174
+ * daemon "Claude auto-approved this signature". A `permission_prompt`
175
+ * Notification in between clears the pending release, so the window bounds
176
+ * only how long a slow TOOL may take — it was 8 s, and a `curl` fetching a
177
+ * web page routinely exceeds that, so the same `curl -sL` signature was held
178
+ * on every batch of one session (measured 2026-09-05).
179
+ */
180
+ export declare const GATE_LEARN_WINDOW_MS: number;
181
+ //# sourceMappingURL=claude-permission-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-permission-rules.d.ts","sourceRoot":"","sources":["../src/claude-permission-rules.ts"],"names":[],"mappings":"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"}