@namzu/sdk 45.0.0 → 45.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/authorization/gate.d.ts.map +1 -1
  3. package/dist/authorization/gate.js +12 -2
  4. package/dist/authorization/gate.js.map +1 -1
  5. package/dist/authorization/rules.d.ts.map +1 -1
  6. package/dist/authorization/rules.js +37 -6
  7. package/dist/authorization/rules.js.map +1 -1
  8. package/dist/authorization/shell-lexer.d.ts +14 -0
  9. package/dist/authorization/shell-lexer.d.ts.map +1 -1
  10. package/dist/authorization/shell-lexer.js +19 -6
  11. package/dist/authorization/shell-lexer.js.map +1 -1
  12. package/dist/bridge/a2a/mapper.d.ts.map +1 -1
  13. package/dist/bridge/a2a/mapper.js +2 -0
  14. package/dist/bridge/a2a/mapper.js.map +1 -1
  15. package/dist/bridge/sse/mapper.d.ts.map +1 -1
  16. package/dist/bridge/sse/mapper.js +1 -0
  17. package/dist/bridge/sse/mapper.js.map +1 -1
  18. package/dist/directory/types.d.ts +2 -0
  19. package/dist/directory/types.d.ts.map +1 -1
  20. package/dist/directory/types.js.map +1 -1
  21. package/dist/manager/resident/outbox.d.ts +4 -4
  22. package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
  23. package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
  24. package/dist/prompt/coding-agent-doctrine.js +1 -0
  25. package/dist/prompt/coding-agent-doctrine.js.map +1 -1
  26. package/dist/public-runtime.d.ts +4 -1
  27. package/dist/public-runtime.d.ts.map +1 -1
  28. package/dist/public-runtime.js +11 -1
  29. package/dist/public-runtime.js.map +1 -1
  30. package/dist/public-tools.d.ts +4 -0
  31. package/dist/public-tools.d.ts.map +1 -1
  32. package/dist/public-tools.js +10 -0
  33. package/dist/public-tools.js.map +1 -1
  34. package/dist/public-types.d.ts +7 -1
  35. package/dist/public-types.d.ts.map +1 -1
  36. package/dist/runtime/query/declined.d.ts +12 -0
  37. package/dist/runtime/query/declined.d.ts.map +1 -0
  38. package/dist/runtime/query/declined.js +12 -0
  39. package/dist/runtime/query/declined.js.map +1 -0
  40. package/dist/runtime/query/executor.d.ts +3 -1
  41. package/dist/runtime/query/executor.d.ts.map +1 -1
  42. package/dist/runtime/query/executor.js +14 -2
  43. package/dist/runtime/query/executor.js.map +1 -1
  44. package/dist/runtime/query/index.d.ts.map +1 -1
  45. package/dist/runtime/query/index.js +1 -0
  46. package/dist/runtime/query/index.js.map +1 -1
  47. package/dist/runtime/query/iteration/index.d.ts.map +1 -1
  48. package/dist/runtime/query/iteration/index.js +7 -0
  49. package/dist/runtime/query/iteration/index.js.map +1 -1
  50. package/dist/runtime/query/iteration/phases/context.d.ts +6 -0
  51. package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
  52. package/dist/runtime/query/iteration/phases/context.js.map +1 -1
  53. package/dist/runtime/query/iteration/phases/handoff.d.ts +22 -0
  54. package/dist/runtime/query/iteration/phases/handoff.d.ts.map +1 -0
  55. package/dist/runtime/query/iteration/phases/handoff.js +65 -0
  56. package/dist/runtime/query/iteration/phases/handoff.js.map +1 -0
  57. package/dist/runtime/query/iteration/phases/index.d.ts +1 -0
  58. package/dist/runtime/query/iteration/phases/index.d.ts.map +1 -1
  59. package/dist/runtime/query/iteration/phases/index.js +1 -0
  60. package/dist/runtime/query/iteration/phases/index.js.map +1 -1
  61. package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
  62. package/dist/runtime/query/iteration/phases/tool-review.js +8 -3
  63. package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
  64. package/dist/runtime/query/resume-pending.d.ts.map +1 -1
  65. package/dist/runtime/query/resume-pending.js +3 -2
  66. package/dist/runtime/query/resume-pending.js.map +1 -1
  67. package/dist/runtime/query/review-policy.d.ts.map +1 -1
  68. package/dist/runtime/query/review-policy.js +4 -3
  69. package/dist/runtime/query/review-policy.js.map +1 -1
  70. package/dist/schedules/cron.d.ts +21 -0
  71. package/dist/schedules/cron.d.ts.map +1 -0
  72. package/dist/schedules/cron.js +167 -0
  73. package/dist/schedules/cron.js.map +1 -0
  74. package/dist/schedules/describe.d.ts +14 -0
  75. package/dist/schedules/describe.d.ts.map +1 -0
  76. package/dist/schedules/describe.js +133 -0
  77. package/dist/schedules/describe.js.map +1 -0
  78. package/dist/schedules/errors.d.ts +11 -0
  79. package/dist/schedules/errors.d.ts.map +1 -0
  80. package/dist/schedules/errors.js +15 -0
  81. package/dist/schedules/errors.js.map +1 -0
  82. package/dist/schedules/evaluate.d.ts +35 -0
  83. package/dist/schedules/evaluate.d.ts.map +1 -0
  84. package/dist/schedules/evaluate.js +158 -0
  85. package/dist/schedules/evaluate.js.map +1 -0
  86. package/dist/schedules/index.d.ts +11 -0
  87. package/dist/schedules/index.d.ts.map +1 -0
  88. package/dist/schedules/index.js +8 -0
  89. package/dist/schedules/index.js.map +1 -0
  90. package/dist/schedules/next-fire.d.ts +50 -0
  91. package/dist/schedules/next-fire.d.ts.map +1 -0
  92. package/dist/schedules/next-fire.js +250 -0
  93. package/dist/schedules/next-fire.js.map +1 -0
  94. package/dist/schedules/spec.d.ts +30 -0
  95. package/dist/schedules/spec.d.ts.map +1 -0
  96. package/dist/schedules/spec.js +169 -0
  97. package/dist/schedules/spec.js.map +1 -0
  98. package/dist/schedules/types.d.ts +144 -0
  99. package/dist/schedules/types.d.ts.map +1 -0
  100. package/dist/schedules/types.js +11 -0
  101. package/dist/schedules/types.js.map +1 -0
  102. package/dist/schedules/tz.d.ts +44 -0
  103. package/dist/schedules/tz.d.ts.map +1 -0
  104. package/dist/schedules/tz.js +141 -0
  105. package/dist/schedules/tz.js.map +1 -0
  106. package/dist/skills/index.d.ts +1 -1
  107. package/dist/skills/index.d.ts.map +1 -1
  108. package/dist/skills/index.js +1 -1
  109. package/dist/skills/index.js.map +1 -1
  110. package/dist/skills/loader.d.ts +16 -3
  111. package/dist/skills/loader.d.ts.map +1 -1
  112. package/dist/skills/loader.js +48 -4
  113. package/dist/skills/loader.js.map +1 -1
  114. package/dist/tools/builtins/browser-url.d.ts +83 -0
  115. package/dist/tools/builtins/browser-url.d.ts.map +1 -0
  116. package/dist/tools/builtins/browser-url.js +240 -0
  117. package/dist/tools/builtins/browser-url.js.map +1 -0
  118. package/dist/tools/builtins/browser.d.ts +367 -0
  119. package/dist/tools/builtins/browser.d.ts.map +1 -0
  120. package/dist/tools/builtins/browser.js +704 -0
  121. package/dist/tools/builtins/browser.js.map +1 -0
  122. package/dist/tools/builtins/skill.d.ts.map +1 -1
  123. package/dist/tools/builtins/skill.js +15 -0
  124. package/dist/tools/builtins/skill.js.map +1 -1
  125. package/dist/tools/defineTool.d.ts +2 -0
  126. package/dist/tools/defineTool.d.ts.map +1 -1
  127. package/dist/tools/defineTool.js +1 -0
  128. package/dist/tools/defineTool.js.map +1 -1
  129. package/dist/tools/schedules/index.d.ts +5 -0
  130. package/dist/tools/schedules/index.d.ts.map +1 -0
  131. package/dist/tools/schedules/index.js +4 -0
  132. package/dist/tools/schedules/index.js.map +1 -0
  133. package/dist/tools/schedules/loop-tool.d.ts +14 -0
  134. package/dist/tools/schedules/loop-tool.d.ts.map +1 -0
  135. package/dist/tools/schedules/loop-tool.js +81 -0
  136. package/dist/tools/schedules/loop-tool.js.map +1 -0
  137. package/dist/tools/schedules/present.d.ts +16 -0
  138. package/dist/tools/schedules/present.d.ts.map +1 -0
  139. package/dist/tools/schedules/present.js +69 -0
  140. package/dist/tools/schedules/present.js.map +1 -0
  141. package/dist/tools/schedules/prompt-scan.d.ts +17 -0
  142. package/dist/tools/schedules/prompt-scan.d.ts.map +1 -0
  143. package/dist/tools/schedules/prompt-scan.js +92 -0
  144. package/dist/tools/schedules/prompt-scan.js.map +1 -0
  145. package/dist/tools/schedules/schedule-tool.d.ts +16 -0
  146. package/dist/tools/schedules/schedule-tool.d.ts.map +1 -0
  147. package/dist/tools/schedules/schedule-tool.js +327 -0
  148. package/dist/tools/schedules/schedule-tool.js.map +1 -0
  149. package/dist/tools/schedules/types.d.ts +184 -0
  150. package/dist/tools/schedules/types.d.ts.map +1 -0
  151. package/dist/tools/schedules/types.js +11 -0
  152. package/dist/tools/schedules/types.js.map +1 -0
  153. package/dist/types/authorization/index.d.ts +86 -9
  154. package/dist/types/authorization/index.d.ts.map +1 -1
  155. package/dist/types/authorization/index.js +11 -1
  156. package/dist/types/authorization/index.js.map +1 -1
  157. package/dist/types/browser/index.d.ts +280 -0
  158. package/dist/types/browser/index.d.ts.map +1 -0
  159. package/dist/types/browser/index.js +12 -0
  160. package/dist/types/browser/index.js.map +1 -0
  161. package/dist/types/session/events.d.ts +6 -0
  162. package/dist/types/session/events.d.ts.map +1 -1
  163. package/dist/types/session/events.js.map +1 -1
  164. package/dist/types/session/records.d.ts +23 -0
  165. package/dist/types/session/records.d.ts.map +1 -1
  166. package/dist/types/session/records.js +9 -0
  167. package/dist/types/session/records.js.map +1 -1
  168. package/dist/types/tool/index.d.ts +41 -0
  169. package/dist/types/tool/index.d.ts.map +1 -1
  170. package/dist/types/tool/index.js.map +1 -1
  171. package/dist/types/tool/presentation.d.ts +7 -0
  172. package/dist/types/tool/presentation.d.ts.map +1 -1
  173. package/dist/utils/frontmatter.d.ts +18 -2
  174. package/dist/utils/frontmatter.d.ts.map +1 -1
  175. package/dist/utils/frontmatter.js +13 -3
  176. package/dist/utils/frontmatter.js.map +1 -1
  177. package/dist/utils/id.d.ts +8 -0
  178. package/dist/utils/id.d.ts.map +1 -1
  179. package/dist/utils/id.js +12 -0
  180. package/dist/utils/id.js.map +1 -1
  181. package/package.json +1 -1
  182. package/src/authorization/gate.ts +14 -2
  183. package/src/authorization/rules.ts +37 -7
  184. package/src/authorization/shell-lexer.ts +36 -6
  185. package/src/bridge/a2a/mapper.ts +2 -0
  186. package/src/bridge/sse/mapper.ts +1 -0
  187. package/src/directory/types.ts +2 -0
  188. package/src/prompt/coding-agent-doctrine.ts +1 -0
  189. package/src/public-runtime.ts +28 -0
  190. package/src/public-tools.ts +35 -0
  191. package/src/public-types.ts +50 -0
  192. package/src/runtime/query/declined.ts +12 -0
  193. package/src/runtime/query/executor.ts +17 -1
  194. package/src/runtime/query/index.ts +1 -0
  195. package/src/runtime/query/iteration/index.ts +8 -0
  196. package/src/runtime/query/iteration/phases/context.ts +6 -0
  197. package/src/runtime/query/iteration/phases/handoff.ts +74 -0
  198. package/src/runtime/query/iteration/phases/index.ts +1 -0
  199. package/src/runtime/query/iteration/phases/tool-review.ts +11 -4
  200. package/src/runtime/query/resume-pending.ts +3 -2
  201. package/src/runtime/query/review-policy.ts +4 -3
  202. package/src/schedules/cron.ts +202 -0
  203. package/src/schedules/describe.ts +138 -0
  204. package/src/schedules/errors.ts +15 -0
  205. package/src/schedules/evaluate.ts +178 -0
  206. package/src/schedules/index.ts +18 -0
  207. package/src/schedules/next-fire.ts +257 -0
  208. package/src/schedules/spec.ts +210 -0
  209. package/src/schedules/types.ts +163 -0
  210. package/src/schedules/tz.ts +155 -0
  211. package/src/skills/index.ts +1 -1
  212. package/src/skills/loader.ts +55 -4
  213. package/src/tools/builtins/browser-url.ts +251 -0
  214. package/src/tools/builtins/browser.ts +817 -0
  215. package/src/tools/builtins/skill.ts +18 -0
  216. package/src/tools/defineTool.ts +3 -0
  217. package/src/tools/schedules/index.ts +4 -0
  218. package/src/tools/schedules/loop-tool.ts +85 -0
  219. package/src/tools/schedules/present.ts +86 -0
  220. package/src/tools/schedules/prompt-scan.ts +96 -0
  221. package/src/tools/schedules/schedule-tool.ts +376 -0
  222. package/src/tools/schedules/types.ts +197 -0
  223. package/src/types/authorization/index.ts +60 -2
  224. package/src/types/browser/index.ts +341 -0
  225. package/src/types/session/events.ts +6 -0
  226. package/src/types/session/records.ts +10 -0
  227. package/src/types/tool/index.ts +42 -0
  228. package/src/types/tool/presentation.ts +7 -0
  229. package/src/utils/frontmatter.ts +29 -3
  230. package/src/utils/id.ts +14 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,60 @@
