@bastani/atomic 0.9.0-alpha.1 → 0.9.0-alpha.2

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 (211) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/builtin/cursor/CHANGELOG.md +6 -0
  3. package/dist/builtin/cursor/package.json +2 -2
  4. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  5. package/dist/builtin/intercom/package.json +2 -2
  6. package/dist/builtin/mcp/CHANGELOG.md +6 -0
  7. package/dist/builtin/mcp/package.json +3 -3
  8. package/dist/builtin/subagents/CHANGELOG.md +6 -0
  9. package/dist/builtin/subagents/package.json +4 -4
  10. package/dist/builtin/web-access/CHANGELOG.md +6 -0
  11. package/dist/builtin/web-access/package.json +2 -2
  12. package/dist/builtin/workflows/CHANGELOG.md +12 -0
  13. package/dist/builtin/workflows/README.md +189 -122
  14. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +30 -27
  15. package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
  16. package/dist/builtin/workflows/builtin/goal.ts +39 -44
  17. package/dist/builtin/workflows/builtin/index.d.ts +1 -0
  18. package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +16 -17
  19. package/dist/builtin/workflows/builtin/open-claude-design.d.ts +1 -0
  20. package/dist/builtin/workflows/builtin/open-claude-design.ts +42 -50
  21. package/dist/builtin/workflows/builtin/ralph.ts +44 -41
  22. package/dist/builtin/workflows/package.json +2 -2
  23. package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
  24. package/dist/builtin/workflows/src/authoring/typebox-defaults.ts +217 -0
  25. package/dist/builtin/workflows/src/authoring/workflow.ts +184 -0
  26. package/dist/builtin/workflows/src/authoring.d.ts +14 -66
  27. package/dist/builtin/workflows/src/engine/graph-inference.ts +100 -0
  28. package/dist/builtin/workflows/src/engine/options.ts +40 -0
  29. package/dist/builtin/workflows/src/engine/primitives/chain.ts +29 -0
  30. package/dist/builtin/workflows/src/engine/primitives/exit.ts +2 -0
  31. package/dist/builtin/workflows/src/engine/primitives/parallel.ts +47 -0
  32. package/dist/builtin/workflows/src/engine/primitives/task.ts +108 -0
  33. package/dist/builtin/workflows/src/engine/primitives/ui.ts +41 -0
  34. package/dist/builtin/workflows/src/engine/primitives/workflow.ts +159 -0
  35. package/dist/builtin/workflows/src/engine/replay.ts +8 -0
  36. package/dist/builtin/workflows/src/engine/run.ts +356 -0
  37. package/dist/builtin/workflows/src/engine/runtime.ts +160 -0
  38. package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +9 -3
  39. package/dist/builtin/workflows/src/extension/workflow-schema.ts +0 -18
  40. package/dist/builtin/workflows/src/index.ts +0 -2
  41. package/dist/builtin/workflows/src/runs/background/runner.ts +6 -3
  42. package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +3 -3
  43. package/dist/builtin/workflows/src/runs/foreground/executor-child-helpers.ts +4 -4
  44. package/dist/builtin/workflows/src/runs/foreground/executor-child-workflow.ts +1 -158
  45. package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +1 -1
  46. package/dist/builtin/workflows/src/runs/foreground/executor-outputs.ts +2 -2
  47. package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +1 -1
  48. package/dist/builtin/workflows/src/runs/foreground/executor-run.ts +1 -359
  49. package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +1 -1
  50. package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +2 -5
  51. package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +12 -4
  52. package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +4 -3
  53. package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +9 -2
  54. package/dist/builtin/workflows/src/runs/foreground/executor-task-context.ts +2 -132
  55. package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -2
  56. package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +2 -100
  57. package/dist/builtin/workflows/src/sdk-surface.ts +6 -9
  58. package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +9 -3
  59. package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +17 -3
  60. package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +3 -33
  61. package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +9 -81
  62. package/dist/builtin/workflows/src/shared/types.ts +25 -8
  63. package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +49 -0
  64. package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +84 -0
  65. package/dist/builtin/workflows/src/workflows/registry.ts +7 -3
  66. package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
  67. package/dist/core/agent-session-auto-compaction.js +6 -1
  68. package/dist/core/agent-session-auto-compaction.js.map +1 -1
  69. package/dist/core/agent-session-bash.d.ts.map +1 -1
  70. package/dist/core/agent-session-bash.js +0 -5
  71. package/dist/core/agent-session-bash.js.map +1 -1
  72. package/dist/core/agent-session-methods.d.ts +0 -2
  73. package/dist/core/agent-session-methods.d.ts.map +1 -1
  74. package/dist/core/agent-session-methods.js.map +1 -1
  75. package/dist/core/agent-session-services.d.ts +0 -1
  76. package/dist/core/agent-session-services.d.ts.map +1 -1
  77. package/dist/core/agent-session-services.js +0 -1
  78. package/dist/core/agent-session-services.js.map +1 -1
  79. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  80. package/dist/core/agent-session-tool-registry.js +0 -2
  81. package/dist/core/agent-session-tool-registry.js.map +1 -1
  82. package/dist/core/agent-session-types.d.ts +0 -2
  83. package/dist/core/agent-session-types.d.ts.map +1 -1
  84. package/dist/core/agent-session-types.js.map +1 -1
  85. package/dist/core/agent-session.d.ts +0 -2
  86. package/dist/core/agent-session.d.ts.map +1 -1
  87. package/dist/core/agent-session.js +0 -1
  88. package/dist/core/agent-session.js.map +1 -1
  89. package/dist/core/atomic-guide-command.d.ts.map +1 -1
  90. package/dist/core/atomic-guide-command.js +1 -1
  91. package/dist/core/atomic-guide-command.js.map +1 -1
  92. package/dist/core/extensions/loader-core.d.ts +1 -3
  93. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  94. package/dist/core/extensions/loader-core.js +13 -6
  95. package/dist/core/extensions/loader-core.js.map +1 -1
  96. package/dist/core/extensions/loader-virtual-modules.d.ts +7 -1
  97. package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
  98. package/dist/core/extensions/loader-virtual-modules.js +34 -2
  99. package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
  100. package/dist/core/extensions/loader.d.ts +2 -1
  101. package/dist/core/extensions/loader.d.ts.map +1 -1
  102. package/dist/core/extensions/loader.js +2 -1
  103. package/dist/core/extensions/loader.js.map +1 -1
  104. package/dist/core/index.d.ts +0 -1
  105. package/dist/core/index.d.ts.map +1 -1
  106. package/dist/core/index.js +0 -1
  107. package/dist/core/index.js.map +1 -1
  108. package/dist/core/model-registry-builtins.d.ts.map +1 -1
  109. package/dist/core/model-registry-builtins.js +6 -0
  110. package/dist/core/model-registry-builtins.js.map +1 -1
  111. package/dist/core/model-registry-schemas.d.ts +65 -13
  112. package/dist/core/model-registry-schemas.d.ts.map +1 -1
  113. package/dist/core/model-registry-schemas.js +10 -0
  114. package/dist/core/model-registry-schemas.js.map +1 -1
  115. package/dist/core/resource-loader-core.d.ts +1 -0
  116. package/dist/core/resource-loader-core.d.ts.map +1 -1
  117. package/dist/core/resource-loader-core.js +2 -0
  118. package/dist/core/resource-loader-core.js.map +1 -1
  119. package/dist/core/resource-loader-extensions.d.ts.map +1 -1
  120. package/dist/core/resource-loader-extensions.js +3 -3
  121. package/dist/core/resource-loader-extensions.js.map +1 -1
  122. package/dist/core/resource-loader-internals.d.ts +1 -0
  123. package/dist/core/resource-loader-internals.d.ts.map +1 -1
  124. package/dist/core/resource-loader-internals.js.map +1 -1
  125. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  126. package/dist/core/resource-loader-reload.js +6 -2
  127. package/dist/core/resource-loader-reload.js.map +1 -1
  128. package/dist/core/sdk-exports.d.ts +1 -1
  129. package/dist/core/sdk-exports.d.ts.map +1 -1
  130. package/dist/core/sdk-exports.js.map +1 -1
  131. package/dist/core/sdk-types.d.ts +0 -3
  132. package/dist/core/sdk-types.d.ts.map +1 -1
  133. package/dist/core/sdk-types.js.map +1 -1
  134. package/dist/core/sdk.d.ts.map +1 -1
  135. package/dist/core/sdk.js +0 -1
  136. package/dist/core/sdk.js.map +1 -1
  137. package/dist/core/session-manager-history.d.ts.map +1 -1
  138. package/dist/core/session-manager-history.js +2 -1
  139. package/dist/core/session-manager-history.js.map +1 -1
  140. package/dist/core/tools/bash.d.ts +0 -5
  141. package/dist/core/tools/bash.d.ts.map +1 -1
  142. package/dist/core/tools/bash.js +10 -11
  143. package/dist/core/tools/bash.js.map +1 -1
  144. package/dist/core/tools/edit-diff-preserve.d.ts +18 -0
  145. package/dist/core/tools/edit-diff-preserve.d.ts.map +1 -0
  146. package/dist/core/tools/edit-diff-preserve.js +85 -0
  147. package/dist/core/tools/edit-diff-preserve.js.map +1 -0
  148. package/dist/core/tools/edit-diff.d.ts +3 -2
  149. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  150. package/dist/core/tools/edit-diff.js +15 -18
  151. package/dist/core/tools/edit-diff.js.map +1 -1
  152. package/dist/core/tools/index.d.ts +0 -1
  153. package/dist/core/tools/index.d.ts.map +1 -1
  154. package/dist/core/tools/index.js +0 -1
  155. package/dist/core/tools/index.js.map +1 -1
  156. package/dist/index.d.ts +2 -2
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +1 -1
  159. package/dist/index.js.map +1 -1
  160. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  161. package/dist/modes/interactive/components/model-selector.js +2 -2
  162. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  163. package/dist/modes/interactive/model-search.d.ts +5 -0
  164. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  165. package/dist/modes/interactive/model-search.js +9 -0
  166. package/dist/modes/interactive/model-search.js.map +1 -1
  167. package/dist/utils/shell.d.ts +1 -0
  168. package/dist/utils/shell.d.ts.map +1 -1
  169. package/dist/utils/shell.js +12 -5
  170. package/dist/utils/shell.js.map +1 -1
  171. package/docs/custom-provider.md +4 -3
  172. package/docs/models.md +3 -2
  173. package/docs/packages.md +2 -2
  174. package/docs/quickstart.md +1 -1
  175. package/docs/sdk.md +2 -40
  176. package/docs/security.md +1 -1
  177. package/docs/workflows.md +238 -173
  178. package/package.json +5 -5
  179. package/dist/builtin/workflows/src/workflows/define-workflow.ts +0 -277
  180. package/dist/core/tools/bash-policy-compile.d.ts +0 -5
  181. package/dist/core/tools/bash-policy-compile.d.ts.map +0 -1
  182. package/dist/core/tools/bash-policy-compile.js +0 -241
  183. package/dist/core/tools/bash-policy-compile.js.map +0 -1
  184. package/dist/core/tools/bash-policy-evaluate.d.ts +0 -3
  185. package/dist/core/tools/bash-policy-evaluate.d.ts.map +0 -1
  186. package/dist/core/tools/bash-policy-evaluate.js +0 -92
  187. package/dist/core/tools/bash-policy-evaluate.js.map +0 -1
  188. package/dist/core/tools/bash-policy-format.d.ts +0 -5
  189. package/dist/core/tools/bash-policy-format.d.ts.map +0 -1
  190. package/dist/core/tools/bash-policy-format.js +0 -49
  191. package/dist/core/tools/bash-policy-format.js.map +0 -1
  192. package/dist/core/tools/bash-policy-parser.d.ts +0 -4
  193. package/dist/core/tools/bash-policy-parser.d.ts.map +0 -1
  194. package/dist/core/tools/bash-policy-parser.js +0 -155
  195. package/dist/core/tools/bash-policy-parser.js.map +0 -1
  196. package/dist/core/tools/bash-policy-segment.d.ts +0 -3
  197. package/dist/core/tools/bash-policy-segment.d.ts.map +0 -1
  198. package/dist/core/tools/bash-policy-segment.js +0 -275
  199. package/dist/core/tools/bash-policy-segment.js.map +0 -1
  200. package/dist/core/tools/bash-policy-shell.d.ts +0 -11
  201. package/dist/core/tools/bash-policy-shell.d.ts.map +0 -1
  202. package/dist/core/tools/bash-policy-shell.js +0 -267
  203. package/dist/core/tools/bash-policy-shell.js.map +0 -1
  204. package/dist/core/tools/bash-policy-types.d.ts +0 -146
  205. package/dist/core/tools/bash-policy-types.d.ts.map +0 -1
  206. package/dist/core/tools/bash-policy-types.js +0 -2
  207. package/dist/core/tools/bash-policy-types.js.map +0 -1
  208. package/dist/core/tools/bash-policy.d.ts +0 -6
  209. package/dist/core/tools/bash-policy.d.ts.map +0 -1
  210. package/dist/core/tools/bash-policy.js +0 -5
  211. package/dist/core/tools/bash-policy.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n}\n\n/**\n * Find bash executable on PATH (cross-platform)\n */\nfunction findBashOnPath(): string | null {\n\tif (process.platform === \"win32\") {\n\t\t// Windows: Use 'where' and verify file exists (where can return non-existent paths)\n\t\ttry {\n\t\t\tconst result = spawnSync(\"where\", [\"bash.exe\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\t\tif (result.status === 0 && result.stdout) {\n\t\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\t\tif (firstMatch && existsSync(firstMatch)) {\n\t\t\t\t\treturn firstMatch;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n\ttry {\n\t\tconst result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch) {\n\t\t\t\treturn firstMatch;\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore errors\n\t}\n\treturn null;\n}\n\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath?: string): ShellConfig {\n\t// 1. Check user-specified shell path\n\tif (customShellPath) {\n\t\tif (existsSync(customShellPath)) {\n\t\t\treturn { shell: customShellPath, args: [\"-c\"] };\n\t\t}\n\t\tthrow new Error(`Custom shell path not found: ${customShellPath}`);\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\t// 2. Try Git Bash in known locations\n\t\tconst paths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) {\n\t\t\tpaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) {\n\t\t\tpaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\n\t\tfor (const path of paths) {\n\t\t\tif (existsSync(path)) {\n\t\t\t\treturn { shell: path, args: [\"-c\"] };\n\t\t\t}\n\t\t}\n\n\t\t// 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n\t\tconst bashOnPath = findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn { shell: bashOnPath, args: [\"-c\"] };\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`No bash shell found. Options:\\n` +\n\t\t\t\t` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n\t\t\t\t` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n\t\t\t\t\" 3. Set shellPath in settings.json\\n\\n\" +\n\t\t\t\t`Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`,\n\t\t);\n\t}\n\n\t// Unix: try /bin/bash, then bash on PATH, then fallback to sh\n\tif (existsSync(\"/bin/bash\")) {\n\t\treturn { shell: \"/bin/bash\", args: [\"-c\"] };\n\t}\n\n\tconst bashOnPath = findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn { shell: bashOnPath, args: [\"-c\"] };\n\t}\n\n\treturn { shell: \"sh\", args: [\"-c\"] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str: string): string {\n\t// Use Array.from to properly iterate over code points (not code units)\n\t// This handles surrogate pairs correctly and catches edge cases where\n\t// codePointAt() might return undefined\n\treturn Array.from(str)\n\t\t.filter((char) => {\n\t\t\t// Filter out characters that cause string-width to crash\n\t\t\t// This includes:\n\t\t\t// - Unicode format characters\n\t\t\t// - Lone surrogates (already filtered by Array.from)\n\t\t\t// - Control chars except \\t \\n \\r\n\t\t\t// - Characters with undefined code points\n\n\t\t\tconst code = char.codePointAt(0);\n\n\t\t\t// Skip if code point is undefined (edge case with invalid strings)\n\t\t\tif (code === undefined) return false;\n\n\t\t\t// Allow tab, newline, carriage return\n\t\t\tif (code === 0x09 || code === 0x0a || code === 0x0d) return true;\n\n\t\t\t// Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0x0d)\n\t\t\tif (code <= 0x1f) return false;\n\n\t\t\t// Filter out Unicode format characters\n\t\t\tif (code >= 0xfff9 && code <= 0xfffb) return false;\n\n\t\t\treturn true;\n\t\t})\n\t\t.join(\"\");\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform)\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../../src/utils/shell.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { spawn, spawnSync } from \"child_process\";\nimport { getBinDir } from \"../config.ts\";\n\nexport interface ShellConfig {\n\tshell: string;\n\targs: string[];\n\tcommandTransport?: \"argv\" | \"stdin\";\n}\n\nfunction isLegacyWslBashPath(path: string): boolean {\n\tconst normalized = path.replace(/\\//g, \"\\\\\").toLowerCase();\n\treturn /^[a-z]:\\\\windows\\\\(?:system32|sysnative)\\\\bash\\.exe$/.test(normalized);\n}\n\nfunction getBashShellConfig(shell: string): ShellConfig {\n\treturn isLegacyWslBashPath(shell) ? { shell, args: [\"-s\"], commandTransport: \"stdin\" } : { shell, args: [\"-c\"] };\n}\n\n/**\n * Find bash executable on PATH (cross-platform)\n */\nfunction findBashOnPath(): string | null {\n\tif (process.platform === \"win32\") {\n\t\t// Windows: Use 'where' and verify file exists (where can return non-existent paths)\n\t\ttry {\n\t\t\tconst result = spawnSync(\"where\", [\"bash.exe\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\t\tif (result.status === 0 && result.stdout) {\n\t\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\t\tif (firstMatch && existsSync(firstMatch)) {\n\t\t\t\t\treturn firstMatch;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore errors\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Unix: Use 'which' and trust its output (handles Termux and special filesystems)\n\ttry {\n\t\tconst result = spawnSync(\"which\", [\"bash\"], { encoding: \"utf-8\", timeout: 5000 });\n\t\tif (result.status === 0 && result.stdout) {\n\t\t\tconst firstMatch = result.stdout.trim().split(/\\r?\\n/)[0];\n\t\t\tif (firstMatch) {\n\t\t\t\treturn firstMatch;\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Ignore errors\n\t}\n\treturn null;\n}\n\n/**\n * Resolve shell configuration based on platform and an optional explicit shell path.\n * Resolution order:\n * 1. User-specified shellPath\n * 2. On Windows: Git Bash in known locations, then bash on PATH\n * 3. On Unix: /bin/bash, then bash on PATH, then fallback to sh\n */\nexport function getShellConfig(customShellPath?: string): ShellConfig {\n\t// 1. Check user-specified shell path\n\tif (customShellPath) {\n\t\tif (existsSync(customShellPath)) {\n\t\t\treturn getBashShellConfig(customShellPath);\n\t\t}\n\t\tthrow new Error(`Custom shell path not found: ${customShellPath}`);\n\t}\n\n\tif (process.platform === \"win32\") {\n\t\t// 2. Try Git Bash in known locations\n\t\tconst paths: string[] = [];\n\t\tconst programFiles = process.env.ProgramFiles;\n\t\tif (programFiles) {\n\t\t\tpaths.push(`${programFiles}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\t\tconst programFilesX86 = process.env[\"ProgramFiles(x86)\"];\n\t\tif (programFilesX86) {\n\t\t\tpaths.push(`${programFilesX86}\\\\Git\\\\bin\\\\bash.exe`);\n\t\t}\n\n\t\tfor (const path of paths) {\n\t\t\tif (existsSync(path)) {\n\t\t\t\treturn getBashShellConfig(path);\n\t\t\t}\n\t\t}\n\n\t\t// 3. Fallback: search bash.exe on PATH (Cygwin, MSYS2, WSL, etc.)\n\t\tconst bashOnPath = findBashOnPath();\n\t\tif (bashOnPath) {\n\t\t\treturn getBashShellConfig(bashOnPath);\n\t\t}\n\n\t\tthrow new Error(\n\t\t\t`No bash shell found. Options:\\n` +\n\t\t\t\t` 1. Install Git for Windows: https://git-scm.com/download/win\\n` +\n\t\t\t\t` 2. Add your bash to PATH (Cygwin, MSYS2, etc.)\\n` +\n\t\t\t\t\" 3. Set shellPath in settings.json\\n\\n\" +\n\t\t\t\t`Searched Git Bash in:\\n${paths.map((p) => ` ${p}`).join(\"\\n\")}`,\n\t\t);\n\t}\n\n\t// Unix: try /bin/bash, then bash on PATH, then fallback to sh\n\tif (existsSync(\"/bin/bash\")) {\n\t\treturn getBashShellConfig(\"/bin/bash\");\n\t}\n\n\tconst bashOnPath = findBashOnPath();\n\tif (bashOnPath) {\n\t\treturn getBashShellConfig(bashOnPath);\n\t}\n\n\treturn { shell: \"sh\", args: [\"-c\"] };\n}\n\nexport function getShellEnv(): NodeJS.ProcessEnv {\n\tconst binDir = getBinDir();\n\tconst pathKey = Object.keys(process.env).find((key) => key.toLowerCase() === \"path\") ?? \"PATH\";\n\tconst currentPath = process.env[pathKey] ?? \"\";\n\tconst pathEntries = currentPath.split(delimiter).filter(Boolean);\n\tconst hasBinDir = pathEntries.includes(binDir);\n\tconst updatedPath = hasBinDir ? currentPath : [binDir, currentPath].filter(Boolean).join(delimiter);\n\n\treturn {\n\t\t...process.env,\n\t\t[pathKey]: updatedPath,\n\t};\n}\n\n/**\n * Sanitize binary output for display/storage.\n * Removes characters that crash string-width or cause display issues:\n * - Control characters (except tab, newline, carriage return)\n * - Lone surrogates\n * - Unicode Format characters (crash string-width due to a bug)\n * - Characters with undefined code points\n */\nexport function sanitizeBinaryOutput(str: string): string {\n\t// Use Array.from to properly iterate over code points (not code units)\n\t// This handles surrogate pairs correctly and catches edge cases where\n\t// codePointAt() might return undefined\n\treturn Array.from(str)\n\t\t.filter((char) => {\n\t\t\t// Filter out characters that cause string-width to crash\n\t\t\t// This includes:\n\t\t\t// - Unicode format characters\n\t\t\t// - Lone surrogates (already filtered by Array.from)\n\t\t\t// - Control chars except \\t \\n \\r\n\t\t\t// - Characters with undefined code points\n\n\t\t\tconst code = char.codePointAt(0);\n\n\t\t\t// Skip if code point is undefined (edge case with invalid strings)\n\t\t\tif (code === undefined) return false;\n\n\t\t\t// Allow tab, newline, carriage return\n\t\t\tif (code === 0x09 || code === 0x0a || code === 0x0d) return true;\n\n\t\t\t// Filter out control characters (0x00-0x1F, except 0x09, 0x0a, 0x0x0d)\n\t\t\tif (code <= 0x1f) return false;\n\n\t\t\t// Filter out Unicode format characters\n\t\t\tif (code >= 0xfff9 && code <= 0xfffb) return false;\n\n\t\t\treturn true;\n\t\t})\n\t\t.join(\"\");\n}\n\n/**\n * Detached child processes must be tracked so they can be killed on parent\n * shutdown signals (SIGHUP/SIGTERM).\n */\nconst trackedDetachedChildPids = new Set<number>();\n\nexport function trackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.add(pid);\n}\n\nexport function untrackDetachedChildPid(pid: number): void {\n\ttrackedDetachedChildPids.delete(pid);\n}\n\nexport function killTrackedDetachedChildren(): void {\n\tfor (const pid of trackedDetachedChildPids) {\n\t\tkillProcessTree(pid);\n\t}\n\ttrackedDetachedChildPids.clear();\n}\n\n/**\n * Kill a process and all its children (cross-platform)\n */\nexport function killProcessTree(pid: number): void {\n\tif (process.platform === \"win32\") {\n\t\t// Use taskkill on Windows to kill process tree\n\t\ttry {\n\t\t\tspawn(\"taskkill\", [\"/F\", \"/T\", \"/PID\", String(pid)], {\n\t\t\t\tstdio: \"ignore\",\n\t\t\t\tdetached: true,\n\t\t\t});\n\t\t} catch {\n\t\t\t// Ignore errors if taskkill fails\n\t\t}\n\t} else {\n\t\t// Use SIGKILL on Unix/Linux/Mac\n\t\ttry {\n\t\t\tprocess.kill(-pid, \"SIGKILL\");\n\t\t} catch {\n\t\t\t// Fallback to killing just the child if process group kill fails\n\t\t\ttry {\n\t\t\t\tprocess.kill(pid, \"SIGKILL\");\n\t\t\t} catch {\n\t\t\t\t// Process already dead\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -227,7 +227,7 @@ models: [{
227
227
  }]
