@bastani/atomic 0.9.5-alpha.5 → 0.9.5-alpha.7
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 +30 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +6 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-control.ts +8 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +2 -0
- package/dist/builtin/workflows/src/runs/foreground/stage-tool-execution-buffer.ts +47 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-pending-tools.ts +9 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-render-settings.ts +27 -0
- package/dist/builtin/workflows/src/tui/stage-chat-view-state.ts +5 -6
- package/dist/bun/split-loader.d.ts +2 -0
- package/dist/bun/split-loader.d.ts.map +1 -0
- package/dist/bun/split-loader.js +37 -0
- package/dist/bun/split-loader.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +6 -4
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-auto-compaction.d.ts +5 -4
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +15 -9
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +1 -1
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +1 -1
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/builtin-packages.d.ts.map +1 -1
- package/dist/core/builtin-packages.js +8 -4
- package/dist/core/builtin-packages.js.map +1 -1
- package/dist/core/copilot-model-catalog.d.ts.map +1 -1
- package/dist/core/copilot-model-catalog.js +3 -2
- package/dist/core/copilot-model-catalog.js.map +1 -1
- package/dist/core/extensions/loader-core.d.ts.map +1 -1
- package/dist/core/extensions/loader-core.js +6 -0
- package/dist/core/extensions/loader-core.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +8 -3
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/model-resolver-scope.d.ts +9 -0
- package/dist/core/model-resolver-scope.d.ts.map +1 -1
- package/dist/core/model-resolver-scope.js +12 -4
- package/dist/core/model-resolver-scope.js.map +1 -1
- package/dist/core/model-resolver.d.ts +3 -2
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +1 -1
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.d.ts +6 -0
- package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -0
- package/dist/core/openai-responses-payload-sanitizer.js +59 -0
- package/dist/core/openai-responses-payload-sanitizer.js.map +1 -0
- package/dist/core/package-manager-auto-resources.d.ts +2 -2
- package/dist/core/package-manager-auto-resources.d.ts.map +1 -1
- package/dist/core/package-manager-auto-resources.js +32 -52
- package/dist/core/package-manager-auto-resources.js.map +1 -1
- package/dist/core/package-manager-resolver.d.ts.map +1 -1
- package/dist/core/package-manager-resolver.js +23 -14
- package/dist/core/package-manager-resolver.js.map +1 -1
- package/dist/core/package-manager-resource-collector.d.ts +3 -3
- package/dist/core/package-manager-resource-collector.d.ts.map +1 -1
- package/dist/core/package-manager-resource-collector.js +76 -73
- package/dist/core/package-manager-resource-collector.js.map +1 -1
- package/dist/core/package-manager-resource-files.d.ts +9 -8
- package/dist/core/package-manager-resource-files.d.ts.map +1 -1
- package/dist/core/package-manager-resource-files.js +92 -81
- package/dist/core/package-manager-resource-files.js.map +1 -1
- package/dist/core/prompt-templates-async.d.ts +3 -0
- package/dist/core/prompt-templates-async.d.ts.map +1 -0
- package/dist/core/prompt-templates-async.js +118 -0
- package/dist/core/prompt-templates-async.js.map +1 -0
- package/dist/core/provider-context-usage.d.ts +11 -0
- package/dist/core/provider-context-usage.d.ts.map +1 -0
- package/dist/core/provider-context-usage.js +58 -0
- package/dist/core/provider-context-usage.js.map +1 -0
- package/dist/core/resource-loader-assets.d.ts +3 -3
- package/dist/core/resource-loader-assets.d.ts.map +1 -1
- package/dist/core/resource-loader-assets.js +66 -83
- package/dist/core/resource-loader-assets.js.map +1 -1
- package/dist/core/resource-loader-core.d.ts +1 -1
- package/dist/core/resource-loader-core.d.ts.map +1 -1
- package/dist/core/resource-loader-core.js +5 -5
- package/dist/core/resource-loader-core.js.map +1 -1
- package/dist/core/resource-loader-extensions.d.ts.map +1 -1
- package/dist/core/resource-loader-extensions.js +4 -0
- package/dist/core/resource-loader-extensions.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +54 -7
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/resource-loader-types.d.ts +7 -1
- package/dist/core/resource-loader-types.d.ts.map +1 -1
- package/dist/core/resource-loader-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +6 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager-core.d.ts.map +1 -1
- package/dist/core/settings-manager-core.js +3 -2
- package/dist/core/settings-manager-core.js.map +1 -1
- package/dist/core/settings-storage.d.ts.map +1 -1
- package/dist/core/settings-storage.js +2 -1
- package/dist/core/settings-storage.js.map +1 -1
- package/dist/core/skills-async.d.ts +3 -0
- package/dist/core/skills-async.d.ts.map +1 -0
- package/dist/core/skills-async.js +269 -0
- package/dist/core/skills-async.js.map +1 -0
- package/dist/core/trust-manager.d.ts +9 -0
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +44 -2
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main-deferred-startup.d.ts +21 -0
- package/dist/main-deferred-startup.d.ts.map +1 -0
- package/dist/main-deferred-startup.js +23 -0
- package/dist/main-deferred-startup.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +28 -26
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +10 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.d.ts +8 -1
- package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +58 -11
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-editor-actions.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-editor-actions.js +13 -13
- package/dist/modes/interactive/interactive-editor-actions.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-extension-runtime.js +16 -0
- package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +48 -0
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +5 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +5 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +2 -2
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +18 -6
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts +5 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +3 -3
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-onboarding.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-onboarding.js +1 -0
- package/dist/modes/interactive/interactive-onboarding.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +43 -6
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +57 -0
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-resource-disclosure.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-resource-disclosure.js +3 -2
- package/dist/modes/interactive/interactive-resource-disclosure.js.map +1 -1
- package/dist/modes/interactive/interactive-resource-rendering.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-resource-rendering.js +10 -8
- package/dist/modes/interactive/interactive-resource-rendering.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +2 -2
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-session-runtime.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-runtime.js +1 -1
- package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +59 -52
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/theme/theme-loading.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-loading.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-loading.js +3 -0
- package/dist/modes/interactive/theme/theme-loading.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +1 -1
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/utils/child-process.d.ts +8 -1
- package/dist/utils/child-process.d.ts.map +1 -1
- package/dist/utils/child-process.js +39 -6
- package/dist/utils/child-process.js.map +1 -1
- package/dist/utils/event-loop.d.ts +7 -0
- package/dist/utils/event-loop.d.ts.map +1 -0
- package/dist/utils/event-loop.js +14 -0
- package/dist/utils/event-loop.js.map +1 -0
- package/dist/utils/json.d.ts +4 -0
- package/dist/utils/json.d.ts.map +1 -1
- package/dist/utils/json.js +8 -0
- package/dist/utils/json.js.map +1 -1
- package/dist/utils/module-require.d.ts +11 -0
- package/dist/utils/module-require.d.ts.map +1 -1
- package/dist/utils/module-require.js +14 -1
- package/dist/utils/module-require.js.map +1 -1
- package/dist/utils/split-launcher.d.ts +38 -0
- package/dist/utils/split-launcher.d.ts.map +1 -0
- package/dist/utils/split-launcher.js +63 -0
- package/dist/utils/split-launcher.js.map +1 -0
- package/docs/compaction.md +3 -0
- package/docs/keybindings.md +2 -2
- package/docs/providers.md +1 -1
- package/docs/settings.md +5 -1
- package/docs/usage.md +1 -1
- package/docs/workflows.md +1 -1
- package/npm-shrinkwrap.json +23 -23
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.5-alpha.7] - 2026-07-07
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Changed interactive Ctrl+C to interrupt the agent when it is busy: a single Ctrl+C now aborts the running agent turn (restoring queued messages to the editor), a running bash command, an active context compaction, or an auto-retry countdown — matching Escape and common CLI muscle memory. When idle, Ctrl+C keeps its previous behavior (first press clears the editor, a quick double-press exits), and the Ctrl+C immediately following an interrupt clears rather than exits. Escape remains the primary interrupt key.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed a noticeable delay before the working spinner appeared after submitting a prompt: the interactive input loop now mounts the spinner immediately on submit (respecting extension `workingVisible` suppression) and yields once so it paints before prompt preflight — extension input hooks, template/skill expansion, auth and compaction checks, and deferred startup completion — runs. Previously the spinner was created only when the agent emitted `agent_start`, so the status row stayed empty during preflight, making Ctrl+C feel unresponsive until the spinner finally appeared. Submissions that resolve without starting an agent turn (e.g. extension slash-commands) clear the pre-shown spinner when idle so it never lingers.
|
|
14
|
+
- Fixed post-context-compaction provider requests so retained pre-compaction assistant usage is scrubbed from the provider-bound context clone. This keeps durable billing history intact while preventing stale high token counts from shrinking `max_output_tokens` to an invalid one-token budget on the first turn after compaction.
|
|
15
|
+
- Fixed auto-compaction continuation for OpenAI Responses providers by normalizing replayed `function_call.id` values to valid `fc_*` item identifiers while preserving `call_id` pairing. This prevents the opaque `400 {"code":"invalid_request_body"}` failure that could appear immediately after compaction even though a manual `Continue` message succeeded.
|
|
16
|
+
- Fixed auto-compaction stalling after a response reaches the maximum output-token limit: length-stopped assistant turns now compact as incomplete work, remove the truncated assistant from retry context, and automatically continue without requiring the user to type `Continue` ([#1662](https://github.com/bastani-inc/atomic/issues/1662)).
|
|
17
|
+
- Reduced Windows compiled-binary interactive cold-start latency by shipping release archives with a small launcher plus a sidecar app bundle instead of one monolithic executable, and by extending the deferred TUI fast path beyond extension module imports. Normal interactive TTY startup now paints and installs the input loop before bundled package/resource discovery scans skills, prompts, themes, context files, and system-prompt files. Deferred loading now uses async filesystem discovery and async file reads for package resources, skills, prompts, themes, and extension-discovered resources, with cooperative yields so Enter, Ctrl+C, rendering, and the normal prompt spinner remain responsive when a submitted prompt needs resources. Startup no longer shows a resource-loading spinner before the user submits a prompt; explicit resource flags, system-prompt inputs, unknown extension flags, model/provider selection, metadata commands, non-TTY modes, and unresolved project-trust prompts stay on the synchronous path.
|
|
18
|
+
- Fixed Windows compiled-binary keyboard responsiveness by avoiding invisible typeahead buffering in normal interactive startup, keeping terminal input attached to the visible editor, handling Ctrl+C globally with a SIGINT fallback, bounding Ctrl+C shutdown input draining to 250ms, and packaging the Windows console-mode helper used by the TUI for virtual-terminal input.
|
|
19
|
+
- Fixed the Anthropic subscription extra-usage warning racing ahead of the startup `RESOURCES` disclosure on the deferred TUI fast path: the warning is now held until after the resource summary line renders (at deferred-startup completion, agent-end disclosure flushes, or the post-prompt flush), so the `RESOURCES` line always appears first.
|
|
20
|
+
- Fixed deferred-startup TUI chat ordering so `RESOURCES`, changelog, update/package/tmux/subscription startup notices, and queued user prompts render in request order instead of completion order. Startup notices now use a stable block above session messages, queued inputs wait for their later `message_start`, and failed pre-prompt echoes are removed from the chat.
|
|
21
|
+
- Fixed Windows release archives to avoid Bun's `--bytecode` standalone executable startup crash and every runtime path that decodes the split-launcher sidecar's macOS build-machine `import.meta.url` on Windows. Windows binaries remain compiled standalone launchers but now ship the source payload instead of embedded bytecode until Bun's Windows bytecode-alignment fix is available. A centralized split-launcher helper (`ATOMIC_CODING_AGENT` + executable path detection) now resolves package assets, built-in package discovery, and — critically — the jiti resolution base next to `atomic.exe`, so the bundled built-in extensions (`mcp`, `web-access`, `intercom`, `cursor`, `workflows`, `subagents`) all load on Windows instead of failing with `File URL path must be an absolute path`.
|
|
22
|
+
|
|
23
|
+
## [0.9.5-alpha.6] - 2026-07-06
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Fixed deferred TUI extension loading so the editor keeps accepting and echoing keystrokes after first paint: startup now yields cooperatively between extension/resource-loading chunks, preserves text typed during completion, and safely queues Enter submissions made before the main prompt loop is ready.
|
|
28
|
+
- Fixed a warm-start TUI first-paint regression where persisted `enabledModels` or `--models` patterns forced all extensions to load synchronously before the first frame. Interactive startup now keeps the deferred-extension fast path and reapplies the model scope after extensions finish loading, preserving extension-registered provider matches and unmatched-pattern warnings without blocking paint.
|
|
29
|
+
- Fixed project trust prompts for bare projects that only create inert `.atomic/` or `.pi/` state: state-only directories such as `todos/` and `sessions/` no longer count as trust inputs or disable deferred extension startup, while trust-requiring config continues to prompt until the user makes an explicit persistent decision and implicit trust is persisted only by the `/reload` path.
|
|
30
|
+
- Fixed a security regression that could silently persist project trust at shutdown or deferred-startup completion after trust-requiring config appeared mid-session; Atomic now preserves the startup trust prompt unless the user explicitly saves a decision or the existing `/reload` implicit-trust flow applies.
|
|
31
|
+
- Fixed BOM-prefixed JSON state files being treated as parse failures: settings and project trust JSON readers now strip a leading UTF-8 BOM before parsing, so Windows-authored `settings.json` and `trust.json` files load the same as BOM-less files instead of silently ignoring user settings.
|
|
32
|
+
- Fixed the bundled workflows documentation to reflect that attached workflow stage chats render live `subagent` widgets for single, parallel, and chain calls, keep them live across attach/re-attach cycles, and let Ctrl+O expand live detail for every child. ([#1643](https://github.com/bastani-inc/atomic/issues/1643))
|
|
33
|
+
- Fixed a Windows `waitForChildProcess` exit-code race where the process-alive poll could report a fast-dying child as gone before Node emitted the real `exit` event, causing bash commands such as `exit 1` to be reported as successful with a fabricated exit code 0 ([#1647](https://github.com/bastani-inc/atomic/issues/1647)).
|
|
34
|
+
|
|
5
35
|
## [0.9.5-alpha.5] - 2026-07-06
|
|
6
36
|
|
|
7
37
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/cursor",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.7",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Experimental first-party Atomic extension for Cursor OAuth, model discovery, and streaming provider registration.",
|
|
6
6
|
"contributors": [
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@bastani/atomic-natives": "0.9.5-alpha.
|
|
43
|
+
"@bastani/atomic-natives": "0.9.5-alpha.7",
|
|
44
44
|
"@bufbuild/protobuf": "^2.12.1",
|
|
45
45
|
"@earendil-works/pi-ai": "^0.80.3"
|
|
46
46
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.7",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/mcp",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.7",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension that adapts MCP (Model Context Protocol) servers into the coding agent. Fork of: https://github.com/nicobailon/pi-mcp-adapter",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.7",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification. Fork of: https://github.com/nicobailon/pi-subagents",
|
|
6
6
|
"contributors": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.7",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.5-alpha.6] - 2026-07-06
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed workflow stage chats so attach, exit, and re-attach cycles during an in-flight `subagent` call replay the latest live tool partial result immediately instead of collapsing single, parallel, or chain calls back to the bare `renderCall` title until the next update; stage chats also prefer renderers from the stage's own agent session before falling back to the host chat so nested workflow stages can render tools that the parent chat does not expose. ([#1643](https://github.com/bastani-inc/atomic/issues/1643))
|
|
14
|
+
|
|
9
15
|
## [0.9.5-alpha.5] - 2026-07-06
|
|
10
16
|
|
|
11
17
|
### Added
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { StageControlHandle, AgentSessionEventListener } from "./stage-control-registry.js";
|
|
2
2
|
import type { LiveStageRuntime } from "./executor-stage-types.js";
|
|
3
3
|
import { isTerminalStage } from "./executor-scheduler.js";
|
|
4
|
+
import { StageToolExecutionBuffer } from "./stage-tool-execution-buffer.js";
|
|
4
5
|
|
|
5
6
|
export function createStageControlHandle(runtime: LiveStageRuntime): StageControlHandle {
|
|
6
7
|
const ensureMessagingSession = async (): Promise<void> => {
|
|
@@ -15,6 +16,8 @@ export function createStageControlHandle(runtime: LiveStageRuntime): StageContro
|
|
|
15
16
|
throw new Error(`atomic-workflows: cannot message stage "${runtime.name}" because no retained session metadata is available.`);
|
|
16
17
|
}
|
|
17
18
|
};
|
|
19
|
+
const toolExecutions = new StageToolExecutionBuffer();
|
|
20
|
+
const unsubscribeToolExecutions = runtime.innerCtx.subscribe((event) => toolExecutions.record(event));
|
|
18
21
|
|
|
19
22
|
return {
|
|
20
23
|
runId: runtime.runId,
|
|
@@ -41,6 +44,9 @@ export function createStageControlHandle(runtime: LiveStageRuntime): StageContro
|
|
|
41
44
|
get agentSession() {
|
|
42
45
|
return runtime.innerCtx.__agentSession();
|
|
43
46
|
},
|
|
47
|
+
pendingToolExecutionEvents() {
|
|
48
|
+
return toolExecutions.replayEvents();
|
|
49
|
+
},
|
|
44
50
|
async ensureAttached() {
|
|
45
51
|
runtime.throwIfStageMutationBlocked();
|
|
46
52
|
await ensureMessagingSession();
|
|
@@ -120,6 +126,8 @@ export function createStageControlHandle(runtime: LiveStageRuntime): StageContro
|
|
|
120
126
|
return runtime.innerCtx.subscribe(listener);
|
|
121
127
|
},
|
|
122
128
|
async dispose() {
|
|
129
|
+
unsubscribeToolExecutions();
|
|
130
|
+
toolExecutions.clear();
|
|
123
131
|
await runtime.releaseLiveHandle();
|
|
124
132
|
},
|
|
125
133
|
};
|
|
@@ -59,6 +59,8 @@ export interface StageControlHandle {
|
|
|
59
59
|
readonly messages: AgentSession["messages"];
|
|
60
60
|
/** Live coding-agent session when available, used by embedded chat/footer UI. */
|
|
61
61
|
readonly agentSession?: AgentSession;
|
|
62
|
+
/** Replayable in-flight tool starts/partial updates for stage-chat remounts. */
|
|
63
|
+
pendingToolExecutionEvents?(): readonly AgentSessionEvent[];
|
|
62
64
|
/** Ensure the SDK session exists. Cheap when already attached. */
|
|
63
65
|
ensureAttached(): Promise<void>;
|
|
64
66
|
/** Send a prompt. Use only when the stage is idle / not streaming. */
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AgentSessionEvent } from "@bastani/atomic";
|
|
2
|
+
|
|
3
|
+
interface PendingToolExecution {
|
|
4
|
+
start: AgentSessionEvent;
|
|
5
|
+
update?: AgentSessionEvent;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function eventType(event: AgentSessionEvent): string {
|
|
9
|
+
return String((event as { type?: unknown }).type ?? "");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function toolCallId(event: AgentSessionEvent): string | undefined {
|
|
13
|
+
const value = (event as { toolCallId?: unknown }).toolCallId;
|
|
14
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class StageToolExecutionBuffer {
|
|
18
|
+
private readonly pending = new Map<string, PendingToolExecution>();
|
|
19
|
+
|
|
20
|
+
record(event: AgentSessionEvent): void {
|
|
21
|
+
const type = eventType(event);
|
|
22
|
+
if (type === "agent_start" || type === "agent_end") {
|
|
23
|
+
this.pending.clear();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const id = toolCallId(event);
|
|
27
|
+
if (id === undefined) return;
|
|
28
|
+
if (type === "tool_execution_start") {
|
|
29
|
+
this.pending.set(id, { start: event });
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (type === "tool_execution_update") {
|
|
33
|
+
const existing = this.pending.get(id);
|
|
34
|
+
if (existing) existing.update = event;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (type === "tool_execution_end") this.pending.delete(id);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
replayEvents(): readonly AgentSessionEvent[] {
|
|
41
|
+
return [...this.pending.values()].flatMap((entry) => entry.update ? [entry.start, entry.update] : [entry.start]);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
clear(): void {
|
|
45
|
+
this.pending.clear();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentSessionEvent } from "@bastani/atomic";
|
|
2
|
+
import type { StageChatViewContext } from "./stage-chat-view-types.js";
|
|
3
|
+
|
|
4
|
+
export function replayPendingToolExecutions(ctx: StageChatViewContext): void {
|
|
5
|
+
const events = ctx.handle?.isDisposed === true
|
|
6
|
+
? []
|
|
7
|
+
: ctx.handle?.pendingToolExecutionEvents?.() ?? [];
|
|
8
|
+
for (const event of events) ctx.chatHost.applyAgentEvent(event as AgentSessionEvent);
|
|
9
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ChatMessageRenderOptions } from "@bastani/atomic";
|
|
2
|
+
import type { StageChatViewContext, StageChatViewOpts } from "./stage-chat-view-types.js";
|
|
3
|
+
|
|
4
|
+
type StageChatRenderSettings = Partial<Omit<ChatMessageRenderOptions, "ui" | "cwd">>;
|
|
5
|
+
|
|
6
|
+
type MessageRendererHost = {
|
|
7
|
+
extensionRunner?: {
|
|
8
|
+
getMessageRenderer?: (customType: string) => ReturnType<NonNullable<StageChatRenderSettings["getCustomMessageRenderer"]>>;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function stageChatRenderSettings(
|
|
13
|
+
ctx: StageChatViewContext,
|
|
14
|
+
opts: StageChatViewOpts,
|
|
15
|
+
): StageChatRenderSettings | undefined {
|
|
16
|
+
const inherited = opts.getChatRenderSettings?.();
|
|
17
|
+
const stageSession = ctx.handle?.isDisposed === true ? undefined : ctx.handle?.agentSession;
|
|
18
|
+
if (!stageSession) return inherited;
|
|
19
|
+
const rendererHost = stageSession as MessageRendererHost;
|
|
20
|
+
return {
|
|
21
|
+
...inherited,
|
|
22
|
+
getToolDefinition: (toolName) =>
|
|
23
|
+
stageSession.getToolDefinition(toolName) ?? inherited?.getToolDefinition?.(toolName),
|
|
24
|
+
getCustomMessageRenderer: (customType) =>
|
|
25
|
+
rendererHost.extensionRunner?.getMessageRenderer?.(customType) ?? inherited?.getCustomMessageRenderer?.(customType),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -4,11 +4,7 @@ import type { PendingPrompt, RunSnapshot, StageSnapshot } from "../shared/store-
|
|
|
4
4
|
import { stageUiBroker } from "../shared/stage-ui-broker.js";
|
|
5
5
|
import { resolveStageChatViewportRows } from "./stage-chat-layout.js";
|
|
6
6
|
import { createPromptCardState } from "./prompt-card.js";
|
|
7
|
-
import {
|
|
8
|
-
hideMountedCustomUi,
|
|
9
|
-
releaseMountedCustomUi,
|
|
10
|
-
showCustomUi,
|
|
11
|
-
} from "./stage-chat-view-custom-ui.js";
|
|
7
|
+
import { hideMountedCustomUi, releaseMountedCustomUi, showCustomUi } from "./stage-chat-view-custom-ui.js";
|
|
12
8
|
import { editorRuleColor } from "./stage-chat-view-footer-status.js";
|
|
13
9
|
import {
|
|
14
10
|
blankLine,
|
|
@@ -30,6 +26,8 @@ import {
|
|
|
30
26
|
} from "./stage-chat-view-types.js";
|
|
31
27
|
import { noticeRow, noticeSummary } from "./stage-chat-view-transcript.js";
|
|
32
28
|
import { applyStageChatLiveHandleEvent } from "./stage-chat-view-live-events.js";
|
|
29
|
+
import { replayPendingToolExecutions } from "./stage-chat-view-pending-tools.js";
|
|
30
|
+
import { stageChatRenderSettings } from "./stage-chat-view-render-settings.js";
|
|
33
31
|
import { hexToAnsi, RESET } from "./color-utils.js";
|
|
34
32
|
import {
|
|
35
33
|
isTerminalOrNonStreamingStageChatStatus,
|
|
@@ -89,6 +87,7 @@ export function initializeStageChatView(
|
|
|
89
87
|
});
|
|
90
88
|
|
|
91
89
|
snapshotMessagesFromHandle(ctx);
|
|
90
|
+
replayPendingToolExecutions(ctx);
|
|
92
91
|
const initialRun = currentRun(ctx);
|
|
93
92
|
const initialStage = initialRun?.stages.find((s) => s.id === ctx.stageId);
|
|
94
93
|
ctx.lastObservedRunStatus = initialRun?.status;
|
|
@@ -187,7 +186,7 @@ function createChatHost(
|
|
|
187
186
|
keybindings: opts.piKeybindings,
|
|
188
187
|
editorFactory: opts.piEditorFactory,
|
|
189
188
|
editorTheme: editorThemeFromGraphTheme(ctx.theme),
|
|
190
|
-
getChatRenderSettings: opts
|
|
189
|
+
getChatRenderSettings: () => stageChatRenderSettings(ctx, opts),
|
|
191
190
|
footerData: opts.footerData,
|
|
192
191
|
renderExtraEntry: (entry) => noticeRow(entry, ctx.theme),
|
|
193
192
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-loader.d.ts","sourceRoot":"","sources":["../../src/bun/split-loader.ts"],"names":[],"mappings":"","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst APP_NAME = \"atomic\";\n\nprocess.title = APP_NAME;\nprocess.env.ATOMIC_CODING_AGENT = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconst args = process.argv.slice(2);\n\nfunction readVersion(): string {\n\ttry {\n\t\tconst packageJsonPath = join(dirname(process.execPath), \"package.json\");\n\t\tconst pkg = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n\t\treturn typeof pkg.version === \"string\" ? pkg.version : \"0.0.0\";\n\t} catch {\n\t\treturn \"0.0.0\";\n\t}\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(readVersion());\n\tprocess.exit(0);\n}\n\nconst appPath = join(dirname(process.execPath), \"app.js\");\nif (!existsSync(appPath)) {\n\tconsole.error(`Atomic startup error: missing app bundle at ${appPath}`);\n\tprocess.exit(1);\n}\n\nvoid import(pathToFileURL(appPath).href);\n"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import { dirname, join } from "node:path";
|
|
11
|
+
import { pathToFileURL } from "node:url";
|
|
12
|
+
const APP_NAME = "atomic";
|
|
13
|
+
process.title = APP_NAME;
|
|
14
|
+
process.env.ATOMIC_CODING_AGENT = "true";
|
|
15
|
+
process.emitWarning = (() => { });
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
function readVersion() {
|
|
18
|
+
try {
|
|
19
|
+
const packageJsonPath = join(dirname(process.execPath), "package.json");
|
|
20
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
21
|
+
return typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return "0.0.0";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (args[0] === "--version" || args[0] === "-v") {
|
|
28
|
+
console.log(readVersion());
|
|
29
|
+
process.exit(0);
|
|
30
|
+
}
|
|
31
|
+
const appPath = join(dirname(process.execPath), "app.js");
|
|
32
|
+
if (!existsSync(appPath)) {
|
|
33
|
+
console.error(`Atomic startup error: missing app bundle at ${appPath}`);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
void import(__rewriteRelativeImportExtension(pathToFileURL(appPath).href));
|
|
37
|
+
//# sourceMappingURL=split-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"split-loader.js","sourceRoot":"","sources":["../../src/bun/split-loader.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAE1B,OAAO,CAAC,KAAK,GAAG,QAAQ,CAAC;AACzB,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,MAAM,CAAC;AACzC,OAAO,CAAC,WAAW,GAAG,CAAC,GAAG,EAAE,GAAE,CAAC,CAA+B,CAAC;AAE/D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,WAAW;IACnB,IAAI,CAAC;QACJ,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAA0B,CAAC;QACvF,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,OAAO,CAAC;IAChB,CAAC;AACF,CAAC;AAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC1D,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAC,+CAA+C,OAAO,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,KAAK,MAAM,kCAAC,aAAa,CAAC,OAAO,CAAC,CAAC,IAAI,EAAC,CAAC","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst APP_NAME = \"atomic\";\n\nprocess.title = APP_NAME;\nprocess.env.ATOMIC_CODING_AGENT = \"true\";\nprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\nconst args = process.argv.slice(2);\n\nfunction readVersion(): string {\n\ttry {\n\t\tconst packageJsonPath = join(dirname(process.execPath), \"package.json\");\n\t\tconst pkg = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as { version?: unknown };\n\t\treturn typeof pkg.version === \"string\" ? pkg.version : \"0.0.0\";\n\t} catch {\n\t\treturn \"0.0.0\";\n\t}\n}\n\nif (args[0] === \"--version\" || args[0] === \"-v\") {\n\tconsole.log(readVersion());\n\tprocess.exit(0);\n}\n\nconst appPath = join(dirname(process.execPath), \"app.js\");\nif (!existsSync(appPath)) {\n\tconsole.error(`Atomic startup error: missing app bundle at ${appPath}`);\n\tprocess.exit(1);\n}\n\nvoid import(pathToFileURL(appPath).href);\n"]}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getHomeDir, normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\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 */\nconst bunFsMarkers = [\"$bunfs\", \"~BUN\", \"%7EBUN\"];\n// Check process.argv[1] as well as import.meta.url: in a CJS (bytecode) bundle\n// import.meta.url is rewritten to the original source path, but argv[1] still\n// points into Bun's virtual filesystem.\nexport const isBunBinary = [import.meta.url, process.argv[1] ?? \"\"].some((candidate) =>\n\tbunFsMarkers.some((marker) => candidate.includes(marker)),\n);\n\n/**\n * Detect if we're running from a single-file bundle produced by `bun run bundle:dev`.\n * The bundle build inlines this env var via `--define`, so it is a compile-time\n * constant there and undefined everywhere else.\n */\nexport const isBundledBuild = process.env.ATOMIC_BUNDLED_BUILD === \"1\";\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\nimport {\n\tdetectInstallMethodForRuntime,\n\tgetSelfUpdateCommandForRuntime,\n\tgetSelfUpdateUnavailableInstructionForRuntime,\n\tgetUpdateInstructionForRuntime,\n\ttype SelfUpdateRuntime,\n} from \"./config-self-update.ts\";\nexport type { InstallMethod, SelfUpdateCommand } from \"./config-self-update.ts\";\n\nfunction selfUpdateRuntime(): SelfUpdateRuntime {\n\treturn {\n\t\tisBunBinary,\n\t\tisBunRuntime,\n\t\tmoduleDir: __dirname,\n\t\tgetPackageDir,\n\t};\n}\n\nexport function detectInstallMethod(): import(\"./config-self-update.ts\").InstallMethod {\n\treturn detectInstallMethodForRuntime(selfUpdateRuntime());\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): import(\"./config-self-update.ts\").SelfUpdateCommand | undefined {\n\treturn getSelfUpdateCommandForRuntime(selfUpdateRuntime(), packageName, npmCommand, updatePackageName);\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\treturn getSelfUpdateUnavailableInstructionForRuntime(selfUpdateRuntime(), packageName, npmCommand, updatePackageName);\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\treturn getUpdateInstructionForRuntime(selfUpdateRuntime(), 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\t// This runs before package.json app config is read, so the env var name is hardcoded.\n\tconst envDir = process.env.ATOMIC_PACKAGE_DIR ?? 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// App Config (from package.json <appName>Config, with piConfig as a legacy shim)\n// =============================================================================\n\ninterface AppConfig {\n\tname?: string;\n\tconfigDir?: string;\n\tchangelogUrl?: string;\n}\n\ninterface PackageJson extends Record<string, unknown> {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: AppConfig;\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\nfunction appNameFromPackageName(packageName: string | undefined): string | undefined {\n\tconst localName = packageName?.split(\"/\").pop()?.trim();\n\treturn localName && localName.length > 0 ? localName : undefined;\n}\n\nfunction readAppConfig(packageJson: PackageJson, appName: string | undefined): AppConfig | undefined {\n\tif (appName) {\n\t\tconst appConfig = packageJson[`${appName}Config`];\n\t\tif (appConfig && typeof appConfig === \"object\" && !Array.isArray(appConfig)) {\n\t\t\treturn appConfig as AppConfig;\n\t\t}\n\t}\n\treturn packageJson.piConfig;\n}\n\nexport const PACKAGE_NAME: string = pkg.name || \"@bastani/atomic\";\nconst packageAppName = appNameFromPackageName(PACKAGE_NAME);\nconst appConfig = readAppConfig(pkg, packageAppName);\nexport const APP_NAME: string = appConfig?.name || packageAppName || \"pi\";\nexport const APP_TITLE: string = appConfig?.name !== undefined || APP_NAME !== \"pi\" ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = appConfig?.configDir || (APP_NAME === \"pi\" ? \".pi\" : `.${APP_NAME}`);\nexport const LEGACY_CONFIG_DIR_NAME = \".pi\";\nexport const CONFIG_DIR_NAMES: readonly string[] =\n\tCONFIG_DIR_NAME === LEGACY_CONFIG_DIR_NAME ? [CONFIG_DIR_NAME] : [CONFIG_DIR_NAME, LEGACY_CONFIG_DIR_NAME];\nexport const VERSION: string = pkg.version || \"0.0.0\";\nexport const CHANGELOG_URL: string | undefined = appConfig?.changelogUrl?.trim() || undefined;\n\nconst ENV_PREFIX = APP_NAME.toUpperCase();\nexport const LEGACY_ENV_PREFIX = \"PI\";\n\n// e.g., ATOMIC_CODING_AGENT_DIR (with PI_CODING_AGENT_DIR as a compatibility alias)\nexport const ENV_AGENT_DIR = `${ENV_PREFIX}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`;\nexport const ENV_PACKAGE_DIR = `${ENV_PREFIX}_PACKAGE_DIR`;\nexport const ENV_OFFLINE = `${ENV_PREFIX}_OFFLINE`;\nexport const ENV_SKIP_VERSION_CHECK = `${ENV_PREFIX}_SKIP_VERSION_CHECK`;\nexport const ENV_STARTUP_BENCHMARK = `${ENV_PREFIX}_STARTUP_BENCHMARK`;\nexport const ENV_TELEMETRY = `${ENV_PREFIX}_TELEMETRY`;\nexport const ENV_SHARE_VIEWER_URL = `${ENV_PREFIX}_SHARE_VIEWER_URL`;\nexport const ENV_CLEAR_ON_SHRINK = `${ENV_PREFIX}_CLEAR_ON_SHRINK`;\nexport const ENV_HARDWARE_CURSOR = `${ENV_PREFIX}_HARDWARE_CURSOR`;\nexport const ENV_TIMING = `${ENV_PREFIX}_TIMING`;\nexport const ENV_CODEX_FAST_MODE = `${ENV_PREFIX}_CODEX_FAST_MODE`;\nexport const WORKFLOW_STAGE_SUBAGENT_GUARD_ENV = `${ENV_PREFIX}_WORKFLOW_STAGE_SUBAGENT_GUARD`;\n\nexport interface CodexFastModeEnvironmentSettings {\n\tchat?: boolean;\n\tworkflow?: boolean;\n}\n\nfunction parseCodexFastModeEnvBoolean(value: string | undefined): boolean | undefined {\n\tswitch (value?.trim().toLowerCase()) {\n\t\tcase \"1\":\n\t\tcase \"true\":\n\t\tcase \"enabled\":\n\t\tcase \"on\":\n\t\t\treturn true;\n\t\tcase \"0\":\n\t\tcase \"false\":\n\t\tcase \"disabled\":\n\t\tcase \"off\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nexport function serializeCodexFastModeEnvironmentSettings(settings: Required<CodexFastModeEnvironmentSettings>): string {\n\treturn `chat=${settings.chat ? \"1\" : \"0\"};workflow=${settings.workflow ? \"1\" : \"0\"}`;\n}\n\nexport function parseCodexFastModeEnvironmentSettings(value: string | undefined): CodexFastModeEnvironmentSettings | undefined {\n\tif (!value) return undefined;\n\tconst settings: CodexFastModeEnvironmentSettings = {};\n\tfor (const part of value.split(/[;,]/)) {\n\t\tconst separatorIndex = part.indexOf(\"=\");\n\t\tif (separatorIndex === -1) continue;\n\t\tconst key = part.slice(0, separatorIndex).trim();\n\t\tconst parsedValue = parseCodexFastModeEnvBoolean(part.slice(separatorIndex + 1));\n\t\tif (parsedValue === undefined) continue;\n\t\tif (key === \"chat\") settings.chat = parsedValue;\n\t\tif (key === \"workflow\") settings.workflow = parsedValue;\n\t}\n\treturn settings.chat !== undefined || settings.workflow !== undefined ? settings : undefined;\n}\n\nexport function getCodexFastModeEnvironmentSettings(): CodexFastModeEnvironmentSettings | undefined {\n\treturn parseCodexFastModeEnvironmentSettings(getEnvValue(ENV_CODEX_FAST_MODE));\n}\n\nexport function setCodexFastModeEnvironmentSettings(settings: Required<CodexFastModeEnvironmentSettings>): void {\n\tsetEnvValue(ENV_CODEX_FAST_MODE, serializeCodexFastModeEnvironmentSettings(settings));\n}\n\nexport function getEnvNames(name: string): string[] {\n\tif (ENV_PREFIX === LEGACY_ENV_PREFIX || !name.startsWith(`${ENV_PREFIX}_`)) return [name];\n\treturn [name, `${LEGACY_ENV_PREFIX}_${name.slice(ENV_PREFIX.length + 1)}`];\n}\n\nexport function getEnvValue(name: string): string | undefined {\n\tfor (const candidate of getEnvNames(name)) {\n\t\tconst value = process.env[candidate];\n\t\tif (value !== undefined) return value;\n\t}\n\treturn undefined;\n}\n\nexport function hasEnvValue(name: string): boolean {\n\treturn getEnvValue(name) !== undefined;\n}\n\nexport function setEnvValue(name: string, value: string): void {\n\tprocess.env[name] = value;\n}\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 = getEnvValue(ENV_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.atomic/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.atomic/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = getEnvValue(ENV_AGENT_DIR);\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(getHomeDir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the legacy pi agent config directory (e.g., ~/.pi/agent/) */\nexport function getLegacyAgentDir(): string {\n\treturn join(getHomeDir(), LEGACY_CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get agent config directories in precedence order (primary first, then legacy). */\nexport function getAgentDirs(): string[] {\n\tconst primary = getAgentDir();\n\tif (hasEnvValue(ENV_AGENT_DIR) || CONFIG_DIR_NAME === LEGACY_CONFIG_DIR_NAME) {\n\t\treturn [primary];\n\t}\n\tconst legacy = getLegacyAgentDir();\n\treturn legacy === primary ? [primary] : [primary, legacy];\n}\n\n/** Get user config root directories in precedence order (primary first, then legacy). */\nexport function getUserConfigDirs(): string[] {\n\treturn CONFIG_DIR_NAMES.map((name) => join(getHomeDir(), name));\n}\n\n/** Get project config directories in precedence order (primary first, then legacy). */\nexport function getProjectConfigDirs(cwd: string): string[] {\n\treturn CONFIG_DIR_NAMES.map((name) => join(cwd, name));\n}\n\n/** Get a path inside every user config root directory. */\nexport function getUserConfigPaths(...segments: string[]): string[] {\n\treturn getUserConfigDirs().map((dir) => join(dir, ...segments));\n}\n\n/** Get a path inside every agent config directory. */\nexport function getAgentConfigPaths(...segments: string[]): string[] {\n\treturn getAgentDirs().map((dir) => join(dir, ...segments));\n}\n\n/** Get a path inside every project config directory. */\nexport function getProjectConfigPaths(cwd: string, ...segments: string[]): string[] {\n\treturn getProjectConfigDirs(cwd).map((dir) => join(dir, ...segments));\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/**\n * Get path to the extension transpile cache directory (jiti fsCache).\n * Scoped by version so release upgrades never read stale transpiled output.\n */\nexport function getExtensionTranspileCacheDir(): string {\n\treturn join(getAgentDir(), \"cache\", \"jiti\", VERSION);\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\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":"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","sourcesContent":["import { existsSync, readFileSync } from \"fs\";\nimport { dirname, join, resolve } from \"path\";\nimport { getHomeDir, normalizePath } from \"./utils/paths.ts\";\nimport { isSplitLauncherRuntime, moduleFileFromMetaUrl } from \"./utils/split-launcher.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = moduleFileFromMetaUrl(import.meta.url, \"app.js\");\nconst __dirname = dirname(__filename);\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 * Split Windows/macOS/Linux release launchers also set ATOMIC_CODING_AGENT before importing the sidecar app bundle.\n */\nconst bunFsMarkers = [\"$bunfs\", \"~BUN\", \"%7EBUN\"];\n// Check process.argv[1] as well as import.meta.url: in a CJS (bytecode) bundle\n// import.meta.url is rewritten to the original source path, but argv[1] still\n// points into Bun's virtual filesystem.\nexport const isBunBinary = isSplitLauncherRuntime() ||\n\t[import.meta.url, process.argv[1] ?? \"\"].some((candidate) =>\n\t\tbunFsMarkers.some((marker) => candidate.includes(marker)),\n\t);\n\n/**\n * Detect if we're running from a single-file bundle produced by `bun run bundle:dev`.\n * The bundle build inlines this env var via `--define`, so it is a compile-time\n * constant there and undefined everywhere else.\n */\nexport const isBundledBuild = process.env.ATOMIC_BUNDLED_BUILD === \"1\";\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\nimport {\n\tdetectInstallMethodForRuntime,\n\tgetSelfUpdateCommandForRuntime,\n\tgetSelfUpdateUnavailableInstructionForRuntime,\n\tgetUpdateInstructionForRuntime,\n\ttype SelfUpdateRuntime,\n} from \"./config-self-update.ts\";\nexport type { InstallMethod, SelfUpdateCommand } from \"./config-self-update.ts\";\n\nfunction selfUpdateRuntime(): SelfUpdateRuntime {\n\treturn {\n\t\tisBunBinary,\n\t\tisBunRuntime,\n\t\tmoduleDir: __dirname,\n\t\tgetPackageDir,\n\t};\n}\n\nexport function detectInstallMethod(): import(\"./config-self-update.ts\").InstallMethod {\n\treturn detectInstallMethodForRuntime(selfUpdateRuntime());\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): import(\"./config-self-update.ts\").SelfUpdateCommand | undefined {\n\treturn getSelfUpdateCommandForRuntime(selfUpdateRuntime(), packageName, npmCommand, updatePackageName);\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageName = packageName,\n): string {\n\treturn getSelfUpdateUnavailableInstructionForRuntime(selfUpdateRuntime(), packageName, npmCommand, updatePackageName);\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\treturn getUpdateInstructionForRuntime(selfUpdateRuntime(), 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\t// This runs before package.json app config is read, so the env var name is hardcoded.\n\tconst envDir = process.env.ATOMIC_PACKAGE_DIR ?? 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// App Config (from package.json <appName>Config, with piConfig as a legacy shim)\n// =============================================================================\n\ninterface AppConfig {\n\tname?: string;\n\tconfigDir?: string;\n\tchangelogUrl?: string;\n}\n\ninterface PackageJson extends Record<string, unknown> {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: AppConfig;\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\nfunction appNameFromPackageName(packageName: string | undefined): string | undefined {\n\tconst localName = packageName?.split(\"/\").pop()?.trim();\n\treturn localName && localName.length > 0 ? localName : undefined;\n}\n\nfunction readAppConfig(packageJson: PackageJson, appName: string | undefined): AppConfig | undefined {\n\tif (appName) {\n\t\tconst appConfig = packageJson[`${appName}Config`];\n\t\tif (appConfig && typeof appConfig === \"object\" && !Array.isArray(appConfig)) {\n\t\t\treturn appConfig as AppConfig;\n\t\t}\n\t}\n\treturn packageJson.piConfig;\n}\n\nexport const PACKAGE_NAME: string = pkg.name || \"@bastani/atomic\";\nconst packageAppName = appNameFromPackageName(PACKAGE_NAME);\nconst appConfig = readAppConfig(pkg, packageAppName);\nexport const APP_NAME: string = appConfig?.name || packageAppName || \"pi\";\nexport const APP_TITLE: string = appConfig?.name !== undefined || APP_NAME !== \"pi\" ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = appConfig?.configDir || (APP_NAME === \"pi\" ? \".pi\" : `.${APP_NAME}`);\nexport const LEGACY_CONFIG_DIR_NAME = \".pi\";\nexport const CONFIG_DIR_NAMES: readonly string[] =\n\tCONFIG_DIR_NAME === LEGACY_CONFIG_DIR_NAME ? [CONFIG_DIR_NAME] : [CONFIG_DIR_NAME, LEGACY_CONFIG_DIR_NAME];\nexport const VERSION: string = pkg.version || \"0.0.0\";\nexport const CHANGELOG_URL: string | undefined = appConfig?.changelogUrl?.trim() || undefined;\n\nconst ENV_PREFIX = APP_NAME.toUpperCase();\nexport const LEGACY_ENV_PREFIX = \"PI\";\n\n// e.g., ATOMIC_CODING_AGENT_DIR (with PI_CODING_AGENT_DIR as a compatibility alias)\nexport const ENV_AGENT_DIR = `${ENV_PREFIX}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`;\nexport const ENV_PACKAGE_DIR = `${ENV_PREFIX}_PACKAGE_DIR`;\nexport const ENV_OFFLINE = `${ENV_PREFIX}_OFFLINE`;\nexport const ENV_SKIP_VERSION_CHECK = `${ENV_PREFIX}_SKIP_VERSION_CHECK`;\nexport const ENV_STARTUP_BENCHMARK = `${ENV_PREFIX}_STARTUP_BENCHMARK`;\nexport const ENV_TELEMETRY = `${ENV_PREFIX}_TELEMETRY`;\nexport const ENV_SHARE_VIEWER_URL = `${ENV_PREFIX}_SHARE_VIEWER_URL`;\nexport const ENV_CLEAR_ON_SHRINK = `${ENV_PREFIX}_CLEAR_ON_SHRINK`;\nexport const ENV_HARDWARE_CURSOR = `${ENV_PREFIX}_HARDWARE_CURSOR`;\nexport const ENV_TIMING = `${ENV_PREFIX}_TIMING`;\nexport const ENV_CODEX_FAST_MODE = `${ENV_PREFIX}_CODEX_FAST_MODE`;\nexport const WORKFLOW_STAGE_SUBAGENT_GUARD_ENV = `${ENV_PREFIX}_WORKFLOW_STAGE_SUBAGENT_GUARD`;\n\nexport interface CodexFastModeEnvironmentSettings {\n\tchat?: boolean;\n\tworkflow?: boolean;\n}\n\nfunction parseCodexFastModeEnvBoolean(value: string | undefined): boolean | undefined {\n\tswitch (value?.trim().toLowerCase()) {\n\t\tcase \"1\":\n\t\tcase \"true\":\n\t\tcase \"enabled\":\n\t\tcase \"on\":\n\t\t\treturn true;\n\t\tcase \"0\":\n\t\tcase \"false\":\n\t\tcase \"disabled\":\n\t\tcase \"off\":\n\t\t\treturn false;\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nexport function serializeCodexFastModeEnvironmentSettings(settings: Required<CodexFastModeEnvironmentSettings>): string {\n\treturn `chat=${settings.chat ? \"1\" : \"0\"};workflow=${settings.workflow ? \"1\" : \"0\"}`;\n}\n\nexport function parseCodexFastModeEnvironmentSettings(value: string | undefined): CodexFastModeEnvironmentSettings | undefined {\n\tif (!value) return undefined;\n\tconst settings: CodexFastModeEnvironmentSettings = {};\n\tfor (const part of value.split(/[;,]/)) {\n\t\tconst separatorIndex = part.indexOf(\"=\");\n\t\tif (separatorIndex === -1) continue;\n\t\tconst key = part.slice(0, separatorIndex).trim();\n\t\tconst parsedValue = parseCodexFastModeEnvBoolean(part.slice(separatorIndex + 1));\n\t\tif (parsedValue === undefined) continue;\n\t\tif (key === \"chat\") settings.chat = parsedValue;\n\t\tif (key === \"workflow\") settings.workflow = parsedValue;\n\t}\n\treturn settings.chat !== undefined || settings.workflow !== undefined ? settings : undefined;\n}\n\nexport function getCodexFastModeEnvironmentSettings(): CodexFastModeEnvironmentSettings | undefined {\n\treturn parseCodexFastModeEnvironmentSettings(getEnvValue(ENV_CODEX_FAST_MODE));\n}\n\nexport function setCodexFastModeEnvironmentSettings(settings: Required<CodexFastModeEnvironmentSettings>): void {\n\tsetEnvValue(ENV_CODEX_FAST_MODE, serializeCodexFastModeEnvironmentSettings(settings));\n}\n\nexport function getEnvNames(name: string): string[] {\n\tif (ENV_PREFIX === LEGACY_ENV_PREFIX || !name.startsWith(`${ENV_PREFIX}_`)) return [name];\n\treturn [name, `${LEGACY_ENV_PREFIX}_${name.slice(ENV_PREFIX.length + 1)}`];\n}\n\nexport function getEnvValue(name: string): string | undefined {\n\tfor (const candidate of getEnvNames(name)) {\n\t\tconst value = process.env[candidate];\n\t\tif (value !== undefined) return value;\n\t}\n\treturn undefined;\n}\n\nexport function hasEnvValue(name: string): boolean {\n\treturn getEnvValue(name) !== undefined;\n}\n\nexport function setEnvValue(name: string, value: string): void {\n\tprocess.env[name] = value;\n}\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 = getEnvValue(ENV_SHARE_VIEWER_URL) || DEFAULT_SHARE_VIEWER_URL;\n\treturn `${baseUrl}#${gistId}`;\n}\n\n// =============================================================================\n// User Config Paths (~/.atomic/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.atomic/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = getEnvValue(ENV_AGENT_DIR);\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(getHomeDir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get the legacy pi agent config directory (e.g., ~/.pi/agent/) */\nexport function getLegacyAgentDir(): string {\n\treturn join(getHomeDir(), LEGACY_CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get agent config directories in precedence order (primary first, then legacy). */\nexport function getAgentDirs(): string[] {\n\tconst primary = getAgentDir();\n\tif (hasEnvValue(ENV_AGENT_DIR) || CONFIG_DIR_NAME === LEGACY_CONFIG_DIR_NAME) {\n\t\treturn [primary];\n\t}\n\tconst legacy = getLegacyAgentDir();\n\treturn legacy === primary ? [primary] : [primary, legacy];\n}\n\n/** Get user config root directories in precedence order (primary first, then legacy). */\nexport function getUserConfigDirs(): string[] {\n\treturn CONFIG_DIR_NAMES.map((name) => join(getHomeDir(), name));\n}\n\n/** Get project config directories in precedence order (primary first, then legacy). */\nexport function getProjectConfigDirs(cwd: string): string[] {\n\treturn CONFIG_DIR_NAMES.map((name) => join(cwd, name));\n}\n\n/** Get a path inside every user config root directory. */\nexport function getUserConfigPaths(...segments: string[]): string[] {\n\treturn getUserConfigDirs().map((dir) => join(dir, ...segments));\n}\n\n/** Get a path inside every agent config directory. */\nexport function getAgentConfigPaths(...segments: string[]): string[] {\n\treturn getAgentDirs().map((dir) => join(dir, ...segments));\n}\n\n/** Get a path inside every project config directory. */\nexport function getProjectConfigPaths(cwd: string, ...segments: string[]): string[] {\n\treturn getProjectConfigDirs(cwd).map((dir) => join(dir, ...segments));\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/**\n * Get path to the extension transpile cache directory (jiti fsCache).\n * Scoped by version so release upgrades never read stale transpiled output.\n */\nexport function getExtensionTranspileCacheDir(): string {\n\treturn join(getAgentDir(), \"cache\", \"jiti\", VERSION);\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\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
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import { dirname, join, resolve } from "path";
|
|
3
|
-
import { fileURLToPath } from "url";
|
|
4
3
|
import { getHomeDir, normalizePath } from "./utils/paths.js";
|
|
4
|
+
import { isSplitLauncherRuntime, moduleFileFromMetaUrl } from "./utils/split-launcher.js";
|
|
5
5
|
// =============================================================================
|
|
6
6
|
// Package Detection
|
|
7
7
|
// =============================================================================
|
|
8
|
-
const __filename =
|
|
8
|
+
const __filename = moduleFileFromMetaUrl(import.meta.url, "app.js");
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
10
|
/**
|
|
11
11
|
* Detect if we're running as a Bun compiled binary.
|
|
12
|
-
* Bun binaries have import.meta.url containing "$bunfs", "~BUN", or "%7EBUN" (Bun's virtual filesystem path)
|
|
12
|
+
* Bun binaries have import.meta.url containing "$bunfs", "~BUN", or "%7EBUN" (Bun's virtual filesystem path).
|
|
13
|
+
* Split Windows/macOS/Linux release launchers also set ATOMIC_CODING_AGENT before importing the sidecar app bundle.
|
|
13
14
|
*/
|
|
14
15
|
const bunFsMarkers = ["$bunfs", "~BUN", "%7EBUN"];
|
|
15
16
|
// Check process.argv[1] as well as import.meta.url: in a CJS (bytecode) bundle
|
|
16
17
|
// import.meta.url is rewritten to the original source path, but argv[1] still
|
|
17
18
|
// points into Bun's virtual filesystem.
|
|
18
|
-
export const isBunBinary =
|
|
19
|
+
export const isBunBinary = isSplitLauncherRuntime() ||
|
|
20
|
+
[import.meta.url, process.argv[1] ?? ""].some((candidate) => bunFsMarkers.some((marker) => candidate.includes(marker)));
|
|
19
21
|
/**
|
|
20
22
|
* Detect if we're running from a single-file bundle produced by `bun run bundle:dev`.
|
|
21
23
|
* The bundle build inlines this env var via `--define`, so it is a compile-time
|