@bridge_gpt/mcp-server 0.2.39 → 0.2.42

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 (74) hide show
  1. package/README.md +10 -10
  2. package/build/agent-capabilities/cli.js +2 -1
  3. package/build/agent-launchers/claude-executor-adapter.js +17 -4
  4. package/build/claude-user-config-doctor.js +42 -11
  5. package/build/cli-release.js +2 -1
  6. package/build/commands.generated.js +4 -4
  7. package/build/conduct-epic/bridge-client.js +354 -113
  8. package/build/conduct-epic/checkpoint-store.js +75 -2
  9. package/build/conduct-epic/cli.js +795 -109
  10. package/build/conduct-epic/cut-protocol.js +327 -0
  11. package/build/conduct-epic/pr-state.js +113 -24
  12. package/build/conduct-epic/spawn.js +14 -2
  13. package/build/conductor/bridge-api-client.js +27 -1
  14. package/build/conductor/cli.js +46 -1
  15. package/build/conductor/doctor.js +101 -16
  16. package/build/conductor/epic-reconcile.js +72 -19
  17. package/build/conductor/epic-runtime.js +15 -3
  18. package/build/conductor/errors.js +47 -0
  19. package/build/conductor/git-hooks.js +205 -11
  20. package/build/conductor/install-doctor.js +230 -1
  21. package/build/conductor/local-merge.js +130 -28
  22. package/build/conductor/tools.js +32 -3
  23. package/build/conductor/worker-ledger-cli.js +27 -1
  24. package/build/conductor-bin.js +15 -15
  25. package/build/credentials-cli.js +3 -2
  26. package/build/doctor.js +107 -41
  27. package/build/executor/cli.js +48 -1
  28. package/build/executor/env.js +21 -0
  29. package/build/executor/index-scope.js +39 -0
  30. package/build/executor/job-log-registry.js +69 -0
  31. package/build/executor/job-runner.js +148 -26
  32. package/build/executor/live-worker-registry.js +83 -0
  33. package/build/executor/observation.js +167 -6
  34. package/build/executor/platform.js +147 -3
  35. package/build/executor/process.js +58 -14
  36. package/build/executor/runner.js +235 -48
  37. package/build/executor/test-clock.js +3 -2
  38. package/build/index-scope-contract.js +96 -0
  39. package/build/index.js +153 -204
  40. package/build/init.js +83 -22
  41. package/build/install-bridge-conductor.js +323 -14
  42. package/build/install-bridge.js +202 -38
  43. package/build/install-doctor.js +23 -9
  44. package/build/install-reexec.js +2 -1
  45. package/build/launcher-config-inspection.js +83 -22
  46. package/build/mcp-host-config.js +331 -67
  47. package/build/mcp-host-targets.js +45 -21
  48. package/build/mcp-identity.js +92 -0
  49. package/build/mcp-install-state.js +94 -1
  50. package/build/mcp-invoke.js +2 -1
  51. package/build/mcp-provisioning.js +45 -12
  52. package/build/mcp-registration-doctor.js +35 -13
  53. package/build/mcp-server-invocation.js +4 -2
  54. package/build/merge-pull-request.js +208 -9
  55. package/build/pipelines.generated.js +3 -3
  56. package/build/plane/defaults.js +4 -1
  57. package/build/plane/preflight.js +81 -10
  58. package/build/plane/test-fakes.js +9 -1
  59. package/build/readme.generated.js +1 -1
  60. package/build/regression-check.js +3 -2
  61. package/build/review-tickets.js +8 -7
  62. package/build/run-unit-tests-launcher.js +74 -1
  63. package/build/schedule-run.js +3 -2
  64. package/build/setup-epic.js +453 -78
  65. package/build/sfcc/tool-wrapper.js +15 -0
  66. package/build/start-tickets-prereqs.js +11 -6
  67. package/build/start-tickets.js +91 -85
  68. package/build/update-check.js +3 -2
  69. package/build/upgrade-advice.js +2 -1
  70. package/build/upgrade-cli.js +50 -18
  71. package/build/version.generated.js +1 -1
  72. package/docs/CONDUCTOR.md +22 -0
  73. package/docs/install/mcp-tool-integrations.md +19 -3
  74. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var __defProp=Object.defineProperty;var __getOwnPropNames=Object.getOwnPropertyNames;var __esm=(fn,res,err)=>function(){if(err)throw err[0];try{return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res}catch(e){throw err=[e],e}};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})};function redactSecretString(value){let out=value;for(let{pattern,replacement}of STANDALONE_PATTERNS)out=out.replace(pattern,replacement);return out=out.replace(ASSIGNMENT_QUOTED,(_m,key,sep,q)=>`${key}${sep}${q}${REDACTED}${q}`),out=out.replace(ASSIGNMENT_UNQUOTED,(_m,key,sep)=>`${key}${sep}${REDACTED}`),out}function isSecretKey(key){let norm=key.toLowerCase().replace(/[_-]/g,"");return SECRET_KEY_WORDS.some(word=>norm===word||norm.endsWith(word))}function redactSecrets(value){if(typeof value=="string")return redactSecretString(value);if(Array.isArray(value))return value.map(item=>item===void 0?null:redactSecrets(item));if(value!==null&&typeof value=="object"){let out={};for(let[key,val]of Object.entries(value))val!==void 0&&(typeof val=="string"&&isSecretKey(key)?out[key]=REDACTED:out[key]=redactSecrets(val));return out}return value}var REDACTED,STANDALONE_PATTERNS,ASSIGNMENT_KEYS,ASSIGNMENT_QUOTED,ASSIGNMENT_UNQUOTED,SECRET_KEY_WORDS,init_redaction=__esm({"src/conductor/redaction.ts"(){"use strict";REDACTED="[REDACTED]",STANDALONE_PATTERNS=[{pattern:/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,replacement:REDACTED},{pattern:/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,replacement:REDACTED},{pattern:/\bBearer\s+[A-Za-z0-9._-]+/gi,replacement:`Bearer ${REDACTED}`},{pattern:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,replacement:REDACTED},{pattern:/\bgh[pousr]_[A-Za-z0-9]{6,}\b/g,replacement:REDACTED},{pattern:/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{6,}\b/g,replacement:REDACTED}],ASSIGNMENT_KEYS="api[_-]?key|apikey|secret|token|password|passwd|pwd|authorization|auth",ASSIGNMENT_QUOTED=new RegExp(`\\b(${ASSIGNMENT_KEYS})(\\s*[:=]\\s*)("|')[^"']*("|')`,"gi"),ASSIGNMENT_UNQUOTED=new RegExp(`\\b(${ASSIGNMENT_KEYS})(\\s*[:=]\\s*)([^\\s"',;}{]+)`,"gi");SECRET_KEY_WORDS=["password","passwd","pwd","secret","token","apikey","authorization","auth"]}});function redactDiagnostic(value){return redactSecretString(value).replace(/(\/(?:Users|home)\/)[^/\s:]+/g,"$1[REDACTED_USER]")}function logInternalErrorDiagnostic(error){try{let name=error instanceof Error?error.name:typeof error,rawMessage=error instanceof Error?error.message:String(error),message=redactDiagnostic(rawMessage).replace(/\s*\n\s*/g," ");console.error(`[conductor:INTERNAL_ERROR] [${name}] ${message}`)}catch{}}function isConductorNativeModuleLoadError(error){if(!(error instanceof Error)||error.name!=="ConductorNativeModuleLoadError")return!1;let details=error.details;if(!details||typeof details!="object"||Array.isArray(details))return!1;let d=details;return typeof d.node_version=="string"&&typeof d.node_modules_abi=="string"&&typeof d.module=="string"}function nativeModuleDetailsEnvelope(details){return{node_version:details.node_version,node_modules_abi:details.node_modules_abi,module:details.module}}function isSqliteBusyError(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&(code.startsWith("SQLITE_BUSY")||code.startsWith("SQLITE_LOCKED")))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("database is locked")||lowered.includes("database is busy")||lowered.includes("sqlite_busy")||lowered.includes("sqlite_locked"))return!0}return!1}function toConductorErrorEnvelope(error){return error instanceof ConductorEpicTickV1FrozenError?{error:"EPIC_TICK_V1_FROZEN",status:400,message:error.message}:isConductorNativeModuleLoadError(error)?{error:"LEDGER_NATIVE_MODULE_LOAD_FAILED",status:500,message:"Conductor ledger native module failed to load for this Node runtime.",details:nativeModuleDetailsEnvelope(error.details)}:error instanceof Error&&error.name==="ConductorPersistenceUnavailableError"?{error:"PERSISTENCE_UNAVAILABLE",status:503,message:"Conductor persistence is unavailable (the optional better-sqlite3 native module is not loaded). Conductor coordination features are disabled; core tools are unaffected."}:error instanceof ConductorLedgerSubprocessRuntimeError?{error:"LEDGER_SUBPROCESS_RUNTIME_UNAVAILABLE",status:503,message:"Conductor worker ledger subprocess is unavailable; the worker Node cannot reach the local ledger. The dispatched conductor Node runtime is missing or invalid \u2014 conductor worker coordination is degraded; core tools are unaffected.",details:{env_var:error.envVar,reason:error.reason}}:error instanceof ConductorValidationError?{error:"VALIDATION_ERROR",status:400,message:redactSecretString(error.message)}:isSqliteBusyError(error)?{error:"STORE_BUSY",status:503,message:"Conductor ledger is busy; retry shortly."}:(logInternalErrorDiagnostic(error),{error:"INTERNAL_ERROR",status:500,message:"Conductor ledger operation failed."})}var ConductorValidationError,ConductorEpicTickV1FrozenError,ConductorLedgerSubprocessRuntimeError,init_errors=__esm({"src/conductor/errors.ts"(){"use strict";init_redaction();ConductorValidationError=class extends Error{constructor(message){super(message),this.name="ConductorValidationError"}},ConductorEpicTickV1FrozenError=class extends Error{constructor(){super("The v1 `conductor epic-tick` path is frozen (EPIC_TICK_V1_FROZEN). Epic Conductor v2 replaces the local epic tick with a server-side reconciler plus the local executor \u2014 run `mcp-server executor` instead."),this.name="ConductorEpicTickV1FrozenError"}},ConductorLedgerSubprocessRuntimeError=class extends Error{reason;envVar;constructor(reason,envVar){super(`Conductor worker ledger subprocess is unavailable (reason: ${reason}).`),this.name="ConductorLedgerSubprocessRuntimeError",this.reason=reason,this.envVar=envVar}}}});function isSemanticEventType(value){return typeof value=="string"&&SEMANTIC_EVENT_TYPES.includes(value)}function assertSemanticEventType(value){if(isSemanticEventType(value))return value;let rendered=typeof value=="string"?value:typeof value;throw new ConductorValidationError(`Unknown conductor event type "${rendered}". Allowed types: ${SEMANTIC_EVENT_TYPES.join(", ")}.`)}var SEMANTIC_EVENT_TYPES,init_taxonomy=__esm({"src/conductor/taxonomy.ts"(){"use strict";init_errors();SEMANTIC_EVENT_TYPES=["run.started","run.heartbeat","run.stopped","agent.notification","tool.intent","worktree.changed","git.commit_created","git.pr_opened","ci.passed","ci.failed","gate.met","supervisor.assessment","message.sent","message.delivered","message.acked","merge.dry_run","merge.attempted","merge.succeeded","merge.failed","merge.conflict","merge.pending_approval","review.passed","review.changes_requested","spec_review.passed","spec_review.changes_requested","parse.triggered","parse.succeeded","parse.failed"]}});function isPlainObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function normalizeEventData(data){if(data==null)return{};if(!isPlainObject(data))throw new ConductorValidationError("Event data must be a JSON object (received an array or primitive).");let offending=Object.keys(data).filter(key=>!ALLOWED_DATA_KEY_SET.has(key));if(offending.length>0)throw new ConductorValidationError(`Event data has non-allowlisted top-level field(s): ${offending.join(", ")}. Place tool-native fields under "data.raw" instead. Allowed top-level keys: ${ALLOWED_DATA_KEYS.join(", ")}.`);return data}function maxInlineStringLength(value){if(typeof value=="string")return value.length;if(Array.isArray(value)){let max=0;for(let item of value)max=Math.max(max,maxInlineStringLength(item));return max}if(isPlainObject(value)){let max=0;for(let val of Object.values(value))max=Math.max(max,maxInlineStringLength(val));return max}return 0}function validateLargePayloadReferences(data){let longest=maxInlineStringLength(data);if(longest>MAX_INLINE_STRING_CHARS)throw new ConductorValidationError(`Event data contains an inline string of ${longest} characters, exceeding the ${MAX_INLINE_STRING_CHARS}-character limit. Store large diffs/transcripts externally and pass a reference via "data.references" or "data.payload_ref".`);let serializedLength=0;try{serializedLength=JSON.stringify(data)?.length??0}catch{throw new ConductorValidationError("Event data is not JSON-serializable.")}if(serializedLength>MAX_TOTAL_DATA_CHARS)throw new ConductorValidationError(`Serialized event data is ${serializedLength} characters, exceeding the ${MAX_TOTAL_DATA_CHARS}-character limit. Pass large content by reference via "data.references" or "data.payload_ref".`)}function prepareDataJsonForStorage(data){let normalized=normalizeEventData(data);validateLargePayloadReferences(normalized);let redacted=redactSecrets(normalized);return JSON.stringify(redacted)}var ALLOWED_DATA_KEYS,ALLOWED_DATA_KEY_SET,MAX_INLINE_STRING_CHARS,MAX_TOTAL_DATA_CHARS,init_data_normalization=__esm({"src/conductor/data-normalization.ts"(){"use strict";init_errors();init_redaction();ALLOWED_DATA_KEYS=["summary","status","message","details","reason","metrics","labels","references","payload_ref","raw"],ALLOWED_DATA_KEY_SET=new Set(ALLOWED_DATA_KEYS),MAX_INLINE_STRING_CHARS=16384,MAX_TOTAL_DATA_CHARS=65536}});import path from"path";function getPrimaryCredentialStorePath(deps){let xdg=deps.env.XDG_CONFIG_HOME;return xdg&&xdg.trim().length>0?path.join(xdg,"bridge","credentials.json"):path.join(deps.homedir(),".config","bridge","credentials.json")}function getFallbackCredentialStorePath(deps){return path.join(deps.homedir(),".bridge","credentials.json")}async function resolveCredentialStorePath(deps){let primaryPath=getPrimaryCredentialStorePath(deps),fallbackPath=getFallbackCredentialStorePath(deps);try{return await deps.stat(primaryPath),{found:!0,path:primaryPath,isPrimary:!0}}catch(err){if((err&&typeof err=="object"?err.code:void 0)!=="ENOENT")return{found:!0,path:primaryPath,isPrimary:!0}}try{return await deps.stat(fallbackPath),{found:!0,path:fallbackPath,isPrimary:!1}}catch{return{found:!1,primaryPath,fallbackPath}}}function warnIfInsecureCredentialFileMode(statResult,platform,filePath,stderr){platform!=="win32"&&(statResult.mode&63)!==0&&(stderr??(m=>process.stderr.write(`${m}
2
+ var __defProp=Object.defineProperty;var __getOwnPropNames=Object.getOwnPropertyNames;var __esm=(fn,res,err)=>function(){if(err)throw err[0];try{return fn&&(res=(0,fn[__getOwnPropNames(fn)[0]])(fn=0)),res}catch(e){throw err=[e],e}};var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})};function redactSecretString(value){let out=value;for(let{pattern,replacement}of STANDALONE_PATTERNS)out=out.replace(pattern,replacement);return out=out.replace(ASSIGNMENT_QUOTED,(_m,key,sep,q)=>`${key}${sep}${q}${REDACTED}${q}`),out=out.replace(ASSIGNMENT_UNQUOTED,(_m,key,sep)=>`${key}${sep}${REDACTED}`),out}function isSecretKey(key){let norm=key.toLowerCase().replace(/[_-]/g,"");return SECRET_KEY_WORDS.some(word=>norm===word||norm.endsWith(word))}function redactSecrets(value){if(typeof value=="string")return redactSecretString(value);if(Array.isArray(value))return value.map(item=>item===void 0?null:redactSecrets(item));if(value!==null&&typeof value=="object"){let out={};for(let[key,val]of Object.entries(value))val!==void 0&&(typeof val=="string"&&isSecretKey(key)?out[key]=REDACTED:out[key]=redactSecrets(val));return out}return value}var REDACTED,STANDALONE_PATTERNS,ASSIGNMENT_KEYS,ASSIGNMENT_QUOTED,ASSIGNMENT_UNQUOTED,SECRET_KEY_WORDS,init_redaction=__esm({"src/conductor/redaction.ts"(){"use strict";REDACTED="[REDACTED]",STANDALONE_PATTERNS=[{pattern:/-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z0-9 ]*PRIVATE KEY-----/g,replacement:REDACTED},{pattern:/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,replacement:REDACTED},{pattern:/\bBearer\s+[A-Za-z0-9._-]+/gi,replacement:`Bearer ${REDACTED}`},{pattern:/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,replacement:REDACTED},{pattern:/\bgh[pousr]_[A-Za-z0-9]{6,}\b/g,replacement:REDACTED},{pattern:/\bsk-(?:ant-|proj-)?[A-Za-z0-9_-]{6,}\b/g,replacement:REDACTED}],ASSIGNMENT_KEYS="api[_-]?key|apikey|secret|token|password|passwd|pwd|authorization|auth",ASSIGNMENT_QUOTED=new RegExp(`\\b(${ASSIGNMENT_KEYS})(\\s*[:=]\\s*)("|')[^"']*("|')`,"gi"),ASSIGNMENT_UNQUOTED=new RegExp(`\\b(${ASSIGNMENT_KEYS})(\\s*[:=]\\s*)([^\\s"',;}{]+)`,"gi");SECRET_KEY_WORDS=["password","passwd","pwd","secret","token","apikey","authorization","auth"]}});function redactDiagnostic(value){return redactSecretString(value).replace(/(\/(?:Users|home)\/)[^/\s:]+/g,"$1[REDACTED_USER]")}function logInternalErrorDiagnostic(error){try{let name=error instanceof Error?error.name:typeof error,rawMessage=error instanceof Error?error.message:String(error),message=redactDiagnostic(rawMessage).replace(/\s*\n\s*/g," ");console.error(`[conductor:INTERNAL_ERROR] [${name}] ${message}`)}catch{}}function isConductorNativeModuleLoadError(error){if(!(error instanceof Error)||error.name!=="ConductorNativeModuleLoadError")return!1;let details=error.details;if(!details||typeof details!="object"||Array.isArray(details))return!1;let d=details;return typeof d.node_version=="string"&&typeof d.node_modules_abi=="string"&&typeof d.module=="string"}function nativeModuleDetailsEnvelope(details){return{node_version:details.node_version,node_modules_abi:details.node_modules_abi,module:details.module}}function isSqliteBusyError(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&(code.startsWith("SQLITE_BUSY")||code.startsWith("SQLITE_LOCKED")))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("database is locked")||lowered.includes("database is busy")||lowered.includes("sqlite_busy")||lowered.includes("sqlite_locked"))return!0}return!1}function toConductorErrorEnvelope(error){return error instanceof ConductorEpicTickV1FrozenError?{error:"EPIC_TICK_V1_FROZEN",status:400,message:error.message}:isConductorNativeModuleLoadError(error)?{error:"LEDGER_NATIVE_MODULE_LOAD_FAILED",status:500,message:"Conductor ledger native module failed to load for this Node runtime.",details:nativeModuleDetailsEnvelope(error.details)}:error instanceof Error&&error.name==="ConductorPersistenceUnavailableError"?{error:"PERSISTENCE_UNAVAILABLE",status:503,message:"Conductor persistence is unavailable (the optional better-sqlite3 native module is not loaded). Conductor coordination features are disabled; core tools are unaffected."}:error instanceof ConductorLedgerSubprocessRuntimeError?{error:"LEDGER_SUBPROCESS_RUNTIME_UNAVAILABLE",status:503,message:"Conductor worker ledger subprocess is unavailable; the worker Node cannot reach the local ledger. The dispatched conductor Node runtime is missing or invalid \u2014 conductor worker coordination is degraded; core tools are unaffected.",details:{env_var:error.envVar,reason:error.reason}}:error instanceof ConductorWorkerContextRequiredError?{error:"WORKER_CONTEXT_REQUIRED",status:400,message:error.message,details:{missing_env_vars:error.missingEnvVars.join(","),alternatives:WORKER_CONTEXT_ALTERNATIVES}}:error instanceof ConductorValidationError?{error:"VALIDATION_ERROR",status:400,message:redactSecretString(error.message)}:isSqliteBusyError(error)?{error:"STORE_BUSY",status:503,message:"Conductor ledger is busy; retry shortly."}:(logInternalErrorDiagnostic(error),{error:"INTERNAL_ERROR",status:500,message:"Conductor ledger operation failed."})}var ConductorValidationError,ConductorEpicTickV1FrozenError,ConductorLedgerSubprocessRuntimeError,WORKER_CONTEXT_ALTERNATIVES,ConductorWorkerContextRequiredError,init_errors=__esm({"src/conductor/errors.ts"(){"use strict";init_redaction();ConductorValidationError=class extends Error{constructor(message){super(message),this.name="ConductorValidationError"}},ConductorEpicTickV1FrozenError=class extends Error{constructor(){super("The v1 `conductor epic-tick` path is frozen (EPIC_TICK_V1_FROZEN). Epic Conductor v2 replaces the local epic tick with a server-side reconciler plus the local executor \u2014 run `mcp-server executor` instead."),this.name="ConductorEpicTickV1FrozenError"}},ConductorLedgerSubprocessRuntimeError=class extends Error{reason;envVar;constructor(reason,envVar){super(`Conductor worker ledger subprocess is unavailable (reason: ${reason}).`),this.name="ConductorLedgerSubprocessRuntimeError",this.reason=reason,this.envVar=envVar}},WORKER_CONTEXT_ALTERNATIVES="get_epic_snapshot, poll_events",ConductorWorkerContextRequiredError=class extends Error{missingEnvVars;constructor(missingEnvVars){super(`This operation is available only inside a conductor-spawned worker session (created by \`start-tickets --conductor\` or an executor job). Missing worker context: ${missingEnvVars.join(", ")}. No fallback was performed. In a plain session use ${WORKER_CONTEXT_ALTERNATIVES} instead.`),this.name="ConductorWorkerContextRequiredError",this.missingEnvVars=missingEnvVars}}}});function isSemanticEventType(value){return typeof value=="string"&&SEMANTIC_EVENT_TYPES.includes(value)}function assertSemanticEventType(value){if(isSemanticEventType(value))return value;let rendered=typeof value=="string"?value:typeof value;throw new ConductorValidationError(`Unknown conductor event type "${rendered}". Allowed types: ${SEMANTIC_EVENT_TYPES.join(", ")}.`)}var SEMANTIC_EVENT_TYPES,init_taxonomy=__esm({"src/conductor/taxonomy.ts"(){"use strict";init_errors();SEMANTIC_EVENT_TYPES=["run.started","run.heartbeat","run.stopped","agent.notification","tool.intent","worktree.changed","git.commit_created","git.pr_opened","ci.passed","ci.failed","gate.met","supervisor.assessment","message.sent","message.delivered","message.acked","merge.dry_run","merge.attempted","merge.succeeded","merge.failed","merge.conflict","merge.pending_approval","review.passed","review.changes_requested","spec_review.passed","spec_review.changes_requested","parse.triggered","parse.succeeded","parse.failed"]}});function isPlainObject(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function normalizeEventData(data){if(data==null)return{};if(!isPlainObject(data))throw new ConductorValidationError("Event data must be a JSON object (received an array or primitive).");let offending=Object.keys(data).filter(key=>!ALLOWED_DATA_KEY_SET.has(key));if(offending.length>0)throw new ConductorValidationError(`Event data has non-allowlisted top-level field(s): ${offending.join(", ")}. Place tool-native fields under "data.raw" instead. Allowed top-level keys: ${ALLOWED_DATA_KEYS.join(", ")}.`);return data}function maxInlineStringLength(value){if(typeof value=="string")return value.length;if(Array.isArray(value)){let max=0;for(let item of value)max=Math.max(max,maxInlineStringLength(item));return max}if(isPlainObject(value)){let max=0;for(let val of Object.values(value))max=Math.max(max,maxInlineStringLength(val));return max}return 0}function validateLargePayloadReferences(data){let longest=maxInlineStringLength(data);if(longest>MAX_INLINE_STRING_CHARS)throw new ConductorValidationError(`Event data contains an inline string of ${longest} characters, exceeding the ${MAX_INLINE_STRING_CHARS}-character limit. Store large diffs/transcripts externally and pass a reference via "data.references" or "data.payload_ref".`);let serializedLength=0;try{serializedLength=JSON.stringify(data)?.length??0}catch{throw new ConductorValidationError("Event data is not JSON-serializable.")}if(serializedLength>MAX_TOTAL_DATA_CHARS)throw new ConductorValidationError(`Serialized event data is ${serializedLength} characters, exceeding the ${MAX_TOTAL_DATA_CHARS}-character limit. Pass large content by reference via "data.references" or "data.payload_ref".`)}function prepareDataJsonForStorage(data){let normalized=normalizeEventData(data);validateLargePayloadReferences(normalized);let redacted=redactSecrets(normalized);return JSON.stringify(redacted)}var ALLOWED_DATA_KEYS,ALLOWED_DATA_KEY_SET,MAX_INLINE_STRING_CHARS,MAX_TOTAL_DATA_CHARS,init_data_normalization=__esm({"src/conductor/data-normalization.ts"(){"use strict";init_errors();init_redaction();ALLOWED_DATA_KEYS=["summary","status","message","details","reason","metrics","labels","references","payload_ref","raw"],ALLOWED_DATA_KEY_SET=new Set(ALLOWED_DATA_KEYS),MAX_INLINE_STRING_CHARS=16384,MAX_TOTAL_DATA_CHARS=65536}});import path from"path";function getPrimaryCredentialStorePath(deps){let xdg=deps.env.XDG_CONFIG_HOME;return xdg&&xdg.trim().length>0?path.join(xdg,"bridge","credentials.json"):path.join(deps.homedir(),".config","bridge","credentials.json")}function getFallbackCredentialStorePath(deps){return path.join(deps.homedir(),".bridge","credentials.json")}async function resolveCredentialStorePath(deps){let primaryPath=getPrimaryCredentialStorePath(deps),fallbackPath=getFallbackCredentialStorePath(deps);try{return await deps.stat(primaryPath),{found:!0,path:primaryPath,isPrimary:!0}}catch(err){if((err&&typeof err=="object"?err.code:void 0)!=="ENOENT")return{found:!0,path:primaryPath,isPrimary:!0}}try{return await deps.stat(fallbackPath),{found:!0,path:fallbackPath,isPrimary:!1}}catch{return{found:!1,primaryPath,fallbackPath}}}function warnIfInsecureCredentialFileMode(statResult,platform,filePath,stderr){platform!=="win32"&&(statResult.mode&63)!==0&&(stderr??(m=>process.stderr.write(`${m}
3
3
  `)))(`Warning: credentials file ${filePath} is group/world-accessible; it should be mode 0600 (run: chmod 600 ${filePath}).`)}function parseCredentialStoreJson(text){let data;try{data=JSON.parse(text)}catch{return{ok:!1,error:"credentials file is not valid JSON"}}if(data===null||typeof data!="object"||Array.isArray(data))return{ok:!1,error:"credentials file must be a JSON object"};for(let[key,value]of Object.entries(data)){if(value===null||typeof value!="object"||Array.isArray(value))return{ok:!1,error:`credentials entry "${key}" must be an object of secret names to strings`};for(let[secretName,secretValue]of Object.entries(value))if(typeof secretValue!="string")return{ok:!1,error:`credentials entry "${key}" has a non-string value for "${secretName}"`}}return{ok:!0,value:data}}function collectEnvValues(env,requiredKeys){let values={},missing=[];for(let key of requiredKeys){let raw=(env[key]??"").trim();raw.length>0?values[key]=raw:missing.push(key)}return{values,missing}}async function resolveCredentialBundle(bundleKey,requiredKeys,deps){let primaryPath=getPrimaryCredentialStorePath(deps),fromEnv=collectEnvValues(deps.env,requiredKeys);if(fromEnv.missing.length===0)return{ok:!0,values:fromEnv.values,source:"env"};let resolution=await resolveCredentialStorePath(deps);if(!resolution.found)return{ok:!1,kind:"not-found",error:`No credentials found for "${bundleKey}". Set ${fromEnv.missing.join(", ")} in the environment, or add them under "${bundleKey}" in ${primaryPath}.`};try{let statResult=await deps.stat(resolution.path);warnIfInsecureCredentialFileMode(statResult,deps.platform,resolution.path,deps.stderr)}catch{}let raw;try{raw=await deps.readFile(resolution.path)}catch{return{ok:!1,kind:"read-error",error:`Unable to read credentials file at ${resolution.path}.`}}let parsed=parseCredentialStoreJson(raw);if(!parsed.ok)return{ok:!1,kind:"parse-error",error:`Invalid credentials file at ${resolution.path}: ${parsed.error}.`};let entry=parsed.value[bundleKey]??{},values={...fromEnv.values},stillMissing=[];for(let key of fromEnv.missing){let storeValue=typeof entry[key]=="string"?entry[key].trim():"";storeValue.length>0?values[key]=storeValue:stillMissing.push(key)}return stillMissing.length>0?{ok:!1,kind:"missing-key",error:`No usable value(s) for ${stillMissing.join(", ")} in "${bundleKey}". Add them under "${bundleKey}" in ${primaryPath}, or set them in the environment.`}:{ok:!0,values,source:"file"}}async function resolveBapiCredentials(repoName,deps){let result=await resolveCredentialBundle(`bapi:${repoName}`,["BAPI_API_KEY"],deps);return result.ok?{ok:!0,credentials:{apiKey:result.values.BAPI_API_KEY,source:result.source}}:{ok:!1,kind:result.kind,error:result.error}}var init_credential_store=__esm({"src/credential-store.ts"(){"use strict"}});import fs from"node:fs";import os from"node:os";import path2 from"node:path";import{execFileSync}from"node:child_process";function getConductorLedgerPath(){let credentialsPath=getPrimaryCredentialStorePath({env:process.env,homedir:os.homedir});return path2.join(path2.dirname(credentialsPath),"events.db")}function getConductorLedgerDirectory(){return path2.dirname(getConductorLedgerPath())}function ensureConductorLedgerDirectory(){let dir=getConductorLedgerDirectory();return fs.mkdirSync(dir,{recursive:!0}),process.platform!=="win32"&&fs.chmodSync(dir,448),dir}function ensureConductorDatabaseFile(){ensureConductorLedgerDirectory();let dbPath=getConductorLedgerPath();if(!fs.existsSync(dbPath)){let fd=fs.openSync(dbPath,"a",384);fs.closeSync(fd)}return process.platform!=="win32"&&fs.chmodSync(dbPath,384),dbPath}function formatMode(mode){return(mode&511).toString(8).padStart(3,"0")}function getConductorPathHealth(){let dbPath=getConductorLedgerPath(),dir=path2.dirname(dbPath),warnings=[],directoryExists=!1,directoryMode=null,directoryPermissionsOk=!0;try{let dirStat=fs.statSync(dir);directoryExists=!0,directoryMode=formatMode(dirStat.mode),process.platform!=="win32"&&(dirStat.mode&63)!==0&&(directoryPermissionsOk=!1,warnings.push(`Conductor ledger directory ${dir} is group/world-accessible; it should be mode 0700.`))}catch{directoryExists=!1}let databaseExists=!1,databaseMode=null,databasePermissionsOk=!0;try{let fileStat=fs.statSync(dbPath);databaseExists=!0,databaseMode=formatMode(fileStat.mode),process.platform!=="win32"&&(fileStat.mode&63)!==0&&(databasePermissionsOk=!1,warnings.push(`Conductor ledger file ${dbPath} is group/world-accessible; it should be mode 0600.`))}catch{databaseExists=!1}return{path:dbPath,directory_path:dir,directory_exists:directoryExists,database_exists:databaseExists,directory_mode:directoryMode,database_mode:databaseMode,directory_permissions_ok:directoryPermissionsOk,database_permissions_ok:databasePermissionsOk,warnings}}function matchesNetworkFsType(raw){let lowered=raw.trim().toLowerCase();if(lowered.length===0)return null;for(let marker of NETWORK_FS_MARKERS)if(lowered.includes(marker))return lowered;return null}function detectNetworkMountedHome(){let home="";try{home=os.homedir()}catch{return{network_mounted:!1,filesystem_type:null,home:"",warning:null}}if(process.platform==="win32")return home.startsWith("\\\\")||home.startsWith("//")?{network_mounted:!0,filesystem_type:"unc",home,warning:`Home directory ${home} appears to be a UNC network share; concurrent SQLite writes to the conductor ledger may be unreliable.`}:{network_mounted:!1,filesystem_type:null,home,warning:null};let args=process.platform==="darwin"?["-f","%T",home]:["-f","-c","%T",home];try{let output=execFileSync("stat",args,{encoding:"utf-8",timeout:1500,stdio:["ignore","pipe","ignore"]}),fsType=matchesNetworkFsType(output);return fsType?{network_mounted:!0,filesystem_type:fsType,home,warning:`Home directory ${home} appears to be on a network filesystem (${fsType}); concurrent SQLite writes to the conductor ledger may be unreliable.`}:{network_mounted:!1,filesystem_type:output.trim().toLowerCase()||null,home,warning:null}}catch{return{network_mounted:!1,filesystem_type:null,home,warning:null}}}var NETWORK_FS_MARKERS,init_paths=__esm({"src/conductor/paths.ts"(){"use strict";init_credential_store();NETWORK_FS_MARKERS=["nfs","cifs","smb","smbfs","afpfs","sshfs","fuse.sshfs","fuse.gvfs","9p","webdav"]}});import{randomUUID}from"node:crypto";import{existsSync}from"node:fs";function buildNativeModuleLoadDetails(){return{node_version:process.version,node_modules_abi:process.versions.modules??"unknown",module:LEDGER_NATIVE_MODULE_NAME}}function classifyDatabaseModuleLoadFailure(error){let code=error&&typeof error=="object"?error.code:void 0,lowered=(error&&typeof error=="object"&&typeof error.message=="string"?error.message:"").toLowerCase();return code==="MODULE_NOT_FOUND"||code==="ERR_MODULE_NOT_FOUND"?new ConductorPersistenceUnavailableError:lowered.includes("node_module_version")||lowered.includes("compiled against a different node.js version")||lowered.includes("module version mismatch")?new ConductorNativeModuleLoadError("abi_mismatch",buildNativeModuleLoadDetails()):code==="ERR_DLOPEN_FAILED"||lowered.includes("dlopen")?new ConductorNativeModuleLoadError("dlopen_failed",buildNativeModuleLoadDetails()):new ConductorPersistenceUnavailableError}async function getDatabaseModule(){if(dbLoadFailure)throw dbLoadFailure;return databaseModulePromise||(databaseModulePromise=(async()=>{try{let mod=await import("better-sqlite3");return mod.default??mod}catch(err){let classified=classifyDatabaseModuleLoadFailure(err);if(dbLoadFailure=classified,databaseModulePromise=null,!dbLoadDiagnosticEmitted){dbLoadDiagnosticEmitted=!0;let kind=classified instanceof ConductorNativeModuleLoadError?classified.failureKind:"unavailable";console.error(`[conductor] ${LEDGER_NATIVE_MODULE_NAME} native module could not be loaded (node=${process.version} abi=${process.versions.modules??"unknown"} kind=${kind}). Conductor coordination features are disabled for this session; core MCP tools are unaffected.`)}throw classified}})(),databaseModulePromise)}function parseBoundedInt(raw,fallback,min,max){if(raw===void 0||raw.trim().length===0)return fallback;let parsed=Number.parseInt(raw.trim(),10);return Number.isFinite(parsed)?Math.min(max,Math.max(min,parsed)):fallback}function resolveConductorStoreConfig(env=process.env){let busy_timeout_ms=parseBoundedInt(env.BAPI_CONDUCTOR_BUSY_TIMEOUT_MS,BUSY_TIMEOUT_DEFAULT,BUSY_TIMEOUT_MIN,BUSY_TIMEOUT_MAX),rawDays=env.BAPI_CONDUCTOR_RETENTION_DAYS,retention_days=RETENTION_DAYS_DEFAULT;if(rawDays!==void 0&&rawDays.trim().length>0){let parsed=Number.parseInt(rawDays.trim(),10);Number.isFinite(parsed)?parsed<=0?retention_days=0:retention_days=Math.min(RETENTION_DAYS_MAX,parsed):retention_days=RETENTION_DAYS_DEFAULT}let rawRows=env.BAPI_CONDUCTOR_RETENTION_MAX_ROWS,retention_max_rows=RETENTION_MAX_ROWS_DEFAULT;if(rawRows!==void 0&&rawRows.trim().length>0){let parsed=Number.parseInt(rawRows.trim(),10);Number.isFinite(parsed)?parsed<=0?retention_max_rows=0:retention_max_rows=Math.min(RETENTION_MAX_ROWS_MAX,Math.max(RETENTION_MAX_ROWS_MIN,parsed)):retention_max_rows=RETENTION_MAX_ROWS_DEFAULT}let rawCooldown=env.BAPI_CONDUCTOR_MESSAGE_COOLDOWN_MS,message_cooldown_ms=MESSAGE_COOLDOWN_DEFAULT_MS;if(rawCooldown!==void 0&&rawCooldown.trim().length>0){let parsed=Number.parseInt(rawCooldown.trim(),10);Number.isFinite(parsed)?parsed<=0?message_cooldown_ms=0:message_cooldown_ms=Math.min(MESSAGE_COOLDOWN_MAX_MS,Math.max(MESSAGE_COOLDOWN_MIN_MS,parsed)):message_cooldown_ms=MESSAGE_COOLDOWN_DEFAULT_MS}return{busy_timeout_ms,retention_days,retention_max_rows,message_cooldown_ms}}function buildTypeCheckClause(){return`CHECK (type IN (${SEMANTIC_EVENT_TYPES.map(t=>`'${t}'`).join(", ")}))`}function buildEventsTableSql(tableName){return`
4
4
  CREATE TABLE IF NOT EXISTS ${tableName} (
5
5
  seq INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -99,14 +99,14 @@ var __defProp=Object.defineProperty;var __getOwnPropNames=Object.getOwnPropertyN
99
99
  LIMIT @limit`),toDelivered=db.prepare("UPDATE messages SET state = 'delivered', updated_at = datetime('now') WHERE seq = @seq AND state = 'pending'"),toAcked=db.prepare("UPDATE messages SET state = 'acked', acked_at = datetime('now'), updated_at = datetime('now') WHERE seq = @seq AND state = 'delivered'"),reread=db.prepare("SELECT * FROM messages WHERE seq = ?"),delivered=[];return db.transaction(()=>{let pending=selectPending.all({run_id:runId,worker_id:workerId,limit});for(let row of pending){if(toDelivered.run({seq:row.seq}).changes!==1)continue;insertRelayAuditEvent(db,{id:`message.delivered:${row.id}`,source:"conductor-worker",type:"message.delivered",run_id:row.run_id,worker_id:row.worker_id,producer:"worker-message-relay",observed_via:"message-relay",data:{summary:"supervisor message delivered to worker",status:"delivered",details:{message_id:row.id,message_type:row.type}}}),toAcked.run({seq:row.seq}),insertRelayAuditEvent(db,{id:`message.acked:${row.id}`,source:"conductor-worker",type:"message.acked",run_id:row.run_id,worker_id:row.worker_id,producer:"worker-message-relay",observed_via:"message-relay",data:{summary:"supervisor message acknowledged by worker",status:"acked",details:{message_id:row.id,message_type:row.type}}});let finalRow=reread.get(row.seq);delivered.push(rowToConductorWorkerMessage(finalRow))}}).immediate(),{messages:delivered,count:delivered.length,acked_count:delivered.length}}finally{db.close()}}var ConductorPersistenceUnavailableError,LEDGER_NATIVE_MODULE_NAME,ConductorNativeModuleLoadError,databaseModulePromise,dbLoadFailure,dbLoadDiagnosticEmitted,BUSY_TIMEOUT_DEFAULT,BUSY_TIMEOUT_MIN,BUSY_TIMEOUT_MAX,RETENTION_DAYS_DEFAULT,RETENTION_DAYS_MAX,RETENTION_MAX_ROWS_DEFAULT,RETENTION_MAX_ROWS_MIN,RETENTION_MAX_ROWS_MAX,POLL_LIMIT_DEFAULT,POLL_LIMIT_MAX,MESSAGE_COOLDOWN_DEFAULT_MS,MESSAGE_COOLDOWN_MIN_MS,MESSAGE_COOLDOWN_MAX_MS,CHECK_MESSAGES_LIMIT_DEFAULT,CHECK_MESSAGES_LIMIT_MAX,WAIT_TIMEOUT_MAX_MS,WAIT_POLL_INTERVAL_MS,SUMMARY_FIELD_MAX_CHARS,CURRENT_CONDUCTOR_SCHEMA_VERSION,MESSAGE_TYPE_PATTERN,init_store=__esm({"src/conductor/store.ts"(){"use strict";init_taxonomy();init_errors();init_data_normalization();init_paths();ConductorPersistenceUnavailableError=class extends Error{constructor(message="Conductor persistence is unavailable: the optional 'better-sqlite3' native module could not be loaded."){super(message),this.name="ConductorPersistenceUnavailableError"}},LEDGER_NATIVE_MODULE_NAME="better-sqlite3",ConductorNativeModuleLoadError=class extends ConductorPersistenceUnavailableError{details;failureKind;constructor(failureKind,details){super("Conductor ledger native module failed to load for this Node runtime."),this.name="ConductorNativeModuleLoadError",this.failureKind=failureKind,this.details=details}};databaseModulePromise=null,dbLoadFailure=null,dbLoadDiagnosticEmitted=!1;BUSY_TIMEOUT_DEFAULT=1e4,BUSY_TIMEOUT_MIN=250,BUSY_TIMEOUT_MAX=12e4,RETENTION_DAYS_DEFAULT=30,RETENTION_DAYS_MAX=3650,RETENTION_MAX_ROWS_DEFAULT=5e4,RETENTION_MAX_ROWS_MIN=100,RETENTION_MAX_ROWS_MAX=1e7,POLL_LIMIT_DEFAULT=100,POLL_LIMIT_MAX=1e3,MESSAGE_COOLDOWN_DEFAULT_MS=3e5,MESSAGE_COOLDOWN_MIN_MS=1e3,MESSAGE_COOLDOWN_MAX_MS=864e5,CHECK_MESSAGES_LIMIT_DEFAULT=10,CHECK_MESSAGES_LIMIT_MAX=100,WAIT_TIMEOUT_MAX_MS=12e4,WAIT_POLL_INTERVAL_MS=500,SUMMARY_FIELD_MAX_CHARS=500;CURRENT_CONDUCTOR_SCHEMA_VERSION=8;MESSAGE_TYPE_PATTERN=/^[A-Za-z0-9._:-]{1,100}$/}});import{createHash}from"node:crypto";function normalizeRepoName(value){if(typeof value!="string")return null;let trimmed=value.trim();return trimmed.length===0||CONTROL_CHAR_RE.test(trimmed)?null:trimmed}function normalizeSha(value){if(typeof value!="string")return null;let lowered=value.trim().toLowerCase();return SHA_RE.test(lowered)?lowered:null}function normalizePrNumber(value){return typeof value!="number"||!Number.isSafeInteger(value)||value<=0?null:value}function canonicalize(value){if(Array.isArray(value))return value.map(item=>canonicalize(item));if(value!==null&&typeof value=="object"){let record=value,sortedKeys=Object.keys(record).sort(),out={};for(let key of sortedKeys)out[key]=canonicalize(record[key]);return out}return value}function stableJsonHash(value){let canonical=canonicalize(value),json=JSON.stringify(canonical)??"null";return createHash("sha256").update(json).digest("hex")}var GIT_HOOK_PRODUCER,CONTROL_CHAR_RE,SHA_RE,init_git_ci_types=__esm({"src/conductor/git-ci-types.ts"(){"use strict";GIT_HOOK_PRODUCER="git-hook",CONTROL_CHAR_RE=/[\u0000-\u001F\u007F]/,SHA_RE=/^[0-9a-f]{40}$|^[0-9a-f]{64}$/}});import{createHash as createHash2}from"node:crypto";function makeProducerDedupeKey(dimensions){let canonical={};for(let[key,value]of Object.entries(dimensions))value!=null&&(canonical[key]=value);return stableJsonHash(canonical)}function makeStableProducerEventId(dedupeKey){let h=createHash2("sha256").update(`conductor-producer:${dedupeKey}`).digest("hex");return`${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20,32)}`}function isDuplicateConstraintError2(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&code.startsWith("SQLITE_CONSTRAINT"))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("unique constraint")||lowered.includes("constraint failed"))return!0}return!1}async function eventAlreadyExists(dedupeKey,deps={}){let pollEvents=deps.pollEvents??(options=>pollConductorEvents(options)),sinceSeq=1;for(let page=0;page<LEDGER_SCAN_MAX_PAGES;page+=1){let result;try{result=await pollEvents({since_seq:sinceSeq,data_mode:"full",limit:LEDGER_SCAN_PAGE_LIMIT})}catch{return!1}for(let event of result.events){if(!event||typeof event!="object")continue;let data=event.data;if(data&&typeof data=="object"){let details=data.details;if(details&&typeof details=="object"&&details.dedupe_key===dedupeKey)return!0}}if(result.count===0||result.next_seq<=sinceSeq)break;sinceSeq=result.next_seq}return!1}async function emitConductorEventIfNew(input,dimensions,deps={}){let emitEvent=deps.emitEvent??emitConductorEvent,dedupeKey=makeProducerDedupeKey(dimensions);if(await eventAlreadyExists(dedupeKey,deps))return{emitted:!1,reason:"duplicate"};let eventId=makeStableProducerEventId(dedupeKey),existingData=input.data??{},existingDetails=existingData.details&&typeof existingData.details=="object"&&!Array.isArray(existingData.details)?existingData.details:{},data={...existingData,details:{...existingDetails,dedupe_key:dedupeKey}};try{return await emitEvent({...input,id:eventId,data}),{emitted:!0,event_id:eventId}}catch(error){if(isDuplicateConstraintError2(error))return{emitted:!1,reason:"duplicate"};throw error}}var LEDGER_SCAN_PAGE_LIMIT,LEDGER_SCAN_MAX_PAGES,init_producer_ledger=__esm({"src/conductor/producer-ledger.ts"(){"use strict";init_store();init_git_ci_types();LEDGER_SCAN_PAGE_LIMIT=500,LEDGER_SCAN_MAX_PAGES=200}});import{execFileSync as execFileSync2}from"node:child_process";import{basename}from"node:path";function runGitCommand(args,options={}){try{let stdout=execFileSync2("git",args,{cwd:options.cwd,timeout:options.timeoutMs??GIT_COMMAND_TIMEOUT_MS,encoding:"utf-8",maxBuffer:GIT_COMMAND_MAX_BUFFER,stdio:["ignore","pipe","ignore"]});return{ok:!0,stdout:typeof stdout=="string"?stdout:""}}catch{return{ok:!1,stdout:""}}}function firstLine(result){if(!result.ok)return null;let trimmed=result.stdout.trim();return trimmed.length>0?trimmed:null}function sanitizeGitRemoteUrl(url){if(typeof url!="string")return null;let trimmed=url.trim();if(trimmed.length===0)return null;if(/^https?:\/\//i.test(trimmed))try{let parsed=new URL(trimmed);return parsed.username="",parsed.password="",parsed.toString()}catch{return trimmed.replace(/^(https?:\/\/)[^/@]*@/i,"$1")}return trimmed}function getGitWorktreeContext(options={}){let cwd=options.cwd??process.cwd(),env=options.env??process.env,topLevel=firstLine(runGitCommand(["rev-parse","--show-toplevel"],{cwd})),isWorktree=topLevel!==null,worktreePath=topLevel??cwd,gitCommonDir=firstLine(runGitCommand(["rev-parse","--git-common-dir"],{cwd})),branchRaw=firstLine(runGitCommand(["rev-parse","--abbrev-ref","HEAD"],{cwd})),branch=branchRaw===null||branchRaw==="HEAD"?null:branchRaw,headSha=normalizeSha(firstLine(runGitCommand(["rev-parse","HEAD"],{cwd}))??""),remoteOrigin=sanitizeGitRemoteUrl(firstLine(runGitCommand(["config","--get","remote.origin.url"],{cwd}))??"");return{repo:normalizeRepoName(env.BAPI_CONDUCTOR_REPO_NAME)??normalizeRepoName(env.BAPI_REPO_NAME)??normalizeRepoName(basename(worktreePath))??"unknown",worktree_path:worktreePath,git_common_dir:gitCommonDir,branch,head_sha:headSha,remote_origin:remoteOrigin,is_worktree:isWorktree}}function parseCoAuthoredByTrailers(message){if(typeof message!="string"||message.length===0)return[];let out=[];for(let line of message.split(/\r?\n/)){let match=CO_AUTHOR_RE.exec(line.trim());match&&out.push({name:match[1].trim(),email:match[2].trim()})}return out}function readHeadCommitMetadata(options={}){let ref=options.ref??"HEAD",result=runGitCommand(["show","-s",`--format=${COMMIT_FORMAT}`,ref],{cwd:options.cwd});if(!result.ok)return null;let fields=result.stdout.replace(/\n$/,"").split("");if(fields.length<10)return null;let[sha,parentsRaw,authorName,authorEmail,committerName,committerEmail,authoredAt,committedAt,subject,body]=fields,parents=parentsRaw.trim().split(/\s+/).map(p=>normalizeSha(p)).filter(p=>p!==null),coAuthors=parseCoAuthoredByTrailers(body);return{sha:normalizeSha(sha),parents,author_name:authorName,author_email:authorEmail,committer_name:committerName,committer_email:committerEmail,authored_at:authoredAt,committed_at:committedAt,subject,body,co_authors:coAuthors,attribution_source:coAuthors.length>0?"co-authored-by-trailer":"commit-author"}}function parseReferenceTransactionUpdates(stdin){if(typeof stdin!="string"||stdin.length===0)return[];let out=[];for(let line of stdin.split(/\r?\n/)){let trimmed=line.trim();if(trimmed.length===0)continue;let parts=trimmed.split(/\s+/);if(parts.length!==3)continue;let oldSha=normalizeSha(parts[0]),newSha=normalizeSha(parts[1]),ref=parts[2];oldSha===null||newSha===null||ref.length===0||REF_CONTROL_CHAR_RE.test(ref)||out.push({old_sha:oldSha,new_sha:newSha,ref})}return out}var GIT_COMMAND_TIMEOUT_MS,GIT_COMMAND_MAX_BUFFER,CO_AUTHOR_RE,COMMIT_FORMAT,REF_CONTROL_CHAR_RE,init_git_inspection=__esm({"src/conductor/git-inspection.ts"(){"use strict";init_git_ci_types();GIT_COMMAND_TIMEOUT_MS=5e3,GIT_COMMAND_MAX_BUFFER=10*1024*1024;CO_AUTHOR_RE=/^co-authored-by:\s*(.+?)\s*<([^<>@\s]+@[^<>\s]+)>\s*$/i;COMMIT_FORMAT="%H%x1f%P%x1f%an%x1f%ae%x1f%cn%x1f%ce%x1f%aI%x1f%cI%x1f%s%x1f%b";REF_CONTROL_CHAR_RE=/[\u0000-\u001F\u007F]/}});import{spawnSync}from"node:child_process";function normalizeRepoRelativePath(input){if(typeof input!="string")return null;let trimmed=input.trim();if(trimmed.length===0||trimmed.startsWith("/")||trimmed.startsWith("\\")||/^[A-Za-z]:[\\/]/.test(trimmed))return null;let p=trimmed.replace(/\\/g,"/");p.startsWith("./")&&(p=p.slice(2));let segments=p.split("/");if(segments.some(s=>s===".."))return null;let cleaned=segments.filter(s=>s!==""&&s!==".").join("/");return cleaned.length>0?cleaned:null}function normalizeDeclaredTouchedFiles(list){if(!Array.isArray(list))return[];let out=new Set;for(let item of list){let norm=normalizeRepoRelativePath(item);norm&&out.add(norm)}return Array.from(out).sort()}function parseDeclaredTouchedFilesFromEnv(env=process.env){let raw=env[DECLARED_TOUCHED_FILES_ENV];if(typeof raw!="string"||raw.trim().length===0)return{specified:!1};let parsed;try{parsed=JSON.parse(raw)}catch{return{specified:!1}}if(!Array.isArray(parsed))return{specified:!1};let files=normalizeDeclaredTouchedFiles(parsed);return files.length===0?{specified:!1}:{specified:!0,files}}function collectBranchChangedFiles(opts={}){let baseRef=opts.baseRef??FILE_SCOPE_GUARD_BASE_REF,spawn=opts.spawnSyncFn??defaultSpawnSync,result;try{result=spawn("git",["diff","--name-only",`${baseRef}...HEAD`],{cwd:opts.cwd,encoding:"utf-8",shell:!1})}catch{return{ok:!1,files:[]}}if(result.error||result.status!==0)return{ok:!1,files:[]};let stdout=typeof result.stdout=="string"?result.stdout:result.stdout?.toString("utf-8")??"",files=[],seen=new Set;for(let line of stdout.split(`
100
100
  `)){let norm=normalizeRepoRelativePath(line);norm&&!seen.has(norm)&&(seen.add(norm),files.push(norm))}return{ok:!0,files}}function analyzeDiffScope(input){if(!input.declared.specified)return{checked:!1,outOfScopeFiles:[],warning:null};let declaredSet=new Set(input.declared.files),outOfScope=input.changedFiles.filter(f=>!declaredSet.has(f)).sort();if(outOfScope.length===0)return{checked:!0,outOfScopeFiles:[],warning:null};let warning=`[file-scope-guard] ${input.ticketKey&&input.ticketKey.trim().length>0?input.ticketKey.trim():"unknown-ticket"}: ${outOfScope.length} file(s) changed outside the declared touched-file set (${input.declared.files.length} declared): ${outOfScope.join(", ")}. Warn-only \u2014 PR creation continues.`;return{checked:!0,outOfScopeFiles:outOfScope,warning}}function runFileScopeGuardCli(deps={}){let env=deps.env??process.env,writeOut=deps.writeOut??(m=>process.stdout.write(`${m}
101
101
  `)),writeErr=deps.writeErr??(m=>process.stderr.write(`${m}
102
- `)),ticketKey=env[FILE_SCOPE_GUARD_TICKET_KEY_ENV],declared=parseDeclaredTouchedFilesFromEnv(env);if(!declared.specified)return 0;let collected=collectBranchChangedFiles({cwd:deps.cwd,spawnSyncFn:deps.spawnSyncFn});if(!collected.ok)return writeErr(`[file-scope-guard] ${ticketKey??"unknown-ticket"}: unable to check file scope (git diff failed); continuing \u2014 PR creation is not blocked.`),0;let analysis=analyzeDiffScope({ticketKey,declared,changedFiles:collected.files});return analysis.warning&&writeOut(analysis.warning),0}var DECLARED_TOUCHED_FILES_ENV,FILE_SCOPE_GUARD_TICKET_KEY_ENV,FILE_SCOPE_GUARD_BASE_REF,defaultSpawnSync,init_file_scope_guard=__esm({"src/conductor/file-scope-guard.ts"(){"use strict";DECLARED_TOUCHED_FILES_ENV="BAPI_CONDUCTOR_DECLARED_TOUCHED_FILES_JSON",FILE_SCOPE_GUARD_TICKET_KEY_ENV="BAPI_CONDUCTOR_TICKET_KEY",FILE_SCOPE_GUARD_BASE_REF="origin/main";defaultSpawnSync=(command,args,options)=>spawnSync(command,args,options)}});import path4 from"node:path";function resolvePackageRootFromModuleUrl(moduleUrl){let pathname;try{pathname=decodeURIComponent(new URL(moduleUrl).pathname)}catch{return null}/^\/[A-Za-z]:/.test(pathname)&&(pathname=pathname.slice(1));let segments=pathname.split(/[\\/]/),markerIndex=-1;for(let i=segments.length-1;i>=0;i--)if(segments[i]==="src"||segments[i]==="build"){markerIndex=i;break}return markerIndex<=0?null:segments.slice(0,markerIndex).join("/")}function basenameAnySep(filePath){let segments=filePath.split(/[\\/]/);return segments[segments.length-1]??""}function resolveMcpShimInvocationForRuntime(deps){let nodeExecutable=deps.nodeExecutable??"node",packageRoot=resolvePackageRootFromModuleUrl(deps.moduleUrl);if(packageRoot){let candidate=`${packageRoot}/build/index.js`;if(deps.fileExists(candidate))return{form:"absolute-build-path",nodeExecutable,serverEntryPath:candidate}}let argv1=deps.argv1;return typeof argv1=="string"&&argv1.length>0&&path4.isAbsolute(argv1)&&basenameAnySep(argv1)==="index.js"&&deps.fileExists(argv1)?{form:"absolute-build-path",nodeExecutable,serverEntryPath:argv1}:{form:"npm-channel",command:"npx",packageSpec:deps.npmPackageSpec??DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC}}var DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC,init_mcp_server_invocation=__esm({"src/mcp-server-invocation.ts"(){"use strict";DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC="@bridge_gpt/mcp-server@latest"}});import path5 from"node:path";function pathApiForPlatform(platform){return platform==="win32"?path5.win32:path5.posix}var init_types=__esm({"src/scheduler-backends/types.ts"(){"use strict"}});function assertNoNul(value,label){if(value.includes("\0"))throw new Error(`Refusing to generate scheduler content: ${label} contains a NUL byte, which is not allowed.`)}function xmlEscape(value){return assertNoNul(value,"xml value"),value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function posixShellQuote(value){return assertNoNul(value,"posix shell value"),value===""?"''":`'${value.replace(/'/g,"'\\''")}'`}function windowsCmdQuote(value){return assertNoNul(value,"windows cmd value"),`"${value.replace(/"/g,'""')}"`}function escapeWindowsCmdSetValue(value){return assertNoNul(value,"windows cmd set value"),value.replace(/%/g,"%%").replace(/"/g,"")}function systemdQuote(value){return assertNoNul(value,"systemd value"),`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function bakedEnvEntries(env){let entries=[["PATH",env.envPath],["BRIDGE_GPT_NODE",env.nodePath],["BRIDGE_GPT_NPX",env.npxPath],["BRIDGE_GPT_AGENT",env.agent],["BRIDGE_GPT_AGENT_PATH",env.agentPath],["BRIDGE_GPT_REPO_PATH",env.repoPath],["BRIDGE_GPT_SCHEDULE_ID",env.scheduleId],["BRIDGE_GPT_COMMAND",env.command],["BRIDGE_GPT_COMMAND_ARGS_JSON",env.commandArgsJson]];env.ideaFile!==void 0&&entries.push(["BRIDGE_GPT_IDEA_FILE",env.ideaFile]);for(let[key,value]of entries)assertNoNul(value,key);return entries}function bakedEnvFromCreateInput(input){return{envPath:input.envPath,nodePath:input.nodePath,npxPath:input.npxPath,agent:input.agent,agentPath:input.agentPath,repoPath:input.repoPath,scheduleId:input.id,command:input.command,commandArgsJson:JSON.stringify(input.args),ideaFile:input.legacyIdeaFile}}function formatEnvExportsForGeneratedUnit(env){return bakedEnvEntries(env).map(([key,value])=>`export ${key}=${posixShellQuote(value)}`).join(`
102
+ `)),ticketKey=env[FILE_SCOPE_GUARD_TICKET_KEY_ENV],declared=parseDeclaredTouchedFilesFromEnv(env);if(!declared.specified)return 0;let collected=collectBranchChangedFiles({cwd:deps.cwd,spawnSyncFn:deps.spawnSyncFn});if(!collected.ok)return writeErr(`[file-scope-guard] ${ticketKey??"unknown-ticket"}: unable to check file scope (git diff failed); continuing \u2014 PR creation is not blocked.`),0;let analysis=analyzeDiffScope({ticketKey,declared,changedFiles:collected.files});return analysis.warning&&writeOut(analysis.warning),0}var DECLARED_TOUCHED_FILES_ENV,FILE_SCOPE_GUARD_TICKET_KEY_ENV,FILE_SCOPE_GUARD_BASE_REF,defaultSpawnSync,init_file_scope_guard=__esm({"src/conductor/file-scope-guard.ts"(){"use strict";DECLARED_TOUCHED_FILES_ENV="BAPI_CONDUCTOR_DECLARED_TOUCHED_FILES_JSON",FILE_SCOPE_GUARD_TICKET_KEY_ENV="BAPI_CONDUCTOR_TICKET_KEY",FILE_SCOPE_GUARD_BASE_REF="origin/main";defaultSpawnSync=(command,args,options)=>spawnSync(command,args,options)}});var MCP_SERVER_NAME,MCP_PACKAGE_NAME,MCP_README_URI,LEGACY_SERVER_NAMES,RECOGNIZED_SERVER_NAMES,init_mcp_identity=__esm({"src/mcp-identity.ts"(){"use strict";MCP_SERVER_NAME="bridge",MCP_PACKAGE_NAME="@bridge_gpt/mcp-server",MCP_README_URI=`${MCP_SERVER_NAME}://readme`,LEGACY_SERVER_NAMES=["bridge-api"],RECOGNIZED_SERVER_NAMES=[MCP_SERVER_NAME,...LEGACY_SERVER_NAMES]}});import path4 from"node:path";function resolvePackageRootFromModuleUrl(moduleUrl){let pathname;try{pathname=decodeURIComponent(new URL(moduleUrl).pathname)}catch{return null}/^\/[A-Za-z]:/.test(pathname)&&(pathname=pathname.slice(1));let segments=pathname.split(/[\\/]/),markerIndex=-1;for(let i=segments.length-1;i>=0;i--)if(segments[i]==="src"||segments[i]==="build"){markerIndex=i;break}return markerIndex<=0?null:segments.slice(0,markerIndex).join("/")}function basenameAnySep(filePath){let segments=filePath.split(/[\\/]/);return segments[segments.length-1]??""}function resolveMcpShimInvocationForRuntime(deps){let nodeExecutable=deps.nodeExecutable??"node",packageRoot=resolvePackageRootFromModuleUrl(deps.moduleUrl);if(packageRoot){let candidate=`${packageRoot}/build/index.js`;if(deps.fileExists(candidate))return{form:"absolute-build-path",nodeExecutable,serverEntryPath:candidate}}let argv1=deps.argv1;return typeof argv1=="string"&&argv1.length>0&&path4.isAbsolute(argv1)&&basenameAnySep(argv1)==="index.js"&&deps.fileExists(argv1)?{form:"absolute-build-path",nodeExecutable,serverEntryPath:argv1}:{form:"npm-channel",command:"npx",packageSpec:deps.npmPackageSpec??DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC}}var DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC,init_mcp_server_invocation=__esm({"src/mcp-server-invocation.ts"(){"use strict";init_mcp_identity();DEFAULT_MCP_SERVER_NPM_CHANNEL_SPEC=`${MCP_PACKAGE_NAME}@latest`}});function resolveProfiles(raw){let baseline=new Set(["core"]);if(raw===void 0)return baseline;let trimmed=raw.trim();if(trimmed==="")return baseline;let tokens=trimmed.split(",").map(t=>t.trim().toLowerCase());if(tokens.some(t=>t==="full"))return new Set(["core","conductor","pipeline-authoring","sfcc","sfcc-write"]);for(let token of tokens)VALID_GROUPS.has(token)&&baseline.add(token);return baseline}var VALID_GROUPS,init_mcp_profile=__esm({"src/mcp-profile.ts"(){"use strict";VALID_GROUPS=new Set(["core","conductor","pipeline-authoring","sfcc","sfcc-write"])}});import path5 from"node:path";function pathApiForPlatform(platform){return platform==="win32"?path5.win32:path5.posix}var init_types=__esm({"src/scheduler-backends/types.ts"(){"use strict"}});function assertNoNul(value,label){if(value.includes("\0"))throw new Error(`Refusing to generate scheduler content: ${label} contains a NUL byte, which is not allowed.`)}function xmlEscape(value){return assertNoNul(value,"xml value"),value.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function posixShellQuote(value){return assertNoNul(value,"posix shell value"),value===""?"''":`'${value.replace(/'/g,"'\\''")}'`}function windowsCmdQuote(value){return assertNoNul(value,"windows cmd value"),`"${value.replace(/"/g,'""')}"`}function escapeWindowsCmdSetValue(value){return assertNoNul(value,"windows cmd set value"),value.replace(/%/g,"%%").replace(/"/g,"")}function systemdQuote(value){return assertNoNul(value,"systemd value"),`"${value.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`}function bakedEnvEntries(env){let entries=[["PATH",env.envPath],["BRIDGE_GPT_NODE",env.nodePath],["BRIDGE_GPT_NPX",env.npxPath],["BRIDGE_GPT_AGENT",env.agent],["BRIDGE_GPT_AGENT_PATH",env.agentPath],["BRIDGE_GPT_REPO_PATH",env.repoPath],["BRIDGE_GPT_SCHEDULE_ID",env.scheduleId],["BRIDGE_GPT_COMMAND",env.command],["BRIDGE_GPT_COMMAND_ARGS_JSON",env.commandArgsJson]];env.ideaFile!==void 0&&entries.push(["BRIDGE_GPT_IDEA_FILE",env.ideaFile]);for(let[key,value]of entries)assertNoNul(value,key);return entries}function bakedEnvFromCreateInput(input){return{envPath:input.envPath,nodePath:input.nodePath,npxPath:input.npxPath,agent:input.agent,agentPath:input.agentPath,repoPath:input.repoPath,scheduleId:input.id,command:input.command,commandArgsJson:JSON.stringify(input.args),ideaFile:input.legacyIdeaFile}}function formatEnvExportsForGeneratedUnit(env){return bakedEnvEntries(env).map(([key,value])=>`export ${key}=${posixShellQuote(value)}`).join(`
103
103
  `)}var init_escaping=__esm({"src/scheduler-backends/escaping.ts"(){"use strict"}});import{promises as fs2}from"node:fs";function launchdLabelForId(id){return`com.bridge-gpt.schedule-run.${id}`}function launchdLabelForMetadata(metadata){let unitPath=metadata.unit_path;if(unitPath&&unitPath.endsWith(".plist")){let base=unitPath.split(/[\\/]/).pop();if(base)return base.slice(0,-6)}return launchdLabelForId(metadata.id)}function launchdPlistPathForId(id,homeDir){return pathApiForPlatform("darwin").join(homeDir,"Library","LaunchAgents",`${launchdLabelForId(id)}.plist`)}function startCalendarIntervalFromIso(runAtIso){let date=new Date(runAtIso);return{Year:date.getFullYear(),Month:date.getMonth()+1,Day:date.getDate(),Hour:date.getHours(),Minute:date.getMinutes()}}function resolveUid(deps){let fromEnv=deps.env.UID;if(fromEnv&&/^\d+$/.test(fromEnv))return fromEnv;let procUid=typeof process.getuid=="function"?process.getuid():void 0;return procUid!==void 0?String(procUid):"501"}function renderLaunchdPlist(input){let label=launchdLabelForId(input.id),cal=startCalendarIntervalFromIso(input.runAtIso),env=bakedEnvEntries(bakedEnvFromCreateInput(input)),programArgs=[input.triggerInvocation.exe,...input.triggerInvocation.args].map(arg=>` <string>${xmlEscape(arg)}</string>`).join(`
104
104
  `),envEntries=env.map(([key,value])=>` <key>${xmlEscape(key)}</key>
105
105
  <string>${xmlEscape(value)}</string>`).join(`
106
106
  `);return['<?xml version="1.0" encoding="UTF-8"?>','<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">','<plist version="1.0">',"<dict>"," <key>Label</key>",` <string>${xmlEscape(label)}</string>`," <key>StartCalendarInterval</key>"," <dict>",` <key>Year</key><integer>${cal.Year}</integer>`,` <key>Month</key><integer>${cal.Month}</integer>`,` <key>Day</key><integer>${cal.Day}</integer>`,` <key>Hour</key><integer>${cal.Hour}</integer>`,` <key>Minute</key><integer>${cal.Minute}</integer>`," </dict>"," <key>EnvironmentVariables</key>"," <dict>",envEntries," </dict>"," <key>ProgramArguments</key>"," <array>",programArgs," </array>"," <key>WorkingDirectory</key>",` <string>${xmlEscape(input.repoPath)}</string>`," <key>StandardOutPath</key>",` <string>${xmlEscape(input.paths.stdoutPath)}</string>`," <key>StandardErrorPath</key>",` <string>${xmlEscape(input.paths.stderrPath)}</string>`,"</dict>","</plist>",""].join(`
107
107
  `)}function createLaunchdBackend(){return{name:"launchd",async isAvailable(deps){return deps.platform==="darwin"},async create(input){let plistPath=launchdPlistPathForId(input.id,input.deps.homeDir),content=renderLaunchdPlist(input),artifact={path:plistPath,content,kind:"launchd-plist"};if(input.dryRun)return{ok:!0,backend:"launchd",unitPath:plistPath,unitPaths:[plistPath],backendJobId:null,artifacts:[artifact]};await fs2.mkdir(pathApiForPlatform("darwin").dirname(plistPath),{recursive:!0}),await fs2.writeFile(plistPath,content,"utf-8");let uid=resolveUid(input.deps),result=await input.deps.runCommand("launchctl",["bootstrap",`gui/${uid}`,plistPath]);return result.exitCode!==0?(await fs2.unlink(plistPath).catch(()=>{}),{ok:!1,backend:"launchd",unitPath:plistPath,unitPaths:[plistPath],backendJobId:null,artifacts:[artifact],error:`launchctl bootstrap failed: ${(result.stderr||result.stdout).trim()}`}):{ok:!0,backend:"launchd",unitPath:plistPath,unitPaths:[plistPath],backendJobId:null,artifacts:[artifact]}},async list(input){let uid=resolveUid(input.deps),entries=[];for(let metadata of input.recorded){let plistPath=metadata.unit_path??launchdPlistPathForId(metadata.id,input.deps.homeDir),exists=!0;try{await fs2.access(plistPath)}catch{exists=!1}if(!exists){entries.push({metadata,status:"stale",detail:"plist missing"});continue}let label=launchdLabelForMetadata(metadata),printed=await input.deps.runCommand("launchctl",["print",`gui/${uid}/${label}`]);entries.push({metadata,status:printed.exitCode===0?"active":"stale",detail:printed.exitCode===0?"loaded":"plist present but not loaded"})}return entries},async cancel(input){let uid=resolveUid(input.deps),label=launchdLabelForMetadata(input.metadata),plistPath=input.metadata.unit_path??launchdPlistPathForId(input.metadata.id,input.deps.homeDir),plistExisted=!0;try{await fs2.access(plistPath)}catch{plistExisted=!1}let bootout=await input.deps.runCommand("launchctl",["bootout",`gui/${uid}/${label}`]);if(plistExisted)try{await fs2.unlink(plistPath)}catch(error){if(error.code!=="ENOENT")return{ok:!1,nativeRemoved:!1,stale:!1,error:String(error)}}let nativeRemoved=bootout.exitCode===0;return{ok:!0,nativeRemoved,stale:!plistExisted||!nativeRemoved}}}}var init_launchd=__esm({"src/scheduler-backends/launchd.ts"(){"use strict";init_types();init_escaping()}});import{promises as fs3}from"node:fs";function taskNameForId(id){return`BridgeGPT-ScheduleRun-${id}`}function cmdWrapperPathForId(id,homeDir){return pathApiForPlatform("win32").join(homeDir,".bridge-gpt","schedules",`${id}.cmd`)}function taskXmlPathForId(id,homeDir){return pathApiForPlatform("win32").join(homeDir,".bridge-gpt","schedules",`${id}.xml`)}function formatTaskSchedulerBoundary(runAtIso){let d=new Date(runAtIso),pad=n=>String(n).padStart(2,"0");return`${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`}function renderWindowsCmdWrapper(input){let env=bakedEnvEntries(bakedEnvFromCreateInput(input)),lines=["@echo off"];for(let[key,value]of env)key==="PATH"?lines.push(`set "PATH=${escapeWindowsCmdSetValue(value)};%PATH%"`):lines.push(`set "${key}=${escapeWindowsCmdSetValue(value)}"`);lines.push(`cd /D ${windowsCmdQuote(input.repoPath)}`);let command=[input.triggerInvocation.exe,...input.triggerInvocation.args].map(part=>windowsCmdQuote(part)).join(" ");return lines.push(`${command} 1>>${windowsCmdQuote(input.paths.stdoutPath)} 2>>${windowsCmdQuote(input.paths.stderrPath)}`),lines.push(""),lines.join(`\r
108
108
  `)}function renderTaskSchedulerXml(input){let wrapperPath=cmdWrapperPathForId(input.id,input.deps.homeDir),boundary=formatTaskSchedulerBoundary(input.runAtIso);return['<?xml version="1.0" encoding="UTF-16"?>','<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">'," <RegistrationInfo>",` <Description>${xmlEscape(`Bridge GPT schedule-run one-shot (${input.id}: ${input.command})`)}</Description>`," </RegistrationInfo>"," <Triggers>"," <TimeTrigger>",` <StartBoundary>${xmlEscape(boundary)}</StartBoundary>`," <Enabled>true</Enabled>"," </TimeTrigger>"," </Triggers>"," <Principals>",' <Principal id="Author">'," <LogonType>InteractiveToken</LogonType>"," </Principal>"," </Principals>"," <Settings>"," <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>"," <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>"," <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>"," <Enabled>true</Enabled>"," </Settings>",' <Actions Context="Author">'," <Exec>",` <Command>${xmlEscape(wrapperPath)}</Command>`," </Exec>"," </Actions>","</Task>",""].join(`\r
109
- `)}async function schtasksResolvable(deps){return(await deps.runCommand("where.exe",["schtasks"])).exitCode===0}function createTaskSchedulerBackend(){return{name:"task-scheduler",async isAvailable(deps){return deps.platform!=="win32"?!1:schtasksResolvable(deps)},async create(input){let wrapperPath=cmdWrapperPathForId(input.id,input.deps.homeDir),xmlPath=taskXmlPathForId(input.id,input.deps.homeDir),wrapperContent=renderWindowsCmdWrapper(input),xmlContent=renderTaskSchedulerXml(input),artifacts=[{path:wrapperPath,content:wrapperContent,kind:"windows-cmd-wrapper"},{path:xmlPath,content:xmlContent,kind:"task-scheduler-xml"}],taskName=taskNameForId(input.id),unitPaths=[wrapperPath,xmlPath];if(input.dryRun)return{ok:!0,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts};await fs3.writeFile(wrapperPath,wrapperContent,"utf-8"),await fs3.writeFile(xmlPath,`\uFEFF${xmlContent}`,"utf16le");let result=await input.deps.runCommand("schtasks",["/Create","/TN",taskName,"/XML",xmlPath,"/F"]);return result.exitCode!==0?(await fs3.unlink(wrapperPath).catch(()=>{}),await fs3.unlink(xmlPath).catch(()=>{}),{ok:!1,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts,error:`schtasks /Create failed: ${(result.stderr||result.stdout).trim()}`}):{ok:!0,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts}},async list(input){let entries=[];for(let metadata of input.recorded){let taskName=metadata.backend_job_id??taskNameForId(metadata.id),query=await input.deps.runCommand("schtasks",["/Query","/TN",taskName]);entries.push({metadata,status:query.exitCode===0?"active":"stale",detail:query.exitCode===0?"task registered":"task not found"})}return entries},async cancel(input){let taskName=input.metadata.backend_job_id??taskNameForId(input.metadata.id),result=await input.deps.runCommand("schtasks",["/Delete","/TN",taskName,"/F"]),wrapperPath=input.metadata.unit_path??cmdWrapperPathForId(input.metadata.id,input.deps.homeDir),xmlPath=taskXmlPathForId(input.metadata.id,input.deps.homeDir);for(let artifactPath of[wrapperPath,xmlPath])try{await fs3.unlink(artifactPath)}catch(error){if(error.code!=="ENOENT")return{ok:!1,nativeRemoved:result.exitCode===0,stale:!1,error:String(error)}}let nativeRemoved=result.exitCode===0;return{ok:!0,nativeRemoved,stale:!nativeRemoved}}}}var init_task_scheduler=__esm({"src/scheduler-backends/task-scheduler.ts"(){"use strict";init_types();init_escaping()}});import{promises as fs4}from"node:fs";function systemdUnitNamesForId(id){return{service:`bridge-gpt-schedule-run-${id}.service`,timer:`bridge-gpt-schedule-run-${id}.timer`}}function systemdUnitPathsForId(id,homeDir){let pathApi=pathApiForPlatform("linux"),dir=pathApi.join(homeDir,".config","systemd","user"),names=systemdUnitNamesForId(id);return{service:pathApi.join(dir,names.service),timer:pathApi.join(dir,names.timer)}}function systemdUnitsForMetadata(metadata,homeDir){let timerPath=metadata.unit_path&&metadata.unit_path.endsWith(".timer")?metadata.unit_path:void 0,servicePath=(metadata.unit_paths??[]).find(p=>p.endsWith(".service"));if(timerPath&&servicePath){let basename2=p=>p.split(/[\\/]/).pop();return{names:{service:basename2(servicePath),timer:basename2(timerPath)},paths:{service:servicePath,timer:timerPath}}}return{names:systemdUnitNamesForId(metadata.id),paths:systemdUnitPathsForId(metadata.id,homeDir)}}function renderSystemdService(input){let envLines=bakedEnvEntries(bakedEnvFromCreateInput(input)).map(([key,value])=>`Environment=${key}=${systemdQuote(value)}`).join(`
109
+ `)}async function schtasksResolvable(deps){return(await deps.runCommand("where.exe",["schtasks"])).exitCode===0}function createTaskSchedulerBackend(){return{name:"task-scheduler",async isAvailable(deps){return deps.platform!=="win32"?!1:schtasksResolvable(deps)},async create(input){let wrapperPath=cmdWrapperPathForId(input.id,input.deps.homeDir),xmlPath=taskXmlPathForId(input.id,input.deps.homeDir),wrapperContent=renderWindowsCmdWrapper(input),xmlContent=renderTaskSchedulerXml(input),artifacts=[{path:wrapperPath,content:wrapperContent,kind:"windows-cmd-wrapper"},{path:xmlPath,content:xmlContent,kind:"task-scheduler-xml"}],taskName=taskNameForId(input.id),unitPaths=[wrapperPath,xmlPath];if(input.dryRun)return{ok:!0,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts};await fs3.writeFile(wrapperPath,wrapperContent,"utf-8"),await fs3.writeFile(xmlPath,`\uFEFF${xmlContent}`,"utf16le");let result=await input.deps.runCommand("schtasks",["/Create","/TN",taskName,"/XML",xmlPath,"/F"]);return result.exitCode!==0?(await fs3.unlink(wrapperPath).catch(()=>{}),await fs3.unlink(xmlPath).catch(()=>{}),{ok:!1,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts,error:`schtasks /Create failed: ${(result.stderr||result.stdout).trim()}`}):{ok:!0,backend:"task-scheduler",unitPath:wrapperPath,unitPaths,backendJobId:taskName,artifacts}},async list(input){let entries=[];for(let metadata of input.recorded){let taskName=metadata.backend_job_id??taskNameForId(metadata.id),query=await input.deps.runCommand("schtasks",["/Query","/TN",taskName]);entries.push({metadata,status:query.exitCode===0?"active":"stale",detail:query.exitCode===0?"task registered":"task not found"})}return entries},async cancel(input){let taskName=input.metadata.backend_job_id??taskNameForId(input.metadata.id),result=await input.deps.runCommand("schtasks",["/Delete","/TN",taskName,"/F"]),wrapperPath=input.metadata.unit_path??cmdWrapperPathForId(input.metadata.id,input.deps.homeDir),xmlPath=taskXmlPathForId(input.metadata.id,input.deps.homeDir);for(let artifactPath of[wrapperPath,xmlPath])try{await fs3.unlink(artifactPath)}catch(error){if(error.code!=="ENOENT")return{ok:!1,nativeRemoved:result.exitCode===0,stale:!1,error:String(error)}}let nativeRemoved=result.exitCode===0;return{ok:!0,nativeRemoved,stale:!nativeRemoved}}}}var init_task_scheduler=__esm({"src/scheduler-backends/task-scheduler.ts"(){"use strict";init_types();init_escaping()}});import{promises as fs4}from"node:fs";function systemdUnitNamesForId(id){return{service:`bridge-gpt-schedule-run-${id}.service`,timer:`bridge-gpt-schedule-run-${id}.timer`}}function systemdUnitPathsForId(id,homeDir){let pathApi=pathApiForPlatform("linux"),dir=pathApi.join(homeDir,".config","systemd","user"),names=systemdUnitNamesForId(id);return{service:pathApi.join(dir,names.service),timer:pathApi.join(dir,names.timer)}}function systemdUnitsForMetadata(metadata,homeDir){let timerPath=metadata.unit_path&&metadata.unit_path.endsWith(".timer")?metadata.unit_path:void 0,servicePath=(metadata.unit_paths??[]).find(p=>p.endsWith(".service"));if(timerPath&&servicePath){let basename3=p=>p.split(/[\\/]/).pop();return{names:{service:basename3(servicePath),timer:basename3(timerPath)},paths:{service:servicePath,timer:timerPath}}}return{names:systemdUnitNamesForId(metadata.id),paths:systemdUnitPathsForId(metadata.id,homeDir)}}function renderSystemdService(input){let envLines=bakedEnvEntries(bakedEnvFromCreateInput(input)).map(([key,value])=>`Environment=${key}=${systemdQuote(value)}`).join(`
110
110
  `),execStart=[input.triggerInvocation.exe,...input.triggerInvocation.args].map(part=>systemdQuote(part)).join(" ");return["[Unit]",`Description=Bridge GPT schedule-run one-shot (${input.id}: ${input.command})`,"","[Service]","Type=oneshot",envLines,`WorkingDirectory=${systemdQuote(input.repoPath)}`,`ExecStart=${execStart}`,`StandardOutput=append:${input.paths.stdoutPath}`,`StandardError=append:${input.paths.stderrPath}`,""].join(`
111
111
  `)}function formatSystemdOnCalendar(runAtIso){let d=new Date(runAtIso),pad=n=>String(n).padStart(2,"0"),date=`${d.getUTCFullYear()}-${pad(d.getUTCMonth()+1)}-${pad(d.getUTCDate())}`,time=`${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;return`${date} ${time} UTC`}function renderSystemdTimer(input){let names=systemdUnitNamesForId(input.id);return["[Unit]",`Description=Bridge GPT schedule-run one-shot timer (${input.id}: ${input.command})`,"","[Timer]",`OnCalendar=${formatSystemdOnCalendar(input.runAtIso)}`,"Persistent=false",`Unit=${names.service}`,"","[Install]","WantedBy=timers.target",""].join(`
112
112
  `)}async function systemctlUserUsable(deps){return(await deps.runCommand("systemctl",["--user","--version"])).exitCode===0}function createSystemdUserBackend(){return{name:"systemd-user",async isAvailable(deps){return deps.platform!=="linux"?!1:systemctlUserUsable(deps)},async create(input){let paths=systemdUnitPathsForId(input.id,input.deps.homeDir),names=systemdUnitNamesForId(input.id),serviceContent=renderSystemdService(input),timerContent=renderSystemdTimer(input),artifacts=[{path:paths.service,content:serviceContent,kind:"systemd-service"},{path:paths.timer,content:timerContent,kind:"systemd-timer"}],unitPaths=[paths.service,paths.timer];if(input.dryRun)return{ok:!0,backend:"systemd-user",unitPath:paths.timer,unitPaths,backendJobId:names.timer,artifacts};let pathApi=pathApiForPlatform("linux");await fs4.mkdir(pathApi.dirname(paths.service),{recursive:!0}),await fs4.writeFile(paths.service,serviceContent,"utf-8"),await fs4.writeFile(paths.timer,timerContent,"utf-8");let cleanupUnitFiles=async()=>{await fs4.unlink(paths.timer).catch(()=>{}),await fs4.unlink(paths.service).catch(()=>{})},reload=await input.deps.runCommand("systemctl",["--user","daemon-reload"]);if(reload.exitCode!==0)return await cleanupUnitFiles(),{ok:!1,backend:"systemd-user",unitPath:paths.timer,unitPaths,backendJobId:names.timer,artifacts,error:`systemctl --user daemon-reload failed: ${(reload.stderr||reload.stdout).trim()}`};let enable=await input.deps.runCommand("systemctl",["--user","enable","--now",names.timer]);return enable.exitCode!==0?(await cleanupUnitFiles(),{ok:!1,backend:"systemd-user",unitPath:paths.timer,unitPaths,backendJobId:names.timer,artifacts,error:`systemctl --user enable --now failed: ${(enable.stderr||enable.stdout).trim()}`}):{ok:!0,backend:"systemd-user",unitPath:paths.timer,unitPaths,backendJobId:names.timer,artifacts}},async list(input){let entries=[];for(let metadata of input.recorded){let{paths,names}=systemdUnitsForMetadata(metadata,input.deps.homeDir),timerExists=!0;try{await fs4.access(paths.timer)}catch{timerExists=!1}if(!timerExists){entries.push({metadata,status:"stale",detail:"timer unit file missing"});continue}let status=await input.deps.runCommand("systemctl",["--user","status",names.timer]);status.exitCode===0?entries.push({metadata,status:"active",detail:"timer active"}):status.exitCode===3?entries.push({metadata,status:"stale",detail:"timer inactive"}):entries.push({metadata,status:"backend-unavailable",detail:"systemctl unavailable"})}return entries},async cancel(input){let{paths,names}=systemdUnitsForMetadata(input.metadata,input.deps.homeDir),disable=await input.deps.runCommand("systemctl",["--user","disable","--now",names.timer]),removedAny=!1;for(let unitPath of[paths.timer,paths.service])try{await fs4.unlink(unitPath),removedAny=!0}catch(error){if(error.code!=="ENOENT")return{ok:!1,nativeRemoved:!1,stale:!1,error:String(error)}}return await input.deps.runCommand("systemctl",["--user","daemon-reload"]),{ok:!0,nativeRemoved:disable.exitCode===0||removedAny,stale:disable.exitCode!==0}}}}var init_systemd_user=__esm({"src/scheduler-backends/systemd-user.ts"(){"use strict";init_types();init_escaping()}});function formatAtTimestamp(runAtIso){let d=new Date(runAtIso),pad=n=>String(n).padStart(2,"0");return`${d.getFullYear()}${pad(d.getMonth()+1)}${pad(d.getDate())}${pad(d.getHours())}${pad(d.getMinutes())}`}function renderAtScript(input){let exports=formatEnvExportsForGeneratedUnit(bakedEnvFromCreateInput(input)),command=[input.triggerInvocation.exe,...input.triggerInvocation.args].map(part=>posixShellQuote(part)).join(" ");return["#!/bin/sh",exports,`cd ${posixShellQuote(input.repoPath)}`,`${command} >>${posixShellQuote(input.paths.stdoutPath)} 2>>${posixShellQuote(input.paths.stderrPath)}`,""].join(`
@@ -117,23 +117,23 @@ ${stderr}`.matchAll(/^job\s+(\d+)\s+at\b/gim)];return matches.length>0?matches[m
117
117
  `),parsed=parseFrontmatterText(frontmatterText);return parsed.ok?{ok:!0,frontmatter:parsed.frontmatter,body}:parsed}function parseFrontmatterText(text){let schedulable=!0,interactive=!1,argumentSchema;for(let rawLine of text.split(`
118
118
  `)){let line=rawLine.trim();if(line===""||line.startsWith("#"))continue;let schedulableMatch=line.match(/^schedulable:\s*(true|false)\s*$/);if(schedulableMatch){schedulable=schedulableMatch[1]==="true";continue}let interactiveMatch=line.match(/^interactive:\s*(true|false)\s*$/);if(interactiveMatch){interactive=interactiveMatch[1]==="true";continue}let argsMatch=rawLine.match(/^\s*arguments:\s*(.*)$/);if(argsMatch){let value=argsMatch[1].trim();if(value==="")return{ok:!1,error:"'arguments:' frontmatter key has no JSON value"};let schemaResult=parseArgumentsSchema(value);if(!schemaResult.ok)return schemaResult;argumentSchema=schemaResult.schema;continue}}return{ok:!0,frontmatter:{schedulable,interactive,argumentSchema}}}function commandsDirForRepo(repoPath,platform){return(platform==="win32"?path6.win32:path6.posix).join(repoPath,".claude","commands")}async function discoverCommandCatalog(repoPath,platform,fsDeps=createDefaultCommandCatalogFsDeps()){let pathApi=platform==="win32"?path6.win32:path6.posix,dir=commandsDirForRepo(repoPath,platform),entries;try{entries=await fsDeps.readdir(dir)}catch(error){if(error.code==="ENOENT")return{commands:[],errors:[]};throw error}let commands=[],errors=[];for(let entry of[...entries].sort()){if(!entry.endsWith(".md"))continue;let name=entry.slice(0,-3),filePath=pathApi.join(dir,entry);if(!COMMAND_NAME_PATTERN.test(name)){errors.push({name,filePath,error:`unsafe command name '${name}' (must match ${COMMAND_NAME_PATTERN.source})`});continue}let raw;try{raw=await fsDeps.readFile(filePath)}catch(error){errors.push({name,filePath,error:`could not read command file: ${error instanceof Error?error.message:String(error)}`});continue}let split=splitFrontmatter(raw);if(!split.ok){errors.push({name,filePath,error:split.error});continue}let fm=split.frontmatter;commands.push({name,filePath,schedulable:fm?.schedulable??!0,interactive:fm?.interactive??!1,body:split.body,argumentSchema:fm?.argumentSchema})}return commands.sort((a,b)=>a.name.localeCompare(b.name)),{commands,errors}}function resolveSchedulableCommand(catalog,name){let broken=catalog.errors.find(e=>e.name===name);if(broken)return{ok:!1,error:`Command '${name}' is not schedulable: ${broken.error}.`};let command=catalog.commands.find(c=>c.name===name);if(!command){let available=catalog.commands.map(c=>c.name).join(", ")||"(none discovered)";return{ok:!1,error:`Unknown command '${name}'. Discovered commands: ${available}.`}}return command.schedulable?{ok:!0,command}:{ok:!1,error:`Command '${name}' is marked 'schedulable: false' and cannot be scheduled.`}}function validateCommandArgv(argv,schema){if(!schema)return{ok:!0,normalizedArgv:[...argv],parsed:{freeform:!0,positionals:{},extraPositionals:[],flags:{}}};let flagByLong=new Map;for(let f of schema.flags)flagByLong.set(f.flag,f);let normalizedArgv=[],positionalTokens=[],flags={};for(let i=0;i<argv.length;i++){let token=argv[i];if(token.startsWith("--")){let eqIndex=token.indexOf("="),flagName=eqIndex===-1?token:token.slice(0,eqIndex),inlineValue=eqIndex===-1?void 0:token.slice(eqIndex+1),descriptor=flagByLong.get(flagName);if(!descriptor)return{ok:!1,error:`Unknown flag '${flagName}' for this command.`};if(descriptor.type==="boolean"){if(inlineValue!==void 0)return{ok:!1,error:`Boolean flag '${flagName}' does not take a value.`};flags[descriptor.name]=!0,normalizedArgv.push(flagName);continue}let value;if(inlineValue!==void 0)value=inlineValue;else{if(i+1>=argv.length)return{ok:!1,error:`Flag '${flagName}' requires a value.`};value=argv[++i]}if(descriptor.repeatable){let existing=flags[descriptor.name];Array.isArray(existing)?existing.push(value):flags[descriptor.name]=[value]}else flags[descriptor.name]=value;normalizedArgv.push(flagName,value);continue}positionalTokens.push(token),normalizedArgv.push(token)}for(let f of schema.flags)if(!(f.name in flags)){if(f.required)return{ok:!1,error:`Missing required flag '${f.flag}'.`};f.default!==void 0&&(flags[f.name]=f.default)}let positionals={},cursor=0;for(let p of schema.positionals){if(p.variadic){let rest=positionalTokens.slice(cursor);if(cursor=positionalTokens.length,p.required&&rest.length===0)return{ok:!1,error:`Missing required positional '${p.name}'.`};positionals[p.name]=rest;continue}if(cursor<positionalTokens.length)positionals[p.name]=positionalTokens[cursor++];else{if(p.required)return{ok:!1,error:`Missing required positional '${p.name}'.`};p.default!==void 0&&(positionals[p.name]=p.default)}}let extraPositionals=positionalTokens.slice(cursor);return extraPositionals.length>0&&!schema.allowExtraPositionals?{ok:!1,error:`Unexpected extra positional argument(s): ${extraPositionals.join(", ")}.`}:{ok:!0,normalizedArgv,parsed:{freeform:!1,positionals,extraPositionals,flags}}}function schemaSupportsAutoFlag(schema){return schema?schema.flags.some(f=>f.flag==="--auto"&&f.type==="boolean"):!1}var PositionalZ,FlagZ,ArgumentSchemaZ,COMMAND_NAME_PATTERN,init_command_catalog=__esm({"src/command-catalog.ts"(){"use strict";PositionalZ=z.object({name:z.string().min(1),type:z.string().default("string"),required:z.boolean().default(!1),variadic:z.boolean().default(!1),default:z.unknown().optional()}),FlagZ=z.object({name:z.string().min(1),flag:z.string().regex(/^--[A-Za-z0-9][A-Za-z0-9-]*$/,"flag must start with '--'"),type:z.string().default("string"),required:z.boolean().default(!1),repeatable:z.boolean().default(!1),default:z.unknown().optional()}),ArgumentSchemaZ=z.object({positionals:z.array(PositionalZ).default([]),flags:z.array(FlagZ).default([]),allowExtraPositionals:z.boolean().default(!1)});COMMAND_NAME_PATTERN=/^[A-Za-z0-9][A-Za-z0-9_-]*$/}});function quotePromptToken(token){return token===""?'""':/^[A-Za-z0-9_@%+=:,./-]+$/.test(token)?token:`"${token.replace(/"/g,'\\"')}"`}function buildAugmentedArgs(input){let args=[...input.args];(input.commandName==="full-automation"||input.commandName==="epic-tick")&&args.push("--scheduled-at",input.scheduledAt);let supportsAuto=schemaSupportsAutoFlag(input.schema)||input.commandName==="full-automation"||input.commandName==="epic-tick",alreadyHasAuto=input.args.includes("--auto");return input.autoApprove&&supportsAuto&&!alreadyHasAuto&&args.push("--auto"),args}function buildTargetCommandLine(input){let parts=[`/${input.commandName}`];for(let arg of buildAugmentedArgs(input))parts.push(quotePromptToken(arg));return parts.join(" ")}function renderLateFireGate(scheduleId,scheduledAt,autoApprove){let lateAction=autoApprove?"explain that the run is firing late and then PROCEED with the command below (this schedule was created with auto-approve).":"explain that the run is firing late and then HALT WITHOUT EXECUTING the command below (this schedule was created without auto-approve, and a headless run must not proceed unconfirmed).";return["## Scheduled-run drift gate","",`This is an automated, headless scheduled run (schedule id: ${scheduleId}).`,`It was scheduled to fire at ${scheduledAt}.`,"",`Before doing anything else, check how late this run is firing. If it is more than ${LATE_FIRE_THRESHOLD_SECONDS} seconds later than the scheduled time above, ${lateAction}`,`If it is within ${LATE_FIRE_THRESHOLD_SECONDS} seconds of the scheduled time, proceed silently.`,"","Then run the following command exactly as written:"].join(`
119
119
  `)}function replaceArgumentsPlaceholder(body,argString){return body.split("$ARGUMENTS").join(argString)}function renderScheduledPrompt(input){let gate=renderLateFireGate(input.scheduleId,input.scheduledAt,input.autoApprove),targetInput={commandName:input.commandName,args:input.args,scheduledAt:input.scheduledAt,autoApprove:input.autoApprove,schema:input.schema},targetCommandLine=buildTargetCommandLine(targetInput),argString=buildAugmentedArgs(targetInput).map(quotePromptToken).join(" "),body=replaceArgumentsPlaceholder(input.commandBody,argString);return[gate,"",targetCommandLine,"",body].join(`
120
- `)}var LATE_FIRE_THRESHOLD_SECONDS,init_scheduled_prompt=__esm({"src/scheduled-prompt.ts"(){"use strict";init_command_catalog();LATE_FIRE_THRESHOLD_SECONDS=60}});async function resolveCommandOnPath(command,envPath,deps){let pathApi=pathApiForPlatform(deps.platform),probe=deps.platform==="win32"?"where.exe":"which",env={...deps.env,PATH:envPath};deps.platform==="win32"&&(env.Path=envPath);let result=await deps.runCommand(probe,[command],{env});if(result.exitCode!==0)return null;let candidate=result.stdout.split(/\r?\n/).map(line=>line.trim()).find(line=>line.length>0);return!candidate||!pathApi.isAbsolute(candidate)?null:pathApi.normalize(candidate)}function buildClaudePrompt(input){return renderScheduledPrompt({scheduleId:input.scheduleId,scheduledAt:input.runAtIso,autoApprove:input.autoApprove,commandName:input.commandName,args:input.args,commandBody:input.commandBody,schema:input.schema})}function createClaudeLauncher(){return{capability:CLAUDE_CAPABILITY,resolveBinary(envPath,deps){return resolveCommandOnPath("claude",envPath,deps)},buildInvocation(exe,input){let prompt=buildClaudePrompt(input);return{exe,args:[CLAUDE_CAPABILITY.promptFlag,prompt],prompt}},formatInvocationLine(invocation,platform){let quote=platform==="win32"?windowsCmdQuote:posixShellQuote;return[invocation.exe,...invocation.args].map(part=>quote(part)).join(" ")}}}var CLAUDE_CAPABILITY,init_claude=__esm({"src/agent-launchers/claude.ts"(){"use strict";init_types();init_escaping();init_scheduled_prompt();init_scheduled_prompt();CLAUDE_CAPABILITY={name:"claude",command:"claude",supportsCwdFlag:!1,promptFlag:"-p"}}});function buildCursorPrompt(input){return renderScheduledPrompt({scheduleId:input.scheduleId,scheduledAt:input.runAtIso,autoApprove:input.autoApprove,commandName:input.commandName,args:input.args,commandBody:input.commandBody,schema:input.schema})}function createCursorLauncher(){return{capability:CURSOR_CAPABILITY,resolveBinary(envPath,deps){return resolveCommandOnPath("cursor-agent",envPath,deps)},buildInvocation(exe,input){let prompt=buildCursorPrompt(input),args=[CURSOR_CAPABILITY.promptFlag,"--output-format","text","--trust","--workspace",input.repoPath,prompt];return{exe,args,prompt}},formatInvocationLine(invocation,platform){let quote=platform==="win32"?windowsCmdQuote:posixShellQuote;return[invocation.exe,...invocation.args].map(part=>quote(part)).join(" ")}}}var CURSOR_CAPABILITY,init_cursor=__esm({"src/agent-launchers/cursor.ts"(){"use strict";init_escaping();init_scheduled_prompt();init_claude();CURSOR_CAPABILITY={name:"cursor-agent",command:"cursor-agent",supportsCwdFlag:!0,promptFlag:"-p"}}});function getAgentLauncher(name){switch(name){case"claude":return CLAUDE_LAUNCHER;case"cursor-agent":return CURSOR_LAUNCHER;default:return null}}function formatValidAgentLauncherNames(){return LAUNCHER_NAMES.join(", ")}var CLAUDE_LAUNCHER,CURSOR_LAUNCHER,LAUNCHER_NAMES,init_agent_launchers=__esm({"src/agent-launchers/index.ts"(){"use strict";init_claude();init_cursor();init_claude();init_cursor();CLAUDE_LAUNCHER=createClaudeLauncher(),CURSOR_LAUNCHER=createCursorLauncher(),LAUNCHER_NAMES=["claude","cursor-agent"]}});var schedule_run_exports={};__export(schedule_run_exports,{buildScheduleMetadata:()=>buildScheduleMetadata,collectScheduleRunPrereqStatus:()=>collectScheduleRunPrereqStatus,commandSucceeded:()=>commandSucceeded,createDefaultScheduleRunDeps:()=>createDefaultScheduleRunDeps,filterScheduleMetadata:()=>filterScheduleMetadata,formatScheduleCancelResult:()=>formatScheduleCancelResult,formatScheduleCreateResult:()=>formatScheduleCreateResult,formatScheduleDoctorReport:()=>formatScheduleDoctorReport,formatScheduleListResult:()=>formatScheduleListResult,getScheduleRunUsage:()=>getScheduleRunUsage,isTransientNpxEntryPath:()=>isTransientNpxEntryPath,latestRunStatus:()=>latestRunStatus,orchestrateScheduleCancel:()=>orchestrateScheduleCancel,orchestrateScheduleCreate:()=>orchestrateScheduleCreate,orchestrateScheduleDoctor:()=>orchestrateScheduleDoctor,orchestrateScheduleExecute:()=>orchestrateScheduleExecute,orchestrateScheduleList:()=>orchestrateScheduleList,parseDurationFromNow:()=>parseDurationFromNow,parseRunAtIso:()=>parseRunAtIso,parseScheduleCancelArgs:()=>parseScheduleCancelArgs,parseScheduleCreateArgs:()=>parseScheduleCreateArgs,parseScheduleDoctorArgs:()=>parseScheduleDoctorArgs,parseScheduleExecuteArgs:()=>parseScheduleExecuteArgs,parseScheduleListArgs:()=>parseScheduleListArgs,parseScheduleRunArgs:()=>parseScheduleRunArgs,resolveScheduleCreateInput:()=>resolveScheduleCreateInput,runScheduleRunCli:()=>runScheduleRunCli,scheduleCommandLabel:()=>scheduleCommandLabel});import{execFile}from"node:child_process";import{promises as fs6}from"node:fs";import{randomUUID as randomUUID2,createHash as createHash3}from"node:crypto";function createDefaultScheduleRunDeps(){return{runCommand:(file,args,options)=>new Promise(resolve2=>{let child=execFile(file,args,{cwd:options?.cwd,env:options?.env??process.env,maxBuffer:67108864,encoding:"utf-8"},(error,stdout,stderr)=>{let exitCode=error&&typeof error.code=="number"?error.code:error?1:0;resolve2({stdout:stdout??"",stderr:stderr??"",exitCode})});options?.input!==void 0&&child.stdin&&(child.stdin.write(options.input),child.stdin.end())}),platform:process.platform,env:process.env,cwd:process.cwd(),execPath:process.execPath,homeDir:process.env.HOME??process.env.USERPROFILE??"",now:()=>Date.now(),cliEntryPath:process.argv[1],bridgeCredentialResolved:()=>!!process.env.BAPI_API_KEY}}function commandSucceeded(result){return result.exitCode===0}function isTransientNpxEntryPath(entryPath){return entryPath?/[\\/]_npx[\\/]/.test(entryPath):!1}function getScheduleRunUsage(){return["Usage:"," npx -y @bridge_gpt/mcp-server schedule-run <create|list|cancel|doctor> [flags]","","Schedules a local, one-shot run of ANY Bridge slash-command automation (from","the repo's .claude/commands/*.md catalog) at a chosen time using an OS-native","scheduler (launchd / Task Scheduler / systemd-user / at). Schedules are stored","locally under ~/.bridge-gpt/schedules/ and are never sent to a server.","","create:"," schedule-run create --in 2h --command review-ticket -- BAPI-999",' schedule-run create --at "<datetime>" --command start-tickets -- BAPI-1 BAPI-2'," legacy: schedule-run create --in 2h --idea-file <path>","","All tokens after a bare -- are the structured argv passed to the command.","","create flags:",' --at "<datetime>" ISO-8601 time to run (mutually exclusive with --in)'," --in <duration> Run after a duration, e.g. 30m, 4h, 1d (mutually exclusive with --at)"," --command <name> Discovered .claude/commands command to schedule"," --idea-file <path> Legacy: schedule /full-automation with this idea file"," --agent <name> Agent to launch (claude [default] or cursor-agent)"," --repo-path <path> Working directory + command catalog root (default: cwd)"," --auto Run hands-off; gate proceeds even when firing late"," --no-auto Late runs halt without executing (headless-safe default)"," --dry-run Print the generated unit + prompt + invocation without creating anything"," --id <id> Override the auto-generated schedule id (mainly for tests)","","list flags:"," --id <id> Filter to a single schedule id"," --agent <name> Filter by agent"," --backend <name> Filter by backend (launchd|task-scheduler|systemd-user|at-fallback)"," --json Emit JSON instead of a table","","cancel:"," cancel <id> Cancel by positional id"," cancel --id <id> Cancel by --id flag"," --agent <name> Only cancel when the recorded agent matches"," --backend <name> Only cancel when the recorded backend matches","","doctor:"," Read-only diagnostics: platform support, backend candidate order, scheduler"," availability, and whether claude/npx resolve on PATH. Creates nothing.",""," -h, --help Show this help"].join(`
121
- `)}function takeValue(argv,index,arg,flag){return arg.startsWith(`${flag}=`)?{value:arg.slice(`${flag}=`.length),nextIndex:index}:index+1>=argv.length?{error:`${flag} requires a value.`}:{value:argv[index+1],nextIndex:index+1}}function matchesFlag(arg,flag){return arg===flag||arg.startsWith(`${flag}=`)}function parseScheduleCreateArgs(argv){let delimIndex=argv.indexOf("--"),schedulerArgs=delimIndex===-1?argv:argv.slice(0,delimIndex),commandArgs=delimIndex===-1?[]:argv.slice(delimIndex+1);if(schedulerArgs.includes("-h")||schedulerArgs.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let at,inDuration,commandName,ideaFile,agent="claude",repoPath,id,sawAutoApprove=!1,sawNoAutoApprove=!1,dryRun=!1;for(let i=0;i<schedulerArgs.length;i++){let arg=schedulerArgs[i];if(matchesFlag(arg,"--at")){let r=takeValue(schedulerArgs,i,arg,"--at");if("error"in r)return{status:"error",message:r.error};at=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--in")){let r=takeValue(schedulerArgs,i,arg,"--in");if("error"in r)return{status:"error",message:r.error};inDuration=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--command")){let r=takeValue(schedulerArgs,i,arg,"--command");if("error"in r)return{status:"error",message:r.error};commandName=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--idea-file")){let r=takeValue(schedulerArgs,i,arg,"--idea-file");if("error"in r)return{status:"error",message:r.error};ideaFile=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(schedulerArgs,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};if(!getAgentLauncher(r.value))return{status:"error",message:`Invalid --agent value: '${r.value}'. Valid: ${formatValidAgentLauncherNames()}.`};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--repo-path")){let r=takeValue(schedulerArgs,i,arg,"--repo-path");if("error"in r)return{status:"error",message:r.error};repoPath=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--id")){let r=takeValue(schedulerArgs,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};id=r.value,i=r.nextIndex;continue}if(arg==="--auto"){sawAutoApprove=!0;continue}if(arg==="--no-auto"){sawNoAutoApprove=!0;continue}if(arg==="--dry-run"){dryRun=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. create takes flags before '--'; put command arguments after '--'.`}}if(!!at==!!inDuration)return{status:"error",message:"create requires exactly one of --at or --in."};if(sawAutoApprove&&sawNoAutoApprove)return{status:"error",message:"--auto and --no-auto are mutually exclusive."};if(id!==void 0&&!SCHEDULE_ID_PATTERN.test(id))return{status:"error",message:`Invalid --id value: '${id}'. Ids must match ${SCHEDULE_ID_PATTERN.source} (start alphanumeric; letters, digits, '_' and '-'; max 64 chars).`};if(ideaFile!==void 0){if(commandName===void 0)commandName="full-automation";else if(commandName!=="full-automation")return{status:"error",message:`--idea-file is only valid for legacy full-automation scheduling, not --command '${commandName}'. Pass command arguments after '--' instead.`}}return commandName===void 0?{status:"error",message:"create requires --command <name> (or legacy --idea-file <path>)."}:{status:"ok",subcommand:"create",options:{at,in:inDuration,commandName,commandArgs,ideaFile,agent,repoPath,autoApprove:!sawNoAutoApprove,autoApproveExplicit:sawAutoApprove||sawNoAutoApprove,dryRun,id}}}function parseScheduleExecuteArgs(argv){let positionals=argv.filter(a=>!a.startsWith("-")),flags=argv.filter(a=>a.startsWith("-"));if(flags.length>0)return{status:"error",message:`_execute takes no flags (got ${flags.join(", ")}).`};if(positionals.length!==1)return{status:"error",message:"_execute requires exactly one schedule id."};let id=positionals[0];return SCHEDULE_ID_PATTERN.test(id)?{status:"ok",subcommand:"_execute",options:{id}}:{status:"error",message:`Invalid schedule id: '${id}'.`}}function parseScheduleListArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let id,agent,backend,json=!1;for(let i=0;i<argv.length;i++){let arg=argv[i];if(matchesFlag(arg,"--id")){let r=takeValue(argv,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};id=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(argv,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};if(!getAgentLauncher(r.value))return{status:"error",message:`Invalid --agent filter: '${r.value}'. Valid: ${formatValidAgentLauncherNames()}.`};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--backend")){let r=takeValue(argv,i,arg,"--backend");if("error"in r)return{status:"error",message:r.error};if(!VALID_BACKEND_NAMES.includes(r.value))return{status:"error",message:`Invalid --backend filter: '${r.value}'. Valid: ${VALID_BACKEND_NAMES.join(", ")}.`};backend=r.value,i=r.nextIndex;continue}if(arg==="--json"){json=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. list takes only flags.`}}return{status:"ok",subcommand:"list",options:{id,agent,backend,json}}}function parseScheduleCancelArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let positionalId,flagId,agent,backend;for(let i=0;i<argv.length;i++){let arg=argv[i];if(matchesFlag(arg,"--id")){let r=takeValue(argv,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};if(flagId!==void 0)return{status:"error",message:"cancel accepts only one --id."};flagId=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(argv,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--backend")){let r=takeValue(argv,i,arg,"--backend");if("error"in r)return{status:"error",message:r.error};if(!VALID_BACKEND_NAMES.includes(r.value))return{status:"error",message:`Invalid --backend filter: '${r.value}'. Valid: ${VALID_BACKEND_NAMES.join(", ")}.`};backend=r.value,i=r.nextIndex;continue}if(arg.startsWith("-"))return{status:"error",message:`Unknown flag: ${arg}`};if(positionalId!==void 0)return{status:"error",message:"cancel accepts only one schedule id."};positionalId=arg}if(positionalId!==void 0&&flagId!==void 0)return{status:"error",message:"cancel accepts a positional id OR --id, not both."};let id=positionalId??flagId;return id?{status:"ok",subcommand:"cancel",options:{id,agent,backend}}:{status:"error",message:"cancel requires a schedule id (positional or --id)."}}function parseScheduleDoctorArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let json=!1;for(let arg of argv){if(arg==="--json"){json=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. doctor takes no positional arguments.`}}return{status:"ok",subcommand:"doctor",options:{json}}}function parseScheduleRunArgs(argv){if(argv.length===0)return{status:"error",message:"Missing subcommand. Expected one of: create, list, cancel, doctor."};let[subcommand,...rest]=argv;if(subcommand==="-h"||subcommand==="--help")return{status:"help",usage:getScheduleRunUsage()};switch(subcommand){case"create":return parseScheduleCreateArgs(rest);case"list":return parseScheduleListArgs(rest);case"cancel":return parseScheduleCancelArgs(rest);case"doctor":return parseScheduleDoctorArgs(rest);case"_execute":return parseScheduleExecuteArgs(rest);default:return{status:"error",message:`Unknown subcommand '${subcommand}'. Expected one of: create, list, cancel, doctor.`}}}function parseRunAtIso(value){let date=new Date(value);return Number.isNaN(date.getTime())?{ok:!1,error:`Invalid --at datetime: '${value}'. Expected an ISO-8601 timestamp.`}:{ok:!0,iso:date.toISOString()}}function parseDurationFromNow(value,nowMs){let match=value.match(/^(\d+)([mhd])$/);if(!match)return{ok:!1,error:`Invalid --in duration: '${value}'. Use a positive number followed by m, h, or d (e.g. 30m, 4h, 1d).`};let amount=Number(match[1]);if(amount<=0)return{ok:!1,error:`Invalid --in duration: '${value}'. Duration must be positive.`};let unitMs=match[2]==="m"?6e4:match[2]==="h"?36e5:864e5;return{ok:!0,iso:new Date(nowMs+amount*unitMs).toISOString()}}function resolveAbsolute(p,deps){let pathApi=pathApiForPlatform(deps.platform);return pathApi.isAbsolute(p)?pathApi.normalize(p):pathApi.resolve(deps.cwd,p)}function collectScheduleRunPrereqStatus(input){return{agentBinaryResolved:input.agentBinaryResolved,repoPathExists:input.repoPathExists,cursorApiKeyPresent:!!input.deps.env.CURSOR_API_KEY,bridgeCredentialResolved:input.deps.bridgeCredentialResolved?.()??!!input.deps.env.BAPI_API_KEY}}async function resolveScheduleCreateInput(options,runAtIso,deps){let launcher=getAgentLauncher(options.agent);if(!launcher)return{ok:!1,error:`Unsupported agent: '${options.agent}'. Valid: ${formatValidAgentLauncherNames()}.`};let commandName=options.commandName;if(!commandName)return{ok:!1,error:"create requires a command (--command or legacy --idea-file)."};let repoPath=resolveAbsolute(options.repoPath??deps.cwd,deps);try{if(!(await fs6.stat(repoPath)).isDirectory())return{ok:!1,error:`--repo-path is not a directory: ${repoPath}`}}catch{return{ok:!1,error:`--repo-path does not exist: ${repoPath}`}}let commandArgs=options.commandArgs,legacyIdeaFile;if(options.ideaFile!==void 0){let ideaFile=resolveAbsolute(options.ideaFile,deps);try{if(!(await fs6.stat(ideaFile)).isFile())return{ok:!1,error:`--idea-file is not a file: ${ideaFile}`}}catch{return{ok:!1,error:`--idea-file does not exist: ${ideaFile}`}}legacyIdeaFile=ideaFile,commandArgs=["--idea-file",ideaFile]}let catalog=await discoverCommandCatalog(repoPath,deps.platform,deps.commandCatalogFsDeps),resolvedCommand=resolveSchedulableCommand(catalog,commandName);if(!resolvedCommand.ok)return{ok:!1,error:resolvedCommand.error};let command=resolvedCommand.command,validation=validateCommandArgv(commandArgs,command.argumentSchema);if(!validation.ok)return{ok:!1,error:`Invalid arguments for '${commandName}': ${validation.error}`};let normalizedArgv=validation.normalizedArgv,envPath=deps.env.PATH??deps.env.Path??"",nodePath=deps.execPath,agentPath=await launcher.resolveBinary(envPath,deps);if(!agentPath)return{ok:!1,error:`Could not resolve the '${launcher.capability.command}' binary on the baked PATH.`};let npxPath=await resolveCommandOnPath("npx",envPath,deps)??"",id=options.id??randomUUID2(),agentInvocation=launcher.buildInvocation(agentPath,{scheduleId:id,runAtIso,commandName,args:normalizedArgv,autoApprove:options.autoApprove,repoPath,commandFilePath:command.filePath,commandBody:command.body,schema:command.argumentSchema}),cliEntryPath=deps.cliEntryPath??process.argv[1]??"",triggerInvocation={exe:nodePath,args:[cliEntryPath,"schedule-run","_execute",id]},commandBodyHash=createHash3("sha256").update(command.body,"utf-8").digest("hex"),warnings=[];command.interactive&&!options.autoApproveExplicit&&warnings.push(`Command '${commandName}' has an interactive step but --auto/--no-auto was not specified; a headless scheduled run may hang waiting for confirmation. Pass --auto to run hands-off.`),isTransientNpxEntryPath(cliEntryPath)&&warnings.push(`The scheduled run re-enters this CLI at '${cliEntryPath}', which is inside an npx cache directory. npx caches can be pruned before a future schedule fires, which would make the run fail with ENOENT. Install the CLI persistently (e.g. \`npm i -g @bridge_gpt/mcp-server\`) and schedule with the installed binary so the trigger path stays stable.`);let paths=getSchedulePaths(id,deps.homeDir,deps.platform);return{ok:!0,resolved:{id,runAtIso,agent:options.agent,command:commandName,args:normalizedArgv,commandFilePath:command.filePath,commandBodyHash,autoApprove:options.autoApprove,repoPath,legacyIdeaFile,envPath,nodePath,npxPath,agentPath,agentInvocation,triggerInvocation,renderedPrompt:agentInvocation.prompt,schema:command.argumentSchema,paths:{schedulesDir:paths.schedulesDir,logsDir:paths.logsDir,stdoutPath:paths.stdoutPath,stderrPath:paths.stderrPath},warnings,prereq:collectScheduleRunPrereqStatus({agent:options.agent,agentBinaryResolved:!!agentPath,repoPathExists:!0,deps})}}}function buildScheduleMetadata(resolved,createResult,createdAtIso){return{id:resolved.id,run_at_iso:resolved.runAtIso,scheduled_at:resolved.runAtIso,backend:createResult.backend,unit_path:createResult.unitPath,unit_paths:createResult.unitPaths,backend_job_id:createResult.backendJobId,agent:resolved.agent,agent_path:resolved.agentPath,command:resolved.command,args:resolved.args,command_file:resolved.commandFilePath,command_body_hash:resolved.commandBodyHash,auto_approve:resolved.autoApprove,repo_path:resolved.repoPath,created_at:createdAtIso,env_path:resolved.envPath,node_path:resolved.nodePath,npx_path:resolved.npxPath,claude_path:resolved.agent==="claude"?resolved.agentPath:void 0,idea_file:resolved.legacyIdeaFile,invocation:resolved.agentInvocation,agent_invocation:resolved.agentInvocation,trigger_invocation:resolved.triggerInvocation,run_history:[{status:"created",at:createdAtIso}],logs:{stdout:resolved.paths.stdoutPath,stderr:resolved.paths.stderrPath}}}function resolveRunAtIso(options,deps){if(options.at!==void 0)return parseRunAtIso(options.at);let nowMs=deps.now?deps.now():Date.now();return parseDurationFromNow(options.in,nowMs)}async function orchestrateScheduleCreate(options,deps){let runAt=resolveRunAtIso(options,deps);if(!runAt.ok)return{ok:!1,error:runAt.error};let resolvedResult=await resolveScheduleCreateInput(options,runAt.iso,deps);if(!resolvedResult.ok)return{ok:!1,error:resolvedResult.error};let resolved=resolvedResult.resolved,createdAtIso=new Date(deps.now?deps.now():Date.now()).toISOString(),metadataPath=getSchedulePaths(resolved.id,deps.homeDir,deps.platform).metadataPath;if(!options.dryRun){let existing;try{existing=await readScheduleMetadata(resolved.id,deps.homeDir,deps.platform)}catch(error){let msg=error instanceof Error?error.message:String(error);return{ok:!1,error:`Could not read existing schedule metadata for id '${resolved.id}' at ${metadataPath}: ${msg}. Resolve or remove it before creating.`}}if(existing)return{ok:!1,error:`A schedule with id '${resolved.id}' already exists (${metadataPath}). Cancel it first (schedule-run cancel <id>) or choose a different --id.`}}let selection=await selectSchedulerBackend(deps,options.dryRun);if(!selection.ok)return{ok:!1,error:selection.error};let backend=selection.backend,createInput={deps,id:resolved.id,runAtIso:resolved.runAtIso,triggerInvocation:resolved.triggerInvocation,agentInvocation:resolved.agentInvocation,command:resolved.command,args:resolved.args,agent:resolved.agent,repoPath:resolved.repoPath,envPath:resolved.envPath,nodePath:resolved.nodePath,npxPath:resolved.npxPath,agentPath:resolved.agentPath,legacyIdeaFile:resolved.legacyIdeaFile,paths:resolved.paths,dryRun:options.dryRun};if(options.dryRun){let createResult2=await backend.create(createInput);return createResult2.ok?{ok:!0,dryRun:!0,metadata:buildScheduleMetadata(resolved,createResult2,createdAtIso),metadataPath,createResult:createResult2,resolved}:{ok:!1,error:createResult2.error??"Backend dry-run failed."}}await ensureScheduleDirectories(deps.homeDir,deps.platform);let createResult=await backend.create(createInput);if(!createResult.ok)return{ok:!1,error:createResult.error??"Scheduler backend create failed."};let metadata=buildScheduleMetadata(resolved,createResult,createdAtIso),scheduledAtIso=new Date(deps.now?deps.now():Date.now()).toISOString();metadata.run_history=[...metadata.run_history??[],{status:"scheduled",at:scheduledAtIso}];try{await writeScheduleMetadata(metadata,deps.homeDir,deps.platform)}catch(error){return await backend.cancel({deps,metadata}).catch(()=>{}),{ok:!1,error:`Created the native ${createResult.backend} unit but failed to persist schedule metadata (${error instanceof Error?error.message:String(error)}); attempted to cancel the native unit.`}}return{ok:!0,dryRun:!1,metadata,metadataPath,createResult,resolved}}function formatPrereqStatus(agent,prereq){let lines=[` agent binary: ${prereq.agentBinaryResolved?"resolved":"MISSING"}`,` repo path: ${prereq.repoPathExists?"exists":"MISSING"}`];return agent==="cursor-agent"?lines.push(` CURSOR_API_KEY set: ${prereq.cursorApiKeyPresent?"yes":"no"}`):lines.push(` Bridge credential: ${prereq.bridgeCredentialResolved?"resolved":"not resolved"}`),lines}function formatScheduleCreateResult(result){if(!result.ok)return`Error: ${result.error}`;let m=result.metadata,r=result.resolved,targetCommandLine=buildTargetCommandLine({commandName:r.command,args:r.args,scheduledAt:r.runAtIso,autoApprove:r.autoApprove,schema:r.schema}),lines=[];lines.push(result.dryRun?"[dry-run] schedule-run create preview":"Schedule created."),lines.push(` id: ${m.id}`),lines.push(` backend: ${m.backend}`),lines.push(` command: ${r.command}`),lines.push(` args: ${r.args.length>0?r.args.join(" "):"(none)"}`),lines.push(` run at: ${m.run_at_iso}`),lines.push(` agent: ${m.agent}`),lines.push(` auto-approve: ${m.auto_approve?"yes":"no"}`),lines.push(` metadata: ${result.metadataPath}${result.dryRun?" (not written in dry-run)":""}`),lines.push(` repo path: ${m.repo_path}`),m.idea_file&&lines.push(` idea file: ${m.idea_file}`),lines.push(` stdout log: ${m.logs.stdout}`),lines.push(` stderr log: ${m.logs.stderr}`),lines.push(` agent binary: ${r.agentPath}`),lines.push(` target command: ${targetCommandLine}`),lines.push(` trigger invocation: ${[r.triggerInvocation.exe,...r.triggerInvocation.args].join(" ")}`),lines.push(` agent invocation: ${[r.agentInvocation.exe,...r.agentInvocation.args].join(" ")}`),m.unit_paths.length>0&&lines.push(` unit paths: ${m.unit_paths.join(", ")}`);for(let warning of r.warnings)lines.push(` warning: ${warning}`);if(result.dryRun){lines.push(""),lines.push("prerequisites (secret-free):"),lines.push(...formatPrereqStatus(r.agent,r.prereq)),lines.push(""),lines.push("----- rendered prompt -----"),lines.push(r.renderedPrompt);for(let artifact of result.createResult.artifacts)lines.push(""),lines.push(`----- ${artifact.kind}: ${artifact.path} -----`),lines.push(artifact.content)}return lines.join(`
120
+ `)}var LATE_FIRE_THRESHOLD_SECONDS,init_scheduled_prompt=__esm({"src/scheduled-prompt.ts"(){"use strict";init_command_catalog();LATE_FIRE_THRESHOLD_SECONDS=60}});async function resolveCommandOnPath(command,envPath,deps){let pathApi=pathApiForPlatform(deps.platform),probe=deps.platform==="win32"?"where.exe":"which",env={...deps.env,PATH:envPath};deps.platform==="win32"&&(env.Path=envPath);let result=await deps.runCommand(probe,[command],{env});if(result.exitCode!==0)return null;let candidate=result.stdout.split(/\r?\n/).map(line=>line.trim()).find(line=>line.length>0);return!candidate||!pathApi.isAbsolute(candidate)?null:pathApi.normalize(candidate)}function buildClaudePrompt(input){return renderScheduledPrompt({scheduleId:input.scheduleId,scheduledAt:input.runAtIso,autoApprove:input.autoApprove,commandName:input.commandName,args:input.args,commandBody:input.commandBody,schema:input.schema})}function createClaudeLauncher(){return{capability:CLAUDE_CAPABILITY,resolveBinary(envPath,deps){return resolveCommandOnPath("claude",envPath,deps)},buildInvocation(exe,input){let prompt=buildClaudePrompt(input);return{exe,args:[CLAUDE_CAPABILITY.promptFlag,prompt],prompt}},formatInvocationLine(invocation,platform){let quote=platform==="win32"?windowsCmdQuote:posixShellQuote;return[invocation.exe,...invocation.args].map(part=>quote(part)).join(" ")}}}var CLAUDE_CAPABILITY,init_claude=__esm({"src/agent-launchers/claude.ts"(){"use strict";init_types();init_escaping();init_scheduled_prompt();init_scheduled_prompt();CLAUDE_CAPABILITY={name:"claude",command:"claude",supportsCwdFlag:!1,promptFlag:"-p"}}});function buildCursorPrompt(input){return renderScheduledPrompt({scheduleId:input.scheduleId,scheduledAt:input.runAtIso,autoApprove:input.autoApprove,commandName:input.commandName,args:input.args,commandBody:input.commandBody,schema:input.schema})}function createCursorLauncher(){return{capability:CURSOR_CAPABILITY,resolveBinary(envPath,deps){return resolveCommandOnPath("cursor-agent",envPath,deps)},buildInvocation(exe,input){let prompt=buildCursorPrompt(input),args=[CURSOR_CAPABILITY.promptFlag,"--output-format","text","--trust","--workspace",input.repoPath,prompt];return{exe,args,prompt}},formatInvocationLine(invocation,platform){let quote=platform==="win32"?windowsCmdQuote:posixShellQuote;return[invocation.exe,...invocation.args].map(part=>quote(part)).join(" ")}}}var CURSOR_CAPABILITY,init_cursor=__esm({"src/agent-launchers/cursor.ts"(){"use strict";init_escaping();init_scheduled_prompt();init_claude();CURSOR_CAPABILITY={name:"cursor-agent",command:"cursor-agent",supportsCwdFlag:!0,promptFlag:"-p"}}});function getAgentLauncher(name){switch(name){case"claude":return CLAUDE_LAUNCHER;case"cursor-agent":return CURSOR_LAUNCHER;default:return null}}function formatValidAgentLauncherNames(){return LAUNCHER_NAMES.join(", ")}var CLAUDE_LAUNCHER,CURSOR_LAUNCHER,LAUNCHER_NAMES,init_agent_launchers=__esm({"src/agent-launchers/index.ts"(){"use strict";init_claude();init_cursor();init_claude();init_cursor();CLAUDE_LAUNCHER=createClaudeLauncher(),CURSOR_LAUNCHER=createCursorLauncher(),LAUNCHER_NAMES=["claude","cursor-agent"]}});var schedule_run_exports={};__export(schedule_run_exports,{buildScheduleMetadata:()=>buildScheduleMetadata,collectScheduleRunPrereqStatus:()=>collectScheduleRunPrereqStatus,commandSucceeded:()=>commandSucceeded,createDefaultScheduleRunDeps:()=>createDefaultScheduleRunDeps,filterScheduleMetadata:()=>filterScheduleMetadata,formatScheduleCancelResult:()=>formatScheduleCancelResult,formatScheduleCreateResult:()=>formatScheduleCreateResult,formatScheduleDoctorReport:()=>formatScheduleDoctorReport,formatScheduleListResult:()=>formatScheduleListResult,getScheduleRunUsage:()=>getScheduleRunUsage,isTransientNpxEntryPath:()=>isTransientNpxEntryPath,latestRunStatus:()=>latestRunStatus,orchestrateScheduleCancel:()=>orchestrateScheduleCancel,orchestrateScheduleCreate:()=>orchestrateScheduleCreate,orchestrateScheduleDoctor:()=>orchestrateScheduleDoctor,orchestrateScheduleExecute:()=>orchestrateScheduleExecute,orchestrateScheduleList:()=>orchestrateScheduleList,parseDurationFromNow:()=>parseDurationFromNow,parseRunAtIso:()=>parseRunAtIso,parseScheduleCancelArgs:()=>parseScheduleCancelArgs,parseScheduleCreateArgs:()=>parseScheduleCreateArgs,parseScheduleDoctorArgs:()=>parseScheduleDoctorArgs,parseScheduleExecuteArgs:()=>parseScheduleExecuteArgs,parseScheduleListArgs:()=>parseScheduleListArgs,parseScheduleRunArgs:()=>parseScheduleRunArgs,resolveScheduleCreateInput:()=>resolveScheduleCreateInput,runScheduleRunCli:()=>runScheduleRunCli,scheduleCommandLabel:()=>scheduleCommandLabel});import{execFile}from"node:child_process";import{promises as fs6}from"node:fs";import{randomUUID as randomUUID2,createHash as createHash3}from"node:crypto";function createDefaultScheduleRunDeps(){return{runCommand:(file,args,options)=>new Promise(resolve2=>{let child=execFile(file,args,{cwd:options?.cwd,env:options?.env??process.env,maxBuffer:67108864,encoding:"utf-8"},(error,stdout,stderr)=>{let exitCode=error&&typeof error.code=="number"?error.code:error?1:0;resolve2({stdout:stdout??"",stderr:stderr??"",exitCode})});options?.input!==void 0&&child.stdin&&(child.stdin.write(options.input),child.stdin.end())}),platform:process.platform,env:process.env,cwd:process.cwd(),execPath:process.execPath,homeDir:process.env.HOME??process.env.USERPROFILE??"",now:()=>Date.now(),cliEntryPath:process.argv[1],bridgeCredentialResolved:()=>!!process.env.BAPI_API_KEY}}function commandSucceeded(result){return result.exitCode===0}function isTransientNpxEntryPath(entryPath){return entryPath?/[\\/]_npx[\\/]/.test(entryPath):!1}function getScheduleRunUsage(){return["Usage:",` npx -y ${MCP_PACKAGE_NAME} schedule-run <create|list|cancel|doctor> [flags]`,"","Schedules a local, one-shot run of ANY Bridge slash-command automation (from","the repo's .claude/commands/*.md catalog) at a chosen time using an OS-native","scheduler (launchd / Task Scheduler / systemd-user / at). Schedules are stored","locally under ~/.bridge-gpt/schedules/ and are never sent to a server.","","create:"," schedule-run create --in 2h --command review-ticket -- BAPI-999",' schedule-run create --at "<datetime>" --command start-tickets -- BAPI-1 BAPI-2'," legacy: schedule-run create --in 2h --idea-file <path>","","All tokens after a bare -- are the structured argv passed to the command.","","create flags:",' --at "<datetime>" ISO-8601 time to run (mutually exclusive with --in)'," --in <duration> Run after a duration, e.g. 30m, 4h, 1d (mutually exclusive with --at)"," --command <name> Discovered .claude/commands command to schedule"," --idea-file <path> Legacy: schedule /full-automation with this idea file"," --agent <name> Agent to launch (claude [default] or cursor-agent)"," --repo-path <path> Working directory + command catalog root (default: cwd)"," --auto Run hands-off; gate proceeds even when firing late"," --no-auto Late runs halt without executing (headless-safe default)"," --dry-run Print the generated unit + prompt + invocation without creating anything"," --id <id> Override the auto-generated schedule id (mainly for tests)","","list flags:"," --id <id> Filter to a single schedule id"," --agent <name> Filter by agent"," --backend <name> Filter by backend (launchd|task-scheduler|systemd-user|at-fallback)"," --json Emit JSON instead of a table","","cancel:"," cancel <id> Cancel by positional id"," cancel --id <id> Cancel by --id flag"," --agent <name> Only cancel when the recorded agent matches"," --backend <name> Only cancel when the recorded backend matches","","doctor:"," Read-only diagnostics: platform support, backend candidate order, scheduler"," availability, and whether claude/npx resolve on PATH. Creates nothing.",""," -h, --help Show this help"].join(`
121
+ `)}function takeValue(argv,index,arg,flag){return arg.startsWith(`${flag}=`)?{value:arg.slice(`${flag}=`.length),nextIndex:index}:index+1>=argv.length?{error:`${flag} requires a value.`}:{value:argv[index+1],nextIndex:index+1}}function matchesFlag(arg,flag){return arg===flag||arg.startsWith(`${flag}=`)}function parseScheduleCreateArgs(argv){let delimIndex=argv.indexOf("--"),schedulerArgs=delimIndex===-1?argv:argv.slice(0,delimIndex),commandArgs=delimIndex===-1?[]:argv.slice(delimIndex+1);if(schedulerArgs.includes("-h")||schedulerArgs.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let at,inDuration,commandName,ideaFile,agent="claude",repoPath,id,sawAutoApprove=!1,sawNoAutoApprove=!1,dryRun=!1;for(let i=0;i<schedulerArgs.length;i++){let arg=schedulerArgs[i];if(matchesFlag(arg,"--at")){let r=takeValue(schedulerArgs,i,arg,"--at");if("error"in r)return{status:"error",message:r.error};at=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--in")){let r=takeValue(schedulerArgs,i,arg,"--in");if("error"in r)return{status:"error",message:r.error};inDuration=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--command")){let r=takeValue(schedulerArgs,i,arg,"--command");if("error"in r)return{status:"error",message:r.error};commandName=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--idea-file")){let r=takeValue(schedulerArgs,i,arg,"--idea-file");if("error"in r)return{status:"error",message:r.error};ideaFile=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(schedulerArgs,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};if(!getAgentLauncher(r.value))return{status:"error",message:`Invalid --agent value: '${r.value}'. Valid: ${formatValidAgentLauncherNames()}.`};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--repo-path")){let r=takeValue(schedulerArgs,i,arg,"--repo-path");if("error"in r)return{status:"error",message:r.error};repoPath=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--id")){let r=takeValue(schedulerArgs,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};id=r.value,i=r.nextIndex;continue}if(arg==="--auto"){sawAutoApprove=!0;continue}if(arg==="--no-auto"){sawNoAutoApprove=!0;continue}if(arg==="--dry-run"){dryRun=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. create takes flags before '--'; put command arguments after '--'.`}}if(!!at==!!inDuration)return{status:"error",message:"create requires exactly one of --at or --in."};if(sawAutoApprove&&sawNoAutoApprove)return{status:"error",message:"--auto and --no-auto are mutually exclusive."};if(id!==void 0&&!SCHEDULE_ID_PATTERN.test(id))return{status:"error",message:`Invalid --id value: '${id}'. Ids must match ${SCHEDULE_ID_PATTERN.source} (start alphanumeric; letters, digits, '_' and '-'; max 64 chars).`};if(ideaFile!==void 0){if(commandName===void 0)commandName="full-automation";else if(commandName!=="full-automation")return{status:"error",message:`--idea-file is only valid for legacy full-automation scheduling, not --command '${commandName}'. Pass command arguments after '--' instead.`}}return commandName===void 0?{status:"error",message:"create requires --command <name> (or legacy --idea-file <path>)."}:{status:"ok",subcommand:"create",options:{at,in:inDuration,commandName,commandArgs,ideaFile,agent,repoPath,autoApprove:!sawNoAutoApprove,autoApproveExplicit:sawAutoApprove||sawNoAutoApprove,dryRun,id}}}function parseScheduleExecuteArgs(argv){let positionals=argv.filter(a=>!a.startsWith("-")),flags=argv.filter(a=>a.startsWith("-"));if(flags.length>0)return{status:"error",message:`_execute takes no flags (got ${flags.join(", ")}).`};if(positionals.length!==1)return{status:"error",message:"_execute requires exactly one schedule id."};let id=positionals[0];return SCHEDULE_ID_PATTERN.test(id)?{status:"ok",subcommand:"_execute",options:{id}}:{status:"error",message:`Invalid schedule id: '${id}'.`}}function parseScheduleListArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let id,agent,backend,json=!1;for(let i=0;i<argv.length;i++){let arg=argv[i];if(matchesFlag(arg,"--id")){let r=takeValue(argv,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};id=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(argv,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};if(!getAgentLauncher(r.value))return{status:"error",message:`Invalid --agent filter: '${r.value}'. Valid: ${formatValidAgentLauncherNames()}.`};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--backend")){let r=takeValue(argv,i,arg,"--backend");if("error"in r)return{status:"error",message:r.error};if(!VALID_BACKEND_NAMES.includes(r.value))return{status:"error",message:`Invalid --backend filter: '${r.value}'. Valid: ${VALID_BACKEND_NAMES.join(", ")}.`};backend=r.value,i=r.nextIndex;continue}if(arg==="--json"){json=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. list takes only flags.`}}return{status:"ok",subcommand:"list",options:{id,agent,backend,json}}}function parseScheduleCancelArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let positionalId,flagId,agent,backend;for(let i=0;i<argv.length;i++){let arg=argv[i];if(matchesFlag(arg,"--id")){let r=takeValue(argv,i,arg,"--id");if("error"in r)return{status:"error",message:r.error};if(flagId!==void 0)return{status:"error",message:"cancel accepts only one --id."};flagId=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--agent")){let r=takeValue(argv,i,arg,"--agent");if("error"in r)return{status:"error",message:r.error};agent=r.value,i=r.nextIndex;continue}if(matchesFlag(arg,"--backend")){let r=takeValue(argv,i,arg,"--backend");if("error"in r)return{status:"error",message:r.error};if(!VALID_BACKEND_NAMES.includes(r.value))return{status:"error",message:`Invalid --backend filter: '${r.value}'. Valid: ${VALID_BACKEND_NAMES.join(", ")}.`};backend=r.value,i=r.nextIndex;continue}if(arg.startsWith("-"))return{status:"error",message:`Unknown flag: ${arg}`};if(positionalId!==void 0)return{status:"error",message:"cancel accepts only one schedule id."};positionalId=arg}if(positionalId!==void 0&&flagId!==void 0)return{status:"error",message:"cancel accepts a positional id OR --id, not both."};let id=positionalId??flagId;return id?{status:"ok",subcommand:"cancel",options:{id,agent,backend}}:{status:"error",message:"cancel requires a schedule id (positional or --id)."}}function parseScheduleDoctorArgs(argv){if(argv.includes("-h")||argv.includes("--help"))return{status:"help",usage:getScheduleRunUsage()};let json=!1;for(let arg of argv){if(arg==="--json"){json=!0;continue}return arg.startsWith("-")?{status:"error",message:`Unknown flag: ${arg}`}:{status:"error",message:`Unexpected positional argument: '${arg}'. doctor takes no positional arguments.`}}return{status:"ok",subcommand:"doctor",options:{json}}}function parseScheduleRunArgs(argv){if(argv.length===0)return{status:"error",message:"Missing subcommand. Expected one of: create, list, cancel, doctor."};let[subcommand,...rest]=argv;if(subcommand==="-h"||subcommand==="--help")return{status:"help",usage:getScheduleRunUsage()};switch(subcommand){case"create":return parseScheduleCreateArgs(rest);case"list":return parseScheduleListArgs(rest);case"cancel":return parseScheduleCancelArgs(rest);case"doctor":return parseScheduleDoctorArgs(rest);case"_execute":return parseScheduleExecuteArgs(rest);default:return{status:"error",message:`Unknown subcommand '${subcommand}'. Expected one of: create, list, cancel, doctor.`}}}function parseRunAtIso(value){let date=new Date(value);return Number.isNaN(date.getTime())?{ok:!1,error:`Invalid --at datetime: '${value}'. Expected an ISO-8601 timestamp.`}:{ok:!0,iso:date.toISOString()}}function parseDurationFromNow(value,nowMs){let match=value.match(/^(\d+)([mhd])$/);if(!match)return{ok:!1,error:`Invalid --in duration: '${value}'. Use a positive number followed by m, h, or d (e.g. 30m, 4h, 1d).`};let amount=Number(match[1]);if(amount<=0)return{ok:!1,error:`Invalid --in duration: '${value}'. Duration must be positive.`};let unitMs=match[2]==="m"?6e4:match[2]==="h"?36e5:864e5;return{ok:!0,iso:new Date(nowMs+amount*unitMs).toISOString()}}function resolveAbsolute(p,deps){let pathApi=pathApiForPlatform(deps.platform);return pathApi.isAbsolute(p)?pathApi.normalize(p):pathApi.resolve(deps.cwd,p)}function collectScheduleRunPrereqStatus(input){return{agentBinaryResolved:input.agentBinaryResolved,repoPathExists:input.repoPathExists,cursorApiKeyPresent:!!input.deps.env.CURSOR_API_KEY,bridgeCredentialResolved:input.deps.bridgeCredentialResolved?.()??!!input.deps.env.BAPI_API_KEY}}async function resolveScheduleCreateInput(options,runAtIso,deps){let launcher=getAgentLauncher(options.agent);if(!launcher)return{ok:!1,error:`Unsupported agent: '${options.agent}'. Valid: ${formatValidAgentLauncherNames()}.`};let commandName=options.commandName;if(!commandName)return{ok:!1,error:"create requires a command (--command or legacy --idea-file)."};let repoPath=resolveAbsolute(options.repoPath??deps.cwd,deps);try{if(!(await fs6.stat(repoPath)).isDirectory())return{ok:!1,error:`--repo-path is not a directory: ${repoPath}`}}catch{return{ok:!1,error:`--repo-path does not exist: ${repoPath}`}}let commandArgs=options.commandArgs,legacyIdeaFile;if(options.ideaFile!==void 0){let ideaFile=resolveAbsolute(options.ideaFile,deps);try{if(!(await fs6.stat(ideaFile)).isFile())return{ok:!1,error:`--idea-file is not a file: ${ideaFile}`}}catch{return{ok:!1,error:`--idea-file does not exist: ${ideaFile}`}}legacyIdeaFile=ideaFile,commandArgs=["--idea-file",ideaFile]}let catalog=await discoverCommandCatalog(repoPath,deps.platform,deps.commandCatalogFsDeps),resolvedCommand=resolveSchedulableCommand(catalog,commandName);if(!resolvedCommand.ok)return{ok:!1,error:resolvedCommand.error};let command=resolvedCommand.command,validation=validateCommandArgv(commandArgs,command.argumentSchema);if(!validation.ok)return{ok:!1,error:`Invalid arguments for '${commandName}': ${validation.error}`};let normalizedArgv=validation.normalizedArgv,envPath=deps.env.PATH??deps.env.Path??"",nodePath=deps.execPath,agentPath=await launcher.resolveBinary(envPath,deps);if(!agentPath)return{ok:!1,error:`Could not resolve the '${launcher.capability.command}' binary on the baked PATH.`};let npxPath=await resolveCommandOnPath("npx",envPath,deps)??"",id=options.id??randomUUID2(),agentInvocation=launcher.buildInvocation(agentPath,{scheduleId:id,runAtIso,commandName,args:normalizedArgv,autoApprove:options.autoApprove,repoPath,commandFilePath:command.filePath,commandBody:command.body,schema:command.argumentSchema}),cliEntryPath=deps.cliEntryPath??process.argv[1]??"",triggerInvocation={exe:nodePath,args:[cliEntryPath,"schedule-run","_execute",id]},commandBodyHash=createHash3("sha256").update(command.body,"utf-8").digest("hex"),warnings=[];command.interactive&&!options.autoApproveExplicit&&warnings.push(`Command '${commandName}' has an interactive step but --auto/--no-auto was not specified; a headless scheduled run may hang waiting for confirmation. Pass --auto to run hands-off.`),isTransientNpxEntryPath(cliEntryPath)&&warnings.push(`The scheduled run re-enters this CLI at '${cliEntryPath}', which is inside an npx cache directory. npx caches can be pruned before a future schedule fires, which would make the run fail with ENOENT. Install the CLI persistently (e.g. \`npm i -g ${MCP_PACKAGE_NAME}\`) and schedule with the installed binary so the trigger path stays stable.`);let paths=getSchedulePaths(id,deps.homeDir,deps.platform);return{ok:!0,resolved:{id,runAtIso,agent:options.agent,command:commandName,args:normalizedArgv,commandFilePath:command.filePath,commandBodyHash,autoApprove:options.autoApprove,repoPath,legacyIdeaFile,envPath,nodePath,npxPath,agentPath,agentInvocation,triggerInvocation,renderedPrompt:agentInvocation.prompt,schema:command.argumentSchema,paths:{schedulesDir:paths.schedulesDir,logsDir:paths.logsDir,stdoutPath:paths.stdoutPath,stderrPath:paths.stderrPath},warnings,prereq:collectScheduleRunPrereqStatus({agent:options.agent,agentBinaryResolved:!!agentPath,repoPathExists:!0,deps})}}}function buildScheduleMetadata(resolved,createResult,createdAtIso){return{id:resolved.id,run_at_iso:resolved.runAtIso,scheduled_at:resolved.runAtIso,backend:createResult.backend,unit_path:createResult.unitPath,unit_paths:createResult.unitPaths,backend_job_id:createResult.backendJobId,agent:resolved.agent,agent_path:resolved.agentPath,command:resolved.command,args:resolved.args,command_file:resolved.commandFilePath,command_body_hash:resolved.commandBodyHash,auto_approve:resolved.autoApprove,repo_path:resolved.repoPath,created_at:createdAtIso,env_path:resolved.envPath,node_path:resolved.nodePath,npx_path:resolved.npxPath,claude_path:resolved.agent==="claude"?resolved.agentPath:void 0,idea_file:resolved.legacyIdeaFile,invocation:resolved.agentInvocation,agent_invocation:resolved.agentInvocation,trigger_invocation:resolved.triggerInvocation,run_history:[{status:"created",at:createdAtIso}],logs:{stdout:resolved.paths.stdoutPath,stderr:resolved.paths.stderrPath}}}function resolveRunAtIso(options,deps){if(options.at!==void 0)return parseRunAtIso(options.at);let nowMs=deps.now?deps.now():Date.now();return parseDurationFromNow(options.in,nowMs)}async function orchestrateScheduleCreate(options,deps){let runAt=resolveRunAtIso(options,deps);if(!runAt.ok)return{ok:!1,error:runAt.error};let resolvedResult=await resolveScheduleCreateInput(options,runAt.iso,deps);if(!resolvedResult.ok)return{ok:!1,error:resolvedResult.error};let resolved=resolvedResult.resolved,createdAtIso=new Date(deps.now?deps.now():Date.now()).toISOString(),metadataPath=getSchedulePaths(resolved.id,deps.homeDir,deps.platform).metadataPath;if(!options.dryRun){let existing;try{existing=await readScheduleMetadata(resolved.id,deps.homeDir,deps.platform)}catch(error){let msg=error instanceof Error?error.message:String(error);return{ok:!1,error:`Could not read existing schedule metadata for id '${resolved.id}' at ${metadataPath}: ${msg}. Resolve or remove it before creating.`}}if(existing)return{ok:!1,error:`A schedule with id '${resolved.id}' already exists (${metadataPath}). Cancel it first (schedule-run cancel <id>) or choose a different --id.`}}let selection=await selectSchedulerBackend(deps,options.dryRun);if(!selection.ok)return{ok:!1,error:selection.error};let backend=selection.backend,createInput={deps,id:resolved.id,runAtIso:resolved.runAtIso,triggerInvocation:resolved.triggerInvocation,agentInvocation:resolved.agentInvocation,command:resolved.command,args:resolved.args,agent:resolved.agent,repoPath:resolved.repoPath,envPath:resolved.envPath,nodePath:resolved.nodePath,npxPath:resolved.npxPath,agentPath:resolved.agentPath,legacyIdeaFile:resolved.legacyIdeaFile,paths:resolved.paths,dryRun:options.dryRun};if(options.dryRun){let createResult2=await backend.create(createInput);return createResult2.ok?{ok:!0,dryRun:!0,metadata:buildScheduleMetadata(resolved,createResult2,createdAtIso),metadataPath,createResult:createResult2,resolved}:{ok:!1,error:createResult2.error??"Backend dry-run failed."}}await ensureScheduleDirectories(deps.homeDir,deps.platform);let createResult=await backend.create(createInput);if(!createResult.ok)return{ok:!1,error:createResult.error??"Scheduler backend create failed."};let metadata=buildScheduleMetadata(resolved,createResult,createdAtIso),scheduledAtIso=new Date(deps.now?deps.now():Date.now()).toISOString();metadata.run_history=[...metadata.run_history??[],{status:"scheduled",at:scheduledAtIso}];try{await writeScheduleMetadata(metadata,deps.homeDir,deps.platform)}catch(error){return await backend.cancel({deps,metadata}).catch(()=>{}),{ok:!1,error:`Created the native ${createResult.backend} unit but failed to persist schedule metadata (${error instanceof Error?error.message:String(error)}); attempted to cancel the native unit.`}}return{ok:!0,dryRun:!1,metadata,metadataPath,createResult,resolved}}function formatPrereqStatus(agent,prereq){let lines=[` agent binary: ${prereq.agentBinaryResolved?"resolved":"MISSING"}`,` repo path: ${prereq.repoPathExists?"exists":"MISSING"}`];return agent==="cursor-agent"?lines.push(` CURSOR_API_KEY set: ${prereq.cursorApiKeyPresent?"yes":"no"}`):lines.push(` Bridge credential: ${prereq.bridgeCredentialResolved?"resolved":"not resolved"}`),lines}function formatScheduleCreateResult(result){if(!result.ok)return`Error: ${result.error}`;let m=result.metadata,r=result.resolved,targetCommandLine=buildTargetCommandLine({commandName:r.command,args:r.args,scheduledAt:r.runAtIso,autoApprove:r.autoApprove,schema:r.schema}),lines=[];lines.push(result.dryRun?"[dry-run] schedule-run create preview":"Schedule created."),lines.push(` id: ${m.id}`),lines.push(` backend: ${m.backend}`),lines.push(` command: ${r.command}`),lines.push(` args: ${r.args.length>0?r.args.join(" "):"(none)"}`),lines.push(` run at: ${m.run_at_iso}`),lines.push(` agent: ${m.agent}`),lines.push(` auto-approve: ${m.auto_approve?"yes":"no"}`),lines.push(` metadata: ${result.metadataPath}${result.dryRun?" (not written in dry-run)":""}`),lines.push(` repo path: ${m.repo_path}`),m.idea_file&&lines.push(` idea file: ${m.idea_file}`),lines.push(` stdout log: ${m.logs.stdout}`),lines.push(` stderr log: ${m.logs.stderr}`),lines.push(` agent binary: ${r.agentPath}`),lines.push(` target command: ${targetCommandLine}`),lines.push(` trigger invocation: ${[r.triggerInvocation.exe,...r.triggerInvocation.args].join(" ")}`),lines.push(` agent invocation: ${[r.agentInvocation.exe,...r.agentInvocation.args].join(" ")}`),m.unit_paths.length>0&&lines.push(` unit paths: ${m.unit_paths.join(", ")}`);for(let warning of r.warnings)lines.push(` warning: ${warning}`);if(result.dryRun){lines.push(""),lines.push("prerequisites (secret-free):"),lines.push(...formatPrereqStatus(r.agent,r.prereq)),lines.push(""),lines.push("----- rendered prompt -----"),lines.push(r.renderedPrompt);for(let artifact of result.createResult.artifacts)lines.push(""),lines.push(`----- ${artifact.kind}: ${artifact.path} -----`),lines.push(artifact.content)}return lines.join(`
122
122
  `)}function filterScheduleMetadata(rows,filters){return rows.filter(row=>!(filters.id!==void 0&&row.id!==filters.id||filters.agent!==void 0&&row.agent!==filters.agent||filters.backend!==void 0&&row.backend!==filters.backend))}async function orchestrateScheduleList(options,deps){let rows=await listScheduleMetadata(deps.homeDir,deps.platform),warnings=[],valid=[];for(let row of rows)row.ok?valid.push(row.metadata):warnings.push(`Skipping malformed schedule metadata ${row.path}: ${row.error}`);let filtered=filterScheduleMetadata(valid,{id:options.id,agent:options.agent,backend:options.backend}),byBackend=new Map;for(let row of filtered){let group=byBackend.get(row.backend)??[];group.push(row),byBackend.set(row.backend,group)}let entries=[];for(let[backendName,recorded]of byBackend){let backend=getSchedulerBackendByName(backendName);if(!backend){for(let metadata of recorded)entries.push({metadata,status:"backend-unavailable",detail:"unknown backend"});continue}let groupEntries=await backend.list({deps,recorded});entries.push(...groupEntries)}return entries.sort((a,b)=>a.metadata.id.localeCompare(b.metadata.id)),{entries,warnings}}function scheduleCommandLabel(m){return m.command?m.command:m.idea_file?"full-automation":"(unknown)"}function latestRunStatus(m){let h=m.run_history;return h&&h.length>0?h[h.length-1].status:""}function formatScheduleListResult(report,json){if(json)return JSON.stringify({entries:report.entries.map(e=>({id:e.metadata.id,command:scheduleCommandLabel(e.metadata),args:e.metadata.args??[],scheduled_at:e.metadata.scheduled_at??e.metadata.run_at_iso,run_at:e.metadata.run_at_iso,backend:e.metadata.backend,agent:e.metadata.agent,native_status:e.status,latest_run_status:latestRunStatus(e.metadata),run_history:e.metadata.run_history??[],status:e.status,unit_path:e.metadata.unit_path})),warnings:report.warnings},null,2);let lines=[];for(let w of report.warnings)lines.push(`Warning: ${w}`);if(report.entries.length===0)return lines.push("No schedules found."),lines.join(`
123
123
  `);lines.push(["ID","COMMAND","RUN_AT","BACKEND","AGENT","NATIVE","LATEST","UNIT_PATH"].join(" "));for(let e of report.entries)lines.push([e.metadata.id,scheduleCommandLabel(e.metadata),e.metadata.run_at_iso,e.metadata.backend,e.metadata.agent,e.status,latestRunStatus(e.metadata)||"-",e.metadata.unit_path??"-"].join(" "));return lines.join(`
124
124
  `)}async function orchestrateScheduleCancel(options,deps){let metadata=await readScheduleMetadata(options.id,deps.homeDir,deps.platform);if(!metadata)return{ok:!1,notFound:!0,error:`No schedule found with id '${options.id}'.`};if(options.agent!==void 0&&metadata.agent!==options.agent)return{ok:!1,notFound:!0,error:`Schedule '${options.id}' does not match agent filter '${options.agent}'.`};if(options.backend!==void 0&&metadata.backend!==options.backend)return{ok:!1,notFound:!0,error:`Schedule '${options.id}' does not match backend filter '${options.backend}'.`};let backend=getSchedulerBackendByName(metadata.backend);if(!backend)return{ok:!1,error:`Unknown backend '${metadata.backend}' recorded for '${options.id}'.`};let cancelResult=await backend.cancel({deps,metadata});if(!cancelResult.ok)return{ok:!1,error:cancelResult.error??"Backend cancel failed."};let canceledAtIso=new Date(deps.now?deps.now():Date.now()).toISOString();return await appendScheduleRunEvent(options.id,{status:"canceled",at:canceledAtIso},deps.homeDir,deps.platform).catch(()=>{}),await deleteScheduleMetadata(options.id,deps.homeDir,deps.platform),{ok:!0,id:options.id,backend:metadata.backend,nativeRemoved:cancelResult.nativeRemoved,stale:cancelResult.stale,metadataRemoved:!0}}function formatScheduleCancelResult(result){return result.ok?[`Schedule '${result.id}' canceled.`,` backend: ${result.backend}`,` native removed: ${result.nativeRemoved?"yes":`no${result.stale?" (stale)":""}`}`,` metadata removed: ${result.metadataRemoved?"yes":"no"}`," logs: preserved"].join(`
125
125
  `):`Error: ${result.error}`}async function orchestrateScheduleDoctor(deps){let platformResult=getSchedulerBackendsForPlatform(deps.platform),envPath=deps.env.PATH??deps.env.Path??"",claudeResolved=!!await resolveCommandOnPath("claude",envPath,deps),cursorResolved=!!await resolveCommandOnPath("cursor-agent",envPath,deps),npxResolved=!!await resolveCommandOnPath("npx",envPath,deps),cursorApiKeyPresent=!!deps.env.CURSOR_API_KEY,bridgeCredentialResolved=deps.bridgeCredentialResolved?.()??!!deps.env.BAPI_API_KEY;if(!platformResult.ok)return{platform:deps.platform,platformSupported:!1,candidateBackends:[],backendAvailability:[],claudeResolved,cursorResolved,npxResolved,cursorApiKeyPresent,bridgeCredentialResolved,unsupportedMessage:platformResult.error};let candidateBackends=platformResult.backends.map(b=>b.name),backendAvailability=[];for(let backend of platformResult.backends)backendAvailability.push({backend:backend.name,available:await backend.isAvailable(deps)});return{platform:deps.platform,platformSupported:!0,candidateBackends,backendAvailability,claudeResolved,cursorResolved,npxResolved,cursorApiKeyPresent,bridgeCredentialResolved}}function formatScheduleDoctorReport(report,json){if(json)return JSON.stringify(report,null,2);let lines=["schedule-run doctor (read-only diagnostics)",`Platform: ${report.platform}`];if(!report.platformSupported)lines.push(report.unsupportedMessage??unsupportedSchedulerPlatformMessage(report.platform));else{lines.push(`Candidate backends (in order): ${report.candidateBackends.join(", ")}`);for(let a of report.backendAvailability)lines.push(` ${a.available?"AVAILABLE ":"UNAVAILABLE"} ${a.backend}`)}return lines.push(`claude on PATH: ${report.claudeResolved?"yes":"no"}`),lines.push(`cursor-agent on PATH: ${report.cursorResolved?"yes":"no"}`),lines.push(`npx on PATH: ${report.npxResolved?"yes":"no"}`),lines.push(`CURSOR_API_KEY set: ${report.cursorApiKeyPresent?"yes":"no"}`),lines.push(`Bridge credential: ${report.bridgeCredentialResolved?"resolved":"not resolved"}`),lines.join(`
126
- `)}function nowIso(deps){return new Date(deps.now?deps.now():Date.now()).toISOString()}async function orchestrateScheduleExecute(options,deps,io){let metadata=await readScheduleMetadata(options.id,deps.homeDir,deps.platform);if(!metadata)return{ok:!1,exitCode:1,error:`No schedule found with id '${options.id}'.`};let agentInvocation=metadata.agent_invocation??metadata.invocation;if(!agentInvocation||!agentInvocation.exe)return await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),message:"missing agent_invocation"},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:1,error:`Schedule '${options.id}' has no agent invocation to run.`};await appendScheduleRunEvent(options.id,{status:"started",at:nowIso(deps)},deps.homeDir,deps.platform).catch(()=>{});let env={...deps.env};metadata.env_path&&(env.PATH=metadata.env_path,deps.platform==="win32"&&(env.Path=metadata.env_path)),env.BRIDGE_GPT_SCHEDULE_ID=metadata.id,metadata.command&&(env.BRIDGE_GPT_COMMAND=metadata.command),metadata.args&&(env.BRIDGE_GPT_COMMAND_ARGS_JSON=JSON.stringify(metadata.args)),metadata.repo_path&&(env.BRIDGE_GPT_REPO_PATH=metadata.repo_path),metadata.agent&&(env.BRIDGE_GPT_AGENT=metadata.agent),metadata.agent_path&&(env.BRIDGE_GPT_AGENT_PATH=metadata.agent_path),metadata.idea_file&&(env.BRIDGE_GPT_IDEA_FILE=metadata.idea_file);let result;try{result=await deps.runCommand(agentInvocation.exe,agentInvocation.args,{cwd:metadata.repo_path,env})}catch(error){let msg=error instanceof Error?error.message:String(error);return await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),message:`agent launch failed: ${msg}`},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:1,error:`Failed to launch agent: ${msg}`}}return result.stdout&&io.writeStdout(result.stdout),result.stderr&&io.writeStderr(result.stderr),result.exitCode===0?(await appendScheduleRunEvent(options.id,{status:"completed",at:nowIso(deps),exit_code:0},deps.homeDir,deps.platform).catch(()=>{}),{ok:!0,exitCode:0}):(await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),exit_code:result.exitCode},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:result.exitCode})}async function runScheduleRunCli(argv,overrides={}){let log=overrides.log??(m=>console.log(m)),errorLog=overrides.errorLog??(m=>console.error(m)),parsed=parseScheduleRunArgs(argv);if(parsed.status==="help")return log(parsed.usage),0;if(parsed.status==="error")return errorLog(`Error: ${parsed.message}`),errorLog(""),errorLog(getScheduleRunUsage()),1;let deps=overrides.deps??createDefaultScheduleRunDeps();try{switch(parsed.subcommand){case"create":{let result=await orchestrateScheduleCreate(parsed.options,deps);return result.ok?(log(formatScheduleCreateResult(result)),0):(errorLog(formatScheduleCreateResult(result)),1)}case"list":{let report=await orchestrateScheduleList(parsed.options,deps);return log(formatScheduleListResult(report,parsed.options.json)),0}case"cancel":{let result=await orchestrateScheduleCancel(parsed.options,deps);return result.ok?(log(formatScheduleCancelResult(result)),0):(errorLog(formatScheduleCancelResult(result)),1)}case"doctor":{let report=await orchestrateScheduleDoctor(deps);return log(formatScheduleDoctorReport(report,parsed.options.json)),report.platformSupported?0:1}case"_execute":{let io={writeStdout:overrides.writeStdout??(chunk=>process.stdout.write(chunk)),writeStderr:overrides.writeStderr??(chunk=>process.stderr.write(chunk))},result=await orchestrateScheduleExecute(parsed.options,deps,io);return!result.ok&&result.error&&errorLog(`Error: ${result.error}`),result.exitCode}}}catch(error){let detail=error instanceof Error?error.message:String(error);return errorLog(`Internal error: ${detail}`),errorLog("Error: schedule-run failed unexpectedly. See the message above for local diagnostics."),1}return 1}var VALID_BACKEND_NAMES,SCHEDULE_ID_PATTERN,init_schedule_run=__esm({"src/schedule-run.ts"(){"use strict";init_scheduler_backends();init_schedule_store();init_agent_launchers();init_claude();init_command_catalog();init_scheduled_prompt();VALID_BACKEND_NAMES=["launchd","task-scheduler","systemd-user","at-fallback"],SCHEDULE_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/}});function listAgentNames(){return Object.keys(AGENT_REGISTRY)}function isAgentName(value){return listAgentNames().includes(value)}function resolveAgentSpec(name){let resolved=name??DEFAULT_AGENT_NAME;return isAgentName(resolved)?AGENT_REGISTRY[resolved]:null}var AGENT_REGISTRY,DEFAULT_AGENT_NAME,init_agent_registry=__esm({"src/agent-registry.ts"(){"use strict";AGENT_REGISTRY={claude:{name:"claude",command:"claude",promptArgStyle:"positional",installHint:{darwin:"npm install -g @anthropic-ai/claude-code",linux:"npm install -g @anthropic-ai/claude-code",win32:"npm install -g @anthropic-ai/claude-code"},authNote:"Claude Code authenticates interactively on first run \u2014 follow its login/auth prompt if asked.",supportsModelOverride:!0,modelFlag:"--model",tierModels:{cheap:"haiku",basic:"sonnet",premium:"opus"},staticModelAliasAllowlist:["haiku","sonnet","opus"],executorAdapter:{adapterId:"claude-reference",strategyId:"claude-strict-mcp-v1",adapterVersion:"1.0.0",supportedPlatforms:["darwin","linux"],capabilityStrategyIds:{mcpScoping:"strict-mcp-config",mcpInitParsing:"claude-system-init",authFailureDetection:"claude-stream-json-result",denyEnforcement:"claude-settings-deny",redaction:"claude-env-name-redaction",lifecycle:"claude-no-lifecycle"},managedCarriers:[],passthroughs:[{passthroughId:"claude-code-oauth-token",envName:"CLAUDE_CODE_OAUTH_TOKEN",billingClass:"subscription",ownership:"operator-owned",rule:"forward-when-present"}]}},"cursor-agent":{name:"cursor-agent",command:"cursor-agent",promptArgStyle:"positional",installHint:{darwin:"curl https://cursor.com/install -fsSL | bash",linux:"curl https://cursor.com/install -fsSL | bash",win32:"irm 'https://cursor.com/install?win32=true' | iex"},authNote:"Run cursor-agent login to authenticate; doctor checks PATH presence only, not login state.",supportsModelOverride:!0,modelFlag:"--model",tierModels:{cheap:"auto",basic:"claude-4.6-sonnet-medium",premium:"claude-opus-4-8-thinking-high"}}},DEFAULT_AGENT_NAME="claude"}});var DEFAULT_PROBE_TIMEOUT_MS,init_types2=__esm({"src/agent-capabilities/types.ts"(){"use strict";DEFAULT_PROBE_TIMEOUT_MS=9e4}});import{join}from"node:path";function buildHeadlessArgs(agentName,opts){let fmt=opts.outputFormat??"text";if(agentName==="cursor-agent")return["-p","--output-format",fmt,"--trust","--workspace",opts.cwd,opts.prompt];let args=["-p"];return opts.permissionMode==="acceptEdits"?args.push("--permission-mode","acceptEdits"):opts.skipPermissions===!0&&args.push("--dangerously-skip-permissions"),typeof opts.model=="string"&&opts.model.trim().length>0&&args.push("--model",opts.model),fmt==="json"?args.push("--output-format","json"):fmt==="stream-json"&&args.push("--output-format","stream-json","--verbose"),args.push(opts.prompt),args}async function createProbeContext(deps,agent,defaultTimeoutMs=DEFAULT_PROBE_TIMEOUT_MS){let launcherDeps={platform:deps.platform,env:deps.env,runCommand:(file,args,options)=>deps.runCommand(file,args,options)},resolvedBinary=await resolveCommandOnPath(agent.command,deps.env.PATH??"",launcherDeps),createdDirs=[],counter=0;return{ctx:{agent,deps,resolvedBinary,marker(name){return`${name}_${deps.uniqueSuffix()}_${counter++}`},async makeTempProject(seed){let dir=await deps.mkdtemp(join(deps.tmpRoot,"agent-cap-"));return createdDirs.push(dir),seed&&await seed(dir),dir},async runHeadless(opts){let exe=resolvedBinary??agent.command,args=buildHeadlessArgs(agent.name,opts),timeoutMs=opts.timeoutMs??defaultTimeoutMs,controller=new AbortController,timedOut=!1,timer=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs),start=deps.now();try{let result=await deps.runCommand(exe,args,{cwd:opts.cwd,env:deps.env,signal:controller.signal}),elapsedMs=deps.now()-start;return timedOut?{kind:"hang",elapsedMs,partialStdout:result.stdout??""}:{kind:"exited",exitCode:result.exitCode,stdout:result.stdout??"",stderr:result.stderr??"",elapsedMs}}catch(err){let elapsedMs=deps.now()-start;return timedOut?{kind:"hang",elapsedMs,partialStdout:""}:{kind:"spawn-error",message:err instanceof Error?err.message:String(err)}}finally{clearTimeout(timer)}}},cleanup:async()=>{for(let dir of createdDirs.splice(0))try{await deps.rm(dir,{recursive:!0,force:!0})}catch{}}}}var init_probe_context=__esm({"src/agent-capabilities/probe-context.ts"(){"use strict";init_claude();init_types2()}});import{execFile as execFile2}from"node:child_process";import{mkdtemp,rm,writeFile,mkdir}from"node:fs/promises";import os2 from"node:os";import{randomBytes}from"node:crypto";function createDefaultAgentCapabilitiesDeps(){let runCommand=(file,args,options)=>new Promise(resolve2=>{execFile2(file,args,{cwd:options?.cwd,env:options?.env??process.env,signal:options?.signal,killSignal:"SIGKILL",maxBuffer:67108864,encoding:"utf-8"},(error,stdout,stderr)=>{let exitCode=error&&typeof error.code=="number"?error.code:error?1:0;resolve2({stdout:stdout??"",stderr:stderr??"",exitCode})})});return{platform:process.platform,env:process.env,runCommand,tmpRoot:os2.tmpdir(),mkdtemp:prefix=>mkdtemp(prefix),rm:(target,opts)=>rm(target,opts),writeFile:(target,data)=>writeFile(target,data,"utf-8"),mkdir:(target,opts)=>mkdir(target,opts).then(()=>{}),now:()=>Date.now(),uniqueSuffix:()=>randomBytes(3).toString("hex").toUpperCase()}}var init_default_deps=__esm({"src/agent-capabilities/default-deps.ts"(){"use strict"}});import{join as join2}from"node:path";function truncate(text){let flat=text.replace(/\s+/g," ").trim();return flat.length>EVIDENCE_MAX?`${flat.slice(0,EVIDENCE_MAX)}\u2026`:flat}function nonExitedResult(run){return run.kind==="hang"?{status:"hang",detail:`agent did not exit within the timeout (${run.elapsedMs}ms) \u2014 likely the version-sensitive -p hang`,elapsedMs:run.elapsedMs,evidence:run.partialStdout?truncate(run.partialStdout):void 0}:run.kind==="spawn-error"?{status:"fail",detail:`could not spawn agent: ${run.message}`}:null}function denyHookCommand(){return`printf '%s' '${JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"agent-capability deny-enforcement probe fallback: tool call denied."}})}'`}async function seedDenyTargetFile(ctx,dir,marker){await ctx.deps.writeFile(join2(dir,DENY_TARGET_FILE),`${marker}
127
- `)}async function seedDenySettings(ctx,dir,marker){await seedDenyTargetFile(ctx,dir,marker);let claudeDir=join2(dir,".claude");await ctx.deps.mkdir(claudeDir,{recursive:!0});let settings={permissions:{deny:[DENY_BASH_RULE]}};await ctx.deps.writeFile(join2(claudeDir,"settings.local.json"),`${JSON.stringify(settings,null,2)}
128
- `)}async function seedDenyHook(ctx,dir,marker){await seedDenyTargetFile(ctx,dir,marker);let claudeDir=join2(dir,".claude");await ctx.deps.mkdir(claudeDir,{recursive:!0});let settings={hooks:{PreToolUse:[{matcher:DENY_HOOK_MATCHER,hooks:[{type:"command",command:denyHookCommand()}]}]}};await ctx.deps.writeFile(join2(claudeDir,"settings.local.json"),`${JSON.stringify(settings,null,2)}
126
+ `)}function nowIso(deps){return new Date(deps.now?deps.now():Date.now()).toISOString()}async function orchestrateScheduleExecute(options,deps,io){let metadata=await readScheduleMetadata(options.id,deps.homeDir,deps.platform);if(!metadata)return{ok:!1,exitCode:1,error:`No schedule found with id '${options.id}'.`};let agentInvocation=metadata.agent_invocation??metadata.invocation;if(!agentInvocation||!agentInvocation.exe)return await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),message:"missing agent_invocation"},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:1,error:`Schedule '${options.id}' has no agent invocation to run.`};await appendScheduleRunEvent(options.id,{status:"started",at:nowIso(deps)},deps.homeDir,deps.platform).catch(()=>{});let env={...deps.env};metadata.env_path&&(env.PATH=metadata.env_path,deps.platform==="win32"&&(env.Path=metadata.env_path)),env.BRIDGE_GPT_SCHEDULE_ID=metadata.id,metadata.command&&(env.BRIDGE_GPT_COMMAND=metadata.command),metadata.args&&(env.BRIDGE_GPT_COMMAND_ARGS_JSON=JSON.stringify(metadata.args)),metadata.repo_path&&(env.BRIDGE_GPT_REPO_PATH=metadata.repo_path),metadata.agent&&(env.BRIDGE_GPT_AGENT=metadata.agent),metadata.agent_path&&(env.BRIDGE_GPT_AGENT_PATH=metadata.agent_path),metadata.idea_file&&(env.BRIDGE_GPT_IDEA_FILE=metadata.idea_file);let result;try{result=await deps.runCommand(agentInvocation.exe,agentInvocation.args,{cwd:metadata.repo_path,env})}catch(error){let msg=error instanceof Error?error.message:String(error);return await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),message:`agent launch failed: ${msg}`},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:1,error:`Failed to launch agent: ${msg}`}}return result.stdout&&io.writeStdout(result.stdout),result.stderr&&io.writeStderr(result.stderr),result.exitCode===0?(await appendScheduleRunEvent(options.id,{status:"completed",at:nowIso(deps),exit_code:0},deps.homeDir,deps.platform).catch(()=>{}),{ok:!0,exitCode:0}):(await appendScheduleRunEvent(options.id,{status:"failed",at:nowIso(deps),exit_code:result.exitCode},deps.homeDir,deps.platform).catch(()=>{}),{ok:!1,exitCode:result.exitCode})}async function runScheduleRunCli(argv,overrides={}){let log=overrides.log??(m=>console.log(m)),errorLog=overrides.errorLog??(m=>console.error(m)),parsed=parseScheduleRunArgs(argv);if(parsed.status==="help")return log(parsed.usage),0;if(parsed.status==="error")return errorLog(`Error: ${parsed.message}`),errorLog(""),errorLog(getScheduleRunUsage()),1;let deps=overrides.deps??createDefaultScheduleRunDeps();try{switch(parsed.subcommand){case"create":{let result=await orchestrateScheduleCreate(parsed.options,deps);return result.ok?(log(formatScheduleCreateResult(result)),0):(errorLog(formatScheduleCreateResult(result)),1)}case"list":{let report=await orchestrateScheduleList(parsed.options,deps);return log(formatScheduleListResult(report,parsed.options.json)),0}case"cancel":{let result=await orchestrateScheduleCancel(parsed.options,deps);return result.ok?(log(formatScheduleCancelResult(result)),0):(errorLog(formatScheduleCancelResult(result)),1)}case"doctor":{let report=await orchestrateScheduleDoctor(deps);return log(formatScheduleDoctorReport(report,parsed.options.json)),report.platformSupported?0:1}case"_execute":{let io={writeStdout:overrides.writeStdout??(chunk=>process.stdout.write(chunk)),writeStderr:overrides.writeStderr??(chunk=>process.stderr.write(chunk))},result=await orchestrateScheduleExecute(parsed.options,deps,io);return!result.ok&&result.error&&errorLog(`Error: ${result.error}`),result.exitCode}}}catch(error){let detail=error instanceof Error?error.message:String(error);return errorLog(`Internal error: ${detail}`),errorLog("Error: schedule-run failed unexpectedly. See the message above for local diagnostics."),1}return 1}var VALID_BACKEND_NAMES,SCHEDULE_ID_PATTERN,init_schedule_run=__esm({"src/schedule-run.ts"(){"use strict";init_scheduler_backends();init_schedule_store();init_agent_launchers();init_claude();init_command_catalog();init_scheduled_prompt();init_mcp_identity();VALID_BACKEND_NAMES=["launchd","task-scheduler","systemd-user","at-fallback"],SCHEDULE_ID_PATTERN=/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/}});function listAgentNames(){return Object.keys(AGENT_REGISTRY)}function isAgentName(value){return listAgentNames().includes(value)}function resolveAgentSpec(name){let resolved=name??DEFAULT_AGENT_NAME;return isAgentName(resolved)?AGENT_REGISTRY[resolved]:null}var AGENT_REGISTRY,DEFAULT_AGENT_NAME,init_agent_registry=__esm({"src/agent-registry.ts"(){"use strict";AGENT_REGISTRY={claude:{name:"claude",command:"claude",promptArgStyle:"positional",installHint:{darwin:"npm install -g @anthropic-ai/claude-code",linux:"npm install -g @anthropic-ai/claude-code",win32:"npm install -g @anthropic-ai/claude-code"},authNote:"Claude Code authenticates interactively on first run \u2014 follow its login/auth prompt if asked.",supportsModelOverride:!0,modelFlag:"--model",tierModels:{cheap:"haiku",basic:"sonnet",premium:"opus"},staticModelAliasAllowlist:["haiku","sonnet","opus"],executorAdapter:{adapterId:"claude-reference",strategyId:"claude-strict-mcp-v1",adapterVersion:"1.0.0",supportedPlatforms:["darwin","linux"],capabilityStrategyIds:{mcpScoping:"strict-mcp-config",mcpInitParsing:"claude-system-init",authFailureDetection:"claude-stream-json-result",denyEnforcement:"claude-settings-deny",redaction:"claude-env-name-redaction",lifecycle:"claude-no-lifecycle"},managedCarriers:[],passthroughs:[{passthroughId:"claude-code-oauth-token",envName:"CLAUDE_CODE_OAUTH_TOKEN",billingClass:"subscription",ownership:"operator-owned",rule:"forward-when-present"}]}},"cursor-agent":{name:"cursor-agent",command:"cursor-agent",promptArgStyle:"positional",installHint:{darwin:"curl https://cursor.com/install -fsSL | bash",linux:"curl https://cursor.com/install -fsSL | bash",win32:"irm 'https://cursor.com/install?win32=true' | iex"},authNote:"Run cursor-agent login to authenticate; doctor checks PATH presence only, not login state.",supportsModelOverride:!0,modelFlag:"--model",tierModels:{cheap:"auto",basic:"claude-4.6-sonnet-medium",premium:"claude-opus-4-8-thinking-high"}}},DEFAULT_AGENT_NAME="claude"}});var DEFAULT_PROBE_TIMEOUT_MS,init_types2=__esm({"src/agent-capabilities/types.ts"(){"use strict";DEFAULT_PROBE_TIMEOUT_MS=9e4}});import{join as join2}from"node:path";function buildHeadlessArgs(agentName,opts){let fmt=opts.outputFormat??"text";if(agentName==="cursor-agent")return["-p","--output-format",fmt,"--trust","--workspace",opts.cwd,opts.prompt];let args=["-p"];return opts.permissionMode==="acceptEdits"?args.push("--permission-mode","acceptEdits"):opts.skipPermissions===!0&&args.push("--dangerously-skip-permissions"),typeof opts.model=="string"&&opts.model.trim().length>0&&args.push("--model",opts.model),fmt==="json"?args.push("--output-format","json"):fmt==="stream-json"&&args.push("--output-format","stream-json","--verbose"),args.push(opts.prompt),args}async function createProbeContext(deps,agent,defaultTimeoutMs=DEFAULT_PROBE_TIMEOUT_MS){let launcherDeps={platform:deps.platform,env:deps.env,runCommand:(file,args,options)=>deps.runCommand(file,args,options)},resolvedBinary=await resolveCommandOnPath(agent.command,deps.env.PATH??"",launcherDeps),createdDirs=[],counter=0;return{ctx:{agent,deps,resolvedBinary,marker(name){return`${name}_${deps.uniqueSuffix()}_${counter++}`},async makeTempProject(seed){let dir=await deps.mkdtemp(join2(deps.tmpRoot,"agent-cap-"));return createdDirs.push(dir),seed&&await seed(dir),dir},async runHeadless(opts){let exe=resolvedBinary??agent.command,args=buildHeadlessArgs(agent.name,opts),timeoutMs=opts.timeoutMs??defaultTimeoutMs,controller=new AbortController,timedOut=!1,timer=setTimeout(()=>{timedOut=!0,controller.abort()},timeoutMs),start=deps.now();try{let result=await deps.runCommand(exe,args,{cwd:opts.cwd,env:deps.env,signal:controller.signal}),elapsedMs=deps.now()-start;return timedOut?{kind:"hang",elapsedMs,partialStdout:result.stdout??""}:{kind:"exited",exitCode:result.exitCode,stdout:result.stdout??"",stderr:result.stderr??"",elapsedMs}}catch(err){let elapsedMs=deps.now()-start;return timedOut?{kind:"hang",elapsedMs,partialStdout:""}:{kind:"spawn-error",message:err instanceof Error?err.message:String(err)}}finally{clearTimeout(timer)}}},cleanup:async()=>{for(let dir of createdDirs.splice(0))try{await deps.rm(dir,{recursive:!0,force:!0})}catch{}}}}var init_probe_context=__esm({"src/agent-capabilities/probe-context.ts"(){"use strict";init_claude();init_types2()}});import{execFile as execFile2}from"node:child_process";import{mkdtemp,rm,writeFile,mkdir}from"node:fs/promises";import os2 from"node:os";import{randomBytes}from"node:crypto";function createDefaultAgentCapabilitiesDeps(){let runCommand=(file,args,options)=>new Promise(resolve2=>{execFile2(file,args,{cwd:options?.cwd,env:options?.env??process.env,signal:options?.signal,killSignal:"SIGKILL",maxBuffer:67108864,encoding:"utf-8"},(error,stdout,stderr)=>{let exitCode=error&&typeof error.code=="number"?error.code:error?1:0;resolve2({stdout:stdout??"",stderr:stderr??"",exitCode})})});return{platform:process.platform,env:process.env,runCommand,tmpRoot:os2.tmpdir(),mkdtemp:prefix=>mkdtemp(prefix),rm:(target,opts)=>rm(target,opts),writeFile:(target,data)=>writeFile(target,data,"utf-8"),mkdir:(target,opts)=>mkdir(target,opts).then(()=>{}),now:()=>Date.now(),uniqueSuffix:()=>randomBytes(3).toString("hex").toUpperCase()}}var init_default_deps=__esm({"src/agent-capabilities/default-deps.ts"(){"use strict"}});import{join as join3}from"node:path";function truncate(text){let flat=text.replace(/\s+/g," ").trim();return flat.length>EVIDENCE_MAX?`${flat.slice(0,EVIDENCE_MAX)}\u2026`:flat}function nonExitedResult(run){return run.kind==="hang"?{status:"hang",detail:`agent did not exit within the timeout (${run.elapsedMs}ms) \u2014 likely the version-sensitive -p hang`,elapsedMs:run.elapsedMs,evidence:run.partialStdout?truncate(run.partialStdout):void 0}:run.kind==="spawn-error"?{status:"fail",detail:`could not spawn agent: ${run.message}`}:null}function denyHookCommand(){return`printf '%s' '${JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"agent-capability deny-enforcement probe fallback: tool call denied."}})}'`}async function seedDenyTargetFile(ctx,dir,marker){await ctx.deps.writeFile(join3(dir,DENY_TARGET_FILE),`${marker}
127
+ `)}async function seedDenySettings(ctx,dir,marker){await seedDenyTargetFile(ctx,dir,marker);let claudeDir=join3(dir,".claude");await ctx.deps.mkdir(claudeDir,{recursive:!0});let settings={permissions:{deny:[DENY_BASH_RULE]}};await ctx.deps.writeFile(join3(claudeDir,"settings.local.json"),`${JSON.stringify(settings,null,2)}
128
+ `)}async function seedDenyHook(ctx,dir,marker){await seedDenyTargetFile(ctx,dir,marker);let claudeDir=join3(dir,".claude");await ctx.deps.mkdir(claudeDir,{recursive:!0});let settings={hooks:{PreToolUse:[{matcher:DENY_HOOK_MATCHER,hooks:[{type:"command",command:denyHookCommand()}]}]}};await ctx.deps.writeFile(join3(claudeDir,"settings.local.json"),`${JSON.stringify(settings,null,2)}
129
129
  `)}function denyProbePrompt(){return["This is an agent-capability probe of permission enforcement.",`Use the Bash tool to run exactly this command: cat ${DENY_TARGET_FILE}`,"Then output the command's exact stdout on its own line.","Use ONLY the Bash tool for this \u2014 do not use Read, Grep, or any other tool, and do not open the file yourself.","If the Bash command is blocked, denied, or errors, output the single word DENIED and nothing else.","Do not guess, fabricate, or infer the file contents \u2014 only report what the command actually returned."].join(`
130
130
  `)}function withDenyLayer(result,layer){return{...result,metadata:{...result.metadata??{},layer}}}function evaluateDenyRun(run,allowedMarker){let nonExited=nonExitedResult(run);if(nonExited)return{kind:"nonexited",result:nonExited};let{exitCode,stdout,stderr,elapsedMs}=run;return exitCode!==0?{kind:"error",result:{status:"fail",detail:`deny-enforcement probe agent exited ${exitCode}`,elapsedMs,evidence:truncate(stdout||stderr)}}:stdout.includes(allowedMarker)?{kind:"allowed",evidence:truncate(stdout)}:{kind:"blocked",evidence:truncate(stdout||stderr)}}async function runDenyEnforcementCheck(ctx,opts){let marker=ctx.marker("DENY_ALLOWED"),prompt=denyProbePrompt(),acceptEdits=opts?.permissionPosture==="accept_edits",runOpts={skipPermissions:!acceptEdits,permissionMode:acceptEdits?"acceptEdits":void 0,model:opts?.model,timeoutMs:opts?.timeoutMs},controlDir=await ctx.makeTempProject(d=>seedDenyTargetFile(ctx,d,marker)),controlRun=await ctx.runHeadless({prompt,cwd:controlDir,...runOpts}),c=evaluateDenyRun(controlRun,marker);if(c.kind==="nonexited")return{result:withDenyLayer(c.result,"none"),layer:"none"};if(c.kind==="error")return{result:withDenyLayer(c.result,"none"),layer:"none"};if(c.kind==="blocked")return{result:withDenyLayer({status:"fail",detail:"control run (no deny rule) did not execute the canary call \u2014 the agent never attempted the Bash command, so deny enforcement cannot be verified (a refusal is NOT enforcement)",elapsedMs:controlRun.elapsedMs,evidence:c.evidence},"none"),layer:"none"};let denyDir=await ctx.makeTempProject(d=>seedDenySettings(ctx,d,marker)),settingsRun=await ctx.runHeadless({prompt,cwd:denyDir,...runOpts}),s=evaluateDenyRun(settingsRun,marker);if(s.kind==="nonexited")return{result:withDenyLayer(s.result,"none"),layer:"none"};if(s.kind==="error")return{result:withDenyLayer(s.result,"none"),layer:"none"};if(s.kind==="blocked")return{result:withDenyLayer({status:"pass",detail:"denied call rejected by settings permissions.deny",elapsedMs:settingsRun.elapsedMs,evidence:s.evidence},"settings-deny"),layer:"settings-deny"};let hookDir=await ctx.makeTempProject(d=>seedDenyHook(ctx,d,marker)),hookRun=await ctx.runHeadless({prompt,cwd:hookDir,...runOpts}),h=evaluateDenyRun(hookRun,marker);return h.kind==="nonexited"?{result:withDenyLayer(h.result,"none"),layer:"none"}:h.kind==="error"?{result:withDenyLayer(h.result,"none"),layer:"none"}:h.kind==="blocked"?{result:withDenyLayer({status:"pass",detail:"settings deny did not reject; PreToolUse hook fallback rejected the call",elapsedMs:hookRun.elapsedMs,evidence:h.evidence},"pretooluse-hook"),layer:"pretooluse-hook"}:{result:withDenyLayer({status:"fail",detail:"deny is NOT enforced for this installed Claude version under --dangerously-skip-permissions (neither settings permissions.deny nor a PreToolUse hook rejected the denied call)",elapsedMs:hookRun.elapsedMs,evidence:h.evidence},"none"),layer:"none"}}var EVIDENCE_MAX,DENY_TARGET_FILE,DENY_BASH_RULE,DENY_HOOK_MATCHER,init_probes=__esm({"src/agent-capabilities/probes.ts"(){"use strict";init_probe_context();EVIDENCE_MAX=200;DENY_TARGET_FILE="deny-probe-target.txt",DENY_BASH_RULE="Bash(cat:*)",DENY_HOOK_MATCHER="Bash"}});var deny_enforcement_preflight_exports={};__export(deny_enforcement_preflight_exports,{runDenyEnforcementPreflight:()=>runDenyEnforcementPreflight});async function runDenyEnforcementPreflight(opts={}){try{let agent=resolveAgentSpec("claude");if(!agent)return{enforced:!1,layer:"none",degraded:!0,warnings:["Could not resolve the 'claude' agent spec for the deny-enforcement preflight.",REFUSE_TO_CLAIM_WARNING]};let deps=opts.capabilityDeps??createDefaultAgentCapabilitiesDeps(),{ctx,cleanup}=await createProbeContext(deps,agent,opts.timeoutMs);try{let{result,layer}=await runDenyEnforcementCheck(ctx,{model:opts.model,timeoutMs:opts.timeoutMs,permissionPosture:opts.permissionPosture});return result.status==="pass"&&layer==="settings-deny"?{enforced:!0,layer:"settings-deny",degraded:!1,warnings:[],status:result.status,detail:result.detail}:result.status==="pass"&&layer==="pretooluse-hook"?{enforced:!0,layer:"pretooluse-hook",degraded:!0,warnings:["settings permissions.deny was not enforced under --dangerously-skip-permissions; relying on PreToolUse fallback."],status:result.status,detail:result.detail}:{enforced:!1,layer:"none",degraded:!0,warnings:[`Deny-layer enforcement probe did not pass: ${result.detail}`,REFUSE_TO_CLAIM_WARNING],status:result.status,detail:result.detail}}finally{await cleanup()}}catch(err){return{enforced:!1,layer:"none",degraded:!0,warnings:[`Deny-layer enforcement preflight failed unexpectedly: ${err instanceof Error?err.message:String(err)}`,REFUSE_TO_CLAIM_WARNING]}}}var REFUSE_TO_CLAIM_WARNING,init_deny_enforcement_preflight=__esm({"src/conductor/deny-enforcement-preflight.ts"(){"use strict";init_agent_registry();init_probe_context();init_default_deps();init_probes();REFUSE_TO_CLAIM_WARNING="The executor claim loop MUST refuse to claim jobs until settings permissions.deny or the PreToolUse fallback enforces the deny layer."}});function parseBoundedSupervisorInt(raw,fallback,min,max){if(raw===void 0)return fallback;let trimmed=raw.trim();if(trimmed.length===0||!/^[+-]?\d+$/.test(trimmed))return fallback;let parsed=Number.parseInt(trimmed,10);return Number.isFinite(parsed)?Math.min(max,Math.max(min,parsed)):fallback}function resolveSupervisorConfig(overrides={},env=process.env){let wake_interval_ms=clampOverride(overrides.wake_interval_ms,parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_WAKE_INTERVAL_MS,45e3,3e4,6e4),3e4,6e4),global_timeout_ms=clampOverride(overrides.global_timeout_ms,parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_GLOBAL_TIMEOUT_MS,864e5,3e5,6048e5),3e5,6048e5),escalation_cooldown_ms=clampOverride(overrides.escalation_cooldown_ms,parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_ESCALATION_COOLDOWN_MS,9e5,3e5,864e5),3e5,864e5),quiet_after_ms=parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_QUIET_AFTER_MS,3e5,6e4,36e5),liveness_stalled_after_ms=parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_LIVENESS_STALLED_AFTER_MS,12e5,3e5,144e5),dead_after_ms=parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_DEAD_AFTER_MS,72e5,6e5,864e5),poll_limit=parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_SUPERVISOR_POLL_LIMIT,POLL_LIMIT_DEFAULT2,POLL_LIMIT_MIN,POLL_LIMIT_MAX2);return{wake_interval_ms,global_timeout_ms,stall_thresholds_ms:resolveStallThresholds(env),liveness:{quiet_after_ms,stalled_after_ms:liveness_stalled_after_ms,dead_after_ms},escalation_cooldown_ms,poll_limit}}function clampOverride(override,base,min,max){return override===void 0||!Number.isFinite(override)?base:Math.min(max,Math.max(min,Math.floor(override)))}function resolveStallThresholds(env){return{not_started:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_NOT_STARTED_MS,15*6e4,6e4,36e5),active:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_ACTIVE_MS,2*36e5,10*6e4,12*36e5),stalled:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_STALLED_MS,30*6e4,5*6e4,6*36e5),blocked:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_BLOCKED_MS,24*36e5,30*6e4,168*36e5),candidate_done:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_CANDIDATE_DONE_MS,30*6e4,5*6e4,6*36e5),verifying:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_VERIFYING_MS,2*36e5,10*6e4,12*36e5),unknown:parseBoundedSupervisorInt(env.BAPI_CONDUCTOR_STALL_UNKNOWN_MS,30*6e4,5*6e4,6*36e5),complete:Number.MAX_SAFE_INTEGER,failed:Number.MAX_SAFE_INTEGER}}var POLL_LIMIT_DEFAULT2,POLL_LIMIT_MIN,POLL_LIMIT_MAX2,init_supervisor_config=__esm({"src/conductor/supervisor-config.ts"(){"use strict";POLL_LIMIT_DEFAULT2=200,POLL_LIMIT_MIN=1,POLL_LIMIT_MAX2=1e3}});import path7 from"path";function hasControlChars(value){for(let i=0;i<value.length;i++){let code=value.charCodeAt(i);if(code<=31||code===127)return!0}return!1}function validateRepoName(raw){if(typeof raw!="string")return{ok:!1,error:"repo_name must be a string"};let value=raw.trim();return value.length===0?{ok:!1,error:"repo_name must be a non-empty string"}:value.includes("/")||value.includes("\\")?{ok:!1,error:"repo_name must not contain path separators"}:hasControlChars(value)?{ok:!1,error:"repo_name must not contain control characters"}:{ok:!0,value}}function validateMcpTarget(raw){if(typeof raw!="string")return{ok:!1,error:"mcp target must be a string"};let value=raw.trim();return value.length===0?{ok:!1,error:"mcp target must be a non-empty string"}:value.includes("/")||value.includes("\\")?{ok:!1,error:"mcp target must not contain path separators"}:hasControlChars(value)?{ok:!1,error:"mcp target must not contain control characters"}:{ok:!0,value}}function parseQuotedString(value){if(value.length<2||value[0]!=='"'||value[value.length-1]!=='"')return null;let inner=value.slice(1,-1);return inner.includes('"')?null:inner}function parseStringArray(value){let trimmed=value.trim();if(trimmed.length<2||trimmed[0]!=="["||trimmed[trimmed.length-1]!=="]")return null;let inner=trimmed.slice(1,-1).trim();if(inner.length===0)return[];let parts=inner.split(","),out=[];for(let part of parts){let element=parseQuotedString(part.trim());if(element===null)return null;out.push(element)}return out}function parseBridgeConfigToml(text){let lines=text.split(`
131
- `),repoName,sawRepoName=!1,mcp=[],currentMcp=null;for(let i=0;i<lines.length;i++){let lineNo=i+1,line=lines[i].trim();if(line.length===0||line.startsWith("#"))continue;if(line==="[[mcp]]"){currentMcp={headerLine:lineNo},mcp.push(currentMcp);continue}if(line.startsWith("["))return{ok:!1,kind:"parse-error",error:`Unsupported table header on line ${lineNo}; only [[mcp]] is allowed`};let eq=line.indexOf("=");if(eq===-1)return{ok:!1,kind:"parse-error",error:`Malformed line ${lineNo}; expected key = "value"`};let key=line.slice(0,eq).trim(),rawValue=line.slice(eq+1).trim();if(key.length===0)return{ok:!1,kind:"parse-error",error:`Malformed line ${lineNo}; missing key`};if(currentMcp===null){if(key==="repo_name"){if(sawRepoName)return{ok:!1,kind:"parse-error",error:`Duplicate repo_name on line ${lineNo}`};sawRepoName=!0;let stringValue=parseQuotedString(rawValue);if(stringValue===null)return{ok:!1,kind:"parse-error",error:`Expected a double-quoted string for '${key}' on line ${lineNo}`};let validated=validateRepoName(stringValue);if(!validated.ok)return{ok:!1,kind:"validation-error",error:validated.error};repoName=validated.value;continue}return key==="target"?{ok:!1,kind:"parse-error",error:`target on line ${lineNo} must appear inside an [[mcp]] section`}:{ok:!1,kind:"parse-error",error:`Unsupported key '${key}' on line ${lineNo}`}}if(key==="args"){if(currentMcp.args!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate args on line ${lineNo}`};let arr=parseStringArray(rawValue);if(arr===null)return{ok:!1,kind:"parse-error",error:`Expected a string array for 'args' on line ${lineNo}`};currentMcp.args=arr;continue}if(key==="target"||key==="command"||key==="secret_bundle"){let stringValue=parseQuotedString(rawValue);if(stringValue===null)return{ok:!1,kind:"parse-error",error:`Expected a double-quoted string for '${key}' on line ${lineNo}`};if(key==="target"){if(currentMcp.target!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate target on line ${lineNo}`};let validated=validateMcpTarget(stringValue);if(!validated.ok)return{ok:!1,kind:"validation-error",error:validated.error};currentMcp.target=validated.value;continue}if(key==="command"){if(currentMcp.command!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate command on line ${lineNo}`};currentMcp.command=stringValue;continue}if(currentMcp.secretBundle!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate secret_bundle on line ${lineNo}`};currentMcp.secretBundle=stringValue;continue}return{ok:!1,kind:"parse-error",error:`Unsupported key '${key}' inside [[mcp]] on line ${lineNo}`}}if(!sawRepoName||repoName===void 0)return{ok:!1,kind:"validation-error",error:"Missing required repo_name"};let cleaned=[];for(let entry of mcp){if(entry.target===void 0)return{ok:!1,kind:"validation-error",error:`An [[mcp]] section on line ${entry.headerLine} is missing its target`};if(entry.target!=="bapi"){if(entry.command===void 0||entry.command.trim().length===0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires a non-empty command`};if(entry.args===void 0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires an args array`};if(entry.secretBundle===void 0||entry.secretBundle.trim().length===0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires a non-empty secret_bundle`}}let clean={target:entry.target};entry.command!==void 0&&(clean.command=entry.command),entry.args!==void 0&&(clean.args=entry.args),entry.secretBundle!==void 0&&(clean.secretBundle=entry.secretBundle),cleaned.push(clean)}return{ok:!0,manifest:{repoName,mcp:cleaned}}}function bridgeConfigPath(projectRoot){return path7.join(projectRoot,".bridge","config")}async function readBridgeConfig(projectRoot,deps){let filePath=bridgeConfigPath(projectRoot),raw;try{raw=await deps.readFile(filePath)}catch(err){return err&&typeof err=="object"&&err.code==="ENOENT"?{ok:!1,kind:"missing"}:{ok:!1,kind:"parse-error",error:"Unable to read .bridge/config"}}return parseBridgeConfigToml(raw)}var init_bridge_config=__esm({"src/bridge-config.ts"(){"use strict"}});async function resolveStartTicketsRepoName(deps){let fromEnv=deps.env.BAPI_REPO_NAME;if(typeof fromEnv=="string"&&fromEnv.trim().length>0)return fromEnv.trim();try{let result=await readBridgeConfig(deps.cwd,{readFile:deps.readFile});if(result.ok&&result.manifest.repoName)return result.manifest.repoName}catch{}return null}var init_start_tickets_repo=__esm({"src/start-tickets-repo.ts"(){"use strict";init_bridge_config()}});var bridge_api_client_exports={};__export(bridge_api_client_exports,{CONDUCTOR_DEFAULT_BASE_URL:()=>CONDUCTOR_DEFAULT_BASE_URL,CONDUCTOR_FETCH_TIMEOUT_MS:()=>CONDUCTOR_FETCH_TIMEOUT_MS,CONDUCTOR_REVIEW_ALIGNMENT_STATUSES:()=>CONDUCTOR_REVIEW_ALIGNMENT_STATUSES,ConductorBridgeApiError:()=>ConductorBridgeApiError,advanceEpicTicketStatus:()=>advanceEpicTicketStatus,approveEpicPlan:()=>approveEpicPlan,bootstrapConductorSupervisorDefaults:()=>bootstrapConductorSupervisorDefaults,buildConductorJiraUrl:()=>buildConductorJiraUrl,buildConductorVcsUrl:()=>buildConductorVcsUrl,buildEpicDispatchKey:()=>buildEpicDispatchKey,claimEpicSupervisionLease:()=>claimEpicSupervisionLease,createEpicRun:()=>createEpicRun,createEpicRunWithDisposition:()=>createEpicRunWithDisposition,createEpicTicketStatus:()=>createEpicTicketStatus,deletePullRequestBranch:()=>deletePullRequestBranch,extractSanitizedErrorDiagnostics:()=>extractSanitizedErrorDiagnostics,fetchActiveEpicRuns:()=>fetchActiveEpicRuns,fetchConductorConfigField:()=>fetchConductorConfigField,fetchConductorJsonPatchWithTimeout:()=>fetchConductorJsonPatchWithTimeout,fetchConductorJsonPostWithTimeout:()=>fetchConductorJsonPostWithTimeout,fetchConductorJsonPutWithTimeout:()=>fetchConductorJsonPutWithTimeout,fetchConductorJsonWithTimeout:()=>fetchConductorJsonWithTimeout,fetchConductorReadiness:()=>fetchConductorReadiness,fetchEffectiveSupervisorConfig:()=>fetchEffectiveSupervisorConfig,fetchEffectiveSupervisorSetup:()=>fetchEffectiveSupervisorSetup,fetchEpicRunState:()=>fetchEpicRunState,fetchParseStatus:()=>fetchParseStatus,fetchPrReviewStatus:()=>fetchPrReviewStatus,fetchShadowDispatchFreshness:()=>fetchShadowDispatchFreshness,getEpicPlan:()=>getEpicPlan,mergePullRequestForGate:()=>mergePullRequestForGate,parseConductorReadinessResponse:()=>parseConductorReadinessResponse,parseConductorSupervisorBootstrapResponse:()=>parseConductorSupervisorBootstrapResponse,pollCiChecksForCommit:()=>pollCiChecksForCommit,reconcileShadowMerge:()=>reconcileShadowMerge,recordEpicDispatch:()=>recordEpicDispatch,remediateEpicTicket:()=>remediateEpicTicket,replaceEpicRunPolicy:()=>replaceEpicRunPolicy,resolveConductorBridgeApiAccess:()=>resolveConductorBridgeApiAccess,safeDiagnosticMessage:()=>safeDiagnosticMessage,storeEpicPlan:()=>storeEpicPlan,transitionEpicDispatch:()=>transitionEpicDispatch,transitionJiraStatus:()=>transitionJiraStatus,triggerRepositoryParse:()=>triggerRepositoryParse,updateApprovedPlanNodeTicketSpec:()=>updateApprovedPlanNodeTicketSpec,updateEpicRunStatus:()=>updateEpicRunStatus,validateEpicPlan:()=>validateEpicPlan});import os4 from"node:os";import{readFile,stat}from"node:fs/promises";async function resolveConductorBridgeApiAccess(deps={}){let env=deps.env??process.env,cwd=deps.cwd??process.cwd(),homedir=deps.homedir??os4.homedir,platform=deps.platform??process.platform,readFileImpl=deps.readFile??(p=>readFile(p,"utf-8")),statImpl=deps.stat??(p=>stat(p)),repoName=deps.repoName?.trim()||await resolveStartTicketsRepoName({env,cwd,readFile:readFileImpl});if(!repoName)return{ok:!1,kind:"repo-missing",error:"could not resolve repo name (set BAPI_REPO_NAME or add a valid .bridge/config)"};let credResult;try{credResult=await resolveBapiCredentials(repoName,{env,homedir,platform,readFile:readFileImpl,stat:statImpl})}catch{return{ok:!1,kind:"credentials-unavailable",error:"failed to resolve Bridge API credentials"}}if(!credResult.ok)return{ok:!1,kind:"credentials-unavailable",error:"Bridge API credentials unavailable"};let baseUrlRaw=env.BAPI_BASE_URL,baseUrl=typeof baseUrlRaw=="string"&&baseUrlRaw.trim().length>0?baseUrlRaw.trim():CONDUCTOR_DEFAULT_BASE_URL;return{ok:!0,access:{repoName,apiKey:credResult.credentials.apiKey,baseUrl}}}function buildConductorJiraUrl(baseUrl,apiPath,params={}){let trimmed=baseUrl.replace(/\/+$/,""),url=new URL(`${trimmed}/jira${apiPath}`);for(let[k,v]of Object.entries(params))url.searchParams.set(k,v);return url.toString()}function redactErrorPreview(text){return text.replace(/sk-[A-Za-z0-9_-]{8,}/g,"[REDACTED]").replace(/(Bearer|X-API-Key|api[_-]?key)\b\s*[:=]?\s*\S+/gi,"$1 [REDACTED]").replace(/(webhook[_-]?url)\b["']?\s*[:=]?\s*["']?https?:\/\/\S+/gi,"$1 [REDACTED]").replace(/https?:\/\/[^\s/@]+:[^\s/@]+@\S+/gi,"[REDACTED]")}function stripWebhookUrlsDeep(value,depth=0){if(depth>12)return;if(Array.isArray(value))return value.map(item=>stripWebhookUrlsDeep(item,depth+1));if(!value||typeof value!="object")return value;let out={};for(let[key,item]of Object.entries(value))key!=="webhook_url"&&(out[key]=stripWebhookUrlsDeep(item,depth+1));return out}function boundedErrorPreview(text){let redacted=redactErrorPreview(text).replace(/\s+/g," ").trim();return redacted.length>CONDUCTOR_ERROR_PREVIEW_MAX?`${redacted.slice(0,CONDUCTOR_ERROR_PREVIEW_MAX)}\u2026`:redacted}function formatValidationDetailItem(item){if(!item||typeof item!="object")return;let record=item,msg=record.msg;if(typeof msg!="string"||!msg.trim())return;let loc=record.loc,parts=Array.isArray(loc)?loc.filter(part=>typeof part=="string"||typeof part=="number"):[],path8=(parts[0]==="body"?parts.slice(1):parts).slice(0,CONDUCTOR_VALIDATION_LOC_MAX_PARTS).join(".");return path8?`${path8}: ${msg}`:msg}function extractSanitizedErrorDiagnostics(body){if(typeof body=="string"){let trimmed=body.trim();return trimmed?{bodyPreview:boundedErrorPreview(trimmed)}:{}}if(!body||typeof body!="object")return{};let record=body,detail=record.detail,errorCode,message;if(Array.isArray(detail))message=formatValidationDetailItem(detail[0]);else if(detail&&typeof detail=="object"){let d=detail;typeof d.error_code=="string"&&(errorCode=d.error_code),typeof d.message=="string"&&(message=d.message)}else typeof detail=="string"&&(message=detail);!errorCode&&typeof record.error_code=="string"&&(errorCode=record.error_code),!message&&typeof record.message=="string"&&(message=record.message);let diagnostics={};return errorCode&&(diagnostics.errorCode=boundedErrorPreview(errorCode)),message&&(diagnostics.bodyPreview=boundedErrorPreview(message)),diagnostics}function redactDiagnosticValues(diagnostics,secrets){let scrub=text=>{let out2=text;for(let secret of secrets)secret&&secret.length>=4&&(out2=out2.split(secret).join("[REDACTED]"));return out2},out={};return diagnostics.errorCode&&(out.errorCode=scrub(diagnostics.errorCode)),diagnostics.bodyPreview&&(out.bodyPreview=scrub(diagnostics.bodyPreview)),out}async function readSanitizedErrorDiagnostics(resp,headers={}){try{let diagnostics=extractSanitizedErrorDiagnostics(stripWebhookUrlsDeep(await resp.json())),secrets=Object.entries(headers).filter(([k])=>/key|authorization|token/i.test(k)).map(([,v])=>v);return redactDiagnosticValues(diagnostics,secrets)}catch{return{}}}function safeDiagnosticMessage(err,fallback){if(err instanceof ConductorBridgeApiError){let parts=[`kind=${err.kind}`];return typeof err.status=="number"&&parts.push(`status=${err.status}`),err.errorCode&&parts.push(`code=${err.errorCode}`),err.bodyPreview&&parts.push(err.bodyPreview),parts.join(" ")}return err instanceof Error?err.constructor.name:fallback}function conductorGetHeaders(access){return{"X-API-Key":access.apiKey}}async function fetchConductorJsonWithTimeout(url,headers,timeoutMs,fetchImpl=globalThis.fetch){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),timeoutMs);try{let resp;try{resp=await fetchImpl(url,{headers,signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(!resp.ok){let diagnostics=await readSanitizedErrorDiagnostics(resp,headers);throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status,diagnostics):resp.status>=500?new ConductorBridgeApiError("server",resp.status,diagnostics):new ConductorBridgeApiError("http",resp.status,diagnostics)}try{return await resp.json()}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function fetchConductorConfigField(access,fieldName,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`/config-field/${encodeURIComponent(fieldName)}`,{repo_name:access.repoName}),body=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);if(body&&typeof body=="object"&&"value"in body)return body.value}async function fetchEffectiveSupervisorSetup(access,epicKey,fetchImpl=globalThis.fetch){let apiPath=epicKey?`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}/supervisor-setup/`:`${EPIC_RUNS_API_PREFIX}/supervisor-setup/defaults/`,url=buildConductorJiraUrl(access.baseUrl,apiPath,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchEffectiveSupervisorConfig(access,epicKey,fetchImpl=globalThis.fetch){let apiPath=epicKey?`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}/supervisor-config/`:`${EPIC_RUNS_API_PREFIX}/supervisor-config/defaults/`,url=buildConductorJiraUrl(access.baseUrl,apiPath,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function pollCiChecksForCommit(access,commitRef,fetchImpl=globalThis.fetch){let sha=normalizeSha(commitRef);if(sha===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorJiraUrl(access.baseUrl,"/poll-ci-checks",{repo_name:access.repoName,commit_ref:sha});return fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchPrReviewStatus(access,prNumber,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(prNumber);if(pr===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/reviews/status`),fullUrl=new URL(url);return fullUrl.searchParams.set("repo_name",access.repoName),fetchConductorJsonWithTimeout(fullUrl.toString(),conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function buildConductorVcsUrl(baseUrl,apiPath){let trimmed=baseUrl.replace(/\/+$/,""),path8=apiPath.startsWith("/")?apiPath:`/${apiPath}`;return new URL(`${trimmed}${path8}`).toString()}function conductorPostHeaders(access){return{"X-API-Key":access.apiKey,"Content-Type":"application/json"}}async function fetchConductorJsonWithMethodAndTimeout(method,url,headers,body,timeoutMs,fetchImpl){let{body:parsed}=await fetchConductorJsonWithMethodStatusAndTimeout(method,url,headers,body,timeoutMs,fetchImpl);return parsed}async function fetchConductorJsonWithMethodStatusAndTimeout(method,url,headers,body,timeoutMs,fetchImpl){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),timeoutMs);try{let resp;try{resp=await fetchImpl(url,{method,headers,body,signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(!resp.ok){let diagnostics=await readSanitizedErrorDiagnostics(resp,headers);throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status,diagnostics):resp.status>=500?new ConductorBridgeApiError("server",resp.status,diagnostics):new ConductorBridgeApiError("http",resp.status,diagnostics)}try{return{status:resp.status,body:await resp.json()}}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function fetchConductorJsonPostWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("POST",url,headers,body,timeoutMs,fetchImpl)}async function fetchConductorJsonPatchWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("PATCH",url,headers,body,timeoutMs,fetchImpl)}async function fetchConductorJsonPutWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("PUT",url,headers,body,timeoutMs,fetchImpl)}async function mergePullRequestForGate(access,request,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(request.pr_number),sha=normalizeSha(request.expected_head_sha);if(pr===null||sha===null||!request.action_key||!request.repo_name)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/merge`),body=JSON.stringify({repo_name:request.repo_name,expected_head_sha:sha,gate:request.gate,action_key:request.action_key,...request.gate_event?{gate_event:request.gate_event}:{}});return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function remediateEpicTicket(access,request,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(request.pr_number);if(pr===null||!request.epic_run_id||!request.ticket_key||!request.head_sha||!request.idempotency_key)throw new ConductorBridgeApiError("invalid-input");if(requireNonNegativeSafeInteger(request.expected_row_version),request.attempt_kind!=="nudge"&&request.attempt_kind!=="redispatch")throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/remediate`),body=JSON.stringify({repo_name:access.repoName,epic_run_id:request.epic_run_id,ticket_key:request.ticket_key,expected_row_version:request.expected_row_version,head_sha:request.head_sha,idempotency_key:request.idempotency_key,attempt_kind:request.attempt_kind,...request.reason?{reason:request.reason}:{}});try{return{ok:!0,conflict:!1,response:await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}}catch(err){if(err instanceof ConductorBridgeApiError&&err.kind==="http"&&err.status===409)return{ok:!0,conflict:!0};throw err}}function requireNonEmptyString(value){if(typeof value!="string"||value.trim().length===0)throw new ConductorBridgeApiError("invalid-input")}function requirePositiveSafeInteger(value){if(typeof value!="number"||!Number.isSafeInteger(value)||value<=0)throw new ConductorBridgeApiError("invalid-input")}function requireNonNegativeSafeInteger(value){if(typeof value!="number"||!Number.isSafeInteger(value)||value<0)throw new ConductorBridgeApiError("invalid-input")}function requireNoSlashPathSegment(value){if(value.includes("/"))throw new ConductorBridgeApiError("invalid-input")}function requireEpicTicketStatusValue(value){if(typeof value!="string"||!EPIC_TICKET_STATUS_VALUES.includes(value))throw new ConductorBridgeApiError("invalid-input")}function requireEpicDispatchTransitionStatus(value){if(typeof value!="string"||!EPIC_DISPATCH_TRANSITION_STATUSES.includes(value))throw new ConductorBridgeApiError("invalid-input")}function epicRunApiPath(epicKey){return`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}`}function epicDispatchTransitionApiPath(dispatchKey,nextStatus){return nextStatus==="run_spawned"?`/epic-runs/dispatch/${encodeURIComponent(dispatchKey)}/run-spawned`:`/epic-runs/dispatch/${encodeURIComponent(dispatchKey)}/terminal`}function buildEpicDispatchKey(epicKey,ticketKey,planVersion,attempt=0){requireNonEmptyString(epicKey),requireNonEmptyString(ticketKey),requireNonNegativeSafeInteger(planVersion),requireNonNegativeSafeInteger(attempt);let base=`dispatch:${epicKey}:${ticketKey}:${planVersion}`;return attempt>0?`${base}:r${attempt}`:base}function parseEpicSupervisionLeaseResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed,row=p.row;if(p.claimed===!0&&row&&typeof row=="object")return{ok:!0,kind:"acquired-or-renewed",row};if(p.claimed===!1&&p.reason==="lease_held"&&row&&typeof row=="object")return{ok:!1,kind:"held-by-other",reason:"lease_held",row};if(p.claimed===!1&&p.reason==="terminal"&&row&&typeof row=="object")return{ok:!1,kind:"terminal",reason:"terminal",row};throw new ConductorBridgeApiError("server")}async function claimEpicSupervisionLease(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.leaseOwner),requirePositiveSafeInteger(request.ttlSeconds);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/lease/claim`),body=JSON.stringify({repo_name:access.repoName,lease_owner:request.leaseOwner,ttl_seconds:request.ttlSeconds}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseEpicSupervisionLeaseResult(parsed)}async function fetchEpicRunState(access,epicKey,fetchImpl=globalThis.fetch){requireNonEmptyString(epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(epicKey)}/state`,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchActiveEpicRuns(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`,{repo_name:access.repoName,status:"active",limit:"20"}),parsed=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);if(parsed&&typeof parsed=="object"){let runs=parsed.runs;if(Array.isArray(runs))return runs}return[]}async function createEpicRun(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let body={repo_name:access.repoName,epic_key:request.epicKey,status:request.status??"planning",current_plan_version:request.currentPlanVersion??0};request.policyJson!==void 0&&(body.policy_json=request.policyJson),request.budgetWallClockSeconds!==void 0&&(body.budget_wall_clock_seconds=request.budgetWallClockSeconds),request.budgetCostCents!==void 0&&(body.budget_cost_cents=request.budgetCostCents);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`);return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function createEpicRunWithDisposition(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let body={repo_name:access.repoName,epic_key:request.epicKey,status:request.status??"planning",current_plan_version:request.currentPlanVersion??0};request.policyJson!==void 0&&(body.policy_json=request.policyJson),request.budgetWallClockSeconds!==void 0&&(body.budget_wall_clock_seconds=request.budgetWallClockSeconds),request.budgetCostCents!==void 0&&(body.budget_cost_cents=request.budgetCostCents);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`),{status,body:parsed}=await fetchConductorJsonWithMethodStatusAndTimeout("POST",url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return{run:parsed,created:status===201}}async function replaceEpicRunPolicy(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicRunId);let url=buildConductorJiraUrl(access.baseUrl,epicRunApiPath(request.epicRunId)),body=JSON.stringify({repo_name:access.repoName,policy_json:request.policyJson});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function updateEpicRunStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let url=buildConductorJiraUrl(access.baseUrl,epicRunApiPath(request.epicKey)),body=JSON.stringify({repo_name:access.repoName,status:request.status,...request.expectedStatus?{expected_status:request.expectedStatus}:{}});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseAdvanceEpicTicketStatusResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed;if(p.ok===!1&&p.kind==="cas-conflict")return{ok:!1,kind:"cas-conflict",...typeof p.current_row_version=="number"?{current_row_version:p.current_row_version}:{},...p.ticket_status&&typeof p.ticket_status=="object"?{ticket_status:p.ticket_status}:{}};if(p.ok===!0&&p.ticket_status&&typeof p.ticket_status=="object")return{ok:!0,ticket_status:p.ticket_status};if("ticket_key"in p&&"status"in p&&"row_version"in p)return{ok:!0,ticket_status:parsed};throw new ConductorBridgeApiError("server")}async function advanceEpicTicketStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonNegativeSafeInteger(request.expectedRowVersion),requireNonNegativeSafeInteger(request.planVersion),requireEpicTicketStatusValue(request.nextStatus),request.dispatchRunId!==void 0&&requireNonEmptyString(request.dispatchRunId);let CAS_ENDPOINT_PATH=`${epicRunApiPath(request.epicKey)}/tickets/${encodeURIComponent(request.ticketKey)}`,url=buildConductorJiraUrl(access.baseUrl,CAS_ENDPOINT_PATH),body=JSON.stringify({repo_name:access.repoName,status:request.nextStatus,plan_version:request.planVersion,expected_row_version:request.expectedRowVersion,...request.dispatchRunId?{dispatch_run_id:request.dispatchRunId}:{}}),parsed=await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseAdvanceEpicTicketStatusResult(parsed)}async function createEpicTicketStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireEpicTicketStatusValue(request.status),requireNonNegativeSafeInteger(request.planVersion),request.dispatchRunId!==void 0&&requireNonEmptyString(request.dispatchRunId);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/tickets`),body=JSON.stringify({repo_name:access.repoName,ticket_key:request.ticketKey,status:request.status,plan_version:request.planVersion,...request.dispatchRunId?{dispatch_run_id:request.dispatchRunId}:{}});await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseEpicDispatchResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed,row=p.row;if(!row||typeof row!="object")throw new ConductorBridgeApiError("server");let dispatch=row;if(p.claimed===!0)return{ok:!0,kind:"claimed",dispatch};if(p.claimed===!1){let reason=p.reason;if(reason==="already_spawned")return{ok:!0,kind:"already-spawned",dispatch};if(reason==="already_exists")return{ok:!0,kind:"already-exists",dispatch};if(reason==="terminal")return{ok:!0,kind:"terminal",terminal:!0,dispatch};if(reason==="lease_held")return{ok:!1,kind:"lease-held",dispatch}}throw new ConductorBridgeApiError("server")}async function recordEpicDispatch(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonEmptyString(request.leaseOwner),requireNonNegativeSafeInteger(request.planVersion),requirePositiveSafeInteger(request.ttlSeconds);let dispatchKey=buildEpicDispatchKey(request.epicKey,request.ticketKey,request.planVersion,request.attempt??0)+(request.reviewRole?":review":""),url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/dispatch/claim`),body=JSON.stringify({repo_name:access.repoName,epic_run_id:request.epicKey,ticket_key:request.ticketKey,plan_version:request.planVersion,lease_owner:request.leaseOwner,ttl_seconds:request.ttlSeconds,dispatch_key:dispatchKey}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseEpicDispatchResult(parsed)}async function transitionEpicDispatch(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.dispatchKey),requireNoSlashPathSegment(request.dispatchKey),requireEpicDispatchTransitionStatus(request.nextStatus),request.nextStatus==="run_spawned"&&requireNonEmptyString(request.runId);let path8=epicDispatchTransitionApiPath(request.dispatchKey,request.nextStatus),url=buildConductorJiraUrl(access.baseUrl,path8),body=request.nextStatus==="run_spawned"?JSON.stringify({repo_name:access.repoName,run_id:request.runId}):JSON.stringify({repo_name:access.repoName});return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseShadowMergeReconcileResult(parsed){let obj=parsed??{};return{applies:obj.applies===!0,scheduled:obj.scheduled===!0,reasonCode:typeof obj.reason_code=="string"?obj.reason_code:"unknown",shadowRepoName:typeof obj.shadow_repo_name=="string"?obj.shadow_repo_name:null,requiredCommitSha:typeof obj.required_commit_sha=="string"?obj.required_commit_sha:null,lifecycleState:typeof obj.lifecycle_state=="string"?obj.lifecycle_state:null}}function parseShadowDispatchFreshnessResult(parsed){let obj=parsed??{},rawVerdict=typeof obj.verdict=="string"?obj.verdict:"",verdict=SHADOW_FRESHNESS_VERDICTS.has(rawVerdict)?rawVerdict:"stale";return{verdict,reasonCode:typeof obj.reason_code=="string"?obj.reason_code:verdict,lifecycleState:typeof obj.lifecycle_state=="string"?obj.lifecycle_state:null,indexedCommitSha:typeof obj.indexed_commit_sha=="string"?obj.indexed_commit_sha:null,shadowRepoName:typeof obj.shadow_repo_name=="string"?obj.shadow_repo_name:null,lastError:typeof obj.last_error=="string"?obj.last_error:null}}async function reconcileShadowMerge(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/shadow/merge-reconcile`),body=JSON.stringify({repo_name:access.repoName,merged_ticket_key:request.mergedTicketKey??null}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseShadowMergeReconcileResult(parsed)}async function fetchShadowDispatchFreshness(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNoSlashPathSegment(request.ticketKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/tickets/${encodeURIComponent(request.ticketKey)}/shadow-freshness`),body=JSON.stringify({repo_name:access.repoName}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseShadowDispatchFreshnessResult(parsed)}async function validateEpicPlan(access,request,fetchImpl=globalThis.fetch){requirePositiveSafeInteger(request.planVersion);let blobVersion=request.planBlob.plan_version;if(blobVersion!==void 0&&blobVersion!==request.planVersion)throw new ConductorValidationError(`planVersion mismatch: request.planVersion=${request.planVersion} but planBlob.plan_version=${blobVersion}`);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/plan/validate`),body={repo_name:access.repoName,plan_version:request.planVersion,plan_blob:request.planBlob};request.epicKey!==void 0&&(body.epic_key=request.epicKey);let parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseValidateEpicPlanResult(parsed)}function parseValidateEpicPlanResult(parsed){if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new ConductorBridgeApiError("server");let p=parsed,planHash=p.plan_hash,serializationEnabled=p.serialization_enabled,insertedEdges=p.inserted_edges;if(p.valid!==!0||typeof planHash!="string"||planHash.trim()===""||typeof serializationEnabled!="boolean"||typeof insertedEdges!="number"||!Number.isSafeInteger(insertedEdges)||insertedEdges<0)throw new ConductorBridgeApiError("server");return{planHash,serializationEnabled,insertedEdges}}async function storeEpicPlan(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requirePositiveSafeInteger(request.planVersion),requireNonEmptyString(request.planHash);let blobVersion=request.planBlob.plan_version;if(blobVersion!==void 0&&blobVersion!==request.planVersion)throw new ConductorValidationError(`planVersion mismatch: request.planVersion=${request.planVersion} but planBlob.plan_version=${blobVersion}`);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/plan`),body=JSON.stringify({repo_name:access.repoName,plan_version:request.planVersion,plan_blob:request.planBlob,plan_hash:request.planHash});return fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function updateApprovedPlanNodeTicketSpec(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonEmptyString(request.expectedPlanHash),requireNonEmptyString(request.ticketSpec);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/plan/nodes/${encodeURIComponent(request.ticketKey)}/ticket-spec`),body=JSON.stringify({repo_name:access.repoName,expected_plan_hash:request.expectedPlanHash,ticket_spec:request.ticketSpec});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseApproveEpicPlanSuccess(parsed){let record=parsed??{},result={ok:!0,plan_hash:record.plan_hash},prov=record.feature_branch_provisioning;if(prov&&typeof prov=="object"&&!Array.isArray(prov)){let p=prov;(p.status==="created"||p.status==="already_exists")&&typeof p.feature_branch=="string"&&typeof p.source_branch=="string"&&typeof p.source_sha=="string"&&typeof p.remote_head_sha=="string"&&(result.featureBranchProvisioning={status:p.status,feature_branch:p.feature_branch,source_branch:p.source_branch,source_sha:p.source_sha,remote_head_sha:p.remote_head_sha})}return result}async function approveEpicPlan(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requirePositiveSafeInteger(request.planVersion);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/approve-plan`),body=JSON.stringify({repo_name:access.repoName,plan_version:request.planVersion});try{let parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseApproveEpicPlanSuccess(parsed)}catch(error){if(error instanceof ConductorBridgeApiError&&error.status===409){let preview=error.bodyPreview??"";return/multiple active runs/i.test(preview)?{ok:!1,kind:"conflict",reason:"multiple_active_runs"}:{ok:!1,kind:"conflict",reason:"superseded"}}throw error}}async function getEpicPlan(access,epicKey,planVersion,fetchImpl=globalThis.fetch){requireNonEmptyString(epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(epicKey)}/plan`,{repo_name:access.repoName,plan_version:String(planVersion)});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchParseStatus(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,"/parse-status",{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function triggerRepositoryParse(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,"/parse-repository"),body=JSON.stringify({repo_name:access.repoName});return fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function deletePullRequestBranch(access,prNumber,expectedHeadSha,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(prNumber);if(pr===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/branch?repo_name=${encodeURIComponent(access.repoName)}&expected_head_sha=${encodeURIComponent(expectedHeadSha)}`),controller=new AbortController,timer=setTimeout(()=>controller.abort(),CONDUCTOR_FETCH_TIMEOUT_MS);try{let resp;try{resp=await fetchImpl(url,{method:"DELETE",headers:{"X-API-Key":access.apiKey},body:"",signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(resp.status===404)return{deleted:!1,branch:null,reason:"not_found"};if(!resp.ok)throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status):resp.status>=500?new ConductorBridgeApiError("server",resp.status):new ConductorBridgeApiError("http",resp.status);try{return await resp.json()}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function transitionJiraStatus(access,ticketNumber,targetStatus="auto",fetchImpl=globalThis.fetch){if(!ticketNumber)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorJiraUrl(access.baseUrl,`/tickets/${encodeURIComponent(ticketNumber)}/jira-status`),body=JSON.stringify({repo_name:access.repoName,target_status:targetStatus});try{return await fetchConductorJsonPutWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl),{status:"transitioned"}}catch(err){if(err instanceof ConductorBridgeApiError&&err.kind==="http"&&err.status===400)return{status:"skipped"};throw err}}function readinessShapeError(){return new ConductorBridgeApiError("invalid-input",void 0,{errorCode:"READINESS_SHAPE_INVALID"})}function requireObject(value){if(typeof value!="object"||value===null||Array.isArray(value))throw readinessShapeError();return value}function requireBool(o,key){let v=o[key];if(typeof v!="boolean")throw readinessShapeError();return v}function requireInt(o,key){let v=o[key];if(typeof v!="number"||!Number.isInteger(v))throw readinessShapeError();return v}function requireNullableInt(o,key){let v=o[key];if(v==null)return null;if(typeof v!="number"||!Number.isInteger(v))throw readinessShapeError();return v}function requireNullableString(o,key){let v=o[key];if(v==null)return null;if(typeof v!="string")throw readinessShapeError();return v}function requireNullableBool(o,key){let v=o[key];if(v==null)return null;if(typeof v!="boolean")throw readinessShapeError();return v}function parseReviewPolicyAlignment(o){let raw=o.review_policy_alignment;if(raw==null)return null;let a=requireObject(raw),explanation=a.explanation;if(typeof explanation!="string")throw readinessShapeError();return{status:requireEnum(a,"status",CONDUCTOR_REVIEW_ALIGNMENT_STATUSES),repo_review_signal:requireNullableString(a,"repo_review_signal"),done_gate_review_signal:requireNullableString(a,"done_gate_review_signal"),explanation}}function requireEnum(o,key,allowed){let v=o[key];if(typeof v!="string"||!allowed.has(v))throw readinessShapeError();return v}function parseConductorReadinessResponse(body){let root=requireObject(body),repoName=root.repo_name;if(typeof repoName!="string"||repoName.length===0)throw readinessShapeError();let sup=requireObject(root.supervisor),gh=requireObject(root.github),rec=requireObject(root.reconciler),exec=requireObject(root.executor),thr=requireObject(root.thresholds);return{repo_name:repoName,supervisor:{setup_present:requireBool(sup,"setup_present"),setup_source:requireEnum(sup,"setup_source",READINESS_SOURCES),setup_created_at:requireNullableString(sup,"setup_created_at"),setup_updated_at:requireNullableString(sup,"setup_updated_at"),config_present:requireBool(sup,"config_present"),config_source:requireEnum(sup,"config_source",READINESS_SOURCES),config_created_at:requireNullableString(sup,"config_created_at"),config_updated_at:requireNullableString(sup,"config_updated_at"),required_checks_count:requireInt(sup,"required_checks_count"),required_checks_empty:requireBool(sup,"required_checks_empty"),auto_merge_enabled:requireBool(sup,"auto_merge_enabled"),merge_approval_required_set:requireBool(sup,"merge_approval_required_set"),review_policy_alignment:parseReviewPolicyAlignment(sup),review_policy_present:sup.review_policy_present===!0},github:{credentials_readable:requireBool(gh,"credentials_readable"),owner_resolved:requireBool(gh,"owner_resolved"),repo_id_resolved:requireBool(gh,"repo_id_resolved"),installation_id_resolved:requireBool(gh,"installation_id_resolved"),credentials_complete:requireBool(gh,"credentials_complete"),actions_probe_succeeded:requireBool(gh,"actions_probe_succeeded"),actions_permission_present:requireBool(gh,"actions_permission_present"),actions_permission_level:requireEnum(gh,"actions_permission_level",ACTIONS_LEVELS),actions_write:requireBool(gh,"actions_write")},reconciler:{liveness_readable:requireBool(rec,"liveness_readable"),last_tick_at:requireNullableString(rec,"last_tick_at"),last_tick_age_seconds:requireNullableInt(rec,"last_tick_age_seconds"),stale:requireBool(rec,"stale"),active_run_count:requireInt(rec,"active_run_count"),expired_lease_count:requireInt(rec,"expired_lease_count")},executor:{liveness_readable:requireBool(exec,"liveness_readable"),last_seen_at:requireNullableString(exec,"last_seen_at"),last_seen_age_seconds:requireNullableInt(exec,"last_seen_age_seconds"),ready:requireNullableBool(exec,"ready")},thresholds:{reconciler_stale_after_seconds:requireInt(thr,"reconciler_stale_after_seconds"),executor_stale_after_seconds:requireInt(thr,"executor_stale_after_seconds")}}}async function fetchConductorReadiness(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/conductor-readiness`,{repo_name:access.repoName}),body=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseConductorReadinessResponse(body)}function parseConductorSupervisorBootstrapResponse(body){let o=requireObject(body),repoName=o.repo_name;if(typeof repoName!="string"||repoName.length===0)throw readinessShapeError();let names=o.audited_field_names;if(!Array.isArray(names)||names.some(n=>typeof n!="string"))throw readinessShapeError();return{repo_name:repoName,setup_written:requireBool(o,"setup_written"),config_written:requireBool(o,"config_written"),setup_source:requireEnum(o,"setup_source",READINESS_SOURCES),config_source:requireEnum(o,"config_source",READINESS_SOURCES),setup_created_at:requireNullableString(o,"setup_created_at"),setup_updated_at:requireNullableString(o,"setup_updated_at"),config_created_at:requireNullableString(o,"config_created_at"),config_updated_at:requireNullableString(o,"config_updated_at"),required_checks_count:requireInt(o,"required_checks_count"),audited_field_names:names}}async function bootstrapConductorSupervisorDefaults(access,request,fetchImpl){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/supervisor-bootstrap`,{repo_name:access.repoName}),body=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(request),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseConductorSupervisorBootstrapResponse(body)}var CONDUCTOR_DEFAULT_BASE_URL,CONDUCTOR_FETCH_TIMEOUT_MS,CONDUCTOR_BRIDGE_API_ERROR_KINDS,CONDUCTOR_ERROR_PREVIEW_MAX,CONDUCTOR_VALIDATION_LOC_MAX_PARTS,ConductorBridgeApiError,EPIC_TICKET_STATUS_VALUES,EPIC_DISPATCH_TRANSITION_STATUSES,EPIC_RUNS_API_PREFIX,SHADOW_FRESHNESS_VERDICTS,CONDUCTOR_REVIEW_ALIGNMENT_STATUSES,READINESS_SOURCES,ACTIONS_LEVELS,init_bridge_api_client=__esm({"src/conductor/bridge-api-client.ts"(){"use strict";init_credential_store();init_start_tickets_repo();init_git_ci_types();init_errors();CONDUCTOR_DEFAULT_BASE_URL="https://bridgegpt-api.com",CONDUCTOR_FETCH_TIMEOUT_MS=3e4;CONDUCTOR_BRIDGE_API_ERROR_KINDS=["invalid-input","network","timeout","unauthorized","server","http"],CONDUCTOR_ERROR_PREVIEW_MAX=200;CONDUCTOR_VALIDATION_LOC_MAX_PARTS=8;ConductorBridgeApiError=class extends Error{kind;status;errorCode;bodyPreview;constructor(kindOrMessage,status,diagnostics){let isKnownKind=CONDUCTOR_BRIDGE_API_ERROR_KINDS.includes(kindOrMessage),errorCode=diagnostics?.errorCode,bodyPreview=diagnostics?.bodyPreview;if(isKnownKind){let parts=[`Conductor Bridge API request failed (${kindOrMessage}${typeof status=="number"?`, status ${status}`:""})`];errorCode&&parts.push(`code=${errorCode}`),bodyPreview&&parts.push(bodyPreview),super(parts.join(": "))}else super(kindOrMessage);this.name="ConductorBridgeApiError",this.kind=isKnownKind?kindOrMessage:"http",typeof status=="number"&&(this.status=status),errorCode&&(this.errorCode=errorCode),bodyPreview&&(this.bodyPreview=bodyPreview)}};EPIC_TICKET_STATUS_VALUES=["planned","ready","dispatched","running","blocked","abandoned","done","ready_for_review","reviewing","parse_pending"];EPIC_DISPATCH_TRANSITION_STATUSES=["run_spawned","terminal"];EPIC_RUNS_API_PREFIX="/epic-runs";SHADOW_FRESHNESS_VERDICTS=new Set(["not_applicable","covered","stale","failed"]);CONDUCTOR_REVIEW_ALIGNMENT_STATUSES=new Set(["aligned","divergent","not_configured","invalid"]),READINESS_SOURCES=new Set(["epic","project_default","none"]),ACTIONS_LEVELS=new Set(["write","read","none","unknown"])}});import{createHash as createHash4}from"node:crypto";function normalizeDimension(value){return(value??"").trim().toLowerCase()}function makeSupervisorIdempotencyKey(meta){return[normalizeDimension(meta.run_id),normalizeDimension(meta.worker_id)||"(run)",normalizeDimension(meta.reason),normalizeDimension(meta.kind),normalizeDimension(meta.cooldown_window)].join("|")}function makeSupervisorAssessmentEventId(idempotencyKey){let h=createHash4("sha256").update(`supervisor.assessment:${idempotencyKey}`).digest("hex");return`${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20,32)}`}function isDuplicateConstraintError3(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&code.startsWith("SQLITE_CONSTRAINT"))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("unique constraint")||lowered.includes("constraint failed"))return!0}return!1}async function emitSupervisorAssessmentIfNew(input,deps={}){let emitEvent=deps.emitEvent??emitConductorEvent,idempotencyKey=makeSupervisorIdempotencyKey(input.idempotency),eventId=makeSupervisorAssessmentEventId(idempotencyKey),details={...input.details??{},idempotency_key:idempotencyKey,reason:input.idempotency.reason,kind:input.idempotency.kind,cooldown_window:input.idempotency.cooldown_window,classification:input.assessment.classification,confidence:input.assessment.confidence},event={id:eventId,source:"conductor-supervisor",type:"supervisor.assessment",run_id:input.run_id,worker_id:input.idempotency.worker_id??input.worker_id??null,producer:"conductor-supervisor",observed_via:"supervisor",data:{summary:`supervisor assessment: ${input.idempotency.reason}`,status:"escalated",reason:input.idempotency.reason,details}};try{let result=await emitEvent(event);return{emitted:!0,event_id:eventId,event:result.event}}catch(error){if(isDuplicateConstraintError3(error))return{emitted:!1,reason:"duplicate"};throw error}}var init_supervisor_ledger=__esm({"src/conductor/supervisor-ledger.ts"(){"use strict";init_store()}});function buildSupervisorEscalationWorkerMessage(candidate,assessment,state){let details={reason:candidate.reason,state:candidate.state,liveness:candidate.liveness,elapsed_ms:candidate.elapsed_ms,assessment_source:"deterministic"};return{run_id:state.run_id,worker_id:candidate.worker_id,type:`supervisor.${candidate.reason}`,cause_seq:state.last_seq,payload:{summary:`supervisor escalation: ${candidate.reason}`,status:"escalated",details},source:"conductor-supervisor",producer:"worker-message-relay"}}async function sendSupervisorEscalationWorkerMessageIfNew(candidate,assessment,state,deps={}){let sendMessage=deps.sendMessage??sendWorkerMessage,input=buildSupervisorEscalationWorkerMessage(candidate,assessment,state);return sendMessage(input)}var init_supervisor_message_relay=__esm({"src/conductor/supervisor-message-relay.ts"(){"use strict";init_store()}});function isTerminalState(state){return TERMINAL_STATES.has(state)}function isoToMs(value){if(typeof value!="string"||value.length===0)return null;let ms=Date.parse(value);return Number.isFinite(ms)?ms:null}function msToIso(now){return new Date(now).toISOString()}function createEmptySupervisorRunState(runId,config,now){let startedIso=msToIso(now);return{run_id:runId,status:"unknown",last_seq:0,last_event_time:null,workers:{},gates:{},latest_assessment:null,escalations:[],started_at:startedIso,updated_at:startedIso,global_deadline_at:msToIso(now+config.global_timeout_ms),roster_discovered:!1}}function isValidSupervisorSummary(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&value.kind===SUPERVISOR_SUMMARY_KIND}function hydrateSupervisorRunStateFromSnapshot(snapshot,runId,config,now){let empty=createEmptySupervisorRunState(runId,config,now),summary=snapshot?.projection?.summary;return isValidSupervisorSummary(summary)?{...empty,status:typeof summary.status=="string"?summary.status:empty.status,last_seq:typeof summary.last_seq=="number"&&summary.last_seq>=0?summary.last_seq:empty.last_seq,last_event_time:typeof summary.last_event_time=="string"?summary.last_event_time:null,workers:isPlainRecord(summary.workers)?summary.workers:{},gates:isPlainRecord(summary.gates)?summary.gates:{},latest_assessment:summary.latest_assessment&&typeof summary.latest_assessment=="object"?summary.latest_assessment:null,escalations:Array.isArray(summary.escalations)?summary.escalations:[],started_at:typeof summary.started_at=="string"?summary.started_at:empty.started_at,global_deadline_at:typeof summary.global_deadline_at=="string"?summary.global_deadline_at:empty.global_deadline_at,roster_discovered:summary.roster_discovered===!0,run_id:runId}:empty}function isPlainRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function ensureWorkerState(state,workerId,options={}){let existing=state.workers[workerId];if(existing)return options.ticketKey&&!existing.ticket_key&&(existing.ticket_key=options.ticketKey),existing;let created={worker_id:workerId,ticket_key:options.ticketKey??null,state:options.fromRoster?"not_started":"unknown",liveness:"unknown",first_seen_seq:options.seq??null,last_event_seq:options.seq??null,last_event_time:null,last_progress_time:null,last_heartbeat_time:null,blocked_reason:null,terminal_reason:null,observed_event_types:[]};return state.workers[workerId]=created,created}function noteObservedType(worker,eventType){worker.observed_event_types.includes(eventType)||worker.observed_event_types.push(eventType)}function eventDetails(event){let details=event.data?.details;return isPlainRecord(details)?details:{}}function extractRoster(event){let candidates=[eventDetails(event).workers,event.data?.workers,isPlainRecord(event.data?.raw)?event.data.raw.workers:void 0];for(let candidate of candidates)if(Array.isArray(candidate)){let roster=[];for(let entry of candidate){if(!isPlainRecord(entry))continue;let workerId=entry.worker_id;if(typeof workerId!="string"||workerId.length===0)continue;let ticketKey=entry.ticket_key;roster.push({worker_id:workerId,ticket_key:typeof ticketKey=="string"?ticketKey:null})}if(roster.length>0)return roster}return[]}function eventStatus(event){let status=event.data?.status;return typeof status=="string"?status.trim().toLowerCase():""}function eventReason(event){let reason=event.data?.reason??eventDetails(event).reason;return typeof reason=="string"?reason.trim().toLowerCase():""}function applyConductorEventToSupervisorState(state,event,now){if(event.run_id!==state.run_id)return state;let eventType=event.type,eventTimeMs=isoToMs(event.time)??now,eventTimeIso=event.time??msToIso(now);if(typeof event.seq=="number"&&event.seq>state.last_seq&&(state.last_seq=event.seq),state.last_event_time=eventTimeIso,state.status==="unknown"&&(state.status="active"),eventType==="run.started"){let roster=extractRoster(event);roster.length>0&&(state.roster_discovered=!0);for(let member of roster){let worker2=ensureWorkerState(state,member.worker_id,{fromRoster:!0,ticketKey:member.ticket_key,seq:event.seq});noteObservedType(worker2,eventType),worker2.last_event_seq=event.seq??worker2.last_event_seq,worker2.last_event_time=eventTimeIso}return state.updated_at=msToIso(now),state}if(eventType==="supervisor.assessment"||eventType==="message.sent")return state.updated_at=msToIso(now),state;let workerId=event.worker_id;if(typeof workerId!="string"||workerId.length===0)return applyRunLevelEvent(state,event,eventType),state.updated_at=msToIso(now),state;let worker=ensureWorkerState(state,workerId,{seq:event.seq});switch(noteObservedType(worker,eventType),worker.last_event_seq=event.seq??worker.last_event_seq,worker.last_event_time=eventTimeIso,eventType){case"run.heartbeat":{worker.last_heartbeat_time=eventTimeIso,!isTerminalState(worker.state)&&worker.state!=="blocked"&&(worker.state==="not_started"||worker.state==="unknown")&&(worker.state="active");break}case"agent.notification":{let status=eventStatus(event),reason=eventReason(event);BLOCKED_STATUS_TOKENS.has(status)||BLOCKED_STATUS_TOKENS.has(reason)?isTerminalState(worker.state)||(worker.state="blocked",worker.blocked_reason=status||reason||"blocked"):!isTerminalState(worker.state)&&worker.state==="not_started"&&(worker.state="active");break}case"tool.intent":case"worktree.changed":case"git.commit_created":{PROGRESS_EVENT_TYPES.has(eventType)&&(worker.last_progress_time=eventTimeIso,isTerminalState(worker.state)||((worker.state==="not_started"||worker.state==="unknown"||worker.state==="stalled"||worker.state==="blocked")&&(worker.state="active"),worker.blocked_reason=null));break}case"gate.met":{isTerminalState(worker.state)||(worker.state="candidate_done");break}case"ci.passed":{isTerminalState(worker.state)||(worker.state="verifying"),worker.last_progress_time=eventTimeIso;break}case"ci.failed":{let reason=eventReason(event);eventStatus(event)==="terminal"||reason==="terminal"||reason==="give_up"?(worker.state="failed",worker.terminal_reason=reason||"ci_failed"):isTerminalState(worker.state)||(worker.last_progress_time=eventTimeIso);break}case"run.stopped":{let status=eventStatus(event),reason=eventReason(event);FAILED_STATUS_TOKENS.has(status)||FAILED_STATUS_TOKENS.has(reason)?(worker.state="failed",worker.terminal_reason=reason||status||"failed"):(worker.state="complete",worker.terminal_reason=reason||status||"complete");break}case"message.delivered":case"message.acked":{!isTerminalState(worker.state)&&(worker.state==="not_started"||worker.state==="unknown")&&(worker.state="active");break}case"merge.succeeded":{worker.state="complete",worker.terminal_reason=worker.terminal_reason||"merge_succeeded";break}case"merge.failed":break;case"merge.dry_run":break;case"merge.pending_approval":break;default:break}return state.updated_at=msToIso(now),state}function applyRunLevelEvent(state,event,eventType){switch(eventType){case"gate.met":state.gates.gate_met=!0;break;case"ci.passed":state.gates.ci="passed";break;case"ci.failed":state.gates.ci="failed";break;case"git.pr_opened":state.gates.pr_opened=!0;break;case"merge.succeeded":case"merge.failed":case"merge.dry_run":case"merge.pending_approval":state.gates.merge=eventType.slice(6);break;default:break}}function classifyWorkerLiveness(worker,config,now){if(isTerminalState(worker.state))return"alive";let lastSignalMs=mostRecentSignalMs(worker);if(lastSignalMs===null)return"unknown";let elapsed=now-lastSignalMs;return elapsed>=config.liveness.dead_after_ms?"dead":elapsed>=config.liveness.stalled_after_ms?"stalled":elapsed>=config.liveness.quiet_after_ms?"quiet":"alive"}function mostRecentSignalMs(worker){let candidates=[isoToMs(worker.last_heartbeat_time),isoToMs(worker.last_event_time),isoToMs(worker.last_progress_time)].filter(v=>v!==null);return candidates.length===0?null:Math.max(...candidates)}function stateAnchorMs(worker){return worker.state==="active"||worker.state==="verifying"?mostRecentSignalMs(worker):isoToMs(worker.last_event_time)??isoToMs(worker.last_heartbeat_time)??isoToMs(worker.last_progress_time)}function applySupervisorHousekeeping(state,config,now){for(let worker of Object.values(state.workers)){if(worker.liveness=classifyWorkerLiveness(worker,config,now),isTerminalState(worker.state)||worker.state==="stalled")continue;let threshold=config.stall_thresholds_ms[worker.state],anchor=stateAnchorMs(worker);anchor!==null&&now-anchor>=threshold&&(worker.state="stalled")}return state.updated_at=msToIso(now),state}function isSupervisorRunTerminal(state){let workers=Object.values(state.workers);return workers.length===0||!state.roster_discovered?!1:workers.every(w=>isTerminalState(w.state))}function hasSupervisorGlobalTimeoutElapsed(state,now){let deadlineMs=isoToMs(state.global_deadline_at);return deadlineMs===null?!1:now>=deadlineMs}function compactWorker(worker){return{worker_id:worker.worker_id,ticket_key:worker.ticket_key,state:worker.state,liveness:worker.liveness,last_event_seq:worker.last_event_seq,last_event_time:worker.last_event_time,last_progress_time:worker.last_progress_time,last_heartbeat_time:worker.last_heartbeat_time,blocked_reason:worker.blocked_reason,terminal_reason:worker.terminal_reason}}function toSupervisorProjectionInput(state){let summary={kind:SUPERVISOR_SUMMARY_KIND,run_id:state.run_id,status:state.status,last_seq:state.last_seq,last_event_time:state.last_event_time,workers:state.workers,gates:state.gates,latest_assessment:state.latest_assessment,escalations:state.escalations,started_at:state.started_at,updated_at:state.updated_at,global_deadline_at:state.global_deadline_at,roster_discovered:state.roster_discovered};return{run_id:state.run_id,status:state.status,last_seq:state.last_seq,last_event_time:state.last_event_time,active_workers:Object.values(state.workers).map(compactWorker),gates:state.gates,assessment:state.latest_assessment,summary}}var SUPERVISOR_SUMMARY_KIND,TERMINAL_STATES,PROGRESS_EVENT_TYPES,BLOCKED_STATUS_TOKENS,FAILED_STATUS_TOKENS,init_supervisor_state=__esm({"src/conductor/supervisor-state.ts"(){"use strict";SUPERVISOR_SUMMARY_KIND="supervisor_projection_summary",TERMINAL_STATES=new Set(["complete","failed"]);PROGRESS_EVENT_TYPES=new Set(["tool.intent","worktree.changed","git.commit_created"]),BLOCKED_STATUS_TOKENS=new Set(["blocked","waiting_for_input","needs_input"]),FAILED_STATUS_TOKENS=new Set(["failed","error","errored","aborted","cancelled","canceled"])}});function elapsedSinceSignal(worker,now){let candidates=[worker.last_event_time,worker.last_progress_time,worker.last_heartbeat_time].map(iso=>iso?Date.parse(iso):NaN).filter(v=>Number.isFinite(v));return candidates.length===0?0:Math.max(0,now-Math.max(...candidates))}function findSupervisorEscalationCandidates(state,config,now){let candidates=[];for(let worker of Object.values(state.workers)){if(worker.state==="complete"||worker.state==="failed")continue;let elapsed=elapsedSinceSignal(worker,now),baseContext={worker_id:worker.worker_id,ticket_key:worker.ticket_key,state:worker.state,liveness:worker.liveness};if(worker.liveness==="dead"){candidates.push({reason:"worker_dead",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});continue}switch(worker.state){case"not_started":worker.liveness!=="alive"&&candidates.push({reason:"worker_not_started",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"blocked":candidates.push({reason:"worker_blocked",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:{...baseContext,blocked_reason:worker.blocked_reason}});break;case"stalled":candidates.push({reason:"worker_stalled",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"candidate_done":worker.liveness!=="alive"&&candidates.push({reason:"candidate_done_stuck",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"verifying":worker.liveness==="stalled"&&candidates.push({reason:"verification_stalled",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;default:break}}let deadlineMs=state.global_deadline_at?Date.parse(state.global_deadline_at):NaN;return Number.isFinite(deadlineMs)&&now>=deadlineMs&&candidates.push({reason:"global_timeout",kind:ESCALATION_KIND,worker_id:null,state:null,liveness:null,elapsed_ms:Math.max(0,now-deadlineMs),context:{run_id:state.run_id,deadline_at:state.global_deadline_at,worker_count:Object.keys(state.workers).length}}),candidates}function cooldownWindowFor(now,cooldownMs){let width=cooldownMs>0?cooldownMs:1;return String(Math.floor(now/width))}function shouldEmitEscalation(state,candidate,config,now){let cooldownWindow=cooldownWindowFor(now,config.escalation_cooldown_ms);return{emit:!state.escalations.some(record=>record.reason===candidate.reason&&(record.worker_id??null)===(candidate.worker_id??null)&&record.cooldown_window===cooldownWindow&&(record.outcome==="emitted"||record.outcome==="duplicate")),cooldown_window:cooldownWindow}}function recordEscalationResult(state,candidate,cooldownWindow,idempotencyKey,outcome,now){let record={idempotency_key:idempotencyKey,worker_id:candidate.worker_id??null,reason:candidate.reason,kind:candidate.kind,cooldown_window:cooldownWindow,outcome,recorded_at:new Date(now).toISOString()};return state.escalations.push(record),record}function formatElapsed(ms){let totalSeconds=Math.max(0,Math.floor(ms/1e3)),hours=Math.floor(totalSeconds/3600),minutes=Math.floor(totalSeconds%3600/60),seconds=totalSeconds%60;return hours>0?`${hours}h${minutes}m`:minutes>0?`${minutes}m`:`${seconds}s`}function formatEscalationForTerminal(runId,candidate){let worker=candidate.worker_id?` worker=${candidate.worker_id}`:"",stateBit=candidate.state?` state=${candidate.state}`:"",liveBit=candidate.liveness?` liveness=${candidate.liveness}`:"",elapsed=` elapsed=${formatElapsed(candidate.elapsed_ms)}`;return`[supervisor] run=${runId}${worker} reason=${candidate.reason}${stateBit}${liveBit}${elapsed}`}var ESCALATION_KIND,init_supervisor_escalation=__esm({"src/conductor/supervisor-escalation.ts"(){"use strict";ESCALATION_KIND="escalation"}});function buildGateIdentity(gateName,configHash){let name=gateName.trim(),hash=typeof configHash=="string"?configHash.trim():"";return hash?`${name}@${hash.toLowerCase()}`:name}function makeMergeActionKey(repo,prNumber,headSha,gateIdentity){let r=normalizeRepoName(repo),pr=normalizePrNumber(prNumber),sha=normalizeSha(headSha),gate=(gateIdentity??"").trim();if(r===null||pr===null||sha===null||gate.length===0)throw new Error("invalid merge action key component");return`merge:${r}:${pr}:${sha}:${gate}`}var init_merge_identity=__esm({"src/conductor/merge-identity.ts"(){"use strict";init_git_ci_types()}});function isPlainObject2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function normalizeEventHeadSha(value){if(typeof value!="string")return null;let trimmed=value.trim();return/^[0-9a-f]{7,40}$/i.test(trimmed)?trimmed.toLowerCase():null}function getRawEventDetails(event){let details=event.data?.details;return isPlainObject2(details)?details:null}function parseHeadObservation(event){let details=getRawEventDetails(event);return{head_sha:details?normalizeEventHeadSha(details.head_sha):null}}function parseMergeLifecycle(event){let details=getRawEventDetails(event);return{action_key:details&&typeof details.action_key=="string"&&details.action_key.trim().length>0?details.action_key.trim():null}}function parseGateMet(event){let details=getRawEventDetails(event);if(!details)return{head_sha:null,repo:null,pr_number:null,gate_name:null,config_hash:null,required_checks:[]};let gateName=typeof details.gate_name=="string"&&details.gate_name.trim().length>0?details.gate_name.trim():null,configHash=typeof details.config_hash=="string"&&details.config_hash.trim().length>0?details.config_hash.trim():null,ciCheckStatus=isPlainObject2(details.ci_check_status)?details.ci_check_status:null,requiredChecks=(Array.isArray(details.required_checks)?details.required_checks:ciCheckStatus&&Array.isArray(ciCheckStatus.required_checks)?ciCheckStatus.required_checks:[]).filter(c=>typeof c=="string"&&c.trim().length>0);return{head_sha:normalizeSha(details.head_sha),repo:normalizeRepoName(details.repo),pr_number:normalizePrNumber(details.pr_number),gate_name:gateName,config_hash:configHash,required_checks:requiredChecks}}function parseSpecReview(event){let details=getRawEventDetails(event);return{head_sha:details?normalizeEventHeadSha(details.head_sha):null}}function parseEmpty(){return EMPTY_DETAILS}function getEventDetails(event,expectedType){if(event.type!==expectedType)return null;let parser=EVENT_PARSERS[expectedType];return parser(event)}function getMergeIdentity(event){if(event.type!=="gate.met")return null;let details=getEventDetails(event,"gate.met");if(details===null)return null;let{repo,pr_number:prNumber,head_sha:headSha,gate_name:gateName}=details;if(repo===null||prNumber===null||headSha===null||gateName===null)return null;let gateIdentity=buildGateIdentity(gateName,details.config_hash),actionKey=makeMergeActionKey(repo,prNumber,headSha,gateIdentity);return{repo,pr_number:prNumber,head_sha:headSha,gate_name:gateName,config_hash:details.config_hash,required_checks:details.required_checks,gate_identity:gateIdentity,action_key:actionKey,gate_event:{id:typeof event.id=="string"?event.id:void 0,seq:typeof event.seq=="number"?event.seq:void 0,time:typeof event.time=="string"?event.time:void 0}}}var EMPTY_DETAILS,EVENT_PARSERS,init_event_accessors=__esm({"src/conductor/event-accessors.ts"(){"use strict";init_git_ci_types();init_merge_identity();EMPTY_DETAILS=Object.freeze({});EVENT_PARSERS={"run.started":parseEmpty,"run.heartbeat":parseEmpty,"run.stopped":parseEmpty,"agent.notification":parseEmpty,"tool.intent":parseEmpty,"worktree.changed":parseEmpty,"git.commit_created":parseEmpty,"git.pr_opened":parseHeadObservation,"ci.passed":parseHeadObservation,"ci.failed":parseHeadObservation,"gate.met":parseGateMet,"supervisor.assessment":parseEmpty,"message.sent":parseEmpty,"message.delivered":parseEmpty,"message.acked":parseEmpty,"merge.dry_run":parseMergeLifecycle,"merge.attempted":parseMergeLifecycle,"merge.succeeded":parseHeadObservation,"merge.failed":parseMergeLifecycle,"merge.conflict":parseHeadObservation,"merge.pending_approval":parseMergeLifecycle,"review.passed":parseHeadObservation,"review.changes_requested":parseHeadObservation,"spec_review.passed":parseSpecReview,"spec_review.changes_requested":parseSpecReview,"parse.triggered":parseEmpty,"parse.succeeded":parseEmpty,"parse.failed":parseEmpty}}});import{createHash as createHash5}from"node:crypto";function extractMergeActionIdentityFromGateEvent(event){return getMergeIdentity(event)}function makeMergeEventId(eventType,actionKey){let h=createHash5("sha256").update(`${eventType}:${actionKey}`).digest("hex");return`${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20,32)}`}async function lookupMergeEventByActionKey(eventType,actionKey,deps){let db=await(deps.openDb??(()=>openReadonlyConductorDatabaseIfExists()))();if(!db)return!1;try{return db.prepare(`SELECT 1 FROM events
131
+ `),repoName,sawRepoName=!1,mcp=[],currentMcp=null;for(let i=0;i<lines.length;i++){let lineNo=i+1,line=lines[i].trim();if(line.length===0||line.startsWith("#"))continue;if(line==="[[mcp]]"){currentMcp={headerLine:lineNo},mcp.push(currentMcp);continue}if(line.startsWith("["))return{ok:!1,kind:"parse-error",error:`Unsupported table header on line ${lineNo}; only [[mcp]] is allowed`};let eq=line.indexOf("=");if(eq===-1)return{ok:!1,kind:"parse-error",error:`Malformed line ${lineNo}; expected key = "value"`};let key=line.slice(0,eq).trim(),rawValue=line.slice(eq+1).trim();if(key.length===0)return{ok:!1,kind:"parse-error",error:`Malformed line ${lineNo}; missing key`};if(currentMcp===null){if(key==="repo_name"){if(sawRepoName)return{ok:!1,kind:"parse-error",error:`Duplicate repo_name on line ${lineNo}`};sawRepoName=!0;let stringValue=parseQuotedString(rawValue);if(stringValue===null)return{ok:!1,kind:"parse-error",error:`Expected a double-quoted string for '${key}' on line ${lineNo}`};let validated=validateRepoName(stringValue);if(!validated.ok)return{ok:!1,kind:"validation-error",error:validated.error};repoName=validated.value;continue}return key==="target"?{ok:!1,kind:"parse-error",error:`target on line ${lineNo} must appear inside an [[mcp]] section`}:{ok:!1,kind:"parse-error",error:`Unsupported key '${key}' on line ${lineNo}`}}if(key==="args"){if(currentMcp.args!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate args on line ${lineNo}`};let arr=parseStringArray(rawValue);if(arr===null)return{ok:!1,kind:"parse-error",error:`Expected a string array for 'args' on line ${lineNo}`};currentMcp.args=arr;continue}if(key==="target"||key==="command"||key==="secret_bundle"){let stringValue=parseQuotedString(rawValue);if(stringValue===null)return{ok:!1,kind:"parse-error",error:`Expected a double-quoted string for '${key}' on line ${lineNo}`};if(key==="target"){if(currentMcp.target!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate target on line ${lineNo}`};let validated=validateMcpTarget(stringValue);if(!validated.ok)return{ok:!1,kind:"validation-error",error:validated.error};currentMcp.target=validated.value;continue}if(key==="command"){if(currentMcp.command!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate command on line ${lineNo}`};currentMcp.command=stringValue;continue}if(currentMcp.secretBundle!==void 0)return{ok:!1,kind:"parse-error",error:`Duplicate secret_bundle on line ${lineNo}`};currentMcp.secretBundle=stringValue;continue}return{ok:!1,kind:"parse-error",error:`Unsupported key '${key}' inside [[mcp]] on line ${lineNo}`}}if(!sawRepoName||repoName===void 0)return{ok:!1,kind:"validation-error",error:"Missing required repo_name"};let cleaned=[];for(let entry of mcp){if(entry.target===void 0)return{ok:!1,kind:"validation-error",error:`An [[mcp]] section on line ${entry.headerLine} is missing its target`};if(entry.target!=="bapi"){if(entry.command===void 0||entry.command.trim().length===0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires a non-empty command`};if(entry.args===void 0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires an args array`};if(entry.secretBundle===void 0||entry.secretBundle.trim().length===0)return{ok:!1,kind:"validation-error",error:`[[mcp]] target '${entry.target}' on line ${entry.headerLine} requires a non-empty secret_bundle`}}let clean={target:entry.target};entry.command!==void 0&&(clean.command=entry.command),entry.args!==void 0&&(clean.args=entry.args),entry.secretBundle!==void 0&&(clean.secretBundle=entry.secretBundle),cleaned.push(clean)}return{ok:!0,manifest:{repoName,mcp:cleaned}}}function bridgeConfigPath(projectRoot){return path7.join(projectRoot,".bridge","config")}async function readBridgeConfig(projectRoot,deps){let filePath=bridgeConfigPath(projectRoot),raw;try{raw=await deps.readFile(filePath)}catch(err){return err&&typeof err=="object"&&err.code==="ENOENT"?{ok:!1,kind:"missing"}:{ok:!1,kind:"parse-error",error:"Unable to read .bridge/config"}}return parseBridgeConfigToml(raw)}var init_bridge_config=__esm({"src/bridge-config.ts"(){"use strict"}});async function resolveStartTicketsRepoName(deps){let fromEnv=deps.env.BAPI_REPO_NAME;if(typeof fromEnv=="string"&&fromEnv.trim().length>0)return fromEnv.trim();try{let result=await readBridgeConfig(deps.cwd,{readFile:deps.readFile});if(result.ok&&result.manifest.repoName)return result.manifest.repoName}catch{}return null}var init_start_tickets_repo=__esm({"src/start-tickets-repo.ts"(){"use strict";init_bridge_config()}});var bridge_api_client_exports={};__export(bridge_api_client_exports,{CONDUCTOR_DEFAULT_BASE_URL:()=>CONDUCTOR_DEFAULT_BASE_URL,CONDUCTOR_FETCH_TIMEOUT_MS:()=>CONDUCTOR_FETCH_TIMEOUT_MS,CONDUCTOR_REVIEW_ALIGNMENT_STATUSES:()=>CONDUCTOR_REVIEW_ALIGNMENT_STATUSES,ConductorBridgeApiError:()=>ConductorBridgeApiError,advanceEpicTicketStatus:()=>advanceEpicTicketStatus,approveEpicPlan:()=>approveEpicPlan,bootstrapConductorSupervisorDefaults:()=>bootstrapConductorSupervisorDefaults,buildConductorJiraUrl:()=>buildConductorJiraUrl,buildConductorVcsUrl:()=>buildConductorVcsUrl,buildEpicDispatchKey:()=>buildEpicDispatchKey,claimEpicSupervisionLease:()=>claimEpicSupervisionLease,createEpicRun:()=>createEpicRun,createEpicRunWithDisposition:()=>createEpicRunWithDisposition,createEpicTicketStatus:()=>createEpicTicketStatus,deletePullRequestBranch:()=>deletePullRequestBranch,extractSanitizedErrorDiagnostics:()=>extractSanitizedErrorDiagnostics,fetchActiveEpicRuns:()=>fetchActiveEpicRuns,fetchConductorConfigField:()=>fetchConductorConfigField,fetchConductorJsonPatchWithTimeout:()=>fetchConductorJsonPatchWithTimeout,fetchConductorJsonPostWithTimeout:()=>fetchConductorJsonPostWithTimeout,fetchConductorJsonPutWithTimeout:()=>fetchConductorJsonPutWithTimeout,fetchConductorJsonWithTimeout:()=>fetchConductorJsonWithTimeout,fetchConductorReadiness:()=>fetchConductorReadiness,fetchEffectiveSupervisorConfig:()=>fetchEffectiveSupervisorConfig,fetchEffectiveSupervisorSetup:()=>fetchEffectiveSupervisorSetup,fetchEpicRunState:()=>fetchEpicRunState,fetchParseStatus:()=>fetchParseStatus,fetchPrReviewStatus:()=>fetchPrReviewStatus,fetchShadowDispatchFreshness:()=>fetchShadowDispatchFreshness,getEpicPlan:()=>getEpicPlan,mergePullRequestForGate:()=>mergePullRequestForGate,parseConductorReadinessResponse:()=>parseConductorReadinessResponse,parseConductorSupervisorBootstrapResponse:()=>parseConductorSupervisorBootstrapResponse,pollCiChecksForCommit:()=>pollCiChecksForCommit,reconcileShadowMerge:()=>reconcileShadowMerge,recordEpicDispatch:()=>recordEpicDispatch,remediateEpicTicket:()=>remediateEpicTicket,replaceEpicRunPolicy:()=>replaceEpicRunPolicy,resolveConductorBridgeApiAccess:()=>resolveConductorBridgeApiAccess,safeDiagnosticMessage:()=>safeDiagnosticMessage,storeEpicPlan:()=>storeEpicPlan,transitionEpicDispatch:()=>transitionEpicDispatch,transitionJiraStatus:()=>transitionJiraStatus,triggerRepositoryParse:()=>triggerRepositoryParse,updateApprovedPlanNodeTicketSpec:()=>updateApprovedPlanNodeTicketSpec,updateEpicRunStatus:()=>updateEpicRunStatus,validateEpicPlan:()=>validateEpicPlan});import os4 from"node:os";import{readFile,stat}from"node:fs/promises";async function resolveConductorBridgeApiAccess(deps={}){let env=deps.env??process.env,cwd=deps.cwd??process.cwd(),homedir=deps.homedir??os4.homedir,platform=deps.platform??process.platform,readFileImpl=deps.readFile??(p=>readFile(p,"utf-8")),statImpl=deps.stat??(p=>stat(p)),repoName=deps.repoName?.trim()||await resolveStartTicketsRepoName({env,cwd,readFile:readFileImpl});if(!repoName)return{ok:!1,kind:"repo-missing",error:"could not resolve repo name (set BAPI_REPO_NAME or add a valid .bridge/config)"};let credResult;try{credResult=await resolveBapiCredentials(repoName,{env,homedir,platform,readFile:readFileImpl,stat:statImpl})}catch{return{ok:!1,kind:"credentials-unavailable",error:"failed to resolve Bridge API credentials"}}if(!credResult.ok)return{ok:!1,kind:"credentials-unavailable",error:"Bridge API credentials unavailable"};let baseUrlRaw=env.BAPI_BASE_URL,baseUrl=typeof baseUrlRaw=="string"&&baseUrlRaw.trim().length>0?baseUrlRaw.trim():CONDUCTOR_DEFAULT_BASE_URL;return{ok:!0,access:{repoName,apiKey:credResult.credentials.apiKey,baseUrl}}}function buildConductorJiraUrl(baseUrl,apiPath,params={}){let trimmed=baseUrl.replace(/\/+$/,""),url=new URL(`${trimmed}/jira${apiPath}`);for(let[k,v]of Object.entries(params))url.searchParams.set(k,v);return url.toString()}function redactErrorPreview(text){return text.replace(/sk-[A-Za-z0-9_-]{8,}/g,"[REDACTED]").replace(/(Bearer|X-API-Key|api[_-]?key)\b\s*[:=]?\s*\S+/gi,"$1 [REDACTED]").replace(/(webhook[_-]?url)\b["']?\s*[:=]?\s*["']?https?:\/\/\S+/gi,"$1 [REDACTED]").replace(/https?:\/\/[^\s/@]+:[^\s/@]+@\S+/gi,"[REDACTED]")}function stripWebhookUrlsDeep(value,depth=0){if(depth>12)return;if(Array.isArray(value))return value.map(item=>stripWebhookUrlsDeep(item,depth+1));if(!value||typeof value!="object")return value;let out={};for(let[key,item]of Object.entries(value))key!=="webhook_url"&&(out[key]=stripWebhookUrlsDeep(item,depth+1));return out}function boundedErrorPreview(text){let redacted=redactErrorPreview(text).replace(/\s+/g," ").trim();return redacted.length>CONDUCTOR_ERROR_PREVIEW_MAX?`${redacted.slice(0,CONDUCTOR_ERROR_PREVIEW_MAX)}\u2026`:redacted}function formatValidationDetailItem(item){if(!item||typeof item!="object")return;let record=item,msg=record.msg;if(typeof msg!="string"||!msg.trim())return;let loc=record.loc,parts=Array.isArray(loc)?loc.filter(part=>typeof part=="string"||typeof part=="number"):[],path8=(parts[0]==="body"?parts.slice(1):parts).slice(0,CONDUCTOR_VALIDATION_LOC_MAX_PARTS).join(".");return path8?`${path8}: ${msg}`:msg}function extractSanitizedErrorDiagnostics(body){if(typeof body=="string"){let trimmed=body.trim();return trimmed?{bodyPreview:boundedErrorPreview(trimmed)}:{}}if(!body||typeof body!="object")return{};let record=body,detail=record.detail,errorCode,message;if(Array.isArray(detail))message=formatValidationDetailItem(detail[0]);else if(detail&&typeof detail=="object"){let d=detail;typeof d.error_code=="string"&&(errorCode=d.error_code),typeof d.message=="string"&&(message=d.message)}else typeof detail=="string"&&(message=detail);!errorCode&&typeof record.error_code=="string"&&(errorCode=record.error_code),!message&&typeof record.message=="string"&&(message=record.message);let diagnostics={};return errorCode&&(diagnostics.errorCode=boundedErrorPreview(errorCode)),message&&(diagnostics.bodyPreview=boundedErrorPreview(message)),diagnostics}function redactDiagnosticValues(diagnostics,secrets){let scrub=text=>{let out2=text;for(let secret of secrets)secret&&secret.length>=4&&(out2=out2.split(secret).join("[REDACTED]"));return out2},out={};return diagnostics.errorCode&&(out.errorCode=scrub(diagnostics.errorCode)),diagnostics.bodyPreview&&(out.bodyPreview=scrub(diagnostics.bodyPreview)),out}async function readSanitizedErrorDiagnostics(resp,headers={}){try{let diagnostics=extractSanitizedErrorDiagnostics(stripWebhookUrlsDeep(await resp.json())),secrets=Object.entries(headers).filter(([k])=>/key|authorization|token/i.test(k)).map(([,v])=>v);return redactDiagnosticValues(diagnostics,secrets)}catch{return{}}}function safeDiagnosticMessage(err,fallback){if(err instanceof ConductorBridgeApiError){let parts=[`kind=${err.kind}`];return typeof err.status=="number"&&parts.push(`status=${err.status}`),err.errorCode&&parts.push(`code=${err.errorCode}`),err.bodyPreview&&parts.push(err.bodyPreview),parts.join(" ")}return err instanceof Error?err.constructor.name:fallback}function conductorGetHeaders(access){return{"X-API-Key":access.apiKey}}async function fetchConductorJsonWithTimeout(url,headers,timeoutMs,fetchImpl=globalThis.fetch){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),timeoutMs);try{let resp;try{resp=await fetchImpl(url,{headers,signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(!resp.ok){let diagnostics=await readSanitizedErrorDiagnostics(resp,headers);throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status,diagnostics):resp.status>=500?new ConductorBridgeApiError("server",resp.status,diagnostics):new ConductorBridgeApiError("http",resp.status,diagnostics)}try{return await resp.json()}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function fetchConductorConfigField(access,fieldName,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`/config-field/${encodeURIComponent(fieldName)}`,{repo_name:access.repoName}),body=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);if(body&&typeof body=="object"&&"value"in body)return body.value}async function fetchEffectiveSupervisorSetup(access,epicKey,fetchImpl=globalThis.fetch){let apiPath=epicKey?`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}/supervisor-setup/`:`${EPIC_RUNS_API_PREFIX}/supervisor-setup/defaults/`,url=buildConductorJiraUrl(access.baseUrl,apiPath,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchEffectiveSupervisorConfig(access,epicKey,fetchImpl=globalThis.fetch){let apiPath=epicKey?`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}/supervisor-config/`:`${EPIC_RUNS_API_PREFIX}/supervisor-config/defaults/`,url=buildConductorJiraUrl(access.baseUrl,apiPath,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function pollCiChecksForCommit(access,commitRef,fetchImpl=globalThis.fetch){let sha=normalizeSha(commitRef);if(sha===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorJiraUrl(access.baseUrl,"/poll-ci-checks",{repo_name:access.repoName,commit_ref:sha});return fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchPrReviewStatus(access,prNumber,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(prNumber);if(pr===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/reviews/status`),fullUrl=new URL(url);return fullUrl.searchParams.set("repo_name",access.repoName),fetchConductorJsonWithTimeout(fullUrl.toString(),conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function buildConductorVcsUrl(baseUrl,apiPath){let trimmed=baseUrl.replace(/\/+$/,""),path8=apiPath.startsWith("/")?apiPath:`/${apiPath}`;return new URL(`${trimmed}${path8}`).toString()}function conductorPostHeaders(access){return{"X-API-Key":access.apiKey,"Content-Type":"application/json"}}async function fetchConductorJsonWithMethodAndTimeout(method,url,headers,body,timeoutMs,fetchImpl){let{body:parsed}=await fetchConductorJsonWithMethodStatusAndTimeout(method,url,headers,body,timeoutMs,fetchImpl);return parsed}async function fetchConductorJsonWithMethodStatusAndTimeout(method,url,headers,body,timeoutMs,fetchImpl){let controller=new AbortController,timer=setTimeout(()=>controller.abort(),timeoutMs);try{let resp;try{resp=await fetchImpl(url,{method,headers,body,signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(!resp.ok){let diagnostics=await readSanitizedErrorDiagnostics(resp,headers);throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status,diagnostics):resp.status>=500?new ConductorBridgeApiError("server",resp.status,diagnostics):new ConductorBridgeApiError("http",resp.status,diagnostics)}try{return{status:resp.status,body:await resp.json()}}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function fetchConductorJsonPostWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("POST",url,headers,body,timeoutMs,fetchImpl)}async function fetchConductorJsonPatchWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("PATCH",url,headers,body,timeoutMs,fetchImpl)}async function fetchConductorJsonPutWithTimeout(url,headers,body,timeoutMs,fetchImpl){return fetchConductorJsonWithMethodAndTimeout("PUT",url,headers,body,timeoutMs,fetchImpl)}async function mergePullRequestForGate(access,request,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(request.pr_number),sha=normalizeSha(request.expected_head_sha);if(pr===null||sha===null||!request.action_key||!request.repo_name)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/merge`),body=JSON.stringify({repo_name:request.repo_name,expected_head_sha:sha,gate:request.gate,action_key:request.action_key,...request.gate_event?{gate_event:request.gate_event}:{}});return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function remediateEpicTicket(access,request,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(request.pr_number);if(pr===null||!request.epic_run_id||!request.ticket_key||!request.head_sha||!request.idempotency_key)throw new ConductorBridgeApiError("invalid-input");if(requireNonNegativeSafeInteger(request.expected_row_version),request.attempt_kind!=="nudge"&&request.attempt_kind!=="redispatch")throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/remediate`),body=JSON.stringify({repo_name:access.repoName,epic_run_id:request.epic_run_id,ticket_key:request.ticket_key,expected_row_version:request.expected_row_version,head_sha:request.head_sha,idempotency_key:request.idempotency_key,attempt_kind:request.attempt_kind,...request.reason?{reason:request.reason}:{}});try{return{ok:!0,conflict:!1,response:await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}}catch(err){if(err instanceof ConductorBridgeApiError&&err.kind==="http"&&err.status===409)return{ok:!0,conflict:!0};throw err}}function requireNonEmptyString(value){if(typeof value!="string"||value.trim().length===0)throw new ConductorBridgeApiError("invalid-input")}function requirePositiveSafeInteger(value){if(typeof value!="number"||!Number.isSafeInteger(value)||value<=0)throw new ConductorBridgeApiError("invalid-input")}function requireNonNegativeSafeInteger(value){if(typeof value!="number"||!Number.isSafeInteger(value)||value<0)throw new ConductorBridgeApiError("invalid-input")}function requireNoSlashPathSegment(value){if(value.includes("/"))throw new ConductorBridgeApiError("invalid-input")}function requireEpicTicketStatusValue(value){if(typeof value!="string"||!EPIC_TICKET_STATUS_VALUES.includes(value))throw new ConductorBridgeApiError("invalid-input")}function requireEpicDispatchTransitionStatus(value){if(typeof value!="string"||!EPIC_DISPATCH_TRANSITION_STATUSES.includes(value))throw new ConductorBridgeApiError("invalid-input")}function epicRunApiPath(epicKey){return`${EPIC_RUNS_API_PREFIX}/runs/${encodeURIComponent(epicKey)}`}function epicDispatchTransitionApiPath(dispatchKey,nextStatus){return nextStatus==="run_spawned"?`/epic-runs/dispatch/${encodeURIComponent(dispatchKey)}/run-spawned`:`/epic-runs/dispatch/${encodeURIComponent(dispatchKey)}/terminal`}function buildEpicDispatchKey(epicKey,ticketKey,planVersion,attempt=0){requireNonEmptyString(epicKey),requireNonEmptyString(ticketKey),requireNonNegativeSafeInteger(planVersion),requireNonNegativeSafeInteger(attempt);let base=`dispatch:${epicKey}:${ticketKey}:${planVersion}`;return attempt>0?`${base}:r${attempt}`:base}function parseEpicSupervisionLeaseResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed,row=p.row;if(p.claimed===!0&&row&&typeof row=="object")return{ok:!0,kind:"acquired-or-renewed",row};if(p.claimed===!1&&p.reason==="lease_held"&&row&&typeof row=="object")return{ok:!1,kind:"held-by-other",reason:"lease_held",row};if(p.claimed===!1&&p.reason==="terminal"&&row&&typeof row=="object")return{ok:!1,kind:"terminal",reason:"terminal",row};throw new ConductorBridgeApiError("server")}async function claimEpicSupervisionLease(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.leaseOwner),requirePositiveSafeInteger(request.ttlSeconds);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/lease/claim`),body=JSON.stringify({repo_name:access.repoName,lease_owner:request.leaseOwner,ttl_seconds:request.ttlSeconds}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseEpicSupervisionLeaseResult(parsed)}async function fetchEpicRunState(access,epicKey,fetchImpl=globalThis.fetch){requireNonEmptyString(epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(epicKey)}/state`,{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchActiveEpicRuns(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`,{repo_name:access.repoName,status:"active",limit:"20"}),parsed=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);if(parsed&&typeof parsed=="object"){let runs=parsed.runs;if(Array.isArray(runs))return runs}return[]}async function createEpicRun(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let body={repo_name:access.repoName,epic_key:request.epicKey,status:request.status??"planning",current_plan_version:request.currentPlanVersion??0};request.policyJson!==void 0&&(body.policy_json=request.policyJson),request.budgetWallClockSeconds!==void 0&&(body.budget_wall_clock_seconds=request.budgetWallClockSeconds),request.budgetCostCents!==void 0&&(body.budget_cost_cents=request.budgetCostCents);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`);return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function createEpicRunWithDisposition(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let body={repo_name:access.repoName,epic_key:request.epicKey,status:request.status??"planning",current_plan_version:request.currentPlanVersion??0};request.policyJson!==void 0&&(body.policy_json=request.policyJson),request.budgetWallClockSeconds!==void 0&&(body.budget_wall_clock_seconds=request.budgetWallClockSeconds),request.budgetCostCents!==void 0&&(body.budget_cost_cents=request.budgetCostCents);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/runs`),{status,body:parsed}=await fetchConductorJsonWithMethodStatusAndTimeout("POST",url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return{run:parsed,created:status===201}}async function replaceEpicRunPolicy(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicRunId);let url=buildConductorJiraUrl(access.baseUrl,epicRunApiPath(request.epicRunId)),body=JSON.stringify({repo_name:access.repoName,policy_json:request.policyJson});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function updateEpicRunStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let url=buildConductorJiraUrl(access.baseUrl,epicRunApiPath(request.epicKey)),body=JSON.stringify({repo_name:access.repoName,status:request.status,...request.expectedStatus?{expected_status:request.expectedStatus}:{}});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseAdvanceEpicTicketStatusResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed;if(p.ok===!1&&p.kind==="cas-conflict")return{ok:!1,kind:"cas-conflict",...typeof p.current_row_version=="number"?{current_row_version:p.current_row_version}:{},...p.ticket_status&&typeof p.ticket_status=="object"?{ticket_status:p.ticket_status}:{}};if(p.ok===!0&&p.ticket_status&&typeof p.ticket_status=="object")return{ok:!0,ticket_status:p.ticket_status};if("ticket_key"in p&&"status"in p&&"row_version"in p)return{ok:!0,ticket_status:parsed};throw new ConductorBridgeApiError("server")}async function advanceEpicTicketStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonNegativeSafeInteger(request.expectedRowVersion),requireNonNegativeSafeInteger(request.planVersion),requireEpicTicketStatusValue(request.nextStatus),request.dispatchRunId!==void 0&&requireNonEmptyString(request.dispatchRunId);let CAS_ENDPOINT_PATH=`${epicRunApiPath(request.epicKey)}/tickets/${encodeURIComponent(request.ticketKey)}`,url=buildConductorJiraUrl(access.baseUrl,CAS_ENDPOINT_PATH),body=JSON.stringify({repo_name:access.repoName,status:request.nextStatus,plan_version:request.planVersion,expected_row_version:request.expectedRowVersion,...request.dispatchRunId?{dispatch_run_id:request.dispatchRunId}:{}}),parsed=await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseAdvanceEpicTicketStatusResult(parsed)}async function createEpicTicketStatus(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireEpicTicketStatusValue(request.status),requireNonNegativeSafeInteger(request.planVersion),request.dispatchRunId!==void 0&&requireNonEmptyString(request.dispatchRunId);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/tickets`),body=JSON.stringify({repo_name:access.repoName,ticket_key:request.ticketKey,status:request.status,plan_version:request.planVersion,...request.dispatchRunId?{dispatch_run_id:request.dispatchRunId}:{}});await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseEpicDispatchResult(parsed){if(!parsed||typeof parsed!="object")throw new ConductorBridgeApiError("server");let p=parsed,row=p.row;if(!row||typeof row!="object")throw new ConductorBridgeApiError("server");let dispatch=row;if(p.claimed===!0)return{ok:!0,kind:"claimed",dispatch};if(p.claimed===!1){let reason=p.reason;if(reason==="already_spawned")return{ok:!0,kind:"already-spawned",dispatch};if(reason==="already_exists")return{ok:!0,kind:"already-exists",dispatch};if(reason==="terminal")return{ok:!0,kind:"terminal",terminal:!0,dispatch};if(reason==="lease_held")return{ok:!1,kind:"lease-held",dispatch}}throw new ConductorBridgeApiError("server")}async function recordEpicDispatch(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonEmptyString(request.leaseOwner),requireNonNegativeSafeInteger(request.planVersion),requirePositiveSafeInteger(request.ttlSeconds);let dispatchKey=buildEpicDispatchKey(request.epicKey,request.ticketKey,request.planVersion,request.attempt??0)+(request.reviewRole?":review":""),url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/dispatch/claim`),body=JSON.stringify({repo_name:access.repoName,epic_run_id:request.epicKey,ticket_key:request.ticketKey,plan_version:request.planVersion,lease_owner:request.leaseOwner,ttl_seconds:request.ttlSeconds,dispatch_key:dispatchKey}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseEpicDispatchResult(parsed)}async function transitionEpicDispatch(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.dispatchKey),requireNoSlashPathSegment(request.dispatchKey),requireEpicDispatchTransitionStatus(request.nextStatus),request.nextStatus==="run_spawned"&&requireNonEmptyString(request.runId);let path8=epicDispatchTransitionApiPath(request.dispatchKey,request.nextStatus),url=buildConductorJiraUrl(access.baseUrl,path8),body=request.nextStatus==="run_spawned"?JSON.stringify({repo_name:access.repoName,run_id:request.runId}):JSON.stringify({repo_name:access.repoName});return await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseShadowMergeReconcileResult(parsed){let obj=parsed??{};return{applies:obj.applies===!0,scheduled:obj.scheduled===!0,reasonCode:typeof obj.reason_code=="string"?obj.reason_code:"unknown",shadowRepoName:typeof obj.shadow_repo_name=="string"?obj.shadow_repo_name:null,requiredCommitSha:typeof obj.required_commit_sha=="string"?obj.required_commit_sha:null,lifecycleState:typeof obj.lifecycle_state=="string"?obj.lifecycle_state:null}}function parseShadowDispatchFreshnessResult(parsed){let obj=parsed??{},rawVerdict=typeof obj.verdict=="string"?obj.verdict:"",verdict=SHADOW_FRESHNESS_VERDICTS.has(rawVerdict)?rawVerdict:"stale";return{verdict,reasonCode:typeof obj.reason_code=="string"?obj.reason_code:verdict,lifecycleState:typeof obj.lifecycle_state=="string"?obj.lifecycle_state:null,indexedCommitSha:typeof obj.indexed_commit_sha=="string"?obj.indexed_commit_sha:null,shadowRepoName:typeof obj.shadow_repo_name=="string"?obj.shadow_repo_name:null,lastError:typeof obj.last_error=="string"?obj.last_error:null,deadlineExpired:obj.deadline_expired===!0,blockedAdvanceReason:typeof obj.blocked_advance_reason=="string"&&obj.blocked_advance_reason.length>0?obj.blocked_advance_reason:null}}async function reconcileShadowMerge(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/shadow/merge-reconcile`),body=JSON.stringify({repo_name:access.repoName,merged_ticket_key:request.mergedTicketKey??null}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseShadowMergeReconcileResult(parsed)}async function fetchShadowDispatchFreshness(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNoSlashPathSegment(request.ticketKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/tickets/${encodeURIComponent(request.ticketKey)}/shadow-freshness`),body=JSON.stringify({repo_name:access.repoName}),parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseShadowDispatchFreshnessResult(parsed)}async function validateEpicPlan(access,request,fetchImpl=globalThis.fetch){requirePositiveSafeInteger(request.planVersion);let blobVersion=request.planBlob.plan_version;if(blobVersion!==void 0&&blobVersion!==request.planVersion)throw new ConductorValidationError(`planVersion mismatch: request.planVersion=${request.planVersion} but planBlob.plan_version=${blobVersion}`);let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/plan/validate`),body={repo_name:access.repoName,plan_version:request.planVersion,plan_blob:request.planBlob};request.epicKey!==void 0&&(body.epic_key=request.epicKey);let parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(body),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseValidateEpicPlanResult(parsed)}function parseValidateEpicPlanResult(parsed){if(!parsed||typeof parsed!="object"||Array.isArray(parsed))throw new ConductorBridgeApiError("server");let p=parsed,planHash=p.plan_hash,serializationEnabled=p.serialization_enabled,insertedEdges=p.inserted_edges;if(p.valid!==!0||typeof planHash!="string"||planHash.trim()===""||typeof serializationEnabled!="boolean"||typeof insertedEdges!="number"||!Number.isSafeInteger(insertedEdges)||insertedEdges<0)throw new ConductorBridgeApiError("server");return{planHash,serializationEnabled,insertedEdges,overlappingPairsFound:safeCount(p.overlapping_pairs_found),undeclaredNodes:safeCount(p.undeclared_nodes),undeclaredPairsSkipped:safeCount(p.undeclared_pairs_skipped),coverageScope:typeof p.coverage_scope=="string"&&p.coverage_scope.trim()!==""?p.coverage_scope:"unreported"}}function safeCount(value){return typeof value=="number"&&Number.isSafeInteger(value)&&value>=0?value:0}async function storeEpicPlan(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requirePositiveSafeInteger(request.planVersion),requireNonEmptyString(request.planHash);let blobVersion=request.planBlob.plan_version;if(blobVersion!==void 0&&blobVersion!==request.planVersion)throw new ConductorValidationError(`planVersion mismatch: request.planVersion=${request.planVersion} but planBlob.plan_version=${blobVersion}`);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/plan`),body=JSON.stringify({repo_name:access.repoName,plan_version:request.planVersion,plan_blob:request.planBlob,plan_hash:request.planHash});return fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function updateApprovedPlanNodeTicketSpec(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requireNonEmptyString(request.ticketKey),requireNonEmptyString(request.expectedPlanHash),requireNonEmptyString(request.ticketSpec);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/plan/nodes/${encodeURIComponent(request.ticketKey)}/ticket-spec`),body=JSON.stringify({repo_name:access.repoName,expected_plan_hash:request.expectedPlanHash,ticket_spec:request.ticketSpec});return await fetchConductorJsonPatchWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}function parseApproveEpicPlanSuccess(parsed){let record=parsed??{},result={ok:!0,plan_hash:record.plan_hash},prov=record.feature_branch_provisioning;if(prov&&typeof prov=="object"&&!Array.isArray(prov)){let p=prov;(p.status==="created"||p.status==="already_exists")&&typeof p.feature_branch=="string"&&typeof p.source_branch=="string"&&typeof p.source_sha=="string"&&typeof p.remote_head_sha=="string"&&(result.featureBranchProvisioning={status:p.status,feature_branch:p.feature_branch,source_branch:p.source_branch,source_sha:p.source_sha,remote_head_sha:p.remote_head_sha})}return result}async function approveEpicPlan(access,request,fetchImpl=globalThis.fetch){requireNonEmptyString(request.epicKey),requirePositiveSafeInteger(request.planVersion);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(request.epicKey)}/approve-plan`),body=JSON.stringify({repo_name:access.repoName,plan_version:request.planVersion});try{let parsed=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseApproveEpicPlanSuccess(parsed)}catch(error){if(error instanceof ConductorBridgeApiError&&error.status===409){let preview=error.bodyPreview??"";return/multiple active runs/i.test(preview)?{ok:!1,kind:"conflict",reason:"multiple_active_runs"}:{ok:!1,kind:"conflict",reason:"superseded"}}throw error}}async function getEpicPlan(access,epicKey,planVersion,fetchImpl=globalThis.fetch){requireNonEmptyString(epicKey);let url=buildConductorJiraUrl(access.baseUrl,`${epicRunApiPath(epicKey)}/plan`,{repo_name:access.repoName,plan_version:String(planVersion)});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function fetchParseStatus(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,"/parse-status",{repo_name:access.repoName});return await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function triggerRepositoryParse(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,"/parse-repository"),body=JSON.stringify({repo_name:access.repoName});return fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl)}async function deletePullRequestBranch(access,prNumber,expectedHeadSha,fetchImpl=globalThis.fetch){let pr=normalizePrNumber(prNumber);if(pr===null)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorVcsUrl(access.baseUrl,`/vcs/pull-requests/${pr}/branch?repo_name=${encodeURIComponent(access.repoName)}&expected_head_sha=${encodeURIComponent(expectedHeadSha)}`),controller=new AbortController,timer=setTimeout(()=>controller.abort(),CONDUCTOR_FETCH_TIMEOUT_MS);try{let resp;try{resp=await fetchImpl(url,{method:"DELETE",headers:{"X-API-Key":access.apiKey},body:"",signal:controller.signal})}catch{throw new ConductorBridgeApiError(controller.signal.aborted?"timeout":"network")}if(resp.status===404)return{deleted:!1,branch:null,reason:"not_found"};if(!resp.ok)throw resp.status===401||resp.status===403?new ConductorBridgeApiError("unauthorized",resp.status):resp.status>=500?new ConductorBridgeApiError("server",resp.status):new ConductorBridgeApiError("http",resp.status);try{return await resp.json()}catch{throw new ConductorBridgeApiError("network")}}finally{clearTimeout(timer)}}async function transitionJiraStatus(access,ticketNumber,targetStatus="auto",fetchImpl=globalThis.fetch){if(!ticketNumber)throw new ConductorBridgeApiError("invalid-input");let url=buildConductorJiraUrl(access.baseUrl,`/tickets/${encodeURIComponent(ticketNumber)}/jira-status`),body=JSON.stringify({repo_name:access.repoName,target_status:targetStatus});try{return await fetchConductorJsonPutWithTimeout(url,conductorPostHeaders(access),body,CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl),{status:"transitioned"}}catch(err){if(err instanceof ConductorBridgeApiError&&err.kind==="http"&&err.status===400)return{status:"skipped"};throw err}}function readinessShapeError(){return new ConductorBridgeApiError("invalid-input",void 0,{errorCode:"READINESS_SHAPE_INVALID"})}function requireObject(value){if(typeof value!="object"||value===null||Array.isArray(value))throw readinessShapeError();return value}function requireBool(o,key){let v=o[key];if(typeof v!="boolean")throw readinessShapeError();return v}function requireInt(o,key){let v=o[key];if(typeof v!="number"||!Number.isInteger(v))throw readinessShapeError();return v}function requireNullableInt(o,key){let v=o[key];if(v==null)return null;if(typeof v!="number"||!Number.isInteger(v))throw readinessShapeError();return v}function requireNullableString(o,key){let v=o[key];if(v==null)return null;if(typeof v!="string")throw readinessShapeError();return v}function requireNullableBool(o,key){let v=o[key];if(v==null)return null;if(typeof v!="boolean")throw readinessShapeError();return v}function parseReviewPolicyAlignment(o){let raw=o.review_policy_alignment;if(raw==null)return null;let a=requireObject(raw),explanation=a.explanation;if(typeof explanation!="string")throw readinessShapeError();return{status:requireEnum(a,"status",CONDUCTOR_REVIEW_ALIGNMENT_STATUSES),repo_review_signal:requireNullableString(a,"repo_review_signal"),done_gate_review_signal:requireNullableString(a,"done_gate_review_signal"),explanation}}function requireEnum(o,key,allowed){let v=o[key];if(typeof v!="string"||!allowed.has(v))throw readinessShapeError();return v}function parseConductorReadinessResponse(body){let root=requireObject(body),repoName=root.repo_name;if(typeof repoName!="string"||repoName.length===0)throw readinessShapeError();let sup=requireObject(root.supervisor),gh=requireObject(root.github),rec=requireObject(root.reconciler),exec=requireObject(root.executor),thr=requireObject(root.thresholds);return{repo_name:repoName,supervisor:{setup_present:requireBool(sup,"setup_present"),setup_source:requireEnum(sup,"setup_source",READINESS_SOURCES),setup_created_at:requireNullableString(sup,"setup_created_at"),setup_updated_at:requireNullableString(sup,"setup_updated_at"),config_present:requireBool(sup,"config_present"),config_source:requireEnum(sup,"config_source",READINESS_SOURCES),config_created_at:requireNullableString(sup,"config_created_at"),config_updated_at:requireNullableString(sup,"config_updated_at"),required_checks_count:requireInt(sup,"required_checks_count"),required_checks_empty:requireBool(sup,"required_checks_empty"),auto_merge_enabled:requireBool(sup,"auto_merge_enabled"),merge_approval_required_set:requireBool(sup,"merge_approval_required_set"),review_policy_alignment:parseReviewPolicyAlignment(sup),review_policy_present:sup.review_policy_present===!0},github:{credentials_readable:requireBool(gh,"credentials_readable"),owner_resolved:requireBool(gh,"owner_resolved"),repo_id_resolved:requireBool(gh,"repo_id_resolved"),installation_id_resolved:requireBool(gh,"installation_id_resolved"),credentials_complete:requireBool(gh,"credentials_complete"),actions_probe_succeeded:requireBool(gh,"actions_probe_succeeded"),actions_permission_present:requireBool(gh,"actions_permission_present"),actions_permission_level:requireEnum(gh,"actions_permission_level",ACTIONS_LEVELS),actions_write:requireBool(gh,"actions_write")},reconciler:{liveness_readable:requireBool(rec,"liveness_readable"),last_tick_at:requireNullableString(rec,"last_tick_at"),last_tick_age_seconds:requireNullableInt(rec,"last_tick_age_seconds"),stale:requireBool(rec,"stale"),active_run_count:requireInt(rec,"active_run_count"),expired_lease_count:requireInt(rec,"expired_lease_count")},executor:{liveness_readable:requireBool(exec,"liveness_readable"),last_seen_at:requireNullableString(exec,"last_seen_at"),last_seen_age_seconds:requireNullableInt(exec,"last_seen_age_seconds"),ready:requireNullableBool(exec,"ready")},thresholds:{reconciler_stale_after_seconds:requireInt(thr,"reconciler_stale_after_seconds"),executor_stale_after_seconds:requireInt(thr,"executor_stale_after_seconds")}}}async function fetchConductorReadiness(access,fetchImpl=globalThis.fetch){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/conductor-readiness`,{repo_name:access.repoName}),body=await fetchConductorJsonWithTimeout(url,conductorGetHeaders(access),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseConductorReadinessResponse(body)}function parseConductorSupervisorBootstrapResponse(body){let o=requireObject(body),repoName=o.repo_name;if(typeof repoName!="string"||repoName.length===0)throw readinessShapeError();let names=o.audited_field_names;if(!Array.isArray(names)||names.some(n=>typeof n!="string"))throw readinessShapeError();return{repo_name:repoName,setup_written:requireBool(o,"setup_written"),config_written:requireBool(o,"config_written"),setup_source:requireEnum(o,"setup_source",READINESS_SOURCES),config_source:requireEnum(o,"config_source",READINESS_SOURCES),setup_created_at:requireNullableString(o,"setup_created_at"),setup_updated_at:requireNullableString(o,"setup_updated_at"),config_created_at:requireNullableString(o,"config_created_at"),config_updated_at:requireNullableString(o,"config_updated_at"),required_checks_count:requireInt(o,"required_checks_count"),audited_field_names:names}}async function bootstrapConductorSupervisorDefaults(access,request,fetchImpl){let url=buildConductorJiraUrl(access.baseUrl,`${EPIC_RUNS_API_PREFIX}/supervisor-bootstrap`,{repo_name:access.repoName}),body=await fetchConductorJsonPostWithTimeout(url,conductorPostHeaders(access),JSON.stringify(request),CONDUCTOR_FETCH_TIMEOUT_MS,fetchImpl);return parseConductorSupervisorBootstrapResponse(body)}var CONDUCTOR_DEFAULT_BASE_URL,CONDUCTOR_FETCH_TIMEOUT_MS,CONDUCTOR_BRIDGE_API_ERROR_KINDS,CONDUCTOR_ERROR_PREVIEW_MAX,CONDUCTOR_VALIDATION_LOC_MAX_PARTS,ConductorBridgeApiError,EPIC_TICKET_STATUS_VALUES,EPIC_DISPATCH_TRANSITION_STATUSES,EPIC_RUNS_API_PREFIX,SHADOW_FRESHNESS_VERDICTS,CONDUCTOR_REVIEW_ALIGNMENT_STATUSES,READINESS_SOURCES,ACTIONS_LEVELS,init_bridge_api_client=__esm({"src/conductor/bridge-api-client.ts"(){"use strict";init_credential_store();init_start_tickets_repo();init_git_ci_types();init_errors();CONDUCTOR_DEFAULT_BASE_URL="https://bridgegpt-api.com",CONDUCTOR_FETCH_TIMEOUT_MS=3e4;CONDUCTOR_BRIDGE_API_ERROR_KINDS=["invalid-input","network","timeout","unauthorized","server","http"],CONDUCTOR_ERROR_PREVIEW_MAX=200;CONDUCTOR_VALIDATION_LOC_MAX_PARTS=8;ConductorBridgeApiError=class extends Error{kind;status;errorCode;bodyPreview;constructor(kindOrMessage,status,diagnostics){let isKnownKind=CONDUCTOR_BRIDGE_API_ERROR_KINDS.includes(kindOrMessage),errorCode=diagnostics?.errorCode,bodyPreview=diagnostics?.bodyPreview;if(isKnownKind){let parts=[`Conductor Bridge API request failed (${kindOrMessage}${typeof status=="number"?`, status ${status}`:""})`];errorCode&&parts.push(`code=${errorCode}`),bodyPreview&&parts.push(bodyPreview),super(parts.join(": "))}else super(kindOrMessage);this.name="ConductorBridgeApiError",this.kind=isKnownKind?kindOrMessage:"http",typeof status=="number"&&(this.status=status),errorCode&&(this.errorCode=errorCode),bodyPreview&&(this.bodyPreview=bodyPreview)}};EPIC_TICKET_STATUS_VALUES=["planned","ready","dispatched","running","blocked","abandoned","done","ready_for_review","reviewing","parse_pending"];EPIC_DISPATCH_TRANSITION_STATUSES=["run_spawned","terminal"];EPIC_RUNS_API_PREFIX="/epic-runs";SHADOW_FRESHNESS_VERDICTS=new Set(["not_applicable","covered","stale","failed"]);CONDUCTOR_REVIEW_ALIGNMENT_STATUSES=new Set(["aligned","divergent","not_configured","invalid"]),READINESS_SOURCES=new Set(["epic","project_default","none"]),ACTIONS_LEVELS=new Set(["write","read","none","unknown"])}});import{createHash as createHash4}from"node:crypto";function normalizeDimension(value){return(value??"").trim().toLowerCase()}function makeSupervisorIdempotencyKey(meta){return[normalizeDimension(meta.run_id),normalizeDimension(meta.worker_id)||"(run)",normalizeDimension(meta.reason),normalizeDimension(meta.kind),normalizeDimension(meta.cooldown_window)].join("|")}function makeSupervisorAssessmentEventId(idempotencyKey){let h=createHash4("sha256").update(`supervisor.assessment:${idempotencyKey}`).digest("hex");return`${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20,32)}`}function isDuplicateConstraintError3(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&code.startsWith("SQLITE_CONSTRAINT"))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("unique constraint")||lowered.includes("constraint failed"))return!0}return!1}async function emitSupervisorAssessmentIfNew(input,deps={}){let emitEvent=deps.emitEvent??emitConductorEvent,idempotencyKey=makeSupervisorIdempotencyKey(input.idempotency),eventId=makeSupervisorAssessmentEventId(idempotencyKey),details={...input.details??{},idempotency_key:idempotencyKey,reason:input.idempotency.reason,kind:input.idempotency.kind,cooldown_window:input.idempotency.cooldown_window,classification:input.assessment.classification,confidence:input.assessment.confidence},event={id:eventId,source:"conductor-supervisor",type:"supervisor.assessment",run_id:input.run_id,worker_id:input.idempotency.worker_id??input.worker_id??null,producer:"conductor-supervisor",observed_via:"supervisor",data:{summary:`supervisor assessment: ${input.idempotency.reason}`,status:"escalated",reason:input.idempotency.reason,details}};try{let result=await emitEvent(event);return{emitted:!0,event_id:eventId,event:result.event}}catch(error){if(isDuplicateConstraintError3(error))return{emitted:!1,reason:"duplicate"};throw error}}var init_supervisor_ledger=__esm({"src/conductor/supervisor-ledger.ts"(){"use strict";init_store()}});function buildSupervisorEscalationWorkerMessage(candidate,assessment,state){let details={reason:candidate.reason,state:candidate.state,liveness:candidate.liveness,elapsed_ms:candidate.elapsed_ms,assessment_source:"deterministic"};return{run_id:state.run_id,worker_id:candidate.worker_id,type:`supervisor.${candidate.reason}`,cause_seq:state.last_seq,payload:{summary:`supervisor escalation: ${candidate.reason}`,status:"escalated",details},source:"conductor-supervisor",producer:"worker-message-relay"}}async function sendSupervisorEscalationWorkerMessageIfNew(candidate,assessment,state,deps={}){let sendMessage=deps.sendMessage??sendWorkerMessage,input=buildSupervisorEscalationWorkerMessage(candidate,assessment,state);return sendMessage(input)}var init_supervisor_message_relay=__esm({"src/conductor/supervisor-message-relay.ts"(){"use strict";init_store()}});function isTerminalState(state){return TERMINAL_STATES.has(state)}function isoToMs(value){if(typeof value!="string"||value.length===0)return null;let ms=Date.parse(value);return Number.isFinite(ms)?ms:null}function msToIso(now){return new Date(now).toISOString()}function createEmptySupervisorRunState(runId,config,now){let startedIso=msToIso(now);return{run_id:runId,status:"unknown",last_seq:0,last_event_time:null,workers:{},gates:{},latest_assessment:null,escalations:[],started_at:startedIso,updated_at:startedIso,global_deadline_at:msToIso(now+config.global_timeout_ms),roster_discovered:!1}}function isValidSupervisorSummary(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)&&value.kind===SUPERVISOR_SUMMARY_KIND}function hydrateSupervisorRunStateFromSnapshot(snapshot,runId,config,now){let empty=createEmptySupervisorRunState(runId,config,now),summary=snapshot?.projection?.summary;return isValidSupervisorSummary(summary)?{...empty,status:typeof summary.status=="string"?summary.status:empty.status,last_seq:typeof summary.last_seq=="number"&&summary.last_seq>=0?summary.last_seq:empty.last_seq,last_event_time:typeof summary.last_event_time=="string"?summary.last_event_time:null,workers:isPlainRecord(summary.workers)?summary.workers:{},gates:isPlainRecord(summary.gates)?summary.gates:{},latest_assessment:summary.latest_assessment&&typeof summary.latest_assessment=="object"?summary.latest_assessment:null,escalations:Array.isArray(summary.escalations)?summary.escalations:[],started_at:typeof summary.started_at=="string"?summary.started_at:empty.started_at,global_deadline_at:typeof summary.global_deadline_at=="string"?summary.global_deadline_at:empty.global_deadline_at,roster_discovered:summary.roster_discovered===!0,run_id:runId}:empty}function isPlainRecord(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function ensureWorkerState(state,workerId,options={}){let existing=state.workers[workerId];if(existing)return options.ticketKey&&!existing.ticket_key&&(existing.ticket_key=options.ticketKey),existing;let created={worker_id:workerId,ticket_key:options.ticketKey??null,state:options.fromRoster?"not_started":"unknown",liveness:"unknown",first_seen_seq:options.seq??null,last_event_seq:options.seq??null,last_event_time:null,last_progress_time:null,last_heartbeat_time:null,blocked_reason:null,terminal_reason:null,observed_event_types:[]};return state.workers[workerId]=created,created}function noteObservedType(worker,eventType){worker.observed_event_types.includes(eventType)||worker.observed_event_types.push(eventType)}function eventDetails(event){let details=event.data?.details;return isPlainRecord(details)?details:{}}function extractRoster(event){let candidates=[eventDetails(event).workers,event.data?.workers,isPlainRecord(event.data?.raw)?event.data.raw.workers:void 0];for(let candidate of candidates)if(Array.isArray(candidate)){let roster=[];for(let entry of candidate){if(!isPlainRecord(entry))continue;let workerId=entry.worker_id;if(typeof workerId!="string"||workerId.length===0)continue;let ticketKey=entry.ticket_key;roster.push({worker_id:workerId,ticket_key:typeof ticketKey=="string"?ticketKey:null})}if(roster.length>0)return roster}return[]}function eventStatus(event){let status=event.data?.status;return typeof status=="string"?status.trim().toLowerCase():""}function eventReason(event){let reason=event.data?.reason??eventDetails(event).reason;return typeof reason=="string"?reason.trim().toLowerCase():""}function applyConductorEventToSupervisorState(state,event,now){if(event.run_id!==state.run_id)return state;let eventType=event.type,eventTimeMs=isoToMs(event.time)??now,eventTimeIso=event.time??msToIso(now);if(typeof event.seq=="number"&&event.seq>state.last_seq&&(state.last_seq=event.seq),state.last_event_time=eventTimeIso,state.status==="unknown"&&(state.status="active"),eventType==="run.started"){let roster=extractRoster(event);roster.length>0&&(state.roster_discovered=!0);for(let member of roster){let worker2=ensureWorkerState(state,member.worker_id,{fromRoster:!0,ticketKey:member.ticket_key,seq:event.seq});noteObservedType(worker2,eventType),worker2.last_event_seq=event.seq??worker2.last_event_seq,worker2.last_event_time=eventTimeIso}return state.updated_at=msToIso(now),state}if(eventType==="supervisor.assessment"||eventType==="message.sent")return state.updated_at=msToIso(now),state;let workerId=event.worker_id;if(typeof workerId!="string"||workerId.length===0)return applyRunLevelEvent(state,event,eventType),state.updated_at=msToIso(now),state;let worker=ensureWorkerState(state,workerId,{seq:event.seq});switch(noteObservedType(worker,eventType),worker.last_event_seq=event.seq??worker.last_event_seq,worker.last_event_time=eventTimeIso,eventType){case"run.heartbeat":{worker.last_heartbeat_time=eventTimeIso,!isTerminalState(worker.state)&&worker.state!=="blocked"&&(worker.state==="not_started"||worker.state==="unknown")&&(worker.state="active");break}case"agent.notification":{let status=eventStatus(event),reason=eventReason(event);BLOCKED_STATUS_TOKENS.has(status)||BLOCKED_STATUS_TOKENS.has(reason)?isTerminalState(worker.state)||(worker.state="blocked",worker.blocked_reason=status||reason||"blocked"):!isTerminalState(worker.state)&&worker.state==="not_started"&&(worker.state="active");break}case"tool.intent":case"worktree.changed":case"git.commit_created":{PROGRESS_EVENT_TYPES.has(eventType)&&(worker.last_progress_time=eventTimeIso,isTerminalState(worker.state)||((worker.state==="not_started"||worker.state==="unknown"||worker.state==="stalled"||worker.state==="blocked")&&(worker.state="active"),worker.blocked_reason=null));break}case"gate.met":{isTerminalState(worker.state)||(worker.state="candidate_done");break}case"ci.passed":{isTerminalState(worker.state)||(worker.state="verifying"),worker.last_progress_time=eventTimeIso;break}case"ci.failed":{let reason=eventReason(event);eventStatus(event)==="terminal"||reason==="terminal"||reason==="give_up"?(worker.state="failed",worker.terminal_reason=reason||"ci_failed"):isTerminalState(worker.state)||(worker.last_progress_time=eventTimeIso);break}case"run.stopped":{let status=eventStatus(event),reason=eventReason(event);FAILED_STATUS_TOKENS.has(status)||FAILED_STATUS_TOKENS.has(reason)?(worker.state="failed",worker.terminal_reason=reason||status||"failed"):(worker.state="complete",worker.terminal_reason=reason||status||"complete");break}case"message.delivered":case"message.acked":{!isTerminalState(worker.state)&&(worker.state==="not_started"||worker.state==="unknown")&&(worker.state="active");break}case"merge.succeeded":{worker.state="complete",worker.terminal_reason=worker.terminal_reason||"merge_succeeded";break}case"merge.failed":break;case"merge.dry_run":break;case"merge.pending_approval":break;default:break}return state.updated_at=msToIso(now),state}function applyRunLevelEvent(state,event,eventType){switch(eventType){case"gate.met":state.gates.gate_met=!0;break;case"ci.passed":state.gates.ci="passed";break;case"ci.failed":state.gates.ci="failed";break;case"git.pr_opened":state.gates.pr_opened=!0;break;case"merge.succeeded":case"merge.failed":case"merge.dry_run":case"merge.pending_approval":state.gates.merge=eventType.slice(6);break;default:break}}function classifyWorkerLiveness(worker,config,now){if(isTerminalState(worker.state))return"alive";let lastSignalMs=mostRecentSignalMs(worker);if(lastSignalMs===null)return"unknown";let elapsed=now-lastSignalMs;return elapsed>=config.liveness.dead_after_ms?"dead":elapsed>=config.liveness.stalled_after_ms?"stalled":elapsed>=config.liveness.quiet_after_ms?"quiet":"alive"}function mostRecentSignalMs(worker){let candidates=[isoToMs(worker.last_heartbeat_time),isoToMs(worker.last_event_time),isoToMs(worker.last_progress_time)].filter(v=>v!==null);return candidates.length===0?null:Math.max(...candidates)}function stateAnchorMs(worker){return worker.state==="active"||worker.state==="verifying"?mostRecentSignalMs(worker):isoToMs(worker.last_event_time)??isoToMs(worker.last_heartbeat_time)??isoToMs(worker.last_progress_time)}function applySupervisorHousekeeping(state,config,now){for(let worker of Object.values(state.workers)){if(worker.liveness=classifyWorkerLiveness(worker,config,now),isTerminalState(worker.state)||worker.state==="stalled")continue;let threshold=config.stall_thresholds_ms[worker.state],anchor=stateAnchorMs(worker);anchor!==null&&now-anchor>=threshold&&(worker.state="stalled")}return state.updated_at=msToIso(now),state}function isSupervisorRunTerminal(state){let workers=Object.values(state.workers);return workers.length===0||!state.roster_discovered?!1:workers.every(w=>isTerminalState(w.state))}function hasSupervisorGlobalTimeoutElapsed(state,now){let deadlineMs=isoToMs(state.global_deadline_at);return deadlineMs===null?!1:now>=deadlineMs}function compactWorker(worker){return{worker_id:worker.worker_id,ticket_key:worker.ticket_key,state:worker.state,liveness:worker.liveness,last_event_seq:worker.last_event_seq,last_event_time:worker.last_event_time,last_progress_time:worker.last_progress_time,last_heartbeat_time:worker.last_heartbeat_time,blocked_reason:worker.blocked_reason,terminal_reason:worker.terminal_reason}}function toSupervisorProjectionInput(state){let summary={kind:SUPERVISOR_SUMMARY_KIND,run_id:state.run_id,status:state.status,last_seq:state.last_seq,last_event_time:state.last_event_time,workers:state.workers,gates:state.gates,latest_assessment:state.latest_assessment,escalations:state.escalations,started_at:state.started_at,updated_at:state.updated_at,global_deadline_at:state.global_deadline_at,roster_discovered:state.roster_discovered};return{run_id:state.run_id,status:state.status,last_seq:state.last_seq,last_event_time:state.last_event_time,active_workers:Object.values(state.workers).map(compactWorker),gates:state.gates,assessment:state.latest_assessment,summary}}var SUPERVISOR_SUMMARY_KIND,TERMINAL_STATES,PROGRESS_EVENT_TYPES,BLOCKED_STATUS_TOKENS,FAILED_STATUS_TOKENS,init_supervisor_state=__esm({"src/conductor/supervisor-state.ts"(){"use strict";SUPERVISOR_SUMMARY_KIND="supervisor_projection_summary",TERMINAL_STATES=new Set(["complete","failed"]);PROGRESS_EVENT_TYPES=new Set(["tool.intent","worktree.changed","git.commit_created"]),BLOCKED_STATUS_TOKENS=new Set(["blocked","waiting_for_input","needs_input"]),FAILED_STATUS_TOKENS=new Set(["failed","error","errored","aborted","cancelled","canceled"])}});function elapsedSinceSignal(worker,now){let candidates=[worker.last_event_time,worker.last_progress_time,worker.last_heartbeat_time].map(iso=>iso?Date.parse(iso):NaN).filter(v=>Number.isFinite(v));return candidates.length===0?0:Math.max(0,now-Math.max(...candidates))}function findSupervisorEscalationCandidates(state,config,now){let candidates=[];for(let worker of Object.values(state.workers)){if(worker.state==="complete"||worker.state==="failed")continue;let elapsed=elapsedSinceSignal(worker,now),baseContext={worker_id:worker.worker_id,ticket_key:worker.ticket_key,state:worker.state,liveness:worker.liveness};if(worker.liveness==="dead"){candidates.push({reason:"worker_dead",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});continue}switch(worker.state){case"not_started":worker.liveness!=="alive"&&candidates.push({reason:"worker_not_started",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"blocked":candidates.push({reason:"worker_blocked",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:{...baseContext,blocked_reason:worker.blocked_reason}});break;case"stalled":candidates.push({reason:"worker_stalled",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"candidate_done":worker.liveness!=="alive"&&candidates.push({reason:"candidate_done_stuck",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;case"verifying":worker.liveness==="stalled"&&candidates.push({reason:"verification_stalled",kind:ESCALATION_KIND,worker_id:worker.worker_id,state:worker.state,liveness:worker.liveness,elapsed_ms:elapsed,context:baseContext});break;default:break}}let deadlineMs=state.global_deadline_at?Date.parse(state.global_deadline_at):NaN;return Number.isFinite(deadlineMs)&&now>=deadlineMs&&candidates.push({reason:"global_timeout",kind:ESCALATION_KIND,worker_id:null,state:null,liveness:null,elapsed_ms:Math.max(0,now-deadlineMs),context:{run_id:state.run_id,deadline_at:state.global_deadline_at,worker_count:Object.keys(state.workers).length}}),candidates}function cooldownWindowFor(now,cooldownMs){let width=cooldownMs>0?cooldownMs:1;return String(Math.floor(now/width))}function shouldEmitEscalation(state,candidate,config,now){let cooldownWindow=cooldownWindowFor(now,config.escalation_cooldown_ms);return{emit:!state.escalations.some(record=>record.reason===candidate.reason&&(record.worker_id??null)===(candidate.worker_id??null)&&record.cooldown_window===cooldownWindow&&(record.outcome==="emitted"||record.outcome==="duplicate")),cooldown_window:cooldownWindow}}function recordEscalationResult(state,candidate,cooldownWindow,idempotencyKey,outcome,now){let record={idempotency_key:idempotencyKey,worker_id:candidate.worker_id??null,reason:candidate.reason,kind:candidate.kind,cooldown_window:cooldownWindow,outcome,recorded_at:new Date(now).toISOString()};return state.escalations.push(record),record}function formatElapsed(ms){let totalSeconds=Math.max(0,Math.floor(ms/1e3)),hours=Math.floor(totalSeconds/3600),minutes=Math.floor(totalSeconds%3600/60),seconds=totalSeconds%60;return hours>0?`${hours}h${minutes}m`:minutes>0?`${minutes}m`:`${seconds}s`}function formatEscalationForTerminal(runId,candidate){let worker=candidate.worker_id?` worker=${candidate.worker_id}`:"",stateBit=candidate.state?` state=${candidate.state}`:"",liveBit=candidate.liveness?` liveness=${candidate.liveness}`:"",elapsed=` elapsed=${formatElapsed(candidate.elapsed_ms)}`;return`[supervisor] run=${runId}${worker} reason=${candidate.reason}${stateBit}${liveBit}${elapsed}`}var ESCALATION_KIND,init_supervisor_escalation=__esm({"src/conductor/supervisor-escalation.ts"(){"use strict";ESCALATION_KIND="escalation"}});function buildGateIdentity(gateName,configHash){let name=gateName.trim(),hash=typeof configHash=="string"?configHash.trim():"";return hash?`${name}@${hash.toLowerCase()}`:name}function makeMergeActionKey(repo,prNumber,headSha,gateIdentity){let r=normalizeRepoName(repo),pr=normalizePrNumber(prNumber),sha=normalizeSha(headSha),gate=(gateIdentity??"").trim();if(r===null||pr===null||sha===null||gate.length===0)throw new Error("invalid merge action key component");return`merge:${r}:${pr}:${sha}:${gate}`}var init_merge_identity=__esm({"src/conductor/merge-identity.ts"(){"use strict";init_git_ci_types()}});function isPlainObject2(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function normalizeEventHeadSha(value){if(typeof value!="string")return null;let trimmed=value.trim();return/^[0-9a-f]{7,40}$/i.test(trimmed)?trimmed.toLowerCase():null}function getRawEventDetails(event){let details=event.data?.details;return isPlainObject2(details)?details:null}function parseHeadObservation(event){let details=getRawEventDetails(event);return{head_sha:details?normalizeEventHeadSha(details.head_sha):null}}function parseMergeLifecycle(event){let details=getRawEventDetails(event);return{action_key:details&&typeof details.action_key=="string"&&details.action_key.trim().length>0?details.action_key.trim():null}}function parseGateMet(event){let details=getRawEventDetails(event);if(!details)return{head_sha:null,repo:null,pr_number:null,gate_name:null,config_hash:null,required_checks:[]};let gateName=typeof details.gate_name=="string"&&details.gate_name.trim().length>0?details.gate_name.trim():null,configHash=typeof details.config_hash=="string"&&details.config_hash.trim().length>0?details.config_hash.trim():null,ciCheckStatus=isPlainObject2(details.ci_check_status)?details.ci_check_status:null,requiredChecks=(Array.isArray(details.required_checks)?details.required_checks:ciCheckStatus&&Array.isArray(ciCheckStatus.required_checks)?ciCheckStatus.required_checks:[]).filter(c=>typeof c=="string"&&c.trim().length>0);return{head_sha:normalizeSha(details.head_sha),repo:normalizeRepoName(details.repo),pr_number:normalizePrNumber(details.pr_number),gate_name:gateName,config_hash:configHash,required_checks:requiredChecks}}function parseSpecReview(event){let details=getRawEventDetails(event);return{head_sha:details?normalizeEventHeadSha(details.head_sha):null}}function parseEmpty(){return EMPTY_DETAILS}function getEventDetails(event,expectedType){if(event.type!==expectedType)return null;let parser=EVENT_PARSERS[expectedType];return parser(event)}function getMergeIdentity(event){if(event.type!=="gate.met")return null;let details=getEventDetails(event,"gate.met");if(details===null)return null;let{repo,pr_number:prNumber,head_sha:headSha,gate_name:gateName}=details;if(repo===null||prNumber===null||headSha===null||gateName===null)return null;let gateIdentity=buildGateIdentity(gateName,details.config_hash),actionKey=makeMergeActionKey(repo,prNumber,headSha,gateIdentity);return{repo,pr_number:prNumber,head_sha:headSha,gate_name:gateName,config_hash:details.config_hash,required_checks:details.required_checks,gate_identity:gateIdentity,action_key:actionKey,gate_event:{id:typeof event.id=="string"?event.id:void 0,seq:typeof event.seq=="number"?event.seq:void 0,time:typeof event.time=="string"?event.time:void 0}}}var EMPTY_DETAILS,EVENT_PARSERS,init_event_accessors=__esm({"src/conductor/event-accessors.ts"(){"use strict";init_git_ci_types();init_merge_identity();EMPTY_DETAILS=Object.freeze({});EVENT_PARSERS={"run.started":parseEmpty,"run.heartbeat":parseEmpty,"run.stopped":parseEmpty,"agent.notification":parseEmpty,"tool.intent":parseEmpty,"worktree.changed":parseEmpty,"git.commit_created":parseEmpty,"git.pr_opened":parseHeadObservation,"ci.passed":parseHeadObservation,"ci.failed":parseHeadObservation,"gate.met":parseGateMet,"supervisor.assessment":parseEmpty,"message.sent":parseEmpty,"message.delivered":parseEmpty,"message.acked":parseEmpty,"merge.dry_run":parseMergeLifecycle,"merge.attempted":parseMergeLifecycle,"merge.succeeded":parseHeadObservation,"merge.failed":parseMergeLifecycle,"merge.conflict":parseHeadObservation,"merge.pending_approval":parseMergeLifecycle,"review.passed":parseHeadObservation,"review.changes_requested":parseHeadObservation,"spec_review.passed":parseSpecReview,"spec_review.changes_requested":parseSpecReview,"parse.triggered":parseEmpty,"parse.succeeded":parseEmpty,"parse.failed":parseEmpty}}});import{createHash as createHash5}from"node:crypto";function extractMergeActionIdentityFromGateEvent(event){return getMergeIdentity(event)}function makeMergeEventId(eventType,actionKey){let h=createHash5("sha256").update(`${eventType}:${actionKey}`).digest("hex");return`${h.slice(0,8)}-${h.slice(8,12)}-${h.slice(12,16)}-${h.slice(16,20)}-${h.slice(20,32)}`}async function lookupMergeEventByActionKey(eventType,actionKey,deps){let db=await(deps.openDb??(()=>openReadonlyConductorDatabaseIfExists()))();if(!db)return!1;try{return db.prepare(`SELECT 1 FROM events
132
132
  WHERE type = ?
133
133
  AND json_extract(data_json, '$.details.action_key') = ?
134
134
  LIMIT 1`).get(eventType,actionKey)!==void 0}finally{db.close()}}async function hasTerminalMergeSucceeded(actionKey,deps={}){return lookupMergeEventByActionKey("merge.succeeded",actionKey,deps)}async function hasMergeDryRun(actionKey,deps={}){return lookupMergeEventByActionKey("merge.dry_run",actionKey,deps)}async function hasMergePendingApproval(actionKey,deps={}){return lookupMergeEventByActionKey("merge.pending_approval",actionKey,deps)}function isDuplicateConstraintError4(error){if(!error||typeof error!="object")return!1;let code=error.code;if(typeof code=="string"&&code.startsWith("SQLITE_CONSTRAINT"))return!0;let message=error.message;if(typeof message=="string"){let lowered=message.toLowerCase();if(lowered.includes("unique constraint")||lowered.includes("constraint failed"))return!0}return!1}async function emitMergeLedgerEventIfNew(input,deps={}){let emitEvent=deps.emitEvent??emitConductorEvent,eventId=makeMergeEventId(input.type,input.action_key),event={id:eventId,source:"conductor-supervisor",type:input.type,run_id:input.run_id??null,worker_id:input.worker_id??null,producer:"conductor-merge",observed_via:"supervisor",data:{summary:input.summary??`${input.type} ${input.action_key}`,status:input.status,reason:input.reason??void 0,details:input.details}};try{let result=await emitEvent(event);return{emitted:!0,event_id:eventId,event:result.event}}catch(error){if(isDuplicateConstraintError4(error))return{emitted:!1,reason:"duplicate"};throw error}}var init_merge_ledger=__esm({"src/conductor/merge-ledger.ts"(){"use strict";init_event_accessors();init_merge_identity();init_store()}});function buildMergeRequestFromGateEvent(identity){return{repo_name:identity.repo,pr_number:identity.pr_number,expected_head_sha:identity.head_sha,gate:{name:identity.gate_name,config_hash:identity.config_hash,required_checks:identity.required_checks},action_key:identity.action_key,gate_event:identity.gate_event}}function mapApiErrorReason(error){if(error instanceof ConductorBridgeApiError)switch(error.kind){case"timeout":return"api_timeout";case"network":return"api_network";case"unauthorized":return"api_unauthorized";case"server":case"http":return"api_unavailable";case"invalid-input":return"api_invalid"}return"api_network"}function resolveAttributionWorkerId(event,identity,resolve2){if(typeof event.worker_id=="string"&&event.worker_id.trim().length>0)return event.worker_id.trim();if(resolve2){let resolved=resolve2(event,identity);if(typeof resolved=="string"&&resolved.trim().length>0)return resolved.trim()}return null}async function processGateMetMerge(access,event,deps={}){let extract=deps.extractIdentity??extractMergeActionIdentityFromGateEvent,checkTerminal=deps.hasTerminal??hasTerminalMergeSucceeded,checkDryRun=deps.hasDryRun??hasMergeDryRun,checkPendingApproval=deps.hasPendingApproval??hasMergePendingApproval,mergeFn=deps.merge??mergePullRequestForGate,identity=extract(event);if(!identity)return{processed:!1,reason:"ineligible"};let actionKey=identity.action_key,attributionWorkerId=resolveAttributionWorkerId(event,identity,deps.resolveWorkerIdForGateEvent);if(await checkTerminal(actionKey))return{processed:!1,reason:"already_succeeded"};let baseDetails={action_key:actionKey,repo:identity.repo,pr_number:identity.pr_number,expected_head_sha:identity.head_sha,gate:identity.gate_identity},response;try{response=await mergeFn(access,buildMergeRequestFromGateEvent(identity))}catch(error){let reason=mapApiErrorReason(error);return await emitMergeLedgerEventIfNew({type:"merge.failed",action_key:actionKey,status:"failed",reason,details:baseDetails,run_id:event.run_id??null,worker_id:attributionWorkerId,summary:`merge.failed ${reason}`},{emitEvent:deps.emitEvent}),{processed:!0,outcome:"api_error",reason}}let emitted=[];for(let ledgerEvent of response.ledger_events??[]){if(ledgerEvent.type==="merge.dry_run"&&await checkDryRun(actionKey)){emitted.push({type:ledgerEvent.type,emitted:!1});continue}if(ledgerEvent.type==="merge.pending_approval"&&await checkPendingApproval(actionKey)){emitted.push({type:ledgerEvent.type,emitted:!1});continue}let result=await emitMergeLedgerEventIfNew({type:ledgerEvent.type,action_key:actionKey,status:ledgerEvent.status,reason:ledgerEvent.reason??null,details:ledgerEvent.details??baseDetails,run_id:event.run_id??null,worker_id:attributionWorkerId},{emitEvent:deps.emitEvent});emitted.push({type:ledgerEvent.type,emitted:result.emitted})}return{processed:!0,outcome:response.status,emitted}}var init_supervisor_merge=__esm({"src/conductor/supervisor-merge.ts"(){"use strict";init_bridge_api_client();init_merge_ledger()}});async function dispatchSupervisorNotification(epicRunId,candidate,assessment,idempotencyKey){let result=await resolveConductorBridgeApiAccess();if(!result.ok)return;let{access}=result,url=buildConductorJiraUrl(access.baseUrl,`/epic-runs/${encodeURIComponent(epicRunId)}/notifications`),payload={repo_name:access.repoName,idempotency_key:idempotencyKey,summary:{reason:candidate.reason,kind:candidate.kind,worker_id:candidate.worker_id??null,elapsed_ms:candidate.elapsed_ms,ticket_key:candidate.context?.ticket_key??null,classification:assessment.classification}},headers={"X-API-Key":access.apiKey,"Content-Type":"application/json"};try{await fetchConductorJsonPostWithTimeout(url,headers,JSON.stringify(payload),CONDUCTOR_FETCH_TIMEOUT_MS,fetch)}catch{}}var init_supervisor_notification=__esm({"src/conductor/supervisor-notification.ts"(){"use strict";init_bridge_api_client()}});var supervisor_runtime_exports={};__export(supervisor_runtime_exports,{runSupervisor:()=>runSupervisor});function deterministicAssessment(candidate){return{classification:"stuck",confidence:1,reason:candidate.reason}}function terminalStatus(state){return Object.values(state.workers).some(w=>w.state==="failed")?"failed":"complete"}async function processEscalations(state,config,deps){let now=deps.now(),candidates=findSupervisorEscalationCandidates(state,config,now);for(let candidate of candidates){let decision=shouldEmitEscalation(state,candidate,config,now);if(!decision.emit)continue;let idempotency={run_id:state.run_id,worker_id:candidate.worker_id,reason:candidate.reason,kind:candidate.kind,cooldown_window:decision.cooldown_window},idempotencyKey=makeSupervisorIdempotencyKey(idempotency),assessment=deterministicAssessment(candidate);state.latest_assessment=assessment;let outcome="skipped";try{outcome=(await deps.emitAssessment({run_id:state.run_id,worker_id:candidate.worker_id,assessment,details:{elapsed_ms:candidate.elapsed_ms,...candidate.context},idempotency})).emitted?"emitted":"duplicate"}catch{outcome="skipped"}if(recordEscalationResult(state,candidate,decision.cooldown_window,idempotencyKey,outcome,now),(outcome==="emitted"||outcome==="duplicate")&&candidate.worker_id)try{await sendSupervisorEscalationWorkerMessageIfNew(candidate,assessment,state,{sendMessage:deps.sendWorkerMessage})}catch{}if(outcome==="emitted"&&(deps.log(formatEscalationForTerminal(state.run_id,candidate)),deps.dispatchNotification))try{await deps.dispatchNotification(state.run_id,candidate,assessment,idempotencyKey)}catch{}}}async function runSupervisor(options,deps={}){let runId=typeof options.run_id=="string"?options.run_id.trim():"";if(runId.length===0)throw new ConductorValidationError("Supervisor requires exactly one non-empty --run-id.");let config=options.config??resolveSupervisorConfig(options.overrides??{}),now=deps.now??(()=>Date.now()),log=deps.log??(m=>process.stdout.write(`${m}
135
135
  `)),errorLog=deps.errorLog??(m=>process.stderr.write(`${m}
136
- `)),waitForEvent=deps.waitForEvent??waitForConductorEvent,getSnapshot=deps.getSnapshot??getSupervisorSnapshot,upsertProjection=deps.upsertProjection??upsertSupervisorProjection,emitAssessment=deps.emitAssessment??emitSupervisorAssessmentIfNew,sendMessage=deps.sendWorkerMessage??sendWorkerMessage,resolveBridgeAccess=deps.resolveBridgeAccess??(()=>resolveConductorBridgeApiAccess()),processMerge=deps.processMerge??processGateMetMerge,dispatchNotification=deps.dispatchNotification??dispatchSupervisorNotification,bridgeAccess=null,bridgeAccessResolved=!1,processGateMetMerges=async events=>{let eligible=events.filter(e=>extractMergeActionIdentityFromGateEvent(e)!==null);if(eligible.length!==0){if(!bridgeAccessResolved){bridgeAccessResolved=!0;try{let result=await resolveBridgeAccess();bridgeAccess=result.ok?result.access:null,result.ok||errorLog(`[supervisor] run=${runId} auto-merge disabled: ${result.kind}`)}catch{bridgeAccess=null}}if(bridgeAccess)for(let event of eligible)try{await processMerge(bridgeAccess,event)}catch{}}},persist=async state2=>{try{await upsertProjection(toSupervisorProjectionInput(state2))}catch{}},state;try{let snapshot=await getSnapshot(runId);state=hydrateSupervisorRunStateFromSnapshot(snapshot,runId,config,now())}catch{return{run_id:runId,status:"failed",exit_code:2,reason:"supervisor failed to load initial snapshot",last_seq:0,worker_count:0}}let sinceSeq=state.last_seq>0?state.last_seq+1:1,iterationCap=Math.max(1e3,Math.ceil(config.global_timeout_ms/Math.max(1,config.wake_interval_ms))+16);try{applySupervisorHousekeeping(state,config,now());for(let iteration=0;iteration<iterationCap;iteration+=1){if(isSupervisorRunTerminal(state))return state.status=terminalStatus(state),await persist(state),log(`[supervisor] run=${runId} complete status=${state.status} workers=${Object.keys(state.workers).length}`),{run_id:runId,status:state.status,exit_code:0,reason:"all workers terminal",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length};if(hasSupervisorGlobalTimeoutElapsed(state,now()))return state.status="timed_out",await persist(state),errorLog(`[supervisor] run=${runId} global timeout elapsed`),{run_id:runId,status:"timed_out",exit_code:2,reason:"global timeout elapsed",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length};let waitResult=await waitForEvent({since_seq:sinceSeq,filter:{run_id:runId},data_mode:"full",timeout_ms:config.wake_interval_ms,limit:config.poll_limit});if(waitResult.events.length>0){let sorted=[...waitResult.events].sort((a,b)=>a.seq-b.seq);for(let event of sorted)applyConductorEventToSupervisorState(state,event,now());sinceSeq=sorted[sorted.length-1].seq+1,await processGateMetMerges(sorted)}applySupervisorHousekeeping(state,config,now()),await processEscalations(state,config,{emitAssessment,sendWorkerMessage:sendMessage,log,now,dispatchNotification}),await persist(state)}return state.status="timed_out",await persist(state),{run_id:runId,status:"timed_out",exit_code:2,reason:"supervisor iteration cap reached",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length}}catch{state.status="failed";try{await upsertProjection(toSupervisorProjectionInput(state))}catch{}return errorLog(`[supervisor] run=${runId} failed unexpectedly`),{run_id:runId,status:"failed",exit_code:2,reason:"supervisor failed unexpectedly",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length}}}var init_supervisor_runtime=__esm({"src/conductor/supervisor-runtime.ts"(){"use strict";init_store();init_supervisor_ledger();init_supervisor_message_relay();init_supervisor_config();init_supervisor_state();init_supervisor_escalation();init_supervisor_ledger();init_bridge_api_client();init_merge_ledger();init_supervisor_merge();init_supervisor_notification();init_errors()}});init_errors();init_store();init_producer_ledger();init_taxonomy();import{readFileSync as readFileSync3,unlinkSync}from"node:fs";init_git_inspection();import{chmodSync,existsSync as existsSync2,mkdirSync,readFileSync,statSync,writeFileSync}from"node:fs";import{dirname,isAbsolute,resolve}from"node:path";import{fileURLToPath}from"node:url";var BRIDGE_CONDUCTOR_HOOK_START="# >>> BRIDGE_CONDUCTOR_HOOK_START >>>",BRIDGE_CONDUCTOR_HOOK_END="# <<< BRIDGE_CONDUCTOR_HOOK_END <<<",MANAGED_HOOK_NAMES=["post-commit","reference-transaction"];function resolveGitHooksDirectory(deps={}){let runGit=deps.runGit??runGitCommand,cwd=deps.cwd??process.cwd(),result=runGit(["rev-parse","--git-common-dir"],{cwd});if(!result.ok)return{is_worktree:!1,hooks_dir:null};let commonDir=result.stdout.trim();if(commonDir.length===0)return{is_worktree:!1,hooks_dir:null};let absoluteCommonDir=isAbsolute(commonDir)?commonDir:resolve(cwd,commonDir);return{is_worktree:!0,hooks_dir:resolve(absoluteCommonDir,"hooks")}}function defaultConductorBin(){return resolve(dirname(fileURLToPath(import.meta.url)),"..","conductor-bin.js")}function wrapManagedBlock(body){return[BRIDGE_CONDUCTOR_HOOK_START,body,BRIDGE_CONDUCTOR_HOOK_END].join(`
136
+ `)),waitForEvent=deps.waitForEvent??waitForConductorEvent,getSnapshot=deps.getSnapshot??getSupervisorSnapshot,upsertProjection=deps.upsertProjection??upsertSupervisorProjection,emitAssessment=deps.emitAssessment??emitSupervisorAssessmentIfNew,sendMessage=deps.sendWorkerMessage??sendWorkerMessage,resolveBridgeAccess=deps.resolveBridgeAccess??(()=>resolveConductorBridgeApiAccess()),processMerge=deps.processMerge??processGateMetMerge,dispatchNotification=deps.dispatchNotification??dispatchSupervisorNotification,bridgeAccess=null,bridgeAccessResolved=!1,processGateMetMerges=async events=>{let eligible=events.filter(e=>extractMergeActionIdentityFromGateEvent(e)!==null);if(eligible.length!==0){if(!bridgeAccessResolved){bridgeAccessResolved=!0;try{let result=await resolveBridgeAccess();bridgeAccess=result.ok?result.access:null,result.ok||errorLog(`[supervisor] run=${runId} auto-merge disabled: ${result.kind}`)}catch{bridgeAccess=null}}if(bridgeAccess)for(let event of eligible)try{await processMerge(bridgeAccess,event)}catch{}}},persist=async state2=>{try{await upsertProjection(toSupervisorProjectionInput(state2))}catch{}},state;try{let snapshot=await getSnapshot(runId);state=hydrateSupervisorRunStateFromSnapshot(snapshot,runId,config,now())}catch{return{run_id:runId,status:"failed",exit_code:2,reason:"supervisor failed to load initial snapshot",last_seq:0,worker_count:0}}let sinceSeq=state.last_seq>0?state.last_seq+1:1,iterationCap=Math.max(1e3,Math.ceil(config.global_timeout_ms/Math.max(1,config.wake_interval_ms))+16);try{applySupervisorHousekeeping(state,config,now());for(let iteration=0;iteration<iterationCap;iteration+=1){if(isSupervisorRunTerminal(state))return state.status=terminalStatus(state),await persist(state),log(`[supervisor] run=${runId} complete status=${state.status} workers=${Object.keys(state.workers).length}`),{run_id:runId,status:state.status,exit_code:0,reason:"all workers terminal",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length};if(hasSupervisorGlobalTimeoutElapsed(state,now()))return state.status="timed_out",await persist(state),errorLog(`[supervisor] run=${runId} global timeout elapsed`),{run_id:runId,status:"timed_out",exit_code:2,reason:"global timeout elapsed",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length};let waitResult=await waitForEvent({since_seq:sinceSeq,filter:{run_id:runId},data_mode:"full",timeout_ms:config.wake_interval_ms,limit:config.poll_limit});if(waitResult.events.length>0){let sorted=[...waitResult.events].sort((a,b)=>a.seq-b.seq);for(let event of sorted)applyConductorEventToSupervisorState(state,event,now());sinceSeq=sorted[sorted.length-1].seq+1,await processGateMetMerges(sorted)}applySupervisorHousekeeping(state,config,now()),await processEscalations(state,config,{emitAssessment,sendWorkerMessage:sendMessage,log,now,dispatchNotification}),await persist(state)}return state.status="timed_out",await persist(state),{run_id:runId,status:"timed_out",exit_code:2,reason:"supervisor iteration cap reached",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length}}catch{state.status="failed";try{await upsertProjection(toSupervisorProjectionInput(state))}catch{}return errorLog(`[supervisor] run=${runId} failed unexpectedly`),{run_id:runId,status:"failed",exit_code:2,reason:"supervisor failed unexpectedly",last_seq:state.last_seq,worker_count:Object.keys(state.workers).length}}}var init_supervisor_runtime=__esm({"src/conductor/supervisor-runtime.ts"(){"use strict";init_store();init_supervisor_ledger();init_supervisor_message_relay();init_supervisor_config();init_supervisor_state();init_supervisor_escalation();init_supervisor_ledger();init_bridge_api_client();init_merge_ledger();init_supervisor_merge();init_supervisor_notification();init_errors()}});init_errors();init_store();init_producer_ledger();init_taxonomy();import{readFileSync as readFileSync3,unlinkSync}from"node:fs";init_git_inspection();import{chmodSync,existsSync as existsSync2,mkdirSync,readFileSync,realpathSync,statSync,writeFileSync}from"node:fs";import{basename as basename2,dirname,isAbsolute,join,resolve}from"node:path";import{fileURLToPath}from"node:url";var BRIDGE_CONDUCTOR_HOOK_START="# >>> BRIDGE_CONDUCTOR_HOOK_START >>>",BRIDGE_CONDUCTOR_HOOK_END="# <<< BRIDGE_CONDUCTOR_HOOK_END <<<",MANAGED_HOOK_NAMES=["post-commit","reference-transaction"];function resolveGitHooksDirectory(deps={}){let runGit=deps.runGit??runGitCommand,cwd=deps.cwd??process.cwd(),result=runGit(["rev-parse","--git-common-dir"],{cwd});if(!result.ok)return{is_worktree:!1,hooks_dir:null};let commonDir=result.stdout.trim();if(commonDir.length===0)return{is_worktree:!1,hooks_dir:null};let absoluteCommonDir=isAbsolute(commonDir)?commonDir:resolve(cwd,commonDir);return{is_worktree:!0,hooks_dir:resolve(absoluteCommonDir,"hooks")}}var CONDUCTOR_BIN_FILENAME="conductor-bin.js",CONDUCTOR_HOOK_BIN_UNRESOLVED_REASON=`no usable ${CONDUCTOR_BIN_FILENAME} was found for the executing artifact (searched: the sibling bundle layout, the parent TypeScript-emit layout, and the invocation target when it is named ${CONDUCTOR_BIN_FILENAME}). Reinstall or rebuild the package so a conductor binary ships beside the executing module.`;function resolveConductorHookBin(overrides={}){let deps={moduleUrl:overrides.moduleUrl??import.meta.url,argv1:overrides.argv1??process.argv[1],realpath:overrides.realpath??defaultRealpath,isFile:overrides.isFile??defaultIsFile},moduleFile=moduleFilePath(deps.moduleUrl),candidates=[];if(moduleFile!==null){let dir=dirname(moduleFile);candidates.push(join(dir,CONDUCTOR_BIN_FILENAME)),candidates.push(join(dir,"..",CONDUCTOR_BIN_FILENAME))}typeof deps.argv1=="string"&&deps.argv1.length>0&&basename2(deps.argv1)===CONDUCTOR_BIN_FILENAME&&candidates.push(deps.argv1);let seen=new Set;for(let candidate of candidates){let canonical;try{canonical=deps.realpath(candidate)}catch{continue}if(canonical!==null&&!seen.has(canonical)){seen.add(canonical);try{if(deps.isFile(canonical))return{ok:!0,path:canonical}}catch{continue}}}return{ok:!1,reason:CONDUCTOR_HOOK_BIN_UNRESOLVED_REASON}}function moduleFilePath(moduleUrl){try{return fileURLToPath(moduleUrl)}catch{return null}}function defaultRealpath(filePath){try{return realpathSync(filePath)}catch{return null}}function defaultIsFile(filePath){try{return statSync(filePath).isFile()}catch{return!1}}function wrapManagedBlock(body){return[BRIDGE_CONDUCTOR_HOOK_START,body,BRIDGE_CONDUCTOR_HOOK_END].join(`
137
137
  `)}function buildPostCommitHookSnippet(conductorBin){let body=["# Managed by Bridge conductor (BAPI-395). Local, unversioned, opportunistic, bypassable.",`( node ${JSON.stringify(conductorBin)} git-hook post-commit >/dev/null 2>&1 & ) || true`].join(`
138
138
  `);return wrapManagedBlock(body)}function buildReferenceTransactionHookSnippet(conductorBin){let body=["# Managed by Bridge conductor (BAPI-395). Local, unversioned, opportunistic, bypassable.",'__bridge_tmp="$(mktemp 2>/dev/null || echo "/tmp/bridge-conductor-refs.$$")"','cat > "$__bridge_tmp"',`( node ${JSON.stringify(conductorBin)} git-hook reference-transaction --phase "$1" --stdin-file "$__bridge_tmp" >/dev/null 2>&1 & ) || true`].join(`
139
139
  `);return wrapManagedBlock(body)}function looksBinary(content){return content.includes("\0")}function mergeManagedHookSnippet(existing,managedBlock){if(existing===null||existing.length===0)return{ok:!0,content:`#!/bin/sh
@@ -141,16 +141,16 @@ ${managedBlock}
141
141
  `,action:"created"};if(looksBinary(existing))return{ok:!1,content:existing,action:"skipped",warning:"existing hook appears binary/unsafe to merge; left untouched"};let startIdx=existing.indexOf(BRIDGE_CONDUCTOR_HOOK_START),endIdx=existing.indexOf(BRIDGE_CONDUCTOR_HOOK_END);if(startIdx!==-1&&endIdx!==-1&&endIdx>startIdx){let before=existing.slice(0,startIdx),after=existing.slice(endIdx+BRIDGE_CONDUCTOR_HOOK_END.length);return{ok:!0,content:`${before}${managedBlock}${after}`,action:"replaced"}}let separator=existing.endsWith(`
142
142
  `)?"":`
143
143
  `;return{ok:!0,content:`${existing}${separator}${managedBlock}
144
- `,action:"appended"}}function snippetForHook(name,conductorBin){return name==="post-commit"?buildPostCommitHookSnippet(conductorBin):buildReferenceTransactionHookSnippet(conductorBin)}function installConductorGitHooks(deps={}){let platform=deps.platform??process.platform,conductorBin=deps.conductorBin??defaultConductorBin(),{is_worktree,hooks_dir}=resolveGitHooksDirectory(deps);if(!is_worktree||hooks_dir===null)return{is_worktree:!1,hooks_dir:null,installed:[],warnings:["not a git worktree; git hooks were not installed (degraded optional capability)"]};let warnings=[];existsSync2(hooks_dir)||mkdirSync(hooks_dir,{recursive:!0});let installed=[];for(let name of MANAGED_HOOK_NAMES){let hookPath=resolve(hooks_dir,name),existing=null;if(existsSync2(hookPath))try{existing=readFileSync(hookPath,"utf-8")}catch{installed.push({name,path:hookPath,action:"skipped",warning:"could not read existing hook"}),warnings.push(`could not read existing ${name} hook; left untouched`);continue}let merge=mergeManagedHookSnippet(existing,snippetForHook(name,conductorBin));if(!merge.ok){installed.push({name,path:hookPath,action:"skipped",warning:merge.warning}),merge.warning&&warnings.push(`${name}: ${merge.warning}`);continue}if(writeFileSync(hookPath,merge.content,"utf-8"),platform!=="win32")try{chmodSync(hookPath,493)}catch{warnings.push(`could not mark ${name} executable`)}installed.push({name,path:hookPath,action:merge.action})}return{is_worktree:!0,hooks_dir,installed,warnings}}function inspectConductorGitHooks(deps={}){let platform=deps.platform??process.platform,{is_worktree,hooks_dir}=resolveGitHooksDirectory(deps);if(!is_worktree||hooks_dir===null)return{is_worktree:!1,hooks_dir:null,hooks:[],warnings:["not a git worktree; conductor git hooks are unavailable (degraded optional capability)"],degraded:!0};let warnings=[],hooks=[];for(let name of MANAGED_HOOK_NAMES){let hookPath=resolve(hooks_dir,name),exists=existsSync2(hookPath),executable=!1,managedPresent=!1;if(exists){try{let mode=statSync(hookPath).mode;executable=platform==="win32"?!0:(mode&73)!==0}catch{}try{managedPresent=readFileSync(hookPath,"utf-8").includes(BRIDGE_CONDUCTOR_HOOK_START)}catch{}}else warnings.push(`${name} hook not installed (degraded optional capability)`);hooks.push({name,path:hookPath,exists,executable,managed_block_present:managedPresent})}let degraded=hooks.some(h=>!h.exists||!h.managed_block_present);return{is_worktree:!0,hooks_dir,hooks,warnings,degraded}}init_file_scope_guard();init_git_ci_types();init_git_inspection();init_producer_ledger();var COMMITTED_REF_PHASE="committed";function buildCommitCreatedEventInput(context,metadata){let details={repo:context.repo,branch:context.branch,worktree_path:context.worktree_path,commit_sha:metadata.sha,parent_shas:metadata.parents,author:{name:metadata.author_name,email:metadata.author_email},committer:{name:metadata.committer_name,email:metadata.committer_email},co_authors:metadata.co_authors,authored_at:metadata.authored_at,committed_at:metadata.committed_at,subject:metadata.subject,attribution_source:metadata.attribution_source};return{source:"git",type:"git.commit_created",subject:context.repo,producer:GIT_HOOK_PRODUCER,observed_via:"git-hook:post-commit",data:{summary:`Commit ${metadata.sha??"(unknown)"} on ${context.branch??"(detached)"}`,status:"created",details}}}function buildWorktreeChangedEventInput(context,updates,phase){let updatesHash=stableJsonHash({phase,updates}),details={repo:context.repo,branch:context.branch,worktree_path:context.worktree_path,transaction_phase:phase,ref_updates:updates,updates_hash:updatesHash};return{source:"git",type:"worktree.changed",subject:context.repo,producer:GIT_HOOK_PRODUCER,observed_via:"git-hook:reference-transaction",data:{summary:`${updates.length} ref update(s) on ${context.repo}`,status:"changed",details}}}async function runPostCommitHookProducer(deps={}){let getContext=deps.getContext??getGitWorktreeContext,readMetadata=deps.readMetadata??readHeadCommitMetadata,emitIfNew=deps.emitIfNew??emitConductorEventIfNew;try{let context=getContext({cwd:deps.cwd,env:deps.env}),metadata=readMetadata({cwd:deps.cwd});if(!metadata||metadata.sha===null)return{ok:!0,emitted:!1,reason:"no-head-commit"};let input=buildCommitCreatedEventInput(context,metadata),decision=await emitIfNew(input,{event_type:"git.commit_created",repo:context.repo,commit_sha:metadata.sha});return{ok:!0,emitted:decision.emitted,reason:decision.reason}}catch{return{ok:!0,emitted:!1,reason:"skipped"}}}async function runReferenceTransactionHookProducer(args,deps={}){let getContext=deps.getContext??getGitWorktreeContext,parseUpdates=deps.parseUpdates??parseReferenceTransactionUpdates,emitIfNew=deps.emitIfNew??emitConductorEventIfNew;try{if(args.phase!==COMMITTED_REF_PHASE)return{ok:!0,emitted:!1,reason:"non-committed-phase"};let updates=parseUpdates(args.stdin);if(updates.length===0)return{ok:!0,emitted:!1,reason:"no-updates"};let context=getContext({cwd:deps.cwd,env:deps.env}),input=buildWorktreeChangedEventInput(context,updates,args.phase),refUpdatesHash=stableJsonHash({phase:args.phase,updates}),decision=await emitIfNew(input,{event_type:"worktree.changed",repo:context.repo,ref_updates_hash:refUpdatesHash});return{ok:!0,emitted:decision.emitted,reason:decision.reason}}catch{return{ok:!0,emitted:!1,reason:"skipped"}}}init_store();import{spawnSync as spawnSync2}from"node:child_process";import{existsSync as existsSync3,readFileSync as readFileSync2}from"node:fs";import{readFile as readFileAsync}from"node:fs/promises";import os3 from"node:os";import path3 from"path";async function detectClaudeLogin(deps){let raw;try{raw=await deps.readFile(path3.join(deps.homedir(),".claude.json"))}catch{return{detected:!1}}let parsed;try{parsed=JSON.parse(raw)}catch{return{detected:!1}}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return{detected:!1};let oauthAccount=parsed.oauthAccount;return oauthAccount!==null&&typeof oauthAccount=="object"&&!Array.isArray(oauthAccount)?{detected:!0}:{detected:!1}}function formatClaudeLoginAdvisory(result){return result.detected?"Claude login: detected (~/.claude.json has an OAuth account). This is advisory only \u2014 it does not guarantee the next worker spawn will authenticate.":"Claude login: not detected. Run `claude login` on this host, or, on a headless host, export CLAUDE_CODE_OAUTH_TOKEN before starting the executor."}init_mcp_server_invocation();function skippedDenyEnforcementResult(){return{enforced:!1,layer:"none",degraded:!0,status:"skip",detail:"deny-enforcement preflight skipped via --no-deny-probe (no agent spawned)",warnings:["Deny-enforcement preflight was SKIPPED (--no-deny-probe): enforcement is UNVERIFIED on this host. Do not treat this report as evidence the deny layer works."]}}async function defaultReadPackageJson(){let packageRoot=resolvePackageRootFromModuleUrl(import.meta.url);if(!packageRoot)throw new Error("unable to resolve package root for package.json");return readFileSync2(`${packageRoot}/package.json`,"utf8")}function readExpectedNodeEngine(packageJsonText){try{let node=JSON.parse(packageJsonText).engines?.node;return typeof node=="string"?node:null}catch{return null}}async function inspectNativeLedger(nativeLoad,deps={}){let warnings=[],engines_node=null;try{let readPkg=deps.readPackageJson??defaultReadPackageJson;engines_node=readExpectedNodeEngine(await readPkg())}catch{engines_node=null}let invocation=deps.resolveMcpInvocation?deps.resolveMcpInvocation():resolveMcpShimInvocationForRuntime({moduleUrl:import.meta.url,nodeExecutable:"node",argv1:process.argv[1],fileExists:existsSync3}),mcp_shim_node=invocation.form==="absolute-build-path"?invocation.nodeExecutable:null,binding_loads=nativeLoad.loads,failure_kind=nativeLoad.failure_kind;nativeLoad.degraded&&nativeLoad.warning&&warnings.push(nativeLoad.warning),invocation.form!=="absolute-build-path"&&warnings.push("Worker MCP registration would use the npm-channel fallback (no resolvable on-disk build entry); registration reliability depends on the package being published."),engines_node===null&&warnings.push("Could not read package.json engines.node; expected Node version is unknown.");let degraded=nativeLoad.degraded||invocation.form!=="absolute-build-path"||engines_node===null;return{cli_node_version:process.version,engines_node,mcp_shim_node,mcp_registration_form:invocation.form,module:nativeLoad.module,node_modules_abi:nativeLoad.node_modules_abi,binding_loads,failure_kind,degraded,warnings}}async function inspectEpicTickSchedule(deps,orchestrateListOverride){try{let schedRun=orchestrateListOverride?null:await Promise.resolve().then(()=>(init_schedule_run(),schedule_run_exports)),doList=orchestrateListOverride||(d=>schedRun.orchestrateScheduleList({json:!1},d)),resolvedDeps=orchestrateListOverride?deps:deps??schedRun.createDefaultScheduleRunDeps(),commandLabel=schedRun?schedRun.scheduleCommandLabel:m2=>m2.command??(m2.idea_file?"full-automation":"(unknown)"),runStatus=schedRun?schedRun.latestRunStatus:m2=>{let h=m2.run_history;return h&&h.length>0?h[h.length-1].status:""},entry=(await doList(resolvedDeps)).entries.find(e=>commandLabel(e.metadata)==="epic-tick");if(!entry)return{registered:!1,backend:null,next_fire_iso:null,latest_run_status:null,degraded:!1,warnings:[]};let m=entry.metadata,latest=runStatus(m);return{registered:!0,backend:m.backend??null,next_fire_iso:m.run_at_iso??null,latest_run_status:latest||null,degraded:!0,warnings:[`An epic-tick schedule is registered, but the v1 \`conductor epic-tick\` path is frozen (EPIC_TICK_V1_FROZEN) \u2014 it advances nothing. Cancel it: \`npx -y @bridge_gpt/mcp-server schedule-run cancel --id ${entry.metadata.id??"<id>"}\`. Epic Conductor v2 reconciles server-side; run jobs locally with \`npx -y @bridge_gpt/mcp-server executor --repo <name>\`.`]}}catch(err){return{registered:!1,backend:null,next_fire_iso:null,latest_run_status:null,degraded:!0,warnings:[`Failed to inspect epic-tick schedule: ${err instanceof Error?err.message:String(err)}`]}}}function inspectMcpProfile(env,epicTick){let resolved_profile=env.BRIDGE_MCP_PROFILE||"core",conductor_context_detected=env.BAPI_CONDUCTOR_ENABLED==="1"||env.BAPI_CONDUCTOR_ENABLED==="true"||epicTick.registered,degraded=conductor_context_detected&&resolved_profile!=="conductor",warnings=[];return degraded&&warnings.push(`BRIDGE_MCP_PROFILE is "${resolved_profile}" but a conductor context is active. Expected "conductor" \u2014 conductor/event/supervisor tools may be missing. Ensure the spawner injects BRIDGE_MCP_PROFILE=conductor into the worker shell environment.`),{resolved_profile,conductor_context_detected,degraded,warnings}}function inspectLocalMerge(runCommand){let run=runCommand??((cmd,args)=>{try{return{status:spawnSync2(cmd,args,{encoding:"utf8",timeout:1e4,env:{...process.env,GH_PROMPT_DISABLED:"1"}}).status}}catch{return{status:null}}}),gh_available=!1,gh_authed=!1;try{gh_available=run("gh",["--version"]).status===0}catch{gh_available=!1}if(gh_available)try{gh_authed=run("gh",["auth","status"]).status===0}catch{gh_authed=!1}let warnings=[];return gh_available?gh_authed||warnings.push("`gh` is installed but not authenticated (`gh auth status` failed). Run `gh auth login` to grant the conductor merge permission; otherwise local merge will emit merge.failed/skip."):warnings.push("`gh` is not installed or not on PATH. Local merge (policy_json.local_merge.enabled) cannot run; install the GitHub CLI to enable conductor-driven merges."),{gh_available,gh_authed,degraded:!gh_available||!gh_authed,warnings}}async function buildConductorDoctorReport(deps={}){let doctorLedger=deps.doctorLedger??doctorConductorLedger,inspectHooks=deps.inspectHooks??inspectConductorGitHooks,epicTick=await inspectEpicTickSchedule(deps.scheduleDeps,deps.orchestrateList),mcp_profile=inspectMcpProfile(deps.env??process.env,epicTick),ledger=await doctorLedger(),native_ledger=await inspectNativeLedger(ledger.native_load,deps),deny_enforcement=deps.skipDenyProbe?skippedDenyEnforcementResult():await inspectDenyEnforcementSafe(deps.inspectDenyEnforcement),claude_login=await detectClaudeLogin({homedir:deps.claudeLoginDeps?.homedir??os3.homedir,readFile:deps.claudeLoginDeps?.readFile??(p=>readFileAsync(p,"utf-8"))});return{ledger,git_hooks:inspectHooks(deps.hooksDeps),epic_tick:epicTick,mcp_profile,local_merge:inspectLocalMerge(deps.runCommand),native_ledger,deny_enforcement,claude_login}}async function inspectDenyEnforcementSafe(inspect){try{let run=inspect;return run||(run=(await Promise.resolve().then(()=>(init_deny_enforcement_preflight(),deny_enforcement_preflight_exports))).runDenyEnforcementPreflight),await run()}catch(err){return{enforced:!1,layer:"none",degraded:!0,warnings:[`Deny-layer enforcement inspection failed: ${err instanceof Error?err.message:String(err)}`,"The executor claim loop MUST refuse to claim jobs until the deny layer is enforced."]}}}function formatConductorDoctorReport(report){let{ledger,git_hooks,epic_tick,mcp_profile,local_merge,native_ledger,deny_enforcement,claude_login}=report,lines=["Conductor ledger doctor","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`path: ${ledger.path}`,`directory exists: ${ledger.directory_exists}`,`database exists: ${ledger.database_exists}`,`directory mode: ${ledger.directory_mode??"n/a"} (ok: ${ledger.directory_permissions_ok})`,`database mode: ${ledger.database_mode??"n/a"} (ok: ${ledger.database_permissions_ok})`,`schema present: ${ledger.schema_present}`,`journal mode: ${ledger.journal_mode??"n/a"}`,`user_version: ${ledger.user_version??"n/a"}`,`event count: ${ledger.event_count??"n/a"}`,`max seq: ${ledger.max_seq??"n/a"}`,`busy_timeout_ms: ${ledger.retention.busy_timeout_ms}`,`retention_days: ${ledger.retention.retention_days}`,`retention_max_rows: ${ledger.retention.retention_max_rows}`,`message_cooldown_ms: ${ledger.message_relay.message_cooldown_ms}`,`degraded (network FS): ${ledger.degraded}`];if(ledger.warnings.length>0){lines.push("warnings:");for(let w of ledger.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("git hooks (optional, local)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),lines.push(`is git worktree: ${git_hooks.is_worktree}`),lines.push(`hooks dir: ${git_hooks.hooks_dir??"n/a"}`),lines.push(`degraded: ${git_hooks.degraded}`);for(let hook of git_hooks.hooks)lines.push(` ${hook.name}: exists=${hook.exists} executable=${hook.executable} managed=${hook.managed_block_present}`);if(git_hooks.warnings.length>0){lines.push("git hook warnings:");for(let w of git_hooks.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Epic Supervisor Schedule (v1 epic-tick \u2014 frozen)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let registeredTag=epic_tick.registered?"[WARNING] registered \u2014 dead timer, remove it":"[SUCCESS] none registered (v1 is frozen)";if(lines.push(`epic-tick schedule: ${registeredTag}`),epic_tick.registered&&(lines.push(`backend: ${epic_tick.backend??"n/a"}`),lines.push(`next fire: ${epic_tick.next_fire_iso??"n/a"}`),lines.push(`latest run status: ${epic_tick.latest_run_status??"n/a"}`)),lines.push(`degraded: ${epic_tick.degraded}`),epic_tick.warnings.length>0){lines.push("epic-tick warnings:");for(let w of epic_tick.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Epic Conductor v2 reconciles epics server-side \u2014 nothing to schedule"),lines.push("locally. To execute claimed jobs on this machine, run:"),lines.push(" npx -y @bridge_gpt/mcp-server executor --repo <name>"),lines.push(""),lines.push("MCP Profile (optional, local)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let profileTag=mcp_profile.degraded?"[WARNING] degraded":"[OK]";if(lines.push(`resolved profile: ${mcp_profile.resolved_profile} ${profileTag}`),lines.push(`conductor context: ${mcp_profile.conductor_context_detected}`),lines.push(`degraded: ${mcp_profile.degraded}`),mcp_profile.warnings.length>0){lines.push("mcp profile warnings:");for(let w of mcp_profile.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Local merge capability (optional, opt-in)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let ghTag=local_merge.gh_available?local_merge.gh_authed?"[OK]":"[WARNING] not authenticated":"[WARNING] not installed";if(lines.push(`gh available: ${local_merge.gh_available} ${ghTag}`),lines.push(`gh authenticated: ${local_merge.gh_authed}`),lines.push(`degraded: ${local_merge.degraded}`),local_merge.warnings.length>0){lines.push("local merge warnings:");for(let w of local_merge.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Native ledger module (required for conductor coordination)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let nativeTag=native_ledger.binding_loads&&!native_ledger.degraded?"[OK]":"[WARNING] degraded";if(lines.push(`binding loads: ${native_ledger.binding_loads} ${nativeTag}`),lines.push(`module: ${native_ledger.module}`),lines.push(`CLI Node: ${native_ledger.cli_node_version}`),lines.push(`engines.node: ${native_ledger.engines_node??"n/a"}`),lines.push(`MCP shim Node: ${native_ledger.mcp_shim_node??"n/a"}`),lines.push(`NODE_MODULE_VERSION: ${native_ledger.node_modules_abi}`),lines.push(`registration form: ${native_ledger.mcp_registration_form}`),lines.push(`failure kind: ${native_ledger.failure_kind}`),lines.push(`degraded: ${native_ledger.degraded}`),native_ledger.warnings.length>0){lines.push("native ledger warnings:");for(let w of native_ledger.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Deny-layer enforcement preflight (required for executor claim)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let denyTag=deny_enforcement.status==="skip"?"[SKIPPED] probe not run (--no-deny-probe) \u2014 enforcement unverified":deny_enforcement.enforced?deny_enforcement.degraded?"[WARNING] degraded \u2014 relying on PreToolUse fallback":"[OK]":"[FATAL] deny not enforced \u2014 executor must refuse to claim jobs";if(lines.push(`enforced: ${deny_enforcement.enforced} ${denyTag}`),lines.push(`layer: ${deny_enforcement.layer}`),lines.push(`degraded: ${deny_enforcement.degraded}`),deny_enforcement.warnings.length>0){lines.push("deny enforcement warnings:");for(let w of deny_enforcement.warnings)lines.push(` - ${w}`)}return lines.push(""),lines.push(formatClaudeLoginAdvisory(claude_login)),lines.join(`
144
+ `,action:"appended"}}var CONDUCTOR_BIN_UNRESOLVED_ERROR="CONDUCTOR_BIN_UNRESOLVED";function snippetForHook(name,conductorBin){return name==="post-commit"?buildPostCommitHookSnippet(conductorBin):buildReferenceTransactionHookSnippet(conductorBin)}function validateResolvedBin(resolution){if(!resolution.ok)return resolution;let canonical=defaultRealpath(resolution.path);return canonical===null||!defaultIsFile(canonical)?{ok:!1,reason:CONDUCTOR_HOOK_BIN_UNRESOLVED_REASON}:{ok:!0,path:canonical}}function installConductorGitHooks(deps={}){let platform=deps.platform??process.platform,resolution=validateResolvedBin(deps.resolveBin?deps.resolveBin():resolveConductorHookBin());if(!resolution.ok)return{ok:!1,error:CONDUCTOR_BIN_UNRESOLVED_ERROR,reason:resolution.reason};let conductorBin=resolution.path,{is_worktree,hooks_dir}=resolveGitHooksDirectory(deps);if(!is_worktree||hooks_dir===null)return{ok:!0,is_worktree:!1,hooks_dir:null,installed:[],warnings:["not a git worktree; git hooks were not installed (degraded optional capability)"],conductor_bin:conductorBin};let warnings=[];existsSync2(hooks_dir)||mkdirSync(hooks_dir,{recursive:!0});let installed=[];for(let name of MANAGED_HOOK_NAMES){let hookPath=resolve(hooks_dir,name),existing=null;if(existsSync2(hookPath))try{existing=readFileSync(hookPath,"utf-8")}catch{installed.push({name,path:hookPath,action:"skipped",warning:"could not read existing hook"}),warnings.push(`could not read existing ${name} hook; left untouched`);continue}let merge=mergeManagedHookSnippet(existing,snippetForHook(name,conductorBin));if(!merge.ok){installed.push({name,path:hookPath,action:"skipped",warning:merge.warning}),merge.warning&&warnings.push(`${name}: ${merge.warning}`);continue}if(writeFileSync(hookPath,merge.content,"utf-8"),platform!=="win32")try{chmodSync(hookPath,493)}catch{warnings.push(`could not mark ${name} executable`)}installed.push({name,path:hookPath,action:merge.action})}return{ok:!0,is_worktree:!0,hooks_dir,installed,warnings,conductor_bin:conductorBin}}function extractManagedHookBinPath(content){let startIdx=content.indexOf(BRIDGE_CONDUCTOR_HOOK_START),endIdx=content.indexOf(BRIDGE_CONDUCTOR_HOOK_END);if(startIdx===-1||endIdx===-1||endIdx<=startIdx)return null;let block=content.slice(startIdx,endIdx),match=/\bnode\s+("(?:[^"\\]|\\.)*")\s+git-hook\b/.exec(block);if(match===null)return null;try{let parsed=JSON.parse(match[1]);return typeof parsed=="string"&&parsed.length>0?parsed:null}catch{return null}}function inspectConductorGitHooks(deps={}){let platform=deps.platform??process.platform,{is_worktree,hooks_dir}=resolveGitHooksDirectory(deps);if(!is_worktree||hooks_dir===null)return{is_worktree:!1,hooks_dir:null,hooks:[],warnings:["not a git worktree; conductor git hooks are unavailable (degraded optional capability)"],degraded:!0};let warnings=[],hooks=[];for(let name of MANAGED_HOOK_NAMES){let hookPath=resolve(hooks_dir,name),exists=existsSync2(hookPath),executable=!1,managedPresent=!1,embeddedBinPath=null,embeddedBinIsFile=!1;if(exists){try{let mode=statSync(hookPath).mode;executable=platform==="win32"?!0:(mode&73)!==0}catch{}try{let content=readFileSync(hookPath,"utf-8");managedPresent=content.includes(BRIDGE_CONDUCTOR_HOOK_START),managedPresent&&(embeddedBinPath=extractManagedHookBinPath(content),embeddedBinIsFile=embeddedBinPath!==null&&defaultIsFile(embeddedBinPath),embeddedBinPath===null?warnings.push(`${name} hook has a managed block with no recognizable conductor command; reinstall with \`conductor install-git-hooks\``):embeddedBinIsFile||warnings.push(`${name} hook points at a missing or invalid conductor binary (${embeddedBinPath}); the hook is dead \u2014 reinstall with \`conductor install-git-hooks\``))}catch{}}else warnings.push(`${name} hook not installed (degraded optional capability)`);hooks.push({name,path:hookPath,exists,executable,managed_block_present:managedPresent,embedded_bin_path:embeddedBinPath,embedded_bin_is_file:embeddedBinIsFile})}let degraded=hooks.some(h=>!h.exists||!h.managed_block_present||!h.embedded_bin_is_file);return{is_worktree:!0,hooks_dir,hooks,warnings,degraded}}init_file_scope_guard();init_git_ci_types();init_git_inspection();init_producer_ledger();var COMMITTED_REF_PHASE="committed";function buildCommitCreatedEventInput(context,metadata){let details={repo:context.repo,branch:context.branch,worktree_path:context.worktree_path,commit_sha:metadata.sha,parent_shas:metadata.parents,author:{name:metadata.author_name,email:metadata.author_email},committer:{name:metadata.committer_name,email:metadata.committer_email},co_authors:metadata.co_authors,authored_at:metadata.authored_at,committed_at:metadata.committed_at,subject:metadata.subject,attribution_source:metadata.attribution_source};return{source:"git",type:"git.commit_created",subject:context.repo,producer:GIT_HOOK_PRODUCER,observed_via:"git-hook:post-commit",data:{summary:`Commit ${metadata.sha??"(unknown)"} on ${context.branch??"(detached)"}`,status:"created",details}}}function buildWorktreeChangedEventInput(context,updates,phase){let updatesHash=stableJsonHash({phase,updates}),details={repo:context.repo,branch:context.branch,worktree_path:context.worktree_path,transaction_phase:phase,ref_updates:updates,updates_hash:updatesHash};return{source:"git",type:"worktree.changed",subject:context.repo,producer:GIT_HOOK_PRODUCER,observed_via:"git-hook:reference-transaction",data:{summary:`${updates.length} ref update(s) on ${context.repo}`,status:"changed",details}}}async function runPostCommitHookProducer(deps={}){let getContext=deps.getContext??getGitWorktreeContext,readMetadata=deps.readMetadata??readHeadCommitMetadata,emitIfNew=deps.emitIfNew??emitConductorEventIfNew;try{let context=getContext({cwd:deps.cwd,env:deps.env}),metadata=readMetadata({cwd:deps.cwd});if(!metadata||metadata.sha===null)return{ok:!0,emitted:!1,reason:"no-head-commit"};let input=buildCommitCreatedEventInput(context,metadata),decision=await emitIfNew(input,{event_type:"git.commit_created",repo:context.repo,commit_sha:metadata.sha});return{ok:!0,emitted:decision.emitted,reason:decision.reason}}catch{return{ok:!0,emitted:!1,reason:"skipped"}}}async function runReferenceTransactionHookProducer(args,deps={}){let getContext=deps.getContext??getGitWorktreeContext,parseUpdates=deps.parseUpdates??parseReferenceTransactionUpdates,emitIfNew=deps.emitIfNew??emitConductorEventIfNew;try{if(args.phase!==COMMITTED_REF_PHASE)return{ok:!0,emitted:!1,reason:"non-committed-phase"};let updates=parseUpdates(args.stdin);if(updates.length===0)return{ok:!0,emitted:!1,reason:"no-updates"};let context=getContext({cwd:deps.cwd,env:deps.env}),input=buildWorktreeChangedEventInput(context,updates,args.phase),refUpdatesHash=stableJsonHash({phase:args.phase,updates}),decision=await emitIfNew(input,{event_type:"worktree.changed",repo:context.repo,ref_updates_hash:refUpdatesHash});return{ok:!0,emitted:decision.emitted,reason:decision.reason}}catch{return{ok:!0,emitted:!1,reason:"skipped"}}}init_store();import{spawnSync as spawnSync2}from"node:child_process";import{existsSync as existsSync3,readFileSync as readFileSync2}from"node:fs";import{readFile as readFileAsync}from"node:fs/promises";import os3 from"node:os";import path3 from"path";async function detectClaudeLogin(deps){let raw;try{raw=await deps.readFile(path3.join(deps.homedir(),".claude.json"))}catch{return{detected:!1}}let parsed;try{parsed=JSON.parse(raw)}catch{return{detected:!1}}if(!parsed||typeof parsed!="object"||Array.isArray(parsed))return{detected:!1};let oauthAccount=parsed.oauthAccount;return oauthAccount!==null&&typeof oauthAccount=="object"&&!Array.isArray(oauthAccount)?{detected:!0}:{detected:!1}}function formatClaudeLoginAdvisory(result){return result.detected?"Claude login: detected (~/.claude.json has an OAuth account). This is advisory only \u2014 it does not guarantee the next worker spawn will authenticate.":"Claude login: not detected. Run `claude login` on this host, or, on a headless host, export CLAUDE_CODE_OAUTH_TOKEN before starting the executor."}init_mcp_server_invocation();init_mcp_identity();init_mcp_profile();var MCP_PROFILE_UNSET="(unset)";function skippedDenyEnforcementResult(){return{enforced:!1,layer:"none",degraded:!0,status:"skip",detail:"deny-enforcement preflight skipped via --no-deny-probe (no agent spawned)",warnings:["Deny-enforcement preflight was SKIPPED (--no-deny-probe): enforcement is UNVERIFIED on this host. Do not treat this report as evidence the deny layer works."]}}async function defaultReadPackageJson(){let packageRoot=resolvePackageRootFromModuleUrl(import.meta.url);if(!packageRoot)throw new Error("unable to resolve package root for package.json");return readFileSync2(`${packageRoot}/package.json`,"utf8")}function readExpectedNodeEngine(packageJsonText){try{let node=JSON.parse(packageJsonText).engines?.node;return typeof node=="string"?node:null}catch{return null}}async function inspectNativeLedger(nativeLoad,deps={}){let warnings=[],engines_node=null;try{let readPkg=deps.readPackageJson??defaultReadPackageJson;engines_node=readExpectedNodeEngine(await readPkg())}catch{engines_node=null}let invocation=deps.resolveMcpInvocation?deps.resolveMcpInvocation():resolveMcpShimInvocationForRuntime({moduleUrl:import.meta.url,nodeExecutable:"node",argv1:process.argv[1],fileExists:existsSync3}),mcp_shim_node=invocation.form==="absolute-build-path"?invocation.nodeExecutable:null,binding_loads=nativeLoad.loads,failure_kind=nativeLoad.failure_kind;nativeLoad.degraded&&nativeLoad.warning&&warnings.push(nativeLoad.warning),invocation.form!=="absolute-build-path"&&warnings.push("Worker MCP registration would use the npm-channel fallback (no resolvable on-disk build entry); registration reliability depends on the package being published."),engines_node===null&&warnings.push("Could not read package.json engines.node; expected Node version is unknown.");let degraded=nativeLoad.degraded||invocation.form!=="absolute-build-path"||engines_node===null;return{cli_node_version:process.version,engines_node,mcp_shim_node,mcp_registration_form:invocation.form,module:nativeLoad.module,node_modules_abi:nativeLoad.node_modules_abi,binding_loads,failure_kind,degraded,warnings}}async function collectConductorNativeLedger(deps={}){let ledger=await(deps.doctorLedger??doctorConductorLedger)(),native_ledger=await inspectNativeLedger(ledger.native_load,deps);return{ledger,native_ledger}}async function inspectEpicTickSchedule(deps,orchestrateListOverride){try{let schedRun=orchestrateListOverride?null:await Promise.resolve().then(()=>(init_schedule_run(),schedule_run_exports)),doList=orchestrateListOverride||(d=>schedRun.orchestrateScheduleList({json:!1},d)),resolvedDeps=orchestrateListOverride?deps:deps??schedRun.createDefaultScheduleRunDeps(),commandLabel=schedRun?schedRun.scheduleCommandLabel:m2=>m2.command??(m2.idea_file?"full-automation":"(unknown)"),runStatus=schedRun?schedRun.latestRunStatus:m2=>{let h=m2.run_history;return h&&h.length>0?h[h.length-1].status:""},entry=(await doList(resolvedDeps)).entries.find(e=>commandLabel(e.metadata)==="epic-tick");if(!entry)return{registered:!1,backend:null,next_fire_iso:null,latest_run_status:null,degraded:!1,warnings:[]};let m=entry.metadata,latest=runStatus(m);return{registered:!0,backend:m.backend??null,next_fire_iso:m.run_at_iso??null,latest_run_status:latest||null,degraded:!0,warnings:[`An epic-tick schedule is registered, but the v1 \`conductor epic-tick\` path is frozen (EPIC_TICK_V1_FROZEN) \u2014 it advances nothing. Cancel it: \`npx -y ${MCP_PACKAGE_NAME} schedule-run cancel --id ${entry.metadata.id??"<id>"}\`. Epic Conductor v2 reconciles server-side; run jobs locally with \`npx -y ${MCP_PACKAGE_NAME} executor --repo <name>\`.`]}}catch(err){return{registered:!1,backend:null,next_fire_iso:null,latest_run_status:null,degraded:!0,warnings:[`Failed to inspect epic-tick schedule: ${err instanceof Error?err.message:String(err)}`]}}}function inspectMcpProfile(env,epicTick){let raw=env.BRIDGE_MCP_PROFILE,raw_profile=raw===void 0?MCP_PROFILE_UNSET:raw,groups=resolveProfiles(raw),active_groups=Array.from(groups),conductor_context_detected=env.BAPI_CONDUCTOR_ENABLED==="1"||env.BAPI_CONDUCTOR_ENABLED==="true"||epicTick.registered,degraded=conductor_context_detected&&!groups.has("conductor"),warnings=[];return degraded&&warnings.push(`BRIDGE_MCP_PROFILE is ${raw_profile} (active groups: ${active_groups.join(", ")}) but a conductor context is active. ADD \`conductor\` to BRIDGE_MCP_PROFILE (e.g. \`${raw_profile===MCP_PROFILE_UNSET?"conductor":`${raw_profile},conductor`}\`) \u2014 do NOT replace the value, which would drop the worker's other groups. Without it the conductor/event/supervisor tools are not registered.`),{raw_profile,active_groups,conductor_context_detected,degraded,warnings}}function inspectLocalMerge(runCommand){let run=runCommand??((cmd,args)=>{try{return{status:spawnSync2(cmd,args,{encoding:"utf8",timeout:1e4,env:{...process.env,GH_PROMPT_DISABLED:"1"}}).status}}catch{return{status:null}}}),gh_available=!1,gh_authed=!1;try{gh_available=run("gh",["--version"]).status===0}catch{gh_available=!1}if(gh_available)try{gh_authed=run("gh",["auth","status"]).status===0}catch{gh_authed=!1}let warnings=[];return gh_available?gh_authed||warnings.push("`gh` is installed but not authenticated (`gh auth status` failed). Run `gh auth login` to grant the conductor merge permission; otherwise local merge will emit merge.failed/skip."):warnings.push("`gh` is not installed or not on PATH. Local merge (policy_json.local_merge.enabled) cannot run; install the GitHub CLI to enable conductor-driven merges."),{gh_available,gh_authed,degraded:!gh_available||!gh_authed,warnings}}async function buildConductorDoctorReport(deps={}){let inspectHooks=deps.inspectHooks??inspectConductorGitHooks,epicTick=await inspectEpicTickSchedule(deps.scheduleDeps,deps.orchestrateList),mcp_profile=inspectMcpProfile(deps.env??process.env,epicTick),{ledger,native_ledger}=await collectConductorNativeLedger(deps),deny_enforcement=deps.skipDenyProbe?skippedDenyEnforcementResult():await inspectDenyEnforcementSafe(deps.inspectDenyEnforcement),claude_login=await detectClaudeLogin({homedir:deps.claudeLoginDeps?.homedir??os3.homedir,readFile:deps.claudeLoginDeps?.readFile??(p=>readFileAsync(p,"utf-8"))});return{ledger,git_hooks:inspectHooks(deps.hooksDeps),epic_tick:epicTick,mcp_profile,local_merge:inspectLocalMerge(deps.runCommand),native_ledger,deny_enforcement,claude_login}}async function inspectDenyEnforcementSafe(inspect){try{let run=inspect;return run||(run=(await Promise.resolve().then(()=>(init_deny_enforcement_preflight(),deny_enforcement_preflight_exports))).runDenyEnforcementPreflight),await run()}catch(err){return{enforced:!1,layer:"none",degraded:!0,warnings:[`Deny-layer enforcement inspection failed: ${err instanceof Error?err.message:String(err)}`,"The executor claim loop MUST refuse to claim jobs until the deny layer is enforced."]}}}function formatConductorDoctorReport(report){let{ledger,git_hooks,epic_tick,mcp_profile,local_merge,native_ledger,deny_enforcement,claude_login}=report,lines=["Conductor ledger doctor","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`path: ${ledger.path}`,`directory exists: ${ledger.directory_exists}`,`database exists: ${ledger.database_exists}`,`directory mode: ${ledger.directory_mode??"n/a"} (ok: ${ledger.directory_permissions_ok})`,`database mode: ${ledger.database_mode??"n/a"} (ok: ${ledger.database_permissions_ok})`,`schema present: ${ledger.schema_present}`,`journal mode: ${ledger.journal_mode??"n/a"}`,`user_version: ${ledger.user_version??"n/a"}`,`event count: ${ledger.event_count??"n/a"}`,`max seq: ${ledger.max_seq??"n/a"}`,`busy_timeout_ms: ${ledger.retention.busy_timeout_ms}`,`retention_days: ${ledger.retention.retention_days}`,`retention_max_rows: ${ledger.retention.retention_max_rows}`,`message_cooldown_ms: ${ledger.message_relay.message_cooldown_ms}`,`degraded (network FS): ${ledger.degraded}`];if(ledger.warnings.length>0){lines.push("warnings:");for(let w of ledger.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("git hooks (optional, local)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"),lines.push(`is git worktree: ${git_hooks.is_worktree}`),lines.push(`hooks dir: ${git_hooks.hooks_dir??"n/a"}`),lines.push(`degraded: ${git_hooks.degraded}`);for(let hook of git_hooks.hooks)lines.push(` ${hook.name}: exists=${hook.exists} executable=${hook.executable} managed=${hook.managed_block_present} bin=${hook.embedded_bin_path??"n/a"} bin_is_file=${hook.embedded_bin_is_file}`);if(git_hooks.warnings.length>0){lines.push("git hook warnings:");for(let w of git_hooks.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Epic Supervisor Schedule (v1 epic-tick \u2014 frozen)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let registeredTag=epic_tick.registered?"[WARNING] registered \u2014 dead timer, remove it":"[SUCCESS] none registered (v1 is frozen)";if(lines.push(`epic-tick schedule: ${registeredTag}`),epic_tick.registered&&(lines.push(`backend: ${epic_tick.backend??"n/a"}`),lines.push(`next fire: ${epic_tick.next_fire_iso??"n/a"}`),lines.push(`latest run status: ${epic_tick.latest_run_status??"n/a"}`)),lines.push(`degraded: ${epic_tick.degraded}`),epic_tick.warnings.length>0){lines.push("epic-tick warnings:");for(let w of epic_tick.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Epic Conductor v2 reconciles epics server-side \u2014 nothing to schedule"),lines.push("locally. To execute claimed jobs on this machine, run:"),lines.push(` npx -y ${MCP_PACKAGE_NAME} executor --repo <name>`),lines.push(""),lines.push("MCP Profile (optional, local)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let profileTag=mcp_profile.degraded?"[WARNING] degraded":"[OK]";if(lines.push(`raw profile: ${mcp_profile.raw_profile}`),lines.push(`active groups: ${mcp_profile.active_groups.join(", ")} ${profileTag}`),lines.push(`conductor context: ${mcp_profile.conductor_context_detected}`),lines.push(`degraded: ${mcp_profile.degraded}`),mcp_profile.warnings.length>0){lines.push("mcp profile warnings:");for(let w of mcp_profile.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Local merge capability (optional, opt-in)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let ghTag=local_merge.gh_available?local_merge.gh_authed?"[OK]":"[WARNING] not authenticated":"[WARNING] not installed";if(lines.push(`gh available: ${local_merge.gh_available} ${ghTag}`),lines.push(`gh authenticated: ${local_merge.gh_authed}`),lines.push(`degraded: ${local_merge.degraded}`),local_merge.warnings.length>0){lines.push("local merge warnings:");for(let w of local_merge.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Native ledger module (required for conductor coordination)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let nativeTag=native_ledger.binding_loads&&!native_ledger.degraded?"[OK]":"[WARNING] degraded";if(lines.push(`binding loads: ${native_ledger.binding_loads} ${nativeTag}`),lines.push(`module: ${native_ledger.module}`),lines.push(`CLI Node: ${native_ledger.cli_node_version}`),lines.push(`engines.node: ${native_ledger.engines_node??"n/a"}`),lines.push(`MCP shim Node: ${native_ledger.mcp_shim_node??"n/a"}`),lines.push(`NODE_MODULE_VERSION: ${native_ledger.node_modules_abi}`),lines.push(`registration form: ${native_ledger.mcp_registration_form}`),lines.push(`failure kind: ${native_ledger.failure_kind}`),lines.push(`degraded: ${native_ledger.degraded}`),native_ledger.warnings.length>0){lines.push("native ledger warnings:");for(let w of native_ledger.warnings)lines.push(` - ${w}`)}lines.push(""),lines.push("Deny-layer enforcement preflight (required for executor claim)"),lines.push("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");let denyTag=deny_enforcement.status==="skip"?"[SKIPPED] probe not run (--no-deny-probe) \u2014 enforcement unverified":deny_enforcement.enforced?deny_enforcement.degraded?"[WARNING] degraded \u2014 relying on PreToolUse fallback":"[OK]":"[FATAL] deny not enforced \u2014 executor must refuse to claim jobs";if(lines.push(`enforced: ${deny_enforcement.enforced} ${denyTag}`),lines.push(`layer: ${deny_enforcement.layer}`),lines.push(`degraded: ${deny_enforcement.degraded}`),deny_enforcement.warnings.length>0){lines.push("deny enforcement warnings:");for(let w of deny_enforcement.warnings)lines.push(` - ${w}`)}return lines.push(""),lines.push(formatClaudeLoginAdvisory(claude_login)),lines.join(`
145
145
  `)}init_supervisor_config();function formatConductorErrorLine(envelope){if(envelope.error==="LEDGER_NATIVE_MODULE_LOAD_FAILED"&&envelope.details){let d=envelope.details;return`${envelope.message} details: module=${d.module} node_version=${d.node_version} node_modules_abi=${d.node_modules_abi}`}return envelope.message}function getConductorUsage(){return["Usage: conductor <command> [options]","","Local append-only event ledger for multi-agent coordination.","Talks ONLY to the local SQLite store (~/.config/bridge/events.db); no Bridge API calls.","","Commands:"," emit-event Append one semantic event to the ledger"," supervise --run-id <id> Run the foreground, run-scoped supervisor loop"," epic-tick Run one stateless reconciliation pass for an Epic"," epic-status Print read-only health summary of an Epic Run"," send-message Enqueue ONE typed supervisor->worker relay message (idempotent)"," check-messages Read + ACK pending relay messages for a worker (no redelivery)"," doctor Read-only health/diagnostics report (ledger + git hooks)"," purge Delete ALL ledger rows (events, messages, supervisor_projection)"," install-git-hooks Install local, opportunistic, non-blocking git hooks"," git-hook post-commit Run the post-commit producer (invoked by the installed hook)"," git-hook reference-transaction --phase <p> --stdin-file <f>"," Run the reference-transaction producer (invoked by the hook)"," file-scope-guard Warn-only: compare the branch diff against the declared"," touched-file set (always exits 0; never blocks a PR)","","supervise options:"," --run-id <id> Run/session identifier to supervise (required)"," --wake-interval-ms <n> Deterministic event-poll cadence (clamped 30000..60000)"," --global-timeout-ms <n> Total wall-clock ceiling for the run"," --escalation-cooldown-ms <n> Min gap between escalations for the same worker+reason","","install-git-hooks notes:"," Hooks are LOCAL, unversioned, opportunistic, and bypassable. Missing hooks are a"," degraded optional capability and never prevent PR/CI gate evaluation.","","emit-event options:"," --type <t> Semantic event type (required). One of:",` ${SEMANTIC_EVENT_TYPES.join(", ")}`," --source <s> Logical producer (required)"," --subject <s> Subject the event is about (e.g. ticket key)"," --run-id <s> Run/session identifier"," --worker-id <s> Worker/agent identifier"," --producer <s> Finer-grained producer identity"," --schema-version <n> Event schema version (default 1)"," --time <iso> ISO-8601 event time (default now)"," --confidence <0..1> Confidence score"," --observed-via <s> Channel the event was observed through"," --data-json <json> Normalized data object (allowlisted top-level keys)"," --data-json-stdin Read the complete normalized data object as JSON from stdin"," (mutually exclusive with --data-json; keeps raw payloads and"," secrets out of the process argument list)"," --raw-json <json> Tool-native object; nested under data.raw"," --payload-ref <ref> Reference for large external payloads (-> data.payload_ref)"," --json Print compact JSON result","","send-message options:"," --run-id <s> Run/session identifier (required)"," --worker-id <s> Target worker identifier (required)"," --type <s> Typed message kind, e.g. supervisor.worker_stalled (required)"," --cause-seq <n> Idempotency cause sequence, non-negative integer (required)"," --payload-json <json> Compact payload object (allowlisted top-level keys)"," --payload-json-stdin Read the payload object as JSON from stdin"," (mutually exclusive with --payload-json)"," --available-at <iso> ISO-8601 time the message becomes available (default now)"," --cooldown-ms <n> Per-call cooldown override in ms"," --json Print compact JSON result"," Note: a duplicate idempotency key or a same-type message inside the cooldown"," window does NOT enqueue a second message.","","check-messages options:"," --run-id <s> Run/session identifier (required)"," --worker-id <s> Worker identifier (required)"," --limit <n> Max messages to deliver/ack (default 10, max 100)"," --json Print compact JSON result"," Note: returned messages are ACKNOWLEDGED by this call and are not redelivered.","","doctor / purge options:"," --json Print machine-readable JSON"," --no-deny-probe (doctor only) Skip the deny-enforcement preflight \u2014 no headless"," agent is spawned; the deny_enforcement section reports an"," explicit skipped state (enforcement UNVERIFIED, never enforced)","","Examples:"," conductor emit-event --type run.started --source git-hook --run-id BAPI-393 \\",` --data-json '{"summary":"run started"}'`," conductor emit-event --type git.commit_created --source git-hook \\",` --raw-json '{"branch":"feature/x","sha":"abc123"}'`," conductor emit-event --type ci.failed --source ci \\"," --payload-ref 'file:///tmp/ci-log.txt'"," conductor emit-event --type merge.succeeded --source conductor-merge \\",` --worker-id w1 --data-json '{"summary":"auto-merged","status":"succeeded"}'`," conductor doctor --json"," conductor purge","","epic-tick options:"," --epic-key <KEY> Epic key to supervise (required, non-empty)"," --scheduled-at <epoch> Epoch-seconds timestamp when this tick was scheduled (optional)"," --lease-ttl-seconds <n> Lease TTL in seconds (optional, default 120)","","approve-plan options:"," approve-plan <epic_key> --plan-version N [--json]"," <epic_key> Epic key (e.g. EPIC-405) (required positional)"," --plan-version <n> Strictly positive plan version to approve (required)"," --json Print compact JSON result"," --help Print this usage message","","epic-status options:"," --epic-key <KEY> Epic key to fetch the snapshot for (required)"," --json Print compact JSON result"," --help Print this usage message","","Examples:"," conductor approve-plan EPIC-405 --plan-version 2"," conductor approve-plan EPIC-405 --plan-version 2 --json"," conductor epic-status --epic-key EPIC-405"," conductor epic-status --epic-key EPIC-405 --json"].join(`
146
- `)}var VALID_COMMANDS=new Set(["emit-event","supervise","epic-tick","approve-plan","epic-status","send-message","check-messages","doctor","purge","install-git-hooks","git-hook","file-scope-guard"]);function parseConductorArgs(argv){if(argv.length===0)return{kind:"help"};let first=argv[0];return first==="-h"||first==="--help"?{kind:"help"}:first.startsWith("-")?{kind:"error",message:`Unknown option "${first}". Run "conductor --help" for usage.`}:VALID_COMMANDS.has(first)?{kind:"command",command:first,argv:argv.slice(1)}:{kind:"error",message:`Unknown command "${first}". Run "conductor --help" for usage.`}}function tokenizeFlags(argv,valueFlags,boolFlags){let values=new Map,bools=new Set;for(let i=0;i<argv.length;i+=1){let token=argv[i];if(token==="-h"){bools.add("--help");continue}if(!token.startsWith("--"))throw new ConductorValidationError(`Unexpected argument "${token}".`);let eq=token.indexOf("="),name=eq>=0?token.slice(0,eq):token;if(boolFlags.has(name)){bools.add(name);continue}if(!valueFlags.has(name))throw new ConductorValidationError(`Unknown flag "${name}".`);let value;if(eq>=0)value=token.slice(eq+1);else{let next=argv[i+1];if(next===void 0)throw new ConductorValidationError(`Flag "${name}" requires a value.`);value=next,i+=1}values.set(name,value)}return{values,bools}}var EMIT_VALUE_FLAGS=new Set(["--type","--source","--id","--subject","--run-id","--worker-id","--producer","--schema-version","--time","--confidence","--observed-via","--data-json","--raw-json","--payload-ref"]),EMIT_BOOL_FLAGS=new Set(["--json","--help","--data-json-stdin"]);function defaultReadStdin(){return readFileSync3(0,"utf-8")}function parseJsonFlag(raw,flag){try{return JSON.parse(raw)}catch{throw new ConductorValidationError(`Flag "${flag}" must be valid JSON.`)}}function isPlainObject3(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function parseEmitEventArgs(argv,deps={}){let{values,bools}=tokenizeFlags(argv,EMIT_VALUE_FLAGS,EMIT_BOOL_FLAGS);if(bools.has("--help"))return{input:{source:"",type:"run.started"},json:bools.has("--json"),help:!0};let type=values.get("--type"),source=values.get("--source");if(!type)throw new ConductorValidationError('Flag "--type" is required for emit-event.');if(!source)throw new ConductorValidationError('Flag "--source" is required for emit-event.');let data={},dataJsonRaw=values.get("--data-json"),dataJsonStdin=bools.has("--data-json-stdin");if(dataJsonRaw!==void 0&&dataJsonStdin)throw new ConductorValidationError('Flags "--data-json" and "--data-json-stdin" are mutually exclusive; pass the normalized data object exactly one way.');if(dataJsonStdin){let stdinRaw=(deps.readStdin??defaultReadStdin)(),parsed=parseJsonFlag(stdinRaw,"--data-json-stdin");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--data-json-stdin" must be a JSON object.');data={...parsed}}else if(dataJsonRaw!==void 0){let parsed=parseJsonFlag(dataJsonRaw,"--data-json");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--data-json" must be a JSON object.');data={...parsed}}let rawJsonRaw=values.get("--raw-json");if(rawJsonRaw!==void 0){let parsedRaw=parseJsonFlag(rawJsonRaw,"--raw-json");if(!isPlainObject3(parsedRaw))throw new ConductorValidationError('Flag "--raw-json" must be a JSON object.');let existingRaw=isPlainObject3(data.raw)?data.raw:{};data.raw={...existingRaw,...parsedRaw}}let payloadRef=values.get("--payload-ref");payloadRef!==void 0&&(data.payload_ref=payloadRef);let schemaVersionRaw=values.get("--schema-version"),confidenceRaw=values.get("--confidence"),input={source,type,id:values.get("--id"),subject:values.get("--subject"),run_id:values.get("--run-id"),worker_id:values.get("--worker-id"),producer:values.get("--producer"),time:values.get("--time"),observed_via:values.get("--observed-via"),data};if(schemaVersionRaw!==void 0){let n=Number.parseInt(schemaVersionRaw,10);if(!Number.isFinite(n))throw new ConductorValidationError('Flag "--schema-version" must be an integer.');input.schema_version=n}if(confidenceRaw!==void 0){let n=Number.parseFloat(confidenceRaw);if(!Number.isFinite(n))throw new ConductorValidationError('Flag "--confidence" must be a number.');input.confidence=n}return{input,json:bools.has("--json"),help:!1}}async function runEmitEventCommand(argv,deps={}){let parsed=parseEmitEventArgs(argv,deps);if(parsed.help)return console.log(getConductorUsage()),0;let result;try{result=await emitConductorEvent(parsed.input)}catch(error){if(isDuplicateConstraintError2(error)){let dup={ok:!1,reason:"duplicate"};return console.log(parsed.json?JSON.stringify(dup):JSON.stringify(dup,null,2)),0}throw error}return parsed.json?console.log(JSON.stringify(result)):console.log(JSON.stringify(result,null,2)),0}var SEND_MESSAGE_VALUE_FLAGS=new Set(["--run-id","--worker-id","--type","--cause-seq","--payload-json","--available-at","--cooldown-ms"]),SEND_MESSAGE_BOOL_FLAGS=new Set(["--payload-json-stdin","--json","--help"]);function parseSendMessageArgs(argv,deps={}){let{values,bools}=tokenizeFlags(argv,SEND_MESSAGE_VALUE_FLAGS,SEND_MESSAGE_BOOL_FLAGS);if(bools.has("--help"))return{input:{run_id:"",worker_id:"",type:"",cause_seq:0},json:bools.has("--json"),help:!0};let runId=values.get("--run-id"),workerId=values.get("--worker-id"),type=values.get("--type"),causeSeqRaw=values.get("--cause-seq");if(!runId)throw new ConductorValidationError('Flag "--run-id" is required for send-message.');if(!workerId)throw new ConductorValidationError('Flag "--worker-id" is required for send-message.');if(!type)throw new ConductorValidationError('Flag "--type" is required for send-message.');if(causeSeqRaw===void 0)throw new ConductorValidationError('Flag "--cause-seq" is required for send-message.');if(!/^\d+$/.test(causeSeqRaw.trim()))throw new ConductorValidationError('Flag "--cause-seq" must be a non-negative integer.');let causeSeq=Number.parseInt(causeSeqRaw.trim(),10),payload={},payloadInline=values.get("--payload-json"),payloadStdin=bools.has("--payload-json-stdin");if(payloadInline!==void 0&&payloadStdin)throw new ConductorValidationError('Flags "--payload-json" and "--payload-json-stdin" are mutually exclusive; pass the payload object exactly one way.');if(payloadStdin){let readStdin=deps.readStdin??defaultReadStdin,parsed=parseJsonFlag(readStdin(),"--payload-json-stdin");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--payload-json-stdin" must be a JSON object.');payload={...parsed}}else if(payloadInline!==void 0){let parsed=parseJsonFlag(payloadInline,"--payload-json");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--payload-json" must be a JSON object.');payload={...parsed}}let input={run_id:runId,worker_id:workerId,type,cause_seq:causeSeq,payload},availableAt=values.get("--available-at");availableAt!==void 0&&(input.available_at=availableAt);let cooldownRaw=values.get("--cooldown-ms");if(cooldownRaw!==void 0){if(!/^\d+$/.test(cooldownRaw.trim()))throw new ConductorValidationError('Flag "--cooldown-ms" must be a non-negative integer.');input.cooldown_ms=Number.parseInt(cooldownRaw.trim(),10)}return{input,json:bools.has("--json"),help:!1}}async function runSendMessageCommand(argv,deps={}){let parsed=parseSendMessageArgs(argv,deps);if(parsed.help)return console.log(getConductorUsage()),0;let result=await sendWorkerMessage(parsed.input);return parsed.json?console.log(JSON.stringify(result)):console.log([`Message ${result.status}.`,` id: ${result.message.id}`,` type: ${result.message.type}`,` state: ${result.message.state}`].join(`
146
+ `)}var CONDUCTOR_HOOK_BIN_ACTION="__hook-bin",VALID_COMMANDS=new Set(["emit-event","supervise","epic-tick","approve-plan","epic-status","send-message","check-messages","doctor","purge","install-git-hooks","git-hook","file-scope-guard",CONDUCTOR_HOOK_BIN_ACTION]);function parseConductorArgs(argv){if(argv.length===0)return{kind:"help"};let first=argv[0];return first==="-h"||first==="--help"?{kind:"help"}:first.startsWith("-")?{kind:"error",message:`Unknown option "${first}". Run "conductor --help" for usage.`}:VALID_COMMANDS.has(first)?{kind:"command",command:first,argv:argv.slice(1)}:{kind:"error",message:`Unknown command "${first}". Run "conductor --help" for usage.`}}function tokenizeFlags(argv,valueFlags,boolFlags){let values=new Map,bools=new Set;for(let i=0;i<argv.length;i+=1){let token=argv[i];if(token==="-h"){bools.add("--help");continue}if(!token.startsWith("--"))throw new ConductorValidationError(`Unexpected argument "${token}".`);let eq=token.indexOf("="),name=eq>=0?token.slice(0,eq):token;if(boolFlags.has(name)){bools.add(name);continue}if(!valueFlags.has(name))throw new ConductorValidationError(`Unknown flag "${name}".`);let value;if(eq>=0)value=token.slice(eq+1);else{let next=argv[i+1];if(next===void 0)throw new ConductorValidationError(`Flag "${name}" requires a value.`);value=next,i+=1}values.set(name,value)}return{values,bools}}var EMIT_VALUE_FLAGS=new Set(["--type","--source","--id","--subject","--run-id","--worker-id","--producer","--schema-version","--time","--confidence","--observed-via","--data-json","--raw-json","--payload-ref"]),EMIT_BOOL_FLAGS=new Set(["--json","--help","--data-json-stdin"]);function defaultReadStdin(){return readFileSync3(0,"utf-8")}function parseJsonFlag(raw,flag){try{return JSON.parse(raw)}catch{throw new ConductorValidationError(`Flag "${flag}" must be valid JSON.`)}}function isPlainObject3(value){return value!==null&&typeof value=="object"&&!Array.isArray(value)}function parseEmitEventArgs(argv,deps={}){let{values,bools}=tokenizeFlags(argv,EMIT_VALUE_FLAGS,EMIT_BOOL_FLAGS);if(bools.has("--help"))return{input:{source:"",type:"run.started"},json:bools.has("--json"),help:!0};let type=values.get("--type"),source=values.get("--source");if(!type)throw new ConductorValidationError('Flag "--type" is required for emit-event.');if(!source)throw new ConductorValidationError('Flag "--source" is required for emit-event.');let data={},dataJsonRaw=values.get("--data-json"),dataJsonStdin=bools.has("--data-json-stdin");if(dataJsonRaw!==void 0&&dataJsonStdin)throw new ConductorValidationError('Flags "--data-json" and "--data-json-stdin" are mutually exclusive; pass the normalized data object exactly one way.');if(dataJsonStdin){let stdinRaw=(deps.readStdin??defaultReadStdin)(),parsed=parseJsonFlag(stdinRaw,"--data-json-stdin");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--data-json-stdin" must be a JSON object.');data={...parsed}}else if(dataJsonRaw!==void 0){let parsed=parseJsonFlag(dataJsonRaw,"--data-json");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--data-json" must be a JSON object.');data={...parsed}}let rawJsonRaw=values.get("--raw-json");if(rawJsonRaw!==void 0){let parsedRaw=parseJsonFlag(rawJsonRaw,"--raw-json");if(!isPlainObject3(parsedRaw))throw new ConductorValidationError('Flag "--raw-json" must be a JSON object.');let existingRaw=isPlainObject3(data.raw)?data.raw:{};data.raw={...existingRaw,...parsedRaw}}let payloadRef=values.get("--payload-ref");payloadRef!==void 0&&(data.payload_ref=payloadRef);let schemaVersionRaw=values.get("--schema-version"),confidenceRaw=values.get("--confidence"),input={source,type,id:values.get("--id"),subject:values.get("--subject"),run_id:values.get("--run-id"),worker_id:values.get("--worker-id"),producer:values.get("--producer"),time:values.get("--time"),observed_via:values.get("--observed-via"),data};if(schemaVersionRaw!==void 0){let n=Number.parseInt(schemaVersionRaw,10);if(!Number.isFinite(n))throw new ConductorValidationError('Flag "--schema-version" must be an integer.');input.schema_version=n}if(confidenceRaw!==void 0){let n=Number.parseFloat(confidenceRaw);if(!Number.isFinite(n))throw new ConductorValidationError('Flag "--confidence" must be a number.');input.confidence=n}return{input,json:bools.has("--json"),help:!1}}async function runEmitEventCommand(argv,deps={}){let parsed=parseEmitEventArgs(argv,deps);if(parsed.help)return console.log(getConductorUsage()),0;let result;try{result=await emitConductorEvent(parsed.input)}catch(error){if(isDuplicateConstraintError2(error)){let dup={ok:!1,reason:"duplicate"};return console.log(parsed.json?JSON.stringify(dup):JSON.stringify(dup,null,2)),0}throw error}return parsed.json?console.log(JSON.stringify(result)):console.log(JSON.stringify(result,null,2)),0}var SEND_MESSAGE_VALUE_FLAGS=new Set(["--run-id","--worker-id","--type","--cause-seq","--payload-json","--available-at","--cooldown-ms"]),SEND_MESSAGE_BOOL_FLAGS=new Set(["--payload-json-stdin","--json","--help"]);function parseSendMessageArgs(argv,deps={}){let{values,bools}=tokenizeFlags(argv,SEND_MESSAGE_VALUE_FLAGS,SEND_MESSAGE_BOOL_FLAGS);if(bools.has("--help"))return{input:{run_id:"",worker_id:"",type:"",cause_seq:0},json:bools.has("--json"),help:!0};let runId=values.get("--run-id"),workerId=values.get("--worker-id"),type=values.get("--type"),causeSeqRaw=values.get("--cause-seq");if(!runId)throw new ConductorValidationError('Flag "--run-id" is required for send-message.');if(!workerId)throw new ConductorValidationError('Flag "--worker-id" is required for send-message.');if(!type)throw new ConductorValidationError('Flag "--type" is required for send-message.');if(causeSeqRaw===void 0)throw new ConductorValidationError('Flag "--cause-seq" is required for send-message.');if(!/^\d+$/.test(causeSeqRaw.trim()))throw new ConductorValidationError('Flag "--cause-seq" must be a non-negative integer.');let causeSeq=Number.parseInt(causeSeqRaw.trim(),10),payload={},payloadInline=values.get("--payload-json"),payloadStdin=bools.has("--payload-json-stdin");if(payloadInline!==void 0&&payloadStdin)throw new ConductorValidationError('Flags "--payload-json" and "--payload-json-stdin" are mutually exclusive; pass the payload object exactly one way.');if(payloadStdin){let readStdin=deps.readStdin??defaultReadStdin,parsed=parseJsonFlag(readStdin(),"--payload-json-stdin");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--payload-json-stdin" must be a JSON object.');payload={...parsed}}else if(payloadInline!==void 0){let parsed=parseJsonFlag(payloadInline,"--payload-json");if(!isPlainObject3(parsed))throw new ConductorValidationError('Flag "--payload-json" must be a JSON object.');payload={...parsed}}let input={run_id:runId,worker_id:workerId,type,cause_seq:causeSeq,payload},availableAt=values.get("--available-at");availableAt!==void 0&&(input.available_at=availableAt);let cooldownRaw=values.get("--cooldown-ms");if(cooldownRaw!==void 0){if(!/^\d+$/.test(cooldownRaw.trim()))throw new ConductorValidationError('Flag "--cooldown-ms" must be a non-negative integer.');input.cooldown_ms=Number.parseInt(cooldownRaw.trim(),10)}return{input,json:bools.has("--json"),help:!1}}async function runSendMessageCommand(argv,deps={}){let parsed=parseSendMessageArgs(argv,deps);if(parsed.help)return console.log(getConductorUsage()),0;let result=await sendWorkerMessage(parsed.input);return parsed.json?console.log(JSON.stringify(result)):console.log([`Message ${result.status}.`,` id: ${result.message.id}`,` type: ${result.message.type}`,` state: ${result.message.state}`].join(`
147
147
  `)),0}var CHECK_MESSAGES_VALUE_FLAGS=new Set(["--run-id","--worker-id","--limit"]),CHECK_MESSAGES_BOOL_FLAGS=new Set(["--json","--help"]);function parseCheckMessagesArgs(argv){let{values,bools}=tokenizeFlags(argv,CHECK_MESSAGES_VALUE_FLAGS,CHECK_MESSAGES_BOOL_FLAGS);if(bools.has("--help"))return{input:{run_id:"",worker_id:""},json:bools.has("--json"),help:!0};let runId=values.get("--run-id"),workerId=values.get("--worker-id");if(!runId)throw new ConductorValidationError('Flag "--run-id" is required for check-messages.');if(!workerId)throw new ConductorValidationError('Flag "--worker-id" is required for check-messages.');let input={run_id:runId,worker_id:workerId},limitRaw=values.get("--limit");if(limitRaw!==void 0){if(!/^\d+$/.test(limitRaw.trim()))throw new ConductorValidationError('Flag "--limit" must be a positive integer.');input.limit=Number.parseInt(limitRaw.trim(),10)}return{input,json:bools.has("--json"),help:!1}}async function runCheckMessagesCommand(argv){let parsed=parseCheckMessagesArgs(argv);if(parsed.help)return console.log(getConductorUsage()),0;let result=await checkWorkerMessages(parsed.input);if(parsed.json)return console.log(JSON.stringify(result)),0;let lines=[`Acknowledged ${result.acked_count} of ${result.count} message(s).`];for(let message of result.messages)lines.push(` ${message.id} [${message.type}] -> ${message.state}`);return console.log(lines.join(`
148
- `)),0}var DIAGNOSTIC_BOOL_FLAGS=new Set(["--json","--help"]),DOCTOR_BOOL_FLAGS=new Set([...DIAGNOSTIC_BOOL_FLAGS,"--no-deny-probe"]);async function runDoctorCommand(argv,deps={}){let{bools}=tokenizeFlags(argv,new Set,DOCTOR_BOOL_FLAGS);if(bools.has("--help"))return console.log(getConductorUsage()),0;let report=await buildConductorDoctorReport(bools.has("--no-deny-probe")?{...deps,skipDenyProbe:!0}:deps);return bools.has("--json")?(console.log(JSON.stringify({...report.ledger,git_hooks:report.git_hooks,epic_tick:report.epic_tick,mcp_profile:report.mcp_profile,native_ledger:report.native_ledger,deny_enforcement:report.deny_enforcement})),0):(console.log(formatConductorDoctorReport(report)),0)}function runInstallGitHooksCommand(argv){let{bools}=tokenizeFlags(argv,new Set,DIAGNOSTIC_BOOL_FLAGS);if(bools.has("--help"))return console.log(getConductorUsage()),0;let result=installConductorGitHooks();if(bools.has("--json"))return console.log(JSON.stringify(result)),0;let lines=["Conductor git hooks install","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`is git worktree: ${result.is_worktree}`,`hooks dir: ${result.hooks_dir??"n/a"}`];for(let hook of result.installed)lines.push(` ${hook.name}: ${hook.action}${hook.warning?` (${hook.warning})`:""}`);if(result.warnings.length>0){lines.push("warnings:");for(let w of result.warnings)lines.push(` - ${w}`)}return console.log(lines.join(`
149
- `)),0}var GIT_HOOK_VALUE_FLAGS=new Set(["--phase","--stdin-file"]),GIT_HOOK_BOOL_FLAGS=new Set(["--help"]);function parseGitHookArgs(argv){let subcommand=argv[0];if(subcommand!=="post-commit"&&subcommand!=="reference-transaction")throw new ConductorValidationError(`Unknown git-hook subcommand "${subcommand??""}". Expected "post-commit" or "reference-transaction".`);let{values}=tokenizeFlags(argv.slice(1),GIT_HOOK_VALUE_FLAGS,GIT_HOOK_BOOL_FLAGS);return{subcommand,phase:values.get("--phase"),stdinFile:values.get("--stdin-file")}}async function runGitHookCommand(argv){let parsed;try{parsed=parseGitHookArgs(argv)}catch{return process.stderr.write(`Warning: conductor git-hook invocation was invalid.
148
+ `)),0}var DIAGNOSTIC_BOOL_FLAGS=new Set(["--json","--help"]),DOCTOR_BOOL_FLAGS=new Set([...DIAGNOSTIC_BOOL_FLAGS,"--no-deny-probe"]);async function runDoctorCommand(argv,deps={}){let{bools}=tokenizeFlags(argv,new Set,DOCTOR_BOOL_FLAGS);if(bools.has("--help"))return console.log(getConductorUsage()),0;let report=await buildConductorDoctorReport(bools.has("--no-deny-probe")?{...deps,skipDenyProbe:!0}:deps);return bools.has("--json")?(console.log(JSON.stringify({...report.ledger,git_hooks:report.git_hooks,epic_tick:report.epic_tick,mcp_profile:report.mcp_profile,native_ledger:report.native_ledger,deny_enforcement:report.deny_enforcement})),0):(console.log(formatConductorDoctorReport(report)),0)}function runInstallGitHooksCommand(argv){let{bools}=tokenizeFlags(argv,new Set,DIAGNOSTIC_BOOL_FLAGS);if(bools.has("--help"))return console.log(getConductorUsage()),0;let result=installConductorGitHooks();if(!result.ok)return bools.has("--json")?(console.error(JSON.stringify({error:result.error,reason:result.reason})),1):(console.error(`Error: conductor git hooks were NOT installed (${result.error}): ${result.reason}`),1);if(bools.has("--json"))return console.log(JSON.stringify(result)),0;let lines=["Conductor git hooks install","\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500",`is git worktree: ${result.is_worktree}`,`hooks dir: ${result.hooks_dir??"n/a"}`,`conductor bin: ${result.conductor_bin}`];for(let hook of result.installed)lines.push(` ${hook.name}: ${hook.action}${hook.warning?` (${hook.warning})`:""}`);if(result.warnings.length>0){lines.push("warnings:");for(let w of result.warnings)lines.push(` - ${w}`)}return console.log(lines.join(`
149
+ `)),0}function runHookBinDiagnosticCommand(){let resolution=resolveConductorHookBin();return resolution.ok?(console.log(resolution.path),0):(console.error(`conductor hook bin UNRESOLVED: ${resolution.reason}`),1)}var GIT_HOOK_VALUE_FLAGS=new Set(["--phase","--stdin-file"]),GIT_HOOK_BOOL_FLAGS=new Set(["--help"]);function parseGitHookArgs(argv){let subcommand=argv[0];if(subcommand!=="post-commit"&&subcommand!=="reference-transaction")throw new ConductorValidationError(`Unknown git-hook subcommand "${subcommand??""}". Expected "post-commit" or "reference-transaction".`);let{values}=tokenizeFlags(argv.slice(1),GIT_HOOK_VALUE_FLAGS,GIT_HOOK_BOOL_FLAGS);return{subcommand,phase:values.get("--phase"),stdinFile:values.get("--stdin-file")}}async function runGitHookCommand(argv){let parsed;try{parsed=parseGitHookArgs(argv)}catch{return process.stderr.write(`Warning: conductor git-hook invocation was invalid.
150
150
  `),0}try{if(parsed.subcommand==="post-commit")return await runPostCommitHookProducer(),0;let stdin="";if(parsed.stdinFile)try{stdin=readFileSync3(parsed.stdinFile,"utf-8")}catch{stdin=""}finally{try{unlinkSync(parsed.stdinFile)}catch{}}return await runReferenceTransactionHookProducer({phase:parsed.phase??"",stdin}),0}catch{return process.stderr.write(`Warning: conductor git-hook producer failed.
151
151
  `),0}}async function runEpicTickCommand(_argv){throw new ConductorEpicTickV1FrozenError}var APPROVE_PLAN_VALUE_FLAGS=new Set(["--plan-version"]),APPROVE_PLAN_BOOL_FLAGS=new Set(["--json","--help"]);function parseApprovePlanArgs(argv){if(argv.length===0||argv[0]==="--help"||argv[0]==="-h")return{epicKey:"",planVersion:0,json:!1,help:!0};let epicKey,restArgv;argv[0].startsWith("-")?restArgv=argv:(epicKey=argv[0],restArgv=argv.slice(1));let{values,bools}=tokenizeFlags(restArgv,APPROVE_PLAN_VALUE_FLAGS,APPROVE_PLAN_BOOL_FLAGS);if(bools.has("--help"))return{epicKey:"",planVersion:0,json:!1,help:!0};if(!epicKey||epicKey.trim().length===0)throw new ConductorValidationError('Argument "<epic_key>" is required for approve-plan and must be non-empty.');let planVersion=parsePositiveIntFlag(values,"--plan-version");if(planVersion===void 0)throw new ConductorValidationError('Flag "--plan-version" is required for approve-plan and must be a strictly positive integer.');if(planVersion===0)throw new ConductorValidationError('Flag "--plan-version" must be a strictly positive integer (\u2265 1).');return{epicKey:epicKey.trim(),planVersion,json:bools.has("--json"),help:!1}}async function runApprovePlanCommand(argv){let parsed;try{parsed=parseApprovePlanArgs(argv)}catch(error){let envelope=toConductorErrorEnvelope(error);return console.error(`Error: ${formatConductorErrorLine(envelope)}`),1}if(parsed.help)return console.log(getConductorUsage()),0;let{resolveConductorBridgeApiAccess:resolveConductorBridgeApiAccess2,approveEpicPlan:approveEpicPlan2}=await Promise.resolve().then(()=>(init_bridge_api_client(),bridge_api_client_exports)),accessResult=await resolveConductorBridgeApiAccess2();if(!accessResult.ok){let envelope={error:"CREDENTIALS_UNAVAILABLE",status:401,message:accessResult.error};return parsed.json?console.log(JSON.stringify({ok:!1,kind:"unauthorized",error:envelope.message})):console.error(`Error: ${accessResult.error}`),1}try{let result=await approveEpicPlan2(accessResult.access,{epicKey:parsed.epicKey,planVersion:parsed.planVersion});if(!result.ok)throw new ConductorValidationError(`approve-plan rejected: version drift or monotonic constraint violation (kind: ${result.kind}). Ensure --plan-version is strictly greater than the current approved version and that the blob has been stored first.`);return parsed.json?console.log(JSON.stringify({ok:!0,plan_hash:result.plan_hash})):console.log(`Plan approved atomically. Epic Key: ${parsed.epicKey}, Plan Version: ${parsed.planVersion}, Approved Hash: ${result.plan_hash}`),0}catch(error){let envelope=toConductorErrorEnvelope(error);return parsed.json?console.log(JSON.stringify(envelope)):console.error(`Error: ${formatConductorErrorLine(envelope)}`),envelope.status>=500?2:1}}var EPIC_STATUS_VALUE_FLAGS=new Set(["--epic-key"]),EPIC_STATUS_BOOL_FLAGS=new Set(["--json","--help"]);function parseEpicStatusArgs(argv){let{values,bools}=tokenizeFlags(argv,EPIC_STATUS_VALUE_FLAGS,EPIC_STATUS_BOOL_FLAGS);if(bools.has("--help"))return{epicKey:"",json:!1,help:!0};let epicKeyRaw=values.get("--epic-key");if(epicKeyRaw===void 0||epicKeyRaw.trim().length===0)throw new ConductorValidationError('Flag "--epic-key" is required for epic-status and must be non-empty.');return{epicKey:epicKeyRaw.trim(),json:bools.has("--json"),help:!1}}async function runEpicStatusCommand(argv){let parsed;try{parsed=parseEpicStatusArgs(argv)}catch(error){let envelope=toConductorErrorEnvelope(error);return console.error(`Error: ${formatConductorErrorLine(envelope)}`),1}if(parsed.help)return console.log(getConductorUsage()),0;let{resolveConductorBridgeApiAccess:resolveConductorBridgeApiAccess2,fetchEpicRunState:fetchEpicRunState2,ConductorBridgeApiError:BridgeApiError}=await Promise.resolve().then(()=>(init_bridge_api_client(),bridge_api_client_exports)),accessResult=await resolveConductorBridgeApiAccess2();if(!accessResult.ok)return parsed.json?console.log(JSON.stringify({ok:!1,kind:"unauthorized",error:accessResult.error})):console.error(`Error: ${accessResult.error}`),1;try{let state=await fetchEpicRunState2(accessResult.access,parsed.epicKey);if(parsed.json)return console.log(JSON.stringify(state)),0;let lines=[],run=state.epic_run;lines.push(`Epic Run: ${run.epic_key}`),lines.push(` status: ${run.status}`),lines.push(` plan_version: ${run.current_plan_version}`);let leaseState=run.lease_owner?`${run.lease_owner} (expires ${run.lease_expires_at??"unknown"})`:"none";lines.push(` lease: ${leaseState}`),lines.push(` budget: ${run.budget_wall_clock_seconds??"unlimited"}s / ${run.budget_cost_cents??"unlimited"} cents`),lines.push(` consumed: ${run.consumed_wall_clock_seconds}s / ${run.consumed_cost_cents} cents`),lines.push(`
152
152
  Tickets (${state.ticket_statuses.length}):`);for(let t of state.ticket_statuses){let dispatchRef=t.dispatch_run_id?`dispatch_run_id=${t.dispatch_run_id}`:"-";lines.push(` ${t.ticket_key} [${t.status}] ${dispatchRef} remediation=${t.remediation_attempts}/${t.remediation_no_progress_attempts}`)}lines.push(`
153
153
  Dispatches (${state.dispatches.length}):`);for(let d of state.dispatches){let runRef=d.run_id?`run_id=${d.run_id}`:"-";lines.push(` ${d.dispatch_key} [${d.status}] ${runRef}`)}return console.log(lines.join(`
154
154
  `)),0}catch(error){if(error instanceof BridgeApiError&&error.status===404)return parsed.json?console.log(JSON.stringify({epic_key:parsed.epicKey,status:"unknown",state:null})):console.log("No such epic found."),0;let envelope=toConductorErrorEnvelope(error);return parsed.json?console.log(JSON.stringify(envelope)):console.error(`Error: ${formatConductorErrorLine(envelope)}`),envelope.status>=500?2:1}}var SUPERVISE_VALUE_FLAGS=new Set(["--run-id","--wake-interval-ms","--global-timeout-ms","--escalation-cooldown-ms"]),SUPERVISE_BOOL_FLAGS=new Set(["--help"]);function parsePositiveIntFlag(values,flag){let raw=values.get(flag);if(raw===void 0)return;if(!/^\d+$/.test(raw.trim()))throw new ConductorValidationError(`Flag "${flag}" must be a non-negative integer.`);let n=Number.parseInt(raw.trim(),10);if(!Number.isFinite(n))throw new ConductorValidationError(`Flag "${flag}" must be a non-negative integer.`);return n}function parseSuperviseArgs(argv){let{values,bools}=tokenizeFlags(argv,SUPERVISE_VALUE_FLAGS,SUPERVISE_BOOL_FLAGS);if(bools.has("--help"))return{runId:"",overrides:{},help:!0};let runIdRaw=values.get("--run-id");if(runIdRaw===void 0||runIdRaw.trim().length===0)throw new ConductorValidationError('Flag "--run-id" is required for supervise and must be non-empty.');let overrides={},wake=parsePositiveIntFlag(values,"--wake-interval-ms");wake!==void 0&&(overrides.wake_interval_ms=wake);let globalTimeout=parsePositiveIntFlag(values,"--global-timeout-ms");globalTimeout!==void 0&&(overrides.global_timeout_ms=globalTimeout);let cooldown=parsePositiveIntFlag(values,"--escalation-cooldown-ms");return cooldown!==void 0&&(overrides.escalation_cooldown_ms=cooldown),{runId:runIdRaw.trim(),overrides,help:!1}}async function runSuperviseCommand(argv){let parsed=parseSuperviseArgs(argv);if(parsed.help)return console.log(getConductorUsage()),0;let config=resolveSupervisorConfig(parsed.overrides);console.log(`[supervisor] starting run=${parsed.runId} wake=${config.wake_interval_ms}ms global_timeout=${config.global_timeout_ms}ms`);let{runSupervisor:runSupervisor2}=await Promise.resolve().then(()=>(init_supervisor_runtime(),supervisor_runtime_exports));return(await runSupervisor2({run_id:parsed.runId,config})).exit_code}async function runPurgeCommand(argv){let{bools}=tokenizeFlags(argv,new Set,DIAGNOSTIC_BOOL_FLAGS);if(bools.has("--help"))return console.log(getConductorUsage()),0;let result=await purgeConductorLedger();return bools.has("--json")?(console.log(JSON.stringify(result)),0):(console.log([`Conductor ledger purged (existed: ${result.existed}).`,` events: ${result.deleted.events}`,` messages: ${result.deleted.messages}`,` supervisor_projection: ${result.deleted.supervisor_projection}`].join(`
155
- `)),0)}async function runConductorCli(argv){let parsed=parseConductorArgs(argv);if(parsed.kind==="help")return console.log(getConductorUsage()),0;if(parsed.kind==="error")return console.error(`Error: ${parsed.message}`),1;try{switch(parsed.command){case"emit-event":return await runEmitEventCommand(parsed.argv);case"supervise":return await runSuperviseCommand(parsed.argv);case"epic-tick":return await runEpicTickCommand(parsed.argv);case"approve-plan":return await runApprovePlanCommand(parsed.argv);case"epic-status":return await runEpicStatusCommand(parsed.argv);case"send-message":return await runSendMessageCommand(parsed.argv);case"check-messages":return await runCheckMessagesCommand(parsed.argv);case"doctor":return await runDoctorCommand(parsed.argv);case"purge":return await runPurgeCommand(parsed.argv);case"install-git-hooks":return runInstallGitHooksCommand(parsed.argv);case"git-hook":return await runGitHookCommand(parsed.argv);case"file-scope-guard":return runFileScopeGuardCli();default:return console.error('Error: Unknown command. Run "conductor --help" for usage.'),1}}catch(error){let envelope=toConductorErrorEnvelope(error);return console.error(`Error: ${formatConductorErrorLine(envelope)}`),envelope.status>=500?2:1}}Promise.resolve(runConductorCli(process.argv.slice(2))).then(exitCode=>{process.exit(exitCode)}).catch(()=>{process.stderr.write(`Error: conductor command failed.
155
+ `)),0)}async function runConductorCli(argv){let parsed=parseConductorArgs(argv);if(parsed.kind==="help")return console.log(getConductorUsage()),0;if(parsed.kind==="error")return console.error(`Error: ${parsed.message}`),1;try{switch(parsed.command){case"emit-event":return await runEmitEventCommand(parsed.argv);case"supervise":return await runSuperviseCommand(parsed.argv);case"epic-tick":return await runEpicTickCommand(parsed.argv);case"approve-plan":return await runApprovePlanCommand(parsed.argv);case"epic-status":return await runEpicStatusCommand(parsed.argv);case"send-message":return await runSendMessageCommand(parsed.argv);case"check-messages":return await runCheckMessagesCommand(parsed.argv);case"doctor":return await runDoctorCommand(parsed.argv);case"purge":return await runPurgeCommand(parsed.argv);case"install-git-hooks":return runInstallGitHooksCommand(parsed.argv);case"git-hook":return await runGitHookCommand(parsed.argv);case CONDUCTOR_HOOK_BIN_ACTION:return runHookBinDiagnosticCommand();case"file-scope-guard":return runFileScopeGuardCli();default:return console.error('Error: Unknown command. Run "conductor --help" for usage.'),1}}catch(error){let envelope=toConductorErrorEnvelope(error);return console.error(`Error: ${formatConductorErrorLine(envelope)}`),envelope.status>=500?2:1}}Promise.resolve(runConductorCli(process.argv.slice(2))).then(exitCode=>{process.exit(exitCode)}).catch(()=>{process.stderr.write(`Error: conductor command failed.
156
156
  `),process.exit(2)});