@agimon-ai/doompi-team 0.0.1-alpha.2 → 0.0.1-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -17
- package/dist/adapters/asyncJobTracker.cjs +2 -0
- package/dist/adapters/asyncJobTracker.cjs.map +1 -0
- package/dist/adapters/asyncJobTracker.mjs +2 -0
- package/dist/adapters/asyncJobTracker.mjs.map +1 -0
- package/dist/adapters/atomicJson.cjs +2 -0
- package/dist/adapters/atomicJson.cjs.map +1 -0
- package/dist/adapters/atomicJson.mjs +2 -0
- package/dist/adapters/atomicJson.mjs.map +1 -0
- package/dist/adapters/pi/extension.cjs +2 -0
- package/dist/adapters/pi/extension.cjs.map +1 -0
- package/dist/adapters/pi/extension.mjs +2 -0
- package/dist/adapters/pi/extension.mjs.map +1 -0
- package/dist/adapters/pollScheduler.cjs +2 -0
- package/dist/adapters/pollScheduler.cjs.map +1 -0
- package/dist/adapters/pollScheduler.mjs +2 -0
- package/dist/adapters/pollScheduler.mjs.map +1 -0
- package/dist/adapters/process/childTranscript.cjs +5 -0
- package/dist/adapters/process/childTranscript.cjs.map +1 -0
- package/dist/adapters/process/childTranscript.mjs +5 -0
- package/dist/adapters/process/childTranscript.mjs.map +1 -0
- package/dist/adapters/process/env.cjs +2 -0
- package/dist/adapters/process/env.cjs.map +1 -0
- package/dist/adapters/process/env.d.cts +69 -0
- package/dist/adapters/process/env.d.cts.map +1 -0
- package/dist/adapters/process/env.d.mts +69 -0
- package/dist/adapters/process/env.d.mts.map +1 -0
- package/dist/adapters/process/env.mjs +2 -0
- package/dist/adapters/process/env.mjs.map +1 -0
- package/dist/adapters/process/sdkRunnerEntry.cjs +2 -0
- package/dist/adapters/process/sdkRunnerEntry.cjs.map +1 -0
- package/dist/adapters/process/sdkRunnerEntry.d.cts +5 -0
- package/dist/adapters/process/sdkRunnerEntry.d.cts.map +1 -0
- package/dist/adapters/process/sdkRunnerEntry.d.mts +5 -0
- package/dist/adapters/process/sdkRunnerEntry.d.mts.map +1 -0
- package/dist/adapters/process/sdkRunnerEntry.mjs +2 -0
- package/dist/adapters/process/sdkRunnerEntry.mjs.map +1 -0
- package/dist/adapters/processTerminal.cjs +2 -0
- package/dist/adapters/processTerminal.cjs.map +1 -0
- package/dist/adapters/processTerminal.mjs +2 -0
- package/dist/adapters/processTerminal.mjs.map +1 -0
- package/dist/adapters/resultWatcher.cjs +2 -0
- package/dist/adapters/resultWatcher.cjs.map +1 -0
- package/dist/adapters/resultWatcher.mjs +2 -0
- package/dist/adapters/resultWatcher.mjs.map +1 -0
- package/dist/adapters/runIdResolver.cjs +2 -0
- package/dist/adapters/runIdResolver.cjs.map +1 -0
- package/dist/adapters/runIdResolver.mjs +2 -0
- package/dist/adapters/runIdResolver.mjs.map +1 -0
- package/dist/adapters/runRegistry.cjs +2 -0
- package/dist/adapters/runRegistry.cjs.map +1 -0
- package/dist/adapters/runRegistry.mjs +2 -0
- package/dist/adapters/runRegistry.mjs.map +1 -0
- package/dist/adapters/scopeOwner.cjs +2 -0
- package/dist/adapters/scopeOwner.cjs.map +1 -0
- package/dist/adapters/scopeOwner.mjs +2 -0
- package/dist/adapters/scopeOwner.mjs.map +1 -0
- package/dist/adapters/staleRunReconciler.cjs +2 -0
- package/dist/adapters/staleRunReconciler.cjs.map +1 -0
- package/dist/adapters/staleRunReconciler.mjs +2 -0
- package/dist/adapters/staleRunReconciler.mjs.map +1 -0
- package/dist/adapters/statusReader.cjs +2 -0
- package/dist/adapters/statusReader.cjs.map +1 -0
- package/dist/adapters/statusReader.mjs +2 -0
- package/dist/adapters/statusReader.mjs.map +1 -0
- package/dist/adapters/suspendedRuns.cjs +6 -0
- package/dist/adapters/suspendedRuns.cjs.map +1 -0
- package/dist/adapters/suspendedRuns.mjs +6 -0
- package/dist/adapters/suspendedRuns.mjs.map +1 -0
- package/dist/api/backgroundWork.cjs +1 -1
- package/dist/api/backgroundWork.d.cts +2 -2
- package/dist/api/backgroundWork.d.mts +2 -2
- package/dist/api/backgroundWork.mjs +1 -1
- package/dist/api/capabilityCeiling.cjs +1 -1
- package/dist/api/capabilityCeiling.d.cts +3 -3
- package/dist/api/capabilityCeiling.d.mts +3 -3
- package/dist/api/capabilityCeiling.mjs +1 -2
- package/dist/api/delegation.cjs +1 -1
- package/dist/api/delegation.d.cts +1 -1
- package/dist/api/delegation.d.mts +1 -1
- package/dist/api/delegation.mjs +1 -1
- package/dist/api/teamSnapshot.cjs +1 -1
- package/dist/api/teamSnapshot.d.cts +2 -2
- package/dist/api/teamSnapshot.d.mts +2 -2
- package/dist/api/teamSnapshot.mjs +1 -2
- package/dist/commands/slash/chainExpression.cjs.map +1 -0
- package/dist/commands/slash/chainExpression.mjs.map +1 -0
- package/dist/commands/slash/doctor.cjs +5 -0
- package/dist/commands/slash/doctor.cjs.map +1 -0
- package/dist/commands/slash/doctor.mjs +5 -0
- package/dist/{slash/doctor.cjs.map → commands/slash/doctor.mjs.map} +1 -1
- package/dist/{slash → commands/slash}/slashCommands.cjs +1 -1
- package/dist/commands/slash/slashCommands.cjs.map +1 -0
- package/dist/{slash → commands/slash}/slashCommands.mjs +2 -2
- package/dist/commands/slash/slashCommands.mjs.map +1 -0
- package/dist/commands/slash/spawnRequestMapping.cjs.map +1 -0
- package/dist/commands/slash/spawnRequestMapping.mjs.map +1 -0
- package/dist/commands/slash/subagentLaunch.cjs +2 -0
- package/dist/commands/slash/subagentLaunch.cjs.map +1 -0
- package/dist/commands/slash/subagentLaunch.mjs +2 -0
- package/dist/commands/slash/subagentLaunch.mjs.map +1 -0
- package/dist/container/globalBridge.cjs.map +1 -1
- package/dist/container/globalBridge.d.cts +1 -1
- package/dist/container/globalBridge.d.mts +1 -1
- package/dist/container/globalBridge.mjs.map +1 -1
- package/dist/container/index.cjs +1 -1
- package/dist/container/index.cjs.map +1 -1
- package/dist/container/index.d.cts +2 -1
- package/dist/container/index.d.cts.map +1 -1
- package/dist/container/index.d.mts +2 -1
- package/dist/container/index.d.mts.map +1 -1
- package/dist/container/index.mjs +1 -1
- package/dist/container/index.mjs.map +1 -1
- package/dist/container/modules/agents.cjs +1 -1
- package/dist/container/modules/agents.cjs.map +1 -1
- package/dist/container/modules/agents.mjs +1 -1
- package/dist/container/modules/agents.mjs.map +1 -1
- package/dist/container/modules/core.cjs +1 -1
- package/dist/container/modules/core.cjs.map +1 -1
- package/dist/container/modules/core.mjs +1 -1
- package/dist/container/modules/core.mjs.map +1 -1
- package/dist/container/modules/extensions.cjs +1 -1
- package/dist/container/modules/extensions.cjs.map +1 -1
- package/dist/container/modules/extensions.mjs +1 -1
- package/dist/container/modules/extensions.mjs.map +1 -1
- package/dist/container/modules/intercom.cjs +1 -1
- package/dist/container/modules/intercom.cjs.map +1 -1
- package/dist/container/modules/intercom.mjs +1 -1
- package/dist/container/modules/intercom.mjs.map +1 -1
- package/dist/container/modules/runs.cjs +1 -1
- package/dist/container/modules/runs.cjs.map +1 -1
- package/dist/container/modules/runs.mjs +1 -1
- package/dist/container/modules/runs.mjs.map +1 -1
- package/dist/container/types.cjs +1 -1
- package/dist/container/types.cjs.map +1 -1
- package/dist/container/types.d.cts +1 -0
- package/dist/container/types.d.cts.map +1 -1
- package/dist/container/types.d.mts +1 -0
- package/dist/container/types.d.mts.map +1 -1
- package/dist/container/types.mjs +1 -1
- package/dist/container/types.mjs.map +1 -1
- package/dist/env.cjs +1 -2
- package/dist/env.d.cts +2 -65
- package/dist/env.d.mts +2 -65
- package/dist/env.mjs +1 -1
- package/dist/env.mjs.map +1 -1
- package/dist/extensions/config.cjs.map +1 -1
- package/dist/extensions/config.mjs.map +1 -1
- package/dist/extensions/delegationBridge.cjs.map +1 -1
- package/dist/extensions/delegationBridge.mjs.map +1 -1
- package/dist/extensions/doom.cjs +1 -1
- package/dist/extensions/doom.cjs.map +1 -1
- package/dist/extensions/doom.mjs +1 -1
- package/dist/extensions/doom.mjs.map +1 -1
- package/dist/extensions/fablePlanBridge.cjs +1 -1
- package/dist/extensions/fablePlanBridge.cjs.map +1 -1
- package/dist/extensions/fablePlanBridge.mjs +1 -1
- package/dist/extensions/fablePlanBridge.mjs.map +1 -1
- package/dist/extensions/managementActions.cjs +1 -1
- package/dist/extensions/managementActions.cjs.map +1 -1
- package/dist/extensions/managementActions.mjs +1 -1
- package/dist/extensions/managementActions.mjs.map +1 -1
- package/dist/extensions/operationJournal.cjs +1 -1
- package/dist/extensions/operationJournal.cjs.map +1 -1
- package/dist/extensions/operationJournal.mjs +1 -1
- package/dist/extensions/operationJournal.mjs.map +1 -1
- package/dist/extensions/orchestratorPrompt.cjs +5 -6
- package/dist/extensions/orchestratorPrompt.cjs.map +1 -1
- package/dist/extensions/orchestratorPrompt.mjs +5 -6
- package/dist/extensions/orchestratorPrompt.mjs.map +1 -1
- package/dist/extensions/schemas.mjs.map +1 -1
- package/dist/extensions/spawnPlan.cjs +3 -2
- package/dist/extensions/spawnPlan.cjs.map +1 -1
- package/dist/extensions/spawnPlan.mjs +3 -2
- package/dist/extensions/spawnPlan.mjs.map +1 -1
- package/dist/extensions/standard.cjs +1 -1
- package/dist/extensions/standard.cjs.map +1 -1
- package/dist/extensions/standard.mjs +1 -1
- package/dist/extensions/standard.mjs.map +1 -1
- package/dist/extensions/statusViews.cjs +1 -1
- package/dist/extensions/statusViews.cjs.map +1 -1
- package/dist/extensions/statusViews.mjs +2 -2
- package/dist/extensions/statusViews.mjs.map +1 -1
- package/dist/extensions/subagentPromptRuntime.cjs +11 -11
- package/dist/extensions/subagentPromptRuntime.cjs.map +1 -1
- package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -1
- package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -1
- package/dist/extensions/subagentPromptRuntime.mjs +5 -5
- package/dist/extensions/subagentPromptRuntime.mjs.map +1 -1
- package/dist/extensions/subagentTool.cjs +5 -6
- package/dist/extensions/subagentTool.cjs.map +1 -1
- package/dist/extensions/subagentTool.mjs +5 -6
- package/dist/extensions/subagentTool.mjs.map +1 -1
- package/dist/extensions/toolDescription.cjs +1 -1
- package/dist/extensions/toolDescription.cjs.map +1 -1
- package/dist/extensions/toolDescription.mjs +1 -1
- package/dist/extensions/toolDescription.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/runs/background/cliRunnerEntry.cjs +1 -2
- package/dist/runs/background/cliRunnerEntry.mjs +1 -2
- package/dist/runs/sdkRunnerEntry.cjs +1 -2
- package/dist/runs/sdkRunnerEntry.d.cts +2 -1
- package/dist/runs/sdkRunnerEntry.d.mts +2 -1
- package/dist/runs/sdkRunnerEntry.mjs +1 -2
- package/dist/schemas/team/backgroundWork.cjs +2 -0
- package/dist/schemas/team/backgroundWork.cjs.map +1 -0
- package/dist/{protocol → schemas/team}/backgroundWork.d.cts +2 -2
- package/dist/schemas/team/backgroundWork.d.cts.map +1 -0
- package/dist/{protocol → schemas/team}/backgroundWork.d.mts +2 -2
- package/dist/schemas/team/backgroundWork.d.mts.map +1 -0
- package/dist/schemas/team/backgroundWork.mjs +2 -0
- package/dist/{protocol/backgroundWork.cjs.map → schemas/team/backgroundWork.mjs.map} +1 -1
- package/dist/schemas/team/capabilityCeiling.cjs +2 -0
- package/dist/schemas/team/capabilityCeiling.cjs.map +1 -0
- package/dist/{protocol → schemas/team}/capabilityCeiling.d.cts +3 -3
- package/dist/schemas/team/capabilityCeiling.d.cts.map +1 -0
- package/dist/{protocol → schemas/team}/capabilityCeiling.d.mts +3 -3
- package/dist/schemas/team/capabilityCeiling.d.mts.map +1 -0
- package/dist/schemas/team/capabilityCeiling.mjs +2 -0
- package/dist/schemas/team/capabilityCeiling.mjs.map +1 -0
- package/dist/schemas/team/delegation.cjs.map +1 -0
- package/dist/{protocol → schemas/team}/delegation.d.cts +1 -1
- package/dist/schemas/team/delegation.d.cts.map +1 -0
- package/dist/{protocol → schemas/team}/delegation.d.mts +1 -1
- package/dist/schemas/team/delegation.d.mts.map +1 -0
- package/dist/schemas/team/delegation.mjs.map +1 -0
- package/dist/schemas/team/packageConfig.cjs +2 -0
- package/dist/schemas/team/packageConfig.cjs.map +1 -0
- package/dist/schemas/team/packageConfig.mjs +2 -0
- package/dist/schemas/team/packageConfig.mjs.map +1 -0
- package/dist/services/agents/discovery.cjs +2 -0
- package/dist/services/agents/discovery.cjs.map +1 -0
- package/dist/services/agents/discovery.mjs +2 -0
- package/dist/services/agents/discovery.mjs.map +1 -0
- package/dist/services/agents/frontmatter.cjs.map +1 -0
- package/dist/{agents → services/agents}/frontmatter.mjs +1 -1
- package/dist/services/agents/frontmatter.mjs.map +1 -0
- package/dist/services/agents/loader.cjs +2 -0
- package/dist/services/agents/loader.cjs.map +1 -0
- package/dist/services/agents/loader.mjs +2 -0
- package/dist/services/agents/loader.mjs.map +1 -0
- package/dist/services/agents/memory.cjs +3 -0
- package/dist/services/agents/memory.cjs.map +1 -0
- package/dist/{agents → services/agents}/memory.mjs +1 -1
- package/dist/services/agents/memory.mjs.map +1 -0
- package/dist/services/agents/projectRoot.cjs +2 -0
- package/dist/services/agents/projectRoot.cjs.map +1 -0
- package/dist/services/agents/projectRoot.mjs +2 -0
- package/dist/services/agents/projectRoot.mjs.map +1 -0
- package/dist/services/agents/settings.cjs +2 -0
- package/dist/services/agents/settings.cjs.map +1 -0
- package/dist/services/agents/settings.mjs +2 -0
- package/dist/services/agents/settings.mjs.map +1 -0
- package/dist/services/agents/skills.cjs +0 -0
- package/dist/services/agents/skills.cjs.map +1 -0
- package/dist/services/agents/skills.mjs +5 -0
- package/dist/services/agents/skills.mjs.map +1 -0
- package/dist/{agents → services/agents}/types.d.cts +4 -4
- package/dist/services/agents/types.d.cts.map +1 -0
- package/dist/{agents → services/agents}/types.d.mts +4 -4
- package/dist/services/agents/types.d.mts.map +1 -0
- package/dist/services/api/backgroundWork.cjs +1 -0
- package/dist/services/api/backgroundWork.d.cts +1 -0
- package/dist/services/api/backgroundWork.d.mts +1 -0
- package/dist/services/api/backgroundWork.mjs +1 -0
- package/dist/services/api/capabilityCeiling.cjs +1 -0
- package/dist/services/api/capabilityCeiling.d.cts +2 -0
- package/dist/services/api/capabilityCeiling.d.mts +2 -0
- package/dist/services/api/capabilityCeiling.mjs +2 -0
- package/dist/services/api/capabilityCeiling.mjs.map +1 -0
- package/dist/services/api/teamSnapshot.cjs +1 -0
- package/dist/services/api/teamSnapshot.d.cts +1 -0
- package/dist/services/api/teamSnapshot.d.mts +1 -0
- package/dist/services/api/teamSnapshot.mjs +2 -0
- package/dist/services/api/teamSnapshot.mjs.map +1 -0
- package/dist/services/intercom/intercomBridge.cjs.map +1 -0
- package/dist/services/intercom/intercomBridge.mjs.map +1 -0
- package/dist/services/intercom/nativeTeamChannel.cjs +5 -0
- package/dist/services/intercom/nativeTeamChannel.cjs.map +1 -0
- package/dist/{intercom → services/intercom}/nativeTeamChannel.d.cts +1 -1
- package/dist/services/intercom/nativeTeamChannel.d.cts.map +1 -0
- package/dist/{intercom → services/intercom}/nativeTeamChannel.d.mts +1 -1
- package/dist/services/intercom/nativeTeamChannel.d.mts.map +1 -0
- package/dist/services/intercom/nativeTeamChannel.mjs +5 -0
- package/dist/services/intercom/nativeTeamChannel.mjs.map +1 -0
- package/dist/services/intercom/supervisorControlChannel.cjs +2 -0
- package/dist/services/intercom/supervisorControlChannel.cjs.map +1 -0
- package/dist/{intercom → services/intercom}/supervisorControlChannel.mjs +1 -1
- package/dist/services/intercom/supervisorControlChannel.mjs.map +1 -0
- package/dist/services/runs/background/asyncExecution.cjs +2 -0
- package/dist/services/runs/background/asyncExecution.cjs.map +1 -0
- package/dist/services/runs/background/asyncExecution.mjs +2 -0
- package/dist/services/runs/background/asyncExecution.mjs.map +1 -0
- package/dist/services/runs/background/asyncJobTracker.cjs +1 -0
- package/dist/services/runs/background/asyncJobTracker.mjs +2 -0
- package/dist/services/runs/background/asyncJobTracker.mjs.map +1 -0
- package/dist/services/runs/background/cliRunnerEntry.cjs +2 -0
- package/dist/services/runs/background/cliRunnerEntry.cjs.map +1 -0
- package/dist/services/runs/background/cliRunnerEntry.mjs +2 -0
- package/dist/services/runs/background/cliRunnerEntry.mjs.map +1 -0
- package/dist/services/runs/background/completionBatcher.cjs.map +1 -0
- package/dist/services/runs/background/completionBatcher.mjs +2 -0
- package/dist/services/runs/background/completionBatcher.mjs.map +1 -0
- package/dist/{runs → services/runs}/background/notify.cjs +1 -1
- package/dist/services/runs/background/notify.cjs.map +1 -0
- package/dist/{runs → services/runs}/background/notify.mjs +1 -1
- package/dist/services/runs/background/notify.mjs.map +1 -0
- package/dist/services/runs/background/parentWatchdog.cjs.map +1 -0
- package/dist/services/runs/background/parentWatchdog.mjs.map +1 -0
- package/dist/services/runs/background/processTerminal.cjs +1 -0
- package/dist/services/runs/background/processTerminal.mjs +2 -0
- package/dist/services/runs/background/processTerminal.mjs.map +1 -0
- package/dist/services/runs/background/resultWatcher.cjs +1 -0
- package/dist/services/runs/background/resultWatcher.mjs +2 -0
- package/dist/services/runs/background/resultWatcher.mjs.map +1 -0
- package/dist/services/runs/background/runIdResolver.cjs +1 -0
- package/dist/services/runs/background/runIdResolver.mjs +2 -0
- package/dist/services/runs/background/runIdResolver.mjs.map +1 -0
- package/dist/services/runs/background/runnerBootstrap.cjs +2 -0
- package/dist/services/runs/background/runnerBootstrap.cjs.map +1 -0
- package/dist/services/runs/background/runnerBootstrap.mjs +2 -0
- package/dist/services/runs/background/runnerBootstrap.mjs.map +1 -0
- package/dist/services/runs/background/runnerExecution.cjs +2 -0
- package/dist/services/runs/background/runnerExecution.cjs.map +1 -0
- package/dist/services/runs/background/runnerExecution.mjs +2 -0
- package/dist/services/runs/background/runnerExecution.mjs.map +1 -0
- package/dist/{runs → services/runs}/background/runnerReporting.cjs +2 -2
- package/dist/services/runs/background/runnerReporting.cjs.map +1 -0
- package/dist/{runs → services/runs}/background/runnerReporting.mjs +2 -2
- package/dist/services/runs/background/runnerReporting.mjs.map +1 -0
- package/dist/services/runs/background/runnerTeamMembership.cjs +2 -0
- package/dist/services/runs/background/runnerTeamMembership.cjs.map +1 -0
- package/dist/services/runs/background/runnerTeamMembership.mjs +2 -0
- package/dist/services/runs/background/runnerTeamMembership.mjs.map +1 -0
- package/dist/services/runs/background/spawnHandshake.cjs +2 -0
- package/dist/services/runs/background/spawnHandshake.cjs.map +1 -0
- package/dist/services/runs/background/spawnHandshake.mjs +2 -0
- package/dist/services/runs/background/spawnHandshake.mjs.map +1 -0
- package/dist/services/runs/background/staleRunReconciler.cjs +1 -0
- package/dist/services/runs/background/staleRunReconciler.mjs +2 -0
- package/dist/services/runs/background/staleRunReconciler.mjs.map +1 -0
- package/dist/services/runs/background/statusReader.cjs +1 -0
- package/dist/services/runs/background/statusReader.mjs +2 -0
- package/dist/services/runs/background/statusReader.mjs.map +1 -0
- package/dist/services/runs/background/statusWriter.cjs +2 -0
- package/dist/services/runs/background/statusWriter.cjs.map +1 -0
- package/dist/services/runs/background/statusWriter.mjs +2 -0
- package/dist/services/runs/background/statusWriter.mjs.map +1 -0
- package/dist/services/runs/background/subagentWait.cjs +2 -0
- package/dist/services/runs/background/subagentWait.cjs.map +1 -0
- package/dist/services/runs/background/subagentWait.mjs +2 -0
- package/dist/services/runs/background/subagentWait.mjs.map +1 -0
- package/dist/{runs/background/terminalPersistence.mjs → services/runs/background/terminalPersistence.cjs} +2 -2
- package/dist/services/runs/background/terminalPersistence.cjs.map +1 -0
- package/dist/services/runs/background/terminalPersistence.mjs +2 -0
- package/dist/services/runs/background/terminalPersistence.mjs.map +1 -0
- package/dist/services/runs/extensionErrorTelemetry.cjs +2 -0
- package/dist/services/runs/extensionErrorTelemetry.cjs.map +1 -0
- package/dist/services/runs/extensionErrorTelemetry.mjs +2 -0
- package/dist/services/runs/extensionErrorTelemetry.mjs.map +1 -0
- package/dist/services/runs/registry/processGroup.cjs.map +1 -0
- package/dist/services/runs/registry/processGroup.mjs.map +1 -0
- package/dist/services/runs/registry/runRegistry.cjs +1 -0
- package/dist/services/runs/registry/runRegistry.mjs +2 -0
- package/dist/services/runs/registry/runRegistry.mjs.map +1 -0
- package/dist/services/runs/registry/sessionLifecycle.cjs +2 -0
- package/dist/services/runs/registry/sessionLifecycle.cjs.map +1 -0
- package/dist/services/runs/registry/sessionLifecycle.mjs +2 -0
- package/dist/services/runs/registry/sessionLifecycle.mjs.map +1 -0
- package/dist/services/runs/registry/suspendedRuns.cjs +1 -0
- package/dist/services/runs/registry/suspendedRuns.mjs +2 -0
- package/dist/services/runs/registry/suspendedRuns.mjs.map +1 -0
- package/dist/services/runs/sdkRunnerEntry.cjs +1 -0
- package/dist/services/runs/sdkRunnerEntry.mjs +1 -0
- package/dist/services/runs/shared/claudeFableProfile.cjs +4 -0
- package/dist/services/runs/shared/claudeFableProfile.cjs.map +1 -0
- package/dist/services/runs/shared/claudeFableProfile.mjs +4 -0
- package/dist/services/runs/shared/claudeFableProfile.mjs.map +1 -0
- package/dist/services/runs/shared/depthGuard.cjs +2 -0
- package/dist/services/runs/shared/depthGuard.cjs.map +1 -0
- package/dist/services/runs/shared/depthGuard.mjs +2 -0
- package/dist/services/runs/shared/depthGuard.mjs.map +1 -0
- package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
- package/dist/services/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
- package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
- package/dist/services/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
- package/dist/services/runs/shared/modelFallback.cjs +2 -0
- package/dist/services/runs/shared/modelFallback.cjs.map +1 -0
- package/dist/services/runs/shared/modelFallback.mjs +2 -0
- package/dist/services/runs/shared/modelFallback.mjs.map +1 -0
- package/dist/services/runs/shared/modelScope.cjs +2 -0
- package/dist/services/runs/shared/modelScope.cjs.map +1 -0
- package/dist/services/runs/shared/modelScope.mjs +2 -0
- package/dist/services/runs/shared/modelScope.mjs.map +1 -0
- package/dist/services/runs/shared/nestedPath.cjs +2 -0
- package/dist/services/runs/shared/nestedPath.cjs.map +1 -0
- package/dist/services/runs/shared/nestedPath.mjs +2 -0
- package/dist/services/runs/shared/nestedPath.mjs.map +1 -0
- package/dist/services/runs/shared/piArgs.cjs +2 -0
- package/dist/services/runs/shared/piArgs.cjs.map +1 -0
- package/dist/services/runs/shared/piArgs.mjs +2 -0
- package/dist/services/runs/shared/piArgs.mjs.map +1 -0
- package/dist/services/runs/shared/piSpawn.cjs +2 -0
- package/dist/services/runs/shared/piSpawn.cjs.map +1 -0
- package/dist/services/runs/shared/piSpawn.mjs +2 -0
- package/dist/services/runs/shared/piSpawn.mjs.map +1 -0
- package/dist/services/runs/shared/runWithConcurrency.cjs +2 -0
- package/dist/services/runs/shared/runWithConcurrency.cjs.map +1 -0
- package/dist/services/runs/shared/runWithConcurrency.d.cts +25 -0
- package/dist/services/runs/shared/runWithConcurrency.d.cts.map +1 -0
- package/dist/services/runs/shared/runWithConcurrency.d.mts +25 -0
- package/dist/services/runs/shared/runWithConcurrency.d.mts.map +1 -0
- package/dist/services/runs/shared/runWithConcurrency.mjs +2 -0
- package/dist/services/runs/shared/runWithConcurrency.mjs.map +1 -0
- package/dist/services/runs/shared/runtimeRegistry.cjs +2 -0
- package/dist/services/runs/shared/runtimeRegistry.cjs.map +1 -0
- package/dist/services/runs/shared/runtimeRegistry.mjs +2 -0
- package/dist/services/runs/shared/runtimeRegistry.mjs.map +1 -0
- package/dist/services/runs/shared/structuredOutput.cjs +2 -0
- package/dist/{runs → services/runs}/shared/structuredOutput.cjs.map +1 -1
- package/dist/services/runs/shared/structuredOutput.mjs +2 -0
- package/dist/{runs → services/runs}/shared/structuredOutput.mjs.map +1 -1
- package/dist/services/runs/shared/toolAvailability.cjs +2 -0
- package/dist/services/runs/shared/toolAvailability.cjs.map +1 -0
- package/dist/services/runs/shared/toolAvailability.mjs +2 -0
- package/dist/services/runs/shared/toolAvailability.mjs.map +1 -0
- package/dist/services/runs/shared/toolBudget.cjs +2 -0
- package/dist/services/runs/shared/toolBudget.cjs.map +1 -0
- package/dist/services/runs/shared/toolBudget.mjs +2 -0
- package/dist/services/runs/shared/toolBudget.mjs.map +1 -0
- package/dist/shared/artifacts.cjs.map +1 -1
- package/dist/shared/artifacts.mjs.map +1 -1
- package/dist/shared/atomicJson.cjs +1 -2
- package/dist/shared/atomicJson.mjs +1 -1
- package/dist/shared/atomicJson.mjs.map +1 -1
- package/dist/shared/childTranscript.cjs +1 -5
- package/dist/shared/childTranscript.mjs +1 -4
- package/dist/shared/childTranscript.mjs.map +1 -1
- package/dist/shared/fileSystemRetry.cjs +1 -1
- package/dist/shared/fileSystemRetry.cjs.map +1 -1
- package/dist/shared/fileSystemRetry.mjs +1 -1
- package/dist/shared/fileSystemRetry.mjs.map +1 -1
- package/dist/shared/formatters.cjs.map +1 -1
- package/dist/shared/formatters.mjs.map +1 -1
- package/dist/shared/paths.cjs +1 -1
- package/dist/shared/paths.cjs.map +1 -1
- package/dist/shared/paths.mjs +1 -1
- package/dist/shared/paths.mjs.map +1 -1
- package/dist/shared/pollScheduler.cjs +1 -2
- package/dist/shared/pollScheduler.mjs +1 -1
- package/dist/shared/pollScheduler.mjs.map +1 -1
- package/dist/shared/scopeOwner.cjs +1 -2
- package/dist/shared/scopeOwner.mjs +1 -1
- package/dist/shared/scopeOwner.mjs.map +1 -1
- package/dist/tui/agentCatalog.cjs +1 -1
- package/dist/tui/agentCatalog.cjs.map +1 -1
- package/dist/tui/agentCatalog.mjs +1 -1
- package/dist/tui/agentCatalog.mjs.map +1 -1
- package/dist/tui/agentResourceProjection.cjs +1 -1
- package/dist/tui/agentResourceProjection.cjs.map +1 -1
- package/dist/tui/agentResourceProjection.mjs +1 -1
- package/dist/tui/agentResourceProjection.mjs.map +1 -1
- package/dist/tui/completionNotice.cjs +1 -1
- package/dist/tui/completionNotice.cjs.map +1 -1
- package/dist/tui/completionNotice.mjs +1 -1
- package/dist/tui/completionNotice.mjs.map +1 -1
- package/dist/tui/fleet.cjs +2 -2
- package/dist/tui/fleet.cjs.map +1 -1
- package/dist/tui/fleet.mjs +2 -2
- package/dist/tui/fleet.mjs.map +1 -1
- package/dist/tui/fleetAgentView.cjs.map +1 -1
- package/dist/tui/fleetAgentView.mjs.map +1 -1
- package/dist/tui/fleetStatus.cjs +1 -1
- package/dist/tui/fleetStatus.cjs.map +1 -1
- package/dist/tui/fleetStatus.mjs +1 -1
- package/dist/tui/fleetStatus.mjs.map +1 -1
- package/dist/tui/fleetTranscript.cjs +1 -1
- package/dist/tui/fleetTranscript.cjs.map +1 -1
- package/dist/tui/fleetTranscript.mjs +1 -1
- package/dist/tui/fleetTranscript.mjs.map +1 -1
- package/dist/tui/register.cjs +1 -1
- package/dist/tui/register.cjs.map +1 -1
- package/dist/tui/register.mjs +1 -1
- package/dist/tui/register.mjs.map +1 -1
- package/dist/tui/subagentToolRender.cjs +3 -0
- package/dist/tui/subagentToolRender.cjs.map +1 -0
- package/dist/tui/subagentToolRender.mjs +3 -0
- package/dist/tui/subagentToolRender.mjs.map +1 -0
- package/dist/{types.d.cts → types/index.d.cts} +2 -2
- package/dist/types/index.d.cts.map +1 -0
- package/dist/{types.d.mts → types/index.d.mts} +2 -2
- package/dist/types/index.d.mts.map +1 -0
- package/package.json +23 -16
- package/dist/agents/discovery.cjs +0 -2
- package/dist/agents/discovery.cjs.map +0 -1
- package/dist/agents/discovery.mjs +0 -2
- package/dist/agents/discovery.mjs.map +0 -1
- package/dist/agents/frontmatter.cjs.map +0 -1
- package/dist/agents/frontmatter.mjs.map +0 -1
- package/dist/agents/loader.cjs +0 -2
- package/dist/agents/loader.cjs.map +0 -1
- package/dist/agents/loader.mjs +0 -2
- package/dist/agents/loader.mjs.map +0 -1
- package/dist/agents/memory.cjs +0 -3
- package/dist/agents/memory.cjs.map +0 -1
- package/dist/agents/memory.mjs.map +0 -1
- package/dist/agents/projectRoot.cjs +0 -2
- package/dist/agents/projectRoot.cjs.map +0 -1
- package/dist/agents/projectRoot.mjs +0 -2
- package/dist/agents/projectRoot.mjs.map +0 -1
- package/dist/agents/settings.cjs +0 -2
- package/dist/agents/settings.cjs.map +0 -1
- package/dist/agents/settings.mjs +0 -2
- package/dist/agents/settings.mjs.map +0 -1
- package/dist/agents/skills.cjs +0 -0
- package/dist/agents/skills.cjs.map +0 -1
- package/dist/agents/skills.mjs +0 -5
- package/dist/agents/skills.mjs.map +0 -1
- package/dist/agents/types.d.cts.map +0 -1
- package/dist/agents/types.d.mts.map +0 -1
- package/dist/api/capabilityCeiling.mjs.map +0 -1
- package/dist/api/teamSnapshot.mjs.map +0 -1
- package/dist/env.cjs.map +0 -1
- package/dist/env.d.cts.map +0 -1
- package/dist/env.d.mts.map +0 -1
- package/dist/extension.cjs +0 -2
- package/dist/extension.cjs.map +0 -1
- package/dist/extension.mjs +0 -2
- package/dist/extension.mjs.map +0 -1
- package/dist/intercom/intercomBridge.cjs.map +0 -1
- package/dist/intercom/intercomBridge.mjs.map +0 -1
- package/dist/intercom/nativeTeamChannel.cjs +0 -5
- package/dist/intercom/nativeTeamChannel.cjs.map +0 -1
- package/dist/intercom/nativeTeamChannel.d.cts.map +0 -1
- package/dist/intercom/nativeTeamChannel.d.mts.map +0 -1
- package/dist/intercom/nativeTeamChannel.mjs +0 -5
- package/dist/intercom/nativeTeamChannel.mjs.map +0 -1
- package/dist/intercom/supervisorControlChannel.cjs +0 -2
- package/dist/intercom/supervisorControlChannel.cjs.map +0 -1
- package/dist/intercom/supervisorControlChannel.mjs.map +0 -1
- package/dist/protocol/backgroundWork.cjs +0 -2
- package/dist/protocol/backgroundWork.d.cts.map +0 -1
- package/dist/protocol/backgroundWork.d.mts.map +0 -1
- package/dist/protocol/backgroundWork.mjs +0 -2
- package/dist/protocol/backgroundWork.mjs.map +0 -1
- package/dist/protocol/capabilityCeiling.cjs +0 -2
- package/dist/protocol/capabilityCeiling.cjs.map +0 -1
- package/dist/protocol/capabilityCeiling.d.cts.map +0 -1
- package/dist/protocol/capabilityCeiling.d.mts.map +0 -1
- package/dist/protocol/capabilityCeiling.mjs +0 -2
- package/dist/protocol/capabilityCeiling.mjs.map +0 -1
- package/dist/protocol/delegation.cjs.map +0 -1
- package/dist/protocol/delegation.d.cts.map +0 -1
- package/dist/protocol/delegation.d.mts.map +0 -1
- package/dist/protocol/delegation.mjs.map +0 -1
- package/dist/runs/background/asyncExecution.cjs +0 -2
- package/dist/runs/background/asyncExecution.cjs.map +0 -1
- package/dist/runs/background/asyncExecution.mjs +0 -2
- package/dist/runs/background/asyncExecution.mjs.map +0 -1
- package/dist/runs/background/asyncJobTracker.cjs +0 -2
- package/dist/runs/background/asyncJobTracker.cjs.map +0 -1
- package/dist/runs/background/asyncJobTracker.mjs +0 -2
- package/dist/runs/background/asyncJobTracker.mjs.map +0 -1
- package/dist/runs/background/cliRunnerEntry.cjs.map +0 -1
- package/dist/runs/background/cliRunnerEntry.mjs.map +0 -1
- package/dist/runs/background/completionBatcher.cjs.map +0 -1
- package/dist/runs/background/completionBatcher.mjs +0 -2
- package/dist/runs/background/completionBatcher.mjs.map +0 -1
- package/dist/runs/background/notify.cjs.map +0 -1
- package/dist/runs/background/notify.mjs.map +0 -1
- package/dist/runs/background/parentWatchdog.cjs.map +0 -1
- package/dist/runs/background/parentWatchdog.mjs.map +0 -1
- package/dist/runs/background/processTerminal.cjs +0 -2
- package/dist/runs/background/processTerminal.cjs.map +0 -1
- package/dist/runs/background/processTerminal.mjs +0 -2
- package/dist/runs/background/processTerminal.mjs.map +0 -1
- package/dist/runs/background/resultWatcher.cjs +0 -2
- package/dist/runs/background/resultWatcher.cjs.map +0 -1
- package/dist/runs/background/resultWatcher.mjs +0 -2
- package/dist/runs/background/resultWatcher.mjs.map +0 -1
- package/dist/runs/background/runIdResolver.cjs +0 -2
- package/dist/runs/background/runIdResolver.cjs.map +0 -1
- package/dist/runs/background/runIdResolver.mjs +0 -2
- package/dist/runs/background/runIdResolver.mjs.map +0 -1
- package/dist/runs/background/runnerBootstrap.cjs +0 -2
- package/dist/runs/background/runnerBootstrap.cjs.map +0 -1
- package/dist/runs/background/runnerBootstrap.mjs +0 -2
- package/dist/runs/background/runnerBootstrap.mjs.map +0 -1
- package/dist/runs/background/runnerExecution.cjs +0 -2
- package/dist/runs/background/runnerExecution.cjs.map +0 -1
- package/dist/runs/background/runnerExecution.mjs +0 -2
- package/dist/runs/background/runnerExecution.mjs.map +0 -1
- package/dist/runs/background/runnerReporting.cjs.map +0 -1
- package/dist/runs/background/runnerReporting.mjs.map +0 -1
- package/dist/runs/background/runnerTeamMembership.cjs +0 -2
- package/dist/runs/background/runnerTeamMembership.cjs.map +0 -1
- package/dist/runs/background/runnerTeamMembership.mjs +0 -2
- package/dist/runs/background/runnerTeamMembership.mjs.map +0 -1
- package/dist/runs/background/spawnHandshake.cjs +0 -2
- package/dist/runs/background/spawnHandshake.cjs.map +0 -1
- package/dist/runs/background/spawnHandshake.mjs +0 -2
- package/dist/runs/background/spawnHandshake.mjs.map +0 -1
- package/dist/runs/background/staleRunReconciler.cjs +0 -2
- package/dist/runs/background/staleRunReconciler.cjs.map +0 -1
- package/dist/runs/background/staleRunReconciler.mjs +0 -2
- package/dist/runs/background/staleRunReconciler.mjs.map +0 -1
- package/dist/runs/background/statusReader.cjs +0 -2
- package/dist/runs/background/statusReader.cjs.map +0 -1
- package/dist/runs/background/statusReader.mjs +0 -2
- package/dist/runs/background/statusReader.mjs.map +0 -1
- package/dist/runs/background/statusWriter.cjs +0 -2
- package/dist/runs/background/statusWriter.cjs.map +0 -1
- package/dist/runs/background/statusWriter.mjs +0 -2
- package/dist/runs/background/statusWriter.mjs.map +0 -1
- package/dist/runs/background/subagentWait.cjs +0 -2
- package/dist/runs/background/subagentWait.cjs.map +0 -1
- package/dist/runs/background/subagentWait.mjs +0 -2
- package/dist/runs/background/subagentWait.mjs.map +0 -1
- package/dist/runs/background/terminalPersistence.cjs +0 -2
- package/dist/runs/background/terminalPersistence.cjs.map +0 -1
- package/dist/runs/background/terminalPersistence.mjs.map +0 -1
- package/dist/runs/registry/processGroup.cjs.map +0 -1
- package/dist/runs/registry/processGroup.mjs.map +0 -1
- package/dist/runs/registry/runRegistry.cjs +0 -2
- package/dist/runs/registry/runRegistry.cjs.map +0 -1
- package/dist/runs/registry/runRegistry.mjs +0 -2
- package/dist/runs/registry/runRegistry.mjs.map +0 -1
- package/dist/runs/registry/sessionLifecycle.cjs +0 -2
- package/dist/runs/registry/sessionLifecycle.cjs.map +0 -1
- package/dist/runs/registry/sessionLifecycle.mjs +0 -2
- package/dist/runs/registry/sessionLifecycle.mjs.map +0 -1
- package/dist/runs/registry/suspendedRuns.cjs +0 -4
- package/dist/runs/registry/suspendedRuns.cjs.map +0 -1
- package/dist/runs/registry/suspendedRuns.mjs +0 -4
- package/dist/runs/registry/suspendedRuns.mjs.map +0 -1
- package/dist/runs/sdkRunnerEntry.cjs.map +0 -1
- package/dist/runs/sdkRunnerEntry.mjs.map +0 -1
- package/dist/runs/shared/claudeFableProfile.cjs +0 -4
- package/dist/runs/shared/claudeFableProfile.cjs.map +0 -1
- package/dist/runs/shared/claudeFableProfile.mjs +0 -4
- package/dist/runs/shared/claudeFableProfile.mjs.map +0 -1
- package/dist/runs/shared/depthGuard.cjs +0 -2
- package/dist/runs/shared/depthGuard.cjs.map +0 -1
- package/dist/runs/shared/depthGuard.mjs +0 -2
- package/dist/runs/shared/depthGuard.mjs.map +0 -1
- package/dist/runs/shared/mcpDirectToolAllowlist.cjs +0 -2
- package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +0 -1
- package/dist/runs/shared/mcpDirectToolAllowlist.mjs +0 -2
- package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +0 -1
- package/dist/runs/shared/modelFallback.cjs +0 -2
- package/dist/runs/shared/modelFallback.cjs.map +0 -1
- package/dist/runs/shared/modelFallback.mjs +0 -2
- package/dist/runs/shared/modelFallback.mjs.map +0 -1
- package/dist/runs/shared/modelScope.cjs +0 -2
- package/dist/runs/shared/modelScope.cjs.map +0 -1
- package/dist/runs/shared/modelScope.mjs +0 -2
- package/dist/runs/shared/modelScope.mjs.map +0 -1
- package/dist/runs/shared/nestedPath.cjs +0 -2
- package/dist/runs/shared/nestedPath.cjs.map +0 -1
- package/dist/runs/shared/nestedPath.mjs +0 -2
- package/dist/runs/shared/nestedPath.mjs.map +0 -1
- package/dist/runs/shared/piArgs.cjs +0 -2
- package/dist/runs/shared/piArgs.cjs.map +0 -1
- package/dist/runs/shared/piArgs.mjs +0 -2
- package/dist/runs/shared/piArgs.mjs.map +0 -1
- package/dist/runs/shared/piSpawn.cjs +0 -2
- package/dist/runs/shared/piSpawn.cjs.map +0 -1
- package/dist/runs/shared/piSpawn.mjs +0 -2
- package/dist/runs/shared/piSpawn.mjs.map +0 -1
- package/dist/runs/shared/runWithConcurrency.cjs +0 -2
- package/dist/runs/shared/runWithConcurrency.cjs.map +0 -1
- package/dist/runs/shared/runWithConcurrency.mjs +0 -2
- package/dist/runs/shared/runWithConcurrency.mjs.map +0 -1
- package/dist/runs/shared/runtimeRegistry.cjs +0 -2
- package/dist/runs/shared/runtimeRegistry.cjs.map +0 -1
- package/dist/runs/shared/runtimeRegistry.mjs +0 -2
- package/dist/runs/shared/runtimeRegistry.mjs.map +0 -1
- package/dist/runs/shared/structuredOutput.cjs +0 -2
- package/dist/runs/shared/structuredOutput.mjs +0 -2
- package/dist/runs/shared/toolAvailability.cjs +0 -2
- package/dist/runs/shared/toolAvailability.cjs.map +0 -1
- package/dist/runs/shared/toolAvailability.mjs +0 -2
- package/dist/runs/shared/toolAvailability.mjs.map +0 -1
- package/dist/runs/shared/toolBudget.cjs +0 -2
- package/dist/runs/shared/toolBudget.cjs.map +0 -1
- package/dist/runs/shared/toolBudget.mjs +0 -2
- package/dist/runs/shared/toolBudget.mjs.map +0 -1
- package/dist/shared/atomicJson.cjs.map +0 -1
- package/dist/shared/childTranscript.cjs.map +0 -1
- package/dist/shared/pollScheduler.cjs.map +0 -1
- package/dist/shared/scopeOwner.cjs.map +0 -1
- package/dist/slash/chainExpression.cjs.map +0 -1
- package/dist/slash/chainExpression.mjs.map +0 -1
- package/dist/slash/doctor.cjs +0 -5
- package/dist/slash/doctor.mjs +0 -5
- package/dist/slash/doctor.mjs.map +0 -1
- package/dist/slash/slashCommands.cjs.map +0 -1
- package/dist/slash/slashCommands.mjs.map +0 -1
- package/dist/slash/spawnRequestMapping.cjs.map +0 -1
- package/dist/slash/spawnRequestMapping.mjs.map +0 -1
- package/dist/slash/subagentLaunch.cjs +0 -2
- package/dist/slash/subagentLaunch.cjs.map +0 -1
- package/dist/slash/subagentLaunch.mjs +0 -2
- package/dist/slash/subagentLaunch.mjs.map +0 -1
- package/dist/types.d.cts.map +0 -1
- package/dist/types.d.mts.map +0 -1
- /package/dist/{slash → commands/slash}/chainExpression.cjs +0 -0
- /package/dist/{slash → commands/slash}/chainExpression.mjs +0 -0
- /package/dist/{slash → commands/slash}/spawnRequestMapping.cjs +0 -0
- /package/dist/{slash → commands/slash}/spawnRequestMapping.mjs +0 -0
- /package/dist/{protocol → schemas/team}/delegation.cjs +0 -0
- /package/dist/{protocol → schemas/team}/delegation.mjs +0 -0
- /package/dist/{agents → services/agents}/frontmatter.cjs +0 -0
- /package/dist/{intercom → services/intercom}/intercomBridge.cjs +0 -0
- /package/dist/{intercom → services/intercom}/intercomBridge.mjs +0 -0
- /package/dist/{runs → services/runs}/background/completionBatcher.cjs +0 -0
- /package/dist/{runs → services/runs}/background/parentWatchdog.cjs +0 -0
- /package/dist/{runs → services/runs}/background/parentWatchdog.mjs +0 -0
- /package/dist/{runs → services/runs}/registry/processGroup.cjs +0 -0
- /package/dist/{runs → services/runs}/registry/processGroup.mjs +0 -0
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{CHILD_TOOL_DIAGNOSTIC_PATH_ENV as t,DOOMPI_CHILD_EXTENSIONS_ENV as n,DOOMPI_SKILL_DIRS_ENV as r,INHERIT_PROJECT_CONTEXT_ENV as i,INHERIT_SKILLS_ENV as a,MCP_DIRECT_CHILD_TOOLS_ENV as o,MCP_DIRECT_TOOLS_ENV as s,PI_CODING_AGENT_PACKAGE_ROOT_ENV as c,PI_INTERCOM_SESSION_ID_ENV as l,PI_INTERCOM_STABLE_ID_ENV as u,REQUIRED_CHILD_TOOLS_ENV as d,STRUCTURED_OUTPUT_CAPTURE_ENV as f,STRUCTURED_OUTPUT_SCHEMA_ENV as p,SUBAGENT_CAPABILITY_CEILING_ENV as m,SUBAGENT_CHILD_AGENT_ENV as h,SUBAGENT_CHILD_ENV as g,SUBAGENT_CHILD_INDEX_ENV as _,SUBAGENT_FANOUT_CHILD_ENV as v,SUBAGENT_INTERCOM_SESSION_NAME_ENV as y,SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV as ee,SUBAGENT_PARENT_CHILD_INDEX_ENV as b,SUBAGENT_PARENT_CONTROL_INBOX_ENV as x,SUBAGENT_PARENT_DEPTH_ENV as S,SUBAGENT_PARENT_EVENT_SINK_ENV as te,SUBAGENT_PARENT_PATH_ENV as C,SUBAGENT_PARENT_ROOT_RUN_ID_ENV as w,SUBAGENT_PARENT_RUN_ID_ENV as ne,SUBAGENT_PARENT_SESSION_ENV as re,SUBAGENT_PROTECTED_PARENT_PIDS_ENV as ie,SUBAGENT_RUN_ID_ENV as ae,SUBAGENT_STEER_ACK_DIR_ENV as oe,SUBAGENT_STEER_CAPABILITY_ENV as se,SUBAGENT_STEER_INBOX_ENV as ce,TOOL_BUDGET_ENV as le,TOOL_BUDGET_ZERO_AUTH_ENV as ue,decodeProtectedParentProcessIds as de,init_env as T}from"../../../adapters/process/env.mjs";import{decodeSubagentCapabilityCeiling as fe,encodeSubagentCapabilityCeiling as pe,init_capabilityCeiling as E,intersectSubagentCapabilityCeilings as D}from"../../../schemas/team/capabilityCeiling.mjs";import{currentChildLaunchTempDir as O,init_paths as k}from"../../../shared/paths.mjs";import{THINKING_LEVELS as A,init_modelInfo as j}from"../../../shared/modelInfo.mjs";import{NATIVE_TEAM_TOOL_NAME as M,clearNativeTeamMemberEnvironment as me,init_nativeTeamChannel as N,nativeTeamMemberEnvironment as he}from"../../intercom/nativeTeamChannel.mjs";import{init_mcpDirectToolAllowlist as P,resolveMcpDirectToolSelections as ge}from"./mcpDirectToolAllowlist.mjs";import{encodeNestedPathEnv as _e,init_nestedPath as ve,parseNestedPathEnv as ye}from"./nestedPath.mjs";import{init_piSpawn as F,resolvePiPackageRoot as be}from"./piSpawn.mjs";import{encodeToolBudgetEnv as xe,init_toolBudget as I}from"./toolBudget.mjs";import*as L from"node:fs";import*as R from"node:path";import{DOOM_CHILD_PROCESS_CONTEXT_ENV as Se,encodeChildProcessContext as Ce}from"@agimon-ai/doompi-extension-contracts/child-process";import{fileURLToPath as we}from"node:url";function z(e,t=H){let n=we(import.meta.url),r=n.split(R.sep).includes(X),i=r?X:it,a=r?at:t,o=R.dirname(n);for(;;){let t=R.join(o,i,`${e}${a}`);if(L.existsSync(t))return t;let n=R.dirname(o);if(n===o)throw Error(`Could not resolve runtime extension ${e}`);o=n}}function Te(e=process.env){let t=e[n];if(!t)return[];let r;try{r=JSON.parse(t)}catch(e){let t=e instanceof Error?` ${e.message}`:``;throw Error(`${n} must be valid JSON.${t}`)}if(!Array.isArray(r)||!r.every(e=>typeof e==`string`))throw Error(`${n} must be a JSON array of extension paths.`);return r}function Ee(e=process.env){let t=e[r];return t?t.split(R.delimiter).filter(Boolean):[]}function De(e,t,n=!1){if(!e||!t)return e;let r=e.lastIndexOf(`:`);return r!==-1&&A.some(t=>t===e.substring(r+1))?n?`${e.slice(0,r)}:${t}`:e:`${e}:${t}`}function B(e){return e.includes(`/`)||e.endsWith(H)||e.endsWith(Pe)}function Oe(e){let t=D(e.capabilityCeiling,e.inheritedCapabilityCeiling),n=t?.allowedTools===void 0?void 0:new Set(t.allowedTools),r=t?.allowedTools?.filter(e=>!(t.allowMcpTools===!0&&e===W)),i=[...new Set((e.excludeTools??[]).map(e=>e.trim()).filter(e=>e.length>0))],a=new Set(i),o=t?.requiredTools??[],s=t?.allowMcpTools===!0,c=s&&[...e.tools??[],...o].includes(W),l=[...new Set([...e.tools??[],...o])].filter(e=>!B(e)&&!(c&&e===W)),u=[...e.mcpDirectTools??[],...c?[ze]:[]];if(e.requireReadTool&&a.has(U))throw Error(`Child tool exclusions exclude required tool '${U}' for lazy skill loading.`);if(e.structuredOutput&&a.has(G))throw Error(`Child tool exclusions exclude required tool '${G}'.`);if(e.requireReadTool&&n&&!n.has(U))throw Error(`Capability ceiling from ${t?.sources.join(`, `)||`unknown source`} excludes required tool '${U}' for lazy skill loading.`);let d=e.tools===void 0?r??[]:(e.requireReadTool&&l.length>0&&!l.includes(U)&&!n?[U,...l]:l).filter(e=>!n||n.has(e)).filter(e=>!a.has(e)),f=d.includes(Be),p=t?.denyExtensions?[]:(e.tools??[]).filter(e=>!l.includes(e)&&B(e)),m=t?.denyExtensions?[]:ge(u,e.cwd),h=m.filter(e=>(s||!n||n.has(e.name))&&!a.has(e.name)),g=h.map(e=>e.name),_=e.tools!==void 0||u.length>0||n!==void 0,v=[...e.structuredOutput?[G]:[],...e.teamToolEnabled?[M]:[]].filter(e=>!a.has(e)),y=[...new Set([...d,...g,...v])];if(e.requireReadTool&&_&&!y.includes(U))throw Error(`Effective child tool allowlist excludes required tool '${U}' for lazy skill loading.`);let ee=_?[...new Set([...e.tools===void 0?[]:d,...u.length?g:[],...v])]:[],b=f?[z(Z,Q),z(ot)]:[z(Z,Q)],x=t?.denyExtensions===!0||e.extensions!==void 0,S=t?.denyExtensions?[]:[...p,...e.extensions??[],...e.subagentOnlyExtensions??[]],te=x?[...new Set([...b,...S])]:[...new Set([...b,...p,...e.subagentOnlyExtensions??[]])],C=e.tools===void 0?void 0:[...new Set([...l,...m.map(e=>e.name)])],w=t?{ceiling:t,...C?{requestedTools:C}:{},effectiveTools:y,removedTools:C?.filter(e=>!y.includes(e))??[],internalTools:v,extensionsDenied:t.denyExtensions,removedExtensionCount:t.denyExtensions?(e.extensions?.length??0)+(e.subagentOnlyExtensions?.length??0)+(e.tools??[]).filter(B).length:0,requestedMcpToolCount:u.length,effectiveMcpTools:g}:void 0;return{...t?{capabilityCeiling:t}:{},excludedTools:i,requestedBuiltinTools:l,declaredBuiltinTools:d,toolExtensionPaths:p,resolvedMcpSelections:m,effectiveMcpSelections:h,effectiveMcpTools:g,explicitToolAllowlist:_,internalTools:v,effectiveToolAllowlist:y,requiredChildTools:ee,fanoutAuthorized:f,runtimeExtensions:b,configuredExtensions:S,extensionArgs:te,disableAmbientExtensions:x,...w?{capabilityAudit:w}:{}}}function ke(e){let t=e.environment??process.env,r=D(e.inheritedCapabilityCeiling,fe(t[m])),i=Oe({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:e.structuredOutput,teamToolEnabled:e.teamToolEnabled,capabilityCeiling:e.capabilityCeiling,inheritedCapabilityCeiling:r}),a=i.explicitToolAllowlist?i.effectiveToolAllowlist:void 0,o=Te(t);return{toolPlan:i,...a&&a.length>0?{tools:a}:{},...a?.length===0?{noTools:`all`}:{},...i.excludedTools.length>0?{excludeTools:i.excludedTools}:{},extensions:[...new Set([...o,...i.extensionArgs])],extensionsProvidedExternally:!!t[n]?.trim(),noAmbientExtensions:i.disableAmbientExtensions,skillPaths:e.inheritSkills?Ee(t):[],noSkills:!e.inheritSkills}}function Ae(){return L.mkdirSync(O(),{recursive:!0,mode:He}),L.mkdtempSync(R.join(O(),Ne))}function je(e){let n=[...e.baseArgs];e.sessionFile?(L.mkdirSync(R.dirname(e.sessionFile),{recursive:!0}),n.push(Ke,e.sessionFile)):(e.sessionEnabled||n.push(qe),e.sessionDir&&(L.mkdirSync(e.sessionDir,{recursive:!0}),n.push(Je,e.sessionDir)));let r=De(e.model,e.thinking);r&&n.push(Ye,r);let{toolPlan:T,...fe}=ke({tools:e.tools,extensions:e.extensions,subagentOnlyExtensions:e.subagentOnlyExtensions,mcpDirectTools:e.mcpDirectTools,cwd:e.cwd,requireReadTool:e.requireReadTool,excludeTools:e.excludeTools,structuredOutput:!!e.structuredOutput,teamToolEnabled:!!e.teamMember||e.teamToolEnabled===!0,capabilityCeiling:e.capabilityCeiling,inheritSkills:e.inheritSkills});T.explicitToolAllowlist&&(n.push(T.effectiveToolAllowlist.length>0?Xe:Ze),T.effectiveToolAllowlist.length>0&&n.push(T.effectiveToolAllowlist.join(`,`))),T.excludedTools.length>0&&n.push(Qe,T.excludedTools.join(`,`)),T.disableAmbientExtensions&&n.push(Y);for(let e of T.extensionArgs)n.push($e,e);e.inheritProjectContext||n.push(et),e.inheritSkills||n.push(tt);let E,D=()=>(E??=Ae(),E);if(e.systemPrompt!==void 0&&e.systemPrompt!==null){let t=(e.promptFileStem??Ie).replace(We,`_`),r=R.join(D(),`${t}${Fe}`);L.writeFileSync(r,e.systemPrompt,{mode:J}),n.push(e.systemPromptMode===`replace`?nt:rt,r)}if(e.task.length>Me){let t=R.join(D(),Le);L.writeFileSync(t,`${V}${e.task}`,{mode:J}),n.push(`@${t}`)}else n.push(`${V}${e.task}`);let O={...e.teamMember?he(e.teamMember):me()},k=process.env.PI_SUBAGENTS_PI_CODING_AGENT_PACKAGE_ROOT??be();k&&(O[c]=k);let A;T.requiredChildTools.length>0&&(A=R.join(D(),Re),O[d]=JSON.stringify(T.requiredChildTools),O[t]=A),O[o]=T.effectiveMcpTools.length>0?JSON.stringify(T.effectiveMcpTools):void 0,O[g]=K,O[v]=T.fanoutAuthorized?K:q;let j=!!(process.env.PI_SUBAGENT_PARENT_EVENT_SINK&&process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID&&process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN),M=e.parentRunId??e.runId??(j?process.env.PI_SUBAGENT_RUN_ID:void 0)??process.env.PI_SUBAGENT_PARENT_RUN_ID??``,N=e.parentChildIndex===void 0?e.childIndex===void 0?process.env.PI_SUBAGENT_PARENT_CHILD_INDEX??``:String(e.childIndex):String(e.parentChildIndex),P=Number(process.env[S]),ge=e.parentDepth??(j&&Number.isFinite(P)?P+1:Ue),ve=e.parentPath??[...ye(process.env.PI_SUBAGENT_PARENT_PATH),...M?[{runId:M,...N&&Ge.test(N)?{stepIndex:Number(N)}:{},...e.childAgentName?{agent:e.childAgentName}:{}}]:[]];O[te]=T.fanoutAuthorized?e.parentEventSink??process.env.PI_SUBAGENT_PARENT_EVENT_SINK??``:``,O[x]=T.fanoutAuthorized?e.parentControlInbox??process.env.PI_SUBAGENT_PARENT_CONTROL_INBOX??``:``,O[w]=T.fanoutAuthorized?e.parentRootRunId??process.env.PI_SUBAGENT_PARENT_ROOT_RUN_ID??e.runId??``:``,O[ne]=T.fanoutAuthorized?M:``,O[b]=T.fanoutAuthorized?N:``,O[S]=T.fanoutAuthorized?String(ge):``,O[C]=T.fanoutAuthorized?_e(ve):``,O[ee]=T.fanoutAuthorized?e.parentCapabilityToken??process.env.PI_SUBAGENT_PARENT_CAPABILITY_TOKEN??``:``,O[i]=e.inheritProjectContext?K:q,O[a]=e.inheritSkills?K:q,O[u]=e.intercomSessionName||void 0,O[l]=void 0,e.intercomSessionName&&(O[y]=e.intercomSessionName),e.runId&&(O[ae]=e.runId),e.childAgentName&&(O[h]=e.childAgentName),e.childIndex!==void 0&&(O[_]=String(e.childIndex)),!T.capabilityCeiling&&e.mcpDirectTools?.length?O[s]=e.mcpDirectTools.join(`,`):T.capabilityCeiling&&T.effectiveMcpSelections.length&&!T.capabilityCeiling.denyExtensions?O[s]=T.effectiveMcpSelections.map(e=>e.selector).join(`,`):O[s]=Ve;let F=pe(T.capabilityCeiling);F&&(O[m]=F),e.structuredOutput&&(O[f]=e.structuredOutput.outputPath,O[p]=e.structuredOutput.schemaPath),e.steerInboxDir&&(O[ce]=e.steerInboxDir),e.steerCapabilityPath&&(O[se]=e.steerCapabilityPath),e.steerAckDir&&(O[oe]=e.steerAckDir);let I=xe(e.toolBudget);return I&&(O[le]=I),O[ue]=e.allowZeroToolBudget?K:void 0,O[ie]=JSON.stringify([...new Set([...de(process.env[ie]),process.pid,process.ppid])].filter(e=>Number.isSafeInteger(e)&&e>1)),O[re]=e.parentSessionId??process.env[re]??``,O[Se]=e.parentSessionId?Ce({parentSessionId:e.parentSessionId,workingDirectory:e.cwd??process.cwd(),...e.childAgentName?{mode:e.childAgentName}:{}}):void 0,{args:n,env:O,sdk:{...e.model||e.thinking?{model:De(e.model,e.thinking)}:{},...fe,noContextFiles:!e.inheritProjectContext,sessionEnabled:e.sessionEnabled,...e.sessionDir?{sessionDir:e.sessionDir}:{},...e.sessionFile?{sessionFile:e.sessionFile}:{},...e.systemPrompt!==void 0&&e.systemPrompt!==null?{systemPrompt:e.systemPrompt}:{},...e.systemPromptMode?{systemPromptMode:e.systemPromptMode}:{}},tempDir:E,toolDiagnosticPath:A,capabilityAudit:T.capabilityAudit}}var Me,Ne,V,H,Pe,Fe,Ie,Le,Re,U,W,ze,Be,G,Ve,K,q,J,He,Ue,We,Ge,Ke,qe,Je,Ye,Xe,Ze,Qe,Y,$e,et,tt,nt,rt,X,it,at,Z,Q,ot,$=e((()=>{T(),E(),j(),k(),N(),P(),ve(),F(),I(),Me=8e3,Ne=`doom-team-launch-`,V=`Task: `,H=`.ts`,Pe=`.js`,Fe=`.md`,Ie=`prompt`,Le=`task.md`,Re=`tool-diagnostic.json`,U=`read`,W=`mcp`,ze=`*`,Be=`subagent`,G=`structured_output`,Ve=`__none__`,K=`1`,q=`0`,J=384,He=448,Ue=1,We=/[^\w.-]/g,Ge=/^\d+$/,Ke=`--session`,qe=`--no-session`,Je=`--session-dir`,Ye=`--model`,Xe=`--tools`,Ze=`--no-tools`,Qe=`--exclude-tools`,Y=`--no-extensions`,$e=`--extension`,et=`--no-context-files`,tt=`--no-skills`,nt=`--system-prompt`,rt=`--append-system-prompt`,X=`dist`,it=`src`,at=`.mjs`,Z=`extensions/subagentPromptRuntimeEntry`,Q=`.cts`,ot=`extension/fanout-child`}));$();export{je as buildPiArgs,$ as init_piArgs,ke as resolvePiSdkResourcePlan};
|
|
2
|
+
//# sourceMappingURL=piArgs.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piArgs.mjs","names":[],"sources":["../../../../src/services/runs/shared/piArgs.ts"],"sourcesContent":["/**\n * The argv and environment handed to a spawned child agent.\n *\n * DESIGN PATTERNS:\n * - `resolvePiLaunchToolPlan` is the single place tool access is decided, and it\n * is pure. Everything about what a child may call is computable and testable\n * without touching the filesystem or spawning anything\n * - Capability ceilings only ever narrow. A ceiling from this process is\n * intersected with the one inherited from our own parent, and every requested\n * tool is then filtered against the result. Nothing in this file can add a tool\n * the ceiling excludes\n * - Fan-out authority is derived, not requested. A child receives the parent\n * event sink, control inbox, capability token and nesting path ONLY if it was\n * granted the `subagent` tool. Otherwise those variables are set to the empty\n * string rather than omitted, so an inherited value from our own environment\n * cannot leak through into a child that is not allowed to fan out\n * - Long task text goes to a private file passed as `@path` instead of argv,\n * because argv is both length-limited and visible in the process table\n *\n * AVOID:\n * - Widening anything here. If a case is ambiguous, narrow it\n * - Omitting a fan-out variable instead of blanking it; omission inherits\n * - Re-declaring env var names; they live in `src/env.ts` and cross processes\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n DOOM_CHILD_PROCESS_CONTEXT_ENV,\n encodeChildProcessContext,\n} from '@agimon-ai/doompi-extension-contracts/child-process';\nimport {\n CHILD_TOOL_DIAGNOSTIC_PATH_ENV,\n decodeProtectedParentProcessIds,\n DOOMPI_CHILD_EXTENSIONS_ENV,\n DOOMPI_SKILL_DIRS_ENV,\n INHERIT_PROJECT_CONTEXT_ENV,\n INHERIT_SKILLS_ENV,\n MCP_DIRECT_CHILD_TOOLS_ENV,\n MCP_DIRECT_TOOLS_ENV,\n PI_CODING_AGENT_PACKAGE_ROOT_ENV,\n PI_INTERCOM_SESSION_ID_ENV,\n PI_INTERCOM_STABLE_ID_ENV,\n REQUIRED_CHILD_TOOLS_ENV,\n STRUCTURED_OUTPUT_CAPTURE_ENV,\n STRUCTURED_OUTPUT_SCHEMA_ENV,\n SUBAGENT_CAPABILITY_CEILING_ENV,\n SUBAGENT_CHILD_AGENT_ENV,\n SUBAGENT_CHILD_ENV,\n SUBAGENT_CHILD_INDEX_ENV,\n SUBAGENT_FANOUT_CHILD_ENV,\n SUBAGENT_INTERCOM_SESSION_NAME_ENV,\n SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV,\n SUBAGENT_PARENT_CHILD_INDEX_ENV,\n SUBAGENT_PARENT_CONTROL_INBOX_ENV,\n SUBAGENT_PARENT_DEPTH_ENV,\n SUBAGENT_PARENT_EVENT_SINK_ENV,\n SUBAGENT_PARENT_PATH_ENV,\n SUBAGENT_PARENT_ROOT_RUN_ID_ENV,\n SUBAGENT_PARENT_RUN_ID_ENV,\n SUBAGENT_PARENT_SESSION_ENV,\n SUBAGENT_PROTECTED_PARENT_PIDS_ENV,\n SUBAGENT_RUN_ID_ENV,\n SUBAGENT_STEER_ACK_DIR_ENV,\n SUBAGENT_STEER_CAPABILITY_ENV,\n SUBAGENT_STEER_INBOX_ENV,\n TOOL_BUDGET_ENV,\n TOOL_BUDGET_ZERO_AUTH_ENV,\n} from '../../../adapters/process/env.ts';\nimport {\n decodeSubagentCapabilityCeiling,\n encodeSubagentCapabilityCeiling,\n intersectSubagentCapabilityCeilings,\n type ResolvedSubagentCapabilityCeiling,\n type SubagentCapabilityAudit,\n} from '../../../schemas/team/capabilityCeiling.ts';\nimport { THINKING_LEVELS } from '../../../shared/modelInfo.ts';\nimport { currentChildLaunchTempDir } from '../../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../../types/index.ts';\nimport {\n clearNativeTeamMemberEnvironment,\n NATIVE_TEAM_TOOL_NAME,\n nativeTeamMemberEnvironment,\n type TeamMemberContext,\n} from '../../intercom/nativeTeamChannel.ts';\nimport { type ResolvedMcpDirectToolSelection, resolveMcpDirectToolSelections } from './mcpDirectToolAllowlist.ts';\nimport { encodeNestedPathEnv, type NestedPathEntry, parseNestedPathEnv } from './nestedPath.ts';\nimport { resolvePiPackageRoot } from './piSpawn.ts';\nimport { encodeToolBudgetEnv, type ResolvedToolBudget } from './toolBudget.ts';\n\n/**\n * Task text longer than this is written to a file and passed as `@path`.\n *\n * Well under the platform argv limit, because the task shares argv with the\n * model, tool and extension flags.\n */\nconst TASK_ARG_LIMIT = 8000;\nconst TEMP_DIRECTORY_PREFIX = 'doom-team-launch-';\nconst TASK_PREFIX = 'Task: ';\nconst TYPESCRIPT_EXTENSION = '.ts';\nconst JAVASCRIPT_EXTENSION = '.js';\nconst PROMPT_FILE_EXTENSION = '.md';\nconst DEFAULT_PROMPT_FILE_STEM = 'prompt';\nconst TASK_FILE_NAME = 'task.md';\nconst TOOL_DIAGNOSTIC_FILE_NAME = 'tool-diagnostic.json';\nconst READ_TOOL_NAME = 'read';\nconst MCP_TOOL_NAME = 'mcp';\nconst ALL_MCP_SERVERS_SELECTOR = '*';\nconst SUBAGENT_TOOL_NAME = 'subagent';\nconst STRUCTURED_OUTPUT_TOOL_NAME = 'structured_output';\nconst NO_MCP_DIRECT_TOOLS = '__none__';\nconst ENABLED_ENV_VALUE = '1';\nconst DISABLED_ENV_VALUE = '0';\nconst PRIVATE_FILE_MODE = 0o600;\nconst PRIVATE_DIR_MODE = 0o700;\nconst ROOT_FANOUT_DEPTH = 1;\nconst UNSAFE_PROMPT_STEM_CHARACTERS = /[^\\w.-]/g;\nconst DIGITS_ONLY = /^\\d+$/;\n\nconst SESSION_FLAG = '--session';\nconst NO_SESSION_FLAG = '--no-session';\nconst SESSION_DIRECTORY_FLAG = '--session-dir';\nconst MODEL_FLAG = '--model';\nconst TOOLS_FLAG = '--tools';\nconst NO_TOOLS_FLAG = '--no-tools';\nconst EXCLUDE_TOOLS_FLAG = '--exclude-tools';\nconst NO_EXTENSIONS_FLAG = '--no-extensions';\nconst EXTENSION_FLAG = '--extension';\nconst NO_CONTEXT_FILES_FLAG = '--no-context-files';\nconst NO_SKILLS_FLAG = '--no-skills';\nconst SYSTEM_PROMPT_FLAG = '--system-prompt';\nconst APPEND_SYSTEM_PROMPT_FLAG = '--append-system-prompt';\n\nconst BUILT_OUTPUT_DIR = 'dist';\nconst SOURCE_DIR = 'src';\nconst BUILT_EXTENSION = '.mjs';\nconst PROMPT_RUNTIME_EXTENSION = 'extensions/subagentPromptRuntimeEntry';\nconst PROMPT_RUNTIME_SOURCE_EXTENSION = '.cts';\nconst FANOUT_CHILD_EXTENSION = 'extension/fanout-child';\n\n/**\n * Locate an extension the child must load, in either a built or a source tree.\n *\n * The child is a separate process loading these by path, so the path has to be\n * the one that exists on disk now: `.mjs` under `dist` when this bundle is\n * built, the original source file when it is not.\n *\n * Resolved on demand rather than at module load. Doing it eagerly would make\n * importing this module throw in any tree where the extensions are not built\n * yet, which turns a launch-time problem into an import-time one.\n */\nfunction resolveRuntimeExtensionPath(relativePath: string, sourceExtension = TYPESCRIPT_EXTENSION): string {\n const modulePath = fileURLToPath(import.meta.url);\n const builtMode = modulePath.split(path.sep).includes(BUILT_OUTPUT_DIR);\n const runtimeRoot = builtMode ? BUILT_OUTPUT_DIR : SOURCE_DIR;\n const extension = builtMode ? BUILT_EXTENSION : sourceExtension;\n let directory = path.dirname(modulePath);\n while (true) {\n const candidate = path.join(directory, runtimeRoot, `${relativePath}${extension}`);\n if (fs.existsSync(candidate)) return candidate;\n const parent = path.dirname(directory);\n if (parent === directory) throw new Error(`Could not resolve runtime extension ${relativePath}`);\n directory = parent;\n }\n}\n\nexport interface BuildPiArgsInput {\n parentSessionId?: string;\n baseArgs: string[];\n task: string;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n model?: string;\n thinking?: string | false;\n systemPromptMode?: 'append' | 'replace';\n inheritProjectContext: boolean;\n inheritSkills: boolean;\n requireReadTool?: boolean;\n tools?: string[];\n excludeTools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n systemPrompt?: string | null;\n mcpDirectTools?: string[];\n cwd?: string;\n promptFileStem?: string;\n intercomSessionName?: string;\n runId?: string;\n childAgentName?: string;\n childIndex?: number;\n parentEventSink?: string;\n parentControlInbox?: string;\n parentRootRunId?: string;\n parentRunId?: string;\n parentChildIndex?: number;\n parentDepth?: number;\n parentPath?: NestedPathEntry[];\n parentCapabilityToken?: string;\n steerInboxDir?: string;\n steerCapabilityPath?: string;\n steerAckDir?: string;\n structuredOutput?: {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n };\n toolBudget?: ResolvedToolBudget;\n allowZeroToolBudget?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n teamMember?: TeamMemberContext;\n teamToolEnabled?: boolean;\n}\n\nexport interface BuildPiArgsResult {\n args: string[];\n env: Record<string, string | undefined>;\n sdk: PiSdkLaunchSettings;\n tempDir?: string;\n toolDiagnosticPath?: string;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface PiSdkLaunchSettings {\n model?: string;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n extensionsProvidedExternally?: boolean;\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n noContextFiles: boolean;\n sessionEnabled: boolean;\n sessionDir?: string;\n sessionFile?: string;\n systemPrompt?: string;\n systemPromptMode?: 'append' | 'replace';\n}\n\nfunction inheritedDoomPiExtensions(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_CHILD_EXTENSIONS_ENV];\n if (!raw) return [];\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (error) {\n const detail = error instanceof Error ? ` ${error.message}` : '';\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be valid JSON.${detail}`);\n }\n if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === 'string')) {\n throw new Error(`${DOOMPI_CHILD_EXTENSIONS_ENV} must be a JSON array of extension paths.`);\n }\n return parsed;\n}\n\nfunction inheritedDoomPiSkillPaths(environment: NodeJS.ProcessEnv = process.env): string[] {\n const raw = environment[DOOMPI_SKILL_DIRS_ENV];\n return raw ? raw.split(path.delimiter).filter(Boolean) : [];\n}\n\n/**\n * Append a thinking level to a model id.\n *\n * A model id that already carries a known level is left alone unless the caller\n * asks to replace it, so an explicit per-agent choice survives an inherited one.\n */\nexport function applyThinkingSuffix(\n model: string | undefined,\n thinking: string | false | undefined,\n replaceExisting = false,\n): string | undefined {\n if (!model || !thinking) return model;\n const colonIdx = model.lastIndexOf(':');\n if (colonIdx !== -1 && THINKING_LEVELS.some((level) => level === model.substring(colonIdx + 1))) {\n return replaceExisting ? `${model.slice(0, colonIdx)}:${thinking}` : model;\n }\n return `${model}:${thinking}`;\n}\n\nexport interface ResolvePiLaunchToolPlanInput {\n tools?: string[];\n extensions?: string[];\n subagentOnlyExtensions?: string[];\n mcpDirectTools?: string[];\n cwd?: string;\n requireReadTool?: boolean;\n excludeTools?: string[];\n structuredOutput?: boolean;\n teamToolEnabled?: boolean;\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n inheritedCapabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n}\n\nexport interface PiLaunchToolPlan {\n capabilityCeiling?: ResolvedSubagentCapabilityCeiling;\n excludedTools: string[];\n requestedBuiltinTools: string[];\n declaredBuiltinTools: string[];\n toolExtensionPaths: string[];\n resolvedMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpSelections: ResolvedMcpDirectToolSelection[];\n effectiveMcpTools: string[];\n explicitToolAllowlist: boolean;\n internalTools: string[];\n effectiveToolAllowlist: string[];\n requiredChildTools: string[];\n fanoutAuthorized: boolean;\n runtimeExtensions: string[];\n configuredExtensions: string[];\n extensionArgs: string[];\n disableAmbientExtensions: boolean;\n capabilityAudit?: SubagentCapabilityAudit;\n}\n\nexport interface ResolvePiSdkResourcePlanInput extends ResolvePiLaunchToolPlanInput {\n inheritSkills: boolean;\n environment?: NodeJS.ProcessEnv;\n}\n\n/** The resource-only subset of Pi SDK settings, safe to calculate without writing launch files. */\nexport interface PiSdkResourcePlan {\n toolPlan: PiLaunchToolPlan;\n tools?: string[];\n noTools?: 'all';\n excludeTools?: string[];\n extensions: string[];\n extensionsProvidedExternally: boolean;\n noAmbientExtensions: boolean;\n skillPaths: string[];\n noSkills: boolean;\n}\n\n/** A tool entry is an extension path, not a builtin name, when it looks like a path. */\nfunction isToolExtensionPath(tool: string): boolean {\n return tool.includes('/') || tool.endsWith(TYPESCRIPT_EXTENSION) || tool.endsWith(JAVASCRIPT_EXTENSION);\n}\n\n/**\n * Decide exactly what the child may call.\n *\n * This is the security boundary. The order matters: the ceiling is computed\n * first, and every later step filters against it. `requireReadTool` can add\n * `read` to a nonempty caller request only when no ceiling is in force. A\n * ceiling or explicit effective allowlist that omits `read` is refused rather\n * than widened.\n */\nexport function resolvePiLaunchToolPlan(input: ResolvePiLaunchToolPlanInput): PiLaunchToolPlan {\n const capabilityCeiling = intersectSubagentCapabilityCeilings(\n input.capabilityCeiling,\n input.inheritedCapabilityCeiling,\n );\n const allowedToolSet =\n capabilityCeiling?.allowedTools === undefined ? undefined : new Set(capabilityCeiling.allowedTools);\n const allowedBuiltinTools = capabilityCeiling?.allowedTools?.filter(\n (tool) => !(capabilityCeiling.allowMcpTools === true && tool === MCP_TOOL_NAME),\n );\n const excludedTools = [\n ...new Set((input.excludeTools ?? []).map((tool) => tool.trim()).filter((tool) => tool.length > 0)),\n ];\n const excludedToolSet = new Set(excludedTools);\n const policyRequiredTools = capabilityCeiling?.requiredTools ?? [];\n const mcpToolsAllowed = capabilityCeiling?.allowMcpTools === true;\n const mcpRequested = mcpToolsAllowed && [...(input.tools ?? []), ...policyRequiredTools].includes(MCP_TOOL_NAME);\n const requestedBuiltinTools = [...new Set([...(input.tools ?? []), ...policyRequiredTools])].filter(\n (tool) => !isToolExtensionPath(tool) && !(mcpRequested && tool === MCP_TOOL_NAME),\n );\n const requestedMcpSelectors = [...(input.mcpDirectTools ?? []), ...(mcpRequested ? [ALL_MCP_SERVERS_SELECTOR] : [])];\n if (input.requireReadTool && excludedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${READ_TOOL_NAME}' for lazy skill loading.`);\n }\n if (input.structuredOutput && excludedToolSet.has(STRUCTURED_OUTPUT_TOOL_NAME)) {\n throw new Error(`Child tool exclusions exclude required tool '${STRUCTURED_OUTPUT_TOOL_NAME}'.`);\n }\n if (input.requireReadTool && allowedToolSet && !allowedToolSet.has(READ_TOOL_NAME)) {\n throw new Error(\n `Capability ceiling from ${capabilityCeiling?.sources.join(', ') || 'unknown source'} excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n // No `tools` at all means \"whatever the host allows\", which under a ceiling\n // becomes exactly the ceiling and without one stays unconstrained.\n const declaredBuiltinTools =\n input.tools === undefined\n ? (allowedBuiltinTools ?? [])\n : (input.requireReadTool &&\n requestedBuiltinTools.length > 0 &&\n !requestedBuiltinTools.includes(READ_TOOL_NAME) &&\n !allowedToolSet\n ? [READ_TOOL_NAME, ...requestedBuiltinTools]\n : requestedBuiltinTools\n )\n .filter((tool) => !allowedToolSet || allowedToolSet.has(tool))\n .filter((tool) => !excludedToolSet.has(tool));\n // Fan-out authority is exactly \"was granted the subagent tool\", read after\n // ceiling filtering so a denied tool cannot confer it.\n const fanoutAuthorized = declaredBuiltinTools.includes(SUBAGENT_TOOL_NAME);\n const toolExtensionPaths: string[] = capabilityCeiling?.denyExtensions\n ? []\n : (input.tools ?? []).filter((tool) => !requestedBuiltinTools.includes(tool) && isToolExtensionPath(tool));\n const resolvedMcpSelections = capabilityCeiling?.denyExtensions\n ? []\n : resolveMcpDirectToolSelections(requestedMcpSelectors, input.cwd);\n const effectiveMcpSelections = resolvedMcpSelections.filter(\n (selection) =>\n (mcpToolsAllowed || !allowedToolSet || allowedToolSet.has(selection.name)) &&\n !excludedToolSet.has(selection.name),\n );\n const effectiveMcpTools = effectiveMcpSelections.map((selection) => selection.name);\n const explicitToolAllowlist =\n input.tools !== undefined || requestedMcpSelectors.length > 0 || allowedToolSet !== undefined;\n // Internal tools are ours, not the caller's, so they bypass the allowlist but\n // are still reported in the audit.\n const internalTools = [\n ...(input.structuredOutput ? [STRUCTURED_OUTPUT_TOOL_NAME] : []),\n ...(input.teamToolEnabled ? [NATIVE_TEAM_TOOL_NAME] : []),\n ].filter((tool) => !excludedToolSet.has(tool));\n const effectiveToolAllowlist = [...new Set([...declaredBuiltinTools, ...effectiveMcpTools, ...internalTools])];\n if (input.requireReadTool && explicitToolAllowlist && !effectiveToolAllowlist.includes(READ_TOOL_NAME)) {\n throw new Error(\n `Effective child tool allowlist excludes required tool '${READ_TOOL_NAME}' for lazy skill loading.`,\n );\n }\n const requiredChildTools = explicitToolAllowlist\n ? [\n ...new Set([\n ...(input.tools !== undefined ? declaredBuiltinTools : []),\n ...(requestedMcpSelectors.length ? effectiveMcpTools : []),\n ...internalTools,\n ]),\n ]\n : [];\n const runtimeExtensions = fanoutAuthorized\n ? [\n resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION),\n resolveRuntimeExtensionPath(FANOUT_CHILD_EXTENSION),\n ]\n : [resolveRuntimeExtensionPath(PROMPT_RUNTIME_EXTENSION, PROMPT_RUNTIME_SOURCE_EXTENSION)];\n const disableAmbientExtensions = capabilityCeiling?.denyExtensions === true || input.extensions !== undefined;\n const configuredExtensions = capabilityCeiling?.denyExtensions\n ? []\n : [...toolExtensionPaths, ...(input.extensions ?? []), ...(input.subagentOnlyExtensions ?? [])];\n const extensionArgs = disableAmbientExtensions\n ? [...new Set([...runtimeExtensions, ...configuredExtensions])]\n : [...new Set([...runtimeExtensions, ...toolExtensionPaths, ...(input.subagentOnlyExtensions ?? [])])];\n const requestedToolNames =\n input.tools !== undefined\n ? [...new Set([...requestedBuiltinTools, ...resolvedMcpSelections.map((selection) => selection.name)])]\n : undefined;\n const capabilityAudit = capabilityCeiling\n ? ({\n ceiling: capabilityCeiling,\n ...(requestedToolNames ? { requestedTools: requestedToolNames } : {}),\n effectiveTools: effectiveToolAllowlist,\n removedTools: requestedToolNames?.filter((tool) => !effectiveToolAllowlist.includes(tool)) ?? [],\n internalTools,\n extensionsDenied: capabilityCeiling.denyExtensions,\n removedExtensionCount: capabilityCeiling.denyExtensions\n ? (input.extensions?.length ?? 0) +\n (input.subagentOnlyExtensions?.length ?? 0) +\n (input.tools ?? []).filter(isToolExtensionPath).length\n : 0,\n requestedMcpToolCount: requestedMcpSelectors.length,\n effectiveMcpTools,\n } satisfies SubagentCapabilityAudit)\n : undefined;\n return {\n ...(capabilityCeiling ? { capabilityCeiling } : {}),\n excludedTools,\n requestedBuiltinTools,\n declaredBuiltinTools,\n toolExtensionPaths,\n resolvedMcpSelections,\n effectiveMcpSelections,\n effectiveMcpTools,\n explicitToolAllowlist,\n internalTools,\n effectiveToolAllowlist,\n requiredChildTools,\n fanoutAuthorized,\n runtimeExtensions,\n configuredExtensions,\n extensionArgs,\n disableAmbientExtensions,\n ...(capabilityAudit ? { capabilityAudit } : {}),\n };\n}\n\n/**\n * Resolve the child SDK's resource settings without creating launch files or\n * starting a child process. Filesystem-backed MCP and runtime-extension lookup\n * still follows the same path as a real launch.\n */\nexport function resolvePiSdkResourcePlan(input: ResolvePiSdkResourcePlanInput): PiSdkResourcePlan {\n const environment = input.environment ?? process.env;\n const inheritedCapabilityCeiling = intersectSubagentCapabilityCeilings(\n input.inheritedCapabilityCeiling,\n decodeSubagentCapabilityCeiling(environment[SUBAGENT_CAPABILITY_CEILING_ENV]),\n );\n const toolPlan = resolvePiLaunchToolPlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: input.structuredOutput,\n teamToolEnabled: input.teamToolEnabled,\n capabilityCeiling: input.capabilityCeiling,\n inheritedCapabilityCeiling,\n });\n const explicitTools = toolPlan.explicitToolAllowlist ? toolPlan.effectiveToolAllowlist : undefined;\n const inheritedExtensions = inheritedDoomPiExtensions(environment);\n return {\n toolPlan,\n ...(explicitTools && explicitTools.length > 0 ? { tools: explicitTools } : {}),\n ...(explicitTools?.length === 0 ? { noTools: 'all' as const } : {}),\n ...(toolPlan.excludedTools.length > 0 ? { excludeTools: toolPlan.excludedTools } : {}),\n extensions: [...new Set([...inheritedExtensions, ...toolPlan.extensionArgs])],\n extensionsProvidedExternally: Boolean(environment[DOOMPI_CHILD_EXTENSIONS_ENV]?.trim()),\n noAmbientExtensions: toolPlan.disableAmbientExtensions,\n skillPaths: input.inheritSkills ? inheritedDoomPiSkillPaths(environment) : [],\n noSkills: !input.inheritSkills,\n };\n}\n\n/**\n * Scratch directory for this launch's prompt, task and diagnostics.\n *\n * Created 0700 under the per-user temp root, because the files inside carry the\n * full task and system prompt.\n */\nfunction createLaunchTempDir(): string {\n fs.mkdirSync(currentChildLaunchTempDir(), { recursive: true, mode: PRIVATE_DIR_MODE });\n return fs.mkdtempSync(path.join(currentChildLaunchTempDir(), TEMP_DIRECTORY_PREFIX));\n}\n\nexport function buildPiArgs(input: BuildPiArgsInput): BuildPiArgsResult {\n const args = [...input.baseArgs];\n\n if (input.sessionFile) {\n fs.mkdirSync(path.dirname(input.sessionFile), { recursive: true });\n args.push(SESSION_FLAG, input.sessionFile);\n } else {\n if (!input.sessionEnabled) {\n args.push(NO_SESSION_FLAG);\n }\n if (input.sessionDir) {\n fs.mkdirSync(input.sessionDir, { recursive: true });\n args.push(SESSION_DIRECTORY_FLAG, input.sessionDir);\n }\n }\n\n const modelArg = applyThinkingSuffix(input.model, input.thinking);\n if (modelArg) {\n args.push(MODEL_FLAG, modelArg);\n }\n\n const resourcePlan = resolvePiSdkResourcePlan({\n tools: input.tools,\n extensions: input.extensions,\n subagentOnlyExtensions: input.subagentOnlyExtensions,\n mcpDirectTools: input.mcpDirectTools,\n cwd: input.cwd,\n requireReadTool: input.requireReadTool,\n excludeTools: input.excludeTools,\n structuredOutput: Boolean(input.structuredOutput),\n teamToolEnabled: Boolean(input.teamMember) || input.teamToolEnabled === true,\n capabilityCeiling: input.capabilityCeiling,\n inheritSkills: input.inheritSkills,\n });\n const { toolPlan, ...sdkResources } = resourcePlan;\n if (toolPlan.explicitToolAllowlist) {\n // An empty allowlist means no tools at all, which is a different flag rather\n // than an empty `--tools` value.\n args.push(toolPlan.effectiveToolAllowlist.length > 0 ? TOOLS_FLAG : NO_TOOLS_FLAG);\n if (toolPlan.effectiveToolAllowlist.length > 0) args.push(toolPlan.effectiveToolAllowlist.join(','));\n }\n if (toolPlan.excludedTools.length > 0) {\n args.push(EXCLUDE_TOOLS_FLAG, toolPlan.excludedTools.join(','));\n }\n if (toolPlan.disableAmbientExtensions) {\n args.push(NO_EXTENSIONS_FLAG);\n }\n for (const extPath of toolPlan.extensionArgs) args.push(EXTENSION_FLAG, extPath);\n\n if (!input.inheritProjectContext) {\n args.push(NO_CONTEXT_FILES_FLAG);\n }\n if (!input.inheritSkills) {\n args.push(NO_SKILLS_FLAG);\n }\n\n let tempDir: string | undefined;\n const ensureTempDir = (): string => {\n tempDir ??= createLaunchTempDir();\n return tempDir;\n };\n\n if (input.systemPrompt !== undefined && input.systemPrompt !== null) {\n const stem = (input.promptFileStem ?? DEFAULT_PROMPT_FILE_STEM).replace(UNSAFE_PROMPT_STEM_CHARACTERS, '_');\n const promptPath = path.join(ensureTempDir(), `${stem}${PROMPT_FILE_EXTENSION}`);\n fs.writeFileSync(promptPath, input.systemPrompt, { mode: PRIVATE_FILE_MODE });\n args.push(input.systemPromptMode === 'replace' ? SYSTEM_PROMPT_FLAG : APPEND_SYSTEM_PROMPT_FLAG, promptPath);\n }\n\n if (input.task.length > TASK_ARG_LIMIT) {\n const taskFilePath = path.join(ensureTempDir(), TASK_FILE_NAME);\n fs.writeFileSync(taskFilePath, `${TASK_PREFIX}${input.task}`, { mode: PRIVATE_FILE_MODE });\n args.push(`@${taskFilePath}`);\n } else {\n args.push(`${TASK_PREFIX}${input.task}`);\n }\n\n // Team membership vars are always written: the clearing form blanks whatever\n // this process inherited so a non-team child cannot join its parent's team.\n const env: Record<string, string | undefined> = {\n ...(input.teamMember ? nativeTeamMemberEnvironment(input.teamMember) : clearNativeTeamMemberEnvironment()),\n };\n const piPackageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] ?? resolvePiPackageRoot();\n if (piPackageRoot) env[PI_CODING_AGENT_PACKAGE_ROOT_ENV] = piPackageRoot;\n let toolDiagnosticPath: string | undefined;\n if (toolPlan.requiredChildTools.length > 0) {\n toolDiagnosticPath = path.join(ensureTempDir(), TOOL_DIAGNOSTIC_FILE_NAME);\n env[REQUIRED_CHILD_TOOLS_ENV] = JSON.stringify(toolPlan.requiredChildTools);\n env[CHILD_TOOL_DIAGNOSTIC_PATH_ENV] = toolDiagnosticPath;\n }\n env[MCP_DIRECT_CHILD_TOOLS_ENV] =\n toolPlan.effectiveMcpTools.length > 0 ? JSON.stringify(toolPlan.effectiveMcpTools) : undefined;\n env[SUBAGENT_CHILD_ENV] = ENABLED_ENV_VALUE;\n env[SUBAGENT_FANOUT_CHILD_ENV] = toolPlan.fanoutAuthorized ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n // We are ourselves a nested child only if our parent granted us the full\n // fan-out route; a partial set of inherited vars is not trusted.\n const inheritedNestedRoute = Boolean(\n process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] &&\n process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] &&\n process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV],\n );\n const parentRunId =\n input.parentRunId ??\n input.runId ??\n (inheritedNestedRoute ? process.env[SUBAGENT_RUN_ID_ENV] : undefined) ??\n process.env[SUBAGENT_PARENT_RUN_ID_ENV] ??\n '';\n const parentChildIndex =\n input.parentChildIndex !== undefined\n ? String(input.parentChildIndex)\n : input.childIndex !== undefined\n ? String(input.childIndex)\n : (process.env[SUBAGENT_PARENT_CHILD_INDEX_ENV] ?? '');\n const inheritedDepth = Number(process.env[SUBAGENT_PARENT_DEPTH_ENV]);\n const parentDepth =\n input.parentDepth ??\n (inheritedNestedRoute && Number.isFinite(inheritedDepth) ? inheritedDepth + 1 : ROOT_FANOUT_DEPTH);\n const parentPath = input.parentPath ?? [\n ...parseNestedPathEnv(process.env[SUBAGENT_PARENT_PATH_ENV]),\n ...(parentRunId\n ? [\n {\n runId: parentRunId,\n ...(parentChildIndex && DIGITS_ONLY.test(parentChildIndex) ? { stepIndex: Number(parentChildIndex) } : {}),\n ...(input.childAgentName ? { agent: input.childAgentName } : {}),\n },\n ]\n : []),\n ];\n // Blanked rather than omitted when fan-out is not authorized: an omitted key\n // would let the child inherit this process's own value.\n env[SUBAGENT_PARENT_EVENT_SINK_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentEventSink ?? process.env[SUBAGENT_PARENT_EVENT_SINK_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentControlInbox ?? process.env[SUBAGENT_PARENT_CONTROL_INBOX_ENV] ?? '')\n : '';\n env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentRootRunId ?? process.env[SUBAGENT_PARENT_ROOT_RUN_ID_ENV] ?? input.runId ?? '')\n : '';\n env[SUBAGENT_PARENT_RUN_ID_ENV] = toolPlan.fanoutAuthorized ? parentRunId : '';\n env[SUBAGENT_PARENT_CHILD_INDEX_ENV] = toolPlan.fanoutAuthorized ? parentChildIndex : '';\n env[SUBAGENT_PARENT_DEPTH_ENV] = toolPlan.fanoutAuthorized ? String(parentDepth) : '';\n env[SUBAGENT_PARENT_PATH_ENV] = toolPlan.fanoutAuthorized ? encodeNestedPathEnv(parentPath) : '';\n env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] = toolPlan.fanoutAuthorized\n ? (input.parentCapabilityToken ?? process.env[SUBAGENT_PARENT_CAPABILITY_TOKEN_ENV] ?? '')\n : '';\n env[INHERIT_PROJECT_CONTEXT_ENV] = input.inheritProjectContext ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[INHERIT_SKILLS_ENV] = input.inheritSkills ? ENABLED_ENV_VALUE : DISABLED_ENV_VALUE;\n env[PI_INTERCOM_STABLE_ID_ENV] = input.intercomSessionName || undefined;\n // Cleared unconditionally: an inherited session id would make the child adopt\n // its parent's intercom identity.\n env[PI_INTERCOM_SESSION_ID_ENV] = undefined;\n if (input.intercomSessionName) {\n env[SUBAGENT_INTERCOM_SESSION_NAME_ENV] = input.intercomSessionName;\n }\n if (input.runId) {\n env[SUBAGENT_RUN_ID_ENV] = input.runId;\n }\n if (input.childAgentName) {\n env[SUBAGENT_CHILD_AGENT_ENV] = input.childAgentName;\n }\n if (input.childIndex !== undefined) {\n env[SUBAGENT_CHILD_INDEX_ENV] = String(input.childIndex);\n }\n // The Pi host reads its own selector list from this var. Without a ceiling the\n // caller's selectors pass through; with one, only the selectors that survived\n // filtering do, and anything else resolves to the explicit \"none\" sentinel.\n if (!toolPlan.capabilityCeiling && input.mcpDirectTools?.length)\n env[MCP_DIRECT_TOOLS_ENV] = input.mcpDirectTools.join(',');\n else if (\n toolPlan.capabilityCeiling &&\n toolPlan.effectiveMcpSelections.length &&\n !toolPlan.capabilityCeiling.denyExtensions\n )\n env[MCP_DIRECT_TOOLS_ENV] = toolPlan.effectiveMcpSelections.map((selection) => selection.selector).join(',');\n else env[MCP_DIRECT_TOOLS_ENV] = NO_MCP_DIRECT_TOOLS;\n const encodedCapabilityCeiling = encodeSubagentCapabilityCeiling(toolPlan.capabilityCeiling);\n if (encodedCapabilityCeiling) env[SUBAGENT_CAPABILITY_CEILING_ENV] = encodedCapabilityCeiling;\n if (input.structuredOutput) {\n env[STRUCTURED_OUTPUT_CAPTURE_ENV] = input.structuredOutput.outputPath;\n env[STRUCTURED_OUTPUT_SCHEMA_ENV] = input.structuredOutput.schemaPath;\n }\n if (input.steerInboxDir) {\n env[SUBAGENT_STEER_INBOX_ENV] = input.steerInboxDir;\n }\n if (input.steerCapabilityPath) env[SUBAGENT_STEER_CAPABILITY_ENV] = input.steerCapabilityPath;\n if (input.steerAckDir) env[SUBAGENT_STEER_ACK_DIR_ENV] = input.steerAckDir;\n const encodedToolBudget = encodeToolBudgetEnv(input.toolBudget);\n if (encodedToolBudget) env[TOOL_BUDGET_ENV] = encodedToolBudget;\n env[TOOL_BUDGET_ZERO_AUTH_ENV] = input.allowZeroToolBudget ? ENABLED_ENV_VALUE : undefined;\n env[SUBAGENT_PROTECTED_PARENT_PIDS_ENV] = JSON.stringify(\n [\n ...new Set([\n ...decodeProtectedParentProcessIds(process.env[SUBAGENT_PROTECTED_PARENT_PIDS_ENV]),\n process.pid,\n process.ppid,\n ]),\n ].filter((pid) => Number.isSafeInteger(pid) && pid > 1),\n );\n env[SUBAGENT_PARENT_SESSION_ENV] = input.parentSessionId ?? process.env[SUBAGENT_PARENT_SESSION_ENV] ?? '';\n env[DOOM_CHILD_PROCESS_CONTEXT_ENV] = input.parentSessionId\n ? encodeChildProcessContext({\n parentSessionId: input.parentSessionId,\n workingDirectory: input.cwd ?? process.cwd(),\n ...(input.childAgentName ? { mode: input.childAgentName } : {}),\n })\n : undefined;\n\n const sdk: PiSdkLaunchSettings = {\n ...(input.model || input.thinking ? { model: applyThinkingSuffix(input.model, input.thinking) } : {}),\n ...sdkResources,\n noContextFiles: !input.inheritProjectContext,\n sessionEnabled: input.sessionEnabled,\n ...(input.sessionDir ? { sessionDir: input.sessionDir } : {}),\n ...(input.sessionFile ? { sessionFile: input.sessionFile } : {}),\n ...(input.systemPrompt !== undefined && input.systemPrompt !== null ? { systemPrompt: input.systemPrompt } : {}),\n ...(input.systemPromptMode ? { systemPromptMode: input.systemPromptMode } : {}),\n };\n\n return { args, env, sdk, tempDir, toolDiagnosticPath, capabilityAudit: toolPlan.capabilityAudit };\n}\n\nexport const parseParentPathEnv = parseNestedPathEnv;\n\nexport function cleanupTempDir(tempDir: string | null | undefined): boolean {\n if (!tempDir) return true;\n try {\n fs.rmSync(tempDir, { recursive: true, force: true });\n return true;\n } catch {\n // The child may still hold the prompt file open. Reporting false lets the\n // caller record the leak; throwing would fail a run that already succeeded.\n return false;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../../../_virtual/_rolldown/runtime.cjs`);require(`../../../adapters/process/env.cjs`);let t=require(`node:fs`);t=e.__toESM(t,1);let n=require(`node:path`);n=e.__toESM(n,1),require(`node:url`);function r(e){let r=n.dirname(e);for(;r!==n.dirname(r);){let e=n.join(r,`package.json`);if(t.existsSync(e)&&i(JSON.parse(t.readFileSync(e,`utf-8`)))===`@earendil-works/pi-coding-agent`)return r;r=n.dirname(r)}}function i(e){if(typeof e!=`object`||!e)return;let t=e.name;return typeof t==`string`?t:void 0}function a(){try{let e=process.argv[1];return e?r(t.realpathSync(e)):void 0}catch{return}}exports.resolvePiPackageRoot=a;
|
|
2
|
+
//# sourceMappingURL=piSpawn.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piSpawn.cjs","names":["path","fs"],"sources":["../../../../src/services/runs/shared/piSpawn.ts"],"sourcesContent":["/**\n * How to invoke the Pi CLI for a child process.\n *\n * DESIGN PATTERNS:\n * - Three resolution tiers, most explicit first: an operator override env var,\n * then a verified script path run through this process's own Node binary, then\n * bare `pi` on PATH. Running the resolved script under `process.execPath` means\n * a child gets the same Node version as its parent, which a shebang would not\n * guarantee\n * - Every resolution step is best-effort. Failing to identify the installed CLI\n * is not an error, it just falls through to the next tier\n * - Filesystem and resolver calls are injectable, because ESM module namespaces\n * are frozen and `node:fs` cannot otherwise be substituted in a test\n *\n * AVOID:\n * - Trusting `process.argv[1]` without confirming it really is the Pi CLI. The\n * host embedding this package has its own entry point there, and spawning that\n * would run the host again rather than the agent\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { PI_SUBAGENT_PI_BINARY_ENV } from '../../../adapters/process/env.ts';\n\nexport const PI_CODING_AGENT_PACKAGE = '@earendil-works/pi-coding-agent';\n\nconst PACKAGE_MANIFEST_NAME = 'package.json';\nconst PI_BIN_FIELD_NAME = 'pi';\nconst PI_PATH_COMMAND = 'pi';\nconst NODE_SCRIPT_EXTENSIONS = /\\.(?:mjs|cjs|js)$/i;\n\n/** Walk up from an entry point to the package root that declares the Pi CLI. */\nexport function findPiPackageRootFromEntry(entryPoint: string): string | undefined {\n let dir = path.dirname(entryPoint);\n while (dir !== path.dirname(dir)) {\n const packageJsonPath = path.join(dir, PACKAGE_MANIFEST_NAME);\n if (fs.existsSync(packageJsonPath)) {\n const manifest: unknown = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n if (readManifestName(manifest) === PI_CODING_AGENT_PACKAGE) return dir;\n }\n dir = path.dirname(dir);\n }\n return undefined;\n}\n\nfunction readManifestName(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const name: unknown = (manifest as { name?: unknown }).name;\n return typeof name === 'string' ? name : undefined;\n}\n\n/**\n * The `bin` entry to spawn, from a package manifest of unknown shape.\n *\n * npm allows `bin` to be either a bare string or a map. The named `pi` entry\n * wins; any single other entry is accepted because a renamed fork still exposes\n * exactly one executable.\n */\nfunction readManifestBinPath(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const bin: unknown = (manifest as { bin?: unknown }).bin;\n if (typeof bin === 'string') return bin;\n if (typeof bin !== 'object' || bin === null) return undefined;\n const entries: Record<string, unknown> = bin as Record<string, unknown>;\n const named: unknown = entries[PI_BIN_FIELD_NAME];\n if (typeof named === 'string') return named;\n const first = Object.values(entries).find((value): value is string => typeof value === 'string');\n return first;\n}\n\nexport function resolveInstalledPiPackageRoot(): string | undefined {\n return findPiPackageRootFromEntry(fileURLToPath(import.meta.resolve(PI_CODING_AGENT_PACKAGE)));\n}\n\nexport function resolvePiPackageRoot(): string | undefined {\n try {\n const entry = process.argv[1];\n return entry ? findPiPackageRootFromEntry(fs.realpathSync(entry)) : undefined;\n } catch {\n // process.argv[1] probing is best-effort; callers fall back to PATH or package resolution.\n return undefined;\n }\n}\n\nexport interface PiSpawnDeps {\n platform?: NodeJS.Platform;\n execPath?: string;\n argv1?: string;\n existsSync?: (filePath: string) => boolean;\n realpathSync?: (filePath: string) => string;\n readFileSync?: (filePath: string, encoding: 'utf-8') => string;\n resolvePackageJson?: () => string;\n resolvePackageEntry?: () => string;\n piPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\ninterface PiSpawnCommand {\n command: string;\n args: string[];\n}\n\nfunction isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {\n if (!existsSync(filePath)) return false;\n return NODE_SCRIPT_EXTENSIONS.test(filePath);\n}\n\nfunction normalizePath(filePath: string): string {\n return path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n}\n\n/** A concrete Pi CLI script this process can hand to Node, or undefined. */\nexport function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {\n const existsSync = deps.existsSync ?? fs.existsSync;\n const realpathSync = deps.realpathSync ?? fs.realpathSync;\n const readFileSync =\n deps.readFileSync ?? ((filePath: string, encoding: 'utf-8') => fs.readFileSync(filePath, encoding));\n const argv1 = deps.argv1 ?? process.argv[1];\n\n // Reuse our own entry point only when it provably belongs to the Pi package.\n if (argv1) {\n const argvPath = normalizePath(argv1);\n if (isRunnableNodeScript(argvPath, existsSync)) {\n try {\n const canonicalArgvPath = realpathSync(argvPath);\n if (isRunnableNodeScript(canonicalArgvPath, existsSync) && findPiPackageRootFromEntry(canonicalArgvPath)) {\n return canonicalArgvPath;\n }\n } catch {\n // Host package metadata is untrusted here; keep resolving the installed Pi CLI.\n }\n }\n }\n\n try {\n const resolvePackageJson =\n deps.resolvePackageJson ??\n (() => {\n const root = deps.piPackageRoot ?? resolvePiPackageRoot();\n if (root) return path.join(root, PACKAGE_MANIFEST_NAME);\n const packageRoot = deps.resolvePackageEntry\n ? findPiPackageRootFromEntry(deps.resolvePackageEntry())\n : resolveInstalledPiPackageRoot();\n if (!packageRoot) throw new Error(`Could not resolve ${PI_CODING_AGENT_PACKAGE} package root`);\n return path.join(packageRoot, PACKAGE_MANIFEST_NAME);\n });\n const packageJsonPath = resolvePackageJson();\n const manifest: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const binPath = readManifestBinPath(manifest);\n if (!binPath) return undefined;\n const candidate = path.resolve(path.dirname(packageJsonPath), binPath);\n if (isRunnableNodeScript(candidate, existsSync)) {\n return candidate;\n }\n } catch {\n // Verified CLI resolution is optional; falling back to `pi` lets PATH handle execution.\n return undefined;\n }\n\n return undefined;\n}\n\nexport function getPiSpawnCommand(args: string[], deps: PiSpawnDeps = {}): PiSpawnCommand {\n const env = deps.env ?? process.env;\n const piBinary = env[PI_SUBAGENT_PI_BINARY_ENV]?.trim();\n if (piBinary) {\n return { command: piBinary, args };\n }\n\n const piCliPath = resolvePiCliScript(deps);\n if (piCliPath) {\n return {\n command: deps.execPath ?? process.execPath,\n args: [piCliPath, ...args],\n };\n }\n\n return { command: PI_PATH_COMMAND, args };\n}\n"],"mappings":"kNAiCA,SAAgB,EAA2B,EAAwC,CACjF,IAAI,EAAMA,EAAK,QAAQ,EAAW,CAClC,KAAO,IAAQA,EAAK,QAAQ,EAAI,EAAE,CAChC,IAAM,EAAkBA,EAAK,KAAK,EAAK,eAAsB,CAC7D,GAAIC,EAAG,WAAW,EAAgB,EAE5B,EADsB,KAAK,MAAMA,EAAG,aAAa,EAAiB,QAAQ,CACjD,CAAC,GAAA,kCAA8B,OAAO,EAErE,EAAMD,EAAK,QAAQ,EAAI,EAK3B,SAAS,EAAiB,EAAuC,CAC/D,GAAI,OAAO,GAAa,WAAY,EAAmB,OACvD,IAAM,EAAiB,EAAgC,KACvD,OAAO,OAAO,GAAS,SAAW,EAAO,IAAA,GA0B3C,SAAgB,GAA2C,CACzD,GAAI,CACF,IAAM,EAAQ,QAAQ,KAAK,GAC3B,OAAO,EAAQ,EAA2BC,EAAG,aAAa,EAAM,CAAC,CAAG,IAAA,QAC9D,CAEN"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{init_env as t}from"../../../adapters/process/env.mjs";import*as n from"node:fs";import*as r from"node:path";import"node:url";function i(e){let t=r.dirname(e);for(;t!==r.dirname(t);){let e=r.join(t,s);if(n.existsSync(e)&&a(JSON.parse(n.readFileSync(e,`utf-8`)))===`@earendil-works/pi-coding-agent`)return t;t=r.dirname(t)}}function a(e){if(typeof e!=`object`||!e)return;let t=e.name;return typeof t==`string`?t:void 0}function o(){try{let e=process.argv[1];return e?i(n.realpathSync(e)):void 0}catch{return}}var s,c=e((()=>{t(),s=`package.json`}));c();export{c as init_piSpawn,o as resolvePiPackageRoot};
|
|
2
|
+
//# sourceMappingURL=piSpawn.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piSpawn.mjs","names":[],"sources":["../../../../src/services/runs/shared/piSpawn.ts"],"sourcesContent":["/**\n * How to invoke the Pi CLI for a child process.\n *\n * DESIGN PATTERNS:\n * - Three resolution tiers, most explicit first: an operator override env var,\n * then a verified script path run through this process's own Node binary, then\n * bare `pi` on PATH. Running the resolved script under `process.execPath` means\n * a child gets the same Node version as its parent, which a shebang would not\n * guarantee\n * - Every resolution step is best-effort. Failing to identify the installed CLI\n * is not an error, it just falls through to the next tier\n * - Filesystem and resolver calls are injectable, because ESM module namespaces\n * are frozen and `node:fs` cannot otherwise be substituted in a test\n *\n * AVOID:\n * - Trusting `process.argv[1]` without confirming it really is the Pi CLI. The\n * host embedding this package has its own entry point there, and spawning that\n * would run the host again rather than the agent\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { PI_SUBAGENT_PI_BINARY_ENV } from '../../../adapters/process/env.ts';\n\nexport const PI_CODING_AGENT_PACKAGE = '@earendil-works/pi-coding-agent';\n\nconst PACKAGE_MANIFEST_NAME = 'package.json';\nconst PI_BIN_FIELD_NAME = 'pi';\nconst PI_PATH_COMMAND = 'pi';\nconst NODE_SCRIPT_EXTENSIONS = /\\.(?:mjs|cjs|js)$/i;\n\n/** Walk up from an entry point to the package root that declares the Pi CLI. */\nexport function findPiPackageRootFromEntry(entryPoint: string): string | undefined {\n let dir = path.dirname(entryPoint);\n while (dir !== path.dirname(dir)) {\n const packageJsonPath = path.join(dir, PACKAGE_MANIFEST_NAME);\n if (fs.existsSync(packageJsonPath)) {\n const manifest: unknown = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n if (readManifestName(manifest) === PI_CODING_AGENT_PACKAGE) return dir;\n }\n dir = path.dirname(dir);\n }\n return undefined;\n}\n\nfunction readManifestName(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const name: unknown = (manifest as { name?: unknown }).name;\n return typeof name === 'string' ? name : undefined;\n}\n\n/**\n * The `bin` entry to spawn, from a package manifest of unknown shape.\n *\n * npm allows `bin` to be either a bare string or a map. The named `pi` entry\n * wins; any single other entry is accepted because a renamed fork still exposes\n * exactly one executable.\n */\nfunction readManifestBinPath(manifest: unknown): string | undefined {\n if (typeof manifest !== 'object' || manifest === null) return undefined;\n const bin: unknown = (manifest as { bin?: unknown }).bin;\n if (typeof bin === 'string') return bin;\n if (typeof bin !== 'object' || bin === null) return undefined;\n const entries: Record<string, unknown> = bin as Record<string, unknown>;\n const named: unknown = entries[PI_BIN_FIELD_NAME];\n if (typeof named === 'string') return named;\n const first = Object.values(entries).find((value): value is string => typeof value === 'string');\n return first;\n}\n\nexport function resolveInstalledPiPackageRoot(): string | undefined {\n return findPiPackageRootFromEntry(fileURLToPath(import.meta.resolve(PI_CODING_AGENT_PACKAGE)));\n}\n\nexport function resolvePiPackageRoot(): string | undefined {\n try {\n const entry = process.argv[1];\n return entry ? findPiPackageRootFromEntry(fs.realpathSync(entry)) : undefined;\n } catch {\n // process.argv[1] probing is best-effort; callers fall back to PATH or package resolution.\n return undefined;\n }\n}\n\nexport interface PiSpawnDeps {\n platform?: NodeJS.Platform;\n execPath?: string;\n argv1?: string;\n existsSync?: (filePath: string) => boolean;\n realpathSync?: (filePath: string) => string;\n readFileSync?: (filePath: string, encoding: 'utf-8') => string;\n resolvePackageJson?: () => string;\n resolvePackageEntry?: () => string;\n piPackageRoot?: string;\n env?: NodeJS.ProcessEnv;\n}\n\ninterface PiSpawnCommand {\n command: string;\n args: string[];\n}\n\nfunction isRunnableNodeScript(filePath: string, existsSync: (filePath: string) => boolean): boolean {\n if (!existsSync(filePath)) return false;\n return NODE_SCRIPT_EXTENSIONS.test(filePath);\n}\n\nfunction normalizePath(filePath: string): string {\n return path.isAbsolute(filePath) ? filePath : path.resolve(filePath);\n}\n\n/** A concrete Pi CLI script this process can hand to Node, or undefined. */\nexport function resolvePiCliScript(deps: PiSpawnDeps = {}): string | undefined {\n const existsSync = deps.existsSync ?? fs.existsSync;\n const realpathSync = deps.realpathSync ?? fs.realpathSync;\n const readFileSync =\n deps.readFileSync ?? ((filePath: string, encoding: 'utf-8') => fs.readFileSync(filePath, encoding));\n const argv1 = deps.argv1 ?? process.argv[1];\n\n // Reuse our own entry point only when it provably belongs to the Pi package.\n if (argv1) {\n const argvPath = normalizePath(argv1);\n if (isRunnableNodeScript(argvPath, existsSync)) {\n try {\n const canonicalArgvPath = realpathSync(argvPath);\n if (isRunnableNodeScript(canonicalArgvPath, existsSync) && findPiPackageRootFromEntry(canonicalArgvPath)) {\n return canonicalArgvPath;\n }\n } catch {\n // Host package metadata is untrusted here; keep resolving the installed Pi CLI.\n }\n }\n }\n\n try {\n const resolvePackageJson =\n deps.resolvePackageJson ??\n (() => {\n const root = deps.piPackageRoot ?? resolvePiPackageRoot();\n if (root) return path.join(root, PACKAGE_MANIFEST_NAME);\n const packageRoot = deps.resolvePackageEntry\n ? findPiPackageRootFromEntry(deps.resolvePackageEntry())\n : resolveInstalledPiPackageRoot();\n if (!packageRoot) throw new Error(`Could not resolve ${PI_CODING_AGENT_PACKAGE} package root`);\n return path.join(packageRoot, PACKAGE_MANIFEST_NAME);\n });\n const packageJsonPath = resolvePackageJson();\n const manifest: unknown = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n const binPath = readManifestBinPath(manifest);\n if (!binPath) return undefined;\n const candidate = path.resolve(path.dirname(packageJsonPath), binPath);\n if (isRunnableNodeScript(candidate, existsSync)) {\n return candidate;\n }\n } catch {\n // Verified CLI resolution is optional; falling back to `pi` lets PATH handle execution.\n return undefined;\n }\n\n return undefined;\n}\n\nexport function getPiSpawnCommand(args: string[], deps: PiSpawnDeps = {}): PiSpawnCommand {\n const env = deps.env ?? process.env;\n const piBinary = env[PI_SUBAGENT_PI_BINARY_ENV]?.trim();\n if (piBinary) {\n return { command: piBinary, args };\n }\n\n const piCliPath = resolvePiCliScript(deps);\n if (piCliPath) {\n return {\n command: deps.execPath ?? process.execPath,\n args: [piCliPath, ...args],\n };\n }\n\n return { command: PI_PATH_COMMAND, args };\n}\n"],"mappings":"uMAiCA,SAAgB,EAA2B,EAAwC,CACjF,IAAI,EAAM,EAAK,QAAQ,EAAW,CAClC,KAAO,IAAQ,EAAK,QAAQ,EAAI,EAAE,CAChC,IAAM,EAAkB,EAAK,KAAK,EAAK,EAAsB,CAC7D,GAAI,EAAG,WAAW,EAAgB,EAE5B,EADsB,KAAK,MAAM,EAAG,aAAa,EAAiB,QAAQ,CACjD,CAAC,GAAA,kCAA8B,OAAO,EAErE,EAAM,EAAK,QAAQ,EAAI,EAK3B,SAAS,EAAiB,EAAuC,CAC/D,GAAI,OAAO,GAAa,WAAY,EAAmB,OACvD,IAAM,EAAiB,EAAgC,KACvD,OAAO,OAAO,GAAS,SAAW,EAAO,IAAA,GA0B3C,SAAgB,GAA2C,CACzD,GAAI,CACF,IAAM,EAAQ,QAAQ,KAAK,GAC3B,OAAO,EAAQ,EAA2B,EAAG,aAAa,EAAM,CAAC,CAAG,IAAA,QAC9D,CAEN,2BA1DyE,CAIvE,EAAwB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
async function e(e,t,n){let r=Date.now(),i=Array.from({length:e.length}),a=Math.max(1,Math.min(t,e.length||1)),o=0;async function s(){for(;;){let t=o;if(o+=1,t>=e.length)return;try{i[t]={status:`fulfilled`,value:await e[t]()}}catch(e){i[t]={status:`rejected`,reason:e}}}}return n?.(`doom_team.concurrency_started`,{"team.task_count":e.length,"team.concurrency":a}),await Promise.all(Array.from({length:a},()=>s())),n?.(`doom_team.concurrency_finished`,{"team.task_count":e.length,"team.concurrency":a,"team.failure_count":i.filter(e=>e?.status===`rejected`).length,duration_ms:Date.now()-r,outcome:`completed`}),i}exports.runWithConcurrency=e;
|
|
2
|
+
//# sourceMappingURL=runWithConcurrency.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWithConcurrency.cjs","names":[],"sources":["../../../../src/services/runs/shared/runWithConcurrency.ts"],"sourcesContent":["/**\n * Runs a batch of async operations with at most N in flight at once, and\n * always settles all of them - one rejection never aborts its peers.\n *\n * WHY THIS EXISTS, RATHER THAN BEING INLINED INTO ITS ONE CALLER:\n * `spawnPlan.ts`'s PARALLEL mode needs exactly this shape (fire up to\n * `concurrency` tasks at once, wait for a slot to free before starting the\n * next, return every outcome regardless of individual failure), and it is a\n * property worth testing directly rather than only through spawn-plan's own\n * fixtures: \"at most N in flight at any moment\" and \"one rejection does not\n * abort its peers\" are each independently verifiable here, which is more\n * precise than inferring them from a higher-level test that also exercises\n * agent resolution, depth checks, and status writes.\n *\n * DELIBERATELY MINIMAL:\n * Bounded concurrency and settle-all, nothing else - no priority ordering\n * beyond FIFO start order, no cancellation, no `AbortSignal`. Reporting is\n * injected by the caller so this host-neutral helper never creates a telemetry\n * resource that it cannot shut down.\n */\n\nexport type ConcurrencyEventReporter = (event: string, attributes: Record<string, unknown>) => void;\n\nexport type ConcurrencyOutcome<T> = { status: 'fulfilled'; value: T } | { status: 'rejected'; reason: unknown };\n\n/**\n * Runs `factories` (each called at most once, lazily, only once a slot is\n * free) with at most `concurrency` in flight at a time. Resolves once every\n * factory has settled, in the SAME ORDER as `factories` regardless of which\n * one finished first - a caller zipping results back against its own input\n * list does not need to track indices itself.\n */\nexport async function runWithConcurrency<T>(\n factories: ReadonlyArray<() => Promise<T>>,\n concurrency: number,\n report?: ConcurrencyEventReporter,\n): Promise<ConcurrencyOutcome<T>[]> {\n const startedAt = Date.now();\n const results: ConcurrencyOutcome<T>[] = Array.from({ length: factories.length });\n const effectiveConcurrency = Math.max(1, Math.min(concurrency, factories.length || 1));\n let nextIndex = 0;\n\n async function worker(): Promise<void> {\n for (;;) {\n const index = nextIndex;\n nextIndex += 1;\n if (index >= factories.length) return;\n try {\n results[index] = { status: 'fulfilled', value: await factories[index]!() };\n } catch (reason) {\n results[index] = { status: 'rejected', reason };\n }\n }\n }\n\n report?.('doom_team.concurrency_started', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n });\n await Promise.all(Array.from({ length: effectiveConcurrency }, () => worker()));\n report?.('doom_team.concurrency_finished', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n 'team.failure_count': results.filter((result) => result?.status === 'rejected').length,\n duration_ms: Date.now() - startedAt,\n outcome: 'completed',\n });\n return results;\n}\n"],"mappings":"AAgCA,eAAsB,EACpB,EACA,EACA,EACkC,CAClC,IAAM,EAAY,KAAK,KAAK,CACtB,EAAmC,MAAM,KAAK,CAAE,OAAQ,EAAU,OAAQ,CAAC,CAC3E,EAAuB,KAAK,IAAI,EAAG,KAAK,IAAI,EAAa,EAAU,QAAU,EAAE,CAAC,CAClF,EAAY,EAEhB,eAAe,GAAwB,CACrC,OAAS,CACP,IAAM,EAAQ,EAEd,GADA,GAAa,EACT,GAAS,EAAU,OAAQ,OAC/B,GAAI,CACF,EAAQ,GAAS,CAAE,OAAQ,YAAa,MAAO,MAAM,EAAU,IAAS,CAAE,OACnE,EAAQ,CACf,EAAQ,GAAS,CAAE,OAAQ,WAAY,SAAQ,GAiBrD,OAZA,IAAS,gCAAiC,CACxC,kBAAmB,EAAU,OAC7B,mBAAoB,EACrB,CAAC,CACF,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAE,OAAQ,EAAsB,KAAQ,GAAQ,CAAC,CAAC,CAC/E,IAAS,iCAAkC,CACzC,kBAAmB,EAAU,OAC7B,mBAAoB,EACpB,qBAAsB,EAAQ,OAAQ,GAAW,GAAQ,SAAW,WAAW,CAAC,OAChF,YAAa,KAAK,KAAK,CAAG,EAC1B,QAAS,YACV,CAAC,CACK"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/services/runs/shared/runWithConcurrency.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Runs a batch of async operations with at most N in flight at once, and
|
|
4
|
+
* always settles all of them - one rejection never aborts its peers.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS, RATHER THAN BEING INLINED INTO ITS ONE CALLER:
|
|
7
|
+
* `spawnPlan.ts`'s PARALLEL mode needs exactly this shape (fire up to
|
|
8
|
+
* `concurrency` tasks at once, wait for a slot to free before starting the
|
|
9
|
+
* next, return every outcome regardless of individual failure), and it is a
|
|
10
|
+
* property worth testing directly rather than only through spawn-plan's own
|
|
11
|
+
* fixtures: "at most N in flight at any moment" and "one rejection does not
|
|
12
|
+
* abort its peers" are each independently verifiable here, which is more
|
|
13
|
+
* precise than inferring them from a higher-level test that also exercises
|
|
14
|
+
* agent resolution, depth checks, and status writes.
|
|
15
|
+
*
|
|
16
|
+
* DELIBERATELY MINIMAL:
|
|
17
|
+
* Bounded concurrency and settle-all, nothing else - no priority ordering
|
|
18
|
+
* beyond FIFO start order, no cancellation, no `AbortSignal`. Reporting is
|
|
19
|
+
* injected by the caller so this host-neutral helper never creates a telemetry
|
|
20
|
+
* resource that it cannot shut down.
|
|
21
|
+
*/
|
|
22
|
+
type ConcurrencyEventReporter = (event: string, attributes: Record<string, unknown>) => void;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ConcurrencyEventReporter };
|
|
25
|
+
//# sourceMappingURL=runWithConcurrency.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWithConcurrency.d.cts","names":[],"sources":["../../../../src/services/runs/shared/runWithConcurrency.ts"],"mappings":";;AAqBA;;;;;;;;;;;;;;;;;;;KAAY,wBAAA,IAA4B,KAAA,UAAe,UAAA,EAAY,MAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/services/runs/shared/runWithConcurrency.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Runs a batch of async operations with at most N in flight at once, and
|
|
4
|
+
* always settles all of them - one rejection never aborts its peers.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS EXISTS, RATHER THAN BEING INLINED INTO ITS ONE CALLER:
|
|
7
|
+
* `spawnPlan.ts`'s PARALLEL mode needs exactly this shape (fire up to
|
|
8
|
+
* `concurrency` tasks at once, wait for a slot to free before starting the
|
|
9
|
+
* next, return every outcome regardless of individual failure), and it is a
|
|
10
|
+
* property worth testing directly rather than only through spawn-plan's own
|
|
11
|
+
* fixtures: "at most N in flight at any moment" and "one rejection does not
|
|
12
|
+
* abort its peers" are each independently verifiable here, which is more
|
|
13
|
+
* precise than inferring them from a higher-level test that also exercises
|
|
14
|
+
* agent resolution, depth checks, and status writes.
|
|
15
|
+
*
|
|
16
|
+
* DELIBERATELY MINIMAL:
|
|
17
|
+
* Bounded concurrency and settle-all, nothing else - no priority ordering
|
|
18
|
+
* beyond FIFO start order, no cancellation, no `AbortSignal`. Reporting is
|
|
19
|
+
* injected by the caller so this host-neutral helper never creates a telemetry
|
|
20
|
+
* resource that it cannot shut down.
|
|
21
|
+
*/
|
|
22
|
+
type ConcurrencyEventReporter = (event: string, attributes: Record<string, unknown>) => void;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ConcurrencyEventReporter };
|
|
25
|
+
//# sourceMappingURL=runWithConcurrency.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWithConcurrency.d.mts","names":[],"sources":["../../../../src/services/runs/shared/runWithConcurrency.ts"],"mappings":";;AAqBA;;;;;;;;;;;;;;;;;;;KAAY,wBAAA,IAA4B,KAAA,UAAe,UAAA,EAAY,MAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";async function t(e,t,n){let r=Date.now(),i=Array.from({length:e.length}),a=Math.max(1,Math.min(t,e.length||1)),o=0;async function s(){for(;;){let t=o;if(o+=1,t>=e.length)return;try{i[t]={status:`fulfilled`,value:await e[t]()}}catch(e){i[t]={status:`rejected`,reason:e}}}}return n?.(`doom_team.concurrency_started`,{"team.task_count":e.length,"team.concurrency":a}),await Promise.all(Array.from({length:a},()=>s())),n?.(`doom_team.concurrency_finished`,{"team.task_count":e.length,"team.concurrency":a,"team.failure_count":i.filter(e=>e?.status===`rejected`).length,duration_ms:Date.now()-r,outcome:`completed`}),i}var n=e((()=>{}));n();export{n as init_runWithConcurrency,t as runWithConcurrency};
|
|
2
|
+
//# sourceMappingURL=runWithConcurrency.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runWithConcurrency.mjs","names":[],"sources":["../../../../src/services/runs/shared/runWithConcurrency.ts"],"sourcesContent":["/**\n * Runs a batch of async operations with at most N in flight at once, and\n * always settles all of them - one rejection never aborts its peers.\n *\n * WHY THIS EXISTS, RATHER THAN BEING INLINED INTO ITS ONE CALLER:\n * `spawnPlan.ts`'s PARALLEL mode needs exactly this shape (fire up to\n * `concurrency` tasks at once, wait for a slot to free before starting the\n * next, return every outcome regardless of individual failure), and it is a\n * property worth testing directly rather than only through spawn-plan's own\n * fixtures: \"at most N in flight at any moment\" and \"one rejection does not\n * abort its peers\" are each independently verifiable here, which is more\n * precise than inferring them from a higher-level test that also exercises\n * agent resolution, depth checks, and status writes.\n *\n * DELIBERATELY MINIMAL:\n * Bounded concurrency and settle-all, nothing else - no priority ordering\n * beyond FIFO start order, no cancellation, no `AbortSignal`. Reporting is\n * injected by the caller so this host-neutral helper never creates a telemetry\n * resource that it cannot shut down.\n */\n\nexport type ConcurrencyEventReporter = (event: string, attributes: Record<string, unknown>) => void;\n\nexport type ConcurrencyOutcome<T> = { status: 'fulfilled'; value: T } | { status: 'rejected'; reason: unknown };\n\n/**\n * Runs `factories` (each called at most once, lazily, only once a slot is\n * free) with at most `concurrency` in flight at a time. Resolves once every\n * factory has settled, in the SAME ORDER as `factories` regardless of which\n * one finished first - a caller zipping results back against its own input\n * list does not need to track indices itself.\n */\nexport async function runWithConcurrency<T>(\n factories: ReadonlyArray<() => Promise<T>>,\n concurrency: number,\n report?: ConcurrencyEventReporter,\n): Promise<ConcurrencyOutcome<T>[]> {\n const startedAt = Date.now();\n const results: ConcurrencyOutcome<T>[] = Array.from({ length: factories.length });\n const effectiveConcurrency = Math.max(1, Math.min(concurrency, factories.length || 1));\n let nextIndex = 0;\n\n async function worker(): Promise<void> {\n for (;;) {\n const index = nextIndex;\n nextIndex += 1;\n if (index >= factories.length) return;\n try {\n results[index] = { status: 'fulfilled', value: await factories[index]!() };\n } catch (reason) {\n results[index] = { status: 'rejected', reason };\n }\n }\n }\n\n report?.('doom_team.concurrency_started', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n });\n await Promise.all(Array.from({ length: effectiveConcurrency }, () => worker()));\n report?.('doom_team.concurrency_finished', {\n 'team.task_count': factories.length,\n 'team.concurrency': effectiveConcurrency,\n 'team.failure_count': results.filter((result) => result?.status === 'rejected').length,\n duration_ms: Date.now() - startedAt,\n outcome: 'completed',\n });\n return results;\n}\n"],"mappings":"mEAgCA,eAAsB,EACpB,EACA,EACA,EACkC,CAClC,IAAM,EAAY,KAAK,KAAK,CACtB,EAAmC,MAAM,KAAK,CAAE,OAAQ,EAAU,OAAQ,CAAC,CAC3E,EAAuB,KAAK,IAAI,EAAG,KAAK,IAAI,EAAa,EAAU,QAAU,EAAE,CAAC,CAClF,EAAY,EAEhB,eAAe,GAAwB,CACrC,OAAS,CACP,IAAM,EAAQ,EAEd,GADA,GAAa,EACT,GAAS,EAAU,OAAQ,OAC/B,GAAI,CACF,EAAQ,GAAS,CAAE,OAAQ,YAAa,MAAO,MAAM,EAAU,IAAS,CAAE,OACnE,EAAQ,CACf,EAAQ,GAAS,CAAE,OAAQ,WAAY,SAAQ,GAiBrD,OAZA,IAAS,gCAAiC,CACxC,kBAAmB,EAAU,OAC7B,mBAAoB,EACrB,CAAC,CACF,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAE,OAAQ,EAAsB,KAAQ,GAAQ,CAAC,CAAC,CAC/E,IAAS,iCAAkC,CACzC,kBAAmB,EAAU,OAC7B,mBAAoB,EACpB,qBAAsB,EAAQ,OAAQ,GAAW,GAAQ,SAAW,WAAW,CAAC,OAChF,YAAa,KAAK,KAAK,CAAG,EAC1B,QAAS,YACV,CAAC,CACK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../../../adapters/process/env.cjs`),t={claude:{command:`claude`,args:[`-p`,`{prompt}`]},antigravity:{command:`antigravity`,args:[`{prompt}`]}};function n(e){return(e??`pi`).trim()===`pi`}function r(e){return e?{...t,...e}:{...t}}function i(t,n,r){return r[e.runtimeBinaryEnvVar(t)]?.trim()||n.command}function a(e,t){return e.replaceAll(`{prompt}`,t.prompt).replaceAll(`{model}`,t.model??``).replaceAll(`{cwd}`,t.cwd)}function o(e,t,n,r=process.env){let o=t[e];if(!o){let n=Object.keys(t).sort().join(`, `)||`(none configured)`;throw Error(`Unknown subagent runtime '${e}'. Configured runtimes: ${n}.`)}return{runtime:e,command:i(e,o,r),args:o.args.map(e=>a(e,n)).filter(e=>e.length>0)}}exports.isPiRuntime=n,exports.resolveRuntimeLaunch=o,exports.resolveRuntimeTable=r;
|
|
2
|
+
//# sourceMappingURL=runtimeRegistry.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeRegistry.cjs","names":["runtimeBinaryEnvVar"],"sources":["../../../../src/services/runs/shared/runtimeRegistry.ts"],"sourcesContent":["/**\n * Which agent runtime executes a run, and how to invoke it.\n *\n * WHY THIS IS CONFIG AND NOT A CLASS PER VENDOR:\n * Every external agent CLI is the same shape from here: a binary, an argv with\n * the prompt substituted in, a working directory, and whatever it prints. There\n * is no per-vendor behaviour worth a per-vendor module, and inventing an\n * adapter interface would mean a new file, a new registration and a new test\n * suite every time someone wants to point a run at a different command. Adding\n * or retargeting a CLI is a config edit.\n *\n * WHAT THIS DELIBERATELY DOES NOT DO:\n * It does not parse vendor output. A generic runner cannot know what a given\n * CLI's JSON stream means, and pretending to would either lock the config down\n * to the two CLIs someone happened to test, or silently mis-report a third. The\n * run's final output is its output; status comes from the run lifecycle, which\n * already knows queued/running/terminal without reading a word of it.\n *\n * `pi` IS NOT IN THIS TABLE:\n * It is not an external command - it runs in-process through the SDK\n * (`runs/sdkRunnerEntry.ts`) and gets the team channel, steering and\n * structured output that an external one-shot cannot. Treating it as one more\n * row here would advertise capabilities the external path does not have.\n *\n * AVOID:\n * - Putting a secret in an argv template; argv is visible in the process table\n * - Adding a placeholder without substituting it. An unsubstituted `{prompt}`\n * reaches the CLI literally\n */\n\nimport { PI_RUNTIME_NAME, runtimeBinaryEnvVar } from '../../../adapters/process/env.ts';\n\n/** One external CLI, as configured. */\nexport interface RuntimeDefinition {\n /** Binary to execute. Resolved against PATH unless overridden by env. */\n command: string;\n /** Argv template. `{prompt}`, `{model}` and `{cwd}` are substituted per run. */\n args: string[];\n}\n\nexport type RuntimeTable = Record<string, RuntimeDefinition>;\n\n/**\n * Shipped defaults, overridable per entry by config.\n *\n * Both are headless one-shot invocations: the prompt goes in, the final answer\n * comes out on stdout, and the process exits. Neither is asked for a structured\n * stream, because nothing here would read it.\n */\nexport const DEFAULT_RUNTIMES: RuntimeTable = {\n claude: { command: 'claude', args: ['-p', '{prompt}'] },\n antigravity: { command: 'antigravity', args: ['{prompt}'] },\n};\n\nexport interface ResolvedRuntimeLaunch {\n runtime: string;\n command: string;\n args: string[];\n}\n\nexport interface RuntimeSubstitutions {\n prompt: string;\n model?: string;\n cwd: string;\n}\n\n/** True for the in-process SDK path, which this module does not describe. */\nexport function isPiRuntime(runtime: string | undefined): boolean {\n return (runtime ?? PI_RUNTIME_NAME).trim() === PI_RUNTIME_NAME;\n}\n\nexport function resolveRuntimeTable(configured: RuntimeTable | undefined): RuntimeTable {\n if (!configured) return { ...DEFAULT_RUNTIMES };\n return { ...DEFAULT_RUNTIMES, ...configured };\n}\n\n/**\n * The binary to run, most explicit source first.\n *\n * The env override exists for the same reason `piSpawn.ts` has one: a\n * developer testing against a locally built CLI must be able to point a run at\n * it without editing shared config.\n */\nfunction resolveCommand(runtime: string, definition: RuntimeDefinition, env: NodeJS.ProcessEnv): string {\n const override = env[runtimeBinaryEnvVar(runtime)]?.trim();\n return override || definition.command;\n}\n\nfunction substitute(template: string, values: RuntimeSubstitutions): string {\n return template\n .replaceAll('{prompt}', values.prompt)\n .replaceAll('{model}', values.model ?? '')\n .replaceAll('{cwd}', values.cwd);\n}\n\n/**\n * Resolve one run's command line.\n *\n * An argument that reduces to the empty string is dropped rather than passed:\n * a template carrying `--model {model}` for a run with no model override would\n * otherwise hand the CLI a bare `--model` with nothing after it.\n */\nexport function resolveRuntimeLaunch(\n runtime: string,\n table: RuntimeTable,\n values: RuntimeSubstitutions,\n env: NodeJS.ProcessEnv = process.env,\n): ResolvedRuntimeLaunch {\n const definition = table[runtime];\n if (!definition) {\n const known = Object.keys(table).sort().join(', ') || '(none configured)';\n throw new Error(`Unknown subagent runtime '${runtime}'. Configured runtimes: ${known}.`);\n }\n return {\n runtime,\n command: resolveCommand(runtime, definition, env),\n args: definition.args.map((arg) => substitute(arg, values)).filter((arg) => arg.length > 0),\n };\n}\n"],"mappings":"qDAiDa,EAAiC,CAC5C,OAAQ,CAAE,QAAS,SAAU,KAAM,CAAC,KAAM,WAAW,CAAE,CACvD,YAAa,CAAE,QAAS,cAAe,KAAM,CAAC,WAAW,CAAE,CAC5D,CAeD,SAAgB,EAAY,EAAsC,CAChE,OAAQ,GAAA,MAA4B,MAAM,GAAA,KAG5C,SAAgB,EAAoB,EAAoD,CAEtF,OADK,EACE,CAAE,GAAG,EAAkB,GAAG,EAAY,CADrB,CAAE,GAAG,EAAkB,CAWjD,SAAS,EAAe,EAAiB,EAA+B,EAAgC,CAEtG,OADiB,EAAIA,EAAAA,oBAAoB,EAAQ,GAAG,MAAM,EACvC,EAAW,QAGhC,SAAS,EAAW,EAAkB,EAAsC,CAC1E,OAAO,EACJ,WAAW,WAAY,EAAO,OAAO,CACrC,WAAW,UAAW,EAAO,OAAS,GAAG,CACzC,WAAW,QAAS,EAAO,IAAI,CAUpC,SAAgB,EACd,EACA,EACA,EACA,EAAyB,QAAQ,IACV,CACvB,IAAM,EAAa,EAAM,GACzB,GAAI,CAAC,EAAY,CACf,IAAM,EAAQ,OAAO,KAAK,EAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAI,oBACtD,MAAU,MAAM,6BAA6B,EAAQ,0BAA0B,EAAM,GAAG,CAE1F,MAAO,CACL,UACA,QAAS,EAAe,EAAS,EAAY,EAAI,CACjD,KAAM,EAAW,KAAK,IAAK,GAAQ,EAAW,EAAK,EAAO,CAAC,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC5F"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{init_env as t,runtimeBinaryEnvVar as n}from"../../../adapters/process/env.mjs";function r(e){return(e??`pi`).trim()===`pi`}function i(e){return e?{...c,...e}:{...c}}function a(e,t,r){return r[n(e)]?.trim()||t.command}function o(e,t){return e.replaceAll(`{prompt}`,t.prompt).replaceAll(`{model}`,t.model??``).replaceAll(`{cwd}`,t.cwd)}function s(e,t,n,r=process.env){let i=t[e];if(!i){let n=Object.keys(t).sort().join(`, `)||`(none configured)`;throw Error(`Unknown subagent runtime '${e}'. Configured runtimes: ${n}.`)}return{runtime:e,command:a(e,i,r),args:i.args.map(e=>o(e,n)).filter(e=>e.length>0)}}var c,l=e((()=>{t(),c={claude:{command:`claude`,args:[`-p`,`{prompt}`]},antigravity:{command:`antigravity`,args:[`{prompt}`]}}}));l();export{l as init_runtimeRegistry,r as isPiRuntime,s as resolveRuntimeLaunch,i as resolveRuntimeTable};
|
|
2
|
+
//# sourceMappingURL=runtimeRegistry.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeRegistry.mjs","names":[],"sources":["../../../../src/services/runs/shared/runtimeRegistry.ts"],"sourcesContent":["/**\n * Which agent runtime executes a run, and how to invoke it.\n *\n * WHY THIS IS CONFIG AND NOT A CLASS PER VENDOR:\n * Every external agent CLI is the same shape from here: a binary, an argv with\n * the prompt substituted in, a working directory, and whatever it prints. There\n * is no per-vendor behaviour worth a per-vendor module, and inventing an\n * adapter interface would mean a new file, a new registration and a new test\n * suite every time someone wants to point a run at a different command. Adding\n * or retargeting a CLI is a config edit.\n *\n * WHAT THIS DELIBERATELY DOES NOT DO:\n * It does not parse vendor output. A generic runner cannot know what a given\n * CLI's JSON stream means, and pretending to would either lock the config down\n * to the two CLIs someone happened to test, or silently mis-report a third. The\n * run's final output is its output; status comes from the run lifecycle, which\n * already knows queued/running/terminal without reading a word of it.\n *\n * `pi` IS NOT IN THIS TABLE:\n * It is not an external command - it runs in-process through the SDK\n * (`runs/sdkRunnerEntry.ts`) and gets the team channel, steering and\n * structured output that an external one-shot cannot. Treating it as one more\n * row here would advertise capabilities the external path does not have.\n *\n * AVOID:\n * - Putting a secret in an argv template; argv is visible in the process table\n * - Adding a placeholder without substituting it. An unsubstituted `{prompt}`\n * reaches the CLI literally\n */\n\nimport { PI_RUNTIME_NAME, runtimeBinaryEnvVar } from '../../../adapters/process/env.ts';\n\n/** One external CLI, as configured. */\nexport interface RuntimeDefinition {\n /** Binary to execute. Resolved against PATH unless overridden by env. */\n command: string;\n /** Argv template. `{prompt}`, `{model}` and `{cwd}` are substituted per run. */\n args: string[];\n}\n\nexport type RuntimeTable = Record<string, RuntimeDefinition>;\n\n/**\n * Shipped defaults, overridable per entry by config.\n *\n * Both are headless one-shot invocations: the prompt goes in, the final answer\n * comes out on stdout, and the process exits. Neither is asked for a structured\n * stream, because nothing here would read it.\n */\nexport const DEFAULT_RUNTIMES: RuntimeTable = {\n claude: { command: 'claude', args: ['-p', '{prompt}'] },\n antigravity: { command: 'antigravity', args: ['{prompt}'] },\n};\n\nexport interface ResolvedRuntimeLaunch {\n runtime: string;\n command: string;\n args: string[];\n}\n\nexport interface RuntimeSubstitutions {\n prompt: string;\n model?: string;\n cwd: string;\n}\n\n/** True for the in-process SDK path, which this module does not describe. */\nexport function isPiRuntime(runtime: string | undefined): boolean {\n return (runtime ?? PI_RUNTIME_NAME).trim() === PI_RUNTIME_NAME;\n}\n\nexport function resolveRuntimeTable(configured: RuntimeTable | undefined): RuntimeTable {\n if (!configured) return { ...DEFAULT_RUNTIMES };\n return { ...DEFAULT_RUNTIMES, ...configured };\n}\n\n/**\n * The binary to run, most explicit source first.\n *\n * The env override exists for the same reason `piSpawn.ts` has one: a\n * developer testing against a locally built CLI must be able to point a run at\n * it without editing shared config.\n */\nfunction resolveCommand(runtime: string, definition: RuntimeDefinition, env: NodeJS.ProcessEnv): string {\n const override = env[runtimeBinaryEnvVar(runtime)]?.trim();\n return override || definition.command;\n}\n\nfunction substitute(template: string, values: RuntimeSubstitutions): string {\n return template\n .replaceAll('{prompt}', values.prompt)\n .replaceAll('{model}', values.model ?? '')\n .replaceAll('{cwd}', values.cwd);\n}\n\n/**\n * Resolve one run's command line.\n *\n * An argument that reduces to the empty string is dropped rather than passed:\n * a template carrying `--model {model}` for a run with no model override would\n * otherwise hand the CLI a bare `--model` with nothing after it.\n */\nexport function resolveRuntimeLaunch(\n runtime: string,\n table: RuntimeTable,\n values: RuntimeSubstitutions,\n env: NodeJS.ProcessEnv = process.env,\n): ResolvedRuntimeLaunch {\n const definition = table[runtime];\n if (!definition) {\n const known = Object.keys(table).sort().join(', ') || '(none configured)';\n throw new Error(`Unknown subagent runtime '${runtime}'. Configured runtimes: ${known}.`);\n }\n return {\n runtime,\n command: resolveCommand(runtime, definition, env),\n args: definition.args.map((arg) => substitute(arg, values)).filter((arg) => arg.length > 0),\n };\n}\n"],"mappings":"yJAmEA,SAAgB,EAAY,EAAsC,CAChE,OAAQ,GAAA,MAA4B,MAAM,GAAA,KAG5C,SAAgB,EAAoB,EAAoD,CAEtF,OADK,EACE,CAAE,GAAG,EAAkB,GAAG,EAAY,CADrB,CAAE,GAAG,EAAkB,CAWjD,SAAS,EAAe,EAAiB,EAA+B,EAAgC,CAEtG,OADiB,EAAI,EAAoB,EAAQ,GAAG,MAAM,EACvC,EAAW,QAGhC,SAAS,EAAW,EAAkB,EAAsC,CAC1E,OAAO,EACJ,WAAW,WAAY,EAAO,OAAO,CACrC,WAAW,UAAW,EAAO,OAAS,GAAG,CACzC,WAAW,QAAS,EAAO,IAAI,CAUpC,SAAgB,EACd,EACA,EACA,EACA,EAAyB,QAAQ,IACV,CACvB,IAAM,EAAa,EAAM,GACzB,GAAI,CAAC,EAAY,CACf,IAAM,EAAQ,OAAO,KAAK,EAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAI,oBACtD,MAAU,MAAM,6BAA6B,EAAQ,0BAA0B,EAAM,GAAG,CAE1F,MAAO,CACL,UACA,QAAS,EAAe,EAAS,EAAY,EAAI,CACjD,KAAM,EAAW,KAAK,IAAK,GAAQ,EAAW,EAAK,EAAO,CAAC,CAAC,OAAQ,GAAQ,EAAI,OAAS,EAAE,CAC5F,oBAvFqF,CAmB3E,EAAiC,CAC5C,OAAQ,CAAE,QAAS,SAAU,KAAM,CAAC,KAAM,WAAW,CAAE,CACvD,YAAa,CAAE,QAAS,cAAe,KAAM,CAAC,WAAW,CAAE,CAC5D"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs`),n=require(`../../../adapters/process/env.cjs`);require(`../../../shared/paths.cjs`);let r=require(`node:fs`);r=e.__toESM(r,1);let i=require(`node:path`);i=e.__toESM(i,1);let a=require(`inversify`),o=require(`node:url`),s=require(`node:module`);const c=`value`,l=`#/properties/${c}`,u=[`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`],d=[`additionalItems`,`additionalProperties`,`contains`,`not`,`propertyNames`,`if`,`then`,`else`,`unevaluatedItems`,`unevaluatedProperties`,`contentSchema`],f=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],p=[`$ref`,`$dynamicRef`,`$recursiveRef`];function m(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function h(e,t,n=!0){if(typeof e==`boolean`||!m(e))return e;let r=e,i={...r},a=n&&typeof r.$id!=`string`;if(a)for(let e of p){let n=r[e];n===`#`?i[e]=t:typeof n==`string`&&n.startsWith(`#/`)&&(i[e]=`${t}${n.slice(1)}`)}for(let e of u){let n=r[e];m(n)&&(i[e]=Object.fromEntries(Object.entries(n).map(([e,n])=>[e,h(n,t,a)])))}let o=r.items;Array.isArray(o)?i.items=o.map(e=>h(e,t,a)):o!==void 0&&(i.items=h(o,t,a));for(let e of d)r[e]!==void 0&&(i[e]=h(r[e],t,a));for(let e of f){let n=r[e];Array.isArray(n)&&(i[e]=n.map(e=>h(e,t,a)))}let s=r.dependencies;return m(s)&&(i.dependencies=Object.fromEntries(Object.entries(s).map(([e,n])=>[e,Array.isArray(n)?n:h(n,t,a)]))),i}function g(e){return{type:`object`,properties:{[c]:h(e,l)},required:[c],additionalProperties:!1}}const _=`typebox/compile`,v=`Compile`;function y(e){return e instanceof Error?e.message:String(e)}function b(e){if(!m(e))return;let t=e[v];return typeof t==`function`?t:void 0}async function x(e){return b(await import((0,o.pathToFileURL)((0,s.createRequire)(i.join(e,`package.json`)).resolve(_)).href))}let S=class{cachedCompile;importCompileModule(){return import(_)}importCompileFromPackageRoot(e){return x(e)}async importCompile(){let e=[];try{let t=b(await this.importCompileModule());if(t)return t;e.push(`${_} did not export a ${v} function`)}catch(t){e.push(`direct import failed: ${y(t)}`)}let t=process.env[n.PI_CODING_AGENT_PACKAGE_ROOT_ENV];if(t)try{let n=await this.importCompileFromPackageRoot(t);if(n)return n;e.push(`Pi package root ${_} did not export a ${v} function`)}catch(t){e.push(`Pi package root import failed: ${y(t)}`)}else e.push(`${n.PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);throw Error(`Cannot load ${_} for structured output validation (${e.join(`; `)})`)}loadCompile(){return this.cachedCompile||=this.importCompile().catch(e=>{throw this.cachedCompile=void 0,e}),this.cachedCompile}reset(){this.cachedCompile=void 0}async validateValue(e,t){let n=await this.loadCompile(),r;try{r=n(e)}catch(e){return{status:`invalid`,message:`invalid outputSchema: ${y(e)}`}}return r.Check(t)?{status:`valid`}:{status:`invalid`,message:[...r.Errors(t)].slice(0,8).map(e=>`${e.instancePath?e.instancePath.replace(/^\//,``).replace(/\//g,`.`):`root`}: ${e.message}`).join(`; `)||`schema validation failed`}}async readStructuredOutput(e){if(!r.existsSync(e.outputPath))return{error:`Missing structured_output call; this step has outputSchema and must finish by calling structured_output.`};let t;try{t=JSON.parse(r.readFileSync(e.outputPath,`utf-8`))}catch(e){return{error:`Failed to read structured output: ${y(e)}`}}try{let n=await this.validateValue(e.schema,t);if(n.status===`invalid`)return{error:`Structured output validation failed: ${n.message}`}}catch(e){return{error:`Failed to validate structured output: ${y(e)}`}}return{value:t}}};S=t.__decorate([(0,a.injectable)()],S),Object.defineProperty(exports,`StructuredOutputValidator`,{enumerable:!0,get:function(){return S}}),exports.createStructuredOutputToolParameters=g;
|
|
2
|
+
//# sourceMappingURL=structuredOutput.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structuredOutput.cjs","names":["path","PI_CODING_AGENT_PACKAGE_ROOT_ENV","fs"],"sources":["../../../src/runs/shared/structuredOutput.ts"],"sourcesContent":["/**\n * Structured output: the schema a step must satisfy, and the file it answers in.\n *\n * A step with an `outputSchema` may not finish in prose. The runtime hands the\n * child a `structured_output` tool whose parameters are derived from the schema,\n * writes the schema to a private temp directory, and validates whatever the child\n * wrote back before the run is allowed to succeed.\n *\n * DESIGN PATTERNS:\n * - The author's schema is nested under a `value` property rather than used as\n * the tool parameters directly, because a tool's parameters must be an object\n * and an author is entitled to declare a top-level array or string\n * - Local JSON pointers are rewritten during that nesting. `#/$defs/x` addressed\n * the author's schema root, which is now one level down, so an unrewritten\n * pointer would resolve against the wrapper and silently validate nothing\n * - Every failure is returned as a message, never thrown. An invalid schema is an\n * authoring mistake to report against the run, not a crash of the parent\n *\n * PERFORMANCE:\n * `typebox/compile` is loaded once per process and memoised. It is a heavy\n * import and every validated step would otherwise pay for it. A failed load\n * clears the memo so a transient resolution failure is retried rather than\n * cached forever.\n *\n * AVOID:\n * - Joining `os.tmpdir()` here; the temp root belongs to `shared/paths.ts`\n * - Treating an absent output file as a validation failure. It means the child\n * never called the tool, which is a different diagnosis for the operator\n */\n\nimport * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { injectable } from 'inversify';\n\nimport { PI_CODING_AGENT_PACKAGE_ROOT_ENV } from '../../env.ts';\nimport { TEMP_ROOT_DIR } from '../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../types.ts';\n\nexport { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from '../../env.ts';\n\nexport const MISSING_STRUCTURED_OUTPUT_CALL_ERROR =\n 'Missing structured_output call; this step has outputSchema and must finish by calling structured_output.';\n\n/** Where the schema and the child's answer live for one run. */\nexport interface StructuredOutputRuntime {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n}\n\n// ============================================================================\n// Wrapping an authored schema as tool parameters\n// ============================================================================\n\n/** The property the author's schema is nested under inside the tool parameters. */\nconst STRUCTURED_OUTPUT_VALUE_PROPERTY = 'value';\n/** JSON pointer that addresses the nested schema from the wrapper root. */\nconst STRUCTURED_OUTPUT_VALUE_POINTER = `#/properties/${STRUCTURED_OUTPUT_VALUE_PROPERTY}`;\n\n/** Keywords whose value is a map of names to subschemas. */\nconst SCHEMA_MAP_KEYWORDS = ['properties', 'patternProperties', '$defs', 'definitions', 'dependentSchemas'] as const;\n/** Keywords whose value is a single subschema. */\nconst SCHEMA_SINGLE_KEYWORDS = [\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'not',\n 'propertyNames',\n 'if',\n 'then',\n 'else',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n 'contentSchema',\n] as const;\n/** Keywords whose value is an array of subschemas. */\nconst SCHEMA_ARRAY_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\n\n/** Reference keywords that can carry a local pointer needing a rebase. */\nconst SCHEMA_REF_KEYWORDS = ['$ref', '$dynamicRef', '$recursiveRef'] as const;\n\n/** A pointer to the schema resource root, which moves when the schema is nested. */\nconst ROOT_POINTER = '#';\nconst LOCAL_POINTER_PREFIX = '#/';\n\nfunction isSchemaRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Rebase local JSON pointers so they still address the author's schema once it\n * has been nested under the wrapper.\n *\n * `$id` stops the descent: a subschema declaring one starts a new resource, so\n * its local pointers address itself and were never relative to the wrapper.\n * Boolean schemas (`true`/`false`) are legal JSON Schema and pass through.\n */\nfunction rewriteLocalJsonPointerRefs(schema: unknown, pointerPrefix: string, inheritsWrapperResource = true): unknown {\n if (typeof schema === 'boolean' || !isSchemaRecord(schema)) return schema;\n const source = schema;\n const rewritten: Record<string, unknown> = { ...source };\n const sharesWrapperResource = inheritsWrapperResource && typeof source.$id !== 'string';\n if (sharesWrapperResource) {\n for (const keyword of SCHEMA_REF_KEYWORDS) {\n const ref = source[keyword];\n if (ref === ROOT_POINTER) rewritten[keyword] = pointerPrefix;\n else if (typeof ref === 'string' && ref.startsWith(LOCAL_POINTER_PREFIX)) {\n rewritten[keyword] = `${pointerPrefix}${ref.slice(ROOT_POINTER.length)}`;\n }\n }\n }\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const entries = source[keyword];\n if (!isSchemaRecord(entries)) continue;\n rewritten[keyword] = Object.fromEntries(\n Object.entries(entries).map(([name, nested]) => [\n name,\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n const items = source.items;\n if (Array.isArray(items)) {\n rewritten.items = items.map((nested) => rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource));\n } else if (items !== undefined) {\n rewritten.items = rewriteLocalJsonPointerRefs(items, pointerPrefix, sharesWrapperResource);\n }\n for (const keyword of SCHEMA_SINGLE_KEYWORDS) {\n if (source[keyword] !== undefined) {\n rewritten[keyword] = rewriteLocalJsonPointerRefs(source[keyword], pointerPrefix, sharesWrapperResource);\n }\n }\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const branches = source[keyword];\n if (Array.isArray(branches)) {\n rewritten[keyword] = branches.map((nested) =>\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n );\n }\n }\n const dependencies = source.dependencies;\n if (isSchemaRecord(dependencies)) {\n // Draft-07 `dependencies` is either a property-name list or a subschema.\n rewritten.dependencies = Object.fromEntries(\n Object.entries(dependencies).map(([name, nested]) => [\n name,\n Array.isArray(nested) ? nested : rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n return rewritten;\n}\n\n/** Parameters for the `structured_output` tool that satisfies `schema`. */\nexport function createStructuredOutputToolParameters(schema: JsonSchemaObject): JsonSchemaObject {\n return {\n type: 'object',\n properties: {\n [STRUCTURED_OUTPUT_VALUE_PROPERTY]: rewriteLocalJsonPointerRefs(schema, STRUCTURED_OUTPUT_VALUE_POINTER),\n },\n required: [STRUCTURED_OUTPUT_VALUE_PROPERTY],\n additionalProperties: false,\n };\n}\n\n// ============================================================================\n// Runtime files\n// ============================================================================\n\nconst STRUCTURED_OUTPUT_DIR_PREFIX = 'doom-team-structured-';\nconst SCHEMA_FILE_NAME = 'schema.json';\nconst OUTPUT_FILE_NAME = 'output.json';\n/** The schema can carry task detail, so it is readable only by its own user. */\nconst PRIVATE_FILE_MODE = 0o600;\n\nexport function assertJsonSchemaObject(schema: unknown, label = 'outputSchema'): asserts schema is JsonSchemaObject {\n if (!isSchemaRecord(schema)) {\n throw new Error(`${label} must be a JSON Schema object.`);\n }\n}\n\n/** Stage the schema on disk and reserve the path the child answers in. */\nexport function createStructuredOutputRuntime(schema: JsonSchemaObject, baseDir?: string): StructuredOutputRuntime {\n assertJsonSchemaObject(schema);\n const rootDir = baseDir ?? TEMP_ROOT_DIR;\n fs.mkdirSync(rootDir, { recursive: true });\n const dir = fs.mkdtempSync(path.join(rootDir, STRUCTURED_OUTPUT_DIR_PREFIX));\n const schemaPath = path.join(dir, SCHEMA_FILE_NAME);\n const outputPath = path.join(dir, OUTPUT_FILE_NAME);\n fs.writeFileSync(schemaPath, JSON.stringify(schema), { mode: PRIVATE_FILE_MODE });\n return { schema, schemaPath, outputPath };\n}\n\n/**\n * Remove the run's schema and output directory.\n *\n * The failure is returned rather than thrown or logged: the directory is under\n * the per-user temp root, so a leftover is harmless and must not fail a run that\n * has already produced its result. Returning it still lets a caller that cares,\n * such as a teardown check, see what happened instead of it vanishing.\n */\nexport function cleanupStructuredOutputRuntime(runtime: StructuredOutputRuntime | undefined): {\n removed: boolean;\n error?: string;\n} {\n if (!runtime) return { removed: false };\n try {\n fs.rmSync(path.dirname(runtime.schemaPath), { recursive: true, force: true });\n return { removed: true };\n } catch (error) {\n return { removed: false, error: toMessage(error) };\n }\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/** The compiled-validator surface this module uses out of `typebox/compile`. */\ninterface CompiledJsonSchema {\n Check(value: unknown): boolean;\n Errors(value: unknown): Iterable<{ instancePath?: string; message?: string }>;\n}\n\ntype CompileJsonSchema = (schema: unknown) => CompiledJsonSchema;\n\nconst TYPEBOX_COMPILE_SPECIFIER = 'typebox/compile';\nconst COMPILE_EXPORT_NAME = 'Compile';\n/** How many schema violations are reported before the message is truncated. */\nconst MAX_REPORTED_SCHEMA_ERRORS = 8;\n/** Path shown for a violation at the document root. */\nconst ROOT_INSTANCE_PATH_LABEL = 'root';\n\nexport type StructuredOutputValidation = { status: 'valid' } | { status: 'invalid'; message: string };\n\nfunction toMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readCompileExport(mod: unknown): CompileJsonSchema | undefined {\n if (!isSchemaRecord(mod)) return undefined;\n const compile = mod[COMPILE_EXPORT_NAME];\n return typeof compile === 'function' ? (compile as CompileJsonSchema) : undefined;\n}\n\n/**\n * Load `typebox/compile` out of the host Pi installation.\n *\n * Exported because the host package root is the only place the dependency is\n * guaranteed to resolve when this extension is loaded from outside the host's\n * own `node_modules` tree.\n */\nexport async function resolveCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n const requireFromRoot = createRequire(path.join(packageRoot, 'package.json'));\n const resolved = requireFromRoot.resolve(TYPEBOX_COMPILE_SPECIFIER);\n const mod: unknown = await import(pathToFileURL(resolved).href);\n return readCompileExport(mod);\n}\n\n/**\n * Validates structured output against an authored JSON Schema.\n *\n * WHY THIS IS A SERVICE AND NOT A FUNCTION:\n * The compiler import is memoised for the life of the process, and that memo is\n * mutable state that needs an owner. As a module-level variable it also could\n * not be reset between tests, which made a single failed-load test poison every\n * later one.\n */\n@injectable()\nexport class StructuredOutputValidator {\n private cachedCompile: Promise<CompileJsonSchema> | undefined;\n\n /** Import seam: ESM namespaces are frozen, so a test cannot spy on the import. */\n protected importCompileModule(): Promise<unknown> {\n return import(TYPEBOX_COMPILE_SPECIFIER);\n }\n\n /** Import seam for the host-package-root fallback. */\n protected importCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n return resolveCompileFromPackageRoot(packageRoot);\n }\n\n /**\n * Resolve the compiler, reporting every attempt that failed.\n *\n * Both routes are named in the error because which one failed is what tells\n * an operator whether the extension is mis-installed or the host env is unset.\n */\n private async importCompile(): Promise<CompileJsonSchema> {\n const failures: string[] = [];\n try {\n const compile = readCompileExport(await this.importCompileModule());\n if (compile) return compile;\n failures.push(`${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`direct import failed: ${toMessage(error)}`);\n }\n const packageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV];\n if (packageRoot) {\n try {\n const compile = await this.importCompileFromPackageRoot(packageRoot);\n if (compile) return compile;\n failures.push(`Pi package root ${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`Pi package root import failed: ${toMessage(error)}`);\n }\n } else {\n failures.push(`${PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);\n }\n throw new Error(\n `Cannot load ${TYPEBOX_COMPILE_SPECIFIER} for structured output validation (${failures.join('; ')})`,\n );\n }\n\n /** Memoised compiler. A rejected load drops the memo so it can be retried. */\n private loadCompile(): Promise<CompileJsonSchema> {\n if (!this.cachedCompile) {\n this.cachedCompile = this.importCompile().catch((error: unknown) => {\n this.cachedCompile = undefined;\n throw error;\n });\n }\n return this.cachedCompile;\n }\n\n /** Drop the memoised compiler. Intended for tests and teardown. */\n reset(): void {\n this.cachedCompile = undefined;\n }\n\n async validateValue(schema: JsonSchemaObject, value: unknown): Promise<StructuredOutputValidation> {\n const compile = await this.loadCompile();\n let validator: CompiledJsonSchema;\n try {\n validator = compile(schema);\n } catch (error) {\n // A schema that will not compile is the author's mistake, not a runtime\n // fault, so it is reported against the run like any other invalid output.\n return { status: 'invalid', message: `invalid outputSchema: ${toMessage(error)}` };\n }\n if (validator.Check(value)) return { status: 'valid' };\n const errors = [...validator.Errors(value)].slice(0, MAX_REPORTED_SCHEMA_ERRORS).map((error) => {\n const pathText = error.instancePath\n ? error.instancePath.replace(/^\\//, '').replace(/\\//g, '.')\n : ROOT_INSTANCE_PATH_LABEL;\n return `${pathText}: ${error.message}`;\n });\n return { status: 'invalid', message: errors.join('; ') || 'schema validation failed' };\n }\n\n /**\n * Read and validate what the child wrote.\n *\n * An absent file is reported as a missing tool call rather than as invalid\n * output: the child never answered at all, which is a different fix.\n */\n async readStructuredOutput(runtime: StructuredOutputRuntime): Promise<{ value?: unknown; error?: string }> {\n if (!fs.existsSync(runtime.outputPath)) {\n return { error: MISSING_STRUCTURED_OUTPUT_CALL_ERROR };\n }\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(runtime.outputPath, 'utf-8')) as unknown;\n } catch (error) {\n return { error: `Failed to read structured output: ${toMessage(error)}` };\n }\n try {\n const validation = await this.validateValue(runtime.schema, value);\n if (validation.status === 'invalid') {\n return { error: `Structured output validation failed: ${validation.message}` };\n }\n } catch (error) {\n // The compiler itself failed to load. That is an environment problem, and\n // reporting it against the run beats crashing the parent mid-orchestration.\n return { error: `Failed to validate structured output: ${toMessage(error)}` };\n }\n return { value };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"structuredOutput.cjs","names":["path","PI_CODING_AGENT_PACKAGE_ROOT_ENV","fs"],"sources":["../../../../src/services/runs/shared/structuredOutput.ts"],"sourcesContent":["/**\n * Structured output: the schema a step must satisfy, and the file it answers in.\n *\n * A step with an `outputSchema` may not finish in prose. The runtime hands the\n * child a `structured_output` tool whose parameters are derived from the schema,\n * writes the schema to a private temp directory, and validates whatever the child\n * wrote back before the run is allowed to succeed.\n *\n * DESIGN PATTERNS:\n * - The author's schema is nested under a `value` property rather than used as\n * the tool parameters directly, because a tool's parameters must be an object\n * and an author is entitled to declare a top-level array or string\n * - Local JSON pointers are rewritten during that nesting. `#/$defs/x` addressed\n * the author's schema root, which is now one level down, so an unrewritten\n * pointer would resolve against the wrapper and silently validate nothing\n * - Every failure is returned as a message, never thrown. An invalid schema is an\n * authoring mistake to report against the run, not a crash of the parent\n *\n * PERFORMANCE:\n * `typebox/compile` is loaded once per process and memoised. It is a heavy\n * import and every validated step would otherwise pay for it. A failed load\n * clears the memo so a transient resolution failure is retried rather than\n * cached forever.\n *\n * AVOID:\n * - Joining `os.tmpdir()` here; the temp root belongs to `shared/paths.ts`\n * - Treating an absent output file as a validation failure. It means the child\n * never called the tool, which is a different diagnosis for the operator\n */\n\nimport * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { injectable } from 'inversify';\n\nimport { PI_CODING_AGENT_PACKAGE_ROOT_ENV } from '../../../adapters/process/env.ts';\nimport { TEMP_ROOT_DIR } from '../../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../../types/index.ts';\n\nexport { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from '../../../adapters/process/env.ts';\n\nexport const MISSING_STRUCTURED_OUTPUT_CALL_ERROR =\n 'Missing structured_output call; this step has outputSchema and must finish by calling structured_output.';\n\n/** Where the schema and the child's answer live for one run. */\nexport interface StructuredOutputRuntime {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n}\n\n// ============================================================================\n// Wrapping an authored schema as tool parameters\n// ============================================================================\n\n/** The property the author's schema is nested under inside the tool parameters. */\nconst STRUCTURED_OUTPUT_VALUE_PROPERTY = 'value';\n/** JSON pointer that addresses the nested schema from the wrapper root. */\nconst STRUCTURED_OUTPUT_VALUE_POINTER = `#/properties/${STRUCTURED_OUTPUT_VALUE_PROPERTY}`;\n\n/** Keywords whose value is a map of names to subschemas. */\nconst SCHEMA_MAP_KEYWORDS = ['properties', 'patternProperties', '$defs', 'definitions', 'dependentSchemas'] as const;\n/** Keywords whose value is a single subschema. */\nconst SCHEMA_SINGLE_KEYWORDS = [\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'not',\n 'propertyNames',\n 'if',\n 'then',\n 'else',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n 'contentSchema',\n] as const;\n/** Keywords whose value is an array of subschemas. */\nconst SCHEMA_ARRAY_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\n\n/** Reference keywords that can carry a local pointer needing a rebase. */\nconst SCHEMA_REF_KEYWORDS = ['$ref', '$dynamicRef', '$recursiveRef'] as const;\n\n/** A pointer to the schema resource root, which moves when the schema is nested. */\nconst ROOT_POINTER = '#';\nconst LOCAL_POINTER_PREFIX = '#/';\n\nfunction isSchemaRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Rebase local JSON pointers so they still address the author's schema once it\n * has been nested under the wrapper.\n *\n * `$id` stops the descent: a subschema declaring one starts a new resource, so\n * its local pointers address itself and were never relative to the wrapper.\n * Boolean schemas (`true`/`false`) are legal JSON Schema and pass through.\n */\nfunction rewriteLocalJsonPointerRefs(schema: unknown, pointerPrefix: string, inheritsWrapperResource = true): unknown {\n if (typeof schema === 'boolean' || !isSchemaRecord(schema)) return schema;\n const source = schema;\n const rewritten: Record<string, unknown> = { ...source };\n const sharesWrapperResource = inheritsWrapperResource && typeof source.$id !== 'string';\n if (sharesWrapperResource) {\n for (const keyword of SCHEMA_REF_KEYWORDS) {\n const ref = source[keyword];\n if (ref === ROOT_POINTER) rewritten[keyword] = pointerPrefix;\n else if (typeof ref === 'string' && ref.startsWith(LOCAL_POINTER_PREFIX)) {\n rewritten[keyword] = `${pointerPrefix}${ref.slice(ROOT_POINTER.length)}`;\n }\n }\n }\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const entries = source[keyword];\n if (!isSchemaRecord(entries)) continue;\n rewritten[keyword] = Object.fromEntries(\n Object.entries(entries).map(([name, nested]) => [\n name,\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n const items = source.items;\n if (Array.isArray(items)) {\n rewritten.items = items.map((nested) => rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource));\n } else if (items !== undefined) {\n rewritten.items = rewriteLocalJsonPointerRefs(items, pointerPrefix, sharesWrapperResource);\n }\n for (const keyword of SCHEMA_SINGLE_KEYWORDS) {\n if (source[keyword] !== undefined) {\n rewritten[keyword] = rewriteLocalJsonPointerRefs(source[keyword], pointerPrefix, sharesWrapperResource);\n }\n }\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const branches = source[keyword];\n if (Array.isArray(branches)) {\n rewritten[keyword] = branches.map((nested) =>\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n );\n }\n }\n const dependencies = source.dependencies;\n if (isSchemaRecord(dependencies)) {\n // Draft-07 `dependencies` is either a property-name list or a subschema.\n rewritten.dependencies = Object.fromEntries(\n Object.entries(dependencies).map(([name, nested]) => [\n name,\n Array.isArray(nested) ? nested : rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n return rewritten;\n}\n\n/** Parameters for the `structured_output` tool that satisfies `schema`. */\nexport function createStructuredOutputToolParameters(schema: JsonSchemaObject): JsonSchemaObject {\n return {\n type: 'object',\n properties: {\n [STRUCTURED_OUTPUT_VALUE_PROPERTY]: rewriteLocalJsonPointerRefs(schema, STRUCTURED_OUTPUT_VALUE_POINTER),\n },\n required: [STRUCTURED_OUTPUT_VALUE_PROPERTY],\n additionalProperties: false,\n };\n}\n\n// ============================================================================\n// Runtime files\n// ============================================================================\n\nconst STRUCTURED_OUTPUT_DIR_PREFIX = 'doom-team-structured-';\nconst SCHEMA_FILE_NAME = 'schema.json';\nconst OUTPUT_FILE_NAME = 'output.json';\n/** The schema can carry task detail, so it is readable only by its own user. */\nconst PRIVATE_FILE_MODE = 0o600;\n\nexport function assertJsonSchemaObject(schema: unknown, label = 'outputSchema'): asserts schema is JsonSchemaObject {\n if (!isSchemaRecord(schema)) {\n throw new Error(`${label} must be a JSON Schema object.`);\n }\n}\n\n/** Stage the schema on disk and reserve the path the child answers in. */\nexport function createStructuredOutputRuntime(schema: JsonSchemaObject, baseDir?: string): StructuredOutputRuntime {\n assertJsonSchemaObject(schema);\n const rootDir = baseDir ?? TEMP_ROOT_DIR;\n fs.mkdirSync(rootDir, { recursive: true });\n const dir = fs.mkdtempSync(path.join(rootDir, STRUCTURED_OUTPUT_DIR_PREFIX));\n const schemaPath = path.join(dir, SCHEMA_FILE_NAME);\n const outputPath = path.join(dir, OUTPUT_FILE_NAME);\n fs.writeFileSync(schemaPath, JSON.stringify(schema), { mode: PRIVATE_FILE_MODE });\n return { schema, schemaPath, outputPath };\n}\n\n/**\n * Remove the run's schema and output directory.\n *\n * The failure is returned rather than thrown or logged: the directory is under\n * the per-user temp root, so a leftover is harmless and must not fail a run that\n * has already produced its result. Returning it still lets a caller that cares,\n * such as a teardown check, see what happened instead of it vanishing.\n */\nexport function cleanupStructuredOutputRuntime(runtime: StructuredOutputRuntime | undefined): {\n removed: boolean;\n error?: string;\n} {\n if (!runtime) return { removed: false };\n try {\n fs.rmSync(path.dirname(runtime.schemaPath), { recursive: true, force: true });\n return { removed: true };\n } catch (error) {\n return { removed: false, error: toMessage(error) };\n }\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/** The compiled-validator surface this module uses out of `typebox/compile`. */\ninterface CompiledJsonSchema {\n Check(value: unknown): boolean;\n Errors(value: unknown): Iterable<{ instancePath?: string; message?: string }>;\n}\n\ntype CompileJsonSchema = (schema: unknown) => CompiledJsonSchema;\n\nconst TYPEBOX_COMPILE_SPECIFIER = 'typebox/compile';\nconst COMPILE_EXPORT_NAME = 'Compile';\n/** How many schema violations are reported before the message is truncated. */\nconst MAX_REPORTED_SCHEMA_ERRORS = 8;\n/** Path shown for a violation at the document root. */\nconst ROOT_INSTANCE_PATH_LABEL = 'root';\n\nexport type StructuredOutputValidation = { status: 'valid' } | { status: 'invalid'; message: string };\n\nfunction toMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readCompileExport(mod: unknown): CompileJsonSchema | undefined {\n if (!isSchemaRecord(mod)) return undefined;\n const compile = mod[COMPILE_EXPORT_NAME];\n return typeof compile === 'function' ? (compile as CompileJsonSchema) : undefined;\n}\n\n/**\n * Load `typebox/compile` out of the host Pi installation.\n *\n * Exported because the host package root is the only place the dependency is\n * guaranteed to resolve when this extension is loaded from outside the host's\n * own `node_modules` tree.\n */\nexport async function resolveCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n const requireFromRoot = createRequire(path.join(packageRoot, 'package.json'));\n const resolved = requireFromRoot.resolve(TYPEBOX_COMPILE_SPECIFIER);\n const mod: unknown = await import(pathToFileURL(resolved).href);\n return readCompileExport(mod);\n}\n\n/**\n * Validates structured output against an authored JSON Schema.\n *\n * WHY THIS IS A SERVICE AND NOT A FUNCTION:\n * The compiler import is memoised for the life of the process, and that memo is\n * mutable state that needs an owner. As a module-level variable it also could\n * not be reset between tests, which made a single failed-load test poison every\n * later one.\n */\n@injectable()\nexport class StructuredOutputValidator {\n private cachedCompile: Promise<CompileJsonSchema> | undefined;\n\n /** Import seam: ESM namespaces are frozen, so a test cannot spy on the import. */\n protected importCompileModule(): Promise<unknown> {\n return import(TYPEBOX_COMPILE_SPECIFIER);\n }\n\n /** Import seam for the host-package-root fallback. */\n protected importCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n return resolveCompileFromPackageRoot(packageRoot);\n }\n\n /**\n * Resolve the compiler, reporting every attempt that failed.\n *\n * Both routes are named in the error because which one failed is what tells\n * an operator whether the extension is mis-installed or the host env is unset.\n */\n private async importCompile(): Promise<CompileJsonSchema> {\n const failures: string[] = [];\n try {\n const compile = readCompileExport(await this.importCompileModule());\n if (compile) return compile;\n failures.push(`${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`direct import failed: ${toMessage(error)}`);\n }\n const packageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV];\n if (packageRoot) {\n try {\n const compile = await this.importCompileFromPackageRoot(packageRoot);\n if (compile) return compile;\n failures.push(`Pi package root ${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`Pi package root import failed: ${toMessage(error)}`);\n }\n } else {\n failures.push(`${PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);\n }\n throw new Error(\n `Cannot load ${TYPEBOX_COMPILE_SPECIFIER} for structured output validation (${failures.join('; ')})`,\n );\n }\n\n /** Memoised compiler. A rejected load drops the memo so it can be retried. */\n private loadCompile(): Promise<CompileJsonSchema> {\n if (!this.cachedCompile) {\n this.cachedCompile = this.importCompile().catch((error: unknown) => {\n this.cachedCompile = undefined;\n throw error;\n });\n }\n return this.cachedCompile;\n }\n\n /** Drop the memoised compiler. Intended for tests and teardown. */\n reset(): void {\n this.cachedCompile = undefined;\n }\n\n async validateValue(schema: JsonSchemaObject, value: unknown): Promise<StructuredOutputValidation> {\n const compile = await this.loadCompile();\n let validator: CompiledJsonSchema;\n try {\n validator = compile(schema);\n } catch (error) {\n // A schema that will not compile is the author's mistake, not a runtime\n // fault, so it is reported against the run like any other invalid output.\n return { status: 'invalid', message: `invalid outputSchema: ${toMessage(error)}` };\n }\n if (validator.Check(value)) return { status: 'valid' };\n const errors = [...validator.Errors(value)].slice(0, MAX_REPORTED_SCHEMA_ERRORS).map((error) => {\n const pathText = error.instancePath\n ? error.instancePath.replace(/^\\//, '').replace(/\\//g, '.')\n : ROOT_INSTANCE_PATH_LABEL;\n return `${pathText}: ${error.message}`;\n });\n return { status: 'invalid', message: errors.join('; ') || 'schema validation failed' };\n }\n\n /**\n * Read and validate what the child wrote.\n *\n * An absent file is reported as a missing tool call rather than as invalid\n * output: the child never answered at all, which is a different fix.\n */\n async readStructuredOutput(runtime: StructuredOutputRuntime): Promise<{ value?: unknown; error?: string }> {\n if (!fs.existsSync(runtime.outputPath)) {\n return { error: MISSING_STRUCTURED_OUTPUT_CALL_ERROR };\n }\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(runtime.outputPath, 'utf-8')) as unknown;\n } catch (error) {\n return { error: `Failed to read structured output: ${toMessage(error)}` };\n }\n try {\n const validation = await this.validateValue(runtime.schema, value);\n if (validation.status === 'invalid') {\n return { error: `Structured output validation failed: ${validation.message}` };\n }\n } catch (error) {\n // The compiler itself failed to load. That is an environment problem, and\n // reporting it against the run beats crashing the parent mid-orchestration.\n return { error: `Failed to validate structured output: ${toMessage(error)}` };\n }\n return { value };\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../../../_virtual/_rolldown/runtime.mjs";import{__decorate as t,init_decorate as n}from"../../../_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs";import{PI_CODING_AGENT_PACKAGE_ROOT_ENV as r,init_env as i}from"../../../adapters/process/env.mjs";import{init_paths as a}from"../../../shared/paths.mjs";import{createRequire as o}from"node:module";import*as s from"node:fs";import*as c from"node:path";import{injectable as l}from"inversify";import{pathToFileURL as u}from"node:url";function d(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function f(e,t,n=!0){if(typeof e==`boolean`||!d(e))return e;let r=e,i={...r},a=n&&typeof r.$id!=`string`;if(a)for(let e of C){let n=r[e];n===w?i[e]=t:typeof n==`string`&&n.startsWith(T)&&(i[e]=`${t}${n.slice(1)}`)}for(let e of b){let n=r[e];d(n)&&(i[e]=Object.fromEntries(Object.entries(n).map(([e,n])=>[e,f(n,t,a)])))}let o=r.items;Array.isArray(o)?i.items=o.map(e=>f(e,t,a)):o!==void 0&&(i.items=f(o,t,a));for(let e of x)r[e]!==void 0&&(i[e]=f(r[e],t,a));for(let e of S){let n=r[e];Array.isArray(n)&&(i[e]=n.map(e=>f(e,t,a)))}let s=r.dependencies;return d(s)&&(i.dependencies=Object.fromEntries(Object.entries(s).map(([e,n])=>[e,Array.isArray(n)?n:f(n,t,a)]))),i}function p(e){return{type:`object`,properties:{[v]:f(e,y)},required:[v],additionalProperties:!1}}function m(e){return e instanceof Error?e.message:String(e)}function h(e){if(!d(e))return;let t=e[D];return typeof t==`function`?t:void 0}async function g(e){return h(await import(u(o(c.join(e,`package.json`)).resolve(E)).href))}var _,v,y,b,x,S,C,w,T,E,D,O,k,A,j=e((()=>{i(),a(),n(),_=`Missing structured_output call; this step has outputSchema and must finish by calling structured_output.`,v=`value`,y=`#/properties/${v}`,b=[`properties`,`patternProperties`,`$defs`,`definitions`,`dependentSchemas`],x=[`additionalItems`,`additionalProperties`,`contains`,`not`,`propertyNames`,`if`,`then`,`else`,`unevaluatedItems`,`unevaluatedProperties`,`contentSchema`],S=[`allOf`,`anyOf`,`oneOf`,`prefixItems`],C=[`$ref`,`$dynamicRef`,`$recursiveRef`],w=`#`,T=`#/`,E=`typebox/compile`,D=`Compile`,O=8,k=`root`,A=class{cachedCompile;importCompileModule(){return import(E)}importCompileFromPackageRoot(e){return g(e)}async importCompile(){let e=[];try{let t=h(await this.importCompileModule());if(t)return t;e.push(`${E} did not export a ${D} function`)}catch(t){e.push(`direct import failed: ${m(t)}`)}let t=process.env[r];if(t)try{let n=await this.importCompileFromPackageRoot(t);if(n)return n;e.push(`Pi package root ${E} did not export a ${D} function`)}catch(t){e.push(`Pi package root import failed: ${m(t)}`)}else e.push(`${r} is not set`);throw Error(`Cannot load ${E} for structured output validation (${e.join(`; `)})`)}loadCompile(){return this.cachedCompile||=this.importCompile().catch(e=>{throw this.cachedCompile=void 0,e}),this.cachedCompile}reset(){this.cachedCompile=void 0}async validateValue(e,t){let n=await this.loadCompile(),r;try{r=n(e)}catch(e){return{status:`invalid`,message:`invalid outputSchema: ${m(e)}`}}return r.Check(t)?{status:`valid`}:{status:`invalid`,message:[...r.Errors(t)].slice(0,O).map(e=>`${e.instancePath?e.instancePath.replace(/^\//,``).replace(/\//g,`.`):k}: ${e.message}`).join(`; `)||`schema validation failed`}}async readStructuredOutput(e){if(!s.existsSync(e.outputPath))return{error:_};let t;try{t=JSON.parse(s.readFileSync(e.outputPath,`utf-8`))}catch(e){return{error:`Failed to read structured output: ${m(e)}`}}try{let n=await this.validateValue(e.schema,t);if(n.status===`invalid`)return{error:`Structured output validation failed: ${n.message}`}}catch(e){return{error:`Failed to validate structured output: ${m(e)}`}}return{value:t}}},A=t([l()],A)}));j();export{A as StructuredOutputValidator,p as createStructuredOutputToolParameters,j as init_structuredOutput};
|
|
2
|
+
//# sourceMappingURL=structuredOutput.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structuredOutput.mjs","names":[],"sources":["../../../src/runs/shared/structuredOutput.ts"],"sourcesContent":["/**\n * Structured output: the schema a step must satisfy, and the file it answers in.\n *\n * A step with an `outputSchema` may not finish in prose. The runtime hands the\n * child a `structured_output` tool whose parameters are derived from the schema,\n * writes the schema to a private temp directory, and validates whatever the child\n * wrote back before the run is allowed to succeed.\n *\n * DESIGN PATTERNS:\n * - The author's schema is nested under a `value` property rather than used as\n * the tool parameters directly, because a tool's parameters must be an object\n * and an author is entitled to declare a top-level array or string\n * - Local JSON pointers are rewritten during that nesting. `#/$defs/x` addressed\n * the author's schema root, which is now one level down, so an unrewritten\n * pointer would resolve against the wrapper and silently validate nothing\n * - Every failure is returned as a message, never thrown. An invalid schema is an\n * authoring mistake to report against the run, not a crash of the parent\n *\n * PERFORMANCE:\n * `typebox/compile` is loaded once per process and memoised. It is a heavy\n * import and every validated step would otherwise pay for it. A failed load\n * clears the memo so a transient resolution failure is retried rather than\n * cached forever.\n *\n * AVOID:\n * - Joining `os.tmpdir()` here; the temp root belongs to `shared/paths.ts`\n * - Treating an absent output file as a validation failure. It means the child\n * never called the tool, which is a different diagnosis for the operator\n */\n\nimport * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { injectable } from 'inversify';\n\nimport { PI_CODING_AGENT_PACKAGE_ROOT_ENV } from '../../env.ts';\nimport { TEMP_ROOT_DIR } from '../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../types.ts';\n\nexport { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from '../../env.ts';\n\nexport const MISSING_STRUCTURED_OUTPUT_CALL_ERROR =\n 'Missing structured_output call; this step has outputSchema and must finish by calling structured_output.';\n\n/** Where the schema and the child's answer live for one run. */\nexport interface StructuredOutputRuntime {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n}\n\n// ============================================================================\n// Wrapping an authored schema as tool parameters\n// ============================================================================\n\n/** The property the author's schema is nested under inside the tool parameters. */\nconst STRUCTURED_OUTPUT_VALUE_PROPERTY = 'value';\n/** JSON pointer that addresses the nested schema from the wrapper root. */\nconst STRUCTURED_OUTPUT_VALUE_POINTER = `#/properties/${STRUCTURED_OUTPUT_VALUE_PROPERTY}`;\n\n/** Keywords whose value is a map of names to subschemas. */\nconst SCHEMA_MAP_KEYWORDS = ['properties', 'patternProperties', '$defs', 'definitions', 'dependentSchemas'] as const;\n/** Keywords whose value is a single subschema. */\nconst SCHEMA_SINGLE_KEYWORDS = [\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'not',\n 'propertyNames',\n 'if',\n 'then',\n 'else',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n 'contentSchema',\n] as const;\n/** Keywords whose value is an array of subschemas. */\nconst SCHEMA_ARRAY_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\n\n/** Reference keywords that can carry a local pointer needing a rebase. */\nconst SCHEMA_REF_KEYWORDS = ['$ref', '$dynamicRef', '$recursiveRef'] as const;\n\n/** A pointer to the schema resource root, which moves when the schema is nested. */\nconst ROOT_POINTER = '#';\nconst LOCAL_POINTER_PREFIX = '#/';\n\nfunction isSchemaRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Rebase local JSON pointers so they still address the author's schema once it\n * has been nested under the wrapper.\n *\n * `$id` stops the descent: a subschema declaring one starts a new resource, so\n * its local pointers address itself and were never relative to the wrapper.\n * Boolean schemas (`true`/`false`) are legal JSON Schema and pass through.\n */\nfunction rewriteLocalJsonPointerRefs(schema: unknown, pointerPrefix: string, inheritsWrapperResource = true): unknown {\n if (typeof schema === 'boolean' || !isSchemaRecord(schema)) return schema;\n const source = schema;\n const rewritten: Record<string, unknown> = { ...source };\n const sharesWrapperResource = inheritsWrapperResource && typeof source.$id !== 'string';\n if (sharesWrapperResource) {\n for (const keyword of SCHEMA_REF_KEYWORDS) {\n const ref = source[keyword];\n if (ref === ROOT_POINTER) rewritten[keyword] = pointerPrefix;\n else if (typeof ref === 'string' && ref.startsWith(LOCAL_POINTER_PREFIX)) {\n rewritten[keyword] = `${pointerPrefix}${ref.slice(ROOT_POINTER.length)}`;\n }\n }\n }\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const entries = source[keyword];\n if (!isSchemaRecord(entries)) continue;\n rewritten[keyword] = Object.fromEntries(\n Object.entries(entries).map(([name, nested]) => [\n name,\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n const items = source.items;\n if (Array.isArray(items)) {\n rewritten.items = items.map((nested) => rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource));\n } else if (items !== undefined) {\n rewritten.items = rewriteLocalJsonPointerRefs(items, pointerPrefix, sharesWrapperResource);\n }\n for (const keyword of SCHEMA_SINGLE_KEYWORDS) {\n if (source[keyword] !== undefined) {\n rewritten[keyword] = rewriteLocalJsonPointerRefs(source[keyword], pointerPrefix, sharesWrapperResource);\n }\n }\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const branches = source[keyword];\n if (Array.isArray(branches)) {\n rewritten[keyword] = branches.map((nested) =>\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n );\n }\n }\n const dependencies = source.dependencies;\n if (isSchemaRecord(dependencies)) {\n // Draft-07 `dependencies` is either a property-name list or a subschema.\n rewritten.dependencies = Object.fromEntries(\n Object.entries(dependencies).map(([name, nested]) => [\n name,\n Array.isArray(nested) ? nested : rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n return rewritten;\n}\n\n/** Parameters for the `structured_output` tool that satisfies `schema`. */\nexport function createStructuredOutputToolParameters(schema: JsonSchemaObject): JsonSchemaObject {\n return {\n type: 'object',\n properties: {\n [STRUCTURED_OUTPUT_VALUE_PROPERTY]: rewriteLocalJsonPointerRefs(schema, STRUCTURED_OUTPUT_VALUE_POINTER),\n },\n required: [STRUCTURED_OUTPUT_VALUE_PROPERTY],\n additionalProperties: false,\n };\n}\n\n// ============================================================================\n// Runtime files\n// ============================================================================\n\nconst STRUCTURED_OUTPUT_DIR_PREFIX = 'doom-team-structured-';\nconst SCHEMA_FILE_NAME = 'schema.json';\nconst OUTPUT_FILE_NAME = 'output.json';\n/** The schema can carry task detail, so it is readable only by its own user. */\nconst PRIVATE_FILE_MODE = 0o600;\n\nexport function assertJsonSchemaObject(schema: unknown, label = 'outputSchema'): asserts schema is JsonSchemaObject {\n if (!isSchemaRecord(schema)) {\n throw new Error(`${label} must be a JSON Schema object.`);\n }\n}\n\n/** Stage the schema on disk and reserve the path the child answers in. */\nexport function createStructuredOutputRuntime(schema: JsonSchemaObject, baseDir?: string): StructuredOutputRuntime {\n assertJsonSchemaObject(schema);\n const rootDir = baseDir ?? TEMP_ROOT_DIR;\n fs.mkdirSync(rootDir, { recursive: true });\n const dir = fs.mkdtempSync(path.join(rootDir, STRUCTURED_OUTPUT_DIR_PREFIX));\n const schemaPath = path.join(dir, SCHEMA_FILE_NAME);\n const outputPath = path.join(dir, OUTPUT_FILE_NAME);\n fs.writeFileSync(schemaPath, JSON.stringify(schema), { mode: PRIVATE_FILE_MODE });\n return { schema, schemaPath, outputPath };\n}\n\n/**\n * Remove the run's schema and output directory.\n *\n * The failure is returned rather than thrown or logged: the directory is under\n * the per-user temp root, so a leftover is harmless and must not fail a run that\n * has already produced its result. Returning it still lets a caller that cares,\n * such as a teardown check, see what happened instead of it vanishing.\n */\nexport function cleanupStructuredOutputRuntime(runtime: StructuredOutputRuntime | undefined): {\n removed: boolean;\n error?: string;\n} {\n if (!runtime) return { removed: false };\n try {\n fs.rmSync(path.dirname(runtime.schemaPath), { recursive: true, force: true });\n return { removed: true };\n } catch (error) {\n return { removed: false, error: toMessage(error) };\n }\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/** The compiled-validator surface this module uses out of `typebox/compile`. */\ninterface CompiledJsonSchema {\n Check(value: unknown): boolean;\n Errors(value: unknown): Iterable<{ instancePath?: string; message?: string }>;\n}\n\ntype CompileJsonSchema = (schema: unknown) => CompiledJsonSchema;\n\nconst TYPEBOX_COMPILE_SPECIFIER = 'typebox/compile';\nconst COMPILE_EXPORT_NAME = 'Compile';\n/** How many schema violations are reported before the message is truncated. */\nconst MAX_REPORTED_SCHEMA_ERRORS = 8;\n/** Path shown for a violation at the document root. */\nconst ROOT_INSTANCE_PATH_LABEL = 'root';\n\nexport type StructuredOutputValidation = { status: 'valid' } | { status: 'invalid'; message: string };\n\nfunction toMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readCompileExport(mod: unknown): CompileJsonSchema | undefined {\n if (!isSchemaRecord(mod)) return undefined;\n const compile = mod[COMPILE_EXPORT_NAME];\n return typeof compile === 'function' ? (compile as CompileJsonSchema) : undefined;\n}\n\n/**\n * Load `typebox/compile` out of the host Pi installation.\n *\n * Exported because the host package root is the only place the dependency is\n * guaranteed to resolve when this extension is loaded from outside the host's\n * own `node_modules` tree.\n */\nexport async function resolveCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n const requireFromRoot = createRequire(path.join(packageRoot, 'package.json'));\n const resolved = requireFromRoot.resolve(TYPEBOX_COMPILE_SPECIFIER);\n const mod: unknown = await import(pathToFileURL(resolved).href);\n return readCompileExport(mod);\n}\n\n/**\n * Validates structured output against an authored JSON Schema.\n *\n * WHY THIS IS A SERVICE AND NOT A FUNCTION:\n * The compiler import is memoised for the life of the process, and that memo is\n * mutable state that needs an owner. As a module-level variable it also could\n * not be reset between tests, which made a single failed-load test poison every\n * later one.\n */\n@injectable()\nexport class StructuredOutputValidator {\n private cachedCompile: Promise<CompileJsonSchema> | undefined;\n\n /** Import seam: ESM namespaces are frozen, so a test cannot spy on the import. */\n protected importCompileModule(): Promise<unknown> {\n return import(TYPEBOX_COMPILE_SPECIFIER);\n }\n\n /** Import seam for the host-package-root fallback. */\n protected importCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n return resolveCompileFromPackageRoot(packageRoot);\n }\n\n /**\n * Resolve the compiler, reporting every attempt that failed.\n *\n * Both routes are named in the error because which one failed is what tells\n * an operator whether the extension is mis-installed or the host env is unset.\n */\n private async importCompile(): Promise<CompileJsonSchema> {\n const failures: string[] = [];\n try {\n const compile = readCompileExport(await this.importCompileModule());\n if (compile) return compile;\n failures.push(`${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`direct import failed: ${toMessage(error)}`);\n }\n const packageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV];\n if (packageRoot) {\n try {\n const compile = await this.importCompileFromPackageRoot(packageRoot);\n if (compile) return compile;\n failures.push(`Pi package root ${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`Pi package root import failed: ${toMessage(error)}`);\n }\n } else {\n failures.push(`${PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);\n }\n throw new Error(\n `Cannot load ${TYPEBOX_COMPILE_SPECIFIER} for structured output validation (${failures.join('; ')})`,\n );\n }\n\n /** Memoised compiler. A rejected load drops the memo so it can be retried. */\n private loadCompile(): Promise<CompileJsonSchema> {\n if (!this.cachedCompile) {\n this.cachedCompile = this.importCompile().catch((error: unknown) => {\n this.cachedCompile = undefined;\n throw error;\n });\n }\n return this.cachedCompile;\n }\n\n /** Drop the memoised compiler. Intended for tests and teardown. */\n reset(): void {\n this.cachedCompile = undefined;\n }\n\n async validateValue(schema: JsonSchemaObject, value: unknown): Promise<StructuredOutputValidation> {\n const compile = await this.loadCompile();\n let validator: CompiledJsonSchema;\n try {\n validator = compile(schema);\n } catch (error) {\n // A schema that will not compile is the author's mistake, not a runtime\n // fault, so it is reported against the run like any other invalid output.\n return { status: 'invalid', message: `invalid outputSchema: ${toMessage(error)}` };\n }\n if (validator.Check(value)) return { status: 'valid' };\n const errors = [...validator.Errors(value)].slice(0, MAX_REPORTED_SCHEMA_ERRORS).map((error) => {\n const pathText = error.instancePath\n ? error.instancePath.replace(/^\\//, '').replace(/\\//g, '.')\n : ROOT_INSTANCE_PATH_LABEL;\n return `${pathText}: ${error.message}`;\n });\n return { status: 'invalid', message: errors.join('; ') || 'schema validation failed' };\n }\n\n /**\n * Read and validate what the child wrote.\n *\n * An absent file is reported as a missing tool call rather than as invalid\n * output: the child never answered at all, which is a different fix.\n */\n async readStructuredOutput(runtime: StructuredOutputRuntime): Promise<{ value?: unknown; error?: string }> {\n if (!fs.existsSync(runtime.outputPath)) {\n return { error: MISSING_STRUCTURED_OUTPUT_CALL_ERROR };\n }\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(runtime.outputPath, 'utf-8')) as unknown;\n } catch (error) {\n return { error: `Failed to read structured output: ${toMessage(error)}` };\n }\n try {\n const validation = await this.validateValue(runtime.schema, value);\n if (validation.status === 'invalid') {\n return { error: `Structured output validation failed: ${validation.message}` };\n }\n } catch (error) {\n // The compiler itself failed to load. That is an environment problem, and\n // reporting it against the run beats crashing the parent mid-orchestration.\n return { error: `Failed to validate structured output: ${toMessage(error)}` };\n }\n return { value };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"structuredOutput.mjs","names":[],"sources":["../../../../src/services/runs/shared/structuredOutput.ts"],"sourcesContent":["/**\n * Structured output: the schema a step must satisfy, and the file it answers in.\n *\n * A step with an `outputSchema` may not finish in prose. The runtime hands the\n * child a `structured_output` tool whose parameters are derived from the schema,\n * writes the schema to a private temp directory, and validates whatever the child\n * wrote back before the run is allowed to succeed.\n *\n * DESIGN PATTERNS:\n * - The author's schema is nested under a `value` property rather than used as\n * the tool parameters directly, because a tool's parameters must be an object\n * and an author is entitled to declare a top-level array or string\n * - Local JSON pointers are rewritten during that nesting. `#/$defs/x` addressed\n * the author's schema root, which is now one level down, so an unrewritten\n * pointer would resolve against the wrapper and silently validate nothing\n * - Every failure is returned as a message, never thrown. An invalid schema is an\n * authoring mistake to report against the run, not a crash of the parent\n *\n * PERFORMANCE:\n * `typebox/compile` is loaded once per process and memoised. It is a heavy\n * import and every validated step would otherwise pay for it. A failed load\n * clears the memo so a transient resolution failure is retried rather than\n * cached forever.\n *\n * AVOID:\n * - Joining `os.tmpdir()` here; the temp root belongs to `shared/paths.ts`\n * - Treating an absent output file as a validation failure. It means the child\n * never called the tool, which is a different diagnosis for the operator\n */\n\nimport * as fs from 'node:fs';\nimport { createRequire } from 'node:module';\nimport * as path from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { injectable } from 'inversify';\n\nimport { PI_CODING_AGENT_PACKAGE_ROOT_ENV } from '../../../adapters/process/env.ts';\nimport { TEMP_ROOT_DIR } from '../../../shared/paths.ts';\nimport type { JsonSchemaObject } from '../../../types/index.ts';\n\nexport { STRUCTURED_OUTPUT_CAPTURE_ENV, STRUCTURED_OUTPUT_SCHEMA_ENV } from '../../../adapters/process/env.ts';\n\nexport const MISSING_STRUCTURED_OUTPUT_CALL_ERROR =\n 'Missing structured_output call; this step has outputSchema and must finish by calling structured_output.';\n\n/** Where the schema and the child's answer live for one run. */\nexport interface StructuredOutputRuntime {\n schema: JsonSchemaObject;\n schemaPath: string;\n outputPath: string;\n}\n\n// ============================================================================\n// Wrapping an authored schema as tool parameters\n// ============================================================================\n\n/** The property the author's schema is nested under inside the tool parameters. */\nconst STRUCTURED_OUTPUT_VALUE_PROPERTY = 'value';\n/** JSON pointer that addresses the nested schema from the wrapper root. */\nconst STRUCTURED_OUTPUT_VALUE_POINTER = `#/properties/${STRUCTURED_OUTPUT_VALUE_PROPERTY}`;\n\n/** Keywords whose value is a map of names to subschemas. */\nconst SCHEMA_MAP_KEYWORDS = ['properties', 'patternProperties', '$defs', 'definitions', 'dependentSchemas'] as const;\n/** Keywords whose value is a single subschema. */\nconst SCHEMA_SINGLE_KEYWORDS = [\n 'additionalItems',\n 'additionalProperties',\n 'contains',\n 'not',\n 'propertyNames',\n 'if',\n 'then',\n 'else',\n 'unevaluatedItems',\n 'unevaluatedProperties',\n 'contentSchema',\n] as const;\n/** Keywords whose value is an array of subschemas. */\nconst SCHEMA_ARRAY_KEYWORDS = ['allOf', 'anyOf', 'oneOf', 'prefixItems'] as const;\n\n/** Reference keywords that can carry a local pointer needing a rebase. */\nconst SCHEMA_REF_KEYWORDS = ['$ref', '$dynamicRef', '$recursiveRef'] as const;\n\n/** A pointer to the schema resource root, which moves when the schema is nested. */\nconst ROOT_POINTER = '#';\nconst LOCAL_POINTER_PREFIX = '#/';\n\nfunction isSchemaRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Rebase local JSON pointers so they still address the author's schema once it\n * has been nested under the wrapper.\n *\n * `$id` stops the descent: a subschema declaring one starts a new resource, so\n * its local pointers address itself and were never relative to the wrapper.\n * Boolean schemas (`true`/`false`) are legal JSON Schema and pass through.\n */\nfunction rewriteLocalJsonPointerRefs(schema: unknown, pointerPrefix: string, inheritsWrapperResource = true): unknown {\n if (typeof schema === 'boolean' || !isSchemaRecord(schema)) return schema;\n const source = schema;\n const rewritten: Record<string, unknown> = { ...source };\n const sharesWrapperResource = inheritsWrapperResource && typeof source.$id !== 'string';\n if (sharesWrapperResource) {\n for (const keyword of SCHEMA_REF_KEYWORDS) {\n const ref = source[keyword];\n if (ref === ROOT_POINTER) rewritten[keyword] = pointerPrefix;\n else if (typeof ref === 'string' && ref.startsWith(LOCAL_POINTER_PREFIX)) {\n rewritten[keyword] = `${pointerPrefix}${ref.slice(ROOT_POINTER.length)}`;\n }\n }\n }\n for (const keyword of SCHEMA_MAP_KEYWORDS) {\n const entries = source[keyword];\n if (!isSchemaRecord(entries)) continue;\n rewritten[keyword] = Object.fromEntries(\n Object.entries(entries).map(([name, nested]) => [\n name,\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n const items = source.items;\n if (Array.isArray(items)) {\n rewritten.items = items.map((nested) => rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource));\n } else if (items !== undefined) {\n rewritten.items = rewriteLocalJsonPointerRefs(items, pointerPrefix, sharesWrapperResource);\n }\n for (const keyword of SCHEMA_SINGLE_KEYWORDS) {\n if (source[keyword] !== undefined) {\n rewritten[keyword] = rewriteLocalJsonPointerRefs(source[keyword], pointerPrefix, sharesWrapperResource);\n }\n }\n for (const keyword of SCHEMA_ARRAY_KEYWORDS) {\n const branches = source[keyword];\n if (Array.isArray(branches)) {\n rewritten[keyword] = branches.map((nested) =>\n rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n );\n }\n }\n const dependencies = source.dependencies;\n if (isSchemaRecord(dependencies)) {\n // Draft-07 `dependencies` is either a property-name list or a subschema.\n rewritten.dependencies = Object.fromEntries(\n Object.entries(dependencies).map(([name, nested]) => [\n name,\n Array.isArray(nested) ? nested : rewriteLocalJsonPointerRefs(nested, pointerPrefix, sharesWrapperResource),\n ]),\n );\n }\n return rewritten;\n}\n\n/** Parameters for the `structured_output` tool that satisfies `schema`. */\nexport function createStructuredOutputToolParameters(schema: JsonSchemaObject): JsonSchemaObject {\n return {\n type: 'object',\n properties: {\n [STRUCTURED_OUTPUT_VALUE_PROPERTY]: rewriteLocalJsonPointerRefs(schema, STRUCTURED_OUTPUT_VALUE_POINTER),\n },\n required: [STRUCTURED_OUTPUT_VALUE_PROPERTY],\n additionalProperties: false,\n };\n}\n\n// ============================================================================\n// Runtime files\n// ============================================================================\n\nconst STRUCTURED_OUTPUT_DIR_PREFIX = 'doom-team-structured-';\nconst SCHEMA_FILE_NAME = 'schema.json';\nconst OUTPUT_FILE_NAME = 'output.json';\n/** The schema can carry task detail, so it is readable only by its own user. */\nconst PRIVATE_FILE_MODE = 0o600;\n\nexport function assertJsonSchemaObject(schema: unknown, label = 'outputSchema'): asserts schema is JsonSchemaObject {\n if (!isSchemaRecord(schema)) {\n throw new Error(`${label} must be a JSON Schema object.`);\n }\n}\n\n/** Stage the schema on disk and reserve the path the child answers in. */\nexport function createStructuredOutputRuntime(schema: JsonSchemaObject, baseDir?: string): StructuredOutputRuntime {\n assertJsonSchemaObject(schema);\n const rootDir = baseDir ?? TEMP_ROOT_DIR;\n fs.mkdirSync(rootDir, { recursive: true });\n const dir = fs.mkdtempSync(path.join(rootDir, STRUCTURED_OUTPUT_DIR_PREFIX));\n const schemaPath = path.join(dir, SCHEMA_FILE_NAME);\n const outputPath = path.join(dir, OUTPUT_FILE_NAME);\n fs.writeFileSync(schemaPath, JSON.stringify(schema), { mode: PRIVATE_FILE_MODE });\n return { schema, schemaPath, outputPath };\n}\n\n/**\n * Remove the run's schema and output directory.\n *\n * The failure is returned rather than thrown or logged: the directory is under\n * the per-user temp root, so a leftover is harmless and must not fail a run that\n * has already produced its result. Returning it still lets a caller that cares,\n * such as a teardown check, see what happened instead of it vanishing.\n */\nexport function cleanupStructuredOutputRuntime(runtime: StructuredOutputRuntime | undefined): {\n removed: boolean;\n error?: string;\n} {\n if (!runtime) return { removed: false };\n try {\n fs.rmSync(path.dirname(runtime.schemaPath), { recursive: true, force: true });\n return { removed: true };\n } catch (error) {\n return { removed: false, error: toMessage(error) };\n }\n}\n\n// ============================================================================\n// Validation\n// ============================================================================\n\n/** The compiled-validator surface this module uses out of `typebox/compile`. */\ninterface CompiledJsonSchema {\n Check(value: unknown): boolean;\n Errors(value: unknown): Iterable<{ instancePath?: string; message?: string }>;\n}\n\ntype CompileJsonSchema = (schema: unknown) => CompiledJsonSchema;\n\nconst TYPEBOX_COMPILE_SPECIFIER = 'typebox/compile';\nconst COMPILE_EXPORT_NAME = 'Compile';\n/** How many schema violations are reported before the message is truncated. */\nconst MAX_REPORTED_SCHEMA_ERRORS = 8;\n/** Path shown for a violation at the document root. */\nconst ROOT_INSTANCE_PATH_LABEL = 'root';\n\nexport type StructuredOutputValidation = { status: 'valid' } | { status: 'invalid'; message: string };\n\nfunction toMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction readCompileExport(mod: unknown): CompileJsonSchema | undefined {\n if (!isSchemaRecord(mod)) return undefined;\n const compile = mod[COMPILE_EXPORT_NAME];\n return typeof compile === 'function' ? (compile as CompileJsonSchema) : undefined;\n}\n\n/**\n * Load `typebox/compile` out of the host Pi installation.\n *\n * Exported because the host package root is the only place the dependency is\n * guaranteed to resolve when this extension is loaded from outside the host's\n * own `node_modules` tree.\n */\nexport async function resolveCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n const requireFromRoot = createRequire(path.join(packageRoot, 'package.json'));\n const resolved = requireFromRoot.resolve(TYPEBOX_COMPILE_SPECIFIER);\n const mod: unknown = await import(pathToFileURL(resolved).href);\n return readCompileExport(mod);\n}\n\n/**\n * Validates structured output against an authored JSON Schema.\n *\n * WHY THIS IS A SERVICE AND NOT A FUNCTION:\n * The compiler import is memoised for the life of the process, and that memo is\n * mutable state that needs an owner. As a module-level variable it also could\n * not be reset between tests, which made a single failed-load test poison every\n * later one.\n */\n@injectable()\nexport class StructuredOutputValidator {\n private cachedCompile: Promise<CompileJsonSchema> | undefined;\n\n /** Import seam: ESM namespaces are frozen, so a test cannot spy on the import. */\n protected importCompileModule(): Promise<unknown> {\n return import(TYPEBOX_COMPILE_SPECIFIER);\n }\n\n /** Import seam for the host-package-root fallback. */\n protected importCompileFromPackageRoot(packageRoot: string): Promise<CompileJsonSchema | undefined> {\n return resolveCompileFromPackageRoot(packageRoot);\n }\n\n /**\n * Resolve the compiler, reporting every attempt that failed.\n *\n * Both routes are named in the error because which one failed is what tells\n * an operator whether the extension is mis-installed or the host env is unset.\n */\n private async importCompile(): Promise<CompileJsonSchema> {\n const failures: string[] = [];\n try {\n const compile = readCompileExport(await this.importCompileModule());\n if (compile) return compile;\n failures.push(`${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`direct import failed: ${toMessage(error)}`);\n }\n const packageRoot = process.env[PI_CODING_AGENT_PACKAGE_ROOT_ENV];\n if (packageRoot) {\n try {\n const compile = await this.importCompileFromPackageRoot(packageRoot);\n if (compile) return compile;\n failures.push(`Pi package root ${TYPEBOX_COMPILE_SPECIFIER} did not export a ${COMPILE_EXPORT_NAME} function`);\n } catch (error) {\n failures.push(`Pi package root import failed: ${toMessage(error)}`);\n }\n } else {\n failures.push(`${PI_CODING_AGENT_PACKAGE_ROOT_ENV} is not set`);\n }\n throw new Error(\n `Cannot load ${TYPEBOX_COMPILE_SPECIFIER} for structured output validation (${failures.join('; ')})`,\n );\n }\n\n /** Memoised compiler. A rejected load drops the memo so it can be retried. */\n private loadCompile(): Promise<CompileJsonSchema> {\n if (!this.cachedCompile) {\n this.cachedCompile = this.importCompile().catch((error: unknown) => {\n this.cachedCompile = undefined;\n throw error;\n });\n }\n return this.cachedCompile;\n }\n\n /** Drop the memoised compiler. Intended for tests and teardown. */\n reset(): void {\n this.cachedCompile = undefined;\n }\n\n async validateValue(schema: JsonSchemaObject, value: unknown): Promise<StructuredOutputValidation> {\n const compile = await this.loadCompile();\n let validator: CompiledJsonSchema;\n try {\n validator = compile(schema);\n } catch (error) {\n // A schema that will not compile is the author's mistake, not a runtime\n // fault, so it is reported against the run like any other invalid output.\n return { status: 'invalid', message: `invalid outputSchema: ${toMessage(error)}` };\n }\n if (validator.Check(value)) return { status: 'valid' };\n const errors = [...validator.Errors(value)].slice(0, MAX_REPORTED_SCHEMA_ERRORS).map((error) => {\n const pathText = error.instancePath\n ? error.instancePath.replace(/^\\//, '').replace(/\\//g, '.')\n : ROOT_INSTANCE_PATH_LABEL;\n return `${pathText}: ${error.message}`;\n });\n return { status: 'invalid', message: errors.join('; ') || 'schema validation failed' };\n }\n\n /**\n * Read and validate what the child wrote.\n *\n * An absent file is reported as a missing tool call rather than as invalid\n * output: the child never answered at all, which is a different fix.\n */\n async readStructuredOutput(runtime: StructuredOutputRuntime): Promise<{ value?: unknown; error?: string }> {\n if (!fs.existsSync(runtime.outputPath)) {\n return { error: MISSING_STRUCTURED_OUTPUT_CALL_ERROR };\n }\n let value: unknown;\n try {\n value = JSON.parse(fs.readFileSync(runtime.outputPath, 'utf-8')) as unknown;\n } catch (error) {\n return { error: `Failed to read structured output: ${toMessage(error)}` };\n }\n try {\n const validation = await this.validateValue(runtime.schema, value);\n if (validation.status === 'invalid') {\n return { error: `Structured output validation failed: ${validation.message}` };\n }\n } catch (error) {\n // The compiler itself failed to load. That is an environment problem, and\n // reporting it against the run beats crashing the parent mid-orchestration.\n return { error: `Failed to validate structured output: ${toMessage(error)}` };\n }\n return { value };\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../../../_virtual/_rolldown/runtime.cjs`),t=require(`../../../adapters/atomicJson.cjs`);require(`../../../shared/atomicJson.cjs`);let n=require(`node:fs`);n=e.__toESM(n,1);const r=new Set([`bash`,`edit`,`find`,`grep`,`ls`,`read`,`write`]);function i(e,i,a,o,s){let c=new Set([...a,...r]),l=i.filter(e=>!c.has(e));if(l.length===0){n.rmSync(e,{force:!0});return}let u=s?.length?l.filter(e=>s.includes(e)):[],d={...o===void 0?{}:{agent:o},required:i,available:a,missing:l,...u.length>0?{missingMcpDirectTools:u}:{}};return t.writePrivateAtomicJson(e,d),d}exports.writeChildToolDiagnostic=i;
|
|
2
|
+
//# sourceMappingURL=toolAvailability.cjs.map
|