@intutic/sync-daemon 1.9.0 → 1.10.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 (200) hide show
  1. package/README.md +2 -2
  2. package/dist/agentReporter.d.ts +205 -0
  3. package/dist/agentReporter.d.ts.map +1 -0
  4. package/dist/agentReporter.js +394 -0
  5. package/dist/agentReporter.js.map +1 -0
  6. package/dist/configReader.d.ts +39 -2
  7. package/dist/configReader.d.ts.map +1 -1
  8. package/dist/configReader.js +56 -2
  9. package/dist/configReader.js.map +1 -1
  10. package/dist/configWriter.d.ts +51 -1
  11. package/dist/configWriter.d.ts.map +1 -1
  12. package/dist/configWriter.js +490 -63
  13. package/dist/configWriter.js.map +1 -1
  14. package/dist/harness/antigravityHooks.d.ts.map +1 -1
  15. package/dist/harness/antigravityHooks.js +33 -55
  16. package/dist/harness/antigravityHooks.js.map +1 -1
  17. package/dist/harness/claudeCodeHooks.d.ts +47 -13
  18. package/dist/harness/claudeCodeHooks.d.ts.map +1 -1
  19. package/dist/harness/claudeCodeHooks.js +323 -55
  20. package/dist/harness/claudeCodeHooks.js.map +1 -1
  21. package/dist/harness/claudeDesktopHooks.d.ts.map +1 -1
  22. package/dist/harness/claudeDesktopHooks.js +35 -48
  23. package/dist/harness/claudeDesktopHooks.js.map +1 -1
  24. package/dist/harness/clineHooks.d.ts.map +1 -1
  25. package/dist/harness/clineHooks.js +42 -34
  26. package/dist/harness/clineHooks.js.map +1 -1
  27. package/dist/harness/codexHooks.d.ts +36 -0
  28. package/dist/harness/codexHooks.d.ts.map +1 -0
  29. package/dist/harness/codexHooks.js +227 -0
  30. package/dist/harness/codexHooks.js.map +1 -0
  31. package/dist/harness/continueHooks.d.ts +45 -5
  32. package/dist/harness/continueHooks.d.ts.map +1 -1
  33. package/dist/harness/continueHooks.js +225 -5
  34. package/dist/harness/continueHooks.js.map +1 -1
  35. package/dist/harness/cursorHooks.d.ts +31 -0
  36. package/dist/harness/cursorHooks.d.ts.map +1 -1
  37. package/dist/harness/cursorHooks.js +78 -49
  38. package/dist/harness/cursorHooks.js.map +1 -1
  39. package/dist/harness/dshHooks.d.ts +198 -0
  40. package/dist/harness/dshHooks.d.ts.map +1 -0
  41. package/dist/harness/dshHooks.js +569 -0
  42. package/dist/harness/dshHooks.js.map +1 -0
  43. package/dist/harness/gateBody.d.ts +422 -0
  44. package/dist/harness/gateBody.d.ts.map +1 -0
  45. package/dist/harness/gateBody.js +1816 -0
  46. package/dist/harness/gateBody.js.map +1 -0
  47. package/dist/harness/gateKind.d.ts +164 -0
  48. package/dist/harness/gateKind.d.ts.map +1 -0
  49. package/dist/harness/gateKind.js +143 -0
  50. package/dist/harness/gateKind.js.map +1 -0
  51. package/dist/harness/githubCopilotHooks.d.ts +54 -0
  52. package/dist/harness/githubCopilotHooks.d.ts.map +1 -0
  53. package/dist/harness/githubCopilotHooks.js +218 -0
  54. package/dist/harness/githubCopilotHooks.js.map +1 -0
  55. package/dist/harness/gooseHooks.d.ts.map +1 -1
  56. package/dist/harness/gooseHooks.js +67 -37
  57. package/dist/harness/gooseHooks.js.map +1 -1
  58. package/dist/harness/grokHooks.d.ts +77 -0
  59. package/dist/harness/grokHooks.d.ts.map +1 -0
  60. package/dist/harness/grokHooks.js +350 -0
  61. package/dist/harness/grokHooks.js.map +1 -0
  62. package/dist/harness/hermesHooks.d.ts.map +1 -1
  63. package/dist/harness/hermesHooks.js +26 -55
  64. package/dist/harness/hermesHooks.js.map +1 -1
  65. package/dist/harness/holdRedaction.d.ts +69 -0
  66. package/dist/harness/holdRedaction.d.ts.map +1 -0
  67. package/dist/harness/holdRedaction.js +211 -0
  68. package/dist/harness/holdRedaction.js.map +1 -0
  69. package/dist/harness/jetbrainsXmlConfig.d.ts +51 -0
  70. package/dist/harness/jetbrainsXmlConfig.d.ts.map +1 -0
  71. package/dist/harness/jetbrainsXmlConfig.js +151 -0
  72. package/dist/harness/jetbrainsXmlConfig.js.map +1 -0
  73. package/dist/harness/mcpAutoWrite.d.ts +100 -3
  74. package/dist/harness/mcpAutoWrite.d.ts.map +1 -1
  75. package/dist/harness/mcpAutoWrite.js +712 -90
  76. package/dist/harness/mcpAutoWrite.js.map +1 -1
  77. package/dist/harness/museHooks.d.ts +53 -0
  78. package/dist/harness/museHooks.d.ts.map +1 -0
  79. package/dist/harness/museHooks.js +273 -0
  80. package/dist/harness/museHooks.js.map +1 -0
  81. package/dist/harness/n8nHooks.d.ts +25 -9
  82. package/dist/harness/n8nHooks.d.ts.map +1 -1
  83. package/dist/harness/n8nHooks.js +174 -9
  84. package/dist/harness/n8nHooks.js.map +1 -1
  85. package/dist/harness/openCodeHooks.d.ts +93 -0
  86. package/dist/harness/openCodeHooks.d.ts.map +1 -0
  87. package/dist/harness/openCodeHooks.js +248 -0
  88. package/dist/harness/openCodeHooks.js.map +1 -0
  89. package/dist/harness/openWebuiHooks.d.ts.map +1 -1
  90. package/dist/harness/openWebuiHooks.js +56 -11
  91. package/dist/harness/openWebuiHooks.js.map +1 -1
  92. package/dist/harness/openclawHooks.d.ts.map +1 -1
  93. package/dist/harness/openclawHooks.js +30 -54
  94. package/dist/harness/openclawHooks.js.map +1 -1
  95. package/dist/harness/openhandsHooks.d.ts.map +1 -1
  96. package/dist/harness/openhandsHooks.js +35 -41
  97. package/dist/harness/openhandsHooks.js.map +1 -1
  98. package/dist/harness/piHooks.d.ts.map +1 -1
  99. package/dist/harness/piHooks.js +31 -58
  100. package/dist/harness/piHooks.js.map +1 -1
  101. package/dist/harness/protectedPaths.d.ts +353 -0
  102. package/dist/harness/protectedPaths.d.ts.map +1 -0
  103. package/dist/harness/protectedPaths.js +805 -0
  104. package/dist/harness/protectedPaths.js.map +1 -0
  105. package/dist/harness/rooCodeHooks.d.ts.map +1 -1
  106. package/dist/harness/rooCodeHooks.js +34 -48
  107. package/dist/harness/rooCodeHooks.js.map +1 -1
  108. package/dist/harness/windsurfHooks.d.ts +72 -0
  109. package/dist/harness/windsurfHooks.d.ts.map +1 -1
  110. package/dist/harness/windsurfHooks.js +172 -58
  111. package/dist/harness/windsurfHooks.js.map +1 -1
  112. package/dist/harness/windsurfJetBrainsProxy.d.ts +78 -0
  113. package/dist/harness/windsurfJetBrainsProxy.d.ts.map +1 -0
  114. package/dist/harness/windsurfJetBrainsProxy.js +159 -0
  115. package/dist/harness/windsurfJetBrainsProxy.js.map +1 -0
  116. package/dist/hashReporter.js +1 -1
  117. package/dist/hashReporter.js.map +1 -1
  118. package/dist/index.d.ts +12 -6
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +14 -6
  121. package/dist/index.js.map +1 -1
  122. package/dist/integrityStore.d.ts +0 -8
  123. package/dist/integrityStore.d.ts.map +1 -1
  124. package/dist/integrityStore.js +6 -29
  125. package/dist/integrityStore.js.map +1 -1
  126. package/dist/lib/approvedBypasses.d.ts +76 -0
  127. package/dist/lib/approvedBypasses.d.ts.map +1 -0
  128. package/dist/lib/approvedBypasses.js +140 -0
  129. package/dist/lib/approvedBypasses.js.map +1 -0
  130. package/dist/lib/complianceProbes.d.ts.map +1 -1
  131. package/dist/lib/complianceProbes.js +5 -0
  132. package/dist/lib/complianceProbes.js.map +1 -1
  133. package/dist/lib/decisionsDigest.d.ts +99 -0
  134. package/dist/lib/decisionsDigest.d.ts.map +1 -0
  135. package/dist/lib/decisionsDigest.js +199 -0
  136. package/dist/lib/decisionsDigest.js.map +1 -0
  137. package/dist/lib/egressPolicy.d.ts +69 -0
  138. package/dist/lib/egressPolicy.d.ts.map +1 -0
  139. package/dist/lib/egressPolicy.js +126 -0
  140. package/dist/lib/egressPolicy.js.map +1 -0
  141. package/dist/lib/gitWorktrees.d.ts +140 -0
  142. package/dist/lib/gitWorktrees.d.ts.map +1 -0
  143. package/dist/lib/gitWorktrees.js +191 -0
  144. package/dist/lib/gitWorktrees.js.map +1 -0
  145. package/dist/lib/policySnapshot.d.ts +224 -0
  146. package/dist/lib/policySnapshot.d.ts.map +1 -0
  147. package/dist/lib/policySnapshot.js +637 -0
  148. package/dist/lib/policySnapshot.js.map +1 -0
  149. package/dist/lib/processPoller.d.ts +44 -0
  150. package/dist/lib/processPoller.d.ts.map +1 -1
  151. package/dist/lib/processPoller.js +176 -1
  152. package/dist/lib/processPoller.js.map +1 -1
  153. package/dist/lib/runtimeEnv.d.ts +8 -0
  154. package/dist/lib/runtimeEnv.d.ts.map +1 -1
  155. package/dist/lib/runtimeEnv.js +3 -0
  156. package/dist/lib/runtimeEnv.js.map +1 -1
  157. package/dist/localTrajectoryHeuristics.d.ts +51 -0
  158. package/dist/localTrajectoryHeuristics.d.ts.map +1 -0
  159. package/dist/localTrajectoryHeuristics.js +90 -0
  160. package/dist/localTrajectoryHeuristics.js.map +1 -0
  161. package/dist/sessionReporter.d.ts +70 -0
  162. package/dist/sessionReporter.d.ts.map +1 -0
  163. package/dist/sessionReporter.js +140 -0
  164. package/dist/sessionReporter.js.map +1 -0
  165. package/dist/skillWriter.d.ts +1 -1
  166. package/dist/skillWriter.d.ts.map +1 -1
  167. package/dist/skillWriter.js +6 -3
  168. package/dist/skillWriter.js.map +1 -1
  169. package/dist/syncLoop.d.ts +105 -3
  170. package/dist/syncLoop.d.ts.map +1 -1
  171. package/dist/syncLoop.js +397 -65
  172. package/dist/syncLoop.js.map +1 -1
  173. package/dist/trajectoryMonitor.d.ts +2 -0
  174. package/dist/trajectoryMonitor.d.ts.map +1 -1
  175. package/dist/trajectoryMonitor.js +57 -0
  176. package/dist/trajectoryMonitor.js.map +1 -1
  177. package/dist/watcher/driftWatcher.d.ts.map +1 -1
  178. package/dist/watcher/driftWatcher.js +12 -3
  179. package/dist/watcher/driftWatcher.js.map +1 -1
  180. package/dist/watcher/settingsGuard.d.ts +23 -0
  181. package/dist/watcher/settingsGuard.d.ts.map +1 -1
  182. package/dist/watcher/settingsGuard.js +202 -17
  183. package/dist/watcher/settingsGuard.js.map +1 -1
  184. package/package.json +37 -6
  185. package/dist/brainIndexer.d.ts +0 -51
  186. package/dist/brainIndexer.d.ts.map +0 -1
  187. package/dist/brainIndexer.js +0 -148
  188. package/dist/brainIndexer.js.map +0 -1
  189. package/dist/harness/cursorHooksJson.d.ts +0 -29
  190. package/dist/harness/cursorHooksJson.d.ts.map +0 -1
  191. package/dist/harness/cursorHooksJson.js +0 -130
  192. package/dist/harness/cursorHooksJson.js.map +0 -1
  193. package/dist/harness/gooseHooksWriter.d.ts +0 -27
  194. package/dist/harness/gooseHooksWriter.d.ts.map +0 -1
  195. package/dist/harness/gooseHooksWriter.js +0 -147
  196. package/dist/harness/gooseHooksWriter.js.map +0 -1
  197. package/dist/harness/openhandsHooksWriter.d.ts +0 -23
  198. package/dist/harness/openhandsHooksWriter.d.ts.map +0 -1
  199. package/dist/harness/openhandsHooksWriter.js +0 -146
  200. package/dist/harness/openhandsHooksWriter.js.map +0 -1
