@songsid/agend 2.1.8-beta.1 → 2.1.8-beta.11

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.
Files changed (119) hide show
  1. package/dist/agent-cli.js +14 -0
  2. package/dist/agent-cli.js.map +1 -1
  3. package/dist/agent-endpoint.d.ts +4 -1
  4. package/dist/agent-endpoint.js +10 -1
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/backend/claude-code.d.ts +35 -5
  7. package/dist/backend/claude-code.js +288 -17
  8. package/dist/backend/claude-code.js.map +1 -1
  9. package/dist/backend/cli-env-probe-worker.d.ts +1 -0
  10. package/dist/backend/cli-env-probe-worker.js +25 -0
  11. package/dist/backend/cli-env-probe-worker.js.map +1 -0
  12. package/dist/backend/codex-session-lookup.d.ts +16 -0
  13. package/dist/backend/codex-session-lookup.js +76 -2
  14. package/dist/backend/codex-session-lookup.js.map +1 -1
  15. package/dist/backend/codex.d.ts +3 -4
  16. package/dist/backend/codex.js +44 -6
  17. package/dist/backend/codex.js.map +1 -1
  18. package/dist/backend/credential-profile.d.ts +9 -0
  19. package/dist/backend/credential-profile.js +20 -0
  20. package/dist/backend/credential-profile.js.map +1 -1
  21. package/dist/backend/grok.js +19 -0
  22. package/dist/backend/grok.js.map +1 -1
  23. package/dist/backend/muse.d.ts +6 -0
  24. package/dist/backend/muse.js +37 -3
  25. package/dist/backend/muse.js.map +1 -1
  26. package/dist/backend/types.d.ts +13 -2
  27. package/dist/backend/types.js +14 -3
  28. package/dist/backend/types.js.map +1 -1
  29. package/dist/channel/adapters/discord.d.ts +16 -4
  30. package/dist/channel/adapters/discord.js +20 -5
  31. package/dist/channel/adapters/discord.js.map +1 -1
  32. package/dist/channel/mcp-tools.js +6 -0
  33. package/dist/channel/mcp-tools.js.map +1 -1
  34. package/dist/cli.js +138 -48
  35. package/dist/cli.js.map +1 -1
  36. package/dist/config-validator.js +11 -0
  37. package/dist/config-validator.js.map +1 -1
  38. package/dist/config.d.ts +1 -0
  39. package/dist/config.js +1 -1
  40. package/dist/config.js.map +1 -1
  41. package/dist/cross-instance-envelope.d.ts +7 -0
  42. package/dist/cross-instance-envelope.js +19 -1
  43. package/dist/cross-instance-envelope.js.map +1 -1
  44. package/dist/daemon.d.ts +130 -6
  45. package/dist/daemon.js +486 -69
  46. package/dist/daemon.js.map +1 -1
  47. package/dist/delivery-outbox.d.ts +9 -1
  48. package/dist/delivery-outbox.js +25 -4
  49. package/dist/delivery-outbox.js.map +1 -1
  50. package/dist/fleet-context.d.ts +5 -0
  51. package/dist/fleet-context.js.map +1 -1
  52. package/dist/fleet-manager.d.ts +165 -18
  53. package/dist/fleet-manager.js +821 -121
  54. package/dist/fleet-manager.js.map +1 -1
  55. package/dist/forged-envelope-scan.d.ts +160 -0
  56. package/dist/forged-envelope-scan.js +312 -0
  57. package/dist/forged-envelope-scan.js.map +1 -0
  58. package/dist/general-knowledge/skills/persona-emoji/SKILL.md +55 -0
  59. package/dist/instance-lifecycle.d.ts +81 -6
  60. package/dist/instance-lifecycle.js +201 -17
  61. package/dist/instance-lifecycle.js.map +1 -1
  62. package/dist/locale.js +34 -4
  63. package/dist/locale.js.map +1 -1
  64. package/dist/login-controller.js +11 -4
  65. package/dist/login-controller.js.map +1 -1
  66. package/dist/login-flows.d.ts +18 -1
  67. package/dist/login-flows.js +9 -2
  68. package/dist/login-flows.js.map +1 -1
  69. package/dist/ls-rows.d.ts +17 -0
  70. package/dist/ls-rows.js +73 -0
  71. package/dist/ls-rows.js.map +1 -1
  72. package/dist/outbound-handlers.d.ts +3 -0
  73. package/dist/outbound-handlers.js +3 -3
  74. package/dist/outbound-handlers.js.map +1 -1
  75. package/dist/outbound-schemas.d.ts +23 -4
  76. package/dist/outbound-schemas.js +12 -0
  77. package/dist/outbound-schemas.js.map +1 -1
  78. package/dist/paths.js +4 -2
  79. package/dist/paths.js.map +1 -1
  80. package/dist/pause-marker.d.ts +10 -1
  81. package/dist/pause-marker.js +26 -2
  82. package/dist/pause-marker.js.map +1 -1
  83. package/dist/service-installer.d.ts +8 -0
  84. package/dist/service-installer.js +36 -1
  85. package/dist/service-installer.js.map +1 -1
  86. package/dist/settings-api.d.ts +8 -8
  87. package/dist/settings-api.js +12 -5
  88. package/dist/settings-api.js.map +1 -1
  89. package/dist/status-emojis.d.ts +28 -1
  90. package/dist/status-emojis.js +11 -1
  91. package/dist/status-emojis.js.map +1 -1
  92. package/dist/target-queue-worker.d.ts +67 -0
  93. package/dist/target-queue-worker.js +76 -0
  94. package/dist/target-queue-worker.js.map +1 -0
  95. package/dist/tool-permissions.js +15 -4
  96. package/dist/tool-permissions.js.map +1 -1
  97. package/dist/topic-commands.d.ts +9 -0
  98. package/dist/topic-commands.js +64 -21
  99. package/dist/topic-commands.js.map +1 -1
  100. package/dist/transcript-monitor.js +3 -0
  101. package/dist/transcript-monitor.js.map +1 -1
  102. package/dist/transcript-sources.d.ts +63 -0
  103. package/dist/transcript-sources.js +171 -27
  104. package/dist/transcript-sources.js.map +1 -1
  105. package/dist/types.d.ts +26 -1
  106. package/dist/types.js +9 -1
  107. package/dist/types.js.map +1 -1
  108. package/dist/ui/settings.html +25 -13
  109. package/dist/wake-coordinator.d.ts +143 -0
  110. package/dist/wake-coordinator.js +321 -0
  111. package/dist/wake-coordinator.js.map +1 -0
  112. package/dist/web-api.d.ts +3 -1
  113. package/dist/web-api.js +1 -1
  114. package/dist/web-api.js.map +1 -1
  115. package/dist/web-terminal.d.ts +2 -0
  116. package/dist/web-terminal.js +3 -6
  117. package/dist/web-terminal.js.map +1 -1
  118. package/package.json +1 -1
  119. package/templates/systemd.service.ejs +7 -0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Phase 2c (docs/design/phase2-submit-contract.md §1.1, §1.5, §4 2c): the