1
1
  # Changelog
2
2
 
3
+ ## 45.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 2b96136: Add the browser tool contract, let `argument_pattern` rules ask for review, and let a scheduled-job proposal carry a browser grant.
8
+
9
+ **Browser tools (new).** `createBrowserTools(host)` returns two tools over a `BrowserHost` you supply: `browser` (navigate, back, forward, reload, snapshot, screenshot, scroll, wait_for, tabs) and `browser_act` (click, type, fill_form, select, press, hover, upload, dialog). The SDK ships no browser engine. Every `browser_act` call carries a required `origin`, and the host contract says the host compares it with the live page before acting. `url` and `origin` are canonicalised by the input schema (WHATWG form, punycode, no default port, no trailing dot on the host). Other schemes, credentials in the URL and cloud metadata addresses in any spelling are refused. Because the gate sees the canonical value, a site rule matches the address the browser loads. Page text is returned inside `wrapUntrusted`, under a `Page: <origin> — "<title>" (tab tN)` header. Hosts refuse by throwing structural shapes (`browser_origin_mismatch`, `browser_stale_ref`, `browser_human_required`, `browser_outcome_unknown`, `browser_site_denied`). New exports: `createBrowserTools`, `BROWSER_TOOL_NAME`, `BROWSER_ACT_TOOL_NAME`, `isBrowserCallReadOnly`, `browserHostErrorOf`, `formatBrowserPageHeader`, `canonicalizeBrowserUrl`, `canonicalizeBrowserOrigin`, `canonicalizeBrowserSitePattern`, `isCloudMetadataHost`, `BROWSER_URL_MAX_LENGTH`, `BROWSER_SNAPSHOT_MAX_CHARS`, `BROWSER_WAIT_MAX_MS`, `BROWSER_FILL_FORM_MAX_FIELDS`, and the types in their signatures (`BrowserHost`, `BrowserCapabilities`, the action, result and error types). Both tools are `category: 'network'`. Do not pair them with a preset that allows network tools by category because a sandbox confines egress: the browser runs outside the sandbox.
10
+
11
+ **`argument_pattern` with `decision: 'review'` (widened union).** `AuthorizationRule`'s `argument_pattern` variant now accepts `'review'`. It matches as `deny` does: the whole value, then every segment of a command line. Code that switches exhaustively over that variant's `decision`, or narrows it to `'allow' | 'deny'`, needs a `review` branch. Existing rules behave as before.
12
+
13
+ **`ToolDefinition.urlArgument` (new, optional).** A tool whose input schema canonicalises an argument to a URL can declare it. An `argument_pattern` rule on that argument then tests the value whole, instead of cutting it at `&`, `;` or `|` as a command line, which made an `allow` for a site decline every address with a query string. Tools that do not declare it are unchanged. `defineTool` accepts it too.
14
+
15
+ **Reason text.** A `custom_pattern` rule with `decision: 'review'` is now described as `sent for review by a pattern rule …`; it used to say `allowed by …`. If you match on the old text, update the match.
16
+
17
+ **Scheduled jobs.** `ScheduleJobDraft.permissions.browser?: ScheduleBrowserGrant` (`profile`, `sites` mapping each site to `read`, `ask` or `act`, `headed?`) and `ScheduleToolHost.browserGrants?: boolean` are new. The `schedule` tool refuses a proposed browser grant unless your host sets `browserGrants: true`, so a host that does not know the field keeps working unchanged and never silently drops a grant. It canonicalises site keys and refuses `*`. It also treats the grant as network access, so the grant is refused beside a shell on the host. The refusal for web access beside a host shell now says "web or browser access".
18
+
19
+ See `docs/sdk/browser-tools.md` and `docs/sdk/review-policy.md#rules-that-ask`.
20
+
21
+ - 2b96136: A generic tool result view may now set `outcome: 'cancelled'` for a call the person declined on the tool's own screen. `save_skill` and the `schedule` tool's `create`, `resume` and `delete` use it (the `schedule` tool also sets `data.cancelled` on those results), and the TUI shows the row as `○ … Cancelled — nothing was saved` instead of `✗ … failed: Error: The operator cancelled`. The model still receives the same refusal text.
22
+ - 2b96136: A tool call a person declines without giving a reason now tells the model not to get the same content or result another way — another tool, another site or address, or a web search — unless it asks first and the person agrees. The text was "User declined to run the proposed tool(s)." (and "The user rejected this tool call." on a resumed decision); in a live session a model whose browser navigation was declined fetched the same page through web search instead.
23
+
24
+ New export: `DECLINED_TOOL_CALL_FEEDBACK`, the text. A host that passes its own `feedback` with a refusal is unchanged. A test or host that matched the old default text must match the new one.
25
+
26
+ - d233f26: Add a `predicate` authorization rule, and export the command-line lexer the gate uses.
27
+
28
+ - `AuthorizationRule` gains `{ type: 'predicate', description, decide }`. `decide(call)` receives the tool name, input, definition and the `commandDialect` the line runs in (`sh` when the caller did not say) and returns `allow`, `deny`, `review` or `null`; it sits in its place in the rule list, after the dangerous-command floor. A `decide` that throws is read as `deny`. New types `AuthorizationPredicate` and `AuthorizationPredicateCall`.
29
+ - `lexShellCommandLine` is exported, with `ShellLexResult`, `ShellCommand`, `ShellWord`, `ShellRedirection` and `ShellLexOptions`, so a predicate reads a command line exactly as the gate does.
30
+ - A lexer result also reports `compoundWords` (a `for` or `select` loop's variable and list, a `case` statement's subject and patterns) and, on a here-document redirection, its `body`.
31
+
32
+ Nothing existing changes behaviour. `AuthorizationRule` is also the type of `GateEvaluationResult.matchedRule`: code that switches over `rule.type` with an exhaustive check (`const x: never = rule`) needs a `predicate` case or a `default:` branch to compile.
33
+
34
+ - 2b96136: `ScheduleToolHost.create()` may return an optional `note`, which the `schedule` tool appends to what the model is told about the new job. Existing hosts that return only `{ name }` are unaffected. The CLI uses it to tell the model that no scheduler is installed, so its reply no longer promises a run that cannot happen until you run `namzu schedule install`.
35
+ - d233f26: Add a schedule time engine and evaluator, and the `schedule` and `session_loop` tools.
36
+
37
+ New exports, all additive: `parseScheduleSpec`, `parseCronExpression`, `nextFireTime`, `previousFireTime`, `upcomingFireTimes`, `countOccurrences`, `describeSchedule`, `validateTimeZone`, `hostTimeZone`, `parseDuration`, `evaluateJob`, `ScheduleValidationError`, `SCHEDULE_CATCH_UP_WINDOW_MS`, `SCHEDULE_LATE_GRACE_MS`, `buildScheduleTools`, `buildSessionLoopTools`, `scanSchedulePrompt`, `revealHiddenCharacters`, `SCHEDULE_TOOL_NAME`, `SESSION_LOOP_TOOL_NAME`, `generateScheduleJobId`, `generateScheduleRunId`, and the types in their signatures (`ScheduleSpec` and its three variants, `CronExpression`, `ScheduleEvaluationInput`, `ScheduleDecision`, `ScheduleSkipReason`, `ScheduleMissedReason`, `ScheduleToolHost`, `ScheduleJobDraft`, `ScheduleJobPreview`, `SessionLoopHost`, `SessionLoop` and their neighbours).
38
+
39
+ Everything here is pure: `Intl` for time zones, no clock, no I/O, no new dependency. Cron follows cronie's DST rule (a fixed-time job fires once across a change; a wildcard job fires at every matching instant). Nothing existing changes. `ScheduleDecision`, `ScheduleSkipReason` and `ScheduleMissedReason` may gain members in a later minor release, so switch over them with a `default:` branch. See `docs/sdk/schedules.md`.
40
+
41
+ - 2b96136: `loadSkill` (and so `SkillRegistry`) skips frontmatter keys it does not read, whatever YAML they are written in, instead of refusing the whole file: a `SKILL.md` carrying `argument-hint: [file]` or a `hooks:` block with a list now loads with those fields ignored. The keys it does read are still parsed strictly; they are exported as `SKILL_FRONTMATTER_KEYS`. `disable-model-invocation: true` now reads as `invocation: operator`; a value other than `true` or `false`, or one that contradicts an explicit `invocation`, refuses the file. `parseFrontmatter` takes an optional third argument, `{ readsKey }`, to get the same leniency for a caller's own vocabulary; without it every key is parsed and refused as before. A skill file that used to be refused over an unread key now loads, and one with `disable-model-invocation: true` is no longer offered to the model — nothing else changes.
42
+ - 2b96136: A tool can now stop the turn for a person: return `handoff: { kind: 'human-required', reason, detail? }` on its `ToolResult` (new type `ToolHandoff`). The kernel commits the batch's results, writes a checkpoint and ends the segment with `turn_paused` instead of calling the model again. The event and its session-log record carry the new optional `handoff` field, and the SSE (`turn.paused`) and A2A bridges forward it. `resumeSession` continues the turn from that checkpoint as it does after a provider pause, with a model call that sees the results. In a delegated child (a turn with `parentSessionId`) the handoff fails the child's turn with a non-retryable `tool_error` naming the reason, so the parent receives a failed child result.
43
+
44
+ Nothing changes for tools that do not set the field. A consumer that switches exhaustively on `turn_paused` fields, or validates session-log records with its own strict schema, should accept `handoff`.
45
+
46
+ ### Patch Changes
47
+
48
+ - 2b96136: The `browser` tool's `cursor` field tells the model it is only the `nextCursor` a previous snapshot returned, to be left out for the top of the page, and never a URL. A model passed the page's address as the cursor and got a refusal before it could read the page.
49
+ - 2b96136: A `browser_human_required` refusal from a browser host now pauses the turn. The browser tools set `ToolResult.handoff` (`reason` in words such as `https://github.com is showing a sign-in page`; `detail` carries `tool: 'browser'`, `cause`, `origin`, `profile` and `loginCommand`) as well as `data.handoff`, so the kernel stops before the next model call and waits for the person, as it does for any tool handoff. Before this, the model read the refusal and carried on. Nothing changes for other refusals.
50
+ - 2b96136: The coding-agent working doctrine now tells the model never to change git configuration (`user.name`/`user.email`, hooks, remotes, credential helpers) or other persistent settings without asking. When a commit fails because no identity is set, it tells you the command instead of inventing an identity.
51
+ - 2b96136: The `schedule` tool's input schema now says that `budget` limits one run and that `maxIterations` counts model steps, not repetitions of the job. A model proposed `maxIterations: 1` for a job meant to post once per run, and every run stopped after its first model call. The CLI's confirmation of a job, on a terminal or in the TUI, warns when it allows fewer than 10 iterations.
52
+ - 2b96136: The `schedule` tool asks the model to leave optional fields (folder, time zone, execution, budget, a visible browser window) unset unless the user asked for them, and the TUI's confirmation of a proposed job marks every such value the model set that differs from what you would get by default, e.g. `Chosen by the model, not the default: time zone America/New_York, not this machine's Europe/Istanbul`.
53
+ - 2b96136: A job the model proposes, resumes or deletes in the TUI is confirmed once, on the job's own screen. The permission review no longer asks "Do you want to run schedule?" first in `prompt`, `accept-edits` or `auto`. `plan` and `strict` still refuse the call, a `schedule` rule of `ask` or `deny` still applies, and `pause` is still reviewed. The SDK's `schedule` tool no longer declares `delete` destructive, since the host confirms it before anything is removed; a host that relied on that flag to review deletes should add an `ask` rule for `schedule`.
54
+ - 2b96136: The `schedule` tool no longer refuses a proposal that uses the `read-only` preset with web or browser access as "a shell on the host". The preset denies `bash`, but the check looked only at explicit rules and `unmatched`, so `{ preset: 'read-only', unmatched: 'park', browser: … }` was refused. A proposal with `edit-in-folder`, or with a `bash` rule that is not `deny`, is still refused.
55
+ - 2b96136: The `schedule` tool's input schema describes `budget.tokenBudget` as what the whole run may spend, with every model call resending the prompt, and the CLI's confirmation of a job warns when it allows fewer than 50 000 tokens. A model proposed 4 000 tokens for a browser job whose runs each took about 110 000.
56
+ - 2b96136: The `skill` tool now presents its calls as `Read skill <name>` (or `List skills`) and hides a successful result, so a host shows one row instead of the raw input and the skill's body. In the TUI, the Working row says `Waiting for you` while the screen that saves a skill is open, instead of counting on as if the turn were working.
57
+
3
58
  ## 45.0.0
4
59
 
5
60
  ### Major Changes
@@ -1 +1 @@
1
- {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAgC5D;AAED,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM;IAiHxD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,oBAAoB;CAyDpD"}
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,cAAc,GAAG,SAAS,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CA4C5D;AAED,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;IACnD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,MAAM,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM;IAiHxD,QAAQ,CAAC,GAAG,EAAE,eAAe,GAAG,oBAAoB;CAyDpD"}
@@ -36,14 +36,24 @@ export function describeRule(rule) {
36
36
  // Names the argument, not just the pattern. That is what tells a
37
37
  // model whether a different value could get through — which is the
38
38
  // difference between rewording once and rewording forever.
39
- const verb = rule.decision === 'deny' ? 'denied' : 'allowed';
39
+ const verb = rule.decision === 'deny'
40
+ ? 'denied'
41
+ : rule.decision === 'review'
42
+ ? 'sent for review'
43
+ : 'allowed';
40
44
  return `${verb} because the \`${rule.argument}\` argument matched ${rule.pattern} (this rule applies to ${rule.toolNames.join(', ')})`;
