@songsid/agend 2.1.12-beta.3 → 2.1.12-beta.5
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 +54 -8
- package/README.zh-TW.md +104 -11
- package/dist/agent-endpoint.d.ts +2 -0
- package/dist/agent-endpoint.js +38 -29
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/factory.js +5 -5
- package/dist/backend/factory.js.map +1 -1
- package/dist/backend/index.d.ts +0 -1
- package/dist/backend/index.js +0 -1
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/kiro.d.ts +10 -1
- package/dist/backend/kiro.js +13 -0
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/mock.d.ts +1 -1
- package/dist/backend/mock.js +1 -1
- package/dist/backend/muse.d.ts +14 -0
- package/dist/backend/muse.js +60 -11
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/removed.d.ts +12 -0
- package/dist/backend/removed.js +18 -0
- package/dist/backend/removed.js.map +1 -0
- package/dist/backend/session-signals.js +5 -10
- package/dist/backend/session-signals.js.map +1 -1
- package/dist/backend/types.d.ts +1 -1
- package/dist/backend/types.js +0 -1
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.js +9 -0
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +14 -8
- package/dist/channel/adapters/telegram.js +80 -26
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -2
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/classic-channel-manager.js +2 -2
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +27 -53
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +1 -1
- package/dist/command-table.js +4 -2
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +82 -10
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +7 -5
- package/dist/config.js.map +1 -1
- package/dist/context-guardian.d.ts +1 -1
- package/dist/context-guardian.js +1 -1
- package/dist/cross-instance-notice.d.ts +39 -0
- package/dist/cross-instance-notice.js +84 -0
- package/dist/cross-instance-notice.js.map +1 -0
- package/dist/daemon.d.ts +6 -0
- package/dist/daemon.js +54 -42
- package/dist/daemon.js.map +1 -1
- package/dist/daily-summary.js +0 -3
- package/dist/daily-summary.js.map +1 -1
- package/dist/fleet-manager.d.ts +16 -3
- package/dist/fleet-manager.js +110 -53
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -1
- package/dist/instance-config-impact.js +3 -0
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +9 -1
- package/dist/instance-lifecycle.js +66 -7
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +28 -2
- package/dist/locale.js.map +1 -1
- package/dist/memory-pressure.d.ts +8 -2
- package/dist/memory-pressure.js +10 -4
- package/dist/memory-pressure.js.map +1 -1
- package/dist/outbound-handlers.js +36 -23
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +0 -1
- package/dist/outbound-schemas.js +4 -4
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/prompt-file-ref.d.ts +42 -0
- package/dist/prompt-file-ref.js +118 -0
- package/dist/prompt-file-ref.js.map +1 -0
- package/dist/reply-dedup.d.ts +5 -0
- package/dist/reply-dedup.js +9 -0
- package/dist/reply-dedup.js.map +1 -1
- package/dist/settings-api.js +5 -1
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-wizard.js +0 -4
- package/dist/setup-wizard.js.map +1 -1
- package/dist/spawn-gate.js +4 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/target-queue-worker.d.ts +1 -1
- package/dist/topic-commands.d.ts +64 -5
- package/dist/topic-commands.js +172 -14
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-jsonl.d.ts +12 -0
- package/dist/transcript-jsonl.js +37 -0
- package/dist/transcript-jsonl.js.map +1 -1
- package/dist/transcript-monitor.js +10 -7
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -1
- package/dist/transcript-sources.js +29 -11
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +13 -4
- package/dist/ui/dashboard.html +3 -3
- package/dist/ui/settings.html +58 -16
- package/dist/update-check.d.ts +15 -6
- package/dist/update-check.js +20 -7
- package/dist/update-check.js.map +1 -1
- package/dist/wake-coordinator.js +1 -1
- package/dist/web-api.js +1 -2
- package/dist/web-api.js.map +1 -1
- package/package.json +1 -1
- package/dist/backend/gemini-cli.d.ts +0 -20
- package/dist/backend/gemini-cli.js +0 -169
- package/dist/backend/gemini-cli.js.map +0 -1
package/dist/spawn-gate.js
CHANGED
|
@@ -21,7 +21,7 @@ export class SpawnGate {
|
|
|
21
21
|
memoryPressure;
|
|
22
22
|
stopMemoryUpdates;
|
|
23
23
|
onMemoryUpdate = (snapshot) => {
|
|
24
|
-
if (!this.memoryPressure.
|
|
24
|
+
if (!this.memoryPressure.advisoryOnly())
|
|
25
25
|
return;
|
|
26
26
|
this.pressureHeld = false;
|
|
27
27
|
this.pressureRetryMs = 5_000;
|
|
@@ -84,7 +84,8 @@ export class SpawnGate {
|
|
|
84
84
|
if (this.nestedQueue.length === 0 && index < 0)
|
|
85
85
|
return;
|
|
86
86
|
// Explicit zero preserves the existing deterministic test/embedding opt-out.
|
|
87
|
-
|
|
87
|
+
// macOS memory is advisory (#1256): admission neither waits for a sample nor reads one.
|
|
88
|
+
const sample = this.options.lowMemoryBytes === 0 || this.memoryPressure.advisoryOnly() ? null : this.memoryPressure.sampleForAdmission();
|
|
88
89
|
if (sample instanceof Promise) {
|
|
89
90
|
this.awaitingMemory = true;
|
|
90
91
|
void sample.finally(() => {
|
|
@@ -94,7 +95,7 @@ export class SpawnGate {
|
|
|
94
95
|
});
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
|
-
let pressure = sample === null
|
|
98
|
+
let pressure = sample === null ? "normal" : sample.level;
|
|
98
99
|
if (this.stopped)
|
|
99
100
|
return;
|
|
100
101
|
if (pressure === "critical") {
|
package/dist/spawn-gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn-gate.js","sourceRoot":"","sources":["../src/spawn-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAA+B,MAAM,sBAAsB,CAAC;AA2BnF,qFAAqF;AACrF,MAAM,OAAO,SAAS;IAgCS;IA/BrB,KAAK,GAAiB,EAAE,CAAC;IACzB,WAAW,GAAiB,EAAE,CAAC;IAC/B,MAAM,GAAG,CAAC,CAAC;IACX,cAAc,GAAG,CAAC,CAAC;IACnB,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,aAAa,GAAG,CAAC,CAAC;IAClB,KAAK,GAAyC,IAAI,CAAC;IACnD,YAAY,GAAG,KAAK,CAAC;IACrB,UAAU,GAAG,KAAK,CAAC;IACnB,OAAO,GAAG,KAAK,CAAC;IAChB,OAAO,GAAG,KAAK,CAAC;IAChB,cAAc,GAAG,KAAK,CAAC;IACvB,eAAe,GAAG,KAAK,CAAC;IACxB,YAAY,GAAG,KAAK,CAAC;IACZ,MAAM,CAAe;IACrB,cAAc,CAAiB;IAC/B,iBAAiB,CAAa;IAC9B,cAAc,GAAG,CAAC,QAAgC,EAAE,EAAE;QACrE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"spawn-gate.js","sourceRoot":"","sources":["../src/spawn-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Phase 2c (docs/design/
|
|
2
|
+
* Phase 2c (docs/design/929-durable-outbox.md §4): the
|
|
3
3
|
* per-target owner of a durable delivery lane when `delivery_worker: on`.
|
|
4
4
|
*
|
|
5
5
|
* ENSURE_AWAKE belongs to the WakeCoordinator (2b); this worker only runs
|
package/dist/topic-commands.d.ts
CHANGED
|
@@ -10,6 +10,61 @@ type ExecutionFleetContext = FleetContext & {
|
|
|
10
10
|
};
|
|
11
11
|
/** Sanitize a directory name into a valid instance name. Keeps Unicode letters (incl. CJK). */
|
|
12
12
|
export declare function sanitizeInstanceName(name: string): string;
|
|
13
|
+
/** Digits of the topic id kept in a fresh instance-name suffix; lengthened on collision. */
|
|
14
|
+
export declare const INSTANCE_NAME_SUFFIX_DIGITS = 6;
|
|
15
|
+
/**
|
|
16
|
+
* Build `<base>-t<last N digits of topicId>` (#1301): when the full-id form
|
|
17
|
+
* is free, N starts at 6 and lengthens on collision, up to the full id.
|
|
18
|
+
* `exists` must cover fleet.yaml keys and instance dirs (a stale tmux window
|
|
19
|
+
* with no config or dir is an orphan that startup cleanup kills — the
|
|
20
|
+
* `-t<digits>` shape is what its matcher recognises). Every name this
|
|
21
|
+
* allocator emits matches the orphan predicate (`isOrphanInstanceWindowName`),
|
|
22
|
+
* so a deleted instance's leftover window is always reaped.
|
|
23
|
+
*
|
|
24
|
+
* A taken candidate is reused as-is ONLY when `isSameTopic` proves the
|
|
25
|
+
* existing entry belongs to this same topic (retry/rebind of a partially
|
|
26
|
+
* created instance keeps the deterministic old path instead of opening a
|
|
27
|
+
* second entry) — this applies to the full form and to every short or
|
|
28
|
+
* lengthened form, so a rebind never allocates a duplicate entry for one
|
|
29
|
+
* topic (#1305 P2-2). A name owned by a *different* topic — including a
|
|
30
|
+
* short suffix that happens to equal another topic's full id (e.g. Discord
|
|
31
|
+
* `blog-t123456` vs Telegram topic `123456`) — is never reused. When even
|
|
32
|
+
* the full-id form is taken by a different topic, allocation refuses with an
|
|
33
|
+
* error (use a different `topic_name`) instead of inventing a non-`-t<digits>`
|
|
34
|
+
* name, so one topic's bind can never overwrite another topic's
|
|
35
|
+
* `working_directory`/`topic_id` (#1305 P1). When `isSameTopic` is omitted
|
|
36
|
+
* the legacy rule applies (a taken full form is reused, taken short forms
|
|
37
|
+
* are skipped); production callers always pass it. A dir-only collision (no
|
|
38
|
+
* config) can never prove same-topic, so callers must report it as a
|
|
39
|
+
* different topic.
|
|
40
|
+
*/
|
|
41
|
+
export declare function uniqueInstanceName(base: string, topicId: number | string, exists: (name: string) => boolean, isSameTopic?: (name: string) => boolean): string;
|
|
42
|
+
/**
|
|
43
|
+
* Base user-facing label for one instance name (#1301): an explicit
|
|
44
|
+
* display_name wins; otherwise only a full snowflake-length `-t<digits>`
|
|
45
|
+
* suffix (19+ digits, the pre-2.1.12 form) is shortened to its last 6,
|
|
46
|
+
* keeping the `-t` shape. Allocator-lengthened suffixes (7–18 digits, #1301
|
|
47
|
+
* collision path) are shown whole. This is only the *base* label — two
|
|
48
|
+
* legacy 19-digit names sharing tail6 still shorten identically, so every
|
|
49
|
+
* fleet renderer must go through `assignDisplayLabels`, which disambiguates
|
|
50
|
+
* against the whole fleet (#1305 P2-1). Agent-facing uses (the `[from:…]`
|
|
51
|
+
* header, logs, lookups) keep the real name — agents address by it.
|
|
52
|
+
*/
|
|
53
|
+
export declare function displayInstanceName(name: string, displayName?: string | null): string;
|
|
54
|
+
/**
|
|
55
|
+
* Fleet-wide effective display labels (#1305 P2-1). The base label is
|
|
56
|
+
* shortened only while it stays unique across every entry's effective label
|
|
57
|
+
* — legacy (19-digit), new short, lengthened, and explicit `display_name`
|
|
58
|
+
* entries all compete in one namespace. On collision a `-t<digits>` name
|
|
59
|
+
* lengthens its shown tail just enough to be unique; an explicit
|
|
60
|
+
* `display_name` collision (or an exhausted digit tail) is qualified with the
|
|
61
|
+
* real name. Lookup names are untouched — only the shown label changes.
|
|
62
|
+
* Entries are processed in name order so the result is deterministic.
|
|
63
|
+
*/
|
|
64
|
+
export declare function assignDisplayLabels(entries: {
|
|
65
|
+
name: string;
|
|
66
|
+
displayName?: string | null;
|
|
67
|
+
}[]): Map<string, string>;
|
|
13
68
|
/** Allowed filename for /save and /load (no path separators, no shell/inject chars). */
|
|
14
69
|
export declare const SAVE_FILENAME_RE: RegExp;
|
|
15
70
|
/** Backends with a native side-question command that does not steer the active turn. */
|
|
@@ -210,11 +265,13 @@ export declare class TopicCommands {
|
|
|
210
265
|
private handleLoginCommand;
|
|
211
266
|
private handleTipsCommand;
|
|
212
267
|
private handleStatusCommand;
|
|
213
|
-
/**
|
|
214
|
-
* `-t<
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
|
|
268
|
+
/** Fleet-wide display labels for status/sysinfo tables (#1305 P2-1):
|
|
269
|
+
* display_name first, else a 19+-digit `-t<digits>` suffix shortened to its
|
|
270
|
+
* last 6 — lengthened only while the label stays unique across every
|
|
271
|
+
* instance, so same-tail legacy entries remain distinguishable. Keeps rows
|
|
272
|
+
* short so a large fleet's table fits Discord's 2000-char limit. The FULL
|
|
273
|
+
* name is still used for all lookups — only the displayed label changes. */
|
|
274
|
+
private displayLabels;
|
|
218
275
|
/** Get fleet status as markdown text (shared by TG + DC) */
|
|
219
276
|
getStatusText(): Promise<string>;
|
|
220
277
|
private handleSysInfoCommand;
|
|
@@ -240,6 +297,8 @@ export declare class TopicCommands {
|
|
|
240
297
|
backendCliVersions?: BackendCliVersionSnapshot;
|
|
241
298
|
}): string;
|
|
242
299
|
private handleUpdateCommand;
|
|
300
|
+
/** #1302: `/visibility [full|summary|hidden]` in the General topic. */
|
|
301
|
+
private handleVisibilityCommand;
|
|
243
302
|
private handleDoctorCommand;
|
|
244
303
|
/** Reply with redirect when message arrives in an unbound topic */
|
|
245
304
|
handleUnboundTopic(msg: InboundMessage): Promise<void>;
|
package/dist/topic-commands.js
CHANGED
|
@@ -11,6 +11,7 @@ import { truncateDisplay, MODEL_DISPLAY_WIDTH_MAX } from "./ls-rows.js";
|
|
|
11
11
|
import { getTmuxSocketName, getTmuxSessionName } from "./paths.js";
|
|
12
12
|
import { t, getLocale } from "./locale.js";
|
|
13
13
|
import { telegramMenu } from "./command-table.js";
|
|
14
|
+
import { runVisibilityCommand } from "./cross-instance-notice.js";
|
|
14
15
|
import { clampContextPercent, parseContextPercent, parseTokenContextRatio, } from "./context-percent.js";
|
|
15
16
|
import { isGeneralInstance } from "./general-instance.js";
|
|
16
17
|
import { backendSupportsSteer } from "./steer-capability.js";
|
|
@@ -25,6 +26,130 @@ export function sanitizeInstanceName(name) {
|
|
|
25
26
|
const sanitized = name.toLowerCase().replace(/[^\p{L}\d-]/gu, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
26
27
|
return sanitized || "project";
|
|
27
28
|
}
|
|
29
|
+
/** Digits of the topic id kept in a fresh instance-name suffix; lengthened on collision. */
|
|
30
|
+
export const INSTANCE_NAME_SUFFIX_DIGITS = 6;
|
|
31
|
+
/**
|
|
32
|
+
* Build `<base>-t<last N digits of topicId>` (#1301): when the full-id form
|
|
33
|
+
* is free, N starts at 6 and lengthens on collision, up to the full id.
|
|
34
|
+
* `exists` must cover fleet.yaml keys and instance dirs (a stale tmux window
|
|
35
|
+
* with no config or dir is an orphan that startup cleanup kills — the
|
|
36
|
+
* `-t<digits>` shape is what its matcher recognises). Every name this
|
|
37
|
+
* allocator emits matches the orphan predicate (`isOrphanInstanceWindowName`),
|
|
38
|
+
* so a deleted instance's leftover window is always reaped.
|
|
39
|
+
*
|
|
40
|
+
* A taken candidate is reused as-is ONLY when `isSameTopic` proves the
|
|
41
|
+
* existing entry belongs to this same topic (retry/rebind of a partially
|
|
42
|
+
* created instance keeps the deterministic old path instead of opening a
|
|
43
|
+
* second entry) — this applies to the full form and to every short or
|
|
44
|
+
* lengthened form, so a rebind never allocates a duplicate entry for one
|
|
45
|
+
* topic (#1305 P2-2). A name owned by a *different* topic — including a
|
|
46
|
+
* short suffix that happens to equal another topic's full id (e.g. Discord
|
|
47
|
+
* `blog-t123456` vs Telegram topic `123456`) — is never reused. When even
|
|
48
|
+
* the full-id form is taken by a different topic, allocation refuses with an
|
|
49
|
+
* error (use a different `topic_name`) instead of inventing a non-`-t<digits>`
|
|
50
|
+
* name, so one topic's bind can never overwrite another topic's
|
|
51
|
+
* `working_directory`/`topic_id` (#1305 P1). When `isSameTopic` is omitted
|
|
52
|
+
* the legacy rule applies (a taken full form is reused, taken short forms
|
|
53
|
+
* are skipped); production callers always pass it. A dir-only collision (no
|
|
54
|
+
* config) can never prove same-topic, so callers must report it as a
|
|
55
|
+
* different topic.
|
|
56
|
+
*/
|
|
57
|
+
export function uniqueInstanceName(base, topicId, exists, isSameTopic) {
|
|
58
|
+
const clean = sanitizeInstanceName(base);
|
|
59
|
+
const id = String(topicId);
|
|
60
|
+
const full = `${clean}-t${id}`;
|
|
61
|
+
const candidates = [];
|
|
62
|
+
for (let n = Math.min(INSTANCE_NAME_SUFFIX_DIGITS, id.length); n < id.length; n++) {
|
|
63
|
+
candidates.push(`${clean}-t${id.slice(-n)}`);
|
|
64
|
+
}
|
|
65
|
+
candidates.push(full);
|
|
66
|
+
// First pass: reuse any candidate already owned by this same topic
|
|
67
|
+
// (retry/rebind keeps the deterministic old path instead of opening a
|
|
68
|
+
// second entry). Every candidate is scanned before anything is allocated:
|
|
69
|
+
// a freed shorter form must not shadow a longer form this topic still owns.
|
|
70
|
+
// Without a proof function the legacy rule applies (a taken full form is
|
|
71
|
+
// reused, taken short forms are skipped).
|
|
72
|
+
for (const name of candidates) {
|
|
73
|
+
if (exists(name) && (isSameTopic?.(name) ?? name === full))
|
|
74
|
+
return name;
|
|
75
|
+
}
|
|
76
|
+
// Second pass: the first free candidate, short first.
|
|
77
|
+
for (const name of candidates) {
|
|
78
|
+
if (!exists(name))
|
|
79
|
+
return name;
|
|
80
|
+
}
|
|
81
|
+
// Even the full-id form is owned by a different topic: refuse. Callers
|
|
82
|
+
// surface this (handleCreate responds an error and rolls back the topic;
|
|
83
|
+
// bindAndStart throws), so creation fails closed with a clear hint.
|
|
84
|
+
throw new Error(`Instance name "${full}" is already used by a different topic; ` +
|
|
85
|
+
`use a different topic_name for topic "${id}".`);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Base user-facing label for one instance name (#1301): an explicit
|
|
89
|
+
* display_name wins; otherwise only a full snowflake-length `-t<digits>`
|
|
90
|
+
* suffix (19+ digits, the pre-2.1.12 form) is shortened to its last 6,
|
|
91
|
+
* keeping the `-t` shape. Allocator-lengthened suffixes (7–18 digits, #1301
|
|
92
|
+
* collision path) are shown whole. This is only the *base* label — two
|
|
93
|
+
* legacy 19-digit names sharing tail6 still shorten identically, so every
|
|
94
|
+
* fleet renderer must go through `assignDisplayLabels`, which disambiguates
|
|
95
|
+
* against the whole fleet (#1305 P2-1). Agent-facing uses (the `[from:…]`
|
|
96
|
+
* header, logs, lookups) keep the real name — agents address by it.
|
|
97
|
+
*/
|
|
98
|
+
export function displayInstanceName(name, displayName) {
|
|
99
|
+
const dn = displayName?.trim();
|
|
100
|
+
if (dn)
|
|
101
|
+
return dn;
|
|
102
|
+
return name.replace(/-t(\d{19,})$/, (_, digits) => `-t${digits.slice(-6)}`);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Fleet-wide effective display labels (#1305 P2-1). The base label is
|
|
106
|
+
* shortened only while it stays unique across every entry's effective label
|
|
107
|
+
* — legacy (19-digit), new short, lengthened, and explicit `display_name`
|
|
108
|
+
* entries all compete in one namespace. On collision a `-t<digits>` name
|
|
109
|
+
* lengthens its shown tail just enough to be unique; an explicit
|
|
110
|
+
* `display_name` collision (or an exhausted digit tail) is qualified with the
|
|
111
|
+
* real name. Lookup names are untouched — only the shown label changes.
|
|
112
|
+
* Entries are processed in name order so the result is deterministic.
|
|
113
|
+
*/
|
|
114
|
+
export function assignDisplayLabels(entries) {
|
|
115
|
+
const sorted = [...entries].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
116
|
+
const used = new Set();
|
|
117
|
+
const out = new Map();
|
|
118
|
+
for (const { name, displayName } of sorted) {
|
|
119
|
+
const explicit = displayName?.trim() || undefined;
|
|
120
|
+
let label = explicit ?? displayInstanceName(name);
|
|
121
|
+
if (used.has(label))
|
|
122
|
+
label = disambiguateLabel(name, explicit, label, used);
|
|
123
|
+
used.add(label);
|
|
124
|
+
out.set(name, label);
|
|
125
|
+
}
|
|
126
|
+
return out;
|
|
127
|
+
}
|
|
128
|
+
function disambiguateLabel(name, explicit, base, used) {
|
|
129
|
+
if (!explicit) {
|
|
130
|
+
const m = name.match(/^(.*-t)(\d+)$/);
|
|
131
|
+
if (m) {
|
|
132
|
+
const [, prefix, digits] = m;
|
|
133
|
+
const shown = digits.length >= 19 ? 6 : digits.length;
|
|
134
|
+
for (let len = shown + 1; len <= digits.length; len++) {
|
|
135
|
+
const candidate = `${prefix}${digits.slice(-len)}`;
|
|
136
|
+
if (!used.has(candidate))
|
|
137
|
+
return candidate;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Every fallback is checked against the same namespace: real names are
|
|
142
|
+
// unique, but they are NOT unique against arbitrary display_name strings,
|
|
143
|
+
// so even the real-name-shaped fallback must be verified. The numbered
|
|
144
|
+
// loop always terminates (i is unbounded) and is deterministic for a
|
|
145
|
+
// given fleet, since entries are processed in name order.
|
|
146
|
+
const short = displayInstanceName(name);
|
|
147
|
+
let candidate = `${base} (${short})`;
|
|
148
|
+
for (let i = 2; used.has(candidate); i++) {
|
|
149
|
+
candidate = `${base} (${short}) (#${i})`;
|
|
150
|
+
}
|
|
151
|
+
return candidate;
|
|
152
|
+
}
|
|
28
153
|
/** Allowed filename for /save and /load (no path separators, no shell/inject chars). */
|
|
29
154
|
export const SAVE_FILENAME_RE = /^[\w.-]+$/;
|
|
30
155
|
/** Backends with a native side-question command that does not steer the active turn. */
|
|
@@ -58,7 +183,7 @@ export function parsePauseWakeCommand(text) {
|
|
|
58
183
|
* The in-session compact/context-reset command for a backend NAME (the fleet
|
|
59
184
|
* process routes /compact via IPC and only has the backend string, not a
|
|
60
185
|
* CliBackend instance). Keep in sync with each backend's getCompactCommand().
|
|
61
|
-
* Most CLIs (claude-code, kiro-cli, codex, opencode
|
|
186
|
+
* Most CLIs (claude-code, kiro-cli, codex, opencode) use "/compact".
|
|
62
187
|
* Antigravity (agy) has NO summarizing compact — its only manual context-reset
|
|
63
188
|
* is "/clear" (a full reset; it also auto-summarizes at a token threshold).
|
|
64
189
|
*/
|
|
@@ -166,7 +291,6 @@ export function clearCommandForBackend(backend) {
|
|
|
166
291
|
return "/clear";
|
|
167
292
|
case "grok":
|
|
168
293
|
return "/new";
|
|
169
|
-
case "gemini-cli":
|
|
170
294
|
default:
|
|
171
295
|
return null;
|
|
172
296
|
}
|
|
@@ -393,6 +517,11 @@ export class TopicCommands {
|
|
|
393
517
|
await this.handleDashboardCommand(msg);
|
|
394
518
|
return true;
|
|
395
519
|
}
|
|
520
|
+
const visibility = text.match(/^\/visibility(?:@\S+)?(?:\s+([\s\S]*))?$/i);
|
|
521
|
+
if (visibility) {
|
|
522
|
+
await this.handleVisibilityCommand(msg, visibility[1] ?? "");
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
396
525
|
return false;
|
|
397
526
|
}
|
|
398
527
|
/**
|
|
@@ -1022,15 +1151,21 @@ export class TopicCommands {
|
|
|
1022
1151
|
const text = await this.getStatusText();
|
|
1023
1152
|
await adapter.sendText(msg.chatId, text, { threadId: msg.threadId });
|
|
1024
1153
|
}
|
|
1025
|
-
/**
|
|
1026
|
-
* `-t<
|
|
1027
|
-
*
|
|
1028
|
-
*
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1154
|
+
/** Fleet-wide display labels for status/sysinfo tables (#1305 P2-1):
|
|
1155
|
+
* display_name first, else a 19+-digit `-t<digits>` suffix shortened to its
|
|
1156
|
+
* last 6 — lengthened only while the label stays unique across every
|
|
1157
|
+
* instance, so same-tail legacy entries remain distinguishable. Keeps rows
|
|
1158
|
+
* short so a large fleet's table fits Discord's 2000-char limit. The FULL
|
|
1159
|
+
* name is still used for all lookups — only the displayed label changes. */
|
|
1160
|
+
displayLabels() {
|
|
1161
|
+
const instances = this.ctx.fleetConfig?.instances ?? {};
|
|
1162
|
+
const names = new Set(Object.keys(instances));
|
|
1163
|
+
for (const ch of this.ctx.classicChannels?.getAll() ?? [])
|
|
1164
|
+
names.add(ch.instanceName);
|
|
1165
|
+
return assignDisplayLabels([...names].map((name) => ({
|
|
1166
|
+
name,
|
|
1167
|
+
displayName: instances[name]?.display_name,
|
|
1168
|
+
})));
|
|
1034
1169
|
}
|
|
1035
1170
|
/** Get fleet status as markdown text (shared by TG + DC) */
|
|
1036
1171
|
async getStatusText() {
|
|
@@ -1045,6 +1180,7 @@ export class TopicCommands {
|
|
|
1045
1180
|
.filter(ch => !fleetNames.has(ch.instanceName))
|
|
1046
1181
|
.map(ch => ({ name: ch.instanceName, classic: true })),
|
|
1047
1182
|
];
|
|
1183
|
+
const labels = this.displayLabels();
|
|
1048
1184
|
for (const { name, classic } of instances) {
|
|
1049
1185
|
const status = this.ctx.getInstanceStatus(name);
|
|
1050
1186
|
const executionState = status === "paused" ? "paused"
|
|
@@ -1076,7 +1212,7 @@ export class TopicCommands {
|
|
|
1076
1212
|
// Running but no execution snapshot yet: the old Status
|
|
1077
1213
|
// column showed 🟢 here — say running, never idle or "—".
|
|
1078
1214
|
: `🟢 ${t("state.running")}`;
|
|
1079
|
-
const displayName =
|
|
1215
|
+
const displayName = labels.get(name) ?? name;
|
|
1080
1216
|
// Model: same source as /ctx — live statusline for claude-code, the
|
|
1081
1217
|
// effective resolver otherwise — capped so one long name cannot blow
|
|
1082
1218
|
// the table wider.
|
|
@@ -1238,6 +1374,19 @@ export class TopicCommands {
|
|
|
1238
1374
|
child.once("error", err => this.ctx.failUpdateProgress?.(err.message));
|
|
1239
1375
|
child.unref();
|
|
1240
1376
|
}
|
|
1377
|
+
/** #1302: `/visibility [full|summary|hidden]` in the General topic. */
|
|
1378
|
+
async handleVisibilityCommand(msg, arg) {
|
|
1379
|
+
const adapter = this.getReplyAdapter(msg);
|
|
1380
|
+
if (!adapter || !this.ctx.fleetConfig)
|
|
1381
|
+
return;
|
|
1382
|
+
// Same rule as /doctor: this adapter's fleet admins only, and an empty list is "nobody", not "everybody".
|
|
1383
|
+
if (!this.ctx.hasFleetAdmins(msg.adapterId) || !this.ctx.isFleetAdmin(msg.userId, msg.adapterId)) {
|
|
1384
|
+
await adapter.sendText(msg.chatId, t("not_authorized"), { threadId: msg.threadId });
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
const reply = runVisibilityCommand(this.ctx.fleetConfig, arg, () => this.ctx.saveFleetConfig());
|
|
1388
|
+
await adapter.sendText(msg.chatId, reply, { threadId: msg.threadId });
|
|
1389
|
+
}
|
|
1241
1390
|
async handleDoctorCommand(msg) {
|
|
1242
1391
|
const adapter = this.getReplyAdapter(msg);
|
|
1243
1392
|
if (!adapter)
|
|
@@ -1296,12 +1445,21 @@ export class TopicCommands {
|
|
|
1296
1445
|
async bindAndStart(dirPath, topicId) {
|
|
1297
1446
|
if (!this.ctx.fleetConfig)
|
|
1298
1447
|
throw new Error("Fleet config not loaded");
|
|
1299
|
-
|
|
1448
|
+
// Short unique suffix (#1301), same rule as create_instance. Reuse of a
|
|
1449
|
+
// taken name requires proof it belongs to this same topic (#1305 P1):
|
|
1450
|
+
// full topic_id string equality; a dir-only collision (no config entry)
|
|
1451
|
+
// can never prove that, so it counts as a different topic.
|
|
1452
|
+
const instances = this.ctx.fleetConfig?.instances ?? {};
|
|
1453
|
+
const wanted = String(topicId);
|
|
1454
|
+
const instanceName = uniqueInstanceName(basename(dirPath), topicId, (candidate) => candidate in instances
|
|
1455
|
+
|| existsSync(this.ctx.getInstanceDir(candidate)), (candidate) => {
|
|
1456
|
+
const owner = instances[candidate];
|
|
1457
|
+
return owner != null && String(owner.topic_id) === wanted;
|
|
1458
|
+
});
|
|
1300
1459
|
this.ctx.fleetConfig.instances[instanceName] = {
|
|
1301
1460
|
working_directory: dirPath,
|
|
1302
1461
|
topic_id: topicId,
|
|
1303
1462
|
restart_policy: this.ctx.fleetConfig.defaults.restart_policy ?? DEFAULT_INSTANCE_CONFIG.restart_policy,
|
|
1304
|
-
context_guardian: this.ctx.fleetConfig.defaults.context_guardian ?? DEFAULT_INSTANCE_CONFIG.context_guardian,
|
|
1305
1463
|
log_level: this.ctx.fleetConfig.defaults.log_level ?? DEFAULT_INSTANCE_CONFIG.log_level,
|
|
1306
1464
|
};
|
|
1307
1465
|
this.ctx.saveFleetConfig();
|