package/README.md CHANGED
@@ -15,7 +15,7 @@ fetch config → write harness files → compute hashes → report drift
15
15
  On each sync cycle the daemon:
16
16
 
17
17
  1. **Fetches** the latest SOP configuration from the control plane
18
- 2. **Writes** harness-specific config files using 18 format-aware config writers
18
+ 2. **Writes** harness-specific config files using 19 format-aware config writers
19
19
  3. **Computes** content hashes for drift detection
20
20
  4. **Reports** any detected drift back to the control plane
21
21
 
@@ -23,7 +23,7 @@ On each sync cycle the daemon:
23
23
 
24
24
  ### Config Writers
25
25
 
26
- 18 harness-specific config writers that translate governance SOPs into native configuration formats (YAML, JSON, TOML, Markdown, environment variables).
26
+ Harness-specific config writers (one module per harness under `src/harness/`) that translate governance SOPs into native configuration formats (YAML, JSON, TOML, Markdown, environment variables); most of them emit blocking pre-tool gates. The authoritative list of which harness gets which gate shape is `src/harness/gateKind.ts`, and `__tests__/harness/gateRegistry.ts` exercises every generated gate — counts are not repeated here because they drifted every time a harness was added.
27
27
 
28
28
  ### Atomic Writes
29
29
 
