@bastani/atomic 0.9.25-alpha.4 → 0.9.25
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 +80 -0
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/mcp/CHANGELOG.md +38 -0
- 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 +20 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +18 -3
- package/dist/modes/interactive/interactive-slash-commands.js +23 -8
- package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
- package/docs/sdk.md +1 -1
- package/docs/sessions.md +1 -1
- package/npm-shrinkwrap.json +32 -32
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,86 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.25] - 2026-10-01
|
|
6
|
+
|
|
7
|
+
### Breaking Changes
|
|
8
|
+
|
|
9
|
+
- Replaced the old MCP adapter with the native client. Only `~/.atomic/agent/mcp.json` and trusted `.atomic/mcp.json` are read, using the native configuration shape. Shared config layers, client imports, and old-field translations are no longer supported; old OAuth credentials are not imported.
|
|
10
|
+
- MCP tools now use `mcp__<server>__<tool>` names and default to `codemode` exposure. The old gateway, configurable prefixes, lazy/idle lifecycle settings, metadata cache, SSE transport, MCP Apps rendering, and setup command are removed. Enabled servers connect in the background; `/mcp reconnect` without a name selects one server rather than reconnecting every server.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- MCP servers can set `oauth.authServerMetadataUrl` to a trusted authorization server metadata document when discovery advertises the wrong server or none. See [MCP authentication](docs/mcp-servers.md#override-oauth-authorization-server-discovery) ([#10172](https://github.com/earendil-works/pi/issues/10172)).
|
|
15
|
+
- Added `/mcp login [server]`, command completion, and server selection for login, logout, and reconnect. The manager offers per-server action menus for enabled state and tool exposure, and OAuth sign-in accepts a pasted redirect URL when the browser is on another machine.
|
|
16
|
+
- MCP servers support `codemode`, `deferred`, `direct`, and `hidden` exposure with per-tool pattern overrides, standard resource list/read tools, and per-server OAuth callback ports and URLs. See [MCP servers](docs/mcp-servers.md).
|
|
17
|
+
- Added shell commands `atomic mcp add`, `remove`, `list`, `login`, and `logout` to configure, check, and authenticate file-configured servers without starting a session.
|
|
18
|
+
- SDK hosts can now manage the workflow runs their session owns through `session.workflows`: `listRuns()`, `getRun()`, `getStages()`, `pause()`, `quit()` and `resume()` return the workflow tool's structured results, and failures reject with typed `WorkflowRunControlError` subclasses (`WorkflowRunNotFoundError`, `WorkflowRunOwnershipError`, `WorkflowRunNotResumableError`, `WorkflowRunDatabaseError`, `WorkflowStageNotFoundError`, `WorkflowStageAmbiguousError`, `WorkflowStageResumeUnsupportedError`) instead of strings. A batch `pause({ all: true })` or `quit({ all: true })` returns a `partial` outcome whose `failedRuns` names the runs still active only when that call stopped at least one run, and rejects with `WorkflowRunControlError` carrying `failedRuns` when active runs could not be stopped and the call stopped none, even if other runs were already paused. Already-paused and already-ended runs are not failures. A database outage while checking who owns a run rejects `pause()` and `quit()` with `WorkflowRunDatabaseError`. It uses the same ownership and durable-resume rules as the `workflow` tool, so runs owned by another session or live process stay read-only ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
|
|
19
|
+
- Codemode scripts can retrieve namespace summaries, instructions, and callable tool names with `describeNamespace(name)`. Tool search indexes namespace instructions without including them in inline tool listings, and codemode listings no longer include tool counts ([#10212](https://github.com/earendil-works/pi/issues/10212)).
|
|
20
|
+
- `/reload` enables tools newly added to `defaultTools`, while preserving session-disabled tools, tools removed from the setting, and explicit CLI tool restrictions ([#10245](https://github.com/earendil-works/pi/issues/10245)).
|
|
21
|
+
- Added Anthropic workload identity federation from the `ANTHROPIC_FEDERATION_RULE_ID`, `ANTHROPIC_ORGANIZATION_ID`, and `ANTHROPIC_IDENTITY_TOKEN_FILE` environment variables, with optional `ANTHROPIC_SERVICE_ACCOUNT_ID` and `ANTHROPIC_WORKSPACE_ID`. See [Providers](docs/providers.md#anthropic-workload-identity-federation) ([#10177](https://github.com/earendil-works/pi/issues/10177), [#10242](https://github.com/earendil-works/pi/pull/10242) by [@philfreo](https://github.com/philfreo)).
|
|
22
|
+
- MCP servers can set `oauth.clientName` for dynamic OAuth registration, or use `"auth": { "provider": "<provider>" }` to send the current provider login token. Provider-token authentication is restricted to global configuration and extension registrations, with HTTPS required except on loopback hosts. See [MCP authentication](docs/mcp-servers.md#authentication) ([#10226](https://github.com/earendil-works/pi/issues/10226)).
|
|
23
|
+
- `/login anthropic` now offers **Copy code login (headless)** when the browser is on another machine and cannot reach Atomic's local callback ([#10194](https://github.com/earendil-works/pi/pull/10194) by [@lucasmeijer](https://github.com/lucasmeijer)).
|
|
24
|
+
- Added GPT-6.1 Sol and its first-party Fast variants for OpenAI API keys and ChatGPT Codex subscriptions.
|
|
25
|
+
- Added **Sign in with ChatGPT** for the OpenAI provider, independently of Codex backend login.
|
|
26
|
+
- Added Jev decision models on Vercel AI Gateway and OpenCode Zen.
|
|
27
|
+
- Added configurable fullscreen mouse-wheel scrolling with terminal-aware automatic behavior or a fixed line count.
|
|
28
|
+
- Extension tools can declare exposure, namespaces, annotations and output schemas, and invoke permitted nested tools through the ordinary validation and permission hooks.
|
|
29
|
+
- Added a selectable system theme based on the terminal's palette and contrast, and OKHSL colors for custom themes.
|
|
30
|
+
- Added opt-in `codemode` scripts for composing permitted tools, filtering output, branch-local JSON storage, and classifier calls, plus `tool_search` for activating deferred tools. Interactive and orchestration tools remain unavailable from scripts.
|
|
31
|
+
- Added `builtin:llama.cpp`, `builtin:codemode`, and `builtin:tool-search` extension resources for explicit loading and settings-based enable/disable controls, with diagnostics when an extension replaces codemode or tool search.
|
|
32
|
+
- Added Ultrafast for GPT-6 Astra as `openai/gpt-6-astra-ultrafast` and `openai-codex/gpt-6-astra-ultrafast`, priced at OpenAI's published Ultrafast rates. GPT-6 Astra is the only model with an Ultrafast choice. If the provider rejects an Ultrafast choice you selected, the request fails.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- MCP now uses pi's native client, tool exposure, resources, and server manager. Calls, including codemode calls, pass through Atomic's tool permission pipeline. Native OAuth credentials are stored in `mcp-auth.json`.
|
|
37
|
+
- `defaultTools` now accepts `+name` and `-name` modifiers. Project modifier-only lists adjust the global selection instead of replacing it.
|
|
38
|
+
- Automatic model routing now includes GPT-6.1 Sol results from Artificial Analysis, FrontierCode, and OpenAI's published external benchmarks, preserving measured efforts and independent reporters. Metadata-backed Fast variants use base-model evidence without inventing separate Fast scores; independently registered Fast IDs require their own evidence.
|
|
39
|
+
- Completed `bash` commands now return bounded structured output for programmatic callers, including nonzero exits, without increasing model-facing output limits.
|
|
40
|
+
- Codex's automatic provider default is now GPT-6.1 Sol. Explicit saved model selections remain unchanged.
|
|
41
|
+
- Reduced transcript/footer and shell-preview rendering work in long sessions.
|
|
42
|
+
- Tool previews without custom renderers now show their arguments in collapsed and expanded views.
|
|
43
|
+
- `-fast` and `-ultrafast` choices for OpenAI and Codex models now follow the tiers each model advertises in Codex's catalog and on OpenAI's pricing page. Models without Fast, such as `gpt-5.3-codex-spark`, `openai/gpt-5-nano`, `openai/gpt-5-pro`, and `openai/o1`, no longer list a `-fast` choice. A tier the model doesn't advertise is left out of the request, which runs at standard processing.
|
|
44
|
+
- OpenAI and Codex Fast usage is priced at each model's published Fast rates instead of a flat 2x, for example 1.7x for GPT-4o. A Fast request that OpenAI serves at Standard is priced at Standard.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- `/session` now shows current message counts, token totals, cost, and the correct session ID during an interactive run instead of displaying the previous turn's statistics or zero counts on the first run ([#3383](https://github.com/bastani-inc/atomic/issues/3383)).
|
|
49
|
+
- MCP OAuth rejects authorization responses from another issuer, including a missing `iss` when the server promises it under RFC 9207.
|
|
50
|
+
- MCP OAuth sign-in and refresh now tolerate empty or null optional token and registration fields, and empty requested scopes use the next scope source ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
51
|
+
- MCP sign-out no longer lets an in-progress OAuth refresh restore deleted credentials.
|
|
52
|
+
- Session shutdown now closes MCP connections that are still opening instead of leaving them running after the session ends.
|
|
53
|
+
- Replacing an extension-contributed MCP server now retires pending connections, and reloading with active servers no longer fails during connection cleanup.
|
|
54
|
+
- Malformed MCP configuration errors no longer quote file contents that may contain credentials.
|
|
55
|
+
- MCP OAuth refreshes authorization-server discovery when a server advertises a changed metadata URL.
|
|
56
|
+
- On a heavily loaded machine, a workflow run could fail with a bare `Query read timeout` while Atomic verified its managed PostgreSQL connection, even though the database was healthy. Health queries now get more time (3 s) on every path, and both the check of a borrowed connection and Atomic's periodic background health check repeat once after a timeout. If the timeout persists, the run fails with a resumable database-unavailable error instead of `Query read timeout`, and other running workflows' database connections are not closed and PostgreSQL is not restarted. A refused or terminated connection, a server shutdown, or a changed database identity is still treated as an outage.
|
|
57
|
+
- Renderer examples now retain the built-in tools' prompt guidance and execution behavior when customizing their display ([#10072](https://github.com/earendil-works/pi/issues/10072)).
|
|
58
|
+
- Reduced model lookup overhead when merging large remote provider catalogs.
|
|
59
|
+
- Invalid extension commands now fail registration with a clear error instead of crashing slash-command completion ([#10054](https://github.com/earendil-works/pi/issues/10054)).
|
|
60
|
+
- Codemode and tool-search descriptions now remain unchanged when deferred tools register, preserving prompt stability while discovery continues to find those tools ([#10212](https://github.com/earendil-works/pi/issues/10212)).
|
|
61
|
+
- Collapsed codemode scripts and results now limit wrapped screen lines, so long single-line JSON no longer fills the transcript. Bash previews use the same cached visual-line component.
|
|
62
|
+
- In `codemode.mode: "only"`, the system prompt's tool list no longer advertises tools whose direct declarations are hidden ([#10192](https://github.com/earendil-works/pi/issues/10192)).
|
|
63
|
+
- Fixed context overflow detection for Z.AI CN endpoint `Prompt exceeds max length` errors ([#10208](https://github.com/earendil-works/pi/issues/10208)).
|
|
64
|
+
- Anthropic tools with strict-schema constraints the provider rejects now fall back to non-strict mode when strict sampling is preferred ([#9953](https://github.com/earendil-works/pi/issues/9953)).
|
|
65
|
+
- Provider retries now use exponential backoff when `Retry-After` contains an unparseable date ([#9571](https://github.com/earendil-works/pi/issues/9571)).
|
|
66
|
+
- MCP sign-in URLs remain clickable when they wrap, including inside the `/mcp` panel ([#10186](https://github.com/earendil-works/pi/issues/10186)).
|
|
67
|
+
- MCP tool names now use JavaScript-safe identifiers with deterministic suffixes for collisions and long names, consistently across direct tools, gateway discovery, and codemode ([#10239](https://github.com/earendil-works/pi/issues/10239)).
|
|
68
|
+
- Codemode `image()` now rejects malformed base64 and unsupported image types before saving a tool result, and detects the MIME type from the image data instead of trusting the supplied type ([#10215](https://github.com/earendil-works/pi/issues/10215)).
|
|
69
|
+
- OpenAI's **Sign in with ChatGPT** login now shows a redirect-URL paste input, allowing authentication from remote machines without a reachable local browser callback.
|
|
70
|
+
- SDK-created sessions now discover package-provided workflows from their resource loader, including after workflow reload, while preserving project trust and custom loaders without workflow resources ([#3372](https://github.com/bastani-inc/atomic/issues/3372)).
|
|
71
|
+
- SDK-created sessions now retain package-contributed MCP servers when adding the shipped MCP extension to a custom resource loader ([#3372](https://github.com/bastani-inc/atomic/issues/3372)).
|
|
72
|
+
- Structured decisions and schema-backed workflow results now accept strict-provider null placeholders for omitted optional fields instead of exhausting output repairs. Explicitly nullable fields keep their null values, and required fields still enforce the original schema.
|
|
73
|
+
- Theme-colored notices now refresh after theme changes and late terminal color replies.
|
|
74
|
+
- llama.cpp unloaded autoload presets now retain their cached effective context size instead of falling back to the model's training limit.
|
|
75
|
+
- Native extension providers with stored credentials become available immediately after registration without exposing unrelated unauthenticated models.
|
|
76
|
+
- Cancelled tools no longer start queued native or nested sequential calls after cancellation.
|
|
77
|
+
- The interactive footer's context percentage, token, cost and cache-hit (`CH`) segments update after every message again, instead of only when a run ends. A new session no longer shows `0.0%` with no token or cost segments for its whole first run, and steered or long runs keep the footer current. The footer totals now include cache-warming requests, which `/session` already counts, and RPC `get_session_stats` responses report the newest reply's usage as `latestAssistantUsage` ([#3328](https://github.com/bastani-inc/atomic/issues/3328); [#3364](https://github.com/bastani-inc/atomic/pull/3364) by [@dairefagan](https://github.com/dairefagan)).
|
|
78
|
+
|
|
79
|
+
## [0.9.25-alpha.5] - 2026-09-30
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
|
|
83
|
+
- `/session` now shows current message counts, token totals, cost, and the correct session ID during an interactive run instead of displaying the previous turn's statistics or zero counts on the first run ([#3383](https://github.com/bastani-inc/atomic/issues/3383)).
|
|
84
|
+
|
|
5
85
|
## [0.9.25-alpha.4] - 2026-09-30
|
|
6
86
|
|
|
7
87
|
### Breaking Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.9.25
|
|
3
|
+
"version": "0.9.25",
|
|
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": [
|
|
@@ -7,6 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.25] - 2026-10-01
|
|
11
|
+
|
|
12
|
+
### Breaking Changes
|
|
13
|
+
|
|
14
|
+
- Replaced the old adapter with the native client. Only `~/.atomic/agent/mcp.json` and trusted `.atomic/mcp.json` are read, using the native configuration shape. Shared config layers, client imports, and old-field translations are no longer supported; old OAuth credentials are not imported.
|
|
15
|
+
- Tools now use `mcp__<server>__<tool>` names and default to `codemode` exposure. The old gateway, configurable prefixes, lazy/idle lifecycle settings, metadata cache, SSE transport, MCP Apps rendering, and setup command are removed. Enabled servers connect in the background; `/mcp reconnect` without a name selects one server rather than reconnecting all servers.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- Set `oauth.authServerMetadataUrl` to use a trusted authorization server metadata document instead of discovery when an MCP server advertises the wrong authorization server or none ([#10172](https://github.com/earendil-works/pi/issues/10172)).
|
|
20
|
+
- Added `/mcp login [server]`, completion and optional server selection for login/logout/reconnect, and a server manager with enabled-state and exposure menus. Sign-in accepts pasted remote-browser redirect URLs.
|
|
21
|
+
- Added native tool exposure modes and per-tool patterns, standard resource list/read tools, and per-server OAuth `callbackPort` and `callbackUrl`.
|
|
22
|
+
- Added shell commands `atomic mcp add`, `remove`, `list`, `login`, and `logout` to configure, check, and authenticate file-configured servers without starting a session.
|
|
23
|
+
- Set `oauth.clientName` to choose the client name sent during dynamic OAuth registration. The default is `atomic` ([#10226](https://github.com/earendil-works/pi/issues/10226)).
|
|
24
|
+
- HTTP MCP servers can set `"auth": { "provider": "<provider>" }` to send the current `/login` token of a provider as the bearer token instead of using MCP OAuth. The token is read for every request and is never stored by MCP. It is accepted only from the global `mcp.json` and extension registrations, requires `https` except on `localhost`, `127.0.0.1`, and `[::1]`, and is sent only to the server's origin.
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Adopted pi's native MCP client, tool exposure, resources, and server manager. Calls, including codemode calls, use Atomic's permission pipeline. Native OAuth credentials are stored in `mcp-auth.json`.
|
|
29
|
+
- MCP tool previews now show arguments in collapsed and expanded views while redacting sensitive argument fields.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- OAuth authorization codes are rejected before exchange when the response's `iss` names another issuer, or is missing when the authorization server promises it under RFC 9207.
|
|
34
|
+
- Empty or null optional OAuth token and client registration fields now count as absent. Refresh responses retain the previous refresh token when the new one is empty, and `expires_in: null` no longer immediately expires a token ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
35
|
+
- Empty OAuth scopes fall through to the configured scope instead of overriding it.
|
|
36
|
+
- Tool and resource listing now accepts an empty or null final pagination cursor ([#10266](https://github.com/earendil-works/pi/issues/10266)).
|
|
37
|
+
- Sign-out no longer lets an in-progress OAuth refresh restore deleted credentials.
|
|
38
|
+
- Session shutdown now closes MCP connections that are still opening instead of leaving them running after the session ends.
|
|
39
|
+
- Replacing or unregistering an extension-contributed server now retires its pending connection without leaving a detached transport running.
|
|
40
|
+
- Reloading a session with active MCP servers no longer fails during cleanup of the old connections.
|
|
41
|
+
- OAuth refreshes discovery when a server advertises a changed metadata URL instead of retaining the previous authorization server.
|
|
42
|
+
- MCP sign-in now displays a clickable terminal hyperlink and a Cmd/Ctrl+click hint, including when the authorization URL wraps across lines ([#10186](https://github.com/earendil-works/pi/issues/10186)).
|
|
43
|
+
- MCP tool names now use JavaScript-safe identifiers. Tools whose names sanitize to the same identifier all receive deterministic hash suffixes, preventing codemode calls from reaching the wrong tool. Server names that differ only in `-` and `_` conflict ([#10239](https://github.com/earendil-works/pi/issues/10239)).
|
|
44
|
+
- Cached MCP tools now reconnect after `/login <provider>` when a provider-authenticated server needs sign-in, without requiring `/mcp reconnect`.
|
|
45
|
+
- Concurrent Atomic processes now coordinate rotating OAuth refresh tokens, reusing the refreshed credential rather than independently rotating the same token.
|
|
46
|
+
- Stalled OAuth refresh requests now time out after 15 seconds, including response-body reads, so connection shutdown can finish and release the refresh lock.
|
|
47
|
+
|
|
10
48
|
## [0.9.25-alpha.4] - 2026-09-30
|
|
11
49
|
|
|
12
50
|
### Breaking Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.25
|
|
3
|
+
"version": "0.9.25",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with parallel execution. 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.25
|
|
3
|
+
"version": "0.9.25",
|
|
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,26 @@ 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.25] - 2026-10-01
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `pause`, `quit` and `resume` results from the `workflow` tool now carry a machine-readable `code` (`run_not_found`, `not_resumable`, `owned_elsewhere`, `database_unavailable`, `stage_not_found`, `stage_ambiguous`, `stage_resume_unsupported` or `control_failed`) when the request could not be carried out, so SDK hosts using `session.workflows` receive typed errors. Resuming a run that is executing in another live Atomic process now reports `owned_elsewhere` instead of `not_resumable`. Pausing or quitting, by full run id, a run owned by another session or executing in another live Atomic process now reports `owned_elsewhere` instead of `Run not found`. Pausing or resuming a stage that does not exist or matches several stages, and resuming a single stage of a durable run, now report `stage_not_found`, `stage_ambiguous` or `stage_resume_unsupported` instead of an uncoded no-op ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
|
|
14
|
+
- Added an official-source GPT-6.1 Sol reference to the prompt-engineering skill, with supported-effort migration guidance and selective use of shared templates whose behavior was observed on Astra.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Pausing a run whose only active stage is waiting for human input now marks the run paused instead of rejecting with `no_active_stages`. An already-open question stays open, questions not yet shown wait until resume, and hosts can hold answers until they resume the run ([#3391](https://github.com/bastani-inc/atomic/issues/3391)).
|
|
19
|
+
- `pause` and `quit` with `all: true` no longer report success when some runs could not be stopped. The result is `partial` only when that call stopped at least one run and others are still active, and a `noop` with `control_failed` when active runs could not be stopped and the call stopped none, even if other runs were already paused. Either result lists each failed run id and reason in the message and in a `failedRuns` list. Runs that are already paused or already ended are not failures, and a batch with nothing left to stop is a benign `noop`. `/workflow pause --all` now names runs that failed to pause instead of reporting them as paused or as "No in-flight runs to pause", and reports an error when it stopped no run. Any failure while inspecting the database to pause or quit an unknown full run id now returns a structured `database_unavailable` result instead of throwing or a generic `control_failed` ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
|
|
20
|
+
- On a heavily loaded machine, a workflow run could fail with a bare `Query read timeout` while Atomic verified its managed PostgreSQL connection, even though the database was healthy. Health queries now get more time (3 s) on every path, and both the check of a borrowed connection and Atomic's periodic background health check repeat once after a timeout. If the timeout persists, the run fails with a resumable database-unavailable error instead of `Query read timeout`, and other running workflows' database connections are not closed and PostgreSQL is not restarted. A refused or terminated connection, a server shutdown, or a changed database identity is still treated as an outage.
|
|
21
|
+
- Fixed a workflow run resumed right after it was paused failing with `Workflow database admission timed out`. A pause or resume now waits for the control write already in flight instead of cancelling it mid-write, which could leave the run's database claim stuck and stall every later pause, resume, or quit on that run until the admission timeout ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
|
|
22
|
+
|
|
23
|
+
## [0.9.25-alpha.5] - 2026-09-30
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Pausing a run whose only active stage is waiting for human input now marks the run paused instead of rejecting with `no_active_stages`. An already-open question stays open, questions not yet shown wait until resume, and hosts can hold answers until they resume the run ([#3391](https://github.com/bastani-inc/atomic/issues/3391)).
|
|
28
|
+
|
|
9
29
|
## [0.9.25-alpha.3] - 2026-09-30
|
|
10
30
|
|
|
11
31
|
### Added
|
|
@@ -92555,7 +92555,8 @@ async function pauseRunWithAction(runId, opts, action = "pause") {
|
|
|
92555
92555
|
const toolControls = opts?.toolControlRegistry ?? toolControlRegistry;
|
|
92556
92556
|
const runtimeControls = ownedRuntimeControls(activeStore, toolControls, runId);
|
|
92557
92557
|
const activeRunIds = new Set([...controlRunIds, ...runtimeControls.map(({ controlRunId }) => controlRunId)]);
|
|
92558
|
-
|
|
92558
|
+
const stageHandles = [...activeRunIds].flatMap((id) => registry.run(id).stages());
|
|
92559
|
+
if (runtimeControls.some(({ controlRunId }) => controlRunId === runId) && [...activeRunIds].every((id) => toolControls.active(id).length === 0) && stageHandles.every((handle) => handle.status === "awaiting_input") && (stageHandles.length === 0 || !isRunFullyPaused(activeStore, runId, controlRunIds))) {
|
|
92559
92560
|
await Promise.all(runtimeControls.map(({ handle }) => handle.pause()));
|
|
92560
92561
|
activeStore.recordRunPaused(runId);
|
|
92561
92562
|
return {
|
|
@@ -92565,6 +92566,14 @@ async function pauseRunWithAction(runId, opts, action = "pause") {
|
|
|
92565
92566
|
message: `Run ${runId} paused (${run.controlPersistence ?? "observed"}). ${run.controlPersistence === "durable" ? "Database persistence confirmed." : "Pause observed locally, not confirmed persisted."} Resume with /workflow resume on this live process; untracked initialization or workflow code may still finish, but further workflow steps and completion wait for resume. Cross-process resume requires durable checkpoint or pending prompt progress.`
|
|
92566
92567
|
};
|
|
92567
92568
|
}
|
|
92569
|
+
const controlRuns = activeStore.runs().filter((candidate) => controlRunIds.includes(candidate.id));
|
|
92570
|
+
const waitingRuns = controlRuns.filter((candidate) => candidate.stages.some((stage) => stage.status === "awaiting_input"));
|
|
92571
|
+
if (runtimeControls.length === 0 && waitingRuns.length > 0 && !isRunFullyPaused(activeStore, runId, controlRunIds) && controlRuns.every((candidate) => candidate.stages.every((stage) => stage.status !== "running" && stage.status !== "pending")) && [...activeRunIds].every((id) => toolControls.active(id).length === 0)) {
|
|
92572
|
+
for (const waitingRun of waitingRuns)
|
|
92573
|
+
activeStore.recordRunPaused(waitingRun.id);
|
|
92574
|
+
activeStore.recordRunPaused(runId);
|
|
92575
|
+
return { ok: true, runId, paused: [] };
|
|
92576
|
+
}
|
|
92568
92577
|
return {
|
|
92569
92578
|
ok: false,
|
|
92570
92579
|
runId,
|
|
@@ -116513,7 +116522,7 @@ function bindWorkflowHumanInput(store, ctx, stageUiBroker = currentStageUiBroker
|
|
|
116513
116522
|
return;
|
|
116514
116523
|
const pending = new Set;
|
|
116515
116524
|
for (const run of store.runs()) {
|
|
116516
|
-
if (run.status !== "running")
|
|
116525
|
+
if (run.status !== "running" && run.status !== "paused")
|
|
116517
116526
|
continue;
|
|
116518
116527
|
for (const stage of run.stages) {
|
|
116519
116528
|
if (stage.status !== "awaiting_input")
|
|
@@ -116533,13 +116542,19 @@ function bindWorkflowHumanInput(store, ctx, stageUiBroker = currentStageUiBroker
|
|
|
116533
116542
|
const ownBinding = childInput?.usesOwnBinding() === true;
|
|
116534
116543
|
const input = ownBinding ? workflowInputBridge(childInput.ui) : ownerInput;
|
|
116535
116544
|
const available = ownBinding ? input?.available() : ctx.hasUI === false && ctx.hasHumanInput === true;
|
|
116536
|
-
if (requests.has(key) || !available)
|
|
116545
|
+
if (requests.has(key) || run.status === "paused" || !available)
|
|
116537
116546
|
continue;
|
|
116538
116547
|
const controller = new AbortController;
|
|
116539
116548
|
requests.set(key, { controller, ownBinding });
|
|
116540
116549
|
Promise.resolve().then(async () => {
|
|
116541
116550
|
if (controller.signal.aborted)
|
|
116542
116551
|
return;
|
|
116552
|
+
if (store.runs().find((candidate) => candidate.id === run.id)?.status !== "running") {
|
|
116553
|
+
if (requests.get(key)?.controller === controller)
|
|
116554
|
+
requests.delete(key);
|
|
116555
|
+
controller.abort();
|
|
116556
|
+
return;
|
|
116557
|
+
}
|
|
116543
116558
|
try {
|
|
116544
116559
|
const scoped = input?.scope(run.id, stage.id, questionnaire?.sessionId);
|
|
116545
116560
|
if (questionnaire) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { computeCacheWaste, createCacheMissModelSource } from "../../core/cache-stats.js";
|
|
2
2
|
import { getUsageCostBreakdown } from "../../core/usage-totals.js";
|
|
3
3
|
import { createChildProcessEnvironment } from "../../utils/child-process.js";
|
|
4
|
+
import { getEngineSessionStats } from "../interactive-engine/engine-session-stats.js";
|
|
4
5
|
import { IsolatedInteractiveRuntime } from "../interactive-engine/isolated-runtime.js";
|
|
5
6
|
import { InteractiveModeBase } from "./interactive-mode-base.js";
|
|
6
7
|
import { BorderedLoader, Container, copyToClipboard, DynamicBorder, fs, getChangelogPath, getShareViewerUrl, hyperlink, Markdown, MissingSessionCwdError, normalizeChangelogLinks, os, parseChangelog, path, SessionImportFileNotFoundError, Spacer, setRegisteredThemes, spawn, spawnSync, Text, theme, } from "./interactive-mode-deps.js";
|
|
@@ -287,8 +288,9 @@ InteractiveModeBase.prototype.handleNameCommand = function (text) {
|
|
|
287
288
|
this.ui.requestRender();
|
|
288
289
|
};
|
|
289
290
|
InteractiveModeBase.prototype.handleSessionCommand = function () {
|
|
290
|
-
const
|
|
291
|
-
const
|
|
291
|
+
const engineStats = getEngineSessionStats(this.session);
|
|
292
|
+
const stats = engineStats ?? this.session.getSessionStats();
|
|
293
|
+
const sessionName = this.session.sessionName;
|
|
292
294
|
let info = `${theme.bold("Session Info")}\n\n`;
|
|
293
295
|
if (sessionName) {
|
|
294
296
|
info += `${theme.fg("dim", "Name:")} ${sessionName}\n`;
|
|
@@ -311,13 +313,26 @@ InteractiveModeBase.prototype.handleSessionCommand = function () {
|
|
|
311
313
|
info += `${theme.fg("dim", "Cache Write:")} ${stats.tokens.cacheWrite.toLocaleString()}\n`;
|
|
312
314
|
}
|
|
313
315
|
info += `${theme.fg("dim", "Total:")} ${stats.tokens.total.toLocaleString()}\n`;
|
|
314
|
-
const
|
|
316
|
+
const mirrorStats = engineStats ? this.session.getSessionStats() : stats;
|
|
317
|
+
const mirrorMatchesEngine = mirrorStats.sessionId === stats.sessionId &&
|
|
318
|
+
mirrorStats.totalMessages === stats.totalMessages &&
|
|
319
|
+
mirrorStats.cost === stats.cost &&
|
|
320
|
+
mirrorStats.tokens.input === stats.tokens.input &&
|
|
321
|
+
mirrorStats.tokens.output === stats.tokens.output &&
|
|
322
|
+
mirrorStats.tokens.cacheRead === stats.tokens.cacheRead &&
|
|
323
|
+
mirrorStats.tokens.cacheWrite === stats.tokens.cacheWrite;
|
|
324
|
+
const entries = engineStats && (this.session.isStreaming || !mirrorMatchesEngine) ? [] : this.sessionManager.getEntries();
|
|
315
325
|
const assistantEntries = entries.filter((entry) => entry.type === "message" && entry.message.role === "assistant");
|
|
316
|
-
const promptTokens =
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
326
|
+
const promptTokens = engineStats
|
|
327
|
+
? engineStats.tokens.input + engineStats.tokens.cacheRead + engineStats.tokens.cacheWrite
|
|
328
|
+
: assistantEntries.reduce((sum, entry) => sum +
|
|
329
|
+
(entry.type === "message" && entry.message.role === "assistant"
|
|
330
|
+
? entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite
|
|
331
|
+
: 0), 0);
|
|
332
|
+
const cacheRead = engineStats
|
|
333
|
+
? engineStats.tokens.cacheRead
|
|
334
|
+
: assistantEntries.reduce((sum, entry) => sum +
|
|
335
|
+
(entry.type === "message" && entry.message.role === "assistant" ? entry.message.usage.cacheRead : 0), 0);
|
|
321
336
|
if (promptTokens > 0)
|
|
322
337
|
info += `${theme.fg("dim", "Cache Hit Rate:")} ${((cacheRead / promptTokens) * 100).toFixed(1)}%\n`;
|
|
323
338
|
const waste = computeCacheWaste(entries, createCacheMissModelSource(this.session.modelRuntime));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-slash-commands.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { computeCacheWaste, createCacheMissModelSource } from \"../../core/cache-stats.ts\";\nimport { getUsageCostBreakdown } from \"../../core/usage-totals.ts\";\nimport { createChildProcessEnvironment } from \"../../utils/child-process.ts\";\nimport { IsolatedInteractiveRuntime } from \"../interactive-engine/isolated-runtime.js\";\nimport { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport {\n\tBorderedLoader,\n\ttype Component,\n\tContainer,\n\tcopyToClipboard,\n\tDynamicBorder,\n\tfs,\n\tgetChangelogPath,\n\tgetShareViewerUrl,\n\thyperlink,\n\tMarkdown,\n\tMissingSessionCwdError,\n\tnormalizeChangelogLinks,\n\tos,\n\tparseChangelog,\n\tpath,\n\tSessionImportFileNotFoundError,\n\tSpacer,\n\tsetRegisteredThemes,\n\tspawn,\n\tspawnSync,\n\tText,\n\ttheme,\n} from \"./interactive-mode-deps.ts\";\nimport { isExpandable } from \"./interactive-mode-helpers.ts\";\n\nInteractiveModeBase.prototype.handleReloadCommand = async function (this: InteractiveModeBase): Promise<void> {\n\tif (this.session.isStreaming) {\n\t\tthis.showWarning(\"Wait for the current response to finish before reloading.\");\n\t\treturn;\n\t}\n\tif (this.compactionActive) {\n\t\tthis.showWarning(\"Wait for compaction to finish before reloading.\");\n\t\treturn;\n\t}\n\n\tthis.resetExtensionUI();\n\n\tconst reloadBox = new Container();\n\tconst borderColor = (s: string) => theme.fg(\"border\", s);\n\treloadBox.addChild(new DynamicBorder(borderColor));\n\treloadBox.addChild(new Spacer(1));\n\treloadBox.addChild(\n\t\tnew Text(theme.fg(\"muted\", \"Reloading keybindings, extensions, skills, prompts, themes...\"), 1, 0),\n\t);\n\treloadBox.addChild(new Spacer(1));\n\treloadBox.addChild(new DynamicBorder(borderColor));\n\n\tconst previousEditor = this.editor;\n\tthis.editorContainer.clear();\n\tthis.editorContainer.addChild(reloadBox);\n\tthis.ui.setFocus(reloadBox);\n\tthis.ui.requestRender(true);\n\tawait new Promise((resolve) => process.nextTick(resolve));\n\n\tconst dismissReloadBox = (editor: Component) => {\n\t\tthis.editorContainer.clear();\n\t\tthis.editorContainer.addChild(editor);\n\t\tthis.ui.setFocus(editor);\n\t\tthis.ui.requestRender();\n\t};\n\n\ttry {\n\t\tif (this.runtimeHost instanceof IsolatedInteractiveRuntime) await this.session.reload();\n\t\telse await this.reloadCoordinator.reload(this.session);\n\t\tconst activeHeader = this.customHeader ?? this.builtInHeader;\n\t\tif (isExpandable(activeHeader)) {\n\t\t\tactiveHeader.setExpanded(this.toolOutputExpanded);\n\t\t}\n\t\tsetRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n\t\tthis.applyRuntimeSettings();\n\t\tawait this.themeController.applyFromSettings();\n\t\tthis.setupAutocompleteProvider();\n\t\tconst runner = this.session.extensionRunner;\n\t\tthis.setupExtensionShortcuts(runner);\n\t\tthis.rebuildChatFromMessages({ resetStartupDisclosure: true });\n\t\tdismissReloadBox(this.editor as Component);\n\t\tconst savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();\n\t\tthis.showLoadedResources({\n\t\t\tforce: false,\n\t\t\tshowDiagnosticsWhenQuiet: true,\n\t\t});\n\t\tif (savedImplicitProjectTrust) {\n\t\t\tthis.showStatus(\"Saved project trust for future sessions\");\n\t\t}\n\t\tconst modelsJsonError = this.session.modelRuntime.getError();\n\t\tif (modelsJsonError) {\n\t\t\tthis.showError(`models.json error: ${modelsJsonError}`);\n\t\t}\n\t\tthis.showStatus(\"Reloaded keybindings, extensions, skills, prompts, themes\");\n\t} catch (error) {\n\t\tdismissReloadBox(previousEditor as Component);\n\t\tthis.showError(`Reload failed: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n};\n\nInteractiveModeBase.prototype.handleExportCommand = async function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n): Promise<void> {\n\tconst outputPath = this.getPathCommandArgument(text, \"/export\");\n\n\ttry {\n\t\tif (outputPath?.endsWith(\".jsonl\")) {\n\t\t\tconst filePath = this.session.exportToJsonl(outputPath);\n\t\t\tthis.showStatus(`Session exported to: ${filePath}`);\n\t\t} else {\n\t\t\tconst filePath = await this.session.exportToHtml(outputPath, { themeName: theme.name });\n\t\t\tthis.showStatus(`Session exported to: ${filePath}`);\n\t\t}\n\t} catch (error: unknown) {\n\t\tthis.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n};\n\nInteractiveModeBase.prototype.getPathCommandArgument = function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n\tcommand: \"/export\" | \"/import\",\n): string | undefined {\n\tif (text === command) {\n\t\treturn undefined;\n\t}\n\tif (!text.startsWith(`${command} `)) {\n\t\treturn undefined;\n\t}\n\n\tconst argsString = text.slice(command.length + 1).trimStart();\n\tif (!argsString) {\n\t\treturn undefined;\n\t}\n\n\tconst firstChar = argsString[0];\n\tif (firstChar === '\"' || firstChar === \"'\") {\n\t\tconst closingQuoteIndex = argsString.indexOf(firstChar, 1);\n\t\tif (closingQuoteIndex < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn argsString.slice(1, closingQuoteIndex);\n\t}\n\n\tconst firstWhitespaceIndex = argsString.search(/\\s/);\n\tif (firstWhitespaceIndex < 0) {\n\t\treturn argsString;\n\t}\n\treturn argsString.slice(0, firstWhitespaceIndex);\n};\n\nInteractiveModeBase.prototype.handleImportCommand = async function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n): Promise<void> {\n\tconst inputPath = this.getPathCommandArgument(text, \"/import\");\n\tif (!inputPath) {\n\t\tthis.showError(\"Usage: /import <path.jsonl>\");\n\t\treturn;\n\t}\n\n\tconst confirmed = await this.showExtensionConfirm(\"Import session\", `Replace current session with ${inputPath}?`);\n\tif (!confirmed) {\n\t\tthis.showStatus(\"Import cancelled\");\n\t\treturn;\n\t}\n\n\tconst finishSuccessfulImport = () => {\n\t\tthis.renderCurrentSessionState();\n\t\tif (this.firstRunNoticeVisible) {\n\t\t\tthis.clearFirstRunOnboardingUi();\n\t\t}\n\t\tthis.showStatus(`Session imported from: ${inputPath}`);\n\t};\n\n\ttry {\n\t\tInteractiveModeBase.prototype.clearWorkingLoader.call(this);\n\t\tconst result = await this.runtimeHost.importFromJsonl(inputPath);\n\t\tif (result.cancelled) {\n\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\treturn;\n\t\t}\n\t\tfinishSuccessfulImport();\n\t} catch (error: unknown) {\n\t\tif (error instanceof MissingSessionCwdError) {\n\t\t\tconst selectedCwd = await this.promptForMissingSessionCwd(error);\n\t\t\tif (!selectedCwd) {\n\t\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst result = await this.runtimeHost.importFromJsonl(inputPath, selectedCwd);\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinishSuccessfulImport();\n\t\t\treturn;\n\t\t}\n\t\tif (error instanceof SessionImportFileNotFoundError) {\n\t\t\tthis.showError(`Failed to import session: ${error.message}`);\n\t\t\treturn;\n\t\t}\n\t\tawait this.handleFatalRuntimeError(\"Failed to import session\", error);\n\t}\n};\n\nInteractiveModeBase.prototype.handleShareCommand = async function (this: InteractiveModeBase): Promise<void> {\n\t// Check if gh is available and logged in\n\ttry {\n\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], {\n\t\t\tencoding: \"utf-8\",\n\t\t\tenv: createChildProcessEnvironment(),\n\t\t});\n\t\tif (authResult.status !== 0) {\n\t\t\tthis.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\treturn;\n\t\t}\n\t} catch {\n\t\tthis.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\treturn;\n\t}\n\n\t// Share an export-only JSONL copy carrying context for the viewer. The\n\t// persisted session is not mutated.\n\tconst tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"atomic-share-\"));\n\tconst tmpFile = path.join(tempDir, \"session.jsonl\");\n\ttry {\n\t\tthis.session.exportToJsonl(tmpFile, { includeShareContext: true });\n\t} catch (error: unknown) {\n\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\tthis.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\treturn;\n\t}\n\n\t// Show cancellable loader, replacing the editor\n\tconst loader = new BorderedLoader(this.ui, theme, \"Creating gist...\");\n\tthis.editorContainer.clear();\n\tthis.editorContainer.addChild(loader);\n\tthis.ui.setFocus(loader);\n\tthis.ui.requestRender();\n\n\tconst restoreEditor = () => {\n\t\tloader.dispose();\n\t\tthis.editorContainer.clear();\n\t\tthis.editorContainer.addChild(this.editor);\n\t\tthis.ui.setFocus(this.editor);\n\t\ttry {\n\t\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t};\n\n\t// Create a secret gist asynchronously\n\tlet proc: ReturnType<typeof spawn> | null = null;\n\n\tloader.onAbort = () => {\n\t\tproc?.kill();\n\t\trestoreEditor();\n\t\tthis.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst result = await new Promise<{\n\t\t\tstdout: string;\n\t\t\tstderr: string;\n\t\t\tcode: number | null;\n\t\t}>((resolve) => {\n\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile], { env: createChildProcessEnvironment() });\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\tstderr += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t});\n\n\t\tif (loader.signal.aborted) return;\n\n\t\trestoreEditor();\n\n\t\tif (result.code !== 0) {\n\t\t\tconst errorMsg = result.stderr?.trim() || \"Unknown error\";\n\t\t\tthis.showError(`Failed to create gist: ${errorMsg}`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Extract gist ID from the URL returned by gh\n\t\t// gh returns something like: https://gist.github.com/username/GIST_ID\n\t\tconst gistUrl = result.stdout?.trim();\n\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\tif (!gistId) {\n\t\t\tthis.showError(\"Failed to parse gist ID from gh output\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Create the preview URL\n\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\tthis.showStatus(`Share URL: ${hyperlink(previewUrl, previewUrl)}\\nGist: ${hyperlink(gistUrl, gistUrl)}`);\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor();\n\t\t\tthis.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n};\n\nInteractiveModeBase.prototype.handleCopyCommand = async function (this: InteractiveModeBase): Promise<void> {\n\tconst text = this.session.getLastAssistantText();\n\tif (!text) {\n\t\tthis.showError(\"No agent messages to copy yet.\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tawait copyToClipboard(text);\n\t\tthis.showStatus(\"Copied last agent message to clipboard\");\n\t} catch (error) {\n\t\tthis.showError(error instanceof Error ? error.message : String(error));\n\t}\n};\n\nInteractiveModeBase.prototype.handleNameCommand = function (this: InteractiveModeBase, text: string): void {\n\tconst name = text.replace(/^\\/name\\s*/, \"\").trim();\n\tif (!name) {\n\t\tconst currentName = this.sessionManager.getSessionName();\n\t\tif (currentName) {\n\t\t\tthis.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.chatContainer.addChild(new Text(theme.fg(\"dim\", `Session name: ${currentName}`), 1, 0));\n\t\t} else {\n\t\t\tthis.showWarning(\"Usage: /name <name>\");\n\t\t}\n\t\tthis.ui.requestRender();\n\t\treturn;\n\t}\n\n\tthis.session.setSessionName(name);\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(theme.fg(\"dim\", `Session name set: ${name}`), 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.handleSessionCommand = function (this: InteractiveModeBase): void {\n\tconst stats = this.session.getSessionStats();\n\tconst sessionName = this.sessionManager.getSessionName();\n\n\tlet info = `${theme.bold(\"Session Info\")}\\n\\n`;\n\tif (sessionName) {\n\t\tinfo += `${theme.fg(\"dim\", \"Name:\")} ${sessionName}\\n`;\n\t}\n\tinfo += `${theme.fg(\"dim\", \"File:\")} ${stats.sessionFile ?? \"In-memory\"}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"ID:\")} ${stats.sessionId}\\n\\n`;\n\tinfo += `${theme.bold(\"Messages\")}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"User:\")} ${stats.userMessages}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Assistant:\")} ${stats.assistantMessages}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Tool Calls:\")} ${stats.toolCalls}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Tool Results:\")} ${stats.toolResults}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.totalMessages}\\n\\n`;\n\tinfo += `${theme.bold(\"Tokens\")}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Input:\")} ${stats.tokens.input.toLocaleString()}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Output:\")} ${stats.tokens.output.toLocaleString()}\\n`;\n\tif (stats.tokens.cacheRead > 0) {\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Read:\")} ${stats.tokens.cacheRead.toLocaleString()}\\n`;\n\t}\n\tif (stats.tokens.cacheWrite > 0) {\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Write:\")} ${stats.tokens.cacheWrite.toLocaleString()}\\n`;\n\t}\n\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.tokens.total.toLocaleString()}\\n`;\n\tconst entries = this.sessionManager.getEntries();\n\tconst assistantEntries = entries.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\");\n\tconst promptTokens = assistantEntries.reduce(\n\t\t(sum, entry) =>\n\t\t\tsum +\n\t\t\t(entry.type === \"message\" && entry.message.role === \"assistant\"\n\t\t\t\t? entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite\n\t\t\t\t: 0),\n\t\t0,\n\t);\n\tconst cacheRead = assistantEntries.reduce(\n\t\t(sum, entry) =>\n\t\t\tsum + (entry.type === \"message\" && entry.message.role === \"assistant\" ? entry.message.usage.cacheRead : 0),\n\t\t0,\n\t);\n\tif (promptTokens > 0)\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Hit Rate:\")} ${((cacheRead / promptTokens) * 100).toFixed(1)}%\\n`;\n\tconst waste = computeCacheWaste(entries, createCacheMissModelSource(this.session.modelRuntime));\n\tif (waste.missCount > 0)\n\t\tinfo += `${theme.fg(\"dim\", \"Wasted Cache Cost:\")} $${waste.missedCost.toFixed(4)} (${waste.missCount} misses)\\n`;\n\n\tif (stats.cost > 0) {\n\t\tinfo += `\\n${theme.bold(\"Cost\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.cost.toFixed(4)}`;\n\t\tfor (const item of getUsageCostBreakdown(entries)) {\n\t\t\tinfo += `\\n${theme.fg(\"dim\", `${item.key}:`)} $${item.cost.toFixed(4)}`;\n\t\t}\n\t}\n\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(info, 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.handleChangelogCommand = function (this: InteractiveModeBase): void {\n\tconst changelogPath = getChangelogPath();\n\tconst allEntries = parseChangelog(changelogPath);\n\n\tconst changelogMarkdown =\n\t\tallEntries.length > 0\n\t\t\t? allEntries\n\t\t\t\t\t.reverse()\n\t\t\t\t\t.map((e) => normalizeChangelogLinks(e.content, e))\n\t\t\t\t\t.join(\"\\n\\n\")\n\t\t\t: \"No changelog entries found.\";\n\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new DynamicBorder());\n\tthis.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"What's New\")), 1, 0));\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, this.getMarkdownThemeWithSettings()));\n\tthis.chatContainer.addChild(new DynamicBorder());\n\tthis.ui.requestRender();\n};\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-slash-commands.js","sourceRoot":"","sources":["../../../src/modes/interactive/interactive-slash-commands.ts"],"names":[],"mappings":"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","sourcesContent":["import { computeCacheWaste, createCacheMissModelSource } from \"../../core/cache-stats.ts\";\nimport { getUsageCostBreakdown } from \"../../core/usage-totals.ts\";\nimport { createChildProcessEnvironment } from \"../../utils/child-process.ts\";\nimport { getEngineSessionStats } from \"../interactive-engine/engine-session-stats.js\";\nimport { IsolatedInteractiveRuntime } from \"../interactive-engine/isolated-runtime.js\";\nimport { InteractiveModeBase } from \"./interactive-mode-base.ts\";\nimport {\n\tBorderedLoader,\n\ttype Component,\n\tContainer,\n\tcopyToClipboard,\n\tDynamicBorder,\n\tfs,\n\tgetChangelogPath,\n\tgetShareViewerUrl,\n\thyperlink,\n\tMarkdown,\n\tMissingSessionCwdError,\n\tnormalizeChangelogLinks,\n\tos,\n\tparseChangelog,\n\tpath,\n\tSessionImportFileNotFoundError,\n\tSpacer,\n\tsetRegisteredThemes,\n\tspawn,\n\tspawnSync,\n\tText,\n\ttheme,\n} from \"./interactive-mode-deps.ts\";\nimport { isExpandable } from \"./interactive-mode-helpers.ts\";\n\nInteractiveModeBase.prototype.handleReloadCommand = async function (this: InteractiveModeBase): Promise<void> {\n\tif (this.session.isStreaming) {\n\t\tthis.showWarning(\"Wait for the current response to finish before reloading.\");\n\t\treturn;\n\t}\n\tif (this.compactionActive) {\n\t\tthis.showWarning(\"Wait for compaction to finish before reloading.\");\n\t\treturn;\n\t}\n\n\tthis.resetExtensionUI();\n\n\tconst reloadBox = new Container();\n\tconst borderColor = (s: string) => theme.fg(\"border\", s);\n\treloadBox.addChild(new DynamicBorder(borderColor));\n\treloadBox.addChild(new Spacer(1));\n\treloadBox.addChild(\n\t\tnew Text(theme.fg(\"muted\", \"Reloading keybindings, extensions, skills, prompts, themes...\"), 1, 0),\n\t);\n\treloadBox.addChild(new Spacer(1));\n\treloadBox.addChild(new DynamicBorder(borderColor));\n\n\tconst previousEditor = this.editor;\n\tthis.editorContainer.clear();\n\tthis.editorContainer.addChild(reloadBox);\n\tthis.ui.setFocus(reloadBox);\n\tthis.ui.requestRender(true);\n\tawait new Promise((resolve) => process.nextTick(resolve));\n\n\tconst dismissReloadBox = (editor: Component) => {\n\t\tthis.editorContainer.clear();\n\t\tthis.editorContainer.addChild(editor);\n\t\tthis.ui.setFocus(editor);\n\t\tthis.ui.requestRender();\n\t};\n\n\ttry {\n\t\tif (this.runtimeHost instanceof IsolatedInteractiveRuntime) await this.session.reload();\n\t\telse await this.reloadCoordinator.reload(this.session);\n\t\tconst activeHeader = this.customHeader ?? this.builtInHeader;\n\t\tif (isExpandable(activeHeader)) {\n\t\t\tactiveHeader.setExpanded(this.toolOutputExpanded);\n\t\t}\n\t\tsetRegisteredThemes(this.session.resourceLoader.getThemes().themes);\n\t\tthis.applyRuntimeSettings();\n\t\tawait this.themeController.applyFromSettings();\n\t\tthis.setupAutocompleteProvider();\n\t\tconst runner = this.session.extensionRunner;\n\t\tthis.setupExtensionShortcuts(runner);\n\t\tthis.rebuildChatFromMessages({ resetStartupDisclosure: true });\n\t\tdismissReloadBox(this.editor as Component);\n\t\tconst savedImplicitProjectTrust = this.maybeSaveImplicitProjectTrustAfterReload();\n\t\tthis.showLoadedResources({\n\t\t\tforce: false,\n\t\t\tshowDiagnosticsWhenQuiet: true,\n\t\t});\n\t\tif (savedImplicitProjectTrust) {\n\t\t\tthis.showStatus(\"Saved project trust for future sessions\");\n\t\t}\n\t\tconst modelsJsonError = this.session.modelRuntime.getError();\n\t\tif (modelsJsonError) {\n\t\t\tthis.showError(`models.json error: ${modelsJsonError}`);\n\t\t}\n\t\tthis.showStatus(\"Reloaded keybindings, extensions, skills, prompts, themes\");\n\t} catch (error) {\n\t\tdismissReloadBox(previousEditor as Component);\n\t\tthis.showError(`Reload failed: ${error instanceof Error ? error.message : String(error)}`);\n\t}\n};\n\nInteractiveModeBase.prototype.handleExportCommand = async function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n): Promise<void> {\n\tconst outputPath = this.getPathCommandArgument(text, \"/export\");\n\n\ttry {\n\t\tif (outputPath?.endsWith(\".jsonl\")) {\n\t\t\tconst filePath = this.session.exportToJsonl(outputPath);\n\t\t\tthis.showStatus(`Session exported to: ${filePath}`);\n\t\t} else {\n\t\t\tconst filePath = await this.session.exportToHtml(outputPath, { themeName: theme.name });\n\t\t\tthis.showStatus(`Session exported to: ${filePath}`);\n\t\t}\n\t} catch (error: unknown) {\n\t\tthis.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t}\n};\n\nInteractiveModeBase.prototype.getPathCommandArgument = function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n\tcommand: \"/export\" | \"/import\",\n): string | undefined {\n\tif (text === command) {\n\t\treturn undefined;\n\t}\n\tif (!text.startsWith(`${command} `)) {\n\t\treturn undefined;\n\t}\n\n\tconst argsString = text.slice(command.length + 1).trimStart();\n\tif (!argsString) {\n\t\treturn undefined;\n\t}\n\n\tconst firstChar = argsString[0];\n\tif (firstChar === '\"' || firstChar === \"'\") {\n\t\tconst closingQuoteIndex = argsString.indexOf(firstChar, 1);\n\t\tif (closingQuoteIndex < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn argsString.slice(1, closingQuoteIndex);\n\t}\n\n\tconst firstWhitespaceIndex = argsString.search(/\\s/);\n\tif (firstWhitespaceIndex < 0) {\n\t\treturn argsString;\n\t}\n\treturn argsString.slice(0, firstWhitespaceIndex);\n};\n\nInteractiveModeBase.prototype.handleImportCommand = async function (\n\tthis: InteractiveModeBase,\n\ttext: string,\n): Promise<void> {\n\tconst inputPath = this.getPathCommandArgument(text, \"/import\");\n\tif (!inputPath) {\n\t\tthis.showError(\"Usage: /import <path.jsonl>\");\n\t\treturn;\n\t}\n\n\tconst confirmed = await this.showExtensionConfirm(\"Import session\", `Replace current session with ${inputPath}?`);\n\tif (!confirmed) {\n\t\tthis.showStatus(\"Import cancelled\");\n\t\treturn;\n\t}\n\n\tconst finishSuccessfulImport = () => {\n\t\tthis.renderCurrentSessionState();\n\t\tif (this.firstRunNoticeVisible) {\n\t\t\tthis.clearFirstRunOnboardingUi();\n\t\t}\n\t\tthis.showStatus(`Session imported from: ${inputPath}`);\n\t};\n\n\ttry {\n\t\tInteractiveModeBase.prototype.clearWorkingLoader.call(this);\n\t\tconst result = await this.runtimeHost.importFromJsonl(inputPath);\n\t\tif (result.cancelled) {\n\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\treturn;\n\t\t}\n\t\tfinishSuccessfulImport();\n\t} catch (error: unknown) {\n\t\tif (error instanceof MissingSessionCwdError) {\n\t\t\tconst selectedCwd = await this.promptForMissingSessionCwd(error);\n\t\t\tif (!selectedCwd) {\n\t\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst result = await this.runtimeHost.importFromJsonl(inputPath, selectedCwd);\n\t\t\tif (result.cancelled) {\n\t\t\t\tthis.showStatus(\"Import cancelled\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinishSuccessfulImport();\n\t\t\treturn;\n\t\t}\n\t\tif (error instanceof SessionImportFileNotFoundError) {\n\t\t\tthis.showError(`Failed to import session: ${error.message}`);\n\t\t\treturn;\n\t\t}\n\t\tawait this.handleFatalRuntimeError(\"Failed to import session\", error);\n\t}\n};\n\nInteractiveModeBase.prototype.handleShareCommand = async function (this: InteractiveModeBase): Promise<void> {\n\t// Check if gh is available and logged in\n\ttry {\n\t\tconst authResult = spawnSync(\"gh\", [\"auth\", \"status\"], {\n\t\t\tencoding: \"utf-8\",\n\t\t\tenv: createChildProcessEnvironment(),\n\t\t});\n\t\tif (authResult.status !== 0) {\n\t\t\tthis.showError(\"GitHub CLI is not logged in. Run 'gh auth login' first.\");\n\t\t\treturn;\n\t\t}\n\t} catch {\n\t\tthis.showError(\"GitHub CLI (gh) is not installed. Install it from https://cli.github.com/\");\n\t\treturn;\n\t}\n\n\t// Share an export-only JSONL copy carrying context for the viewer. The\n\t// persisted session is not mutated.\n\tconst tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"atomic-share-\"));\n\tconst tmpFile = path.join(tempDir, \"session.jsonl\");\n\ttry {\n\t\tthis.session.exportToJsonl(tmpFile, { includeShareContext: true });\n\t} catch (error: unknown) {\n\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\tthis.showError(`Failed to export session: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\treturn;\n\t}\n\n\t// Show cancellable loader, replacing the editor\n\tconst loader = new BorderedLoader(this.ui, theme, \"Creating gist...\");\n\tthis.editorContainer.clear();\n\tthis.editorContainer.addChild(loader);\n\tthis.ui.setFocus(loader);\n\tthis.ui.requestRender();\n\n\tconst restoreEditor = () => {\n\t\tloader.dispose();\n\t\tthis.editorContainer.clear();\n\t\tthis.editorContainer.addChild(this.editor);\n\t\tthis.ui.setFocus(this.editor);\n\t\ttry {\n\t\t\tfs.rmSync(tempDir, { recursive: true, force: true });\n\t\t} catch {\n\t\t\t// Ignore cleanup errors\n\t\t}\n\t};\n\n\t// Create a secret gist asynchronously\n\tlet proc: ReturnType<typeof spawn> | null = null;\n\n\tloader.onAbort = () => {\n\t\tproc?.kill();\n\t\trestoreEditor();\n\t\tthis.showStatus(\"Share cancelled\");\n\t};\n\n\ttry {\n\t\tconst result = await new Promise<{\n\t\t\tstdout: string;\n\t\t\tstderr: string;\n\t\t\tcode: number | null;\n\t\t}>((resolve) => {\n\t\t\tproc = spawn(\"gh\", [\"gist\", \"create\", \"--public=false\", tmpFile], { env: createChildProcessEnvironment() });\n\t\t\tlet stdout = \"\";\n\t\t\tlet stderr = \"\";\n\t\t\tproc.stdout?.on(\"data\", (data) => {\n\t\t\t\tstdout += data.toString();\n\t\t\t});\n\t\t\tproc.stderr?.on(\"data\", (data) => {\n\t\t\t\tstderr += data.toString();\n\t\t\t});\n\t\t\tproc.on(\"close\", (code) => resolve({ stdout, stderr, code }));\n\t\t});\n\n\t\tif (loader.signal.aborted) return;\n\n\t\trestoreEditor();\n\n\t\tif (result.code !== 0) {\n\t\t\tconst errorMsg = result.stderr?.trim() || \"Unknown error\";\n\t\t\tthis.showError(`Failed to create gist: ${errorMsg}`);\n\t\t\treturn;\n\t\t}\n\n\t\t// Extract gist ID from the URL returned by gh\n\t\t// gh returns something like: https://gist.github.com/username/GIST_ID\n\t\tconst gistUrl = result.stdout?.trim();\n\t\tconst gistId = gistUrl?.split(\"/\").pop();\n\t\tif (!gistId) {\n\t\t\tthis.showError(\"Failed to parse gist ID from gh output\");\n\t\t\treturn;\n\t\t}\n\n\t\t// Create the preview URL\n\t\tconst previewUrl = getShareViewerUrl(gistId);\n\t\tthis.showStatus(`Share URL: ${hyperlink(previewUrl, previewUrl)}\\nGist: ${hyperlink(gistUrl, gistUrl)}`);\n\t} catch (error: unknown) {\n\t\tif (!loader.signal.aborted) {\n\t\t\trestoreEditor();\n\t\t\tthis.showError(`Failed to create gist: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\t}\n};\n\nInteractiveModeBase.prototype.handleCopyCommand = async function (this: InteractiveModeBase): Promise<void> {\n\tconst text = this.session.getLastAssistantText();\n\tif (!text) {\n\t\tthis.showError(\"No agent messages to copy yet.\");\n\t\treturn;\n\t}\n\n\ttry {\n\t\tawait copyToClipboard(text);\n\t\tthis.showStatus(\"Copied last agent message to clipboard\");\n\t} catch (error) {\n\t\tthis.showError(error instanceof Error ? error.message : String(error));\n\t}\n};\n\nInteractiveModeBase.prototype.handleNameCommand = function (this: InteractiveModeBase, text: string): void {\n\tconst name = text.replace(/^\\/name\\s*/, \"\").trim();\n\tif (!name) {\n\t\tconst currentName = this.sessionManager.getSessionName();\n\t\tif (currentName) {\n\t\t\tthis.chatContainer.addChild(new Spacer(1));\n\t\t\tthis.chatContainer.addChild(new Text(theme.fg(\"dim\", `Session name: ${currentName}`), 1, 0));\n\t\t} else {\n\t\t\tthis.showWarning(\"Usage: /name <name>\");\n\t\t}\n\t\tthis.ui.requestRender();\n\t\treturn;\n\t}\n\n\tthis.session.setSessionName(name);\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(theme.fg(\"dim\", `Session name set: ${name}`), 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.handleSessionCommand = function (this: InteractiveModeBase): void {\n\tconst engineStats = getEngineSessionStats(this.session);\n\tconst stats = engineStats ?? this.session.getSessionStats();\n\tconst sessionName = this.session.sessionName;\n\n\tlet info = `${theme.bold(\"Session Info\")}\\n\\n`;\n\tif (sessionName) {\n\t\tinfo += `${theme.fg(\"dim\", \"Name:\")} ${sessionName}\\n`;\n\t}\n\tinfo += `${theme.fg(\"dim\", \"File:\")} ${stats.sessionFile ?? \"In-memory\"}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"ID:\")} ${stats.sessionId}\\n\\n`;\n\tinfo += `${theme.bold(\"Messages\")}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"User:\")} ${stats.userMessages}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Assistant:\")} ${stats.assistantMessages}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Tool Calls:\")} ${stats.toolCalls}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Tool Results:\")} ${stats.toolResults}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.totalMessages}\\n\\n`;\n\tinfo += `${theme.bold(\"Tokens\")}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Input:\")} ${stats.tokens.input.toLocaleString()}\\n`;\n\tinfo += `${theme.fg(\"dim\", \"Output:\")} ${stats.tokens.output.toLocaleString()}\\n`;\n\tif (stats.tokens.cacheRead > 0) {\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Read:\")} ${stats.tokens.cacheRead.toLocaleString()}\\n`;\n\t}\n\tif (stats.tokens.cacheWrite > 0) {\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Write:\")} ${stats.tokens.cacheWrite.toLocaleString()}\\n`;\n\t}\n\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.tokens.total.toLocaleString()}\\n`;\n\tconst mirrorStats = engineStats ? this.session.getSessionStats() : stats;\n\tconst mirrorMatchesEngine =\n\t\tmirrorStats.sessionId === stats.sessionId &&\n\t\tmirrorStats.totalMessages === stats.totalMessages &&\n\t\tmirrorStats.cost === stats.cost &&\n\t\tmirrorStats.tokens.input === stats.tokens.input &&\n\t\tmirrorStats.tokens.output === stats.tokens.output &&\n\t\tmirrorStats.tokens.cacheRead === stats.tokens.cacheRead &&\n\t\tmirrorStats.tokens.cacheWrite === stats.tokens.cacheWrite;\n\tconst entries =\n\t\tengineStats && (this.session.isStreaming || !mirrorMatchesEngine) ? [] : this.sessionManager.getEntries();\n\tconst assistantEntries = entries.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\");\n\tconst promptTokens = engineStats\n\t\t? engineStats.tokens.input + engineStats.tokens.cacheRead + engineStats.tokens.cacheWrite\n\t\t: assistantEntries.reduce(\n\t\t\t\t(sum, entry) =>\n\t\t\t\t\tsum +\n\t\t\t\t\t(entry.type === \"message\" && entry.message.role === \"assistant\"\n\t\t\t\t\t\t? entry.message.usage.input + entry.message.usage.cacheRead + entry.message.usage.cacheWrite\n\t\t\t\t\t\t: 0),\n\t\t\t\t0,\n\t\t\t);\n\tconst cacheRead = engineStats\n\t\t? engineStats.tokens.cacheRead\n\t\t: assistantEntries.reduce(\n\t\t\t\t(sum, entry) =>\n\t\t\t\t\tsum +\n\t\t\t\t\t(entry.type === \"message\" && entry.message.role === \"assistant\" ? entry.message.usage.cacheRead : 0),\n\t\t\t\t0,\n\t\t\t);\n\tif (promptTokens > 0)\n\t\tinfo += `${theme.fg(\"dim\", \"Cache Hit Rate:\")} ${((cacheRead / promptTokens) * 100).toFixed(1)}%\\n`;\n\tconst waste = computeCacheWaste(entries, createCacheMissModelSource(this.session.modelRuntime));\n\tif (waste.missCount > 0)\n\t\tinfo += `${theme.fg(\"dim\", \"Wasted Cache Cost:\")} $${waste.missedCost.toFixed(4)} (${waste.missCount} misses)\\n`;\n\n\tif (stats.cost > 0) {\n\t\tinfo += `\\n${theme.bold(\"Cost\")}\\n`;\n\t\tinfo += `${theme.fg(\"dim\", \"Total:\")} ${stats.cost.toFixed(4)}`;\n\t\tfor (const item of getUsageCostBreakdown(entries)) {\n\t\t\tinfo += `\\n${theme.fg(\"dim\", `${item.key}:`)} $${item.cost.toFixed(4)}`;\n\t\t}\n\t}\n\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Text(info, 1, 0));\n\tthis.ui.requestRender();\n};\n\nInteractiveModeBase.prototype.handleChangelogCommand = function (this: InteractiveModeBase): void {\n\tconst changelogPath = getChangelogPath();\n\tconst allEntries = parseChangelog(changelogPath);\n\n\tconst changelogMarkdown =\n\t\tallEntries.length > 0\n\t\t\t? allEntries\n\t\t\t\t\t.reverse()\n\t\t\t\t\t.map((e) => normalizeChangelogLinks(e.content, e))\n\t\t\t\t\t.join(\"\\n\\n\")\n\t\t\t: \"No changelog entries found.\";\n\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new DynamicBorder());\n\tthis.chatContainer.addChild(new Text(theme.bold(theme.fg(\"accent\", \"What's New\")), 1, 0));\n\tthis.chatContainer.addChild(new Spacer(1));\n\tthis.chatContainer.addChild(new Markdown(changelogMarkdown, 1, 1, this.getMarkdownThemeWithSettings()));\n\tthis.chatContainer.addChild(new DynamicBorder());\n\tthis.ui.requestRender();\n};\n"]}
|
package/docs/sdk.md
CHANGED
|
@@ -244,7 +244,7 @@ interface SessionWorkflows {
|
|
|
244
244
|
|
|
245
245
|
`listRuns()` returns the same per-run data as `workflow status`: id, workflow name, status, active stages, and unanswered prompts (`awaitingInput`). Run IDs accept the full UUID or a unique 8-character prefix. `getRun()`, `getStages()`, `pause()` and `quit()` resolve a prefix against the runs this session holds and reject it at once when none matches, so pass the full UUID for a run recorded by an earlier process. `pause`, `quit` and `resume` resolve with the tool's acknowledged outcome: `action`, `runId` (`--all` for a batch), a `status` of `ok`, `running`, `paused`, `partial`, `noop` or `cancelled`, and a human-readable `message`. A `noop` means the request was understood and found nothing to change, such as pausing a run that already ended. A `partial` outcome means part of the request took effect. For `pause({ all: true })` and `quit({ all: true })`, `partial` means this call stopped at least one run and others are still active: `failedRuns` lists each run that is still active with its `runId`, a `reason` (for example `pause_failed` or `no_active_stages`) and a `message`, so check `outcome.status === "partial"` before treating a batch stop as complete. If active runs could not be stopped and this call stopped none, the call rejects with `WorkflowRunControlError` (`WORKFLOW_RUN_CONTROL_FAILED`) whose `failedRuns` carries the same list, even when other runs were already paused. Runs that are already paused or already ended are not failures, and a batch with no active run left to stop resolves as a `noop`. Call `getRun()` before retrying.
|
|
246
246
|
|
|
247
|
-
Pausing a run doesn't park a stage that is waiting on a prompt.
|
|
247
|
+
Pausing a run doesn't park a stage that is waiting on a prompt, including an `ask_user_question` delivered through `HostInput.questionnaire`. If no other work is active, `pause(runId)` and `pause({ all: true })` mark the run `paused` without cancelling its question. Questions not yet shown wait until the run resumes. A later pause counts it as already paused. If your host then answers an already-open prompt, the stage can continue its turn before you call `resume`. To keep a paused run fully stopped, hold prompt answers until you resume it.
|
|
248
248
|
|
|
249
249
|
Requests that cannot be carried out reject with a subclass of `WorkflowRunControlError`. Branch on `code` or use `instanceof`:
|
|
250
250
|
|
package/docs/sessions.md
CHANGED
|
@@ -21,7 +21,7 @@ atomic --session <path|id> # Use a file, exact ID, or unique 8-hex UUID prefix
|
|
|
21
21
|
atomic --fork <path|id> # Fork a file, exact ID, or unique 8-hex UUID prefix
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Use `/session` in interactive mode to see the current session file, session ID, message count, tokens, and cost.
|
|
24
|
+
Use `/session` in interactive mode to see the current session file, session ID, message count, tokens, and cost. You can use it while a run is active; its totals update after each completed message, not each streaming text chunk. Detailed cost and cache-waste breakdowns are shown after the run finishes only when the available session history matches those totals; otherwise, only the total cost is shown.
|
|
25
25
|
|
|
26
26
|
For UUID-backed sessions, `--session` and `--fork` accept either the full UUID or exactly eight hexadecimal prefix characters. A prefix must be unique within the current project (or, if no local session matches, across the global session store); collisions list the matching UUIDs and require the full value. Exact custom session IDs keep their existing priority. `--session-id` remains an exact project-local ID used to open or create a session, not a prefix selector.
|
|
27
27
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.25
|
|
3
|
+
"version": "0.9.25",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.25
|
|
9
|
+
"version": "0.9.25",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.25
|
|
13
|
-
"@bastani/pi-ai": "0.9.25
|
|
12
|
+
"@bastani/atomic-natives": "0.9.25",
|
|
13
|
+
"@bastani/pi-ai": "0.9.25",
|
|
14
14
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
15
15
|
"@earendil-works/pi-agent-core": "0.99.2",
|
|
16
16
|
"@earendil-works/pi-client": "0.99.2",
|
|
@@ -431,18 +431,18 @@
|
|
|
431
431
|
}
|
|
432
432
|
},
|
|
433
433
|
"node_modules/@bastani/atomic-natives": {
|
|
434
|
-
"version": "0.9.25
|
|
435
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.25
|
|
434
|
+
"version": "0.9.25",
|
|
435
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.25.tgz",
|
|
436
436
|
"license": "MIT",
|
|
437
437
|
"optionalDependencies": {
|
|
438
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.25
|
|
439
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.25
|
|
440
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.25
|
|
441
|
-
"@bastani/atomic-natives-linux-arm64-musl": "0.9.25
|
|
442
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.25
|
|
443
|
-
"@bastani/atomic-natives-linux-x64-musl": "0.9.25
|
|
444
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.25
|
|
445
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.25
|
|
438
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.25",
|
|
439
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.25",
|
|
440
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.25",
|
|
441
|
+
"@bastani/atomic-natives-linux-arm64-musl": "0.9.25",
|
|
442
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.25",
|
|
443
|
+
"@bastani/atomic-natives-linux-x64-musl": "0.9.25",
|
|
444
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.25",
|
|
445
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.25"
|
|
446
446
|
},
|
|
447
447
|
"engines": {
|
|
448
448
|
"bun": ">=1.4.2",
|
|
@@ -450,8 +450,8 @@
|
|
|
450
450
|
}
|
|
451
451
|
},
|
|
452
452
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
453
|
-
"version": "0.9.25
|
|
454
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.25
|
|
453
|
+
"version": "0.9.25",
|
|
454
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.25.tgz",
|
|
455
455
|
"license": "MIT",
|
|
456
456
|
"os": [
|
|
457
457
|
"darwin"
|
|
@@ -462,8 +462,8 @@
|
|
|
462
462
|
"optional": true
|
|
463
463
|
},
|
|
464
464
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
465
|
-
"version": "0.9.25
|
|
466
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.25
|
|
465
|
+
"version": "0.9.25",
|
|
466
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.25.tgz",
|
|
467
467
|
"license": "MIT",
|
|
468
468
|
"os": [
|
|
469
469
|
"darwin"
|
|
@@ -474,8 +474,8 @@
|
|
|
474
474
|
"optional": true
|
|
475
475
|
},
|
|
476
476
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
477
|
-
"version": "0.9.25
|
|
478
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.25
|
|
477
|
+
"version": "0.9.25",
|
|
478
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.25.tgz",
|
|
479
479
|
"license": "MIT",
|
|
480
480
|
"os": [
|
|
481
481
|
"linux"
|
|
@@ -489,8 +489,8 @@
|
|
|
489
489
|
"optional": true
|
|
490
490
|
},
|
|
491
491
|
"node_modules/@bastani/atomic-natives-linux-arm64-musl": {
|
|
492
|
-
"version": "0.9.25
|
|
493
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.25
|
|
492
|
+
"version": "0.9.25",
|
|
493
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-musl/-/atomic-natives-linux-arm64-musl-0.9.25.tgz",
|
|
494
494
|
"license": "MIT",
|
|
495
495
|
"os": [
|
|
496
496
|
"linux"
|
|
@@ -504,8 +504,8 @@
|
|
|
504
504
|
"optional": true
|
|
505
505
|
},
|
|
506
506
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
507
|
-
"version": "0.9.25
|
|
508
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.25
|
|
507
|
+
"version": "0.9.25",
|
|
508
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.25.tgz",
|
|
509
509
|
"license": "MIT",
|
|
510
510
|
"os": [
|
|
511
511
|
"linux"
|
|
@@ -519,8 +519,8 @@
|
|
|
519
519
|
"optional": true
|
|
520
520
|
},
|
|
521
521
|
"node_modules/@bastani/atomic-natives-linux-x64-musl": {
|
|
522
|
-
"version": "0.9.25
|
|
523
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.25
|
|
522
|
+
"version": "0.9.25",
|
|
523
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-musl/-/atomic-natives-linux-x64-musl-0.9.25.tgz",
|
|
524
524
|
"license": "MIT",
|
|
525
525
|
"os": [
|
|
526
526
|
"linux"
|
|
@@ -534,8 +534,8 @@
|
|
|
534
534
|
"optional": true
|
|
535
535
|
},
|
|
536
536
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
537
|
-
"version": "0.9.25
|
|
538
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.25
|
|
537
|
+
"version": "0.9.25",
|
|
538
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.25.tgz",
|
|
539
539
|
"license": "MIT",
|
|
540
540
|
"os": [
|
|
541
541
|
"win32"
|
|
@@ -546,8 +546,8 @@
|
|
|
546
546
|
"optional": true
|
|
547
547
|
},
|
|
548
548
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
549
|
-
"version": "0.9.25
|
|
550
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.25
|
|
549
|
+
"version": "0.9.25",
|
|
550
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.25.tgz",
|
|
551
551
|
"license": "MIT",
|
|
552
552
|
"os": [
|
|
553
553
|
"win32"
|
|
@@ -558,8 +558,8 @@
|
|
|
558
558
|
"optional": true
|
|
559
559
|
},
|
|
560
560
|
"node_modules/@bastani/pi-ai": {
|
|
561
|
-
"version": "0.9.25
|
|
562
|
-
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.25
|
|
561
|
+
"version": "0.9.25",
|
|
562
|
+
"resolved": "https://registry.npmjs.org/@bastani/pi-ai/-/pi-ai-0.9.25.tgz",
|
|
563
563
|
"license": "MIT",
|
|
564
564
|
"dependencies": {
|
|
565
565
|
"@anthropic-ai/sdk": "0.124.0",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.25
|
|
3
|
+
"version": "0.9.25",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@bastani/atomic-natives": "0.9.25
|
|
84
|
-
"@bastani/pi-ai": "0.9.25
|
|
83
|
+
"@bastani/atomic-natives": "0.9.25",
|
|
84
|
+
"@bastani/pi-ai": "0.9.25",
|
|
85
85
|
"@dbos-inc/dbos-sdk": "4.25.14",
|
|
86
86
|
"@earendil-works/pi-agent-core": "0.99.2",
|
|
87
87
|
"@earendil-works/pi-client": "0.99.2",
|