@pi-unipi/unipi 3.0.0-alpha.2 → 3.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +292 -0
- package/README.md +8 -11
- package/docs/prefix-cache-architecture.md +14 -0
- package/package.json +22 -24
- package/packages/ask-user/README.md +55 -107
- package/packages/ask-user/ask-ui.ts +306 -732
- package/packages/ask-user/clipboard.ts +50 -0
- package/packages/ask-user/config.ts +74 -78
- package/packages/ask-user/package.json +2 -2
- package/packages/ask-user/questions.ts +151 -0
- package/packages/ask-user/skills/ask-user/SKILL.md +59 -133
- package/packages/ask-user/tools.ts +198 -432
- package/packages/autocomplete/package.json +1 -1
- package/packages/autocomplete/src/constants.ts +38 -43
- package/packages/autocomplete/src/sorting.ts +8 -0
- package/packages/background-tasks/package.json +2 -2
- package/packages/background-tasks/src/config.ts +0 -73
- package/packages/background-tasks/src/index.ts +20 -16
- package/packages/background-tasks/src/registry.ts +1 -171
- package/packages/background-tasks/src/types.ts +0 -32
- package/packages/btw/README.md +13 -56
- package/packages/btw/extensions/btw.ts +403 -1796
- package/packages/btw/package.json +5 -2
- package/packages/btw/skills/btw/SKILL.md +7 -143
- package/packages/compactor/README.md +56 -287
- package/packages/compactor/package.json +5 -9
- package/packages/compactor/skills/compactor/SKILL.md +13 -20
- package/packages/compactor/src/card.ts +90 -0
- package/packages/compactor/src/commands/index.ts +73 -130
- package/packages/compactor/src/compaction/compact-args.ts +5 -3
- package/packages/compactor/src/compaction/filter-noise.ts +1 -1
- package/packages/compactor/src/compaction/hooks.ts +487 -311
- package/packages/compactor/src/compaction/source.ts +178 -0
- package/packages/compactor/src/compaction/summarize.ts +586 -52
- package/packages/compactor/src/config/manager.ts +130 -127
- package/packages/compactor/src/config/schema.ts +32 -48
- package/packages/compactor/src/index.ts +40 -431
- package/packages/compactor/src/info-screen.ts +44 -190
- package/packages/compactor/src/session/recall-blocks.ts +1 -1
- package/packages/compactor/src/stats.ts +76 -0
- package/packages/compactor/src/tools/context-budget.ts +17 -34
- package/packages/compactor/src/tools/ctx-doctor.ts +45 -36
- package/packages/compactor/src/tools/register.ts +29 -269
- package/packages/compactor/src/types.ts +47 -186
- package/packages/core/README.md +25 -0
- package/packages/core/child-agent.ts +1 -0
- package/packages/core/command-echo.ts +63 -0
- package/packages/core/compaction-context.ts +41 -0
- package/packages/core/constants.ts +8 -38
- package/packages/core/events.ts +0 -53
- package/packages/core/fusion-status.ts +4 -0
- package/packages/core/global.d.ts +10 -0
- package/packages/core/harness-messages.ts +392 -0
- package/packages/core/index.ts +14 -0
- package/packages/core/kanboard-status.ts +49 -0
- package/packages/core/long-horizon-owner-status.ts +46 -0
- package/packages/core/model-cache.ts +81 -7
- package/packages/core/package.json +6 -3
- package/packages/core/src/attach/detect.ts +163 -0
- package/packages/core/src/child-agent/child-args.ts +31 -0
- package/packages/core/src/child-agent/delivery.ts +41 -0
- package/packages/core/src/child-agent/index.ts +5 -0
- package/packages/core/src/child-agent/readers.ts +203 -0
- package/packages/core/src/child-agent/runtime.ts +584 -0
- package/packages/core/src/evidence.ts +78 -0
- package/packages/core/src/hints/browser.ts +278 -0
- package/packages/core/src/hints/crab-data.ts +19 -0
- package/packages/core/src/hints/index.ts +865 -0
- package/packages/core/src/hints/lines.ts +607 -0
- package/packages/core/src/hints/store.ts +120 -0
- package/packages/core/src/jev/chatter.ts +24 -0
- package/packages/core/src/jev/settings.ts +177 -14
- package/packages/core/src/package-colors.ts +2 -0
- package/packages/core/src/settings/catalog.ts +39 -15
- package/packages/core/src/settings/engine.ts +48 -2
- package/packages/core/src/settings/hub.ts +83 -20
- package/packages/core/src/settings/open.ts +49 -0
- package/packages/core/src/settings/schema.ts +27 -7
- package/packages/core/src/tui/hub-kit.ts +18 -5
- package/packages/core/src/tui/kit.ts +198 -0
- package/packages/core/src/tui/progress.ts +73 -0
- package/packages/core/src/turn/arbiter.ts +290 -0
- package/packages/footer/README.md +4 -6
- package/packages/footer/package.json +3 -3
- package/packages/footer/src/glance-editor.ts +19 -11
- package/packages/footer/src/help.ts +1 -1
- package/packages/footer/src/index.ts +36 -3
- package/packages/footer/src/presets.ts +3 -4
- package/packages/footer/src/rendering/icons.ts +0 -20
- package/packages/footer/src/segments/compactor.ts +52 -142
- package/packages/footer/src/segments/status-ext.ts +0 -1
- package/packages/fusion/README.md +14 -4
- package/packages/fusion/package.json +4 -3
- package/packages/fusion/src/child-args.ts +1 -0
- package/packages/fusion/src/index.ts +161 -8
- package/packages/fusion/src/pi-settings.ts +57 -0
- package/packages/fusion/src/picker.ts +186 -51
- package/packages/fusion/src/preset.ts +56 -2
- package/packages/fusion/src/prompts.ts +1 -1
- package/packages/fusion/src/sidekick-runtime.ts +1 -420
- package/packages/fusion/src/tools.ts +107 -128
- package/packages/fusion/src/transcript.ts +27 -85
- package/packages/info-screen/package.json +2 -2
- package/packages/input-shortcuts/README.md +18 -30
- package/packages/input-shortcuts/package.json +2 -2
- package/packages/input-shortcuts/src/burst.ts +88 -0
- package/packages/input-shortcuts/src/chord-overlay.ts +20 -70
- package/packages/input-shortcuts/src/cleared-input.ts +97 -0
- package/packages/input-shortcuts/src/index.ts +99 -193
- package/packages/input-shortcuts/src/last-response.ts +40 -0
- package/packages/input-shortcuts/src/registers.ts +8 -23
- package/packages/input-shortcuts/src/types.ts +4 -16
- package/packages/input-shortcuts/src/undo-redo.ts +59 -47
- package/packages/kanboard/README.md +51 -47
- package/packages/kanboard/index.ts +293 -55
- package/packages/kanboard/package.json +8 -8
- package/packages/kanboard/skills/kanboard/SKILL.md +61 -27
- package/packages/kanboard/src/badges.ts +93 -0
- package/packages/kanboard/src/bin.ts +4 -2
- package/packages/kanboard/src/commands.ts +218 -84
- package/packages/kanboard/src/debug.ts +20 -0
- package/packages/kanboard/src/guard.ts +267 -109
- package/packages/kanboard/src/monitor.ts +330 -0
- package/packages/kanboard/src/notice-buffer.ts +74 -0
- package/packages/kanboard/src/progress.ts +27 -0
- package/packages/kanboard/src/reminders.ts +234 -0
- package/packages/kanboard/src/settings.ts +69 -15
- package/packages/kanboard/src/shapes.ts +5 -0
- package/packages/long-horizon/index.ts +190 -13
- package/packages/long-horizon/package.json +3 -3
- package/packages/long-horizon/src/commands.ts +103 -7
- package/packages/long-horizon/src/compaction-brief.ts +35 -0
- package/packages/long-horizon/src/engine/continuation.ts +84 -15
- package/packages/long-horizon/src/engine/goal-state.ts +64 -13
- package/packages/long-horizon/src/engine/nudge-stash.ts +71 -0
- package/packages/long-horizon/src/engine/ralph.ts +3 -2
- package/packages/long-horizon/src/engine/runaway.ts +68 -11
- package/packages/long-horizon/src/engine/verifier.ts +19 -0
- package/packages/long-horizon/src/gate.ts +37 -12
- package/packages/long-horizon/src/judge/resolve.ts +1 -0
- package/packages/long-horizon/src/owner.ts +35 -2
- package/packages/long-horizon/src/progress.ts +87 -0
- package/packages/long-horizon/src/prompts/goal.ts +1 -1
- package/packages/long-horizon/src/runtime.ts +172 -18
- package/packages/long-horizon/src/settings.ts +54 -39
- package/packages/long-horizon/src/tools/goal.ts +6 -0
- package/packages/long-horizon/src/tools/graph.ts +1 -1
- package/packages/long-horizon/src/tools/swarm.ts +3 -3
- package/packages/mcp/package.json +2 -2
- package/packages/memory/commands.ts +7 -2
- package/packages/memory/index.ts +210 -32
- package/packages/memory/package.json +3 -3
- package/packages/memory/save-session.ts +264 -0
- package/packages/memory/settings.ts +17 -0
- package/packages/memory/tools.ts +253 -203
- package/packages/notify/package.json +2 -2
- package/packages/skill-registry/README.md +53 -16
- package/packages/skill-registry/index.ts +230 -0
- package/packages/skill-registry/package.json +19 -8
- package/packages/skill-registry/src/editor.ts +206 -0
- package/packages/skill-registry/src/judge.ts +289 -0
- package/packages/skill-registry/src/registry.ts +87 -0
- package/packages/skill-registry/src/settings.ts +259 -0
- package/packages/skill-registry/src/vault.ts +80 -0
- package/packages/subagents/README.md +39 -119
- package/packages/subagents/package.json +6 -13
- package/packages/subagents/skills/subagents/SKILL.md +18 -42
- package/packages/subagents/src/agents.ts +213 -0
- package/packages/subagents/src/cards.ts +182 -0
- package/packages/subagents/src/index.ts +609 -1084
- package/packages/subagents/src/manager.ts +429 -0
- package/packages/subagents/src/profiles.ts +130 -0
- package/packages/subagents/src/transcript.ts +154 -0
- package/packages/subagents/src/ui.ts +389 -0
- package/packages/unipi/bundled.js +39756 -45569
- package/packages/unipi/index.ts +55 -10
- package/packages/updater/package.json +2 -2
- package/packages/utility/README.md +76 -69
- package/packages/utility/package.json +2 -2
- package/packages/utility/skills/image/SKILL.md +37 -0
- package/packages/utility/skills/utility/SKILL.md +17 -60
- package/packages/utility/src/answer/extract.ts +128 -0
- package/packages/utility/src/answer/index.ts +213 -0
- package/packages/utility/src/answer/reply.ts +133 -0
- package/packages/utility/src/answer/web.ts +167 -0
- package/packages/utility/src/attach/index.ts +205 -0
- package/packages/utility/src/commands.ts +38 -142
- package/packages/utility/src/diagnostics/engine.ts +50 -5
- package/packages/utility/src/image/index.ts +33 -0
- package/packages/utility/src/image/models.ts +221 -0
- package/packages/{image/src → utility/src/image}/recognize.ts +2 -2
- package/packages/utility/src/image/settings.ts +178 -0
- package/packages/{image/src/image-source.ts → utility/src/image/source.ts} +1 -1
- package/packages/utility/src/image/tools.ts +168 -0
- package/packages/utility/src/image/transports.ts +186 -0
- package/packages/utility/src/index.ts +68 -389
- package/packages/utility/src/lifecycle/cleanup.ts +116 -311
- package/packages/utility/src/rename/gate.ts +102 -0
- package/packages/utility/src/rename/index.ts +191 -0
- package/packages/utility/src/rename/session.ts +170 -0
- package/packages/utility/src/render/delegated.ts +285 -0
- package/packages/utility/src/render/harness.ts +683 -0
- package/packages/utility/src/render/parse.ts +156 -0
- package/packages/utility/src/render/pi-settings.ts +38 -0
- package/packages/utility/src/render/reply-bg.ts +307 -0
- package/packages/utility/src/render/simple.ts +724 -0
- package/packages/utility/src/render/spacing.ts +235 -0
- package/packages/utility/src/render/styled.ts +251 -0
- package/packages/utility/src/render/tools.ts +353 -0
- package/packages/utility/src/settings.ts +166 -233
- package/packages/utility/src/types.ts +1 -222
- package/packages/watchdog/index.ts +17 -6
- package/packages/watchdog/package.json +3 -3
- package/packages/watchdog/src/config.ts +3 -2
- package/packages/web-api/package.json +2 -2
- package/packages/workflow/README.md +3 -0
- package/packages/workflow/index.ts +0 -2
- package/packages/workflow/package.json +2 -2
- package/packages/workflow/src/permission/decide.ts +6 -4
- package/packages/workflow/src/permission/index.ts +17 -7
- package/packages/workflow/src/permission/settings.ts +39 -4
- package/packages/workflow/src/plan/index.ts +19 -4
- package/packages/background-tasks/extensions/delegate-child.ts +0 -1
- package/packages/background-tasks/src/context-parent-snapshot.ts +0 -142
- package/packages/background-tasks/src/context-token-budget.ts +0 -903
- package/packages/background-tasks/src/context-visible-conversation-v2.ts +0 -551
- package/packages/background-tasks/src/delegate/artifacts.ts +0 -487
- package/packages/background-tasks/src/delegate/budget.ts +0 -415
- package/packages/background-tasks/src/delegate/hook-contract-evidence.json +0 -18
- package/packages/background-tasks/src/delegate/hook-contract.ts +0 -154
- package/packages/background-tasks/src/delegate/launch.ts +0 -484
- package/packages/background-tasks/src/delegate/result-package.ts +0 -459
- package/packages/background-tasks/src/delegate/runner.ts +0 -430
- package/packages/background-tasks/src/delegate/seed.ts +0 -423
- package/packages/background-tasks/src/delegate/types.ts +0 -323
- package/packages/background-tasks/src/delegate-child-extension.ts +0 -978
- package/packages/background-tasks/src/delegate-extension.ts +0 -654
- package/packages/background-tasks/src/fixtures/delegate-context-incident.json +0 -17
- package/packages/compactor/skills/compactor-detail/SKILL.md +0 -116
- package/packages/compactor/skills/compactor-doctor/SKILL.md +0 -71
- package/packages/compactor/skills/compactor-stats/SKILL.md +0 -51
- package/packages/compactor/src/compaction/build-sections.ts +0 -76
- package/packages/compactor/src/compaction/extract/goals.ts +0 -36
- package/packages/compactor/src/compaction/extract/preferences.ts +0 -40
- package/packages/compactor/src/compaction/format.ts +0 -53
- package/packages/compactor/src/compaction/merge.ts +0 -143
- package/packages/compactor/src/config/presets.ts +0 -160
- package/packages/compactor/src/executor/executor.ts +0 -233
- package/packages/compactor/src/executor/runtime.ts +0 -115
- package/packages/compactor/src/security/evaluator.ts +0 -89
- package/packages/compactor/src/security/policy.ts +0 -96
- package/packages/compactor/src/security/scanner.ts +0 -65
- package/packages/compactor/src/session/auto-inject.ts +0 -60
- package/packages/compactor/src/session/db.ts +0 -325
- package/packages/compactor/src/session/extract.ts +0 -144
- package/packages/compactor/src/session/resume-inject.ts +0 -64
- package/packages/compactor/src/session/snapshot.ts +0 -327
- package/packages/compactor/src/tools/ctx-batch-execute.ts +0 -41
- package/packages/compactor/src/tools/ctx-execute-file.ts +0 -23
- package/packages/compactor/src/tools/ctx-execute.ts +0 -23
- package/packages/compactor/src/tools/ctx-stats.ts +0 -96
- package/packages/image/README.md +0 -99
- package/packages/image/package.json +0 -61
- package/packages/image/skills/image/SKILL.md +0 -76
- package/packages/image/src/generate.ts +0 -256
- package/packages/image/src/index.ts +0 -135
- package/packages/image/src/models.ts +0 -519
- package/packages/image/src/openai-images-api.ts +0 -282
- package/packages/image/src/register-providers.ts +0 -209
- package/packages/image/src/settings.ts +0 -173
- package/packages/image/src/tools.ts +0 -326
- package/packages/input-shortcuts/src/clipboard.ts +0 -119
- package/packages/kanboard/src/runner.ts +0 -817
- package/packages/skill-registry/skills/auto/SKILL.md +0 -465
- package/packages/skill-registry/skills/brainstorm/SKILL.md +0 -219
- package/packages/skill-registry/skills/chore-create/SKILL.md +0 -315
- package/packages/skill-registry/skills/chore-execute/SKILL.md +0 -314
- package/packages/skill-registry/skills/consolidate/SKILL.md +0 -142
- package/packages/skill-registry/skills/consultant/SKILL.md +0 -97
- package/packages/skill-registry/skills/debug/SKILL.md +0 -228
- package/packages/skill-registry/skills/document/SKILL.md +0 -120
- package/packages/skill-registry/skills/fix/SKILL.md +0 -212
- package/packages/skill-registry/skills/gather-context/SKILL.md +0 -145
- package/packages/skill-registry/skills/plan/SKILL.md +0 -231
- package/packages/skill-registry/skills/quick-fix/SKILL.md +0 -135
- package/packages/skill-registry/skills/quick-work/SKILL.md +0 -110
- package/packages/skill-registry/skills/research/SKILL.md +0 -251
- package/packages/skill-registry/skills/review-work/SKILL.md +0 -187
- package/packages/skill-registry/skills/scan-issues/SKILL.md +0 -195
- package/packages/skill-registry/skills/work/SKILL.md +0 -218
- package/packages/skill-registry/skills/worktree-create/SKILL.md +0 -69
- package/packages/skill-registry/skills/worktree-list/SKILL.md +0 -78
- package/packages/skill-registry/skills/worktree-merge/SKILL.md +0 -89
- package/packages/subagents/agents/delegate.md +0 -14
- package/packages/subagents/agents/oracle.md +0 -78
- package/packages/subagents/agents/researcher.md +0 -52
- package/packages/subagents/agents/reviewer.md +0 -80
- package/packages/subagents/agents/scout.md +0 -50
- package/packages/subagents/agents/worker.md +0 -59
- package/packages/subagents/prompts/council.md +0 -48
- package/packages/subagents/prompts/gather-context-and-clarify.md +0 -13
- package/packages/subagents/prompts/parallel-cleanup.md +0 -59
- package/packages/subagents/prompts/parallel-research.md +0 -50
- package/packages/subagents/prompts/parallel-review.md +0 -54
- package/packages/subagents/prompts/review-loop.md +0 -43
- package/packages/subagents/skills/council-mode/SKILL.md +0 -230
- package/packages/subagents/skills/subagents/references/constraints-and-recipes.md +0 -259
- package/packages/subagents/skills/subagents/references/execution-controls.md +0 -454
- package/packages/subagents/skills/subagents/references/management-authoring-rpc.md +0 -161
- package/packages/subagents/skills/subagents/references/multi-lane-orchestration.md +0 -39
- package/packages/subagents/skills/subagents/references/prompting-and-roles.md +0 -267
- package/packages/subagents/src/acceptance.ts +0 -331
- package/packages/subagents/src/agent-manager.ts +0 -405
- package/packages/subagents/src/agent-memory.ts +0 -300
- package/packages/subagents/src/agent-overrides.ts +0 -183
- package/packages/subagents/src/agent-runner.ts +0 -271
- package/packages/subagents/src/async-runner.ts +0 -422
- package/packages/subagents/src/authority-policy.ts +0 -47
- package/packages/subagents/src/budgets.ts +0 -285
- package/packages/subagents/src/child-safety.ts +0 -140
- package/packages/subagents/src/config.ts +0 -249
- package/packages/subagents/src/conversation-viewer.ts +0 -281
- package/packages/subagents/src/core-compat.ts +0 -94
- package/packages/subagents/src/custom-agents.ts +0 -343
- package/packages/subagents/src/file-system-retry.ts +0 -50
- package/packages/subagents/src/fleet-data.ts +0 -105
- package/packages/subagents/src/fleet-view.ts +0 -322
- package/packages/subagents/src/foreground-detach.ts +0 -59
- package/packages/subagents/src/fork-context.ts +0 -285
- package/packages/subagents/src/global.d.ts +0 -7
- package/packages/subagents/src/guide.ts +0 -129
- package/packages/subagents/src/mission-state.ts +0 -133
- package/packages/subagents/src/mission-store.ts +0 -436
- package/packages/subagents/src/output-limits.ts +0 -142
- package/packages/subagents/src/parity-types.ts +0 -315
- package/packages/subagents/src/pi-args.ts +0 -167
- package/packages/subagents/src/result-files.ts +0 -232
- package/packages/subagents/src/result-watcher.ts +0 -221
- package/packages/subagents/src/retained-children.ts +0 -176
- package/packages/subagents/src/run-fanout-budget.ts +0 -356
- package/packages/subagents/src/scheduled-runs.ts +0 -349
- package/packages/subagents/src/schemas.ts +0 -263
- package/packages/subagents/src/slash-commands.ts +0 -80
- package/packages/subagents/src/supervisor-channel.ts +0 -249
- package/packages/subagents/src/tool-handler.ts +0 -1144
- package/packages/subagents/src/types.ts +0 -238
- package/packages/subagents/src/widget.ts +0 -457
- package/packages/subagents/src/workflow-script.ts +0 -737
- package/packages/subagents/src/workflow-worker.ts +0 -384
- package/packages/subagents/src/worktree.ts +0 -614
- package/packages/utility/src/analytics/collector.ts +0 -293
- package/packages/utility/src/info-screen.ts +0 -80
- package/packages/utility/src/lifecycle/process.ts +0 -162
- package/packages/utility/src/prefix-cache.ts +0 -263
- package/packages/utility/src/skill-discovery.ts +0 -542
- package/packages/utility/src/tools/env.ts +0 -113
- package/packages/utility/src/tui/name-badge-state.ts +0 -315
- package/packages/utility/src/tui/name-badge.ts +0 -109
- /package/packages/{subagents/src → core/src/child-agent}/pi-spawn.ts +0 -0
|
@@ -19,6 +19,7 @@ export const PACKAGE_ORDER: string[] = [
|
|
|
19
19
|
"btw",
|
|
20
20
|
"mcp",
|
|
21
21
|
"utility",
|
|
22
|
+
"skill-registry",
|
|
22
23
|
"ask-user",
|
|
23
24
|
"info",
|
|
24
25
|
"web-api",
|
|
@@ -35,19 +36,18 @@ export const PACKAGE_ORDER: string[] = [
|
|
|
35
36
|
];
|
|
36
37
|
|
|
37
38
|
// ─── Command Registry ────────────────────────────────────────────────
|
|
38
|
-
/** Mapping of full command name → package name (
|
|
39
|
+
/** Mapping of full command name → package name (46 verified commands) */
|
|
39
40
|
export const COMMAND_REGISTRY: Record<string, string> = {
|
|
40
41
|
// workflow (2 commands)
|
|
41
42
|
"unipi:plan": "workflow",
|
|
42
43
|
"unipi:permission": "workflow",
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// long-horizon (4 commands)
|
|
45
|
+
// long-horizon (5 commands)
|
|
47
46
|
"unipi:goal": "long-horizon",
|
|
48
47
|
"unipi:ralph": "long-horizon",
|
|
49
48
|
"unipi:swarm": "long-horizon",
|
|
50
49
|
"unipi:graph": "long-horizon",
|
|
50
|
+
"unipi:regular": "long-horizon",
|
|
51
51
|
|
|
52
52
|
// memory (7 commands)
|
|
53
53
|
"unipi:memory": "memory",
|
|
@@ -58,34 +58,32 @@ export const COMMAND_REGISTRY: Record<string, string> = {
|
|
|
58
58
|
"unipi:memory-forget": "memory",
|
|
59
59
|
"unipi:global-memory-list": "memory",
|
|
60
60
|
|
|
61
|
-
// btw
|
|
61
|
+
// btw
|
|
62
62
|
"unipi:btw": "btw",
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"unipi:
|
|
66
|
-
"unipi:
|
|
67
|
-
"unipi:btw-summarize": "btw",
|
|
63
|
+
|
|
64
|
+
// subagents
|
|
65
|
+
"unipi:subagents": "subagents",
|
|
66
|
+
"unipi:agents": "subagents",
|
|
68
67
|
|
|
69
68
|
// mcp (5 commands)
|
|
70
69
|
"unipi:mcp-status": "mcp",
|
|
71
70
|
|
|
72
|
-
// utility
|
|
71
|
+
// utility
|
|
73
72
|
"unipi:continue": "utility",
|
|
74
|
-
"unipi:
|
|
75
|
-
"unipi:status": "utility",
|
|
73
|
+
"unipi:retry": "utility",
|
|
76
74
|
"unipi:cleanup": "utility",
|
|
77
|
-
"unipi:env": "utility",
|
|
78
75
|
"unipi:doctor": "utility",
|
|
76
|
+
"unipi:answer": "utility",
|
|
77
|
+
|
|
78
|
+
// skill-registry
|
|
79
|
+
"unipi:skills": "skill-registry",
|
|
79
80
|
|
|
80
81
|
// ask-user (1 command)
|
|
81
82
|
|
|
82
83
|
// utility (settings hub)
|
|
83
84
|
"unipi:settings": "utility",
|
|
84
85
|
|
|
85
|
-
// subagents (
|
|
86
|
-
"unipi:subagents-fleet": "subagents",
|
|
87
|
-
"unipi:subagents-doctor": "subagents",
|
|
88
|
-
"unipi:subagents-guide": "subagents",
|
|
86
|
+
// subagents (no user commands — Devin model)
|
|
89
87
|
|
|
90
88
|
// background-tasks (8 commands)
|
|
91
89
|
"unipi:bg": "background-tasks",
|
|
@@ -97,14 +95,14 @@ export const COMMAND_REGISTRY: Record<string, string> = {
|
|
|
97
95
|
|
|
98
96
|
// info (2 commands)
|
|
99
97
|
"unipi:info": "info",
|
|
98
|
+
"unipi:hint": "info",
|
|
100
99
|
|
|
101
100
|
// web-api (2 commands)
|
|
102
101
|
|
|
103
|
-
// compact (
|
|
104
|
-
"unipi:
|
|
105
|
-
"unipi:compact":
|
|
102
|
+
// compact (6 commands)
|
|
103
|
+
"unipi:compact-vcc": "compact",
|
|
104
|
+
"unipi:compact-by-llm": "compact",
|
|
106
105
|
"unipi:session-recall": "compact",
|
|
107
|
-
"unipi:compact-recall": "compact",
|
|
108
106
|
"unipi:compact-stats": "compact",
|
|
109
107
|
"unipi:compact-doctor": "compact",
|
|
110
108
|
"unipi:compact-help": "compact",
|
|
@@ -135,12 +133,12 @@ export const COMMAND_REGISTRY: Record<string, string> = {
|
|
|
135
133
|
export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
136
134
|
"unipi:plan": "Plan mode — investigate read-only, then approve a plan",
|
|
137
135
|
"unipi:permission": "Permission mode — ask · auto (jev-judged) · full",
|
|
138
|
-
"unipi:prefix-cache": "Show privacy-safe provider prefix-cache diagnostics",
|
|
139
136
|
|
|
140
137
|
"unipi:goal": "One objective until verifiably true · medium complexity · pareto cost/success",
|
|
141
138
|
"unipi:ralph": "Checklist grind over iterations · enumerable chores · low cost, solid success",
|
|
142
139
|
"unipi:swarm": "Parallel fan-out + synthesis · complex decomposable · higher cost, high coverage",
|
|
143
140
|
"unipi:graph": "Dependent multi-step work · later steps need earlier results · highest cost",
|
|
141
|
+
"unipi:regular": "Regular mode — stop the active owner and run prompts without long-horizon routing",
|
|
144
142
|
|
|
145
143
|
"unipi:memory": "Memory palace — status, migrate, recall/write toggles",
|
|
146
144
|
"unipi:memory-process": "Analyze text and store extracted memories",
|
|
@@ -150,21 +148,20 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
150
148
|
"unipi:memory-forget": "Delete a memory by title",
|
|
151
149
|
"unipi:global-memory-list": "List all memories across all projects",
|
|
152
150
|
|
|
153
|
-
"unipi:btw": "
|
|
154
|
-
|
|
155
|
-
"unipi:
|
|
156
|
-
"unipi:
|
|
157
|
-
"unipi:btw-inject": "Inject the BTW thread into the main agent",
|
|
158
|
-
"unipi:btw-summarize": "Summarize and inject the BTW thread",
|
|
151
|
+
"unipi:btw": "Ask a side question in an inline panel (read-only)",
|
|
152
|
+
|
|
153
|
+
"unipi:subagents": "Open the subagent panel (also ↓ from an empty input)",
|
|
154
|
+
"unipi:agents": "Manage subagent profiles — create, edit, copy, delete custom agents",
|
|
159
155
|
|
|
160
156
|
"unipi:mcp-status": "Show MCP server status",
|
|
161
157
|
|
|
162
|
-
"unipi:continue": "Continue the
|
|
163
|
-
"unipi:
|
|
164
|
-
"unipi:
|
|
165
|
-
"unipi:
|
|
166
|
-
"unipi:
|
|
167
|
-
"unipi:
|
|
158
|
+
"unipi:continue": "Continue from where the agent stopped (/unipi:retry)",
|
|
159
|
+
"unipi:retry": "Retry the last turn (alias of /unipi:continue)",
|
|
160
|
+
"unipi:cleanup": "Remove stale UniPi temp files and leftovers (preview first)",
|
|
161
|
+
"unipi:doctor": "Check UniPi's runtime: config, model cache, Decision Model, skills",
|
|
162
|
+
"unipi:answer": "Answer the last reply — fixed input under the scrollable reply, per question, or web form",
|
|
163
|
+
"unipi:skills": "Manage skills — on/off per project, listed or not, the skill vault",
|
|
164
|
+
|
|
168
165
|
"unipi:kanboard": "Kanboard — capture tasks, run them, open the board",
|
|
169
166
|
"unipi:kanboard-add": "Kanboard — capture a task into Backlog",
|
|
170
167
|
"unipi:kanboard-do": "Kanboard — let the agent work the board for a turn",
|
|
@@ -173,14 +170,14 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
173
170
|
"unipi:settings": "Configure all unipi modules in one panel",
|
|
174
171
|
|
|
175
172
|
"unipi:info": "Show system information",
|
|
173
|
+
"unipi:hint": "Browse and search Unicrab hints, or cycle/reset",
|
|
176
174
|
|
|
177
175
|
|
|
178
|
-
"unipi:
|
|
179
|
-
"unipi:compact":
|
|
176
|
+
"unipi:compact-vcc": "Lossless compaction now — no model call (keep:N)",
|
|
177
|
+
"unipi:compact-by-llm": "Compact now with a model-written summary",
|
|
180
178
|
"unipi:session-recall": "Search session history, including compacted-away messages",
|
|
181
|
-
"unipi:compact-
|
|
182
|
-
"unipi:compact-
|
|
183
|
-
"unipi:compact-doctor": "Diagnose compaction issues",
|
|
179
|
+
"unipi:compact-stats": "Show this session's compaction savings",
|
|
180
|
+
"unipi:compact-doctor": "Check compaction settings",
|
|
184
181
|
"unipi:compact-help": "Show compactor command help",
|
|
185
182
|
"unipi:notify-event": "Toggle a notify event without the TUI: <event> <on|off>",
|
|
186
183
|
|
|
@@ -195,9 +192,6 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
|
|
|
195
192
|
"unipi:bg-tasks": "Open the background task manager UI",
|
|
196
193
|
"unipi:model": "Pick a model or Fusion lead+sidekick pair (Devin-style picker)",
|
|
197
194
|
"unipi:fusion-stats": "Estimated Fusion savings (sidekick tokens priced at lead rates)",
|
|
198
|
-
"unipi:subagents-fleet": "Open the subagents fleet view",
|
|
199
|
-
"unipi:subagents-doctor": "Diagnose subagents configuration",
|
|
200
|
-
"unipi:subagents-guide": "Show the subagents usage guide",
|
|
201
195
|
};
|
|
202
196
|
|
|
203
197
|
// ─── Package Display Names ───────────────────────────────────────────
|
|
@@ -210,6 +204,7 @@ export const PACKAGE_LABELS: Record<string, string> = {
|
|
|
210
204
|
btw: "btw",
|
|
211
205
|
mcp: "mcp",
|
|
212
206
|
utility: "utility",
|
|
207
|
+
"skill-registry": "skills",
|
|
213
208
|
"ask-user": "ask-user",
|
|
214
209
|
info: "info",
|
|
215
210
|
"web-api": "web-api",
|
|
@@ -16,6 +16,12 @@ export interface TaggedItem {
|
|
|
16
16
|
|
|
17
17
|
// ─── 4-tier priority ─────────────────────────────────────────────────
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* UniPi commands that supersede a same-named pi built-in: typing the bare
|
|
21
|
+
* name ranks the unipi command FIRST (`/settings` → `/unipi:settings`).
|
|
22
|
+
*/
|
|
23
|
+
export const PREFERRED_OVER_BUILTIN = new Set(["settings"]);
|
|
24
|
+
|
|
19
25
|
/**
|
|
20
26
|
* Compute the match-quality tier for an autocomplete item.
|
|
21
27
|
*
|
|
@@ -38,6 +44,8 @@ export function crossItemPriority(
|
|
|
38
44
|
|
|
39
45
|
const q = query.toLowerCase();
|
|
40
46
|
|
|
47
|
+
// Tier -1: a unipi command that supersedes the same-named built-in
|
|
48
|
+
if (isUnipi && short === q && PREFERRED_OVER_BUILTIN.has(q)) return -1;
|
|
41
49
|
// Tier 0: exact full-value match
|
|
42
50
|
if (full === q) return 0;
|
|
43
51
|
// Tier 1: unipi short-name exact match
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-unipi/background-tasks",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.21",
|
|
4
4
|
"description": "Background tasks for UniPi — durable shell jobs and delegated background agents with a footer dock",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@earendil-works/pi-ai": "^0.87.1",
|
|
13
|
-
"@pi-unipi/core": "3.0.0-alpha.
|
|
13
|
+
"@pi-unipi/core": "3.0.0-alpha.21",
|
|
14
14
|
"turndown": "^7.2.4"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
@@ -27,14 +27,6 @@ export interface BackgroundTasksConfig {
|
|
|
27
27
|
maxFinishedTasks: number;
|
|
28
28
|
/** Output cap in bytes before a task is killed+failed (default 20 MiB). */
|
|
29
29
|
maxOutputBytes: number;
|
|
30
|
-
/** Delegate defaults. */
|
|
31
|
-
delegate: {
|
|
32
|
-
extensionMode: "isolated" | "ambient";
|
|
33
|
-
autoDeliver: "never" | "when_small" | "always";
|
|
34
|
-
maxTurns: number;
|
|
35
|
-
maxToolCalls: number;
|
|
36
|
-
timeoutSeconds: number;
|
|
37
|
-
};
|
|
38
30
|
}
|
|
39
31
|
|
|
40
32
|
export const DEFAULT_CONFIG: BackgroundTasksConfig = {
|
|
@@ -44,13 +36,6 @@ export const DEFAULT_CONFIG: BackgroundTasksConfig = {
|
|
|
44
36
|
defaultTimeoutSeconds: 0,
|
|
45
37
|
maxFinishedTasks: 30,
|
|
46
38
|
maxOutputBytes: 20 * 1024 * 1024,
|
|
47
|
-
delegate: {
|
|
48
|
-
extensionMode: "isolated",
|
|
49
|
-
autoDeliver: "when_small",
|
|
50
|
-
maxTurns: 40,
|
|
51
|
-
maxToolCalls: 120,
|
|
52
|
-
timeoutSeconds: 900,
|
|
53
|
-
},
|
|
54
39
|
};
|
|
55
40
|
|
|
56
41
|
function getGlobalConfigPath(): string {
|
|
@@ -144,32 +129,6 @@ export function validateBackgroundTasksConfig(config: unknown): string[] {
|
|
|
144
129
|
problems.push("maxOutputBytes must be an integer >= 1024");
|
|
145
130
|
}
|
|
146
131
|
}
|
|
147
|
-
if (c.delegate !== undefined) {
|
|
148
|
-
if (typeof c.delegate !== "object" || c.delegate === null) {
|
|
149
|
-
problems.push("delegate must be an object");
|
|
150
|
-
} else {
|
|
151
|
-
const d = c.delegate as Record<string, unknown>;
|
|
152
|
-
if (d.extensionMode !== undefined && d.extensionMode !== "isolated" && d.extensionMode !== "ambient") {
|
|
153
|
-
problems.push('delegate.extensionMode must be "isolated" or "ambient"');
|
|
154
|
-
}
|
|
155
|
-
if (
|
|
156
|
-
d.autoDeliver !== undefined &&
|
|
157
|
-
d.autoDeliver !== "never" &&
|
|
158
|
-
d.autoDeliver !== "when_small" &&
|
|
159
|
-
d.autoDeliver !== "always"
|
|
160
|
-
) {
|
|
161
|
-
problems.push('delegate.autoDeliver must be "never", "when_small", or "always"');
|
|
162
|
-
}
|
|
163
|
-
for (const key of ["maxTurns", "maxToolCalls"] as const) {
|
|
164
|
-
if (d[key] !== undefined && (typeof d[key] !== "number" || !Number.isInteger(d[key]) || (d[key] as number) < 1)) {
|
|
165
|
-
problems.push(`delegate.${key} must be a positive integer`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (d.timeoutSeconds !== undefined && (typeof d.timeoutSeconds !== "number" || !Number.isFinite(d.timeoutSeconds) || (d.timeoutSeconds as number) <= 0)) {
|
|
169
|
-
problems.push("delegate.timeoutSeconds must be a positive number");
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
132
|
return problems;
|
|
174
133
|
}
|
|
175
134
|
|
|
@@ -203,29 +162,6 @@ registerSettings({
|
|
|
203
162
|
{ key: "maxOutputBytes", type: "number", label: "Output cap bytes", min: 1024, description: "Kill+fail a task past this output size" },
|
|
204
163
|
],
|
|
205
164
|
},
|
|
206
|
-
{
|
|
207
|
-
title: "Delegate",
|
|
208
|
-
fields: [
|
|
209
|
-
{
|
|
210
|
-
key: "delegate.extensionMode",
|
|
211
|
-
type: "enum",
|
|
212
|
-
label: "Extension mode",
|
|
213
|
-
options: [
|
|
214
|
-
{ value: "isolated", label: "isolated" },
|
|
215
|
-
{ value: "ambient", label: "ambient (weakens isolation)" },
|
|
216
|
-
],
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
key: "delegate.autoDeliver",
|
|
220
|
-
type: "enum",
|
|
221
|
-
label: "Auto deliver",
|
|
222
|
-
options: ["when_small", "always", "never"],
|
|
223
|
-
},
|
|
224
|
-
{ key: "delegate.maxTurns", type: "number", label: "Max turns", min: 1 },
|
|
225
|
-
{ key: "delegate.maxToolCalls", type: "number", label: "Max tool calls", min: 1 },
|
|
226
|
-
{ key: "delegate.timeoutSeconds", type: "number", label: "Timeout s", min: 1 },
|
|
227
|
-
],
|
|
228
|
-
},
|
|
229
165
|
],
|
|
230
166
|
});
|
|
231
167
|
|
|
@@ -278,15 +214,6 @@ export function loadBackgroundTasksConfig(cwd: string): LoadedBackgroundTasksCon
|
|
|
278
214
|
typeof merged.maxOutputBytes === "number" && Number.isInteger(merged.maxOutputBytes) && merged.maxOutputBytes >= 1024
|
|
279
215
|
? merged.maxOutputBytes
|
|
280
216
|
: DEFAULT_CONFIG.maxOutputBytes,
|
|
281
|
-
delegate: {
|
|
282
|
-
...DEFAULT_CONFIG.delegate,
|
|
283
|
-
...merged.delegate,
|
|
284
|
-
extensionMode: merged.delegate?.extensionMode === "ambient" ? "ambient" : "isolated",
|
|
285
|
-
autoDeliver:
|
|
286
|
-
merged.delegate?.autoDeliver === "never" || merged.delegate?.autoDeliver === "always"
|
|
287
|
-
? merged.delegate.autoDeliver
|
|
288
|
-
: "when_small",
|
|
289
|
-
},
|
|
290
217
|
};
|
|
291
218
|
return { config, warnings };
|
|
292
219
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import { createSpinnerLine, setHerdrWorking } from "@pi-unipi/core";
|
|
13
|
+
import { createSpinnerLine, isChildProcess, registerWaitSource, setHerdrWorking } from "@pi-unipi/core";
|
|
14
14
|
import { loadBackgroundTasksConfig } from "./config.js";
|
|
15
15
|
import { BackgroundTaskRegistry } from "./registry.js";
|
|
16
16
|
import {
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
type BackgroundTaskExtensionService,
|
|
19
19
|
} from "./extension-api.js";
|
|
20
20
|
import { registerToolsAndCommands } from "./tools.js";
|
|
21
|
-
import { registerDelegateExtension } from "./delegate-extension.js";
|
|
22
21
|
import { setSharedTaskRegistry, clearSharedTaskRegistry } from "./registry-shared.js";
|
|
23
22
|
import { formatDuration, taskDisplayName, type BgTask, type StartTaskOptions } from "./types.js";
|
|
24
23
|
|
|
@@ -44,6 +43,15 @@ function pendingWakeText(registry: BackgroundTaskRegistry, isIdle: () => boolean
|
|
|
44
43
|
return `waiting on ${count}${detail} — agent resumes automatically when done`;
|
|
45
44
|
}
|
|
46
45
|
|
|
46
|
+
/** Arbiter wait-source reason (lead only): what a running wake-task is, or null. */
|
|
47
|
+
export function pendingWakeReason(tasks: readonly { status: string; triggerOnCompletion: boolean; command?: string; name?: string; description?: string; id?: string }[]): string | null {
|
|
48
|
+
const pendingWake = tasks.filter((task) => task.status === "running" && task.triggerOnCompletion);
|
|
49
|
+
if (pendingWake.length === 0) return null;
|
|
50
|
+
const first = pendingWake[0];
|
|
51
|
+
const more = pendingWake.length > 1 ? ` +${String(pendingWake.length - 1)} more` : "";
|
|
52
|
+
return `bg: ${first === undefined ? "task" : taskDisplayName(first)}${more}`;
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
export default function backgroundTasksExtension(pi: ExtensionAPI): void {
|
|
48
56
|
const { config, warnings } = loadBackgroundTasksConfig(process.cwd());
|
|
49
57
|
|
|
@@ -77,6 +85,16 @@ export default function backgroundTasksExtension(pi: ExtensionAPI): void {
|
|
|
77
85
|
});
|
|
78
86
|
setSharedTaskRegistry(registry);
|
|
79
87
|
|
|
88
|
+
// Turn-arbiter wait source (lead only): while a task that will wake the
|
|
89
|
+
// agent is still running, a nudge would race the wake — defer to it.
|
|
90
|
+
if (!isChildProcess()) {
|
|
91
|
+
try {
|
|
92
|
+
registerWaitSource("background-tasks", () => pendingWakeReason(registry.allTasks()));
|
|
93
|
+
} catch {
|
|
94
|
+
// Registration must never block module load.
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
80
98
|
const eventService: BackgroundTaskExtensionService = installBackgroundTaskExtensionApi({
|
|
81
99
|
events: pi.events,
|
|
82
100
|
registry,
|
|
@@ -205,11 +223,6 @@ export default function backgroundTasksExtension(pi: ExtensionAPI): void {
|
|
|
205
223
|
return result;
|
|
206
224
|
},
|
|
207
225
|
rerunTask: async (task) => {
|
|
208
|
-
if (task.delegate !== undefined) {
|
|
209
|
-
throw new Error(
|
|
210
|
-
"Only shell-command tasks can be rerun from the dock; relaunch this typed workflow through its owning tool.",
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
226
|
const rerunOptions: StartTaskOptions = {
|
|
214
227
|
name: taskDisplayName(task),
|
|
215
228
|
isAgent: task.isAgent,
|
|
@@ -261,15 +274,6 @@ export default function backgroundTasksExtension(pi: ExtensionAPI): void {
|
|
|
261
274
|
clearFinishedNotices,
|
|
262
275
|
});
|
|
263
276
|
|
|
264
|
-
registerDelegateExtension(pi, {
|
|
265
|
-
startDelegateTask: async (ctx, options) => {
|
|
266
|
-
currentCtx = ctx;
|
|
267
|
-
return registry.startDelegateTask(ctx, options);
|
|
268
|
-
},
|
|
269
|
-
snapshot: (task) => registry.snapshot(task),
|
|
270
|
-
resolveTask: (idOrPrefix) => registry.resolveTask(idOrPrefix),
|
|
271
|
-
});
|
|
272
|
-
|
|
273
277
|
pi.on("session_start", async (_event, ctx) => {
|
|
274
278
|
registry.setShuttingDown(false);
|
|
275
279
|
wakeLineInstalled = false; // pi clears extension widgets on reload/new session
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
type BgTaskSnapshot,
|
|
28
28
|
type JsonObject,
|
|
29
29
|
type KillKind,
|
|
30
|
-
type StartDelegateTaskOptions,
|
|
31
30
|
type StartTaskOptions,
|
|
32
31
|
type TaskContextUsage,
|
|
33
32
|
type TaskStatus,
|
|
@@ -637,31 +636,6 @@ function noopOnChange(): void {
|
|
|
637
636
|
return undefined;
|
|
638
637
|
}
|
|
639
638
|
|
|
640
|
-
/**
|
|
641
|
-
* Deliver the delegate prompt bytes over stdin.
|
|
642
|
-
*
|
|
643
|
-
* A failure to deliver the seed is loud: the caller terminates the task rather
|
|
644
|
-
* than letting a child run without the context it was supposed to receive.
|
|
645
|
-
*/
|
|
646
|
-
function writeDelegateStdin(
|
|
647
|
-
child: BackgroundTaskChildProcess,
|
|
648
|
-
bytes: Buffer,
|
|
649
|
-
onError: (error: Error) => void,
|
|
650
|
-
): void {
|
|
651
|
-
const stdin = child.stdin;
|
|
652
|
-
if (stdin === undefined || stdin === null) {
|
|
653
|
-
onError(new Error('delegate child stdin pipe is unavailable'));
|
|
654
|
-
return;
|
|
655
|
-
}
|
|
656
|
-
stdin.once('error', onError);
|
|
657
|
-
stdin.write(bytes, (error?: Error | null) => {
|
|
658
|
-
if (error !== undefined && error !== null) {
|
|
659
|
-
onError(error);
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
|
-
stdin.end();
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
639
|
|
|
666
640
|
export class BackgroundTaskRegistry {
|
|
667
641
|
private readonly tasks = new Map<string, BgTask>();
|
|
@@ -921,145 +895,6 @@ export class BackgroundTaskRegistry {
|
|
|
921
895
|
}
|
|
922
896
|
}
|
|
923
897
|
|
|
924
|
-
/**
|
|
925
|
-
* Start a prepared delegate child.
|
|
926
|
-
*
|
|
927
|
-
* The caller has already completed preflight, so by the time this runs the
|
|
928
|
-
* seed, budget plan, and artifact directory exist and the argv is fixed. The
|
|
929
|
-
* child is launched directly, never through a shell, and its terminal state
|
|
930
|
-
* flows through the same durable notification path as `bg_run`.
|
|
931
|
-
*/
|
|
932
|
-
async startDelegateTask(
|
|
933
|
-
ctx: BackgroundTaskContext,
|
|
934
|
-
request: StartDelegateTaskOptions,
|
|
935
|
-
): Promise<BgTask> {
|
|
936
|
-
if (this.shuttingDown)
|
|
937
|
-
throw new Error('Cannot start a delegate task while Pi is shutting down');
|
|
938
|
-
|
|
939
|
-
const launch = resolvePiLaunch({ platform: this.platform });
|
|
940
|
-
assertWindowsCommandLineWithinLimit(launch, request.argv, this.platform, 'bg-delegate');
|
|
941
|
-
|
|
942
|
-
const dir = await this.ensureRuntimeDir(ctx);
|
|
943
|
-
const id = request.facts.taskId;
|
|
944
|
-
const outputAbsPath = join(dir.abs, `${id}.output`);
|
|
945
|
-
const metadataAbsPath = join(dir.abs, `${id}.json`);
|
|
946
|
-
const outputPath = join(dir.display, `${id}.output`);
|
|
947
|
-
|
|
948
|
-
const task: BgTask = {
|
|
949
|
-
id,
|
|
950
|
-
name: normalizeTaskName(request.name) ?? 'Delegate task',
|
|
951
|
-
command: ['pi', ...request.argv].map(shellQuote).join(' '),
|
|
952
|
-
status: 'running',
|
|
953
|
-
outputPath,
|
|
954
|
-
outputAbsPath,
|
|
955
|
-
metadataAbsPath,
|
|
956
|
-
cwd: ctx.cwd,
|
|
957
|
-
startTime: this.now(),
|
|
958
|
-
exitCode: undefined,
|
|
959
|
-
pid: undefined,
|
|
960
|
-
bytesWritten: 0,
|
|
961
|
-
isAgent: true,
|
|
962
|
-
notified: false,
|
|
963
|
-
notifyOnCompletion: request.notifyOnCompletion,
|
|
964
|
-
triggerOnCompletion: request.triggerOnCompletion,
|
|
965
|
-
timeoutSeconds: request.timeoutSeconds,
|
|
966
|
-
model: request.facts.route.qualifiedId,
|
|
967
|
-
delegate: request.facts,
|
|
968
|
-
waiters: [],
|
|
969
|
-
};
|
|
970
|
-
this.tasks.set(id, task);
|
|
971
|
-
|
|
972
|
-
const stream = createWriteStream(outputAbsPath, { flags: 'a', encoding: 'utf8' });
|
|
973
|
-
task.stream = stream;
|
|
974
|
-
stream.on('error', (error) => {
|
|
975
|
-
task.error = `Output file write failed: ${error.message}`;
|
|
976
|
-
});
|
|
977
|
-
|
|
978
|
-
try {
|
|
979
|
-
const child = this.spawn(launch.executable, piLaunchArgv(launch, [...request.argv]), {
|
|
980
|
-
cwd: ctx.cwd,
|
|
981
|
-
detached: this.platform !== 'win32',
|
|
982
|
-
shell: false,
|
|
983
|
-
// The seed travels over stdin, never as a shell or positional argument,
|
|
984
|
-
// so the bytes the child reads are exactly the bytes that were persisted
|
|
985
|
-
// and hashed, with no quoting or command-line length limit in the path.
|
|
986
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
987
|
-
env: request.env,
|
|
988
|
-
windowsHide: true,
|
|
989
|
-
});
|
|
990
|
-
task.child = child;
|
|
991
|
-
task.pid = child.pid;
|
|
992
|
-
writeDelegateStdin(child, request.stdinBytes, (error) => {
|
|
993
|
-
this.writeNotice(task, `\n[delegate stdin write failed: ${error.message}]\n`);
|
|
994
|
-
if (task.status === 'running') {
|
|
995
|
-
task.killKind = 'user';
|
|
996
|
-
task.error = `Delegate seed could not be delivered: ${error.message}`;
|
|
997
|
-
try {
|
|
998
|
-
this.requestKill(task, 'SIGTERM');
|
|
999
|
-
} catch {
|
|
1000
|
-
void this.finalizeTask(task, 'failed', null, undefined, task.error);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
});
|
|
1004
|
-
|
|
1005
|
-
child.stdout?.on('data', (data) => {
|
|
1006
|
-
this.appendChildOutput(task, data, 'stdout');
|
|
1007
|
-
});
|
|
1008
|
-
child.stderr?.on('data', (data) => {
|
|
1009
|
-
this.appendChildOutput(task, data, 'stderr');
|
|
1010
|
-
});
|
|
1011
|
-
child.on('error', (error) => {
|
|
1012
|
-
this.writeNotice(task, `\n[delegate spawn error: ${error.message}]\n`);
|
|
1013
|
-
void this.finalizeTask(task, 'failed', null, undefined, error.message);
|
|
1014
|
-
});
|
|
1015
|
-
child.on('close', (code, signalName) => {
|
|
1016
|
-
let status: TaskStatus;
|
|
1017
|
-
let error: string | undefined;
|
|
1018
|
-
if (task.killKind === 'user' || task.killKind === 'shutdown') {
|
|
1019
|
-
status = 'killed';
|
|
1020
|
-
} else if (task.killKind === 'timeout') {
|
|
1021
|
-
status = 'failed';
|
|
1022
|
-
error = task.error ?? `Timed out after ${String(request.timeoutSeconds ?? 0)}s`;
|
|
1023
|
-
} else if ((code ?? 0) === 0) {
|
|
1024
|
-
status = 'completed';
|
|
1025
|
-
} else {
|
|
1026
|
-
status = 'failed';
|
|
1027
|
-
error = `Exited with code ${code === null ? 'null' : String(code)}${signalName ? ` (${signalName})` : ''}`;
|
|
1028
|
-
}
|
|
1029
|
-
void this.finalizeTask(task, status, code, signalName, error);
|
|
1030
|
-
});
|
|
1031
|
-
|
|
1032
|
-
if (request.timeoutSeconds !== undefined) {
|
|
1033
|
-
task.timeoutHandle = setTimeout(() => {
|
|
1034
|
-
if (task.status !== 'running') return;
|
|
1035
|
-
task.killKind = 'timeout';
|
|
1036
|
-
task.error = `Timed out after ${String(request.timeoutSeconds)}s`;
|
|
1037
|
-
this.writeNotice(task, `\n[delegate timeout: ${task.error}]\n`);
|
|
1038
|
-
try {
|
|
1039
|
-
this.requestKill(task, 'SIGTERM');
|
|
1040
|
-
} catch (error) {
|
|
1041
|
-
void this.finalizeTask(
|
|
1042
|
-
task,
|
|
1043
|
-
'failed',
|
|
1044
|
-
null,
|
|
1045
|
-
undefined,
|
|
1046
|
-
`${task.error}; kill failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
1047
|
-
);
|
|
1048
|
-
}
|
|
1049
|
-
}, request.timeoutSeconds * 1000);
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1052
|
-
await this.writeMetadata(task);
|
|
1053
|
-
this.onChange();
|
|
1054
|
-
return task;
|
|
1055
|
-
} catch (error) {
|
|
1056
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1057
|
-
this.writeNotice(task, `\n[delegate spawn exception: ${message}]\n`);
|
|
1058
|
-
await this.finalizeTask(task, 'failed', null, undefined, message);
|
|
1059
|
-
throw new Error(`Failed to start delegate task: ${message}`);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
898
|
resolveTask(idOrPrefix: string): BgTask {
|
|
1064
899
|
const id = idOrPrefix.trim();
|
|
1065
900
|
if (!id) throw new Error('Task ID is required');
|
|
@@ -1816,12 +1651,7 @@ export class BackgroundTaskRegistry {
|
|
|
1816
1651
|
task.exitCode === undefined ? '' : `\n <exit-code>${String(task.exitCode)}</exit-code>`;
|
|
1817
1652
|
const error = task.error ? `\n <error>${escapeXml(task.error)}</error>` : '';
|
|
1818
1653
|
const taskName = taskDisplayName(task);
|
|
1819
|
-
const guidance =
|
|
1820
|
-
task.delegate === undefined
|
|
1821
|
-
? 'Terminal state and output metadata are durable. Do not call bg_status to reconfirm; use bg_logs only if output is needed.'
|
|
1822
|
-
: task.status === 'completed'
|
|
1823
|
-
? `Delegate result is durably committed. Call bg_result({taskId:${JSON.stringify(task.id)}}) once to retrieve it; do not poll.`
|
|
1824
|
-
: `Delegate ended ${task.status}. Inspect the preserved artifacts at ${task.delegate.artifactDir}; do not poll.`;
|
|
1654
|
+
const guidance = 'Terminal state and output metadata are durable. Do not call bg_status to reconfirm; use bg_logs only if output is needed.';
|
|
1825
1655
|
const content = [
|
|
1826
1656
|
'<background-task-notification>',
|
|
1827
1657
|
` <task-id>${task.id}</task-id>`,
|