commonswarm 0.1.22 → 0.1.23
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/cswarm.cjs +142 -44
- package/package.json +1 -1
package/cswarm.cjs
CHANGED
|
@@ -13511,6 +13511,7 @@ __export(cli_exports, {
|
|
|
13511
13511
|
listenerPermissionMode: () => listenerPermissionMode,
|
|
13512
13512
|
listenerStatusJson: () => listenerStatusJson,
|
|
13513
13513
|
renderRoster: () => renderRoster,
|
|
13514
|
+
replyRefusalHint: () => replyRefusalHint,
|
|
13514
13515
|
resolveDetachedClaudeExecutable: () => resolveDetachedClaudeExecutable,
|
|
13515
13516
|
resolveDetachedCodexExecutable: () => resolveDetachedCodexExecutable,
|
|
13516
13517
|
resolveTurnBudgetOrDefer: () => resolveTurnBudgetOrDefer
|
|
@@ -22162,15 +22163,8 @@ function createWorkspaceError(status, body) {
|
|
|
22162
22163
|
return new CreateWorkspaceError(
|
|
22163
22164
|
status,
|
|
22164
22165
|
code,
|
|
22165
|
-
/*
|
|
22166
|
-
|
|
22167
|
-
* is unreachable from every surface — `archived_at` exists and nothing writes it — and on a
|
|
22168
|
-
* self-serve deployment the reader IS the operator, so it named a person who does not exist
|
|
22169
|
-
* to perform an action that does not exist.
|
|
22170
|
-
*
|
|
22171
|
-
* It now states the limit, does not offer a remedy that is unimplemented, and names the one
|
|
22172
|
-
* route that does work: someone else's invitation, which is not capped. */
|
|
22173
|
-
`${limit === null ? "You have already created as many workspaces as this account allows." : `You have already created ${limit} workspaces, which is the limit for one account.`} Workspaces cannot be removed yet, so this limit is a ceiling rather than a queue. Workspaces you were invited to do not count against it \u2014 a collaborator can still add you to theirs.`
|
|
22166
|
+
/* Closing one live workspace now frees a slot; name the exact confirmed command. */
|
|
22167
|
+
`${limit === null ? "You have already created as many workspaces as this account allows." : `You have already created ${limit} workspaces, which is the limit for one account.`} Close one with cswarm workspace close <full-id|exact-name> --confirm <same-selector>, then try again. Workspaces you were invited to do not count against it.`
|
|
22174
22168
|
);
|
|
22175
22169
|
}
|
|
22176
22170
|
if (status === 403) {
|
|
@@ -22797,6 +22791,12 @@ var CONTENT_TYPES = /* @__PURE__ */ new Map([
|
|
|
22797
22791
|
[".md", "text/markdown"],
|
|
22798
22792
|
[".txt", "text/plain"],
|
|
22799
22793
|
[".csv", "text/csv"],
|
|
22794
|
+
// .html/.htm: a web/marketing team's deliverables (Fastio feedback 2026-08-19). Every
|
|
22795
|
+
// download is served Content-Disposition: attachment (§5), never rendered inline, so HTML
|
|
22796
|
+
// is no more dangerous than the .svg already permitted — the spec treats all downloads as
|
|
22797
|
+
// untrusted attachments the consumer must not execute.
|
|
22798
|
+
[".html", "text/html"],
|
|
22799
|
+
[".htm", "text/html"],
|
|
22800
22800
|
[".json", "application/json"],
|
|
22801
22801
|
[".yaml", "application/yaml"],
|
|
22802
22802
|
[".yml", "application/yaml"],
|
|
@@ -27730,6 +27730,7 @@ var DEFAULT_MEMBERSHIP_REVOKED = {
|
|
|
27730
27730
|
message: "Your previously selected workspace is no longer available to this account. CommonSwarm cleared that saved selection."
|
|
27731
27731
|
};
|
|
27732
27732
|
var PROJECT_NOT_AVAILABLE = "That workspace is not available to this account. Run cswarm workspaces to see workspaces you can select.";
|
|
27733
|
+
var ARCHIVED_PROJECT_NOT_AVAILABLE = "That workspace is closed and cannot be selected. Run cswarm workspaces to see live workspaces you can select.";
|
|
27733
27734
|
function compareText(left, right) {
|
|
27734
27735
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
27735
27736
|
}
|
|
@@ -27767,8 +27768,8 @@ var WorkspaceResolutionError = class extends WorkspaceCliError {
|
|
|
27767
27768
|
};
|
|
27768
27769
|
var WorkspaceUnavailableError = class extends WorkspaceCliError {
|
|
27769
27770
|
code = "project_not_available";
|
|
27770
|
-
constructor() {
|
|
27771
|
-
super(
|
|
27771
|
+
constructor(message = PROJECT_NOT_AVAILABLE) {
|
|
27772
|
+
super(message);
|
|
27772
27773
|
this.name = "WorkspaceUnavailableError";
|
|
27773
27774
|
}
|
|
27774
27775
|
structured() {
|
|
@@ -27872,41 +27873,41 @@ function cloudWorkspaceDirectory(target2, fetcher = fetch) {
|
|
|
27872
27873
|
"workspaces",
|
|
27873
27874
|
{
|
|
27874
27875
|
select: "workspace_id,name,archived_at",
|
|
27876
|
+
archived_at: "is.null",
|
|
27875
27877
|
order: "workspace_id.asc"
|
|
27876
27878
|
},
|
|
27877
27879
|
fetcher
|
|
27878
27880
|
)
|
|
27879
27881
|
]);
|
|
27880
|
-
const
|
|
27882
|
+
const roles = /* @__PURE__ */ new Map();
|
|
27883
|
+
for (const row of membershipRows) {
|
|
27884
|
+
const workspaceId2 = checkedUuid(row.workspace_id, "workspace_id");
|
|
27885
|
+
roles.set(workspaceId2, checkedRole(row.role));
|
|
27886
|
+
}
|
|
27887
|
+
const result = [];
|
|
27881
27888
|
for (const row of workspaceRows) {
|
|
27882
27889
|
const workspaceId2 = checkedUuid(row.workspace_id, "workspace_id");
|
|
27883
27890
|
const archivedAt = checkedNullableTimestamp(
|
|
27884
27891
|
row.archived_at,
|
|
27885
27892
|
"archived_at"
|
|
27886
27893
|
);
|
|
27887
|
-
|
|
27894
|
+
if (archivedAt !== null) continue;
|
|
27895
|
+
const role = roles.get(workspaceId2);
|
|
27896
|
+
if (!role) {
|
|
27897
|
+
throw new Error(
|
|
27898
|
+
"workspace read omitted the current user's live membership"
|
|
27899
|
+
);
|
|
27900
|
+
}
|
|
27901
|
+
result.push({
|
|
27902
|
+
workspace_id: workspaceId2,
|
|
27888
27903
|
name: sanitizeDisplayLabel(
|
|
27889
27904
|
checkedString(row.name, "workspace name"),
|
|
27890
27905
|
"Unnamed workspace"
|
|
27891
27906
|
),
|
|
27892
|
-
|
|
27907
|
+
role,
|
|
27908
|
+
archived: false
|
|
27893
27909
|
});
|
|
27894
27910
|
}
|
|
27895
|
-
const result = membershipRows.map((row) => {
|
|
27896
|
-
const workspaceId2 = checkedUuid(row.workspace_id, "workspace_id");
|
|
27897
|
-
const project = names.get(workspaceId2);
|
|
27898
|
-
if (!project) {
|
|
27899
|
-
throw new Error(
|
|
27900
|
-
"workspace read omitted a workspace for a live membership"
|
|
27901
|
-
);
|
|
27902
|
-
}
|
|
27903
|
-
return {
|
|
27904
|
-
workspace_id: workspaceId2,
|
|
27905
|
-
name: project.name,
|
|
27906
|
-
role: checkedRole(row.role),
|
|
27907
|
-
archived: project.archived
|
|
27908
|
-
};
|
|
27909
|
-
});
|
|
27910
27911
|
return sortWorkspaces(result);
|
|
27911
27912
|
},
|
|
27912
27913
|
async status(session, workspaceId2) {
|
|
@@ -27961,6 +27962,9 @@ function cloudWorkspaceDirectory(target2, fetcher = fetch) {
|
|
|
27961
27962
|
you: userId === session.userId
|
|
27962
27963
|
};
|
|
27963
27964
|
});
|
|
27965
|
+
if (!members.some((member) => member.you)) {
|
|
27966
|
+
throw new WorkspaceUnavailableError();
|
|
27967
|
+
}
|
|
27964
27968
|
const memberNames = new Map(
|
|
27965
27969
|
members.map((member) => [member.user_id, member.name])
|
|
27966
27970
|
);
|
|
@@ -28086,6 +28090,32 @@ async function clearWorkspaceDefault(store2, userId, expectedWorkspaceId) {
|
|
|
28086
28090
|
return true;
|
|
28087
28091
|
});
|
|
28088
28092
|
}
|
|
28093
|
+
async function updateWorkspaceDefaultAfterClose(store2, userId, closedWorkspaceId, workspaces) {
|
|
28094
|
+
return await store2.withLock(async () => {
|
|
28095
|
+
const current = await store2.readProfile();
|
|
28096
|
+
if (current.userId !== userId || current.workspaceId !== closedWorkspaceId) {
|
|
28097
|
+
return {
|
|
28098
|
+
closedWasSelected: false,
|
|
28099
|
+
nextWorkspace: null,
|
|
28100
|
+
selectedWorkspaceId: current.userId === userId ? current.workspaceId : null
|
|
28101
|
+
};
|
|
28102
|
+
}
|
|
28103
|
+
const nextWorkspace = sortWorkspaces(workspaces).find(
|
|
28104
|
+
(workspace) => workspace.workspace_id !== closedWorkspaceId && !workspace.archived
|
|
28105
|
+
) ?? null;
|
|
28106
|
+
await store2.writeProfile({
|
|
28107
|
+
...current,
|
|
28108
|
+
workspaceId: nextWorkspace?.workspace_id ?? null,
|
|
28109
|
+
principalId: null,
|
|
28110
|
+
principalName: null
|
|
28111
|
+
});
|
|
28112
|
+
return {
|
|
28113
|
+
closedWasSelected: true,
|
|
28114
|
+
nextWorkspace,
|
|
28115
|
+
selectedWorkspaceId: nextWorkspace?.workspace_id ?? null
|
|
28116
|
+
};
|
|
28117
|
+
});
|
|
28118
|
+
}
|
|
28089
28119
|
function workspaceOverride(explicit, environmental) {
|
|
28090
28120
|
if (explicit !== void 0) {
|
|
28091
28121
|
if (!UUID_RE6.test(explicit)) {
|
|
@@ -28144,6 +28174,14 @@ async function resolveWorkspace(options) {
|
|
|
28144
28174
|
throw new WorkspaceResolutionError(workspaces);
|
|
28145
28175
|
}
|
|
28146
28176
|
async function selectWorkspace(selector, workspaces, store2, userId) {
|
|
28177
|
+
const selected = resolveWorkspaceSelector(selector, workspaces);
|
|
28178
|
+
if (selected.archived) {
|
|
28179
|
+
throw new WorkspaceUnavailableError(ARCHIVED_PROJECT_NOT_AVAILABLE);
|
|
28180
|
+
}
|
|
28181
|
+
await writeWorkspaceDefault(store2, userId, selected.workspace_id);
|
|
28182
|
+
return selected;
|
|
28183
|
+
}
|
|
28184
|
+
function resolveWorkspaceSelector(selector, workspaces) {
|
|
28147
28185
|
const sorted = sortWorkspaces(workspaces);
|
|
28148
28186
|
let selected;
|
|
28149
28187
|
if (UUID_RE6.test(selector)) {
|
|
@@ -28162,7 +28200,6 @@ async function selectWorkspace(selector, workspaces, store2, userId) {
|
|
|
28162
28200
|
selected = matches[0];
|
|
28163
28201
|
}
|
|
28164
28202
|
if (!selected) throw new WorkspaceUnavailableError();
|
|
28165
|
-
await writeWorkspaceDefault(store2, userId, selected.workspace_id);
|
|
28166
28203
|
return selected;
|
|
28167
28204
|
}
|
|
28168
28205
|
function holderLabel(holder) {
|
|
@@ -28181,13 +28218,8 @@ function relativeExpiry(expiry, now = Date.now()) {
|
|
|
28181
28218
|
const amount = relativeMagnitude(remaining);
|
|
28182
28219
|
return remaining >= 0 ? `expires in ${amount}` : `expired ${amount} ago`;
|
|
28183
28220
|
}
|
|
28184
|
-
var ARCHIVE_NOT_ENFORCED_CODE = "workspace_archive_not_enforced";
|
|
28185
|
-
var ARCHIVE_NOT_ENFORCED_MESSAGE = "Archiving a workspace does not restrict what members or their agents can do in it: an archived workspace stays selectable, and commands against it still succeed while your membership is live. Removing a workspace from this list means ending your membership, which this CLI cannot do \u2014 ask whoever runs the workspace.";
|
|
28186
28221
|
function archiveKnownGaps() {
|
|
28187
|
-
return [
|
|
28188
|
-
code: ARCHIVE_NOT_ENFORCED_CODE,
|
|
28189
|
-
message: ARCHIVE_NOT_ENFORCED_MESSAGE
|
|
28190
|
-
}];
|
|
28222
|
+
return [];
|
|
28191
28223
|
}
|
|
28192
28224
|
function renderWorkspaces(workspaces, currentWorkspaceId) {
|
|
28193
28225
|
if (workspaces.length === 0) {
|
|
@@ -28211,9 +28243,6 @@ function renderWorkspaces(workspaces, currentWorkspaceId) {
|
|
|
28211
28243
|
"No workspace is selected. Run cswarm use <full-id|exact-name>."
|
|
28212
28244
|
);
|
|
28213
28245
|
}
|
|
28214
|
-
if (workspaces.some((workspace) => workspace.archived)) {
|
|
28215
|
-
lines.push(ARCHIVE_NOT_ENFORCED_MESSAGE);
|
|
28216
|
-
}
|
|
28217
28246
|
return lines.join("\n");
|
|
28218
28247
|
}
|
|
28219
28248
|
function renderStatus(options) {
|
|
@@ -36933,8 +36962,8 @@ var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
|
|
|
36933
36962
|
AGENT_CREDENTIAL_MESSAGE_D088
|
|
36934
36963
|
];
|
|
36935
36964
|
function packageVersion() {
|
|
36936
|
-
if ("0.1.
|
|
36937
|
-
return "0.1.
|
|
36965
|
+
if ("0.1.23".length > 0) {
|
|
36966
|
+
return "0.1.23";
|
|
36938
36967
|
}
|
|
36939
36968
|
try {
|
|
36940
36969
|
const value = JSON.parse(
|
|
@@ -37072,6 +37101,7 @@ Usage:
|
|
|
37072
37101
|
cswarm invite [--url <url> --anon-key <key>] [--workspace-id <uuid>] --email <email>
|
|
37073
37102
|
cswarm invite revoke [--url <url> --anon-key <key>] [--workspace-id <uuid>] --invitation-id <uuid> [--json]
|
|
37074
37103
|
cswarm member remove <full-user-id|exact-name> --confirm <same-selector> [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--json]
|
|
37104
|
+
cswarm workspace close <full-id|exact-name> --confirm <same-selector> [--url <url> --anon-key <key>] [--json]
|
|
37075
37105
|
cswarm accept --link-stdin [--name <name>] [--no-browser] [--json]
|
|
37076
37106
|
cswarm accept <https://...#invite=...|cswarm://accept/...> [--name <name>] [--no-browser] [--json] # unsafe: shell history/process list
|
|
37077
37107
|
cswarm accept --invitation-token-stdin [--url <url> --anon-key <key>]
|
|
@@ -37100,6 +37130,7 @@ Credential selection for command/dogfood:
|
|
|
37100
37130
|
feedback command only, nothing persisted -- either form
|
|
37101
37131
|
listen start persists durable state, rotates -- needs expires_at
|
|
37102
37132
|
token revoke names what it revokes -- needs token_id
|
|
37133
|
+
workspace close is human-session-only; it never accepts an agent token
|
|
37103
37134
|
|
|
37104
37135
|
Found a bug or missing feature in cswarm itself? cswarm feedback sends it to the
|
|
37105
37136
|
deployment's operators \u2014 agents are encouraged to report friction they hit.
|
|
@@ -37108,6 +37139,8 @@ Signals (intention sharing) accept the same credential selection. Agent mode
|
|
|
37108
37139
|
never opens a browser or infers a human's saved workspace. Durations use a whole
|
|
37109
37140
|
number plus m, h, or d (for example 90m, 24h, or 7d) and are capped at 30d.
|
|
37110
37141
|
Place -- before signal text that itself begins with -- to stop option parsing.
|
|
37142
|
+
Signal text is at most 2000 characters and --about at most 500; a longer body is
|
|
37143
|
+
refused locally before any network call, so compose within the limit.
|
|
37111
37144
|
|
|
37112
37145
|
listen start --turn-budget bounds ONE worker prompt turn (default 10m): how long
|
|
37113
37146
|
the worker may think and use tools on a single message before the turn times out
|
|
@@ -37120,7 +37153,7 @@ TTL); a turn that lands just before a rotation can be clamped to the ~5m
|
|
|
37120
37153
|
renewal lead, and if it times out there, durable delivery retries it on the
|
|
37121
37154
|
fresh credential.
|
|
37122
37155
|
|
|
37123
|
-
Invite, legacy token accept, principal create/revoke, human token mint/revoke, link, and
|
|
37156
|
+
Invite, legacy token accept, principal create/revoke, human token mint/revoke, link, new, and workspace close require a
|
|
37124
37157
|
stored human login. Agent self-surrender of a token uses --agent-token-stdin and never takes the secret on argv. Invite-link accept signs in when needed, then accepts and
|
|
37125
37158
|
registers one principal. Invitation links, agent credentials, and capability links
|
|
37126
37159
|
appear only in fresh success responses.
|
|
@@ -37815,6 +37848,53 @@ async function runMember(args) {
|
|
|
37815
37848
|
`);
|
|
37816
37849
|
}
|
|
37817
37850
|
}
|
|
37851
|
+
async function runWorkspace(args) {
|
|
37852
|
+
args.assertShape([...TARGET_FLAGS, "confirm", "json"], 3);
|
|
37853
|
+
if (args.positionals[1] !== "close") {
|
|
37854
|
+
throw new UsageError(
|
|
37855
|
+
`unknown workspace command: ${args.positionals[1] ?? "(missing)"}`
|
|
37856
|
+
);
|
|
37857
|
+
}
|
|
37858
|
+
const selector = args.positionals[2];
|
|
37859
|
+
if (args.required("confirm") !== selector) {
|
|
37860
|
+
throw new Error(
|
|
37861
|
+
"--confirm must exactly repeat the workspace selector; no request was sent"
|
|
37862
|
+
);
|
|
37863
|
+
}
|
|
37864
|
+
const cloud = await target(args);
|
|
37865
|
+
const human = await humanCredential(args, cloud);
|
|
37866
|
+
const directory = cloudWorkspaceDirectory(cloud);
|
|
37867
|
+
const projects = await directory.list(human);
|
|
37868
|
+
const selected = resolveWorkspaceSelector(selector, projects);
|
|
37869
|
+
const response = (await sendConnectWithPending(
|
|
37870
|
+
new ThinCommandClient(cloud),
|
|
37871
|
+
human,
|
|
37872
|
+
selected.workspace_id,
|
|
37873
|
+
{ kind: "archive_workspace" }
|
|
37874
|
+
)).response;
|
|
37875
|
+
if (response.status !== "accepted") {
|
|
37876
|
+
throw new Error(
|
|
37877
|
+
`Workspace close was rejected: ${response.reason ?? "domain rejection"}. The workspace is still open.`
|
|
37878
|
+
);
|
|
37879
|
+
}
|
|
37880
|
+
const { closedWasSelected, nextWorkspace, selectedWorkspaceId } = await updateWorkspaceDefaultAfterClose(
|
|
37881
|
+
human.store,
|
|
37882
|
+
human.userId,
|
|
37883
|
+
selected.workspace_id,
|
|
37884
|
+
projects
|
|
37885
|
+
);
|
|
37886
|
+
const message = nextWorkspace ? `Closed workspace ${selected.name} (${selected.workspace_id}). It is hidden for everyone, and ${nextWorkspace.name} (${nextWorkspace.workspace_id}) is now selected.` : closedWasSelected ? `Closed workspace ${selected.name} (${selected.workspace_id}). It is hidden for everyone. No live workspace remains, so the selected workspace was cleared.` : `Closed workspace ${selected.name} (${selected.workspace_id}). It is hidden for everyone. Your selected workspace was not changed.`;
|
|
37887
|
+
const output = {
|
|
37888
|
+
message,
|
|
37889
|
+
status: response.status,
|
|
37890
|
+
workspace_id: selected.workspace_id,
|
|
37891
|
+
selected_workspace_id: selectedWorkspaceId,
|
|
37892
|
+
command_event_ids: response.event_ids
|
|
37893
|
+
};
|
|
37894
|
+
if (args.has("json")) printJson(output);
|
|
37895
|
+
else process.stdout.write(`${message}
|
|
37896
|
+
`);
|
|
37897
|
+
}
|
|
37818
37898
|
async function runLegacyAccept(args) {
|
|
37819
37899
|
const invitationToken = await invitationCredential(args);
|
|
37820
37900
|
const cloud = await target(args);
|
|
@@ -38507,8 +38587,10 @@ function resolveTurnBudgetOrDefer(configuredBudgetMs, credentialExpiresAt, nowMs
|
|
|
38507
38587
|
}
|
|
38508
38588
|
return clampTurnBudgetToCredential(configuredBudgetMs, credentialExpiresAt, nowMs);
|
|
38509
38589
|
}
|
|
38590
|
+
var SIGNAL_BODY_MAX = 2e3;
|
|
38591
|
+
var SIGNAL_ABOUT_MAX = 500;
|
|
38510
38592
|
function signalText(value, label) {
|
|
38511
|
-
const maximum = label === "body" ?
|
|
38593
|
+
const maximum = label === "body" ? SIGNAL_BODY_MAX : SIGNAL_ABOUT_MAX;
|
|
38512
38594
|
if (value.length < (label === "body" ? 1 : 0) || value.length > maximum) {
|
|
38513
38595
|
throw new Error(
|
|
38514
38596
|
`${label === "body" ? "signal text" : "--about"} must be ${label === "body" ? "1.." : "at most "}${maximum} characters`
|
|
@@ -38767,6 +38849,10 @@ Check whether you are about to do the same work.
|
|
|
38767
38849
|
`}`
|
|
38768
38850
|
);
|
|
38769
38851
|
}
|
|
38852
|
+
function replyRefusalHint(error) {
|
|
38853
|
+
if (!(error instanceof CommandHttpError) || error.status !== 403) return null;
|
|
38854
|
+
return "reply was refused (403). The most common cause is that the signal was not addressed to you \u2014 you cannot reply to your own ask; reply to the other party's signal, reach someone directly with cswarm ask --to <agent>, or post a channel-visible cswarm note. If you did receive that signal, the refusal is an authorization one instead: the credential may be revoked or expired, or it may not be a member of this workspace.";
|
|
38855
|
+
}
|
|
38770
38856
|
async function runReply(args) {
|
|
38771
38857
|
args.assertShape([
|
|
38772
38858
|
...TARGET_FLAGS,
|
|
@@ -38798,7 +38884,14 @@ async function runReply(args) {
|
|
|
38798
38884
|
about: null,
|
|
38799
38885
|
...untilMs2 === void 0 ? {} : { until_ms: untilMs2 }
|
|
38800
38886
|
};
|
|
38801
|
-
|
|
38887
|
+
let result;
|
|
38888
|
+
try {
|
|
38889
|
+
result = await postSignalCommand(cloud, credential, command2);
|
|
38890
|
+
} catch (error) {
|
|
38891
|
+
const hint = replyRefusalHint(error);
|
|
38892
|
+
if (hint !== null) throw new Error(hint);
|
|
38893
|
+
throw error;
|
|
38894
|
+
}
|
|
38802
38895
|
const signal = result.response.signal;
|
|
38803
38896
|
if (args.has("json")) {
|
|
38804
38897
|
printJson({
|
|
@@ -40355,6 +40448,10 @@ async function main() {
|
|
|
40355
40448
|
await runMember(args);
|
|
40356
40449
|
return;
|
|
40357
40450
|
}
|
|
40451
|
+
if (verb === "workspace") {
|
|
40452
|
+
await runWorkspace(args);
|
|
40453
|
+
return;
|
|
40454
|
+
}
|
|
40358
40455
|
if (verb === "target") {
|
|
40359
40456
|
await runTarget(args);
|
|
40360
40457
|
return;
|
|
@@ -40500,6 +40597,7 @@ ${usage()}
|
|
|
40500
40597
|
listenerPermissionMode,
|
|
40501
40598
|
listenerStatusJson,
|
|
40502
40599
|
renderRoster,
|
|
40600
|
+
replyRefusalHint,
|
|
40503
40601
|
resolveDetachedClaudeExecutable,
|
|
40504
40602
|
resolveDetachedCodexExecutable,
|
|
40505
40603
|
resolveTurnBudgetOrDefer
|