vgxness 1.19.5 → 1.19.6

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.
@@ -0,0 +1,84 @@
1
+ export function buildResumeAfterApprovalResult(input) {
2
+ const operationKind = stringFromObject(input.executorOutput, 'operationKind') ?? operationKindFromOperation(input.operation);
3
+ const command = operationKind === 'allowlisted-command' ? extractAllowlistedCommandMetadata(input.executorOutput) : undefined;
4
+ return {
5
+ kind: 'resume-after-approval-result',
6
+ version: 1,
7
+ operationKind,
8
+ runId: input.runId,
9
+ approvalId: input.approvalId,
10
+ attemptId: input.attemptId,
11
+ permissionEventId: input.permissionEventId,
12
+ pendingExecutionEventId: input.pendingExecutionEventId,
13
+ operationFingerprint: input.operationFingerprint,
14
+ executor: input.executorName,
15
+ status: input.status,
16
+ ...(command === undefined ? {} : { command }),
17
+ error: input.error === undefined ? null : { code: input.error.code, message: input.error.message },
18
+ safety: buildSafety(input.executorOutput),
19
+ };
20
+ }
21
+ function extractAllowlistedCommandMetadata(output) {
22
+ if (!isObject(output))
23
+ return undefined;
24
+ const command = isObject(output.command) ? output.command : output;
25
+ const commandId = stringField(command.commandId) ?? stringField(output.commandId);
26
+ const argv = stringArray(command.argv) ?? stringArray(output.argv);
27
+ if (commandId === undefined || argv === undefined)
28
+ return undefined;
29
+ const result = { commandId, argv };
30
+ setOptionalNumberOrNull(result, 'exitCode', command.exitCode);
31
+ setOptionalStringOrNull(result, 'signal', command.signal);
32
+ setOptionalBoolean(result, 'timedOut', command.timedOut);
33
+ setOptionalBoolean(result, 'outputTruncated', command.outputTruncated);
34
+ setOptionalNumber(result, 'stdoutBytes', command.stdoutBytes);
35
+ setOptionalNumber(result, 'stderrBytes', command.stderrBytes);
36
+ return result;
37
+ }
38
+ function buildSafety(output) {
39
+ const source = isObject(output) && isObject(output.command) && isObject(output.command.safety) ? output.command.safety : isObject(output) && isObject(output.safety) ? output.safety : undefined;
40
+ return {
41
+ metadataOnly: true,
42
+ rawStdoutPersisted: false,
43
+ rawStderrPersisted: false,
44
+ providerPayloadPersisted: false,
45
+ executorOutputWhitelisted: true,
46
+ ...(typeof source?.boundedProcess === 'boolean' ? { boundedProcess: source.boundedProcess } : {}),
47
+ ...(typeof source?.shellDisabled === 'boolean' ? { shellDisabled: source.shellDisabled } : {}),
48
+ ...(typeof source?.argvArrayOnly === 'boolean' ? { argvArrayOnly: source.argvArrayOnly } : {}),
49
+ ...(typeof source?.providerConfigWritesBlocked === 'boolean' ? { providerConfigWritesBlocked: source.providerConfigWritesBlocked } : {}),
50
+ ...(typeof source?.createsSandbox === 'boolean' ? { createsSandbox: source.createsSandbox } : {}),
51
+ ...(typeof source?.createsWorktree === 'boolean' ? { createsWorktree: source.createsWorktree } : {}),
52
+ };
53
+ }
54
+ function operationKindFromOperation(operation) {
55
+ return isObject(operation.input) && typeof operation.input.operationKind === 'string' ? operation.input.operationKind : 'generic-operation';
56
+ }
57
+ function stringFromObject(value, key) {
58
+ return isObject(value) ? stringField(value[key]) : undefined;
59
+ }
60
+ function stringField(value) {
61
+ return typeof value === 'string' ? value : undefined;
62
+ }
63
+ function stringArray(value) {
64
+ return Array.isArray(value) && value.every((item) => typeof item === 'string') ? value : undefined;
65
+ }
66
+ function setOptionalNumber(target, key, value) {
67
+ if (typeof value === 'number')
68
+ target[key] = value;
69
+ }
70
+ function setOptionalBoolean(target, key, value) {
71
+ if (typeof value === 'boolean')
72
+ target[key] = value;
73
+ }
74
+ function setOptionalNumberOrNull(target, key, value) {
75
+ if (typeof value === 'number' || value === null)
76
+ target[key] = value;
77
+ }
78
+ function setOptionalStringOrNull(target, key, value) {
79
+ if (typeof value === 'string' || value === null)
80
+ target[key] = value;
81
+ }
82
+ function isObject(value) {
83
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
84
+ }
@@ -7,6 +7,7 @@ import { evaluateOperationRetry as evaluateOperationRetryPolicy } from './operat
7
7
  import { AllowlistedApplyProgressCommandExecutor } from '../workflows/command-allowlist-adapter.js';