228
228
  ```
229
229
 
230
- Use `openrouter` for OpenRouter-style `reasoning: { effort }` controls. Use `together` for Together-style `reasoning: { enabled }` controls; with `supportsReasoningEffort`, it also sends `reasoning_effort`. Use `qwen-chat-template` instead for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking`.
230
+ Use `openrouter` for OpenRouter-style `reasoning: { effort }` controls. Use `together` for Together-style `reasoning: { enabled }` controls; with `supportsReasoningEffort`, it also sends `reasoning_effort`. Use `qwen-chat-template` for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking` and need `preserve_thinking`.
231
231
  Use `cacheControlFormat: "anthropic"` for OpenAI-compatible providers that expose Anthropic-style prompt caching via `cache_control` on the system prompt, last tool definition, and last user/assistant text content.
232
232
 
233
233
  > Migration note: Mistral moved from `openai-completions` to `mistral-conversations`.
@@ -642,11 +642,12 @@ interface ProviderModelConfig {
642
642
  requiresAssistantAfterToolResult?: boolean;
643
643
  requiresThinkingAsText?: boolean;
644
644
  requiresReasoningContentOnAssistantMessages?: boolean;
645
- thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "zai" | "qwen" | "qwen-chat-template";
645
+ thinkingFormat?: "openai" | "openrouter" | "deepseek" | "together" | "zai" | "qwen" | "chat-template" | "qwen-chat-template" | "string-thinking" | "ant-ling";
646
+ chatTemplateKwargs?: Record<string, string | number | boolean | null | { "$var": "thinking.enabled" | "thinking.effort"; omitWhenOff?: boolean }>;
646
647
  cacheControlFormat?: "anthropic";
647
648
  };
648
649
  }
649
650
  ```
650
651
 
651
- `openrouter` sends `reasoning: { effort }`. `deepseek` sends `thinking: { type: "enabled" | "disabled" }` and `reasoning_effort` when enabled. `together` sends `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` is for DashScope-style top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking`.
652
+ `openrouter` sends `reasoning: { effort }`. `deepseek` sends `thinking: { type: "enabled" | "disabled" }` and `reasoning_effort` when enabled. `together` sends `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` is for DashScope-style top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that read `chat_template_kwargs.enable_thinking` and need `preserve_thinking`. Use `chat-template` for configurable `chat_template_kwargs`, for example DeepSeek V3.x behind vLLM with `chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } }`.
652
653
  `cacheControlFormat: "anthropic"` applies Anthropic-style `cache_control` markers to the system prompt, last tool definition, and last user/assistant text content.
package/docs/models.md CHANGED
@@ -461,14 +461,15 @@ For providers with partial OpenAI compatibility, use the `compat` field.
461
461
  | `requiresAssistantAfterToolResult` | Insert an assistant message before a user message after tool results |
462
462
  | `requiresThinkingAsText` | Convert thinking blocks to plain text |
463
463
  | `requiresReasoningContentOnAssistantMessages` | Include empty `reasoning_content` on all replayed assistant messages when reasoning is enabled |
464
- | `thinkingFormat` | Use `reasoning_effort`, `openrouter`, `deepseek`, `together`, `zai`, `qwen`, or `qwen-chat-template` thinking parameters |
464
+ | `thinkingFormat` | Use `reasoning_effort`, `openrouter`, `deepseek`, `together`, `zai`, `qwen`, `chat-template`, or `qwen-chat-template` thinking parameters |
465
+ | `chatTemplateKwargs` | `chat_template_kwargs` values for `thinkingFormat: "chat-template"`; use `{ "$var": "thinking.enabled" }` or `{ "$var": "thinking.effort" }` for Atomic-controlled thinking values |
465
466
  | `cacheControlFormat` | Use Anthropic-style `cache_control` markers on the system prompt, last tool definition, and last user/assistant text content. Currently only `anthropic` is supported. |
466
467
  | `supportsStrictMode` | Include the `strict` field in tool definitions |
467
468
  | `supportsLongCacheRetention` | Whether the provider accepts long cache retention when cache retention is `long`: `prompt_cache_retention: "24h"` for OpenAI prompt caching, or `cache_control.ttl: "1h"` when `cacheControlFormat` is `anthropic`. Default: `true`. |
468
469
  | `openRouterRouting` | OpenRouter provider routing preferences. This object is sent as-is in the `provider` field of the [OpenRouter API request](https://openrouter.ai/docs/guides/routing/provider-selection). |
469
470
  | `vercelGatewayRouting` | Vercel AI Gateway routing config for provider selection (`only`, `order`) |
470
471
 
471
- `openrouter` uses `reasoning: { effort }`. `together` uses `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` uses top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that require `chat_template_kwargs.enable_thinking`.
472
+ `openrouter` uses `reasoning: { effort }`. `together` uses `reasoning: { enabled }` and also `reasoning_effort` when `supportsReasoningEffort` is enabled. `qwen` uses top-level `enable_thinking`. Use `qwen-chat-template` for local Qwen-compatible servers that require `chat_template_kwargs.enable_thinking` and `preserve_thinking`. Use `chat-template` for vLLM/Hugging Face chat templates that need configurable `chat_template_kwargs`, such as `chatTemplateKwargs: { "thinking": { "$var": "thinking.enabled" } }` for DeepSeek V3.x templates.
472
473
 
473
474
  `cacheControlFormat: "anthropic"` is for OpenAI-compatible providers that expose Anthropic-style prompt caching through `cache_control` markers on text content and tool definitions.
474
475
 
package/docs/packages.md CHANGED
@@ -174,7 +174,7 @@ If no app manifest (`atomic`, or legacy `pi`) is present, Atomic auto-discovers
174
174
  - `skills/` recursively finds `SKILL.md` folders and loads top-level `.md` files as skills
175
175
  - `prompts/` loads `.md` files
176
176
  - `themes/` loads `.json` files
177
- - `workflows/` loads workflow SDK files (`.ts`, `.js`, `.mjs`, `.cjs`); `workflow/` is also accepted as a singular alias. Workflow files should `import { defineWorkflow, Type } from "@bastani/workflows"` and export `defineWorkflow(...).compile()` output. TypeScript package authors do not need a hand-authored `.d.ts`, a `declare module` shim, or a `tsconfig` `paths` alias for the SDK import — the SDK types ship with `@bastani/atomic`. A package that also imports `@bastani/atomic` picks them up automatically; a pure workflow-only package adds one opt-in line (`compilerOptions.types: ["@bastani/atomic/workflows/ambient"]` or a `/// <reference types="@bastani/atomic/workflows/ambient" />` directive). See the workflow SDK typing guidance under Programmatic Usage in the workflows guide.
177
+ - `workflows/` loads workflow SDK files (`.ts`, `.js`, `.mjs`, `.cjs`); `workflow/` is also accepted as a singular alias. Workflow files should `import { workflow } from "@bastani/workflows"`, import `Type` from `typebox`, and export the `workflow({ ... })` result. TypeScript package authors do not need a hand-authored `.d.ts`, a `declare module` shim, or a `tsconfig` `paths` alias for the SDK import — the SDK types ship with `@bastani/atomic`. A package that also imports `@bastani/atomic` picks them up automatically; a pure workflow-only package adds one opt-in line (`compilerOptions.types: ["@bastani/atomic/workflows/ambient"]` or a `/// <reference types="@bastani/atomic/workflows/ambient" />` directive). See the workflow SDK typing guidance under Programmatic Usage in the workflows guide.
178
178
 
179
179
  When a package manifest exists, declared resource arrays normally define what loads. Workflows are the exception: if `atomic.workflows` / legacy `pi.workflows` is omitted, Atomic still checks conventional `workflows/` and `workflow/` directories.
180
180
 
@@ -184,7 +184,7 @@ Third-party runtime dependencies belong in `dependencies` in `package.json`. Dep
184
184
 
185
185
  Atomic bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@earendil-works/pi-ai`, `@earendil-works/pi-agent-core`, `@bastani/atomic`, `@earendil-works/pi-tui`, `typebox`.
186
186
 
187
- Workflow packages should author workflow files with `import { defineWorkflow, Type } from "@bastani/workflows"` and export definitions produced by `defineWorkflow(...).compile()`. Do not use the removed `runWorkflow` object-form API, and do not hand-roll objects with `__piWorkflow: true`; discovery accepts only compiled definitions. `@bastani/workflows` is not a separate npm package: its types resolve through `@bastani/atomic`, so list `@bastani/atomic` and `typebox` in `peerDependencies` (the workflow SDK's emitted types reference `typebox`). A pure workflow-only package also adds the one-line ambient opt-in noted above; a package that imports `@bastani/atomic` elsewhere picks the types up automatically.
187
+ Workflow packages should author workflow files with `import { workflow } from "@bastani/workflows"`, `import { Type } from "typebox"`, and export definitions produced by `workflow({ ... })`. Do not use the removed `runWorkflow` object-form API, and do not hand-roll objects with `__piWorkflow: true`; discovery accepts only definitions minted by `workflow({ ... })`. `@bastani/workflows` is not a separate npm package: its types resolve through `@bastani/atomic`, so list `@bastani/atomic` and `typebox` in `peerDependencies`. A pure workflow-only package also adds the one-line ambient opt-in noted above; a package that imports `@bastani/atomic` elsewhere picks the types up automatically.
188
188
 
189
189
  Package-authored workflows should follow the same guiding principles as project workflows mentioned in docs/workflows.md.
190
190
 
@@ -164,7 +164,7 @@ consolidates findings into blockers vs. suggestions and returns
164
164
  Atomic will:
165
165
 
166
166
  - ask clarifying questions if stage purpose, inputs, models, or handoffs are ambiguous,
167
- - write a `.atomic/workflows/<name>.ts` definition that uses `defineWorkflow(...).input(...).run(...).compile()`,
167
+ - write a `.atomic/workflows/<name>.ts` definition that uses `workflow({ ... })` and imports `Type` from `typebox`,
168
168
  - and run `/workflow reload` so the generated workflow is rediscovered and can be launched with `/workflow <name>`.
169
169
 
170
170
  The same plain-chat approach works for editing or hardening an existing workflow — ask Atomic to add a stage, switch a model, save artifacts, or wire in a human approval gate. For the full authoring reference, see [Workflows](/workflows). The authoring guide also covers [workflow composition](/workflows#workflow-composition), including calling user-defined workflows or builtin workflows such as `deep-research-codebase`, `goal`, and `ralph` from `@bastani/workflows/builtin`.
package/docs/sdk.md CHANGED
@@ -539,45 +539,9 @@ const { session } = await createAgentSession({
539
539
  });
540
540
  ```
