@agimon-ai/doompi-team 0.0.1-alpha.0
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/LICENSE +25 -0
- package/README.md +46 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorate.mjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateMetadata.mjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.cjs +1 -0
- package/dist/_virtual/_@oxc-project_runtime@0.127.0/helpers/decorateParam.mjs +1 -0
- package/dist/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist/_virtual/_rolldown/runtime.mjs +1 -0
- package/dist/agents/discovery.cjs +2 -0
- package/dist/agents/discovery.cjs.map +1 -0
- package/dist/agents/discovery.mjs +2 -0
- package/dist/agents/discovery.mjs.map +1 -0
- package/dist/agents/frontmatter.cjs +10 -0
- package/dist/agents/frontmatter.cjs.map +1 -0
- package/dist/agents/frontmatter.mjs +10 -0
- package/dist/agents/frontmatter.mjs.map +1 -0
- package/dist/agents/loader.cjs +2 -0
- package/dist/agents/loader.cjs.map +1 -0
- package/dist/agents/loader.mjs +2 -0
- package/dist/agents/loader.mjs.map +1 -0
- package/dist/agents/memory.cjs +3 -0
- package/dist/agents/memory.cjs.map +1 -0
- package/dist/agents/memory.mjs +3 -0
- package/dist/agents/memory.mjs.map +1 -0
- package/dist/agents/projectRoot.cjs +2 -0
- package/dist/agents/projectRoot.cjs.map +1 -0
- package/dist/agents/projectRoot.mjs +2 -0
- package/dist/agents/projectRoot.mjs.map +1 -0
- package/dist/agents/settings.cjs +2 -0
- package/dist/agents/settings.cjs.map +1 -0
- package/dist/agents/settings.mjs +2 -0
- package/dist/agents/settings.mjs.map +1 -0
- package/dist/agents/skills.cjs +0 -0
- package/dist/agents/skills.cjs.map +1 -0
- package/dist/agents/skills.mjs +5 -0
- package/dist/agents/skills.mjs.map +1 -0
- package/dist/agents/types.d.cts +121 -0
- package/dist/agents/types.d.cts.map +1 -0
- package/dist/agents/types.d.mts +121 -0
- package/dist/agents/types.d.mts.map +1 -0
- package/dist/api/backgroundWork.cjs +1 -0
- package/dist/api/backgroundWork.d.cts +2 -0
- package/dist/api/backgroundWork.d.mts +2 -0
- package/dist/api/backgroundWork.mjs +1 -0
- package/dist/api/capabilityCeiling.cjs +1 -0
- package/dist/api/capabilityCeiling.d.cts +3 -0
- package/dist/api/capabilityCeiling.d.mts +3 -0
- package/dist/api/capabilityCeiling.mjs +2 -0
- package/dist/api/capabilityCeiling.mjs.map +1 -0
- package/dist/api/delegation.cjs +1 -0
- package/dist/api/delegation.d.cts +2 -0
- package/dist/api/delegation.d.mts +2 -0
- package/dist/api/delegation.mjs +1 -0
- package/dist/api/teamSnapshot.cjs +1 -0
- package/dist/api/teamSnapshot.d.cts +2 -0
- package/dist/api/teamSnapshot.d.mts +2 -0
- package/dist/api/teamSnapshot.mjs +2 -0
- package/dist/api/teamSnapshot.mjs.map +1 -0
- package/dist/container/bindOrRebind.cjs +2 -0
- package/dist/container/bindOrRebind.cjs.map +1 -0
- package/dist/container/bindOrRebind.mjs +2 -0
- package/dist/container/bindOrRebind.mjs.map +1 -0
- package/dist/container/globalBridge.cjs +2 -0
- package/dist/container/globalBridge.cjs.map +1 -0
- package/dist/container/globalBridge.d.cts +19 -0
- package/dist/container/globalBridge.d.cts.map +1 -0
- package/dist/container/globalBridge.d.mts +19 -0
- package/dist/container/globalBridge.d.mts.map +1 -0
- package/dist/container/globalBridge.mjs +2 -0
- package/dist/container/globalBridge.mjs.map +1 -0
- package/dist/container/index.cjs +2 -0
- package/dist/container/index.cjs.map +1 -0
- package/dist/container/index.d.cts +38 -0
- package/dist/container/index.d.cts.map +1 -0
- package/dist/container/index.d.mts +38 -0
- package/dist/container/index.d.mts.map +1 -0
- package/dist/container/index.mjs +2 -0
- package/dist/container/index.mjs.map +1 -0
- package/dist/container/modules/agents.cjs +2 -0
- package/dist/container/modules/agents.cjs.map +1 -0
- package/dist/container/modules/agents.d.cts +1 -0
- package/dist/container/modules/agents.d.mts +1 -0
- package/dist/container/modules/agents.mjs +2 -0
- package/dist/container/modules/agents.mjs.map +1 -0
- package/dist/container/modules/core.cjs +2 -0
- package/dist/container/modules/core.cjs.map +1 -0
- package/dist/container/modules/core.d.cts +1 -0
- package/dist/container/modules/core.d.mts +1 -0
- package/dist/container/modules/core.mjs +2 -0
- package/dist/container/modules/core.mjs.map +1 -0
- package/dist/container/modules/extensions.cjs +2 -0
- package/dist/container/modules/extensions.cjs.map +1 -0
- package/dist/container/modules/extensions.mjs +2 -0
- package/dist/container/modules/extensions.mjs.map +1 -0
- package/dist/container/modules/intercom.cjs +2 -0
- package/dist/container/modules/intercom.cjs.map +1 -0
- package/dist/container/modules/intercom.mjs +2 -0
- package/dist/container/modules/intercom.mjs.map +1 -0
- package/dist/container/modules/runs.cjs +2 -0
- package/dist/container/modules/runs.cjs.map +1 -0
- package/dist/container/modules/runs.mjs +2 -0
- package/dist/container/modules/runs.mjs.map +1 -0
- package/dist/container/types.cjs +2 -0
- package/dist/container/types.cjs.map +1 -0
- package/dist/container/types.d.cts +45 -0
- package/dist/container/types.d.cts.map +1 -0
- package/dist/container/types.d.mts +45 -0
- package/dist/container/types.d.mts.map +1 -0
- package/dist/container/types.mjs +2 -0
- package/dist/container/types.mjs.map +1 -0
- package/dist/env.cjs +2 -0
- package/dist/env.cjs.map +1 -0
- package/dist/env.d.cts +65 -0
- package/dist/env.d.cts.map +1 -0
- package/dist/env.d.mts +65 -0
- package/dist/env.d.mts.map +1 -0
- package/dist/env.mjs +2 -0
- package/dist/env.mjs.map +1 -0
- package/dist/extension.cjs +2 -0
- package/dist/extension.cjs.map +1 -0
- package/dist/extension.mjs +2 -0
- package/dist/extension.mjs.map +1 -0
- package/dist/extensions/config.cjs +2 -0
- package/dist/extensions/config.cjs.map +1 -0
- package/dist/extensions/config.mjs +2 -0
- package/dist/extensions/config.mjs.map +1 -0
- package/dist/extensions/delegationBridge.cjs +2 -0
- package/dist/extensions/delegationBridge.cjs.map +1 -0
- package/dist/extensions/delegationBridge.mjs +2 -0
- package/dist/extensions/delegationBridge.mjs.map +1 -0
- package/dist/extensions/doom.cjs +2 -0
- package/dist/extensions/doom.cjs.map +1 -0
- package/dist/extensions/doom.d.cts +8 -0
- package/dist/extensions/doom.d.cts.map +1 -0
- package/dist/extensions/doom.d.mts +8 -0
- package/dist/extensions/doom.d.mts.map +1 -0
- package/dist/extensions/doom.mjs +2 -0
- package/dist/extensions/doom.mjs.map +1 -0
- package/dist/extensions/fablePlanBridge.cjs +2 -0
- package/dist/extensions/fablePlanBridge.cjs.map +1 -0
- package/dist/extensions/fablePlanBridge.mjs +2 -0
- package/dist/extensions/fablePlanBridge.mjs.map +1 -0
- package/dist/extensions/managementActions.cjs +2 -0
- package/dist/extensions/managementActions.cjs.map +1 -0
- package/dist/extensions/managementActions.mjs +2 -0
- package/dist/extensions/managementActions.mjs.map +1 -0
- package/dist/extensions/operationJournal.cjs +2 -0
- package/dist/extensions/operationJournal.cjs.map +1 -0
- package/dist/extensions/operationJournal.mjs +2 -0
- package/dist/extensions/operationJournal.mjs.map +1 -0
- package/dist/extensions/orchestratorPrompt.cjs +35 -0
- package/dist/extensions/orchestratorPrompt.cjs.map +1 -0
- package/dist/extensions/orchestratorPrompt.mjs +35 -0
- package/dist/extensions/orchestratorPrompt.mjs.map +1 -0
- package/dist/extensions/pi.cjs +2 -0
- package/dist/extensions/pi.cjs.map +1 -0
- package/dist/extensions/pi.d.cts +2 -0
- package/dist/extensions/pi.d.mts +2 -0
- package/dist/extensions/pi.mjs +2 -0
- package/dist/extensions/pi.mjs.map +1 -0
- package/dist/extensions/schemas.cjs +1 -0
- package/dist/extensions/schemas.mjs +2 -0
- package/dist/extensions/schemas.mjs.map +1 -0
- package/dist/extensions/spawnPlan.cjs +3 -0
- package/dist/extensions/spawnPlan.cjs.map +1 -0
- package/dist/extensions/spawnPlan.mjs +3 -0
- package/dist/extensions/spawnPlan.mjs.map +1 -0
- package/dist/extensions/standard.cjs +2 -0
- package/dist/extensions/standard.cjs.map +1 -0
- package/dist/extensions/standard.d.cts +8 -0
- package/dist/extensions/standard.d.cts.map +1 -0
- package/dist/extensions/standard.d.mts +8 -0
- package/dist/extensions/standard.d.mts.map +1 -0
- package/dist/extensions/standard.mjs +2 -0
- package/dist/extensions/standard.mjs.map +1 -0
- package/dist/extensions/statusViews.cjs +7 -0
- package/dist/extensions/statusViews.cjs.map +1 -0
- package/dist/extensions/statusViews.mjs +7 -0
- package/dist/extensions/statusViews.mjs.map +1 -0
- package/dist/extensions/subagentPromptRuntime.cjs +18 -0
- package/dist/extensions/subagentPromptRuntime.cjs.map +1 -0
- package/dist/extensions/subagentPromptRuntime.d.cts +58 -0
- package/dist/extensions/subagentPromptRuntime.d.cts.map +1 -0
- package/dist/extensions/subagentPromptRuntime.d.mts +58 -0
- package/dist/extensions/subagentPromptRuntime.d.mts.map +1 -0
- package/dist/extensions/subagentPromptRuntime.mjs +18 -0
- package/dist/extensions/subagentPromptRuntime.mjs.map +1 -0
- package/dist/extensions/subagentPromptRuntimeEntry.cjs +2 -0
- package/dist/extensions/subagentPromptRuntimeEntry.cjs.map +1 -0
- package/dist/extensions/subagentPromptRuntimeEntry.d.cts +2 -0
- package/dist/extensions/subagentPromptRuntimeEntry.d.mts +2 -0
- package/dist/extensions/subagentPromptRuntimeEntry.mjs +2 -0
- package/dist/extensions/subagentPromptRuntimeEntry.mjs.map +1 -0
- package/dist/extensions/subagentTool.cjs +7 -0
- package/dist/extensions/subagentTool.cjs.map +1 -0
- package/dist/extensions/subagentTool.mjs +7 -0
- package/dist/extensions/subagentTool.mjs.map +1 -0
- package/dist/extensions/toolDescription.cjs +2 -0
- package/dist/extensions/toolDescription.cjs.map +1 -0
- package/dist/extensions/toolDescription.mjs +2 -0
- package/dist/extensions/toolDescription.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +34 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +34 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/dist/intercom/intercomBridge.cjs +2 -0
- package/dist/intercom/intercomBridge.cjs.map +1 -0
- package/dist/intercom/intercomBridge.mjs +2 -0
- package/dist/intercom/intercomBridge.mjs.map +1 -0
- package/dist/intercom/nativeTeamChannel.cjs +5 -0
- package/dist/intercom/nativeTeamChannel.cjs.map +1 -0
- package/dist/intercom/nativeTeamChannel.d.cts +22 -0
- package/dist/intercom/nativeTeamChannel.d.cts.map +1 -0
- package/dist/intercom/nativeTeamChannel.d.mts +22 -0
- package/dist/intercom/nativeTeamChannel.d.mts.map +1 -0
- package/dist/intercom/nativeTeamChannel.mjs +5 -0
- package/dist/intercom/nativeTeamChannel.mjs.map +1 -0
- package/dist/intercom/supervisorControlChannel.cjs +2 -0
- package/dist/intercom/supervisorControlChannel.cjs.map +1 -0
- package/dist/intercom/supervisorControlChannel.mjs +2 -0
- package/dist/intercom/supervisorControlChannel.mjs.map +1 -0
- package/dist/protocol/backgroundWork.cjs +2 -0
- package/dist/protocol/backgroundWork.cjs.map +1 -0
- package/dist/protocol/backgroundWork.d.cts +52 -0
- package/dist/protocol/backgroundWork.d.cts.map +1 -0
- package/dist/protocol/backgroundWork.d.mts +52 -0
- package/dist/protocol/backgroundWork.d.mts.map +1 -0
- package/dist/protocol/backgroundWork.mjs +2 -0
- package/dist/protocol/backgroundWork.mjs.map +1 -0
- package/dist/protocol/capabilityCeiling.cjs +2 -0
- package/dist/protocol/capabilityCeiling.cjs.map +1 -0
- package/dist/protocol/capabilityCeiling.d.cts +51 -0
- package/dist/protocol/capabilityCeiling.d.cts.map +1 -0
- package/dist/protocol/capabilityCeiling.d.mts +51 -0
- package/dist/protocol/capabilityCeiling.d.mts.map +1 -0
- package/dist/protocol/capabilityCeiling.mjs +2 -0
- package/dist/protocol/capabilityCeiling.mjs.map +1 -0
- package/dist/protocol/delegation.cjs +2 -0
- package/dist/protocol/delegation.cjs.map +1 -0
- package/dist/protocol/delegation.d.cts +269 -0
- package/dist/protocol/delegation.d.cts.map +1 -0
- package/dist/protocol/delegation.d.mts +269 -0
- package/dist/protocol/delegation.d.mts.map +1 -0
- package/dist/protocol/delegation.mjs +2 -0
- package/dist/protocol/delegation.mjs.map +1 -0
- package/dist/runs/background/asyncExecution.cjs +2 -0
- package/dist/runs/background/asyncExecution.cjs.map +1 -0
- package/dist/runs/background/asyncExecution.mjs +2 -0
- package/dist/runs/background/asyncExecution.mjs.map +1 -0
- package/dist/runs/background/asyncJobTracker.cjs +2 -0
- package/dist/runs/background/asyncJobTracker.cjs.map +1 -0
- package/dist/runs/background/asyncJobTracker.mjs +2 -0
- package/dist/runs/background/asyncJobTracker.mjs.map +1 -0
- package/dist/runs/background/cliRunnerEntry.cjs +2 -0
- package/dist/runs/background/cliRunnerEntry.cjs.map +1 -0
- package/dist/runs/background/cliRunnerEntry.d.cts +1 -0
- package/dist/runs/background/cliRunnerEntry.d.mts +1 -0
- package/dist/runs/background/cliRunnerEntry.mjs +2 -0
- package/dist/runs/background/cliRunnerEntry.mjs.map +1 -0
- package/dist/runs/background/completionBatcher.cjs +2 -0
- package/dist/runs/background/completionBatcher.cjs.map +1 -0
- package/dist/runs/background/completionBatcher.mjs +2 -0
- package/dist/runs/background/completionBatcher.mjs.map +1 -0
- package/dist/runs/background/notify.cjs +4 -0
- package/dist/runs/background/notify.cjs.map +1 -0
- package/dist/runs/background/notify.mjs +4 -0
- package/dist/runs/background/notify.mjs.map +1 -0
- package/dist/runs/background/parentWatchdog.cjs +2 -0
- package/dist/runs/background/parentWatchdog.cjs.map +1 -0
- package/dist/runs/background/parentWatchdog.mjs +2 -0
- package/dist/runs/background/parentWatchdog.mjs.map +1 -0
- package/dist/runs/background/processTerminal.cjs +2 -0
- package/dist/runs/background/processTerminal.cjs.map +1 -0
- package/dist/runs/background/processTerminal.mjs +2 -0
- package/dist/runs/background/processTerminal.mjs.map +1 -0
- package/dist/runs/background/resultWatcher.cjs +2 -0
- package/dist/runs/background/resultWatcher.cjs.map +1 -0
- package/dist/runs/background/resultWatcher.mjs +2 -0
- package/dist/runs/background/resultWatcher.mjs.map +1 -0
- package/dist/runs/background/runIdResolver.cjs +2 -0
- package/dist/runs/background/runIdResolver.cjs.map +1 -0
- package/dist/runs/background/runIdResolver.mjs +2 -0
- package/dist/runs/background/runIdResolver.mjs.map +1 -0
- package/dist/runs/background/runnerBootstrap.cjs +2 -0
- package/dist/runs/background/runnerBootstrap.cjs.map +1 -0
- package/dist/runs/background/runnerBootstrap.mjs +2 -0
- package/dist/runs/background/runnerBootstrap.mjs.map +1 -0
- package/dist/runs/background/runnerExecution.cjs +2 -0
- package/dist/runs/background/runnerExecution.cjs.map +1 -0
- package/dist/runs/background/runnerExecution.mjs +2 -0
- package/dist/runs/background/runnerExecution.mjs.map +1 -0
- package/dist/runs/background/runnerReporting.cjs +3 -0
- package/dist/runs/background/runnerReporting.cjs.map +1 -0
- package/dist/runs/background/runnerReporting.mjs +3 -0
- package/dist/runs/background/runnerReporting.mjs.map +1 -0
- package/dist/runs/background/runnerTeamMembership.cjs +2 -0
- package/dist/runs/background/runnerTeamMembership.cjs.map +1 -0
- package/dist/runs/background/runnerTeamMembership.mjs +2 -0
- package/dist/runs/background/runnerTeamMembership.mjs.map +1 -0
- package/dist/runs/background/spawnHandshake.cjs +2 -0
- package/dist/runs/background/spawnHandshake.cjs.map +1 -0
- package/dist/runs/background/spawnHandshake.mjs +2 -0
- package/dist/runs/background/spawnHandshake.mjs.map +1 -0
- package/dist/runs/background/staleRunReconciler.cjs +2 -0
- package/dist/runs/background/staleRunReconciler.cjs.map +1 -0
- package/dist/runs/background/staleRunReconciler.mjs +2 -0
- package/dist/runs/background/staleRunReconciler.mjs.map +1 -0
- package/dist/runs/background/statusReader.cjs +2 -0
- package/dist/runs/background/statusReader.cjs.map +1 -0
- package/dist/runs/background/statusReader.mjs +2 -0
- package/dist/runs/background/statusReader.mjs.map +1 -0
- package/dist/runs/background/statusWriter.cjs +2 -0
- package/dist/runs/background/statusWriter.cjs.map +1 -0
- package/dist/runs/background/statusWriter.mjs +2 -0
- package/dist/runs/background/statusWriter.mjs.map +1 -0
- package/dist/runs/background/subagentWait.cjs +2 -0
- package/dist/runs/background/subagentWait.cjs.map +1 -0
- package/dist/runs/background/subagentWait.mjs +2 -0
- package/dist/runs/background/subagentWait.mjs.map +1 -0
- package/dist/runs/background/terminalPersistence.cjs +2 -0
- package/dist/runs/background/terminalPersistence.cjs.map +1 -0
- package/dist/runs/background/terminalPersistence.mjs +2 -0
- package/dist/runs/background/terminalPersistence.mjs.map +1 -0
- package/dist/runs/registry/processGroup.cjs +2 -0
- package/dist/runs/registry/processGroup.cjs.map +1 -0
- package/dist/runs/registry/processGroup.mjs +2 -0
- package/dist/runs/registry/processGroup.mjs.map +1 -0
- package/dist/runs/registry/runRegistry.cjs +2 -0
- package/dist/runs/registry/runRegistry.cjs.map +1 -0
- package/dist/runs/registry/runRegistry.mjs +2 -0
- package/dist/runs/registry/runRegistry.mjs.map +1 -0
- package/dist/runs/registry/sessionLifecycle.cjs +2 -0
- package/dist/runs/registry/sessionLifecycle.cjs.map +1 -0
- package/dist/runs/registry/sessionLifecycle.mjs +2 -0
- package/dist/runs/registry/sessionLifecycle.mjs.map +1 -0
- package/dist/runs/registry/suspendedRuns.cjs +4 -0
- package/dist/runs/registry/suspendedRuns.cjs.map +1 -0
- package/dist/runs/registry/suspendedRuns.mjs +4 -0
- package/dist/runs/registry/suspendedRuns.mjs.map +1 -0
- package/dist/runs/sdkRunnerEntry.cjs +2 -0
- package/dist/runs/sdkRunnerEntry.cjs.map +1 -0
- package/dist/runs/sdkRunnerEntry.d.cts +1 -0
- package/dist/runs/sdkRunnerEntry.d.mts +1 -0
- package/dist/runs/sdkRunnerEntry.mjs +2 -0
- package/dist/runs/sdkRunnerEntry.mjs.map +1 -0
- package/dist/runs/shared/claudeFableProfile.cjs +4 -0
- package/dist/runs/shared/claudeFableProfile.cjs.map +1 -0
- package/dist/runs/shared/claudeFableProfile.mjs +4 -0
- package/dist/runs/shared/claudeFableProfile.mjs.map +1 -0
- package/dist/runs/shared/depthGuard.cjs +2 -0
- package/dist/runs/shared/depthGuard.cjs.map +1 -0
- package/dist/runs/shared/depthGuard.mjs +2 -0
- package/dist/runs/shared/depthGuard.mjs.map +1 -0
- package/dist/runs/shared/mcpDirectToolAllowlist.cjs +2 -0
- package/dist/runs/shared/mcpDirectToolAllowlist.cjs.map +1 -0
- package/dist/runs/shared/mcpDirectToolAllowlist.mjs +2 -0
- package/dist/runs/shared/mcpDirectToolAllowlist.mjs.map +1 -0
- package/dist/runs/shared/modelFallback.cjs +2 -0
- package/dist/runs/shared/modelFallback.cjs.map +1 -0
- package/dist/runs/shared/modelFallback.mjs +2 -0
- package/dist/runs/shared/modelFallback.mjs.map +1 -0
- package/dist/runs/shared/modelScope.cjs +2 -0
- package/dist/runs/shared/modelScope.cjs.map +1 -0
- package/dist/runs/shared/modelScope.mjs +2 -0
- package/dist/runs/shared/modelScope.mjs.map +1 -0
- package/dist/runs/shared/nestedPath.cjs +2 -0
- package/dist/runs/shared/nestedPath.cjs.map +1 -0
- package/dist/runs/shared/nestedPath.mjs +2 -0
- package/dist/runs/shared/nestedPath.mjs.map +1 -0
- package/dist/runs/shared/piArgs.cjs +2 -0
- package/dist/runs/shared/piArgs.cjs.map +1 -0
- package/dist/runs/shared/piArgs.mjs +2 -0
- package/dist/runs/shared/piArgs.mjs.map +1 -0
- package/dist/runs/shared/piSpawn.cjs +2 -0
- package/dist/runs/shared/piSpawn.cjs.map +1 -0
- package/dist/runs/shared/piSpawn.mjs +2 -0
- package/dist/runs/shared/piSpawn.mjs.map +1 -0
- package/dist/runs/shared/runWithConcurrency.cjs +2 -0
- package/dist/runs/shared/runWithConcurrency.cjs.map +1 -0
- package/dist/runs/shared/runWithConcurrency.mjs +2 -0
- package/dist/runs/shared/runWithConcurrency.mjs.map +1 -0
- package/dist/runs/shared/runtimeRegistry.cjs +2 -0
- package/dist/runs/shared/runtimeRegistry.cjs.map +1 -0
- package/dist/runs/shared/runtimeRegistry.mjs +2 -0
- package/dist/runs/shared/runtimeRegistry.mjs.map +1 -0
- package/dist/runs/shared/structuredOutput.cjs +2 -0
- package/dist/runs/shared/structuredOutput.cjs.map +1 -0
- package/dist/runs/shared/structuredOutput.mjs +2 -0
- package/dist/runs/shared/structuredOutput.mjs.map +1 -0
- package/dist/runs/shared/toolAvailability.cjs +2 -0
- package/dist/runs/shared/toolAvailability.cjs.map +1 -0
- package/dist/runs/shared/toolAvailability.mjs +2 -0
- package/dist/runs/shared/toolAvailability.mjs.map +1 -0
- package/dist/runs/shared/toolBudget.cjs +2 -0
- package/dist/runs/shared/toolBudget.cjs.map +1 -0
- package/dist/runs/shared/toolBudget.mjs +2 -0
- package/dist/runs/shared/toolBudget.mjs.map +1 -0
- package/dist/shared/artifacts.cjs +2 -0
- package/dist/shared/artifacts.cjs.map +1 -0
- package/dist/shared/artifacts.mjs +2 -0
- package/dist/shared/artifacts.mjs.map +1 -0
- package/dist/shared/atomicJson.cjs +2 -0
- package/dist/shared/atomicJson.cjs.map +1 -0
- package/dist/shared/atomicJson.mjs +2 -0
- package/dist/shared/atomicJson.mjs.map +1 -0
- package/dist/shared/boundedKeySet.cjs +2 -0
- package/dist/shared/boundedKeySet.cjs.map +1 -0
- package/dist/shared/boundedKeySet.mjs +2 -0
- package/dist/shared/boundedKeySet.mjs.map +1 -0
- package/dist/shared/childTranscript.cjs +5 -0
- package/dist/shared/childTranscript.cjs.map +1 -0
- package/dist/shared/childTranscript.mjs +5 -0
- package/dist/shared/childTranscript.mjs.map +1 -0
- package/dist/shared/configDir.cjs +2 -0
- package/dist/shared/configDir.cjs.map +1 -0
- package/dist/shared/configDir.mjs +2 -0
- package/dist/shared/configDir.mjs.map +1 -0
- package/dist/shared/errors.cjs +2 -0
- package/dist/shared/errors.cjs.map +1 -0
- package/dist/shared/errors.mjs +2 -0
- package/dist/shared/errors.mjs.map +1 -0
- package/dist/shared/fileSystemRetry.cjs +2 -0
- package/dist/shared/fileSystemRetry.cjs.map +1 -0
- package/dist/shared/fileSystemRetry.mjs +2 -0
- package/dist/shared/fileSystemRetry.mjs.map +1 -0
- package/dist/shared/formatters.cjs +2 -0
- package/dist/shared/formatters.cjs.map +1 -0
- package/dist/shared/formatters.mjs +2 -0
- package/dist/shared/formatters.mjs.map +1 -0
- package/dist/shared/lruCache.cjs +2 -0
- package/dist/shared/lruCache.cjs.map +1 -0
- package/dist/shared/lruCache.mjs +2 -0
- package/dist/shared/lruCache.mjs.map +1 -0
- package/dist/shared/modelInfo.cjs +2 -0
- package/dist/shared/modelInfo.cjs.map +1 -0
- package/dist/shared/modelInfo.mjs +2 -0
- package/dist/shared/modelInfo.mjs.map +1 -0
- package/dist/shared/modelResolution.cjs +2 -0
- package/dist/shared/modelResolution.cjs.map +1 -0
- package/dist/shared/modelResolution.mjs +2 -0
- package/dist/shared/modelResolution.mjs.map +1 -0
- package/dist/shared/paths.cjs +2 -0
- package/dist/shared/paths.cjs.map +1 -0
- package/dist/shared/paths.mjs +2 -0
- package/dist/shared/paths.mjs.map +1 -0
- package/dist/shared/pollScheduler.cjs +2 -0
- package/dist/shared/pollScheduler.cjs.map +1 -0
- package/dist/shared/pollScheduler.mjs +2 -0
- package/dist/shared/pollScheduler.mjs.map +1 -0
- package/dist/shared/scopeOwner.cjs +2 -0
- package/dist/shared/scopeOwner.cjs.map +1 -0
- package/dist/shared/scopeOwner.mjs +2 -0
- package/dist/shared/scopeOwner.mjs.map +1 -0
- package/dist/shared/versioned.cjs +2 -0
- package/dist/shared/versioned.cjs.map +1 -0
- package/dist/shared/versioned.mjs +2 -0
- package/dist/shared/versioned.mjs.map +1 -0
- package/dist/slash/chainExpression.cjs +2 -0
- package/dist/slash/chainExpression.cjs.map +1 -0
- package/dist/slash/chainExpression.mjs +2 -0
- package/dist/slash/chainExpression.mjs.map +1 -0
- package/dist/slash/doctor.cjs +5 -0
- package/dist/slash/doctor.cjs.map +1 -0
- package/dist/slash/doctor.mjs +5 -0
- package/dist/slash/doctor.mjs.map +1 -0
- package/dist/slash/slashCommands.cjs +4 -0
- package/dist/slash/slashCommands.cjs.map +1 -0
- package/dist/slash/slashCommands.mjs +4 -0
- package/dist/slash/slashCommands.mjs.map +1 -0
- package/dist/slash/spawnRequestMapping.cjs +2 -0
- package/dist/slash/spawnRequestMapping.cjs.map +1 -0
- package/dist/slash/spawnRequestMapping.mjs +2 -0
- package/dist/slash/spawnRequestMapping.mjs.map +1 -0
- package/dist/slash/subagentLaunch.cjs +2 -0
- package/dist/slash/subagentLaunch.cjs.map +1 -0
- package/dist/slash/subagentLaunch.mjs +2 -0
- package/dist/slash/subagentLaunch.mjs.map +1 -0
- package/dist/tui/agentCatalog.cjs +2 -0
- package/dist/tui/agentCatalog.cjs.map +1 -0
- package/dist/tui/agentCatalog.mjs +2 -0
- package/dist/tui/agentCatalog.mjs.map +1 -0
- package/dist/tui/agentResourceProjection.cjs +2 -0
- package/dist/tui/agentResourceProjection.cjs.map +1 -0
- package/dist/tui/agentResourceProjection.mjs +2 -0
- package/dist/tui/agentResourceProjection.mjs.map +1 -0
- package/dist/tui/completionNotice.cjs +5 -0
- package/dist/tui/completionNotice.cjs.map +1 -0
- package/dist/tui/completionNotice.mjs +5 -0
- package/dist/tui/completionNotice.mjs.map +1 -0
- package/dist/tui/fleet.cjs +3 -0
- package/dist/tui/fleet.cjs.map +1 -0
- package/dist/tui/fleet.mjs +3 -0
- package/dist/tui/fleet.mjs.map +1 -0
- package/dist/tui/fleetAgentView.cjs +2 -0
- package/dist/tui/fleetAgentView.cjs.map +1 -0
- package/dist/tui/fleetAgentView.mjs +2 -0
- package/dist/tui/fleetAgentView.mjs.map +1 -0
- package/dist/tui/fleetStatus.cjs +2 -0
- package/dist/tui/fleetStatus.cjs.map +1 -0
- package/dist/tui/fleetStatus.mjs +2 -0
- package/dist/tui/fleetStatus.mjs.map +1 -0
- package/dist/tui/fleetTranscript.cjs +5 -0
- package/dist/tui/fleetTranscript.cjs.map +1 -0
- package/dist/tui/fleetTranscript.mjs +5 -0
- package/dist/tui/fleetTranscript.mjs.map +1 -0
- package/dist/tui/register.cjs +2 -0
- package/dist/tui/register.cjs.map +1 -0
- package/dist/tui/register.mjs +2 -0
- package/dist/tui/register.mjs.map +1 -0
- package/dist/types.d.cts +59 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +59 -0
- package/dist/types.d.mts.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scopeOwner.mjs","names":[],"sources":["../../src/shared/scopeOwner.ts"],"sourcesContent":["/**\n * Who owns a session scope, recorded on disk so a later sweep can tell an\n * abandoned tree from a live one.\n *\n * WHY A FILE AND NOT AN IN-MEMORY REGISTRY:\n * The process that owns a scope is exactly the process that cannot report on\n * it once it is gone. A crashed session leaves its whole tree behind, and the\n * only thing able to reclaim that is a different process reading something the\n * dead one left written down.\n *\n * WHY LIVENESS IS NOT DECIDED HERE:\n * This module records `hostPid` and reads it back; it does not decide whether a\n * scope is reapable. That rule needs run liveness too - after `/new` the\n * abandoned scope's `hostPid` is the still-live current process, so a\n * hostPid-only test would never reap it - and it belongs with the run registry\n * that knows about runs.\n *\n * AVOID:\n * - Treating a missing or unreadable owner file as \"safe to delete\". An\n * unreadable owner is unknown, not dead\n */\n\nimport * as fs from 'node:fs';\n\nimport { writeAtomicJson } from './atomicJson.ts';\nimport { scopeOwnerPath, type SessionScope } from './paths.ts';\nimport { parseVersioned } from './versioned.ts';\n\nconst SCOPE_OWNER_VERSION = 1;\n\nexport interface ScopeOwnerRecord {\n version: typeof SCOPE_OWNER_VERSION;\n rootSessionId: string;\n /** The process that adopted this scope. Dead pid plus no live runs means reapable. */\n hostPid: number;\n startedAt: number;\n}\n\n/**\n * Claim a scope for this process.\n *\n * Rewritten rather than written once: `/resume` reopens the same session id,\n * so the same scope is legitimately re-adopted by a later process, and the\n * record has to name the process that owns it now rather than the one that\n * first created the directory.\n */\nexport function writeScopeOwner(scope: SessionScope, now: number = Date.now()): ScopeOwnerRecord {\n const record: ScopeOwnerRecord = {\n version: SCOPE_OWNER_VERSION,\n rootSessionId: scope.rootSessionId,\n hostPid: process.pid,\n startedAt: now,\n };\n writeAtomicJson(scopeOwnerPath(scope), record);\n return record;\n}\n\n/** `undefined` when the scope has no readable owner: unknown, which is not the same as dead. */\nexport function readScopeOwner(scope: SessionScope): ScopeOwnerRecord | undefined {\n let raw: string;\n try {\n raw = fs.readFileSync(scopeOwnerPath(scope), 'utf-8');\n } catch {\n // Absent or unreadable. Both mean \"cannot say who owns this\", and the\n // caller must treat that as unknown rather than unowned.\n return undefined;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return undefined;\n }\n\n const result = parseVersioned<ScopeOwnerRecord>(parsed, [SCOPE_OWNER_VERSION]);\n if (!result.ok) return undefined;\n const record = result.value;\n if (typeof record.rootSessionId !== 'string' || !record.rootSessionId) return undefined;\n if (!Number.isInteger(record.hostPid)) return undefined;\n return record;\n}\n"],"mappings":"iSA8CA,SAAgB,EAAgB,EAAqB,EAAc,KAAK,KAAK,CAAoB,CAC/F,IAAM,EAA2B,CAC/B,QAAS,EACT,cAAe,EAAM,cACrB,QAAS,QAAQ,IACjB,UAAW,EACZ,CAED,OADA,EAAgB,EAAe,EAAM,CAAE,EAAO,CACvC,EAIT,SAAgB,EAAe,EAAmD,CAChF,IAAI,EACJ,GAAI,CACF,EAAM,EAAG,aAAa,EAAe,EAAM,CAAE,QAAQ,MAC/C,CAGN,OAGF,IAAI,EACJ,GAAI,CACF,EAAS,KAAK,MAAM,EAAI,MAClB,CACN,OAGF,IAAM,EAAS,EAAiC,EAAQ,CAAC,EAAoB,CAAC,CAC9E,GAAI,CAAC,EAAO,GAAI,OAChB,IAAM,EAAS,EAAO,MAClB,YAAO,EAAO,eAAkB,UAAY,CAAC,EAAO,gBACnD,OAAO,UAAU,EAAO,QAAQ,CACrC,OAAO,qBAxDyC,IACa,IACf,CAE1C,EAAsB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return{ok:!1,failure:{reason:`not-an-object`}};let n=e.version;return typeof n!=`number`||!Number.isInteger(n)?{ok:!1,failure:{reason:`missing-version`}}:t.includes(n)?{ok:!0,value:e}:{ok:!1,failure:{reason:`unsupported-version`,found:n}}}exports.parseVersioned=e;
|
|
2
|
+
//# sourceMappingURL=versioned.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versioned.cjs","names":[],"sources":["../../src/shared/versioned.ts"],"sourcesContent":["/**\n * Version envelope shared by every artifact this package writes to disk.\n *\n * DESIGN PATTERNS:\n * - Every record carries `version` from the day it is created, so a later format\n * change can be detected rather than guessed at\n * - Readers reject an unknown version instead of coercing it: a run directory\n * written by a newer build is skipped, not misread\n *\n * WHY THIS EXISTS:\n * Several predecessor artifacts had no version field at all, which left no way\n * to change their shape without a silent misparse in a mixed-version session.\n *\n * AVOID:\n * - Bumping a version to add an optional field; additive changes stay compatible\n * - Reading a record without going through `parseVersioned`\n */\n\nexport interface VersionedRecord {\n version: number;\n}\n\nexport type VersionedParseFailure =\n | { reason: 'not-an-object' }\n | { reason: 'missing-version' }\n | { reason: 'unsupported-version'; found: number };\n\nexport type VersionedParseResult<T> = { ok: true; value: T } | { ok: false; failure: VersionedParseFailure };\n\n/**\n * Validate that `value` is an object carrying one of `supportedVersions`.\n *\n * Returns a result rather than throwing because most callers are scanning a\n * directory and want to skip a bad record, not abort the sweep.\n */\nexport function parseVersioned<T extends VersionedRecord>(\n value: unknown,\n supportedVersions: readonly number[],\n): VersionedParseResult<T> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, failure: { reason: 'not-an-object' } };\n }\n const found = (value as Partial<VersionedRecord>).version;\n if (typeof found !== 'number' || !Number.isInteger(found)) {\n return { ok: false, failure: { reason: 'missing-version' } };\n }\n if (!supportedVersions.includes(found)) {\n return { ok: false, failure: { reason: 'unsupported-version', found } };\n }\n return { ok: true, value: value as T };\n}\n\n/** Human-readable explanation for a rejected record, for logs and diagnostics. */\nexport function describeVersionedFailure(failure: VersionedParseFailure, label: string): string {\n switch (failure.reason) {\n case 'not-an-object':\n return `${label} is not an object.`;\n case 'missing-version':\n return `${label} has no integer version field.`;\n case 'unsupported-version':\n return `${label} has unsupported version ${failure.found}.`;\n }\n}\n"],"mappings":"AAmCA,SAAgB,EACd,EACA,EACyB,CACzB,GAAI,CAAC,GAAS,OAAO,GAAU,UAAY,MAAM,QAAQ,EAAM,CAC7D,MAAO,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,gBAAiB,CAAE,CAE5D,IAAM,EAAS,EAAmC,QAOlD,OANI,OAAO,GAAU,UAAY,CAAC,OAAO,UAAU,EAAM,CAChD,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,kBAAmB,CAAE,CAEzD,EAAkB,SAAS,EAAM,CAG/B,CAAE,GAAI,GAAa,QAAY,CAF7B,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,sBAAuB,QAAO,CAAE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{__esmMin as e}from"../_virtual/_rolldown/runtime.mjs";function t(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return{ok:!1,failure:{reason:`not-an-object`}};let n=e.version;return typeof n!=`number`||!Number.isInteger(n)?{ok:!1,failure:{reason:`missing-version`}}:t.includes(n)?{ok:!0,value:e}:{ok:!1,failure:{reason:`unsupported-version`,found:n}}}var n=e((()=>{}));n();export{n as init_versioned,t as parseVersioned};
|
|
2
|
+
//# sourceMappingURL=versioned.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"versioned.mjs","names":[],"sources":["../../src/shared/versioned.ts"],"sourcesContent":["/**\n * Version envelope shared by every artifact this package writes to disk.\n *\n * DESIGN PATTERNS:\n * - Every record carries `version` from the day it is created, so a later format\n * change can be detected rather than guessed at\n * - Readers reject an unknown version instead of coercing it: a run directory\n * written by a newer build is skipped, not misread\n *\n * WHY THIS EXISTS:\n * Several predecessor artifacts had no version field at all, which left no way\n * to change their shape without a silent misparse in a mixed-version session.\n *\n * AVOID:\n * - Bumping a version to add an optional field; additive changes stay compatible\n * - Reading a record without going through `parseVersioned`\n */\n\nexport interface VersionedRecord {\n version: number;\n}\n\nexport type VersionedParseFailure =\n | { reason: 'not-an-object' }\n | { reason: 'missing-version' }\n | { reason: 'unsupported-version'; found: number };\n\nexport type VersionedParseResult<T> = { ok: true; value: T } | { ok: false; failure: VersionedParseFailure };\n\n/**\n * Validate that `value` is an object carrying one of `supportedVersions`.\n *\n * Returns a result rather than throwing because most callers are scanning a\n * directory and want to skip a bad record, not abort the sweep.\n */\nexport function parseVersioned<T extends VersionedRecord>(\n value: unknown,\n supportedVersions: readonly number[],\n): VersionedParseResult<T> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return { ok: false, failure: { reason: 'not-an-object' } };\n }\n const found = (value as Partial<VersionedRecord>).version;\n if (typeof found !== 'number' || !Number.isInteger(found)) {\n return { ok: false, failure: { reason: 'missing-version' } };\n }\n if (!supportedVersions.includes(found)) {\n return { ok: false, failure: { reason: 'unsupported-version', found } };\n }\n return { ok: true, value: value as T };\n}\n\n/** Human-readable explanation for a rejected record, for logs and diagnostics. */\nexport function describeVersionedFailure(failure: VersionedParseFailure, label: string): string {\n switch (failure.reason) {\n case 'not-an-object':\n return `${label} is not an object.`;\n case 'missing-version':\n return `${label} has no integer version field.`;\n case 'unsupported-version':\n return `${label} has unsupported version ${failure.found}.`;\n }\n}\n"],"mappings":"6DAmCA,SAAgB,EACd,EACA,EACyB,CACzB,GAAI,CAAC,GAAS,OAAO,GAAU,UAAY,MAAM,QAAQ,EAAM,CAC7D,MAAO,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,gBAAiB,CAAE,CAE5D,IAAM,EAAS,EAAmC,QAOlD,OANI,OAAO,GAAU,UAAY,CAAC,OAAO,UAAU,EAAM,CAChD,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,kBAAmB,CAAE,CAEzD,EAAkB,SAAS,EAAM,CAG/B,CAAE,GAAI,GAAa,QAAY,CAF7B,CAAE,GAAI,GAAO,QAAS,CAAE,OAAQ,sBAAuB,QAAO,CAAE"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e){let t={};for(let n of e.split(`,`)){let e=n.trim();if(!e)continue;let r=e.indexOf(`=`);if(r===-1){e===`progress`&&(t.progress=!0);continue}let i=e.slice(0,r).trim(),a=e.slice(r+1).trim();switch(i){case`output`:t.output=a===`false`?!1:a;break;case`outputMode`:(a===`inline`||a===`file-only`)&&(t.outputMode=a);break;case`reads`:t.reads=a===`false`?!1:a.split(`+`).filter(Boolean);break;case`model`:t.model=a||void 0;break;case`skill`:case`skills`:t.skill=a===`false`?!1:a.split(`+`).filter(Boolean);break;case`progress`:t.progress=a!==`false`;break;case`as`:t.as=a||void 0;break;case`label`:t.label=a||void 0;break;case`phase`:t.phase=a||void 0;break;case`cwd`:t.cwd=a||void 0;break;case`count`:{let e=Number(a);Number.isInteger(e)&&e>0&&(t.count=e);break}case`outputSchema`:t.outputSchema=a||void 0;break;case`acceptance`:t.acceptance=a||void 0;break}}return t}function t(t){let n=t.indexOf(`[`);if(n===-1)return{name:t,config:{}};let r=t.lastIndexOf(`]`);return{name:t.slice(0,n),config:e(t.slice(n+1,r===-1?void 0:r))}}var n=class extends Error{};function r(e){let n,r,i=e.match(/^(\S+(?:\[[^\]]*\])?)\s+(?:"([^"]*)"|'([^']*)')$/);if(i)n=i[1],r=(i[2]??i[3])||void 0;else{let t=e.indexOf(` -- `);t===-1?n=e:(n=e.slice(0,t).trim(),r=e.slice(t+4).trim()||void 0)}return{kind:`step`,...t(n),task:r}}const i=`--fork`,a=[`--bg`,`--async`];var o=class extends n{constructor(e){super(`'${e}' is no longer needed: every run in this package is already background.`),this.flag=e,this.name=`DeprecatedBackgroundFlagError`}};function s(e,t){return e===t||e.endsWith(` ${t}`)}function c(e,t){return e===t?``:e.slice(0,-(t.length+1)).trim()}function l(e){let t=e.trim(),n=!1;for(;;){if(s(t,i)){n=!0,t=c(t,i);continue}let e=a.find(e=>s(t,e));if(e)throw new o(e);break}return{args:t,fork:n}}exports.SlashParseError=n,exports.extractForkFlag=l,exports.parseAgentToken=t,exports.parseSingleTaskToken=r;
|
|
2
|
+
//# sourceMappingURL=chainExpression.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chainExpression.cjs","names":[],"sources":["../../src/slash/chainExpression.ts"],"sourcesContent":["/**\n * Parses `/chain`/`/parallel`/`/run` slash-command argument strings into\n * structured steps: inline per-agent config (`agent[key=value,...]`),\n * `->`-separated chain steps, and `(a | b)`-style parallel groups within a\n * chain. Pure string parsing - nothing here calls into `SpawnPlanner` or\n * knows what a parsed field is used for; see `subagentLaunch.ts` for the\n * execution side and whichever module maps a `ParsedStep` onto a\n * `SpawnPlanTaskInput`/`SpawnPlanChainStepInput` for what happens to a\n * field this parser accepts once `SpawnPlanner`'s own request shape is\n * settled for this port (see the port's own tracking, not this file).\n *\n * WHY THIS IS ITS OWN MODULE, SEPARATE FROM COMMAND REGISTRATION:\n * The predecessor kept this logic inline in `slashCommands.ts`. Splitting\n * it out means the string-parsing rules - which are intricate and worth\n * testing in isolation (quote tracking, nested parens, top-level-only arrow\n * and pipe splitting) - do not need a `pi.registerCommand` fixture to test,\n * and stay unaffected by whatever `SpawnPlanner` request shape a caller\n * eventually maps a `ParsedStep` onto.\n *\n * AVOID:\n * - Adding execution or `SpawnPlanner` knowledge here. If a function needs\n * to know what a field does once parsed, it belongs in the caller, not\n * this file\n */\n\nexport interface InlineConfig {\n output?: string | false;\n outputMode?: 'inline' | 'file-only';\n reads?: string[] | false;\n model?: string;\n skill?: string[] | false;\n progress?: boolean;\n as?: string;\n label?: string;\n phase?: string;\n cwd?: string;\n count?: number;\n outputSchema?: string;\n acceptance?: string;\n}\n\n/** Parses the `key=value,...` body of `agent[...]` inline config. Unknown keys are ignored, not rejected. */\nexport function parseInlineConfig(raw: string): InlineConfig {\n const config: InlineConfig = {};\n for (const part of raw.split(',')) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf('=');\n if (eq === -1) {\n if (trimmed === 'progress') config.progress = true;\n continue;\n }\n const key = trimmed.slice(0, eq).trim();\n const val = trimmed.slice(eq + 1).trim();\n switch (key) {\n case 'output':\n config.output = val === 'false' ? false : val;\n break;\n case 'outputMode':\n if (val === 'inline' || val === 'file-only') config.outputMode = val;\n break;\n case 'reads':\n config.reads = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'model':\n config.model = val || undefined;\n break;\n case 'skill':\n case 'skills':\n config.skill = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'progress':\n config.progress = val !== 'false';\n break;\n case 'as':\n config.as = val || undefined;\n break;\n case 'label':\n config.label = val || undefined;\n break;\n case 'phase':\n config.phase = val || undefined;\n break;\n case 'cwd':\n config.cwd = val || undefined;\n break;\n case 'count': {\n const n = Number(val);\n if (Number.isInteger(n) && n > 0) config.count = n;\n break;\n }\n case 'outputSchema':\n config.outputSchema = val || undefined;\n break;\n case 'acceptance':\n config.acceptance = val || undefined;\n break;\n }\n }\n return config;\n}\n\n/** Splits `agent[key=value]` into the bare agent name and its parsed inline config. */\nexport function parseAgentToken(token: string): { name: string; config: InlineConfig } {\n const bracket = token.indexOf('[');\n if (bracket === -1) return { name: token, config: {} };\n const end = token.lastIndexOf(']');\n return {\n name: token.slice(0, bracket),\n config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)),\n };\n}\n\nexport interface ParsedStep {\n kind: 'step';\n name: string;\n config: InlineConfig;\n task?: string;\n}\n\nexport class SlashParseError extends Error {}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n let agentPart: string;\n let task: string | undefined;\n const qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n if (qMatch) {\n agentPart = qMatch[1]!;\n task = (qMatch[2] ?? qMatch[3]) || undefined;\n } else {\n const dashIdx = token.indexOf(' -- ');\n if (dashIdx !== -1) {\n agentPart = token.slice(0, dashIdx).trim();\n task = token.slice(dashIdx + 4).trim() || undefined;\n } else {\n agentPart = token;\n }\n }\n return { kind: 'step', ...parseAgentToken(agentPart), task };\n}\n\n/**\n * User-typed flag selecting fork context for a run.\n *\n * Named because it is part of the command surface a user types, so the literal\n * appears in the parser, in help text and in any error naming it. Three copies\n * of a user-facing token drift one edit at a time, and the failure mode is a\n * flag the help promises and the parser does not accept.\n */\nconst FORK_FLAG = '--fork';\n\n/**\n * The predecessor's flags that used to select background execution. `--async`\n * was a synonym for the same flag, accepted by the since-removed prompt\n * workflow commands; it stays rejected here so anyone carrying an old\n * invocation gets the explanation rather than an unknown-flag error.\n */\nconst DEPRECATED_BACKGROUND_FLAGS = ['--bg', '--async'];\n\n/**\n * Thrown when a command's argument text still contains a background-mode\n * flag. Distinct from a generic parse error so the message can say\n * specifically why the flag is gone, not just that it was unexpected -\n * caught the same way as any other `SlashParseError` by\n * `reportKnownErrorOrRethrow`.\n */\nexport class DeprecatedBackgroundFlagError extends SlashParseError {\n constructor(readonly flag: string) {\n super(`'${flag}' is no longer needed: every run in this package is already background.`);\n this.name = 'DeprecatedBackgroundFlagError';\n }\n}\n\nfunction matchesTrailingFlag(text: string, flag: string): boolean {\n return text === flag || text.endsWith(` ${flag}`);\n}\n\nfunction stripTrailingFlag(text: string, flag: string): string {\n return text === flag ? '' : text.slice(0, -(flag.length + 1)).trim();\n}\n\n/**\n * Removes a trailing ` --fork` flag, returning the remaining argument text.\n *\n * `--bg`/`--async` are gone entirely - not stripped, not accepted, not\n * silently ignored. A user typing `--bg` out of habit gets an explicit,\n * named rejection here rather than falling through as literal text that\n * then produces an unrelated \"no such agent\" error further down the\n * pipeline, which points at the wrong problem. See `subagentLaunch.ts`'s\n * module doc for why background is the only mode.\n */\nexport function extractForkFlag(rawArgs: string): { args: string; fork: boolean } {\n let trimmed = rawArgs.trim();\n let fork = false;\n for (;;) {\n if (matchesTrailingFlag(trimmed, FORK_FLAG)) {\n fork = true;\n trimmed = stripTrailingFlag(trimmed, FORK_FLAG);\n continue;\n }\n const deprecatedFlag = DEPRECATED_BACKGROUND_FLAGS.find((flag) => matchesTrailingFlag(trimmed, flag));\n if (deprecatedFlag) throw new DeprecatedBackgroundFlagError(deprecatedFlag);\n break;\n }\n return { args: trimmed, fork };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e){let t={};for(let n of e.split(`,`)){let e=n.trim();if(!e)continue;let r=e.indexOf(`=`);if(r===-1){e===`progress`&&(t.progress=!0);continue}let i=e.slice(0,r).trim(),a=e.slice(r+1).trim();switch(i){case`output`:t.output=a===`false`?!1:a;break;case`outputMode`:(a===`inline`||a===`file-only`)&&(t.outputMode=a);break;case`reads`:t.reads=a===`false`?!1:a.split(`+`).filter(Boolean);break;case`model`:t.model=a||void 0;break;case`skill`:case`skills`:t.skill=a===`false`?!1:a.split(`+`).filter(Boolean);break;case`progress`:t.progress=a!==`false`;break;case`as`:t.as=a||void 0;break;case`label`:t.label=a||void 0;break;case`phase`:t.phase=a||void 0;break;case`cwd`:t.cwd=a||void 0;break;case`count`:{let e=Number(a);Number.isInteger(e)&&e>0&&(t.count=e);break}case`outputSchema`:t.outputSchema=a||void 0;break;case`acceptance`:t.acceptance=a||void 0;break}}return t}function t(t){let n=t.indexOf(`[`);if(n===-1)return{name:t,config:{}};let r=t.lastIndexOf(`]`);return{name:t.slice(0,n),config:e(t.slice(n+1,r===-1?void 0:r))}}var n=class extends Error{};function r(e){let n,r,i=e.match(/^(\S+(?:\[[^\]]*\])?)\s+(?:"([^"]*)"|'([^']*)')$/);if(i)n=i[1],r=(i[2]??i[3])||void 0;else{let t=e.indexOf(` -- `);t===-1?n=e:(n=e.slice(0,t).trim(),r=e.slice(t+4).trim()||void 0)}return{kind:`step`,...t(n),task:r}}const i=`--fork`,a=[`--bg`,`--async`];var o=class extends n{constructor(e){super(`'${e}' is no longer needed: every run in this package is already background.`),this.flag=e,this.name=`DeprecatedBackgroundFlagError`}};function s(e,t){return e===t||e.endsWith(` ${t}`)}function c(e,t){return e===t?``:e.slice(0,-(t.length+1)).trim()}function l(e){let t=e.trim(),n=!1;for(;;){if(s(t,i)){n=!0,t=c(t,i);continue}let e=a.find(e=>s(t,e));if(e)throw new o(e);break}return{args:t,fork:n}}export{n as SlashParseError,l as extractForkFlag,t as parseAgentToken,r as parseSingleTaskToken};
|
|
2
|
+
//# sourceMappingURL=chainExpression.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chainExpression.mjs","names":[],"sources":["../../src/slash/chainExpression.ts"],"sourcesContent":["/**\n * Parses `/chain`/`/parallel`/`/run` slash-command argument strings into\n * structured steps: inline per-agent config (`agent[key=value,...]`),\n * `->`-separated chain steps, and `(a | b)`-style parallel groups within a\n * chain. Pure string parsing - nothing here calls into `SpawnPlanner` or\n * knows what a parsed field is used for; see `subagentLaunch.ts` for the\n * execution side and whichever module maps a `ParsedStep` onto a\n * `SpawnPlanTaskInput`/`SpawnPlanChainStepInput` for what happens to a\n * field this parser accepts once `SpawnPlanner`'s own request shape is\n * settled for this port (see the port's own tracking, not this file).\n *\n * WHY THIS IS ITS OWN MODULE, SEPARATE FROM COMMAND REGISTRATION:\n * The predecessor kept this logic inline in `slashCommands.ts`. Splitting\n * it out means the string-parsing rules - which are intricate and worth\n * testing in isolation (quote tracking, nested parens, top-level-only arrow\n * and pipe splitting) - do not need a `pi.registerCommand` fixture to test,\n * and stay unaffected by whatever `SpawnPlanner` request shape a caller\n * eventually maps a `ParsedStep` onto.\n *\n * AVOID:\n * - Adding execution or `SpawnPlanner` knowledge here. If a function needs\n * to know what a field does once parsed, it belongs in the caller, not\n * this file\n */\n\nexport interface InlineConfig {\n output?: string | false;\n outputMode?: 'inline' | 'file-only';\n reads?: string[] | false;\n model?: string;\n skill?: string[] | false;\n progress?: boolean;\n as?: string;\n label?: string;\n phase?: string;\n cwd?: string;\n count?: number;\n outputSchema?: string;\n acceptance?: string;\n}\n\n/** Parses the `key=value,...` body of `agent[...]` inline config. Unknown keys are ignored, not rejected. */\nexport function parseInlineConfig(raw: string): InlineConfig {\n const config: InlineConfig = {};\n for (const part of raw.split(',')) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n const eq = trimmed.indexOf('=');\n if (eq === -1) {\n if (trimmed === 'progress') config.progress = true;\n continue;\n }\n const key = trimmed.slice(0, eq).trim();\n const val = trimmed.slice(eq + 1).trim();\n switch (key) {\n case 'output':\n config.output = val === 'false' ? false : val;\n break;\n case 'outputMode':\n if (val === 'inline' || val === 'file-only') config.outputMode = val;\n break;\n case 'reads':\n config.reads = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'model':\n config.model = val || undefined;\n break;\n case 'skill':\n case 'skills':\n config.skill = val === 'false' ? false : val.split('+').filter(Boolean);\n break;\n case 'progress':\n config.progress = val !== 'false';\n break;\n case 'as':\n config.as = val || undefined;\n break;\n case 'label':\n config.label = val || undefined;\n break;\n case 'phase':\n config.phase = val || undefined;\n break;\n case 'cwd':\n config.cwd = val || undefined;\n break;\n case 'count': {\n const n = Number(val);\n if (Number.isInteger(n) && n > 0) config.count = n;\n break;\n }\n case 'outputSchema':\n config.outputSchema = val || undefined;\n break;\n case 'acceptance':\n config.acceptance = val || undefined;\n break;\n }\n }\n return config;\n}\n\n/** Splits `agent[key=value]` into the bare agent name and its parsed inline config. */\nexport function parseAgentToken(token: string): { name: string; config: InlineConfig } {\n const bracket = token.indexOf('[');\n if (bracket === -1) return { name: token, config: {} };\n const end = token.lastIndexOf(']');\n return {\n name: token.slice(0, bracket),\n config: parseInlineConfig(token.slice(bracket + 1, end !== -1 ? end : undefined)),\n };\n}\n\nexport interface ParsedStep {\n kind: 'step';\n name: string;\n config: InlineConfig;\n task?: string;\n}\n\nexport class SlashParseError extends Error {}\n\nexport function parseSingleTaskToken(token: string): ParsedStep {\n let agentPart: string;\n let task: string | undefined;\n const qMatch = token.match(/^(\\S+(?:\\[[^\\]]*\\])?)\\s+(?:\"([^\"]*)\"|'([^']*)')$/);\n if (qMatch) {\n agentPart = qMatch[1]!;\n task = (qMatch[2] ?? qMatch[3]) || undefined;\n } else {\n const dashIdx = token.indexOf(' -- ');\n if (dashIdx !== -1) {\n agentPart = token.slice(0, dashIdx).trim();\n task = token.slice(dashIdx + 4).trim() || undefined;\n } else {\n agentPart = token;\n }\n }\n return { kind: 'step', ...parseAgentToken(agentPart), task };\n}\n\n/**\n * User-typed flag selecting fork context for a run.\n *\n * Named because it is part of the command surface a user types, so the literal\n * appears in the parser, in help text and in any error naming it. Three copies\n * of a user-facing token drift one edit at a time, and the failure mode is a\n * flag the help promises and the parser does not accept.\n */\nconst FORK_FLAG = '--fork';\n\n/**\n * The predecessor's flags that used to select background execution. `--async`\n * was a synonym for the same flag, accepted by the since-removed prompt\n * workflow commands; it stays rejected here so anyone carrying an old\n * invocation gets the explanation rather than an unknown-flag error.\n */\nconst DEPRECATED_BACKGROUND_FLAGS = ['--bg', '--async'];\n\n/**\n * Thrown when a command's argument text still contains a background-mode\n * flag. Distinct from a generic parse error so the message can say\n * specifically why the flag is gone, not just that it was unexpected -\n * caught the same way as any other `SlashParseError` by\n * `reportKnownErrorOrRethrow`.\n */\nexport class DeprecatedBackgroundFlagError extends SlashParseError {\n constructor(readonly flag: string) {\n super(`'${flag}' is no longer needed: every run in this package is already background.`);\n this.name = 'DeprecatedBackgroundFlagError';\n }\n}\n\nfunction matchesTrailingFlag(text: string, flag: string): boolean {\n return text === flag || text.endsWith(` ${flag}`);\n}\n\nfunction stripTrailingFlag(text: string, flag: string): string {\n return text === flag ? '' : text.slice(0, -(flag.length + 1)).trim();\n}\n\n/**\n * Removes a trailing ` --fork` flag, returning the remaining argument text.\n *\n * `--bg`/`--async` are gone entirely - not stripped, not accepted, not\n * silently ignored. A user typing `--bg` out of habit gets an explicit,\n * named rejection here rather than falling through as literal text that\n * then produces an unrelated \"no such agent\" error further down the\n * pipeline, which points at the wrong problem. See `subagentLaunch.ts`'s\n * module doc for why background is the only mode.\n */\nexport function extractForkFlag(rawArgs: string): { args: string; fork: boolean } {\n let trimmed = rawArgs.trim();\n let fork = false;\n for (;;) {\n if (matchesTrailingFlag(trimmed, FORK_FLAG)) {\n fork = true;\n trimmed = stripTrailingFlag(trimmed, FORK_FLAG);\n continue;\n }\n const deprecatedFlag = DEPRECATED_BACKGROUND_FLAGS.find((flag) => matchesTrailingFlag(trimmed, flag));\n if (deprecatedFlag) throw new DeprecatedBackgroundFlagError(deprecatedFlag);\n break;\n }\n return { args: trimmed, fork };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const e=require(`../_virtual/_rolldown/runtime.cjs`);require(`../env.cjs`);const t=require(`../shared/paths.cjs`),n=require(`../intercom/intercomBridge.cjs`);let r=require(`node:fs`);r=e.__toESM(r,1);let i=require(`@agimon-ai/doompi-extension-contracts/child-process`);function a(e){return e instanceof Error?`${e.name}: ${e.message}`:String(e)}function o(e,t){try{return t()}catch(t){return`- ${e}: failed - ${a(t)}`}}function s(e,t){try{if(!r.existsSync(t))return`- ${e}: missing (${t})`;if(!r.statSync(t).isDirectory())throw Error(`not a directory: ${t}`);return r.accessSync(t,r.constants.R_OK|r.constants.W_OK),`- ${e}: ok (${t})`}catch(n){return`- ${e}: failed (${t}) - ${a(n)}`}}const c=[`plugin`,`user`,`project`],l=[`project`,`project-settings`,`user`,`user-settings`,`extension`,`builtin`,`unknown`];function u(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=c.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function d(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=l.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function f(e){let t=[`- current session file: ${e.currentSessionFile??`not available`}`,`- current session id: ${e.currentSessionId??`not available`}`];return e.sessionError&&t.push(`- session manager: failed - ${e.sessionError}`),t}function p(e,t){return[o(`agents`,()=>{let n=t.discovery.discover(e.cwd,e.agentScope).agents;return`- agents: total ${n.length} (${u(n)})`}),o(`skills`,()=>{let n=t.skills.discoverAvailableSkills(e.cwd);return`- skills: total ${n.length} (${d(n)})`})]}function m(){let e=[],t=(process.env[i.SUBAGENT_PARENT_SESSION_ENV]??``).trim();e.push(t?`- parent session: set (${t})`:`- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI`);let n=process.env[i.SUBAGENT_CHILD_ENV]===`1`;return e.push(`- subagent process: ${n?`yes (${i.SUBAGENT_CHILD_ENV}=1)`:`no`}`),e}function h(e){return o(`intercom bridge`,()=>{let t=n.diagnoseIntercomBridge({config:e.intercomBridgeConfig,context:e.context,orchestratorTarget:e.orchestratorTarget});return[`- bridge: ${t.active?`active`:`inactive`}${t.reason?` (${t.reason})`:``}`,`- mode: ${t.mode}; context: ${e.context??`unspecified`}`,`- orchestrator target: ${t.orchestratorTarget??`not available`}`,`- intercom: ${t.intercomAvailable?`available`:`unavailable`} (${t.extensionDir})`].join(`
|
|
2
|
+
`)}).split(`
|
|
3
|
+
`)}function g(e,n){return[`Subagents doctor report`,``,`Runtime`,`- cwd: ${e.cwd}`,`- async support: available (this package is async-only)`,...f(e),``,`Filesystem`,s(`temp root`,t.TEMP_ROOT_DIR),s(`runs`,t.currentRunsDir()),s(`results`,t.currentResultsDir()),``,`Discovery`,...p(e,n),``,`Permission system`,...m(),``,`Intercom bridge`,...h(e)].join(`
|
|
4
|
+
`)}exports.buildDoctorReport=g;
|
|
5
|
+
//# sourceMappingURL=doctor.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.cjs","names":["fs","SUBAGENT_PARENT_SESSION_ENV","SUBAGENT_CHILD_ENV","diagnoseIntercomBridge","TEMP_ROOT_DIR","currentRunsDir","currentResultsDir"],"sources":["../../src/slash/doctor.ts"],"sourcesContent":["/**\n * `/subagents-doctor`: a diagnostic report of this package's own runtime\n * state - filesystem roots, agent/skill discovery, the intercom bridge, and\n * the child-process signal env vars - for a user debugging \"why didn't my\n * subagent do X\".\n *\n * WHY THIS PORTS AS A SMALL PORT, NOT A DEFERRAL:\n * Read (not ported) the predecessor's foreground executor's `doctor` action\n * and `extension/doctor.ts`'s `buildDoctorReport` in full before deciding.\n * Every section it builds has a real doom-team equivalent: filesystem roots\n * (`shared/paths.ts`), agent/skill discovery (`AgentDiscoveryService`/\n * `SkillDiscoveryService`), the permission-system env signals\n * (`SUBAGENT_CHILD_ENV`/`SUBAGENT_PARENT_SESSION_ENV` - same wire names),\n * and the intercom bridge diagnostic (`diagnoseIntercomBridge`, already\n * ported). This package is also inherently async-only, so the predecessor's\n * \"async support: available/unavailable\" runtime check has nothing to\n * branch on here - it always reports available.\n *\n * WHAT IS DELIBERATELY LEFT OUT, AND WHY:\n * - Chain and prompt-workflow counts. The saved-work surface was REMOVED BY\n * DECISION (see `slashCommands.ts`'s header), so there is nothing to\n * count rather than something not yet built. Reporting a zero would imply\n * a feature that is simply absent\n * - The spawn-budget section entirely. `runs/shared/spawn-budget.ts` DOES\n * exist, but its own header says `maxSubagentSpawnsPerSession` is NOT\n * enforced by `SpawnPlanner` yet. Reporting a budget number nothing\n * enforces would be the same class of lie as parsing an inline-config\n * field and silently ignoring it - see `spawnRequestMapping.ts`\n *\n * AVOID:\n * - Reporting a spawn budget. There is no enforcement to report on yet\n */\n\nimport * as fs from 'node:fs';\n\nimport type { DiscoveredSkill, ISkillDiscoveryService, SkillSource } from '../agents/skills.ts';\nimport type { AgentScope, AgentSource, IAgentDiscoveryService } from '../agents/types.ts';\nimport { SUBAGENT_CHILD_ENV, SUBAGENT_PARENT_SESSION_ENV } from '../env.ts';\nimport { diagnoseIntercomBridge, type IntercomBridgeConfigInput } from '../intercom/intercomBridge.ts';\nimport { currentResultsDir, currentRunsDir, TEMP_ROOT_DIR } from '../shared/paths.ts';\n\nexport interface DoctorReportInput {\n cwd: string;\n agentScope: AgentScope;\n intercomBridgeConfig?: IntercomBridgeConfigInput;\n context?: 'fresh' | 'fork';\n orchestratorTarget?: string;\n currentSessionFile?: string | null;\n currentSessionId?: string | null;\n sessionError?: string;\n}\n\nexport interface DoctorReportDeps {\n discovery: IAgentDiscoveryService;\n skills: ISkillDiscoveryService;\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? `${error.name}: ${error.message}` : String(error);\n}\n\nfunction lineFromCheck(label: string, check: () => string): string {\n try {\n return check();\n } catch (error) {\n return `- ${label}: failed - ${errorText(error)}`;\n }\n}\n\nfunction formatExistingDirectory(label: string, dirPath: string): string {\n try {\n if (!fs.existsSync(dirPath)) return `- ${label}: missing (${dirPath})`;\n const stats = fs.statSync(dirPath);\n if (!stats.isDirectory()) throw new Error(`not a directory: ${dirPath}`);\n fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n return `- ${label}: ok (${dirPath})`;\n } catch (error) {\n return `- ${label}: failed (${dirPath}) - ${errorText(error)}`;\n }\n}\n\nconst AGENT_SOURCE_ORDER: AgentSource[] = ['plugin', 'user', 'project'];\nconst SKILL_SOURCE_ORDER: SkillSource[] = [\n 'project',\n 'project-settings',\n 'user',\n 'user-settings',\n 'extension',\n 'builtin',\n 'unknown',\n];\n\nfunction formatSourceCounts(agents: Array<{ source: AgentSource }>): string {\n const counts = new Map<AgentSource, number>();\n for (const agent of agents) counts.set(agent.source, (counts.get(agent.source) ?? 0) + 1);\n const parts = AGENT_SOURCE_ORDER.map((source) => `${source} ${counts.get(source) ?? 0}`).filter(\n (part) => !part.endsWith(' 0'),\n );\n return parts.length > 0 ? parts.join(', ') : 'none';\n}\n\nfunction formatSkillSourceCounts(skills: DiscoveredSkill[]): string {\n const counts = new Map<SkillSource, number>();\n for (const skill of skills) counts.set(skill.source, (counts.get(skill.source) ?? 0) + 1);\n const parts = SKILL_SOURCE_ORDER.map((source) => `${source} ${counts.get(source) ?? 0}`).filter(\n (part) => !part.endsWith(' 0'),\n );\n return parts.length > 0 ? parts.join(', ') : 'none';\n}\n\nfunction formatSessionLines(input: DoctorReportInput): string[] {\n const lines = [\n `- current session file: ${input.currentSessionFile ?? 'not available'}`,\n `- current session id: ${input.currentSessionId ?? 'not available'}`,\n ];\n if (input.sessionError) lines.push(`- session manager: failed - ${input.sessionError}`);\n return lines;\n}\n\nfunction formatDiscovery(input: DoctorReportInput, deps: DoctorReportDeps): string[] {\n return [\n lineFromCheck('agents', () => {\n const agents = deps.discovery.discover(input.cwd, input.agentScope).agents;\n return `- agents: total ${agents.length} (${formatSourceCounts(agents)})`;\n }),\n lineFromCheck('skills', () => {\n const skills = deps.skills.discoverAvailableSkills(input.cwd);\n return `- skills: total ${skills.length} (${formatSkillSourceCounts(skills)})`;\n }),\n ];\n}\n\nfunction formatPermissionSystemSection(): string[] {\n const lines: string[] = [];\n const parentSession = (process.env[SUBAGENT_PARENT_SESSION_ENV] ?? '').trim();\n lines.push(\n parentSession\n ? `- parent session: set (${parentSession})`\n : '- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI',\n );\n const isChild = process.env[SUBAGENT_CHILD_ENV] === '1';\n lines.push(`- subagent process: ${isChild ? `yes (${SUBAGENT_CHILD_ENV}=1)` : 'no'}`);\n return lines;\n}\n\nfunction formatIntercomSection(input: DoctorReportInput): string[] {\n return lineFromCheck('intercom bridge', () => {\n const diagnostic = diagnoseIntercomBridge({\n config: input.intercomBridgeConfig,\n context: input.context,\n orchestratorTarget: input.orchestratorTarget,\n });\n return [\n `- bridge: ${diagnostic.active ? 'active' : 'inactive'}${diagnostic.reason ? ` (${diagnostic.reason})` : ''}`,\n `- mode: ${diagnostic.mode}; context: ${input.context ?? 'unspecified'}`,\n `- orchestrator target: ${diagnostic.orchestratorTarget ?? 'not available'}`,\n `- intercom: ${diagnostic.intercomAvailable ? 'available' : 'unavailable'} (${diagnostic.extensionDir})`,\n ].join('\\n');\n }).split('\\n');\n}\n\nexport function buildDoctorReport(input: DoctorReportInput, deps: DoctorReportDeps): string {\n const lines = [\n 'Subagents doctor report',\n '',\n 'Runtime',\n `- cwd: ${input.cwd}`,\n '- async support: available (this package is async-only)',\n ...formatSessionLines(input),\n '',\n 'Filesystem',\n formatExistingDirectory('temp root', TEMP_ROOT_DIR),\n formatExistingDirectory('runs', currentRunsDir()),\n formatExistingDirectory('results', currentResultsDir()),\n '',\n 'Discovery',\n ...formatDiscovery(input, deps),\n '',\n 'Permission system',\n ...formatPermissionSystemSection(),\n '',\n 'Intercom bridge',\n ...formatIntercomSection(input),\n ];\n return lines.join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{SUBAGENT_CHILD_ENV as e,SUBAGENT_PARENT_SESSION_ENV as t,init_env as n}from"../env.mjs";import{TEMP_ROOT_DIR as r,currentResultsDir as i,currentRunsDir as a,init_paths as o}from"../shared/paths.mjs";import{diagnoseIntercomBridge as s}from"../intercom/intercomBridge.mjs";import*as c from"node:fs";n(),o();function l(e){return e instanceof Error?`${e.name}: ${e.message}`:String(e)}function u(e,t){try{return t()}catch(t){return`- ${e}: failed - ${l(t)}`}}function d(e,t){try{if(!c.existsSync(t))return`- ${e}: missing (${t})`;if(!c.statSync(t).isDirectory())throw Error(`not a directory: ${t}`);return c.accessSync(t,c.constants.R_OK|c.constants.W_OK),`- ${e}: ok (${t})`}catch(n){return`- ${e}: failed (${t}) - ${l(n)}`}}const f=[`plugin`,`user`,`project`],p=[`project`,`project-settings`,`user`,`user-settings`,`extension`,`builtin`,`unknown`];function m(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=f.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function h(e){let t=new Map;for(let n of e)t.set(n.source,(t.get(n.source)??0)+1);let n=p.map(e=>`${e} ${t.get(e)??0}`).filter(e=>!e.endsWith(` 0`));return n.length>0?n.join(`, `):`none`}function g(e){let t=[`- current session file: ${e.currentSessionFile??`not available`}`,`- current session id: ${e.currentSessionId??`not available`}`];return e.sessionError&&t.push(`- session manager: failed - ${e.sessionError}`),t}function _(e,t){return[u(`agents`,()=>{let n=t.discovery.discover(e.cwd,e.agentScope).agents;return`- agents: total ${n.length} (${m(n)})`}),u(`skills`,()=>{let n=t.skills.discoverAvailableSkills(e.cwd);return`- skills: total ${n.length} (${h(n)})`})]}function v(){let n=[],r=(process.env[t]??``).trim();n.push(r?`- parent session: set (${r})`:`- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI`);let i=process.env[e]===`1`;return n.push(`- subagent process: ${i?`yes (${e}=1)`:`no`}`),n}function y(e){return u(`intercom bridge`,()=>{let t=s({config:e.intercomBridgeConfig,context:e.context,orchestratorTarget:e.orchestratorTarget});return[`- bridge: ${t.active?`active`:`inactive`}${t.reason?` (${t.reason})`:``}`,`- mode: ${t.mode}; context: ${e.context??`unspecified`}`,`- orchestrator target: ${t.orchestratorTarget??`not available`}`,`- intercom: ${t.intercomAvailable?`available`:`unavailable`} (${t.extensionDir})`].join(`
|
|
2
|
+
`)}).split(`
|
|
3
|
+
`)}function b(e,t){return[`Subagents doctor report`,``,`Runtime`,`- cwd: ${e.cwd}`,`- async support: available (this package is async-only)`,...g(e),``,`Filesystem`,d(`temp root`,r),d(`runs`,a()),d(`results`,i()),``,`Discovery`,..._(e,t),``,`Permission system`,...v(),``,`Intercom bridge`,...y(e)].join(`
|
|
4
|
+
`)}export{b as buildDoctorReport};
|
|
5
|
+
//# sourceMappingURL=doctor.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.mjs","names":[],"sources":["../../src/slash/doctor.ts"],"sourcesContent":["/**\n * `/subagents-doctor`: a diagnostic report of this package's own runtime\n * state - filesystem roots, agent/skill discovery, the intercom bridge, and\n * the child-process signal env vars - for a user debugging \"why didn't my\n * subagent do X\".\n *\n * WHY THIS PORTS AS A SMALL PORT, NOT A DEFERRAL:\n * Read (not ported) the predecessor's foreground executor's `doctor` action\n * and `extension/doctor.ts`'s `buildDoctorReport` in full before deciding.\n * Every section it builds has a real doom-team equivalent: filesystem roots\n * (`shared/paths.ts`), agent/skill discovery (`AgentDiscoveryService`/\n * `SkillDiscoveryService`), the permission-system env signals\n * (`SUBAGENT_CHILD_ENV`/`SUBAGENT_PARENT_SESSION_ENV` - same wire names),\n * and the intercom bridge diagnostic (`diagnoseIntercomBridge`, already\n * ported). This package is also inherently async-only, so the predecessor's\n * \"async support: available/unavailable\" runtime check has nothing to\n * branch on here - it always reports available.\n *\n * WHAT IS DELIBERATELY LEFT OUT, AND WHY:\n * - Chain and prompt-workflow counts. The saved-work surface was REMOVED BY\n * DECISION (see `slashCommands.ts`'s header), so there is nothing to\n * count rather than something not yet built. Reporting a zero would imply\n * a feature that is simply absent\n * - The spawn-budget section entirely. `runs/shared/spawn-budget.ts` DOES\n * exist, but its own header says `maxSubagentSpawnsPerSession` is NOT\n * enforced by `SpawnPlanner` yet. Reporting a budget number nothing\n * enforces would be the same class of lie as parsing an inline-config\n * field and silently ignoring it - see `spawnRequestMapping.ts`\n *\n * AVOID:\n * - Reporting a spawn budget. There is no enforcement to report on yet\n */\n\nimport * as fs from 'node:fs';\n\nimport type { DiscoveredSkill, ISkillDiscoveryService, SkillSource } from '../agents/skills.ts';\nimport type { AgentScope, AgentSource, IAgentDiscoveryService } from '../agents/types.ts';\nimport { SUBAGENT_CHILD_ENV, SUBAGENT_PARENT_SESSION_ENV } from '../env.ts';\nimport { diagnoseIntercomBridge, type IntercomBridgeConfigInput } from '../intercom/intercomBridge.ts';\nimport { currentResultsDir, currentRunsDir, TEMP_ROOT_DIR } from '../shared/paths.ts';\n\nexport interface DoctorReportInput {\n cwd: string;\n agentScope: AgentScope;\n intercomBridgeConfig?: IntercomBridgeConfigInput;\n context?: 'fresh' | 'fork';\n orchestratorTarget?: string;\n currentSessionFile?: string | null;\n currentSessionId?: string | null;\n sessionError?: string;\n}\n\nexport interface DoctorReportDeps {\n discovery: IAgentDiscoveryService;\n skills: ISkillDiscoveryService;\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? `${error.name}: ${error.message}` : String(error);\n}\n\nfunction lineFromCheck(label: string, check: () => string): string {\n try {\n return check();\n } catch (error) {\n return `- ${label}: failed - ${errorText(error)}`;\n }\n}\n\nfunction formatExistingDirectory(label: string, dirPath: string): string {\n try {\n if (!fs.existsSync(dirPath)) return `- ${label}: missing (${dirPath})`;\n const stats = fs.statSync(dirPath);\n if (!stats.isDirectory()) throw new Error(`not a directory: ${dirPath}`);\n fs.accessSync(dirPath, fs.constants.R_OK | fs.constants.W_OK);\n return `- ${label}: ok (${dirPath})`;\n } catch (error) {\n return `- ${label}: failed (${dirPath}) - ${errorText(error)}`;\n }\n}\n\nconst AGENT_SOURCE_ORDER: AgentSource[] = ['plugin', 'user', 'project'];\nconst SKILL_SOURCE_ORDER: SkillSource[] = [\n 'project',\n 'project-settings',\n 'user',\n 'user-settings',\n 'extension',\n 'builtin',\n 'unknown',\n];\n\nfunction formatSourceCounts(agents: Array<{ source: AgentSource }>): string {\n const counts = new Map<AgentSource, number>();\n for (const agent of agents) counts.set(agent.source, (counts.get(agent.source) ?? 0) + 1);\n const parts = AGENT_SOURCE_ORDER.map((source) => `${source} ${counts.get(source) ?? 0}`).filter(\n (part) => !part.endsWith(' 0'),\n );\n return parts.length > 0 ? parts.join(', ') : 'none';\n}\n\nfunction formatSkillSourceCounts(skills: DiscoveredSkill[]): string {\n const counts = new Map<SkillSource, number>();\n for (const skill of skills) counts.set(skill.source, (counts.get(skill.source) ?? 0) + 1);\n const parts = SKILL_SOURCE_ORDER.map((source) => `${source} ${counts.get(source) ?? 0}`).filter(\n (part) => !part.endsWith(' 0'),\n );\n return parts.length > 0 ? parts.join(', ') : 'none';\n}\n\nfunction formatSessionLines(input: DoctorReportInput): string[] {\n const lines = [\n `- current session file: ${input.currentSessionFile ?? 'not available'}`,\n `- current session id: ${input.currentSessionId ?? 'not available'}`,\n ];\n if (input.sessionError) lines.push(`- session manager: failed - ${input.sessionError}`);\n return lines;\n}\n\nfunction formatDiscovery(input: DoctorReportInput, deps: DoctorReportDeps): string[] {\n return [\n lineFromCheck('agents', () => {\n const agents = deps.discovery.discover(input.cwd, input.agentScope).agents;\n return `- agents: total ${agents.length} (${formatSourceCounts(agents)})`;\n }),\n lineFromCheck('skills', () => {\n const skills = deps.skills.discoverAvailableSkills(input.cwd);\n return `- skills: total ${skills.length} (${formatSkillSourceCounts(skills)})`;\n }),\n ];\n}\n\nfunction formatPermissionSystemSection(): string[] {\n const lines: string[] = [];\n const parentSession = (process.env[SUBAGENT_PARENT_SESSION_ENV] ?? '').trim();\n lines.push(\n parentSession\n ? `- parent session: set (${parentSession})`\n : '- parent session: not set - ask forwarding from a subprocess child will not reach a parent UI',\n );\n const isChild = process.env[SUBAGENT_CHILD_ENV] === '1';\n lines.push(`- subagent process: ${isChild ? `yes (${SUBAGENT_CHILD_ENV}=1)` : 'no'}`);\n return lines;\n}\n\nfunction formatIntercomSection(input: DoctorReportInput): string[] {\n return lineFromCheck('intercom bridge', () => {\n const diagnostic = diagnoseIntercomBridge({\n config: input.intercomBridgeConfig,\n context: input.context,\n orchestratorTarget: input.orchestratorTarget,\n });\n return [\n `- bridge: ${diagnostic.active ? 'active' : 'inactive'}${diagnostic.reason ? ` (${diagnostic.reason})` : ''}`,\n `- mode: ${diagnostic.mode}; context: ${input.context ?? 'unspecified'}`,\n `- orchestrator target: ${diagnostic.orchestratorTarget ?? 'not available'}`,\n `- intercom: ${diagnostic.intercomAvailable ? 'available' : 'unavailable'} (${diagnostic.extensionDir})`,\n ].join('\\n');\n }).split('\\n');\n}\n\nexport function buildDoctorReport(input: DoctorReportInput, deps: DoctorReportDeps): string {\n const lines = [\n 'Subagents doctor report',\n '',\n 'Runtime',\n `- cwd: ${input.cwd}`,\n '- async support: available (this package is async-only)',\n ...formatSessionLines(input),\n '',\n 'Filesystem',\n formatExistingDirectory('temp root', TEMP_ROOT_DIR),\n formatExistingDirectory('runs', currentRunsDir()),\n formatExistingDirectory('results', currentResultsDir()),\n '',\n 'Discovery',\n ...formatDiscovery(input, deps),\n '',\n 'Permission system',\n ...formatPermissionSystemSection(),\n '',\n 'Intercom bridge',\n ...formatIntercomSection(input),\n ];\n return lines.join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const e=require(`../shared/modelResolution.cjs`),t=require(`../runs/shared/modelFallback.cjs`),n=require(`../extensions/spawnPlan.cjs`),r=require(`../runs/background/asyncJobTracker.cjs`),i=require(`./chainExpression.cjs`),a=require(`./doctor.cjs`),o=require(`./spawnRequestMapping.cjs`),s=require(`./subagentLaunch.cjs`);function c(e,t){e.sendMessage({customType:`subagent-slash-result`,content:t,display:!0})}function l(e,t){e.hasUI&&e.ui.setStatus(`subagent-slash`,t)}function u(e,t){e.ui.notify(t,`error`)}function d(e,t){e.ui.notify(t,`info`)}function f(e){return e?e.attentionReason?`${e.status??`running`} - needs attention: ${e.attentionReason}`:e.activityState?`${e.status??`running`} - ${e.activityState}`:e.status??`running`:`starting…`}function p(e,t,n,i,a,o){s.watchTrackedRunUntilTerminal(n.scheduler,i,a,n=>{if(l(t,`${o} (${a}): ${f(n)}`),n?.status===void 0||!r.TERMINAL_ASYNC_JOB_STATES.has(n.status))return;l(t,void 0);let i=n.status===`complete`||n.status===`completed`?`completed`:n.status;c(e,n.error?`## Subagent ${i}\n\n${o} (${a})\n\n${n.error}`:`## Subagent ${i}\n\n${o} (${a})`)})}function m(e,t,n,r,i){let a=i.outcomes.filter(e=>e.runId),o=i.outcomes.filter(e=>!e.runId);if(a.length>0){c(e,`## Subagent started\n\n${a.map(e=>`${e.agent} (${e.runId})${e.warning?`\n Warning: ${e.warning}`:``}`).join(`, `)}`),l(t,`${a.length} run${a.length===1?``:`s`} started…`);for(let i of a)i.runId&&p(e,t,n,r,i.runId,i.agent)}o.length>0&&u(t,`Some subagents failed to start:\n${o.map(e=>`${e.agent}: ${e.error??`spawn failed`}`).join(`
|
|
2
|
+
`)}`)}function h(e,t){if(e.baseCwd)return e.baseCwd;u(t,`Subagent session cwd is not initialized yet`)}function g(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(u(r,`Unknown agent: ${n}`),!1)}function _(e,t){if(t instanceof o.UnsupportedInlineConfigError||t instanceof i.SlashParseError){u(e,t.message);return}throw t}function v(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>i.parseSingleTaskToken(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),a=t.slice(n+4).trim();if(!r||!a)return;let o=r.split(/\s+/).filter(Boolean).map(e=>i.parseSingleTaskToken(e));if(o.length!==0)return{steps:o,task:a,perStep:!1}}function y(l,f,p){l.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(r,a)=>{let c=p.tracker.forSession(a.sessionManager.getSessionId()),{args:d,fork:v}=i.extractForkFlag(r),y=d.trim();if(!y){u(a,`Usage: /run <agent> [task] [--fork]`);return}let b=y.indexOf(` `),{name:x,config:S}=i.parseAgentToken(b===-1?y:y.slice(0,b)),C=b===-1?``:y.slice(b+1).trim(),w=h(f,a);if(w&&g(p,w,x,a))try{let r=n.captureSessionForkSource(a.sessionManager,`settled`),i=t.normalizeParentModel(a.model),u=o.taskInputFromParsedStep({name:x,config:S,task:C},w,v?`fork`:void 0);m(l,a,p,c,await s.launchSingleSubagent(p.spawnPlanner,c,{agent:u.agent,task:u.task??``,cwd:u.cwd??w,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...u.model?{model:u.model}:{},...u.context?{context:u.context}:{},...r?{parentSessionFile:r.sessionFile,parentLeafId:r.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...i?{parentModel:i}:{}},p.loadConfig()))}catch(e){_(a,e)}}}),l.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(r,a)=>{let c=p.tracker.forSession(a.sessionManager.getSessionId()),{args:d,fork:y}=i.extractForkFlag(r),b=h(f,a);if(!b)return;let x=v(d);if(!x){u(a,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of x.steps)if(!g(p,b,e.name,a))return;if(!x.steps.some(e=>e.task)&&!x.task){u(a,`At least one step must have a task`);return}try{let r=n.captureSessionForkSource(a.sessionManager,`settled`),i=t.normalizeParentModel(a.model),u=x.steps.map(e=>o.taskInputFromParsedStep({name:e.name,config:e.config,task:e.task??x.task},b,y?`fork`:void 0));m(l,a,p,c,await s.launchParallelSubagents(p.spawnPlanner,c,{tasks:u,cwd:b,agentScope:`both`,parentSessionId:a.sessionManager.getSessionId(),...r?{parentSessionFile:r.sessionFile,parentLeafId:r.leafId}:{},availableModels:e.authenticatedModelInfos(a.modelRegistry),...i?{parentModel:i}:{}},p.loadConfig()))}catch(e){_(a,e)}}}),l.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,t)=>{c(l,a.buildDoctorReport({cwd:t.cwd,agentScope:`both`},{discovery:p.discovery,skills:p.skills}))}}),l.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,t)=>{let n=p.tracker.forSession(t.sessionManager.getSessionId()),i=e.trim();if(!i){c(l,b(n.list()));return}try{p.management.stop(r.resolveTrackedRunId(n,i)),d(t,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){u(t,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function b(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
|
|
3
|
+
`)}exports.registerSlashCommands=y;
|
|
4
|
+
//# sourceMappingURL=slashCommands.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slashCommands.cjs","names":["TERMINAL_ASYNC_JOB_STATES","UnsupportedInlineConfigError","SlashParseError","parseSingleTaskToken","extractForkFlag","parseAgentToken","captureSessionForkSource","normalizeParentModel","taskInputFromParsedStep","launchSingleSubagent","authenticatedModelInfos","launchParallelSubagents","buildDoctorReport","resolveTrackedRunId"],"sources":["../../src/slash/slashCommands.ts"],"sourcesContent":["/**\n * The core `/run`, `/chain`, `/parallel` slash commands. Replaces the\n * always-blocking predecessor with the async-only shape this port settled\n * on: a command launches a spawn, sends an initial status message, and\n * hands off to `watchTrackedRunUntilTerminal` (render-key gated, backed by\n * `PollScheduler`) to update the status bar and finalize the message once\n * the run reaches a terminal state - never by awaiting completion. See\n * `subagentLaunch.ts`'s module doc for the full reasoning.\n *\n * WHAT IS NOT HERE, AND WHY:\n * - `/run-chain`, `/prompt-workflow` and `/chain-prompts`: the whole SAVED\n * work surface - saved agent pipelines (`ChainConfig`, never ported) and\n * saved `.md` prompt templates (ported, then deleted). REMOVED BY\n * DECISION, not deferred: overly complicated for the use they were\n * getting. Do not re-add them because a reader notices the predecessor had\n * them. Ad-hoc chaining (`/chain scout \"x\" -> planner`) is a different\n * feature, lives in `chainExpression.ts`, and stays\n * - `/subagent-cost`: REMOVED BY DECISION. It reads usage/cost data\n * (`totalTokens`/`totalCost`) that nothing in this package's\n * runs/extensions surface tracks - a genuinely absent data source, and\n * building it would mean threading usage out of every child process\n * - `/subagents-check-profile`: removed at the source. Calls\n * `checkSubagentProfile`/`listSubagentProfiles`, which are referenced but\n * defined nowhere in the entire predecessor package - a live\n * `ReferenceError` that only shipped because that package sets\n * `noCheck: true`. Typecheck is on here; porting it faithfully would not\n * compile, and it was asked to be removed independently of that\n * - The `SUBAGENT_FLEET_COMMAND` registration and its `Ctrl+Alt+F` shortcut:\n * fleet view is its own piece, registered by whoever builds it\n * - Inline parallel groups within `/chain` (`(a | b)` syntax): the field\n * mapping for a group's own config exists (`spawnRequestMapping.ts`),\n * but wiring a group INTO a chain request is left for the same pass that\n * revisits per-task field support, so `/chain` reports a clear\n * not-yet-supported message rather than silently flattening a group\n * - `/subagents` (admin) command registration: a separate file, not yet\n * ported\n *\n * `/subagents-doctor` IS here, in `doctor.ts` - read (not ported) the\n * predecessor's foreground-executor `doctor` action before deciding, and it\n * turned out to be a small, mostly-mechanical port. See that module's own\n * doc for what it deliberately leaves out (chain counts, spawn-budget\n * reporting).\n *\n * AVOID:\n * - Awaiting a SINGLE/PARALLEL spawn for a result that will not exist yet.\n * See `subagentLaunch.ts`\n * - A private polling loop for a message's live status. Use\n * `watchTrackedRunUntilTerminal`\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport type { ISkillDiscoveryService } from '../agents/skills.ts';\nimport type { AgentScope, IAgentDiscoveryService } from '../agents/types.ts';\nimport type { ExtensionConfig } from '../extensions/config.ts';\nimport type { IManagementActions } from '../extensions/managementActions.ts';\nimport { captureSessionForkSource, type ISpawnPlanner, type SpawnPlanResult } from '../extensions/spawnPlan.ts';\nimport type { IAsyncJobTracker, ITrackedAsyncJobs, TrackedAsyncJob } from '../runs/background/asyncJobTracker.ts';\nimport { resolveTrackedRunId, TERMINAL_ASYNC_JOB_STATES } from '../runs/background/asyncJobTracker.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport { normalizeParentModel } from '../runs/shared/modelFallback.ts';\nimport { authenticatedModelInfos } from '../shared/modelResolution.ts';\nimport {\n extractForkFlag,\n parseAgentToken,\n parseSingleTaskToken,\n SlashParseError,\n type ParsedStep,\n} from './chainExpression.ts';\nimport { buildDoctorReport } from './doctor.ts';\nimport { taskInputFromParsedStep, UnsupportedInlineConfigError } from './spawnRequestMapping.ts';\nimport { launchParallelSubagents, launchSingleSubagent, watchTrackedRunUntilTerminal } from './subagentLaunch.ts';\n\nexport interface SlashCommandDeps {\n spawnPlanner: ISpawnPlanner;\n skills: ISkillDiscoveryService;\n tracker: IAsyncJobTracker;\n scheduler: IPollScheduler;\n discovery: IAgentDiscoveryService;\n /**\n * Used by `/subagents-stop`. Preferred over calling `requestSlashRunStop`\n * directly because it resolves an id PREFIX through `RunIdResolver` and\n * raises a real error for an unknown or ambiguous one, instead of writing a\n * stop request into a directory for a run that does not exist.\n */\n management: IManagementActions;\n loadConfig: () => ExtensionConfig;\n}\n\nexport interface SlashCommandState {\n baseCwd: string | undefined;\n}\n\nconst SLASH_STATUS_KEY = 'subagent-slash';\nconst SLASH_RESULT_CUSTOM_TYPE = 'subagent-slash-result';\n\nfunction sendSlashText(pi: ExtensionAPI, text: string): void {\n pi.sendMessage({ customType: SLASH_RESULT_CUSTOM_TYPE, content: text, display: true });\n}\n\nfunction setSlashStatus(ctx: ExtensionContext, text: string | undefined): void {\n if (ctx.hasUI) ctx.ui.setStatus(SLASH_STATUS_KEY, text);\n}\n\nfunction notifyError(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'error');\n}\n\nfunction notifyInfo(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'info');\n}\n\nfunction statusTextFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'starting…';\n if (job.attentionReason) return `${job.status ?? 'running'} - needs attention: ${job.attentionReason}`;\n if (job.activityState) return `${job.status ?? 'running'} - ${job.activityState}`;\n return job.status ?? 'running';\n}\n\n/**\n * Watches one launched run to a terminal state and finalizes its message.\n * Each launched run gets its own subscriber, so a PARALLEL launch's\n * siblings finalize independently rather than all waiting on the slowest.\n */\nfunction watchAndFinalize(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: ITrackedAsyncJobs,\n runId: string,\n agent: string,\n): void {\n watchTrackedRunUntilTerminal(deps.scheduler, jobs, runId, (job) => {\n setSlashStatus(ctx, `${agent} (${runId}): ${statusTextFor(job)}`);\n if (job?.status === undefined || !TERMINAL_ASYNC_JOB_STATES.has(job.status)) return;\n setSlashStatus(ctx, undefined);\n const outcome = job.status === 'complete' || job.status === 'completed' ? 'completed' : job.status;\n sendSlashText(\n pi,\n job.error\n ? `## Subagent ${outcome}\\n\\n${agent} (${runId})\\n\\n${job.error}`\n : `## Subagent ${outcome}\\n\\n${agent} (${runId})`,\n );\n });\n}\n\nfunction reportSpawnResult(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: ITrackedAsyncJobs,\n result: SpawnPlanResult,\n): void {\n const started = result.outcomes.filter((outcome) => outcome.runId);\n const failed = result.outcomes.filter((outcome) => !outcome.runId);\n if (started.length > 0) {\n const label = started\n .map(\n (outcome) => `${outcome.agent} (${outcome.runId})${outcome.warning ? `\\n Warning: ${outcome.warning}` : ''}`,\n )\n .join(', ');\n sendSlashText(pi, `## Subagent started\\n\\n${label}`);\n setSlashStatus(ctx, `${started.length} run${started.length === 1 ? '' : 's'} started…`);\n for (const outcome of started) {\n if (outcome.runId) watchAndFinalize(pi, ctx, deps, jobs, outcome.runId, outcome.agent);\n }\n }\n if (failed.length > 0) {\n const label = failed.map((outcome) => `${outcome.agent}: ${outcome.error ?? 'spawn failed'}`).join('\\n');\n notifyError(ctx, `Some subagents failed to start:\\n${label}`);\n }\n}\n\nfunction requireBaseCwd(state: SlashCommandState, ctx: ExtensionContext): string | undefined {\n if (state.baseCwd) return state.baseCwd;\n notifyError(ctx, 'Subagent session cwd is not initialized yet');\n return undefined;\n}\n\nfunction findAgentOrNotify(deps: SlashCommandDeps, baseCwd: string, name: string, ctx: ExtensionContext): boolean {\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (agents.find((agent) => agent.name === name)) return true;\n notifyError(ctx, `Unknown agent: ${name}`);\n return false;\n}\n\nfunction reportKnownErrorOrRethrow(ctx: ExtensionContext, error: unknown): void {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n notifyError(ctx, error.message);\n return;\n }\n throw error;\n}\n\n/**\n * Shared arg parsing for /chain (no inline group) and /parallel:\n * \"agent1 task1 -> agent2 task2\" or \"agent1 agent2 -- shared task\".\n */\nfunction parseAgentArgsFallback(input: string): { steps: ParsedStep[]; task: string; perStep: boolean } | undefined {\n const trimmed = input.trim();\n if (trimmed.includes(' -> ')) {\n const steps = trimmed\n .split(' -> ')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => parseSingleTaskToken(segment));\n if (steps.length === 0) return undefined;\n return { steps, task: steps.find((step) => step.task)?.task ?? '', perStep: true };\n }\n const delimiterIndex = trimmed.indexOf(' -- ');\n if (delimiterIndex === -1) return undefined;\n const agentsPart = trimmed.slice(0, delimiterIndex).trim();\n const sharedTask = trimmed.slice(delimiterIndex + 4).trim();\n if (!agentsPart || !sharedTask) return undefined;\n const steps = agentsPart\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => parseSingleTaskToken(token));\n if (steps.length === 0) return undefined;\n return { steps, task: sharedTask, perStep: false };\n}\n\nexport function registerSlashCommands(pi: ExtensionAPI, state: SlashCommandState, deps: SlashCommandDeps): void {\n pi.registerCommand('run', {\n description: 'Run a subagent in the background: /run agent[model=x] [task] [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const input = cleanedArgs.trim();\n if (!input) {\n notifyError(ctx, 'Usage: /run <agent> [task] [--fork]');\n return;\n }\n const firstSpace = input.indexOf(' ');\n const { name: agentName, config } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n const task = firstSpace === -1 ? '' : input.slice(firstSpace + 1).trim();\n\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n if (!findAgentOrNotify(deps, baseCwd, agentName, ctx)) return;\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const taskInput = taskInputFromParsedStep(\n { name: agentName, config, task },\n baseCwd,\n fork ? 'fork' : undefined,\n );\n const result = await launchSingleSubagent(\n deps.spawnPlanner,\n jobs,\n {\n agent: taskInput.agent,\n task: taskInput.task ?? '',\n cwd: taskInput.cwd ?? baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(taskInput.model ? { model: taskInput.model } : {}),\n ...(taskInput.context ? { context: taskInput.context } : {}),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('parallel', {\n description: 'Run agents in parallel: /parallel scout \"task1\" -> reviewer \"task2\" [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n\n const parsed = parseAgentArgsFallback(cleanedArgs);\n if (!parsed) {\n notifyError(ctx, 'Usage: /parallel agent1 \"task1\" -> agent2 \"task2\"');\n return;\n }\n for (const step of parsed.steps) {\n if (!findAgentOrNotify(deps, baseCwd, step.name, ctx)) return;\n }\n if (!parsed.steps.some((step) => step.task) && !parsed.task) {\n notifyError(ctx, 'At least one step must have a task');\n return;\n }\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const tasks = parsed.steps.map((step) =>\n taskInputFromParsedStep(\n { name: step.name, config: step.config, task: step.task ?? parsed.task },\n baseCwd,\n fork ? 'fork' : undefined,\n ),\n );\n const result = await launchParallelSubagents(\n deps.spawnPlanner,\n jobs,\n {\n tasks,\n cwd: baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('subagents-doctor', {\n description: 'Show subagent diagnostics',\n handler: async (_args, ctx) => {\n sendSlashText(\n pi,\n buildDoctorReport({ cwd: ctx.cwd, agentScope: 'both' }, { discovery: deps.discovery, skills: deps.skills }),\n );\n },\n });\n\n pi.registerCommand('subagents-stop', {\n description: 'Stop a running subagent: /subagents-stop [run-id]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const id = args.trim();\n if (!id) {\n sendSlashText(pi, stoppableRunsReport(jobs.list()));\n return;\n }\n try {\n deps.management.stop(resolveTrackedRunId(jobs, id));\n // Deliberately reports the REQUEST, not the outcome. Stop is\n // asynchronous in this package: the request is a file the child\n // claims on its next control-channel tick, so claiming \"stopped\"\n // here would assert something this process has not observed. The\n // run's own status is what confirms it, via /subagents-fleet or a\n // completion notification.\n notifyInfo(ctx, `Stop requested for ${id}. The run reports its own final state once it acknowledges.`);\n } catch (error) {\n // `ManagementActions.stop` throws only for an id that resolves to no\n // run or to more than one. Both are bad user input, not internal\n // faults, so they are notified rather than rethrown at the host - the\n // same treatment `reportKnownErrorOrRethrow` gives a parse error.\n notifyError(ctx, error instanceof Error ? error.message : `Could not stop '${id}'.`);\n }\n },\n });\n}\n\n/**\n * The no-argument `/subagents-stop` listing.\n *\n * The predecessor opened a TUI selector overlay here. This reports the same\n * information as text instead, for one reason worth stating rather than\n * hiding: a selector is a second, independent renderer of run state, and this\n * package already has one in `/subagents-fleet` that shows more (live status,\n * transcripts, and the full set of runtime controls including stop). Building\n * a second, weaker one would mean two things to keep in step. Passing an\n * explicit id stays the direct path, and the fleet overlay is the interactive\n * one.\n */\nfunction stoppableRunsReport(runs: readonly TrackedAsyncJob[]): string {\n const stoppable = runs.filter((run) => run.status === 'running' || run.status === 'pending');\n if (stoppable.length === 0) return 'No running subagents to stop.';\n const lines = stoppable.map((run) => `- ${run.runId}${run.status ? ` (${run.status})` : ''}`);\n return [\n 'Running subagents:',\n ...lines,\n '',\n 'Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively.',\n ].join('\\n');\n}\n"],"mappings":"kUAgGA,SAAS,EAAc,EAAkB,EAAoB,CAC3D,EAAG,YAAY,CAAE,WAAY,wBAA0B,QAAS,EAAM,QAAS,GAAM,CAAC,CAGxF,SAAS,EAAe,EAAuB,EAAgC,CACzE,EAAI,OAAO,EAAI,GAAG,UAAU,iBAAkB,EAAK,CAGzD,SAAS,EAAY,EAAuB,EAAuB,CACjE,EAAI,GAAG,OAAO,EAAS,QAAQ,CAGjC,SAAS,EAAW,EAAuB,EAAuB,CAChE,EAAI,GAAG,OAAO,EAAS,OAAO,CAGhC,SAAS,EAAc,EAA0C,CAI/D,OAHK,EACD,EAAI,gBAAwB,GAAG,EAAI,QAAU,UAAU,sBAAsB,EAAI,kBACjF,EAAI,cAAsB,GAAG,EAAI,QAAU,UAAU,KAAK,EAAI,gBAC3D,EAAI,QAAU,UAHJ,YAWnB,SAAS,EACP,EACA,EACA,EACA,EACA,EACA,EACM,CACN,EAAA,6BAA6B,EAAK,UAAW,EAAM,EAAQ,GAAQ,CAEjE,GADA,EAAe,EAAK,GAAG,EAAM,IAAI,EAAM,KAAK,EAAc,EAAI,GAAG,CAC7D,GAAK,SAAW,IAAA,IAAa,CAACA,EAAAA,0BAA0B,IAAI,EAAI,OAAO,CAAE,OAC7E,EAAe,EAAK,IAAA,GAAU,CAC9B,IAAM,EAAU,EAAI,SAAW,YAAc,EAAI,SAAW,YAAc,YAAc,EAAI,OAC5F,EACE,EACA,EAAI,MACA,eAAe,EAAQ,MAAM,EAAM,IAAI,EAAM,OAAO,EAAI,QACxD,eAAe,EAAQ,MAAM,EAAM,IAAI,EAAM,GAClD,EACD,CAGJ,SAAS,EACP,EACA,EACA,EACA,EACA,EACM,CACN,IAAM,EAAU,EAAO,SAAS,OAAQ,GAAY,EAAQ,MAAM,CAC5D,EAAS,EAAO,SAAS,OAAQ,GAAY,CAAC,EAAQ,MAAM,CAClE,GAAI,EAAQ,OAAS,EAAG,CAMtB,EAAc,EAAI,0BALJ,EACX,IACE,GAAY,GAAG,EAAQ,MAAM,IAAI,EAAQ,MAAM,GAAG,EAAQ,QAAU,gBAAgB,EAAQ,UAAY,KAC1G,CACA,KAAK,KACyC,GAAG,CACpD,EAAe,EAAK,GAAG,EAAQ,OAAO,MAAM,EAAQ,SAAW,EAAI,GAAK,IAAI,WAAW,CACvF,IAAK,IAAM,KAAW,EAChB,EAAQ,OAAO,EAAiB,EAAI,EAAK,EAAM,EAAM,EAAQ,MAAO,EAAQ,MAAM,CAGtF,EAAO,OAAS,GAElB,EAAY,EAAK,oCADH,EAAO,IAAK,GAAY,GAAG,EAAQ,MAAM,IAAI,EAAQ,OAAS,iBAAiB,CAAC,KAAK;EACzC,GAAG,CAIjE,SAAS,EAAe,EAA0B,EAA2C,CAC3F,GAAI,EAAM,QAAS,OAAO,EAAM,QAChC,EAAY,EAAK,8CAA8C,CAIjE,SAAS,EAAkB,EAAwB,EAAiB,EAAc,EAAgC,CAIhH,OAHe,EAAK,UAAU,SAAS,EAAS,OAA4B,CAAC,OAClE,KAAM,GAAU,EAAM,OAAS,EAAK,CAAS,IACxD,EAAY,EAAK,kBAAkB,IAAO,CACnC,IAGT,SAAS,EAA0B,EAAuB,EAAsB,CAC9E,GAAI,aAAiBC,EAAAA,8BAAgC,aAAiBC,EAAAA,gBAAiB,CACrF,EAAY,EAAK,EAAM,QAAQ,CAC/B,OAEF,MAAM,EAOR,SAAS,EAAuB,EAAoF,CAClH,IAAM,EAAU,EAAM,MAAM,CAC5B,GAAI,EAAQ,SAAS,OAAO,CAAE,CAC5B,IAAM,EAAQ,EACX,MAAM,OAAO,CACb,IAAK,GAAY,EAAQ,MAAM,CAAC,CAChC,OAAO,QAAQ,CACf,IAAK,GAAYC,EAAAA,qBAAqB,EAAQ,CAAC,CAElD,OADI,EAAM,SAAW,EAAG,OACjB,CAAE,QAAO,KAAM,EAAM,KAAM,GAAS,EAAK,KAAK,EAAE,MAAQ,GAAI,QAAS,GAAM,CAEpF,IAAM,EAAiB,EAAQ,QAAQ,OAAO,CAC9C,GAAI,IAAmB,GAAI,OAC3B,IAAM,EAAa,EAAQ,MAAM,EAAG,EAAe,CAAC,MAAM,CACpD,EAAa,EAAQ,MAAM,EAAiB,EAAE,CAAC,MAAM,CAC3D,GAAI,CAAC,GAAc,CAAC,EAAY,OAChC,IAAM,EAAQ,EACX,MAAM,MAAM,CACZ,OAAO,QAAQ,CACf,IAAK,GAAUA,EAAAA,qBAAqB,EAAM,CAAC,CAC1C,KAAM,SAAW,EACrB,MAAO,CAAE,QAAO,KAAM,EAAY,QAAS,GAAO,CAGpD,SAAgB,EAAsB,EAAkB,EAA0B,EAA8B,CAC9G,EAAG,gBAAgB,MAAO,CACxB,YAAa,wEACb,QAAS,MAAO,EAAM,IAAQ,CAC5B,IAAM,EAAO,EAAK,QAAQ,WAAW,EAAI,eAAe,cAAc,CAAC,CACjE,CAAE,KAAM,EAAa,QAASC,EAAAA,gBAAgB,EAAK,CACnD,EAAQ,EAAY,MAAM,CAChC,GAAI,CAAC,EAAO,CACV,EAAY,EAAK,sCAAsC,CACvD,OAEF,IAAM,EAAa,EAAM,QAAQ,IAAI,CAC/B,CAAE,KAAM,EAAW,UAAWC,EAAAA,gBAAgB,IAAe,GAAK,EAAQ,EAAM,MAAM,EAAG,EAAW,CAAC,CACrG,EAAO,IAAe,GAAK,GAAK,EAAM,MAAM,EAAa,EAAE,CAAC,MAAM,CAElE,EAAU,EAAe,EAAO,EAAI,CACrC,MACA,EAAkB,EAAM,EAAS,EAAW,EAAI,CAErD,GAAI,CACF,IAAM,EAAmBC,EAAAA,yBAAyB,EAAI,eAAgB,UAAU,CAC1E,EAAcC,EAAAA,qBAAqB,EAAI,MAAM,CAC7C,EAAYC,EAAAA,wBAChB,CAAE,KAAM,EAAW,SAAQ,OAAM,CACjC,EACA,EAAO,OAAS,IAAA,GACjB,CAoBD,EAAkB,EAAI,EAAK,EAAM,EAAM,MAnBlBC,EAAAA,qBACnB,EAAK,aACL,EACA,CACE,MAAO,EAAU,MACjB,KAAM,EAAU,MAAQ,GACxB,IAAK,EAAU,KAAO,EACtB,WAAY,OACZ,gBAAiB,EAAI,eAAe,cAAc,CAClD,GAAI,EAAU,MAAQ,CAAE,MAAO,EAAU,MAAO,CAAG,EAAE,CACrD,GAAI,EAAU,QAAU,CAAE,QAAS,EAAU,QAAS,CAAG,EAAE,CAC3D,GAAI,EACA,CAAE,kBAAmB,EAAiB,YAAa,aAAc,EAAiB,OAAQ,CAC1F,EAAE,CACN,gBAAiBC,EAAAA,wBAAwB,EAAI,cAAc,CAC3D,GAAI,EAAc,CAAE,cAAa,CAAG,EAAE,CACvC,CACD,EAAK,YAAY,CAClB,CAC6C,OACvC,EAAO,CACd,EAA0B,EAAK,EAAM,GAG1C,CAAC,CAEF,EAAG,gBAAgB,WAAY,CAC7B,YAAa,+EACb,QAAS,MAAO,EAAM,IAAQ,CAC5B,IAAM,EAAO,EAAK,QAAQ,WAAW,EAAI,eAAe,cAAc,CAAC,CACjE,CAAE,KAAM,EAAa,QAASN,EAAAA,gBAAgB,EAAK,CACnD,EAAU,EAAe,EAAO,EAAI,CAC1C,GAAI,CAAC,EAAS,OAEd,IAAM,EAAS,EAAuB,EAAY,CAClD,GAAI,CAAC,EAAQ,CACX,EAAY,EAAK,oDAAoD,CACrE,OAEF,IAAK,IAAM,KAAQ,EAAO,MACxB,GAAI,CAAC,EAAkB,EAAM,EAAS,EAAK,KAAM,EAAI,CAAE,OAEzD,GAAI,CAAC,EAAO,MAAM,KAAM,GAAS,EAAK,KAAK,EAAI,CAAC,EAAO,KAAM,CAC3D,EAAY,EAAK,qCAAqC,CACtD,OAGF,GAAI,CACF,IAAM,EAAmBE,EAAAA,yBAAyB,EAAI,eAAgB,UAAU,CAC1E,EAAcC,EAAAA,qBAAqB,EAAI,MAAM,CAC7C,EAAQ,EAAO,MAAM,IAAK,GAC9BC,EAAAA,wBACE,CAAE,KAAM,EAAK,KAAM,OAAQ,EAAK,OAAQ,KAAM,EAAK,MAAQ,EAAO,KAAM,CACxE,EACA,EAAO,OAAS,IAAA,GACjB,CACF,CAiBD,EAAkB,EAAI,EAAK,EAAM,EAAM,MAhBlBG,EAAAA,wBACnB,EAAK,aACL,EACA,CACE,QACA,IAAK,EACL,WAAY,OACZ,gBAAiB,EAAI,eAAe,cAAc,CAClD,GAAI,EACA,CAAE,kBAAmB,EAAiB,YAAa,aAAc,EAAiB,OAAQ,CAC1F,EAAE,CACN,gBAAiBD,EAAAA,wBAAwB,EAAI,cAAc,CAC3D,GAAI,EAAc,CAAE,cAAa,CAAG,EAAE,CACvC,CACD,EAAK,YAAY,CAClB,CAC6C,OACvC,EAAO,CACd,EAA0B,EAAK,EAAM,GAG1C,CAAC,CAEF,EAAG,gBAAgB,mBAAoB,CACrC,YAAa,4BACb,QAAS,MAAO,EAAO,IAAQ,CAC7B,EACE,EACAE,EAAAA,kBAAkB,CAAE,IAAK,EAAI,IAAK,WAAY,OAAQ,CAAE,CAAE,UAAW,EAAK,UAAW,OAAQ,EAAK,OAAQ,CAAC,CAC5G,EAEJ,CAAC,CAEF,EAAG,gBAAgB,iBAAkB,CACnC,YAAa,oDACb,QAAS,MAAO,EAAM,IAAQ,CAC5B,IAAM,EAAO,EAAK,QAAQ,WAAW,EAAI,eAAe,cAAc,CAAC,CACjE,EAAK,EAAK,MAAM,CACtB,GAAI,CAAC,EAAI,CACP,EAAc,EAAI,EAAoB,EAAK,MAAM,CAAC,CAAC,CACnD,OAEF,GAAI,CACF,EAAK,WAAW,KAAKC,EAAAA,oBAAoB,EAAM,EAAG,CAAC,CAOnD,EAAW,EAAK,sBAAsB,EAAG,6DAA6D,OAC/F,EAAO,CAKd,EAAY,EAAK,aAAiB,MAAQ,EAAM,QAAU,mBAAmB,EAAG,IAAI,GAGzF,CAAC,CAeJ,SAAS,EAAoB,EAA0C,CACrE,IAAM,EAAY,EAAK,OAAQ,GAAQ,EAAI,SAAW,WAAa,EAAI,SAAW,UAAU,CAG5F,OAFI,EAAU,SAAW,EAAU,gCAE5B,CACL,qBACA,GAHY,EAAU,IAAK,GAAQ,KAAK,EAAI,QAAQ,EAAI,OAAS,KAAK,EAAI,OAAO,GAAK,KAG9E,CACR,GACA,kHACD,CAAC,KAAK;EAAK"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{authenticatedModelInfos as e,init_modelResolution as t}from"../shared/modelResolution.mjs";import{init_modelFallback as n,normalizeParentModel as r}from"../runs/shared/modelFallback.mjs";import{captureSessionForkSource as i,init_spawnPlan as a}from"../extensions/spawnPlan.mjs";import{TERMINAL_ASYNC_JOB_STATES as o,init_asyncJobTracker as s,resolveTrackedRunId as c}from"../runs/background/asyncJobTracker.mjs";import{SlashParseError as l,extractForkFlag as u,parseAgentToken as d,parseSingleTaskToken as f}from"./chainExpression.mjs";import{buildDoctorReport as p}from"./doctor.mjs";import{UnsupportedInlineConfigError as m,taskInputFromParsedStep as h}from"./spawnRequestMapping.mjs";import{launchParallelSubagents as g,launchSingleSubagent as _,watchTrackedRunUntilTerminal as v}from"./subagentLaunch.mjs";a(),s(),n(),t();function y(e,t){e.sendMessage({customType:`subagent-slash-result`,content:t,display:!0})}function b(e,t){e.hasUI&&e.ui.setStatus(`subagent-slash`,t)}function x(e,t){e.ui.notify(t,`error`)}function S(e,t){e.ui.notify(t,`info`)}function C(e){return e?e.attentionReason?`${e.status??`running`} - needs attention: ${e.attentionReason}`:e.activityState?`${e.status??`running`} - ${e.activityState}`:e.status??`running`:`starting…`}function w(e,t,n,r,i,a){v(n.scheduler,r,i,n=>{if(b(t,`${a} (${i}): ${C(n)}`),n?.status===void 0||!o.has(n.status))return;b(t,void 0);let r=n.status===`complete`||n.status===`completed`?`completed`:n.status;y(e,n.error?`## Subagent ${r}\n\n${a} (${i})\n\n${n.error}`:`## Subagent ${r}\n\n${a} (${i})`)})}function T(e,t,n,r,i){let a=i.outcomes.filter(e=>e.runId),o=i.outcomes.filter(e=>!e.runId);if(a.length>0){y(e,`## Subagent started\n\n${a.map(e=>`${e.agent} (${e.runId})${e.warning?`\n Warning: ${e.warning}`:``}`).join(`, `)}`),b(t,`${a.length} run${a.length===1?``:`s`} started…`);for(let i of a)i.runId&&w(e,t,n,r,i.runId,i.agent)}o.length>0&&x(t,`Some subagents failed to start:\n${o.map(e=>`${e.agent}: ${e.error??`spawn failed`}`).join(`
|
|
2
|
+
`)}`)}function E(e,t){if(e.baseCwd)return e.baseCwd;x(t,`Subagent session cwd is not initialized yet`)}function D(e,t,n,r){return e.discovery.discover(t,`both`).agents.find(e=>e.name===n)?!0:(x(r,`Unknown agent: ${n}`),!1)}function O(e,t){if(t instanceof m||t instanceof l){x(e,t.message);return}throw t}function k(e){let t=e.trim();if(t.includes(` -> `)){let e=t.split(` -> `).map(e=>e.trim()).filter(Boolean).map(e=>f(e));return e.length===0?void 0:{steps:e,task:e.find(e=>e.task)?.task??``,perStep:!0}}let n=t.indexOf(` -- `);if(n===-1)return;let r=t.slice(0,n).trim(),i=t.slice(n+4).trim();if(!r||!i)return;let a=r.split(/\s+/).filter(Boolean).map(e=>f(e));if(a.length!==0)return{steps:a,task:i,perStep:!1}}function A(t,n,a){t.registerCommand(`run`,{description:`Run a subagent in the background: /run agent[model=x] [task] [--fork]`,handler:async(o,s)=>{let c=a.tracker.forSession(s.sessionManager.getSessionId()),{args:l,fork:f}=u(o),p=l.trim();if(!p){x(s,`Usage: /run <agent> [task] [--fork]`);return}let m=p.indexOf(` `),{name:g,config:v}=d(m===-1?p:p.slice(0,m)),y=m===-1?``:p.slice(m+1).trim(),b=E(n,s);if(b&&D(a,b,g,s))try{let n=i(s.sessionManager,`settled`),o=r(s.model),l=h({name:g,config:v,task:y},b,f?`fork`:void 0);T(t,s,a,c,await _(a.spawnPlanner,c,{agent:l.agent,task:l.task??``,cwd:l.cwd??b,agentScope:`both`,parentSessionId:s.sessionManager.getSessionId(),...l.model?{model:l.model}:{},...l.context?{context:l.context}:{},...n?{parentSessionFile:n.sessionFile,parentLeafId:n.leafId}:{},availableModels:e(s.modelRegistry),...o?{parentModel:o}:{}},a.loadConfig()))}catch(e){O(s,e)}}}),t.registerCommand(`parallel`,{description:`Run agents in parallel: /parallel scout "task1" -> reviewer "task2" [--fork]`,handler:async(o,s)=>{let c=a.tracker.forSession(s.sessionManager.getSessionId()),{args:l,fork:d}=u(o),f=E(n,s);if(!f)return;let p=k(l);if(!p){x(s,`Usage: /parallel agent1 "task1" -> agent2 "task2"`);return}for(let e of p.steps)if(!D(a,f,e.name,s))return;if(!p.steps.some(e=>e.task)&&!p.task){x(s,`At least one step must have a task`);return}try{let n=i(s.sessionManager,`settled`),o=r(s.model),l=p.steps.map(e=>h({name:e.name,config:e.config,task:e.task??p.task},f,d?`fork`:void 0));T(t,s,a,c,await g(a.spawnPlanner,c,{tasks:l,cwd:f,agentScope:`both`,parentSessionId:s.sessionManager.getSessionId(),...n?{parentSessionFile:n.sessionFile,parentLeafId:n.leafId}:{},availableModels:e(s.modelRegistry),...o?{parentModel:o}:{}},a.loadConfig()))}catch(e){O(s,e)}}}),t.registerCommand(`subagents-doctor`,{description:`Show subagent diagnostics`,handler:async(e,n)=>{y(t,p({cwd:n.cwd,agentScope:`both`},{discovery:a.discovery,skills:a.skills}))}}),t.registerCommand(`subagents-stop`,{description:`Stop a running subagent: /subagents-stop [run-id]`,handler:async(e,n)=>{let r=a.tracker.forSession(n.sessionManager.getSessionId()),i=e.trim();if(!i){y(t,j(r.list()));return}try{a.management.stop(c(r,i)),S(n,`Stop requested for ${i}. The run reports its own final state once it acknowledges.`)}catch(e){x(n,e instanceof Error?e.message:`Could not stop '${i}'.`)}}})}function j(e){let t=e.filter(e=>e.status===`running`||e.status===`pending`);return t.length===0?`No running subagents to stop.`:[`Running subagents:`,...t.map(e=>`- ${e.runId}${e.status?` (${e.status})`:``}`),``,"Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively."].join(`
|
|
3
|
+
`)}export{A as registerSlashCommands};
|
|
4
|
+
//# sourceMappingURL=slashCommands.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slashCommands.mjs","names":[],"sources":["../../src/slash/slashCommands.ts"],"sourcesContent":["/**\n * The core `/run`, `/chain`, `/parallel` slash commands. Replaces the\n * always-blocking predecessor with the async-only shape this port settled\n * on: a command launches a spawn, sends an initial status message, and\n * hands off to `watchTrackedRunUntilTerminal` (render-key gated, backed by\n * `PollScheduler`) to update the status bar and finalize the message once\n * the run reaches a terminal state - never by awaiting completion. See\n * `subagentLaunch.ts`'s module doc for the full reasoning.\n *\n * WHAT IS NOT HERE, AND WHY:\n * - `/run-chain`, `/prompt-workflow` and `/chain-prompts`: the whole SAVED\n * work surface - saved agent pipelines (`ChainConfig`, never ported) and\n * saved `.md` prompt templates (ported, then deleted). REMOVED BY\n * DECISION, not deferred: overly complicated for the use they were\n * getting. Do not re-add them because a reader notices the predecessor had\n * them. Ad-hoc chaining (`/chain scout \"x\" -> planner`) is a different\n * feature, lives in `chainExpression.ts`, and stays\n * - `/subagent-cost`: REMOVED BY DECISION. It reads usage/cost data\n * (`totalTokens`/`totalCost`) that nothing in this package's\n * runs/extensions surface tracks - a genuinely absent data source, and\n * building it would mean threading usage out of every child process\n * - `/subagents-check-profile`: removed at the source. Calls\n * `checkSubagentProfile`/`listSubagentProfiles`, which are referenced but\n * defined nowhere in the entire predecessor package - a live\n * `ReferenceError` that only shipped because that package sets\n * `noCheck: true`. Typecheck is on here; porting it faithfully would not\n * compile, and it was asked to be removed independently of that\n * - The `SUBAGENT_FLEET_COMMAND` registration and its `Ctrl+Alt+F` shortcut:\n * fleet view is its own piece, registered by whoever builds it\n * - Inline parallel groups within `/chain` (`(a | b)` syntax): the field\n * mapping for a group's own config exists (`spawnRequestMapping.ts`),\n * but wiring a group INTO a chain request is left for the same pass that\n * revisits per-task field support, so `/chain` reports a clear\n * not-yet-supported message rather than silently flattening a group\n * - `/subagents` (admin) command registration: a separate file, not yet\n * ported\n *\n * `/subagents-doctor` IS here, in `doctor.ts` - read (not ported) the\n * predecessor's foreground-executor `doctor` action before deciding, and it\n * turned out to be a small, mostly-mechanical port. See that module's own\n * doc for what it deliberately leaves out (chain counts, spawn-budget\n * reporting).\n *\n * AVOID:\n * - Awaiting a SINGLE/PARALLEL spawn for a result that will not exist yet.\n * See `subagentLaunch.ts`\n * - A private polling loop for a message's live status. Use\n * `watchTrackedRunUntilTerminal`\n */\n\nimport type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';\n\nimport type { ISkillDiscoveryService } from '../agents/skills.ts';\nimport type { AgentScope, IAgentDiscoveryService } from '../agents/types.ts';\nimport type { ExtensionConfig } from '../extensions/config.ts';\nimport type { IManagementActions } from '../extensions/managementActions.ts';\nimport { captureSessionForkSource, type ISpawnPlanner, type SpawnPlanResult } from '../extensions/spawnPlan.ts';\nimport type { IAsyncJobTracker, ITrackedAsyncJobs, TrackedAsyncJob } from '../runs/background/asyncJobTracker.ts';\nimport { resolveTrackedRunId, TERMINAL_ASYNC_JOB_STATES } from '../runs/background/asyncJobTracker.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport { normalizeParentModel } from '../runs/shared/modelFallback.ts';\nimport { authenticatedModelInfos } from '../shared/modelResolution.ts';\nimport {\n extractForkFlag,\n parseAgentToken,\n parseSingleTaskToken,\n SlashParseError,\n type ParsedStep,\n} from './chainExpression.ts';\nimport { buildDoctorReport } from './doctor.ts';\nimport { taskInputFromParsedStep, UnsupportedInlineConfigError } from './spawnRequestMapping.ts';\nimport { launchParallelSubagents, launchSingleSubagent, watchTrackedRunUntilTerminal } from './subagentLaunch.ts';\n\nexport interface SlashCommandDeps {\n spawnPlanner: ISpawnPlanner;\n skills: ISkillDiscoveryService;\n tracker: IAsyncJobTracker;\n scheduler: IPollScheduler;\n discovery: IAgentDiscoveryService;\n /**\n * Used by `/subagents-stop`. Preferred over calling `requestSlashRunStop`\n * directly because it resolves an id PREFIX through `RunIdResolver` and\n * raises a real error for an unknown or ambiguous one, instead of writing a\n * stop request into a directory for a run that does not exist.\n */\n management: IManagementActions;\n loadConfig: () => ExtensionConfig;\n}\n\nexport interface SlashCommandState {\n baseCwd: string | undefined;\n}\n\nconst SLASH_STATUS_KEY = 'subagent-slash';\nconst SLASH_RESULT_CUSTOM_TYPE = 'subagent-slash-result';\n\nfunction sendSlashText(pi: ExtensionAPI, text: string): void {\n pi.sendMessage({ customType: SLASH_RESULT_CUSTOM_TYPE, content: text, display: true });\n}\n\nfunction setSlashStatus(ctx: ExtensionContext, text: string | undefined): void {\n if (ctx.hasUI) ctx.ui.setStatus(SLASH_STATUS_KEY, text);\n}\n\nfunction notifyError(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'error');\n}\n\nfunction notifyInfo(ctx: ExtensionContext, message: string): void {\n ctx.ui.notify(message, 'info');\n}\n\nfunction statusTextFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'starting…';\n if (job.attentionReason) return `${job.status ?? 'running'} - needs attention: ${job.attentionReason}`;\n if (job.activityState) return `${job.status ?? 'running'} - ${job.activityState}`;\n return job.status ?? 'running';\n}\n\n/**\n * Watches one launched run to a terminal state and finalizes its message.\n * Each launched run gets its own subscriber, so a PARALLEL launch's\n * siblings finalize independently rather than all waiting on the slowest.\n */\nfunction watchAndFinalize(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: ITrackedAsyncJobs,\n runId: string,\n agent: string,\n): void {\n watchTrackedRunUntilTerminal(deps.scheduler, jobs, runId, (job) => {\n setSlashStatus(ctx, `${agent} (${runId}): ${statusTextFor(job)}`);\n if (job?.status === undefined || !TERMINAL_ASYNC_JOB_STATES.has(job.status)) return;\n setSlashStatus(ctx, undefined);\n const outcome = job.status === 'complete' || job.status === 'completed' ? 'completed' : job.status;\n sendSlashText(\n pi,\n job.error\n ? `## Subagent ${outcome}\\n\\n${agent} (${runId})\\n\\n${job.error}`\n : `## Subagent ${outcome}\\n\\n${agent} (${runId})`,\n );\n });\n}\n\nfunction reportSpawnResult(\n pi: ExtensionAPI,\n ctx: ExtensionContext,\n deps: SlashCommandDeps,\n jobs: ITrackedAsyncJobs,\n result: SpawnPlanResult,\n): void {\n const started = result.outcomes.filter((outcome) => outcome.runId);\n const failed = result.outcomes.filter((outcome) => !outcome.runId);\n if (started.length > 0) {\n const label = started\n .map(\n (outcome) => `${outcome.agent} (${outcome.runId})${outcome.warning ? `\\n Warning: ${outcome.warning}` : ''}`,\n )\n .join(', ');\n sendSlashText(pi, `## Subagent started\\n\\n${label}`);\n setSlashStatus(ctx, `${started.length} run${started.length === 1 ? '' : 's'} started…`);\n for (const outcome of started) {\n if (outcome.runId) watchAndFinalize(pi, ctx, deps, jobs, outcome.runId, outcome.agent);\n }\n }\n if (failed.length > 0) {\n const label = failed.map((outcome) => `${outcome.agent}: ${outcome.error ?? 'spawn failed'}`).join('\\n');\n notifyError(ctx, `Some subagents failed to start:\\n${label}`);\n }\n}\n\nfunction requireBaseCwd(state: SlashCommandState, ctx: ExtensionContext): string | undefined {\n if (state.baseCwd) return state.baseCwd;\n notifyError(ctx, 'Subagent session cwd is not initialized yet');\n return undefined;\n}\n\nfunction findAgentOrNotify(deps: SlashCommandDeps, baseCwd: string, name: string, ctx: ExtensionContext): boolean {\n const agents = deps.discovery.discover(baseCwd, 'both' satisfies AgentScope).agents;\n if (agents.find((agent) => agent.name === name)) return true;\n notifyError(ctx, `Unknown agent: ${name}`);\n return false;\n}\n\nfunction reportKnownErrorOrRethrow(ctx: ExtensionContext, error: unknown): void {\n if (error instanceof UnsupportedInlineConfigError || error instanceof SlashParseError) {\n notifyError(ctx, error.message);\n return;\n }\n throw error;\n}\n\n/**\n * Shared arg parsing for /chain (no inline group) and /parallel:\n * \"agent1 task1 -> agent2 task2\" or \"agent1 agent2 -- shared task\".\n */\nfunction parseAgentArgsFallback(input: string): { steps: ParsedStep[]; task: string; perStep: boolean } | undefined {\n const trimmed = input.trim();\n if (trimmed.includes(' -> ')) {\n const steps = trimmed\n .split(' -> ')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => parseSingleTaskToken(segment));\n if (steps.length === 0) return undefined;\n return { steps, task: steps.find((step) => step.task)?.task ?? '', perStep: true };\n }\n const delimiterIndex = trimmed.indexOf(' -- ');\n if (delimiterIndex === -1) return undefined;\n const agentsPart = trimmed.slice(0, delimiterIndex).trim();\n const sharedTask = trimmed.slice(delimiterIndex + 4).trim();\n if (!agentsPart || !sharedTask) return undefined;\n const steps = agentsPart\n .split(/\\s+/)\n .filter(Boolean)\n .map((token) => parseSingleTaskToken(token));\n if (steps.length === 0) return undefined;\n return { steps, task: sharedTask, perStep: false };\n}\n\nexport function registerSlashCommands(pi: ExtensionAPI, state: SlashCommandState, deps: SlashCommandDeps): void {\n pi.registerCommand('run', {\n description: 'Run a subagent in the background: /run agent[model=x] [task] [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const input = cleanedArgs.trim();\n if (!input) {\n notifyError(ctx, 'Usage: /run <agent> [task] [--fork]');\n return;\n }\n const firstSpace = input.indexOf(' ');\n const { name: agentName, config } = parseAgentToken(firstSpace === -1 ? input : input.slice(0, firstSpace));\n const task = firstSpace === -1 ? '' : input.slice(firstSpace + 1).trim();\n\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n if (!findAgentOrNotify(deps, baseCwd, agentName, ctx)) return;\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const taskInput = taskInputFromParsedStep(\n { name: agentName, config, task },\n baseCwd,\n fork ? 'fork' : undefined,\n );\n const result = await launchSingleSubagent(\n deps.spawnPlanner,\n jobs,\n {\n agent: taskInput.agent,\n task: taskInput.task ?? '',\n cwd: taskInput.cwd ?? baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(taskInput.model ? { model: taskInput.model } : {}),\n ...(taskInput.context ? { context: taskInput.context } : {}),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('parallel', {\n description: 'Run agents in parallel: /parallel scout \"task1\" -> reviewer \"task2\" [--fork]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const { args: cleanedArgs, fork } = extractForkFlag(args);\n const baseCwd = requireBaseCwd(state, ctx);\n if (!baseCwd) return;\n\n const parsed = parseAgentArgsFallback(cleanedArgs);\n if (!parsed) {\n notifyError(ctx, 'Usage: /parallel agent1 \"task1\" -> agent2 \"task2\"');\n return;\n }\n for (const step of parsed.steps) {\n if (!findAgentOrNotify(deps, baseCwd, step.name, ctx)) return;\n }\n if (!parsed.steps.some((step) => step.task) && !parsed.task) {\n notifyError(ctx, 'At least one step must have a task');\n return;\n }\n\n try {\n const parentForkSource = captureSessionForkSource(ctx.sessionManager, 'settled');\n const parentModel = normalizeParentModel(ctx.model);\n const tasks = parsed.steps.map((step) =>\n taskInputFromParsedStep(\n { name: step.name, config: step.config, task: step.task ?? parsed.task },\n baseCwd,\n fork ? 'fork' : undefined,\n ),\n );\n const result = await launchParallelSubagents(\n deps.spawnPlanner,\n jobs,\n {\n tasks,\n cwd: baseCwd,\n agentScope: 'both',\n parentSessionId: ctx.sessionManager.getSessionId(),\n ...(parentForkSource\n ? { parentSessionFile: parentForkSource.sessionFile, parentLeafId: parentForkSource.leafId }\n : {}),\n availableModels: authenticatedModelInfos(ctx.modelRegistry),\n ...(parentModel ? { parentModel } : {}),\n },\n deps.loadConfig(),\n );\n reportSpawnResult(pi, ctx, deps, jobs, result);\n } catch (error) {\n reportKnownErrorOrRethrow(ctx, error);\n }\n },\n });\n\n pi.registerCommand('subagents-doctor', {\n description: 'Show subagent diagnostics',\n handler: async (_args, ctx) => {\n sendSlashText(\n pi,\n buildDoctorReport({ cwd: ctx.cwd, agentScope: 'both' }, { discovery: deps.discovery, skills: deps.skills }),\n );\n },\n });\n\n pi.registerCommand('subagents-stop', {\n description: 'Stop a running subagent: /subagents-stop [run-id]',\n handler: async (args, ctx) => {\n const jobs = deps.tracker.forSession(ctx.sessionManager.getSessionId());\n const id = args.trim();\n if (!id) {\n sendSlashText(pi, stoppableRunsReport(jobs.list()));\n return;\n }\n try {\n deps.management.stop(resolveTrackedRunId(jobs, id));\n // Deliberately reports the REQUEST, not the outcome. Stop is\n // asynchronous in this package: the request is a file the child\n // claims on its next control-channel tick, so claiming \"stopped\"\n // here would assert something this process has not observed. The\n // run's own status is what confirms it, via /subagents-fleet or a\n // completion notification.\n notifyInfo(ctx, `Stop requested for ${id}. The run reports its own final state once it acknowledges.`);\n } catch (error) {\n // `ManagementActions.stop` throws only for an id that resolves to no\n // run or to more than one. Both are bad user input, not internal\n // faults, so they are notified rather than rethrown at the host - the\n // same treatment `reportKnownErrorOrRethrow` gives a parse error.\n notifyError(ctx, error instanceof Error ? error.message : `Could not stop '${id}'.`);\n }\n },\n });\n}\n\n/**\n * The no-argument `/subagents-stop` listing.\n *\n * The predecessor opened a TUI selector overlay here. This reports the same\n * information as text instead, for one reason worth stating rather than\n * hiding: a selector is a second, independent renderer of run state, and this\n * package already has one in `/subagents-fleet` that shows more (live status,\n * transcripts, and the full set of runtime controls including stop). Building\n * a second, weaker one would mean two things to keep in step. Passing an\n * explicit id stays the direct path, and the fleet overlay is the interactive\n * one.\n */\nfunction stoppableRunsReport(runs: readonly TrackedAsyncJob[]): string {\n const stoppable = runs.filter((run) => run.status === 'running' || run.status === 'pending');\n if (stoppable.length === 0) return 'No running subagents to stop.';\n const lines = stoppable.map((run) => `- ${run.runId}${run.status ? ` (${run.status})` : ''}`);\n return [\n 'Running subagents:',\n ...lines,\n '',\n 'Stop one with `/subagents-stop <run-id>`, or open `/subagents-fleet` to inspect and control them interactively.',\n ].join('\\n');\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=[{key:`output`,isSet:e=>e.output!==void 0},{key:`outputMode`,isSet:e=>e.outputMode!==void 0},{key:`reads`,isSet:e=>e.reads!==void 0},{key:`skill`,isSet:e=>e.skill!==void 0},{key:`progress`,isSet:e=>e.progress!==void 0},{key:`count`,isSet:e=>e.count!==void 0},{key:`outputSchema`,isSet:e=>e.outputSchema!==void 0},{key:`acceptance`,isSet:e=>e.acceptance!==void 0}];var t=class extends Error{constructor(e,t){super(`'${e}' is not supported yet for '${t}': SpawnPlanner does not accept it as a per-task override.`),this.key=e,this.name=`UnsupportedInlineConfigError`}};function n(n,r){for(let{key:i,isSet:a}of e)if(a(n))throw new t(i,r)}function r(e,t,r){return n(e.config,e.name),{agent:e.name,...e.task?{task:e.task}:{},cwd:e.config.cwd??t,...e.config.model?{model:e.config.model}:{},...r?{context:r}:{}}}exports.UnsupportedInlineConfigError=t,exports.taskInputFromParsedStep=r;
|
|
2
|
+
//# sourceMappingURL=spawnRequestMapping.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawnRequestMapping.cjs","names":[],"sources":["../../src/slash/spawnRequestMapping.ts"],"sourcesContent":["/**\n * Maps a parsed slash-command step (`chainExpression.ts`'s `ParsedStep`/\n * carrying the predecessor's full 13-key inline-config\n * vocabulary) onto `SpawnPlanner`'s actual request shapes\n * (`SpawnPlanTaskInput`), which accepts far fewer\n * fields today.\n *\n * WHY A SET INLINE-CONFIG KEY WITH NO DESTINATION THROWS, RATHER THAN\n * BEING DROPPED:\n * Parsing syntax a user can type and then silently ignoring it is the same\n * class of lie as a coverage number that does not mean what it claims -\n * nothing would tell the user their `[skill=x]` did nothing, and they would\n * reasonably conclude the feature is broken rather than simply not built\n * yet. `port-result-watcher` explicitly deferred per-task\n * `skill`/`toolBudget`/`turnBudget`/`outputSchema`/`acceptance`/`output`\n * overrides when it built `spawnPlan.ts` - listed as unwired, not\n * unwanted - so this is scoping DOWN a vocabulary that already has a home\n * to grow back into, not designing a small one. The error names the exact\n * key and says \"not yet supported\", distinct from an unrecognized key\n * (which `parseInlineConfig` already drops silently, matching the\n * predecessor's own behavior for a typo).\n *\n * WHY THE NOT-YET-SUPPORTED LIST IS DATA, NOT A SWITCH:\n * Wiring one of these up later (e.g. once `SpawnPlanTaskInput` grows a\n * `skill` field) means deleting one entry from\n * `NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS` and adding the field to the\n * builder functions below - not re-deriving which keys are safe to pass\n * through.\n *\n * AVOID:\n * - Silently dropping a set inline-config key with no destination\n * - Inlining the not-yet-supported check as ad hoc `if` statements at each\n * call site instead of the shared list below\n */\n\nimport type { SpawnPlanTaskInput } from '../extensions/spawnPlan.ts';\nimport type { InlineConfig, ParsedStep } from './chainExpression.ts';\n\ninterface NotYetSupportedKey {\n key: keyof InlineConfig;\n isSet: (config: InlineConfig) => boolean;\n}\n\nconst NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS: readonly NotYetSupportedKey[] = [\n { key: 'output', isSet: (c) => c.output !== undefined },\n { key: 'outputMode', isSet: (c) => c.outputMode !== undefined },\n { key: 'reads', isSet: (c) => c.reads !== undefined },\n { key: 'skill', isSet: (c) => c.skill !== undefined },\n { key: 'progress', isSet: (c) => c.progress !== undefined },\n { key: 'count', isSet: (c) => c.count !== undefined },\n { key: 'outputSchema', isSet: (c) => c.outputSchema !== undefined },\n { key: 'acceptance', isSet: (c) => c.acceptance !== undefined },\n];\n\nexport class UnsupportedInlineConfigError extends Error {\n constructor(\n readonly key: string,\n agentName: string,\n ) {\n super(`'${key}' is not supported yet for '${agentName}': SpawnPlanner does not accept it as a per-task override.`);\n this.name = 'UnsupportedInlineConfigError';\n }\n}\n\n/** Throws `UnsupportedInlineConfigError` naming the first not-yet-supported key the user actually set. */\nexport function assertSupportedInlineConfig(config: InlineConfig, agentName: string): void {\n for (const { key, isSet } of NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS) {\n if (isSet(config)) throw new UnsupportedInlineConfigError(key, agentName);\n }\n}\n\n/** Builds a `SpawnPlanTaskInput` for a SINGLE/PARALLEL step. Throws if the step set a not-yet-supported inline-config key. */\nexport function taskInputFromParsedStep(\n step: Pick<ParsedStep, 'name' | 'config' | 'task'>,\n cwd: string,\n context?: 'fresh' | 'fork',\n): SpawnPlanTaskInput {\n assertSupportedInlineConfig(step.config, step.name);\n return {\n agent: step.name,\n ...(step.task ? { task: step.task } : {}),\n cwd: step.config.cwd ?? cwd,\n ...(step.config.model ? { model: step.config.model } : {}),\n ...(context ? { context } : {}),\n };\n}\n"],"mappings":"AA2CA,MAAM,EAAsE,CAC1E,CAAE,IAAK,SAAU,MAAQ,GAAM,EAAE,SAAW,IAAA,GAAW,CACvD,CAAE,IAAK,aAAc,MAAQ,GAAM,EAAE,aAAe,IAAA,GAAW,CAC/D,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,WAAY,MAAQ,GAAM,EAAE,WAAa,IAAA,GAAW,CAC3D,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,eAAgB,MAAQ,GAAM,EAAE,eAAiB,IAAA,GAAW,CACnE,CAAE,IAAK,aAAc,MAAQ,GAAM,EAAE,aAAe,IAAA,GAAW,CAChE,CAED,IAAa,EAAb,cAAkD,KAAM,CACtD,YACE,EACA,EACA,CACA,MAAM,IAAI,EAAI,8BAA8B,EAAU,4DAA4D,CAHzG,KAAA,IAAA,EAIT,KAAK,KAAO,iCAKhB,SAAgB,EAA4B,EAAsB,EAAyB,CACzF,IAAK,GAAM,CAAE,MAAK,WAAW,EAC3B,GAAI,EAAM,EAAO,CAAE,MAAM,IAAI,EAA6B,EAAK,EAAU,CAK7E,SAAgB,EACd,EACA,EACA,EACoB,CAEpB,OADA,EAA4B,EAAK,OAAQ,EAAK,KAAK,CAC5C,CACL,MAAO,EAAK,KACZ,GAAI,EAAK,KAAO,CAAE,KAAM,EAAK,KAAM,CAAG,EAAE,CACxC,IAAK,EAAK,OAAO,KAAO,EACxB,GAAI,EAAK,OAAO,MAAQ,CAAE,MAAO,EAAK,OAAO,MAAO,CAAG,EAAE,CACzD,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=[{key:`output`,isSet:e=>e.output!==void 0},{key:`outputMode`,isSet:e=>e.outputMode!==void 0},{key:`reads`,isSet:e=>e.reads!==void 0},{key:`skill`,isSet:e=>e.skill!==void 0},{key:`progress`,isSet:e=>e.progress!==void 0},{key:`count`,isSet:e=>e.count!==void 0},{key:`outputSchema`,isSet:e=>e.outputSchema!==void 0},{key:`acceptance`,isSet:e=>e.acceptance!==void 0}];var t=class extends Error{constructor(e,t){super(`'${e}' is not supported yet for '${t}': SpawnPlanner does not accept it as a per-task override.`),this.key=e,this.name=`UnsupportedInlineConfigError`}};function n(n,r){for(let{key:i,isSet:a}of e)if(a(n))throw new t(i,r)}function r(e,t,r){return n(e.config,e.name),{agent:e.name,...e.task?{task:e.task}:{},cwd:e.config.cwd??t,...e.config.model?{model:e.config.model}:{},...r?{context:r}:{}}}export{t as UnsupportedInlineConfigError,r as taskInputFromParsedStep};
|
|
2
|
+
//# sourceMappingURL=spawnRequestMapping.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawnRequestMapping.mjs","names":[],"sources":["../../src/slash/spawnRequestMapping.ts"],"sourcesContent":["/**\n * Maps a parsed slash-command step (`chainExpression.ts`'s `ParsedStep`/\n * carrying the predecessor's full 13-key inline-config\n * vocabulary) onto `SpawnPlanner`'s actual request shapes\n * (`SpawnPlanTaskInput`), which accepts far fewer\n * fields today.\n *\n * WHY A SET INLINE-CONFIG KEY WITH NO DESTINATION THROWS, RATHER THAN\n * BEING DROPPED:\n * Parsing syntax a user can type and then silently ignoring it is the same\n * class of lie as a coverage number that does not mean what it claims -\n * nothing would tell the user their `[skill=x]` did nothing, and they would\n * reasonably conclude the feature is broken rather than simply not built\n * yet. `port-result-watcher` explicitly deferred per-task\n * `skill`/`toolBudget`/`turnBudget`/`outputSchema`/`acceptance`/`output`\n * overrides when it built `spawnPlan.ts` - listed as unwired, not\n * unwanted - so this is scoping DOWN a vocabulary that already has a home\n * to grow back into, not designing a small one. The error names the exact\n * key and says \"not yet supported\", distinct from an unrecognized key\n * (which `parseInlineConfig` already drops silently, matching the\n * predecessor's own behavior for a typo).\n *\n * WHY THE NOT-YET-SUPPORTED LIST IS DATA, NOT A SWITCH:\n * Wiring one of these up later (e.g. once `SpawnPlanTaskInput` grows a\n * `skill` field) means deleting one entry from\n * `NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS` and adding the field to the\n * builder functions below - not re-deriving which keys are safe to pass\n * through.\n *\n * AVOID:\n * - Silently dropping a set inline-config key with no destination\n * - Inlining the not-yet-supported check as ad hoc `if` statements at each\n * call site instead of the shared list below\n */\n\nimport type { SpawnPlanTaskInput } from '../extensions/spawnPlan.ts';\nimport type { InlineConfig, ParsedStep } from './chainExpression.ts';\n\ninterface NotYetSupportedKey {\n key: keyof InlineConfig;\n isSet: (config: InlineConfig) => boolean;\n}\n\nconst NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS: readonly NotYetSupportedKey[] = [\n { key: 'output', isSet: (c) => c.output !== undefined },\n { key: 'outputMode', isSet: (c) => c.outputMode !== undefined },\n { key: 'reads', isSet: (c) => c.reads !== undefined },\n { key: 'skill', isSet: (c) => c.skill !== undefined },\n { key: 'progress', isSet: (c) => c.progress !== undefined },\n { key: 'count', isSet: (c) => c.count !== undefined },\n { key: 'outputSchema', isSet: (c) => c.outputSchema !== undefined },\n { key: 'acceptance', isSet: (c) => c.acceptance !== undefined },\n];\n\nexport class UnsupportedInlineConfigError extends Error {\n constructor(\n readonly key: string,\n agentName: string,\n ) {\n super(`'${key}' is not supported yet for '${agentName}': SpawnPlanner does not accept it as a per-task override.`);\n this.name = 'UnsupportedInlineConfigError';\n }\n}\n\n/** Throws `UnsupportedInlineConfigError` naming the first not-yet-supported key the user actually set. */\nexport function assertSupportedInlineConfig(config: InlineConfig, agentName: string): void {\n for (const { key, isSet } of NOT_YET_SUPPORTED_INLINE_CONFIG_KEYS) {\n if (isSet(config)) throw new UnsupportedInlineConfigError(key, agentName);\n }\n}\n\n/** Builds a `SpawnPlanTaskInput` for a SINGLE/PARALLEL step. Throws if the step set a not-yet-supported inline-config key. */\nexport function taskInputFromParsedStep(\n step: Pick<ParsedStep, 'name' | 'config' | 'task'>,\n cwd: string,\n context?: 'fresh' | 'fork',\n): SpawnPlanTaskInput {\n assertSupportedInlineConfig(step.config, step.name);\n return {\n agent: step.name,\n ...(step.task ? { task: step.task } : {}),\n cwd: step.config.cwd ?? cwd,\n ...(step.config.model ? { model: step.config.model } : {}),\n ...(context ? { context } : {}),\n };\n}\n"],"mappings":"AA2CA,MAAM,EAAsE,CAC1E,CAAE,IAAK,SAAU,MAAQ,GAAM,EAAE,SAAW,IAAA,GAAW,CACvD,CAAE,IAAK,aAAc,MAAQ,GAAM,EAAE,aAAe,IAAA,GAAW,CAC/D,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,WAAY,MAAQ,GAAM,EAAE,WAAa,IAAA,GAAW,CAC3D,CAAE,IAAK,QAAS,MAAQ,GAAM,EAAE,QAAU,IAAA,GAAW,CACrD,CAAE,IAAK,eAAgB,MAAQ,GAAM,EAAE,eAAiB,IAAA,GAAW,CACnE,CAAE,IAAK,aAAc,MAAQ,GAAM,EAAE,aAAe,IAAA,GAAW,CAChE,CAED,IAAa,EAAb,cAAkD,KAAM,CACtD,YACE,EACA,EACA,CACA,MAAM,IAAI,EAAI,8BAA8B,EAAU,4DAA4D,CAHzG,KAAA,IAAA,EAIT,KAAK,KAAO,iCAKhB,SAAgB,EAA4B,EAAsB,EAAyB,CACzF,IAAK,GAAM,CAAE,MAAK,WAAW,EAC3B,GAAI,EAAM,EAAO,CAAE,MAAM,IAAI,EAA6B,EAAK,EAAU,CAK7E,SAAgB,EACd,EACA,EACA,EACoB,CAEpB,OADA,EAA4B,EAAK,OAAQ,EAAK,KAAK,CAC5C,CACL,MAAO,EAAK,KACZ,GAAI,EAAK,KAAO,CAAE,KAAM,EAAK,KAAM,CAAG,EAAE,CACxC,IAAK,EAAK,OAAO,KAAO,EACxB,GAAI,EAAK,OAAO,MAAQ,CAAE,MAAO,EAAK,OAAO,MAAO,CAAG,EAAE,CACzD,GAAI,EAAU,CAAE,UAAS,CAAG,EAAE,CAC/B"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=require(`../_virtual/_rolldown/runtime.cjs`);require(`../intercom/supervisorControlChannel.cjs`),require(`../shared/paths.cjs`);const t=require(`../runs/background/asyncJobTracker.cjs`);let n=require(`node:path`);n=e.__toESM(n,1);function r(e,t){for(let n of t)n.runId&&e.track(n.runId)}async function i(e,t,n,i){let a=await e.spawn({single:{agent:n.agent,task:n.task,...n.model?{model:n.model}:{},...n.context?{context:n.context}:{}},cwd:n.cwd,agentScope:n.agentScope,...n.parentSessionId?{parentSessionId:n.parentSessionId}:{},...n.currentDepth===void 0?{}:{currentDepth:n.currentDepth},...n.availableModels===void 0?{}:{availableModels:n.availableModels},...n.parentModel?{parentModel:n.parentModel}:{},...n.parentSessionFile?{parentSessionFile:n.parentSessionFile}:{},...n.parentLeafId?{parentLeafId:n.parentLeafId}:{}},i);return r(t,a.outcomes),a}async function a(e,t,n,i){let a=await e.spawn({tasks:n.tasks,cwd:n.cwd,agentScope:n.agentScope,...n.concurrency===void 0?{}:{concurrency:n.concurrency},...n.parentSessionId?{parentSessionId:n.parentSessionId}:{},...n.currentDepth===void 0?{}:{currentDepth:n.currentDepth},...n.availableModels===void 0?{}:{availableModels:n.availableModels},...n.parentModel?{parentModel:n.parentModel}:{},...n.parentSessionFile?{parentSessionFile:n.parentSessionFile}:{},...n.parentLeafId?{parentLeafId:n.parentLeafId}:{}},i);return r(t,a.outcomes),a}function o(e){return e?`${e.status??``}:${e.updatedAt??``}:${e.activityState??``}:${e.attentionReason??``}`:`untracked`}function s(e,n,r,i,a={}){let s,c;return s=e.register({id:`slash-run-watch-${r}`,intervalMs:a.intervalMs??500,run:()=>{let e=n.get(r),a=o(e);return a===c?!1:(c=a,i(e),e?.status!==void 0&&t.TERMINAL_ASYNC_JOB_STATES.has(e.status)&&s?.(),!0)}}),s}exports.launchParallelSubagents=a,exports.launchSingleSubagent=i,exports.watchTrackedRunUntilTerminal=s;
|
|
2
|
+
//# sourceMappingURL=subagentLaunch.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagentLaunch.cjs","names":["TERMINAL_ASYNC_JOB_STATES"],"sources":["../../src/slash/subagentLaunch.ts"],"sourcesContent":["/**\n * Launches a subagent spawn from a slash command and tracks the result,\n * plus the stop path for cancelling one. Replaces the predecessor's\n * `slash-bridge.ts`.\n *\n * WHY THE EVENT BUS IS GONE:\n * The predecessor's `registerSlashSubagentBridge` was one of three bridges\n * (`registerSlashSubagentBridge`, `registerSubagentRpcBridge`,\n * `registerPromptTemplateDelegationBridge`) sharing one `pi.events` channel\n * into one foreground executor, so decoupling was load-bearing there. In\n * this package, only the slash layer calls into `SpawnPlanner` today - no\n * RPC bridge exists, and the delegation bridge is out of scope (see\n * `nested-events.ts`'s and this port's own precedent for not building\n * infrastructure a second consumer does not exist to use yet). A command\n * handler resolves `SpawnPlanner` and calls it directly.\n *\n * WHY THIS DOES NOT AWAIT COMPLETION FOR SINGLE/PARALLEL:\n * `SpawnPlanner.spawn()`'s own contract (see `spawnPlan.ts`) resolves once\n * each child confirms it started, not once it finishes -\n * `SpawnPlanChildOutcome.summary` stays `undefined` for exactly that reason.\n * This package is async-only: a slash command that instead blocked until\n * completion would reintroduce the foreground model through the back door.\n * `launchChainSubagents` is the one exception, and deliberately not\n * refactored to match: CHAIN mode has to wait for each step to resolve\n * `{previous}`/`{outputs.name}` before starting the next one, so awaiting\n * `spawnChain()` is chain mode's own real shape, not a leftover synchronous\n * branch.\n *\n * WHY `AsyncJobTracker`, NOT A NEW POLLER:\n * `AsyncJobTracker`'s own module doc already deferred \"TUI rendering\" to\n * this package's slash+TUI port. `watchTrackedRunUntilTerminal` below reads\n * from it and registers with `PollScheduler` (the one master tick every\n * other watcher in this package uses) rather than owning a private timer or\n * a loop that polls and self-terminates. The render-key gate (only calling\n * `onChange` when the tracked job's status/updatedAt/activityState actually\n * changed) is the fix for the predecessor's fleet-view bug this package\n * exists to remove - re-rendering, and re-reading, only on real change - and\n * unregistering once terminal is a structural property of the subscription\n * itself, not a condition checked inside a loop this module owns.\n *\n * WHY A STOP-REQUEST FAILURE IS NOT SWALLOWED:\n * `requestAsyncInterrupt`/`requestAsyncStop` are synchronous and already\n * propagate a write failure by throwing; `requestSlashRunStop` does not\n * wrap them in a try/catch. The actual stop still happens out-of-band in\n * whichever process owns the run - \"fire-and-forget\" describes that\n * asynchrony, not permission to lose a failed write silently. Same\n * distinction `control-channel.ts`'s `removeIfPresent` draws between a\n * missing file (benign) and a real error (must propagate).\n *\n * AVOID:\n * - Awaiting `spawn()` for a result that will not exist yet. See above\n * - A bare `try { requestSlashRunStop(...) } catch {}` at any call site\n * - A private `setInterval`/`setTimeout` loop for polling a tracked run.\n * Register with `PollScheduler` instead\n */\n\nimport * as path from 'node:path';\n\nimport type { AgentScope } from '../agents/types.ts';\nimport type { ExtensionConfig } from '../extensions/config.ts';\nimport type {\n ISpawnPlanner,\n SpawnPlanChildOutcome,\n SpawnPlanResult,\n SpawnPlanTaskInput,\n} from '../extensions/spawnPlan.ts';\nimport { requestAsyncInterrupt, requestAsyncStop } from '../intercom/supervisorControlChannel.ts';\nimport { currentRunsDir } from '../shared/paths.ts';\nimport {\n TERMINAL_ASYNC_JOB_STATES,\n type ITrackedAsyncJobs,\n type TrackedAsyncJob,\n} from '../runs/background/asyncJobTracker.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport type { AvailableModelInfo, ParentModel } from '../runs/shared/modelFallback.ts';\n\nexport interface SlashSingleLaunchInput {\n agent: string;\n task: string;\n cwd: string;\n agentScope: AgentScope;\n model?: string;\n context?: 'fresh' | 'fork';\n parentSessionId?: string;\n currentDepth?: number;\n availableModels?: AvailableModelInfo[];\n parentModel?: ParentModel;\n parentSessionFile?: string;\n parentLeafId?: string;\n}\n\nexport interface SlashParallelLaunchInput {\n tasks: SpawnPlanTaskInput[];\n cwd: string;\n agentScope: AgentScope;\n concurrency?: number;\n parentSessionId?: string;\n currentDepth?: number;\n availableModels?: AvailableModelInfo[];\n parentModel?: ParentModel;\n parentSessionFile?: string;\n parentLeafId?: string;\n}\n\nfunction trackLaunchedRuns(tracker: ITrackedAsyncJobs, outcomes: SpawnPlanChildOutcome[]): void {\n for (const outcome of outcomes) {\n if (outcome.runId) tracker.track(outcome.runId);\n }\n}\n\n/** SINGLE mode: fires one child, returns once it has started, and tracks it for live display. */\nexport async function launchSingleSubagent(\n planner: ISpawnPlanner,\n tracker: ITrackedAsyncJobs,\n input: SlashSingleLaunchInput,\n config: ExtensionConfig,\n): Promise<SpawnPlanResult> {\n const result = await planner.spawn(\n {\n single: {\n agent: input.agent,\n task: input.task,\n ...(input.model ? { model: input.model } : {}),\n ...(input.context ? { context: input.context } : {}),\n },\n cwd: input.cwd,\n agentScope: input.agentScope,\n ...(input.parentSessionId ? { parentSessionId: input.parentSessionId } : {}),\n ...(input.currentDepth !== undefined ? { currentDepth: input.currentDepth } : {}),\n ...(input.availableModels !== undefined ? { availableModels: input.availableModels } : {}),\n ...(input.parentModel ? { parentModel: input.parentModel } : {}),\n ...(input.parentSessionFile ? { parentSessionFile: input.parentSessionFile } : {}),\n ...(input.parentLeafId ? { parentLeafId: input.parentLeafId } : {}),\n },\n config,\n );\n trackLaunchedRuns(tracker, result.outcomes);\n return result;\n}\n\n/** PARALLEL mode: fans out N children, returns once each has started, and tracks every one for live display. */\nexport async function launchParallelSubagents(\n planner: ISpawnPlanner,\n tracker: ITrackedAsyncJobs,\n input: SlashParallelLaunchInput,\n config: ExtensionConfig,\n): Promise<SpawnPlanResult> {\n const result = await planner.spawn(\n {\n tasks: input.tasks,\n cwd: input.cwd,\n agentScope: input.agentScope,\n ...(input.concurrency !== undefined ? { concurrency: input.concurrency } : {}),\n ...(input.parentSessionId ? { parentSessionId: input.parentSessionId } : {}),\n ...(input.currentDepth !== undefined ? { currentDepth: input.currentDepth } : {}),\n ...(input.availableModels !== undefined ? { availableModels: input.availableModels } : {}),\n ...(input.parentModel ? { parentModel: input.parentModel } : {}),\n ...(input.parentSessionFile ? { parentSessionFile: input.parentSessionFile } : {}),\n ...(input.parentLeafId ? { parentLeafId: input.parentLeafId } : {}),\n },\n config,\n );\n trackLaunchedRuns(tracker, result.outcomes);\n return result;\n}\n\nexport type SlashStopMode = 'interrupt' | 'stop';\n\n/**\n * Ask a tracked run to stop. See the module doc: a write failure here is a\n * real failure and is NOT caught - the caller must surface it.\n */\nexport function requestSlashRunStop(runId: string, mode: SlashStopMode = 'stop', reason?: string): void {\n const asyncDir = path.join(currentRunsDir(), runId);\n const payload = reason ? { reason } : {};\n if (mode === 'interrupt') requestAsyncInterrupt(asyncDir, payload);\n else requestAsyncStop(asyncDir, payload);\n}\n\nexport interface SlashRunWatchOptions {\n intervalMs?: number;\n}\n\nconst DEFAULT_SLASH_RUN_WATCH_INTERVAL_MS = 500;\n\nfunction renderKeyFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'untracked';\n return `${job.status ?? ''}:${job.updatedAt ?? ''}:${job.activityState ?? ''}:${job.attentionReason ?? ''}`;\n}\n\n/**\n * Call `onChange` only when a tracked run's status actually changes, and\n * stop watching once it reaches a terminal state - a structural property of\n * unregistering from `PollScheduler`, not a condition checked inside a loop\n * this function owns. See the module doc's `AsyncJobTracker`/`PollScheduler`\n * section for why.\n *\n * Returns an unregister function; call it to stop watching early (e.g. the\n * caller navigated away from the message before the run finished).\n */\nexport function watchTrackedRunUntilTerminal(\n scheduler: IPollScheduler,\n tracker: ITrackedAsyncJobs,\n runId: string,\n onChange: (job: TrackedAsyncJob | undefined) => void,\n options: SlashRunWatchOptions = {},\n): () => void {\n let unregister: (() => void) | undefined;\n let lastRenderKey: string | undefined;\n\n const check = (): boolean => {\n const job = tracker.get(runId);\n const key = renderKeyFor(job);\n if (key === lastRenderKey) return false;\n lastRenderKey = key;\n onChange(job);\n if (job?.status !== undefined && TERMINAL_ASYNC_JOB_STATES.has(job.status)) unregister?.();\n return true;\n };\n\n unregister = scheduler.register({\n id: `slash-run-watch-${runId}`,\n intervalMs: options.intervalMs ?? DEFAULT_SLASH_RUN_WATCH_INTERVAL_MS,\n run: check,\n });\n return unregister;\n}\n"],"mappings":"8OAwGA,SAAS,EAAkB,EAA4B,EAAyC,CAC9F,IAAK,IAAM,KAAW,EAChB,EAAQ,OAAO,EAAQ,MAAM,EAAQ,MAAM,CAKnD,eAAsB,EACpB,EACA,EACA,EACA,EAC0B,CAC1B,IAAM,EAAS,MAAM,EAAQ,MAC3B,CACE,OAAQ,CACN,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,GAAI,EAAM,MAAQ,CAAE,MAAO,EAAM,MAAO,CAAG,EAAE,CAC7C,GAAI,EAAM,QAAU,CAAE,QAAS,EAAM,QAAS,CAAG,EAAE,CACpD,CACD,IAAK,EAAM,IACX,WAAY,EAAM,WAClB,GAAI,EAAM,gBAAkB,CAAE,gBAAiB,EAAM,gBAAiB,CAAG,EAAE,CAC3E,GAAI,EAAM,eAAiB,IAAA,GAAmD,EAAE,CAAzC,CAAE,aAAc,EAAM,aAAc,CAC3E,GAAI,EAAM,kBAAoB,IAAA,GAAyD,EAAE,CAA/C,CAAE,gBAAiB,EAAM,gBAAiB,CACpF,GAAI,EAAM,YAAc,CAAE,YAAa,EAAM,YAAa,CAAG,EAAE,CAC/D,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CACjF,GAAI,EAAM,aAAe,CAAE,aAAc,EAAM,aAAc,CAAG,EAAE,CACnE,CACD,EACD,CAED,OADA,EAAkB,EAAS,EAAO,SAAS,CACpC,EAIT,eAAsB,EACpB,EACA,EACA,EACA,EAC0B,CAC1B,IAAM,EAAS,MAAM,EAAQ,MAC3B,CACE,MAAO,EAAM,MACb,IAAK,EAAM,IACX,WAAY,EAAM,WAClB,GAAI,EAAM,cAAgB,IAAA,GAAiD,EAAE,CAAvC,CAAE,YAAa,EAAM,YAAa,CACxE,GAAI,EAAM,gBAAkB,CAAE,gBAAiB,EAAM,gBAAiB,CAAG,EAAE,CAC3E,GAAI,EAAM,eAAiB,IAAA,GAAmD,EAAE,CAAzC,CAAE,aAAc,EAAM,aAAc,CAC3E,GAAI,EAAM,kBAAoB,IAAA,GAAyD,EAAE,CAA/C,CAAE,gBAAiB,EAAM,gBAAiB,CACpF,GAAI,EAAM,YAAc,CAAE,YAAa,EAAM,YAAa,CAAG,EAAE,CAC/D,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CACjF,GAAI,EAAM,aAAe,CAAE,aAAc,EAAM,aAAc,CAAG,EAAE,CACnE,CACD,EACD,CAED,OADA,EAAkB,EAAS,EAAO,SAAS,CACpC,EAsBT,SAAS,EAAa,EAA0C,CAE9D,OADK,EACE,GAAG,EAAI,QAAU,GAAG,GAAG,EAAI,WAAa,GAAG,GAAG,EAAI,eAAiB,GAAG,GAAG,EAAI,iBAAmB,KADtF,YAcnB,SAAgB,EACd,EACA,EACA,EACA,EACA,EAAgC,EAAE,CACtB,CACZ,IAAI,EACA,EAiBJ,MALA,GAAa,EAAU,SAAS,CAC9B,GAAI,mBAAmB,IACvB,WAAY,EAAQ,YAAc,IAClC,QAb2B,CAC3B,IAAM,EAAM,EAAQ,IAAI,EAAM,CACxB,EAAM,EAAa,EAAI,CAK7B,OAJI,IAAQ,EAAsB,IAClC,EAAgB,EAChB,EAAS,EAAI,CACT,GAAK,SAAW,IAAA,IAAaA,EAAAA,0BAA0B,IAAI,EAAI,OAAO,EAAE,KAAc,CACnF,KAOR,CAAC,CACK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{init_supervisorControlChannel as e}from"../intercom/supervisorControlChannel.mjs";import{init_paths as t}from"../shared/paths.mjs";import{TERMINAL_ASYNC_JOB_STATES as n,init_asyncJobTracker as r}from"../runs/background/asyncJobTracker.mjs";e(),t(),r();function i(e,t){for(let n of t)n.runId&&e.track(n.runId)}async function a(e,t,n,r){let a=await e.spawn({single:{agent:n.agent,task:n.task,...n.model?{model:n.model}:{},...n.context?{context:n.context}:{}},cwd:n.cwd,agentScope:n.agentScope,...n.parentSessionId?{parentSessionId:n.parentSessionId}:{},...n.currentDepth===void 0?{}:{currentDepth:n.currentDepth},...n.availableModels===void 0?{}:{availableModels:n.availableModels},...n.parentModel?{parentModel:n.parentModel}:{},...n.parentSessionFile?{parentSessionFile:n.parentSessionFile}:{},...n.parentLeafId?{parentLeafId:n.parentLeafId}:{}},r);return i(t,a.outcomes),a}async function o(e,t,n,r){let a=await e.spawn({tasks:n.tasks,cwd:n.cwd,agentScope:n.agentScope,...n.concurrency===void 0?{}:{concurrency:n.concurrency},...n.parentSessionId?{parentSessionId:n.parentSessionId}:{},...n.currentDepth===void 0?{}:{currentDepth:n.currentDepth},...n.availableModels===void 0?{}:{availableModels:n.availableModels},...n.parentModel?{parentModel:n.parentModel}:{},...n.parentSessionFile?{parentSessionFile:n.parentSessionFile}:{},...n.parentLeafId?{parentLeafId:n.parentLeafId}:{}},r);return i(t,a.outcomes),a}function s(e){return e?`${e.status??``}:${e.updatedAt??``}:${e.activityState??``}:${e.attentionReason??``}`:`untracked`}function c(e,t,r,i,a={}){let o,c;return o=e.register({id:`slash-run-watch-${r}`,intervalMs:a.intervalMs??500,run:()=>{let e=t.get(r),a=s(e);return a===c?!1:(c=a,i(e),e?.status!==void 0&&n.has(e.status)&&o?.(),!0)}}),o}export{o as launchParallelSubagents,a as launchSingleSubagent,c as watchTrackedRunUntilTerminal};
|
|
2
|
+
//# sourceMappingURL=subagentLaunch.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagentLaunch.mjs","names":[],"sources":["../../src/slash/subagentLaunch.ts"],"sourcesContent":["/**\n * Launches a subagent spawn from a slash command and tracks the result,\n * plus the stop path for cancelling one. Replaces the predecessor's\n * `slash-bridge.ts`.\n *\n * WHY THE EVENT BUS IS GONE:\n * The predecessor's `registerSlashSubagentBridge` was one of three bridges\n * (`registerSlashSubagentBridge`, `registerSubagentRpcBridge`,\n * `registerPromptTemplateDelegationBridge`) sharing one `pi.events` channel\n * into one foreground executor, so decoupling was load-bearing there. In\n * this package, only the slash layer calls into `SpawnPlanner` today - no\n * RPC bridge exists, and the delegation bridge is out of scope (see\n * `nested-events.ts`'s and this port's own precedent for not building\n * infrastructure a second consumer does not exist to use yet). A command\n * handler resolves `SpawnPlanner` and calls it directly.\n *\n * WHY THIS DOES NOT AWAIT COMPLETION FOR SINGLE/PARALLEL:\n * `SpawnPlanner.spawn()`'s own contract (see `spawnPlan.ts`) resolves once\n * each child confirms it started, not once it finishes -\n * `SpawnPlanChildOutcome.summary` stays `undefined` for exactly that reason.\n * This package is async-only: a slash command that instead blocked until\n * completion would reintroduce the foreground model through the back door.\n * `launchChainSubagents` is the one exception, and deliberately not\n * refactored to match: CHAIN mode has to wait for each step to resolve\n * `{previous}`/`{outputs.name}` before starting the next one, so awaiting\n * `spawnChain()` is chain mode's own real shape, not a leftover synchronous\n * branch.\n *\n * WHY `AsyncJobTracker`, NOT A NEW POLLER:\n * `AsyncJobTracker`'s own module doc already deferred \"TUI rendering\" to\n * this package's slash+TUI port. `watchTrackedRunUntilTerminal` below reads\n * from it and registers with `PollScheduler` (the one master tick every\n * other watcher in this package uses) rather than owning a private timer or\n * a loop that polls and self-terminates. The render-key gate (only calling\n * `onChange` when the tracked job's status/updatedAt/activityState actually\n * changed) is the fix for the predecessor's fleet-view bug this package\n * exists to remove - re-rendering, and re-reading, only on real change - and\n * unregistering once terminal is a structural property of the subscription\n * itself, not a condition checked inside a loop this module owns.\n *\n * WHY A STOP-REQUEST FAILURE IS NOT SWALLOWED:\n * `requestAsyncInterrupt`/`requestAsyncStop` are synchronous and already\n * propagate a write failure by throwing; `requestSlashRunStop` does not\n * wrap them in a try/catch. The actual stop still happens out-of-band in\n * whichever process owns the run - \"fire-and-forget\" describes that\n * asynchrony, not permission to lose a failed write silently. Same\n * distinction `control-channel.ts`'s `removeIfPresent` draws between a\n * missing file (benign) and a real error (must propagate).\n *\n * AVOID:\n * - Awaiting `spawn()` for a result that will not exist yet. See above\n * - A bare `try { requestSlashRunStop(...) } catch {}` at any call site\n * - A private `setInterval`/`setTimeout` loop for polling a tracked run.\n * Register with `PollScheduler` instead\n */\n\nimport * as path from 'node:path';\n\nimport type { AgentScope } from '../agents/types.ts';\nimport type { ExtensionConfig } from '../extensions/config.ts';\nimport type {\n ISpawnPlanner,\n SpawnPlanChildOutcome,\n SpawnPlanResult,\n SpawnPlanTaskInput,\n} from '../extensions/spawnPlan.ts';\nimport { requestAsyncInterrupt, requestAsyncStop } from '../intercom/supervisorControlChannel.ts';\nimport { currentRunsDir } from '../shared/paths.ts';\nimport {\n TERMINAL_ASYNC_JOB_STATES,\n type ITrackedAsyncJobs,\n type TrackedAsyncJob,\n} from '../runs/background/asyncJobTracker.ts';\nimport type { IPollScheduler } from '../shared/pollScheduler.ts';\nimport type { AvailableModelInfo, ParentModel } from '../runs/shared/modelFallback.ts';\n\nexport interface SlashSingleLaunchInput {\n agent: string;\n task: string;\n cwd: string;\n agentScope: AgentScope;\n model?: string;\n context?: 'fresh' | 'fork';\n parentSessionId?: string;\n currentDepth?: number;\n availableModels?: AvailableModelInfo[];\n parentModel?: ParentModel;\n parentSessionFile?: string;\n parentLeafId?: string;\n}\n\nexport interface SlashParallelLaunchInput {\n tasks: SpawnPlanTaskInput[];\n cwd: string;\n agentScope: AgentScope;\n concurrency?: number;\n parentSessionId?: string;\n currentDepth?: number;\n availableModels?: AvailableModelInfo[];\n parentModel?: ParentModel;\n parentSessionFile?: string;\n parentLeafId?: string;\n}\n\nfunction trackLaunchedRuns(tracker: ITrackedAsyncJobs, outcomes: SpawnPlanChildOutcome[]): void {\n for (const outcome of outcomes) {\n if (outcome.runId) tracker.track(outcome.runId);\n }\n}\n\n/** SINGLE mode: fires one child, returns once it has started, and tracks it for live display. */\nexport async function launchSingleSubagent(\n planner: ISpawnPlanner,\n tracker: ITrackedAsyncJobs,\n input: SlashSingleLaunchInput,\n config: ExtensionConfig,\n): Promise<SpawnPlanResult> {\n const result = await planner.spawn(\n {\n single: {\n agent: input.agent,\n task: input.task,\n ...(input.model ? { model: input.model } : {}),\n ...(input.context ? { context: input.context } : {}),\n },\n cwd: input.cwd,\n agentScope: input.agentScope,\n ...(input.parentSessionId ? { parentSessionId: input.parentSessionId } : {}),\n ...(input.currentDepth !== undefined ? { currentDepth: input.currentDepth } : {}),\n ...(input.availableModels !== undefined ? { availableModels: input.availableModels } : {}),\n ...(input.parentModel ? { parentModel: input.parentModel } : {}),\n ...(input.parentSessionFile ? { parentSessionFile: input.parentSessionFile } : {}),\n ...(input.parentLeafId ? { parentLeafId: input.parentLeafId } : {}),\n },\n config,\n );\n trackLaunchedRuns(tracker, result.outcomes);\n return result;\n}\n\n/** PARALLEL mode: fans out N children, returns once each has started, and tracks every one for live display. */\nexport async function launchParallelSubagents(\n planner: ISpawnPlanner,\n tracker: ITrackedAsyncJobs,\n input: SlashParallelLaunchInput,\n config: ExtensionConfig,\n): Promise<SpawnPlanResult> {\n const result = await planner.spawn(\n {\n tasks: input.tasks,\n cwd: input.cwd,\n agentScope: input.agentScope,\n ...(input.concurrency !== undefined ? { concurrency: input.concurrency } : {}),\n ...(input.parentSessionId ? { parentSessionId: input.parentSessionId } : {}),\n ...(input.currentDepth !== undefined ? { currentDepth: input.currentDepth } : {}),\n ...(input.availableModels !== undefined ? { availableModels: input.availableModels } : {}),\n ...(input.parentModel ? { parentModel: input.parentModel } : {}),\n ...(input.parentSessionFile ? { parentSessionFile: input.parentSessionFile } : {}),\n ...(input.parentLeafId ? { parentLeafId: input.parentLeafId } : {}),\n },\n config,\n );\n trackLaunchedRuns(tracker, result.outcomes);\n return result;\n}\n\nexport type SlashStopMode = 'interrupt' | 'stop';\n\n/**\n * Ask a tracked run to stop. See the module doc: a write failure here is a\n * real failure and is NOT caught - the caller must surface it.\n */\nexport function requestSlashRunStop(runId: string, mode: SlashStopMode = 'stop', reason?: string): void {\n const asyncDir = path.join(currentRunsDir(), runId);\n const payload = reason ? { reason } : {};\n if (mode === 'interrupt') requestAsyncInterrupt(asyncDir, payload);\n else requestAsyncStop(asyncDir, payload);\n}\n\nexport interface SlashRunWatchOptions {\n intervalMs?: number;\n}\n\nconst DEFAULT_SLASH_RUN_WATCH_INTERVAL_MS = 500;\n\nfunction renderKeyFor(job: TrackedAsyncJob | undefined): string {\n if (!job) return 'untracked';\n return `${job.status ?? ''}:${job.updatedAt ?? ''}:${job.activityState ?? ''}:${job.attentionReason ?? ''}`;\n}\n\n/**\n * Call `onChange` only when a tracked run's status actually changes, and\n * stop watching once it reaches a terminal state - a structural property of\n * unregistering from `PollScheduler`, not a condition checked inside a loop\n * this function owns. See the module doc's `AsyncJobTracker`/`PollScheduler`\n * section for why.\n *\n * Returns an unregister function; call it to stop watching early (e.g. the\n * caller navigated away from the message before the run finished).\n */\nexport function watchTrackedRunUntilTerminal(\n scheduler: IPollScheduler,\n tracker: ITrackedAsyncJobs,\n runId: string,\n onChange: (job: TrackedAsyncJob | undefined) => void,\n options: SlashRunWatchOptions = {},\n): () => void {\n let unregister: (() => void) | undefined;\n let lastRenderKey: string | undefined;\n\n const check = (): boolean => {\n const job = tracker.get(runId);\n const key = renderKeyFor(job);\n if (key === lastRenderKey) return false;\n lastRenderKey = key;\n onChange(job);\n if (job?.status !== undefined && TERMINAL_ASYNC_JOB_STATES.has(job.status)) unregister?.();\n return true;\n };\n\n unregister = scheduler.register({\n id: `slash-run-watch-${runId}`,\n intervalMs: options.intervalMs ?? DEFAULT_SLASH_RUN_WATCH_INTERVAL_MS,\n run: check,\n });\n return unregister;\n}\n"],"mappings":"0PAkEkG,IAC9C,IAKL,CAgC/C,SAAS,EAAkB,EAA4B,EAAyC,CAC9F,IAAK,IAAM,KAAW,EAChB,EAAQ,OAAO,EAAQ,MAAM,EAAQ,MAAM,CAKnD,eAAsB,EACpB,EACA,EACA,EACA,EAC0B,CAC1B,IAAM,EAAS,MAAM,EAAQ,MAC3B,CACE,OAAQ,CACN,MAAO,EAAM,MACb,KAAM,EAAM,KACZ,GAAI,EAAM,MAAQ,CAAE,MAAO,EAAM,MAAO,CAAG,EAAE,CAC7C,GAAI,EAAM,QAAU,CAAE,QAAS,EAAM,QAAS,CAAG,EAAE,CACpD,CACD,IAAK,EAAM,IACX,WAAY,EAAM,WAClB,GAAI,EAAM,gBAAkB,CAAE,gBAAiB,EAAM,gBAAiB,CAAG,EAAE,CAC3E,GAAI,EAAM,eAAiB,IAAA,GAAmD,EAAE,CAAzC,CAAE,aAAc,EAAM,aAAc,CAC3E,GAAI,EAAM,kBAAoB,IAAA,GAAyD,EAAE,CAA/C,CAAE,gBAAiB,EAAM,gBAAiB,CACpF,GAAI,EAAM,YAAc,CAAE,YAAa,EAAM,YAAa,CAAG,EAAE,CAC/D,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CACjF,GAAI,EAAM,aAAe,CAAE,aAAc,EAAM,aAAc,CAAG,EAAE,CACnE,CACD,EACD,CAED,OADA,EAAkB,EAAS,EAAO,SAAS,CACpC,EAIT,eAAsB,EACpB,EACA,EACA,EACA,EAC0B,CAC1B,IAAM,EAAS,MAAM,EAAQ,MAC3B,CACE,MAAO,EAAM,MACb,IAAK,EAAM,IACX,WAAY,EAAM,WAClB,GAAI,EAAM,cAAgB,IAAA,GAAiD,EAAE,CAAvC,CAAE,YAAa,EAAM,YAAa,CACxE,GAAI,EAAM,gBAAkB,CAAE,gBAAiB,EAAM,gBAAiB,CAAG,EAAE,CAC3E,GAAI,EAAM,eAAiB,IAAA,GAAmD,EAAE,CAAzC,CAAE,aAAc,EAAM,aAAc,CAC3E,GAAI,EAAM,kBAAoB,IAAA,GAAyD,EAAE,CAA/C,CAAE,gBAAiB,EAAM,gBAAiB,CACpF,GAAI,EAAM,YAAc,CAAE,YAAa,EAAM,YAAa,CAAG,EAAE,CAC/D,GAAI,EAAM,kBAAoB,CAAE,kBAAmB,EAAM,kBAAmB,CAAG,EAAE,CACjF,GAAI,EAAM,aAAe,CAAE,aAAc,EAAM,aAAc,CAAG,EAAE,CACnE,CACD,EACD,CAED,OADA,EAAkB,EAAS,EAAO,SAAS,CACpC,EAsBT,SAAS,EAAa,EAA0C,CAE9D,OADK,EACE,GAAG,EAAI,QAAU,GAAG,GAAG,EAAI,WAAa,GAAG,GAAG,EAAI,eAAiB,GAAG,GAAG,EAAI,iBAAmB,KADtF,YAcnB,SAAgB,EACd,EACA,EACA,EACA,EACA,EAAgC,EAAE,CACtB,CACZ,IAAI,EACA,EAiBJ,MALA,GAAa,EAAU,SAAS,CAC9B,GAAI,mBAAmB,IACvB,WAAY,EAAQ,YAAc,IAClC,QAb2B,CAC3B,IAAM,EAAM,EAAQ,IAAI,EAAM,CACxB,EAAM,EAAa,EAAI,CAK7B,OAJI,IAAQ,EAAsB,IAClC,EAAgB,EAChB,EAAS,EAAI,CACT,GAAK,SAAW,IAAA,IAAa,EAA0B,IAAI,EAAI,OAAO,EAAE,KAAc,CACnF,KAOR,CAAC,CACK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
require(`../_virtual/_rolldown/runtime.cjs`);let e=require(`@earendil-works/pi-tui`),t=require(`@agimon-ai/doompi-ui/components/doomOverlay`);t.DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;const n=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,r=[`tools`,`skills`,`extensions`],i=[[`↑↓/jk`,`move`],[`enter`,`view`],[`tab`,`cycle`],[`J/K`,`scroll`]];function a(t,n){let r=Math.max(0,n),i=(0,e.truncateToWidth)(t,r,`…`);return i+` `.repeat(Math.max(0,r-(0,e.visibleWidth)(i)))}function o(t,n,r){let i=Math.max(0,r),o=(0,e.visibleWidth)(n);return o+2>=i?a(t,i):`${a(t,Math.max(1,i-o-2))} ${a(n,o)}`}function s(t,n,r,i,a){for(let o of(0,e.wrapTextWithAnsi)(n,Math.max(1,r)))t.push(a.fg(i,o))}function c(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)s(e,` • ${t.name}`,r,`text`,i),t.detail&&s(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function l(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function u(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),s(i,e.error,n,`error`,r),i.push(``));let a=l(e,t);return c(i,`PROJECTED EFFECTIVE`,a.effective,n,r),c(i,`REMOVED BY PARENT`,a.removed,n,r),c(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function d(t,n,i){return(0,e.truncateToWidth)(r.map(e=>{let n=e.toUpperCase();return e===t?i.inverse(i.bold(` ${n} `)):i.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,n),`…`)}function f(t){let n=Math.max(2,t-(0,e.visibleWidth)(`│`)),r=Math.max(1,Math.floor(n/3)),i=Math.max(1,n-r),a=+(r>=3&&i>=3);return{leftContentWidth:Math.max(1,r-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var p=class extends t.DoomOverlay{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=r.indexOf(this.tab);this.switchTab(r[(e+1)%r.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(t){if((0,e.matchesKey)(t,`escape`)||(0,e.matchesKey)(t,`ctrl+c`)){this.done(void 0);return}if((0,e.matchesKey)(t,e.Key.shift(`k`)))return this.scrollDetail(-1);if((0,e.matchesKey)(t,e.Key.shift(`j`)))return this.scrollDetail(1);if((0,e.matchesKey)(t,`up`)||t===`k`)return this.moveCursor(-1);if((0,e.matchesKey)(t,`down`)||t===`j`)return this.moveCursor(1);if((0,e.matchesKey)(t,`pageUp`))return this.moveCursor(-this.listPageSize);if((0,e.matchesKey)(t,`pageDown`))return this.moveCursor(this.listPageSize);if((0,e.matchesKey)(t,`enter`))return this.inspectCursor();if((0,e.matchesKey)(t,`tab`))return this.cycleTab();if(t===`t`)return this.switchTab(`tools`);if(t===`s`)return this.switchTab(`skills`);if(t===`e`)return this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),n=this.inspectedEntry(),r=this.entries.length?String(this.cursorIndex+1):`empty`,a=e?n?`C${r} I${(this.inspectedIndex??0)+1}`:`C${r} I-`:`empty`;return{title:`AGENTS`,accent:t.DOOM_OVERLAY_ACCENT,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:`↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close`,footerHints:i,footerRight:a}}renderBody(e,t){let n=f(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),o=` `.repeat(n.gutterWidth),s=this.theme.fg(`borderMuted`,`│`),c=[];for(let e=0;e<t;e++)c.push(`${a(r[e]??``,n.leftContentWidth)}${o}${s}${o}${a(i[e]??``,n.rightContentWidth)}`);return c.map(t=>a(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return s(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let s=r+t===this.cursorIndex,c=s?this.theme.fg(`accent`,`›`):` `,l=i.agent.runtime??`pi`,u=o(`${c} ${s?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${l}`,e),d=s?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(d,a(u,e)))}return n.slice(0,t)}renderDetail(e,t){let r=this.inspectedEntry();if(!r){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let r=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return s(r,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),r.push(``),s(r,n,e,`dim`,this.theme),r.slice(0,t)}let i=r.agent.runtime??`pi`,a=[o(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${r.agent.name}`)),`${r.agent.source} · ${i}`,e)];s(a,r.agent.description,e,`text`,this.theme),s(a,r.resources.notice||n,e,r.resources.configuredOnly?`warning`:`dim`,this.theme),a.push(d(this.tab,e,this.theme),``);let c=u(r.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-a.length),this.detailTotal=c.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,c.length-this.detailPageSize)),[...a,...c.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function m(e,n){await e.ui.custom((e,t,r,i)=>new p(e,t,n,i),t.DOOM_FULLSCREEN_UI_OPTIONS)}exports.openAgentCatalog=m;
|
|
2
|
+
//# sourceMappingURL=agentCatalog.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentCatalog.cjs","names":["DOOM_FULLSCREEN_UI_OPTIONS","DoomOverlay","Key","DOOM_OVERLAY_ACCENT"],"sources":["../../src/tui/agentCatalog.ts"],"sourcesContent":["import type { ExtensionContext, Theme } from '@earendil-works/pi-coding-agent';\nimport {\n DOOM_FULLSCREEN_UI_OPTIONS,\n DOOM_OVERLAY_ACCENT,\n DoomOverlay,\n type DoomOverlayChrome,\n type DoomOverlayTui,\n} from '@agimon-ai/doompi-ui/components/doomOverlay';\nimport { Key, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from '@earendil-works/pi-tui';\n\nimport type { AgentConfig } from '../agents/types.ts';\nimport type {\n AgentCatalogEntry,\n AgentResourceProjection,\n ProjectedResource,\n ResourceTabProjection,\n} from './agentResourceProjection.ts';\n\nexport const AGENT_CATALOG_OVERLAY_OPTIONS = DOOM_FULLSCREEN_UI_OPTIONS.overlayOptions;\nexport type AgentResourceTab = 'tools' | 'skills' | 'extensions';\n\ntype ThemeBg = Parameters<Theme['bg']>[0];\ntype ThemeColor = Parameters<Theme['fg']>[0];\n\ninterface SplitLayout {\n leftContentWidth: number;\n rightContentWidth: number;\n gutterWidth: number;\n}\n\nconst TITLE = 'AGENTS';\nconst BREADCRUMB = 'SPC › a / agents › l / available';\nconst SELECTION_MARKER = '›';\nconst ELLIPSIS = '…';\nconst DEFAULT_PAGE_SIZE = 1;\nconst PI_RUNTIME = 'pi';\nconst DIVIDER = '│';\nconst PROJECTED_EFFECTIVE = 'PROJECTED EFFECTIVE';\nconst REMOVED_BY_PARENT = 'REMOVED BY PARENT';\nconst UNRESOLVED_AT_PREVIEW = 'UNRESOLVED AT PREVIEW';\nconst PROJECTION_ERROR = 'PROJECTION ERROR';\nconst GLOBAL_PREVIEW_NOTICE =\n 'Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.';\nconst TAB_ORDER: readonly AgentResourceTab[] = ['tools', 'skills', 'extensions'];\nconst FOOTER = '↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close';\nconst FOOTER_HINTS: readonly (readonly [string, string])[] = [\n ['↑↓/jk', 'move'],\n ['enter', 'view'],\n ['tab', 'cycle'],\n ['J/K', 'scroll'],\n];\n\nfunction fit(text: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const clipped = truncateToWidth(text, safeWidth, ELLIPSIS);\n return clipped + ' '.repeat(Math.max(0, safeWidth - visibleWidth(clipped)));\n}\n\nfunction rightAligned(left: string, right: string, width: number): string {\n const safeWidth = Math.max(0, width);\n const rightWidth = visibleWidth(right);\n if (rightWidth + 2 >= safeWidth) return fit(left, safeWidth);\n const leftWidth = Math.max(1, safeWidth - rightWidth - 2);\n return `${fit(left, leftWidth)} ${fit(right, rightWidth)}`;\n}\n\nfunction plural(count: number, singular: string): string {\n return `${count} ${singular}${count === 1 ? '' : 's'}`;\n}\n\nexport function agentResourceSummary(agent: AgentConfig): string {\n const mcpTools = plural(agent.mcpDirectTools?.length ?? 0, 'MCP tool');\n const skills = plural(agent.skills?.length ?? 0, 'skill');\n const extensions = plural((agent.extensions?.length ?? 0) + (agent.subagentOnlyExtensions?.length ?? 0), 'extension');\n const configured = `${mcpTools} · ${skills} · ${extensions}`;\n return agent.tools === undefined\n ? `tools default · configured: ${configured}`\n : `configured: ${plural(agent.tools.length, 'tool')} · ${configured}`;\n}\n\nfunction appendWrapped(lines: string[], text: string, width: number, colour: ThemeColor, theme: Theme): void {\n for (const line of wrapTextWithAnsi(text, Math.max(1, width))) lines.push(theme.fg(colour, line));\n}\n\nfunction appendResources(\n lines: string[],\n heading: string,\n items: readonly ProjectedResource[],\n width: number,\n theme: Theme,\n): void {\n lines.push(theme.bold(theme.fg('accent', heading)));\n if (items.length === 0) {\n lines.push(theme.fg('dim', ' none'));\n } else {\n for (const item of items) {\n appendWrapped(lines, ` • ${item.name}`, width, 'text', theme);\n if (item.detail) appendWrapped(lines, ` ${item.detail}`, width, 'dim', theme);\n }\n }\n lines.push('');\n}\n\nfunction tabProjection(projection: AgentResourceProjection, tab: AgentResourceTab): ResourceTabProjection {\n if (tab === 'skills') return projection.skills;\n if (tab === 'extensions') return projection.extensions;\n return projection.tools;\n}\n\nfunction resourceLines(\n projection: AgentResourceProjection,\n tab: AgentResourceTab,\n width: number,\n theme: Theme,\n): string[] {\n const lines: string[] = [];\n if (projection.error) {\n lines.push(theme.bold(theme.fg('error', PROJECTION_ERROR)));\n appendWrapped(lines, projection.error, width, 'error', theme);\n lines.push('');\n }\n const resources = tabProjection(projection, tab);\n appendResources(lines, PROJECTED_EFFECTIVE, resources.effective, width, theme);\n appendResources(lines, REMOVED_BY_PARENT, resources.removed, width, theme);\n appendResources(lines, UNRESOLVED_AT_PREVIEW, resources.unresolved, width, theme);\n return lines;\n}\n\nfunction tabStrip(tab: AgentResourceTab, width: number, theme: Theme): string {\n const labels = TAB_ORDER.map((candidate) => {\n const label = candidate.toUpperCase();\n return candidate === tab ? theme.inverse(theme.bold(` ${label} `)) : theme.fg('dim', ` ${label} `);\n }).join(' ');\n return truncateToWidth(labels, Math.max(0, width), ELLIPSIS);\n}\n\nfunction splitLayout(width: number): SplitLayout {\n const paneBudget = Math.max(2, width - visibleWidth(DIVIDER));\n const leftPaneWidth = Math.max(1, Math.floor(paneBudget / 3));\n const rightPaneWidth = Math.max(1, paneBudget - leftPaneWidth);\n const gutterWidth = leftPaneWidth >= 3 && rightPaneWidth >= 3 ? 1 : 0;\n return {\n leftContentWidth: Math.max(1, leftPaneWidth - gutterWidth),\n rightContentWidth: Math.max(1, rightPaneWidth - gutterWidth),\n gutterWidth,\n };\n}\n\nexport class AgentCatalogComponent extends DoomOverlay {\n private readonly entries: AgentCatalogEntry[];\n private cursorIndex = 0;\n private inspectedIndex: number | undefined;\n private tab: AgentResourceTab = 'tools';\n private listPageSize = DEFAULT_PAGE_SIZE;\n private detailPageSize = DEFAULT_PAGE_SIZE;\n private detailOffset = 0;\n private detailTotal = 0;\n\n constructor(\n tui: DoomOverlayTui,\n theme: Theme,\n entries: readonly AgentCatalogEntry[],\n private readonly done: (result: undefined) => void,\n ) {\n super(tui, theme);\n this.entries = [...entries].sort((left, right) => left.agent.name.localeCompare(right.agent.name));\n }\n\n private cursorEntry(): AgentCatalogEntry | undefined {\n return this.entries[Math.min(this.cursorIndex, Math.max(0, this.entries.length - 1))];\n }\n\n private inspectedEntry(): AgentCatalogEntry | undefined {\n if (this.inspectedIndex === undefined) return undefined;\n return this.entries[this.inspectedIndex];\n }\n\n private moveCursor(delta: number): void {\n if (this.entries.length === 0) return;\n const next = Math.max(0, Math.min(this.entries.length - 1, this.cursorIndex + delta));\n if (next === this.cursorIndex) return;\n this.cursorIndex = next;\n this.invalidate();\n }\n\n private inspectCursor(): void {\n if (!this.cursorEntry()) return;\n this.inspectedIndex = this.cursorIndex;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private switchTab(tab: AgentResourceTab): void {\n if (this.tab === tab) return;\n this.tab = tab;\n this.detailOffset = 0;\n this.invalidate();\n }\n\n private cycleTab(): void {\n const current = TAB_ORDER.indexOf(this.tab);\n this.switchTab(TAB_ORDER[(current + 1) % TAB_ORDER.length] ?? 'tools');\n }\n\n private scrollDetail(delta: number): void {\n if (!this.inspectedEntry()) return;\n const maximum = Math.max(0, this.detailTotal - this.detailPageSize);\n const next = Math.max(0, Math.min(maximum, this.detailOffset + delta));\n if (next === this.detailOffset) return;\n this.detailOffset = next;\n this.invalidate();\n }\n\n handleInput(data: string): void {\n if (matchesKey(data, 'escape') || matchesKey(data, 'ctrl+c')) {\n this.done(undefined);\n return;\n }\n if (matchesKey(data, Key.shift('k'))) return this.scrollDetail(-1);\n if (matchesKey(data, Key.shift('j'))) return this.scrollDetail(1);\n if (matchesKey(data, 'up') || data === 'k') return this.moveCursor(-1);\n if (matchesKey(data, 'down') || data === 'j') return this.moveCursor(1);\n if (matchesKey(data, 'pageUp')) return this.moveCursor(-this.listPageSize);\n if (matchesKey(data, 'pageDown')) return this.moveCursor(this.listPageSize);\n if (matchesKey(data, 'enter')) return this.inspectCursor();\n if (matchesKey(data, 'tab')) return this.cycleTab();\n if (data === 't') return this.switchTab('tools');\n if (data === 's') return this.switchTab('skills');\n if (data === 'e') return this.switchTab('extensions');\n }\n\n protected getChrome(): DoomOverlayChrome {\n const cursor = this.cursorEntry();\n const inspected = this.inspectedEntry();\n const cursorPosition = this.entries.length ? String(this.cursorIndex + 1) : 'empty';\n const footerRight = !cursor\n ? 'empty'\n : inspected\n ? `C${cursorPosition} I${(this.inspectedIndex ?? 0) + 1}`\n : `C${cursorPosition} I-`;\n return {\n title: TITLE,\n accent: DOOM_OVERLAY_ACCENT,\n breadcrumb: BREADCRUMB,\n headerRight: `${this.entries.length} available · ${this.tab}`,\n footer: FOOTER,\n footerHints: FOOTER_HINTS,\n footerRight,\n };\n }\n\n protected renderBody(width: number, height: number): string[] {\n const layout = splitLayout(width);\n const left = this.renderList(layout.leftContentWidth, height);\n const right = this.renderDetail(layout.rightContentWidth, height);\n const gutter = ' '.repeat(layout.gutterWidth);\n const divider = this.theme.fg('borderMuted', DIVIDER);\n const lines: string[] = [];\n for (let index = 0; index < height; index++) {\n lines.push(\n `${fit(left[index] ?? '', layout.leftContentWidth)}${gutter}${divider}${gutter}${fit(\n right[index] ?? '',\n layout.rightContentWidth,\n )}`,\n );\n }\n return lines.map((line) => fit(line, width));\n }\n\n private renderList(width: number, height: number): string[] {\n const lines = [this.theme.bold(this.theme.fg('accent', `AGENTS ${this.entries.length}`))];\n if (this.entries.length === 0) {\n appendWrapped(lines, 'No enabled agents are available from this session cwd.', width, 'dim', this.theme);\n this.listPageSize = DEFAULT_PAGE_SIZE;\n return lines.slice(0, height);\n }\n\n this.listPageSize = Math.max(DEFAULT_PAGE_SIZE, height - 1);\n const start = Math.max(\n 0,\n Math.min(this.cursorIndex - this.listPageSize + 1, Math.max(0, this.entries.length - this.listPageSize)),\n );\n for (const [offset, entry] of this.entries.slice(start, start + this.listPageSize).entries()) {\n const index = start + offset;\n const current = index === this.cursorIndex;\n const marker = current ? this.theme.fg('accent', SELECTION_MARKER) : ' ';\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const name = current ? this.theme.bold(entry.agent.name) : entry.agent.name;\n const row = rightAligned(`${marker} ${name}`, `${entry.agent.source} · ${runtime}`, width);\n const background: ThemeBg = current ? 'selectedBg' : 'userMessageBg';\n lines.push(this.theme.bg(background, fit(row, width)));\n }\n return lines.slice(0, height);\n }\n\n private renderDetail(width: number, height: number): string[] {\n const entry = this.inspectedEntry();\n if (!entry) {\n this.detailTotal = 0;\n this.detailPageSize = Math.max(DEFAULT_PAGE_SIZE, height);\n this.detailOffset = 0;\n const lines = [this.theme.bold(this.theme.fg('accent', 'AGENT RESOURCES')), ''];\n appendWrapped(lines, 'Press Enter to inspect the cursor agent.', width, 'text', this.theme);\n lines.push('');\n appendWrapped(lines, GLOBAL_PREVIEW_NOTICE, width, 'dim', this.theme);\n return lines.slice(0, height);\n }\n\n const runtime = entry.agent.runtime ?? PI_RUNTIME;\n const header = [\n rightAligned(\n this.theme.bold(this.theme.fg('accent', `INSPECTING ${entry.agent.name}`)),\n `${entry.agent.source} · ${runtime}`,\n width,\n ),\n ];\n appendWrapped(header, entry.agent.description, width, 'text', this.theme);\n appendWrapped(\n header,\n entry.resources.notice || GLOBAL_PREVIEW_NOTICE,\n width,\n entry.resources.configuredOnly ? 'warning' : 'dim',\n this.theme,\n );\n header.push(tabStrip(this.tab, width, this.theme), '');\n\n const resources = resourceLines(entry.resources, this.tab, width, this.theme);\n this.detailPageSize = Math.max(0, height - header.length);\n this.detailTotal = resources.length;\n this.detailOffset = Math.min(this.detailOffset, Math.max(0, resources.length - this.detailPageSize));\n return [...header, ...resources.slice(this.detailOffset, this.detailOffset + this.detailPageSize)].slice(0, height);\n }\n}\n\nexport async function openAgentCatalog(ctx: ExtensionContext, entries: readonly AgentCatalogEntry[]): Promise<void> {\n await ctx.ui.custom<undefined>(\n (tui, theme, _keybindings, done) => new AgentCatalogComponent(tui, theme, entries, done),\n DOOM_FULLSCREEN_UI_OPTIONS,\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{Key as e,matchesKey as t,truncateToWidth as n,visibleWidth as r,wrapTextWithAnsi as i}from"@earendil-works/pi-tui";import{DOOM_FULLSCREEN_UI_OPTIONS as a,DOOM_OVERLAY_ACCENT as o,DoomOverlay as s}from"@agimon-ai/doompi-ui/components/doomOverlay";a.overlayOptions;const c=`Launch projection from the current parent-policy snapshot. Child resource loading can still change qualified resources.`,l=[`tools`,`skills`,`extensions`],u=[[`↑↓/jk`,`move`],[`enter`,`view`],[`tab`,`cycle`],[`J/K`,`scroll`]];function d(e,t){let i=Math.max(0,t),a=n(e,i,`…`);return a+` `.repeat(Math.max(0,i-r(a)))}function f(e,t,n){let i=Math.max(0,n),a=r(t);return a+2>=i?d(e,i):`${d(e,Math.max(1,i-a-2))} ${d(t,a)}`}function p(e,t,n,r,a){for(let o of i(t,Math.max(1,n)))e.push(a.fg(r,o))}function m(e,t,n,r,i){if(e.push(i.bold(i.fg(`accent`,t))),n.length===0)e.push(i.fg(`dim`,` none`));else for(let t of n)p(e,` • ${t.name}`,r,`text`,i),t.detail&&p(e,` ${t.detail}`,r,`dim`,i);e.push(``)}function h(e,t){return t===`skills`?e.skills:t===`extensions`?e.extensions:e.tools}function g(e,t,n,r){let i=[];e.error&&(i.push(r.bold(r.fg(`error`,`PROJECTION ERROR`))),p(i,e.error,n,`error`,r),i.push(``));let a=h(e,t);return m(i,`PROJECTED EFFECTIVE`,a.effective,n,r),m(i,`REMOVED BY PARENT`,a.removed,n,r),m(i,`UNRESOLVED AT PREVIEW`,a.unresolved,n,r),i}function _(e,t,r){return n(l.map(t=>{let n=t.toUpperCase();return t===e?r.inverse(r.bold(` ${n} `)):r.fg(`dim`,` ${n} `)}).join(` `),Math.max(0,t),`…`)}function v(e){let t=Math.max(2,e-r(`│`)),n=Math.max(1,Math.floor(t/3)),i=Math.max(1,t-n),a=+(n>=3&&i>=3);return{leftContentWidth:Math.max(1,n-a),rightContentWidth:Math.max(1,i-a),gutterWidth:a}}var y=class extends s{entries;cursorIndex=0;inspectedIndex;tab=`tools`;listPageSize=1;detailPageSize=1;detailOffset=0;detailTotal=0;constructor(e,t,n,r){super(e,t),this.done=r,this.entries=[...n].sort((e,t)=>e.agent.name.localeCompare(t.agent.name))}cursorEntry(){return this.entries[Math.min(this.cursorIndex,Math.max(0,this.entries.length-1))]}inspectedEntry(){if(this.inspectedIndex!==void 0)return this.entries[this.inspectedIndex]}moveCursor(e){if(this.entries.length===0)return;let t=Math.max(0,Math.min(this.entries.length-1,this.cursorIndex+e));t!==this.cursorIndex&&(this.cursorIndex=t,this.invalidate())}inspectCursor(){this.cursorEntry()&&(this.inspectedIndex=this.cursorIndex,this.detailOffset=0,this.invalidate())}switchTab(e){this.tab!==e&&(this.tab=e,this.detailOffset=0,this.invalidate())}cycleTab(){let e=l.indexOf(this.tab);this.switchTab(l[(e+1)%l.length]??`tools`)}scrollDetail(e){if(!this.inspectedEntry())return;let t=Math.max(0,this.detailTotal-this.detailPageSize),n=Math.max(0,Math.min(t,this.detailOffset+e));n!==this.detailOffset&&(this.detailOffset=n,this.invalidate())}handleInput(n){if(t(n,`escape`)||t(n,`ctrl+c`)){this.done(void 0);return}if(t(n,e.shift(`k`)))return this.scrollDetail(-1);if(t(n,e.shift(`j`)))return this.scrollDetail(1);if(t(n,`up`)||n===`k`)return this.moveCursor(-1);if(t(n,`down`)||n===`j`)return this.moveCursor(1);if(t(n,`pageUp`))return this.moveCursor(-this.listPageSize);if(t(n,`pageDown`))return this.moveCursor(this.listPageSize);if(t(n,`enter`))return this.inspectCursor();if(t(n,`tab`))return this.cycleTab();if(n===`t`)return this.switchTab(`tools`);if(n===`s`)return this.switchTab(`skills`);if(n===`e`)return this.switchTab(`extensions`)}getChrome(){let e=this.cursorEntry(),t=this.inspectedEntry(),n=this.entries.length?String(this.cursorIndex+1):`empty`,r=e?t?`C${n} I${(this.inspectedIndex??0)+1}`:`C${n} I-`:`empty`;return{title:`AGENTS`,accent:o,breadcrumb:`SPC › a / agents › l / available`,headerRight:`${this.entries.length} available · ${this.tab}`,footer:`↑↓/jk cursor · PgUp/PgDn page · enter inspect · tab resource · J/K scroll · esc close`,footerHints:u,footerRight:r}}renderBody(e,t){let n=v(e),r=this.renderList(n.leftContentWidth,t),i=this.renderDetail(n.rightContentWidth,t),a=` `.repeat(n.gutterWidth),o=this.theme.fg(`borderMuted`,`│`),s=[];for(let e=0;e<t;e++)s.push(`${d(r[e]??``,n.leftContentWidth)}${a}${o}${a}${d(i[e]??``,n.rightContentWidth)}`);return s.map(t=>d(t,e))}renderList(e,t){let n=[this.theme.bold(this.theme.fg(`accent`,`AGENTS ${this.entries.length}`))];if(this.entries.length===0)return p(n,`No enabled agents are available from this session cwd.`,e,`dim`,this.theme),this.listPageSize=1,n.slice(0,t);this.listPageSize=Math.max(1,t-1);let r=Math.max(0,Math.min(this.cursorIndex-this.listPageSize+1,Math.max(0,this.entries.length-this.listPageSize)));for(let[t,i]of this.entries.slice(r,r+this.listPageSize).entries()){let a=r+t===this.cursorIndex,o=a?this.theme.fg(`accent`,`›`):` `,s=i.agent.runtime??`pi`,c=f(`${o} ${a?this.theme.bold(i.agent.name):i.agent.name}`,`${i.agent.source} · ${s}`,e),l=a?`selectedBg`:`userMessageBg`;n.push(this.theme.bg(l,d(c,e)))}return n.slice(0,t)}renderDetail(e,t){let n=this.inspectedEntry();if(!n){this.detailTotal=0,this.detailPageSize=Math.max(1,t),this.detailOffset=0;let n=[this.theme.bold(this.theme.fg(`accent`,`AGENT RESOURCES`)),``];return p(n,`Press Enter to inspect the cursor agent.`,e,`text`,this.theme),n.push(``),p(n,c,e,`dim`,this.theme),n.slice(0,t)}let r=n.agent.runtime??`pi`,i=[f(this.theme.bold(this.theme.fg(`accent`,`INSPECTING ${n.agent.name}`)),`${n.agent.source} · ${r}`,e)];p(i,n.agent.description,e,`text`,this.theme),p(i,n.resources.notice||c,e,n.resources.configuredOnly?`warning`:`dim`,this.theme),i.push(_(this.tab,e,this.theme),``);let a=g(n.resources,this.tab,e,this.theme);return this.detailPageSize=Math.max(0,t-i.length),this.detailTotal=a.length,this.detailOffset=Math.min(this.detailOffset,Math.max(0,a.length-this.detailPageSize)),[...i,...a.slice(this.detailOffset,this.detailOffset+this.detailPageSize)].slice(0,t)}};async function b(e,t){await e.ui.custom((e,n,r,i)=>new y(e,n,t,i),a)}export{b as openAgentCatalog};
|
|
2
|
+
//# sourceMappingURL=agentCatalog.mjs.map
|