@amaster.ai/employee-runtime-connector 0.1.1-beta.248 → 0.1.1-beta.249

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.
@@ -17397,6 +17397,28 @@ function createPiOutputRetentionCompactor() {
17397
17397
  };
17398
17398
  }
17399
17399
 
17400
+ // src/amaster-runtime-daemon/task-session-checkpoint.mjs
17401
+ function taskSessionCheckpointMatches(command, manifest) {
17402
+ const payload = asRecord(command.payload);
17403
+ const session = asRecord(payload.nativeSession);
17404
+ const expected = {
17405
+ companyId: readString(payload.companyId),
17406
+ issueId: readString(command.issueId ?? payload.issueId),
17407
+ agentId: readString(payload.agentId),
17408
+ sourceRunId: readString(session.sourceRunId),
17409
+ sourceCommandId: readString(session.sourceCommandId),
17410
+ sessionId: readString(session.sessionId)
17411
+ };
17412
+ return session.mode === "task_session" && session.resume === true && manifest.kind === "task_session" && Object.entries(expected).every(([key, value]) => value !== null && value === manifest[key]);
17413
+ }
17414
+ function taskSessionCheckpointPaths(workspaceStatus) {
17415
+ const artifacts = workspaceStatus.artifacts;
17416
+ if (asRecord(workspaceStatus.metadata).artifactScanTruncated === true || !Array.isArray(artifacts) || artifacts.length > 20) {
17417
+ throw new Error("native_session_checkpoint_unavailable: workspace inventory exceeds checkpoint limits");
17418
+ }
17419
+ return artifacts.map((file) => file.relativePath);
17420
+ }
17421
+
17400
17422
  // src/amaster-runtime-daemon/pi-run-exit-closure-guard.mjs