8
8
  import { RunRepository, } from './repositories/runs.js';
9
9
  import { buildRunInsights, buildRunOperatorResumePlan } from './run-insights.js';
10
+ import { buildResumeAfterApprovalResult } from './resume-after-approval-result.js';
10
11
  const preflightSafety = {
11
12
  operationExecuted: false,
12
13
  executorInvoked: false,
@@ -459,7 +460,19 @@ export class RunService {
459
460
  const executed = input.executor.execute({ runId: approval.value.runId, operation });
460
461
  if (!executed.ok) {
461
462
  const error = { code: executed.error.code, message: executed.error.message };
462
- const attempt = this.runs.completeOperationAttempt({ attemptId: reserved.value.id, status: 'failed', error });
463
+ const result = buildResumeAfterApprovalResult({
464
+ runId: approval.value.runId,
465
+ approvalId: approval.value.id,
466
+ attemptId: reserved.value.id,
467
+ permissionEventId: permissionEvent.id,
468
+ pendingExecutionEventId: pendingExecutionEvent.id,
469
+ operationFingerprint: replayGuard.operationFingerprint,
470
+ executorName: input.executor.name,
471
+ operation,
472
+ status: 'failed',
473
+ error,
474
+ });
475
+ const attempt = this.runs.completeOperationAttempt({ attemptId: reserved.value.id, status: 'failed', output: result, error });
463
476
  if (!attempt.ok)
464
477
  return attempt;
465
478
  const executionEvent = this.runs.appendEvent({
@@ -478,6 +491,7 @@ export class RunService {
478
491
  operationFingerprint: replayGuard.operationFingerprint,
479
492
  resumedFromApprovalId: approval.value.id,
480
493
  executorInvoked: true,
494
+ result,
481
495
  error,
482
496
  }),
483
497
  relatedType: 'approval',
@@ -486,7 +500,7 @@ export class RunService {
486
500
  if (!executionEvent.ok)
487
501
  return { ok: false, error: executionEvent.error };
488
502
  const linkedAttempt = this.runs.attachAttemptResultEvent(attempt.value.id, executionEvent.value.id);
489
- const evidence = appendApplyProgressAllowlistEvidenceIfNeeded(this.runs, approval.value.id, permissionEvent, pendingExecutionEvent, linkedAttempt.ok ? linkedAttempt.value : attempt.value, executionEvent.value, replayGuard.operationFingerprint, input.executor.name, operation, undefined, error);
503
+ const evidence = appendApplyProgressAllowlistEvidenceIfNeeded(this.runs, approval.value.id, permissionEvent, pendingExecutionEvent, linkedAttempt.ok ? linkedAttempt.value : attempt.value, executionEvent.value, replayGuard.operationFingerprint, input.executor.name, operation, result);
490
504
  if (!evidence.ok)
491
505
  return { ok: false, error: evidence.error };
492
506
  return {
@@ -498,12 +512,25 @@ export class RunService {
498
512
  attempt: linkedAttempt.ok ? linkedAttempt.value : attempt.value,
499
513
  executionEvent: executionEvent.value,
500
514
  status: 'failed',
515
+ output: result,
501
516
  ...(evidence.value === undefined ? {} : evidence.value),
502
517
  },
503
518
  };
504
519
  }
505
520
  const output = executed.value.output;
506
- const attempt = this.runs.completeOperationAttempt({ attemptId: reserved.value.id, status: 'succeeded', ...(output === undefined ? {} : { output }) });
521
+ const result = buildResumeAfterApprovalResult({
522
+ runId: approval.value.runId,
523
+ approvalId: approval.value.id,
524
+ attemptId: reserved.value.id,
525
+ permissionEventId: permissionEvent.id,
526
+ pendingExecutionEventId: pendingExecutionEvent.id,
527
+ operationFingerprint: replayGuard.operationFingerprint,
528
+ executorName: input.executor.name,
529
+ operation,
530
+ status: 'succeeded',
531
+ ...(output === undefined ? {} : { executorOutput: output }),
532
+ });
533
+ const attempt = this.runs.completeOperationAttempt({ attemptId: reserved.value.id, status: 'succeeded', output: result });
507
534
  if (!attempt.ok)
508
535
  return attempt;
509
536
  const executionEvent = this.runs.appendEvent({
@@ -522,7 +549,7 @@ export class RunService {
522
549
  operationFingerprint: replayGuard.operationFingerprint,
523
550
  resumedFromApprovalId: approval.value.id,
524
551
  executorInvoked: true,
525
- output: output ?? null,
552
+ result,
526
553
  }),
527
554
  relatedType: 'approval',
528
555
  relatedId: approval.value.id,
@@ -530,7 +557,7 @@ export class RunService {
530
557
  if (!executionEvent.ok)
531
558
  return { ok: false, error: executionEvent.error };
532
559
  const linkedAttempt = this.runs.attachAttemptResultEvent(attempt.value.id, executionEvent.value.id);
533
- const evidence = appendApplyProgressAllowlistEvidenceIfNeeded(this.runs, approval.value.id, permissionEvent, pendingExecutionEvent, linkedAttempt.ok ? linkedAttempt.value : attempt.value, executionEvent.value, replayGuard.operationFingerprint, input.executor.name, operation, output, undefined);
560
+ const evidence = appendApplyProgressAllowlistEvidenceIfNeeded(this.runs, approval.value.id, permissionEvent, pendingExecutionEvent, linkedAttempt.ok ? linkedAttempt.value : attempt.value, executionEvent.value, replayGuard.operationFingerprint, input.executor.name, operation, result);
534
561
  if (!evidence.ok)
535
562
  return { ok: false, error: evidence.error };
536
563
  return {
@@ -542,7 +569,7 @@ export class RunService {
542
569
  attempt: linkedAttempt.ok ? linkedAttempt.value : attempt.value,
543
570
  executionEvent: executionEvent.value,
544
571
  status: 'succeeded',
545
- ...(output === undefined ? {} : { output }),
572
+ output: result,
546
573
  ...(evidence.value === undefined ? {} : evidence.value),
547
574
  },
548
575
  };
@@ -1002,24 +1029,21 @@ function workflowConflictDecision(input, runWorkflow) {
1002
1029
  auditEvidence: [`runWorkflow:${runWorkflow}`, `explicitWorkflow:${input.workflow}`],
1003
1030
  };
1004
1031
  }
1005
- function appendApplyProgressAllowlistEvidenceIfNeeded(runs, approvalId, permissionEvent, pendingExecutionEvent, attempt, executionEvent, operationFingerprint, executorName, operation, output, error) {
1032
+ function appendApplyProgressAllowlistEvidenceIfNeeded(runs, approvalId, permissionEvent, pendingExecutionEvent, attempt, executionEvent, operationFingerprint, executorName, operation, result) {
1006
1033
  if (!isApplyProgressAllowlistedCommandOperation(operation))
1007
1034
  return { ok: true, value: undefined };
1008
1035
  const base = {
1009
- kind: 'apply-progress-operation',
1010
- operationKind: 'allowlisted-command',
1011
- runId: attempt.runId,
1012
- approvalId,
1013
- attemptId: attempt.id,
1014
- pendingExecutionEventId: pendingExecutionEvent.id,
1015
- permissionEventId: permissionEvent.id,
1036
+ ...result,
1016
1037
  executionEventId: executionEvent.id,
1017
- operationFingerprint,
1018
- executor: executorName,
1019
- operation: operationMetadata(operation),
1020
- status: attempt.status,
1021
- output: output ?? null,
1022
- error: error ?? null,
1038
+ audit: {
1039
+ metadataOnly: true,
1040
+ operationFingerprint,
1041
+ executor: executorName,
1042
+ approvalId,
1043
+ pendingExecutionEventId: pendingExecutionEvent.id,
1044
+ permissionEventId: permissionEvent.id,
1045
+ attemptId: attempt.id,
1046
+ },
1023
1047
  };
1024
1048
  const evidence = runs.appendEvent({
1025
1049
  runId: attempt.runId,
@@ -162,6 +162,11 @@ function acceptedEvidence(workspaceRoot, cwd, checks) {
162
162
  enforceable: true,
163
163
  createsSandbox: false,
164
164
  createsWorktree: false,
165
+ filesystemIsolation: false,
166
+ networkIsolation: false,
167
+ shellDisabled: true,
168
+ argvArrayOnly: true,
169
+ providerConfigWritesBlocked: true,
165
170
  workspaceRoot,
166
171
  cwd,
167
172
  capabilities: {
@@ -55,16 +55,31 @@ export class CommandAllowlistAdapter {
55
55
  const result = this.runner(this.request);
56
56
  if (!result.ok)
57
57
  throw new Error(`${result.error.code}: ${result.error.message}`);
58
+ const stdoutBytes = Buffer.byteLength(result.value.stdout);
59
+ const stderrBytes = Buffer.byteLength(result.value.stderr);
60
+ const safety = {
61
+ strategy: result.value.evidence.strategy,
62
+ boundedProcess: true,
63
+ createsSandbox: result.value.evidence.createsSandbox,
64
+ createsWorktree: result.value.evidence.createsWorktree,
65
+ filesystemIsolation: result.value.evidence.filesystemIsolation,
66
+ networkIsolation: result.value.evidence.networkIsolation,
67
+ shellDisabled: result.value.evidence.shellDisabled,
68
+ argvArrayOnly: result.value.evidence.argvArrayOnly,
69
+ providerConfigWritesBlocked: result.value.evidence.providerConfigWritesBlocked,
70
+ };
58
71
  const output = {
59
- command: this.commandId,
72
+ commandId: this.commandId,
60
73
  executable: this.entry.executable,
61
- args: this.entry.args,
74
+ argv: [this.entry.executable, ...this.entry.args],
75
+ cwd: this.plan.request.cwd,
62
76
  exitCode: result.value.exitCode,
63
77
  signal: result.value.signal,
64
78
  timedOut: result.value.timedOut,
65
79
  outputTruncated: result.value.outputTruncated,
66
- stdout: result.value.stdout,
67
- stderr: result.value.stderr,
80
+ stdoutBytes,
81
+ stderrBytes,
82
+ safety,
68
83
  };
69
84
  const failed = result.value.timedOut || result.value.exitCode !== 0;
70
85
  return {
@@ -77,6 +92,11 @@ export class CommandAllowlistAdapter {
77
92
  shell: false,
78
93
  argv: [this.entry.executable, ...this.entry.args],
79
94
  cwd: this.plan.request.cwd,
95
+ stdoutBytes,
96
+ stderrBytes,
97
+ outputTruncated: result.value.outputTruncated,
98
+ timedOut: result.value.timedOut,
99
+ safety,
80
100
  },
81
101
  ...(failed
82
102
  ? {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vgxness",
3
- "version": "1.19.5",
3
+ "version": "1.19.6",
4
4
  "description": "CLI and MCP control plane for guided AI-agent workflows, SDD, memory, and OpenCode setup.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {