tmux-ide 2.9.0-beta.19 → 2.9.0-beta.21

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 (90) hide show
  1. package/bin/cli.js +1979 -783
  2. package/package.json +4 -2
  3. package/packages/contracts/src/__tests__/daemon-wire.test.ts +32 -0
  4. package/packages/contracts/src/daemon-events.ts +12 -12
  5. package/packages/contracts/src/daemon-wire.ts +30 -0
  6. package/packages/daemon/dist/command-center/agent-status-watch.js +9 -2
  7. package/packages/daemon/dist/command-center/diagnostics.js +65 -0
  8. package/packages/daemon/dist/command-center/log-stream.js +9 -0
  9. package/packages/daemon/dist/command-center/resources/fleet-preview-route.js +22 -6
  10. package/packages/daemon/dist/command-center/server.js +7 -0
  11. package/packages/daemon/dist/doctor.js +62 -0
  12. package/packages/daemon/dist/lib/__tests__/installed-recovery-fixture.js +400 -0
  13. package/packages/daemon/dist/lib/app-config.js +4 -2
  14. package/packages/daemon/dist/lib/canonical-daemon.js +1 -0
  15. package/packages/daemon/dist/lib/daemon-embed.js +24 -0
  16. package/packages/daemon/dist/lib/daemon-provenance.js +575 -0
  17. package/packages/daemon/dist/lib/headless-daemon.js +1 -0
  18. package/packages/daemon/dist/lib/log-sanitize.js +199 -0
  19. package/packages/daemon/dist/lib/log.js +123 -13
  20. package/packages/daemon/dist/lib/soak-diagnostics.js +124 -0
  21. package/packages/daemon/dist/lib/soak-verdict.js +472 -0
  22. package/packages/daemon/dist/lib/terminal-host-color.js +33 -0
  23. package/packages/daemon/dist/lib/tmux-external-interaction-observer.js +187 -39
  24. package/packages/daemon/dist/lib/tmux-interaction-retention.js +21 -0
  25. package/packages/daemon/dist/lib/workspace-promotion.js +55 -37
  26. package/packages/daemon/dist/terminal/mirror/session-channel.js +2 -1
  27. package/packages/daemon/dist/tui/mirror/automatic-contrast.js +161 -0
  28. package/packages/daemon/dist/tui/mirror/open-tui-workspace-runtime-port.js +9 -3
  29. package/packages/daemon/dist/tui/mirror/pane-surface.jsx +7 -5
  30. package/packages/daemon/dist/tui/mirror/resize-transaction.js +48 -20
  31. package/packages/daemon/dist/tui/mirror/runtime/application-appearance-owner.js +40 -6
  32. package/packages/daemon/dist/tui/mirror/runtime/application-fleet-preview.js +4 -1
  33. package/packages/daemon/dist/tui/mirror/runtime/application-machine-sidebar.jsx +63 -42
  34. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-interaction-controller.js +138 -67
  35. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-palette-owner.js +44 -28
  36. package/packages/daemon/dist/tui/mirror/runtime/application-terminal-workspace.jsx +49 -11
  37. package/packages/daemon/dist/tui/mirror/runtime/semantic-shell-viewport-resize.js +140 -2
  38. package/packages/daemon/dist/tui/mirror/runtime/workspace-terminal-fast-lane.js +3 -1
  39. package/packages/daemon/dist/tui/mirror/semantic-pane-render-source.js +2 -1
  40. package/packages/daemon/dist/tui/mirror/theme.js +4 -31
  41. package/packages/daemon/dist/tui/mirror/workspace/terminal-pane-header.jsx +15 -8
  42. package/packages/daemon/dist/tui/team/wait-receipts.js +112 -33
  43. package/packages/daemon/src/command-center/agent-status-watch.ts +8 -2
  44. package/packages/daemon/src/command-center/diagnostics.ts +75 -0
  45. package/packages/daemon/src/command-center/log-stream.ts +8 -0
  46. package/packages/daemon/src/command-center/resources/fleet-preview-route.ts +27 -5
  47. package/packages/daemon/src/command-center/server.ts +8 -0
  48. package/packages/daemon/src/doctor.ts +70 -0
  49. package/packages/daemon/src/lib/app-config.ts +11 -3
  50. package/packages/daemon/src/lib/canonical-daemon.ts +1 -0
  51. package/packages/daemon/src/lib/daemon-embed.ts +30 -0
  52. package/packages/daemon/src/lib/daemon-provenance.ts +769 -0
  53. package/packages/daemon/src/lib/fleet-preview-model.ts +1 -0
  54. package/packages/daemon/src/lib/headless-daemon.ts +1 -0
  55. package/packages/daemon/src/lib/log-sanitize.ts +248 -0
  56. package/packages/daemon/src/lib/log.ts +165 -14
  57. package/packages/daemon/src/lib/soak-diagnostics.ts +183 -0
  58. package/packages/daemon/src/lib/soak-verdict.ts +785 -0
  59. package/packages/daemon/src/lib/terminal-host-color.ts +43 -0
  60. package/packages/daemon/src/lib/tmux-external-interaction-observer.ts +233 -37
  61. package/packages/daemon/src/lib/tmux-interaction-retention.ts +24 -0
  62. package/packages/daemon/src/lib/workspace-promotion.ts +74 -45
  63. package/packages/daemon/src/terminal/mirror/session-channel.ts +2 -1
  64. package/packages/daemon/src/tui/mirror/automatic-contrast.ts +180 -0
  65. package/packages/daemon/src/tui/mirror/open-tui-workspace-runtime-port.ts +26 -5
  66. package/packages/daemon/src/tui/mirror/pane-surface.tsx +9 -8
  67. package/packages/daemon/src/tui/mirror/resize-transaction.ts +46 -22
  68. package/packages/daemon/src/tui/mirror/runtime/application-appearance-owner.ts +45 -6
  69. package/packages/daemon/src/tui/mirror/runtime/application-fleet-preview.ts +4 -0
  70. package/packages/daemon/src/tui/mirror/runtime/application-fleet-switcher.tsx +2 -1
  71. package/packages/daemon/src/tui/mirror/runtime/application-machine-sidebar.tsx +99 -75
  72. package/packages/daemon/src/tui/mirror/runtime/application-palette-preview.tsx +13 -3
  73. package/packages/daemon/src/tui/mirror/runtime/application-reference-sheet.tsx +125 -0
  74. package/packages/daemon/src/tui/mirror/runtime/application-root-v2.tsx +2 -1
  75. package/packages/daemon/src/tui/mirror/runtime/application-shell-overlays.tsx +199 -157
  76. package/packages/daemon/src/tui/mirror/runtime/application-shell-view.tsx +2 -0
  77. package/packages/daemon/src/tui/mirror/runtime/application-terminal-interaction-controller.ts +148 -69
  78. package/packages/daemon/src/tui/mirror/runtime/application-terminal-palette-owner.ts +55 -28
  79. package/packages/daemon/src/tui/mirror/runtime/application-terminal-workspace.tsx +59 -17
  80. package/packages/daemon/src/tui/mirror/runtime/semantic-shell-viewport-resize.ts +151 -3
  81. package/packages/daemon/src/tui/mirror/runtime/workspace-terminal-fast-lane.ts +3 -1
  82. package/packages/daemon/src/tui/mirror/semantic-pane-render-source.ts +2 -1
  83. package/packages/daemon/src/tui/mirror/theme.ts +4 -39
  84. package/packages/daemon/src/tui/mirror/workspace/terminal-pane-header.tsx +21 -8
  85. package/packages/daemon/src/tui/team/wait-receipts.ts +115 -40
  86. package/packages/daemon-client/src/terminal-fast-lane.test.ts +18 -0
  87. package/packages/daemon-client/src/terminal-fast-lane.ts +7 -2
  88. package/packages/tmux-bridge/src/index.ts +2 -0
  89. package/packages/tmux-bridge/src/runner.test.ts +41 -0
  90. package/packages/tmux-bridge/src/runner.ts +41 -2
