@songsid/agend 2.1.4-beta.26 → 2.1.4-beta.28
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/README.zh-TW.md +1 -1
- package/dist/backend/antigravity.d.ts +8 -5
- package/dist/backend/antigravity.js +150 -30
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/channel/adapters/discord.js +36 -0
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/agy-mcp-launcher.d.ts +2 -0
- package/dist/channel/agy-mcp-launcher.js +28 -0
- package/dist/channel/agy-mcp-launcher.js.map +1 -0
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.js +33 -4
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-context.d.ts +9 -0
- package/dist/fleet-manager.d.ts +18 -0
- package/dist/fleet-manager.js +206 -10
- package/dist/fleet-manager.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -0
- package/dist/instance-lifecycle.js +35 -4
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +79 -35
- package/dist/locale.js.map +1 -1
- package/dist/login-flows.d.ts +6 -0
- package/dist/login-flows.js +7 -0
- package/dist/login-flows.js.map +1 -1
- package/dist/setup-wizard.js +2 -2
- package/dist/setup-wizard.js.map +1 -1
- package/dist/tips.js +111 -111
- package/dist/tips.js.map +1 -1
- package/dist/topic-commands.d.ts +2 -0
- package/dist/topic-commands.js +37 -0
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +35 -10
- package/dist/transcript-sources.js +190 -38
- package/dist/transcript-sources.js.map +1 -1
- package/package.json +1 -1
package/dist/fleet-context.d.ts
CHANGED
|
@@ -116,6 +116,15 @@ export interface FleetContext {
|
|
|
116
116
|
loginSubmitInput?(text: string): Promise<string>;
|
|
117
117
|
/** Abort the active login session. */
|
|
118
118
|
cancelLoginSession?(): Promise<string>;
|
|
119
|
+
/** `/install-cli <backend>` — install a CLI in a dedicated window; returns a status line. */
|
|
120
|
+
startInstallSession?(backend: string, chat: {
|
|
121
|
+
adapter: import("./channel/types.js").ChannelAdapter;
|
|
122
|
+
adapterId: string;
|
|
123
|
+
chatId: string;
|
|
124
|
+
threadId?: string;
|
|
125
|
+
}): Promise<string>;
|
|
126
|
+
/** Abort the active install session. */
|
|
127
|
+
cancelInstallSession?(): Promise<string>;
|
|
119
128
|
/** Human-readable effective model for an instance (resolves inherited defaults). */
|
|
120
129
|
modelDisplayForInstance?(name: string): string;
|
|
121
130
|
/**
|
package/dist/fleet-manager.d.ts
CHANGED
|
@@ -857,6 +857,24 @@ export declare class FleetManager implements FleetContext, LifecycleContext, Arc
|
|
|
857
857
|
private handleLoginConfirm;
|
|
858
858
|
/** Kiro provider button → drive the CLI's arrow-key selector. */
|
|
859
859
|
private handleLoginMenuSelect;
|
|
860
|
+
private activeInstall;
|
|
861
|
+
/** Start a CLI install session. Caller enforces admin. */
|
|
862
|
+
startInstallSession(backendArg: string, chat: {
|
|
863
|
+
adapter: ChannelAdapter;
|
|
864
|
+
adapterId: string;
|
|
865
|
+
chatId: string;
|
|
866
|
+
threadId?: string;
|
|
867
|
+
}): Promise<string>;
|
|
868
|
+
/** `/install-cli cancel` — abort the active install and remove its window. */
|
|
869
|
+
cancelInstallSession(): Promise<string>;
|
|
870
|
+
/** `command -v` on a login shell, so PATH additions from rc files count. */
|
|
871
|
+
private verifyBinaryOnLoginShell;
|
|
872
|
+
/** "Sign in now?" button after a successful install. */
|
|
873
|
+
private handleInstallLoginConfirm;
|
|
874
|
+
/** Discord native `/login` slash — shared by every adapter dispatch block. */
|
|
875
|
+
private handleLoginSlash;
|
|
876
|
+
/** Discord native `/install-cli` slash — shared by every dispatch block. */
|
|
877
|
+
private handleInstallCliSlash;
|
|
860
878
|
queueMirrorMessage(text: string): void;
|
|
861
879
|
/** Push an SSE event to all connected Web UI clients. */
|
|
862
880
|
emitSseEvent(event: string, data: unknown): void;
|
package/dist/fleet-manager.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync, rmSync, readdirSync, renameSync, copyFileSync, chmodSync, statSync } from "node:fs";
|
|
2
2
|
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
3
4
|
import { createServer } from "node:http";
|
|
4
5
|
import { join, dirname, basename } from "node:path";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
@@ -214,6 +215,7 @@ const TIP_UNLOCK_CALLBACK_PREFIX = "tip-unlock:";
|
|
|
214
215
|
const LOGIN_CALLBACK_PREFIX = "login:";
|
|
215
216
|
const LOGIN_MENU_CALLBACK_PREFIX = "login-menu:";
|
|
216
217
|
const LOGIN_CONFIRM_CALLBACK_PREFIX = "login-confirm:";
|
|
218
|
+
const INSTALL_LOGIN_CALLBACK_PREFIX = "install-login:";
|
|
217
219
|
const CLEAR_CONFIRM_TIMEOUT_MS = 15_000;
|
|
218
220
|
/** Default lifetime for long-lived nonce prompts (clear overrides this to 15s). */
|
|
219
221
|
const NONCE_BUTTON_TIMEOUT_MS = 15 * 60_000;
|
|
@@ -1273,12 +1275,6 @@ export class FleetManager {
|
|
|
1273
1275
|
}
|
|
1274
1276
|
const backend = config.backend ?? this.fleetConfig?.defaults?.backend ?? "claude-code";
|
|
1275
1277
|
if (config.general_topic) {
|
|
1276
|
-
// antigravity (agy) does not read MCP instructions — fleet context and
|
|
1277
|
-
// routing instructions are not injected, so it cannot act as a dispatcher.
|
|
1278
|
-
if (backend === "antigravity") {
|
|
1279
|
-
this.logger.warn({ name }, "antigravity backend does not support MCP instructions — general dispatcher will not work correctly");
|
|
1280
|
-
this.notifyInstanceTopic(name, t("general.antigravity_unsupported"));
|
|
1281
|
-
}
|
|
1282
1278
|
this.ensureGeneralInstructions(config.working_directory, backend, name);
|
|
1283
1279
|
}
|
|
1284
1280
|
else if (kind === "fleet-topic") {
|
|
@@ -1674,6 +1670,10 @@ export class FleetManager {
|
|
|
1674
1670
|
const { getTmuxSocketName: getSocket } = await import("./paths.js");
|
|
1675
1671
|
TmuxManager.setSocketName(getSocket());
|
|
1676
1672
|
await TmuxManager.ensureSession(getTmuxSession());
|
|
1673
|
+
// Pre-flight (advisory, fire-and-forget): warm the per-backend auth cache
|
|
1674
|
+
// before instances spawn, so a CLI that comes up on its sign-in screen gets
|
|
1675
|
+
// an instant 🔑 verdict instead of decaying into crash/MCP-died noise.
|
|
1676
|
+
this.lifecycle.primeAuthVerification(Object.values(fleet.instances).map(config => config.backend ?? fleet.defaults?.backend ?? "claude-code"));
|
|
1677
1677
|
// Start tmux control mode client for idle detection
|
|
1678
1678
|
if (!this.controlClient) {
|
|
1679
1679
|
this.controlClient = new TmuxControlClient(getTmuxSession(), 2000, this.logger);
|
|
@@ -2375,6 +2375,8 @@ export class FleetManager {
|
|
|
2375
2375
|
return;
|
|
2376
2376
|
if (await this.handleLoginConfirm(data, adapterId, this.adapter ?? undefined))
|
|
2377
2377
|
return;
|
|
2378
|
+
if (await this.handleInstallLoginConfirm(data, adapterId, this.adapter ?? undefined))
|
|
2379
|
+
return;
|
|
2378
2380
|
if (await this.handleClearConfirmation(data, adapterId, this.adapter ?? undefined))
|
|
2379
2381
|
return;
|
|
2380
2382
|
if (await this.handleExitRestartPrompt(data, adapterId, this.adapter ?? undefined))
|
|
@@ -2504,6 +2506,12 @@ export class FleetManager {
|
|
|
2504
2506
|
});
|
|
2505
2507
|
await data.respond(result);
|
|
2506
2508
|
}
|
|
2509
|
+
else if (data.command === "login") {
|
|
2510
|
+
await this.handleLoginSlash(data, adapterId, this.adapter);
|
|
2511
|
+
}
|
|
2512
|
+
else if (data.command === "install-cli") {
|
|
2513
|
+
await this.handleInstallCliSlash(data, adapterId, this.adapter);
|
|
2514
|
+
}
|
|
2507
2515
|
else if (data.command === "clear") {
|
|
2508
2516
|
await this.handleClearSlash(data, adapterId);
|
|
2509
2517
|
}
|
|
@@ -2668,6 +2676,12 @@ export class FleetManager {
|
|
|
2668
2676
|
});
|
|
2669
2677
|
await data.respond(result);
|
|
2670
2678
|
}
|
|
2679
|
+
else if (data.command === "login") {
|
|
2680
|
+
await this.handleLoginSlash(data, adapterId, this.adapter);
|
|
2681
|
+
}
|
|
2682
|
+
else if (data.command === "install-cli") {
|
|
2683
|
+
await this.handleInstallCliSlash(data, adapterId, this.adapter);
|
|
2684
|
+
}
|
|
2671
2685
|
}, this.logger, "adapter.slash_command"));
|
|
2672
2686
|
await this.topicCommands.registerBotCommands().catch(e => this.logger.warn({ err: e }, "registerBotCommands failed (non-fatal)"));
|
|
2673
2687
|
// Background-probe each backend's CLI env (version/models) → cli-env cache.
|
|
@@ -2754,6 +2768,8 @@ export class FleetManager {
|
|
|
2754
2768
|
return;
|
|
2755
2769
|
if (await this.handleLoginConfirm(data, adapterId, adapter))
|
|
2756
2770
|
return;
|
|
2771
|
+
if (await this.handleInstallLoginConfirm(data, adapterId, adapter))
|
|
2772
|
+
return;
|
|
2757
2773
|
if (await this.handleClearConfirmation(data, adapterId, adapter))
|
|
2758
2774
|
return;
|
|
2759
2775
|
if (await this.handleExitRestartPrompt(data, adapterId, adapter))
|
|
@@ -3000,6 +3016,12 @@ export class FleetManager {
|
|
|
3000
3016
|
});
|
|
3001
3017
|
await data.respond(result);
|
|
3002
3018
|
}
|
|
3019
|
+
else if (data.command === "login") {
|
|
3020
|
+
await this.handleLoginSlash(data, adapterId, adapter);
|
|
3021
|
+
}
|
|
3022
|
+
else if (data.command === "install-cli") {
|
|
3023
|
+
await this.handleInstallCliSlash(data, adapterId, adapter);
|
|
3024
|
+
}
|
|
3003
3025
|
}, this.logger, `adapter[${adapterId}].slash_command`));
|
|
3004
3026
|
await adapter.start();
|
|
3005
3027
|
if (channelConfig.group_id) {
|
|
@@ -6238,6 +6260,9 @@ export class FleetManager {
|
|
|
6238
6260
|
return t("login.unsupported", backendArg);
|
|
6239
6261
|
if (this.activeLogin)
|
|
6240
6262
|
return t("login.busy", this.activeLogin.backend);
|
|
6263
|
+
// Install sessions share the window namespace — never run both at once.
|
|
6264
|
+
if (this.activeInstall)
|
|
6265
|
+
return t("install.busy");
|
|
6241
6266
|
// Token-free pre-check (5s cap): re-login while auth still works is
|
|
6242
6267
|
// usually a mistake, so it needs a confirmed click. An invalid OR
|
|
6243
6268
|
// uncertain result (timeout, missing binary) proceeds straight to login —
|
|
@@ -6269,6 +6294,9 @@ export class FleetManager {
|
|
|
6269
6294
|
async launchLoginSession(flow, backend, chat) {
|
|
6270
6295
|
if (this.activeLogin)
|
|
6271
6296
|
return t("login.busy", this.activeLogin.backend);
|
|
6297
|
+
// Install sessions share the window namespace — never run both at once.
|
|
6298
|
+
if (this.activeInstall)
|
|
6299
|
+
return t("install.busy");
|
|
6272
6300
|
const sessionName = getTmuxSession();
|
|
6273
6301
|
await TmuxManager.ensureSession(sessionName);
|
|
6274
6302
|
const tmux = new TmuxManager(sessionName, "");
|
|
@@ -6302,7 +6330,9 @@ export class FleetManager {
|
|
|
6302
6330
|
text = t("login.success", backend, woken.length ? woken.join(", ") : none, restarted.length ? restarted.join(", ") : none);
|
|
6303
6331
|
}
|
|
6304
6332
|
else if (detail === "cancelled") {
|
|
6305
|
-
|
|
6333
|
+
// The cancel command's own reply already announced this — a second
|
|
6334
|
+
// message here was a duplicate.
|
|
6335
|
+
return;
|
|
6306
6336
|
}
|
|
6307
6337
|
else {
|
|
6308
6338
|
text = t("login.failed", backend, detail);
|
|
@@ -6447,6 +6477,173 @@ export class FleetManager {
|
|
|
6447
6477
|
await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, ok ? t("login.provider_selected", label) : t("login.no_session"));
|
|
6448
6478
|
return true;
|
|
6449
6479
|
}
|
|
6480
|
+
// ── Remote CLI install (`/install-cli`) ──────────────────────────────────
|
|
6481
|
+
//
|
|
6482
|
+
// Same dedicated-window model as /login (and the same LoginSession state
|
|
6483
|
+
// machine — an install is a login flow with no auth hints): run the
|
|
6484
|
+
// installer, judge by exit code, verify the binary on a fresh login shell,
|
|
6485
|
+
// then offer to chain straight into /login.
|
|
6486
|
+
activeInstall = null;
|
|
6487
|
+
/** Start a CLI install session. Caller enforces admin. */
|
|
6488
|
+
async startInstallSession(backendArg, chat) {
|
|
6489
|
+
const backend = LOGIN_BACKEND_ALIASES[backendArg.toLowerCase()] ?? backendArg.toLowerCase();
|
|
6490
|
+
const info = BACKEND_INSTALLATION_INFO[backend];
|
|
6491
|
+
if (!info)
|
|
6492
|
+
return t("install.unsupported", backendArg);
|
|
6493
|
+
if (checkBinaryInstalled(info.binary))
|
|
6494
|
+
return t("install.already", backend, info.binary);
|
|
6495
|
+
if (this.activeInstall)
|
|
6496
|
+
return t("install.busy");
|
|
6497
|
+
if (this.activeLogin)
|
|
6498
|
+
return t("login.busy", this.activeLogin.backend);
|
|
6499
|
+
const sessionName = getTmuxSession();
|
|
6500
|
+
await TmuxManager.ensureSession(sessionName);
|
|
6501
|
+
const tmux = new TmuxManager(sessionName, "");
|
|
6502
|
+
// A synthetic login flow: success is decided by the installer's exit code
|
|
6503
|
+
// (LoginSession treats a clean exit as success), never by pane text — and
|
|
6504
|
+
// installer output that happens to contain a URL must not be forwarded as
|
|
6505
|
+
// an auth hint, hence the no-op events below.
|
|
6506
|
+
const flow = {
|
|
6507
|
+
backend,
|
|
6508
|
+
command: info.install,
|
|
6509
|
+
successPattern: /$^/,
|
|
6510
|
+
timeoutMs: 10 * 60 * 1000,
|
|
6511
|
+
};
|
|
6512
|
+
const session = new LoginSession(flow, tmux, {
|
|
6513
|
+
onMenu: () => { },
|
|
6514
|
+
onAuthHint: () => { },
|
|
6515
|
+
onNeedInput: () => { },
|
|
6516
|
+
onDone: async ({ ok, detail }) => {
|
|
6517
|
+
this.activeInstall = null;
|
|
6518
|
+
if (!ok) {
|
|
6519
|
+
// A cancel is user-initiated — the cancel command's own reply already
|
|
6520
|
+
// said so; a second message here would be a duplicate.
|
|
6521
|
+
if (detail !== "cancelled") {
|
|
6522
|
+
await chat.adapter.sendText(chat.chatId, t("install.failed", backend, detail), { threadId: chat.threadId }).catch(() => { });
|
|
6523
|
+
}
|
|
6524
|
+
return;
|
|
6525
|
+
}
|
|
6526
|
+
// The installer may only have added the binary to a profile PATH; a
|
|
6527
|
+
// fresh login shell sees that, the fleet process's PATH may not.
|
|
6528
|
+
if (!this.verifyBinaryOnLoginShell(info.binary)) {
|
|
6529
|
+
await chat.adapter.sendText(chat.chatId, t("install.verify_failed", backend, info.binary), { threadId: chat.threadId }).catch(() => { });
|
|
6530
|
+
return;
|
|
6531
|
+
}
|
|
6532
|
+
if (!LOGIN_FLOWS[backend]) {
|
|
6533
|
+
await chat.adapter.sendText(chat.chatId, t("install.success_no_login", backend), { threadId: chat.threadId }).catch(() => { });
|
|
6534
|
+
return;
|
|
6535
|
+
}
|
|
6536
|
+
await this.postNonceButtonPrompt({
|
|
6537
|
+
prefix: INSTALL_LOGIN_CALLBACK_PREFIX,
|
|
6538
|
+
alertType: "login",
|
|
6539
|
+
instanceName: backend,
|
|
6540
|
+
adapter: chat.adapter,
|
|
6541
|
+
adapterId: chat.adapterId,
|
|
6542
|
+
chatId: chat.chatId,
|
|
6543
|
+
threadId: chat.threadId,
|
|
6544
|
+
message: t("install.login_prompt", backend),
|
|
6545
|
+
choices: [
|
|
6546
|
+
{ action: "go", label: t("install.login_now") },
|
|
6547
|
+
{ action: "later", label: t("install.later") },
|
|
6548
|
+
],
|
|
6549
|
+
expiredText: t("install.later_ack", backend),
|
|
6550
|
+
});
|
|
6551
|
+
},
|
|
6552
|
+
}, this.logger);
|
|
6553
|
+
this.activeInstall = { session, backend, chat };
|
|
6554
|
+
try {
|
|
6555
|
+
await session.start();
|
|
6556
|
+
}
|
|
6557
|
+
catch (err) {
|
|
6558
|
+
this.activeInstall = null;
|
|
6559
|
+
return t("install.failed", backend, err.message);
|
|
6560
|
+
}
|
|
6561
|
+
return t("install.started", backend);
|
|
6562
|
+
}
|
|
6563
|
+
/** `/install-cli cancel` — abort the active install and remove its window. */
|
|
6564
|
+
async cancelInstallSession() {
|
|
6565
|
+
if (!this.activeInstall)
|
|
6566
|
+
return t("install.no_session");
|
|
6567
|
+
const backend = this.activeInstall.backend;
|
|
6568
|
+
await this.activeInstall.session.cancel();
|
|
6569
|
+
return t("install.cancelled", backend);
|
|
6570
|
+
}
|
|
6571
|
+
/** `command -v` on a login shell, so PATH additions from rc files count. */
|
|
6572
|
+
verifyBinaryOnLoginShell(binary) {
|
|
6573
|
+
try {
|
|
6574
|
+
const result = spawnSync("bash", ["-lc", `command -v ${binary}`], { timeout: 10_000, stdio: "pipe" });
|
|
6575
|
+
return result.status === 0;
|
|
6576
|
+
}
|
|
6577
|
+
catch {
|
|
6578
|
+
return false;
|
|
6579
|
+
}
|
|
6580
|
+
}
|
|
6581
|
+
/** "Sign in now?" button after a successful install. */
|
|
6582
|
+
async handleInstallLoginConfirm(data, callbackAdapterId, receivingAdapter) {
|
|
6583
|
+
const claimed = this.consumeNonceCallback(INSTALL_LOGIN_CALLBACK_PREFIX, /^install-login:([0-9a-f]+):(go|later)$/, data, callbackAdapterId, receivingAdapter);
|
|
6584
|
+
if (claimed === null)
|
|
6585
|
+
return false;
|
|
6586
|
+
if (claimed === "consumed")
|
|
6587
|
+
return true;
|
|
6588
|
+
const { entry, action } = claimed;
|
|
6589
|
+
const backend = entry.instanceName;
|
|
6590
|
+
if (action === "later") {
|
|
6591
|
+
await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("install.later_ack", backend));
|
|
6592
|
+
return true;
|
|
6593
|
+
}
|
|
6594
|
+
await this.retireNonceButtons(entry, entry.messageId ?? data.messageId, t("login.starting_backend", backend));
|
|
6595
|
+
const text = await this.startLoginSession(backend, {
|
|
6596
|
+
adapter: entry.adapter,
|
|
6597
|
+
adapterId: entry.adapterId,
|
|
6598
|
+
chatId: entry.chatId,
|
|
6599
|
+
threadId: entry.threadId,
|
|
6600
|
+
});
|
|
6601
|
+
if (text)
|
|
6602
|
+
await entry.adapter.sendText(entry.chatId, text, { threadId: entry.threadId }).catch(() => { });
|
|
6603
|
+
return true;
|
|
6604
|
+
}
|
|
6605
|
+
/** Discord native `/login` slash — shared by every adapter dispatch block. */
|
|
6606
|
+
async handleLoginSlash(data, adapterId, adapter) {
|
|
6607
|
+
if (!data.userId || !this.isFleetAdmin(data.userId, adapterId)) {
|
|
6608
|
+
await data.respond(t("permission.denied"));
|
|
6609
|
+
return;
|
|
6610
|
+
}
|
|
6611
|
+
const chat = { adapter, adapterId, chatId: data.channelId };
|
|
6612
|
+
if (data.options?.cancel === true) {
|
|
6613
|
+
await data.respond(await this.cancelLoginSession());
|
|
6614
|
+
return;
|
|
6615
|
+
}
|
|
6616
|
+
const code = String(data.options?.code ?? "").trim();
|
|
6617
|
+
if (code) {
|
|
6618
|
+
await data.respond(await this.loginSubmitInput(code));
|
|
6619
|
+
return;
|
|
6620
|
+
}
|
|
6621
|
+
const backend = String(data.options?.backend ?? "").trim();
|
|
6622
|
+
if (backend) {
|
|
6623
|
+
const text = await this.startLoginSession(backend, chat);
|
|
6624
|
+
await data.respond(text ?? t("login.confirm_posted"));
|
|
6625
|
+
return;
|
|
6626
|
+
}
|
|
6627
|
+
await this.promptLoginBackends(chat);
|
|
6628
|
+
await data.respond(t("login.chooser_posted"));
|
|
6629
|
+
}
|
|
6630
|
+
/** Discord native `/install-cli` slash — shared by every dispatch block. */
|
|
6631
|
+
async handleInstallCliSlash(data, adapterId, adapter) {
|
|
6632
|
+
if (!data.userId || !this.isFleetAdmin(data.userId, adapterId)) {
|
|
6633
|
+
await data.respond(t("permission.denied"));
|
|
6634
|
+
return;
|
|
6635
|
+
}
|
|
6636
|
+
if (data.options?.cancel === true) {
|
|
6637
|
+
await data.respond(await this.cancelInstallSession());
|
|
6638
|
+
return;
|
|
6639
|
+
}
|
|
6640
|
+
const backend = String(data.options?.backend ?? "").trim();
|
|
6641
|
+
if (!backend) {
|
|
6642
|
+
await data.respond(t("install.usage"));
|
|
6643
|
+
return;
|
|
6644
|
+
}
|
|
6645
|
+
await data.respond(await this.startInstallSession(backend, { adapter, adapterId, chatId: data.channelId }));
|
|
6646
|
+
}
|
|
6450
6647
|
queueMirrorMessage(text) {
|
|
6451
6648
|
const mirrorTopicId = this.fleetConfig?.channel?.mirror_topic_id;
|
|
6452
6649
|
if (mirrorTopicId == null || !this.adapter)
|
|
@@ -6618,9 +6815,8 @@ Plus the operational skills (fleet-health, instance-lifecycle, scheduling, sessi
|
|
|
6618
6815
|
}
|
|
6619
6816
|
/** Resolve the workspace path a backend actually uses before publishing knowledge. */
|
|
6620
6817
|
resolveKnowledgeWorkDir(workDir, backend, instanceName) {
|
|
6621
|
-
//
|
|
6622
|
-
//
|
|
6623
|
-
// CLI actually runs, not where fleet.yaml points.
|
|
6818
|
+
// Backend resolution may create/normalize the real cwd. Instructions and
|
|
6819
|
+
// skills must land where the CLI actually runs, not an assumed path.
|
|
6624
6820
|
try {
|
|
6625
6821
|
const resolved = createBackend(backend, join(getAgendHome(), "cli-env"))
|
|
6626
6822
|
.resolveWorkingDirectory?.(workDir, instanceName);
|