17401
17423
  function readText(value) {
17402
17424
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -30823,7 +30845,7 @@ function assertRequiredTaskAttachmentMaterialized(input, materialized) {
30823
30845
  }
30824
30846
 
30825
30847
  // src/amaster-runtime-daemon.mjs
30826
- var CONNECTOR_VERSION = "0.1.1-beta.248";
30848
+ var CONNECTOR_VERSION = "0.1.1-beta.249";
30827
30849
  var CONNECTOR_CONTRACT_VERSION = "2026-06-04.v1";
30828
30850
  var daemonRequire = createRequire(import.meta.url);
30829
30851
  var MAX_CHECKPOINT_BYTES = 20 * 1024 * 1024;
@@ -35631,9 +35653,20 @@ async function materializeRequiredArtifactInputs(config, command, workspace) {
35631
35653
  function issueCheckpointDir(workspace) {
35632
35654
  return join17(dirname11(workspace.runDir), "checkpoint");
35633
35655
  }
35634
- async function clearIssueCheckpoint(config, command, workspace, reason) {
35656
+ async function clearIssueCheckpoint(config, command, workspace, reason, consumedSource = null) {
35635
35657
  const checkpointDir = issueCheckpointDir(workspace);
35636
35658
  if (!existsSync17(checkpointDir)) return false;
35659
+ if (consumedSource !== null) {
35660
+ const sourceRunId = readString(consumedSource.sourceRunId);
35661
+ if (!sourceRunId) return false;
35662
+ let manifest;
35663
+ try {
35664
+ manifest = asRecord(JSON.parse(readFileSync18(join17(checkpointDir, "manifest.json"), "utf8")));
35665
+ } catch {
35666
+ return false;
35667
+ }
35668
+ if (readString(manifest.issueId) !== commandIssueId(command) || readString(manifest.sourceRunId) !== sourceRunId) return false;
35669
+ }
35637
35670
  rmSync9(checkpointDir, { recursive: true, force: true });
35638
35671
  await ingestLog(config, command, "system", "info", "Cleared issue continuation checkpoint", { reason });
35639
35672
  return true;
@@ -35675,9 +35708,10 @@ async function materializeIssueCheckpoint(config, command, workspace) {
35675
35708
  const checkpointDir = issueCheckpointDir(workspace);
35676
35709
  const manifestPath = join17(checkpointDir, "manifest.json");
35677
35710
  const expectedContinuation = expectedContinuationCheckpoint(command);
35711
+ const unavailable2 = { files: [], taskSessionRestored: false };
35678
35712
  if (!existsSync17(manifestPath)) {
35679
35713
  if (expectedContinuation) throw new Error("continuation_checkpoint_unavailable: manifest_missing");
35680
- return [];
35714
+ return unavailable2;
35681
35715
  }
35682
35716
  let manifest;
35683
35717
  try {
@@ -35690,12 +35724,20 @@ async function materializeIssueCheckpoint(config, command, workspace) {
35690
35724
  if (!Number.isFinite(expiresAt) || expiresAt <= Date.now() || readString(manifest.issueId) !== commandIssueId(command)) {
35691
35725
  rmSync9(checkpointDir, { recursive: true, force: true });
35692
35726
  if (expectedContinuation) throw new Error("continuation_checkpoint_unavailable: manifest_expired_or_mismatched");
35693
- return [];
35727
+ return unavailable2;
35694
35728
  }
35695
35729
  try {
35730
+ if (!expectedContinuation && asRecord(asRecord(command.payload).nativeSession).mode === "task_session" && manifest.kind !== "task_session") {
35731
+ return unavailable2;
35732
+ }
35696
35733
  if (readString(manifest.kind) === "continue_task" && !expectedContinuation) {
35697
- return [];
35734
+ return unavailable2;
35735
+ }
35736
+ const taskSessionRestored = !expectedContinuation && taskSessionCheckpointMatches(command, manifest) && resolveNativeSessionRequest(command, workspace).used;
35737
+ if (manifest.kind === "task_session" && !taskSessionRestored && !expectedContinuation) {
35738
+ return unavailable2;
35698
35739
  }
35740
+ if (taskSessionRestored && !Array.isArray(manifest.files)) throw new Error("task session checkpoint file inventory is missing");
35699
35741
  const files = Array.isArray(manifest.files) ? manifest.files : [];
35700
35742
  if (files.length > 20) throw new Error("issue checkpoint manifest exceeds the limit of 20 files");
35701
35743
  if (expectedContinuation) {
@@ -35724,7 +35766,7 @@ async function materializeIssueCheckpoint(config, command, workspace) {
35724
35766
  }
35725
35767
  const expectedSha256 = readString(file.sha256);
35726
35768
  const expectedByteSize = readNumber(file.byteSize, null);
35727
- if (!expectedSha256 || expectedByteSize === null || expectedByteSize <= 0) {
35769
+ if (!expectedSha256 || expectedByteSize === null || expectedByteSize < 0 || expectedByteSize === 0 && !taskSessionRestored) {
35728
35770
  throw new Error(`issue checkpoint evidence is incomplete: ${relativePath}`);
35729
35771
  }
35730
35772
  if (hashFileSha256(source) !== expectedSha256 || statSync11(source).size !== expectedByteSize) {
@@ -35779,7 +35821,7 @@ async function materializeIssueCheckpoint(config, command, workspace) {
35779
35821
  checkpointExpiresAt: new Date(expiresAt).toISOString()
35780
35822
  });
35781
35823
  }
35782
- return materialized;
35824
+ return { files: materialized, taskSessionRestored };
35783
35825
  } catch (restoreErr) {
35784
35826
  try {
35785
35827
  await clearIssueCheckpoint(config, command, workspace, "restore_failed");
@@ -35806,7 +35848,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates, optio
35806
35848
  let totalBytes = 0;
35807
35849
  const workspaceRoot = realpathSync8(workspace.cwd);
35808
35850
  const requiredPaths = Array.isArray(options.requiredPaths) ? options.requiredPaths : [];
35809
- const selectedCandidates = requiredPaths.length > 0 ? requiredPaths.map((requiredPath) => {
35851
+ const selectedCandidates = requiredPaths.length > 0 || options.taskSession ? requiredPaths.map((requiredPath) => {
35810
35852
  const normalized = safeCheckpointRelativePath(requiredPath);
35811
35853
  if (!normalized) {
35812
35854
  throw new Error(`continuation_checkpoint_file_unavailable: ${requiredPath}`);
@@ -35837,7 +35879,7 @@ async function saveIssueCheckpoint(config, command, workspace, candidates, optio
35837
35879
  const relativePath = safeCheckpointRelativePath(candidate.rawPath);
35838
35880
  const source = readString(candidate.filePath);
35839
35881
  if (!relativePath || !source || !existsSync17(source) || !statSync11(source).isFile()) {
35840
- if (requiredPaths.length > 0) throw new Error(`continuation_checkpoint_file_unavailable: ${candidate.rawPath}`);
35882
+ if (requiredPaths.length > 0 || options.taskSession) throw new Error(`continuation_checkpoint_file_unavailable: ${candidate.rawPath}`);
35841
35883
  continue;
35842
35884
  }
35843
35885
  const ownedSource = realpathSync8(source);
@@ -35845,8 +35887,8 @@ async function saveIssueCheckpoint(config, command, workspace, candidates, optio
35845
35887
  throw new Error(`issue checkpoint source escapes its execution workspace: ${relativePath}`);
35846
35888
  }
35847
35889
  const byteSize = statSync11(ownedSource).size;
35848
- if (byteSize <= 0 || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) {
35849
- if (requiredPaths.length > 0) throw new Error(`continuation_checkpoint_file_size_invalid: ${relativePath}`);
35890
+ if (byteSize <= 0 && !options.taskSession || totalBytes + byteSize > MAX_CHECKPOINT_BYTES) {
35891
+ if (requiredPaths.length > 0 || options.taskSession) throw new Error(`continuation_checkpoint_file_size_invalid: ${relativePath}`);
35850
35892
  continue;
35851
35893
  }
35852
35894
  const target = resolve16(filesDir, relativePath);
@@ -35860,15 +35902,22 @@ async function saveIssueCheckpoint(config, command, workspace, candidates, optio
35860
35902
  totalBytes += byteSize;
35861
35903
  files.push({ path: relativePath, byteSize, sha256: hashFileSha256(target) });
35862
35904
  }
35863
- if (files.length === 0) {
35905
+ if (files.length === 0 && !options.taskSession) {
35864
35906
  rmSync9(stagingDir, { recursive: true, force: true });
35865
35907
  rmSync9(checkpointDir, { recursive: true, force: true });
35866
35908
  return null;
35867
35909
  }
35868
35910
  const manifest = {
35869
- version: options.continuation ? 2 : 1,
35911
+ version: options.continuation || options.taskSession ? 2 : 1,
35870
35912
  issueId: commandIssueId(command),
35871
35913
  sourceRunId: commandRunId(command),
35914
+ ...options.taskSession ? {
35915
+ kind: "task_session",
35916
+ companyId: readString(asRecord(command.payload).companyId),
35917
+ agentId: readString(asRecord(command.payload).agentId),
35918
+ sourceCommandId: command.commandId,
35919
+ sessionId: options.taskSession.sessionId
35920
+ } : {},
35872
35921
  ...options.continuation ? {
35873
35922
  kind: "continue_task",
35874
35923
  continuationChainId: options.continuation.chainId,
@@ -35970,7 +36019,19 @@ async function executeRunCommand(config, command) {
35970
36019
  agentInstructionFiles: [...finalAgentInstructionFiles.values()].sort((left, right) => left.path.localeCompare(right.path)),
35971
36020
  workspaceProjectInstructionProjection: workspaceProjectInstructionReceipt
35972
36021
  });
35973
- const materializedCheckpointFiles = await materializeIssueCheckpoint(config, command, workspace);
36022
+ const restoredCheckpoint = await materializeIssueCheckpoint(config, command, workspace);
36023
+ const materializedCheckpointFiles = restoredCheckpoint.files;
36024
+ const requestedNativeSession = asRecord(asRecord(command.payload).nativeSession);
36025
+ const taskSessionCheckpointUnavailable = Object.keys(governedMcp).length > 0 && requestedNativeSession.mode === "task_session" && !expectedContinuationCheckpoint(command) && !restoredCheckpoint.taskSessionRestored;
36026
+ if (taskSessionCheckpointUnavailable && requestedNativeSession.required === true) {
36027
+ throw new Error("native_session_required: exact task-session workspace checkpoint is unavailable");
36028
+ }
36029
+ const executionCommand = taskSessionCheckpointUnavailable ? { ...command, payload: { ...asRecord(command.payload), nativeSession: void 0 } } : command;
36030
+ if (taskSessionCheckpointUnavailable) {
36031
+ await ingestLog(config, command, "system", "info", "Starting fresh: no exact task-session workspace checkpoint is available", {
36032
+ skippedReason: "native_session_checkpoint_unavailable"
36033
+ });
36034
+ }
35974
36035
  const requiredArtifactInputs = await materializeRequiredArtifactInputs(config, command, workspace);
35975
36036
  let materializedAttachments = requiredArtifactInputs;
35976
36037
  try {
@@ -36016,7 +36077,10 @@ async function executeRunCommand(config, command) {
36016
36077
  AMASTER_BROWSER_SESSION_USER_DATA_DIR: ownedProfile.userDataDir
36017
36078
  };
36018
36079
  }
36019
- invocation = buildExecutorInvocation(executor, command, workspace);
36080
+ invocation = buildExecutorInvocation(executor, executionCommand, workspace);
36081
+ if (taskSessionCheckpointUnavailable) {
36082
+ invocation.nativeSession = { ...asRecord(invocation.nativeSession), requested: true, skippedReason: "native_session_checkpoint_unavailable" };
36083
+ }
36020
36084
  });
36021
36085
  if (executor.kind === "codex" && Object.keys(governedMcp).length > 0) {
36022
36086
  managedMcpProfile = await runExecutionStage("managed_mcp", () => prepareManagedCodexMcpProfile({
@@ -36028,7 +36092,7 @@ async function executeRunCommand(config, command) {
36028
36092
  runDir: workspace.runDir,
36029
36093
  cwd,
36030
36094
  runtimeAuth: commandRuntimeAuth(command),
36031
- nativeSession: asRecord(asRecord(command.payload).nativeSession),
36095
+ nativeSession: asRecord(asRecord(executionCommand.payload).nativeSession),
36032
36096
  baseEnv: executorEnv,
36033
36097
  commandEnv: commandExecutorEnv(command),
36034
36098
  extraArgs: splitExtraArgs(process.env.AMASTER_CODEX_EXTRA_ARGS)
@@ -36061,7 +36125,7 @@ async function executeRunCommand(config, command) {
36061
36125
  runtimeCacheRoot: join17(dirname11(config.daemonStateFile), "cache"),
36062
36126
  cwd,
36063
36127
  runtimeAuth: commandRuntimeAuth(command),
36064
- nativeSession: asRecord(asRecord(command.payload).nativeSession),
36128
+ nativeSession: asRecord(asRecord(executionCommand.payload).nativeSession),
36065
36129
  baseEnv: executorEnv,
36066
36130
  commandEnv: piProfileCommandEnv,
36067
36131
  extraArgs: splitExtraArgs(process.env.AMASTER_PI_EXTRA_ARGS),
@@ -36211,7 +36275,7 @@ async function executeRunCommand(config, command) {
36211
36275
  };
36212
36276
  }
36213
36277
  );
36214
- const promptCompilation = await runExecutionStage("prompt_compilation", () => buildCommandPrompt(command, workspace, materializedAttachments, {
36278
+ const promptCompilation = await runExecutionStage("prompt_compilation", () => buildCommandPrompt(executionCommand, workspace, materializedAttachments, {
36215
36279
  runnerKind: config.runnerKind,
36216
36280
  negotiatedCapabilities: command.requiredCapabilities,
36217
36281
  executorKind: executor.kind,
@@ -36604,7 +36668,10 @@ async function executeRunCommand(config, command) {
36604
36668
  rawPath: artifact.relativePath,
36605
36669
  filePath: resolve16(cwd, artifact.relativePath)
36606
36670
  }))
36607
- ) : null;
36671
+ ) : readString(terminalRunDisposition?.disposition) !== "continuation_scheduled" ? await saveIssueCheckpoint(config, command, workspace, [], {
36672
+ requiredPaths: taskSessionCheckpointPaths(workspaceStatus),
36673
+ taskSession: { sessionId: preservedRollout.sessionId }
36674
+ }) : null;
36608
36675
  nativeSessionRollout = {
36609
36676
  status: preservedRollout.status,
36610
36677
  sessionId: preservedRollout.sessionId,
@@ -36633,7 +36700,9 @@ async function executeRunCommand(config, command) {
36633
36700
  }
36634
36701
  const approvedContinuationSucceeded = nativeSessionRequest.mode === "governed_action_approval" && approvedMcpInvocationSucceeded(mcpToolResults, nativeSessionRequest.invocationId);
36635
36702
  if (approvedContinuationSucceeded) {
36636
- await clearIssueCheckpoint(config, command, workspace, "approved_action_succeeded");
36703
+ await clearIssueCheckpoint(config, command, workspace, "approved_action_succeeded", {
36704
+ sourceRunId: nativeSessionRequest.sourceRunId
36705
+ });
36637
36706
  }
36638
36707
  const taskSessionContinuationSucceeded = nativeSessionRequest.mode === "task_session" && asRecord(invocation.nativeSession).used === true && shouldPreserveNativeSession && nativeSessionRollout?.status === "preserved";
36639
36708
  if (managedMcpProfile && (approvedContinuationSucceeded || taskSessionContinuationSucceeded)) {
@@ -7,7 +7,7 @@ import { homedir, hostname } from "node:os";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { BUILD_SUPPORTED_CAPABILITIES } from "./amaster-runtime-daemon/capability-registry.mjs";
9
9
 
10
- const CONNECTOR_VERSION = "0.1.1-beta.248";
10
+ const CONNECTOR_VERSION = "0.1.1-beta.249";
11
11
 
12
12
  const CONFIG_KEY_MAP = new Map([
13
13
  ["server_url", "AMASTER_EMPLOYEE_SERVER_URL"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/employee-runtime-connector",
3
- "version": "0.1.1-beta.248",
3
+ "version": "0.1.1-beta.249",
4
4
  "description": "MirrorX runtime connector CLI and daemon",
5
5
  "license": "MIT",
6
6
  "type": "module",