local-commander-agent 0.3.14-cli.1 → 0.3.15-recovery.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "local-commander-agent",
3
- "version": "0.3.14-cli.1",
3
+ "version": "0.3.15-recovery.1",
4
4
  "description": "Windows companion for Local Commander: connect AI clients to local files, approved commands and localhost. Requires https://localcmd.app.",
5
5
  "type": "module",
6
6
  "bin": {
Binary file
Binary file
Binary file
package/runtime/agent.mjs CHANGED
@@ -24317,7 +24317,8 @@ var PermissionScopeSchema = external_exports.enum([
24317
24317
  "files:write",
24318
24318
  "commands:execute",
24319
24319
  "processes:control",
24320
- "localhost:access"
24320
+ "localhost:access",
24321
+ "business:read"
24321
24322
  ]);
24322
24323
  var OperationStateSchema = external_exports.enum([
24323
24324
  "queued",
@@ -24486,11 +24487,12 @@ var ClientFrameSchema = external_exports.discriminatedUnion("type", [
24486
24487
  ]);
24487
24488
  var TerminalMetricsSchema = external_exports.object({ stdoutBytes: external_exports.number().int().min(0).max(4194304), stderrBytes: external_exports.number().int().min(0).max(4194304), outputTruncated: external_exports.boolean() }).strict();
24488
24489
  var TERMINAL_METRICS_CAPABILITY = "terminalMetrics";
24490
+ var REJECTION_RESULT_CAPABILITY = "rejectionResultV1";
24489
24491
  var NATIVE_CAPACITY_CAPABILITY = "nativeCapacity";
24490
24492
  var NativeCapacitySchema = external_exports.object({ type: external_exports.literal("nativeCapacity"), protocolVersion: external_exports.literal(1), connectionEpoch: epoch, safeSlots: external_exports.number().int().min(1).max(32), agentVersion: external_exports.string().regex(/^[A-Za-z0-9._+-]{1,64}$/) }).strict();
24491
24493
  var NATIVE_STATUS_CAPABILITY = "nativeStatusV1";
24492
24494
  var NativeStatusSchema = NativeCapacitySchema.extend({ type: external_exports.literal("nativeStatus"), active: external_exports.number().int().min(0).max(32), queued: external_exports.number().int().min(0).max(256), paused: external_exports.boolean() }).strict().refine((v) => v.active <= v.safeSlots);
24493
- var TerminalEventSchema = external_exports.object({ type: external_exports.literal("executionResult"), protocolVersion: external_exports.literal(1), requestId: uuid8, tenantId: uuid8, deviceId: uuid8, connectionEpoch: epoch, binding: ExecutionBindingSchema, state: external_exports.enum(["finished", "failed", "cancelled", "unknown"]), resultCode: external_exports.string().regex(/^[A-Z0-9_]{1,40}$/), metrics: TerminalMetricsSchema.optional() }).strict();
24495
+ var TerminalEventSchema = external_exports.object({ type: external_exports.literal("executionResult"), protocolVersion: external_exports.literal(1), requestId: uuid8, tenantId: uuid8, deviceId: uuid8, connectionEpoch: epoch, binding: ExecutionBindingSchema, state: external_exports.enum(["finished", "failed", "cancelled", "unknown", "rejected"]), resultCode: external_exports.string().regex(/^[A-Z0-9_]{1,40}$/), metrics: TerminalMetricsSchema.optional() }).strict();
24494
24496
  var TerminalEventAckSchema = external_exports.object({ type: external_exports.literal("executionResultAck"), protocolVersion: external_exports.literal(1), requestId: uuid8, ok: external_exports.boolean() }).strict();
24495
24497
  function canonicalJson(value) {
24496
24498
  function canonical2(v) {
@@ -25014,12 +25016,13 @@ var NativeJournal = class _NativeJournal {
25014
25016
  return this.enqueue(async () => [...this.entries.values()].filter((e) => !terminal.has(e.state)).map(clone2));
25015
25017
  }
25016
25018
  listUnreportedResults() {
25017
- return this.enqueue(async () => [...this.entries.values()].filter((e) => !e.reportedAt && e.resultCode && e.workspaceGrantId && e.policyVersion && ["finished", "failed", "cancelled", "unknown"].includes(e.state)).map(clone2));
25019
+ return this.enqueue(async () => [...this.entries.values()].filter((e) => !e.reportedAt && (e.resultCode || e.state === "rejected") && e.workspaceGrantId && e.policyVersion && ["finished", "failed", "cancelled", "unknown", "rejected"].includes(e.state)).map((e) => ({ ...clone2(e), resultCode: e.state === "rejected" ? "PRE_ACCEPTANCE_REJECTED" : e.resultCode })));
25018
25020
  }
25019
25021
  markReported(id2, resultCode) {
25020
25022
  return this.enqueue(async () => {
25021
25023
  const e = this.need(id2);
25022
- if (!e.resultCode || e.resultCode !== resultCode || !e.workspaceGrantId || !e.policyVersion || !["finished", "failed", "cancelled", "unknown"].includes(e.state)) throw failure2("JOURNAL_STATE_INVALID");
25024
+ if (e.state === "rejected" && resultCode === "PRE_ACCEPTANCE_REJECTED") e.resultCode = resultCode;
25025
+ if (!e.resultCode || e.resultCode !== resultCode || !e.workspaceGrantId || !e.policyVersion || !["finished", "failed", "cancelled", "unknown", "rejected"].includes(e.state)) throw failure2("JOURNAL_STATE_INVALID");
25023
25026
  if (e.reportedAt) return;
25024
25027
  e.reportedAt = this.now().toISOString();
25025
25028
  e.updatedAt = e.reportedAt;
@@ -25058,7 +25061,7 @@ var NativeJournal = class _NativeJournal {
25058
25061
  let count = 0;
25059
25062
  const cutoff = this.now().getTime() - this.options.retentionMs;
25060
25063
  for (const e of [...this.entries.values()]) {
25061
- if (!terminal.has(e.state) || e.resultCode && e.workspaceGrantId && !e.reportedAt || Date.parse(e.updatedAt) >= cutoff) continue;
25064
+ if (!terminal.has(e.state) || (e.resultCode || e.state === "rejected") && e.workspaceGrantId && !e.reportedAt || Date.parse(e.updatedAt) >= cutoff) continue;
25062
25065
  if (digest2(await this.readOwned(e.executionId)) !== this.digests.get(e.executionId)) throw failure2("JOURNAL_CORRUPT");
25063
25066
  await rm(this.file(e.executionId));
25064
25067
  this.totalBytes -= this.sizes.get(e.executionId);
@@ -28538,7 +28541,7 @@ var NativeRelayBridge = class {
28538
28541
  this.runtime.connected(connection, (frame) => {
28539
28542
  if (frame.type === "control_result") this.control.get(frame.requestId)?.resolve(frame);
28540
28543
  else if ("binding" in frame) this.execution.get(frame.binding.executionId)?.resolve(frame);
28541
- if (frame.type === "result") void this.flushTerminal().catch(() => {
28544
+ if (frame.type === "result" || frame.type === "not_accepted" && frame.provedNotStarted) void this.flushTerminal().catch(() => {
28542
28545
  });
28543
28546
  return true;
28544
28547
  });
@@ -28553,7 +28556,7 @@ var NativeRelayBridge = class {
28553
28556
  this.terminalSending.add(id2);
28554
28557
  try {
28555
28558
  const binding2 = { tenantId: event.tenantId, deviceId: event.deviceId, grantId: event.grantId, sessionId: event.sessionId, operationId: event.operationId, executionId: id2, connectionEpoch: event.connectionEpoch, workspaceGrantId: event.workspaceGrantId, policyVersion: event.policyVersion, payloadHash: event.payloadHash, deadlineAt: event.deadlineAt, ...event.accountId ? { accountId: event.accountId } : {} };
28556
- if (!["finished", "failed", "cancelled", "unknown"].includes(event.state)) continue;
28559
+ if (!["finished", "failed", "cancelled", "unknown", "rejected"].includes(event.state)) continue;
28557
28560
  await this.sendTerminal(binding2, event.state, event.resultCode, terminalMetrics(event.result));
28558
28561
  await this.journal.markReported(id2, event.resultCode);
28559
28562
  } catch {
@@ -29063,6 +29066,7 @@ async function connectOnce(options) {
29063
29066
  }, maxFrameBytes);
29064
29067
  const readyFrame = await waitForMessage(socket, maxFrameBytes, connectTimeoutMs, "RELAY_HANDSHAKE_TIMEOUT");
29065
29068
  const { connectionEpoch, terminalMetrics: terminalMetrics2 } = validateReady(readyFrame, enrollment, protocolVersion2);
29069
+ const rejectionResults = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(REJECTION_RESULT_CAPABILITY);
29066
29070
  const incidents = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("incidentBatchV1");
29067
29071
  const monitorHeartbeat = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes("monitorHeartbeatV1") && typeof readyFrame.heartbeatMs === "number" && Number.isInteger(readyFrame.heartbeatMs) && readyFrame.heartbeatMs >= 1e3 && readyFrame.heartbeatMs <= 6e4 ? readyFrame.heartbeatMs : void 0;
29068
29072
  const nativeStatus = Array.isArray(readyFrame.capabilities) && readyFrame.capabilities.includes(NATIVE_STATUS_CAPABILITY) && options.status;
@@ -29194,6 +29198,7 @@ async function connectOnce(options) {
29194
29198
  }
29195
29199
  } } : {},
29196
29200
  sendTerminal: (binding2, state, resultCode, metrics) => {
29201
+ if (state === "rejected" && !rejectionResults) return Promise.reject(new RelayClientError("RELAY_RESULT_UNSUPPORTED"));
29197
29202
  if (pendingTerminal.size >= 64) return Promise.reject(new RelayClientError("RELAY_PENDING_LIMIT"));
29198
29203
  const requestId = randomUUID6();
29199
29204
  const event = { type: "executionResult", protocolVersion: 1, requestId, tenantId, deviceId, connectionEpoch, binding: binding2, state, resultCode, ...terminalMetrics2 && metrics ? { metrics } : {} };
@@ -31601,7 +31606,7 @@ async function readFabricRequest(input2 = process.stdin) {
31601
31606
  }
31602
31607
 
31603
31608
  // agent/src/main.ts
31604
- var AGENT_VERSION2 = true ? "0.3.14-cli.1" : "0.3.2";
31609
+ var AGENT_VERSION2 = true ? "0.3.15-recovery.1" : "0.3.2";
31605
31610
  function processAlive(pid) {
31606
31611
  if (!Number.isInteger(pid) || pid <= 0) return false;
31607
31612
  try {
@@ -31751,6 +31756,7 @@ async function runAgent(options) {
31751
31756
  });
31752
31757
  fabric?.connected(connection.deviceId);
31753
31758
  await bridge.connected(connection);
31759
+ await options.journal.prune();
31754
31760
  incidentProducer.connected(connection.sendIncidentBatch);
31755
31761
  supervisor.observe({ kind: "connected" });
31756
31762
  monitor(() => options.monitor?.setConnection("connected", connection));