@bastani/atomic 0.9.19-alpha.8 → 0.9.19

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.
Files changed (111) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +38 -0
  3. package/dist/builtin/intercom/README.md +7 -7
  4. package/dist/builtin/intercom/broker/client.ts +4 -0
  5. package/dist/builtin/intercom/broker/send-handler.ts +18 -1
  6. package/dist/builtin/intercom/index.bundle.mjs +20 -17
  7. package/dist/builtin/intercom/package.json +1 -1
  8. package/dist/builtin/intercom/skills/intercom/SKILL.md +3 -3
  9. package/dist/builtin/intercom/types.ts +1 -1
  10. package/dist/builtin/mcp/CHANGELOG.md +8 -0
  11. package/dist/builtin/mcp/package.json +1 -1
  12. package/dist/builtin/subagents/CHANGELOG.md +30 -0
  13. package/dist/builtin/subagents/package.json +1 -1
  14. package/dist/builtin/web-access/CHANGELOG.md +20 -0
  15. package/dist/builtin/web-access/index.bundle.mjs +19 -17
  16. package/dist/builtin/web-access/package.json +1 -1
  17. package/dist/builtin/workflows/CHANGELOG.md +66 -0
  18. package/dist/builtin/workflows/package.json +1 -1
  19. package/dist/builtin/workflows/src/extension/index.bundle.mjs +324 -40
  20. package/dist/builtin/workflows/src/index.js +97 -18
  21. package/dist/core/extensions/api-types.d.ts +2 -0
  22. package/dist/core/extensions/api-types.d.ts.map +1 -1
  23. package/dist/core/extensions/api-types.js.map +1 -1
  24. package/dist/core/extensions/index.d.ts +1 -1
  25. package/dist/core/extensions/index.d.ts.map +1 -1
  26. package/dist/core/extensions/index.js.map +1 -1
  27. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  28. package/dist/core/extensions/loader-api.js.map +1 -1
  29. package/dist/core/extensions/loader-host-modules.d.ts.map +1 -1
  30. package/dist/core/extensions/loader-host-modules.js +3 -1
  31. package/dist/core/extensions/loader-host-modules.js.map +1 -1
  32. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  33. package/dist/core/extensions/loader-virtual-modules.js +2 -0
  34. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  35. package/dist/core/extensions/reactive-widget.d.ts +6 -0
  36. package/dist/core/extensions/reactive-widget.d.ts.map +1 -1
  37. package/dist/core/extensions/reactive-widget.js +7 -1
  38. package/dist/core/extensions/reactive-widget.js.map +1 -1
  39. package/dist/core/extensions/runner-shortcuts.d.ts.map +1 -1
  40. package/dist/core/extensions/runner-shortcuts.js +32 -3
  41. package/dist/core/extensions/runner-shortcuts.js.map +1 -1
  42. package/dist/core/extensions/runtime-types.d.ts +4 -0
  43. package/dist/core/extensions/runtime-types.d.ts.map +1 -1
  44. package/dist/core/extensions/runtime-types.js.map +1 -1
  45. package/dist/core/extensions/ui-types.d.ts +20 -0
  46. package/dist/core/extensions/ui-types.d.ts.map +1 -1
  47. package/dist/core/extensions/ui-types.js.map +1 -1
  48. package/dist/core/keybinding-identity.d.ts +4 -0
  49. package/dist/core/keybinding-identity.d.ts.map +1 -0
  50. package/dist/core/keybinding-identity.js +10 -0
  51. package/dist/core/keybinding-identity.js.map +1 -0
  52. package/dist/core/keybindings.d.ts +10 -0
  53. package/dist/core/keybindings.d.ts.map +1 -1
  54. package/dist/core/keybindings.js +2 -0
  55. package/dist/core/keybindings.js.map +1 -1
  56. package/dist/core/tools/bash.d.ts.map +1 -1
  57. package/dist/core/tools/bash.js +7 -1
  58. package/dist/core/tools/bash.js.map +1 -1
  59. package/dist/index-extensions.d.ts +1 -1
  60. package/dist/index-extensions.d.ts.map +1 -1
  61. package/dist/index-extensions.js.map +1 -1
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +1 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/modes/interactive/components/scroll-widget.d.ts +23 -0
  67. package/dist/modes/interactive/components/scroll-widget.d.ts.map +1 -0
  68. package/dist/modes/interactive/components/scroll-widget.js +61 -0
  69. package/dist/modes/interactive/components/scroll-widget.js.map +1 -0
  70. package/dist/modes/interactive/interactive-extension-runtime.js +10 -3
  71. package/dist/modes/interactive/interactive-extension-runtime.js.map +1 -1
  72. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  73. package/dist/modes/interactive/interactive-mode-base.js +3 -2
  74. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  75. package/dist/modes/interactive-engine/engine-custom-ui.d.ts +4 -1
  76. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  77. package/dist/modes/interactive-engine/engine-custom-ui.js +15 -7
  78. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  79. package/dist/modes/interactive-engine/engine-dialog-host.d.ts.map +1 -1
  80. package/dist/modes/interactive-engine/engine-dialog-host.js +4 -1
  81. package/dist/modes/interactive-engine/engine-dialog-host.js.map +1 -1
  82. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
  83. package/dist/modes/interactive-engine/extension-ui-bridge.js +1 -1
  84. package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
  85. package/dist/modes/interactive-engine/protocol.d.ts +12 -1
  86. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  87. package/dist/modes/interactive-engine/protocol.js +45 -2
  88. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  89. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  90. package/dist/modes/interactive-engine/remote-component.js +18 -8
  91. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  92. package/dist/modes/rpc/rpc-extension-ui.d.ts.map +1 -1
  93. package/dist/modes/rpc/rpc-extension-ui.js +2 -1
  94. package/dist/modes/rpc/rpc-extension-ui.js.map +1 -1
  95. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  96. package/dist/modes/rpc/rpc-mode.js +1 -0
  97. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  98. package/dist/modes/rpc/rpc-types.d.ts +4 -0
  99. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  100. package/dist/modes/rpc/rpc-types.js.map +1 -1
  101. package/docs/extensions/api-reference.md +2 -0
  102. package/docs/extensions/authoring.md +2 -0
  103. package/docs/intercom/reference.md +4 -0
  104. package/docs/intercom.md +4 -4
  105. package/docs/keybindings.md +17 -0
  106. package/docs/tui.md +34 -0
  107. package/docs/web-access.md +10 -0
  108. package/docs/workflows/api-reference.md +2 -0
  109. package/docs/workflows/operations.md +8 -0
  110. package/npm-shrinkwrap.json +32 -32
  111. package/package.json +3 -3
