agent-transport-system 0.4.91 → 0.4.93

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/dist/ats.js CHANGED
@@ -27,7 +27,7 @@ import wrapAnsi from "wrap-ansi";
27
27
  import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
28
28
 
29
29
  //#region package.json
30
- var version = "0.4.91";
30
+ var version = "0.4.93";
31
31
  var package_default = {
32
32
  $schema: "https://www.schemastore.org/package.json",
33
33
  name: "agent-transport-system",
@@ -7514,7 +7514,7 @@ async function resolveDaemonDeviceId(input) {
7514
7514
  return explicit;
7515
7515
  }
7516
7516
  const persisted = normalizeOptionalText$43(await readFile(input.deviceIdPath, "utf8").catch(() => ""));
7517
- if (persisted) return persisted;
7517
+ if (persisted && !(input.shouldDiscardPersistedDeviceId?.(persisted) ?? false)) return persisted;
7518
7518
  const generated = randomUUID();
7519
7519
  await writeDaemonDeviceId({
7520
7520
  deviceId: generated,
@@ -24267,12 +24267,14 @@ async function resolveLifecycleCommandOptions(input) {
24267
24267
  const preferCommandGateway = shouldPreferCommandResolvedGatewayForLifecycle();
24268
24268
  const gatewayUrl = explicitGatewayUrl ?? (preferCommandGateway ? commandGatewayUrl : null) ?? normalizeGatewayBaseUrlOrNull(currentContract?.gatewayUrl) ?? normalizeGatewayBaseUrlOrNull(runtimeSnapshot?.gatewayUrl) ?? commandGatewayUrl;
24269
24269
  const atsProfileId = normalizeOptionalText$43(input.profile) ?? normalizeOptionalText$43(runtimeSnapshot?.atsProfileId) ?? fallbackProfile?.atsProfileId ?? reusableCurrentContract?.profileId;
24270
+ const shouldDiscardPersistedDeviceId = resolveAtsEnvPreset() === "prod" ? isUnsafeProductionDeviceId : void 0;
24270
24271
  const deviceId = runtimePaths ? await resolveDaemonDeviceId({
24271
24272
  deviceId: resolvePreferredDaemonDeviceId({
24272
24273
  explicitDeviceId: input.deviceId,
24273
24274
  contractDeviceId: reusableCurrentContract?.deviceId
24274
24275
  }),
24275
- deviceIdPath: runtimePaths.deviceIdPath
24276
+ deviceIdPath: runtimePaths.deviceIdPath,
24277
+ ...shouldDiscardPersistedDeviceId ? { shouldDiscardPersistedDeviceId } : {}
24276
24278
  }).catch(() => reusableCurrentContract?.deviceId ?? null) : normalizeOptionalText$43(input.deviceId) ?? reusableCurrentContract?.deviceId ?? null;
24277
24279
  const heartbeatMs = normalizeHeartbeatIntervalMs(input.heartbeatMs ?? currentContract?.heartbeatMs);
24278
24280
  return {
@@ -49843,7 +49845,14 @@ async function attachDaemonReinstallEvidence(input) {
49843
49845
  };
49844
49846
  }
49845
49847
  function buildDaemonReinstallFailureMessage(input) {
49846
- if (input.resolvedView === "human") return `ATS service reinstall failed. ${buildDaemonServiceRefreshNextStep()} For diagnostics, run \`ats service status --view agent\`.`;
49848
+ if (input.resolvedView === "human") {
49849
+ if (input.errorMessage.includes("test fixture identity")) return [
49850
+ "ATS service reinstall failed because this production lane contains old test setup identity that cannot be reused.",
49851
+ "Rerun the setup command from ATS Web so ATS can write a fresh production service contract.",
49852
+ "For diagnostics, run `ats service status --view agent`."
49853
+ ].join(" ");
49854
+ return `ATS service reinstall failed. ${buildDaemonServiceRefreshNextStep()} For diagnostics, run \`ats service status --view agent\`.`;
49855
+ }
49847
49856
  const failureContext = formatDaemonFailureContextText({
49848
49857
  backupDataPath: input.backupDataPath,
49849
49858
  evidencePath: input.evidencePath,
@@ -54120,6 +54129,28 @@ async function resolveDaemonServiceParticipationStatus(input) {
54120
54129
  async function runDaemonServiceParticipationGate(input) {
54121
54130
  if (!shouldRunDaemonServiceParticipationGate(input)) return { status: "aligned" };
54122
54131
  const initialStatus = await resolveDaemonServiceParticipationStatus();
54132
+ if (isRunningAdvisoryOnlyServiceDrift(initialStatus)) {
54133
+ const accountIssue = await resolveDaemonServiceAccountAlignmentIssue(input);
54134
+ if (!accountIssue) return { status: "aligned" };
54135
+ const codePrefix = resolveDaemonServiceParticipationCodePrefix(input.intent);
54136
+ if (input.autoRepair === true) return await runDaemonServiceParticipationRefresh({
54137
+ input,
54138
+ codePrefix,
54139
+ expectedVersion: initialStatus.expectedVersion,
54140
+ accountIssue
54141
+ });
54142
+ renderDaemonStartNeedsAttention({
54143
+ presenter: input.presenter,
54144
+ codePrefix,
54145
+ summary: accountIssue.summary
54146
+ });
54147
+ input.presenter.line({
54148
+ code: `${codePrefix}.account_alignment_failed`,
54149
+ text: accountIssue.summary,
54150
+ data: { reasonCode: accountIssue.reasonCode }
54151
+ });
54152
+ return { status: "needs_attention" };
54153
+ }
54123
54154
  if (input.forceRefresh === true && initialStatus.kind === "ready") return await runDaemonServiceParticipationRefresh({
54124
54155
  input,
54125
54156
  codePrefix: resolveDaemonServiceParticipationCodePrefix(input.intent),
@@ -54160,6 +54191,9 @@ async function runDaemonServiceParticipationGate(input) {
54160
54191
  status: installStageResult.status
54161
54192
  });
54162
54193
  }
54194
+ function isRunningAdvisoryOnlyServiceDrift(status) {
54195
+ return status.kind === "needs_repair" && status.runtimeStatus === "running" && status.anomalyCodes.length > 0 && status.anomalyCodes.every((code) => DAEMON_SERVICE_WAKEABILITY_ADVISORY_ANOMALIES.has(code));
54196
+ }
54163
54197
  function shouldRunDaemonServiceParticipationGate(input) {
54164
54198
  return input.resolvedView === "human" && (input.allowPrompt || input.autoRepair === true) && (input.forcePrompt === true || shouldRequireDaemonServiceParticipation(input.localDemand));
54165
54199
  }
@@ -56930,6 +56964,12 @@ const TERMINAL_PREPARE_STEP_ORDER = [
56930
56964
  "report_runtime",
56931
56965
  "verify_setup"
56932
56966
  ];
56967
+ var PrepareSessionBlockedByCoreError = class extends Error {
56968
+ constructor(message) {
56969
+ super(message);
56970
+ this.name = "PrepareSessionBlockedByCoreError";
56971
+ }
56972
+ };
56933
56973
  async function runPrepareSessionExecutor(input) {
56934
56974
  let initial = await resolvePrepareSessionToken({
56935
56975
  gatewayUrl: input.gatewayUrl,
@@ -57090,11 +57130,18 @@ async function runTerminalStep(input) {
57090
57130
  stepId: input.stepId,
57091
57131
  status: "completed"
57092
57132
  });
57093
- return await input.stream.waitForSnapshot((snapshot) => {
57133
+ const resolvedSnapshot = await input.stream.waitForSnapshot((snapshot) => {
57094
57134
  const step = findStep(snapshot, input.stepId);
57095
- return snapshot.sessionRevision > stepCompleteRevision && step?.state === "complete";
57135
+ return snapshot.sessionRevision > stepCompleteRevision && (step?.state === "complete" || step?.state === "blocked" || snapshot.phase === "blocked" || snapshot.lifecycleStatus !== "active");
57136
+ });
57137
+ assertTerminalStepCompletedOrThrow({
57138
+ input: input.input,
57139
+ snapshot: resolvedSnapshot,
57140
+ stepId: input.stepId
57096
57141
  });
57142
+ return resolvedSnapshot;
57097
57143
  } catch (error) {
57144
+ if (error instanceof PrepareSessionBlockedByCoreError) throw error;
57098
57145
  if (error instanceof PrepareSessionRevisionConflictError) {
57099
57146
  const message = "This setup changed while Terminal was working. Run the same setup command again to continue from the latest step.";
57100
57147
  emitHumanStatus(input.input, "Setup changed", [message]);
@@ -57123,6 +57170,13 @@ async function runTerminalStep(input) {
57123
57170
  throw userFacingError;
57124
57171
  }
57125
57172
  }
57173
+ function assertTerminalStepCompletedOrThrow(input) {
57174
+ if (findStep(input.snapshot, input.stepId)?.state === "complete" && input.snapshot.phase !== "blocked") return;
57175
+ const blocker = input.snapshot.blockers.find((candidate) => candidate.stepId === input.stepId) ?? input.snapshot.blockers[0] ?? null;
57176
+ const message = blocker?.message ?? "ATS setup is blocked. Return to ATS Web for details.";
57177
+ emitHumanStatus(input.input, "Setup blocked", [message, ...blocker?.reasonCode ? [`Support code: ${blocker.reasonCode}`] : []]);
57178
+ throw new PrepareSessionBlockedByCoreError(message);
57179
+ }
57126
57180
  function resolveNextTerminalPrepareStep(snapshot) {
57127
57181
  if (snapshot.selectedLocalAgentIds.length === 0) return null;
57128
57182
  return TERMINAL_PREPARE_STEP_ORDER.find((stepId) => {