@evalops/maestro 0.10.46 → 0.10.48

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.
Files changed (152) hide show
  1. package/README.md +4 -0
  2. package/dist/agent/providers/openai-codex-session.js +1 -1
  3. package/dist/agent/providers/openai-codex-session.js.map +1 -1
  4. package/dist/app-server/in-process-client.d.ts +2 -2
  5. package/dist/app-server/in-process-client.js.map +1 -1
  6. package/dist/app-server/protocol-modes-api.js +1 -1
  7. package/dist/app-server/protocol-modes-api.js.map +1 -1
  8. package/dist/app-server/sandbox-check-api.d.ts +21 -0
  9. package/dist/app-server/{sandbox-proof-api.d.ts.map → sandbox-check-api.d.ts.map} +1 -1
  10. package/dist/app-server/{sandbox-proof-api.js → sandbox-check-api.js} +18 -18
  11. package/dist/app-server/{sandbox-proof-api.js.map → sandbox-check-api.js.map} +1 -1
  12. package/dist/app-server/session-api.d.ts +5 -5
  13. package/dist/app-server/session-api.js +18 -18
  14. package/dist/app-server/session-api.js.map +1 -1
  15. package/dist/audit/logger.d.ts +1 -1
  16. package/dist/cli/args.d.ts.map +1 -1
  17. package/dist/cli/args.js +3 -1
  18. package/dist/cli/args.js.map +1 -1
  19. package/dist/cli/commands/codex.js +30 -3
  20. package/dist/cli/commands/codex.js.map +1 -1
  21. package/dist/cli/commands/update.d.ts +12 -0
  22. package/dist/cli/commands/update.d.ts.map +1 -0
  23. package/dist/cli/commands/update.js +148 -0
  24. package/dist/cli/commands/update.js.map +1 -0
  25. package/dist/cli/help.d.ts.map +1 -1
  26. package/dist/cli/help.js +4 -0
  27. package/dist/cli/help.js.map +1 -1
  28. package/dist/cli-tui/auth-state.d.ts +7 -0
  29. package/dist/cli-tui/auth-state.d.ts.map +1 -0
  30. package/dist/cli-tui/auth-state.js +46 -0
  31. package/dist/cli-tui/auth-state.js.map +1 -0
  32. package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
  33. package/dist/cli-tui/commands/command-catalog.js +8 -3
  34. package/dist/cli-tui/commands/command-catalog.js.map +1 -1
  35. package/dist/cli-tui/commands/command-suite-handlers.d.ts +2 -5
  36. package/dist/cli-tui/commands/command-suite-handlers.d.ts.map +1 -1
  37. package/dist/cli-tui/commands/command-suite-handlers.js.map +1 -1
  38. package/dist/cli-tui/commands/subcommands/auth-commands.d.ts +6 -5
  39. package/dist/cli-tui/commands/subcommands/auth-commands.d.ts.map +1 -1
  40. package/dist/cli-tui/commands/subcommands/auth-commands.js +2 -2
  41. package/dist/cli-tui/commands/subcommands/auth-commands.js.map +1 -1
  42. package/dist/cli-tui/commands/subcommands/ui-commands.d.ts +1 -1
  43. package/dist/cli-tui/commands/subcommands/ui-commands.js +2 -2
  44. package/dist/cli-tui/commands/subcommands/ui-commands.js.map +1 -1
  45. package/dist/cli-tui/footer.d.ts.map +1 -1
  46. package/dist/cli-tui/footer.js +1 -1
  47. package/dist/cli-tui/footer.js.map +1 -1
  48. package/dist/cli-tui/oauth/oauth-flow-controller.d.ts.map +1 -1
  49. package/dist/cli-tui/oauth/oauth-flow-controller.js +24 -11
  50. package/dist/cli-tui/oauth/oauth-flow-controller.js.map +1 -1
  51. package/dist/cli-tui/selectors/oauth-selector-view.d.ts +1 -0
  52. package/dist/cli-tui/selectors/oauth-selector-view.d.ts.map +1 -1
  53. package/dist/cli-tui/selectors/oauth-selector-view.js +1 -1
  54. package/dist/cli-tui/selectors/oauth-selector-view.js.map +1 -1
  55. package/dist/cli-tui/selectors/oauth-selector.d.ts +2 -1
  56. package/dist/cli-tui/selectors/oauth-selector.d.ts.map +1 -1
  57. package/dist/cli-tui/selectors/oauth-selector.js +25 -2
  58. package/dist/cli-tui/selectors/oauth-selector.js.map +1 -1
  59. package/dist/cli-tui/tui-renderer/command-suite-wiring.d.ts +2 -5
  60. package/dist/cli-tui/tui-renderer/command-suite-wiring.d.ts.map +1 -1
  61. package/dist/cli-tui/tui-renderer/command-suite-wiring.js.map +1 -1
  62. package/dist/cli-tui/tui-renderer/ui-state-controller.d.ts +1 -1
  63. package/dist/cli-tui/tui-renderer/ui-state-controller.d.ts.map +1 -1
  64. package/dist/cli-tui/tui-renderer/ui-state-controller.js +5 -11
  65. package/dist/cli-tui/tui-renderer/ui-state-controller.js.map +1 -1
  66. package/dist/cli-tui/tui-renderer.d.ts +0 -4
  67. package/dist/cli-tui/tui-renderer.d.ts.map +1 -1
  68. package/dist/cli-tui/tui-renderer.js +4 -29
  69. package/dist/cli-tui/tui-renderer.js.map +1 -1
  70. package/dist/cli-tui/ui-state.js +1 -1
  71. package/dist/cli-tui/ui-state.js.map +1 -1
  72. package/dist/cli-tui/utils/footer-utils.d.ts +1 -1
  73. package/dist/cli-tui/utils/footer-utils.d.ts.map +1 -1
  74. package/dist/cli-tui/utils/footer-utils.js.map +1 -1
  75. package/dist/cli.js +4800 -3779
  76. package/dist/cli.js.map +1 -1
  77. package/dist/codex/app-server-client.d.ts +16 -2
  78. package/dist/codex/app-server-client.d.ts.map +1 -1
  79. package/dist/codex/app-server-client.js +67 -7
  80. package/dist/codex/app-server-client.js.map +1 -1
  81. package/dist/codex/auth.d.ts +4 -0
  82. package/dist/codex/auth.d.ts.map +1 -0
  83. package/dist/codex/auth.js +103 -0
  84. package/dist/codex/auth.js.map +1 -0
  85. package/dist/db/schema.d.ts +1 -1
  86. package/dist/evalops/agent-bootstrap.js +2 -2
  87. package/dist/evalops/agent-bootstrap.js.map +1 -1
  88. package/dist/main.d.ts.map +1 -1
  89. package/dist/main.js +10 -1
  90. package/dist/main.js.map +1 -1
  91. package/dist/models/config-loader.d.ts +12 -12
  92. package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +19 -19
  93. package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -1
  94. package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js +12 -13
  95. package/dist/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -1
  96. package/dist/node_modules/@evalops/contracts/dist/scenario.d.ts +2 -0
  97. package/dist/node_modules/@evalops/contracts/dist/scenario.d.ts.map +1 -1
  98. package/dist/node_modules/@evalops/contracts/dist/scenario.js.map +1 -1
  99. package/dist/node_modules/@evalops/contracts/package.json +1 -1
  100. package/dist/node_modules/@evalops/tui/package.json +1 -1
  101. package/dist/oauth/index.d.ts +1 -0
  102. package/dist/oauth/index.d.ts.map +1 -1
  103. package/dist/oauth/index.js +42 -2
  104. package/dist/oauth/index.js.map +1 -1
  105. package/dist/platform/operating-plane-client.d.ts +3 -3
  106. package/dist/platform/operating-plane-client.d.ts.map +1 -1
  107. package/dist/platform/operating-plane-client.js.map +1 -1
  108. package/dist/platform/operating-plane-summary.js +3 -6
  109. package/dist/platform/operating-plane-summary.js.map +1 -1
  110. package/dist/server/agent-trajectory-scenarios.d.ts.map +1 -1
  111. package/dist/server/agent-trajectory-scenarios.js +29 -6
  112. package/dist/server/agent-trajectory-scenarios.js.map +1 -1
  113. package/dist/server/app-context.d.ts +2 -0
  114. package/dist/server/app-context.d.ts.map +1 -1
  115. package/dist/server/app-context.js.map +1 -1
  116. package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
  117. package/dist/server/handlers/headless-sessions.js +44 -10
  118. package/dist/server/handlers/headless-sessions.js.map +1 -1
  119. package/dist/server/handlers/hosted-runner-identity.d.ts +2 -0
  120. package/dist/server/handlers/hosted-runner-identity.d.ts.map +1 -1
  121. package/dist/server/handlers/hosted-runner-identity.js +2 -0
  122. package/dist/server/handlers/hosted-runner-identity.js.map +1 -1
  123. package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -1
  124. package/dist/server/handlers/platform-a2a-push.js +113 -2
  125. package/dist/server/handlers/platform-a2a-push.js.map +1 -1
  126. package/dist/server/handlers/ui.d.ts.map +1 -1
  127. package/dist/server/handlers/ui.js +5 -5
  128. package/dist/server/handlers/ui.js.map +1 -1
  129. package/dist/server/headless-in-process-host.d.ts.map +1 -1
  130. package/dist/server/headless-in-process-host.js +1 -1
  131. package/dist/server/headless-in-process-host.js.map +1 -1
  132. package/dist/server/headless-runtime-service.d.ts +9 -2
  133. package/dist/server/headless-runtime-service.d.ts.map +1 -1
  134. package/dist/server/headless-runtime-service.js +54 -15
  135. package/dist/server/headless-runtime-service.js.map +1 -1
  136. package/dist/server/stores/ui-store.d.ts.map +1 -1
  137. package/dist/server/stores/ui-store.js +8 -1
  138. package/dist/server/stores/ui-store.js.map +1 -1
  139. package/dist/tools/background/task-runtime.js +1 -1
  140. package/dist/tools/background/task-runtime.js.map +1 -1
  141. package/dist/tools/background/task-types.d.ts +1 -1
  142. package/dist/update/check.d.ts +2 -0
  143. package/dist/update/check.d.ts.map +1 -1
  144. package/dist/update/check.js +100 -41
  145. package/dist/update/check.js.map +1 -1
  146. package/dist/update/startup-refresh.d.ts +56 -0
  147. package/dist/update/startup-refresh.d.ts.map +1 -0
  148. package/dist/update/startup-refresh.js +321 -0
  149. package/dist/update/startup-refresh.js.map +1 -0
  150. package/dist/version.json +2 -2
  151. package/package.json +297 -296
  152. package/dist/app-server/sandbox-proof-api.d.ts +0 -21
