usebeeline 0.0.110 → 0.0.112
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/usebeeline.mjs +120 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
<p align="center"><strong>Team messaging for agents and humans.</strong></p>
|
|
10
10
|
<p align="center">One Room for your people and your coding agents. Talk it through, hand off the work, watch it merge.</p>
|
|
11
11
|
|
|
12
|
-
`usebeeline` connects **a coding agent you already run — Claude Code, Codex, Goose, Pi, or
|
|
12
|
+
`usebeeline` connects **a coding agent you already run — Claude Code, Codex, Goose, Pi, Grok, or Cursor — to a Room in the Beeline app on your phone**. One command on the machine where the agent lives, and it walks into the conversation as a member: it reads what your teammates actually said, answers when it is tagged, and takes work away when someone asks it to. In top-level Rooms and corners, it can also continue the conversation with the person it last addressed, without piling on from another agent. Nothing is retyped into a prompt box.
|
|
13
13
|
|
|
14
14
|
The agent stays on your machine. Your provider key stays on your machine. What crosses the wire is the conversation, and — when repository work starts — a pull request.
|
|
15
15
|
|
package/dist/usebeeline.mjs
CHANGED
|
@@ -6092,16 +6092,18 @@ var AGENT_KINDS = [
|
|
|
6092
6092
|
"goose",
|
|
6093
6093
|
"pi",
|
|
6094
6094
|
"grok",
|
|
6095
|
+
"cursor",
|
|
6095
6096
|
"reference",
|
|
6096
6097
|
"custom"
|
|
6097
6098
|
];
|
|
6098
|
-
var AUTO_DETECT_AGENT_KINDS = ["codex", "claude", "goose", "pi", "grok"];
|
|
6099
|
+
var AUTO_DETECT_AGENT_KINDS = ["codex", "claude", "goose", "pi", "grok", "cursor"];
|
|
6099
6100
|
var AGENT_EXECUTABLES = {
|
|
6100
6101
|
codex: "codex",
|
|
6101
6102
|
claude: "claude",
|
|
6102
6103
|
goose: "goose",
|
|
6103
6104
|
pi: "pi",
|
|
6104
|
-
grok: "grok"
|
|
6105
|
+
grok: "grok",
|
|
6106
|
+
cursor: "cursor-agent"
|
|
6105
6107
|
};
|
|
6106
6108
|
var ADAPTER_INSTALL_COMMANDS = {
|
|
6107
6109
|
codex: {
|
|
@@ -6115,6 +6117,10 @@ var ADAPTER_INSTALL_COMMANDS = {
|
|
|
6115
6117
|
pi: {
|
|
6116
6118
|
command: "npm",
|
|
6117
6119
|
args: ["install", "-g", "pi-acp"]
|
|
6120
|
+
},
|
|
6121
|
+
cursor: {
|
|
6122
|
+
command: "npm",
|
|
6123
|
+
args: ["install", "-g", "cursor-agent-acp"]
|
|
6118
6124
|
}
|
|
6119
6125
|
};
|
|
6120
6126
|
function adapterInstallHint(kind) {
|
|
@@ -6295,6 +6301,11 @@ function resolveAgentCommand(opts) {
|
|
|
6295
6301
|
const command2 = requireExecutable("pi-acp", env, cwd, `Pi needs an ACP adapter. Install it with \`${adapterInstallHint("pi")}\`, then retry with \`--agent pi\`.`);
|
|
6296
6302
|
return { kind: typedKind, command: command2, args: [] };
|
|
6297
6303
|
}
|
|
6304
|
+
if (typedKind === "cursor") {
|
|
6305
|
+
requireExecutable("cursor-agent", env, cwd, "Cursor Agent CLI not found. Install it from https://cursor.com/docs/cli, then retry with `--agent cursor`.");
|
|
6306
|
+
const command2 = requireExecutable("cursor-agent-acp", env, cwd, `Cursor ACP adapter not found. Install it with \`${adapterInstallHint("cursor")}\`, then retry with \`--agent cursor\`.`);
|
|
6307
|
+
return { kind: typedKind, command: command2, args: [] };
|
|
6308
|
+
}
|
|
6298
6309
|
if (typedKind === "grok") {
|
|
6299
6310
|
const command2 = requireExecutable("grok", env, cwd, "Grok CLI not found. Install it with `curl -fsSL https://x.ai/cli/install.sh | bash`, then retry with `--agent grok`.");
|
|
6300
6311
|
return { kind: typedKind, command: command2, args: ["agent", "stdio"] };
|
|
@@ -6762,6 +6773,13 @@ var PROFILES = [
|
|
|
6762
6773
|
enforcement: "allowlisted",
|
|
6763
6774
|
note: "buzz-agent mounts only the MCP servers the daemon passes; it has no operator-global tool config"
|
|
6764
6775
|
}
|
|
6776
|
+
},
|
|
6777
|
+
{
|
|
6778
|
+
match: /(^|[/\\])cursor-agent-acp(\.[a-z]+)?$/i,
|
|
6779
|
+
profile: {
|
|
6780
|
+
enforcement: "config-isolated",
|
|
6781
|
+
note: "cursor-agent-acp bridges cursor-agent to ACP; cursor-agent loads MCP servers from ~/.cursor/mcp.json, so an isolated CURSOR_HOME scopes the session"
|
|
6782
|
+
}
|
|
6765
6783
|
}
|
|
6766
6784
|
];
|
|
6767
6785
|
function sessionToolScopeMeta(agentCommand) {
|
|
@@ -18026,6 +18044,7 @@ var DaemonApiClient = class {
|
|
|
18026
18044
|
liveReconnectDelayMs = 1e3;
|
|
18027
18045
|
liveRooms = /* @__PURE__ */ new Map();
|
|
18028
18046
|
roomsChangedListener;
|
|
18047
|
+
configChangedListener;
|
|
18029
18048
|
constructor(baseUrl, daemonToken, agentId, fetchImpl = fetch, webSocketFactory = (url, protocols) => new wrapper_default(url, protocols)) {
|
|
18030
18049
|
this.baseUrl = baseUrl;
|
|
18031
18050
|
this.daemonToken = daemonToken;
|
|
@@ -18078,6 +18097,12 @@ var DaemonApiClient = class {
|
|
|
18078
18097
|
setRoomsChangedListener(listener) {
|
|
18079
18098
|
this.roomsChangedListener = listener;
|
|
18080
18099
|
}
|
|
18100
|
+
/** Register the one listener invoked when the server reports the agent's
|
|
18101
|
+
* model/effort selection changed — the wake that hot-restarts every
|
|
18102
|
+
* retained session (agent-wide; the event names no single Room). */
|
|
18103
|
+
setConfigChangedListener(listener) {
|
|
18104
|
+
this.configChangedListener = listener;
|
|
18105
|
+
}
|
|
18081
18106
|
updateLiveCursor(roomId, cursor3) {
|
|
18082
18107
|
const room = this.liveRooms.get(roomId);
|
|
18083
18108
|
if (room && cursor3)
|
|
@@ -18127,6 +18152,10 @@ var DaemonApiClient = class {
|
|
|
18127
18152
|
this.roomsChangedListener?.();
|
|
18128
18153
|
return;
|
|
18129
18154
|
}
|
|
18155
|
+
if (event.type === "config-changed") {
|
|
18156
|
+
this.configChangedListener?.();
|
|
18157
|
+
return;
|
|
18158
|
+
}
|
|
18130
18159
|
if (event.type === "subscribed" && typeof event.roomId === "string") {
|
|
18131
18160
|
const capabilities = event.capabilities;
|
|
18132
18161
|
this.liveRooms.get(event.roomId)?.onState?.(true, {
|
|
@@ -18510,6 +18539,10 @@ var HARNESS_HOME_STATE_DIRS = [
|
|
|
18510
18539
|
{
|
|
18511
18540
|
match: /(^|[/\\])grok(\.[a-z]+)?$/i,
|
|
18512
18541
|
dirs: [".grok"]
|
|
18542
|
+
},
|
|
18543
|
+
{
|
|
18544
|
+
match: /(^|[/\\])cursor-agent-acp(\.[a-z]+)?$/i,
|
|
18545
|
+
dirs: [".cursor"]
|
|
18513
18546
|
}
|
|
18514
18547
|
];
|
|
18515
18548
|
function harnessHomeStateDirs(agentCommand, home = homedir3()) {
|
|
@@ -19381,6 +19414,7 @@ function isAgentPairingCode(value) {
|
|
|
19381
19414
|
|
|
19382
19415
|
// apps/body/dist/beeline-skill.js
|
|
19383
19416
|
var USING_BEELINE_SKILL_NAME = "using-beeline";
|
|
19417
|
+
var BEELINE_TRIAGE_SKILL_NAME = "beeline-triage";
|
|
19384
19418
|
var BEELINE_REVIEW_SKILL_NAME = "beeline-review";
|
|
19385
19419
|
function isConfiguredReviewer(agentHandle, reviewerHandle) {
|
|
19386
19420
|
return Boolean(agentHandle && reviewerHandle && agentHandle.replace(/^@/, "") === reviewerHandle.replace(/^@/, ""));
|
|
@@ -19397,6 +19431,7 @@ var BEELINE_ROOM_CAPABILITIES = [
|
|
|
19397
19431
|
`To react to things that HAPPEN in this Room rather than only to what is said to you, call beeline-agent subscribe_events with the kinds you want (${SERVER_EVENT_KINDS.join(", ")}); each one then wakes you for a turn. Subscriptions are per Room and cover every way the event lands: joining a Room you subscribed to wakes you, and so does a person arriving in the Workspace when that arrival projects into this Room - subscribe to joined in an onboarding Room and every newcomer wakes you, exactly like a greeter. It replaces your list, so send every kind you want - list_event_subscriptions shows the current one. You do this yourself: nobody has to configure it for you. grant-decided carries the grant id and status and resumes the turn that asked for the grant.`,
|
|
19398
19432
|
"To state something that happened so the Room and other agents can act on it, call beeline-agent emit_event with your own agent:<slug> kind, one sentence, and optionally the agent members to wake. Chains of events are bounded and a refused emit posts nothing.",
|
|
19399
19433
|
"When repository work is needed, you MUST call beeline-agent open_corner with a name of at most three words - it titles the corner everywhere - and a complete objective of no more than 24 words. The host-governed call is the only way to start write work.",
|
|
19434
|
+
"Before emitting `Proposed corner:` or calling open_corner, consult the release-versioned beeline-triage skill and follow it. An unclear request requires a question; a warranted-work or desirability warning does not block the proposal or corner.",
|
|
19400
19435
|
"Never open a corner from your own reading of a person's ask. For every ask, first reply on one line `Proposed corner: <name> \u2014 <objective>`, using the exact title and objective you would pass to open_corner, then stop and wait. If one message contains several asks, list one numbered `Proposed corner:` line per ask; `go on 1 and 3` opens exactly those objectives and leaves the others proposed. A person's `go`, `yes`, or equivalent opens exactly the proposed corner; if they edit it, their edited text is the objective. Skip this ceremony only when the message itself explicitly commands a corner and states its scope, such as `open a corner and do X` or `go build X in a corner`; open that scope immediately.",
|
|
19401
19436
|
"Agreement is not action: never merely acknowledge an ask. Reply with a proposed corner, a question, or a line beginning `parked:` with the reason.",
|
|
19402
19437
|
"When open_corner succeeds, the server posts the corner card: do not announce or restate the opening. End the turn with nothing more unless the person asked something else.",
|
|
@@ -19488,6 +19523,11 @@ Follow these steps in order. Do not skip or reorder them.
|
|
|
19488
19523
|
|
|
19489
19524
|
## 2. P0 - OBJECTIVE FULFILLED, DEMONSTRATED
|
|
19490
19525
|
|
|
19526
|
+
Before judging the implementation, independently repeat the two judgment legs from request triage:
|
|
19527
|
+
|
|
19528
|
+
- **Work warranted:** For a bug, reproduce the reported behavior on the target branch. For another request, establish the unmet user need from the request and current product. Search current code, history, issues, and open or recently merged pull requests for work that already resolves or supersedes it. Treat title similarity only as a candidate, not proof of duplication. FAIL confirmed duplicate or obsolete work.
|
|
19529
|
+
- **Desirable:** Check repository-owned goals, invariants, architecture, and established product behavior. Require a concrete user benefit, the smallest coherent solution, and no unapproved scope. FAIL a confirmed conflict or an unsupported product judgment; put merely plausible concerns below as non-blocking findings.
|
|
19530
|
+
|
|
19491
19531
|
- Quote the corner objective verbatim.
|
|
19492
19532
|
- Derive its end-user story in one sentence: \`a user who does X sees Y\`.
|
|
19493
19533
|
- Make Y happen against the built PR head: run the app or affected service and perform X.
|
|
@@ -19531,6 +19571,8 @@ Follow these steps in order. Do not skip or reorder them.
|
|
|
19531
19571
|
|
|
19532
19572
|
\`objective quoted:\`
|
|
19533
19573
|
\`user story:\`
|
|
19574
|
+
\`work warranted evidence:\`
|
|
19575
|
+
\`desirability evidence:\`
|
|
19534
19576
|
\`how Y was demonstrated (or FAIL):\`
|
|
19535
19577
|
\`commands run + results:\`
|
|
19536
19578
|
\`critical findings (block):\`
|
|
@@ -19545,6 +19587,49 @@ Then take exactly one action:
|
|
|
19545
19587
|
- Approving is your last step as reviewer. The author merges it; you never do, and nothing merges it automatically.
|
|
19546
19588
|
`;
|
|
19547
19589
|
}
|
|
19590
|
+
function beelineTriageSkillMarkdown(releaseId) {
|
|
19591
|
+
return `---
|
|
19592
|
+
name: beeline-triage
|
|
19593
|
+
description: Clarify and assess a user request before proposing or opening a Beeline corner. Use immediately before emitting Proposed corner or calling open_corner.
|
|
19594
|
+
---
|
|
19595
|
+
|
|
19596
|
+
<!-- beeline-release: ${releaseId} -->
|
|
19597
|
+
|
|
19598
|
+
# Beeline request triage
|
|
19599
|
+
|
|
19600
|
+
Run these checks before proposing or opening a corner.
|
|
19601
|
+
|
|
19602
|
+
## 1. Is it clear?
|
|
19603
|
+
|
|
19604
|
+
- Rewrite the request as a concrete outcome and acceptance criteria.
|
|
19605
|
+
- State material exclusions needed to prevent unrequested work.
|
|
19606
|
+
- Keep the corner objective complete and within 24 words.
|
|
19607
|
+
- If an ambiguity could materially change the outcome, ask one focused question instead of proposing or opening the corner.
|
|
19608
|
+
|
|
19609
|
+
## 2. Is work warranted?
|
|
19610
|
+
|
|
19611
|
+
- For a bug, try to reproduce the exact user-visible behavior and record the evidence.
|
|
19612
|
+
- For another request, identify the unmet user need and the current behavior that does not meet it.
|
|
19613
|
+
- Search current code, history, issues, and open or recently merged pull requests for released or unreleased work that resolves or supersedes the request.
|
|
19614
|
+
- Treat similar titles as candidates. Confirm behavior and scope before calling work duplicate.
|
|
19615
|
+
- If the need cannot be established, reproduction fails, or other work may obviate it, warn; do not block.
|
|
19616
|
+
|
|
19617
|
+
## 3. Is it desirable?
|
|
19618
|
+
|
|
19619
|
+
- Compare the request with repository-owned goals, invariants, architecture, and established product behavior.
|
|
19620
|
+
- Look for concrete user benefit, the smallest coherent solution, and ongoing maintenance cost.
|
|
19621
|
+
- Do not invent product strategy. If the evidence is absent or conflicting, warn; do not block.
|
|
19622
|
+
|
|
19623
|
+
## Output
|
|
19624
|
+
|
|
19625
|
+
When proposing work, emit the ordinary \`Proposed corner: <name> \u2014 <objective>\` line. Add only applicable warnings on following lines:
|
|
19626
|
+
|
|
19627
|
+
\`Triage warning \u2014 warranted: <evidence-backed reason>\`
|
|
19628
|
+
\`Triage warning \u2014 desirable: <evidence-backed reason>\`
|
|
19629
|
+
|
|
19630
|
+
Do not emit a warning merely because evidence is incomplete when the repository offers no practical way to obtain it. Never describe a warning as approval or rejection. Warnings inform the user and implementer; they do not block work.
|
|
19631
|
+
`;
|
|
19632
|
+
}
|
|
19548
19633
|
|
|
19549
19634
|
// apps/body/dist/external-mcp-capabilities.js
|
|
19550
19635
|
var SQUIRE_MCP_VERSION = "latest";
|
|
@@ -20139,11 +20224,15 @@ var SHARED_CREDENTIALS = [
|
|
|
20139
20224
|
// Grok relocates ~/.grok via GROK_HOME; auth.json holds its login (same
|
|
20140
20225
|
// shape as codex).
|
|
20141
20226
|
{ dir: "grok", source: ".grok/auth.json", target: "auth.json" },
|
|
20142
|
-
{ dir: "pi", source: ".pi/agent/auth.json", target: "auth.json" }
|
|
20227
|
+
{ dir: "pi", source: ".pi/agent/auth.json", target: "auth.json" },
|
|
20228
|
+
// Cursor CLI stores auth state under ~/.cursor/; cursor-agent-acp
|
|
20229
|
+
// reads CURSOR_HOME to relocate the data directory.
|
|
20230
|
+
{ dir: "cursor", source: ".cursor/agent-cli-state.json", target: "agent-cli-state.json" }
|
|
20143
20231
|
];
|
|
20144
20232
|
var GOOSE_SHARED_CONFIG_FILES = ["config.yaml", "secrets.yaml"];
|
|
20145
20233
|
var BEELINE_DEFAULT_SKILL_NAMES = [
|
|
20146
20234
|
BEELINE_REVIEW_SKILL_NAME,
|
|
20235
|
+
BEELINE_TRIAGE_SKILL_NAME,
|
|
20147
20236
|
USING_BEELINE_SKILL_NAME
|
|
20148
20237
|
];
|
|
20149
20238
|
var OPERATOR_SKILL_SOURCE_DIRS = [
|
|
@@ -20152,7 +20241,7 @@ var OPERATOR_SKILL_SOURCE_DIRS = [
|
|
|
20152
20241
|
".codex/skills",
|
|
20153
20242
|
".pi/agent/skills"
|
|
20154
20243
|
];
|
|
20155
|
-
var AGENT_SKILL_DIRS = ["claude", "codex", "grok", "pi"];
|
|
20244
|
+
var AGENT_SKILL_DIRS = ["claude", "codex", "grok", "pi", "cursor"];
|
|
20156
20245
|
function agentSkillDir(kind) {
|
|
20157
20246
|
return AGENT_SKILL_DIRS.includes(kind ?? "") ? kind : "codex";
|
|
20158
20247
|
}
|
|
@@ -20180,6 +20269,7 @@ var HOME_SUBDIRS = [
|
|
|
20180
20269
|
"goose",
|
|
20181
20270
|
"grok",
|
|
20182
20271
|
"pi",
|
|
20272
|
+
"cursor",
|
|
20183
20273
|
"state",
|
|
20184
20274
|
"cache",
|
|
20185
20275
|
"tmp"
|
|
@@ -20225,6 +20315,7 @@ async function prepareRoomAgentHome(input) {
|
|
|
20225
20315
|
async function provisionAgentSkillsAndMcp(root, operatorHome, skillReleaseId, failClosed, sharedSkills, skillDir, openRouterRouting, isReviewer) {
|
|
20226
20316
|
const managedSkills = [
|
|
20227
20317
|
{ name: USING_BEELINE_SKILL_NAME, content: usingBeelineSkillMarkdown(skillReleaseId) },
|
|
20318
|
+
{ name: BEELINE_TRIAGE_SKILL_NAME, content: beelineTriageSkillMarkdown(skillReleaseId) },
|
|
20228
20319
|
...isReviewer ? [{ name: BEELINE_REVIEW_SKILL_NAME, content: beelineReviewSkillMarkdown(skillReleaseId) }] : []
|
|
20229
20320
|
];
|
|
20230
20321
|
const shared = await resolveSharedSkillSources(operatorHome, sharedSkills);
|
|
@@ -20634,6 +20725,7 @@ function roomAgentHomeEnv(root) {
|
|
|
20634
20725
|
CODEX_HOME: resolve13(resolved, "codex"),
|
|
20635
20726
|
GOOSE_PATH_ROOT: resolve13(resolved, "goose"),
|
|
20636
20727
|
GROK_HOME: resolve13(resolved, "grok"),
|
|
20728
|
+
CURSOR_HOME: resolve13(resolved, "cursor"),
|
|
20637
20729
|
PI_CODING_AGENT_DIR: resolve13(resolved, "pi"),
|
|
20638
20730
|
XDG_STATE_HOME: resolve13(resolved, "state"),
|
|
20639
20731
|
XDG_CACHE_HOME: resolve13(resolved, "cache"),
|
|
@@ -20645,6 +20737,7 @@ var HARNESS_STATE_ENV_VARS = [
|
|
|
20645
20737
|
"CODEX_HOME",
|
|
20646
20738
|
"GOOSE_PATH_ROOT",
|
|
20647
20739
|
"GROK_HOME",
|
|
20740
|
+
"CURSOR_HOME",
|
|
20648
20741
|
"PI_CODING_AGENT_DIR",
|
|
20649
20742
|
"XDG_STATE_HOME",
|
|
20650
20743
|
"XDG_CACHE_HOME",
|
|
@@ -24434,6 +24527,23 @@ var SessionScheduler = class {
|
|
|
24434
24527
|
this.live.delete(key);
|
|
24435
24528
|
await this.retire(session);
|
|
24436
24529
|
}
|
|
24530
|
+
/**
|
|
24531
|
+
* Retire every RETAINED session — the warm processes holding no turn — in
|
|
24532
|
+
* one pass. This is the config-change hot restart: a phone-side model/effort
|
|
24533
|
+
* selection change must not wait for each Room's next hand-back currency
|
|
24534
|
+
* check to notice. A busy, draining, queued, or still-spawning session is
|
|
24535
|
+
* deliberately left alone: interrupting a live turn buys nothing, and its
|
|
24536
|
+
* next hand-back runs the ordinary `isCurrent` check, which cold-activates
|
|
24537
|
+
* against the new selection. Suspending a key that is no longer live is a
|
|
24538
|
+
* no-op, so overlapping wakes coalesce safely.
|
|
24539
|
+
*/
|
|
24540
|
+
async suspendIdle() {
|
|
24541
|
+
for (const [key, session] of [...this.live.entries()]) {
|
|
24542
|
+
if (session.pending || this.busy.has(key) || this.drainingKeys.has(key) || (this.queues.get(key)?.length ?? 0) > 0)
|
|
24543
|
+
continue;
|
|
24544
|
+
await this.suspend(key);
|
|
24545
|
+
}
|
|
24546
|
+
}
|
|
24437
24547
|
/**
|
|
24438
24548
|
* Tear down a poisoned session even when its task is still marked busy.
|
|
24439
24549
|
* The watchdog uses this only after a Room has stopped making progress; the
|
|
@@ -24867,6 +24977,9 @@ var RoomRuntimeCoordinator = class {
|
|
|
24867
24977
|
this.options.daemonApi.setRoomsChangedListener?.(() => {
|
|
24868
24978
|
this.discoveryWakes.wake();
|
|
24869
24979
|
});
|
|
24980
|
+
this.options.daemonApi.setConfigChangedListener?.(() => {
|
|
24981
|
+
void this.scheduler.suspendIdle().catch((error) => console.error("[body] config-change session restart failed", error));
|
|
24982
|
+
});
|
|
24870
24983
|
this.watchdogStaleMs = options.watchdogStaleMs ?? DEFAULT_ROOM_WATCHDOG_STALE_MS;
|
|
24871
24984
|
this.reconcileHeartbeatMs = options.reconcileHeartbeatMs ?? DEFAULT_RECONCILE_HEARTBEAT_MS;
|
|
24872
24985
|
this.drainDeadlineMs = options.drainDeadlineMs ?? DEFAULT_DRAIN_DEADLINE_MS;
|
|
@@ -25900,6 +26013,7 @@ Install one of these supported agents:
|
|
|
25900
26013
|
goose https://block.github.io/goose/docs/getting-started/installation/
|
|
25901
26014
|
pi npm install -g @mariozechner/pi-coding-agent pi-acp
|
|
25902
26015
|
grok curl -fsSL https://x.ai/cli/install.sh | bash
|
|
26016
|
+
cursor npm install -g cursor-agent-acp
|
|
25903
26017
|
Then retry, or explicitly use \`--agent reference\` with an LLM key.
|
|
25904
26018
|
For another ACP server, use \`--agent custom --agent-command "<cmd> [args...]"\`.`;
|
|
25905
26019
|
async function clackConfirmInstall(message) {
|
|
@@ -26138,7 +26252,8 @@ var DEFAULT_MODELS = {
|
|
|
26138
26252
|
xai: "grok-4",
|
|
26139
26253
|
codex: "gpt-5.4",
|
|
26140
26254
|
claude: "claude-opus-4-1",
|
|
26141
|
-
grok: "grok-4"
|
|
26255
|
+
grok: "grok-4",
|
|
26256
|
+
cursor: "claude-sonnet-4"
|
|
26142
26257
|
};
|
|
26143
26258
|
function connectHarnessNeedsProvider(harness) {
|
|
26144
26259
|
return CONNECT_PROVIDER_HARNESSES.has(harness);
|