@songsid/agend 2.2.0-alpha.2 → 2.2.0-alpha.3
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 +4 -4
- package/README.zh-TW.md +4 -4
- package/dist/agent-endpoint.d.ts +4 -1
- package/dist/agent-endpoint.js +14 -2
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/atomic-write.d.ts +21 -0
- package/dist/atomic-write.js +65 -0
- package/dist/atomic-write.js.map +1 -0
- package/dist/auth-api.js +2 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/codex.d.ts +7 -0
- package/dist/backend/codex.js +7 -0
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/muse.d.ts +7 -0
- package/dist/backend/muse.js +7 -0
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +6 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/binary-probe.d.ts +80 -0
- package/dist/binary-probe.js +182 -0
- package/dist/binary-probe.js.map +1 -0
- package/dist/cache-service.d.ts +17 -1
- package/dist/cache-service.js +39 -4
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +5 -1
- package/dist/channel/adapters/discord.js +56 -11
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +38 -1
- package/dist/channel/adapters/telegram.js +82 -0
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +1 -1
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.d.ts +8 -1
- package/dist/channel/tool-router.js +4 -2
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/channel/types.d.ts +21 -0
- package/dist/cli.js +133 -38
- package/dist/cli.js.map +1 -1
- package/dist/connection-secrets.d.ts +5 -0
- package/dist/connection-secrets.js.map +1 -1
- package/dist/cpu-profile.js +50 -0
- package/dist/cpu-profile.js.map +1 -1
- package/dist/daemon.d.ts +12 -0
- package/dist/daemon.js +166 -26
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +1 -0
- package/dist/delivery-outbox.js +12 -0
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/discord-permissions.d.ts +33 -0
- package/dist/discord-permissions.js +42 -0
- package/dist/discord-permissions.js.map +1 -0
- package/dist/env-file.d.ts +11 -0
- package/dist/env-file.js +27 -0
- package/dist/env-file.js.map +1 -0
- package/dist/fleet-context.d.ts +5 -0
- package/dist/fleet-context.js.map +1 -1
- package/dist/fleet-level-config.d.ts +8 -1
- package/dist/fleet-level-config.js +31 -0
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +76 -7
- package/dist/fleet-manager.js +599 -127
- package/dist/fleet-manager.js.map +1 -1
- package/dist/fleet-stop-budget.d.ts +22 -0
- package/dist/fleet-stop-budget.js +95 -0
- package/dist/fleet-stop-budget.js.map +1 -0
- package/dist/kiro-transcript-lane.d.ts +8 -4
- package/dist/kiro-transcript-lane.js +66 -44
- package/dist/kiro-transcript-lane.js.map +1 -1
- package/dist/locale.js +82 -0
- package/dist/locale.js.map +1 -1
- package/dist/next-steps.d.ts +5 -0
- package/dist/next-steps.js +26 -0
- package/dist/next-steps.js.map +1 -0
- package/dist/outbound-handlers.js +8 -0
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +4 -0
- package/dist/outbound-schemas.js +6 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/outbox-open-error.d.ts +7 -0
- package/dist/outbox-open-error.js +15 -0
- package/dist/outbox-open-error.js.map +1 -0
- package/dist/pane-context-cache.d.ts +25 -0
- package/dist/pane-context-cache.js +73 -0
- package/dist/pane-context-cache.js.map +1 -0
- package/dist/paths.d.ts +0 -7
- package/dist/paths.js +8 -2
- package/dist/paths.js.map +1 -1
- package/dist/provider-probe.d.ts +15 -0
- package/dist/provider-probe.js +20 -0
- package/dist/provider-probe.js.map +1 -1
- package/dist/public-link-progress.d.ts +73 -0
- package/dist/public-link-progress.js +190 -0
- package/dist/public-link-progress.js.map +1 -0
- package/dist/public-web-gateway.js +1 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/public-web-link.d.ts +6 -1
- package/dist/public-web-link.js +87 -15
- package/dist/public-web-link.js.map +1 -1
- package/dist/quickstart-api.d.ts +93 -20
- package/dist/quickstart-api.js +194 -62
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +15 -0
- package/dist/quickstart.js +100 -29
- package/dist/quickstart.js.map +1 -1
- package/dist/reply-buttons-controller.d.ts +98 -0
- package/dist/reply-buttons-controller.js +174 -0
- package/dist/reply-buttons-controller.js.map +1 -0
- package/dist/reply-buttons.d.ts +113 -0
- package/dist/reply-buttons.js +208 -0
- package/dist/reply-buttons.js.map +1 -0
- package/dist/reply-dedup.js +3 -1
- package/dist/reply-dedup.js.map +1 -1
- package/dist/restart-guard.d.ts +1 -0
- package/dist/restart-guard.js +8 -3
- package/dist/restart-guard.js.map +1 -1
- package/dist/service-activation.d.ts +15 -2
- package/dist/service-activation.js +81 -4
- package/dist/service-activation.js.map +1 -1
- package/dist/service-installer.js +19 -1
- package/dist/service-installer.js.map +1 -1
- package/dist/settings-api.js +53 -12
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-authority.d.ts +11 -0
- package/dist/settings-authority.js +128 -0
- package/dist/settings-authority.js.map +1 -0
- package/dist/settings-change.d.ts +5 -0
- package/dist/settings-change.js +4 -3
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-confirmation.d.ts +3 -0
- package/dist/settings-confirmation.js +7 -1
- package/dist/settings-confirmation.js.map +1 -1
- package/dist/settings-effect.js +19 -7
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-http-confirmation.js +1 -1
- package/dist/settings-http-confirmation.js.map +1 -1
- package/dist/settings-redaction.d.ts +18 -0
- package/dist/settings-redaction.js +58 -0
- package/dist/settings-redaction.js.map +1 -0
- package/dist/setup-form.d.ts +9 -1
- package/dist/setup-form.js +25 -1
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-host.js +13 -3
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +26 -19
- package/dist/setup-wizard.js.map +1 -1
- package/dist/systemd-runtime.d.ts +15 -0
- package/dist/systemd-runtime.js +41 -0
- package/dist/systemd-runtime.js.map +1 -0
- package/dist/tmux-control.d.ts +22 -0
- package/dist/tmux-control.js +82 -17
- package/dist/tmux-control.js.map +1 -1
- package/dist/token-env-name.d.ts +37 -0
- package/dist/token-env-name.js +93 -0
- package/dist/token-env-name.js.map +1 -0
- package/dist/tool-permissions.js +5 -3
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +7 -16
- package/dist/topic-commands.js +45 -83
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-monitor.js +3 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +68 -0
- package/dist/transcript-sources.js +336 -29
- package/dist/transcript-sources.js.map +1 -1
- package/dist/transcript-turns.d.ts +39 -0
- package/dist/transcript-turns.js +58 -0
- package/dist/transcript-turns.js.map +1 -0
- package/dist/tunnel/cloudflared-install.d.ts +18 -0
- package/dist/tunnel/cloudflared-install.js +15 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/turn-reply-guard.d.ts +3 -0
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/ui/chat-render.js +32 -6
- package/dist/ui/chat-store.js +21 -1
- package/dist/ui/chat-strings.js +8 -0
- package/dist/ui/chat-thread.js +109 -52
- package/dist/ui/first-run.js +64 -0
- package/dist/ui/html-attachment.js +26 -0
- package/dist/ui/panel-chat.js +13 -5
- package/dist/ui/panel-fleet.js +5 -5
- package/dist/ui/panel-settings.js +18 -8
- package/dist/ui/preview-panel.js +38 -3
- package/dist/ui/settings-apply.js +3 -1
- package/dist/ui/settings-dialogs.js +95 -25
- package/dist/ui/settings-discord.js +130 -0
- package/dist/ui/settings-model.js +21 -0
- package/dist/ui/settings-strings.js +46 -6
- package/dist/ui/settings-token.js +54 -0
- package/dist/ui/settings-wizard.js +63 -29
- package/dist/ui/shared/app-shell.js +19 -33
- package/dist/ui/shared/app-store.js +5 -3
- package/dist/ui/shared/app-stream.js +2 -1
- package/dist/ui/shared/app.css +34 -2
- package/dist/ui/shared/app.js +2 -1
- package/dist/ui/shared/instance-nav.js +310 -0
- package/dist/ui/shared/panel-view.js +12 -190
- package/dist/ui/shared/view-roster-store.js +5 -0
- package/dist/ui/shared/view-strings.js +12 -0
- package/dist/update-dispatch.d.ts +1 -1
- package/dist/update-dispatch.js +1 -1
- package/dist/update-install.d.ts +15 -3
- package/dist/update-install.js +41 -13
- package/dist/update-install.js.map +1 -1
- package/dist/update-launch.d.ts +22 -0
- package/dist/update-launch.js +106 -0
- package/dist/update-launch.js.map +1 -0
- package/dist/update-marker.js +3 -8
- package/dist/update-marker.js.map +1 -1
- package/dist/usage/format-rich.js +7 -1
- package/dist/usage/format-rich.js.map +1 -1
- package/dist/usage/i18n-keys.d.ts +1 -1
- package/dist/usage/i18n-keys.js +1 -1
- package/dist/usage/i18n-keys.js.map +1 -1
- package/dist/usage/providers.d.ts +4 -0
- package/dist/usage/providers.js +2 -1
- package/dist/usage/providers.js.map +1 -1
- package/dist/usage/usage-api.js +48 -2
- package/dist/usage/usage-api.js.map +1 -1
- package/dist/view-api.d.ts +40 -0
- package/dist/view-api.js +28 -10
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +8 -0
- package/dist/web-api.js +50 -16
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.d.ts +8 -0
- package/dist/web-auth.js +34 -8
- package/dist/web-auth.js.map +1 -1
- package/dist/web-chat-history.d.ts +21 -0
- package/dist/web-chat-history.js +44 -0
- package/dist/web-chat-history.js.map +1 -1
- package/dist/web-host-guard.d.ts +18 -2
- package/dist/web-host-guard.js +30 -5
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-session.d.ts +7 -1
- package/dist/web-session.js +23 -2
- package/dist/web-session.js.map +1 -1
- package/launcher/postinstall.cjs +8 -4
- package/package.json +1 -1
- package/templates/systemd.service.ejs +3 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Shared outer grace for service-managed and detached fleets (#1071).
|
|
2
|
+
* This covers multiple 15/5/2-second Kiro batches; it is not an unlimited
|
|
3
|
+
* guarantee for arbitrarily large fleets or stuck transport operations. */
|
|
4
|
+
export declare const FLEET_STOP_TIMEOUT_MS: number;
|
|
5
|
+
export type DetachedOwnerState = "fleet" | "gone" | "other" | "unknown" | "waiting";
|
|
6
|
+
export interface DetachedStopDeps {
|
|
7
|
+
/** No signal is authorized by an unreadable identity. */
|
|
8
|
+
inspect(): DetachedOwnerState;
|
|
9
|
+
signal(signal: "SIGTERM" | "SIGKILL"): void;
|
|
10
|
+
now(): number;
|
|
11
|
+
sleep(ms: number): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
/** Stop the proven owner, and do not admit a replacement until it is gone.
|
|
14
|
+
* No sleep subprocesses, no wall-clock budgets, and no kill(0) error treated
|
|
15
|
+
* as exit proof except ESRCH (the caller's inspect contract). */
|
|
16
|
+
export declare function stopDetachedOwner(deps: DetachedStopDeps): Promise<void>;
|
|
17
|
+
/** systemctl show's human-readable TimeoutStopUSec, not a permissive parseInt. */
|
|
18
|
+
export declare function systemdStopTimeoutMs(raw: string): number | null;
|
|
19
|
+
/** Cached at claim and re-read before signals: a recycled PID is not our owner. */
|
|
20
|
+
export declare function detachedProcessStart(pid: number): string | null;
|
|
21
|
+
/** A Linux zombie has exited even while its parent has not reaped the PID. */
|
|
22
|
+
export declare function detachedProcessExited(pid: number): boolean;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
/** Shared outer grace for service-managed and detached fleets (#1071).
|
|
4
|
+
* This covers multiple 15/5/2-second Kiro batches; it is not an unlimited
|
|
5
|
+
* guarantee for arbitrarily large fleets or stuck transport operations. */
|
|
6
|
+
export const FLEET_STOP_TIMEOUT_MS = 5 * 60_000;
|
|
7
|
+
const EXIT_CONFIRM_MS = 5_000;
|
|
8
|
+
const POLL_MS = 500;
|
|
9
|
+
/** Stop the proven owner, and do not admit a replacement until it is gone.
|
|
10
|
+
* No sleep subprocesses, no wall-clock budgets, and no kill(0) error treated
|
|
11
|
+
* as exit proof except ESRCH (the caller's inspect contract). */
|
|
12
|
+
export async function stopDetachedOwner(deps) {
|
|
13
|
+
const inspect = () => {
|
|
14
|
+
const state = deps.inspect();
|
|
15
|
+
if (state === "unknown")
|
|
16
|
+
throw new Error("Cannot confirm the detached fleet owner; nothing else was signalled or started");
|
|
17
|
+
return state;
|
|
18
|
+
};
|
|
19
|
+
const alive = (state) => state === "fleet" || state === "waiting";
|
|
20
|
+
const first = inspect();
|
|
21
|
+
if (first === "waiting")
|
|
22
|
+
throw new Error("Cannot confirm the detached fleet command; nothing was signalled or started");
|
|
23
|
+
if (!alive(first))
|
|
24
|
+
return;
|
|
25
|
+
const deadline = deps.now() + FLEET_STOP_TIMEOUT_MS;
|
|
26
|
+
deps.signal("SIGTERM");
|
|
27
|
+
while (alive(inspect())) {
|
|
28
|
+
const remaining = deadline - deps.now();
|
|
29
|
+
if (remaining <= 0)
|
|
30
|
+
break;
|
|
31
|
+
await deps.sleep(Math.min(POLL_MS, remaining));
|
|
32
|
+
}
|
|
33
|
+
// Re-read identity at the effect boundary, including after the last wait.
|
|
34
|
+
// An empty command on the captured birth can be a transient exit transition.
|
|
35
|
+
// It only admits passive waiting: never a KILL or replacement.
|
|
36
|
+
const beforeKill = inspect();
|
|
37
|
+
if (beforeKill === "waiting")
|
|
38
|
+
throw new Error("Cannot confirm the detached fleet command after its grace; refusing to signal or start a duplicate");
|
|
39
|
+
if (!alive(beforeKill))
|
|
40
|
+
return;
|
|
41
|
+
deps.signal("SIGKILL");
|
|
42
|
+
const exitDeadline = deps.now() + EXIT_CONFIRM_MS;
|
|
43
|
+
while (alive(inspect())) {
|
|
44
|
+
const remaining = exitDeadline - deps.now();
|
|
45
|
+
if (remaining <= 0)
|
|
46
|
+
throw new Error("Detached fleet has not exited after SIGKILL; refusing to start a duplicate");
|
|
47
|
+
await deps.sleep(Math.min(POLL_MS, remaining));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** systemctl show's human-readable TimeoutStopUSec, not a permissive parseInt. */
|
|
51
|
+
export function systemdStopTimeoutMs(raw) {
|
|
52
|
+
const text = raw.trim();
|
|
53
|
+
if (text === "infinity")
|
|
54
|
+
return Infinity;
|
|
55
|
+
const units = { us: 0.001, ms: 1, s: 1_000, min: 60_000, h: 3_600_000, d: 86_400_000 };
|
|
56
|
+
if (!/^(?:\d+(?:\.\d+)?(?:us|ms|s|min|h|d))(?:\s+\d+(?:\.\d+)?(?:us|ms|s|min|h|d))*$/.test(text))
|
|
57
|
+
return null;
|
|
58
|
+
let total = 0;
|
|
59
|
+
for (const part of text.split(/\s+/)) {
|
|
60
|
+
const match = /^(\d+(?:\.\d+)?)(us|ms|s|min|h|d)$/.exec(part);
|
|
61
|
+
total += Number(match[1]) * units[match[2]];
|
|
62
|
+
}
|
|
63
|
+
return Number.isFinite(total) ? total : null;
|
|
64
|
+
}
|
|
65
|
+
/** Cached at claim and re-read before signals: a recycled PID is not our owner. */
|
|
66
|
+
export function detachedProcessStart(pid) {
|
|
67
|
+
try {
|
|
68
|
+
if (process.platform === "linux") {
|
|
69
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
70
|
+
// comm can contain spaces and ')': fields after its LAST ')' start at #3.
|
|
71
|
+
const tail = stat.slice(stat.lastIndexOf(")") + 2).trim().split(/\s+/);
|
|
72
|
+
return stat.lastIndexOf(")") > 0 && /^\d+$/.test(tail[19] ?? "") ? tail[19] : null;
|
|
73
|
+
}
|
|
74
|
+
return execFileSync("ps", ["-p", String(pid), "-o", "lstart="], { encoding: "utf8", timeout: 1_000, stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** A Linux zombie has exited even while its parent has not reaped the PID. */
|
|
81
|
+
export function detachedProcessExited(pid) {
|
|
82
|
+
if (process.platform !== "linux")
|
|
83
|
+
return false;
|
|
84
|
+
try {
|
|
85
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
86
|
+
const end = stat.lastIndexOf(")");
|
|
87
|
+
const tail = stat.slice(end + 2).trim().split(/\s+/);
|
|
88
|
+
return end > 0 && stat.startsWith(`${pid} (`) && /^\d+$/.test(tail[19] ?? "")
|
|
89
|
+
&& (tail[0] === "Z" || tail[0] === "X");
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
} // No readable exit evidence: still unknown, never exit.
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=fleet-stop-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-stop-budget.js","sourceRoot":"","sources":["../src/fleet-stop-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { KiroDbCursor } from "./kiro-db-reader.js";
|
|
2
2
|
import type { TranscriptEvents } from "./transcript-sources.js";
|
|
3
3
|
export declare const KIRO_TRANSCRIPT_BUDGET_MS = 15000;
|
|
4
|
+
/** One replacement can read while one retired native call is still held. */
|
|
5
|
+
export declare const KIRO_TRANSCRIPT_MAX_WORKERS = 2;
|
|
4
6
|
export interface KiroDbInput {
|
|
5
7
|
dbPath: string;
|
|
6
8
|
workingDirectory: string;
|
|
@@ -32,15 +34,16 @@ interface Isolate {
|
|
|
32
34
|
ref(): unknown;
|
|
33
35
|
unref(): unknown;
|
|
34
36
|
}
|
|
35
|
-
/** One
|
|
36
|
-
*
|
|
37
|
-
*
|
|
37
|
+
/** One active isolate, one queued/in-flight request per source, warm RO handles.
|
|
38
|
+
* A retired isolate stops owning reads immediately, but keeps its physical slot
|
|
39
|
+
* until exit. One spare slot allows recovery from a stuck native call without a
|
|
40
|
+
* worker herd. If both slots are stuck, requests keep their original deadlines.
|
|
38
41
|
*/
|
|
39
42
|
export declare class KiroTranscriptLane implements KiroDbLane {
|
|
40
43
|
private factory;
|
|
41
44
|
private now;
|
|
42
45
|
private worker;
|
|
43
|
-
private
|
|
46
|
+
private physical;
|
|
44
47
|
private owners;
|
|
45
48
|
private pending;
|
|
46
49
|
private nextId;
|
|
@@ -50,6 +53,7 @@ export declare class KiroTranscriptLane implements KiroDbLane {
|
|
|
50
53
|
private settle;
|
|
51
54
|
private recycle;
|
|
52
55
|
private ensureWorker;
|
|
56
|
+
private dispatch;
|
|
53
57
|
private read;
|
|
54
58
|
}
|
|
55
59
|
export declare const sharedKiroTranscriptLane: KiroTranscriptLane;
|
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { Worker } from "node:worker_threads";
|
|
2
2
|
import { performance } from "node:perf_hooks";
|
|
3
3
|
export const KIRO_TRANSCRIPT_BUDGET_MS = 15_000;
|
|
4
|
+
/** One replacement can read while one retired native call is still held. */
|
|
5
|
+
export const KIRO_TRANSCRIPT_MAX_WORKERS = 2;
|
|
4
6
|
function createIsolate() {
|
|
5
7
|
return import.meta.url.endsWith(".ts")
|
|
6
8
|
? new Worker(`const { workerData } = require("node:worker_threads"); import("tsx/esm/api").then(({ tsImport }) => tsImport(workerData.entry, workerData.entry));`, { eval: true, execArgv: [], workerData: { entry: new URL("./kiro-transcript-worker.ts", import.meta.url).href } })
|
|
7
9
|
: new Worker(new URL("./kiro-transcript-worker.js", import.meta.url), { execArgv: [] });
|
|
8
10
|
}
|
|
9
|
-
/** One
|
|
10
|
-
*
|
|
11
|
-
*
|
|
11
|
+
/** One active isolate, one queued/in-flight request per source, warm RO handles.
|
|
12
|
+
* A retired isolate stops owning reads immediately, but keeps its physical slot
|
|
13
|
+
* until exit. One spare slot allows recovery from a stuck native call without a
|
|
14
|
+
* worker herd. If both slots are stuck, requests keep their original deadlines.
|
|
12
15
|
*/
|
|
13
16
|
export class KiroTranscriptLane {
|
|
14
17
|
factory;
|
|
15
18
|
now;
|
|
16
19
|
worker = null;
|
|
17
|
-
|
|
20
|
+
physical = new Set();
|
|
18
21
|
owners = new Set();
|
|
19
22
|
pending = new Map();
|
|
20
23
|
nextId = 0;
|
|
@@ -52,54 +55,89 @@ export class KiroTranscriptLane {
|
|
|
52
55
|
this.pending.delete(id);
|
|
53
56
|
clearTimeout(request.timer);
|
|
54
57
|
request.resolve(reply);
|
|
55
|
-
if (!this.pending.
|
|
56
|
-
|
|
58
|
+
if (request.worker && ![...this.pending.values()].some(other => other.worker === request.worker))
|
|
59
|
+
request.worker.unref();
|
|
57
60
|
}
|
|
58
|
-
recycle() {
|
|
59
|
-
|
|
60
|
-
if (!worker || this.exiting)
|
|
61
|
+
recycle(worker = this.worker) {
|
|
62
|
+
if (!worker || this.worker !== worker)
|
|
61
63
|
return;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
// Detach before settling promises: no continuation or old event may use it.
|
|
65
|
+
this.worker = null;
|
|
66
|
+
for (const [id, request] of this.pending)
|
|
67
|
+
if (request.worker === worker)
|
|
68
|
+
this.settle(id, null);
|
|
69
|
+
// Only the exact exit listener releases its physical reservation. Neither
|
|
70
|
+
// a resolved nor a rejected termination promise proves the native call left.
|
|
66
71
|
try {
|
|
67
72
|
void worker.terminate().catch(() => { });
|
|
68
73
|
}
|
|
69
74
|
catch { /* retain physical reservation */ }
|
|
75
|
+
// Native Worker.terminate() calls ref(); undo it after the attempt so a
|
|
76
|
+
// stuck retiree cannot keep daemon shutdown alive by itself.
|
|
77
|
+
worker.unref();
|
|
78
|
+
this.dispatch();
|
|
70
79
|
}
|
|
71
80
|
ensureWorker() {
|
|
72
81
|
if (this.worker)
|
|
73
82
|
return this.worker;
|
|
83
|
+
if (this.physical.size >= KIRO_TRANSCRIPT_MAX_WORKERS)
|
|
84
|
+
return null;
|
|
74
85
|
const worker = this.factory();
|
|
86
|
+
this.physical.add(worker);
|
|
75
87
|
this.worker = worker;
|
|
76
88
|
worker.on("message", (message) => {
|
|
77
|
-
if (this.worker !== worker
|
|
89
|
+
if (this.worker !== worker)
|
|
78
90
|
return;
|
|
79
91
|
const request = this.pending.get(message.id);
|
|
80
|
-
if (!request)
|
|
92
|
+
if (!request || request.worker !== worker)
|
|
81
93
|
return;
|
|
82
94
|
if (this.now() >= request.deadlineAt) {
|
|
83
95
|
this.settle(message.id, null);
|
|
84
|
-
this.recycle();
|
|
96
|
+
this.recycle(worker);
|
|
85
97
|
}
|
|
86
98
|
else
|
|
87
99
|
this.settle(message.id, message.reply);
|
|
88
100
|
});
|
|
89
|
-
worker.on("error", () =>
|
|
90
|
-
this.recycle(); });
|
|
101
|
+
worker.on("error", () => this.recycle(worker));
|
|
91
102
|
worker.on("exit", () => {
|
|
92
|
-
if (this.worker
|
|
93
|
-
return;
|
|
94
|
-
this.worker
|
|
95
|
-
|
|
103
|
+
if (!this.physical.delete(worker))
|
|
104
|
+
return; // late/duplicate exit owns only itself
|
|
105
|
+
if (this.worker === worker)
|
|
106
|
+
this.worker = null;
|
|
96
107
|
for (const [id, request] of this.pending)
|
|
97
108
|
if (request.worker === worker)
|
|
98
109
|
this.settle(id, null);
|
|
110
|
+
this.dispatch();
|
|
99
111
|
});
|
|
100
112
|
worker.unref();
|
|
101
113
|
return worker;
|
|
102
114
|
}
|
|
115
|
+
dispatch() {
|
|
116
|
+
for (const [id, request] of this.pending) {
|
|
117
|
+
if (request.worker)
|
|
118
|
+
continue;
|
|
119
|
+
if (!this.owners.has(request.owner) || this.now() >= request.deadlineAt) {
|
|
120
|
+
this.settle(id, null);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const worker = this.ensureWorker();
|
|
125
|
+
if (!worker)
|
|
126
|
+
return; // physical cap; exit will wake the original queue
|
|
127
|
+
if (this.now() >= request.deadlineAt) {
|
|
128
|
+
this.settle(id, null);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
request.worker = worker;
|
|
132
|
+
worker.ref();
|
|
133
|
+
worker.postMessage({ id, owner: request.owner, deadlineAt: request.deadlineAt, input: request.input });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
this.settle(id, null);
|
|
137
|
+
this.recycle();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
103
141
|
read(owner, input) {
|
|
104
142
|
if (!this.owners.has(owner))
|
|
105
143
|
return Promise.resolve(null);
|
|
@@ -109,31 +147,15 @@ export class KiroTranscriptLane {
|
|
|
109
147
|
const id = ++this.nextId, deadlineAt = this.now() + KIRO_TRANSCRIPT_BUDGET_MS;
|
|
110
148
|
let resolve;
|
|
111
149
|
const promise = new Promise(done => { resolve = done; });
|
|
112
|
-
const request = { owner, deadlineAt, promise, resolve, timer: setTimeout(() => {
|
|
150
|
+
const request = { owner, deadlineAt, promise, resolve, input, timer: setTimeout(() => {
|
|
151
|
+
if (!this.pending.has(id))
|
|
152
|
+
return;
|
|
113
153
|
this.settle(id, null);
|
|
114
|
-
|
|
154
|
+
if (request.worker)
|
|
155
|
+
this.recycle(request.worker);
|
|
115
156
|
}, KIRO_TRANSCRIPT_BUDGET_MS) };
|
|
116
157
|
this.pending.set(id, request);
|
|
117
|
-
|
|
118
|
-
if (this.exiting)
|
|
119
|
-
await this.exiting;
|
|
120
|
-
if (!this.pending.has(id) || !this.owners.has(owner))
|
|
121
|
-
return;
|
|
122
|
-
if (this.now() >= deadlineAt) {
|
|
123
|
-
this.settle(id, null);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
const worker = this.ensureWorker();
|
|
128
|
-
request.worker = worker;
|
|
129
|
-
worker.ref();
|
|
130
|
-
worker.postMessage({ id, owner, deadlineAt, input });
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
this.settle(id, null);
|
|
134
|
-
this.recycle();
|
|
135
|
-
}
|
|
136
|
-
})();
|
|
158
|
+
this.dispatch();
|
|
137
159
|
return promise;
|
|
138
160
|
}
|
|
139
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kiro-transcript-lane.js","sourceRoot":"","sources":["../src/kiro-transcript-lane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAI9C,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"kiro-transcript-lane.js","sourceRoot":"","sources":["../src/kiro-transcript-lane.ts"],"names":[],"mappings":"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"}
|
package/dist/locale.js
CHANGED
|
@@ -84,6 +84,34 @@ const enMessages = {
|
|
|
84
84
|
"dashboard.public_cleanup": "⚠️ Public web access is closed, but the tunnel process could not be confirmed stopped. Resolve its cleanup before opening another link.",
|
|
85
85
|
"dashboard.private_link": "🔐 Web sign-in\n{0}\nCode: {1} (single use, {2} minutes)\nLink expires: {3}\nDo not forward. Use /dashboard revoke to sign out everyone and close the public link.",
|
|
86
86
|
"dashboard.private_sent": "🔐 Sign-in details sent privately.",
|
|
87
|
+
"dashboard.private_sent_dm": "🔐 Sign-in details sent to you by DM.",
|
|
88
|
+
"dashboard.progress.title": "🌐 Opening a temporary public link · {0} s",
|
|
89
|
+
"dashboard.progress.seconds": "{0} s",
|
|
90
|
+
"dashboard.progress.check": "Check cloudflared",
|
|
91
|
+
"dashboard.progress.check_download": "cloudflared is not installed: fetching the pinned {0}",
|
|
92
|
+
"dashboard.progress.download": "Download cloudflared",
|
|
93
|
+
"dashboard.progress.download_of": "Download cloudflared: {0} / {1} MB",
|
|
94
|
+
"dashboard.progress.download_bytes": "Download cloudflared: {0} MB",
|
|
95
|
+
"dashboard.progress.verify": "Verify the file (pinned version and SHA256)",
|
|
96
|
+
"dashboard.progress.tunnel": "Start the tunnel",
|
|
97
|
+
"dashboard.progress.address": "Wait for the public address to answer",
|
|
98
|
+
"dashboard.progress.deliver": "Send you the link privately",
|
|
99
|
+
"dashboard.progress.fail.unsupported-platform": "no pinned cloudflared exists for this platform",
|
|
100
|
+
"dashboard.progress.fail.download-failed": "the download did not complete (network, proxy or GitHub)",
|
|
101
|
+
"dashboard.progress.fail.checksum-mismatch": "the file did not match the pinned SHA256 and was deleted",
|
|
102
|
+
"dashboard.progress.fail.install-failed": "it could not be saved in AgEnD's bin directory",
|
|
103
|
+
"dashboard.progress.fail.cancelled": "cancelled",
|
|
104
|
+
"dashboard.progress.fail.spawn-failed": "cloudflared could not be started",
|
|
105
|
+
"dashboard.progress.fail.no-address": "Cloudflare gave no public address in time",
|
|
106
|
+
"dashboard.progress.fail.unreachable": "the public address never reached this fleet",
|
|
107
|
+
"dashboard.progress.fail.lease-held": "another tunnel is still running (a /login link, or one whose cleanup is unconfirmed)",
|
|
108
|
+
"dashboard.progress.fail.gateway-failed": "the local gateway could not start",
|
|
109
|
+
"dashboard.progress.fail.delivery-failed": "the link could not be delivered privately, so it was closed",
|
|
110
|
+
"dashboard.progress.fail.closed": "the link was closed while it was starting",
|
|
111
|
+
"dashboard.progress.fail.unknown": "it stopped unexpectedly",
|
|
112
|
+
"dashboard.private_sent_here": "🔐 The bot could not DM you, so your sign-in details are posted here, visible only to you.",
|
|
113
|
+
"dashboard.private_sending": "⏳ Sending your sign-in details privately…",
|
|
114
|
+
"dashboard.menu_failed": "⚠️ The /dashboard menu could not be shown. Run /dashboard again.",
|
|
87
115
|
"dashboard.private_failed": "Private delivery or link startup was not confirmed. On Telegram, /start this bot privately first, then retry /dashboard. No sign-in code is posted here.",
|
|
88
116
|
"web.public_login_notice": "🔐 New web sign-in · public: {0} (session {1}). If this was not you, use /dashboard revoke.",
|
|
89
117
|
"dashboard.title": "📊 AgEnD Dashboard",
|
|
@@ -261,6 +289,11 @@ const enMessages = {
|
|
|
261
289
|
"buttons.stale_notice": "⌛ This prompt has expired. Run the command again for a new one.",
|
|
262
290
|
"buttons.admin_only": "⛔ Only a fleet admin can use this button.",
|
|
263
291
|
"buttons.not_allowed": "⛔ You can't use this button.",
|
|
292
|
+
"reply_buttons.chosen": "✓ {0} — {1}",
|
|
293
|
+
"reply_buttons.expired": "⌛ Expired — reply in text",
|
|
294
|
+
"reply_buttons.answered": "Already answered.",
|
|
295
|
+
"reply_buttons.closed": "This choice is closed — reply in text.",
|
|
296
|
+
"reply_buttons.sent": "Sent: {0}",
|
|
264
297
|
"menu.click_stale": "⚠️ Nothing was changed: the instance moved to another bot, or you are no longer an admin there. Open the menu again.",
|
|
265
298
|
"buttons.wrong_place": "⚠️ This button does not match the prompt it belongs to. Run the command again.",
|
|
266
299
|
"buttons.post_failed": "⚠️ Could not post the buttons: {0}",
|
|
@@ -652,6 +685,8 @@ const enMessages = {
|
|
|
652
685
|
"usage.error.unreachable": "Could not reach {0}.",
|
|
653
686
|
"usage.error.token_rejected": "Token rejected. Run `{0}` once to refresh the login.",
|
|
654
687
|
"usage.error.rate_limited": "Rate limited by {0} — try again later.",
|
|
688
|
+
"usage.error.rate_limited_transient": "{0}: can't fetch usage right now (rate limited by {0}). This does not affect your agents.",
|
|
689
|
+
"usage.stale_rate_limited": "data from {0} min ago — can't refresh right now",
|
|
655
690
|
"usage.error.http": "Usage request failed (HTTP {0}).",
|
|
656
691
|
"usage.error.billing_http": "Billing request failed (HTTP {0}).",
|
|
657
692
|
"usage.error.invalid_response": "Invalid response from usage endpoint.",
|
|
@@ -693,6 +728,7 @@ const enMessages = {
|
|
|
693
728
|
"model.switching": "⏳ Switching {0} to `{1}`…",
|
|
694
729
|
"model.switch_failed": "Model switch to `{0}` failed: {1}",
|
|
695
730
|
"model.pattern_warning": "⚠️ \"{0}\" does not match {1}'s usual pattern — passing through anyway.\n",
|
|
731
|
+
"model.invalid_chars": "❌ Model name must not contain newlines or control characters.",
|
|
696
732
|
"model.persist_failed": "❌ Could not set model for {0}.",
|
|
697
733
|
"model.runtime_success": "✅ Switched {0} to `{1}` (runtime).",
|
|
698
734
|
"model.restart_success": "✅ Set {0} to `{1}` and restarted.",
|
|
@@ -761,6 +797,11 @@ const enMessages = {
|
|
|
761
797
|
"storm.recovered": "✅ tmux recovery finished: {0}/{1} instances recovered. Unresolved: {2}.",
|
|
762
798
|
"storm.timed_out": "⚠️ tmux recovery timed out: {0}/{1} instances recovered. Unresolved: {2}.",
|
|
763
799
|
"storm.none": "none",
|
|
800
|
+
"delivery.outbox_unavailable": "Delivery queue unavailable: {0}. {1} AgEnD does not quarantine or reset the queue; fleet startup and new message delivery stop until it can be opened. Do not delete or reset this queue: it contains pending messages and submission evidence.",
|
|
801
|
+
"delivery.outbox_corrupt": "SQLite reports corruption. Stop AgEnD before backing up the database together with its -wal and -shm files; restore a trusted backup or repair a copy before explicitly replacing it.",
|
|
802
|
+
"delivery.outbox_busy": "Another process holds a SQLite lock beyond the open timeout. Check for another AgEnD process or database tool, let its transaction finish, then retry startup.",
|
|
803
|
+
"delivery.outbox_abi": "The SQLite native driver cannot load on this Node.js or architecture. Reinstall AgEnD with its supported runtime (agend update --force), then retry startup; replacing the database will not fix the driver.",
|
|
804
|
+
"delivery.outbox_other": "Check the underlying error in daemon.log, the data-directory permissions, disk space and storage I/O, then retry startup.",
|
|
764
805
|
"eventlog.locked": "⚠️ events.db stayed locked by another process for 5 s, so it was not opened. The file was left untouched; event logging is off until AgEnD restarts.",
|
|
765
806
|
"eventlog.abi": "⚠️ events.db could not be opened because AgEnD's SQLite driver does not load on this Node.js (it was built for another version or architecture). The file was left untouched. Reinstall AgEnD (or run `npm rebuild better-sqlite3` in its package) and restart.",
|
|
766
807
|
"eventlog.unopenable": "⚠️ events.db could not be opened (permissions, disk or I/O — see daemon.log). The file was left untouched; event logging is off until AgEnD restarts.",
|
|
@@ -919,6 +960,34 @@ const zhTWMessages = {
|
|
|
919
960
|
"dashboard.public_cleanup": "⚠️ 公開網頁入口已關閉,但無法確認 tunnel 行程已停止。請先處理清理問題,再開新連結。",
|
|
920
961
|
"dashboard.private_link": "🔐 網頁登入\n{0}\n登入碼:{1}(只能用一次,{2} 分鐘內有效)\n連結期限:{3}\n不要轉傳。/dashboard revoke 會登出所有瀏覽器並關閉公開連結。",
|
|
921
962
|
"dashboard.private_sent": "🔐 登入資訊已私送。",
|
|
963
|
+
"dashboard.private_sent_dm": "🔐 登入資訊已私訊給你。",
|
|
964
|
+
"dashboard.progress.title": "🌐 正在開啟臨時公開連結 · {0} 秒",
|
|
965
|
+
"dashboard.progress.seconds": "{0} 秒",
|
|
966
|
+
"dashboard.progress.check": "檢查 cloudflared",
|
|
967
|
+
"dashboard.progress.check_download": "尚未安裝 cloudflared:下載固定版本 {0}",
|
|
968
|
+
"dashboard.progress.download": "下載 cloudflared",
|
|
969
|
+
"dashboard.progress.download_of": "下載 cloudflared:{0} / {1} MB",
|
|
970
|
+
"dashboard.progress.download_bytes": "下載 cloudflared:{0} MB",
|
|
971
|
+
"dashboard.progress.verify": "驗證檔案(固定版本與 SHA256)",
|
|
972
|
+
"dashboard.progress.tunnel": "啟動 tunnel",
|
|
973
|
+
"dashboard.progress.address": "等待公開網址可以連上",
|
|
974
|
+
"dashboard.progress.deliver": "私送連結給你",
|
|
975
|
+
"dashboard.progress.fail.unsupported-platform": "這個平台沒有固定版本的 cloudflared",
|
|
976
|
+
"dashboard.progress.fail.download-failed": "下載沒有完成(網路、proxy 或 GitHub)",
|
|
977
|
+
"dashboard.progress.fail.checksum-mismatch": "檔案與固定的 SHA256 不符,已刪除",
|
|
978
|
+
"dashboard.progress.fail.install-failed": "無法存進 AgEnD 的 bin 目錄",
|
|
979
|
+
"dashboard.progress.fail.cancelled": "已取消",
|
|
980
|
+
"dashboard.progress.fail.spawn-failed": "無法啟動 cloudflared",
|
|
981
|
+
"dashboard.progress.fail.no-address": "Cloudflare 沒有及時給出公開網址",
|
|
982
|
+
"dashboard.progress.fail.unreachable": "公開網址一直連不到這個 fleet",
|
|
983
|
+
"dashboard.progress.fail.lease-held": "還有另一個 tunnel 在執行(/login 的連結,或尚未確認清理的連結)",
|
|
984
|
+
"dashboard.progress.fail.gateway-failed": "本機 gateway 無法啟動",
|
|
985
|
+
"dashboard.progress.fail.delivery-failed": "連結無法私送,已關閉",
|
|
986
|
+
"dashboard.progress.fail.closed": "連結在啟動途中被關閉",
|
|
987
|
+
"dashboard.progress.fail.unknown": "意外中止",
|
|
988
|
+
"dashboard.private_sent_here": "🔐 bot 無法私訊你,登入資訊改貼在這裡,只有你看得到。",
|
|
989
|
+
"dashboard.private_sending": "⏳ 正在私送登入資訊…",
|
|
990
|
+
"dashboard.menu_failed": "⚠️ 無法顯示 /dashboard 選單,請再執行一次 /dashboard。",
|
|
922
991
|
"dashboard.private_failed": "無法確認私送或連結啟動。Telegram 請先私訊這個 bot 的 /start,再重試 /dashboard。此處不會貼出登入碼。",
|
|
923
992
|
"web.public_login_notice": "🔐 有新的網頁登入 · 公開入口:{0}(session {1})。如果不是你,請用 /dashboard revoke。",
|
|
924
993
|
"dashboard.title": "📊 AgEnD 儀表板",
|
|
@@ -1096,6 +1165,11 @@ const zhTWMessages = {
|
|
|
1096
1165
|
"buttons.stale_notice": "⌛ 此提示已逾時,請重新執行指令取得新的提示。",
|
|
1097
1166
|
"buttons.admin_only": "⛔ 只有 fleet 管理員可以使用這個按鈕。",
|
|
1098
1167
|
"buttons.not_allowed": "⛔ 你無法使用這個按鈕。",
|
|
1168
|
+
"reply_buttons.chosen": "✓ {0} — {1}",
|
|
1169
|
+
"reply_buttons.expired": "⌛ 已逾時,請直接回覆文字",
|
|
1170
|
+
"reply_buttons.answered": "已經有人回答了。",
|
|
1171
|
+
"reply_buttons.closed": "這個選項已關閉,請直接回覆文字。",
|
|
1172
|
+
"reply_buttons.sent": "已送出:{0}",
|
|
1099
1173
|
"menu.click_stale": "⚠️ 沒有變更:這個 instance 已移到另一個 bot,或你已不再是那裡的管理員。請重新開啟選單。",
|
|
1100
1174
|
"buttons.wrong_place": "⚠️ 這個按鈕和它所屬的提示對不上,請重新執行指令。",
|
|
1101
1175
|
"buttons.post_failed": "⚠️ 無法送出按鈕:{0}",
|
|
@@ -1487,6 +1561,8 @@ const zhTWMessages = {
|
|
|
1487
1561
|
"usage.error.unreachable": "無法連線至 {0}。",
|
|
1488
1562
|
"usage.error.token_rejected": "Token 已被拒絕。請執行一次 `{0}` 以更新登入。",
|
|
1489
1563
|
"usage.error.rate_limited": "{0} 暫時限制請求速率,請稍後再試。",
|
|
1564
|
+
"usage.error.rate_limited_transient": "暫時查不到 {0} 用量({0} 限制查詢頻率),不影響你的 agent。",
|
|
1565
|
+
"usage.stale_rate_limited": "{0} 分鐘前的資料,暫時無法更新",
|
|
1490
1566
|
"usage.error.http": "用量請求失敗(HTTP {0})。",
|
|
1491
1567
|
"usage.error.billing_http": "計費請求失敗(HTTP {0})。",
|
|
1492
1568
|
"usage.error.invalid_response": "用量端點回傳了無效資料。",
|
|
@@ -1528,6 +1604,7 @@ const zhTWMessages = {
|
|
|
1528
1604
|
"model.switching": "⏳ 正在將 {0} 切換到 `{1}`…",
|
|
1529
1605
|
"model.switch_failed": "切換至模型 `{0}` 失敗:{1}",
|
|
1530
1606
|
"model.pattern_warning": "⚠️ \"{0}\" 不符合 {1} 常見的模型名稱格式 — 仍會原樣傳給 CLI。\n",
|
|
1607
|
+
"model.invalid_chars": "❌ 模型名稱不得包含換行或控制字元。",
|
|
1531
1608
|
"model.persist_failed": "❌ 無法設定 {0} 的模型。",
|
|
1532
1609
|
"model.runtime_success": "✅ 已即時將 {0} 切換到 `{1}`。",
|
|
1533
1610
|
"model.restart_success": "✅ 已將 {0} 設為 `{1}` 並重啟。",
|
|
@@ -1596,6 +1673,11 @@ const zhTWMessages = {
|
|
|
1596
1673
|
"storm.recovered": "✅ tmux 恢復完成:{0}/{1} 個 instance 已恢復。尚未恢復:{2}。",
|
|
1597
1674
|
"storm.timed_out": "⚠️ tmux 恢復逾時:{0}/{1} 個 instance 已恢復。尚未恢復:{2}。",
|
|
1598
1675
|
"storm.none": "無",
|
|
1676
|
+
"delivery.outbox_unavailable": "投遞佇列無法開啟:{0}。{1} AgEnD 不會隔離或重設佇列;在能開啟前,fleet 啟動與新訊息投遞均停止。請勿刪除或重設佇列:它保存待送訊息與提交證據。",
|
|
1677
|
+
"delivery.outbox_corrupt": "SQLite 回報毀損。先停止 AgEnD,再一併備份資料庫及 -wal、-shm 檔案;明確替換前,請還原可信備份或修復副本。",
|
|
1678
|
+
"delivery.outbox_busy": "其他行程持有 SQLite 鎖超過開檔逾時。檢查另一個 AgEnD 行程或資料庫工具,待其 transaction 完成後重試啟動。",
|
|
1679
|
+
"delivery.outbox_abi": "SQLite 原生驅動無法在這個 Node.js 或架構載入。請以 AgEnD 支援的 runtime 重新安裝(agend update --force),再重試啟動;替換資料庫不能修復驅動。",
|
|
1680
|
+
"delivery.outbox_other": "請查看 daemon.log 的原始錯誤,檢查資料目錄權限、磁碟空間與儲存 I/O,再重試啟動。",
|
|
1599
1681
|
"eventlog.locked": "⚠️ events.db 被其他行程鎖住超過 5 秒,因此沒有開啟。檔案原封不動;在 AgEnD 重新啟動前,事件紀錄暫停。",
|
|
1600
1682
|
"eventlog.abi": "⚠️ events.db 無法開啟:AgEnD 的 SQLite 驅動在這個 Node.js 上載入失敗(是為其他版本或架構編譯的)。檔案原封不動。請重新安裝 AgEnD(或在套件目錄執行 `npm rebuild better-sqlite3`)後重新啟動。",
|
|
1601
1683
|
"eventlog.unopenable": "⚠️ events.db 無法開啟(權限、磁碟或 I/O 問題,詳見 daemon.log)。檔案原封不動;在 AgEnD 重新啟動前,事件紀錄暫停。",
|