3
+ * per-target owner of a durable delivery lane when `delivery_worker: on`.
4
+ *
5
+ * ENSURE_AWAKE belongs to the WakeCoordinator (2b); this worker only runs
6
+ * once the target is awake: WAIT_ACCEPTING (the daemon's own verdict, via
7
+ * the coordinator's blocksClaim — the worker never reads a pane) → CLAIM →
8
+ * HANDOFF → AWAIT_RESULT, one row at a time, in created_seq order.
9
+ *
10
+ * Ownership is granted and released by the FleetManager, only while the lane
11
+ * is empty (no row of the target in flight, neither the pump's nor this
12
+ * worker's), inside the pump's synchronous section. The pump skips every
13
+ * target a worker owns. With the outbox claim CAS, the attempt/generation
14
+ * fence and "never replay an unknown submission", that keeps one claimer and
15
+ * one pane writer per target at any time (§1.5).
16
+ */
17
+ import type { ClaimedOutboxDelivery } from "./delivery-outbox.js";
18
+ export interface TargetQueueWorkerDeps {
19
+ /** Whether this worker still owns its target's lane. */
20
+ owns(): boolean;
21
+ /**
22
+ * Whether the target is still `delivery_worker: on`. Checked before every
23
+ * claim: after a switch back, the worker finishes only the row it already
24
+ * claimed and then stops, so the pump takes the lane over (synchronously,
25
+ * in its next pass) instead of the worker draining the queue to the end.
26
+ */
27
+ wanted(): boolean;
28
+ /** Whether the outbox can be queried (closed database / shutting down → false). */
29
+ available(): boolean;
30
+ /** Paused, being woken, restarting, or not accepting by the daemon's own account. */
31
+ blocked(): boolean;
32
+ /** The target daemon's current bootId (null when it has none). */
33
+ daemonBootId(): string | null;
34
+ /** Claim the head row of this target for `bootId` (synchronous CAS). */
35
+ claim(bootId: string): ClaimedOutboxDelivery | undefined;
36
+ /** Shared active-delivery budget with the pump. */
37
+ tryAcquireBudget(): boolean;
38
+ /**
39
+ * Return the budget taken for one attempt, exactly once. It never kicks the
40
+ * pump: with nothing claimable (e.g. a retry not yet due) a kick would turn
41
+ * an unexpired retry_wait into a zero-delay claim loop; a not-yet-due retry
42
+ * is woken by the pump's nextRetryAt timer. The kick after a *claimed* row
43
+ * belongs to `dispatch` (it runs once the hand-off has settled).
44
+ */
45
+ releaseBudget(): void;
46
+ /** HANDOFF + AWAIT_RESULT: resolves when the row has left delivering/submission_started. */
47
+ dispatch(claimed: ClaimedOutboxDelivery): Promise<void>;
48
+ /** Ask the wake coordinator to look at this target (it is paused/blocked). */
49
+ kickCoordinator(): void;
50
+ logger: {
51
+ warn(obj: object, msg: string): void;
52
+ };
53
+ }
54
+ export declare class TargetQueueWorker {
55
+ readonly target: string;
56
+ private readonly deps;
57
+ private running;
58
+ private again;
59
+ /** A row of this target is claimed by this worker and not yet released. */
60
+ inFlight: boolean;
61
+ constructor(target: string, deps: TargetQueueWorkerDeps);
62
+ /** Whether a drain loop is running (the lane may become in-flight at any step). */
63
+ get busy(): boolean;
64
+ /** Drain the lane until it is empty or blocked. Re-entrant calls join the running loop. */
65
+ drain(): Promise<void>;
66
+ private loop;
67
+ }
@@ -0,0 +1,76 @@
1
+ export class TargetQueueWorker {
2
+ target;
3
+ deps;
4
+ running = null;
5
+ again = false;
6
+ /** A row of this target is claimed by this worker and not yet released. */
7
+ inFlight = false;
8
+ constructor(target, deps) {
9
+ this.target = target;
10
+ this.deps = deps;
11
+ }
12
+ /** Whether a drain loop is running (the lane may become in-flight at any step). */
13
+ get busy() {
14
+ return this.running !== null;
15
+ }
16
+ /** Drain the lane until it is empty or blocked. Re-entrant calls join the running loop. */
17
+ drain() {
18
+ if (this.running) {
19
+ this.again = true;
20
+ return this.running;
21
+ }
22
+ const run = this.loop().catch(err => {
23
+ this.deps.logger.warn({ target: this.target, err: err instanceof Error ? err.message : String(err) }, "Queue worker drain failed; rows stay in the outbox");
24
+ }).finally(() => {
25
+ if (this.running === run)
26
+ this.running = null;
27
+ });
28
+ this.running = run;
29
+ return run;
30
+ }
31
+ async loop() {
32
+ do {
33
+ this.again = false;
34
+ for (;;) {
35
+ if (!this.deps.owns() || !this.deps.wanted() || !this.deps.available())
36
+ return;
37
+ // WAIT_ACCEPTING and CLAIM in one synchronous step: the verdict, the
38
+ // bootId and the claim are about the same daemon generation.
39
+ if (this.deps.blocked()) {
40
+ this.deps.kickCoordinator();
41
+ break;
42
+ }
43
+ const bootId = this.deps.daemonBootId();
44
+ if (!bootId) {
45
+ this.deps.kickCoordinator();
46
+ break;
47
+ }
48
+ if (!this.deps.tryAcquireBudget())
49
+ break;
50
+ let claimed;
51
+ try {
52
+ claimed = this.deps.claim(bootId);
53
+ }
54
+ catch (err) {
55
+ // e.g. SQLITE_BUSY: nothing was claimed, so the budget goes back now —
56
+ // a leaked slot here would starve every lane once eight leaked.
57
+ this.deps.releaseBudget();
58
+ throw err;
59
+ }
60
+ if (!claimed) {
61
+ this.deps.releaseBudget();
62
+ break;
63
+ }
64
+ this.inFlight = true;
65
+ try {
66
+ await this.deps.dispatch(claimed);
67
+ }
68
+ finally {
69
+ this.inFlight = false;
70
+ this.deps.releaseBudget();
71
+ }
72
+ }
73
+ } while (this.again);
74
+ }
75
+ }
76
+ //# sourceMappingURL=target-queue-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-queue-worker.js","sourceRoot":"","sources":["../src/target-queue-worker.ts"],"names":[],"mappings":"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"}
@@ -40,7 +40,7 @@ const WORKER = [
40
40
  "get_fleet_status", "get_fleet_config", "get_usage", "get_effort", "get_instance_logs",
41
41
  "list_decisions", "list_schedules", "list_deployments", "validate_config",
42
42
  // Its own things.
43
- "task", "post_decision", "set_display_name", "set_description",
43
+ "task", "post_decision", "set_display_name", "set_description", "list_emojis", "set_persona_emoji", "preview_emojis",
44
44
  // Its own schedules. Present here, but not a free hand: scheduleOpRefusal
45
45
  // limits a non-coordinator to schedules that target itself and that it
46
46
  // created (#895). The target is the control, not whether the tool is listed.
@@ -81,18 +81,23 @@ export const TOOL_PROFILES = {
81
81
  "create_instance", "start_instance", "restart_instance", "wake_instance",
82
82
  "task", "list_decisions", "post_decision",
83
83
  "create_schedule", "list_schedules", "update_schedule", "delete_schedule",
84
+ // Persona emoji (v2.1.9): every instance can see the server's emojis, and
85
+ // a dispatcher can choose its own status stamp like any worker.
86
+ "list_emojis", "preview_emojis", "set_persona_emoji",
84
87
  ],
85
88
  standard: [
86
89
  "reply", "react", "edit_message",
87
90
  "send_to_instance", "broadcast", "list_instances", "describe_instance", "delivery_status",
88
- "list_decisions", "post_decision", "task", "set_display_name", "set_description",
91
+ "list_decisions", "post_decision", "task", "set_display_name", "set_description", "list_emojis", "set_persona_emoji", "preview_emojis",
89
92
  "validate_config", "get_fleet_status", "get_usage", "get_effort", "get_instance_logs", "get_fleet_config",
90
93
  // Self-scheduling, same scope as worker (#895).
91
94
  "create_schedule", "list_schedules", "update_schedule", "delete_schedule",
92
95
  ],
93
96
  // No schedules: keep `minimal` narrow while preserving the status lookup a
94
- // minimal sender needs to resolve an accepted operation safely.
95
- minimal: ["reply", "send_to_instance", "delivery_status", "list_decisions", "download_attachment"],
97
+ // minimal sender needs to resolve an accepted operation safely. Persona emoji
98
+ // is see-only here (v2.1.9): listing and previewing the server's emojis
99
+ // change nothing; setting a stamp stays with the larger profiles.
100
+ minimal: ["reply", "send_to_instance", "delivery_status", "list_decisions", "download_attachment", "list_emojis", "preview_emojis"],
96
101
  };
97
102
  const PROFILE_SETS = Object.fromEntries(Object.entries(TOOL_PROFILES).map(([name, tools]) => [name, new Set(tools)]));
98
103
  /**
@@ -184,6 +189,9 @@ export const IPC_TYPE_TOOLS = {
184
189
  fleet_task: "task",
185
190
  fleet_set_display_name: "set_display_name",
186
191
  fleet_set_description: "set_description",
192
+ fleet_list_emojis: "list_emojis",
193
+ fleet_set_persona_emoji: "set_persona_emoji",
194
+ fleet_preview_emojis: "preview_emojis",
187
195
  };
188
196
  /**
189
197
  * Agent-endpoint ops that never reach its `OP_MAP`.
@@ -206,6 +214,9 @@ export const EARLY_AGENT_OP_TOOLS = {
206
214
  usage: "get_usage",
207
215
  rename: "set_display_name",
208
216
  "set-description": "set_description",
217
+ emojis: "list_emojis",
218
+ "persona-emoji": "set_persona_emoji",
219
+ "emoji-preview": "preview_emojis",
209
220
  };
210
221
  /**
211
222
  * What to say to an agent that was refused.
@@ -1 +1 @@
1
- {"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../src/tool-permissions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;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;IACvD,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,2EAA2E;IAC3E,0EAA0E;IAC1E,gDAAgD;IAChD,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,WAAW,EAAE,eAAe,EAAE,iBAAiB;IAC3G,4DAA4D;IAC5D,gBAAgB,EAAE,mBAAmB,EAAE,YAAY,EAAE,aAAa;IAClE,kBAAkB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB;IACtF,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB;IACzE,kBAAkB;IAClB,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB;IAC9D,0EAA0E;IAC1E,uEAAuE;IACvE,6EAA6E;IAC7E,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB;IACvD,gFAAgF;IAChF,eAAe,EAAE,cAAc;CAChC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,aAAa,GAAsB;IACvC,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB;IACxD,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB;IACxF,iBAAiB,EAAE,qBAAqB;IACxC,aAAa,EAAE,aAAa,EAAE,aAAa;IAC3C,uBAAuB,EAAE,wBAAwB;IACjD,+EAA+E;IAC/E,iBAAiB;CAClB,CAAC;AAEF,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAqD;IAC7E,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,CAAC,GAAG,MAAM,EAAE,GAAG,aAAa,CAAC;IAC1C,OAAO,EAAE;QACP,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,qBAAqB;QACvD,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa;QACjH,kBAAkB,EAAE,eAAe,EAAE,qBAAqB,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB;QAC3G,iBAAiB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe;QACxE,MAAM,EAAE,gBAAgB,EAAE,eAAe;QACzC,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB;KAC1E;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,OAAO,EAAE,cAAc;QAChC,kBAAkB,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB;QACzF,gBAAgB,EAAE,eAAe,EAAE,MAAM,EAAE,kBAAkB,EAAE,iBAAiB;QAChF,iBAAiB,EAAE,kBAAkB,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,kBAAkB;QACzG,gDAAgD;QAChD,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,iBAAiB;KAC1E;IACD,2EAA2E;IAC3E,gEAAgE;IAChE,OAAO,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,qBAAqB,CAAC;CACnG,CAAC;AAEF,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CACZ,CAAC;AAEnE;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAoB;IAC3C,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAoB,EAAE,IAAY;IAC3D,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAkE,EAClE,IAAY,EACZ,eAA4B,QAAQ;IAEpC,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,CAAC;IAClC,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,IAAI,MAAM,EAAE,aAAa,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3E,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAyB;IAC7D,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;GAQG;AACH;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAa;IAC1C,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACxG,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAqC;IAC9D,qBAAqB,EAAE,iBAAiB;IACxC,mBAAmB,EAAE,gBAAgB;IACrC,qBAAqB,EAAE,iBAAiB;IACxC,qBAAqB,EAAE,iBAAiB;IACxC,qBAAqB,EAAE,eAAe;IACtC,mBAAmB,EAAE,gBAAgB;IACrC,qBAAqB,EAAE,iBAAiB;IACxC,UAAU,EAAE,MAAM;IAClB,sBAAsB,EAAE,kBAAkB;IAC1C,qBAAqB,EAAE,iBAAiB;CACzC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAqC;IACpE,iBAAiB,EAAE,iBAAiB;IACpC,eAAe,EAAE,gBAAgB;IACjC,iBAAiB,EAAE,iBAAiB;IACpC,iBAAiB,EAAE,iBAAiB;IACpC,0EAA0E;IAC1E,yEAAyE;IACzE,eAAe,EAAE,eAAe;IAChC,iBAAiB,EAAE,eAAe;IAClC,eAAe,EAAE,gBAAgB;IACjC,iBAAiB,EAAE,iBAAiB;IACpC,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,kBAAkB;IAC1B,iBAAiB,EAAE,iBAAiB;CACrC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAoB,EAAE,IAAY;IACnE,OAAO,GAAG,IAAI,yDAAyD,OAAO,mBAAmB,IAAI,6BAA6B;UAC9H,yEAAyE;UACzE,2EAA2E,CAAC;AAClF,CAAC;AAED;;;GAGG;AACH,MAAM,gBAAgB,GAA6B,IAAI,GAAG,CAAc,CAAC,MAAM,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC;AAI5G;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAAoB,EACpB,MAAc,EACd,EAAc,EACd,OAAkG;IAElG,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,MAAM,IAAI,GAAG,GAAG,EAAE,WAAW,CAAC;IAC9B,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IAC1D,IAAI,EAAE,KAAK,QAAQ,EAAE,CAAC;QACpB,MAAM,MAAM,GAAG,SAAS,IAAI,MAAM,CAAC;QACnC,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,MAAM,GAAG,CAAC,CAAC;IACnH,CAAC;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,2EAA2E;IAC3E,qCAAqC;IACrC,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC7D,OAAO,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EACjD,QAAQ,CAAC,MAAM,KAAK,MAAM;YACxB,CAAC,CAAC,mCAAmC,QAAQ,CAAC,MAAM,GAAG;YACvD,CAAC,CAAC,sBAAsB,QAAQ,CAAC,MAAM,eAAe,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,EAAE,KAAK,QAAQ,IAAI,SAAS,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;QACzD,OAAO,sBAAsB,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,yBAAyB,SAAS,GAAG,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+FAA+F;AAC/F,SAAS,sBAAsB,CAAC,OAAoB,EAAE,IAAY,EAAE,MAAc,EAAE,SAAiB;IACnG,OAAO,GAAG,IAAI,wBAAwB,OAAO,6DAA6D;UACtG,yBAAyB,MAAM,yCAAyC,SAAS,IAAI;UACrF,sFAAsF;UACtF,yCAAyC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"tool-permissions.js","sourceRoot":"","sources":["../src/tool-permissions.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import type { FleetContext } from "./fleet-context.js";
2
2
  import type { InboundMessage } from "./channel/types.js";
3
3
  import { type TokenContextRatio } from "./context-percent.js";
4
+ import { type BackendCliVersionSnapshot } from "./backend/types.js";
4
5
  export { parseContextPercent, parseTokenContextRatio } from "./context-percent.js";
5
6
  export type { TokenContextRatio } from "./context-percent.js";
6
7
  type ExecutionFleetContext = FleetContext & {
@@ -191,6 +192,10 @@ export declare class TopicCommands {
191
192
  /** Get fleet status as markdown text (shared by TG + DC) */
192
193
  getStatusText(): Promise<string>;
193
194
  private handleSysInfoCommand;
195
+ /** Share the send-completion gate across topic messages and Discord slash replies. */
196
+ sendSysInfo(send: (text: string) => Promise<unknown>, opts?: {
197
+ platform?: "telegram" | "discord";
198
+ }): Promise<void>;
194
199
  /**
195
200
  * Get system info as formatted text.
196
201
  *
@@ -201,8 +206,12 @@ export declare class TopicCommands {
201
206
  *
202
207
  * @param opts.platform - "telegram" uses markdown table, "discord" uses plain lines
203
208
  */
209
+ getSysInfoTextAsync(opts?: {
210
+ platform?: "telegram" | "discord";
211
+ }): Promise<string>;
204
212
  getSysInfoText(opts?: {
205
213
  platform?: "telegram" | "discord";
214
+ backendCliVersions?: BackendCliVersionSnapshot;
206
215
  }): string;
207
216
  private handleUpdateCommand;
208
217
  private handleDoctorCommand;
@@ -7,11 +7,13 @@ import { createRequire } from "node:module";
7
7
  const execAsync = promisify(exec);
8
8
  import { DEFAULT_INSTANCE_CONFIG } from "./config.js";
9
9
  import { formatCents } from "./cost-guard.js";
10
+ import { truncateDisplay, MODEL_DISPLAY_WIDTH_MAX } from "./ls-rows.js";
10
11
  import { getTmuxSocketName, getTmuxSessionName } from "./paths.js";
11
12
  import { t, getLocale } from "./locale.js";
12
13
  import { clampContextPercent, parseContextPercent, parseTokenContextRatio, } from "./context-percent.js";
13
14
  import { isGeneralInstance } from "./general-instance.js";
14
15
  import { backendSupportsSteer } from "./steer-capability.js";
16
+ import { SYSINFO_BACKEND_IDS } from "./backend/types.js";
15
17
  export { parseContextPercent, parseTokenContextRatio } from "./context-percent.js";
16
18
  /** Sanitize a directory name into a valid instance name. Keeps Unicode letters (incl. CJK). */
17
19
  export function sanitizeInstanceName(name) {
@@ -81,6 +83,26 @@ function tmuxVersion() {
81
83
  }
82
84
  return cachedTmuxVersion;
83
85
  }
86
+ const SYSINFO_BACKEND_LABEL_KEYS = {
87
+ "claude-code": "sysinfo.backend_cli_claude_code",
88
+ codex: "sysinfo.backend_cli_codex",
89
+ "kiro-cli": "sysinfo.backend_cli_kiro_cli",
90
+ grok: "sysinfo.backend_cli_grok",
91
+ antigravity: "sysinfo.backend_cli_antigravity",
92
+ muse: "sysinfo.backend_cli_muse",
93
+ };
94
+ function backendCliLines(versions) {
95
+ return [
96
+ `**${t("sysinfo.backend_clis")}**`,
97
+ ...SYSINFO_BACKEND_IDS.map(id => {
98
+ const label = t(SYSINFO_BACKEND_LABEL_KEYS[id]);
99
+ const info = versions?.[id];
100
+ const version = info?.version
101
+ ?? (info?.probing ? t("sysinfo.cli_version_probing") : t("sysinfo.cli_version_unknown"));
102
+ return `- ${label}: ${version}`;
103
+ }),
104
+ ];
105
+ }
84
106
  export function compactCommandForBackend(backend) {
85
107
  if (backend === "antigravity")
86
108
  return "/clear";
@@ -1022,28 +1044,31 @@ export class TopicCommands {
1022
1044
  : resolveInstanceContext(this.ctx.dataDir, name, backend);
1023
1045
  const contextStr = context == null ? "-" : `${Math.round(context)}%`;
1024
1046
  const costCents = this.ctx.costGuard?.getDailyCostCents(name) ?? 0;
1025
- let icon;
1026
- if (costPaused || status === "paused")
1027
- icon = "⏸";
1028
- else if (status === "running")
1029
- icon = "🟢";
1030
- else if (status === "crashed")
1031
- icon = "🔴";
1032
- else
1033
- icon = "⚪";
1034
- const stateLabel = executionState === "idle" ? `🟢 ${t("state.idle")}`
1035
- : executionState === "working" ? `🔵 ${t("state.working")}`
1036
- : executionState === "stuck" ? `🔴 ${t("state.stuck")}`
1037
- : executionState === "paused" ? `⏸ ${t("state.paused")}`
1038
- : "—";
1047
+ // Merged State (#1052): lifecycle + execution state in one column. The
1048
+ // old Status icon column duplicated it (⏸/⏸, 🟢/🟢); IPC duplicated it
1049
+ // too (✗ exactly when State is stopped/crashed/—) and stays queryable
1050
+ // via /api/fleet's per-instance `ipc` flag.
1051
+ const stateLabel = status === "paused" || costPaused || executionState === "paused" ? `⏸ ${t("state.paused")}`
1052
+ : status === "stopped" ? `✗ ${t("state.stopped")}`
1053
+ : status === "crashed" ? `🔴 ${t("state.crashed")}`
1054
+ : executionState === "idle" ? `🟢 ${t("state.idle")}`
1055
+ : executionState === "working" ? `🔵 ${t("state.working")}`
1056
+ : executionState === "stuck" ? `🔴 ${t("state.stuck")}`
1057
+ // Running but no execution snapshot yet: the old Status
1058
+ // column showed 🟢 here — say running, never idle or "—".
1059
+ : `🟢 ${t("state.running")}`;
1039
1060
  const displayName = this.shortInstanceName(name);
1040
- // IPC reachability moved here from /sysinfo: it is per-instance health, and
1041
- // /status is now the one place that shows the fleet per instance.
1042
- const ipc = this.ctx.instanceIpcClients.has(name) ? "✓" : "✗";
1061
+ // Model: same source as /ctx — live statusline for claude-code, the
1062
+ // effective resolver otherwise — capped so one long name cannot blow
1063
+ // the table wider.
1064
+ const modelDisplay = backend === "claude-code"
1065
+ ? readStatuslineModel(this.ctx.dataDir, name) ?? this.ctx.modelDisplayForInstance?.(name) ?? "default"
1066
+ : this.ctx.modelDisplayForInstance?.(name) ?? "default";
1067
+ const model = truncateDisplay(modelDisplay, MODEL_DISPLAY_WIDTH_MAX);
1043
1068
  // "-" distinguishes "backend has no effort setting" from an unset one:
1044
1069
  // an empty cell would read as missing data rather than not-applicable.
1045
1070
  const effort = this.ctx.resolveInstanceEffort?.(name).effort ?? "-";
1046
- rows.push(`| ${displayName} | ${backend} | ${contextStr} | ${effort} | ${formatCents(costCents)} | ${icon} | ${stateLabel} | ${ipc} |`);
1071
+ rows.push(`| ${displayName} | ${backend} | ${model} | ${contextStr} | ${effort} | ${formatCents(costCents)} | ${stateLabel} |`);
1047
1072
  }
1048
1073
  if (rows.length === 0)
1049
1074
  return t("status.no_instances");
@@ -1051,7 +1076,7 @@ export class TopicCommands {
1051
1076
  `## ${t("status.title")}`,
1052
1077
  "",
1053
1078
  t("status.table_header"),
1054
- "|----------|---------|-----|--------|------|--------|-------|-----|",
1079
+ "|----------|---------|-------|-----|--------|------|-------|",
1055
1080
  ...rows,
1056
1081
  "",
1057
1082
  t("status.paused_count", pausedCount),
@@ -1080,8 +1105,17 @@ export class TopicCommands {
1080
1105
  if (!adapter)
1081
1106
  return;
1082
1107
  const platform = adapter.type === "discord" ? "discord" : "telegram";
1083
- const text = this.getSysInfoText({ platform });
1084
- await adapter.sendText(msg.chatId, text, { threadId: msg.threadId });
1108
+ await this.sendSysInfo(text => adapter.sendText(msg.chatId, text, { threadId: msg.threadId }), { platform });
1109
+ }
1110
+ /** Share the send-completion gate across topic messages and Discord slash replies. */
1111
+ async sendSysInfo(send, opts) {
1112
+ const text = await this.getSysInfoTextAsync(opts);
1113
+ try {
1114
+ await send(text);
1115
+ }
1116
+ finally {
1117
+ this.ctx.refreshBackendCliVersions?.();
1118
+ }
1085
1119
  }
1086
1120
  /**
1087
1121
  * Get system info as formatted text.
@@ -1093,6 +1127,10 @@ export class TopicCommands {
1093
1127
  *
1094
1128
  * @param opts.platform - "telegram" uses markdown table, "discord" uses plain lines
1095
1129
  */
1130
+ async getSysInfoTextAsync(opts) {
1131
+ const backendCliVersions = this.ctx.getBackendCliVersionSnapshot?.();
1132
+ return this.getSysInfoText({ ...opts, backendCliVersions });
1133
+ }
1096
1134
  getSysInfoText(opts) {
1097
1135
  const info = this.ctx.getSysInfo();
1098
1136
  const upHours = Math.floor(info.uptime_seconds / 3600);
@@ -1106,6 +1144,7 @@ export class TopicCommands {
1106
1144
  ...(info.fleet_mem_mb !== null ? [`${t("sysinfo.fleet_mem")}: ${(info.fleet_mem_mb / 1024).toFixed(1)} GB`] : []),
1107
1145
  `${t("sysinfo.system_mem")}: ${info.system_mem_gb.used} / ${info.system_mem_gb.total} GB`,
1108
1146
  ];
1147
+ const backendVersions = backendCliLines(opts?.backendCliVersions);
1109
1148
  const resources = [
1110
1149
  `📚 **${t("sysinfo.resources")}**`,
1111
1150
  `- ${t("sysinfo.docs")}: https://songsid.github.io/AgEnD`,
@@ -1124,6 +1163,8 @@ export class TopicCommands {
1124
1163
  `${t("sysinfo.memory")}: ${info.memory_mb.rss} MB RSS`,
1125
1164
  `${t("sysinfo.heap")}: ${info.memory_mb.heapUsed} / ${info.memory_mb.heapTotal} MB`,
1126
1165
  "",
1166
+ ...backendVersions,
1167
+ "",
1127
1168
  ...summaryLines,
1128
1169
  "",
1129
1170
  ...resources,
@@ -1143,6 +1184,8 @@ export class TopicCommands {
1143
1184
  `| ${t("sysinfo.memory")} | ${info.memory_mb.rss} MB RSS |`,
1144
1185
  `| ${t("sysinfo.heap")} | ${info.memory_mb.heapUsed} / ${info.memory_mb.heapTotal} MB |`,
1145
1186
  "",
1187
+ ...backendVersions,
1188
+ "",
1146
1189
  ...summaryLines,
1147
1190
  "",
1148
1191
  ...resources,