@@ -74476,13 +74476,15 @@ async function extractContent(url, signal, options) {
74476
74476
  if (signal?.aborted) {
74477
74477
  return { url, title: "", content: "", error: "Aborted" };
74478
74478
  }
74479
- const frameResult = await extractRequestedFrames(url, options, signal);
74480
- if (frameResult)
74481
- return frameResult;
74482
74479
  const localVideo = safeVideoInfo2(url);
74483
74480
  if (localVideo.error) {
74484
74481
  return { url, title: "", content: "", error: localVideo.error };
74485
74482
  }
74483
+ if (localVideo.info || isYouTubeURL(url).isYouTube) {
74484
+ const frameResult = await extractRequestedFrames(url, options, signal);
74485
+ if (frameResult)
74486
+ return frameResult;
74487
+ }
74486
74488
  if (localVideo.info) {
74487
74489
  try {
74488
74490
  const result = await extractVideo(localVideo.info, signal, options);
@@ -90949,29 +90951,29 @@ function registerContentTools(pi, deps) {
90949
90951
  pi.registerTool({
90950
90952
  name: "fetch_content",
90951
90953
  label: "Fetch Content",
90952
- description: "Fetch URL(s) and extract readable content as markdown. Supports YouTube video transcripts (with thumbnail), GitHub repository contents, and local video files (with frame thumbnail). Video frames can be extracted via timestamp/range or sampled across the entire video with frames alone. Falls back to Gemini for pages that block bots or fail Readability extraction. For YouTube and video files: ALWAYS pass the user's specific question via the prompt parameter this directs the AI to focus on that aspect of the video, producing much better results than a generic extraction. Content is always stored and can be retrieved with get_search_content.",
90953
- promptSnippet: "Use to extract readable content from URL(s), YouTube, GitHub repos, or local videos. For video questions, pass the user's exact question in prompt.",
90954
+ description: `Fetch webpages, PDFs, GitHub repositories, YouTube videos, or local video files. For ordinary pages, pass only {"urls":["https://example.com"]}; readable content is returned as markdown. For video analysis, include the user's question in prompt. Optional frames and timestamp extract images only from YouTube or local videos and are ignored for other inputs, including in mixed batches. Content is stored for get_search_content. Blocked or unreadable pages use extraction fallbacks.`,
90955
+ promptSnippet: "Fetch webpages with urls only. For YouTube or local video analysis, include the user's question in prompt; omit frames and timestamp unless images are wanted.",
90954
90956
  parameters: Type2.Object({
90955
90957
  urls: Type2.Array(Type2.String({ minLength: 1 }), {
90956
90958
  minItems: 1,
90957
90959
  description: 'URLs or local video paths to fetch. Always use an array, even for one URL: {"urls":["https://example.com"]}. Multiple URLs are fetched in parallel.'
90958
90960
  }),
90959
90961
  forceClone: Type2.Optional(Type2.Boolean({
90960
- description: "Force cloning large GitHub repositories that exceed the size threshold"
90962
+ description: "GitHub repositories only: allow cloning above the configured size threshold. Omit for webpages and videos."
90961
90963
  })),
90962
90964
  prompt: Type2.Optional(Type2.String({
90963
- description: "Question or instruction for video analysis (YouTube and video files). Pass the user's specific question here — e.g. 'describe the book shown at the advice for beginners section'. Without this, a generic transcript extraction is used which may miss what the user is asking about."
90965
+ description: "YouTube/local video analysis only: the user's specific question. Omit for webpages; this is not a webpage search or extraction filter."
90964
90966
  })),
90965
90967
  timestamp: Type2.Optional(Type2.String({
90966
- description: "Extract video frame(s) at a timestamp or time range. Single: '1:23:45', '23:45', or '85' (seconds). Range: '23:41-25:00' extracts evenly-spaced frames across that span (default 6). Use frames with ranges to control density; single+frames uses a fixed 5s interval. YouTube requires yt-dlp + ffmpeg; local videos require ffmpeg. Use a range when you know the approximate area but not the exact moment — you'll get a contact sheet to visually identify the right frame."
90968
+ description: "YouTube/local video images only: seconds ('85'), time ('1:25'), or range ('1:25-2:00'). Omit for text/transcripts. Ignored for non-video inputs. Ranges default to 6 frames; use frames to adjust."
90967
90969
  })),
90968
90970
  frames: Type2.Optional(Type2.Integer({
90969
90971
  minimum: 1,
90970
90972
  maximum: 12,
90971
- description: "Number of frames to extract. Use with timestamp range for custom density, with single timestamp to get N frames at 5s intervals, or alone to sample across the entire video. Requires yt-dlp + ffmpeg for YouTube, ffmpeg for local video."
90973
+ description: "YouTube/local video images only: 1-12 frames. Alone, samples the whole video; with a range, samples that span; with a single timestamp, uses 5s intervals. Ignored for non-video inputs. Omit for text/transcripts. Requires ffmpeg, plus yt-dlp for YouTube."
90972
90974
  })),
90973
90975
  model: Type2.Optional(Type2.String({
90974
- description: "Override the Gemini model for video/YouTube analysis (e.g. 'gemini-2.5-flash', 'gemini-3-flash-preview'). Defaults to config or gemini-3-flash-preview."
90976
+ description: "Gemini model override for YouTube/local video analysis only. Omit to use the configured default; does not select the webpage extraction model."
90975
90977
  }))
90976
90978
  }, { additionalProperties: false }),
90977
90979
  async execute(_toolCallId, params, signal, onUpdate) {
@@ -97598,18 +97600,18 @@ function webAccess(pi) {
97598
97600
  pi.registerTool({
97599
97601
  name: "fetch_content",
97600
97602
  label: "Fetch Content",
97601
- description: "Fetch URL(s) and extract readable content as markdown. Supports YouTube video transcripts (with thumbnail), GitHub repository contents, and local video files (with frame thumbnail). Video frames can be extracted via timestamp/range or sampled across the entire video with frames alone. Falls back to Gemini for pages that block bots or fail Readability extraction. For YouTube and video files: ALWAYS pass the user's specific question via the prompt parameter this directs the AI to focus on that aspect of the video, producing much better results than a generic extraction. Content is always stored and can be retrieved with get_search_content.",
97602
- promptSnippet: "Use to extract readable content from URL(s), YouTube, GitHub repos, or local videos. For video questions, pass the user's exact question in prompt.",
97603
+ description: `Fetch webpages, PDFs, GitHub repositories, YouTube videos, or local video files. For ordinary pages, pass only {"urls":["https://example.com"]}; readable content is returned as markdown. For video analysis, include the user's question in prompt. Optional frames and timestamp extract images only from YouTube or local videos and are ignored for other inputs, including in mixed batches. Content is stored for get_search_content. Blocked or unreadable pages use extraction fallbacks.`,
97604
+ promptSnippet: "Fetch webpages with urls only. For YouTube or local video analysis, include the user's question in prompt; omit frames and timestamp unless images are wanted.",
97603
97605
  parameters: Type4.Object({
97604
97606
  urls: Type4.Array(Type4.String({ minLength: 1 }), {
97605
97607
  minItems: 1,
97606
97608
  description: 'URLs or local video paths to fetch. Always use an array, even for one URL: {"urls":["https://example.com"]}. Multiple URLs are fetched in parallel.'
97607
97609
  }),
97608
- forceClone: Type4.Optional(Type4.Boolean({ description: "Force cloning large GitHub repositories that exceed the size threshold" })),
97609
- prompt: Type4.Optional(Type4.String({ description: "Question or instruction for video analysis (YouTube and video files)." })),
97610
- timestamp: Type4.Optional(Type4.String({ description: "Extract video frame(s) at a timestamp or time range." })),
97611
- frames: Type4.Optional(Type4.Integer({ minimum: 1, maximum: 12, description: "Number of frames to extract." })),
97612
- model: Type4.Optional(Type4.String({ description: "Override the Gemini model for video/YouTube analysis." }))
97610
+ forceClone: Type4.Optional(Type4.Boolean({ description: "GitHub repositories only: allow cloning above the configured size threshold. Omit for webpages and videos." })),
97611
+ prompt: Type4.Optional(Type4.String({ description: "YouTube/local video analysis only: the user's specific question. Omit for webpages; this is not a webpage search or extraction filter." })),
97612
+ timestamp: Type4.Optional(Type4.String({ description: "YouTube/local video images only: seconds ('85'), time ('1:25'), or range ('1:25-2:00'). Omit for text/transcripts. Ignored for non-video inputs. Ranges default to 6 frames; use frames to adjust." })),
97613
+ frames: Type4.Optional(Type4.Integer({ minimum: 1, maximum: 12, description: "YouTube/local video images only: 1-12 frames. Alone, samples the whole video; with a range, samples that span; with a single timestamp, uses 5s intervals. Ignored for non-video inputs. Omit for text/transcripts. Requires ffmpeg, plus yt-dlp for YouTube." })),
97614
+ model: Type4.Optional(Type4.String({ description: "Gemini model override for YouTube/local video analysis only. Omit to use the configured default; does not select the webpage extraction model." }))
97613
97615
  }, { additionalProperties: false }),
97614
97616
  execute: (...args) => executeHeavyTool(loadHeavy, "fetch_content", args),
97615
97617
  renderResult: (...args) => renderHeavyToolResult(loadedHeavy?.heavy ?? null, "fetch_content", args)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/web-access",
3
- "version": "0.9.19-alpha.8",
3
+ "version": "0.9.19",
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,72 @@ 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.19] - 2026-09-13
10
+
11
+ Cumulative release of the `0.9.19-alpha.1` through `0.9.19-alpha.11` prereleases. Per-change details remain in the unchanged prerelease sections below.
12
+
13
+ ### Breaking Changes
14
+
15
+ - Workflow control uses `pause` across slash commands, tool actions, runtime APIs and lifecycle events. Run-level pause preserves resumable work, nested checkpoint tails and executor-only waits; targeted stage pause retains queued messages, and targeted `ctx.tool` pause cancels only that call. Use `resume` to continue eligible work.
16
+
17
+ ### Added
18
+
19
+ - Connected workflow activity to host observers and the built-in Herdr reporter, with root snapshots that distinguish execution, human waits, pauses, recovery and acknowledged failures. Typed lifecycle, activity, completion and heartbeat hooks preserve canonical nested identities without synthesizing completions during restore ([#2891](https://github.com/bastani-inc/atomic/issues/2891)).
20
+ - Added source-qualified stage-local `/skill:` discovery and one-time expansion for idle, steering and follow-up submissions, retaining Enter/Ctrl+F intent and human-input ownership. Editable post-mortem chats can use skills without restarting execution; `StageSendUserMessageOptions.expandPromptTemplates` opts programmatic delivery into expansion.
21
+ - Added bound owner-task inspection to stage chats with compact background counts below the composer, shared `/tasks` navigation and readable shaded completion cards ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
22
+ - Graph node cards show effective model and thinking identity, preserving canonical fast suffixes, updating on fallback and restoring through durable resume ([#1859](https://github.com/bastani-inc/atomic/pull/1859) by [@sina85](https://github.com/sina85)).
23
+ - Main-chat workflow cards support viewport-local wheel scrolling and an overflow-only scrollbar. Configurable Alt+K/J shortcuts, labeled Option on macOS, retain Alt+PageUp/PageDown aliases and yield to editor bindings. Ten-row and short-terminal caps preserve multiline-draft access and run anchors through live changes and resize.
24
+
25
+ ### Changed
26
+
27
+ - Incoming Intercom sends and asks cancel a live stage's current model call or cancellable tool and process messages in the same generation. Ordered delivery survives preflight and persistence races without replaying completed tools or cancelling a child that is asking its parent.
28
+ - Reduced default stage and authored parallel concurrency from 4 to 3, preserving explicit overrides.
29
+ - Open Claude Design starts with Fable 5.1 at medium, then Copilot Fable 5.1 and Astra at medium, with Fable-first OpenRouter fallbacks. Goal and Ralph orchestration, Ralph research and design use Fable fallbacks at medium and Sol at high; Goal/Ralph reviewers use Astra/Sol at high. Ralph prompt refinement remains at high, and OpenRouter Grok fallbacks explicitly use xhigh.
30
+ - Guidance uses project CI timing to plan critical-path work, avoids redundant full-suite runs without skipping gates, and routes user questions through structured question tools when available. Requests to work "quickly" select inline execution; launches inherit configured limits without routine budget questions while preserving approval before raising exhausted budgets.
31
+ - Graph cards omit generated dependency labels and extra padding, leave absent models blank, and show queued-message counts on a separate row. Status detail uses local time rather than UTC ([#3008](https://github.com/bastani-inc/atomic/issues/3008)).
32
+
33
+ ### Fixed
34
+
35
+ - Model fallback releases failed-attempt Intercom ownership before replacement, shares concurrent attachment/steering setup, and stops on cleanup failure. Repeated nested `ctx.workflow()` calls use unambiguous boundary identities instead of colliding during fallback ([#3020](https://github.com/bastani-inc/atomic/issues/3020)).
36
+ - Unchanged stage routes are no longer republished on every store update, avoiding redundant broker traffic and `List sessions timeout`. Genuine changes publish immediately, and rejected or unacknowledged announcements remain retryable.
37
+ - Restored embedded Postgres discovery in Bun-compiled and nested npm installations. Early exit reports the retained server's log instead of a readiness timeout; competing listeners and process-query failures cannot masquerade as readiness.
38
+ - Reduced checkpoint-heavy durable resume latency, especially on Windows, without changing decoded values or original errors. Ended recoverable blocks resume through continuation rather than reporting snapshot-only success.
39
+ - Initialization cancellation no longer leaves uncontrollable empty runs. Whole-run pause retains live executors and nested owners until resume, while quit retires them; durable resume replaces abandoned executors without replacing surviving paused owners. Original tool failures, closed-admission errors and child cleanup survive cancellation races.
40
+ - Stage pause cancels owned active and admitted queued agents and commands and waits for admission and cleanup; resume permits fresh work without reviving cancelled executions or affecting siblings. Durable tool callbacks wait for admitted agent tasks to settle before checkpointing, preserving commit/cancellation fences ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
41
+ - Quit and pause dismiss owned active-tool and readiness questions, reject late answers, and ask readiness again on resume. Failed cancellation releases only its temporary hold instead of stranding a running stage ([#2897](https://github.com/bastani-inc/atomic/issues/2897)).
42
+ - Completed stages retain their late-message routing for post-mortem asks. Non-agent prompt/tool names do not invalidate genuine duplicate-agent routing ([#2895](https://github.com/bastani-inc/atomic/pull/2895)).
43
+ - Preserved complete stage artifacts across follow-up clarification, compaction and fallback. Failed retries discard provisional answers without losing earlier accepted reports; typed child workflows can receive structured output without graph projection freezing it ([#2936](https://github.com/bastani-inc/atomic/issues/2936)).
44
+ - Local stage listing and background counts include recursively nested stages without duplicate boundaries. Warm-first verifier and tournament groups declare possible-stage names without spurious builtin discovery warnings ([#3001](https://github.com/bastani-inc/atomic/issues/3001)).
45
+ - Skill autocomplete shares lazy attachment without checkpointing on every keystroke. Unsupported custom hosts report unavailable invocation rather than bypassing admission.
46
+ - Stage `/tasks` stays local, retains model/reasoning/cwd/branch/MCP context, and keeps counts visible beside questions on narrow terminals. Detail pages remain fullscreen, and navigation does not create false input notices or approval waits.
47
+ - Workflow graph interiors and autocomplete use the terminal background; themed chrome and focused tabs retain fill and styling through truncation. Graph/picker navigation no longer falsely marks Herdr blocked.
48
+ - Live continuation prevents brief false idle reports. Settled failures retain attention without reporting an active decision wait; genuine questions and exhausted budgets remain blocked. Already-aborted lifecycle kill events and checkpoint interrupt outcomes remain accurate ([#2891](https://github.com/bastani-inc/atomic/issues/2891), [#2912](https://github.com/bastani-inc/atomic/pull/2912)).
49
+ - Workflow summaries fit narrow terminals, keep the viewed run anchored across insertion/removal and collapse/resize, and use a concise `↑↓ scroll` hint without a redundant visible-row counter ([#3015](https://github.com/bastani-inc/atomic/issues/3015), [#3017](https://github.com/bastani-inc/atomic/pull/3017)).
50
+
51
+ ## [0.9.19-alpha.11] - 2026-09-13
52
+
53
+ ### Fixed
54
+
55
+ - Repeated nested `ctx.workflow()` invocations use unambiguous Intercom boundary identities, preventing duplicate-owner and heavy-initialization warnings during model fallback while preserving route ownership checks.
56
+
57
+ ## [0.9.19-alpha.10] - 2026-09-13
58
+
59
+ ### Added
60
+
61
+ - Main-chat workflow cards now scroll with the wheel over their actual allocated viewport, with a slim scrollbar only when content overflows. Configurable Alt+K/J shortcuts, labeled Option on macOS, retain Alt+PageUp/PageDown aliases and yield to configured editor bindings. The ten-row/short-terminal cap, multiline-draft reachability and run-ID anchors remain intact across insertion, deletion, collapse and resize, including isolated-engine sessions.
62
+
63
+ ### Fixed
64
+
65
+ - Model fallback releases the failed attempt's Intercom ownership before initializing its replacement, avoiding duplicate live-stage ownership warnings while retaining queued delivery handoff. Concurrent attachment and steering wait for cleanup and share successor creation. Cancellation during cleanup no longer starts a replacement session, and failed extension initialization cleans up its session. If that cleanup fails, the stage stops rather than retrying or creating another session, preserving both the initialization and cleanup errors for diagnosis ([#3020](https://github.com/bastani-inc/atomic/issues/3020)).
66
+ - Removed the confusing visible-row counter from the main-chat workflow widget hint; the final hint now reads `↑↓ scroll` followed by available scrolling shortcuts, matching the `/tasks` hint style.
67
+
68
+ ## [0.9.19-alpha.9] - 2026-09-12
69
+
70
+ ### Fixed
71
+
72
+ - Kept the background workflow summary within narrow terminal widths, including 27 columns. The shared workflow widget now stays within ten rows, shrinks on short terminals, and scrolls one row at a time with Alt+PageUp / Alt+PageDown without taking focus from the editor. All workflow rows remain reachable when a multiline draft reduces the visible widget area ([#3015](https://github.com/bastani-inc/atomic/issues/3015)).
73
+ - Kept the workflow being read in view when live runs are inserted or removed above it, including workflows with identical names. Resizing to a collapsed summary and back preserves the reading position; removing the viewed run selects its next surviving neighbour, or the previous one when no later run remains ([#3017](https://github.com/bastani-inc/atomic/pull/3017)).
74
+
9
75
  ## [0.9.19-alpha.8] - 2026-09-12
10
76
 
11
77
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.19-alpha.8",
3
+ "version": "0.9.19",
4
4
  "private": true,
5
5
  "description": "Atomic extension for multi-stage workflow authoring and execution.",
6
6
  "contributors": [