@songsid/agend 2.2.0-beta.9 → 2.2.1
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 +40 -24
- package/README.zh-TW.md +40 -24
- package/dist/agent-endpoint.js +3 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.js +7 -1
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.d.ts +3 -1
- package/dist/auth-api.js +15 -1
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/antigravity.d.ts +33 -0
- package/dist/backend/antigravity.js +126 -18
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +3 -0
- package/dist/backend/claude-code.js +9 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-metadata.d.ts +33 -0
- package/dist/backend/codex-metadata.js +122 -18
- package/dist/backend/codex-metadata.js.map +1 -1
- package/dist/backend/codex.d.ts +3 -0
- package/dist/backend/codex.js +17 -1
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/effort-metadata.d.ts +37 -1
- package/dist/backend/effort-metadata.js +86 -15
- package/dist/backend/effort-metadata.js.map +1 -1
- package/dist/backend/grok.d.ts +3 -0
- package/dist/backend/grok.js +9 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro.d.ts +3 -1
- package/dist/backend/kiro.js +7 -3
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/launch-effort.d.ts +61 -0
- package/dist/backend/launch-effort.js +170 -0
- package/dist/backend/launch-effort.js.map +1 -0
- package/dist/backend/types.d.ts +24 -0
- package/dist/backend/types.js +12 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/backend-command.d.ts +91 -0
- package/dist/backend-command.js +122 -0
- package/dist/backend-command.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +12 -0
- package/dist/channel/adapters/discord.js +49 -2
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +18 -0
- package/dist/channel/adapters/telegram.js +24 -3
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.d.ts +2 -0
- package/dist/channel/tool-router.js +1 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/types.d.ts +16 -0
- package/dist/cli.js +124 -24
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +2 -2
- package/dist/command-table.js +5 -2
- package/dist/command-table.js.map +1 -1
- package/dist/compact-watch.d.ts +86 -0
- package/dist/compact-watch.js +288 -0
- package/dist/compact-watch.js.map +1 -0
- package/dist/config-validator.js +39 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/daemon.d.ts +11 -0
- package/dist/daemon.js +179 -18
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +8 -1
- package/dist/delivery-outbox.js +6 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/doctor.js +7 -0
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-context.d.ts +7 -0
- package/dist/fleet-manager.d.ts +158 -9
- package/dist/fleet-manager.js +827 -118
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +4 -3
- package/dist/forged-envelope-scan.js +4 -3
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +4 -1
- package/dist/install-lock.d.ts +18 -1
- package/dist/install-lock.js +30 -3
- package/dist/install-lock.js.map +1 -1
- package/dist/instance-avatar.d.ts +5 -4
- package/dist/instance-avatar.js +12 -8
- package/dist/instance-avatar.js.map +1 -1
- package/dist/instructions.js +2 -2
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-compact-pane.d.ts +38 -0
- package/dist/kiro-compact-pane.js +57 -0
- package/dist/kiro-compact-pane.js.map +1 -0
- package/dist/launchd-handoff.d.ts +43 -0
- package/dist/launchd-handoff.js +56 -0
- package/dist/launchd-handoff.js.map +1 -0
- package/dist/locale.js +202 -30
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +10 -2
- package/dist/log-service.js.map +1 -1
- package/dist/login-shell.d.ts +21 -0
- package/dist/login-shell.js +98 -0
- package/dist/login-shell.js.map +1 -0
- package/dist/outbound-handlers.d.ts +27 -0
- package/dist/outbound-handlers.js +120 -36
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +12 -0
- package/dist/outbound-schemas.js +15 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/provider-probe.d.ts +29 -0
- package/dist/provider-probe.js +198 -2
- package/dist/provider-probe.js.map +1 -1
- package/dist/public-web-gateway.d.ts +2 -0
- package/dist/public-web-gateway.js +11 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +1 -1
- package/dist/quickstart-api.js +8 -6
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +12 -0
- package/dist/quickstart.js +36 -6
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +86 -5
- package/dist/reply-buttons-controller.js +271 -7
- package/dist/reply-buttons-controller.js.map +1 -1
- package/dist/reply-buttons.d.ts +48 -3
- package/dist/reply-buttons.js +105 -10
- package/dist/reply-buttons.js.map +1 -1
- package/dist/reply-polls.d.ts +85 -0
- package/dist/reply-polls.js +154 -0
- package/dist/reply-polls.js.map +1 -0
- package/dist/restart-guard.d.ts +6 -3
- package/dist/restart-guard.js +6 -3
- package/dist/restart-guard.js.map +1 -1
- package/dist/restart-progress.d.ts +0 -2
- package/dist/restart-progress.js +0 -2
- package/dist/restart-progress.js.map +1 -1
- package/dist/sd-notify.d.ts +22 -1
- package/dist/sd-notify.js +63 -10
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-activation.d.ts +15 -7
- package/dist/service-activation.js +42 -26
- package/dist/service-activation.js.map +1 -1
- package/dist/service-installer.d.ts +24 -0
- package/dist/service-installer.js +49 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +11 -0
- package/dist/service-plan.js +23 -0
- package/dist/service-plan.js.map +1 -1
- package/dist/systemd-peer-bus.d.ts +95 -0
- package/dist/systemd-peer-bus.js +430 -0
- package/dist/systemd-peer-bus.js.map +1 -0
- package/dist/systemd-runtime.d.ts +27 -1
- package/dist/systemd-runtime.js +69 -7
- package/dist/systemd-runtime.js.map +1 -1
- package/dist/tool-permissions.js +3 -3
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +68 -2
- package/dist/topic-commands.js +141 -27
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +7 -2
- package/dist/transcript-jsonl.js +13 -7
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-sources.js +6 -1
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/dist/ui/chat-commands.js +1 -0
- package/dist/ui/chat-render.js +55 -10
- package/dist/ui/chat-store.js +69 -5
- package/dist/ui/chat-strings.js +28 -16
- package/dist/ui/chat-thread.js +132 -14
- package/dist/ui/chat-tour.js +17 -14
- package/dist/ui/panel-chat.js +16 -10
- package/dist/ui/panel-fleet.js +15 -2
- package/dist/ui/panel-log.js +4 -4
- package/dist/ui/panel-needs.js +10 -7
- package/dist/ui/panel-settings.js +58 -7
- package/dist/ui/settings-dialogs.js +11 -6
- package/dist/ui/settings-model.js +3 -1
- package/dist/ui/settings-strings.js +24 -10
- package/dist/ui/settings-token.js +7 -0
- package/dist/ui/settings-wizard.js +5 -3
- package/dist/ui/shared/app-i18n.js +1 -1
- package/dist/ui/shared/app-stream.js +4 -1
- package/dist/ui/shared/app.css +52 -10
- package/dist/ui/shared/header-tools.js +34 -14
- package/dist/ui/shared/instance-switch.js +5 -2
- package/dist/ui/shared/panel-view.js +15 -4
- package/dist/ui/shared/signin.js +15 -9
- package/dist/ui/shared/ui-icons.js +1 -0
- package/dist/ui/shared/view-strings.js +10 -2
- package/dist/ui/signin.html +8 -3
- package/dist/update-check.d.ts +31 -0
- package/dist/update-check.js +47 -0
- package/dist/update-check.js.map +1 -1
- package/dist/update-launch.d.ts +48 -1
- package/dist/update-launch.js +159 -5
- package/dist/update-launch.js.map +1 -1
- package/dist/usage/providers.d.ts +28 -8
- package/dist/usage/providers.js +96 -41
- package/dist/usage/providers.js.map +1 -1
- package/dist/view-api.js +26 -9
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +44 -2
- package/dist/web-api.js +265 -57
- package/dist/web-api.js.map +1 -1
- package/dist/web-chat-history.d.ts +26 -1
- package/dist/web-chat-history.js +47 -8
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-commands.d.ts +39 -3
- package/dist/web-commands.js +22 -5
- package/dist/web-commands.js.map +1 -1
- package/dist/web-login.d.ts +14 -0
- package/dist/web-login.js +4 -2
- package/dist/web-login.js.map +1 -1
- package/dist/web-prefs.d.ts +18 -0
- package/dist/web-prefs.js +36 -4
- package/dist/web-prefs.js.map +1 -1
- package/dist/web-profile.d.ts +32 -0
- package/dist/web-profile.js +132 -0
- package/dist/web-profile.js.map +1 -0
- package/dist/web-session.d.ts +14 -0
- package/dist/web-session.js +10 -0
- package/dist/web-session.js.map +1 -1
- package/dist/web-upload.d.ts +119 -4
- package/dist/web-upload.js +252 -39
- package/dist/web-upload.js.map +1 -1
- package/launcher/install-admission.cjs +61 -6
- package/package.json +3 -3
package/dist/tool-permissions.js
CHANGED
|
@@ -29,7 +29,7 @@ import { TOOLS } from "./channel/mcp-tools.js";
|
|
|
29
29
|
/** Everything an agent that is doing the work needs, and nothing that runs the fleet. */
|
|
30
30
|
const WORKER = [
|
|
31
31
|
// Talking to people.
|
|
32
|
-
"reply", "react", "edit_message", "download_attachment",
|
|
32
|
+
"reply", "react", "edit_message", "download_attachment", "close_poll",
|
|
33
33
|
// Talking to peers. `report_result` is why `standard` was never usable as a
|
|
34
34
|
// worker profile: without it the delegate → work → report protocol has no
|
|
35
35
|
// last step. `delegate_task` is here because it creates nothing and needs a
|
|
@@ -78,7 +78,7 @@ export const TOOL_PROFILES = {
|
|
|
78
78
|
worker: WORKER,
|
|
79
79
|
coordinator: [...WORKER, ...ORCHESTRATION],
|
|
80
80
|
general: [
|
|
81
|
-
"reply", "react", "edit_message", "download_attachment",
|
|
81
|
+
"reply", "react", "edit_message", "download_attachment", "close_poll",
|
|
82
82
|
"list_teams", "list_instances", "describe_instance", "get_fleet_status", "get_usage", "get_effort", "list_models",
|
|
83
83
|
// Read-only: what each kiro instance runs on, for explaining a kiro incompatibility.
|
|
84
84
|
"kiro_engine_status",
|
|
@@ -92,7 +92,7 @@ export const TOOL_PROFILES = {
|
|
|
92
92
|
"list_stickers", "preview_stickers",
|
|
93
93
|
],
|
|
94
94
|
standard: [
|
|
95
|
-
"reply", "react", "edit_message",
|
|
95
|
+
"reply", "react", "edit_message", "close_poll",
|
|
96
96
|
"send_to_instance", "broadcast", "list_instances", "describe_instance", "delivery_status",
|
|
97
97
|
"list_decisions", "post_decision", "task", "set_display_name", "set_description", "list_emojis", "set_persona_emoji", "preview_emojis",
|
|
98
98
|
"list_stickers", "preview_stickers",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../src/tool-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAI/C,yFAAyF;AACzF,MAAM,MAAM,GAAsB;IAChC,qBAAqB;IACrB,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB;
|
|
1
|
+
{"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../src/tool-permissions.ts"],"names":[],"mappings":"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"}
|
package/dist/topic-commands.d.ts
CHANGED
|
@@ -70,6 +70,45 @@ export declare function assignDisplayLabels(entries: {
|
|
|
70
70
|
}[]): Map<string, string>;
|
|
71
71
|
/** Allowed filename for /save and /load (no path separators, no shell/inject chars). */
|
|
72
72
|
export declare const SAVE_FILENAME_RE: RegExp;
|
|
73
|
+
/**
|
|
74
|
+
* #1809: resolve a display label (as shown by `agend ls`) back to a real instance name.
|
|
75
|
+
* Returns the real name on a unique match, `null` when the query does not match any label,
|
|
76
|
+
* or `{ ambiguous: true, realNames }` when two labels are identical under case-folding
|
|
77
|
+
* (e.g. display_names "Prism" and "prism" both fold to "prism").
|
|
78
|
+
* Always case-insensitive. Real names are NOT resolved here — callers must try real names first.
|
|
79
|
+
*/
|
|
80
|
+
export declare function resolveByLabel(query: string, entries: {
|
|
81
|
+
name: string;
|
|
82
|
+
displayName?: string | null;
|
|
83
|
+
}[]): string | null | {
|
|
84
|
+
ambiguous: true;
|
|
85
|
+
realNames: string[];
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* #1809: full label/name resolution pipeline without process.exit or readline — suitable for
|
|
89
|
+
* unit testing and for callers that want to decide what to do on each outcome.
|
|
90
|
+
*
|
|
91
|
+
* Resolution order:
|
|
92
|
+
* 1. Exact match on real name (case-insensitive) — always wins.
|
|
93
|
+
* 2. Exact match on the display label `agend ls` shows (via `resolveByLabel`).
|
|
94
|
+
* 3. No match → `{ kind: "none" }`.
|
|
95
|
+
*
|
|
96
|
+
* Returns `{ kind: "name", realName }` on success,
|
|
97
|
+
* `{ kind: "ambiguous", realNames }` when two labels are case-identical,
|
|
98
|
+
* or `{ kind: "none" }` when nothing matched.
|
|
99
|
+
*/
|
|
100
|
+
export declare function resolveName(query: string, entries: {
|
|
101
|
+
name: string;
|
|
102
|
+
displayName?: string | null;
|
|
103
|
+
}[]): {
|
|
104
|
+
kind: "name";
|
|
105
|
+
realName: string;
|
|
106
|
+
} | {
|
|
107
|
+
kind: "ambiguous";
|
|
108
|
+
realNames: string[];
|
|
109
|
+
} | {
|
|
110
|
+
kind: "none";
|
|
111
|
+
};
|
|
73
112
|
/** Backends with a native side-question command that does not steer the active turn. */
|
|
74
113
|
export declare const BTW_SUPPORTED_BACKENDS: Set<string>;
|
|
75
114
|
/**
|
|
@@ -86,7 +125,14 @@ export declare function parsePauseWakeCommand(text: string): {
|
|
|
86
125
|
action: "pause" | "wake";
|
|
87
126
|
instance?: string;
|
|
88
127
|
} | null;
|
|
89
|
-
|
|
128
|
+
/**
|
|
129
|
+
* Board 0340ec89: agy's own `/compact` summarizes the conversation (verified on 1.3.6: "Conversation compacted · 5 steps
|
|
130
|
+
* summarized", tests/fixtures/agy-1.3.6-compact.pane.txt). AgEnD used to send `/clear` for an agy compact, which wiped
|
|
131
|
+
* the conversation instead. An agy known to be older than the version `/compact` was verified on is refused (null),
|
|
132
|
+
* never cleared; an agy whose version is not known yet gets `/compact` (a version without it ignores the line).
|
|
133
|
+
*/
|
|
134
|
+
export declare const AGY_COMPACT_MIN_VERSION = "1.3.6";
|
|
135
|
+
export declare function compactCommandForBackend(backend: string, version?: string | null): string | null;
|
|
90
136
|
/**
|
|
91
137
|
* Backends whose `/compact` verifiably takes custom summarization instructions
|
|
92
138
|
* (#1145). Checked against the real CLIs, not assumed:
|
|
@@ -97,7 +143,7 @@ export declare function compactCommandForBackend(backend: string): string;
|
|
|
97
143
|
* compact into a prompt, so it must never be appended.
|
|
98
144
|
* - grok 1.0.46: the binary answers "/compact takes no arguments."
|
|
99
145
|
* - opencode 1.18: `/compact` calls session.summarize with no text.
|
|
100
|
-
* - kiro-cli: takes none (audit); antigravity
|
|
146
|
+
* - kiro-cli: takes none (audit); antigravity's own /compact (1.3.6+, board 0340ec89) takes none either.
|
|
101
147
|
* - muse 1.4.2: accepts the line (empty session: "nothing to summarize") but
|
|
102
148
|
* no use of the text is verifiable — unsupported until shown otherwise.
|
|
103
149
|
*/
|
|
@@ -179,6 +225,8 @@ export declare class TopicCommands {
|
|
|
179
225
|
* stretch, so the instance cannot be rebound to another bot between the check and the act. The refusal, if any.
|
|
180
226
|
*/
|
|
181
227
|
private tableRefusal;
|
|
228
|
+
/** Where the adapter's fleet-admin list is in fleet.yaml (the fleet's answer; a bare key without it). */
|
|
229
|
+
private adminListKey;
|
|
182
230
|
private sendRefusal;
|
|
183
231
|
private getReplyAdapter;
|
|
184
232
|
/**
|
|
@@ -194,6 +242,10 @@ export declare class TopicCommands {
|
|
|
194
242
|
private ownedCopy;
|
|
195
243
|
/** Parse and dispatch commands from the General topic */
|
|
196
244
|
handleGeneralCommand(msg: InboundMessage, instanceName?: string): Promise<boolean>;
|
|
245
|
+
/**
|
|
246
|
+
* General's action-first menu. The click owns private issuance; no URL or code exists in this copy.
|
|
247
|
+
*/
|
|
248
|
+
getDashboardMenuText(): string;
|
|
197
249
|
/**
|
|
198
250
|
* Pure, secret-free dashboard/menu copy. Issuance belongs to the private
|
|
199
251
|
* delivery action; rendering or previewing this text cannot retire a code.
|
|
@@ -240,6 +292,15 @@ export declare class TopicCommands {
|
|
|
240
292
|
private autoPauseLineFor;
|
|
241
293
|
/** Send the backend-appropriate compact command to an instance's tmux pane */
|
|
242
294
|
sendCompact(instanceName: string, instructions?: string): Promise<string>;
|
|
295
|
+
/**
|
|
296
|
+
* sendCompact, saying whether the command was handed to the daemon (the web chat follows a sent one to its end,
|
|
297
|
+
* board 003648ac). `notify` runs only when it is about to be handed over; its id rides along so the daemon says when
|
|
298
|
+
* the command reached the pane (`raw_paste_written`). A write the IPC refuses is not sent.
|
|
299
|
+
*/
|
|
300
|
+
compactInstance(instanceName: string, instructions?: string, notify?: () => string | null): {
|
|
301
|
+
sent: boolean;
|
|
302
|
+
text: string;
|
|
303
|
+
};
|
|
243
304
|
/** Whether the instance backend exposes a verified full-reset command. */
|
|
244
305
|
supportsClear(instanceName: string): boolean;
|
|
245
306
|
/**
|
|
@@ -261,6 +322,11 @@ export declare class TopicCommands {
|
|
|
261
322
|
sendBtw(instanceName: string, content: string, msg: Pick<InboundMessage, "chatId" | "messageId" | "username" | "userId" | "threadId" | "adapterId" | "source" | "humanOrigin" | "humanOriginalBody">): string;
|
|
262
323
|
/** Send the backend-appropriate full conversation reset through raw_paste. */
|
|
263
324
|
sendClear(instanceName: string): Promise<string>;
|
|
325
|
+
/** sendClear, saying whether the command was handed to the daemon (board 003648ac: the web chat's card then leaves). */
|
|
326
|
+
clearInstance(instanceName: string): {
|
|
327
|
+
sent: boolean;
|
|
328
|
+
text: string;
|
|
329
|
+
};
|
|
264
330
|
/** Send a backend-appropriate session-save command to a fleet-topic instance. */
|
|
265
331
|
sendSave(instanceName: string, filename: string): Promise<string>;
|
|
266
332
|
private handleRestartCommand;
|
package/dist/topic-commands.js
CHANGED
|
@@ -3,7 +3,7 @@ import { LOGIN_BACKEND_ALIASES } from "./login-flows.js";
|
|
|
3
3
|
import { measureSyncWork } from "./sync-work-attribution.js";
|
|
4
4
|
import { LOOPBACK_HOST_NAMES } from "./web-host-guard.js";
|
|
5
5
|
import { WEB_REMOTE_DOCS_URL } from "./upgrade-notices.js";
|
|
6
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
6
|
+
import { closeSync, readFileSync, existsSync } from "node:fs";
|
|
7
7
|
import { exec, execFileSync } from "node:child_process";
|
|
8
8
|
import { promisify } from "node:util";
|
|
9
9
|
import { join, basename } from "node:path";
|
|
@@ -21,10 +21,11 @@ import { runVisibilityCommand } from "./cross-instance-notice.js";
|
|
|
21
21
|
import { clampContextPercent, parseContextPercent, parseTokenContextRatio, } from "./context-percent.js";
|
|
22
22
|
import { isGeneralInstance } from "./general-instance.js";
|
|
23
23
|
import { instanceSupportsSteer } from "./steer-capability.js";
|
|
24
|
+
import { compareSemver } from "./update-check.js";
|
|
24
25
|
import { SYSINFO_BACKEND_IDS } from "./backend/types.js";
|
|
25
26
|
import { recordInternalRequest, withOrigin } from "./fleet-control-audit.js";
|
|
26
27
|
import { resolveInstalledAgend } from "./update-dispatch.js";
|
|
27
|
-
import { resolveUpdateLaunch, watchUpdateLaunch } from "./update-launch.js";
|
|
28
|
+
import { resolveUpdateLaunch, openUpdateLog, updateLogPath, watchUpdateLaunch } from "./update-launch.js";
|
|
28
29
|
import { selfCommand } from "./cli-entry.js";
|
|
29
30
|
export { parseContextPercent, parseTokenContextRatio } from "./context-percent.js";
|
|
30
31
|
/** Longest one setMyCommands call may take. */
|
|
@@ -160,6 +161,54 @@ function disambiguateLabel(name, explicit, base, used) {
|
|
|
160
161
|
}
|
|
161
162
|
/** Allowed filename for /save and /load (no path separators, no shell/inject chars). */
|
|
162
163
|
export const SAVE_FILENAME_RE = /^[\w.-]+$/;
|
|
164
|
+
/**
|
|
165
|
+
* #1809: resolve a display label (as shown by `agend ls`) back to a real instance name.
|
|
166
|
+
* Returns the real name on a unique match, `null` when the query does not match any label,
|
|
167
|
+
* or `{ ambiguous: true, realNames }` when two labels are identical under case-folding
|
|
168
|
+
* (e.g. display_names "Prism" and "prism" both fold to "prism").
|
|
169
|
+
* Always case-insensitive. Real names are NOT resolved here — callers must try real names first.
|
|
170
|
+
*/
|
|
171
|
+
export function resolveByLabel(query, entries) {
|
|
172
|
+
const labelMap = assignDisplayLabels(entries);
|
|
173
|
+
const q = query.toLowerCase();
|
|
174
|
+
const matches = [];
|
|
175
|
+
for (const [realName, label] of labelMap) {
|
|
176
|
+
if (label.toLowerCase() === q)
|
|
177
|
+
matches.push(realName);
|
|
178
|
+
}
|
|
179
|
+
if (matches.length === 0)
|
|
180
|
+
return null;
|
|
181
|
+
if (matches.length === 1)
|
|
182
|
+
return matches[0];
|
|
183
|
+
return { ambiguous: true, realNames: matches };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* #1809: full label/name resolution pipeline without process.exit or readline — suitable for
|
|
187
|
+
* unit testing and for callers that want to decide what to do on each outcome.
|
|
188
|
+
*
|
|
189
|
+
* Resolution order:
|
|
190
|
+
* 1. Exact match on real name (case-insensitive) — always wins.
|
|
191
|
+
* 2. Exact match on the display label `agend ls` shows (via `resolveByLabel`).
|
|
192
|
+
* 3. No match → `{ kind: "none" }`.
|
|
193
|
+
*
|
|
194
|
+
* Returns `{ kind: "name", realName }` on success,
|
|
195
|
+
* `{ kind: "ambiguous", realNames }` when two labels are case-identical,
|
|
196
|
+
* or `{ kind: "none" }` when nothing matched.
|
|
197
|
+
*/
|
|
198
|
+
export function resolveName(query, entries) {
|
|
199
|
+
// Step 1: exact real-name match wins.
|
|
200
|
+
const q = query.toLowerCase();
|
|
201
|
+
const exactReal = entries.find(e => e.name.toLowerCase() === q);
|
|
202
|
+
if (exactReal)
|
|
203
|
+
return { kind: "name", realName: exactReal.name };
|
|
204
|
+
// Step 2: label match.
|
|
205
|
+
const labelResult = resolveByLabel(query, entries);
|
|
206
|
+
if (labelResult === null)
|
|
207
|
+
return { kind: "none" };
|
|
208
|
+
if (typeof labelResult === "string")
|
|
209
|
+
return { kind: "name", realName: labelResult };
|
|
210
|
+
return { kind: "ambiguous", realNames: labelResult.realNames };
|
|
211
|
+
}
|
|
163
212
|
/** Backends with a native side-question command that does not steer the active turn. */
|
|
164
213
|
export const BTW_SUPPORTED_BACKENDS = new Set(["claude-code"]);
|
|
165
214
|
/**
|
|
@@ -241,10 +290,18 @@ function backendCliLines(versions) {
|
|
|
241
290
|
}),
|
|
242
291
|
];
|
|
243
292
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Board 0340ec89: agy's own `/compact` summarizes the conversation (verified on 1.3.6: "Conversation compacted · 5 steps
|
|
295
|
+
* summarized", tests/fixtures/agy-1.3.6-compact.pane.txt). AgEnD used to send `/clear` for an agy compact, which wiped
|
|
296
|
+
* the conversation instead. An agy known to be older than the version `/compact` was verified on is refused (null),
|
|
297
|
+
* never cleared; an agy whose version is not known yet gets `/compact` (a version without it ignores the line).
|
|
298
|
+
*/
|
|
299
|
+
export const AGY_COMPACT_MIN_VERSION = "1.3.6";
|
|
300
|
+
export function compactCommandForBackend(backend, version) {
|
|
301
|
+
if (backend !== "antigravity")
|
|
302
|
+
return "/compact";
|
|
303
|
+
const v = typeof version === "string" ? version.match(/\d+\.\d+\.\d+/)?.[0] : undefined;
|
|
304
|
+
return v && (compareSemver(v, AGY_COMPACT_MIN_VERSION) ?? 0) < 0 ? null : "/compact";
|
|
248
305
|
}
|
|
249
306
|
/**
|
|
250
307
|
* Backends whose `/compact` verifiably takes custom summarization instructions
|
|
@@ -256,7 +313,7 @@ export function compactCommandForBackend(backend) {
|
|
|
256
313
|
* compact into a prompt, so it must never be appended.
|
|
257
314
|
* - grok 1.0.46: the binary answers "/compact takes no arguments."
|
|
258
315
|
* - opencode 1.18: `/compact` calls session.summarize with no text.
|
|
259
|
-
* - kiro-cli: takes none (audit); antigravity
|
|
316
|
+
* - kiro-cli: takes none (audit); antigravity's own /compact (1.3.6+, board 0340ec89) takes none either.
|
|
260
317
|
* - muse 1.4.2: accepts the line (empty session: "nothing to summarize") but
|
|
261
318
|
* no use of the text is verifiable — unsupported until shown otherwise.
|
|
262
319
|
*/
|
|
@@ -447,6 +504,7 @@ const INSTANCE_FORMS = [
|
|
|
447
504
|
["collab", bare("collab")],
|
|
448
505
|
["effort", withArgs("effort")],
|
|
449
506
|
["model", withArgs("model")],
|
|
507
|
+
["backend", withArgs("backend")],
|
|
450
508
|
["compact", text => parseCompactCommand(text) !== null],
|
|
451
509
|
["steer", withArgs("steer")],
|
|
452
510
|
["btw", withArgs("btw")],
|
|
@@ -489,8 +547,15 @@ export class TopicCommands {
|
|
|
489
547
|
}, "telegram");
|
|
490
548
|
if (decision.allow || "passthrough" in decision)
|
|
491
549
|
return null;
|
|
550
|
+
// A command off for want of fleet admins names where they go (`{0}` in its disabled reply).
|
|
551
|
+
if (decision.reply === spec.disabled)
|
|
552
|
+
return [...decision.reply, this.adminListKey(msg.adapterId)];
|
|
492
553
|
return decision.reply;
|
|
493
554
|
}
|
|
555
|
+
/** Where the adapter's fleet-admin list is in fleet.yaml (the fleet's answer; a bare key without it). */
|
|
556
|
+
adminListKey(adapterId) {
|
|
557
|
+
return this.ctx.adminListKey?.(adapterId) ?? "access.allowed_users";
|
|
558
|
+
}
|
|
494
559
|
async sendRefusal(msg, [key, ...args]) {
|
|
495
560
|
const adapter = this.getReplyAdapter(msg);
|
|
496
561
|
if (adapter)
|
|
@@ -596,6 +661,13 @@ export class TopicCommands {
|
|
|
596
661
|
}
|
|
597
662
|
return false;
|
|
598
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* General's action-first menu. The click owns private issuance; no URL or code exists in this copy.
|
|
666
|
+
*/
|
|
667
|
+
getDashboardMenuText() {
|
|
668
|
+
const access = this.ctx.getDashboardAccess?.();
|
|
669
|
+
return access?.ready && access.token ? t("dashboard.menu_instruction") : t("dashboard.starting");
|
|
670
|
+
}
|
|
599
671
|
/**
|
|
600
672
|
* Pure, secret-free dashboard/menu copy. Issuance belongs to the private
|
|
601
673
|
* delivery action; rendering or previewing this text cannot retire a code.
|
|
@@ -633,7 +705,7 @@ export class TopicCommands {
|
|
|
633
705
|
const threadId = msg.threadId;
|
|
634
706
|
// The caller's own adapter decides, and an empty list means the command is off for everyone.
|
|
635
707
|
if (!this.ctx.hasFleetAdmins(msg.adapterId)) {
|
|
636
|
-
await adapter.sendText(chatId, t("dashboard.disabled"), { threadId });
|
|
708
|
+
await adapter.sendText(chatId, t("dashboard.disabled", this.adminListKey(msg.adapterId)), { threadId });
|
|
637
709
|
return;
|
|
638
710
|
}
|
|
639
711
|
if (!this.ctx.isFleetAdmin(msg.userId, msg.adapterId)) {
|
|
@@ -770,6 +842,23 @@ export class TopicCommands {
|
|
|
770
842
|
}
|
|
771
843
|
return true;
|
|
772
844
|
}
|
|
845
|
+
if (command === "backend") {
|
|
846
|
+
const adapter = this.getReplyAdapter(msg);
|
|
847
|
+
if (!adapter)
|
|
848
|
+
return false;
|
|
849
|
+
// #1806: the same gate as /model.
|
|
850
|
+
if (!this.ctx.isFleetAdmin(msg.userId, msg.adapterId)) {
|
|
851
|
+
await adapter.sendText(msg.chatId, t("permission.denied"), { threadId: msg.threadId });
|
|
852
|
+
return true;
|
|
853
|
+
}
|
|
854
|
+
if (this.ctx.runBackendCommand) {
|
|
855
|
+
await this.ctx.runBackendCommand(instanceName, text, msg.userId, msg.threadId ?? msg.chatId, adapter, msg.chatId, msg.threadId, msg.adapterId);
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
await adapter.sendText(msg.chatId, t("backend.usage"), { threadId: msg.threadId });
|
|
859
|
+
}
|
|
860
|
+
return true;
|
|
861
|
+
}
|
|
773
862
|
if (command === "compact") {
|
|
774
863
|
const compact = parseCompactCommand(text);
|
|
775
864
|
const adapter = this.getReplyAdapter(msg);
|
|
@@ -990,6 +1079,14 @@ export class TopicCommands {
|
|
|
990
1079
|
}
|
|
991
1080
|
/** Send the backend-appropriate compact command to an instance's tmux pane */
|
|
992
1081
|
async sendCompact(instanceName, instructions) {
|
|
1082
|
+
return this.compactInstance(instanceName, instructions).text;
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* sendCompact, saying whether the command was handed to the daemon (the web chat follows a sent one to its end,
|
|
1086
|
+
* board 003648ac). `notify` runs only when it is about to be handed over; its id rides along so the daemon says when
|
|
1087
|
+
* the command reached the pane (`raw_paste_written`). A write the IPC refuses is not sent.
|
|
1088
|
+
*/
|
|
1089
|
+
compactInstance(instanceName, instructions, notify) {
|
|
993
1090
|
const ipc = this.ctx.instanceIpcClients.get(instanceName);
|
|
994
1091
|
if (ipc?.connected) {
|
|
995
1092
|
const classicBackend = this.ctx.classicChannels?.getChannelIdByInstance(instanceName)
|
|
@@ -998,26 +1095,34 @@ export class TopicCommands {
|
|
|
998
1095
|
const backend = this.ctx.fleetConfig?.instances[instanceName]?.backend
|
|
999
1096
|
?? classicBackend
|
|
1000
1097
|
?? this.ctx.fleetConfig?.defaults?.backend ?? "claude-code";
|
|
1001
|
-
const
|
|
1098
|
+
const agyVersion = backend === "antigravity" ? this.ctx.getBackendCliVersionSnapshot?.()?.antigravity?.version ?? null : null;
|
|
1099
|
+
const base = compactCommandForBackend(backend, agyVersion);
|
|
1100
|
+
if (base === null)
|
|
1101
|
+
return { sent: false, text: t("compact.unsupported_version", backend, agyVersion ?? "?", AGY_COMPACT_MIN_VERSION) };
|
|
1002
1102
|
const custom = normalizeCompactInstructions(instructions);
|
|
1003
1103
|
if (custom.length > COMPACT_INSTRUCTIONS_MAX) {
|
|
1004
1104
|
// Refuse rather than cut: a truncated instruction is a different instruction.
|
|
1005
|
-
return t("compact.instructions_too_long", String(COMPACT_INSTRUCTIONS_MAX));
|
|
1105
|
+
return { sent: false, text: t("compact.instructions_too_long", String(COMPACT_INSTRUCTIONS_MAX)) };
|
|
1006
1106
|
}
|
|
1107
|
+
const id = notify?.() ?? null;
|
|
1108
|
+
const paste = (content) => ipc.send({ type: "raw_paste", content, ...(id ? { notify_written: id } : {}) }) !== false;
|
|
1007
1109
|
if (!custom) {
|
|
1008
|
-
|
|
1009
|
-
|
|
1110
|
+
if (!paste(base))
|
|
1111
|
+
return { sent: false, text: t("compact.not_connected") };
|
|
1112
|
+
return { sent: true, text: t("compact.sent", base) };
|
|
1010
1113
|
}
|
|
1011
1114
|
if (backendSupportsCompactInstructions(backend)) {
|
|
1012
|
-
|
|
1013
|
-
|
|
1115
|
+
if (!paste(`${base} ${custom}`))
|
|
1116
|
+
return { sent: false, text: t("compact.not_connected") };
|
|
1117
|
+
return { sent: true, text: t("compact.sent_with_instructions", base) };
|
|
1014
1118
|
}
|
|
1015
1119
|
// Compact as asked, without the text, and say so — never send it (codex
|
|
1016
1120
|
// would take it for a chat message) and never drop it unannounced.
|
|
1017
|
-
|
|
1018
|
-
|
|
1121
|
+
if (!paste(base))
|
|
1122
|
+
return { sent: false, text: t("compact.not_connected") };
|
|
1123
|
+
return { sent: true, text: `${t("compact.sent", base)}\n${t("compact.instructions_ignored", backend)}` };
|
|
1019
1124
|
}
|
|
1020
|
-
return t("compact.not_connected");
|
|
1125
|
+
return { sent: false, text: t("compact.not_connected") };
|
|
1021
1126
|
}
|
|
1022
1127
|
/** Whether the instance backend exposes a verified full-reset command. */
|
|
1023
1128
|
supportsClear(instanceName) {
|
|
@@ -1099,20 +1204,24 @@ export class TopicCommands {
|
|
|
1099
1204
|
}
|
|
1100
1205
|
/** Send the backend-appropriate full conversation reset through raw_paste. */
|
|
1101
1206
|
async sendClear(instanceName) {
|
|
1207
|
+
return this.clearInstance(instanceName).text;
|
|
1208
|
+
}
|
|
1209
|
+
/** sendClear, saying whether the command was handed to the daemon (board 003648ac: the web chat's card then leaves). */
|
|
1210
|
+
clearInstance(instanceName) {
|
|
1102
1211
|
const backend = this.effectiveBackend(instanceName);
|
|
1103
1212
|
const cmd = clearCommandForBackend(backend);
|
|
1104
1213
|
if (!cmd)
|
|
1105
|
-
return t("clear.unsupported");
|
|
1214
|
+
return { sent: false, text: t("clear.unsupported") };
|
|
1106
1215
|
const ipc = this.ctx.instanceIpcClients.get(instanceName);
|
|
1107
1216
|
if (ipc?.connected) {
|
|
1108
|
-
ipc.send({
|
|
1217
|
+
const sent = ipc.send({
|
|
1109
1218
|
type: "raw_paste",
|
|
1110
1219
|
content: cmd,
|
|
1111
1220
|
...(backend === "kiro-cli" ? { confirm_clear: true } : {}),
|
|
1112
|
-
});
|
|
1113
|
-
return t("clear.sent", cmd);
|
|
1221
|
+
}) !== false;
|
|
1222
|
+
return sent ? { sent: true, text: t("clear.sent", cmd) } : { sent: false, text: t("clear.not_connected") };
|
|
1114
1223
|
}
|
|
1115
|
-
return t("clear.not_connected");
|
|
1224
|
+
return { sent: false, text: t("clear.not_connected") };
|
|
1116
1225
|
}
|
|
1117
1226
|
/** Send a backend-appropriate session-save command to a fleet-topic instance. */
|
|
1118
1227
|
async sendSave(instanceName, filename) {
|
|
@@ -1498,7 +1607,7 @@ export class TopicCommands {
|
|
|
1498
1607
|
const threadId = msg.threadId;
|
|
1499
1608
|
// Access control — only fleet admins of THIS adapter can trigger an update; empty = disabled
|
|
1500
1609
|
if (!this.ctx.hasFleetAdmins(msg.adapterId)) {
|
|
1501
|
-
await adapter.sendText(chatId, t("update.disabled"), { threadId });
|
|
1610
|
+
await adapter.sendText(chatId, t("update.disabled", this.adminListKey(msg.adapterId)), { threadId });
|
|
1502
1611
|
return;
|
|
1503
1612
|
}
|
|
1504
1613
|
if (!this.ctx.isFleetAdmin(msg.userId, msg.adapterId)) {
|
|
@@ -1511,7 +1620,7 @@ export class TopicCommands {
|
|
|
1511
1620
|
// agend, verified by identity, by absolute path — or a refusal, never whatever `agend` is first on PATH.
|
|
1512
1621
|
const installed = await resolveInstalledAgend();
|
|
1513
1622
|
if (!installed.ok) {
|
|
1514
|
-
this.ctx.failUpdateProgress?.(
|
|
1623
|
+
this.ctx.failUpdateProgress?.(`${t("update.failure.shell")} ${t("update.failure.installed", installed.reason)}`);
|
|
1515
1624
|
return;
|
|
1516
1625
|
}
|
|
1517
1626
|
const { spawn } = await import("node:child_process");
|
|
@@ -1519,17 +1628,22 @@ export class TopicCommands {
|
|
|
1519
1628
|
recordInternalRequest(this.ctx.dataDir, "update", origin);
|
|
1520
1629
|
const launch = await resolveUpdateLaunch(installed.agend);
|
|
1521
1630
|
if (!launch.ok) {
|
|
1522
|
-
this.ctx.failUpdateProgress?.(
|
|
1631
|
+
this.ctx.failUpdateProgress?.(`${t("update.failure.shell")} ${t("update.failure.independent", launch.reason)}`);
|
|
1523
1632
|
return;
|
|
1524
1633
|
}
|
|
1525
1634
|
if (!this.ctx.hasFleetAdmins(msg.adapterId) || !this.ctx.isFleetAdmin(msg.userId, msg.adapterId) || this.ctx.isFleetStopping()) {
|
|
1526
1635
|
this.ctx.failUpdateProgress?.(t("not_authorized"));
|
|
1527
1636
|
return;
|
|
1528
1637
|
}
|
|
1638
|
+
const logPath = updateLogPath(this.ctx.dataDir);
|
|
1639
|
+
const ts = new Date().toISOString();
|
|
1640
|
+
const logFd = openUpdateLog(logPath, `--- /update ${ts} ---`);
|
|
1529
1641
|
const child = spawn(launch.command, launch.args, {
|
|
1530
|
-
detached: true, stdio: "ignore", env: withOrigin(origin),
|
|
1642
|
+
detached: true, stdio: ["ignore", logFd ? logFd.fd : "ignore", logFd ? logFd.fd : "ignore"], env: withOrigin(origin),
|
|
1531
1643
|
});
|
|
1532
|
-
|
|
1644
|
+
if (logFd)
|
|
1645
|
+
closeSync(logFd.fd);
|
|
1646
|
+
watchUpdateLaunch(child, message => this.ctx.failUpdateProgress?.(message), logFd ? logPath : undefined, logFd?.offset, installed.agend);
|
|
1533
1647
|
child.unref();
|
|
1534
1648
|
}
|
|
1535
1649
|
/** #1302: `/visibility [full|summary|hidden]` in the General topic. */
|