@@ -19,6 +19,7 @@ export async function streamBoundedLogs(
19
19
  entries?: number;
20
20
  bytes?: number;
21
21
  writeTimeoutMs?: number;
22
+ heartbeatIntervalMs?: number;
22
23
  },
23
24
  ): Promise<void> {
24
25
  const maxEntries = options.entries ?? 256;
@@ -29,6 +30,7 @@ export async function streamBoundedLogs(
29
30
  let wake: (() => void) | null = null;
30
31
  let unsubscribe = () => {};
31
32
  let timer: ReturnType<typeof setTimeout> | null = null;
33
+ let heartbeatTimer: ReturnType<typeof setInterval> | null = null;
32
34
  let cancelWrite: (() => void) | null = null;
33
35
  const cleanup = () => {
34
36
  if (closed) return;
@@ -38,6 +40,8 @@ export async function streamBoundedLogs(
38
40
  bytes = 0;
39
41
  if (timer) clearTimeout(timer);
40
42
  timer = null;
43
+ if (heartbeatTimer) clearInterval(heartbeatTimer);
44
+ heartbeatTimer = null;
41
45
  wake?.();
42
46
  wake = null;
43
47
  cancelWrite?.();
@@ -67,6 +71,10 @@ export async function streamBoundedLogs(
67
71
  unsubscribe();
68
72
  return;
69
73
  }
74
+ heartbeatTimer = setInterval(() => {
75
+ if (!closed && queue.length === 0 && !push({ event: "heartbeat", data: "keep-alive" })) abort();
76
+ }, options.heartbeatIntervalMs ?? 15_000);
77
+ heartbeatTimer.unref?.();
70
78
  try {
71
79
  // Keep newest bounded history, reserving room for gap/bookmark metadata.
72
80
  const retained: Frame[] = [];
@@ -15,6 +15,7 @@ type Capture = ((
15
15
  liveSessionId: string,
16
16
  signal?: AbortSignal,
17
17
  windowId?: string,
18
+ paneId?: string,
18
19
  ) => Promise<FleetPreviewSnapshot | null>;
19
20
  };
20
21
  const cleanText = (value: string) => stripVTControlCharacters(value).replace(/[^\P{Cc}\n\t]/gu, "");
@@ -26,6 +27,7 @@ export function createFleetPreviewCapture(
26
27
  liveSessionId: string,
27
28
  signal?: AbortSignal,
28
29
  windowId?: string,
30
+ paneId?: string,
29
31
  ): Promise<FleetPreviewSnapshot | null> => {
30
32
  const readSessions = async () => {
31
33
  const raw = await run(
@@ -76,8 +78,14 @@ export function createFleetPreviewCapture(
76
78
  );
77
79
  }
78
80
  const windowRows = rows.filter((row) => /^@\d+$/u.test(row[3] ?? ""));
81
+ const requestedPane = paneId ? windowRows.find((row) => row[0] === paneId) : undefined;
82
+ if (paneId && (!requestedPane || (windowId && requestedPane[3] !== windowId))) return null;
79
83
  const selectedWindowId =
80
- windowId ?? windowRows.find((row) => row[1] === "1")?.[3] ?? windowRows[0]?.[3] ?? null;
84
+ requestedPane?.[3] ??
85
+ windowId ??
86
+ windowRows.find((row) => row[1] === "1")?.[3] ??
87
+ windowRows[0]?.[3] ??
88
+ null;
81
89
  if (windowId && !windowRows.some((row) => row[3] === windowId)) return null;
82
90
  const toWindow = (row: string[]): FleetPreviewWindow => ({
83
91
  id: row[3]!,
@@ -116,7 +124,7 @@ export function createFleetPreviewCapture(
116
124
  }
117
125
  windows.sort((a, b) => a.index - b.index);
118
126
  const candidates = selectedWindowId ? rows.filter((r) => r[3] === selectedWindowId) : rows;
119
- const pane = candidates.find((r) => r[2] === "1")?.[0] ?? candidates[0]?.[0];
127
+ const pane = paneId ?? candidates.find((r) => r[2] === "1")?.[0] ?? candidates[0]?.[0];
120
128
  if (!pane || !/^%\d+$/u.test(pane)) return null;
121
129
  // Passive capture never changes active windows, size, input or terminal ownership.
122
130
  const captured = await run(["capture-pane", "-p", "-t", pane, "-S", "-24"], signal);
@@ -126,6 +134,7 @@ export function createFleetPreviewCapture(
126
134
  return null;
127
135
  return {
128
136
  windows,
137
+ selectedPaneId: pane,
129
138
  selectedWindowId,
130
139
  text: cleanText(captured)
131
140
  .split("\n")
@@ -141,6 +150,10 @@ export function createFleetPreviewCapture(
141
150
  }
142
151
  const requestSchema = z.strictObject({
143
152
  expectedInstanceId: z.uuid(),
153
+ paneId: z
154
+ .string()
155
+ .regex(/^%\d+$/u)
156
+ .optional(),
144
157
  windowId: z
145
158
  .string()
146
159
  .regex(/^@\d+$/u)
@@ -189,10 +202,15 @@ export function mountFleetPreviewRoute(
189
202
  pending = true;
190
203
  try {
191
204
  const signal = AbortSignal.any([c.req.raw.signal, AbortSignal.timeout(1500)]);
192
- if (input.data.windowId && !options.capture.snapshot)
205
+ if ((input.data.windowId || input.data.paneId) && !options.capture.snapshot)
193
206
  return c.json({ error: "Window preview unavailable" }, 503);
194
207
  const snapshot = options.capture.snapshot
195
- ? await options.capture.snapshot(input.data.liveSessionId, signal, input.data.windowId)
208
+ ? await options.capture.snapshot(
209
+ input.data.liveSessionId,
210
+ signal,
211
+ input.data.windowId,
212
+ input.data.paneId,
213
+ )
196
214
  : null;
197
215
  // Older capture providers remain valid for the original text-only contract.
198
216
  const legacy = !options.capture.snapshot
@@ -206,7 +224,11 @@ export function mountFleetPreviewRoute(
206
224
  liveSessionId: input.data.liveSessionId,
207
225
  text,
208
226
  ...(snapshot
209
- ? { windows: snapshot.windows, selectedWindowId: snapshot.selectedWindowId }
227
+ ? {
228
+ windows: snapshot.windows,
229
+ selectedWindowId: snapshot.selectedWindowId,
230
+ selectedPaneId: snapshot.selectedPaneId,
231
+ }
210
232
  : {}),
211
233
  });
212
234
  } catch {
@@ -155,6 +155,7 @@ import { mountWorkspaceResourceRoutes } from "./resources/workspace-resource-rou
155
155
  import { mountFleetResourceRoute } from "./resources/fleet-resource-route.ts";
156
156
  import { mountWorkspaceMissionsRoute } from "./resources/workspace-missions-route.ts";
157
157
  import { ownerAuthorityGate, requireOwnerAuthority } from "./owner-authority.ts";
158
+ import { mountDiagnosticsRoute } from "./diagnostics.ts";
158
159
  import {
159
160
  mountStartupReadinessRoute,
160
161
  type StartupReadinessAttachmentAuthority,
@@ -532,6 +533,13 @@ export function createApp(options: CreateAppOptions = {}): Hono {
532
533
  // Allow cross-origin (Next.js dashboard, Tailscale, etc.)
533
534
  app.use("/*", cors());
534
535
 
536
+ // Owner-only reads use the same early routing boundary as issuance below:
537
+ // remote/project credentials neither authorize nor block the owner bearer.
538
+ mountDiagnosticsRoute(app, {
539
+ daemon: daemonInstanceIdentity,
540
+ ownerToken: options.remoteAccess?.ownerToken ?? null,
541
+ });
542
+
535
543
  // This exact route carries its own owner-only bearer and correlation gate.
536
544
  // Mount it before remote and project auth so a valid host capability is
537
545
  // neither rejected nor confused with any remotely shared user credential.
@@ -9,6 +9,10 @@ import { findCompiledTui, hasDevelopmentTuiSource, isBunAvailable } from "./tui/
9
9
  import { claudeSettingsPath } from "./tui/integrations/claude.ts";
10
10
  import { readNotificationPrefs, resolveNativeMacosNotifierPath } from "./tui/chrome/notify.ts";
11
11
  import { resolveConfig } from "./lib/resolved-config.ts";
12
+ import {
13
+ collectDaemonProvenanceReport,
14
+ type DaemonProvenanceReport,
15
+ } from "./lib/daemon-provenance.ts";
12
16
 
13
17
  interface CheckResult {
14
18
  label: string;
@@ -108,6 +112,55 @@ export function notifierRow(present: boolean): CheckResult {
108
112
  };
109
113
  }
110
114
 
115
+ /**
116
+ * PURE — the "canonical daemon" row from a provenance report. Optional: a
117
+ * machine without a running daemon is healthy; the row exists so triage sees
118
+ * identity, supervisor and the real log destination without a second command.
119
+ */
120
+ export function daemonProvenanceRow(report: DaemonProvenanceReport): CheckResult {
121
+ const label = "canonical daemon";
122
+ const historical = report.logFiles.filter((f) => f.status === "historical").length;
123
+ const suffix = historical
124
+ ? ` — ${historical} historical log file${historical === 1 ? "" : "s"} (see \`tmux-ide daemon info\`)`
125
+ : "";
126
+ const d = report.daemon;
127
+ switch (report.status) {
128
+ case "running":
129
+ return {
130
+ label,
131
+ pass: true,
132
+ detail:
133
+ `running v${d!.productVersion} pid ${d!.pid} (${d!.supervisor ?? "unknown supervisor"}) · ` +
134
+ `logs → ${d!.logDestination}${suffix}`,
135
+ optional: true,
136
+ };
137
+ case "stale-record":
138
+ return {
139
+ label,
140
+ pass: false,
141
+ detail: `record names pid ${d!.pid} (v${d!.productVersion}) but it is not running${suffix}`,
142
+ optional: true,
143
+ };
144
+ case "record-invalid":
145
+ return {
146
+ label,
147
+ pass: false,
148
+ detail: `record invalid (${report.record.status === "invalid" ? report.record.reason : "unknown"})${suffix}`,
149
+ optional: true,
150
+ };
151
+ default:
152
+ return {
153
+ label,
154
+ pass: true,
155
+ detail:
156
+ report.record.status === "reserved"
157
+ ? `not running (reserved for supervisor ${report.record.supervisionId})${suffix}`
158
+ : `not running${suffix}`,
159
+ optional: true,
160
+ };
161
+ }
162
+ }
163
+
111
164
  function check(
112
165
  label: string,
113
166
  fn: () => string,
@@ -328,6 +381,23 @@ export async function doctor({
328
381
  ),
329
382
  );
330
383
 
384
+ // Canonical daemon identity + log provenance (credential-free), so a triage
385
+ // never chases a stale, manually redirected log file.
386
+ checks.push(
387
+ (() => {
388
+ try {
389
+ return daemonProvenanceRow(collectDaemonProvenanceReport());
390
+ } catch (e) {
391
+ return {
392
+ label: "canonical daemon",
393
+ pass: false,
394
+ detail: `provenance unavailable: ${(e as Error).message}`,
395
+ optional: true,
396
+ };
397
+ }
398
+ })(),
399
+ );
400
+
331
401
  // Native branded sender: only when the macOS channel is actually on.
332
402
  if (process.platform === "darwin" && readNotificationPrefs().macos) {
333
403
  checks.push(notifierRow(resolveNativeMacosNotifierPath() !== null));
@@ -84,7 +84,9 @@ export interface AppThemeGlyphs {
84
84
  * reads as one system.
85
85
  */
86
86
  export interface AppTheme {
87
- /** Explicit palette mode or terminal-following mode. Default keeps legacy dark visuals. */
87
+ /** Improve composed app text contrast. Default true. */
88
+ automaticContrast: boolean;
89
+ /** Explicit palette mode or terminal-following mode. Defaults to following the terminal. */
88
90
  mode: ThemeModeSetting;
89
91
  preset?: string;
90
92
  /** Primary/brand accent (default `colour75`). */
@@ -263,7 +265,8 @@ export const DEFAULT_APP_CONFIG: AppConfig = {
263
265
  panels: { explorer: "M-e", changes: "M-g", config: "M-," },
264
266
  },
265
267
  theme: {
266
- mode: "dark",
268
+ automaticContrast: true,
269
+ mode: "system",
267
270
  accent: "colour75",
268
271
  muted: "colour240",
269
272
  fg: "colour250",
@@ -395,7 +398,12 @@ export function parseAppConfig(input: unknown): AppConfig {
395
398
  },
396
399
  },
397
400
  theme: {
398
- mode: pickChoice(theme.mode, ["dark", "light", "system"], D.theme.mode),
401
+ automaticContrast: pickBool(theme.automaticContrast, D.theme.automaticContrast),
402
+ mode: pickChoice(
403
+ theme.mode,
404
+ ["dark", "light", "system"],
405
+ findVisualThemePreset(theme.preset)?.appearance ?? D.theme.mode,
406
+ ),
399
407
  ...(findVisualThemePreset(theme.preset) ? { preset: String(theme.preset) } : {}),
400
408
  accent: pickString(theme.accent, D.theme.accent),
401
409
  muted: pickString(theme.muted, D.theme.muted),
@@ -646,6 +646,7 @@ export function writeCanonicalDaemonInfo(
646
646
  ...(info.environmentId !== undefined ? { environmentId: info.environmentId } : {}),
647
647
  bindHostname: info.bindHostname,
648
648
  authToken: info.authToken,
649
+ ...(info.provenance !== undefined ? { provenance: info.provenance } : {}),
649
650
  };
650
651
  writeFileSync(tmpPath, JSON.stringify(persisted, null, 2) + "\n", {
651
652
  encoding: "utf-8",
@@ -104,6 +104,8 @@ import {
104
104
  } from "./pane-source-credentials.ts";
105
105
  import { setActivationBackend, type ProjectActivationOptions } from "./active-projects.ts";
106
106
  import { readOrMintEnvironmentId } from "./environment-identity.ts";
107
+ import { captureDaemonProvenance } from "./daemon-provenance.ts";
108
+ import { registerLogSecret, setLogIdentity } from "./log.ts";
107
109
  import {
108
110
  canonicalDaemonUrl,
109
111
  clearCanonicalDaemonInfoIfOwned,
@@ -163,6 +165,12 @@ export function resolveDaemonProductVersion(
163
165
  export interface EmbeddedDaemonOptions {
164
166
  /** @internal Headless lifecycle only; explicit reservation, never inferred from ancestry. */
165
167
  supervisionId?: string;
168
+ /**
169
+ * @internal How this process came to own the daemon: the foreground
170
+ * `--headless` owner or a host embedding `startEmbeddedDaemon` directly.
171
+ * Stamped into the daemon record for triage; defaults to "embedded".
172
+ */
173
+ launcher?: "headless" | "embedded";
166
174
  /** @internal Successful previous generation stop in this same process. */
167
175
  predecessor?: CanonicalDaemonPredecessor;
168
176
  /** @internal Let the foreground lifecycle owner serialize settings restarts. */
@@ -1190,6 +1198,9 @@ async function startEmbeddedDaemonGeneration(
1190
1198
  internalReadOwnerToken: localBypassToken,
1191
1199
  registry: workspaceRegistry,
1192
1200
  tmuxAuthority,
1201
+ // A gap cannot reconstruct historical interactions. Refresh inventory
1202
+ // facts while authored operations retain their observation deadlines.
1203
+ onGap: () => terminalInventoryRuntime?.invalidate(),
1193
1204
  onObserved: ({ workspaceName, semanticPaneId, operationKind, operationId }) => {
1194
1205
  if (operationKind !== "workspace.pane.read") terminalInventoryRuntime?.invalidate();
1195
1206
  if (operationId) {
@@ -1558,6 +1569,24 @@ async function startEmbeddedDaemonGeneration(
1558
1569
  console.error("[daemon] Direct terminal startup rollback reported cleanup failures.");
1559
1570
  }
1560
1571
  };
1572
+ // Provenance (launcher, supervisor, actual stdout/stderr destination) is
1573
+ // derived from this process, never from file-name conventions, so a later
1574
+ // `daemon info` reads the truth from the record. Capture never throws;
1575
+ // whatever it could not determine is reported as a warning.
1576
+ const provenance = captureDaemonProvenance({
1577
+ launcher: opts.launcher ?? "embedded",
1578
+ ...(opts.supervisionId ? { supervisionId: opts.supervisionId } : {}),
1579
+ });
1580
+ if (provenance.warnings?.length && !opts.silent) {
1581
+ for (const warning of provenance.warnings) {
1582
+ console.warn(`[daemon] log provenance degraded: ${warning}`);
1583
+ }
1584
+ }
1585
+ // Every structured record now carries this generation's identity, and the
1586
+ // local bypass / shared tokens are redacted wherever they might appear.
1587
+ setLogIdentity({ instanceId, version: productVersion });
1588
+ registerLogSecret(localBypassToken);
1589
+ registerLogSecret(opts.authToken);
1561
1590
  try {
1562
1591
  writeCanonicalDaemonInfo(
1563
1592
  {
@@ -1571,6 +1600,7 @@ async function startEmbeddedDaemonGeneration(
1571
1600
  environmentId,
1572
1601
  bindHostname,
1573
1602
  authToken: localBypassToken,
1603
+ provenance,
1574
1604
  },
1575
1605
  claim,
1576
1606
  );