541
541
 
542
- #### Bash command policy
542
+ #### Bash tool behavior
543
543
 
544
- `bashPolicy` narrows what the built-in `bash` tool may execute after `tools`/`excludedTools` have already decided that `bash` is exposed. It does not grant shell access by itself.
545
-
546
- ```typescript
547
- import { createAgentSession, type BashCommandPolicy } from "@bastani/atomic";
548
-
549
- const playwrightCliOnly: BashCommandPolicy = {
550
- default: "deny",
551
- allow: [
552
- "which playwright-cli",
553
- { prefix: "playwright-cli " },
554
- { prefix: "grep " },
555
- { glob: "bun test test/unit/*.test.ts" },
556
- { regex: "^rg\\b" },
557
- ],
558
- deny: [{ regex: "\\brm\\b" }], // deny rules win over allow rules
559
- // match defaults to "segments"
560
- };
561
-
562
- const { session } = await createAgentSession({
563
- tools: ["read", "bash"],
564
- bashPolicy: playwrightCliOnly,
565
- });
566
- ```
567
-
568
- Rules match exact command strings, prefixes, command-string globs, or JavaScript regular expressions. `default` defaults to `"allow"` for backward compatibility; set `default: "deny"` for an allowlist-only shell. Omitting `bashPolicy`, passing `{}`, or passing a default-allow policy with no `allow`/`deny` rules is a compatibility no-op and does not parse the command. Empty `allow`/`deny` arrays and match-only default-allow policies are treated the same; malformed policy objects still fail closed.
569
-
570
- Glob rules match command target strings, not filesystem path segments. `*` and `?` can match `/`, so `{ glob: "playwright-cli *" }` matches `playwright-cli http://localhost:3000`, `playwright-cli docs/index.html`, and `playwright-cli ./preview/output.html`, while still matching the whole target so `echo playwright-cli docs/index.html` does not match unless the pattern includes leading wildcards. Backslash escapes the next glob character when you need a literal `*`, `?`, or bracket; inside bracket classes, escaped metacharacters such as `\-`, `\^`, `\]`, `\[`, and `\\` stay literal instead of becoming regex ranges, negation markers, class delimiters, or backslash escapes. Malformed glob bracket classes or ranges, such as `{ glob: "echo [z-a]" }`, fail closed as `invalid-policy` rather than surfacing raw regular-expression errors.
571
-
572
- Runtime policy validation is part of enforcement for JavaScript/JSON callers: a provided policy must be a non-null object with only the top-level keys `default`, `allow`, `deny`, and `match`; typoed or extra keys such as `denny` or `extra` are rejected as `invalid-policy` even when the policy otherwise looks like default-allow. `allow`/`deny` must be arrays when present, rules must be non-empty strings or one-variant objects with string values, regex flags must be strings, and invalid regexes, invalid globs, or stateful `g`/`y` flags are rejected as `invalid-policy` before shell execution.
573
-
574
- By default, `match: "segments"` parses shell separators and substitutions and requires every executable segment to pass. Separators include pipes, `&&`, `||`, `;`, background `&`, and unquoted line terminators: LF, CRLF, and bare CR are command separators rather than ordinary whitespace. Bash noclobber redirection `>|` is treated as redirection syntax rather than a pipeline separator after a command head, so `echo ok >|/tmp/out` remains one `echo` segment. For example, `playwright-cli snapshot | grep title` must satisfy both the `playwright-cli` rule and the `grep` rule, and `playwright-cli snapshot; rm -rf /` or `playwright-cli snapshot\nrm -rf /` is blocked when `rm` is denied or when `default: "deny"` has no matching allow rule. Segment mode also checks command substitutions (`$(...)`, backticks) and process substitutions (`<(...)`, `>(...)`). Syntax Atomic cannot safely segment is rejected before a shell process starts.
575
-
576
- Segment mode requires each command head to be a statically identifiable literal word. Literal names such as `grep`, `./script`, `/usr/bin/env`, `bun`, `playwright-cli`, and names containing hyphens, underscores, dots, or slashes are accepted when they contain no shell expansion syntax. Atomic conservatively rejects Bash reserved words and compound introducers (`coproc`, `if`, `for`, `while`, `case`, `{`, `}`, `!`), leading redirection syntax (`>file cmd`, `2>file cmd`, `<file cmd`, `&>file cmd`, `>|file cmd`, `<&0 cmd`, `>&2 cmd`), redirection operators attached to the command-head word (`cmd>file`, `cmd>>file`, `cmd>|file`, `cmd2>file`, `cmd>&2`, `cmd</tmp/in`), leading environment assignment words (`PATH=/tmp:$PATH playwright-cli snapshot`, `LD_PRELOAD=/tmp/x playwright-cli snapshot`, `FOO=bar`), variable or parameter-expanded heads (`$cmd`, `${cmd}`), quote- or escape-constructed heads (`r''m`, `"rm"`, `r\m`), tilde/glob/brace-expanded heads (`~/bin/rm`, `r*m`, `{rm,echo}`), and command/process substitutions or backticks embedded in the head. Substitutions in argument positions are still parsed so nested commands must also pass the policy.
577
-
578
- Use `match: "whole"` only when you intentionally want rules to match the raw command string as-is. Whole-command prefix rules can allow shell operators inside the same raw string.
579
-
580
- `AgentSession.executeBash()` applies the same session `bashPolicy` before adding any configured command prefix or invoking the execution backend.
544
+ Atomic's built-in `bash` tool matches upstream pi: when `bash` is enabled, commands execute through the configured shell with the Atomic process permissions. Use `tools`, `excludedTools`, or `noTools` to decide whether a session exposes the `bash` tool at all. Atomic no longer provides a command-level allow/deny option for `bash`; use an operating-system/container sandbox or a custom tool/extension when you need command allowlisting or stronger isolation.
581
545
 
