@caupulican/pi-adaptative 0.80.102 → 0.81.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/CHANGELOG.md +131 -0
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -3
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +6 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +152 -512
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +635 -4590
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
- package/dist/core/autonomy/session-lane-record.js.map +1 -1
- package/dist/core/autonomy/status.d.ts +1 -0
- package/dist/core/autonomy/status.d.ts.map +1 -1
- package/dist/core/autonomy/status.js +1 -0
- package/dist/core/autonomy/status.js.map +1 -1
- package/dist/core/autonomy-telemetry.d.ts +80 -0
- package/dist/core/autonomy-telemetry.d.ts.map +1 -0
- package/dist/core/autonomy-telemetry.js +266 -0
- package/dist/core/autonomy-telemetry.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +186 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -0
- package/dist/core/background-lane-controller.js +691 -0
- package/dist/core/background-lane-controller.js.map +1 -0
- package/dist/core/bash-execution-controller.d.ts +51 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -0
- package/dist/core/bash-execution-controller.js +96 -0
- package/dist/core/bash-execution-controller.js.map +1 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +9 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction-support.d.ts +56 -0
- package/dist/core/compaction-support.d.ts.map +1 -0
- package/dist/core/compaction-support.js +99 -0
- package/dist/core/compaction-support.js.map +1 -0
- package/dist/core/context/artifact-retrieval.d.ts +1 -1
- package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
- package/dist/core/context/artifact-retrieval.js +1 -1
- package/dist/core/context/artifact-retrieval.js.map +1 -1
- package/dist/core/context/context-composition.d.ts.map +1 -1
- package/dist/core/context/context-composition.js +1 -1
- package/dist/core/context/context-composition.js.map +1 -1
- package/dist/core/context/tool-output-packer.d.ts +1 -1
- package/dist/core/context/tool-output-packer.d.ts.map +1 -1
- package/dist/core/context/tool-output-packer.js +1 -1
- package/dist/core/context/tool-output-packer.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +1 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +223 -0
- package/dist/core/context-pipeline.d.ts.map +1 -0
- package/dist/core/context-pipeline.js +594 -0
- package/dist/core/context-pipeline.js.map +1 -0
- package/dist/core/cost/daily-usage.d.ts +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +1 -1
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/cost/session-usage.d.ts +1 -1
- package/dist/core/cost/session-usage.d.ts.map +1 -1
- package/dist/core/cost/session-usage.js +1 -1
- package/dist/core/cost/session-usage.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +1 -1
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/exec.d.ts +2 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +15 -9
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +2 -2
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/builtin.d.ts.map +1 -1
- package/dist/core/extensions/builtin.js +2 -2
- package/dist/core/extensions/builtin.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +24 -0
- package/dist/core/goal-loop-controller.d.ts.map +1 -0
- package/dist/core/goal-loop-controller.js +83 -0
- package/dist/core/goal-loop-controller.js.map +1 -0
- package/dist/core/goals/goal-runtime-snapshot.d.ts +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +1 -1
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/learning/learning-audit.d.ts +1 -1
- package/dist/core/learning/learning-audit.d.ts.map +1 -1
- package/dist/core/learning/learning-audit.js.map +1 -1
- package/dist/core/learning/session-learning-decision.d.ts +1 -1
- package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
- package/dist/core/learning/session-learning-decision.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +99 -0
- package/dist/core/local-runtime-controller.d.ts.map +1 -0
- package/dist/core/local-runtime-controller.js +214 -0
- package/dist/core/local-runtime-controller.js.map +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +1 -1
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +139 -0
- package/dist/core/memory-controller.d.ts.map +1 -0
- package/dist/core/memory-controller.js +323 -0
- package/dist/core/memory-controller.js.map +1 -0
- package/dist/core/model-router/status.d.ts +1 -1
- package/dist/core/model-router/status.d.ts.map +1 -1
- package/dist/core/model-router/status.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +140 -0
- package/dist/core/model-router-controller.d.ts.map +1 -0
- package/dist/core/model-router-controller.js +623 -0
- package/dist/core/model-router-controller.js.map +1 -0
- package/dist/core/model-selection-controller.d.ts +95 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -0
- package/dist/core/model-selection-controller.js +252 -0
- package/dist/core/model-selection-controller.js.map +1 -0
- package/dist/core/models/model-ref.d.ts +13 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +22 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +77 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -0
- package/dist/core/profile-filter-controller.js +159 -0
- package/dist/core/profile-filter-controller.js.map +1 -0
- package/dist/core/reflection-controller.d.ts +111 -0
- package/dist/core/reflection-controller.d.ts.map +1 -0
- package/dist/core/reflection-controller.js +412 -0
- package/dist/core/reflection-controller.js.map +1 -0
- package/dist/core/research/model-fitness.d.ts +12 -0
- package/dist/core/research/model-fitness.d.ts.map +1 -1
- package/dist/core/research/model-fitness.js +21 -0
- package/dist/core/research/model-fitness.js.map +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/session-evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +222 -0
- package/dist/core/runtime-builder.d.ts.map +1 -0
- package/dist/core/runtime-builder.js +640 -0
- package/dist/core/runtime-builder.js.map +1 -0
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-analytics.d.ts +96 -0
- package/dist/core/session-analytics.d.ts.map +1 -0
- package/dist/core/session-analytics.js +331 -0
- package/dist/core/session-analytics.js.map +1 -0
- package/dist/core/session-manager-factory.d.ts +18 -0
- package/dist/core/session-manager-factory.d.ts.map +1 -0
- package/dist/core/session-manager-factory.js +32 -0
- package/dist/core/session-manager-factory.js.map +1 -0
- package/dist/core/session-tree-navigator.d.ts +68 -0
- package/dist/core/session-tree-navigator.d.ts.map +1 -0
- package/dist/core/session-tree-navigator.js +217 -0
- package/dist/core/session-tree-navigator.js.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +63 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.js +181 -0
- package/dist/core/system-prompt-builder.js.map +1 -0
- package/dist/core/tool-gate-controller.d.ts +36 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -0
- package/dist/core/tool-gate-controller.js +94 -0
- package/dist/core/tool-gate-controller.js.map +1 -0
- package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
- package/dist/core/tools/artifact-retrieve.js +1 -1
- package/dist/core/tools/artifact-retrieve.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +49 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +61 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -12
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +59 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.js +398 -0
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts +168 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.js +1239 -0
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts +26 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.js +103 -0
- package/dist/modes/interactive/autocomplete-provider.js.map +1 -0
- package/dist/modes/interactive/autonomy-commands.d.ts +38 -0
- package/dist/modes/interactive/autonomy-commands.d.ts.map +1 -0
- package/dist/modes/interactive/autonomy-commands.js +142 -0
- package/dist/modes/interactive/autonomy-commands.js.map +1 -0
- package/dist/modes/interactive/clipboard-input.d.ts +37 -0
- package/dist/modes/interactive/clipboard-input.d.ts.map +1 -0
- package/dist/modes/interactive/clipboard-input.js +59 -0
- package/dist/modes/interactive/clipboard-input.js.map +1 -0
- package/dist/modes/interactive/compaction-queue.d.ts +30 -0
- package/dist/modes/interactive/compaction-queue.d.ts.map +1 -0
- package/dist/modes/interactive/compaction-queue.js +91 -0
- package/dist/modes/interactive/compaction-queue.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +27 -0
- package/dist/modes/interactive/config-backup.d.ts.map +1 -0
- package/dist/modes/interactive/config-backup.js +146 -0
- package/dist/modes/interactive/config-backup.js.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts +48 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.js +43 -0
- package/dist/modes/interactive/editor-overlay-host.js.map +1 -0
- package/dist/modes/interactive/extension-ui-host.d.ts +165 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -0
- package/dist/modes/interactive/extension-ui-host.js +610 -0
- package/dist/modes/interactive/extension-ui-host.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts +18 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +107 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/history-reload-math.d.ts +24 -0
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -0
- package/dist/modes/interactive/history-reload-math.js +129 -0
- package/dist/modes/interactive/history-reload-math.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +22 -238
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +714 -5910
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +46 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -0
- package/dist/modes/interactive/key-handlers.js +80 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -0
- package/dist/modes/interactive/local-model-commands.d.ts +68 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -0
- package/dist/modes/interactive/local-model-commands.js +288 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts +77 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.js +917 -0
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -0
- package/dist/modes/interactive/report-commands.d.ts +46 -0
- package/dist/modes/interactive/report-commands.d.ts.map +1 -0
- package/dist/modes/interactive/report-commands.js +255 -0
- package/dist/modes/interactive/report-commands.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +73 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +278 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts +64 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.js +202 -0
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -0
- package/dist/modes/interactive/session-flow-commands.d.ts +139 -0
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-flow-commands.js +458 -0
- package/dist/modes/interactive/session-flow-commands.js.map +1 -0
- package/dist/modes/interactive/session-io-commands.d.ts +73 -0
- package/dist/modes/interactive/session-io-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-io-commands.js +202 -0
- package/dist/modes/interactive/session-io-commands.js.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts +42 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.js +287 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts +55 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.js +177 -0
- package/dist/modes/interactive/signal-lifecycle.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +38 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +189 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -14
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -30
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/process-memory.d.ts +8 -0
- package/dist/utils/process-memory.d.ts.map +1 -0
- package/dist/utils/process-memory.js +11 -0
- package/dist/utils/process-memory.js.map +1 -0
- package/dist/utils/shell.d.ts +0 -9
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +0 -37
- package/dist/utils/shell.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/11-sessions.ts +8 -8
- package/examples/sdk/13-session-runtime.ts +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -143
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -659
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -153
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/message-retention.d.ts +0 -26
- package/dist/core/message-retention.d.ts.map +0 -1
- package/dist/core/message-retention.js +0 -95
- package/dist/core/message-retention.js.map +0 -1
- package/dist/core/messages.d.ts +0 -77
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -123
- package/dist/core/messages.js.map +0 -1
- package/dist/core/session-manager.d.ts +0 -337
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js +0 -1328
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/tools/truncate.d.ts +0 -70
- package/dist/core/tools/truncate.d.ts.map +0 -1
- package/dist/core/tools/truncate.js +0 -215
- package/dist/core/tools/truncate.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,134 @@
|
|
|
1
|
+
## [0.81.0] - 2026-07-04
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
- Foreground bash commands with no explicit `timeout` are now killed after 600s of continuous
|
|
5
|
+
silence (no stdout/stderr output), not by total runtime — a command that keeps producing output
|
|
6
|
+
is never killed by this. Passing an explicit `timeout` disables the silence watchdog in favor of
|
|
7
|
+
the wall-clock limit; backgrounded (`cmd &`) work is exempt by construction. Wires the
|
|
8
|
+
`createSilenceWatchdog` primitive from `@caupulican/pi-agent-core`'s reliability kernel into the
|
|
9
|
+
bash tool.
|
|
10
|
+
- A silently dead provider stream can no longer wedge a turn forever. Every provider stream a
|
|
11
|
+
session starts is now wrapped once (at construction) with the reliability kernel's
|
|
12
|
+
`withStreamIdleWatchdog`: it bounds the wait for the first event (120s connect allowance) and the
|
|
13
|
+
gap between subsequent events (30s idle). On a stall it aborts the inner request and surfaces a
|
|
14
|
+
retryable `stream stalled` error, which the existing auto-retry path picks up — so a hung
|
|
15
|
+
connection now fails over instead of hanging. The bound is on silence, never on total runtime, so
|
|
16
|
+
a stream that keeps emitting is never cut off.
|
|
17
|
+
- Process memory (rss, heap used, external — rounded to MB) is now surfaced as self-telemetry: the
|
|
18
|
+
`/usage` command prints a "Process" section, and `getAutonomyDiagnosticSnapshot` gains a
|
|
19
|
+
`processMemory` family rendered by `formatAutonomyDiagnostics`. Unlike the snapshot's other
|
|
20
|
+
families, `processMemory` reflects live process state rather than recorded session activity, so it
|
|
21
|
+
is always present, even when nothing else has happened yet.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- truncate and sanitizeBinaryOutput now live in @caupulican/pi-agent-core (single canonical copy).
|
|
25
|
+
- convertToLlm and the custom message types (BashExecutionMessage, CustomMessage, BranchSummaryMessage, CompactionSummaryMessage) now come from @caupulican/pi-agent-core (moved out of `core/messages.ts`); coding-agent re-exports convertToLlm unchanged, so its public API is preserved.
|
|
26
|
+
- The tool-result-details retention helpers (`compactToolResultDetailsForRetention`, `compactRetainedDetails`, and their byte budgets) and the `normalizePath`/`resolvePath` path helpers now come from @caupulican/pi-agent-core (`message-retention` moved to the main entry, path helpers to the `/node` entry). `utils/paths.ts` re-exports `normalizePath`/`resolvePath` unchanged, so its consumers are unaffected.
|
|
27
|
+
- `SessionManager` no longer reads app config. Its constructor and statics (`create`, `open`, `continueRecent`, `forkFrom`, `list`) now take the agent config dir explicitly, and `listAll` takes the sessions-root dir explicitly — the kernel-promotion seam, so `SessionManager` no longer imports `config.ts`. A new host-layer `core/session-manager-factory.ts` (`createSession`, `openSession`, `continueRecentSession`, `forkSession`, `listSessions`, `listAllSessions`) is the single visible place that closes over `getAgentDir()`/`getSessionsDir()` and delegates; call sites that already hold their own agent dir (SDK, session runtime) pass it directly. Behavior is unchanged (`usesDefaultSessionDir()` now compares against the injected agent dir, identical to the previous config-derived value in the CLI).
|
|
28
|
+
- `SessionManager` and the session storage types (`SessionEntry`, `SessionHeader`, `SessionContext`, `SessionInfo`, `SessionTreeNode`, `CompactionEntry`, `BranchSummaryEntry`, `CustomEntry`, `CustomMessageEntry`, `LabelEntry`, `SessionInfoEntry`, `FileEntry`, `ReadonlySessionManager`, `NewSessionOptions`, `SessionListProgress`) and functions (`buildSessionContext`, `migrateSessionEntries`, `parseSessionEntries`, `getLatestCompactionEntry`, `getDefaultSessionDir`, `loadEntriesFromFile`, `findMostRecentSession`, `assertValidSessionId`, `isAutoLearnSessionId`, `CURRENT_SESSION_VERSION`) now come from `@caupulican/pi-agent-core/node` (moved out of `core/session-manager.ts`); `core/session-manager-factory.ts` still wraps it with the same host-layer API, so coding-agent's public surface and behavior are unchanged.
|
|
29
|
+
- The compaction + branch-summarization module (`shouldCompact`, `prepareCompaction`, `compact`, `generateSummary`, `findCutPoint`, `findTurnStartIndex`, `estimateTokens`, `estimateContextTokens`, `calculateContextTokens`, `getLastAssistantUsage`, `serializeConversation`, `DEFAULT_COMPACTION_SETTINGS`, `collectEntriesForBranchSummary`, `prepareBranchEntries`, `generateBranchSummary`, and the `CompactionResult`/`CompactionSettings`/`CompactionPreparation`/`FileOperations` types) now comes from `@caupulican/pi-agent-core/node` (moved out of `core/compaction/`); the `#30` cost-guard triggers (`triggerPercent`, `MIN_COMPACTION_SAVINGS`) ride along unchanged. `AgentSession` still owns the auto-compaction orchestration and calls into the promoted functions; coding-agent re-exports the surface unchanged, so its public API and behavior are preserved.
|
|
30
|
+
- Auto-retry, stalled-stream abort, bash silence watchdog, exec kill escalation, and bash/edit write serialization now ride the shared reliability kernel (@caupulican/pi-agent-core).
|
|
31
|
+
- Provider errors containing auth wording (401/unauthorized/invalid api key) are now terminal instead of retried, even when combined with transient wording (e.g. "fetch failed: 401 unauthorized") — retrying on bad credentials is pointless. Previously such mixed messages were retried.
|
|
32
|
+
- Custom retry settings are now capped at 120s per backoff step (maxDelayMs). Default behavior (2s/4s/8s) is unchanged; only aggressive custom baseDelayMs/maxRetries combinations are affected.
|
|
33
|
+
- The Auto Learn / native-reflection controller moved out of `interactive-mode.ts` into `modes/interactive/auto-learn-controller.ts` (new `AutoLearnController`): the disk-backed run-state machine (state.json + lockfile), the background-learner spawn/prune lifecycle, and the in-process reflection pass now live in one module. `InteractiveMode` constructs it with narrow deps (a live session accessor, the host's self-modification-source resolver, and a small UI callback surface) and delegates at every call-in point; behavior is unchanged.
|
|
34
|
+
- The local-runtime (Ollama) lifecycle moved out of `agent-session.ts` into `core/local-runtime-controller.ts` (new `LocalRuntimeController`): the cached per-server `OllamaRuntime` instances, the "confirmed up this session" flag, the #31 install-on-consent flow, and the #27 router tier-escalation fallback now live in one module. `AgentSession` constructs it with narrow deps (agent dir, a last-assistant-message accessor, the session's UI context/event emitter, and the router's own tier resolver) and delegates at every call-in point (`getLocalRuntime` keeps its public signature); behavior is unchanged.
|
|
35
|
+
- System-prompt construction moved out of `agent-session.ts` into `core/system-prompt-builder.ts` (new `SystemPromptBuilder`): the situational-soul (R6), self-modification, and autonomy guardrail blocks, the per-tool snippet/guideline options assembly, and the `_baseSystemPromptOptions` state now live in one module (distinct from the existing pure `core/system-prompt.ts` string renderer it feeds). `AgentSession` constructs it with narrow accessor deps (cwd, the settings/resource/memory managers, the tool registries, and the active extensions — each read fresh so mid-session reassignment is tracked) and delegates at every call-in point; behavior is unchanged.
|
|
36
|
+
- Autonomy telemetry and the status/diagnostic snapshots moved out of `agent-session.ts` into `core/autonomy-telemetry.ts` (new `AutonomyTelemetry`): the G3 telemetry sink, the G8 gate-outcome recorder plus the bounded gate-outcome history (owning the `_lastAutonomyGateOutcome` / `_gateOutcomeHistory` state), and the `getAutonomyStatusSnapshot` / `getAutonomyDiagnosticSnapshot` builders now live in one module. `AgentSession` constructs it with narrow accessor deps (the session manager, the last router decision, cost/goal/lane getters, and the research/delegation/learning snapshot getters — each read fresh) and delegates at every call-in point (`_emitAutonomyTelemetry`, `_recordGateOutcome`, `getGateOutcomeHistory`, and both public snapshot methods keep their signatures); behavior is unchanged.
|
|
37
|
+
- The background lanes moved out of `agent-session.ts` into `core/background-lane-controller.ts` (new `BackgroundLaneController`): idle goal auto-continue, the autonomous research lane, scout-worker delegation, and the model-fitness probe — plus the shared lane-model/profile/envelope resolution helpers — now live in one module, owning the lane timers, the single-flight guards, the last research-lane skip reason, the live `LaneTracker`, and the in-flight research/worker abort controllers. `AgentSession` constructs it with narrow accessor deps (the session manager, settings, model registry, live model, capability envelope, the model-capability profile, the goal continuation LOOP, the isolated-completion primitive, spawned-usage accounting, and the telemetry sink — each read fresh) and delegates at every call-in point: the idle triggers off the prompt tail, the dispose-time timer clears + lane aborts, the router judge's lane-model resolution, and the public `runResearchLaneOnce` / `runWorkerDelegationOnce` / `runModelFitness` / `getStoredFitnessReports` / `getLaneRecords` methods keep their signatures. The drive-loop boundary is preserved — the controller only ever asks the session to `continueGoalLoop`, never touching `prompt()` or streaming/retry state; behavior is unchanged.
|
|
38
|
+
- The memory subsystem moved out of `agent-session.ts` into `core/memory-controller.ts` (new `MemoryController`): the observe-only local OKF retrieval, the bounded prompt-evidence surfacing pilot, cross-session recall gating/effectiveness, and the plug-and-play `MemoryManager` (bundled file-store + transcript-recall providers plus extension contributions) now live in one module, owning the lazily-built OKF provider, the latest retrieval/prompt-inclusion reports, the reload-safe `MemoryManager`, the recall `EffectivenessTracker`, and the extension-contributed pending providers. `AgentSession` constructs it with narrow accessor deps (settings, the current turn index, agent/workspace dirs, the session id, the child-session flag, and the tool-registry refresh — each read fresh) and delegates at every call-in point: the context-transform hot path (`_runMemoryRetrieval` / `_maybeAppendMemoryEvidenceBlock` stay as one-line delegations so the transform keeps owning the pass ordering), the drive-loop cross-session recall (`shouldAttemptRecall` / prefetch / `recordRecallOutcome`), the context_audit memory diagnostics, dispose-time shutdown, reload's provider reset + re-init, the memory-tool surfacing, and the reflection engine's fresh-memory reads. The public `getMemoryRetrievalReport` / `getMemoryPromptInclusionReport` / `registerMemoryProvider` methods keep their signatures. The controller imports no compaction/context-pipeline internals; behavior is unchanged.
|
|
39
|
+
- The per-turn context pipeline moved out of `agent-session.ts` into `core/context-pipeline.ts` (new `ContextPipeline`): the observe-only context audit, the shadow prompt-policy plan and its correlation with legacy context-gc, the enforcement pilot, the relevance-curation queue plus the fitness-gated curation-model resolver / brain-curation drain / compaction pre-digest, the legacy context-gc pass and its packed-artifact reference release, the tool-output artifact store, and the current-context token estimate now live in one module, owning the latest audit/policy/correlation/enforcement/gc reports, the `BrainCurator` sidecar and its curation/pre-digest skip reasons, and the lazily-built artifact store. `AgentSession` constructs it with narrow accessor deps (the current turn index, the session/settings managers, the model registry, agent/workspace dirs, the active tool names, the disposed flag, the isolated-completion primitive, spawned-usage accounting, and the live `MemoryManager` — each read fresh) and delegates at every call-in point: `_installAgentContextTransform` stays host-side and keeps the pass ordering, with each stage (`_estimateCurrentContextTokens`, `_runContextAudit`, `_runPromptPolicyPlanning`, `_applyContextGc`, `_correlatePromptPolicyWithContextGc`, `_runPromptEnforcement`, `_enqueueRelevanceCuration`, `_maybeDrainBrainCuration`) a one-line delegation; the compaction pre-digest, executor reflex-brain model resolution, runtime tool-artifact-store build, per-turn cost guard, composition dashboard, and dispose-time artifact sweep likewise delegate. The public `getContextAuditReport` / `getPromptPolicyReport` / `getPromptPolicyGcCorrelation` / `getPromptEnforcementReport` / `getContextGcReport` / `getContextCurationStatus` methods keep their signatures. The pipeline reaches `MemoryController` only through the `getMemoryManager` dep (never imports it), and `MemoryController` never imports the pipeline, so the transform stays the single place the two subsystems meet; behavior is unchanged.
|
|
40
|
+
- Two pure computation clusters moved out of `interactive-mode.ts` into new sibling modules. `modes/interactive/history-reload-math.ts` holds the TUI reload-window math (`messagesForTuiHistoryReload`, `estimateTuiHistoryLines`, the text/message tail-trimmers, and the message-text extractors, plus the `TUI_HISTORY_RELOAD_MAX_LINES`/`_WRAP_WIDTH` budgets). `modes/interactive/resource-display.ts` holds the startup "loaded resources" formatters (path/label/scope-group/diagnostics rendering). `InteractiveMode` retains thin `this.`-delegating wrappers only where its stateful display code (`showLoadedResources`, `renderSessionContext`, `addMessageToChat`) or the existing prototype-based tests resolve a formatter through `this`; the rest are called directly from the modules. Behavior is unchanged.
|
|
41
|
+
- The editor-overlay swap that `interactive-mode.ts` repeats ~23× (both showing an overlay in place of the editor — selectors, dialogs, loaders, the reload notice — and restoring the editor afterwards) is now unified behind `modes/interactive/editor-overlay-host.ts` (new `EditorOverlayHost`). Its single `swap(component, options)` method performs the `clear → addChild → focus → requestRender` sequence, parameterizing the real per-site deltas: the focus target (defaults to the mounted component; the selector helper focuses a distinct child), `setFocus` vs `restoreFocus` (the latter for the two selector-return paths that prefer the topmost visible overlay), and the render request (`requestRender()`, `requestRender(true)` for the reload notice, or none where the caller renders later). Per-site cleanup that isn't a swap concern (component `dispose()`, temp-file unlink, clearing the stored selector reference, restoring saved editor text) stays inline at each call site. The editor-*replacement* path (`setCustomEditorComponent`, which clears early, rebuilds the editor, then mounts it) is a different shape and is left as-is. Behavior is unchanged.
|
|
42
|
+
- The resource-profile and external-source menu flows moved out of `interactive-mode.ts` into `modes/interactive/profile-menu-controller.ts` (new `ProfileMenuController`): the `/profiles` command, the resources-hub menu tree (active-profile selection, manage/create/delete/persist profiles, the per-profile library resource-grant editor, and external-root add/remove), and the profile-apply/reload/mutation-refresh logic now live in one module (23 methods). It holds no state of its own — every fact still lives in `settingsManager`, the profile registry, and the session resource loader — so `InteractiveMode` constructs it with narrow deps (a live session accessor and a UI callback surface, including the shared `showSelector`/`EditorOverlayHost`) and keeps thin one-line delegators at the three call-in points (`handleResourcesHubAction`, `handleProfilesCommand`, `refreshAfterProfileMutation`); behavior is unchanged.
|
|
43
|
+
- The auth / login / OAuth dialog flows moved out of `interactive-mode.ts` into `modes/interactive/auth-dialogs-controller.ts` (new `AuthDialogsController`): the `/login` and `/logout` command handling (provider resolution and selection, the auth-type/provider selectors), the subscription (OAuth) login dialog, the API-key login dialog, the Amazon Bedrock setup notice, the in-dialog OAuth select prompt, and post-login model adoption now live in one module (12 methods), together with the auth-provider classification helpers (`isApiKeyLoginProvider`, `isUnknownModel`, `hasDefaultModelProvider`, `BEDROCK_PROVIDER_ID`) that only those flows used. It holds no state of its own — every credential/provider fact still lives in `session.modelRegistry.authStorage` — so `InteractiveMode` constructs it with narrow deps (a live session accessor and a UI callback surface, including the shared `showSelector`/`EditorOverlayHost`) and reaches it at the single external call-in point (`showOAuthSelector`, for `/login` and `/logout`); behavior is unchanged.
|
|
44
|
+
- The config backup/restore commands and the read-only report/easter-egg commands moved out of `interactive-mode.ts` into two new sibling modules. `modes/interactive/config-backup.ts` holds `/config-backup` and `/config-restore` (the profile + resource-settings snapshot and its round-trip, including the pre-restore confirmation and the security rule that restored external roots come back untrusted). `modes/interactive/report-commands.ts` holds the read-only reports (`/usage`, `/changelog`, `/hotkeys`, `/debug`) and the easter-egg renders (`/arminsayshi`, `/dementedelves`, and the kimi-k2.5 daxnuts trigger). Both are plain function modules that operate through a narrow structural `host` seam (the settings manager plus status/error/selector callbacks; or the chat container, TUI, and a few read accessors), so `InteractiveMode` keeps thin wrappers that build the host from `this` at call time — required both because those fields are private and because the existing prototype-based tests invoke the wrappers through `this`. Behavior is unchanged.
|
|
45
|
+
- The model-router turn routing moved out of `agent-session.ts` into `core/model-router-controller.ts` (new `ModelRouterController`): the regex/executor route resolver, the optional bounded routing judge, the executor lane (Level-0 toolkit direct hit plus the speculative brain-refined retry), the per-tier thinking/tool-surface swap around a routed turn, the cheap-research-turn session buffer with mutating-tool escalation to an expensive retry, and the router status/diagnostics report now live in one module, owning the transient per-turn route state (active intent/route, the cheap-turn session buffer, the escalation-requested and retry-in-flight flags) and the sticky last-decision/skip-reason/intent. The parallel routed drive path (`runRoutedTurn`) keeps the actual agent.prompt()/continue() loop host-side — `AgentSession._runAgentPrompt`/`_promptUnserialized` are untouched and reached through a `runAgentPrompt` dep, so the drive loop is never duplicated. `AgentSession` constructs it with narrow accessor deps (the live agent, current model, the session/settings managers, the model registry, agent dir, the reflection abort signal, the base system prompt, the isolated-completion primitive, spawned-usage accounting, the event/telemetry emitters, and the recently-extracted `BackgroundLaneController.resolveLaneModel` / `ContextPipeline.resolveCurationModelIfFit`) and keeps a one-line delegation at every call-in: the routing prep + routed-turn entry in `_promptUnserialized`, the `beforeToolCall` mutating-tool escalation branch (`maybeEscalateToolCall`), the `message_end` cheap-turn buffering (`captureSessionMessage`), the retry-event suppression (`isRetryInFlight`), and the public `getModelRouterStatus` plus the autonomy-telemetry last-decision read. Behavior and event ordering are unchanged.
|
|
46
|
+
- The runtime build and the self-modification-safe extension reload moved out of `agent-session.ts` into `core/runtime-builder.ts` (new `RuntimeBuilder`): the tool-registry assembly (`refreshToolRegistry`), the base-tool-definition + `ExtensionRunner` build (`buildRuntime`), the crown-jewel `reload()` with its snapshot / doctor / commit-or-rollback sequence, and the single-extension live load/unload/reconcile operations now live in one module, owning the five tool-registry maps (base tool definitions, the wrapped tool registry, the definition registry, and the per-tool prompt snippet/guideline maps). The reload snapshot spans state owned by other collaborators — the extension runner and its ref, `agent.state.tools`/`agent.state.systemPrompt`, and `_baseSystemPrompt` — which stay host/agent-owned and are captured and restored through narrow get/set deps so save/restore mutate exactly the same fields as before (the `_extensionRunnerRef.current` update folds into `setExtensionRunner`, matching the host's field-then-ref pattern); only the tool-registry maps are owned by the builder. `_bindExtensionCore` stays host-side (it exposes the session's own public surface to the runner — host identity, not build logic) and is invoked from `buildRuntime` via a `bindExtensionCore` dep. `AgentSession` constructs it with narrow accessor deps (the live agent, cwd, the session/settings managers, the model registry, the resource loader, the extension-runner get/set, the base-system-prompt get/set, the custom-tools/base-override, the requested-active-tool-names request, the profile tool filter + its warning sink, memory subsystem accessors, the goal/context-gc/worker/model-fitness tool callbacks, the isolated-completion primitive and spawned-usage accounting, the doctor context-snapshot/context-usage probes, and the streaming/compacting refusal guards) and keeps byte-identical one-line delegations for the public `reload` / `loadExtensionLive` / `unloadExtensionLive` / `reconcileLoadedExtensions` API and for `getAllTools` / `getToolDefinition`, plus a private `_refreshToolRegistry` delegation for its internal callers. The preflight → doctor → commit/rollback sequence and refusal behavior are unchanged.
|
|
47
|
+
- The extension UI surface moved out of `interactive-mode.ts` into `modes/interactive/extension-ui-host.ts` (new `ExtensionUiHost`): the extension-provided dialogs (`select`/`confirm`/`input`, the multi-line editor, and the overlay-capable `custom` component), the above/below-editor widget mounting, extension status text, the custom footer/header swaps, the custom editor-component swap (`setCustomEditorComponent`, its early `editorContainer.clear()` preserved verbatim), keyboard-shortcut wiring, terminal-input listeners, the extension-error render, and the `ExtensionUIContext` handed to extensions now live in one module (22 methods). It owns exactly the state this cluster mutates (the live selector/input/editor dialog components, the above/below widget maps, the terminal-input unsubscribers, the custom footer/header, and the current custom-editor factory). `InteractiveMode` constructs it with narrow deps (a live session accessor plus a UI callback surface: the stable containers/TUI/overlay-host/footer passed directly, the mutable active editor and built-in header reached through get/set accessors, and the render-core / status operations that stay host-side — working indicator, hidden-thinking label, autocomplete rebuild, tools-expansion, terminal title, and shutdown/abort/reload — exposed as callbacks) and keeps one-line delegations at every call-in point: the session-invalidate reset and `handleReloadCommand`'s `resetExtensionUI`, `bindCurrentSessionExtensions`' context/error/shortcut wiring, the reload and live-refresh shortcut re-wiring, the branch-summary and `/import` confirm/selector/editor prompts, the initial widget render, `stop()`'s listener teardown, and the three `getCustomHeader()` header reads. The extension test suites are the lock — extensions see an identical `ExtensionUIContext`; behavior is unchanged.
|
|
48
|
+
- The residual command/flow/plumbing clusters moved out of `interactive-mode.ts` into thirteen new sibling modules, bringing the file under the 4,000-line cap (5,870 → 3,971): `session-flow-commands.ts` (tree/session/fork navigation and the model selectors), `settings-selector-flow.ts` (`/settings`), `local-model-commands.ts` (`/models` lifecycle and `/fitness`), `autonomy-commands.ts` (`/autonomy`, `/auto-learn`), `session-io-commands.ts` (import/export/share/copy/name), `resource-shell-commands.ts` (`/install-resources`, `/curate`, bash, `/compact`), `external-editor.ts` (`$EDITOR`/`$VISUAL` launch), `autocomplete-provider.ts` (base completion set), `startup-checks.ts` (changelog notice, update/tmux checks, notifications, install telemetry, trust warning), `signal-lifecycle.ts` (SIGTERM/SIGHUP/uncaught handlers, graceful+emergency shutdown, Ctrl+Z suspend), `key-handlers.ts` (editor/global key wiring), `clipboard-input.ts` (image paste + user-input assembly), and `compaction-queue.ts` (post-compaction queue flush). Each is a plain function module operating through a narrow structural `host` seam; `InteractiveMode` keeps thin wrappers that build the host from `this` at call time (with get/set accessors for the fields a flow mutates — e.g. `loadingAnimation`, `isShuttingDown`/`signalCleanupHandlers`, `isBashMode`, the clipboard queue/counter, `compactionQueuedMessages`) both because those members are private and because the existing prototype-based tests invoke the wrappers through `this`. The slash-command router, `handleEvent`, the streaming/status-loader lifecycle, `renderSessionContext`, and the render core stay host-side. Bodies are verbatim; behavior is unchanged.
|
|
49
|
+
- The residual autonomy/session/runtime clusters moved out of `agent-session.ts` into eight new `core/` collaborator classes, bringing the file under the 4,000-line cap (5,387 → 3,963): `reflection-controller.ts` (`ReflectionController` — the native end-of-loop reflection pass, the isolated-completion primitive, and the gated learning-apply/rollback path), `goal-loop-controller.ts` (`GoalLoopController` — the bounded goal auto-continuation loop), `session-analytics.ts` (`SessionAnalytics` — usage/cost/stats accounting, the /context window estimate, and HTML/JSONL export, owning the spawned-usage and daily-usage memo caches), `session-tree-navigator.ts` (`SessionTreeNavigator` — in-file branch switching + fork-selector reads), `model-selection-controller.ts` (`ModelSelectionController` — the manual model switch/cycle and thinking-level set/cycle/clamp, distinct from the per-turn `ModelRouterController`), `bash-execution-controller.ts` (`BashExecutionController` — the `/bash` path and its streaming-deferred pending-message queue), `profile-filter-controller.ts` (`ProfileFilterController` — resource-profile tool/extension gating and reload-time profile model re-apply), and `tool-gate-controller.ts` (`ToolGateController` — the agent `beforeToolCall`/`afterToolCall` hooks: router escalation, autonomy gating, extension tool hooks, and the untrusted-content output boundary). `AgentSession` constructs each with narrow lazy accessor deps and keeps same-signature public delegations at every call-in point, so callers, the constructor dep closures, and the drive loop are untouched (the `model`/`thinkingLevel` getters, the branch-summary abort controller read by `isCompacting`, and the bash-flush call sites all stay host-side). The drive loop (`_promptUnserialized`/`_handleAgentEvent`/`_handlePostAgentRun`), compaction, the retry bridge, and the extension-core wiring stay host-side. Bodies are verbatim; behavior is unchanged.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
- `pi --version` resolved through the full application import graph (~1s to print a version string). A fast path in the CLI entry now answers `--version`/`-v` from already-loaded config (~150ms, −85%); any combined invocation still routes through the full parser unchanged.
|
|
53
|
+
- Auto-compaction could fail or skip invisibly: three bail paths (no model, summarizer auth failure, nothing to compact) ended with no result and no reason, and the TUI rendered nothing for that combination — indistinguishable from broken compaction. Every auto-compaction outcome now carries a `result`, an `errorMessage`, or a new `skipReason` on `compaction_end`, and the TUI renders all of them. The cheap summarizer model (#30) also falls back to the session model when its key resolution fails at request time instead of silently giving up.
|
|
54
|
+
- `pi --help` had regressed from ~160ms to ~400ms: `config.ts`'s `normalizePath` import (needed
|
|
55
|
+
just to resolve `PI_PACKAGE_DIR`) went through `utils/paths.ts`, which re-exported from
|
|
56
|
+
`@caupulican/pi-agent-core/node` — a barrel that also loads `SessionManager`, compaction,
|
|
57
|
+
messages, and process-tree, none of which the help path needs. `utils/paths.ts` now imports from
|
|
58
|
+
the kernel's new granular `@caupulican/pi-agent-core/paths` subpath instead, restoring `--help` to
|
|
59
|
+
its ~160ms baseline; behavior and the re-exported surface are unchanged.
|
|
60
|
+
- Bash commands could previously race file-tool (`edit`/`write`) mutations: because a shell command
|
|
61
|
+
cannot statically declare which files it touches, it wasn't serialized against them at all. The
|
|
62
|
+
bash tool's foreground command execution now goes through a readers-writer barrier shared with
|
|
63
|
+
`withFileMutationQueue`: file mutations are readers (still parallel with each other across
|
|
64
|
+
different files), and bash is the sole writer — it waits for all in-flight/queued file mutations
|
|
65
|
+
to drain, then runs exclusively while blocking new ones, and queues FIFO against other bash
|
|
66
|
+
invocations. New `withExclusiveMutationBarrier` in `file-mutation-queue.ts`.
|
|
67
|
+
- `execCommand`'s kill path (used by aborted/timed-out commands, including extensions' `ctx.exec`)
|
|
68
|
+
now actually escalates to SIGKILL: it previously gated escalation on `ChildProcess.killed`, which
|
|
69
|
+
Node sets the moment a signal is *sent* rather than when the process dies, so a child trapping
|
|
70
|
+
SIGTERM survived forever. The kill path now delegates to the reliability kernel's `killTree`
|
|
71
|
+
(liveness-probed SIGTERM → SIGKILL escalation). Commands also spawn in their own process group on
|
|
72
|
+
POSIX so aborting kills grandchildren, not just the direct child. Spawn failures (e.g. ENOENT) are
|
|
73
|
+
now surfaced via a new `ExecResult.errorMessage` field instead of being silently swallowed as a
|
|
74
|
+
bare `code: 1`.
|
|
75
|
+
- Model adoption ignored the fitness probe's own verdict. Two gates, both fixed:
|
|
76
|
+
- `/models suggest` (and the manual `/fitness` picker) could probe a model, get zero successes on
|
|
77
|
+
every one of the six surfaces, and still land it as judge model / Model Router settings because
|
|
78
|
+
the post-probe role selector opened regardless of the result. `runFitnessAndAssign` — the single
|
|
79
|
+
site both flows funnel through — now checks the new pure `isProbeAllFailed(report)` predicate
|
|
80
|
+
(research/core/research/model-fitness.ts) and, on an all-lanes-failed probe, refuses adoption
|
|
81
|
+
outright: no role assigned, no settings written, just a clear "failed the fitness probe on all
|
|
82
|
+
surfaces — not configured" message pointing at manual `/model` as the opt-in override. A partial
|
|
83
|
+
or full pass keeps the existing selector flow unchanged. The predicate itself had a latent
|
|
84
|
+
vacuous-truth gap: when every lane surface was ungraded (`total: 0`) but the judge ran and
|
|
85
|
+
failed, `gradedLanes.every(...)` was trivially true over the empty array, so a report with zero
|
|
86
|
+
lane evidence could still be read as all-lanes-failed — it now requires at least one actually
|
|
87
|
+
graded lane before returning that verdict.
|
|
88
|
+
- Manual `/model <ref>` had no gate at all, so a model already known (from a stored fitness
|
|
89
|
+
report) to fail on every surface, or a local Ollama model whose weights don't fit in RAM, could
|
|
90
|
+
be set silently and 500 every subsequent turn (llama-server OOM). `AgentSession.setModel` is
|
|
91
|
+
advisory-only here by design — a human's explicit choice is never blocked — but now emits a
|
|
92
|
+
`warning` event (the same plain-text channel print/RPC modes already render, never a prompt)
|
|
93
|
+
when the target has a recorded all-lanes-failed probe on this host, or is an Ollama model whose
|
|
94
|
+
installed size exceeds ~90% of `os.totalmem()`. This advisory now also covers `cycleModel`
|
|
95
|
+
(reachable via the `app.model.cycleForward`/`cycleBackward` keybindings and the RPC
|
|
96
|
+
`cycleModel` call), which previously bypassed it entirely on both the scoped (`--models`) and
|
|
97
|
+
all-available cycle paths, silently landing on a known-bad or OOM-prone model. The Ollama
|
|
98
|
+
size/RAM lookup (and `/models remove`) also missed installed models referenced by a bare tag —
|
|
99
|
+
Ollama's `/api/tags` always reports an explicit tag, defaulting to `:latest`, so an exact-string
|
|
100
|
+
match silently skipped the check whenever a user typed a bare ref (e.g. `llama3` vs. the
|
|
101
|
+
installed `llama3:latest`); both call sites now share one `matchesInstalledLocalModel` helper
|
|
102
|
+
(`core/models/model-ref.ts`) that accounts for the bare/`:latest` pairing.
|
|
103
|
+
- `output-accumulator-io-errors.test.ts`'s `vi.mock("node:fs", ...)` factory returned only the three
|
|
104
|
+
members the test overrides (`closeSync`, `openSync`, `writeSync`), so any other `node:fs` export
|
|
105
|
+
accessed during the run — `existsSync`, read at import time by `@caupulican/pi-ai`'s
|
|
106
|
+
`env-api-keys.ts` — threw inside vitest's mock proxy and surfaced as an unhandled rejection, even
|
|
107
|
+
though the test's own assertions passed. The mock now spreads the real module
|
|
108
|
+
(`importOriginal()`) and overrides only the three functions it needs, so unmocked exports stay
|
|
109
|
+
real.
|
|
110
|
+
- `keyHandlersHost()` snapshotted `editor`, `session`, and `settingsManager` onto the key-handler
|
|
111
|
+
host object at `setupKeyHandlers()`'s one-time init instead of reading them live off `this`. All
|
|
112
|
+
three are swappable after init — `editor` via extension custom editors (`setEditor`, whose
|
|
113
|
+
`onEscape` delegates back through the closures installed on `defaultEditor`), and
|
|
114
|
+
`session`/`settingsManager` via `/reload`'s runtime-host swap — so Escape handling kept reading
|
|
115
|
+
the stale pre-swap objects: Escape could fail to abort bash on a reloaded session, and the
|
|
116
|
+
double-escape `/tree`/`/fork` trigger could read the wrong editor's text. `keyHandlersHost()` now
|
|
117
|
+
exposes `editor`, `session`, and `settingsManager` as live getters over the instance (matching the
|
|
118
|
+
existing `isBashMode`/`lastEscapeTime` accessor pattern); `defaultEditor` and `ui` stay plain
|
|
119
|
+
properties since they're set once and never swapped.
|
|
120
|
+
|
|
121
|
+
## [0.80.103] - 2026-07-03
|
|
122
|
+
|
|
123
|
+
### Fixed
|
|
124
|
+
|
|
125
|
+
- Config-directory override environment variables are now POSIX-valid and actually usable. Because
|
|
126
|
+
`piConfig.name` is `pi-adaptative`, the derived names were `PI-ADAPTATIVE_CODING_AGENT_DIR` and
|
|
127
|
+
`PI-ADAPTATIVE_CODING_AGENT_SESSION_DIR` — but a hyphen is invalid in a shell variable name, so
|
|
128
|
+
`export PI-ADAPTATIVE_CODING_AGENT_DIR=…` is a parse error and the documented override (shown in
|
|
129
|
+
`pi --help`) silently could not be set. The names are now sanitized to
|
|
130
|
+
`PI_ADAPTATIVE_CODING_AGENT_DIR` and `PI_ADAPTATIVE_CODING_AGENT_SESSION_DIR`.
|
|
131
|
+
|
|
1
132
|
## [0.80.102] - 2026-07-03
|
|
2
133
|
|
|
3
134
|
### Fixed
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* TUI session selector for --resume flag
|
|
3
3
|
*/
|
|
4
|
-
import type { SessionInfo, SessionListProgress } from "
|
|
4
|
+
import type { SessionInfo, SessionListProgress } from "@caupulican/pi-agent-core/node";
|
|
5
5
|
type SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;
|
|
6
6
|
/** Show TUI session selector and return selected session path or null if cancelled */
|
|
7
7
|
export declare function selectSession(currentSessionsLoader: SessionsLoader, allSessionsLoader: SessionsLoader): Promise<string | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAKvF,KAAK,cAAc,GAAG,CAAC,UAAU,CAAC,EAAE,mBAAmB,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAEnF,sFAAsF;AACtF,wBAAsB,aAAa,CAClC,qBAAqB,EAAE,cAAc,EACrC,iBAAiB,EAAE,cAAc,GAC/B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoCxB","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport type { SessionInfo, SessionListProgress } from \"@caupulican/pi-agent-core/node\";\nimport { ProcessTerminal, setKeybindings, TUI } from \"@caupulican/pi-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../../src/cli/session-picker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qDAAqD,CAAC;AAI/F,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,qBAAqC,EACrC,iBAAiC,EACR;IACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC;QAC1C,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;QAChD,cAAc,CAAC,WAAW,CAAC,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,wBAAwB,CAC5C,qBAAqB,EACrB,iBAAiB,EACjB,CAAC,IAAY,EAAE,EAAE,CAAC;YACjB,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;gBAChB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,CAAC;YACf,CAAC;QAAA,CACD,EACD,GAAG,EAAE,CAAC;YACL,EAAE,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAA,CAChB,EACD,GAAG,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,EACxB,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,EAAE,CACtC,CAAC;QAEF,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACtB,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,KAAK,EAAE,CAAC;IAAA,CACX,CAAC,CAAC;AAAA,CACH","sourcesContent":["/**\n * TUI session selector for --resume flag\n */\n\nimport type { SessionInfo, SessionListProgress } from \"@caupulican/pi-agent-core/node\";\nimport { ProcessTerminal, setKeybindings, TUI } from \"@caupulican/pi-tui\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { SessionSelectorComponent } from \"../modes/interactive/components/session-selector.ts\";\n\ntype SessionsLoader = (onProgress?: SessionListProgress) => Promise<SessionInfo[]>;\n\n/** Show TUI session selector and return selected session path or null if cancelled */\nexport async function selectSession(\n\tcurrentSessionsLoader: SessionsLoader,\n\tallSessionsLoader: SessionsLoader,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tconst keybindings = KeybindingsManager.create();\n\t\tsetKeybindings(keybindings);\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tcurrentSessionsLoader,\n\t\t\tallSessionsLoader,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tui.stop();\n\t\t\t\tprocess.exit(0);\n\t\t\t},\n\t\t\t() => ui.requestRender(),\n\t\t\t{ showRenameHint: false, keybindings },\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n"]}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n */\nimport { APP_NAME } from \"./config.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\n\nprocess.title = APP_NAME;\nprocess.env.PI_CODING_AGENT = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\n// Configure undici's global dispatcher before provider SDKs issue requests.\n// Runtime settings are applied once SettingsManager has loaded global/project settings.\nconfigureHttpDispatcher();\n\nconst cliArgs = process.argv.slice(2);\nconst [firstArg] = cliArgs;\nconst packageCommands = new Set([\"install\", \"remove\", \"uninstall\", \"update\", \"list\", \"config\"]);\nif ((cliArgs.includes(\"--help\") || cliArgs.includes(\"-h\")) && !packageCommands.has(firstArg ?? \"\")) {\n\tconst [{ parseArgs, printHelp }, { takeOverStdout }] = await Promise.all([\n\t\timport(\"./cli/args.ts\"),\n\t\timport(\"./core/output-guard.ts\"),\n\t]);\n\tconst parsed = parseArgs(cliArgs);\n\tif (parsed.mode === \"json\" || parsed.mode === \"rpc\" || parsed.print || !process.stdin.isTTY) {\n\t\ttakeOverStdout();\n\t}\n\tprintHelp([]);\n\tprocess.exit(0);\n}\n\nconst { main } = await import(\"./main.ts\");\nmain(cliArgs);\n"]}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n */\nimport { APP_NAME, VERSION } from \"./config.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\n\nprocess.title = APP_NAME;\nprocess.env.PI_CODING_AGENT = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\n// Configure undici's global dispatcher before provider SDKs issue requests.\n// Runtime settings are applied once SettingsManager has loaded global/project settings.\nconfigureHttpDispatcher();\n\nconst cliArgs = process.argv.slice(2);\nconst [firstArg] = cliArgs;\nconst packageCommands = new Set([\"install\", \"remove\", \"uninstall\", \"update\", \"list\", \"config\"]);\n\n// Fast path: version needs nothing beyond config.ts (already loaded). Mirrors main.ts's\n// `parsed.version` output exactly; skipping main's import graph turns ~1s into ~150ms.\nif ((firstArg === \"--version\" || firstArg === \"-v\") && cliArgs.length === 1) {\n\tconsole.log(VERSION);\n\tprocess.exit(0);\n}\nif ((cliArgs.includes(\"--help\") || cliArgs.includes(\"-h\")) && !packageCommands.has(firstArg ?? \"\")) {\n\tconst [{ parseArgs, printHelp }, { takeOverStdout }] = await Promise.all([\n\t\timport(\"./cli/args.ts\"),\n\t\timport(\"./core/output-guard.ts\"),\n\t]);\n\tconst parsed = parseArgs(cliArgs);\n\tif (parsed.mode === \"json\" || parsed.mode === \"rpc\" || parsed.print || !process.stdin.isTTY) {\n\t\ttakeOverStdout();\n\t}\n\tprintHelp([]);\n\tprocess.exit(0);\n}\n\nconst { main } = await import(\"./main.ts\");\nmain(cliArgs);\n"]}
|
package/dist/cli.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Test with: npx tsx src/cli-new.ts [args...]
|
|
7
7
|
*/
|
|
8
|
-
import { APP_NAME } from "./config.js";
|
|
8
|
+
import { APP_NAME, VERSION } from "./config.js";
|
|
9
9
|
import { configureHttpDispatcher } from "./core/http-dispatcher.js";
|
|
10
10
|
process.title = APP_NAME;
|
|
11
11
|
process.env.PI_CODING_AGENT = "true";
|
|
@@ -16,6 +16,12 @@ configureHttpDispatcher();
|
|
|
16
16
|
const cliArgs = process.argv.slice(2);
|
|
17
17
|
const [firstArg] = cliArgs;
|
|
18
18
|
const packageCommands = new Set(["install", "remove", "uninstall", "update", "list", "config"]);
|
|
19
|
+
// Fast path: version needs nothing beyond config.ts (already loaded). Mirrors main.ts's
|
|
20
|
+
// `parsed.version` output exactly; skipping main's import graph turns ~1s into ~150ms.
|
|
21
|
+
if ((firstArg === "--version" || firstArg === "-v") && cliArgs.length === 1) {
|
|
22
|
+
console.log(VERSION);
|
|
23
|
+
process.exit(0);
|
|
24
|
+
}
|
|
19
25
|
if ((cliArgs.includes("--help") || cliArgs.includes("-h")) && !packageCommands.has(firstArg ?? "")) {
|
|
20
26
|
const [{ parseArgs, printHelp }, { takeOverStdout }] = await Promise.all([
|
|
21
27
|
import("./cli/args.js"),
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AACH,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC;AACrC,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAA+B,CAAC;AAE/D,4EAA4E;AAC5E,wFAAwF;AACxF,uBAAuB,EAAE,CAAC;AAE1B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;AAC3B,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEhG,wFAAwF;AACxF,uFAAuF;AACvF,IAAI,CAAC,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AACD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;IACpG,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxE,MAAM,CAAC,eAAe,CAAC;QACvB,MAAM,CAAC,wBAAwB,CAAC;KAChC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC7F,cAAc,EAAE,CAAC;IAClB,CAAC;IACD,SAAS,CAAC,EAAE,CAAC,CAAC;IACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC;AAC3C,IAAI,CAAC,OAAO,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\n/**\n * CLI entry point for the refactored coding agent.\n * Uses main.ts with AgentSession and new mode modules.\n *\n * Test with: npx tsx src/cli-new.ts [args...]\n */\nimport { APP_NAME, VERSION } from \"./config.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\n\nprocess.title = APP_NAME;\nprocess.env.PI_CODING_AGENT = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\n// Configure undici's global dispatcher before provider SDKs issue requests.\n// Runtime settings are applied once SettingsManager has loaded global/project settings.\nconfigureHttpDispatcher();\n\nconst cliArgs = process.argv.slice(2);\nconst [firstArg] = cliArgs;\nconst packageCommands = new Set([\"install\", \"remove\", \"uninstall\", \"update\", \"list\", \"config\"]);\n\n// Fast path: version needs nothing beyond config.ts (already loaded). Mirrors main.ts's\n// `parsed.version` output exactly; skipping main's import graph turns ~1s into ~150ms.\nif ((firstArg === \"--version\" || firstArg === \"-v\") && cliArgs.length === 1) {\n\tconsole.log(VERSION);\n\tprocess.exit(0);\n}\nif ((cliArgs.includes(\"--help\") || cliArgs.includes(\"-h\")) && !packageCommands.has(firstArg ?? \"\")) {\n\tconst [{ parseArgs, printHelp }, { takeOverStdout }] = await Promise.all([\n\t\timport(\"./cli/args.ts\"),\n\t\timport(\"./core/output-guard.ts\"),\n\t]);\n\tconst parsed = parseArgs(cliArgs);\n\tif (parsed.mode === \"json\" || parsed.mode === \"rpc\" || parsed.print || !process.stdin.isTTY) {\n\t\ttakeOverStdout();\n\t}\n\tprintHelp([]);\n\tprocess.exit(0);\n}\n\nconst { main } = await import(\"./main.ts\");\nmain(cliArgs);\n"]}
|
package/dist/config.d.ts
CHANGED
|
@@ -78,6 +78,17 @@ export declare const APP_NAME: string;
|
|
|
78
78
|
export declare const APP_TITLE: string;
|
|
79
79
|
export declare const CONFIG_DIR_NAME: string;
|
|
80
80
|
export declare const VERSION: string;
|
|
81
|
+
/**
|
|
82
|
+
* Build a POSIX-valid environment-variable name from an app name and a suffix.
|
|
83
|
+
*
|
|
84
|
+
* APP_NAME comes from `piConfig.name`, which may contain characters that are invalid in a shell
|
|
85
|
+
* env-var name — notably the hyphen in "pi-adaptative". A hyphenated name cannot be exported from
|
|
86
|
+
* a shell (`export PI-ADAPTATIVE_CODING_AGENT_DIR=…` is a parse error), which silently made the
|
|
87
|
+
* documented config-dir override unusable. Uppercase, collapse every character outside [A-Z0-9_]
|
|
88
|
+
* to "_", and prefix "_" if the result would start with a digit (names may not begin with one).
|
|
89
|
+
* e.g. "pi" -> PI_CODING_AGENT_DIR, "pi-adaptative" -> PI_ADAPTATIVE_CODING_AGENT_DIR.
|
|
90
|
+
*/
|
|
91
|
+
export declare function toEnvVarName(appName: string, suffix: string): string;
|
|
81
92
|
export declare const ENV_AGENT_DIR: string;
|
|
82
93
|
export declare const ENV_SESSION_DIR: string;
|
|
83
94
|
export declare function expandTildePath(path: string): string;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,eAAO,MAAM,WAAW,SACqF,CAAC;AAE9G,gEAAgE;AAChE,eAAO,MAAM,YAAY,SAAyB,CAAC;AAMnD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEvF,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAsBD,wBAAgB,mBAAmB,IAAI,aAAa,CAqBnD;AAkND,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,MAAM,CAaR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOhE;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAqBtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,+BAA+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAOhD;AAED,8CAA8C;AAC9C,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAO/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAwBD,eAAO,MAAM,YAAY,EAAE,MAAgD,CAAC;AAC5E,eAAO,MAAM,QAAQ,EAAE,MAA6B,CAAC;AACrD,eAAO,MAAM,SAAS,EAAE,MAAsC,CAAC;AAC/D,eAAO,MAAM,eAAe,EAAE,MAAyC,CAAC;AACxE,eAAO,MAAM,OAAO,EAAE,MAA+B,CAAC;AAGtD,eAAO,MAAM,aAAa,QAA+C,CAAC;AAC1E,eAAO,MAAM,eAAe,QAAuD,CAAC;AAEpF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,0DAA0D;AAC1D,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC","sourcesContent":["import { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst PI_ADAPTATIVE_RELEASES_URL = \"https://github.com/Caupulican/pi-adaptative/releases/latest\";\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\tupdatePackageName,\n\t\t\t\t]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\tupdatePackageName,\n\t\t\t\t]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\tupdatePackageName,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: ${PI_ADAPTATIVE_RELEASES_URL}`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n/**\n * Get path to bundled resources directory (shipped with package).\n * - For Bun binary: bundled-resources/ next to executable\n * - For Node.js (dist/): dist/bundled-resources/\n * - For tsx (src/): src/bundled-resources/\n */\nexport function getBundledResourcesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"bundled-resources\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"bundled-resources\");\n}\n\n/**\n * Get path to bundled skills directory.\n */\nexport function getBundledSkillsDir(): string {\n\treturn join(getBundledResourcesDir(), \"skills\");\n}\n\n/**\n * Get path to bundled prompts directory.\n */\nexport function getBundledPromptsDir(): string {\n\treturn join(getBundledResourcesDir(), \"prompts\");\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@caupulican/pi-adaptative\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n// e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR\nexport const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.pi/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.pi/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to reusable profile definitions directory */\nexport function getProfilesDir(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \"profiles\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,eAAO,MAAM,WAAW,SACqF,CAAC;AAE9G,gEAAgE;AAChE,eAAO,MAAM,YAAY,SAAyB,CAAC;AAMnD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEvF,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAsBD,wBAAgB,mBAAmB,IAAI,aAAa,CAqBnD;AAkND,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,iBAAiB,SAAc,GAC7B,MAAM,CAaR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOhE;AAMD;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAqBtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,+BAA+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAOhD;AAED,8CAA8C;AAC9C,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAO/C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAwBD,eAAO,MAAM,YAAY,EAAE,MAAgD,CAAC;AAC5E,eAAO,MAAM,QAAQ,EAAE,MAA6B,CAAC;AACrD,eAAO,MAAM,SAAS,EAAE,MAAsC,CAAC;AAC/D,eAAO,MAAM,eAAe,EAAE,MAAyC,CAAC;AACxE,eAAO,MAAM,OAAO,EAAE,MAA+B,CAAC;AAEtD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIpE;AAED,eAAO,MAAM,aAAa,QAA6C,CAAC;AACxE,eAAO,MAAM,eAAe,QAAqD,CAAC;AAElF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAID,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGxD;AAMD,0DAA0D;AAC1D,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,yDAAyD;AACzD,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAEvE;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC","sourcesContent":["import { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst PI_ADAPTATIVE_RELEASES_URL = \"https://github.com/Caupulican/pi-adaptative/releases/latest\";\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageName = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\tupdatePackageName,\n\t\t\t\t]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", updatePackageName]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\tupdatePackageName,\n\t\t\t\t]),\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\tupdatePackageName,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\tupdatePackageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\treturn root ? [root, dirname(root)] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tif (method === \"bun-binary\") {\n\t\treturn `Download from: ${PI_ADAPTATIVE_RELEASES_URL}`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageName, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${updatePackageName} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = process.env.PI_PACKAGE_DIR;\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n/**\n * Get path to bundled resources directory (shipped with package).\n * - For Bun binary: bundled-resources/ next to executable\n * - For Node.js (dist/): dist/bundled-resources/\n * - For tsx (src/): src/bundled-resources/\n */\nexport function getBundledResourcesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"bundled-resources\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"bundled-resources\");\n}\n\n/**\n * Get path to bundled skills directory.\n */\nexport function getBundledSkillsDir(): string {\n\treturn join(getBundledResourcesDir(), \"skills\");\n}\n\n/**\n * Get path to bundled prompts directory.\n */\nexport function getBundledPromptsDir(): string {\n\treturn join(getBundledResourcesDir(), \"prompts\");\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"@caupulican/pi-adaptative\";\nexport const APP_NAME: string = piConfigName || \"pi\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".pi\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\n/**\n * Build a POSIX-valid environment-variable name from an app name and a suffix.\n *\n * APP_NAME comes from `piConfig.name`, which may contain characters that are invalid in a shell\n * env-var name — notably the hyphen in \"pi-adaptative\". A hyphenated name cannot be exported from\n * a shell (`export PI-ADAPTATIVE_CODING_AGENT_DIR=…` is a parse error), which silently made the\n * documented config-dir override unusable. Uppercase, collapse every character outside [A-Z0-9_]\n * to \"_\", and prefix \"_\" if the result would start with a digit (names may not begin with one).\n * e.g. \"pi\" -> PI_CODING_AGENT_DIR, \"pi-adaptative\" -> PI_ADAPTATIVE_CODING_AGENT_DIR.\n */\nexport function toEnvVarName(appName: string, suffix: string): string {\n\tconst prefix = appName.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n\tconst safePrefix = /^[0-9]/.test(prefix) ? `_${prefix}` : prefix;\n\treturn `${safePrefix}_${suffix}`;\n}\n\nexport const ENV_AGENT_DIR = toEnvVarName(APP_NAME, \"CODING_AGENT_DIR\");\nexport const ENV_SESSION_DIR = toEnvVarName(APP_NAME, \"CODING_AGENT_SESSION_DIR\");\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\nconst DEFAULT_SHARE_VIEWER_URL = \"https://pi.dev/session/\";\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string {\n\tconst baseUrl = process.env.PI_SHARE_VIEWER_URL || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.pi/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.pi/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json */\nexport function getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to reusable profile definitions directory */\nexport function getProfilesDir(agentDir: string = getAgentDir()): string {\n\treturn join(agentDir, \"profiles\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
|
package/dist/config.js
CHANGED
|
@@ -401,9 +401,23 @@ export const APP_NAME = piConfigName || "pi";
|
|
|
401
401
|
export const APP_TITLE = piConfigName ? APP_NAME : "π";
|
|
402
402
|
export const CONFIG_DIR_NAME = pkg.piConfig?.configDir || ".pi";
|
|
403
403
|
export const VERSION = pkg.version || "0.0.0";
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
404
|
+
/**
|
|
405
|
+
* Build a POSIX-valid environment-variable name from an app name and a suffix.
|
|
406
|
+
*
|
|
407
|
+
* APP_NAME comes from `piConfig.name`, which may contain characters that are invalid in a shell
|
|
408
|
+
* env-var name — notably the hyphen in "pi-adaptative". A hyphenated name cannot be exported from
|
|
409
|
+
* a shell (`export PI-ADAPTATIVE_CODING_AGENT_DIR=…` is a parse error), which silently made the
|
|
410
|
+
* documented config-dir override unusable. Uppercase, collapse every character outside [A-Z0-9_]
|
|
411
|
+
* to "_", and prefix "_" if the result would start with a digit (names may not begin with one).
|
|
412
|
+
* e.g. "pi" -> PI_CODING_AGENT_DIR, "pi-adaptative" -> PI_ADAPTATIVE_CODING_AGENT_DIR.
|
|
413
|
+
*/
|
|
414
|
+
export function toEnvVarName(appName, suffix) {
|
|
415
|
+
const prefix = appName.toUpperCase().replace(/[^A-Z0-9_]/g, "_");
|
|
416
|
+
const safePrefix = /^[0-9]/.test(prefix) ? `_${prefix}` : prefix;
|
|
417
|
+
return `${safePrefix}_${suffix}`;
|
|
418
|
+
}
|
|
419
|
+
export const ENV_AGENT_DIR = toEnvVarName(APP_NAME, "CODING_AGENT_DIR");
|
|
420
|
+
export const ENV_SESSION_DIR = toEnvVarName(APP_NAME, "CODING_AGENT_SESSION_DIR");
|
|
407
421
|
export function expandTildePath(path) {
|
|
408
422
|
return normalizePath(path);
|
|
409
423
|
}
|