41
45
  }
42
46
  case 'custom_pattern': {
43
47
  const where = rule.target === 'both' ? 'name or arguments' : rule.target;
44
- const verb = rule.decision === 'deny' ? 'denied' : 'allowed';
48
+ const verb = rule.decision === 'deny'
49
+ ? 'denied'
50
+ : rule.decision === 'review'
51
+ ? 'sent for review'
52
+ : 'allowed';
45
53
  return `${verb} by a pattern rule matching the ${where}: ${rule.pattern}`;
46
54
  }
55
+ case 'predicate':
56
+ return rule.description;
47
57
  default: {
48
58
  const exhaustive = rule;
49
59
  return `matched an unrecognised rule: ${JSON.stringify(exhaustive)}`;
@@ -1 +1 @@
1
- {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/authorization/gate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED,wBAAgB,YAAY,CAC3B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,OAAO,GAAE,mBAAwB,GAC/B,YAAY,GAAG,IAAI,CAoJrB"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAA;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;CACtC;AAED,wBAAgB,YAAY,CAC3B,IAAI,EAAE,iBAAiB,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,eAAe,CAAC,EAAE,MAAM,EACxB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,OAAO,GAAE,mBAAwB,GAC/B,YAAY,GAAG,IAAI,CAkLrB"}
@@ -103,20 +103,35 @@ export function evaluateRule(rule, toolName, toolInput, toolDef, compiledPattern
103
103
  // A command line is not one string, and testing it as one is how a
104
104
  // prohibition gets bypassed: `^git push` sees `git push origin main`
105
105
  // and does not see `true; git push origin main`. See
106
- // `decomposeCommandLine` for the measurement and for why the two
106
+ // `decomposeCommandLine` for the measurement and for why the
107
107
  // decisions must read the result differently.
108
- const { segments, opaque } = decomposeCommandLine(subject, dialect);
109
- if (rule.decision === 'deny') {
108
+ //
109
+ // An argument the tool declares as a canonical URL is not a command
110
+ // line, and cutting it at `&` would make an `allow` for a site
111
+ // decline every address with a query string. See
112
+ // `ToolDefinition.urlArgument`.
113
+ const isUrl = toolDef?.urlArgument === rule.argument;
114
+ const { segments, opaque } = isUrl
115
+ ? { segments: [subject], opaque: false }
116
+ : decomposeCommandLine(subject, dialect);
117
+ if (rule.decision === 'deny' || rule.decision === 'review') {
110
118
  // ANY segment. The whole subject is tested first so an
111
119
  // unanchored deny keeps matching across a boundary, which
112
120
  // splitting alone would have taken away. Then each command's
113
121
  // words as bash passes them, so that `'git' push` is `git push`.
122
+ //
123
+ // `review` reads like `deny`, because it is a restriction too: a
124
+ // rule that asks before `git push` must ask before
125
+ // `true; git push` as well. Matching too much costs a prompt;
126
+ // matching too little skips the question the operator asked for.
114
127
  if (compiledPattern.test(subject))
115
- return 'deny';
128
+ return rule.decision;
116
129
  if (segments.some((segment) => compiledPattern.test(segment)))
117
- return 'deny';
130
+ return rule.decision;
131
+ if (isUrl)
132
+ return null;
118
133
  return decodedCommands(subject, dialect).some((text) => compiledPattern.test(text))
119
- ? 'deny'
134
+ ? rule.decision
120
135
  : null;
121
136
  }
122
137
  // EVERY segment, and nothing that hides one. Permission is a claim
@@ -133,6 +148,22 @@ export function evaluateRule(rule, toolName, toolInput, toolDef, compiledPattern
133
148
  }
134
149
  return null;
135
150
  }
151
+ case 'predicate': {
152
+ // A rule that throws has not decided the call is safe. Reading the
153
+ // exception as "no opinion" would let the next rule, or the mode,
154
+ // approve what this one was written to refuse.
155
+ try {
156
+ return rule.decide({
157
+ toolName,
158
+ toolInput,
159
+ toolDef,
160
+ commandDialect: dialect,
161
+ });
162
+ }
163
+ catch {
164
+ return 'deny';
165
+ }
166
+ }
136
167
  default: {
137
168
  const _exhaustive = rule;
138
169
  throw new Error(`Unhandled verification rule type: ${_exhaustive.type}`);
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/authorization/rules.ts"],"names":[],"mappings":"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"}
@@ -81,6 +81,13 @@ export interface ShellRedirection {
81
81
  readonly fd?: string;
82
82
  /** The target word. For a here-document, its delimiter. */
83
83
  readonly target: ShellWord;
84
+ /**
85
+ * A here-document's body as written, up to its delimiter line, once the
86
+ * lexer has read it: the text the command reads on its input, which is
87
+ * a command line of its own when the command is a shell (`bash <<EOF`).
88
+ * Absent for every other operator and for a body the line never reached.
89
+ */
90
+ readonly body?: string;
84
91
  }
85
92
  /** One simple command. */
86
93
  export interface ShellCommand {
@@ -114,6 +121,13 @@ export interface ShellLexResult {
114
121
  * (`{ a; } > f`) that belong to no single simple command.
115
122
  */
116
123
  readonly redirections: readonly ShellRedirection[];
124
+ /**
125
+ * Words that belong to no simple command: a `for` or `select` loop's
126
+ * variable and the words of its list, and a `case` statement's subject
127
+ * and patterns. `for d in ~/x; do rm -r "$d"; done` passes `~/x` to `rm`
128
+ * although no command lists it.
129
+ */
130
+ readonly compoundWords: readonly ShellWord[];
117
131
  /** True when {@link commands} may not be everything the line runs. */
118
132
  readonly opaque: boolean;
119
133
  /** False when parsing stopped early: a syntax error or an unsupported construct. */
@@ -1 +1 @@
1
- {"version":3,"file":"shell-lexer.d.ts","sourceRoot":"","sources":["../../src/authorization/shell-lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAC1B;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAA;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;IAC1C;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAQ5C,CAAA;AAOF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,MAAM,WAAW,eAAe;IAC/B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAC/B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAkB/F;AA4lED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
1
+ {"version":3,"file":"shell-lexer.d.ts","sourceRoot":"","sources":["../../src/authorization/shell-lexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,sEAAsE;IACtE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACxB;AAED,6DAA6D;AAC7D,MAAM,WAAW,gBAAgB;IAChC;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,mEAAmE;IACnE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAA;IAClD,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,cAAc;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;IAC1C;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,SAAS,EAAE,CAAA;IAC5C,sEAAsE;IACtE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAQ5C,CAAA;AAOF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,MAAM,WAAW,eAAe;IAC/B,sBAAsB;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAC/B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,cAAc,CAmB/F;AA2mED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7C"}
@@ -84,6 +84,7 @@ export function lexShellCommandLine(line, options = {}) {
84
84
  return {
85
85
  commands: context.commands,
86
86
  redirections: context.redirections,
87
+ compoundWords: context.compoundWords,
87
88
  opaque: context.reasons.size > 0,
88
89
  complete: context.complete,
89
90
  reasons: [...context.reasons],
@@ -92,6 +93,7 @@ export function lexShellCommandLine(line, options = {}) {
92
93
  class Context {
93
94
  commands = [];
94
95
  redirections = [];
96
+ compoundWords = [];
95
97
  reasons = new Set();
96
98
  complete = true;
97
99
  /**
@@ -625,6 +627,7 @@ class Parser {
625
627
  const name = this.takePlainWord();
626
628
  if (name.kind !== 'word')
627
629
  throw this.unexpected(name);
630
+ this.context.compoundWords.push(name.word);
628
631
  this.newlines();
629
632
  token = this.peek();
630
633
  if (token.kind === 'word' && !token.word.quoted && token.word.value === 'in') {
@@ -640,8 +643,10 @@ class Parser {
640
643
  }
641
644
  for (;;) {
642
645
  token = this.takePlainWord();
643
- if (token.kind === 'word')
646
+ if (token.kind === 'word') {
647
+ this.context.compoundWords.push(token.word);
644
648
  continue;
649
+ }
645
650
  if (token.kind === 'newline' || (token.kind === 'op' && token.op === ';'))
646
651
  break;
647
652
  throw this.unexpected(token);
@@ -688,6 +693,7 @@ class Parser {
688
693
  const subject = this.takePlainWord();
689
694
  if (subject.kind !== 'word')
690
695
  throw this.unexpected(subject);
696
+ this.context.compoundWords.push(subject.word);
691
697
  this.newlines();
692
698
  const keyword = this.take();
693
699
  if (keyword.kind !== 'word' || keyword.word.quoted || keyword.word.value !== 'in') {
@@ -720,6 +726,7 @@ class Parser {
720
726
  const pattern = this.take();
721
727
  if (pattern.kind !== 'word')
722
728
  throw this.unexpected(pattern);
729
+ this.context.compoundWords.push(pattern.word);
723
730
  const next = this.take();
724
731
  if (next.kind === 'op' && next.op === '|')
725
732
  continue;
@@ -943,6 +950,11 @@ class Parser {
943
950
  // Ubuntu ship).
944
951
  this.context.opaque('quoted or expanding target of >& or <&');
945
952
  }
953
+ const redirection = {
954
+ operator: operator.op,
955
+ ...(operator.fd !== undefined ? { fd: operator.fd } : {}),
956
+ target: target.word,
957
+ };
946
958
  if (operator.op === '<<' || operator.op === '<<-') {
947
959
  if (target.word.value.includes('\n')) {
948
960
  // Bash starts the body at the newline inside the delimiter, so
@@ -955,13 +967,10 @@ class Parser {
955
967
  delimiter: target.word.value,
956
968
  stripTabs: operator.op === '<<-',
957
969
  quoted: target.word.quoted,
970
+ redirection,
958
971
  });
959
972
  }
960
- return {
961
- operator: operator.op,
962
- ...(operator.fd !== undefined ? { fd: operator.fd } : {}),
963
- target: target.word,
964
- };
973
+ return redirection;
965
974
  }
966
975
  /**
967
976
  * What a finished simple command means for the rest of the line: a nested
@@ -1463,7 +1472,9 @@ class Parser {
1463
1472
  const heredoc = this.heredocs.shift();
1464
1473
  let i = this.pos;
1465
1474
  const bodyStart = i;
1475
+ let bodyEnd = i;
1466
1476
  for (;;) {
1477
+ bodyEnd = i;
1467
1478
  if (i >= src.length)
1468
1479
  break;
1469
1480
  let line = '';
@@ -1488,7 +1499,9 @@ class Parser {
1488
1499
  i = j;
1489
1500
  if (test === heredoc.delimiter)
1490
1501
  break;
1502
+ bodyEnd = i;
1491
1503
  }
1504
+ heredoc.redirection.body = src.slice(bodyStart, bodyEnd);
1492
1505
  if (!heredoc.quoted) {
1493
1506
  const body = src.slice(bodyStart, i);
1494
1507
  if (/\$[({[]|`/.test(body))