582
546
  #### Tools with Custom cwd
583
547
 
@@ -1284,8 +1248,6 @@ createGrepTool, createFindTool, createLsTool
1284
1248
  // Types
1285
1249
  type CreateAgentSessionOptions
1286
1250
  type CreateAgentSessionResult
1287
- type BashCommandPolicy
1288
- type BashCommandRule
1289
1251
  type StructuredOutputCapture
1290
1252
  type StructuredOutputToolOptions
1291
1253
  type ExtensionFactory
package/docs/security.md CHANGED
@@ -33,7 +33,7 @@ This is intentional. Atomic is designed to operate on local source trees, invoke
33
33
 
34
34
  Project trust is only an input-loading guard. It prevents a repository from silently changing Atomic's settings or extensions before you approve it. It does not make untrusted code, untrusted prompts, or untrusted model output safe. Prompt injection from repository files, comments, documentation, context files, or build output is expected local-agent risk and cannot be reliably prevented by Atomic.
35
35
 
36
- `bashPolicy` is a command-scoping guardrail for the built-in `bash` tool, not a sandbox. It can block model-supplied commands before shell execution, including disallowed segments in pipelines, command substitutions, process substitutions, and unquoted newline-separated commands (LF, CRLF, or bare CR). In segment mode, Atomic also rejects reserved or compound shell heads such as `coproc`, `if`, `for`, `while`, `case`, `{`, `}`, and `!`; leading redirection syntax such as `>file command`, `2>file command`, `<file command`, `&>file command`, `>|file command`, `<&0 command`, or `>&2 command`; redirection operators attached to the command head such as `cmd>file`, `cmd>>file`, `cmd>|file`, `cmd2>file`, `cmd>&2`, or `cmd</tmp/in`; leading environment assignments (`PATH=... command`, `LD_PRELOAD=... command`, assignment-only segments); and non-literal command heads such as variable-expanded, quote/escape-constructed, glob/brace/tilde-expanded, or substitution-built executable names instead of trying to normalize shell syntax. Non-leading Bash noclobber redirection `>|` after a literal command head is treated as redirection syntax rather than a pipeline separator, so it stays within the current command segment. Runtime-malformed policy objects, including typoed or extra top-level keys outside `default`, `allow`, `deny`, and `match`, fail closed rather than being partially interpreted, malformed glob bracket ranges become `invalid-policy` denials instead of raw JavaScript errors, and escaped glob bracket-class metacharacters such as `\-`, `\^`, `\]`, `\[`, and `\\` stay literal. Glob rules are command-string patterns where `*` and `?` may match `/`; they scope command text, not filesystem access. Default-allow policies with no allow/deny rules intentionally preserve legacy behavior and do not parse commands unless the policy object itself is invalid. `bashPolicy` cannot restrict what an allowed program does after it starts, and it does not isolate files, network access, credentials, shell startup behavior, aliases/functions, or child processes. Be especially careful when allowing interpreters, shells, package managers, `curl`, `git`, `sudo`, `env`, `xargs`, or other programs that can delegate arbitrary work.
36
+ The built-in `bash` tool follows upstream pi behavior: if the tool is enabled, model-supplied commands run through the configured shell with the same permissions as the Atomic process. Atomic does not provide command-level allow/deny policy for `bash`. Use `tools`, `excludedTools`, or `noTools` to decide whether a session exposes shell access at all, and use a container, VM, remote sandbox, restricted OS account, or custom extension/tool when you need command allowlisting or stronger isolation. Be especially careful with interpreters, shells, package managers, `curl`, `git`, `sudo`, `env`, `xargs`, or other programs that can delegate arbitrary work.
37
37
 
38
38
  ## Running Untrusted or Unmonitored Work
39
39