@@ -1 +1 @@
1
- {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../../src/server/stores/ui-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAWzD,UAAU,WAAW;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAmCD,wBAAgB,cAAc,IAAI,WAAW,CAI5C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAIvD;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,GACf,OAAO,CAKT"}
1
+ {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../../src/server/stores/ui-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAWzD,UAAU,WAAW;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAyCD,wBAAgB,cAAc,IAAI,WAAW,CAI5C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAIvD;AAED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,MAAM,GACf,OAAO,CAKT"}
@@ -9,6 +9,13 @@ const KEY_REGEX = /^[A-Za-z0-9._-]+$/;
9
9
  function sanitizeKey(key) {
10
10
  return KEY_REGEX.test(key) ? key : null;
11
11
  }
12
+ function normalizeFooterMode(value) {
13
+ if (value === "rich" || value === "solo")
14
+ return value;
15
+ if (value === "ensemble")
16
+ return "rich";
17
+ return undefined;
18
+ }
12
19
  function normalize(raw) {
13
20
  if (!raw || typeof raw !== "object" || !("sessions" in raw)) {
14
21
  return { sessions: {} };
@@ -28,7 +35,7 @@ function normalize(raw) {
28
35
  steeringMode: state.steeringMode,
29
36
  followUpMode: state.followUpMode,
30
37
  compactTools: state.compactTools,
31
- footerMode: state.footerMode,
38
+ footerMode: normalizeFooterMode(state.footerMode),
32
39
  cleanMode: state.cleanMode,
33
40
  reducedMotion: state.reducedMotion,
34
41
  recentCommands: state.recentCommands,
@@ -1 +1 @@
1
- {"version":3,"file":"ui-store.js","sourceRoot":"","sources":["../../../src/server/stores/ui-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport type { UiState } from \"../../cli-tui/ui-state.js\";\nimport { getAgentDir } from \"../../config/constants.js\";\nimport { tryParseJson } from \"../../utils/json.js\";\nimport { resolveEnvPath } from \"../../utils/path-expansion.js\";\n\nconst UI_STATE_PATH =\n\tresolveEnvPath(process.env.MAESTRO_WEB_UI_STATE) ??\n\tresolve(getAgentDir(), \"web-ui-state.json\");\n\nconst KEY_REGEX = /^[A-Za-z0-9._-]+$/;\n\ninterface UiStateFile {\n\tsessions: Record<string, UiState>;\n}\n\nfunction sanitizeKey(key: string): string | null {\n\treturn KEY_REGEX.test(key) ? key : null;\n}\n\nfunction normalize(raw: unknown): UiStateFile {\n\tif (!raw || typeof raw !== \"object\" || !(\"sessions\" in raw)) {\n\t\treturn { sessions: {} };\n\t}\n\tconst sessions = (raw as { sessions?: unknown }).sessions;\n\tif (!sessions || typeof sessions !== \"object\") return { sessions: {} };\n\tconst result: Record<string, UiState> = {};\n\tfor (const [k, v] of Object.entries(sessions as Record<string, unknown>)) {\n\t\tconst key = sanitizeKey(k);\n\t\tif (!key) continue;\n\t\tif (v && typeof v === \"object\") {\n\t\t\tconst state = v as UiState;\n\t\t\tresult[key] = {\n\t\t\t\tqueueMode: state.queueMode,\n\t\t\t\tsteeringMode: state.steeringMode,\n\t\t\t\tfollowUpMode: state.followUpMode,\n\t\t\t\tcompactTools: state.compactTools,\n\t\t\t\tfooterMode: state.footerMode,\n\t\t\t\tcleanMode: state.cleanMode,\n\t\t\t\treducedMotion: state.reducedMotion,\n\t\t\t\trecentCommands: state.recentCommands,\n\t\t\t\tfavoriteCommands: state.favoriteCommands,\n\t\t\t\tzenMode: state.zenMode,\n\t\t\t};\n\t\t}\n\t}\n\treturn { sessions: result };\n}\n\nexport function loadWebUiState(): UiStateFile {\n\tif (!existsSync(UI_STATE_PATH)) return { sessions: {} };\n\tconst raw = tryParseJson(readFileSync(UI_STATE_PATH, \"utf-8\"));\n\treturn normalize(raw);\n}\n\nexport function saveWebUiState(state: UiStateFile): void {\n\tconst normalized = normalize(state);\n\tmkdirSync(dirname(UI_STATE_PATH), { recursive: true });\n\twriteFileSync(UI_STATE_PATH, JSON.stringify(normalized, null, 2), \"utf-8\");\n}\n\nexport function getSessionUiState(\n\tstate: UiStateFile,\n\tsessionId: string,\n): UiState {\n\tconst key = sanitizeKey(sessionId);\n\tif (!key) throw new Error(\"Invalid sessionId format\");\n\tif (!state.sessions[key]) state.sessions[key] = {};\n\treturn state.sessions[key];\n}\n"]}
1
+ {"version":3,"file":"ui-store.js","sourceRoot":"","sources":["../../../src/server/stores/ui-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport type { UiState } from \"../../cli-tui/ui-state.js\";\nimport { getAgentDir } from \"../../config/constants.js\";\nimport { tryParseJson } from \"../../utils/json.js\";\nimport { resolveEnvPath } from \"../../utils/path-expansion.js\";\n\nconst UI_STATE_PATH =\n\tresolveEnvPath(process.env.MAESTRO_WEB_UI_STATE) ??\n\tresolve(getAgentDir(), \"web-ui-state.json\");\n\nconst KEY_REGEX = /^[A-Za-z0-9._-]+$/;\n\ninterface UiStateFile {\n\tsessions: Record<string, UiState>;\n}\n\nfunction sanitizeKey(key: string): string | null {\n\treturn KEY_REGEX.test(key) ? key : null;\n}\n\nfunction normalizeFooterMode(value: unknown): UiState[\"footerMode\"] {\n\tif (value === \"rich\" || value === \"solo\") return value;\n\tif (value === \"ensemble\") return \"rich\";\n\treturn undefined;\n}\n\nfunction normalize(raw: unknown): UiStateFile {\n\tif (!raw || typeof raw !== \"object\" || !(\"sessions\" in raw)) {\n\t\treturn { sessions: {} };\n\t}\n\tconst sessions = (raw as { sessions?: unknown }).sessions;\n\tif (!sessions || typeof sessions !== \"object\") return { sessions: {} };\n\tconst result: Record<string, UiState> = {};\n\tfor (const [k, v] of Object.entries(sessions as Record<string, unknown>)) {\n\t\tconst key = sanitizeKey(k);\n\t\tif (!key) continue;\n\t\tif (v && typeof v === \"object\") {\n\t\t\tconst state = v as UiState;\n\t\t\tresult[key] = {\n\t\t\t\tqueueMode: state.queueMode,\n\t\t\t\tsteeringMode: state.steeringMode,\n\t\t\t\tfollowUpMode: state.followUpMode,\n\t\t\t\tcompactTools: state.compactTools,\n\t\t\t\tfooterMode: normalizeFooterMode(state.footerMode),\n\t\t\t\tcleanMode: state.cleanMode,\n\t\t\t\treducedMotion: state.reducedMotion,\n\t\t\t\trecentCommands: state.recentCommands,\n\t\t\t\tfavoriteCommands: state.favoriteCommands,\n\t\t\t\tzenMode: state.zenMode,\n\t\t\t};\n\t\t}\n\t}\n\treturn { sessions: result };\n}\n\nexport function loadWebUiState(): UiStateFile {\n\tif (!existsSync(UI_STATE_PATH)) return { sessions: {} };\n\tconst raw = tryParseJson(readFileSync(UI_STATE_PATH, \"utf-8\"));\n\treturn normalize(raw);\n}\n\nexport function saveWebUiState(state: UiStateFile): void {\n\tconst normalized = normalize(state);\n\tmkdirSync(dirname(UI_STATE_PATH), { recursive: true });\n\twriteFileSync(UI_STATE_PATH, JSON.stringify(normalized, null, 2), \"utf-8\");\n}\n\nexport function getSessionUiState(\n\tstate: UiStateFile,\n\tsessionId: string,\n): UiState {\n\tconst key = sanitizeKey(sessionId);\n\tif (!key) throw new Error(\"Invalid sessionId format\");\n\tif (!state.sessions[key]) state.sessions[key] = {};\n\treturn state.sessions[key];\n}\n"]}
@@ -331,7 +331,7 @@ export class BackgroundTaskRuntime {
331
331
  };
332
332
  attach(child.stdout);
333
333
  attach(child.stderr);
334
- child.once("exit", closeStream);
334
+ child.once("close", closeStream);
335
335
  child.once("error", closeStream);
336
336
  }
337
337
  }
@@ -1 +1 @@
1
- {"version":3,"file":"task-runtime.js","sourceRoot":"","sources":["../../../src/tools/background/task-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ChildProcess,\n\ttype SpawnOptions,\n\tspawn,\n} from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\n\nimport {\n\tgetShellConfig,\n\tkillProcessTree,\n\tparseCommandArguments,\n} from \"../shell-utils.js\";\nimport { ToolError } from \"../tool-dsl.js\";\nimport {\n\tResourceMonitor,\n\ttype RestartPolicy,\n\tRotatingLogWriter,\n\tcanRestart,\n\tcomputeRestartDelay,\n\tincrementAttempts,\n} from \"./index.js\";\nimport { archivedLogPath, rotateArchives } from \"./log-files.js\";\nimport { evaluateResourceLimitBreach } from \"./resource-limits.js\";\nimport type {\n\tBackgroundTask,\n\tBackgroundTaskHistoryEvent,\n\tBackgroundTaskNotification,\n\tChildProcessWithUsage,\n} from \"./task-types.js\";\n\nconst RESOURCE_POLL_INTERVAL_MS = 200;\n\nexport interface BackgroundTaskRuntimeHooks {\n\temitTaskNotification: (payload: BackgroundTaskNotification) => void;\n\temitTaskTelemetry: (\n\t\ttask: BackgroundTask,\n\t\tevent: BackgroundTaskHistoryEvent,\n\t) => void;\n\tmaybeNotifyRestart: (task: BackgroundTask, policy: RestartPolicy) => void;\n\tnotifyFailure: (\n\t\ttask: BackgroundTask,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t) => void;\n\tscheduleCleanup: (task: BackgroundTask) => void;\n\tsetFailureReason: (task: BackgroundTask, reason: string) => void;\n}\n\nexport class BackgroundTaskRuntime {\n\tconstructor(\n\t\tprivate readonly hooks: BackgroundTaskRuntimeHooks,\n\t\tprivate readonly resourceMonitor = new ResourceMonitor(),\n\t) {}\n\n\tlaunchProcess(task: BackgroundTask): void {\n\t\tconst child = this.createChildProcess(task);\n\t\tthis.attachLogging(child, task);\n\t\ttask.process = child;\n\t\ttask.failureReason = undefined;\n\t\ttask.lastLimitBreach = undefined;\n\t\ttask.pid = child.pid ?? undefined;\n\t\tthis.startUsageMonitor(task);\n\t\ttask.status = \"running\";\n\t\ttask.stopRequested = false;\n\t\ttask.exitCode = undefined;\n\t\ttask.signal = undefined;\n\t\ttask.finishedAt = undefined;\n\t\ttask.completion = new Promise<void>((resolve) => {\n\t\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\t\tthis.handleChildExit(task, child, resolve, code, signal);\n\t\t\t});\n\t\t\tchild.once(\"error\", (error) => {\n\t\t\t\tthis.handleChildError(task, child, resolve, error);\n\t\t\t});\n\t\t});\n\t\tthis.hooks.emitTaskTelemetry(task, \"started\");\n\t}\n\n\tstopUsageMonitor(task: BackgroundTask): void {\n\t\tif (task.usageMonitor) {\n\t\t\tclearInterval(task.usageMonitor);\n\t\t\ttask.usageMonitor = null;\n\t\t}\n\t}\n\n\tdisableRestart(task: BackgroundTask): void {\n\t\tthis.cancelRestart(task);\n\t\ttask.restartPolicy = undefined;\n\t}\n\n\tdisposeTask(task: BackgroundTask): void {\n\t\tthis.cancelRestart(task);\n\t\tthis.stopUsageMonitor(task);\n\t}\n\n\tprivate createChildProcess(task: BackgroundTask): ChildProcess {\n\t\tconst mergedEnv: NodeJS.ProcessEnv = task.env;\n\t\tconst spawnOptions: SpawnOptions = {\n\t\t\tdetached: true,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\tcwd: task.cwd,\n\t\t\tenv: mergedEnv,\n\t\t};\n\t\tif (task.shellMode === \"shell\") {\n\t\t\tconst { shell, args } = getShellConfig();\n\t\t\treturn spawn(shell, [...args, task.command], spawnOptions);\n\t\t}\n\t\tlet parsed: string[];\n\t\ttry {\n\t\t\tparsed = parseCommandArguments(task.command);\n\t\t} catch (error) {\n\t\t\tthrow new ToolError(\n\t\t\t\terror instanceof Error\n\t\t\t\t\t? error.message\n\t\t\t\t\t: \"Failed to parse command arguments\",\n\t\t\t);\n\t\t}\n\t\tif (parsed.length === 0) {\n\t\t\tthrow new ToolError(\"Command must contain an executable to run\");\n\t\t}\n\t\treturn spawn(parsed[0]!, parsed.slice(1), spawnOptions);\n\t}\n\n\tprivate handleChildExit(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t\tresolve: () => void,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t): void {\n\t\tif (task.process !== child) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.exitCode = code;\n\t\ttask.signal = signal;\n\t\ttask.pid = undefined;\n\t\tthis.stopUsageMonitor(task);\n\t\tthis.captureResourceUsage(task, child);\n\t\ttask.terminatingForLimits = false;\n\t\tconst forcedFailure = Boolean(task.failureReason);\n\t\tif (forcedFailure) {\n\t\t\tthis.disableRestart(task);\n\t\t}\n\t\tif (task.stopRequested) {\n\t\t\ttask.status = \"stopped\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.hooks.scheduleCleanup(task);\n\t\t\tthis.hooks.emitTaskTelemetry(task, \"stopped\");\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tif (!forcedFailure && code === 0) {\n\t\t\ttask.status = \"exited\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.hooks.scheduleCleanup(task);\n\t\t\tthis.hooks.emitTaskTelemetry(task, \"exited\");\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tif (!forcedFailure && this.scheduleRestart(task)) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.status = \"failed\";\n\t\ttask.finishedAt = Date.now();\n\t\tthis.hooks.scheduleCleanup(task);\n\t\tthis.hooks.emitTaskTelemetry(task, \"failed\");\n\t\tif (!forcedFailure) {\n\t\t\tthis.hooks.notifyFailure(task, code, signal);\n\t\t}\n\t\tresolve();\n\t}\n\n\tprivate handleChildError(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t\tresolve: () => void,\n\t\t_error: Error,\n\t): void {\n\t\tif (task.process !== child) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.pid = undefined;\n\t\tthis.stopUsageMonitor(task);\n\t\tthis.captureResourceUsage(task, child);\n\t\ttask.terminatingForLimits = false;\n\t\tconst forcedFailure = Boolean(task.failureReason);\n\t\tif (forcedFailure) {\n\t\t\tthis.disableRestart(task);\n\t\t}\n\t\tif (!forcedFailure && this.scheduleRestart(task)) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.status = \"failed\";\n\t\ttask.finishedAt = Date.now();\n\t\tthis.hooks.scheduleCleanup(task);\n\t\tthis.hooks.emitTaskTelemetry(task, \"failed\");\n\t\tif (!forcedFailure) {\n\t\t\tthis.hooks.notifyFailure(task, null, null);\n\t\t}\n\t\tresolve();\n\t}\n\n\tprivate captureResourceUsage(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t): void {\n\t\tconst { resourceUsage } = child as ChildProcessWithUsage;\n\t\tif (typeof resourceUsage !== \"function\") {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst usage = resourceUsage.call(child);\n\t\t\tif (!task.resourceUsage) {\n\t\t\t\ttask.resourceUsage = {};\n\t\t\t}\n\t\t\tconst target = task.resourceUsage;\n\t\t\tif (usage.maxRSS) {\n\t\t\t\ttarget.maxRssKb = Math.max(target.maxRssKb ?? 0, usage.maxRSS);\n\t\t\t}\n\t\t\tif (usage.userCPUTime) {\n\t\t\t\ttarget.userMs = Math.max(target.userMs ?? 0, usage.userCPUTime / 1000);\n\t\t\t}\n\t\t\tif (usage.systemCPUTime) {\n\t\t\t\ttarget.systemMs = Math.max(\n\t\t\t\t\ttarget.systemMs ?? 0,\n\t\t\t\t\tusage.systemCPUTime / 1000,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore metrics errors\n\t\t}\n\t\tthis.enforceRuntimeLimits(task);\n\t}\n\n\tprivate scheduleRestart(task: BackgroundTask): boolean {\n\t\tconst policy = task.restartPolicy;\n\t\tif (!policy || task.stopRequested) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!canRestart(policy)) {\n\t\t\treturn false;\n\t\t}\n\t\tincrementAttempts(policy);\n\t\ttask.status = \"restarting\";\n\t\tthis.hooks.emitTaskTelemetry(task, \"restarted\");\n\t\tthis.hooks.maybeNotifyRestart(task, policy);\n\t\tthis.cancelRestart(task);\n\t\tconst delay = computeRestartDelay(policy);\n\t\ttask.restartTimer = setTimeout(() => {\n\t\t\ttask.restartTimer = null;\n\t\t\tthis.launchProcess(task);\n\t\t}, delay);\n\t\tif (task.restartTimer.unref) {\n\t\t\ttask.restartTimer.unref();\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate cancelRestart(task: BackgroundTask): void {\n\t\tif (task.restartTimer) {\n\t\t\tclearTimeout(task.restartTimer);\n\t\t\ttask.restartTimer = null;\n\t\t}\n\t}\n\n\tprivate startUsageMonitor(task: BackgroundTask): void {\n\t\tif (!task.pid || task.usageMonitor) {\n\t\t\treturn;\n\t\t}\n\t\tconst mode = this.getMonitoringMode();\n\t\ttask.monitoringMode = mode;\n\t\tif (mode === \"disabled\") {\n\t\t\treturn;\n\t\t}\n\t\tthis.sampleResourceUsage(task);\n\t\tconst monitor = setInterval(() => {\n\t\t\tthis.sampleResourceUsage(task);\n\t\t}, RESOURCE_POLL_INTERVAL_MS);\n\t\tif (monitor.unref) {\n\t\t\tmonitor.unref();\n\t\t}\n\t\ttask.usageMonitor = monitor;\n\t}\n\n\tprivate getMonitoringMode(): \"proc\" | \"ps\" | \"disabled\" {\n\t\treturn this.resourceMonitor.getMode();\n\t}\n\n\tprivate sampleResourceUsage(task: BackgroundTask): void {\n\t\tif (!task.pid) {\n\t\t\tthis.stopUsageMonitor(task);\n\t\t\treturn;\n\t\t}\n\t\tconst usage = this.resourceMonitor.getUsage(task.pid);\n\t\tif (!usage) {\n\t\t\tif (task.monitoringMode === \"ps\") {\n\t\t\t\tthis.stopUsageMonitor(task);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!task.resourceUsage) {\n\t\t\ttask.resourceUsage = {};\n\t\t}\n\t\tconst target = task.resourceUsage;\n\t\tif (usage.maxRssKb !== undefined) {\n\t\t\ttarget.maxRssKb = Math.max(target.maxRssKb ?? 0, usage.maxRssKb);\n\t\t}\n\t\tif (usage.userMs !== undefined) {\n\t\t\ttarget.userMs = Math.max(target.userMs ?? 0, usage.userMs);\n\t\t}\n\t\tif (usage.systemMs !== undefined) {\n\t\t\ttarget.systemMs = Math.max(target.systemMs ?? 0, usage.systemMs);\n\t\t}\n\t\tthis.enforceRuntimeLimits(task);\n\t}\n\n\tprivate enforceRuntimeLimits(task: BackgroundTask): void {\n\t\tif (!task.resourceUsage || task.terminatingForLimits) {\n\t\t\treturn;\n\t\t}\n\t\tconst breach = evaluateResourceLimitBreach(task.resourceUsage, task.limits);\n\t\tif (!breach || task.failureReason) {\n\t\t\treturn;\n\t\t}\n\t\tconst describe =\n\t\t\tbreach.kind === \"memory\"\n\t\t\t\t? `${(breach.actual / 1024).toFixed(1)}MB > ${(breach.limit / 1024).toFixed(1)}MB`\n\t\t\t\t: `${Math.round(breach.actual)}ms > ${Math.round(breach.limit)}ms`;\n\t\tthis.hooks.setFailureReason(\n\t\t\ttask,\n\t\t\t`Resource limit (${breach.kind} ${describe})`,\n\t\t);\n\t\ttask.lastLimitBreach = breach;\n\t\ttask.terminatingForLimits = true;\n\t\tthis.disableRestart(task);\n\t\tif (!task.pid) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tkillProcessTree(task.pid);\n\t\t} catch (error) {\n\t\t\tconst errMessage =\n\t\t\t\terror instanceof Error ? error.message : \"Failed to terminate process\";\n\t\t\tthis.hooks.emitTaskNotification({\n\t\t\t\ttaskId: task.id,\n\t\t\t\tstatus: task.status,\n\t\t\t\tcommand: task.command,\n\t\t\t\tkind: \"limit\",\n\t\t\t\tlevel: \"warn\",\n\t\t\t\treason: `${task.failureReason}; kill error: ${errMessage}`,\n\t\t\t\tmessage: \"resource limit hit but termination failed\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.hooks.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"limit\",\n\t\t\tlevel: \"warn\",\n\t\t\treason: task.failureReason,\n\t\t\tmessage: \"exceeded resource limits; terminating\",\n\t\t});\n\t}\n\n\tprivate attachLogging(child: ChildProcess, task: BackgroundTask): void {\n\t\tlet existingSize = 0;\n\t\ttry {\n\t\t\texistingSize = statSync(task.logPath).size;\n\t\t} catch {\n\t\t\t// File may not exist yet\n\t\t}\n\t\tconst writer = new RotatingLogWriter({\n\t\t\tlimit: task.limits.logSizeLimit,\n\t\t\tsegments: task.limits.logSegments,\n\t\t\tlogPath: task.logPath,\n\t\t\texistingSize,\n\t\t\tmarkTruncated: () => {\n\t\t\t\ttask.logTruncated = true;\n\t\t\t},\n\t\t\tshiftArchives: () =>\n\t\t\t\trotateArchives(task.logPath, task.limits.logSegments),\n\t\t\tarchivedPath: (index) => archivedLogPath(task.logPath, index),\n\t\t});\n\t\ttask.logWriter = writer;\n\n\t\tlet closed = false;\n\t\tconst closeStream = () => {\n\t\t\tif (closed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tclosed = true;\n\t\t\twriter.end();\n\t\t};\n\n\t\tconst attach = (source?: NodeJS.ReadableStream | null) => {\n\t\t\tif (!source) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsource.pipe(writer, { end: false });\n\t\t\tsource.on(\"error\", () => {\n\t\t\t\ttask.logTruncated = true;\n\t\t\t\tcloseStream();\n\t\t\t});\n\t\t};\n\n\t\tattach(child.stdout);\n\t\tattach(child.stderr);\n\n\t\tchild.once(\"exit\", closeStream);\n\t\tchild.once(\"error\", closeStream);\n\t}\n}\n"]}
1
+ {"version":3,"file":"task-runtime.js","sourceRoot":"","sources":["../../../src/tools/background/task-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\ttype ChildProcess,\n\ttype SpawnOptions,\n\tspawn,\n} from \"node:child_process\";\nimport { existsSync, statSync } from \"node:fs\";\n\nimport {\n\tgetShellConfig,\n\tkillProcessTree,\n\tparseCommandArguments,\n} from \"../shell-utils.js\";\nimport { ToolError } from \"../tool-dsl.js\";\nimport {\n\tResourceMonitor,\n\ttype RestartPolicy,\n\tRotatingLogWriter,\n\tcanRestart,\n\tcomputeRestartDelay,\n\tincrementAttempts,\n} from \"./index.js\";\nimport { archivedLogPath, rotateArchives } from \"./log-files.js\";\nimport { evaluateResourceLimitBreach } from \"./resource-limits.js\";\nimport type {\n\tBackgroundTask,\n\tBackgroundTaskHistoryEvent,\n\tBackgroundTaskNotification,\n\tChildProcessWithUsage,\n} from \"./task-types.js\";\n\nconst RESOURCE_POLL_INTERVAL_MS = 200;\n\nexport interface BackgroundTaskRuntimeHooks {\n\temitTaskNotification: (payload: BackgroundTaskNotification) => void;\n\temitTaskTelemetry: (\n\t\ttask: BackgroundTask,\n\t\tevent: BackgroundTaskHistoryEvent,\n\t) => void;\n\tmaybeNotifyRestart: (task: BackgroundTask, policy: RestartPolicy) => void;\n\tnotifyFailure: (\n\t\ttask: BackgroundTask,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t) => void;\n\tscheduleCleanup: (task: BackgroundTask) => void;\n\tsetFailureReason: (task: BackgroundTask, reason: string) => void;\n}\n\nexport class BackgroundTaskRuntime {\n\tconstructor(\n\t\tprivate readonly hooks: BackgroundTaskRuntimeHooks,\n\t\tprivate readonly resourceMonitor = new ResourceMonitor(),\n\t) {}\n\n\tlaunchProcess(task: BackgroundTask): void {\n\t\tconst child = this.createChildProcess(task);\n\t\tthis.attachLogging(child, task);\n\t\ttask.process = child;\n\t\ttask.failureReason = undefined;\n\t\ttask.lastLimitBreach = undefined;\n\t\ttask.pid = child.pid ?? undefined;\n\t\tthis.startUsageMonitor(task);\n\t\ttask.status = \"running\";\n\t\ttask.stopRequested = false;\n\t\ttask.exitCode = undefined;\n\t\ttask.signal = undefined;\n\t\ttask.finishedAt = undefined;\n\t\ttask.completion = new Promise<void>((resolve) => {\n\t\t\tchild.once(\"exit\", (code, signal) => {\n\t\t\t\tthis.handleChildExit(task, child, resolve, code, signal);\n\t\t\t});\n\t\t\tchild.once(\"error\", (error) => {\n\t\t\t\tthis.handleChildError(task, child, resolve, error);\n\t\t\t});\n\t\t});\n\t\tthis.hooks.emitTaskTelemetry(task, \"started\");\n\t}\n\n\tstopUsageMonitor(task: BackgroundTask): void {\n\t\tif (task.usageMonitor) {\n\t\t\tclearInterval(task.usageMonitor);\n\t\t\ttask.usageMonitor = null;\n\t\t}\n\t}\n\n\tdisableRestart(task: BackgroundTask): void {\n\t\tthis.cancelRestart(task);\n\t\ttask.restartPolicy = undefined;\n\t}\n\n\tdisposeTask(task: BackgroundTask): void {\n\t\tthis.cancelRestart(task);\n\t\tthis.stopUsageMonitor(task);\n\t}\n\n\tprivate createChildProcess(task: BackgroundTask): ChildProcess {\n\t\tconst mergedEnv: NodeJS.ProcessEnv = task.env;\n\t\tconst spawnOptions: SpawnOptions = {\n\t\t\tdetached: true,\n\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\tcwd: task.cwd,\n\t\t\tenv: mergedEnv,\n\t\t};\n\t\tif (task.shellMode === \"shell\") {\n\t\t\tconst { shell, args } = getShellConfig();\n\t\t\treturn spawn(shell, [...args, task.command], spawnOptions);\n\t\t}\n\t\tlet parsed: string[];\n\t\ttry {\n\t\t\tparsed = parseCommandArguments(task.command);\n\t\t} catch (error) {\n\t\t\tthrow new ToolError(\n\t\t\t\terror instanceof Error\n\t\t\t\t\t? error.message\n\t\t\t\t\t: \"Failed to parse command arguments\",\n\t\t\t);\n\t\t}\n\t\tif (parsed.length === 0) {\n\t\t\tthrow new ToolError(\"Command must contain an executable to run\");\n\t\t}\n\t\treturn spawn(parsed[0]!, parsed.slice(1), spawnOptions);\n\t}\n\n\tprivate handleChildExit(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t\tresolve: () => void,\n\t\tcode: number | null,\n\t\tsignal: NodeJS.Signals | null,\n\t): void {\n\t\tif (task.process !== child) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.exitCode = code;\n\t\ttask.signal = signal;\n\t\ttask.pid = undefined;\n\t\tthis.stopUsageMonitor(task);\n\t\tthis.captureResourceUsage(task, child);\n\t\ttask.terminatingForLimits = false;\n\t\tconst forcedFailure = Boolean(task.failureReason);\n\t\tif (forcedFailure) {\n\t\t\tthis.disableRestart(task);\n\t\t}\n\t\tif (task.stopRequested) {\n\t\t\ttask.status = \"stopped\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.hooks.scheduleCleanup(task);\n\t\t\tthis.hooks.emitTaskTelemetry(task, \"stopped\");\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tif (!forcedFailure && code === 0) {\n\t\t\ttask.status = \"exited\";\n\t\t\ttask.finishedAt = Date.now();\n\t\t\tthis.hooks.scheduleCleanup(task);\n\t\t\tthis.hooks.emitTaskTelemetry(task, \"exited\");\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\tif (!forcedFailure && this.scheduleRestart(task)) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.status = \"failed\";\n\t\ttask.finishedAt = Date.now();\n\t\tthis.hooks.scheduleCleanup(task);\n\t\tthis.hooks.emitTaskTelemetry(task, \"failed\");\n\t\tif (!forcedFailure) {\n\t\t\tthis.hooks.notifyFailure(task, code, signal);\n\t\t}\n\t\tresolve();\n\t}\n\n\tprivate handleChildError(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t\tresolve: () => void,\n\t\t_error: Error,\n\t): void {\n\t\tif (task.process !== child) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.pid = undefined;\n\t\tthis.stopUsageMonitor(task);\n\t\tthis.captureResourceUsage(task, child);\n\t\ttask.terminatingForLimits = false;\n\t\tconst forcedFailure = Boolean(task.failureReason);\n\t\tif (forcedFailure) {\n\t\t\tthis.disableRestart(task);\n\t\t}\n\t\tif (!forcedFailure && this.scheduleRestart(task)) {\n\t\t\tresolve();\n\t\t\treturn;\n\t\t}\n\t\ttask.status = \"failed\";\n\t\ttask.finishedAt = Date.now();\n\t\tthis.hooks.scheduleCleanup(task);\n\t\tthis.hooks.emitTaskTelemetry(task, \"failed\");\n\t\tif (!forcedFailure) {\n\t\t\tthis.hooks.notifyFailure(task, null, null);\n\t\t}\n\t\tresolve();\n\t}\n\n\tprivate captureResourceUsage(\n\t\ttask: BackgroundTask,\n\t\tchild: ChildProcess,\n\t): void {\n\t\tconst { resourceUsage } = child as ChildProcessWithUsage;\n\t\tif (typeof resourceUsage !== \"function\") {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tconst usage = resourceUsage.call(child);\n\t\t\tif (!task.resourceUsage) {\n\t\t\t\ttask.resourceUsage = {};\n\t\t\t}\n\t\t\tconst target = task.resourceUsage;\n\t\t\tif (usage.maxRSS) {\n\t\t\t\ttarget.maxRssKb = Math.max(target.maxRssKb ?? 0, usage.maxRSS);\n\t\t\t}\n\t\t\tif (usage.userCPUTime) {\n\t\t\t\ttarget.userMs = Math.max(target.userMs ?? 0, usage.userCPUTime / 1000);\n\t\t\t}\n\t\t\tif (usage.systemCPUTime) {\n\t\t\t\ttarget.systemMs = Math.max(\n\t\t\t\t\ttarget.systemMs ?? 0,\n\t\t\t\t\tusage.systemCPUTime / 1000,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore metrics errors\n\t\t}\n\t\tthis.enforceRuntimeLimits(task);\n\t}\n\n\tprivate scheduleRestart(task: BackgroundTask): boolean {\n\t\tconst policy = task.restartPolicy;\n\t\tif (!policy || task.stopRequested) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!canRestart(policy)) {\n\t\t\treturn false;\n\t\t}\n\t\tincrementAttempts(policy);\n\t\ttask.status = \"restarting\";\n\t\tthis.hooks.emitTaskTelemetry(task, \"restarted\");\n\t\tthis.hooks.maybeNotifyRestart(task, policy);\n\t\tthis.cancelRestart(task);\n\t\tconst delay = computeRestartDelay(policy);\n\t\ttask.restartTimer = setTimeout(() => {\n\t\t\ttask.restartTimer = null;\n\t\t\tthis.launchProcess(task);\n\t\t}, delay);\n\t\tif (task.restartTimer.unref) {\n\t\t\ttask.restartTimer.unref();\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate cancelRestart(task: BackgroundTask): void {\n\t\tif (task.restartTimer) {\n\t\t\tclearTimeout(task.restartTimer);\n\t\t\ttask.restartTimer = null;\n\t\t}\n\t}\n\n\tprivate startUsageMonitor(task: BackgroundTask): void {\n\t\tif (!task.pid || task.usageMonitor) {\n\t\t\treturn;\n\t\t}\n\t\tconst mode = this.getMonitoringMode();\n\t\ttask.monitoringMode = mode;\n\t\tif (mode === \"disabled\") {\n\t\t\treturn;\n\t\t}\n\t\tthis.sampleResourceUsage(task);\n\t\tconst monitor = setInterval(() => {\n\t\t\tthis.sampleResourceUsage(task);\n\t\t}, RESOURCE_POLL_INTERVAL_MS);\n\t\tif (monitor.unref) {\n\t\t\tmonitor.unref();\n\t\t}\n\t\ttask.usageMonitor = monitor;\n\t}\n\n\tprivate getMonitoringMode(): \"proc\" | \"ps\" | \"disabled\" {\n\t\treturn this.resourceMonitor.getMode();\n\t}\n\n\tprivate sampleResourceUsage(task: BackgroundTask): void {\n\t\tif (!task.pid) {\n\t\t\tthis.stopUsageMonitor(task);\n\t\t\treturn;\n\t\t}\n\t\tconst usage = this.resourceMonitor.getUsage(task.pid);\n\t\tif (!usage) {\n\t\t\tif (task.monitoringMode === \"ps\") {\n\t\t\t\tthis.stopUsageMonitor(task);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (!task.resourceUsage) {\n\t\t\ttask.resourceUsage = {};\n\t\t}\n\t\tconst target = task.resourceUsage;\n\t\tif (usage.maxRssKb !== undefined) {\n\t\t\ttarget.maxRssKb = Math.max(target.maxRssKb ?? 0, usage.maxRssKb);\n\t\t}\n\t\tif (usage.userMs !== undefined) {\n\t\t\ttarget.userMs = Math.max(target.userMs ?? 0, usage.userMs);\n\t\t}\n\t\tif (usage.systemMs !== undefined) {\n\t\t\ttarget.systemMs = Math.max(target.systemMs ?? 0, usage.systemMs);\n\t\t}\n\t\tthis.enforceRuntimeLimits(task);\n\t}\n\n\tprivate enforceRuntimeLimits(task: BackgroundTask): void {\n\t\tif (!task.resourceUsage || task.terminatingForLimits) {\n\t\t\treturn;\n\t\t}\n\t\tconst breach = evaluateResourceLimitBreach(task.resourceUsage, task.limits);\n\t\tif (!breach || task.failureReason) {\n\t\t\treturn;\n\t\t}\n\t\tconst describe =\n\t\t\tbreach.kind === \"memory\"\n\t\t\t\t? `${(breach.actual / 1024).toFixed(1)}MB > ${(breach.limit / 1024).toFixed(1)}MB`\n\t\t\t\t: `${Math.round(breach.actual)}ms > ${Math.round(breach.limit)}ms`;\n\t\tthis.hooks.setFailureReason(\n\t\t\ttask,\n\t\t\t`Resource limit (${breach.kind} ${describe})`,\n\t\t);\n\t\ttask.lastLimitBreach = breach;\n\t\ttask.terminatingForLimits = true;\n\t\tthis.disableRestart(task);\n\t\tif (!task.pid) {\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\tkillProcessTree(task.pid);\n\t\t} catch (error) {\n\t\t\tconst errMessage =\n\t\t\t\terror instanceof Error ? error.message : \"Failed to terminate process\";\n\t\t\tthis.hooks.emitTaskNotification({\n\t\t\t\ttaskId: task.id,\n\t\t\t\tstatus: task.status,\n\t\t\t\tcommand: task.command,\n\t\t\t\tkind: \"limit\",\n\t\t\t\tlevel: \"warn\",\n\t\t\t\treason: `${task.failureReason}; kill error: ${errMessage}`,\n\t\t\t\tmessage: \"resource limit hit but termination failed\",\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tthis.hooks.emitTaskNotification({\n\t\t\ttaskId: task.id,\n\t\t\tstatus: task.status,\n\t\t\tcommand: task.command,\n\t\t\tkind: \"limit\",\n\t\t\tlevel: \"warn\",\n\t\t\treason: task.failureReason,\n\t\t\tmessage: \"exceeded resource limits; terminating\",\n\t\t});\n\t}\n\n\tprivate attachLogging(child: ChildProcess, task: BackgroundTask): void {\n\t\tlet existingSize = 0;\n\t\ttry {\n\t\t\texistingSize = statSync(task.logPath).size;\n\t\t} catch {\n\t\t\t// File may not exist yet\n\t\t}\n\t\tconst writer = new RotatingLogWriter({\n\t\t\tlimit: task.limits.logSizeLimit,\n\t\t\tsegments: task.limits.logSegments,\n\t\t\tlogPath: task.logPath,\n\t\t\texistingSize,\n\t\t\tmarkTruncated: () => {\n\t\t\t\ttask.logTruncated = true;\n\t\t\t},\n\t\t\tshiftArchives: () =>\n\t\t\t\trotateArchives(task.logPath, task.limits.logSegments),\n\t\t\tarchivedPath: (index) => archivedLogPath(task.logPath, index),\n\t\t});\n\t\ttask.logWriter = writer;\n\n\t\tlet closed = false;\n\t\tconst closeStream = () => {\n\t\t\tif (closed) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tclosed = true;\n\t\t\twriter.end();\n\t\t};\n\n\t\tconst attach = (source?: NodeJS.ReadableStream | null) => {\n\t\t\tif (!source) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsource.pipe(writer, { end: false });\n\t\t\tsource.on(\"error\", () => {\n\t\t\t\ttask.logTruncated = true;\n\t\t\t\tcloseStream();\n\t\t\t});\n\t\t};\n\n\t\tattach(child.stdout);\n\t\tattach(child.stderr);\n\n\t\tchild.once(\"close\", closeStream);\n\t\tchild.once(\"error\", closeStream);\n\t}\n}\n"]}
@@ -121,7 +121,7 @@ export declare function buildTaskDetail(task: BackgroundTask): {
121
121
  status: BackgroundTaskStatus;
122
122
  command: string;
123
123
  logPath: string;
124
- shellMode: "shell" | "exec";
124
+ shellMode: "exec" | "shell";
125
125
  logTruncated: boolean;
126
126
  restartAttempts: number;
127
127
  restartMaxAttempts: number;
@@ -10,7 +10,9 @@ interface CheckForUpdateOptions {
10
10
  fetch?: typeof fetch;
11
11
  timeoutMs?: number;
12
12
  url?: string;
13
+ urls?: string[];
13
14
  }
15
+ export declare const resolveUpdateUrls: (options?: Pick<CheckForUpdateOptions, "url" | "urls">, env?: NodeJS.ProcessEnv) => string[];
14
16
  export declare function compareVersions(current: string, latest: string): number;
15
17
  export declare function checkForUpdate(currentVersion: string, options?: CheckForUpdateOptions): Promise<UpdateCheckResult>;
16
18
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,qBAAqB;IAC9B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AA4FD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBvE;AAED,wBAAsB,cAAc,CACnC,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,iBAAiB,CAAC,CA4D5B"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,qBAAqB;IAC9B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAgBD,eAAO,MAAM,iBAAiB,GAC7B,UAAS,IAAI,CAAC,qBAAqB,EAAE,KAAK,GAAG,MAAM,CAAM,EACzD,MAAK,MAAM,CAAC,UAAwB,KAClC,MAAM,EAgBR,CAAC;AA4FF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBvE;AAED,wBAAsB,cAAc,CACnC,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,iBAAiB,CAAC,CAoG5B"}
@@ -1,6 +1,37 @@
1
+ import { getPackageName } from "../package-metadata.js";
1
2
  import { withTimeout } from "../utils/async.js";
2
- const DEFAULT_UPDATE_URL = "https://raw.githubusercontent.com/evalops/hopper/main/public/composer/version.json";
3
+ const DEFAULT_GCS_UPDATE_URL = "https://storage.googleapis.com/evalops-prod-maestro-releases/maestro/version.json";
4
+ const NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org";
3
5
  const DEFAULT_TIMEOUT_MS = 5_000;
6
+ const splitUrlList = (value) => {
7
+ if (!value) {
8
+ return [];
9
+ }
10
+ return value
11
+ .split(/[\n,]/u)
12
+ .map((url) => url.trim())
13
+ .filter(Boolean);
14
+ };
15
+ const npmLatestUrl = (packageName = getPackageName()) => {
16
+ return `${NPM_REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`;
17
+ };
18
+ export const resolveUpdateUrls = (options = {}, env = process.env) => {
19
+ const explicitUrls = options.urls?.map((url) => url.trim()).filter(Boolean);
20
+ if (explicitUrls && explicitUrls.length > 0) {
21
+ return explicitUrls;
22
+ }
23
+ if (options.url?.trim()) {
24
+ return [options.url.trim()];
25
+ }
26
+ const envUrls = splitUrlList(env.MAESTRO_UPDATE_URLS);
27
+ if (envUrls.length > 0) {
28
+ return envUrls;
29
+ }
30
+ if (env.MAESTRO_UPDATE_URL?.trim()) {
31
+ return [env.MAESTRO_UPDATE_URL.trim()];
32
+ }
33
+ return [DEFAULT_GCS_UPDATE_URL, npmLatestUrl()];
34
+ };
4
35
  const toErrorMessage = (error) => {
5
36
  if (error instanceof Error) {
6
37
  return error.message;
@@ -102,58 +133,86 @@ export function compareVersions(current, latest) {
102
133
  return comparePreRelease(currentPre, latestPre);
103
134
  }
104
135
  export async function checkForUpdate(currentVersion, options = {}) {
105
- const url = options.url ?? process.env.MAESTRO_UPDATE_URL ?? DEFAULT_UPDATE_URL;
136
+ const urls = resolveUpdateUrls(options);
106
137
  const fetchImpl = options.fetch ?? fetch;
107
138
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
108
- try {
109
- const response = await withTimeout(fetchImpl(url, {
110
- headers: { Accept: "application/json" },
111
- }), timeoutMs, `Update check timed out after ${timeoutMs}ms`);
112
- if (!response.ok) {
113
- return {
114
- currentVersion,
115
- isUpdateAvailable: false,
116
- sourceUrl: url,
117
- error: `Update check failed (${response.status} ${response.statusText || ""})`.trim(),
118
- };
119
- }
120
- let payload;
139
+ let lastResult = null;
140
+ let bestUpdateResult = null;
141
+ let bestCurrentResult = null;
142
+ for (const url of urls) {
121
143
  try {
122
- payload = (await response.json());
123
- }
124
- catch (error) {
125
- return {
144
+ const response = await withTimeout(fetchImpl(url, {
145
+ headers: { Accept: "application/json" },
146
+ }), timeoutMs, `Update check timed out after ${timeoutMs}ms`);
147
+ if (!response.ok) {
148
+ lastResult = {
149
+ currentVersion,
150
+ isUpdateAvailable: false,
151
+ sourceUrl: url,
152
+ error: `Update check failed (${response.status} ${response.statusText || ""})`.trim(),
153
+ };
154
+ continue;
155
+ }
156
+ let payload;
157
+ try {
158
+ payload = (await response.json());
159
+ }
160
+ catch (error) {
161
+ lastResult = {
162
+ currentVersion,
163
+ isUpdateAvailable: false,
164
+ sourceUrl: url,
165
+ error: `Invalid update metadata: ${toErrorMessage(error)}`,
166
+ };
167
+ continue;
168
+ }
169
+ if (!payload || typeof payload.version !== "string") {
170
+ lastResult = {
171
+ currentVersion,
172
+ isUpdateAvailable: false,
173
+ sourceUrl: url,
174
+ error: "Update metadata missing version field",
175
+ };
176
+ continue;
177
+ }
178
+ const latestVersion = payload.version.trim();
179
+ const comparison = compareVersions(currentVersion.trim(), latestVersion);
180
+ const result = {
126
181
  currentVersion,
127
- isUpdateAvailable: false,
182
+ latestVersion,
183
+ notes: normalizeNotes(payload.notes),
184
+ isUpdateAvailable: comparison < 0,
128
185
  sourceUrl: url,
129
- error: `Invalid update metadata: ${toErrorMessage(error)}`,
130
186
  };
187
+ lastResult = result;
188
+ if (result.isUpdateAvailable) {
189
+ if (!bestUpdateResult ||
190
+ compareVersions(bestUpdateResult.latestVersion ?? currentVersion, latestVersion) < 0) {
191
+ bestUpdateResult = result;
192
+ }
193
+ continue;
194
+ }
195
+ if (!bestCurrentResult ||
196
+ compareVersions(bestCurrentResult.latestVersion ?? currentVersion, latestVersion) < 0) {
197
+ bestCurrentResult = result;
198
+ }
131
199
  }
132
- if (!payload || typeof payload.version !== "string") {
133
- return {
200
+ catch (error) {
201
+ lastResult = {
134
202
  currentVersion,
135
203
  isUpdateAvailable: false,
136
204
  sourceUrl: url,
137
- error: "Update metadata missing version field",
205
+ error: toErrorMessage(error),
138
206
  };
139
207
  }
140
- const latestVersion = payload.version.trim();
141
- const comparison = compareVersions(currentVersion.trim(), latestVersion);
142
- return {
143
- currentVersion,
144
- latestVersion,
145
- notes: normalizeNotes(payload.notes),
146
- isUpdateAvailable: comparison < 0,
147
- sourceUrl: url,
148
- };
149
- }
150
- catch (error) {
151
- return {
152
- currentVersion,
153
- isUpdateAvailable: false,
154
- sourceUrl: url,
155
- error: toErrorMessage(error),
156
- };
157
208
  }
209
+ return (bestUpdateResult ??
210
+ bestCurrentResult ??
211
+ lastResult ?? {
212
+ currentVersion,
213
+ isUpdateAvailable: false,
214
+ sourceUrl: urls[0] ?? "",
215
+ error: "No update metadata sources configured",
216
+ });
158
217
  }
159
218
  //# sourceMappingURL=check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"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","sourcesContent":["import { withTimeout } from \"../utils/async.js\";\n\nconst DEFAULT_UPDATE_URL =\n\t\"https://raw.githubusercontent.com/evalops/hopper/main/public/composer/version.json\";\nconst DEFAULT_TIMEOUT_MS = 5_000;\n\ninterface VersionMetadata {\n\tversion: string;\n\tnotes?: string;\n}\n\nexport interface UpdateCheckResult {\n\tcurrentVersion: string;\n\tlatestVersion?: string;\n\tnotes?: string;\n\tisUpdateAvailable: boolean;\n\tsourceUrl: string;\n\terror?: string;\n}\n\ninterface CheckForUpdateOptions {\n\tfetch?: typeof fetch;\n\ttimeoutMs?: number;\n\turl?: string;\n}\n\nconst toErrorMessage = (error: unknown): string => {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tif (typeof error === \"string\") {\n\t\treturn error;\n\t}\n\treturn \"Unknown error\";\n};\n\nconst normalizeNotes = (value: unknown): string | undefined => {\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn trimmed.length ? trimmed : undefined;\n};\n\nconst parseNumericSegment = (segment: string): number => {\n\tconst value = Number.parseInt(segment, 10);\n\treturn Number.isNaN(value) ? 0 : value;\n};\n\nconst parseMainSegments = (version: string): number[] => {\n\treturn version.split(\".\").map((segment) => parseNumericSegment(segment));\n};\n\nconst parsePreReleaseSegments = (version: string): string[] => {\n\treturn version ? version.split(\".\") : [];\n};\n\nconst isNumericIdentifier = (segment: string): boolean => {\n\treturn /^[0-9]+$/.test(segment);\n};\n\nconst comparePreRelease = (\n\taSegments: string[],\n\tbSegments: string[],\n): number => {\n\tif (aSegments.length === 0 && bSegments.length === 0) {\n\t\treturn 0;\n\t}\n\tif (aSegments.length === 0) {\n\t\treturn 1;\n\t}\n\tif (bSegments.length === 0) {\n\t\treturn -1;\n\t}\n\tconst length = Math.max(aSegments.length, bSegments.length);\n\tfor (let i = 0; i < length; i++) {\n\t\tconst a = aSegments[i];\n\t\tconst b = bSegments[i];\n\t\tif (a === undefined) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (b === undefined) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (a === b) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst aIsNum = isNumericIdentifier(a);\n\t\tconst bIsNum = isNumericIdentifier(b);\n\t\tif (aIsNum && bIsNum) {\n\t\t\tconst aNum = Number.parseInt(a, 10);\n\t\t\tconst bNum = Number.parseInt(b, 10);\n\t\t\tif (aNum < bNum) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (aNum > bNum) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (aIsNum && !bIsNum) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (!aIsNum && bIsNum) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (a < b) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (a > b) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n};\n\nexport function compareVersions(current: string, latest: string): number {\n\tconst [currentMainPart, currentPreReleasePart = \"\"] = current.split(\"-\", 2);\n\tconst [latestMainPart, latestPreReleasePart = \"\"] = latest.split(\"-\", 2);\n\tconst currentMain = parseMainSegments(currentMainPart!);\n\tconst latestMain = parseMainSegments(latestMainPart!);\n\tconst length = Math.max(currentMain.length, latestMain.length);\n\tfor (let i = 0; i < length; i++) {\n\t\tconst currentValue = currentMain[i] ?? 0;\n\t\tconst latestValue = latestMain[i] ?? 0;\n\t\tif (currentValue < latestValue) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (currentValue > latestValue) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\tconst currentPre = parsePreReleaseSegments(currentPreReleasePart);\n\tconst latestPre = parsePreReleaseSegments(latestPreReleasePart);\n\treturn comparePreRelease(currentPre, latestPre);\n}\n\nexport async function checkForUpdate(\n\tcurrentVersion: string,\n\toptions: CheckForUpdateOptions = {},\n): Promise<UpdateCheckResult> {\n\tconst url =\n\t\toptions.url ?? process.env.MAESTRO_UPDATE_URL ?? DEFAULT_UPDATE_URL;\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n\ttry {\n\t\tconst response = await withTimeout(\n\t\t\tfetchImpl(url, {\n\t\t\t\theaders: { Accept: \"application/json\" },\n\t\t\t}),\n\t\t\ttimeoutMs,\n\t\t\t`Update check timed out after ${timeoutMs}ms`,\n\t\t);\n\n\t\tif (!response.ok) {\n\t\t\treturn {\n\t\t\t\tcurrentVersion,\n\t\t\t\tisUpdateAvailable: false,\n\t\t\t\tsourceUrl: url,\n\t\t\t\terror:\n\t\t\t\t\t`Update check failed (${response.status} ${response.statusText || \"\"})`.trim(),\n\t\t\t};\n\t\t}\n\t\tlet payload: VersionMetadata;\n\t\ttry {\n\t\t\tpayload = (await response.json()) as VersionMetadata;\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tcurrentVersion,\n\t\t\t\tisUpdateAvailable: false,\n\t\t\t\tsourceUrl: url,\n\t\t\t\terror: `Invalid update metadata: ${toErrorMessage(error)}`,\n\t\t\t};\n\t\t}\n\t\tif (!payload || typeof payload.version !== \"string\") {\n\t\t\treturn {\n\t\t\t\tcurrentVersion,\n\t\t\t\tisUpdateAvailable: false,\n\t\t\t\tsourceUrl: url,\n\t\t\t\terror: \"Update metadata missing version field\",\n\t\t\t};\n\t\t}\n\t\tconst latestVersion = payload.version.trim();\n\t\tconst comparison = compareVersions(currentVersion.trim(), latestVersion);\n\t\treturn {\n\t\t\tcurrentVersion,\n\t\t\tlatestVersion,\n\t\t\tnotes: normalizeNotes(payload.notes),\n\t\t\tisUpdateAvailable: comparison < 0,\n\t\t\tsourceUrl: url,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tcurrentVersion,\n\t\t\tisUpdateAvailable: false,\n\t\t\tsourceUrl: url,\n\t\t\terror: toErrorMessage(error),\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPackageName } from \"../package-metadata.js\";\nimport { withTimeout } from \"../utils/async.js\";\n\nconst DEFAULT_GCS_UPDATE_URL =\n\t\"https://storage.googleapis.com/evalops-prod-maestro-releases/maestro/version.json\";\nconst NPM_REGISTRY_BASE_URL = \"https://registry.npmjs.org\";\nconst DEFAULT_TIMEOUT_MS = 5_000;\n\ninterface VersionMetadata {\n\tversion: string;\n\tnotes?: string;\n}\n\nexport interface UpdateCheckResult {\n\tcurrentVersion: string;\n\tlatestVersion?: string;\n\tnotes?: string;\n\tisUpdateAvailable: boolean;\n\tsourceUrl: string;\n\terror?: string;\n}\n\ninterface CheckForUpdateOptions {\n\tfetch?: typeof fetch;\n\ttimeoutMs?: number;\n\turl?: string;\n\turls?: string[];\n}\n\nconst splitUrlList = (value: string | undefined): string[] => {\n\tif (!value) {\n\t\treturn [];\n\t}\n\treturn value\n\t\t.split(/[\\n,]/u)\n\t\t.map((url) => url.trim())\n\t\t.filter(Boolean);\n};\n\nconst npmLatestUrl = (packageName = getPackageName()): string => {\n\treturn `${NPM_REGISTRY_BASE_URL}/${encodeURIComponent(packageName)}/latest`;\n};\n\nexport const resolveUpdateUrls = (\n\toptions: Pick<CheckForUpdateOptions, \"url\" | \"urls\"> = {},\n\tenv: NodeJS.ProcessEnv = process.env,\n): string[] => {\n\tconst explicitUrls = options.urls?.map((url) => url.trim()).filter(Boolean);\n\tif (explicitUrls && explicitUrls.length > 0) {\n\t\treturn explicitUrls;\n\t}\n\tif (options.url?.trim()) {\n\t\treturn [options.url.trim()];\n\t}\n\tconst envUrls = splitUrlList(env.MAESTRO_UPDATE_URLS);\n\tif (envUrls.length > 0) {\n\t\treturn envUrls;\n\t}\n\tif (env.MAESTRO_UPDATE_URL?.trim()) {\n\t\treturn [env.MAESTRO_UPDATE_URL.trim()];\n\t}\n\treturn [DEFAULT_GCS_UPDATE_URL, npmLatestUrl()];\n};\n\nconst toErrorMessage = (error: unknown): string => {\n\tif (error instanceof Error) {\n\t\treturn error.message;\n\t}\n\tif (typeof error === \"string\") {\n\t\treturn error;\n\t}\n\treturn \"Unknown error\";\n};\n\nconst normalizeNotes = (value: unknown): string | undefined => {\n\tif (typeof value !== \"string\") {\n\t\treturn undefined;\n\t}\n\tconst trimmed = value.trim();\n\treturn trimmed.length ? trimmed : undefined;\n};\n\nconst parseNumericSegment = (segment: string): number => {\n\tconst value = Number.parseInt(segment, 10);\n\treturn Number.isNaN(value) ? 0 : value;\n};\n\nconst parseMainSegments = (version: string): number[] => {\n\treturn version.split(\".\").map((segment) => parseNumericSegment(segment));\n};\n\nconst parsePreReleaseSegments = (version: string): string[] => {\n\treturn version ? version.split(\".\") : [];\n};\n\nconst isNumericIdentifier = (segment: string): boolean => {\n\treturn /^[0-9]+$/.test(segment);\n};\n\nconst comparePreRelease = (\n\taSegments: string[],\n\tbSegments: string[],\n): number => {\n\tif (aSegments.length === 0 && bSegments.length === 0) {\n\t\treturn 0;\n\t}\n\tif (aSegments.length === 0) {\n\t\treturn 1;\n\t}\n\tif (bSegments.length === 0) {\n\t\treturn -1;\n\t}\n\tconst length = Math.max(aSegments.length, bSegments.length);\n\tfor (let i = 0; i < length; i++) {\n\t\tconst a = aSegments[i];\n\t\tconst b = bSegments[i];\n\t\tif (a === undefined) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (b === undefined) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (a === b) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst aIsNum = isNumericIdentifier(a);\n\t\tconst bIsNum = isNumericIdentifier(b);\n\t\tif (aIsNum && bIsNum) {\n\t\t\tconst aNum = Number.parseInt(a, 10);\n\t\t\tconst bNum = Number.parseInt(b, 10);\n\t\t\tif (aNum < bNum) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (aNum > bNum) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (aIsNum && !bIsNum) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (!aIsNum && bIsNum) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (a < b) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (a > b) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n};\n\nexport function compareVersions(current: string, latest: string): number {\n\tconst [currentMainPart, currentPreReleasePart = \"\"] = current.split(\"-\", 2);\n\tconst [latestMainPart, latestPreReleasePart = \"\"] = latest.split(\"-\", 2);\n\tconst currentMain = parseMainSegments(currentMainPart!);\n\tconst latestMain = parseMainSegments(latestMainPart!);\n\tconst length = Math.max(currentMain.length, latestMain.length);\n\tfor (let i = 0; i < length; i++) {\n\t\tconst currentValue = currentMain[i] ?? 0;\n\t\tconst latestValue = latestMain[i] ?? 0;\n\t\tif (currentValue < latestValue) {\n\t\t\treturn -1;\n\t\t}\n\t\tif (currentValue > latestValue) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\tconst currentPre = parsePreReleaseSegments(currentPreReleasePart);\n\tconst latestPre = parsePreReleaseSegments(latestPreReleasePart);\n\treturn comparePreRelease(currentPre, latestPre);\n}\n\nexport async function checkForUpdate(\n\tcurrentVersion: string,\n\toptions: CheckForUpdateOptions = {},\n): Promise<UpdateCheckResult> {\n\tconst urls = resolveUpdateUrls(options);\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\tlet lastResult: UpdateCheckResult | null = null;\n\tlet bestUpdateResult: UpdateCheckResult | null = null;\n\tlet bestCurrentResult: UpdateCheckResult | null = null;\n\n\tfor (const url of urls) {\n\t\ttry {\n\t\t\tconst response = await withTimeout(\n\t\t\t\tfetchImpl(url, {\n\t\t\t\t\theaders: { Accept: \"application/json\" },\n\t\t\t\t}),\n\t\t\t\ttimeoutMs,\n\t\t\t\t`Update check timed out after ${timeoutMs}ms`,\n\t\t\t);\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlastResult = {\n\t\t\t\t\tcurrentVersion,\n\t\t\t\t\tisUpdateAvailable: false,\n\t\t\t\t\tsourceUrl: url,\n\t\t\t\t\terror:\n\t\t\t\t\t\t`Update check failed (${response.status} ${response.statusText || \"\"})`.trim(),\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet payload: VersionMetadata;\n\t\t\ttry {\n\t\t\t\tpayload = (await response.json()) as VersionMetadata;\n\t\t\t} catch (error) {\n\t\t\t\tlastResult = {\n\t\t\t\t\tcurrentVersion,\n\t\t\t\t\tisUpdateAvailable: false,\n\t\t\t\t\tsourceUrl: url,\n\t\t\t\t\terror: `Invalid update metadata: ${toErrorMessage(error)}`,\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!payload || typeof payload.version !== \"string\") {\n\t\t\t\tlastResult = {\n\t\t\t\t\tcurrentVersion,\n\t\t\t\t\tisUpdateAvailable: false,\n\t\t\t\t\tsourceUrl: url,\n\t\t\t\t\terror: \"Update metadata missing version field\",\n\t\t\t\t};\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst latestVersion = payload.version.trim();\n\t\t\tconst comparison = compareVersions(currentVersion.trim(), latestVersion);\n\t\t\tconst result = {\n\t\t\t\tcurrentVersion,\n\t\t\t\tlatestVersion,\n\t\t\t\tnotes: normalizeNotes(payload.notes),\n\t\t\t\tisUpdateAvailable: comparison < 0,\n\t\t\t\tsourceUrl: url,\n\t\t\t};\n\t\t\tlastResult = result;\n\t\t\tif (result.isUpdateAvailable) {\n\t\t\t\tif (\n\t\t\t\t\t!bestUpdateResult ||\n\t\t\t\t\tcompareVersions(\n\t\t\t\t\t\tbestUpdateResult.latestVersion ?? currentVersion,\n\t\t\t\t\t\tlatestVersion,\n\t\t\t\t\t) < 0\n\t\t\t\t) {\n\t\t\t\t\tbestUpdateResult = result;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!bestCurrentResult ||\n\t\t\t\tcompareVersions(\n\t\t\t\t\tbestCurrentResult.latestVersion ?? currentVersion,\n\t\t\t\t\tlatestVersion,\n\t\t\t\t) < 0\n\t\t\t) {\n\t\t\t\tbestCurrentResult = result;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tlastResult = {\n\t\t\t\tcurrentVersion,\n\t\t\t\tisUpdateAvailable: false,\n\t\t\t\tsourceUrl: url,\n\t\t\t\terror: toErrorMessage(error),\n\t\t\t};\n\t\t}\n\t}\n\n\treturn (\n\t\tbestUpdateResult ??\n\t\tbestCurrentResult ??\n\t\tlastResult ?? {\n\t\t\tcurrentVersion,\n\t\t\tisUpdateAvailable: false,\n\t\t\tsourceUrl: urls[0] ?? \"\",\n\t\t\terror: \"No update metadata sources configured\",\n\t\t}\n\t);\n}\n"]}
@@ -0,0 +1,56 @@
1
+ import { type UpdateCheckResult } from "./check.js";
2
+ type PackageManager = "npm" | "bun";
3
+ type GlobalInstallContext = {
4
+ packageManager: PackageManager;
5
+ prefix: string;
6
+ };
7
+ export type StartupUpdateOutcome = {
8
+ status: "skipped";
9
+ reason: string;
10
+ } | {
11
+ status: "current";
12
+ check: UpdateCheckResult;
13
+ } | {
14
+ status: "available";
15
+ check: UpdateCheckResult;
16
+ } | {
17
+ status: "failed";
18
+ check?: UpdateCheckResult;
19
+ error: string;
20
+ } | {
21
+ status: "updated";
22
+ check: UpdateCheckResult;
23
+ } | {
24
+ status: "restarted";
25
+ check: UpdateCheckResult;
26
+ exitCode: number;
27
+ };
28
+ type StartupUpdateOptions = {
29
+ args?: string[];
30
+ argv?: string[];
31
+ currentVersion: string;
32
+ env?: NodeJS.ProcessEnv;
33
+ isTty?: boolean;
34
+ now?: number;
35
+ packageName?: string;
36
+ checkForUpdateImpl?: (currentVersion: string, options?: {
37
+ timeoutMs?: number;
38
+ urls?: string[];
39
+ }) => Promise<UpdateCheckResult>;
40
+ checkTimeoutMs?: number;
41
+ globalInstallContexts?: GlobalInstallContext[] | null;
42
+ globalPrefix?: string | null;
43
+ installPackage?: (packageManager: PackageManager, packageName: string, version: string) => {
44
+ status: number | null;
45
+ error?: Error;
46
+ };
47
+ restart?: false | (() => {
48
+ status: number | null;
49
+ error?: Error;
50
+ });
51
+ statePath?: string;
52
+ };
53
+ export declare const isInstalledPackageEntrypoint: (entrypoint: string | undefined, packageName?: string, globalPrefix?: string | null) => boolean;
54
+ export declare function attemptStartupUpdate(options: StartupUpdateOptions): Promise<StartupUpdateOutcome>;
55
+ export {};
56
+ //# sourceMappingURL=startup-refresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-refresh.d.ts","sourceRoot":"","sources":["../../src/update/startup-refresh.ts"],"names":[],"mappings":"AAgBA,OAAO,EACN,KAAK,iBAAiB,EAGtB,MAAM,YAAY,CAAC;AAapB,KAAK,cAAc,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpC,KAAK,oBAAoB,GAAG;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;CACf,CAAC;AAQF,MAAM,MAAM,oBAAoB,GAC7B;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,GACjD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,GAC/C;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,KAAK,oBAAoB,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,CACpB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAC7C,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IACtD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,CAAC,EAAE,CAChB,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,KACX;QACJ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,KAAK,CAAC,EAAE,KAAK,CAAC;KACd,CAAC;IACF,OAAO,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA+DF,eAAO,MAAM,4BAA4B,GACxC,YAAY,MAAM,GAAG,SAAS,EAC9B,oBAA8B,EAC9B,eAAe,MAAM,GAAG,IAAI,KAC1B,OAgBF,CAAC;AA+KF,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC,CAmJ/B"}