@bermudi/pi-delegate 0.1.18 → 0.1.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.
package/README.md CHANGED
@@ -35,17 +35,16 @@ delegate({
35
35
  ```
36
36
 
37
37
  Parent extension/MCP tools are not copied, and project instructions are rebuilt
38
- for the task's `cwd`. Omit `agent` when you want an ad-hoc task using delegate's
39
- normal inline defaults instead.
38
+ for the task's `cwd`. Omit `agent` when you want an inline task using delegate's
39
+ normal defaults instead.
40
40
 
41
41
  The other built-ins are:
42
42
 
43
43
  - `scout` — read-only investigation with `read`, `grep`, `find`, and `ls`.
44
44
  - `coder` — implementation and verification with `read`, `write`, `edit`, and
45
45
  `bash` in the shared workspace.
46
- - `reviewer` — review with `read` and `bash`, using a disposable scratch copy by
47
- default. Set `workspace: "shared"` when a reviewer needs a persistent
48
- `sessionId`.
46
+ - `reviewer` — review with `read` and `bash` in the shared workspace by default.
47
+ Set `workspace: "scratch"` when its project changes should be discarded.
49
48
 
50
49
  ### Shared-write safety
51
50
 
@@ -64,7 +63,7 @@ visible batch-level warning while it is active.
64
63
  A same-named Markdown file can override any built-in (first definition wins
65
64
  across `.pi/agents/`, `~/.pi/agent/agents/`, `~/.agents/`, `.claude/agents/`,
66
65
  `~/.claude/agents/`). A prompt-only override keeps the built-in's tools and
67
- workspace — `scout` stays read-only and `reviewer` stays scratch unless the
66
+ workspace — `scout` stays read-only and `reviewer` stays shared unless the
68
67
  file explicitly sets `tools` or `workspace`. Fresh built-ins inherit the
69
68
  parent's exact model object and thinking level; an explicit `model`/`thinking`
70
69
  in the Markdown file replaces that inheritance. Task fields always win. For
@@ -106,7 +105,7 @@ host filesystem.
106
105
 
107
106
  ### Git-native isolated writers
108
107
 
109
- Use `workspace: "isolated"` for synchronous, one-shot coding tasks that should
108
+ Use `workspace: "isolated"` for sync or async one-shot coding tasks that should
110
109
  run in parallel without sharing a working tree:
111
110
 
112
111
  ```ts
@@ -128,10 +127,12 @@ still matches the baseline.
128
127
 
129
128
  A clean reconciliation reports `applied_unverified`: textual merging does not
130
129
  prove the code builds or tests pass, so the result includes a suggested
131
- verification call. Isolated mode currently requires Git, rejects async and
132
- session reuse, disables whole-task retries, and rejects repositories with
133
- submodules. It is separation, not confinement: absolute-path writes can still
134
- reach the host.
130
+ verification call. Async isolated tasks prepare after returning their ticket and
131
+ settle only after reconciliation. Cancellation never applies unfinished work; a
132
+ completed proposal cancelled before source application is retained as a private
133
+ ref and full patch. Isolated mode requires Git, rejects session reuse, disables
134
+ whole-task retries, and rejects repositories with submodules. It is separation,
135
+ not confinement: absolute-path writes can still reach the host.
135
136
 
136
137
  ### Token accounting
137
138
 
@@ -216,8 +217,8 @@ over an installed extension.
216
217
  and workspace, and an explicit `model`/`thinking` replaces parent inheritance.
217
218
  For `default`, the `delegate.json` override maps are ignored (task fields still
218
219
  win); for the other built-ins, those maps win field-by-field over frontmatter.
219
- - **Ad-hoc subagent** — A subagent created from inline task fields instead of a
220
- named Markdown agent profile. In current output this is labeled `ad-hoc`.
220
+ - **Inline subagent** — A subagent created from inline task fields instead of a
221
+ named Markdown agent profile. In current output this is labeled `inline`.
221
222
  - **Inline task** — The task object itself when its configuration is supplied
222
223
  directly in the delegate call. Prefer this term over “inline agent” when
223
224
  talking about the API shape.
package/agents.ts CHANGED
@@ -120,7 +120,7 @@ export const BUILTIN_AGENT_CONFIGS: Readonly<Record<string, AgentConfig>> = {
120
120
  [DEFAULT_AGENT_NAME]: {
121
121
  name: DEFAULT_AGENT_NAME,
122
122
  description:
123
- "General-purpose subagent mirroring the live parent model, thinking level, native tools, and base prompt. Prefer it for general work; pick a specialist only when its role, tool limits, or scratch workspace genuinely fit.",
123
+ "General-purpose subagent mirroring the live parent model, thinking level, native tools, and base prompt. Prefer it for general work; pick a specialist when its role fits.",
124
124
  tools: DEFAULT_TOOLS,
125
125
  systemPrompt: "",
126
126
  builtin: true,
package/concurrency.ts CHANGED
@@ -181,6 +181,11 @@ export function getModelKey(model: Model<Api> | undefined): string {
181
181
  *
182
182
  * The total number of concurrently running tasks is also capped by the
183
183
  * configured `maxConcurrent` value, shared across all `delegate` invocations.
184
+ *
185
+ * `beforeAcquire` runs per item before its global slot is acquired — a
186
+ * serialized successor awaits its predecessor there while holding only its
187
+ * per-model worker slot, never a global slot, so a serialized batch cannot
188
+ * pin the shared semaphore while running one task at a time.
184
189
  */
185
190
  export async function mapConcurrentByModel<T, R>(
186
191
  items: T[],
@@ -188,6 +193,7 @@ export async function mapConcurrentByModel<T, R>(
188
193
  getConcurrency: (modelKey: string) => number,
189
194
  fn: (item: T, index: number) => Promise<R>,
190
195
  signal?: AbortSignal,
196
+ beforeAcquire?: (index: number) => Promise<void>,
191
197
  ): Promise<R[]> {
192
198
  if (items.length === 0) return [];
193
199
  const results: R[] = new Array(items.length);
@@ -215,6 +221,7 @@ export async function mapConcurrentByModel<T, R>(
215
221
  group.limit,
216
222
  async (_item, localIdx) => {
217
223
  const globalIdx = group.indices[localIdx]!;
224
+ if (beforeAcquire) await beforeAcquire(globalIdx);
218
225
  const acquired = await acquireGlobal(signal);
219
226
  if (!acquired) {
220
227
  // Aborted while queued for a global slot: we hold no slot, so we
package/delegate.ts CHANGED
@@ -52,11 +52,14 @@ export type { AgentOverride } from "./config.ts";
52
52
  export {
53
53
  checkout,
54
54
  commit,
55
+ recordUse,
55
56
  configFor,
56
57
  closePooledAgent,
57
58
  closeAllPooledAgents,
58
59
  listPooledAgents,
59
60
  withSessionLock,
61
+ SessionPool,
62
+ defaultSessionPool,
60
63
  } from "./pool.ts";
61
64
  export type {
62
65
  FrozenConfig,
@@ -79,8 +82,11 @@ export {
79
82
  resolveFinalTicketStatus,
80
83
  settleTicket,
81
84
  formatCompletedTicket,
85
+ TicketRegistry,
82
86
  } from "./tickets.ts";
83
87
  export type { TicketDelivery, SettleTicketOptions } from "./tickets.ts";
88
+ export { createDelegateRuntime, getDefaultDelegateRuntime } from "./runtime.ts";
89
+ export type { DelegateRuntime } from "./runtime.ts";
84
90
  export {
85
91
  recordTreeNavigation,
86
92
  getCurrentLeafId,