github-router 0.3.168 → 0.3.175
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/dist/browser-ext/manifest.json +1 -1
- package/dist/{engine-RA1Orodr.js → engine-cUomEg92.js} +1 -1
- package/dist/main.js +555 -172
- package/dist/main.js.map +1 -1
- package/dist/{peer-mcp-personas-D826LsJJ.js → peer-mcp-personas-BCGYWok0.js} +520 -382
- package/dist/peer-mcp-personas-BCGYWok0.js.map +1 -0
- package/package.json +1 -1
- package/dist/peer-mcp-personas-D826LsJJ.js.map +0 -1
|
@@ -1565,7 +1565,7 @@ function tool(toolNameHttp, description, inputSchema, handler) {
|
|
|
1565
1565
|
};
|
|
1566
1566
|
}
|
|
1567
1567
|
const ARTIFACT_TOOLS = Object.freeze([
|
|
1568
|
-
tool("artifact_open", "
|
|
1568
|
+
tool("artifact_open", "Opens a workspace file in ai-or-die's Artifact review panel for human review, replacing the current review if one is already open. The caller provides a workspace-relative or absolute file path and can set mode:\"interactive\" when the HTML carries data-aod-* action controls. It returns the review URL/session identifiers plus next-step guidance for draining feedback. Use it when the user should review a durable artifact before work continues; it is not for one-line status updates or non-file content. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1569
1569
|
file: stringProp$2("Workspace-relative or absolute file path to show in the Artifact panel."),
|
|
1570
1570
|
mode: enumProp$1(["static", "interactive"], "Advisory. \"interactive\" signals the HTML contains data-aod-* action controls the panel should wire; \"static\" (default) is a read-and-annotate artifact.")
|
|
1571
1571
|
}, ["file"]), async (args, signal) => {
|
|
@@ -1584,7 +1584,7 @@ const ARTIFACT_TOOLS = Object.freeze([
|
|
|
1584
1584
|
next_step: "Tell the user to review at the Artifact panel, then call artifact_await to receive their feedback."
|
|
1585
1585
|
});
|
|
1586
1586
|
}),
|
|
1587
|
-
tool("artifact_update", "
|
|
1587
|
+
tool("artifact_update", "Replaces the current Artifact review's content in place without opening a separate review. The caller provides exactly one of file, a workspace-relative or absolute file path, or html, raw HTML written into the existing review sandbox; html requires an already-open review, and idempotencyKey can make retries deduplicate on the server. It returns a minimal success signal plus next-step guidance for awaiting further feedback. Use it when revised content should replace what the human is already reviewing; use artifact_refresh instead when the existing on-disk artifact only needs to be reloaded. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1588
1588
|
file: stringProp$2("Workspace-relative or absolute file path to become the review's new content."),
|
|
1589
1589
|
html: stringProp$2("Raw HTML to write into the review's existing sandboxed file, then reload."),
|
|
1590
1590
|
idempotencyKey: stringProp$2("Optional stable key so a retried update is de-duplicated by the server.")
|
|
@@ -1595,27 +1595,19 @@ const ARTIFACT_TOOLS = Object.freeze([
|
|
|
1595
1595
|
const html = optionalString$2(args, "html");
|
|
1596
1596
|
if (file === void 0 === (html === void 0)) throw new ArtifactToolInputError("INVALID_ARGUMENT", "artifact_update requires EXACTLY ONE of arguments.file or arguments.html");
|
|
1597
1597
|
const idempotencyKey = optionalString$2(args, "idempotencyKey");
|
|
1598
|
-
return ok$2({
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
}),
|
|
1605
|
-
ok: true,
|
|
1606
|
-
next_step: "The panel now shows the updated content. Call artifact_await for further feedback."
|
|
1607
|
-
});
|
|
1598
|
+
return ok$2(formatUpdateSuccess(await clientFromEnv(env).update({
|
|
1599
|
+
file,
|
|
1600
|
+
html,
|
|
1601
|
+
idempotencyKey,
|
|
1602
|
+
signal
|
|
1603
|
+
})));
|
|
1608
1604
|
}),
|
|
1609
|
-
tool("artifact_refresh", "
|
|
1605
|
+
tool("artifact_refresh", "Reloads the currently-open Artifact review from its existing on-disk file without changing the content source. The tool takes no inputs and returns a minimal success signal plus next-step guidance for awaiting feedback. Use it after an out-of-band edit changes the reviewed file on disk and the panel needs to pick up that version. Do not use it to replace the artifact with a new file or raw HTML; use artifact_update for that. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({}, []), async (_args, signal) => {
|
|
1610
1606
|
const env = readArtifactEnv();
|
|
1611
1607
|
if (!env) return missingEnvResult();
|
|
1612
|
-
return ok$2(
|
|
1613
|
-
...await clientFromEnv(env).refresh(signal),
|
|
1614
|
-
ok: true,
|
|
1615
|
-
next_step: "The panel reloaded the artifact. Call artifact_await for feedback."
|
|
1616
|
-
});
|
|
1608
|
+
return ok$2(formatRefreshSuccess(await clientFromEnv(env).refresh(signal)));
|
|
1617
1609
|
}),
|
|
1618
|
-
tool("artifact_await", "
|
|
1610
|
+
tool("artifact_await", "Waits for the human's next Artifact review events and returns a typed drain containing comments, structured action-button or checkbox events, status, cursor, and next-step guidance. The caller can pass the cursor from a previous response to receive only newer events and can provide timeoutMs as the server long-hold budget. It may return an empty events list on a quiet long-hold; callers should pass the returned cursor on the next artifact_await call. Use it as the primary review-feedback drain after artifact_open or artifact_update; it supersedes artifact_poll, which is legacy comments-only. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1619
1611
|
cursor: stringProp$2("High-water cursor from the previous artifact_await response. Omit on the first call."),
|
|
1620
1612
|
timeoutMs: numberProp$2("Optional server long-hold budget in ms (default ~25000).")
|
|
1621
1613
|
}, []), async (args, signal) => {
|
|
@@ -1629,35 +1621,23 @@ const ARTIFACT_TOOLS = Object.freeze([
|
|
|
1629
1621
|
signal
|
|
1630
1622
|
})));
|
|
1631
1623
|
}),
|
|
1632
|
-
tool("artifact_dismiss", "
|
|
1624
|
+
tool("artifact_dismiss", "Hides the ai-or-die Artifact panel UI while keeping the current review alive. The tool takes no inputs and returns a minimal success signal plus next-step guidance for reopening or awaiting later feedback. Use it when the panel should get out of the way but queued feedback should remain preserved, the channel should stay open, and the review should be re-openable. Do not use it when the review loop is finished; use artifact_end to close the review instead. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({}, []), async (_args, signal) => {
|
|
1633
1625
|
const env = readArtifactEnv();
|
|
1634
1626
|
if (!env) return missingEnvResult();
|
|
1635
|
-
return ok$2(
|
|
1636
|
-
...await clientFromEnv(env).dismiss(signal),
|
|
1637
|
-
ok: true,
|
|
1638
|
-
next_step: "The panel is hidden but the review is still live. Re-open the artifact or call artifact_await when ready."
|
|
1639
|
-
});
|
|
1627
|
+
return ok$2(formatDismissSuccess(await clientFromEnv(env).dismiss(signal)));
|
|
1640
1628
|
}),
|
|
1641
|
-
tool("artifact_reply", "
|
|
1629
|
+
tool("artifact_reply", "Sends the agent's reply back to the ai-or-die Artifact review panel after applying or responding to human feedback. The caller provides the reply text, and the tool returns a minimal success signal plus next-step guidance for either continuing the review loop or moving on. Use it to acknowledge what changed, answer a reviewer question, or summarize how feedback was handled after artifact_await returns events. Do not use it to replace panel content, wait for more feedback, hide the UI, or close the review. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({ text: stringProp$2("Agent reply text to deliver to the human Artifact review panel.") }, ["text"]), async (args, signal) => {
|
|
1642
1630
|
const env = readArtifactEnv();
|
|
1643
1631
|
if (!env) return missingEnvResult();
|
|
1644
1632
|
const text = requiredString$2(args, "text");
|
|
1645
|
-
return ok$2(
|
|
1646
|
-
...await clientFromEnv(env).agentReply(text, signal),
|
|
1647
|
-
ok: true,
|
|
1648
|
-
next_step: "Wait for further human review, or continue if the review loop is complete."
|
|
1649
|
-
});
|
|
1633
|
+
return ok$2(formatReplySuccess(await clientFromEnv(env).agentReply(text, signal)));
|
|
1650
1634
|
}),
|
|
1651
|
-
tool("artifact_end", "
|
|
1635
|
+
tool("artifact_end", "Ends and closes the ai-or-die Artifact review panel when the review loop is complete. The tool takes no inputs and returns a minimal success signal plus terminal next-step guidance. Use it after the human review is finished and no further feedback should arrive. Do not use it for a temporary hide or pause; use artifact_dismiss when the review should stay live. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({}, []), async (_args, signal) => {
|
|
1652
1636
|
const env = readArtifactEnv();
|
|
1653
1637
|
if (!env) return missingEnvResult();
|
|
1654
|
-
return ok$2(
|
|
1655
|
-
...await clientFromEnv(env).end(signal),
|
|
1656
|
-
ok: true,
|
|
1657
|
-
next_step: "Artifact review loop ended."
|
|
1658
|
-
});
|
|
1638
|
+
return ok$2(formatEndSuccess(await clientFromEnv(env).end(signal)));
|
|
1659
1639
|
}),
|
|
1660
|
-
tool("artifact_poll", "
|
|
1640
|
+
tool("artifact_poll", "Provides the frozen legacy polling path for Artifact review feedback. The caller may provide timeoutMs as an advisory per-call budget, and the tool returns the old comments-only payload with status, prompts, and next-step guidance rather than typed action events or a cursor. Use it only for compatibility with older clients or flows that still require the old payload shape. New callers should use artifact_await instead because it returns typed comments and structured action-button or checkbox events. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({ timeoutMs: numberProp$2("Optional per-call budget hint in ms (advisory).") }, []), async (_args, signal) => {
|
|
1661
1641
|
const env = readArtifactEnv();
|
|
1662
1642
|
if (!env) return missingEnvResult();
|
|
1663
1643
|
return ok$2(formatPollResponse(await pollUntilReady(clientFromEnv(env), signal)));
|
|
@@ -1735,6 +1715,50 @@ function formatPollResponse(response) {
|
|
|
1735
1715
|
next_step: response.next_step ?? defaultPollNextStep(response.status)
|
|
1736
1716
|
});
|
|
1737
1717
|
}
|
|
1718
|
+
function formatUpdateSuccess(response) {
|
|
1719
|
+
return definedObject$1({
|
|
1720
|
+
ok: true,
|
|
1721
|
+
viewUrl: stringField$1(response, "viewUrl"),
|
|
1722
|
+
next_step: "The panel now shows the updated content. Call artifact_await for further feedback."
|
|
1723
|
+
});
|
|
1724
|
+
}
|
|
1725
|
+
function formatRefreshSuccess(response) {
|
|
1726
|
+
return definedObject$1({
|
|
1727
|
+
ok: true,
|
|
1728
|
+
viewUrl: stringField$1(response, "viewUrl"),
|
|
1729
|
+
panelUrl: stringField$1(response, "panelUrl"),
|
|
1730
|
+
status: stringField$1(response, "status"),
|
|
1731
|
+
visibility: stringField$1(response, "visibility"),
|
|
1732
|
+
next_step: "The panel reloaded the artifact. Call artifact_await for feedback."
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
function formatDismissSuccess(response) {
|
|
1736
|
+
return definedObject$1({
|
|
1737
|
+
ok: true,
|
|
1738
|
+
viewUrl: stringField$1(response, "viewUrl"),
|
|
1739
|
+
panelUrl: stringField$1(response, "panelUrl"),
|
|
1740
|
+
status: stringField$1(response, "status"),
|
|
1741
|
+
visibility: stringField$1(response, "visibility"),
|
|
1742
|
+
next_step: "The panel is hidden but the review is still live. Re-open the artifact or call artifact_await when ready."
|
|
1743
|
+
});
|
|
1744
|
+
}
|
|
1745
|
+
function formatReplySuccess(response) {
|
|
1746
|
+
return definedObject$1({
|
|
1747
|
+
ok: true,
|
|
1748
|
+
reply: response.reply,
|
|
1749
|
+
delivered: booleanField(response, "delivered"),
|
|
1750
|
+
confirmed: booleanField(response, "confirmed"),
|
|
1751
|
+
status: stringField$1(response, "status"),
|
|
1752
|
+
next_step: "Wait for further human review, or continue if the review loop is complete."
|
|
1753
|
+
});
|
|
1754
|
+
}
|
|
1755
|
+
function formatEndSuccess(response) {
|
|
1756
|
+
return definedObject$1({
|
|
1757
|
+
ok: true,
|
|
1758
|
+
status: response.status,
|
|
1759
|
+
next_step: "Artifact review loop ended."
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1738
1762
|
/**
|
|
1739
1763
|
* Shape the typed drain for the model: pass events through verbatim (unknown
|
|
1740
1764
|
* `kind`s preserved — the model ignores what it does not understand), echo the
|
|
@@ -1839,6 +1863,14 @@ function definedObject$1(input) {
|
|
|
1839
1863
|
for (const [key, value] of Object.entries(input)) if (value !== void 0) result[key] = value;
|
|
1840
1864
|
return result;
|
|
1841
1865
|
}
|
|
1866
|
+
function stringField$1(input, key) {
|
|
1867
|
+
const value = input[key];
|
|
1868
|
+
return typeof value === "string" ? value : void 0;
|
|
1869
|
+
}
|
|
1870
|
+
function booleanField(input, key) {
|
|
1871
|
+
const value = input[key];
|
|
1872
|
+
return typeof value === "boolean" ? value : void 0;
|
|
1873
|
+
}
|
|
1842
1874
|
function objectSchema$2(properties, required) {
|
|
1843
1875
|
return {
|
|
1844
1876
|
type: "object",
|
|
@@ -3596,10 +3628,10 @@ function createFleetTools(options = {}) {
|
|
|
3596
3628
|
};
|
|
3597
3629
|
}
|
|
3598
3630
|
return Object.freeze([
|
|
3599
|
-
tool$1("list_instances", "
|
|
3631
|
+
tool$1("list_instances", "Lists registered remote ai-or-die fleet instances and probes whether each instance is currently reachable. It takes no input; the registry decides which instances exist, and credentials or tunnel tokens are not returned. It returns instances with id, label, reachable status, sessionCount and lastSeen for reachable hosts, or error and hint for unreachable hosts. It is useful as the discovery entry point before list_sessions, create_session, or other fleet tools that need an instance id. It is not for local repository search or for reading sessions; use local tools for this machine and list_sessions after choosing an instance.", objectSchema$1({}, []), async () => {
|
|
3600
3632
|
return ok$1({ instances: await mapWithConcurrency(await getRegistry().listInstances(), fleetFanoutConcurrency(LIST_INSTANCES_FANOUT_CONCURRENCY), (instance) => probeInstance(instance)) });
|
|
3601
3633
|
}),
|
|
3602
|
-
tool$1("list_sessions", "
|
|
3634
|
+
tool$1("list_sessions", "Lists sessions on one remote ai-or-die fleet instance and returns session ids that can be used by the other fleet session tools. The optional instance input is an id or label; when it is omitted, the registry default or sole instance is used. It returns resolvedInstance and sessions, with each sessionId globalized as instanceId:localSessionId. It is useful after list_instances to choose a remote session to inspect, message, drive, or stop. It is not a fleet-wide listing and does not read transcript output; call it per instance, and use read_session for a session's text tail.", objectSchema$1({ instance: stringProp$1("Instance id or label. Defaults to the registry default, or the sole instance.") }, []), async (args, signal) => {
|
|
3603
3635
|
const instance = await resolve(optionalString$1(args, "instance"));
|
|
3604
3636
|
const response = await clientFor(instance).listSessions(signal);
|
|
3605
3637
|
return ok$1({
|
|
@@ -3607,11 +3639,10 @@ function createFleetTools(options = {}) {
|
|
|
3607
3639
|
sessions: response.sessions.map((session) => globalizeSession(instance.id, session))
|
|
3608
3640
|
});
|
|
3609
3641
|
}),
|
|
3610
|
-
tool$1("read_session", "
|
|
3642
|
+
tool$1("read_session", "Reads recent text output from an addressed remote ai-or-die fleet session. The required sessionId must be a global id in instanceId:localSessionId form; the optional instance input is only a cross-check and must resolve to the same instance. It returns resolvedInstance, sessionId, text, truncated, source, and the session status snapshot. It is useful for inspecting the transcript tail after send_message, await_turn, or drive_task. It is not for lifecycle-only checks or live waiting; use session_status for point-in-time state and await_turn to wait for new events.", objectSchema$1({
|
|
3611
3643
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3612
3644
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3613
|
-
lines: numberProp$1("Number of recent lines to read.")
|
|
3614
|
-
format: stringProp$1("Reserved for future formatting; results are JSON text today.")
|
|
3645
|
+
lines: numberProp$1("Number of recent lines to read.")
|
|
3615
3646
|
}, ["sessionId"]), async (args, signal) => {
|
|
3616
3647
|
const { instance, localId, globalId } = await resolveSession(args);
|
|
3617
3648
|
const lines = optionalNumber$1(args, "lines");
|
|
@@ -3622,7 +3653,7 @@ function createFleetTools(options = {}) {
|
|
|
3622
3653
|
sessionId: globalId
|
|
3623
3654
|
});
|
|
3624
3655
|
}),
|
|
3625
|
-
tool$1("session_status", "
|
|
3656
|
+
tool$1("session_status", "Fetches the lifecycle and interaction status for an addressed remote ai-or-die fleet session. The required sessionId must be a global id in instanceId:localSessionId form; the optional instance input is only a cross-check and must resolve to the same instance. It returns resolvedInstance, sessionId, and a status object that can include lifecycle, interactionState, canAcceptInput, blockReason, and awaiting details. It is useful before deciding whether a session can accept a message or is awaiting a prompt. It is not a transcript reader or event watcher; use read_session for output text and await_turn for turn-completion events.", objectSchema$1({
|
|
3626
3657
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3627
3658
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId.")
|
|
3628
3659
|
}, ["sessionId"]), async (args, signal) => {
|
|
@@ -3634,7 +3665,7 @@ function createFleetTools(options = {}) {
|
|
|
3634
3665
|
sessionId: globalId
|
|
3635
3666
|
});
|
|
3636
3667
|
}),
|
|
3637
|
-
tool$1("send_message", "
|
|
3668
|
+
tool$1("send_message", "Sends a free-text message to an existing remote ai-or-die fleet session. The required sessionId must be global, message is the text to deliver, requireIdle defaults to true, waitForIdleMs can wait briefly for readiness, awaitMs waits only for best-effort delivery confirmation, and idempotencyKey is usually auto-generated unless retrying the same send. It returns resolvedInstance, sessionId, delivered, confirmed, submitted when the remote proves the composer accepted the message, and confirmationPending/confirmationTimedOut when delivery succeeded but the turn outran the await window; delivered:false or notReady is reported as an error result. It is useful for sending the next free-text instruction to an idle session, especially with awaitMs:0 followed by await_turn for the actual turn boundary. It is not for answering an awaited choice prompt or sending control keys; use respond for prompts and send_keys for submit, interrupt, or literal key sequences.", objectSchema$1({
|
|
3638
3669
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3639
3670
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3640
3671
|
message: stringProp$1("Message text to deliver to the session."),
|
|
@@ -3691,7 +3722,7 @@ function createFleetTools(options = {}) {
|
|
|
3691
3722
|
...isError ? { message: "message was not delivered to the session by the upstream instance" } : confirmationTimedOut ? { message: "delivered; turn completion not confirmed in the await window. Use await_turn filtered to this sessionId to observe completion (the idempotencyKey makes a retried send safe)." } : {}
|
|
3692
3723
|
}, isError);
|
|
3693
3724
|
}),
|
|
3694
|
-
tool$1("send_keys", "
|
|
3725
|
+
tool$1("send_keys", "Sends key input to an existing remote ai-or-die fleet session. The required sessionId must be global; provide exactly one of op or keys, where op is a named operation (`submit` for Enter or `interrupt` for Ctrl-C) and keys is a literal key sequence; raw only applies to literal keys. It returns resolvedInstance, sessionId, delivered, duplicated when an idempotency retry was deduped, and the mapped key name when op was used. It is useful for control-key actions such as submitting a typed prompt or interrupting a busy turn without stopping the session. It is not the normal free-text path and not the prompt-answer path; use send_message for free text and respond for awaited prompts.", objectSchema$1({
|
|
3695
3726
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3696
3727
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3697
3728
|
op: stringProp$1("Higher-level named op: 'submit' (Enter) or 'interrupt' (Ctrl-C). Mapped to the ai-or-die named key with raw off. Do NOT also pass keys."),
|
|
@@ -3726,10 +3757,11 @@ function createFleetTools(options = {}) {
|
|
|
3726
3757
|
op,
|
|
3727
3758
|
mappedKeys: keys
|
|
3728
3759
|
},
|
|
3729
|
-
|
|
3760
|
+
delivered: response.delivered,
|
|
3761
|
+
...response.duplicated === void 0 ? {} : { duplicated: response.duplicated }
|
|
3730
3762
|
});
|
|
3731
3763
|
}),
|
|
3732
|
-
tool$1("respond", "
|
|
3764
|
+
tool$1("respond", "Answers an awaited prompt in an existing remote ai-or-die fleet session by selecting a choice, selecting an exact option value, or sending explicit keys. The required sessionId must be global; choose the answer mode that matches the prompt, and idempotencyKey is usually auto-generated unless retrying the same response. It returns resolvedInstance, sessionId, delivered, duplicated when an idempotency retry was deduped, and any awaitingKind or mappedKeys supplied by the remote; delivered:false is reported as an error result. It is useful only when session_status or await_turn shows the session is waiting for a prompt or choice. It is not for ordinary free-text instructions or control keys; use send_message for free text and send_keys for submit or interrupt.", objectSchema$1({
|
|
3733
3765
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3734
3766
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3735
3767
|
choice: stringProp$1("Named or numbered choice to select."),
|
|
@@ -3745,23 +3777,35 @@ function createFleetTools(options = {}) {
|
|
|
3745
3777
|
idempotencyKey: optionalString$1(args, "idempotencyKey") ?? randomUUID()
|
|
3746
3778
|
});
|
|
3747
3779
|
const response = await clientFor(instance).respond(localId, input, signal);
|
|
3748
|
-
|
|
3780
|
+
const delivered = response.delivered !== false;
|
|
3781
|
+
return jsonResult$1({
|
|
3749
3782
|
resolvedInstance: publicInstance(instance),
|
|
3750
3783
|
sessionId: globalId,
|
|
3751
|
-
...response
|
|
3752
|
-
|
|
3784
|
+
...response,
|
|
3785
|
+
delivered,
|
|
3786
|
+
...delivered ? {} : { message: "response was not delivered to the session by the upstream instance" }
|
|
3787
|
+
}, !delivered);
|
|
3753
3788
|
}),
|
|
3754
|
-
tool$1("create_session", "
|
|
3789
|
+
tool$1("create_session", "Creates a new session on a specific remote ai-or-die fleet instance. The instance input is required and never defaults; agent is required and must be one of claude, codex, copilot, gemini, or terminal; start:true is required for the session to actually run and be driveable. It returns resolvedInstance plus the remote create response, with sessionId converted to the global instanceId:localSessionId form when creation succeeds. It is useful when the user wants a new remote session to run on a named fleet host before using drive_task, send_message, or await_turn. It is not for selecting or inspecting an existing session; use list_instances and list_sessions first when the target is unknown.", objectSchema$1({
|
|
3755
3790
|
instance: stringProp$1("Required instance id or label. Create never uses the registry default."),
|
|
3756
|
-
agent:
|
|
3791
|
+
agent: {
|
|
3792
|
+
...stringProp$1("Required agent/runtime to create on the instance. Valid values: claude, codex, copilot, gemini, terminal."),
|
|
3793
|
+
enum: [
|
|
3794
|
+
"claude",
|
|
3795
|
+
"codex",
|
|
3796
|
+
"copilot",
|
|
3797
|
+
"gemini",
|
|
3798
|
+
"terminal"
|
|
3799
|
+
]
|
|
3800
|
+
},
|
|
3757
3801
|
name: stringProp$1("Optional display name for the session."),
|
|
3758
3802
|
workingDir: stringProp$1("Optional working directory on the remote instance."),
|
|
3759
3803
|
idempotencyKey: stringProp$1("Optional caller idempotency key; auto-generated when omitted."),
|
|
3760
|
-
start: booleanProp("
|
|
3761
|
-
readyTimeoutMs: numberProp$1("
|
|
3762
|
-
permissionMode: stringProp$1("
|
|
3763
|
-
agentArgs: arrayProp("
|
|
3764
|
-
disableStopGate: booleanProp("
|
|
3804
|
+
start: booleanProp("Set true to start the remote session immediately; without start:true the created session is not running or driveable."),
|
|
3805
|
+
readyTimeoutMs: numberProp$1("Bounded milliseconds to wait for the agent to become driveable before returning. The response carries ready, bound, and blocker."),
|
|
3806
|
+
permissionMode: stringProp$1("Claude-only permission mode for the launched agent: plan, acceptEdits, default, or bypassPermissions. Rejected with BAD_REQUEST if unknown or if agentArgs also sets it."),
|
|
3807
|
+
agentArgs: arrayProp("Claude-only extra launcher args appended after the github-router prefix. Do not include --permission-mode or --dangerously-skip-permissions; use permissionMode instead."),
|
|
3808
|
+
disableStopGate: booleanProp("Claude-only option to disable the structural Stop-gate on the launched session by injecting --no-stop-gate into agentArgs, so a driven session's turn-end does not hang on a blocking Stop hook. Requires a remote github-router that understands the flag.")
|
|
3765
3809
|
}, ["instance", "agent"]), async (args, signal) => {
|
|
3766
3810
|
const instance = await resolve(requiredString$1(args, "instance"));
|
|
3767
3811
|
const agent = requiredString$1(args, "agent");
|
|
@@ -3789,7 +3833,7 @@ function createFleetTools(options = {}) {
|
|
|
3789
3833
|
sessionId: localSessionId ? encodeSessionId(instance.id, localSessionId) : response.sessionId
|
|
3790
3834
|
});
|
|
3791
3835
|
}),
|
|
3792
|
-
tool$1("stop_session", "
|
|
3836
|
+
tool$1("stop_session", "Terminates an existing remote ai-or-die fleet session. The required sessionId must be global; instance is only a cross-check, mode is an optional remote-understood stop mode, and idempotencyKey is usually auto-generated unless retrying the same stop. It returns resolvedInstance, sessionId, stopped, and lifecycle. It is useful when the remote session should be ended and its in-flight turn should be killed. It is destructive and irreversible, with no resume companion; to merely unstick or interrupt a busy session without terminating it, use send_keys with op `interrupt`.", objectSchema$1({
|
|
3793
3837
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3794
3838
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3795
3839
|
idempotencyKey: stringProp$1("Optional caller idempotency key; auto-generated when omitted."),
|
|
@@ -3807,10 +3851,10 @@ function createFleetTools(options = {}) {
|
|
|
3807
3851
|
...response
|
|
3808
3852
|
});
|
|
3809
3853
|
}),
|
|
3810
|
-
tool$1("await_turn", "Long-
|
|
3854
|
+
tool$1("await_turn", "Long-polls session events across remote ai-or-die fleet instances. The caller selects targets with instances, sessionIds, or neither for every registered instance; timeoutMs bounds each per-instance long poll, kinds filters event kinds, and watcherId isolates cursor state for concurrent watchers. It returns resolvedInstances, time-sorted stamped events, gaps, cursors, more, optional per-session settled classifications, and optional per-instance errors. It is useful after send_message with awaitMs:0 to observe the real turn boundary; a settled status such as turn_ended or waiting_input is the reliable completion signal, while idle flickers are not completion. It is not a transcript reader or a one-shot task driver; use read_session for text output and drive_task when sending one prompt and waiting for its report should be a single composite operation.", objectSchema$1({
|
|
3811
3855
|
instances: arrayProp("Instance ids or labels to poll. Omit with sessionIds to target those session instances; omit both to poll every registered instance."),
|
|
3812
3856
|
sessionIds: arrayProp("Global session ids to filter to."),
|
|
3813
|
-
timeoutMs: numberProp$1(
|
|
3857
|
+
timeoutMs: numberProp$1(`Long-poll timeout per instance in milliseconds (default ${AWAIT_TURN_DEFAULT_TIMEOUT_MS}).`),
|
|
3814
3858
|
kinds: arrayProp("Optional event kinds to filter to."),
|
|
3815
3859
|
watcherId: stringProp$1("Optional stable id for this watcher. Use a distinct value for concurrent watchers over the same target set to keep cursors isolated.")
|
|
3816
3860
|
}, []), async (args, signal) => {
|
|
@@ -3873,7 +3917,7 @@ function createFleetTools(options = {}) {
|
|
|
3873
3917
|
...errors.length > 0 ? { errors } : {}
|
|
3874
3918
|
});
|
|
3875
3919
|
}),
|
|
3876
|
-
tool$1("drive_task", "
|
|
3920
|
+
tool$1("drive_task", "Drives one prompt on an existing remote ai-or-die fleet session to completion and returns a parsed operator report. The required sessionId must be global, prompt is the single instruction to send, timeoutMs controls when a hung turn is interrupted for recovery, and expectReport defaults to true so a nonce-guarded OPERATOR REPORT trailer is appended and parsed. It returns resolvedInstance, sessionId, state, summary, ask, artifact, raw, settled, submitted, reportFound, and recovery fields such as interrupted or recovered; state must be read together with settled and interrupted because a timeout recovery can leave work needing verification. It is useful as the composite path that performs the safe send_message plus await_turn plus read_session sequence for one already-created session. It is not a session creator, a multi-turn conversation loop, or a simple transcript read; use create_session first when needed, send_message and await_turn when controlling each step manually, and read_session when only the transcript tail is needed.", objectSchema$1({
|
|
3877
3921
|
sessionId: stringProp$1("Global session id in the form instanceId:localSessionId."),
|
|
3878
3922
|
instance: stringProp$1("Optional instance id/label; when supplied it must agree with sessionId."),
|
|
3879
3923
|
prompt: stringProp$1("The task/prompt to drive on the session."),
|
|
@@ -3898,7 +3942,7 @@ function createFleetTools(options = {}) {
|
|
|
3898
3942
|
...result
|
|
3899
3943
|
}, result.error !== void 0);
|
|
3900
3944
|
}),
|
|
3901
|
-
tool$1("read_file", "
|
|
3945
|
+
tool$1("read_file", "Reads a file from one remote ai-or-die fleet instance's filesystem. The required path is passed to the remote host as an unsanitized read request; this router does not confine it to a local workspace, and path policy is delegated to the remote instance. It returns resolvedInstance plus the remote file-content response. It is useful for reading a known file on a remote fleet host after choosing an instance. It is not for local files, directory browsing, text search, git revisions, or session transcripts; use local Read for this machine, list_dir to browse remote directories, search to find remote files, git_show for revision content, and read_session for terminal output.", objectSchema$1({
|
|
3902
3946
|
instance: stringProp$1("Instance id or label. Defaults to the registry default, or the sole instance."),
|
|
3903
3947
|
path: stringProp$1("Remote file path to read.")
|
|
3904
3948
|
}, ["path"]), async (args, signal) => {
|
|
@@ -3909,7 +3953,7 @@ function createFleetTools(options = {}) {
|
|
|
3909
3953
|
...response
|
|
3910
3954
|
});
|
|
3911
3955
|
}),
|
|
3912
|
-
tool$1("list_dir", "
|
|
3956
|
+
tool$1("list_dir", "Lists a directory on one remote ai-or-die fleet instance. The required path is the remote directory path, and instance can select a registered host or default to the registry default or sole instance. It returns resolvedInstance plus the remote directory-listing response. It is useful for browsing a remote workspace before choosing a file to read or search. It is not for local directories, file contents, git revisions, or session transcripts; use local filesystem tools for this machine, read_file for remote file contents, git_show for revision content, and read_session for terminal output.", objectSchema$1({
|
|
3913
3957
|
instance: stringProp$1("Instance id or label. Defaults to the registry default, or the sole instance."),
|
|
3914
3958
|
path: stringProp$1("Remote directory path to list.")
|
|
3915
3959
|
}, ["path"]), async (args, signal) => {
|
|
@@ -3920,7 +3964,7 @@ function createFleetTools(options = {}) {
|
|
|
3920
3964
|
...response
|
|
3921
3965
|
});
|
|
3922
3966
|
}),
|
|
3923
|
-
tool$1("search", "
|
|
3967
|
+
tool$1("search", "Searches files on one remote ai-or-die fleet instance's workspace, where a fleet instance is a registered remote host exposed through the fleet MCP server. The required query is sent to that remote instance, and path can narrow the remote search scope; this does not search the local repository or the web. It returns resolvedInstance plus the remote search response. It is useful when the target content lives on a remote fleet host. It is not for this checkout, semantic code discovery, or internet research; use mcp__search__code for the local workspace and mcp__search__web for web search.", objectSchema$1({
|
|
3924
3968
|
instance: stringProp$1("Instance id or label. Defaults to the registry default, or the sole instance."),
|
|
3925
3969
|
query: stringProp$1("Search query."),
|
|
3926
3970
|
path: stringProp$1("Optional path scope.")
|
|
@@ -3932,18 +3976,16 @@ function createFleetTools(options = {}) {
|
|
|
3932
3976
|
...response
|
|
3933
3977
|
});
|
|
3934
3978
|
}),
|
|
3935
|
-
tool$1("git_show", "
|
|
3979
|
+
tool$1("git_show", "Shows git content on one remote ai-or-die fleet instance, such as a file at a specific revision or a commit object. The required path identifies the remote repository path or file path, and the optional ref is a git commit-ish such as HEAD, a branch, a tag, or a commit SHA. It returns resolvedInstance plus the remote git-show response. It is useful when the caller needs repository content as it existed at a revision on the remote host. It is not for current working-tree reads, directory listings, local git commands, or web search; use read_file for current remote file content and local tools for this checkout.", objectSchema$1({
|
|
3936
3980
|
instance: stringProp$1("Instance id or label. Defaults to the registry default, or the sole instance."),
|
|
3937
3981
|
path: stringProp$1("Remote repository path or file path for git-show."),
|
|
3938
|
-
ref: stringProp$1("Optional git ref
|
|
3939
|
-
rev: stringProp$1("Optional git revision alias."),
|
|
3940
|
-
commit: stringProp$1("Optional commit id.")
|
|
3982
|
+
ref: stringProp$1("Optional git ref, revision, or commit-ish, such as HEAD, a branch, a tag, or a commit SHA.")
|
|
3941
3983
|
}, ["path"]), async (args, signal) => {
|
|
3942
3984
|
const instance = await resolve(optionalString$1(args, "instance"));
|
|
3943
|
-
const response = await clientFor(instance).gitShow({
|
|
3944
|
-
|
|
3945
|
-
|
|
3946
|
-
}, signal);
|
|
3985
|
+
const response = await clientFor(instance).gitShow(definedObject({
|
|
3986
|
+
path: requiredString$1(args, "path"),
|
|
3987
|
+
ref: optionalString$1(args, "ref")
|
|
3988
|
+
}), signal);
|
|
3947
3989
|
return ok$1({
|
|
3948
3990
|
resolvedInstance: publicInstance(instance),
|
|
3949
3991
|
...response
|
|
@@ -10421,7 +10463,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10421
10463
|
};
|
|
10422
10464
|
}
|
|
10423
10465
|
return Object.freeze([
|
|
10424
|
-
tool$1("start_mission", "
|
|
10466
|
+
tool$1("start_mission", "Registers a first-mate mission in the local durable controller for one or more GitHub repositories; it does not dispatch work or touch GitHub on this call. Inputs provide the mission goal, owner/name repos, user-blessed acceptance criteria, and optional priority, house rules, default cloud-agent model, plan gate, and CI requirement. Returns the new mission id and normalized repo list so later wakes can decompose and dispatch units. Use when the operator has accepted mission scope and wants the first-mate loop to own tracking. It is not for one-off status reads, adding units to an existing mission, or missions whose acceptance criteria are still unsettled.", objectSchema({
|
|
10425
10467
|
goal: stringProp("Mission goal."),
|
|
10426
10468
|
repos: stringArrayProp("Repositories as owner/name strings."),
|
|
10427
10469
|
acceptance_criteria: stringProp("User-blessed acceptance criteria for the mission."),
|
|
@@ -10460,7 +10502,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10460
10502
|
repos
|
|
10461
10503
|
});
|
|
10462
10504
|
}),
|
|
10463
|
-
tool$1("scaffold_repo", "
|
|
10505
|
+
tool$1("scaffold_repo", "Seeds first-mate and agentic-dev convention files into a GitHub repository by creating a scaffold branch, committing deterministic files, and opening a pull request; it does not write directly to the default branch. Inputs name the owner/name repo, optional base ref, handling mode, and optional detection overrides for stack, OS, package manager, commands, and UI evidence. Returns the pull request plus committed, preserved, and per-file report data, or a no-op note when nothing needs seeding. Use when preparing an owned repository for the first-mate cloud-agent workflow. It is not for arbitrary third-party repositories, normal feature work, or repeated runs unless the operator intentionally wants missing or enhanced convention files.", objectSchema({
|
|
10464
10506
|
repo: stringProp("Repository as an owner/name string."),
|
|
10465
10507
|
mode: enumProp([
|
|
10466
10508
|
"add-missing-only",
|
|
@@ -10521,7 +10563,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10521
10563
|
report: plan.reports
|
|
10522
10564
|
});
|
|
10523
10565
|
}),
|
|
10524
|
-
tool$1("advance", "
|
|
10566
|
+
tool$1("advance", "Wakes the first-mate controller once, optionally applying model answers and human decisions before driving eligible missions. Inputs can supply prior request answers, bound returned request count, provider concurrency, scope the wake to one mission, or include inactive missions in the returned view. Returns the compact board, inactive summary, pending model and human requests, applied answer count, next wake timing, and whether this caller actually drove or deferred to another driver. Use when the operator is advancing the durable loop, responding to needsModel/needsHuman, or scheduling the next wake from nextWakeSeconds. It is not for read-only status checks; board reads the whole portfolio without a wake, and mission_status reads a mission-id-scoped status view.", objectSchema({
|
|
10525
10567
|
model_answers: arrayOfObjectsProp("Optional model judgments to apply before the wake.", {
|
|
10526
10568
|
requestId: stringProp("Request id from a previous needsModel entry."),
|
|
10527
10569
|
verdict: anyProp("Structured verdict for the request kind.")
|
|
@@ -10575,7 +10617,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10575
10617
|
drove: result.drove !== false
|
|
10576
10618
|
});
|
|
10577
10619
|
}),
|
|
10578
|
-
tool$1("board", "
|
|
10620
|
+
tool$1("board", "Reads the compact first-mate portfolio board without waking the controller, dispatching work, or applying answers. Inputs only choose whether inactive missions are included; active missions are returned by default with inactive counts summarized separately. Returns the same board shape that advance returns as a side effect, including mission phase counts, blocked counts, unit rows, and inactive summary. Use when the operator needs a whole-portfolio snapshot. It is not for driving progress or applying pending requests; advance does that, and mission_status is the read path scoped to a single mission id.", objectSchema({ include_all: boolProp("When true, include inactive missions in the board. Default returns active missions only and summarizes inactive counts.") }, []), async (args) => {
|
|
10579
10621
|
const includeAll = optionalBoolean(args, "include_all") ?? false;
|
|
10580
10622
|
const [missions, units] = await Promise.all([readMissions(), loadAllUnits()]);
|
|
10581
10623
|
return ok({
|
|
@@ -10583,7 +10625,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10583
10625
|
inactiveSummary: summarizeInactiveMissions(missions)
|
|
10584
10626
|
});
|
|
10585
10627
|
}),
|
|
10586
|
-
tool$1("merge_pr", "
|
|
10628
|
+
tool$1("merge_pr", "Merges a live GitHub pull request immediately, which is irreversible through this tool once GitHub accepts the merge. Inputs identify the repo and PR, bind the action to the exact reviewed head SHA, optionally bind the reviewed base branch, select the merge method, and can explicitly override ownership with allow_unowned. Returns GitHub's merge result and merge SHA after the live PR passes head-SHA and optional base concurrency checks, ownership checks, OPEN/not-draft/mergeable checks, and available CI or workflow checks. Use only after out-of-band human authorization for this exact head; this tool does not consult the first-mate approval ledger. It is not for PRs that are not agent-authored or correlated to a first-mate unit (unit.pr === pr) unless allow_unowned is intentionally set; a repo with no configured CI can merge on operator review plus the non-CI guards.", objectSchema({
|
|
10587
10629
|
repo: stringProp("Repository as an owner/name string."),
|
|
10588
10630
|
pr: numberProp("Pull request number."),
|
|
10589
10631
|
expected_head_sha: stringProp("The exact head commit SHA the operator reviewed. The merge is REJECTED if the live head has moved from this value; re-review the new head before merging."),
|
|
@@ -10593,7 +10635,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10593
10635
|
"squash",
|
|
10594
10636
|
"rebase"
|
|
10595
10637
|
], "Merge method. Defaults to squash."),
|
|
10596
|
-
allow_unowned: boolProp("Set true to merge a PR that is neither agent-authored nor
|
|
10638
|
+
allow_unowned: boolProp("Set true to merge a PR that is neither agent-authored nor correlated to a first-mate unit (unit.pr === pr). Dangerous, explicit opt-in; the override is audit-logged.")
|
|
10597
10639
|
}, [
|
|
10598
10640
|
"repo",
|
|
10599
10641
|
"pr",
|
|
@@ -10625,10 +10667,10 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10625
10667
|
sha: merged.sha
|
|
10626
10668
|
});
|
|
10627
10669
|
}),
|
|
10628
|
-
tool$1("close_pr", "
|
|
10670
|
+
tool$1("close_pr", "Closes a live GitHub pull request without merging it and reconciles any correlated first-mate units as terminal in the local ledger. Inputs identify the owner/name repo and PR, with allow_unowned as an explicit override for PRs outside first-mate ownership. Returns the closed state plus reconciliation counts, or an already-closed note when the PR was previously closed. Use when the operator wants to stop an open PR rather than merge it. It is not for merged PRs, or for PRs that are not agent-authored or correlated to a first-mate unit (unit.pr === pr), unless allow_unowned is intentionally set.", objectSchema({
|
|
10629
10671
|
repo: stringProp("Repository as an owner/name string."),
|
|
10630
10672
|
pr: numberProp("Pull request number."),
|
|
10631
|
-
allow_unowned: boolProp("Set true to close a PR that is neither agent-authored nor
|
|
10673
|
+
allow_unowned: boolProp("Set true to close a PR that is neither agent-authored nor correlated to a first-mate unit (unit.pr === pr). Explicit opt-in; audit-logged.")
|
|
10632
10674
|
}, ["repo", "pr"]), async (args) => {
|
|
10633
10675
|
const repoSlug = requiredString(args, "repo");
|
|
10634
10676
|
const repo = parseRepoSlug(repoSlug);
|
|
@@ -10655,10 +10697,10 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10655
10697
|
reconciled
|
|
10656
10698
|
});
|
|
10657
10699
|
}),
|
|
10658
|
-
tool$1("mark_ready", "
|
|
10700
|
+
tool$1("mark_ready", "Marks an open draft GitHub pull request ready for review through GitHub's ready-for-review mutation. Inputs identify the owner/name repo and PR, with allow_unowned as an explicit override for PRs outside first-mate ownership. Returns whether the PR is ready and whether it was already non-draft. Use when a first-mate or operator-owned draft PR should enter human or CI review. It is not for closed or merged PRs, or for PRs that are not agent-authored or correlated to a first-mate unit (unit.pr === pr), unless allow_unowned is intentionally set.", objectSchema({
|
|
10659
10701
|
repo: stringProp("Repository as an owner/name string."),
|
|
10660
10702
|
pr: numberProp("Pull request number."),
|
|
10661
|
-
allow_unowned: boolProp("Set true to mark a PR ready when it is neither agent-authored nor
|
|
10703
|
+
allow_unowned: boolProp("Set true to mark a PR ready when it is neither agent-authored nor correlated to a first-mate unit (unit.pr === pr). Explicit opt-in; audit-logged.")
|
|
10662
10704
|
}, ["repo", "pr"]), async (args) => {
|
|
10663
10705
|
const repoSlug = requiredString(args, "repo");
|
|
10664
10706
|
const repo = parseRepoSlug(repoSlug);
|
|
@@ -10681,7 +10723,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10681
10723
|
alreadyReady: false
|
|
10682
10724
|
});
|
|
10683
10725
|
}),
|
|
10684
|
-
tool$1("add_units", "
|
|
10726
|
+
tool$1("add_units", "Adds dispatchable units to an existing active first-mate mission without dispatching them immediately. Inputs name the mission and unit list; each unit supplies a title plus optional repo, provider, same-call dependency indices, and model override. Returns the mission id and the units actually added after validation and deduplication. Use when the operator has decomposed additional work for a mission that is already active. It is not for creating a new mission, adding work to inactive missions, or expressing dependencies on units from earlier calls; dependsOn indices are 0-based within this submitted list, invalid or self indices are ignored, and cycles are rejected.", objectSchema({
|
|
10685
10727
|
mission_id: stringProp("Mission id to add units to."),
|
|
10686
10728
|
units: arrayOfObjectsProp("Units to add to the mission.", {
|
|
10687
10729
|
title: stringProp("Unit title."),
|
|
@@ -10711,7 +10753,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10711
10753
|
added: await addUnitsToMission(mission, units, deps, existingUnits)
|
|
10712
10754
|
});
|
|
10713
10755
|
}),
|
|
10714
|
-
tool$1("abandon_mission", "
|
|
10756
|
+
tool$1("abandon_mission", "Marks a first-mate mission abandoned in the local durable ledgers so it drops from the active board, and terminalizes live units without merging. Inputs name the mission and can include a short operator reason returned in the tool result. Returns the abandoned mission id and the number of units marked terminal. Use when the operator is permanently retiring a mission from first-mate tracking. It is local-ledger-only and terminal, not a remote cancellation tool: open PRs stay open and GitHub cloud agents keep running unless the operator closes or stops that work separately.", objectSchema({
|
|
10715
10757
|
mission_id: stringProp("Mission id to abandon."),
|
|
10716
10758
|
reason: stringProp("Optional short reason for the abandonment.")
|
|
10717
10759
|
}, ["mission_id"]), async (args) => {
|
|
@@ -10742,7 +10784,7 @@ function createFirstMateTools(depsOverride = {}) {
|
|
|
10742
10784
|
...reason !== void 0 ? { reason } : {}
|
|
10743
10785
|
});
|
|
10744
10786
|
}),
|
|
10745
|
-
tool$1("mission_status", "
|
|
10787
|
+
tool$1("mission_status", "Reads compact first-mate mission status without waking the controller or dispatching work. Inputs can filter by mission_id and can include inactive missions; active missions are returned by default with inactive counts summarized separately. Returns mission status rows built from the same board data, including counts, blocked count, unit rows, and done/failed summary. Use when the operator needs a mission-id-scoped read or a compact status list. It is not for the whole portfolio board without a mission filter, which is board, and it is not for driving progress, which is advance.", objectSchema({
|
|
10746
10788
|
mission_id: stringProp("Optional mission id to filter to."),
|
|
10747
10789
|
include_all: boolProp("When true, include inactive missions in the status list. Default returns active missions only and summarizes inactive counts.")
|
|
10748
10790
|
}, []), async (args) => {
|
|
@@ -18487,7 +18529,7 @@ function toolEnvelope(data, isError) {
|
|
|
18487
18529
|
* and (3) opens a WS to the bridge, sends the tool call, awaits the
|
|
18488
18530
|
* response with a per-tool timeout.
|
|
18489
18531
|
*
|
|
18490
|
-
* Each entry carries
|
|
18532
|
+
* Each entry carries a browser capability tag so `browserToolsEnabled()`
|
|
18491
18533
|
* in `src/routes/mcp/handler.ts` drops them at both list-time and
|
|
18492
18534
|
* call-time when the operator hasn't opted in via `--browse` or
|
|
18493
18535
|
* `GH_ROUTER_ENABLE_BROWSE=1`.
|
|
@@ -18505,7 +18547,7 @@ function toolEnvelope(data, isError) {
|
|
|
18505
18547
|
const BROWSER_TOOLS = Object.freeze([
|
|
18506
18548
|
{
|
|
18507
18549
|
toolNameHttp: "browser_list_tabs",
|
|
18508
|
-
description: "
|
|
18550
|
+
description: "Lists open tabs across all browser windows. It takes no input and returns each tab's id, URL, title, active flag, and window id. The returned tab ids are the inputs used by tab-scoped browser tools, especially for pre-existing tabs that were not opened by browser_open_tab. It is a power-tier discovery tool for tab selection and inventory, not a page-content reader or navigation tool.",
|
|
18509
18551
|
inputSchema: {
|
|
18510
18552
|
type: "object",
|
|
18511
18553
|
additionalProperties: false,
|
|
@@ -18518,7 +18560,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18518
18560
|
},
|
|
18519
18561
|
{
|
|
18520
18562
|
toolNameHttp: "browser_open_tab",
|
|
18521
|
-
description: "
|
|
18563
|
+
description: "Opens a URL in a new browser tab, or navigates the currently active tab when reuseActive is true, then waits briefly for the tab load state to reach complete. It takes a URL and optional reuseActive flag, and returns the tab id, final URL, and a synthetic statusCode load flag where 200 means the tab reported complete and 0 means it did not. The statusCode is not the page's HTTP response code, so a loaded 404 page can still return 200. Use this to establish a tab before other browser tools; blocked URLs return {blocked, reason}, including browser settings/preferences/extensions/flags pages, file:// by default, and extension options/popup pages, while devtools:// is allowed.",
|
|
18522
18564
|
inputSchema: {
|
|
18523
18565
|
type: "object",
|
|
18524
18566
|
required: ["url"],
|
|
@@ -18526,11 +18568,11 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18526
18568
|
properties: {
|
|
18527
18569
|
url: {
|
|
18528
18570
|
type: "string",
|
|
18529
|
-
description: "
|
|
18571
|
+
description: "URL to load. Browser-internal settings, preferences, extensions, flags, password/management pages, extension options/popup pages, and file:// URLs by default are blocked before dispatch."
|
|
18530
18572
|
},
|
|
18531
18573
|
reuseActive: {
|
|
18532
18574
|
type: "boolean",
|
|
18533
|
-
description: "When true,
|
|
18575
|
+
description: "When true, navigates the currently active tab instead of opening a new tab. Default false. Use browser_navigate when you already know the target tab id."
|
|
18534
18576
|
}
|
|
18535
18577
|
}
|
|
18536
18578
|
},
|
|
@@ -18541,7 +18583,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18541
18583
|
},
|
|
18542
18584
|
{
|
|
18543
18585
|
toolNameHttp: "browser_close_tab",
|
|
18544
|
-
description: "
|
|
18586
|
+
description: "Closes one or more browser tabs by id. It takes a non-empty tabIds array, usually obtained from browser_list_tabs, and returns {closed: N} after requesting Chrome to remove those tabs. This is a power-tier tab lifecycle tool for cleanup or closing known throwaway tabs. Avoid using it when the user may still need a tab, and prefer leaving the tab open if the id was not freshly discovered or created for the current task.",
|
|
18545
18587
|
inputSchema: {
|
|
18546
18588
|
type: "object",
|
|
18547
18589
|
required: ["tabIds"],
|
|
@@ -18549,7 +18591,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18549
18591
|
properties: { tabIds: {
|
|
18550
18592
|
type: "array",
|
|
18551
18593
|
items: { type: "number" },
|
|
18552
|
-
description: "
|
|
18594
|
+
description: "Non-empty array of tab ids to close, usually from browser_list_tabs or browser_open_tab."
|
|
18553
18595
|
} }
|
|
18554
18596
|
},
|
|
18555
18597
|
capability: "browser_power",
|
|
@@ -18559,7 +18601,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18559
18601
|
},
|
|
18560
18602
|
{
|
|
18561
18603
|
toolNameHttp: "browser_navigate",
|
|
18562
|
-
description: "
|
|
18604
|
+
description: "Navigates an existing tab by going to a URL, moving back or forward in history, or reloading. It takes a tab id plus an action, with url required only for action='goto', and returns {finalUrl, statusCode} for completed navigation or {blocked, reason} for a policy-blocked URL. The statusCode is a synthetic load-complete flag, not the page's HTTP response code. Use this when the target tab already exists; use browser_open_tab to create a new tab, and expect the same URL policy blocks as open_tab, including browser-internal pages, file:// by default, and extension options/popup pages.",
|
|
18563
18605
|
inputSchema: {
|
|
18564
18606
|
type: "object",
|
|
18565
18607
|
required: ["tabId", "action"],
|
|
@@ -18567,7 +18609,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18567
18609
|
properties: {
|
|
18568
18610
|
tabId: {
|
|
18569
18611
|
type: "number",
|
|
18570
|
-
description: "Tab id from browser_list_tabs
|
|
18612
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18571
18613
|
},
|
|
18572
18614
|
action: {
|
|
18573
18615
|
type: "string",
|
|
@@ -18577,15 +18619,15 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18577
18619
|
"forward",
|
|
18578
18620
|
"reload"
|
|
18579
18621
|
],
|
|
18580
|
-
description: "
|
|
18622
|
+
description: "Navigation action: goto a URL, go back, go forward, or reload the current page."
|
|
18581
18623
|
},
|
|
18582
18624
|
url: {
|
|
18583
18625
|
type: "string",
|
|
18584
|
-
description: "
|
|
18626
|
+
description: "URL to load when action='goto'. Ignored for back, forward, and reload."
|
|
18585
18627
|
},
|
|
18586
18628
|
hard: {
|
|
18587
18629
|
type: "boolean",
|
|
18588
|
-
description: "Reload only:
|
|
18630
|
+
description: "Reload only: when true, bypasses cache like Ctrl+Shift+R. Default false."
|
|
18589
18631
|
}
|
|
18590
18632
|
}
|
|
18591
18633
|
},
|
|
@@ -18596,7 +18638,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18596
18638
|
},
|
|
18597
18639
|
{
|
|
18598
18640
|
toolNameHttp: "browser_screenshot",
|
|
18599
|
-
description: "
|
|
18641
|
+
description: "Captures a screenshot of the visible area of a tab, as PNG by default or JPEG when requested. It takes a tab id and optional format, then returns base64-encoded image bytes plus contentType. The tab must be active in its window, so this tool auto-activates the tab if needed and that changes which tab is focused. Use screenshot for visual layout, canvas, SVG, maps, or image-only regions; prefer browser_observe when page text and actionable state are enough.",
|
|
18600
18642
|
inputSchema: {
|
|
18601
18643
|
type: "object",
|
|
18602
18644
|
required: ["tabId"],
|
|
@@ -18604,12 +18646,12 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18604
18646
|
properties: {
|
|
18605
18647
|
tabId: {
|
|
18606
18648
|
type: "number",
|
|
18607
|
-
description: "Tab id from browser_list_tabs
|
|
18649
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18608
18650
|
},
|
|
18609
18651
|
format: {
|
|
18610
18652
|
type: "string",
|
|
18611
18653
|
enum: ["png", "jpeg"],
|
|
18612
|
-
description: "Image format. Default 'png'."
|
|
18654
|
+
description: "Image format for the returned screenshot. Default 'png'; use 'jpeg' when smaller image bytes are preferable."
|
|
18613
18655
|
}
|
|
18614
18656
|
}
|
|
18615
18657
|
},
|
|
@@ -18620,7 +18662,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18620
18662
|
},
|
|
18621
18663
|
{
|
|
18622
18664
|
toolNameHttp: "browser_read_page",
|
|
18623
|
-
description: "
|
|
18665
|
+
description: "Returns a compressed page snapshot for a tab: visible text, interactive elements with refs, viewport metadata, and visualSurfaces for canvas or SVG regions that need vision. It takes a tab id and optional mode, and each element includes a ref plus bbox in CSS viewport pixels, the same coordinate space used by browser_mouse, browser_drag, and scroll at-pointer. Refs persist across snapshots of the same document until navigation or DOM replacement, and are a better input to follow-up actions than brittle CSS selectors. Use read_page when enumeration, coordinates, refs, or raw snapshot structure are needed; prefer browser_act or browser_find for intent-driven interaction, browser_observe for a short natural-language page summary, and browser_screenshot for visual pixels.",
|
|
18624
18666
|
inputSchema: {
|
|
18625
18667
|
type: "object",
|
|
18626
18668
|
required: ["tabId"],
|
|
@@ -18628,12 +18670,12 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18628
18670
|
properties: {
|
|
18629
18671
|
tabId: {
|
|
18630
18672
|
type: "number",
|
|
18631
|
-
description: "Tab id from browser_list_tabs
|
|
18673
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18632
18674
|
},
|
|
18633
18675
|
mode: {
|
|
18634
18676
|
type: "string",
|
|
18635
18677
|
enum: ["summary", "full"],
|
|
18636
|
-
description: "Snapshot scope. Default 'summary'
|
|
18678
|
+
description: "Snapshot scope. Default 'summary' focuses on viewport-visible text and elements; 'full' asks for a broader page-wide snapshot. The default CDP extractor caps around 500 elements and 32 KiB text, with legacy fallback caps possibly lower or higher by mode."
|
|
18637
18679
|
}
|
|
18638
18680
|
}
|
|
18639
18681
|
},
|
|
@@ -18644,13 +18686,16 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18644
18686
|
},
|
|
18645
18687
|
{
|
|
18646
18688
|
toolNameHttp: "browser_scroll",
|
|
18647
|
-
description: "
|
|
18689
|
+
description: "Scrolls a tab or a scrollable region inside a tab. It takes a tab id, target mode, and mode-specific fields for page top/bottom, pixel deltas, element centering, or wheel scrolling at a pointer. The at-pointer path dispatches a real wheel event at a ref, selector, or CSS viewport coordinate, which is the path for chat panes, infinite lists, and modal bodies with their own scroll containers. Use browser_act with action='scroll_into_view' or intent mode for simple element reveal; use browser_scroll when page-level movement, precise deltas, or sub-container wheel scrolling are needed.",
|
|
18648
18690
|
inputSchema: {
|
|
18649
18691
|
type: "object",
|
|
18650
18692
|
required: ["tabId", "target"],
|
|
18651
18693
|
additionalProperties: false,
|
|
18652
18694
|
properties: {
|
|
18653
|
-
tabId: {
|
|
18695
|
+
tabId: {
|
|
18696
|
+
type: "number",
|
|
18697
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18698
|
+
},
|
|
18654
18699
|
target: {
|
|
18655
18700
|
type: "string",
|
|
18656
18701
|
enum: [
|
|
@@ -18660,39 +18705,39 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18660
18705
|
"element",
|
|
18661
18706
|
"at-pointer"
|
|
18662
18707
|
],
|
|
18663
|
-
description: "Scroll target
|
|
18708
|
+
description: "Scroll target mode: page top, page bottom, pixel delta, element centering, or wheel event at a pointer."
|
|
18664
18709
|
},
|
|
18665
18710
|
pixels: {
|
|
18666
18711
|
type: "number",
|
|
18667
|
-
description: "Pixel delta when target=pixels. Positive scrolls down
|
|
18712
|
+
description: "Pixel delta when target='pixels'. Positive scrolls down and negative scrolls up."
|
|
18668
18713
|
},
|
|
18669
18714
|
ref: {
|
|
18670
18715
|
type: "string",
|
|
18671
|
-
description: "Element ref. For target=element,
|
|
18716
|
+
description: "Element ref. For target='element', the element is centered; for target='at-pointer', the element bbox center becomes the wheel position."
|
|
18672
18717
|
},
|
|
18673
18718
|
selector: {
|
|
18674
18719
|
type: "string",
|
|
18675
|
-
description: "CSS selector. For target=at-pointer,
|
|
18720
|
+
description: "CSS selector fallback when no ref is available. For target='at-pointer', resolves to the element bbox center."
|
|
18676
18721
|
},
|
|
18677
18722
|
x: {
|
|
18678
18723
|
type: "number",
|
|
18679
|
-
description: "Pointer x
|
|
18724
|
+
description: "Pointer x in CSS viewport pixels for target='at-pointer'. Pair with y. Exactly one of ref, selector, or x+y is required for at-pointer."
|
|
18680
18725
|
},
|
|
18681
18726
|
y: {
|
|
18682
18727
|
type: "number",
|
|
18683
|
-
description: "Pointer y
|
|
18728
|
+
description: "Pointer y in CSS viewport pixels for target='at-pointer'. Pair with x."
|
|
18684
18729
|
},
|
|
18685
18730
|
deltaX: {
|
|
18686
18731
|
type: "number",
|
|
18687
|
-
description: "Wheel delta x
|
|
18732
|
+
description: "Wheel delta x in CSS pixels for target='at-pointer'. Default 0. Clamped to absolute value 10000."
|
|
18688
18733
|
},
|
|
18689
18734
|
deltaY: {
|
|
18690
18735
|
type: "number",
|
|
18691
|
-
description: "Wheel delta y
|
|
18736
|
+
description: "Wheel delta y in CSS pixels for target='at-pointer'. Positive scrolls down. Default 0. Clamped to absolute value 10000; at least one of deltaX or deltaY must be non-zero."
|
|
18692
18737
|
},
|
|
18693
18738
|
force: {
|
|
18694
18739
|
type: "boolean",
|
|
18695
|
-
description: "
|
|
18740
|
+
description: "For target='at-pointer', skips the pre-wheel elementFromPoint hit-test. Default false. Set true only when an overlay covers the target but forwards wheel events."
|
|
18696
18741
|
}
|
|
18697
18742
|
}
|
|
18698
18743
|
},
|
|
@@ -18703,16 +18748,19 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18703
18748
|
},
|
|
18704
18749
|
{
|
|
18705
18750
|
toolNameHttp: "browser_keyboard",
|
|
18706
|
-
description: "
|
|
18751
|
+
description: "Sends a discrete key or chord to the focused element or browser via CDP Input.dispatchKeyEvent. It takes a tab id and a keys string such as 'Control+L', 'Command+L', 'Enter', 'Escape', or 'ArrowDown', and returns the extension dispatch result. Browser-level shortcuts such as Ctrl+T and Ctrl+W actually fire because this uses chrome.debugger input rather than synthetic DOM events. Use keyboard for shortcuts and non-printable control keys; prefer browser_type for literal text entry into a focused field and browser_act with action='fill' for plain form values.",
|
|
18707
18752
|
inputSchema: {
|
|
18708
18753
|
type: "object",
|
|
18709
18754
|
required: ["tabId", "keys"],
|
|
18710
18755
|
additionalProperties: false,
|
|
18711
18756
|
properties: {
|
|
18712
|
-
tabId: {
|
|
18757
|
+
tabId: {
|
|
18758
|
+
type: "number",
|
|
18759
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18760
|
+
},
|
|
18713
18761
|
keys: {
|
|
18714
18762
|
type: "string",
|
|
18715
|
-
description: "Key or chord.
|
|
18763
|
+
description: "Key or chord. Join modifiers with '+', using Control, Ctrl, Alt, Shift, Meta, Command, or Cmd. A single named key such as Enter or Escape is also valid."
|
|
18716
18764
|
}
|
|
18717
18765
|
}
|
|
18718
18766
|
},
|
|
@@ -18723,13 +18771,16 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18723
18771
|
},
|
|
18724
18772
|
{
|
|
18725
18773
|
toolNameHttp: "browser_wait",
|
|
18726
|
-
description: "
|
|
18774
|
+
description: "Waits for a tab condition without mutating the page. It takes a tab id, an until mode, and the matching operand: a CSS selector for element appearance, a JavaScript regex string for URL matching, or networkIdle for the heuristic of tab status complete plus 500 ms quiet. It returns {ok: true, elapsedMs} on success and {ok: false, reason: 'timeout'} when the condition is not reached before the timeout. Use wait after navigation or actions that trigger asynchronous rendering; do not use it as a page reader, and prefer browser_observe or browser_read_page when the task is to inspect current content.",
|
|
18727
18775
|
inputSchema: {
|
|
18728
18776
|
type: "object",
|
|
18729
18777
|
required: ["tabId", "until"],
|
|
18730
18778
|
additionalProperties: false,
|
|
18731
18779
|
properties: {
|
|
18732
|
-
tabId: {
|
|
18780
|
+
tabId: {
|
|
18781
|
+
type: "number",
|
|
18782
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18783
|
+
},
|
|
18733
18784
|
until: {
|
|
18734
18785
|
type: "string",
|
|
18735
18786
|
enum: [
|
|
@@ -18737,19 +18788,19 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18737
18788
|
"url",
|
|
18738
18789
|
"networkIdle"
|
|
18739
18790
|
],
|
|
18740
|
-
description: "
|
|
18791
|
+
description: "Condition to wait for: selector, URL regex match, or network-idle heuristic."
|
|
18741
18792
|
},
|
|
18742
18793
|
selector: {
|
|
18743
18794
|
type: "string",
|
|
18744
|
-
description: "CSS selector when until=selector."
|
|
18795
|
+
description: "CSS selector required when until='selector'."
|
|
18745
18796
|
},
|
|
18746
18797
|
urlPattern: {
|
|
18747
18798
|
type: "string",
|
|
18748
|
-
description: "
|
|
18799
|
+
description: "JavaScript regex source string required when until='url'."
|
|
18749
18800
|
},
|
|
18750
18801
|
timeoutMs: {
|
|
18751
18802
|
type: "number",
|
|
18752
|
-
description: "
|
|
18803
|
+
description: "Maximum wait in milliseconds. Default 10000, hard cap 60000."
|
|
18753
18804
|
}
|
|
18754
18805
|
}
|
|
18755
18806
|
},
|
|
@@ -18760,20 +18811,23 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18760
18811
|
},
|
|
18761
18812
|
{
|
|
18762
18813
|
toolNameHttp: "browser_eval_js",
|
|
18763
|
-
description: "
|
|
18814
|
+
description: "Evaluates a JavaScript expression in the tab's main world, equivalent to typing in the DevTools console. It takes a tab id, expression, and optional timeout, awaits promises returned by the expression, and returns {result} or {error}. The expression can read or mutate the page, storage, cookies, or location, so this is the power-tier escape hatch for behaviors the structured browser tools do not cover. Prefer dedicated tools for navigation, clicking, filling, extraction, diagnostics, and screenshots; note that URL policy checks only apply directly to browser_open_tab and browser_navigate, while extension-side navigation blocking still applies to many browser-internal pages.",
|
|
18764
18815
|
inputSchema: {
|
|
18765
18816
|
type: "object",
|
|
18766
18817
|
required: ["tabId", "expression"],
|
|
18767
18818
|
additionalProperties: false,
|
|
18768
18819
|
properties: {
|
|
18769
|
-
tabId: {
|
|
18820
|
+
tabId: {
|
|
18821
|
+
type: "number",
|
|
18822
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18823
|
+
},
|
|
18770
18824
|
expression: {
|
|
18771
18825
|
type: "string",
|
|
18772
|
-
description: "
|
|
18826
|
+
description: "JavaScript expression to evaluate. Size should stay small for reliability, but no schema length cap is enforced. Top-level await is not supported; wrap async work in (async () => ...)()."
|
|
18773
18827
|
},
|
|
18774
18828
|
timeoutMs: {
|
|
18775
18829
|
type: "number",
|
|
18776
|
-
description: "
|
|
18830
|
+
description: "Maximum evaluation time in milliseconds. Default 5000, hard cap 30000."
|
|
18777
18831
|
}
|
|
18778
18832
|
}
|
|
18779
18833
|
},
|
|
@@ -18784,7 +18838,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18784
18838
|
},
|
|
18785
18839
|
{
|
|
18786
18840
|
toolNameHttp: "browser_download",
|
|
18787
|
-
description: "
|
|
18841
|
+
description: "Triggers a browser download from a direct URL and waits for the extension's completion signal. It takes a tab id for association, source='url', the URL, and optional saveAs path, then returns {downloadId, path, bytes, mimeType} when Chrome reports the download complete. The file lands in Chrome's default Downloads directory unless saveAs provides a relative filename or subdirectory, and conflicts are auto-uniquified by the browser. Use this for known direct download URLs; it does not click page links, and the extension currently waits up to 60 seconds internally, so downloads that finish after 60 seconds can report timeout even though the outer wire budget is larger.",
|
|
18788
18842
|
inputSchema: {
|
|
18789
18843
|
type: "object",
|
|
18790
18844
|
required: ["tabId", "url"],
|
|
@@ -18792,20 +18846,20 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18792
18846
|
properties: {
|
|
18793
18847
|
tabId: {
|
|
18794
18848
|
type: "number",
|
|
18795
|
-
description: "Tab id
|
|
18849
|
+
description: "Tab id for association and logging; the download itself is window-scoped, not tab-scoped."
|
|
18796
18850
|
},
|
|
18797
18851
|
source: {
|
|
18798
18852
|
type: "string",
|
|
18799
18853
|
enum: ["url"],
|
|
18800
|
-
description: "Download source. Only 'url' supported in v1; click-then-wait
|
|
18854
|
+
description: "Download source. Only 'url' is supported in v1; click-then-wait is not on this surface."
|
|
18801
18855
|
},
|
|
18802
18856
|
url: {
|
|
18803
18857
|
type: "string",
|
|
18804
|
-
description: "Direct URL to download.
|
|
18858
|
+
description: "Direct URL to download. No schema length cap is enforced."
|
|
18805
18859
|
},
|
|
18806
18860
|
saveAs: {
|
|
18807
18861
|
type: "string",
|
|
18808
|
-
description: "Optional filename
|
|
18862
|
+
description: "Optional relative filename or subdirectory under Downloads. Chrome enforces download-path restrictions and auto-uniquifies conflicts."
|
|
18809
18863
|
}
|
|
18810
18864
|
}
|
|
18811
18865
|
},
|
|
@@ -18816,13 +18870,16 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18816
18870
|
},
|
|
18817
18871
|
{
|
|
18818
18872
|
toolNameHttp: "browser_mouse",
|
|
18819
|
-
description: "
|
|
18873
|
+
description: "Moves, clicks, double-clicks, presses, or releases the mouse through real CDP Input.dispatchMouseEvent calls. It takes a tab id, action, exactly one target form (ref, selector, or x+y CSS viewport coordinates), and optional button, trajectory, and force settings. Use mouse for hover-to-reveal menus, canvas/map/image-map clicks, event.isTrusted checks, precise coordinate targeting, or low-level press/release sequences that browser_act cannot express. Prefer browser_act for ordinary element clicks and fills; by default ref/selector targets are hit-tested with elementFromPoint and fail with target_obscured unless force is true.",
|
|
18820
18874
|
inputSchema: {
|
|
18821
18875
|
type: "object",
|
|
18822
18876
|
required: ["tabId", "action"],
|
|
18823
18877
|
additionalProperties: false,
|
|
18824
18878
|
properties: {
|
|
18825
|
-
tabId: {
|
|
18879
|
+
tabId: {
|
|
18880
|
+
type: "number",
|
|
18881
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18882
|
+
},
|
|
18826
18883
|
action: {
|
|
18827
18884
|
type: "string",
|
|
18828
18885
|
enum: [
|
|
@@ -18832,19 +18889,19 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18832
18889
|
"down",
|
|
18833
18890
|
"up"
|
|
18834
18891
|
],
|
|
18835
|
-
description: "
|
|
18892
|
+
description: "Mouse action. move positions the cursor for hover; click sends press+release; dblclick sends two press/release cycles; down presses only; up releases only."
|
|
18836
18893
|
},
|
|
18837
18894
|
ref: {
|
|
18838
18895
|
type: "string",
|
|
18839
|
-
description: "Element ref from browser_read_page
|
|
18896
|
+
description: "Element ref from browser_read_page or browser_find. Resolves to bbox center. Exactly one of ref, selector, or x+y is required."
|
|
18840
18897
|
},
|
|
18841
18898
|
selector: {
|
|
18842
18899
|
type: "string",
|
|
18843
|
-
description: "CSS selector
|
|
18900
|
+
description: "CSS selector fallback. Resolves to bbox center. Exactly one of ref, selector, or x+y is required."
|
|
18844
18901
|
},
|
|
18845
18902
|
x: {
|
|
18846
18903
|
type: "number",
|
|
18847
|
-
description: "Target x in CSS viewport pixels. Pair with y. Use when working from a screenshot or eval_js output."
|
|
18904
|
+
description: "Target x in CSS viewport pixels. Pair with y. Use when working from a screenshot, canvas coordinate, or eval_js output."
|
|
18848
18905
|
},
|
|
18849
18906
|
y: {
|
|
18850
18907
|
type: "number",
|
|
@@ -18857,19 +18914,19 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18857
18914
|
"right",
|
|
18858
18915
|
"middle"
|
|
18859
18916
|
],
|
|
18860
|
-
description: "Mouse button for click
|
|
18917
|
+
description: "Mouse button for click, dblclick, down, or up. Default 'left'. Ignored for action='move'."
|
|
18861
18918
|
},
|
|
18862
18919
|
steps: {
|
|
18863
18920
|
type: "number",
|
|
18864
|
-
description: "
|
|
18921
|
+
description: "Trajectory step count. Values greater than 1 interpolate the cursor approach over multiple mouseMoved events. Default 1. Clamped to [1, 100]."
|
|
18865
18922
|
},
|
|
18866
18923
|
stepDelayMs: {
|
|
18867
18924
|
type: "number",
|
|
18868
|
-
description: "Pause between interpolated mouseMoved events when steps
|
|
18925
|
+
description: "Pause between interpolated mouseMoved events when steps is greater than 1. Default 8. Clamped to [0, 50]."
|
|
18869
18926
|
},
|
|
18870
18927
|
force: {
|
|
18871
18928
|
type: "boolean",
|
|
18872
|
-
description: "
|
|
18929
|
+
description: "For ref or selector targets, skips the elementFromPoint hit-test. Default false. Use only when an overlay covers the target but forwards pointer events."
|
|
18873
18930
|
}
|
|
18874
18931
|
}
|
|
18875
18932
|
},
|
|
@@ -18880,20 +18937,23 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18880
18937
|
},
|
|
18881
18938
|
{
|
|
18882
18939
|
toolNameHttp: "browser_drag",
|
|
18883
|
-
description: "
|
|
18940
|
+
description: "Drags from a source target to a destination target through CDP input events. It takes a tab id, one source target, one destination target, and optional button, trajectory, mode, and force settings; targets can be refs, selectors, or CSS viewport coordinates. Auto mode chooses HTML5 native drag-and-drop for draggable='true' sources, using Input.setInterceptDrags plus Input.dispatchDragEvent, and otherwise uses pointer drag events for libraries such as react-dnd, Sortable.js, and mouse-event-based handlers. Use drag for actual drag-and-drop interactions; use browser_mouse for simple clicks, hover, or isolated press/release gestures. Returns {ok: true, mode_used, from, to} so the caller can verify whether pointer or html5 ran and which coordinates were used.",
|
|
18884
18941
|
inputSchema: {
|
|
18885
18942
|
type: "object",
|
|
18886
18943
|
required: ["tabId"],
|
|
18887
18944
|
additionalProperties: false,
|
|
18888
18945
|
properties: {
|
|
18889
|
-
tabId: {
|
|
18946
|
+
tabId: {
|
|
18947
|
+
type: "number",
|
|
18948
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
18949
|
+
},
|
|
18890
18950
|
fromRef: {
|
|
18891
18951
|
type: "string",
|
|
18892
|
-
description: "Source ref from browser_read_page
|
|
18952
|
+
description: "Source element ref from browser_read_page or browser_find. Preferred when available."
|
|
18893
18953
|
},
|
|
18894
18954
|
fromSelector: {
|
|
18895
18955
|
type: "string",
|
|
18896
|
-
description: "Source CSS selector
|
|
18956
|
+
description: "Source CSS selector fallback when no source ref is available."
|
|
18897
18957
|
},
|
|
18898
18958
|
fromX: {
|
|
18899
18959
|
type: "number",
|
|
@@ -18905,11 +18965,11 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18905
18965
|
},
|
|
18906
18966
|
toRef: {
|
|
18907
18967
|
type: "string",
|
|
18908
|
-
description: "Destination ref from browser_read_page
|
|
18968
|
+
description: "Destination element ref from browser_read_page or browser_find. Preferred when available."
|
|
18909
18969
|
},
|
|
18910
18970
|
toSelector: {
|
|
18911
18971
|
type: "string",
|
|
18912
|
-
description: "Destination CSS selector
|
|
18972
|
+
description: "Destination CSS selector fallback when no destination ref is available."
|
|
18913
18973
|
},
|
|
18914
18974
|
toX: {
|
|
18915
18975
|
type: "number",
|
|
@@ -18922,15 +18982,15 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18922
18982
|
button: {
|
|
18923
18983
|
type: "string",
|
|
18924
18984
|
enum: ["left", "middle"],
|
|
18925
|
-
description: "Mouse button held during drag. Default 'left'."
|
|
18985
|
+
description: "Mouse button held during the drag. Default 'left'."
|
|
18926
18986
|
},
|
|
18927
18987
|
steps: {
|
|
18928
18988
|
type: "number",
|
|
18929
|
-
description: "Intermediate mouseMoved events from
|
|
18989
|
+
description: "Intermediate mouseMoved events from source to destination with the button held. Drag-detect libraries often need a trajectory. Default 15. Clamped to [1, 100]."
|
|
18930
18990
|
},
|
|
18931
18991
|
stepDelayMs: {
|
|
18932
18992
|
type: "number",
|
|
18933
|
-
description: "Pause between intermediate moves. Default 12. Clamped to [0, 50]."
|
|
18993
|
+
description: "Pause between intermediate moves in milliseconds. Default 12. Clamped to [0, 50]."
|
|
18934
18994
|
},
|
|
18935
18995
|
mode: {
|
|
18936
18996
|
type: "string",
|
|
@@ -18939,11 +18999,11 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18939
18999
|
"pointer",
|
|
18940
19000
|
"html5"
|
|
18941
19001
|
],
|
|
18942
|
-
description: "Drag mode. 'auto'
|
|
19002
|
+
description: "Drag mode. 'auto' is the default and picks html5 if the source has draggable='true', else pointer. Override only when auto detection chooses the wrong path."
|
|
18943
19003
|
},
|
|
18944
19004
|
force: {
|
|
18945
19005
|
type: "boolean",
|
|
18946
|
-
description: "
|
|
19006
|
+
description: "Skips the pre-press elementFromPoint hit-test on the source only. Default false. The destination is used as-is."
|
|
18947
19007
|
}
|
|
18948
19008
|
}
|
|
18949
19009
|
},
|
|
@@ -18954,20 +19014,23 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18954
19014
|
},
|
|
18955
19015
|
{
|
|
18956
19016
|
toolNameHttp: "browser_type",
|
|
18957
|
-
description: "
|
|
19017
|
+
description: "Types text into the currently focused element one character at a time via CDP Input.dispatchKeyEvent. It takes a tab id, text, and optional per-character delay; each character fires keyboard/input events, which supports autocomplete, chips, search-as-you-type fields, and handlers that listen on keydown rather than only reading element.value. Special text characters map to named keys: \\n sends Enter, \\t sends Tab, and \\b sends Backspace; other control characters below 0x20 are rejected with an actionable error. Use browser_type when real keystrokes matter, use browser_act with action='fill' for plain form-value entry, and use browser_keyboard for shortcuts or named control keys such as Control+L or Escape.",
|
|
18958
19018
|
inputSchema: {
|
|
18959
19019
|
type: "object",
|
|
18960
19020
|
required: ["tabId", "text"],
|
|
18961
19021
|
additionalProperties: false,
|
|
18962
19022
|
properties: {
|
|
18963
|
-
tabId: {
|
|
19023
|
+
tabId: {
|
|
19024
|
+
type: "number",
|
|
19025
|
+
description: "Tab id from browser_list_tabs or browser_open_tab. The text goes to whatever element is currently focused in that tab."
|
|
19026
|
+
},
|
|
18964
19027
|
text: {
|
|
18965
19028
|
type: "string",
|
|
18966
|
-
description: "
|
|
19029
|
+
description: "Text to type, up to 4096 Unicode code points. Newline, tab, and backspace are dispatched as Enter, Tab, and Backspace."
|
|
18967
19030
|
},
|
|
18968
19031
|
delayMs: {
|
|
18969
19032
|
type: "number",
|
|
18970
|
-
description: "Pause between characters. Default 0. Clamped to [0, 50]. Set
|
|
19033
|
+
description: "Pause between characters in milliseconds. Default 0. Clamped to [0, 50]. Set above 0 for debounced search-as-you-type inputs."
|
|
18971
19034
|
}
|
|
18972
19035
|
}
|
|
18973
19036
|
},
|
|
@@ -18978,17 +19041,20 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
18978
19041
|
},
|
|
18979
19042
|
{
|
|
18980
19043
|
toolNameHttp: "browser_diagnostics",
|
|
18981
|
-
description: "
|
|
19044
|
+
description: "Drains buffered console messages or network responses for a tab, with filtering before the result is returned. It takes a tab id, kind='console' or 'network', and optional level, regex, and limit filters, then returns {kind, total, returned, entries}; total is the pre-filter count and returned is the post-filter limited count. The first call for a tab lazily attaches chrome.debugger, so very-early load events from before that call are missed. Use diagnostics to investigate console errors, warnings, and request URLs; do not use it as a page-content reader, and raise limit or loosen regex when returned equals the requested limit.",
|
|
18982
19045
|
inputSchema: {
|
|
18983
19046
|
type: "object",
|
|
18984
19047
|
required: ["tabId", "kind"],
|
|
18985
19048
|
additionalProperties: false,
|
|
18986
19049
|
properties: {
|
|
18987
|
-
tabId: {
|
|
19050
|
+
tabId: {
|
|
19051
|
+
type: "number",
|
|
19052
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
19053
|
+
},
|
|
18988
19054
|
kind: {
|
|
18989
19055
|
type: "string",
|
|
18990
19056
|
enum: ["console", "network"],
|
|
18991
|
-
description: "
|
|
19057
|
+
description: "Diagnostic stream to drain: console messages or network responses."
|
|
18992
19058
|
},
|
|
18993
19059
|
level: {
|
|
18994
19060
|
type: "string",
|
|
@@ -19000,15 +19066,15 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19000
19066
|
"debug",
|
|
19001
19067
|
"all"
|
|
19002
19068
|
],
|
|
19003
|
-
description: "Console only. Default 'all'. Ignored when kind=network."
|
|
19069
|
+
description: "Console only. Default 'all'. Ignored when kind='network'."
|
|
19004
19070
|
},
|
|
19005
19071
|
regex: {
|
|
19006
19072
|
type: "string",
|
|
19007
|
-
description: "Optional
|
|
19073
|
+
description: "Optional JavaScript regex source string. For console, matches message text; for network, matches request URL."
|
|
19008
19074
|
},
|
|
19009
19075
|
limit: {
|
|
19010
19076
|
type: "number",
|
|
19011
|
-
description: "
|
|
19077
|
+
description: "Maximum entries to return after filtering. Default 100. Hard cap 1000."
|
|
19012
19078
|
}
|
|
19013
19079
|
}
|
|
19014
19080
|
},
|
|
@@ -19056,20 +19122,23 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19056
19122
|
},
|
|
19057
19123
|
{
|
|
19058
19124
|
toolNameHttp: "browser_find",
|
|
19059
|
-
description: "
|
|
19125
|
+
description: "Finds up to 5 page elements that match a natural-language intent. It takes a tab id and intent, reads a fresh snapshot internally, and returns ranked candidates with refs, roles, names, bboxes, and match reasons when available. The returned refs can be passed to browser_act in REF mode or to low-level power tools such as browser_mouse. Use find when a specific element is needed and a short candidate list is better than the full browser_read_page snapshot; use read_page when broad enumeration or raw text/context is needed.",
|
|
19060
19126
|
inputSchema: {
|
|
19061
19127
|
type: "object",
|
|
19062
19128
|
required: ["tabId", "intent"],
|
|
19063
19129
|
additionalProperties: false,
|
|
19064
19130
|
properties: {
|
|
19065
|
-
tabId: {
|
|
19131
|
+
tabId: {
|
|
19132
|
+
type: "number",
|
|
19133
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
19134
|
+
},
|
|
19066
19135
|
intent: {
|
|
19067
19136
|
type: "string",
|
|
19068
|
-
description: "Natural-language description of
|
|
19137
|
+
description: "Natural-language description of the element to find, such as 'the search box at the top' or 'the Submit button'."
|
|
19069
19138
|
}
|
|
19070
19139
|
}
|
|
19071
19140
|
},
|
|
19072
|
-
capability: "
|
|
19141
|
+
capability: "browser_compound",
|
|
19073
19142
|
async handler(args, signal) {
|
|
19074
19143
|
const tabId = typeof args.tabId === "number" ? args.tabId : void 0;
|
|
19075
19144
|
const intent = typeof args.intent === "string" ? args.intent : "";
|
|
@@ -19095,20 +19164,23 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19095
19164
|
},
|
|
19096
19165
|
{
|
|
19097
19166
|
toolNameHttp: "browser_act",
|
|
19098
|
-
description: "
|
|
19167
|
+
description: "Performs a high-level click, fill, type, select, or scroll-into-view action against a tab. It has two modes: INTENT mode takes a natural-language intent and resolves the element/action internally, while REF mode takes a ref from browser_find or browser_read_page plus optional action and value for direct dispatch without a compressor round trip. Visual fallback can click canvas or SVG regions by combining screenshot analysis with a coordinate click when text-based matching fails. Use act for ordinary page interaction before reaching for browser_mouse, browser_type, browser_keyboard, or browser_scroll; single-action results include {ok, action_taken, target_ref, navigated}, multi-step intents return summary/steps fields, and visual fallback returns click_visual with x/y coordinates.",
|
|
19099
19168
|
inputSchema: {
|
|
19100
19169
|
type: "object",
|
|
19101
19170
|
required: ["tabId"],
|
|
19102
19171
|
additionalProperties: false,
|
|
19103
19172
|
properties: {
|
|
19104
|
-
tabId: {
|
|
19173
|
+
tabId: {
|
|
19174
|
+
type: "number",
|
|
19175
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
19176
|
+
},
|
|
19105
19177
|
intent: {
|
|
19106
19178
|
type: "string",
|
|
19107
|
-
description: "Natural-language description of the action
|
|
19179
|
+
description: "Natural-language description of the action for INTENT mode. If both intent and ref are provided, ref mode wins and intent is ignored."
|
|
19108
19180
|
},
|
|
19109
19181
|
ref: {
|
|
19110
19182
|
type: "string",
|
|
19111
|
-
description: "Element ref from browser_find
|
|
19183
|
+
description: "Element ref from browser_find or browser_read_page for REF mode, which dispatches directly without a compressor round trip."
|
|
19112
19184
|
},
|
|
19113
19185
|
action: {
|
|
19114
19186
|
type: "string",
|
|
@@ -19119,15 +19191,15 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19119
19191
|
"select",
|
|
19120
19192
|
"scroll_into_view"
|
|
19121
19193
|
],
|
|
19122
|
-
description: "REF mode
|
|
19194
|
+
description: "REF mode action. Defaults to 'click'. Ignored in INTENT mode, where the resolved action comes from the intent and matched element."
|
|
19123
19195
|
},
|
|
19124
19196
|
value: {
|
|
19125
19197
|
type: "string",
|
|
19126
|
-
description: "
|
|
19198
|
+
description: "String value for fill, type, or select actions. In INTENT mode, this is available to the resolver when the action requires a value."
|
|
19127
19199
|
}
|
|
19128
19200
|
}
|
|
19129
19201
|
},
|
|
19130
|
-
capability: "
|
|
19202
|
+
capability: "browser_compound",
|
|
19131
19203
|
async handler(args, signal) {
|
|
19132
19204
|
const tabId = typeof args.tabId === "number" ? args.tabId : void 0;
|
|
19133
19205
|
if (!tabId) return toolEnvelope({ error: "tabId required" }, true);
|
|
@@ -19220,16 +19292,19 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19220
19292
|
},
|
|
19221
19293
|
{
|
|
19222
19294
|
toolNameHttp: "browser_observe",
|
|
19223
|
-
description: "
|
|
19295
|
+
description: "Produces a short natural-language description of the current page's user-actionable state, including visible forms, buttons, links, and content sections. It takes a tab id and optional intent focus, then returns a 2-4 sentence summary plus whether visualSurfaces such as canvas or SVG are present. Use observe before browser_act when the page state is unknown, or after navigation to confirm what loaded. Prefer observe over screenshot when text and controls are enough; switch to browser_screenshot for visual layout or canvas/SVG details, and use browser_read_page when raw refs, bboxes, or element lists are needed.",
|
|
19224
19296
|
inputSchema: {
|
|
19225
19297
|
type: "object",
|
|
19226
19298
|
required: ["tabId"],
|
|
19227
19299
|
additionalProperties: false,
|
|
19228
19300
|
properties: {
|
|
19229
|
-
tabId: {
|
|
19301
|
+
tabId: {
|
|
19302
|
+
type: "number",
|
|
19303
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
19304
|
+
},
|
|
19230
19305
|
intent: {
|
|
19231
19306
|
type: "string",
|
|
19232
|
-
description: "Optional natural-language focus
|
|
19307
|
+
description: "Optional natural-language focus for the summary, such as 'describe the form' or 'what is in the sidebar'."
|
|
19233
19308
|
}
|
|
19234
19309
|
}
|
|
19235
19310
|
},
|
|
@@ -19243,7 +19318,7 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19243
19318
|
},
|
|
19244
19319
|
{
|
|
19245
19320
|
toolNameHttp: "browser_extract",
|
|
19246
|
-
description: "
|
|
19321
|
+
description: "Extracts structured data from the current page into a JSON object matching the provided schema. It takes a tab id, a schema or schema-shaped descriptor, and a plain-language instruction; the inner compressor reads the page snapshot and returns only the typed object rather than the raw element list. Use extract when the desired output shape is known, such as rows of {title, author, url}; use browser_observe for a prose overview and browser_read_page when the lead model needs raw refs, bboxes, or page text. Bad schemas or wrong-shape compressor results are returned as fixable error envelopes so the caller can simplify the schema or clarify the instruction.",
|
|
19247
19322
|
inputSchema: {
|
|
19248
19323
|
type: "object",
|
|
19249
19324
|
required: [
|
|
@@ -19253,11 +19328,14 @@ const BROWSER_TOOLS = Object.freeze([
|
|
|
19253
19328
|
],
|
|
19254
19329
|
additionalProperties: false,
|
|
19255
19330
|
properties: {
|
|
19256
|
-
tabId: {
|
|
19257
|
-
|
|
19331
|
+
tabId: {
|
|
19332
|
+
type: "number",
|
|
19333
|
+
description: "Tab id from browser_list_tabs or browser_open_tab."
|
|
19334
|
+
},
|
|
19335
|
+
schema: { description: "JSON schema, or a schema-shaped descriptor, for the desired output shape." },
|
|
19258
19336
|
instruction: {
|
|
19259
19337
|
type: "string",
|
|
19260
|
-
description: "
|
|
19338
|
+
description: "Plain-language extraction instruction, such as 'the visible PR list' or 'all product cards with price and URL'."
|
|
19261
19339
|
}
|
|
19262
19340
|
}
|
|
19263
19341
|
},
|
|
@@ -23432,12 +23510,17 @@ async function countTokens(body, extraHeaders, callerSignal, retryTransient = fa
|
|
|
23432
23510
|
* slug too — `state.models?.data` mirrors Copilot's catalog where these
|
|
23433
23511
|
* land under the dotted slug, so we match by Copilot's actual id shape.
|
|
23434
23512
|
*/
|
|
23513
|
+
function geminiAvailable(source = state) {
|
|
23514
|
+
const models = source.models?.data;
|
|
23515
|
+
if (!models) return false;
|
|
23516
|
+
return models.some((m) => /^gemini-3\..*pro/i.test(m.id));
|
|
23517
|
+
}
|
|
23435
23518
|
function standInToolEnabled() {
|
|
23436
23519
|
const models = state.models?.data;
|
|
23437
23520
|
if (!models) return false;
|
|
23438
23521
|
const hasGpt55 = models.some((m) => m.id === "gpt-5.5");
|
|
23439
23522
|
const hasOpus = models.some((m) => m.id === "claude-opus-4-7" || m.id === "claude-opus-4.7");
|
|
23440
|
-
const hasGeminiPro =
|
|
23523
|
+
const hasGeminiPro = geminiAvailable();
|
|
23441
23524
|
return hasGpt55 && hasOpus && hasGeminiPro;
|
|
23442
23525
|
}
|
|
23443
23526
|
const IMPLEMENTER_SUBAGENT_MODEL = "gpt-5.5";
|
|
@@ -23483,8 +23566,8 @@ function workerToolsEnabled() {
|
|
|
23483
23566
|
return found.capabilities?.supports?.tool_calls === true;
|
|
23484
23567
|
}
|
|
23485
23568
|
/**
|
|
23486
|
-
* Gate for the compound L2 browser tools (`
|
|
23487
|
-
*
|
|
23569
|
+
* Gate for the compound L2 browser tools (`browser_act`, `browser_observe`,
|
|
23570
|
+
* `browser_extract`, `browser_find`).
|
|
23488
23571
|
*
|
|
23489
23572
|
* Returns true iff `compressorAvailable()` — i.e. at least one model in
|
|
23490
23573
|
* the compressor fallback chain (`gpt-5.4-mini` → `claude-sonnet-4.6` →
|
|
@@ -23507,19 +23590,19 @@ function browserCompoundToolsEnabled() {
|
|
|
23507
23590
|
* Gate for the L0/L1 power browser tools (`browser_read_page`,
|
|
23508
23591
|
* `browser_mouse`, `browser_drag`, `browser_type`, `browser_keyboard`,
|
|
23509
23592
|
* `browser_scroll`, `browser_eval_js`, `browser_diagnostics`,
|
|
23510
|
-
* `
|
|
23511
|
-
* `
|
|
23593
|
+
* `browser_close_tab`, `browser_list_tabs`, `browser_wait`,
|
|
23594
|
+
* `browser_download`).
|
|
23512
23595
|
*
|
|
23513
23596
|
* Returns true iff `state.powerBrowseEnabled` (set by `--power-browse`
|
|
23514
23597
|
* or `GH_ROUTER_ENABLE_POWER_BROWSE=1`). When off, the default
|
|
23515
|
-
* `--browse` surface exposes
|
|
23516
|
-
* `
|
|
23517
|
-
*
|
|
23518
|
-
*
|
|
23598
|
+
* `--browse` surface exposes the base lead tools (`navigate`, `screenshot`,
|
|
23599
|
+
* `open_tab`) and, when the compound gate passes, `act`, `observe`,
|
|
23600
|
+
* `extract`, and `find`. Power mode adds the raw primitives for users who
|
|
23601
|
+
* want direct coord/keystroke control.
|
|
23519
23602
|
*
|
|
23520
23603
|
* `handler.ts` filter chain ANDs this with `browserToolsEnabled()`
|
|
23521
|
-
* (defense-in-depth
|
|
23522
|
-
* setup path already forces basic on when power is on).
|
|
23604
|
+
* (defense-in-depth: power without the base browser server is meaningless and
|
|
23605
|
+
* the setup path already forces basic on when power is on).
|
|
23523
23606
|
*/
|
|
23524
23607
|
function browserPowerToolsEnabled() {
|
|
23525
23608
|
return state.powerBrowseEnabled === true;
|
|
@@ -23715,11 +23798,6 @@ function checkAuth(c) {
|
|
|
23715
23798
|
};
|
|
23716
23799
|
return { ok: true };
|
|
23717
23800
|
}
|
|
23718
|
-
function geminiAvailable() {
|
|
23719
|
-
const models = state.models?.data;
|
|
23720
|
-
if (!models) return false;
|
|
23721
|
-
return models.some((m) => /^gemini-3\..*pro/i.test(m.id));
|
|
23722
|
-
}
|
|
23723
23801
|
/**
|
|
23724
23802
|
* The 1M-context Opus 4.6 variant (`claude-opus-4.6-1m`, `max_prompt_tokens`
|
|
23725
23803
|
* 936K). opus_critic prefers it so it can take large artifacts in one shot
|
|
@@ -28220,6 +28298,142 @@ function round2(n) {
|
|
|
28220
28298
|
* into each sub-orchestration. The verifier only range-checks the declaration. */
|
|
28221
28299
|
const MAX_RECURSION_DEPTH = 3;
|
|
28222
28300
|
|
|
28301
|
+
//#endregion
|
|
28302
|
+
//#region src/lib/orchestration/select.ts
|
|
28303
|
+
const subsetOf = (a, b) => {
|
|
28304
|
+
for (const x of a) if (!b.has(x)) return false;
|
|
28305
|
+
return true;
|
|
28306
|
+
};
|
|
28307
|
+
function selectChampion(orchestrated, baseline, canonicalGateIds, tiePolicy) {
|
|
28308
|
+
if (!subsetOf(orchestrated.passed, orchestrated.ran)) return {
|
|
28309
|
+
winner: "baseline",
|
|
28310
|
+
reason: "orchestrated outcome malformed (passed not a subset of ran)"
|
|
28311
|
+
};
|
|
28312
|
+
if (!subsetOf(baseline.passed, baseline.ran)) return {
|
|
28313
|
+
winner: "baseline",
|
|
28314
|
+
reason: "baseline outcome malformed (passed not a subset of ran)"
|
|
28315
|
+
};
|
|
28316
|
+
if (canonicalGateIds.size === 0) return {
|
|
28317
|
+
winner: "baseline",
|
|
28318
|
+
reason: "no executable gate for this ask — ship the baseline (judgment-only)"
|
|
28319
|
+
};
|
|
28320
|
+
for (const id of canonicalGateIds) if (!orchestrated.ran.has(id)) return {
|
|
28321
|
+
winner: "baseline",
|
|
28322
|
+
reason: `orchestrated did not run canonical gate "${id}"`
|
|
28323
|
+
};
|
|
28324
|
+
let baselinePass = 0;
|
|
28325
|
+
let orchestratedPass = 0;
|
|
28326
|
+
for (const id of canonicalGateIds) {
|
|
28327
|
+
if (baseline.passed.has(id)) baselinePass += 1;
|
|
28328
|
+
if (orchestrated.passed.has(id)) orchestratedPass += 1;
|
|
28329
|
+
else if (baseline.passed.has(id)) return {
|
|
28330
|
+
winner: "baseline",
|
|
28331
|
+
reason: `orchestrated regresses on canonical check "${id}" the baseline passed`
|
|
28332
|
+
};
|
|
28333
|
+
}
|
|
28334
|
+
if (orchestratedPass > baselinePass) return {
|
|
28335
|
+
winner: "orchestrated",
|
|
28336
|
+
reason: "orchestrated passes strictly more canonical executable checks"
|
|
28337
|
+
};
|
|
28338
|
+
if (tiePolicy === "superset") return {
|
|
28339
|
+
winner: "orchestrated",
|
|
28340
|
+
reason: "orchestrated matches the baseline on the canonical checks (superset policy)"
|
|
28341
|
+
};
|
|
28342
|
+
return {
|
|
28343
|
+
winner: "baseline",
|
|
28344
|
+
reason: "orchestrated does not pass strictly more canonical checks than the baseline (strict policy)"
|
|
28345
|
+
};
|
|
28346
|
+
}
|
|
28347
|
+
|
|
28348
|
+
//#endregion
|
|
28349
|
+
//#region src/lib/orchestration/gate-runner.ts
|
|
28350
|
+
async function runGateChecks(checks, cwd, exec) {
|
|
28351
|
+
const results = await Promise.all(checks.map(async (c) => {
|
|
28352
|
+
try {
|
|
28353
|
+
const r = await exec({
|
|
28354
|
+
command: c.command,
|
|
28355
|
+
cwd
|
|
28356
|
+
});
|
|
28357
|
+
return {
|
|
28358
|
+
id: c.id,
|
|
28359
|
+
passed: r.exitCode === 0
|
|
28360
|
+
};
|
|
28361
|
+
} catch {
|
|
28362
|
+
return {
|
|
28363
|
+
id: c.id,
|
|
28364
|
+
passed: false
|
|
28365
|
+
};
|
|
28366
|
+
}
|
|
28367
|
+
}));
|
|
28368
|
+
const passed = /* @__PURE__ */ new Set();
|
|
28369
|
+
const ran = /* @__PURE__ */ new Set();
|
|
28370
|
+
for (const r of results) {
|
|
28371
|
+
ran.add(r.id);
|
|
28372
|
+
if (r.passed) passed.add(r.id);
|
|
28373
|
+
}
|
|
28374
|
+
return {
|
|
28375
|
+
passed,
|
|
28376
|
+
ran
|
|
28377
|
+
};
|
|
28378
|
+
}
|
|
28379
|
+
|
|
28380
|
+
//#endregion
|
|
28381
|
+
//#region src/lib/orchestration/gate-registry.ts
|
|
28382
|
+
/**
|
|
28383
|
+
* Built-in sealed gates. Commands follow this repo's TS/Bun conventions (the
|
|
28384
|
+
* `bun run <script>` indirection means a repo without that script simply fails
|
|
28385
|
+
* the check, which the selector treats as not-passed rather than a crash). New
|
|
28386
|
+
* ecosystems get a new sealed id here, never a caller-supplied command.
|
|
28387
|
+
*/
|
|
28388
|
+
const SEALED_GATES = {
|
|
28389
|
+
"default-ci": [
|
|
28390
|
+
{
|
|
28391
|
+
id: "typecheck",
|
|
28392
|
+
command: "bun run typecheck"
|
|
28393
|
+
},
|
|
28394
|
+
{
|
|
28395
|
+
id: "test",
|
|
28396
|
+
command: "bun test"
|
|
28397
|
+
},
|
|
28398
|
+
{
|
|
28399
|
+
id: "lint",
|
|
28400
|
+
command: "bun run lint"
|
|
28401
|
+
}
|
|
28402
|
+
],
|
|
28403
|
+
"typecheck-test": [{
|
|
28404
|
+
id: "typecheck",
|
|
28405
|
+
command: "bun run typecheck"
|
|
28406
|
+
}, {
|
|
28407
|
+
id: "test",
|
|
28408
|
+
command: "bun test"
|
|
28409
|
+
}],
|
|
28410
|
+
"typecheck-only": [{
|
|
28411
|
+
id: "typecheck",
|
|
28412
|
+
command: "bun run typecheck"
|
|
28413
|
+
}]
|
|
28414
|
+
};
|
|
28415
|
+
/** The set of sealed gate ids, used as the kernel's `knownGateIds` so the IR
|
|
28416
|
+
* verifier rejects an executable gate that references an unregistered id. */
|
|
28417
|
+
function sealedGateIds() {
|
|
28418
|
+
return new Set(Object.keys(SEALED_GATES));
|
|
28419
|
+
}
|
|
28420
|
+
/**
|
|
28421
|
+
* Resolve a sealed gate by id. Returns a DEFENSIVE CLONE (fresh objects) so a
|
|
28422
|
+
* caller can never mutate the registry's command set. `undefined` for an
|
|
28423
|
+
* unknown id, which `run_workflow` rejects before executing anything.
|
|
28424
|
+
*/
|
|
28425
|
+
function resolveSealedGate(gateId) {
|
|
28426
|
+
const checks = SEALED_GATES[gateId];
|
|
28427
|
+
if (!checks) return void 0;
|
|
28428
|
+
return {
|
|
28429
|
+
id: gateId,
|
|
28430
|
+
checks: checks.map((c) => ({
|
|
28431
|
+
id: c.id,
|
|
28432
|
+
command: c.command
|
|
28433
|
+
}))
|
|
28434
|
+
};
|
|
28435
|
+
}
|
|
28436
|
+
|
|
28223
28437
|
//#endregion
|
|
28224
28438
|
//#region src/lib/orchestration/verify.ts
|
|
28225
28439
|
const VALID_ROLES = new Set([
|
|
@@ -28244,6 +28458,7 @@ const VALID_ON_FAIL = new Set([
|
|
|
28244
28458
|
"escalate"
|
|
28245
28459
|
]);
|
|
28246
28460
|
function verifyWorkflowIR(ir, opts = {}) {
|
|
28461
|
+
const knownGateIds = opts.knownGateIds ?? sealedGateIds();
|
|
28247
28462
|
const v = [];
|
|
28248
28463
|
const push = (code, message, nodeId) => {
|
|
28249
28464
|
v.push(nodeId === void 0 ? {
|
|
@@ -28321,7 +28536,7 @@ function verifyWorkflowIR(ir, opts = {}) {
|
|
|
28321
28536
|
const g = n.gate;
|
|
28322
28537
|
if (g.kind === "executable") {
|
|
28323
28538
|
if (typeof g.gateId !== "string" || g.gateId.length === 0) push("BAD_GATE", `executable gate on node "${n.id}" must reference a sealed gateId (gate-immutability)`, n.id);
|
|
28324
|
-
else if (
|
|
28539
|
+
else if (!knownGateIds.has(g.gateId)) push("UNKNOWN_GATE_ID", `executable gate on node "${n.id}" references gateId "${g.gateId}" not in the kernel's sealed-gate registry`, n.id);
|
|
28325
28540
|
}
|
|
28326
28541
|
if (g.kind === "cross_lab") {
|
|
28327
28542
|
if (typeof g.checkerLab !== "string" || g.checkerLab.length === 0) push("BAD_GATE", `cross_lab gate on node "${n.id}" must name a checkerLab`, n.id);
|
|
@@ -28428,53 +28643,6 @@ function hasCycle(nodes, byId) {
|
|
|
28428
28643
|
return false;
|
|
28429
28644
|
}
|
|
28430
28645
|
|
|
28431
|
-
//#endregion
|
|
28432
|
-
//#region src/lib/orchestration/select.ts
|
|
28433
|
-
const subsetOf = (a, b) => {
|
|
28434
|
-
for (const x of a) if (!b.has(x)) return false;
|
|
28435
|
-
return true;
|
|
28436
|
-
};
|
|
28437
|
-
function selectChampion(orchestrated, baseline, canonicalGateIds, tiePolicy) {
|
|
28438
|
-
if (!subsetOf(orchestrated.passed, orchestrated.ran)) return {
|
|
28439
|
-
winner: "baseline",
|
|
28440
|
-
reason: "orchestrated outcome malformed (passed not a subset of ran)"
|
|
28441
|
-
};
|
|
28442
|
-
if (!subsetOf(baseline.passed, baseline.ran)) return {
|
|
28443
|
-
winner: "baseline",
|
|
28444
|
-
reason: "baseline outcome malformed (passed not a subset of ran)"
|
|
28445
|
-
};
|
|
28446
|
-
if (canonicalGateIds.size === 0) return {
|
|
28447
|
-
winner: "baseline",
|
|
28448
|
-
reason: "no executable gate for this ask — ship the baseline (judgment-only)"
|
|
28449
|
-
};
|
|
28450
|
-
for (const id of canonicalGateIds) if (!orchestrated.ran.has(id)) return {
|
|
28451
|
-
winner: "baseline",
|
|
28452
|
-
reason: `orchestrated did not run canonical gate "${id}"`
|
|
28453
|
-
};
|
|
28454
|
-
let baselinePass = 0;
|
|
28455
|
-
let orchestratedPass = 0;
|
|
28456
|
-
for (const id of canonicalGateIds) {
|
|
28457
|
-
if (baseline.passed.has(id)) baselinePass += 1;
|
|
28458
|
-
if (orchestrated.passed.has(id)) orchestratedPass += 1;
|
|
28459
|
-
else if (baseline.passed.has(id)) return {
|
|
28460
|
-
winner: "baseline",
|
|
28461
|
-
reason: `orchestrated regresses on canonical check "${id}" the baseline passed`
|
|
28462
|
-
};
|
|
28463
|
-
}
|
|
28464
|
-
if (orchestratedPass > baselinePass) return {
|
|
28465
|
-
winner: "orchestrated",
|
|
28466
|
-
reason: "orchestrated passes strictly more canonical executable checks"
|
|
28467
|
-
};
|
|
28468
|
-
if (tiePolicy === "superset") return {
|
|
28469
|
-
winner: "orchestrated",
|
|
28470
|
-
reason: "orchestrated matches the baseline on the canonical checks (superset policy)"
|
|
28471
|
-
};
|
|
28472
|
-
return {
|
|
28473
|
-
winner: "baseline",
|
|
28474
|
-
reason: "orchestrated does not pass strictly more canonical checks than the baseline (strict policy)"
|
|
28475
|
-
};
|
|
28476
|
-
}
|
|
28477
|
-
|
|
28478
28646
|
//#endregion
|
|
28479
28647
|
//#region src/lib/orchestration/kernel.ts
|
|
28480
28648
|
const DEFAULT_MAX_RETRIES = 2;
|
|
@@ -28594,6 +28762,7 @@ const clone = (v) => typeof structuredClone === "function" ? structuredClone(v)
|
|
|
28594
28762
|
async function decomposeWorkflow(ask, deps, opts = {}) {
|
|
28595
28763
|
const maxRounds = Math.max(1, opts.maxRounds ?? DEFAULT_MAX_ROUNDS);
|
|
28596
28764
|
const verifyOpts = opts.verify ?? {};
|
|
28765
|
+
const context = typeof opts.context === "string" && opts.context.trim().length > 0 ? opts.context.trim() : void 0;
|
|
28597
28766
|
let feedback;
|
|
28598
28767
|
let lastViolations = [{
|
|
28599
28768
|
code: "NO_DRAFT",
|
|
@@ -28603,6 +28772,7 @@ async function decomposeWorkflow(ask, deps, opts = {}) {
|
|
|
28603
28772
|
for (let round = 1; round <= maxRounds; round += 1) {
|
|
28604
28773
|
const drafted = await safeDraft(deps, {
|
|
28605
28774
|
ask,
|
|
28775
|
+
context,
|
|
28606
28776
|
feedback
|
|
28607
28777
|
});
|
|
28608
28778
|
attempts += 1;
|
|
@@ -28627,6 +28797,7 @@ async function decomposeWorkflow(ask, deps, opts = {}) {
|
|
|
28627
28797
|
if (round < maxRounds) {
|
|
28628
28798
|
const next = await safeDraft(deps, {
|
|
28629
28799
|
ask,
|
|
28800
|
+
context,
|
|
28630
28801
|
feedback: concerns
|
|
28631
28802
|
});
|
|
28632
28803
|
attempts += 1;
|
|
@@ -28852,38 +29023,6 @@ function detectGateWeakening(diff) {
|
|
|
28852
29023
|
};
|
|
28853
29024
|
}
|
|
28854
29025
|
|
|
28855
|
-
//#endregion
|
|
28856
|
-
//#region src/lib/orchestration/gate-runner.ts
|
|
28857
|
-
async function runGateChecks(checks, cwd, exec) {
|
|
28858
|
-
const results = await Promise.all(checks.map(async (c) => {
|
|
28859
|
-
try {
|
|
28860
|
-
const r = await exec({
|
|
28861
|
-
command: c.command,
|
|
28862
|
-
cwd
|
|
28863
|
-
});
|
|
28864
|
-
return {
|
|
28865
|
-
id: c.id,
|
|
28866
|
-
passed: r.exitCode === 0
|
|
28867
|
-
};
|
|
28868
|
-
} catch {
|
|
28869
|
-
return {
|
|
28870
|
-
id: c.id,
|
|
28871
|
-
passed: false
|
|
28872
|
-
};
|
|
28873
|
-
}
|
|
28874
|
-
}));
|
|
28875
|
-
const passed = /* @__PURE__ */ new Set();
|
|
28876
|
-
const ran = /* @__PURE__ */ new Set();
|
|
28877
|
-
for (const r of results) {
|
|
28878
|
-
ran.add(r.id);
|
|
28879
|
-
if (r.passed) passed.add(r.id);
|
|
28880
|
-
}
|
|
28881
|
-
return {
|
|
28882
|
-
passed,
|
|
28883
|
-
ran
|
|
28884
|
-
};
|
|
28885
|
-
}
|
|
28886
|
-
|
|
28887
29026
|
//#endregion
|
|
28888
29027
|
//#region src/lib/orchestration/stop-gate.ts
|
|
28889
29028
|
async function evaluateStopGate(input) {
|
|
@@ -28929,63 +29068,6 @@ const liveExec = async ({ command, cwd }) => {
|
|
|
28929
29068
|
}
|
|
28930
29069
|
};
|
|
28931
29070
|
|
|
28932
|
-
//#endregion
|
|
28933
|
-
//#region src/lib/orchestration/gate-registry.ts
|
|
28934
|
-
/**
|
|
28935
|
-
* Built-in sealed gates. Commands follow this repo's TS/Bun conventions (the
|
|
28936
|
-
* `bun run <script>` indirection means a repo without that script simply fails
|
|
28937
|
-
* the check, which the selector treats as not-passed rather than a crash). New
|
|
28938
|
-
* ecosystems get a new sealed id here, never a caller-supplied command.
|
|
28939
|
-
*/
|
|
28940
|
-
const SEALED_GATES = {
|
|
28941
|
-
"default-ci": [
|
|
28942
|
-
{
|
|
28943
|
-
id: "typecheck",
|
|
28944
|
-
command: "bun run typecheck"
|
|
28945
|
-
},
|
|
28946
|
-
{
|
|
28947
|
-
id: "test",
|
|
28948
|
-
command: "bun test"
|
|
28949
|
-
},
|
|
28950
|
-
{
|
|
28951
|
-
id: "lint",
|
|
28952
|
-
command: "bun run lint"
|
|
28953
|
-
}
|
|
28954
|
-
],
|
|
28955
|
-
"typecheck-test": [{
|
|
28956
|
-
id: "typecheck",
|
|
28957
|
-
command: "bun run typecheck"
|
|
28958
|
-
}, {
|
|
28959
|
-
id: "test",
|
|
28960
|
-
command: "bun test"
|
|
28961
|
-
}],
|
|
28962
|
-
"typecheck-only": [{
|
|
28963
|
-
id: "typecheck",
|
|
28964
|
-
command: "bun run typecheck"
|
|
28965
|
-
}]
|
|
28966
|
-
};
|
|
28967
|
-
/** The set of sealed gate ids, used as the kernel's `knownGateIds` so the IR
|
|
28968
|
-
* verifier rejects an executable gate that references an unregistered id. */
|
|
28969
|
-
function sealedGateIds() {
|
|
28970
|
-
return new Set(Object.keys(SEALED_GATES));
|
|
28971
|
-
}
|
|
28972
|
-
/**
|
|
28973
|
-
* Resolve a sealed gate by id. Returns a DEFENSIVE CLONE (fresh objects) so a
|
|
28974
|
-
* caller can never mutate the registry's command set. `undefined` for an
|
|
28975
|
-
* unknown id, which `run_workflow` rejects before executing anything.
|
|
28976
|
-
*/
|
|
28977
|
-
function resolveSealedGate(gateId) {
|
|
28978
|
-
const checks = SEALED_GATES[gateId];
|
|
28979
|
-
if (!checks) return void 0;
|
|
28980
|
-
return {
|
|
28981
|
-
id: gateId,
|
|
28982
|
-
checks: checks.map((c) => ({
|
|
28983
|
-
id: c.id,
|
|
28984
|
-
command: c.command
|
|
28985
|
-
}))
|
|
28986
|
-
};
|
|
28987
|
-
}
|
|
28988
|
-
|
|
28989
29071
|
//#endregion
|
|
28990
29072
|
//#region src/lib/orchestration/runner-live.ts
|
|
28991
29073
|
/** Map a node role to the worker-engine mode. `baseline` is pre-mapped to
|
|
@@ -29476,6 +29558,19 @@ async function decideStopHook(input) {
|
|
|
29476
29558
|
let dynamicBaselineKey;
|
|
29477
29559
|
const planMode = input.planMode === true || payload.plan_mode === true;
|
|
29478
29560
|
const scanDiff = (diff) => planMode ? stripPlanMemoryDiffHunks(diff) : diff;
|
|
29561
|
+
const capturedDiff = async (workdir) => {
|
|
29562
|
+
try {
|
|
29563
|
+
return {
|
|
29564
|
+
diff: await input.captureDiff(workdir),
|
|
29565
|
+
captured: true
|
|
29566
|
+
};
|
|
29567
|
+
} catch {
|
|
29568
|
+
return {
|
|
29569
|
+
diff: "",
|
|
29570
|
+
captured: false
|
|
29571
|
+
};
|
|
29572
|
+
}
|
|
29573
|
+
};
|
|
29479
29574
|
const runGate = async () => {
|
|
29480
29575
|
if (input.resolveChecks) {
|
|
29481
29576
|
const resolved = await input.resolveChecks(cwd).catch(() => null);
|
|
@@ -29483,27 +29578,37 @@ async function decideStopHook(input) {
|
|
|
29483
29578
|
resolvedKey = resolved.descriptorKey;
|
|
29484
29579
|
dynamicBaselineKey = resolved.baselineKey;
|
|
29485
29580
|
const workdir = resolved.workdir || cwd;
|
|
29486
|
-
const diff$1 = await
|
|
29581
|
+
const { diff: diff$1, captured: captured$1 } = await capturedDiff(workdir);
|
|
29582
|
+
if (captured$1 && diff$1.length === 0) return {
|
|
29583
|
+
kind: "no-diff",
|
|
29584
|
+
diff: diff$1
|
|
29585
|
+
};
|
|
29487
29586
|
const result$1 = await evaluateStopGate({
|
|
29488
29587
|
checks: resolved.checks,
|
|
29489
29588
|
cwd: workdir,
|
|
29490
29589
|
exec: input.exec,
|
|
29491
|
-
diff: scanDiff(diff$1)
|
|
29590
|
+
diff: captured$1 ? scanDiff(diff$1) : ""
|
|
29492
29591
|
});
|
|
29493
29592
|
return {
|
|
29593
|
+
kind: "evaluated",
|
|
29494
29594
|
failedChecks: [...result$1.failedChecks],
|
|
29495
29595
|
weakeningPatterns: [...new Set(result$1.weakening.map((w) => w.pattern))],
|
|
29496
29596
|
diff: diff$1
|
|
29497
29597
|
};
|
|
29498
29598
|
}
|
|
29499
|
-
const diff = await
|
|
29599
|
+
const { diff, captured } = await capturedDiff(cwd);
|
|
29600
|
+
if (captured && diff.length === 0) return {
|
|
29601
|
+
kind: "no-diff",
|
|
29602
|
+
diff
|
|
29603
|
+
};
|
|
29500
29604
|
const result = await runStopGateForLaunch({
|
|
29501
29605
|
workspace: cwd,
|
|
29502
29606
|
gateId: input.gateId,
|
|
29503
29607
|
exec: input.exec,
|
|
29504
|
-
diff: scanDiff(diff)
|
|
29608
|
+
diff: captured ? scanDiff(diff) : ""
|
|
29505
29609
|
});
|
|
29506
29610
|
return {
|
|
29611
|
+
kind: "evaluated",
|
|
29507
29612
|
failedChecks: [...result.failedChecks],
|
|
29508
29613
|
weakeningPatterns: [...new Set(result.weakening.map((w) => w.pattern))],
|
|
29509
29614
|
diff
|
|
@@ -29517,6 +29622,7 @@ async function decideStopHook(input) {
|
|
|
29517
29622
|
if (timer) clearTimeout(timer);
|
|
29518
29623
|
if (raced === "timeout") return { exitCode: 0 };
|
|
29519
29624
|
if (raced === null) return { exitCode: 0 };
|
|
29625
|
+
if (raced.kind === "no-diff") return { exitCode: 0 };
|
|
29520
29626
|
const baselineKey = dynamicBaselineKey ?? JSON.stringify([
|
|
29521
29627
|
sessionId,
|
|
29522
29628
|
cwd,
|
|
@@ -29804,8 +29910,8 @@ function buildLiveDecomposeDeps(opts) {
|
|
|
29804
29910
|
endpoint: "/v1/messages",
|
|
29805
29911
|
effort: "xhigh"
|
|
29806
29912
|
};
|
|
29807
|
-
const deps = { async draftIR({ ask, feedback }) {
|
|
29808
|
-
const userText = `Ask:\n${ask}` + (feedback && feedback.length > 0 ? `\n\nFix these issues from the previous draft:\n- ${feedback.join("\n- ")}` : "");
|
|
29913
|
+
const deps = { async draftIR({ ask, context, feedback }) {
|
|
29914
|
+
const userText = `Ask:\n${ask}` + (context && context.trim().length > 0 ? `\n\nContext:\n${context.trim()}` : "") + (feedback && feedback.length > 0 ? `\n\nFix these issues from the previous draft:\n- ${feedback.join("\n- ")}` : "");
|
|
29809
29915
|
return extractJson(await dispatchModelCall({
|
|
29810
29916
|
model: driver.model,
|
|
29811
29917
|
endpoint: driver.endpoint,
|
|
@@ -30154,9 +30260,9 @@ Reply format (markdown):
|
|
|
30154
30260
|
|
|
30155
30261
|
Resilience reminder:
|
|
30156
30262
|
If your session terminates abnormally before "Status: complete", the lead will retry once. On recovery, ask the lead to confirm what's already been done before re-applying changes — duplicate edits are worse than a slow restart.`;
|
|
30157
|
-
const OPUS_CRITIC_BASE = `You are opus-critic, a fresh-context
|
|
30263
|
+
const OPUS_CRITIC_BASE = `You are opus-critic, a fresh-context same-lab adversarial reviewer running on Opus 4.6. The lead orchestrator that just delegated to you runs newer Opus-family context, but you are NOT the lead. You did not see the lead's reasoning trace. You only see the brief.
|
|
30158
30264
|
|
|
30159
|
-
Your job is to spot what the lead missed because of cognitive momentum, sunk-cost on a plan, or motivated reasoning toward a particular fix. Your blind-spot diversification is LIMITED compared to codex-critic (gpt-5.5) and gemini-critic (gemini-3.1-pro)
|
|
30265
|
+
Your job is to spot what the lead missed because of cognitive momentum, sunk-cost on a plan, or motivated reasoning toward a particular fix. Your blind-spot diversification is LIMITED compared to codex-critic (gpt-5.5) and gemini-critic (gemini-3.1-pro), same lab, adjacent model family, related priors. Use that honestly: don't pretend to find a different perspective when the obvious read is "the lead got it right." Silence on good work is a valid and welcome answer.
|
|
30160
30266
|
|
|
30161
30267
|
Sycophancy is the failure mode you exist to fight. Manufactured contrarianism is a different failure of the same shape — do neither.
|
|
30162
30268
|
|
|
@@ -30169,7 +30275,7 @@ const PERSONAS_READ = Object.freeze([
|
|
|
30169
30275
|
toolNameHttp: "codex_critic",
|
|
30170
30276
|
model: "gpt-5.5",
|
|
30171
30277
|
endpoint: "/v1/responses",
|
|
30172
|
-
description: "Adversarial
|
|
30278
|
+
description: "Adversarial architecture and design critic backed by gpt-5.5 (OpenAI, ≈922K-token input window), the strongest cross-lab reasoning critic in this surface. It reviews plans, designs, tradeoffs, and large code-change proposals for unsound assumptions, missing failure modes, and overlooked alternatives, then returns a calibrated objection or `no material objection`. Use when a decision or design needs a different-lab strategic challenge before implementation or merge. Not for line-level bug finding in a concrete diff or file, use codex_reviewer or gemini_reviewer; pass the artifact and constraints verbatim.",
|
|
30173
30279
|
baseInstructions: CRITIC_BASE,
|
|
30174
30280
|
agentPrompt: "",
|
|
30175
30281
|
writeCapable: false,
|
|
@@ -30187,7 +30293,7 @@ const PERSONAS_READ = Object.freeze([
|
|
|
30187
30293
|
toolNameHttp: "gemini_critic",
|
|
30188
30294
|
model: "gemini-3.1-pro-preview",
|
|
30189
30295
|
endpoint: "/v1/chat/completions",
|
|
30190
|
-
description: "Adversarial
|
|
30296
|
+
description: "Adversarial third-lab critic backed by gemini-3.1-pro-preview (Google), strong on formal reasoning, invariants, proofs, and cross-checking another critic's conclusion. It reviews plans, designs, mathematical arguments, and large artifacts for assumption gaps or invariant failures, then returns a focused critique or no-material-objection style verdict. Use when codex_critic's result needs an independent lab check or when the artifact hinges on formal correctness. Not for line-level diff review, use gemini_reviewer or codex_reviewer; pass the artifact and constraints verbatim.",
|
|
30191
30297
|
baseInstructions: GEMINI_CRITIC_BASE,
|
|
30192
30298
|
agentPrompt: "",
|
|
30193
30299
|
writeCapable: false,
|
|
@@ -30205,7 +30311,7 @@ const PERSONAS_READ = Object.freeze([
|
|
|
30205
30311
|
toolNameHttp: "codex_reviewer",
|
|
30206
30312
|
model: "gpt-5.3-codex",
|
|
30207
30313
|
endpoint: "/v1/responses",
|
|
30208
|
-
description: "Line-level
|
|
30314
|
+
description: "Line-level code reviewer backed by gpt-5.3-codex (OpenAI, ≈272K-token input window), a code-specialist reviewer that is fastest around high effort (~16s at high effort). It reviews concrete diffs, files, or function bodies and returns findings with severity, file:line locations, issue impact, and a minimal suggested fix. Use when the artifact is actual code and the goal is bug, edge-case, security, concurrency, resource, or idiom review. Not for architecture or tradeoff review, use codex_critic or gemini_critic; pass the diff or file content verbatim.",
|
|
30209
30315
|
baseInstructions: REVIEWER_BASE,
|
|
30210
30316
|
agentPrompt: "",
|
|
30211
30317
|
writeCapable: false,
|
|
@@ -30223,7 +30329,7 @@ const PERSONAS_READ = Object.freeze([
|
|
|
30223
30329
|
toolNameHttp: "gemini_reviewer",
|
|
30224
30330
|
model: "gemini-3.1-pro-preview",
|
|
30225
30331
|
endpoint: "/v1/chat/completions",
|
|
30226
|
-
description: "Line-level
|
|
30332
|
+
description: "Line-level code reviewer backed by gemini-3.1-pro-preview (Google), providing second-lab coverage that catches a different slice of concrete-code defects than codex_reviewer. It reviews diffs, files, or function bodies and returns severity-ranked findings with file:line citations and suggested fixes. Use alongside codex_reviewer when a non-trivial diff benefits from cross-lab code-review coverage, especially around invariants or edge cases. Not for architecture or product-design review, use codex_critic or gemini_critic; pass the code artifact verbatim.",
|
|
30227
30333
|
baseInstructions: GEMINI_REVIEWER_BASE,
|
|
30228
30334
|
agentPrompt: "",
|
|
30229
30335
|
writeCapable: false,
|
|
@@ -30241,7 +30347,7 @@ const PERSONAS_READ = Object.freeze([
|
|
|
30241
30347
|
toolNameHttp: "opus_critic",
|
|
30242
30348
|
model: "claude-opus-4-6",
|
|
30243
30349
|
endpoint: "/v1/messages",
|
|
30244
|
-
description: "Adversarial
|
|
30350
|
+
description: "Adversarial same-lab critic backed by fresh-context Opus 4.6, with limited blind-spot diversity compared with cross-lab critics. It reviews plans, designs, or code tradeoffs for cognitive momentum, sunk-cost reasoning, and confabulated assumptions, then returns a calibrated objection or no material objection. Use when a same-family sanity check can catch lead-context drift or when comparing against codex_critic / gemini_critic findings. Not a substitute for cross-lab review on security-sensitive or high-risk changes; use codex_critic or gemini_critic for stronger diversity. On enterprise catalogs that carry Opus-4.6-1M it runs with ≈936K input tokens; otherwise ≈168K. Pinned two minors behind the default Opus so the panel spans more of the version curve. Pass artifact verbatim.",
|
|
30245
30351
|
baseInstructions: OPUS_CRITIC_BASE,
|
|
30246
30352
|
agentPrompt: "",
|
|
30247
30353
|
writeCapable: false,
|
|
@@ -30259,7 +30365,7 @@ const PERSONAS_WRITE = Object.freeze([{
|
|
|
30259
30365
|
toolNameHttp: "codex_implementer",
|
|
30260
30366
|
model: "gpt-5.3-codex",
|
|
30261
30367
|
endpoint: "/v1/responses",
|
|
30262
|
-
description: "Targeted implementation
|
|
30368
|
+
description: "Targeted implementation persona backed by gpt-5.3-codex with workspace-write access. It executes self-contained coding tasks from a pasted spec, reads the relevant files, edits the workspace, verifies the result, and returns changed files plus verification output. Use when the task is bounded enough for direct implementation and the caller can provide acceptance criteria and file context up front. Not for open-ended planning or broad repo exploration, use plan or explore first; not for read-only review, use codex_reviewer or gemini_reviewer. Because it can mutate the workspace, scope files and allowed changes explicitly and pass the spec verbatim.",
|
|
30263
30369
|
baseInstructions: IMPLEMENTER_BASE,
|
|
30264
30370
|
agentPrompt: "",
|
|
30265
30371
|
writeCapable: true,
|
|
@@ -30354,8 +30460,8 @@ function buildAgentPrompt(persona, opts) {
|
|
|
30354
30460
|
* - Conditionally lists gemini_critic only when `geminiAvailable`.
|
|
30355
30461
|
* - Conditionally lists the `worker-*` background dispatcher subagents
|
|
30356
30462
|
* (worker-explore / worker-review / worker-plan / worker-implement /
|
|
30357
|
-
* worker-test), the non-blocking-guard fact, and
|
|
30358
|
-
*
|
|
30463
|
+
* worker-test), the non-blocking-guard fact, and the worker code-search
|
|
30464
|
+
* affordance only when `workerToolsAvailable` (mirrors
|
|
30359
30465
|
* `workerToolsEnabled()` so the snippet never names a surface gated out
|
|
30360
30466
|
* of the live catalog). The raw `mcp__<workers>__*` tools are named only
|
|
30361
30467
|
* as the guarded plumbing the dispatchers call, never as a main-agent
|
|
@@ -30379,15 +30485,19 @@ function buildPeerAwarenessSnippet(opts) {
|
|
|
30379
30485
|
const orchestrateKey = key("orchestrate");
|
|
30380
30486
|
const browserKey = key("browser");
|
|
30381
30487
|
const decideKey = key("decide");
|
|
30488
|
+
const fleetKey = key("fleet");
|
|
30489
|
+
const compoundBrowseAvailable = opts.browseAvailable && opts.compoundBrowseAvailable;
|
|
30490
|
+
const powerBrowseAvailable = opts.browseAvailable && opts.powerBrowseAvailable === true;
|
|
30382
30491
|
const criticList = ["`codex_critic` (gpt-5.5)", "`codex_reviewer` (gpt-5.3-codex)"];
|
|
30383
30492
|
if (opts.geminiAvailable) {
|
|
30384
30493
|
criticList.push("`gemini_reviewer` (gemini-3.1-pro, line-level code review)");
|
|
30385
30494
|
criticList.push("`gemini_critic` (gemini-3.1-pro)");
|
|
30386
30495
|
}
|
|
30387
|
-
criticList.push("`opus_critic` (Opus 4.
|
|
30496
|
+
criticList.push("`opus_critic` (Opus 4.6)");
|
|
30388
30497
|
const codexCliClause = opts.codexCli ? " `mcp__codex-cli__codex` dispatches to `codex-implementer` (gpt-5.3-codex with workspace-write) for end-to-end coding tasks." : "";
|
|
30389
30498
|
const para2Parts = [`\`mcp__${searchKey}__code\` is the one-stop code search (no extra model call). Its DEFAULT mode (or \`mode:"semantic"\`) ranks by MEANING via ColBERT over a per-workspace index, the first thing to reach for on intent/concept questions ("where is retry/backoff handled", "how does auth work"); when that index isn't ready it transparently falls back to lexical (the response \`source\` says which engine ran). Forced modes cover the rest: \`lexical\` (BM25F-ranked + tree-sitter, best for exact symbols), \`exact\`, \`regex\`, \`complete\` (exhaustive set), \`ast_pattern\`+\`ast_lang\` for multi-line AST shapes, \`scan\` for a whole-workspace symbol outline, \`multiline\` for cross-line regex. Multiple queries can run in a single turn. The index covers code-shaped files; for unstructured files (logs, \`.csv\`, \`.env*\`, config-only wiring), \`grep\`/\`glob\` still apply.`];
|
|
30390
30499
|
if (opts.workerToolsAvailable) para2Parts.push(`\`worker-*\` are background Agent subagents (subagent_type) that run the matching worker in its own context and deliver the result as a completion notification, so a long run never blocks the turn: \`worker-explore\` (read-only research), \`worker-review\` (reads the code to verify a change or claim), \`worker-plan\` (ordered implementation plan), \`worker-implement\` (edit/write/bash; \`worktree: true\` isolates in a git worktree and returns the diff), \`worker-test\` (independent test author). The raw \`mcp__${workersKey}__*\` tools they call are guarded (a direct main-thread call is redirected to the matching agent); Workers themselves have \`code_search\`.`);
|
|
30500
|
+
if (opts.workerToolsAvailable && opts.implementerAvailable) para2Parts.push(`For a bounded, well-scoped implementation, prefer the \`implementer\` subagent (Task, runs on gpt-5.5) over \`worker-implement\`; reach for \`worker-implement\` only when you specifically need git-worktree isolation, parallel variants, or a throwaway experiment.`);
|
|
30391
30501
|
if (opts.workerToolsAvailable) para2Parts.push(`\`mcp__${orchestrateKey}__decompose\` composes an open-ended ask into a typed, VERIFIED workflow IR (a strong driver decorrelated by a cross-lab critic, so the decompose step isn't a single point of failure), and \`mcp__${orchestrateKey}__run_workflow\` executes that IR through a frozen kernel delivering max(orchestrated, baseline) over a sealed executable gate, so it never ships worse than a plain single-model run. \`mcp__${orchestrateKey}__verify_workflow\` checks an IR's floor invariants before you run it, and \`mcp__${orchestrateKey}__attest_step\` audits that a finished run's producers were each checked by a different lab. They suit non-trivial, role-separated asks; a trivial ask does not need them.`);
|
|
30392
30502
|
else para2Parts.push(`\`mcp__${orchestrateKey}__verify_workflow\` statically checks a workflow IR's floor invariants and \`mcp__${orchestrateKey}__attest_step\` audits a run's cross-lab lineage (the \`decompose\`/\`run_workflow\` composer + kernel need the worker backend, unavailable here).`);
|
|
30393
30503
|
if (opts.workerToolsAvailable) {
|
|
@@ -30396,10 +30506,10 @@ function buildPeerAwarenessSnippet(opts) {
|
|
|
30396
30506
|
}
|
|
30397
30507
|
para2Parts.push(`\`mcp__${searchKey}__web\` surfaces citable sources for docs, errors, and upstream issues.`);
|
|
30398
30508
|
if (opts.standInAvailable) para2Parts.push(`\`mcp__${decideKey}__stand_in\` provides three-lab consensus for decision tiebreak when the user is unavailable.`);
|
|
30399
|
-
if (opts.browseAvailable) {
|
|
30400
|
-
|
|
30401
|
-
|
|
30402
|
-
}
|
|
30509
|
+
if (opts.browseAvailable) para2Parts.push(`\`mcp__${browserKey}__*\` tools drive a real Chrome / Edge browser via a local extension. Lead browse surface includes \`__navigate\` / \`__open_tab\` / \`__screenshot\` for state, visuals, and navigation.`);
|
|
30510
|
+
if (compoundBrowseAvailable) para2Parts.push(`Compound browse surface includes \`mcp__${browserKey}__act(intent, value?)\` / \`__observe(intent?)\` / \`__extract(schema, instruction)\` / \`__find\`; an inner fast model resolves intent, find/observe yield element refs act consumes, and the lead never sees raw DOM.`);
|
|
30511
|
+
if (powerBrowseAvailable) para2Parts.push(`Power browse surface adds \`mcp__${browserKey}__mouse\`, \`__drag\`, \`__type\`, \`__keyboard\`, \`__scroll\`, \`__eval_js\`, \`__read_page\`, \`__diagnostics\`, \`__list_tabs\`, \`__close_tab\`, \`__wait\`, and \`__download\` for direct DOM and coordinate control.`);
|
|
30512
|
+
if (opts.fleetAvailable) para2Parts.push(`\`mcp__${fleetKey}__*\` tools drive remote ai-or-die coding sessions (list / read / create / stop / await / drive, plus remote read_file / list_dir / search / git_show); they act on a REMOTE fleet instance, not the local repo.`);
|
|
30403
30513
|
return [
|
|
30404
30514
|
"## Peer review and advisor",
|
|
30405
30515
|
"",
|
|
@@ -30408,6 +30518,31 @@ function buildPeerAwarenessSnippet(opts) {
|
|
|
30408
30518
|
para2Parts.join(" ")
|
|
30409
30519
|
].join("\n");
|
|
30410
30520
|
}
|
|
30521
|
+
/**
|
|
30522
|
+
* Compact, gated capability SUMMARY for the spawned session's system prompt
|
|
30523
|
+
* (`--append-system-prompt`). The FULL per-tool inventory lives once in the
|
|
30524
|
+
* mirrored CLAUDE.md (buildPeerAwarenessSnippet); this ~300-token summary gives
|
|
30525
|
+
* the main agent high-salience awareness of what is available without
|
|
30526
|
+
* duplicating the full snippet in the context window every turn. Gated
|
|
30527
|
+
* identically to the full snippet so it never names a surface the live
|
|
30528
|
+
* tools/list dropped. Factual present tense, no imperatives.
|
|
30529
|
+
*/
|
|
30530
|
+
function buildPeerAwarenessSummary(opts) {
|
|
30531
|
+
const key = (g) => opts.groupKeys?.[g] ?? GROUP_META[g].preferredKey;
|
|
30532
|
+
const lines = [
|
|
30533
|
+
"## Injected capabilities (summary)",
|
|
30534
|
+
"",
|
|
30535
|
+
`A layer of MCP tools, background workers, and skills is injected into this session. Cross-lab peer critics under \`mcp__${key("peers")}__*\` (plus the \`peer-review-coordinator\` subagent) review plans and diffs adversarially, and Claude Code's built-in \`advisor\` catches approach drift. \`mcp__${key("search")}__code\` is meaning-first code search and \`mcp__${key("search")}__web\` returns citable web sources.`
|
|
30536
|
+
];
|
|
30537
|
+
if (opts.workerToolsAvailable) lines.push(`Background \`worker-*\` agents (explore, review, plan, implement, test) run delegated work in their own context without blocking your turn, and \`mcp__${key("orchestrate")}__*\` composes, verifies, and runs floor-raising workflows.`);
|
|
30538
|
+
if (opts.standInAvailable) lines.push(`\`mcp__${key("decide")}__stand_in\` returns a three-lab consensus for a decision when the user is unavailable.`);
|
|
30539
|
+
if (opts.browseAvailable) lines.push(`\`mcp__${key("browser")}__*\` drives a real Chrome or Edge browser.`);
|
|
30540
|
+
if (opts.fleetAvailable) lines.push(`\`mcp__${key("fleet")}__*\` drives remote ai-or-die coding sessions.`);
|
|
30541
|
+
if (opts.agentToolsAvailable === true) lines.push("The `/gh-first-mate` skill drives a durable GitHub cloud-agent loop.");
|
|
30542
|
+
lines.push("");
|
|
30543
|
+
lines.push(`Each tool's own description carries when to use it and when not. The full per-tool inventory (models, gating, workers, skills) is in the "Peer review and advisor" section of your CLAUDE.md project instructions.`);
|
|
30544
|
+
return lines.join("\n");
|
|
30545
|
+
}
|
|
30411
30546
|
/** Convenience: every persona that should be registered for the given mode. */
|
|
30412
30547
|
function personasFor(opts) {
|
|
30413
30548
|
const result = [];
|
|
@@ -30418,7 +30553,7 @@ function personasFor(opts) {
|
|
|
30418
30553
|
if (opts.codexCli) for (const p of PERSONAS_WRITE) result.push(p);
|
|
30419
30554
|
return result;
|
|
30420
30555
|
}
|
|
30421
|
-
const WEB_SEARCH_DESCRIPTION = "Web search via GitHub Copilot's MCP
|
|
30556
|
+
const WEB_SEARCH_DESCRIPTION = "Web search via GitHub Copilot's MCP that returns answer text plus source URLs the caller can cite. It accepts a natural-language `query`; the upstream provider rewrites for the search index and the handler formats any references as markdown links. Use for current external information such as API documentation, error-message diagnosis, upstream issue searches, and claims that need web sources. Not for local repository discovery or code navigation, use code, Read, Grep, or Glob for workspace content. Prefer it over the built-in WebSearch when source URLs are needed or the built-in surface is geographically constrained.";
|
|
30422
30557
|
/**
|
|
30423
30558
|
* Format a `searchWeb()` result as an MCP-friendly text block. Mirrors
|
|
30424
30559
|
* the legacy inject format that `injectWebSearchIfNeeded` produces and
|
|
@@ -30453,7 +30588,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30453
30588
|
if (!query) return {
|
|
30454
30589
|
content: [{
|
|
30455
30590
|
type: "text",
|
|
30456
|
-
text: "
|
|
30591
|
+
text: "web: arguments.query is required (must be a non-empty string)"
|
|
30457
30592
|
}],
|
|
30458
30593
|
isError: true
|
|
30459
30594
|
};
|
|
@@ -30466,7 +30601,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30466
30601
|
return {
|
|
30467
30602
|
content: [{
|
|
30468
30603
|
type: "text",
|
|
30469
|
-
text: `
|
|
30604
|
+
text: `web failed: ${err instanceof Error ? err.message : String(err)}`
|
|
30470
30605
|
}],
|
|
30471
30606
|
isError: true
|
|
30472
30607
|
};
|
|
@@ -30625,7 +30760,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30625
30760
|
toolNameHttp: "explore",
|
|
30626
30761
|
group: "workers",
|
|
30627
30762
|
capability: "worker",
|
|
30628
|
-
description: "Runs as the background `worker-explore` agent. Dispatch via the Agent tool (subagent_type: worker-explore) so
|
|
30763
|
+
description: "Runs as the background `worker-explore` agent. Dispatch via the Agent tool (subagent_type: worker-explore) so the turn is never blocked; the result arrives as a completion notification. Read-only investigation by an autonomous worker (Pi runtime; default model `claude-sonnet-5` at xhigh reasoning, override via the `model` arg with any Copilot-catalog model that advertises `tool_calls`). It has read, glob, grep, semantic-first code search, web search, fetch_url, advisor, update_plan, and read-only toolbelt tools, and it returns a single text answer. Use for bounded research, repo discovery, dependency investigation, or multi-file reading that would otherwise consume the lead context window. Not for implementation, test authoring, or verification of a concrete diff; use implement, test, or review for those scopes. Brief the investigation goal and constraints, not step-by-step tool semantics.",
|
|
30629
30764
|
inputSchema: {
|
|
30630
30765
|
type: "object",
|
|
30631
30766
|
required: ["prompt"],
|
|
@@ -30637,7 +30772,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30637
30772
|
},
|
|
30638
30773
|
model: {
|
|
30639
30774
|
type: "string",
|
|
30640
|
-
description: "Optional Copilot catalog model id (defaults to
|
|
30775
|
+
description: "Optional Copilot catalog model id (defaults to claude-sonnet-5). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch."
|
|
30641
30776
|
},
|
|
30642
30777
|
thinking: {
|
|
30643
30778
|
type: "string",
|
|
@@ -30649,7 +30784,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30649
30784
|
"high",
|
|
30650
30785
|
"xhigh"
|
|
30651
30786
|
],
|
|
30652
|
-
description: "Optional reasoning depth (default
|
|
30787
|
+
description: "Optional reasoning depth (default xhigh). Silently clamped to the model's allowed range; \"off\" drops the parameter entirely."
|
|
30653
30788
|
},
|
|
30654
30789
|
workspace: {
|
|
30655
30790
|
type: "string",
|
|
@@ -30673,7 +30808,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30673
30808
|
toolNameHttp: "implement",
|
|
30674
30809
|
group: "workers",
|
|
30675
30810
|
capability: "worker",
|
|
30676
|
-
description: "Runs as the background `worker-implement` agent. Dispatch via the Agent tool (subagent_type: worker-implement) so
|
|
30811
|
+
description: "Runs as the background `worker-implement` agent. Dispatch via the Agent tool (subagent_type: worker-implement) so the turn is never blocked; the result arrives as a completion notification. Delegates a scoped coding task to an autonomous worker (Pi runtime; default model `gpt-5.5` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the explore read-only tools plus edit, write, bash, and codex_review, and it returns its final text with any changed files or worktree diff. Use for bounded implementation work that may take a while or benefits from isolated worker context. Not for pure research, planning, review, or independent test authoring; use explore, plan, review, or test for those scopes. With `worktree: false` (default) edits happen in place, so concurrent implement calls and lead edits to the same files can race. With `worktree: true` it runs in an isolated git worktree and returns the diff; this errors if the workspace is not a git repository.",
|
|
30677
30812
|
inputSchema: {
|
|
30678
30813
|
type: "object",
|
|
30679
30814
|
required: ["prompt"],
|
|
@@ -30685,7 +30820,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30685
30820
|
},
|
|
30686
30821
|
worktree: {
|
|
30687
30822
|
type: "boolean",
|
|
30688
|
-
description: "When true, run inside a fresh git worktree and return Pi's final text followed by the unified diff (so the lead can review before merging). When false/omitted, edits the workspace in place
|
|
30823
|
+
description: "When true, run inside a fresh git worktree and return Pi's final text followed by the unified diff (so the lead can review before merging). When false/omitted, edits the workspace in place, so concurrent worker calls and lead edits can race. Errors if true and the workspace is not a git repository."
|
|
30689
30824
|
},
|
|
30690
30825
|
model: {
|
|
30691
30826
|
type: "string",
|
|
@@ -30725,7 +30860,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30725
30860
|
toolNameHttp: "review",
|
|
30726
30861
|
group: "workers",
|
|
30727
30862
|
capability: "worker",
|
|
30728
|
-
description: "Runs as the background `worker-review` agent. Dispatch via the Agent tool (subagent_type: worker-review) so
|
|
30863
|
+
description: "Runs as the background `worker-review` agent. Dispatch via the Agent tool (subagent_type: worker-review) so the turn is never blocked; the result arrives as a completion notification. Read-only code review by an autonomous worker (Pi runtime; default model `gemini-3.1-pro-preview`, default thinking xhigh clamped to high for that model, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read-only toolset as explore and verifies claims against surrounding repository context before returning severity-ranked findings with `file:line` citations. Use for reviewing a change, diff, or correctness claim when the reviewer should read the code itself rather than trusting a pasted artifact. Not for architecture critique, implementation, or test authoring; use codex_critic or gemini_critic for design review, implement for edits, and test for independent test creation.",
|
|
30729
30864
|
inputSchema: {
|
|
30730
30865
|
type: "object",
|
|
30731
30866
|
required: ["prompt"],
|
|
@@ -30737,7 +30872,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30737
30872
|
},
|
|
30738
30873
|
model: {
|
|
30739
30874
|
type: "string",
|
|
30740
|
-
description: "Optional Copilot catalog model id (defaults to
|
|
30875
|
+
description: "Optional Copilot catalog model id (defaults to gemini-3.1-pro-preview). Must advertise tool_calls support; the engine emits an isError envelope listing the eligible catalog models on mismatch."
|
|
30741
30876
|
},
|
|
30742
30877
|
thinking: {
|
|
30743
30878
|
type: "string",
|
|
@@ -30749,7 +30884,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30749
30884
|
"high",
|
|
30750
30885
|
"xhigh"
|
|
30751
30886
|
],
|
|
30752
|
-
description: "Optional reasoning depth (default
|
|
30887
|
+
description: "Optional reasoning depth (defaults to xhigh, clamped to high for the default review model). Silently clamped to the model's allowed range; \"off\" drops the parameter entirely."
|
|
30753
30888
|
},
|
|
30754
30889
|
workspace: {
|
|
30755
30890
|
type: "string",
|
|
@@ -30773,7 +30908,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30773
30908
|
toolNameHttp: "plan",
|
|
30774
30909
|
group: "workers",
|
|
30775
30910
|
capability: "worker",
|
|
30776
|
-
description: "Runs as the background `worker-plan` agent. Dispatch via the Agent tool (subagent_type: worker-plan) so
|
|
30911
|
+
description: "Runs as the background `worker-plan` agent. Dispatch via the Agent tool (subagent_type: worker-plan) so the turn is never blocked; the result arrives as a completion notification. Read-only implementation planning by an autonomous worker (Pi runtime; default model `claude-opus-4.8` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read-only toolset as explore and returns a concrete, ordered implementation plan covering files, approach, risks, and how acceptance criteria will be verified. Use before coding when the task needs repo-grounded sequencing or acceptance criteria translated into implementation steps. Not for editing files, running an implementation, writing tests, or adversarial review; use implement, test, or review for those scopes.",
|
|
30777
30912
|
inputSchema: {
|
|
30778
30913
|
type: "object",
|
|
30779
30914
|
required: ["prompt"],
|
|
@@ -30797,7 +30932,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30797
30932
|
"high",
|
|
30798
30933
|
"xhigh"
|
|
30799
30934
|
],
|
|
30800
|
-
description: "Optional reasoning depth (default
|
|
30935
|
+
description: "Optional reasoning depth (default xhigh). Silently clamped to the model's allowed range; \"off\" drops the parameter entirely."
|
|
30801
30936
|
},
|
|
30802
30937
|
workspace: {
|
|
30803
30938
|
type: "string",
|
|
@@ -30821,7 +30956,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30821
30956
|
toolNameHttp: "test",
|
|
30822
30957
|
group: "workers",
|
|
30823
30958
|
capability: "worker",
|
|
30824
|
-
description: "Runs as the background `worker-test` agent. Dispatch via the Agent tool (subagent_type: worker-test) so
|
|
30959
|
+
description: "Runs as the background `worker-test` agent. Dispatch via the Agent tool (subagent_type: worker-test) so the turn is never blocked; the result arrives as a completion notification. Independent adversarial test authoring by an autonomous worker (Pi runtime; default model `gpt-5.5` at xhigh reasoning, override via `model` with any Copilot-catalog model that advertises `tool_calls`). It has the same read/write toolset as implement and writes tests that try to break the implementation through edge cases, error paths, and acceptance criteria, then runs them and reports pass/fail. Use when a separate test author should challenge an implementation without modifying the production code to make tests pass. Not for implementing fixes, broad research, or code review; use implement, explore, or review for those scopes. With `worktree: true` it runs in an isolated git worktree and returns the test diff; this errors if the workspace is not a git repository.",
|
|
30825
30960
|
inputSchema: {
|
|
30826
30961
|
type: "object",
|
|
30827
30962
|
required: ["prompt"],
|
|
@@ -30833,7 +30968,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30833
30968
|
},
|
|
30834
30969
|
worktree: {
|
|
30835
30970
|
type: "boolean",
|
|
30836
|
-
description: "When true, run inside a fresh git worktree and return Pi's final text followed by the unified diff (so the lead can review the authored tests before merging). When false/omitted, writes tests in place
|
|
30971
|
+
description: "When true, run inside a fresh git worktree and return Pi's final text followed by the unified diff (so the lead can review the authored tests before merging). When false/omitted, writes tests in place, so concurrent worker calls and lead edits can race. Errors if true and the workspace is not a git repository."
|
|
30837
30972
|
},
|
|
30838
30973
|
model: {
|
|
30839
30974
|
type: "string",
|
|
@@ -30872,7 +31007,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30872
31007
|
{
|
|
30873
31008
|
toolNameHttp: "verify_workflow",
|
|
30874
31009
|
group: "orchestrate",
|
|
30875
|
-
description: "Statically
|
|
31010
|
+
description: "Statically verifies a workflow IR against the orchestration floor invariants before the kernel runs it. It accepts the typed WorkflowIR as `ir` and an optional `knownGateIds` allowlist, then returns {ok, violations:[{code, message, nodeId?}]} with stable violation codes such as NO_BASELINE, SELECTOR_NOT_RAW_ASK, SAME_LAB_CHECK, ORPHAN_NODE, or MISSING_INTEGRATION_GATE. Use immediately after composing or receiving a workflow IR, especially before paying for run_workflow, so structural floor failures can be fixed while still in data form. Not a runner, model reviewer, or proof that the user's spec is correct; use run_workflow to execute sealed gates and use critic/review tools for advisory review.",
|
|
30876
31011
|
inputSchema: {
|
|
30877
31012
|
type: "object",
|
|
30878
31013
|
required: ["ir"],
|
|
@@ -30902,7 +31037,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30902
31037
|
toolNameHttp: "decompose",
|
|
30903
31038
|
group: "orchestrate",
|
|
30904
31039
|
capability: "worker",
|
|
30905
|
-
description: "
|
|
31040
|
+
description: "Composes a verified, tool-routed WorkflowIR from an open-ended software ask. A strong driver model drafts the IR, the static verifier checks floor invariants, the driver re-drafts on violations, and a cross-lab critic reviews a clean draft; optional `context` supplies repo facts, constraints, or research findings to the driver. It returns {ok, ir, rounds, concerns?} on success, or {ok:false, violations, rounds} when it cannot converge. Use for non-trivial, role-separated asks where blind-spot reduction and sealed-gate structure justify orchestration. Not for trivial edits, direct implementation, or execution; use implement for a scoped code change and run_workflow only after the IR is verified.",
|
|
30906
31041
|
inputSchema: {
|
|
30907
31042
|
type: "object",
|
|
30908
31043
|
required: ["ask"],
|
|
@@ -30935,7 +31070,10 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30935
31070
|
effort: "high"
|
|
30936
31071
|
},
|
|
30937
31072
|
signal
|
|
30938
|
-
}), {
|
|
31073
|
+
}), {
|
|
31074
|
+
maxRounds: 3,
|
|
31075
|
+
context: typeof args.context === "string" ? args.context : void 0
|
|
31076
|
+
});
|
|
30939
31077
|
return {
|
|
30940
31078
|
content: [{
|
|
30941
31079
|
type: "text",
|
|
@@ -30949,7 +31087,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
30949
31087
|
toolNameHttp: "run_workflow",
|
|
30950
31088
|
group: "orchestrate",
|
|
30951
31089
|
capability: "worker",
|
|
30952
|
-
description: "
|
|
31090
|
+
description: "Executes a verified WorkflowIR through the frozen orchestration kernel. The kernel runs a single-model baseline beside the orchestrated DAG, gates producers over the sealed executable `gateId` selected by the caller, and returns {ok, outcome:{status, winner?, artifact?, reason, gatesPassed?}}. It uses champion retention: the orchestrated candidate wins only when it does not regress the baseline's executable checks; otherwise the baseline ships. Use after decompose and verify_workflow for non-trivial asks in a git workspace with a meaningful sealed gate. Not for composing an IR, performing advisory review, or running arbitrary model-authored shell commands; use decompose or verify_workflow before this tool, and use ordinary tests or review tools outside the workflow kernel.",
|
|
30953
31091
|
inputSchema: {
|
|
30954
31092
|
type: "object",
|
|
30955
31093
|
required: [
|
|
@@ -31014,7 +31152,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
31014
31152
|
{
|
|
31015
31153
|
toolNameHttp: "attest_step",
|
|
31016
31154
|
group: "orchestrate",
|
|
31017
|
-
description: "
|
|
31155
|
+
description: "Audits self-reported producer lineage for bias-isolation structure. It accepts `nodes` with each producer lab, final artifact hash, and checker hashes, then returns {attested, recommendation:'accept'|'ship_baseline', nodes:[{id, attested, reason}]}. The check passes only when every producer has a different-lab check over the same final artifact hash, so missing, same-lab, or stale checks fail closed to a baseline recommendation. Use for workflows composed outside run_workflow, where lineage is self-reported and needs a deterministic completeness gate. Not a security boundary, hash authenticator, or executor; run_workflow is the kernel-owned path when the router must control artifacts, gates, and hashes.",
|
|
31018
31156
|
inputSchema: {
|
|
31019
31157
|
type: "object",
|
|
31020
31158
|
required: ["nodes"],
|
|
@@ -31072,7 +31210,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
31072
31210
|
toolNameHttp: "browse",
|
|
31073
31211
|
group: "workers",
|
|
31074
31212
|
capability: "browse_agent",
|
|
31075
|
-
description: "Runs as the background `worker-browse` agent. Dispatch via the Agent tool (subagent_type: worker-browse) so
|
|
31213
|
+
description: "Runs as the background `worker-browse` agent. Dispatch via the Agent tool (subagent_type: worker-browse) so the turn is never blocked; the result arrives as a completion notification. A Pi-driven autonomous browser worker (default model `gpt-5.4-mini`) drives a real browser to accomplish `task`, keeps raw DOM and page snapshots inside its own context, and returns a single text result. Use for delegated multi-step web tasks such as comparing prices, logging into a dashboard, or summarizing pages when the lead does not need to steer each click. Not for direct in-context browser control, screenshots, or precise element interactions; use the `browser` MCP tools for those. Pass `sessionId` to continue a prior browse session, or omit it for a fresh isolated session; multiple calls run as parallel sessions on the shared browser.",
|
|
31076
31214
|
inputSchema: {
|
|
31077
31215
|
type: "object",
|
|
31078
31216
|
required: ["task"],
|
|
@@ -31100,7 +31238,7 @@ const NON_PERSONA_MCP_TOOLS = Object.freeze([
|
|
|
31100
31238
|
toolNameHttp: "stand_in",
|
|
31101
31239
|
group: "decide",
|
|
31102
31240
|
capability: "stand_in",
|
|
31103
|
-
description: "
|
|
31241
|
+
description: "Three-lab away-mode decision tiebreak advisor for moments when the user is unavailable and the agent is stuck between two or more concrete options. It polls gpt-5.5, Opus 4.7, and gemini-3.1-pro-preview across blind and informed voting rounds, then returns a ranked-choice verdict such as consensus, majority, no_consensus, or need_more_info. Use when work would otherwise halt on a bounded choice the user would normally make. Not for code review, open-ended exploration, single-model second opinions, or bypassing confirmation on irreversible actions such as push, delete, drop, or deploy; use peer-review-coordinator or the individual critics for review and still ask the user for destructive actions.",
|
|
31104
31242
|
inputSchema: {
|
|
31105
31243
|
type: "object",
|
|
31106
31244
|
required: ["decision", "options"],
|
|
@@ -31189,7 +31327,7 @@ function assertMcpToolSurfaceConsistent() {
|
|
|
31189
31327
|
* accessibility) and never throws — its `{text, isError?}` envelope
|
|
31190
31328
|
* is forwarded verbatim into the MCP `tool result` shape.
|
|
31191
31329
|
*
|
|
31192
|
-
* Arg-validation policy mirrors `
|
|
31330
|
+
* Arg-validation policy mirrors `web`'s pattern: shape errors
|
|
31193
31331
|
* surface as `isError: true` tool-result envelopes (NOT JSON-RPC -32602
|
|
31194
31332
|
* errors). The MCP `tools/list` JSON schema already documents the
|
|
31195
31333
|
* required/optional fields; this runtime check is defense against a
|
|
@@ -31396,7 +31534,7 @@ async function runBrowseToolCall(args, signal) {
|
|
|
31396
31534
|
* failures, abstains) all surface inside the structured `StandInResult`
|
|
31397
31535
|
* envelope, which we JSON-stringify into the single MCP text block.
|
|
31398
31536
|
*
|
|
31399
|
-
* Arg-validation policy mirrors `runWorkerToolCall` and `
|
|
31537
|
+
* Arg-validation policy mirrors `runWorkerToolCall` and `web`:
|
|
31400
31538
|
* shape errors surface as `isError: true` tool-result envelopes (NOT
|
|
31401
31539
|
* JSON-RPC -32602). The `tools/list` JSON schema documents required
|
|
31402
31540
|
* fields; this runtime check is defense against a schema-ignoring
|
|
@@ -31494,5 +31632,5 @@ async function runStandInToolCall(args, signal) {
|
|
|
31494
31632
|
}
|
|
31495
31633
|
|
|
31496
31634
|
//#endregion
|
|
31497
|
-
export {
|
|
31498
|
-
//# sourceMappingURL=peer-mcp-personas-
|
|
31635
|
+
export { isAdvisorRequested as $, cacheModels as $t, liveExec as A, hasSupportedBrowserInstalled as At, withNoOutputRetry as B, DEFAULT_CODEX_MODEL_FALLBACKS as Bt, fileReviewDebounce as C, pickEndpoint as Ct, stopGateEnabledForRepo as D, readResponseBodyCapped as Dt, repoRoot as E, MAX_RESPONSE_BODY_BYTES as Et, IMPLEMENT_DEFAULT_MODEL as F, ArtifactClient as Ft, vscodeRipgrepPath as G, pickClaudeDefault as Gt, buildToolbeltAwareness as H, UPSTREAM_FETCH_TIMEOUT_MS as Ht, PLAN_DEFAULT_MODEL as I, collapsePathKeys as It, searchWeb as J, setupCopilotToken as Jt, TOOLBELT_TOOLS$1 as K, getPackageVersion as Kt, REVIEW_DEFAULT_MODEL as L, toolbeltPathOverride as Lt, BROWSE_DEFAULT_MODEL as M, extractTarGzMember as Mt, DEFAULT_MODEL as N, extractZipMember as Nt, stopReviewStateDir as O, parseJsonOrDiagnose as Ot, EXPLORE_DEFAULT_MODEL as P, shouldUseInsecureTls as Pt, injectAdvisorTool as Q, cacheCopilotVersion as Qt, appendPlanReminder as R, DEFAULT_CLAUDE_MODEL_FALLBACKS as Rt, fileLastPromptStore as S, resolveMcpToolTimeoutMs as St, repoFingerprint as T, createChatCompletions as Tt, toolbeltEnabled as U, UPSTREAM_INACTIVITY_TIMEOUT_MS as Ut, availableToolCommands as V, DEFAULT_PORT as Vt, toolbeltSkipSet as W, generateRandomPort as Wt, ADVISOR_TOOL_INSTRUCTIONS as X, setupGitHubToken as Xt, ADVISOR_INTERNAL_TOOL_NAME as Y, setupGitHubAgentToken as Yt, buildAdvisorStream as Z, tryRefreshAndRetry as Zt, stopGateId as _, workerToolsEnabled as _t, buildPeerAwarenessSnippet as a, sleep as an, relayAnthropicStream as at, fileBaselineStore as b, getTokenCount as bt, buildArtifactOpenHookCommand as c, HTTPError as cn, agentToolsEnabled as ct, captureLaunchBaseline as d, copilotBaseUrl as dn, browserCompoundToolsEnabled as dt, cacheVSCodeVersion as en, buildAnthropicErrorEvent as et, decideStopHook as f, copilotHeaders as fn, browserToolsEnabled as ft, stopGateDisabled as g, standInToolEnabled as gt, launchBaselineKey as h, implementerSubagentModel as ht, buildAgentPrompt as i, resolveModel as in, readIteratorWithTimeout as it, resolveSealedGate as j, provisionAndIndexColbert as jt, trustRepo as k, provisionBrowserAssets as kt, buildSessionBindHookCommand as l, forwardError as ln, artifactToolsEnabled as lt, injectStopHookIntoSettingsFile as m, state as mn, geminiAvailable as mt, MCP_GROUPS as n, isNullish as nn, isControllerClosedError as nt, buildPeerAwarenessSummary as o, getModels as on, handleMcpDelete as ot, fileBlockBudget as p, githubHeaders as pn, fleetToolsEnabled as pt, assetFor as q, withInstallLock as qt, assertMcpToolSurfaceConsistent as r, resolveCodexModel as rn, logStreamError as rt, personasFor as s, fetchWithTransientRetry as sn, handleMcpPost as st, GROUP_META as t, filterBetaHeader as tn, buildOpenAIErrorEvent as tt, buildStopHookCommand as u, GITHUB_API_BASE_URL as un, browseAgentEnabled as ut, stopGatePlanMode as v, countTokens as vt, isSubagentContext as w, createResponses as wt, fileFindingsStore as x, assembleResponsesPayload as xt, stopReviewEnabled as y, createMessages as yt, runWorkerAgent as z, DEFAULT_CODEX_MODEL as zt };
|
|
31636
|
+
//# sourceMappingURL=peer-mcp-personas-BCGYWok0.js.map
|