@askexenow/exe-os 0.9.63 → 0.9.64

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/bin/cli.js CHANGED
@@ -820,7 +820,7 @@ function isLegacySplitPostToolCommand(command) {
820
820
  function textHasLegacySplitPostToolHook(text) {
821
821
  return [EXE_HOOK_FILES.ingest, EXE_HOOK_FILES.errorRecall, EXE_HOOK_FILES.ingestWorker].some((file) => text.includes(file));
822
822
  }
823
- var EXE_HOOK_FILES, EXE_HOOKS, EXE_HOOK_MANIFEST, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
823
+ var EXE_HOOK_FILES, EXE_HOOKS, LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS;
824
824
  var init_runtime_hook_manifest = __esm({
825
825
  "src/adapters/runtime-hook-manifest.ts"() {
826
826
  "use strict";
@@ -844,116 +844,6 @@ var init_runtime_hook_manifest = __esm({
844
844
  notification: "dist/hooks/notification.js",
845
845
  instructionsLoaded: "dist/hooks/instructions-loaded.js"
846
846
  };
847
- EXE_HOOK_MANIFEST = [
848
- {
849
- key: "postToolCombined",
850
- event: "PostToolUse",
851
- commandMarker: EXE_HOOKS.postToolCombined,
852
- owner: "exe-os",
853
- purpose: "Single PostToolUse entrypoint for ingestion, error recall, summaries, and bug detection.",
854
- runtimes: ["claude", "codex", "opencode"],
855
- checkpointRole: "none"
856
- },
857
- {
858
- key: "sessionStart",
859
- event: "SessionStart",
860
- commandMarker: EXE_HOOKS.sessionStart,
861
- owner: "exe-os",
862
- purpose: "Loads agent identity, procedures, and boot context.",
863
- runtimes: ["claude", "codex", "opencode"],
864
- checkpointRole: "none"
865
- },
866
- {
867
- key: "promptSubmit",
868
- event: "UserPromptSubmit",
869
- commandMarker: EXE_HOOKS.promptSubmit,
870
- owner: "exe-os",
871
- purpose: "Injects current tasks, pending reviews, and local context before each prompt.",
872
- runtimes: ["claude", "codex", "opencode"],
873
- checkpointRole: "none"
874
- },
875
- {
876
- key: "heartbeat",
877
- event: "UserPromptSubmit",
878
- commandMarker: EXE_HOOKS.heartbeat,
879
- owner: "exe-os",
880
- purpose: "Lightweight heartbeat/status sidecar for Claude Code sessions.",
881
- runtimes: ["claude"],
882
- checkpointRole: "none"
883
- },
884
- {
885
- key: "stop",
886
- event: "Stop",
887
- commandMarker: EXE_HOOKS.stop,
888
- owner: "exe-os",
889
- purpose: "Finalizes task state, capacity signals, and emergency checkpointing.",
890
- runtimes: ["claude", "codex", "opencode"],
891
- checkpointRole: "capacity_checkpoint"
892
- },
893
- {
894
- key: "preToolUse",
895
- event: "PreToolUse",
896
- commandMarker: EXE_HOOKS.preToolUse,
897
- owner: "exe-os",
898
- purpose: "Preflight guardrails before shell/tool execution.",
899
- runtimes: ["claude", "codex", "opencode"],
900
- checkpointRole: "none"
901
- },
902
- {
903
- key: "subagentStop",
904
- event: "SubagentStop",
905
- commandMarker: EXE_HOOKS.subagentStop,
906
- owner: "exe-os",
907
- purpose: "Captures subagent completion context.",
908
- runtimes: ["claude"],
909
- checkpointRole: "none"
910
- },
911
- {
912
- key: "preCompact",
913
- event: "PreCompact",
914
- commandMarker: EXE_HOOKS.preCompact,
915
- owner: "exe-os",
916
- purpose: "Writes active-task snapshot and compaction recovery context.",
917
- runtimes: ["claude"],
918
- checkpointRole: "recovery_context"
919
- },
920
- {
921
- key: "postCompact",
922
- event: "PostCompact",
923
- commandMarker: EXE_HOOKS.postCompact,
924
- owner: "exe-os",
925
- purpose: "Rehydrates recovery context after compaction.",
926
- runtimes: ["claude"],
927
- checkpointRole: "recovery_context"
928
- },
929
- {
930
- key: "sessionEnd",
931
- event: "SessionEnd",
932
- commandMarker: EXE_HOOKS.sessionEnd,
933
- owner: "exe-os",
934
- purpose: "Stores session-end checkpoint and triages orphaned in-progress tasks.",
935
- runtimes: ["claude"],
936
- checkpointRole: "session_summary"
937
- },
938
- {
939
- key: "notification",
940
- event: "Notification",
941
- commandMarker: EXE_HOOKS.notification,
942
- owner: "exe-os",
943
- purpose: "Captures runtime notifications and nudges.",
944
- runtimes: ["claude"],
945
- checkpointRole: "none"
946
- },
947
- {
948
- key: "instructionsLoaded",
949
- event: "InstructionsLoaded",
950
- commandMarker: EXE_HOOKS.instructionsLoaded,
951
- owner: "exe-os",
952
- purpose: "Applies runtime instruction post-processing.",
953
- runtimes: ["claude"],
954
- checkpointRole: "none"
955
- }
956
- ];
957
847
  LEGACY_SPLIT_POST_TOOL_HOOK_MARKERS = [
958
848
  "dist/hooks/ingest.js",
959
849
  "dist/hooks/error-recall.js",
@@ -17385,7 +17275,13 @@ async function runStackUpdate(options) {
17385
17275
  writeFileSync20(tmp, patched, { mode: 384 });
17386
17276
  renameSync7(tmp, options.envFile);
17387
17277
  const composeArgs = ["compose", "--file", options.composeFile, "--env-file", options.envFile];
17278
+ let registryForLogout;
17388
17279
  try {
17280
+ const creds = await fetchImageCredentials(options);
17281
+ if (creds) {
17282
+ (options.dockerLogin ?? defaultDockerLogin)(creds);
17283
+ registryForLogout = creds.registry;
17284
+ }
17389
17285
  exec2("docker", [...composeArgs, "pull"]);
17390
17286
  exec2("docker", [...composeArgs, "up", "-d"]);
17391
17287
  await verifyReleaseHealth(plan.release, options.healthRetries ?? 12, options.healthDelayMs ?? 5e3);
@@ -17401,8 +17297,28 @@ async function runStackUpdate(options) {
17401
17297
  const reason = err instanceof Error ? err.message : String(err);
17402
17298
  await postDeployAudit(options, "failed", plan.targetVersion, previousVersion, reason, { rollbackAttempted: true });
17403
17299
  throw new Error(`Stack update failed and rollback was attempted: ${reason}`);
17300
+ } finally {
17301
+ if (registryForLogout) {
17302
+ try {
17303
+ (options.dockerLogout ?? defaultDockerLogout)(registryForLogout);
17304
+ } catch {
17305
+ }
17306
+ }
17404
17307
  }
17405
17308
  }
17309
+ async function fetchImageCredentials(options) {
17310
+ if (!options.imageCredentialsUrl) return null;
17311
+ const res = await fetch(options.imageCredentialsUrl, {
17312
+ method: "POST",
17313
+ headers: {
17314
+ "content-type": "application/json",
17315
+ ...options.manifestAuthToken ? { authorization: `Bearer ${options.manifestAuthToken}` } : {}
17316
+ },
17317
+ body: JSON.stringify({ deviceId: options.deviceId, licenseKey: options.licenseKey })
17318
+ });
17319
+ if (!res.ok) throw new Error(`Failed to fetch image credentials: HTTP ${res.status}`);
17320
+ return await res.json();
17321
+ }
17406
17322
  function readCurrentStackVersion(lockFile) {
17407
17323
  if (!existsSync30(lockFile)) return void 0;
17408
17324
  try {
@@ -17466,6 +17382,15 @@ function httpStatus(urlString) {
17466
17382
  function defaultExec(cmd, args2, opts) {
17467
17383
  execFileSync3(cmd, args2, { stdio: "inherit", cwd: opts?.cwd });
17468
17384
  }
17385
+ function defaultDockerLogin(creds) {
17386
+ execFileSync3("docker", ["login", creds.registry, "-u", creds.username, "--password-stdin"], {
17387
+ input: creds.password,
17388
+ stdio: ["pipe", "inherit", "inherit"]
17389
+ });
17390
+ }
17391
+ function defaultDockerLogout(registry) {
17392
+ execFileSync3("docker", ["logout", registry], { stdio: "ignore" });
17393
+ }
17469
17394
  async function defaultFetchText(ref, authToken) {
17470
17395
  const res = await fetch(ref, {
17471
17396
  headers: authToken ? { authorization: `Bearer ${authToken}` } : void 0
@@ -17492,6 +17417,7 @@ function defaultStackPaths() {
17492
17417
  envFile: process.env.EXE_STACK_ENV_FILE || (existsSync30(cwdEnv) ? cwdEnv : "/opt/exe-stack/.env"),
17493
17418
  manifestRef: process.env.EXE_STACK_MANIFEST || "https://update.askexe.com/stack-manifest.json",
17494
17419
  auditUrl: process.env.EXE_STACK_AUDIT_URL || "https://update.askexe.com/v1/deploy-audits",
17420
+ imageCredentialsUrl: process.env.EXE_STACK_IMAGE_CREDENTIALS_URL || "https://update.askexe.com/v1/image-credentials",
17495
17421
  manifestAuthToken: process.env.EXE_STACK_UPDATE_TOKEN,
17496
17422
  manifestPublicKey: loadDefaultPublicKey()
17497
17423
  };
@@ -17522,6 +17448,7 @@ function parseArgs4(args2) {
17522
17448
  composeFile: defaults.composeFile,
17523
17449
  envFile: defaults.envFile,
17524
17450
  auditUrl: defaults.auditUrl,
17451
+ imageCredentialsUrl: defaults.imageCredentialsUrl,
17525
17452
  manifestAuthToken: defaults.manifestAuthToken,
17526
17453
  manifestPublicKey: defaults.manifestPublicKey,
17527
17454
  deviceId: process.env.EXE_DEVICE_ID,
@@ -17551,6 +17478,9 @@ function parseArgs4(args2) {
17551
17478
  else if (arg === "--auth-token-env") opts.manifestAuthToken = process.env[next()] ?? "";
17552
17479
  else if (arg === "--audit-url") opts.auditUrl = next();
17553
17480
  else if (arg.startsWith("--audit-url=")) opts.auditUrl = arg.split("=").slice(1).join("=");
17481
+ else if (arg === "--image-credentials-url") opts.imageCredentialsUrl = next();
17482
+ else if (arg.startsWith("--image-credentials-url=")) opts.imageCredentialsUrl = arg.split("=").slice(1).join("=");
17483
+ else if (arg === "--no-image-credentials") opts.imageCredentialsUrl = void 0;
17554
17484
  else if (arg === "--device-id") opts.deviceId = next();
17555
17485
  else if (arg.startsWith("--device-id=")) opts.deviceId = arg.split("=").slice(1).join("=");
17556
17486
  else if (arg === "--license-key") opts.licenseKey = next();
@@ -17588,6 +17518,8 @@ Options:
17588
17518
  --auth-token <token> Bearer token for private update manifest/audit API
17589
17519
  --auth-token-env <name> Read bearer token from an environment variable
17590
17520
  --audit-url <url> Deploy-audit endpoint (default: EXE_STACK_AUDIT_URL/update.askexe.com)
17521
+ --image-credentials-url <url> Registry credential broker endpoint
17522
+ --no-image-credentials Skip registry credential broker / Docker login
17591
17523
  --device-id <id> Device ID to include in deploy audit
17592
17524
  --license-key <key> License key to include in deploy audit
17593
17525
  --rollback Restore latest backed-up .env and restart stack