@@ -0,0 +1,205 @@
1
+ /**
2
+ * agentReporter.ts — register the workspace's agents with the control plane.
3
+ *
4
+ * Each detected harness is a durable agent identity. On the sync loop, the
5
+ * daemon collects the facets it can see locally — the configured guardrails,
6
+ * the role SOPs on disk, the skills bundled into the workspace, the MCP servers
7
+ * declared in the harness config, and the budget tier — and reports them to
8
+ * `POST /api/v1/agents/report`. The control plane rescores posture on each
9
+ * report, so the dashboard ring stays live.
10
+ *
11
+ * The daemon only reports what is locally observable; the control plane owns
12
+ * anything requiring cross-session state (agent-to-agent links from session
13
+ * parentage, spend actuals).
14
+ *
15
+ * @module
16
+ */
17
+ import { type HarnessType } from '@intutic/shared-types';
18
+ /** Live egress-enforcement status read from the proxy's own diagnostic endpoint. */
19
+ export interface EgressFacet {
20
+ mode: string;
21
+ denied: number;
22
+ would_deny: number;
23
+ }
24
+ /**
25
+ * Summary of the proxy's last scheduled guard-liveness probe run
26
+ * (`GET /intutic/probes`, Wave 6.1 audit-remediation). `ranAt` is the Unix
27
+ * timestamp the *scheduled loop* recorded, not when this fetch ran — a dead
28
+ * loop shows up here as a timestamp that stops advancing, not a fresh
29
+ * "just ran" answer every cycle.
30
+ */
31
+ export interface GuardProbesFacet {
32
+ total: number;
33
+ failed: number;
34
+ ranAt: number;
35
+ /** probe_id of every failing probe, capped at 10 — enough to act on
36
+ * without turning this into an unbounded transcript. */
37
+ failing: string[];
38
+ }
39
+ interface AgentFacets {
40
+ guardrails: {
41
+ dlp: boolean;
42
+ wasm_rules: number;
43
+ /**
44
+ * True only when this harness's gate mechanism is `'hook'` (an on-disk
45
+ * file the daemon writes and verified existence of) — kept for older
46
+ * control-plane deployments that read this boolean directly. `false` for
47
+ * `gateKind: 'sdk'` is NOT "this harness is unprotected"; see
48
+ * `gate_kind` below and `harness/gateKind.ts`'s module doc. Previously
49
+ * hardcoded `true` for every harness regardless of mechanism.
50
+ */
51
+ hook_gate: boolean;
52
+ /** How this harness's tool calls get gated — see `harness/gateKind.ts`. */
53
+ gate_kind: import('./harness/gateKind.js').GateKind;
54
+ pcas: boolean;
55
+ /** Present when the local proxy answered GET /intutic/egress (LLD #63 §4). */
56
+ egress?: EgressFacet;
57
+ };
58
+ sops: Array<{
59
+ sop_id: string;
60
+ name: string;
61
+ enforced: boolean;
62
+ }>;
63
+ budgets: {
64
+ tier?: string;
65
+ };
66
+ mcp_tools: Array<{
67
+ server: string;
68
+ harness: string;
69
+ transport: string;
70
+ wrapped: boolean;
71
+ }>;
72
+ skills: Array<{
73
+ name: string;
74
+ source: string;
75
+ /** Whether `scanSkillContent` actually ran against this skill's
76
+ * `SKILL.md`. `false` on a read failure — never omitted, and never
77
+ * paired with `clean: true`; see `collectSkills` below. */
78
+ scanned: boolean;
79
+ /** Only meaningful when `scanned` is `true`. `false` means the content
80
+ * scan found at least one pattern match (report-only — see
81
+ * `packages/shared-types/src/skillScan.ts`'s doc comment; nothing here
82
+ * blocks or modifies the skill). */
83
+ clean: boolean;
84
+ /** Count of findings when scanned and not clean; `0` when scanned+clean
85
+ * or when unscanned (there is nothing to count). */
86
+ findingsCount: number;
87
+ /**
88
+ * Bundled-script enumeration for this skill (TD-356, Phase S2) — files
89
+ * alongside `SKILL.md` inside the same skill directory, discovered by
90
+ * the same bounded, symlink-skipping walk `discoverSkillBundledFiles`
91
+ * (`tools/cli/src/commands/skill.ts`) uses, and content-scanned via
92
+ * `scanScriptContent` when a recognized language and within
93
+ * `MAX_SCRIPT_SCAN_BYTES`. Omitted (not `{total: 0, ...}`) when the
94
+ * skill has no bundled files at all — `agentPosture.ts`'s `skills`
95
+ * scorer treats an absent facet as "nothing to say," not as a finding.
96
+ */
97
+ scripts?: {
98
+ /** Every bundled file the walk found, scanned or not. */
99
+ total: number;
100
+ /** How many of `total` were actually content-scanned — excludes
101
+ * unreadable files, files over the byte cap (refused, not skipped),
102
+ * and files whose language `detectScriptLanguage` could not
103
+ * determine. */
104
+ scanned: number;
105
+ /** How many of `scanned` came back with at least one finding. */
106
+ flagged: number;
107
+ };
108
+ /**
109
+ * sha256 of the `SKILL.md` content this row describes (Phase S5,
110
+ * TD-357) — lets `services/control-plane/src/routes/agents.ts` look up
111
+ * a previously-judged semantic verdict
112
+ * (`services/semanticSkillAnalysisService.ts`'s `skills:semantic:*`
113
+ * Valkey entry) keyed by the exact content this cycle read, without this
114
+ * daemon ever transmitting the content itself over `/api/v1/agents/report`
115
+ * — only the CLI's `/skills/report` path (opt-in,
116
+ * `semanticSkillAnalysisEnabled`) does that. Absent when `SKILL.md`
117
+ * could not be read.
118
+ */
119
+ sha256?: string;
120
+ }>;
121
+ loops: {
122
+ configured: boolean;
123
+ };
124
+ harness: {
125
+ type: string;
126
+ config_synced: boolean;
127
+ };
128
+ memory: Array<{
129
+ provider: string;
130
+ configured: boolean;
131
+ }>;
132
+ /**
133
+ * Present only when the local proxy answered `GET /intutic/probes`. A
134
+ * sibling of `guardrails`, not a member of it — `guardrails` already names
135
+ * one boolean/count per guard mechanism (dlp, wasm_rules, hook_gate, pcas,
136
+ * egress); guard-liveness is a different axis (did the loaded guards prove
137
+ * themselves against a live probe, on a schedule) and collapsing it into
138
+ * `guardrails` would make `hasOwnProperty` checks there ambiguous between
139
+ * "this guard exists" and "this guard is alive". Absence here (vs. a
140
+ * present-but-empty facet) is itself meaningful to `agentPosture.ts`: no
141
+ * report means `not_enforced`, never a silent pass.
142
+ */
143
+ guardProbes?: GuardProbesFacet;
144
+ }
145
+ export interface AgentReport {
146
+ agentKey: string;
147
+ displayName: string;
148
+ harnessType: string;
149
+ agentRole: string;
150
+ facets: AgentFacets;
151
+ }
152
+ /**
153
+ * Read the local proxy's egress-enforcement status (LLD #63 §4). The proxy
154
+ * exposes `{mode, denied, would_deny}` at `GET /intutic/egress`, but nothing
155
+ * plumbed those counters off the machine — this is the wiring that carries them
156
+ * up so an egress denial is visible in the dashboard, not just the proxy log.
157
+ * Best-effort: an unreachable or non-managed proxy simply omits the facet.
158
+ */
159
+ export declare function fetchEgressStatus(): Promise<EgressFacet | null>;
160
+ /**
161
+ * Read the local proxy's last scheduled guard-liveness probe run
162
+ * (`GET /intutic/probes`, loopback-only — this must run on the same machine
163
+ * as the proxy, exactly like `fetchEgressStatus` above). Best-effort: an
164
+ * unreachable proxy, a 403 (non-loopback — should not happen here), or a 503
165
+ * (suite hasn't run yet, the narrow window right after proxy start) all
166
+ * simply omit the facet rather than reporting a false pass.
167
+ */
168
+ export declare function fetchGuardProbes(): Promise<GuardProbesFacet | null>;
169
+ /**
170
+ * Read the local proxy's process-lifetime instance id (`GET /intutic/instance`,
171
+ * loopback-only like the two probes above; TD-231, Wave 5.6). The control
172
+ * plane derives one `agent_sessions` row per (workspace, harness, instance)
173
+ * for the traces that proxy publishes; knowing the id lets the daemon register
174
+ * that same row with the workspace's git/task context instead of opening a
175
+ * separate `ses_` session the traces never join.
176
+ *
177
+ * Returns `null` — and the caller falls back to a `ses_` session — for an
178
+ * unreachable or non-managed proxy, a non-OK answer, a malformed body, and for
179
+ * a SHARED GATEWAY (`shared_gateway: true`, or an id that does not carry the
180
+ * local `proxy_` prefix): a gateway pod's row aggregates every developer
181
+ * behind it, so one developer's branch must never be written onto it.
182
+ */
183
+ export declare function fetchLocalProxyInstanceId(): Promise<string | null>;
184
+ /**
185
+ * Build a facet report for one harness in the workspace.
186
+ *
187
+ * `dlpEnabled` / `policyEnforced` come from the daemon's known proxy config;
188
+ * the daemon spawns and configures the proxy, so it knows these without a
189
+ * round-trip.
190
+ */
191
+ export declare function collectAgentReport(opts: {
192
+ workspaceRoot: string;
193
+ harnessType: HarnessType;
194
+ agentRole?: string;
195
+ configSynced: boolean;
196
+ dlpEnabled: boolean;
197
+ policyEnforced: boolean;
198
+ budgetTier?: string;
199
+ /** Workspace policy: may local vaults feed /fix? Defaults to allowed. */
200
+ allowLocalVaults?: boolean;
201
+ }): Promise<AgentReport>;
202
+ /** POST a report to the control plane. Non-fatal on failure (mirrors reportStatus). */
203
+ export declare function reportAgent(controlPlaneUrl: string, apiKey: string, workspaceId: string, report: AgentReport): Promise<void>;
204
+ export {};
205
+ //# sourceMappingURL=agentReporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentReporter.d.ts","sourceRoot":"","sources":["../src/agentReporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,394 @@
1
+ /**
2
+ * agentReporter.ts — register the workspace's agents with the control plane.
3
+ *
4
+ * Each detected harness is a durable agent identity. On the sync loop, the
5
+ * daemon collects the facets it can see locally — the configured guardrails,
6
+ * the role SOPs on disk, the skills bundled into the workspace, the MCP servers
7
+ * declared in the harness config, and the budget tier — and reports them to
8
+ * `POST /api/v1/agents/report`. The control plane rescores posture on each
9
+ * report, so the dashboard ring stays live.
10
+ *
11
+ * The daemon only reports what is locally observable; the control plane owns
12
+ * anything requiring cross-session state (agent-to-agent links from session
13
+ * parentage, spend actuals).
14
+ *
15
+ * @module
16
+ */
17
+ import { readFile, readdir, access } from 'node:fs/promises';
18
+ import { join } from 'node:path';
19
+ import { createHash } from 'node:crypto';
20
+ import { newIso } from '@intutic/id';
21
+ import { scanSkillContent, scanScriptContent, detectScriptLanguage, MAX_SKILL_DIR_DEPTH, MAX_FILES_PER_SKILL, MAX_SCRIPT_SCAN_BYTES, } from '@intutic/shared-types';
22
+ import { discoverMcpServers } from './harness/mcpAutoWrite.js';
23
+ import { gateKindForHarness } from './harness/gateKind.js';
24
+ async function exists(p) {
25
+ try {
26
+ await access(p);
27
+ return true;
28
+ }
29
+ catch {
30
+ return false;
31
+ }
32
+ }
33
+ /**
34
+ * Read the local proxy's egress-enforcement status (LLD #63 §4). The proxy
35
+ * exposes `{mode, denied, would_deny}` at `GET /intutic/egress`, but nothing
36
+ * plumbed those counters off the machine — this is the wiring that carries them
37
+ * up so an egress denial is visible in the dashboard, not just the proxy log.
38
+ * Best-effort: an unreachable or non-managed proxy simply omits the facet.
39
+ */
40
+ export async function fetchEgressStatus() {
41
+ // Regex-free trailing-slash trim — CodeQL flags `/\/+$/` as a polynomial
42
+ // pattern even on operator-env input; a loop sidesteps the category.
43
+ let base = process.env.INTUTIC_PROXY_URL ?? 'http://localhost:4000';
44
+ while (base.endsWith('/'))
45
+ base = base.slice(0, -1);
46
+ try {
47
+ const res = await fetch(`${base}/intutic/egress`, { signal: AbortSignal.timeout(2000) });
48
+ if (!res.ok)
49
+ return null;
50
+ const body = (await res.json());
51
+ if (typeof body.mode !== 'string')
52
+ return null;
53
+ return {
54
+ mode: body.mode,
55
+ denied: typeof body.denied === 'number' ? body.denied : 0,
56
+ would_deny: typeof body.would_deny === 'number' ? body.would_deny : 0,
57
+ };
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ }
63
+ /**
64
+ * Read the local proxy's last scheduled guard-liveness probe run
65
+ * (`GET /intutic/probes`, loopback-only — this must run on the same machine
66
+ * as the proxy, exactly like `fetchEgressStatus` above). Best-effort: an
67
+ * unreachable proxy, a 403 (non-loopback — should not happen here), or a 503
68
+ * (suite hasn't run yet, the narrow window right after proxy start) all
69
+ * simply omit the facet rather than reporting a false pass.
70
+ */
71
+ export async function fetchGuardProbes() {
72
+ let base = process.env.INTUTIC_PROXY_URL ?? 'http://localhost:4000';
73
+ while (base.endsWith('/'))
74
+ base = base.slice(0, -1);
75
+ try {
76
+ const res = await fetch(`${base}/intutic/probes`, { signal: AbortSignal.timeout(2000) });
77
+ if (!res.ok)
78
+ return null;
79
+ const body = (await res.json());
80
+ if (typeof body.total !== 'number' || typeof body.failed !== 'number' || typeof body.ran_at !== 'number') {
81
+ return null;
82
+ }
83
+ const probes = Array.isArray(body.probes) ? body.probes : [];
84
+ const failing = probes
85
+ .filter((p) => typeof p === 'object' && p !== null)
86
+ .filter((p) => p.passed === false && typeof p.probe_id === 'string')
87
+ .map((p) => p.probe_id)
88
+ .slice(0, 10);
89
+ return { total: body.total, failed: body.failed, ranAt: body.ran_at, failing };
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ }
95
+ /**
96
+ * Read the local proxy's process-lifetime instance id (`GET /intutic/instance`,
97
+ * loopback-only like the two probes above; TD-231, Wave 5.6). The control
98
+ * plane derives one `agent_sessions` row per (workspace, harness, instance)
99
+ * for the traces that proxy publishes; knowing the id lets the daemon register
100
+ * that same row with the workspace's git/task context instead of opening a
101
+ * separate `ses_` session the traces never join.
102
+ *
103
+ * Returns `null` — and the caller falls back to a `ses_` session — for an
104
+ * unreachable or non-managed proxy, a non-OK answer, a malformed body, and for
105
+ * a SHARED GATEWAY (`shared_gateway: true`, or an id that does not carry the
106
+ * local `proxy_` prefix): a gateway pod's row aggregates every developer
107
+ * behind it, so one developer's branch must never be written onto it.
108
+ */
109
+ export async function fetchLocalProxyInstanceId() {
110
+ let base = process.env.INTUTIC_PROXY_URL ?? 'http://localhost:4000';
111
+ while (base.endsWith('/'))
112
+ base = base.slice(0, -1);
113
+ try {
114
+ const res = await fetch(`${base}/intutic/instance`, { signal: AbortSignal.timeout(2000) });
115
+ if (!res.ok)
116
+ return null;
117
+ const body = (await res.json());
118
+ if (typeof body.proxy_instance_id !== 'string' || body.shared_gateway === true)
119
+ return null;
120
+ return body.proxy_instance_id.startsWith('proxy_') ? body.proxy_instance_id : null;
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ /** Count `.wasm` rules under `~/.intutic/wasm` (best-effort). */
127
+ async function countWasmRules() {
128
+ const dir = join(process.env.HOME ?? '', '.intutic', 'wasm');
129
+ try {
130
+ const entries = await readdir(dir);
131
+ return entries.filter((e) => e.endsWith('.wasm')).length;
132
+ }
133
+ catch {
134
+ return 0;
135
+ }
136
+ }
137
+ /** Role SOPs on disk under `<root>/.intutic/sops`. */
138
+ async function collectSops(workspaceRoot) {
139
+ const dir = join(workspaceRoot, '.intutic', 'sops');
140
+ try {
141
+ const entries = await readdir(dir);
142
+ const out = [];
143
+ for (const file of entries.filter((e) => e.endsWith('.md'))) {
144
+ const body = await readFile(join(dir, file), 'utf8').catch(() => '');
145
+ // An SOP is "enforced" if it declares deny_tools or allow_harnesses.
146
+ const enforced = /deny_tools|allow_harnesses/.test(body);
147
+ out.push({ sop_id: file.replace(/\.md$/, ''), name: file, enforced });
148
+ }
149
+ return out;
150
+ }
151
+ catch {
152
+ return [];
153
+ }
154
+ }
155
+ /**
156
+ * Bounded, symlink-skipping walk of one skill directory's bundled files
157
+ * (siblings of `SKILL.md`), content-scanning each one via `scanScriptContent`
158
+ * when its language is recognized and it is within `MAX_SCRIPT_SCAN_BYTES`.
159
+ *
160
+ * TD-356, Phase S2: mirrors `discoverSkillBundledFiles`
161
+ * (`tools/cli/src/commands/skill.ts`) closely — the exact same caps
162
+ * (`MAX_SKILL_DIR_DEPTH`, `MAX_FILES_PER_SKILL`) and symlink-skip discipline
163
+ * (`Dirent.isSymbolicLink()` checked and skipped outright during `readdir`,
164
+ * never stat-ed or resolved — a symlink inside a skill directory could point
165
+ * outside it, or outside the workspace entirely, turning a bounded walk
166
+ * unbounded) — but is its own implementation, not a shared import. This
167
+ * module has no dependency on `tools/cli`; `collectSkills` already
168
+ * re-implements skill-directory discovery independently of the CLI's
169
+ * `discoverSkillFiles` for the same reason, and this walk follows that same
170
+ * precedent rather than introducing a new cross-package dependency for it.
171
+ *
172
+ * Returns `undefined` (not `{total: 0, scanned: 0, flagged: 0}`) when the
173
+ * skill has no bundled files at all, so `collectSkills` can omit `scripts`
174
+ * entirely for the common case of a skill that is only a `SKILL.md` — see
175
+ * that field's own doc comment on the `AgentFacets['skills']` item type.
176
+ */
177
+ async function collectSkillScripts(skillDir) {
178
+ const files = [];
179
+ async function walk(dir, depth) {
180
+ if (depth > MAX_SKILL_DIR_DEPTH || files.length >= MAX_FILES_PER_SKILL)
181
+ return;
182
+ let entries;
183
+ try {
184
+ entries = await readdir(dir, { withFileTypes: true });
185
+ }
186
+ catch {
187
+ return;
188
+ }
189
+ for (const entry of entries) {
190
+ if (files.length >= MAX_FILES_PER_SKILL)
191
+ return;
192
+ if (entry.isSymbolicLink())
193
+ continue; // never follow — see this function's doc comment
194
+ const full = join(dir, entry.name);
195
+ if (entry.isDirectory()) {
196
+ await walk(full, depth + 1);
197
+ }
198
+ else if (entry.isFile()) {
199
+ if (depth === 0 && entry.name === 'SKILL.md')
200
+ continue;
201
+ files.push(full);
202
+ }
203
+ }
204
+ }
205
+ await walk(skillDir, 0);
206
+ if (files.length === 0)
207
+ return undefined;
208
+ let scanned = 0;
209
+ let flagged = 0;
210
+ for (const filePath of files) {
211
+ let buffer;
212
+ try {
213
+ buffer = await readFile(filePath);
214
+ }
215
+ catch {
216
+ continue; // unreadable — counted in `total`, not `scanned`
217
+ }
218
+ if (buffer.length > MAX_SCRIPT_SCAN_BYTES)
219
+ continue; // refused, not silently skipped or scanned
220
+ const firstLine = buffer.toString('utf8', 0, Math.min(buffer.length, 200)).split('\n')[0];
221
+ const language = detectScriptLanguage(filePath, firstLine);
222
+ if (language === 'unknown')
223
+ continue; // not a script language this scanner understands
224
+ const result = scanScriptContent(buffer.toString('utf8'), language);
225
+ scanned++;
226
+ if (!result.clean)
227
+ flagged++;
228
+ }
229
+ return { total: files.length, scanned, flagged };
230
+ }
231
+ /**
232
+ * Bundled skills under `<root>/.agents/skills/<name>/SKILL.md`, content-
233
+ * scanned via `scanSkillContent` (`@intutic/shared-types`) on every cycle,
234
+ * plus (TD-356, Phase S2) a bounded enumeration of each skill's bundled
235
+ * scripts via `collectSkillScripts`, attached as the `scripts` facet.
236
+ *
237
+ * Report-only, matching `scanSkillContent`'s own doc comment: this function
238
+ * never modifies, blocks, or removes anything — it reads and attaches a
239
+ * verdict for `agentPosture.ts`'s content-aware `skills` scoring to consume.
240
+ *
241
+ * Refusal-not-pass: a `SKILL.md` that cannot be read (permissions, vanished
242
+ * between `readdir` and `readFile`, not a regular file, …) is reported
243
+ * `scanned: false, clean: false` — never `clean: true`, and never silently
244
+ * dropped from the list. An unreadable skill is not a skill the daemon can
245
+ * vouch for, and dropping it would make a workspace's posture score look
246
+ * better than what is actually known. The `scripts` enumeration runs
247
+ * regardless of whether `SKILL.md` itself was readable — a script bundled
248
+ * next to an unreadable `SKILL.md` is still on disk and still a surface to
249
+ * report on.
250
+ */
251
+ async function collectSkills(workspaceRoot) {
252
+ const dir = join(workspaceRoot, '.agents', 'skills');
253
+ let entries;
254
+ try {
255
+ entries = await readdir(dir, { withFileTypes: true });
256
+ }
257
+ catch {
258
+ return [];
259
+ }
260
+ const dirs = entries.filter((e) => e.isDirectory());
261
+ const out = [];
262
+ for (const e of dirs) {
263
+ const skillDir = join(dir, e.name);
264
+ const skillMdPath = join(skillDir, 'SKILL.md');
265
+ const scripts = await collectSkillScripts(skillDir);
266
+ try {
267
+ const content = await readFile(skillMdPath, 'utf8');
268
+ const result = scanSkillContent(content);
269
+ const sha256 = createHash('sha256').update(content, 'utf8').digest('hex');
270
+ out.push({
271
+ name: e.name,
272
+ source: '.agents/skills',
273
+ scanned: true,
274
+ clean: result.clean,
275
+ findingsCount: result.findings.length,
276
+ sha256,
277
+ ...(scripts ? { scripts } : {}),
278
+ });
279
+ }
280
+ catch {
281
+ out.push({
282
+ name: e.name,
283
+ source: '.agents/skills',
284
+ scanned: false,
285
+ clean: false,
286
+ findingsCount: 0,
287
+ ...(scripts ? { scripts } : {}),
288
+ });
289
+ }
290
+ }
291
+ return out;
292
+ }
293
+ /** Local notes vaults (Obsidian/Logseq/Foam) at or above the workspace root. */
294
+ async function detectLocalVaults(workspaceRoot) {
295
+ const markers = ['.obsidian', '.logseq', '.foam'];
296
+ const found = [];
297
+ let dir = workspaceRoot;
298
+ for (let depth = 0; depth < 8; depth++) {
299
+ for (const marker of markers) {
300
+ if (await exists(join(dir, marker))) {
301
+ found.push(marker.slice(1));
302
+ }
303
+ }
304
+ const parent = join(dir, '..');
305
+ if (parent === dir)
306
+ break;
307
+ dir = parent;
308
+ }
309
+ return [...new Set(found)];
310
+ }
311
+ /**
312
+ * MCP servers declared across every harness config format this daemon knows
313
+ * how to parse (see `mcpAutoWrite.ts`'s `discoverMcpServers` — 11 config paths
314
+ * across 9 harnesses), with each server's proxy-wrapped status. Previously
315
+ * this only read 3 hardcoded paths (`.mcp.json`, `.cursor/mcp.json`,
316
+ * `~/.claude.json`) and flattened per declared tool; `discoverMcpServers` is
317
+ * the shared, read-only extraction of the same format knowledge
318
+ * `injectMcpServer` uses to wrap servers, so this reporter's coverage can
319
+ * never silently lag behind what actually gets wrapped.
320
+ */
321
+ async function collectMcpTools(workspaceRoot) {
322
+ return discoverMcpServers(workspaceRoot);
323
+ }
324
+ /**
325
+ * Build a facet report for one harness in the workspace.
326
+ *
327
+ * `dlpEnabled` / `policyEnforced` come from the daemon's known proxy config;
328
+ * the daemon spawns and configures the proxy, so it knows these without a
329
+ * round-trip.
330
+ */
331
+ export async function collectAgentReport(opts) {
332
+ const [wasmRules, sops, skills, mcpTools, vaults, egress, guardProbes] = await Promise.all([
333
+ countWasmRules(),
334
+ collectSops(opts.workspaceRoot),
335
+ collectSkills(opts.workspaceRoot),
336
+ collectMcpTools(opts.workspaceRoot),
337
+ detectLocalVaults(opts.workspaceRoot),
338
+ fetchEgressStatus(),
339
+ fetchGuardProbes(),
340
+ ]);
341
+ const role = opts.agentRole ?? '';
342
+ return {
343
+ agentKey: `${opts.harnessType}:${role || 'default'}`,
344
+ displayName: role ? `${opts.harnessType} (${role})` : opts.harnessType,
345
+ harnessType: opts.harnessType,
346
+ agentRole: role,
347
+ facets: {
348
+ guardrails: {
349
+ dlp: opts.dlpEnabled,
350
+ wasm_rules: wasmRules,
351
+ // Computed per-harness rather than hardcoded true — see gateKind.ts's
352
+ // module doc for why "the daemon writes the hook gate for every
353
+ // harness it supports" was never actually true (langgraph, aider).
354
+ hook_gate: gateKindForHarness(opts.harnessType) === 'hook',
355
+ gate_kind: gateKindForHarness(opts.harnessType),
356
+ pcas: opts.policyEnforced,
357
+ // Present only when the local proxy answered; an egress denial thus
358
+ // becomes visible in the dashboard, not just the proxy's own log.
359
+ ...(egress ? { egress } : {}),
360
+ },
361
+ sops,
362
+ budgets: { tier: opts.budgetTier },
363
+ mcp_tools: mcpTools,
364
+ skills,
365
+ loops: { configured: false }, // set by the loops feature when a run is active
366
+ harness: { type: opts.harnessType, config_synced: opts.configSynced },
367
+ // Visibility, not content: which vault kinds exist near the workspace,
368
+ // and whether workspace policy lets them feed /fix. Note names/content
369
+ // never leave the machine.
370
+ memory: opts.allowLocalVaults === false
371
+ ? []
372
+ : vaults.map((kind) => ({ provider: `local-vault:${kind}`, configured: true })),
373
+ ...(guardProbes ? { guardProbes } : {}),
374
+ },
375
+ };
376
+ }
377
+ /** POST a report to the control plane. Non-fatal on failure (mirrors reportStatus). */
378
+ export async function reportAgent(controlPlaneUrl, apiKey, workspaceId, report) {
379
+ try {
380
+ const res = await fetch(`${controlPlaneUrl}/api/v1/agents/report`, {
381
+ method: 'POST',
382
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` },
383
+ body: JSON.stringify({ ...report, reportedAt: newIso() }),
384
+ signal: AbortSignal.timeout(15_000),
385
+ });
386
+ if (!res.ok) {
387
+ console.warn(`[sync-daemon] reportAgent failed for ${report.agentKey}: ${res.status}`);
388
+ }
389
+ }
390
+ catch (err) {
391
+ console.warn(`[sync-daemon] reportAgent error for ${report.agentKey}:`, err instanceof Error ? err.message : err);
392
+ }
393
+ }
394
+ //# sourceMappingURL=agentReporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentReporter.js","sourceRoot":"","sources":["../src/agentReporter.ts"],"names":[],"mappings":"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"}