@songsid/agend 2.1.0-beta.3 → 2.1.0-beta.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/README.zh-TW.md +2 -1
- package/dist/access-path.js +3 -3
- package/dist/access-path.js.map +1 -1
- package/dist/agent-cli.js +1 -1
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.d.ts +8 -0
- package/dist/agent-endpoint.js +36 -8
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/antigravity.js +3 -2
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.js +4 -4
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/factory.js +4 -1
- package/dist/backend/factory.js.map +1 -1
- package/dist/backend/grok.d.ts +51 -0
- package/dist/backend/grok.js +282 -0
- package/dist/backend/grok.js.map +1 -0
- package/dist/backend/kiro.js +3 -2
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +12 -2
- package/dist/backend/types.js +1 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/adapters/discord.d.ts +20 -0
- package/dist/channel/adapters/discord.js +85 -11
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.js +4 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/mcp-tools.js +17 -1
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +14 -1
- package/dist/classic-channel-manager.js +65 -4
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +108 -16
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.js +68 -1
- package/dist/config-validator.js.map +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.js +13 -1
- package/dist/config.js.map +1 -1
- package/dist/context-guardian.d.ts +2 -0
- package/dist/context-guardian.js +10 -2
- package/dist/context-guardian.js.map +1 -1
- package/dist/daemon-entry.js +2 -1
- package/dist/daemon-entry.js.map +1 -1
- package/dist/daemon.d.ts +76 -6
- package/dist/daemon.js +451 -113
- package/dist/daemon.js.map +1 -1
- package/dist/fleet-context.d.ts +4 -0
- package/dist/fleet-manager.d.ts +88 -7
- package/dist/fleet-manager.js +712 -129
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +1 -1
- package/dist/general-knowledge/skills/model-discovery/SKILL.md +1 -0
- package/dist/instance-lifecycle.d.ts +11 -1
- package/dist/instance-lifecycle.js +64 -22
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +26 -2
- package/dist/locale.js.map +1 -1
- package/dist/logger.d.ts +6 -0
- package/dist/logger.js +29 -10
- package/dist/logger.js.map +1 -1
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +203 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +40 -1
- package/dist/outbound-schemas.js +36 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pause-marker.d.ts +5 -0
- package/dist/pause-marker.js +36 -0
- package/dist/pause-marker.js.map +1 -0
- package/dist/settings-api.d.ts +20 -2
- package/dist/settings-api.js +213 -9
- package/dist/settings-api.js.map +1 -1
- package/dist/setup-wizard.js +8 -0
- package/dist/setup-wizard.js.map +1 -1
- package/dist/statusline-watcher.d.ts +1 -1
- package/dist/statusline-watcher.js +3 -2
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/tmux-control.d.ts +7 -0
- package/dist/tmux-control.js +22 -1
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +1 -1
- package/dist/tmux-manager.js.map +1 -1
- package/dist/topic-commands.d.ts +19 -1
- package/dist/topic-commands.js +132 -23
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-monitor.js +2 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/types.d.ts +23 -1
- package/dist/ui/dashboard.html +2 -2
- package/dist/ui/settings.html +453 -74
- package/dist/web-api.d.ts +1 -0
- package/dist/web-api.js +24 -15
- package/dist/web-api.js.map +1 -1
- package/dist/workflow-templates/default.md +0 -4
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -11,6 +11,8 @@ import { homedir, totalmem, freemem } from "node:os";
|
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { spawn, execSync, execFileSync } from "node:child_process";
|
|
13
13
|
import { getAgendHome, getTmuxSocketName } from "./paths.js";
|
|
14
|
+
import { readClassicLastActivityAt } from "./classic-channel-manager.js";
|
|
15
|
+
import { hasPausedMarker } from "./pause-marker.js";
|
|
14
16
|
/** Prefix tmux args with -L when socket isolation is active. */
|
|
15
17
|
function tmuxArgs(args) {
|
|
16
18
|
const socket = getTmuxSocketName();
|
|
@@ -1889,14 +1891,14 @@ function getTreeRssKb(pid, depth = 0) {
|
|
|
1889
1891
|
return total;
|
|
1890
1892
|
}
|
|
1891
1893
|
function getInstanceStatusStandalone(name) {
|
|
1894
|
+
if (hasPausedMarker(join(DATA_DIR, "instances", name)))
|
|
1895
|
+
return "paused";
|
|
1892
1896
|
const pidPath = join(DATA_DIR, "instances", name, "daemon.pid");
|
|
1893
1897
|
if (!existsSync(pidPath))
|
|
1894
1898
|
return "stopped";
|
|
1895
1899
|
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1896
1900
|
try {
|
|
1897
1901
|
process.kill(pid, 0);
|
|
1898
|
-
if (existsSync(join(DATA_DIR, "instances", name, "paused-state.json")))
|
|
1899
|
-
return "paused";
|
|
1900
1902
|
return "running";
|
|
1901
1903
|
}
|
|
1902
1904
|
catch {
|
|
@@ -1938,6 +1940,7 @@ function formatTimeSince(isoStr) {
|
|
|
1938
1940
|
* kiro classic "8% !>" / TUI "◔ 1%" / bracket "[8%]" / prompt "8% ❯"
|
|
1939
1941
|
* codex "Context N% left" (remaining → 100-N) or "Context N% used"
|
|
1940
1942
|
* opencode "1.2K (6%)"
|
|
1943
|
+
* grok "12K / 500K" (used tokens / context window)
|
|
1941
1944
|
* Duplicated (not imported) so this CLI entry point stays free of the daemon's
|
|
1942
1945
|
* dependency graph. All returned values are context USED (low % = fresh).
|
|
1943
1946
|
*/
|
|
@@ -1948,6 +1951,18 @@ const defaultParser = (output) => {
|
|
|
1948
1951
|
const left = line.match(/Context\s+(\d+)%\s+left/i);
|
|
1949
1952
|
if (left)
|
|
1950
1953
|
return 100 - parseInt(left[1], 10);
|
|
1954
|
+
const ratio = line.match(/(\d+\.?\d*[KkMm]?)\s*\/\s*(\d+\.?\d*[KkMm]?)/);
|
|
1955
|
+
if (ratio) {
|
|
1956
|
+
const tokenCount = (value) => {
|
|
1957
|
+
const suffix = value.at(-1)?.toLowerCase();
|
|
1958
|
+
const multiplier = suffix === "k" ? 1_000 : suffix === "m" ? 1_000_000 : 1;
|
|
1959
|
+
return parseFloat(value) * multiplier;
|
|
1960
|
+
};
|
|
1961
|
+
const used = tokenCount(ratio[1]);
|
|
1962
|
+
const total = tokenCount(ratio[2]);
|
|
1963
|
+
if (Number.isFinite(used) && Number.isFinite(total) && total > 0)
|
|
1964
|
+
return used / total * 100;
|
|
1965
|
+
}
|
|
1951
1966
|
const m = line.match(/(\d+)%.*[!❯>]/)
|
|
1952
1967
|
|| line.match(/◔\s*(\d+)%/)
|
|
1953
1968
|
|| line.match(/\[(\d+)%\]/)
|
|
@@ -2084,19 +2099,40 @@ async function lsAction(opts) {
|
|
|
2084
2099
|
}
|
|
2085
2100
|
catch { /* ignore */ }
|
|
2086
2101
|
}
|
|
2087
|
-
//
|
|
2102
|
+
// Classic activity is channel-driven. Lightweight Classic daemons often
|
|
2103
|
+
// have no statusline/output log, so prefer the persisted inbound timestamp
|
|
2104
|
+
// and fall back to their durable chat-log mtime for pre-migration history.
|
|
2088
2105
|
let lastActivity = null;
|
|
2089
|
-
|
|
2090
|
-
|
|
2106
|
+
if (isClassic) {
|
|
2107
|
+
let classicActivity = readClassicLastActivityAt(DATA_DIR, name) ?? 0;
|
|
2091
2108
|
try {
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2109
|
+
const inboundPath = join(DATA_DIR, "instances", name, "last-inbound-at");
|
|
2110
|
+
if (existsSync(inboundPath)) {
|
|
2111
|
+
const inboundAt = Number(readFileSync(inboundPath, "utf-8").trim());
|
|
2112
|
+
if (Number.isFinite(inboundAt) && inboundAt >= 0 && inboundAt <= Date.now()) {
|
|
2113
|
+
classicActivity = Math.max(classicActivity, inboundAt);
|
|
2114
|
+
}
|
|
2095
2115
|
}
|
|
2096
2116
|
}
|
|
2097
2117
|
catch { /* ignore */ }
|
|
2118
|
+
if (classicActivity) {
|
|
2119
|
+
lastActivity = formatTimeSince(new Date(classicActivity).toISOString());
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
else {
|
|
2123
|
+
// Fleet activity: prefer statusline.json mtime (updated on real agent activity).
|
|
2124
|
+
for (const probe of ["statusline.json", "daemon.log", "output.log"]) {
|
|
2125
|
+
const p = join(DATA_DIR, "instances", name, probe);
|
|
2126
|
+
try {
|
|
2127
|
+
if (existsSync(p)) {
|
|
2128
|
+
lastActivity = formatTimeSince(statSync(p).mtime.toISOString());
|
|
2129
|
+
break;
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
catch { /* ignore */ }
|
|
2133
|
+
}
|
|
2098
2134
|
}
|
|
2099
|
-
return { name, backend, status, teams, source, context, memMb, lastActivity, idle: undefined };
|
|
2135
|
+
return { name, backend, status, teams, source, context, memMb, lastActivity, classic: isClassic, idle: undefined, state: undefined };
|
|
2100
2136
|
});
|
|
2101
2137
|
// Enrich with idle state from fleet API (if fleet is running)
|
|
2102
2138
|
try {
|
|
@@ -2104,11 +2140,37 @@ async function lsAction(opts) {
|
|
|
2104
2140
|
const resp = await fetch(`http://127.0.0.1:${port}/api/fleet`, { signal: AbortSignal.timeout(2000) });
|
|
2105
2141
|
const apiData = await resp.json();
|
|
2106
2142
|
for (const inst of apiData.instances ?? []) {
|
|
2107
|
-
|
|
2143
|
+
let row = rows.find(r => r.name === inst.name);
|
|
2144
|
+
if (!row && inst.classic) {
|
|
2145
|
+
classicNames.add(inst.name);
|
|
2146
|
+
const channelId = inst.channelId ?? "";
|
|
2147
|
+
row = {
|
|
2148
|
+
name: inst.name,
|
|
2149
|
+
backend: inst.backend ?? "claude-code",
|
|
2150
|
+
status: inst.status ?? "stopped",
|
|
2151
|
+
teams: ["(classic)"],
|
|
2152
|
+
source: inst.adapterId?.toLowerCase().includes("telegram") || channelId.startsWith("-") || (channelId.length > 0 && channelId.length < 17) ? "TG" : "DC",
|
|
2153
|
+
context: null,
|
|
2154
|
+
memMb: null,
|
|
2155
|
+
lastActivity: inst.lastActivity ? formatTimeSince(new Date(inst.lastActivity).toISOString()) : null,
|
|
2156
|
+
classic: true,
|
|
2157
|
+
idle: inst.idle,
|
|
2158
|
+
state: inst.state,
|
|
2159
|
+
};
|
|
2160
|
+
rows.push(row);
|
|
2161
|
+
}
|
|
2108
2162
|
if (row) {
|
|
2109
2163
|
row.idle = inst.idle;
|
|
2110
2164
|
if (inst.status)
|
|
2111
2165
|
row.status = inst.status;
|
|
2166
|
+
if (inst.backend)
|
|
2167
|
+
row.backend = inst.backend;
|
|
2168
|
+
if (inst.classic)
|
|
2169
|
+
row.classic = true;
|
|
2170
|
+
if (inst.state)
|
|
2171
|
+
row.state = inst.state;
|
|
2172
|
+
if (inst.lastActivity)
|
|
2173
|
+
row.lastActivity = formatTimeSince(new Date(inst.lastActivity).toISOString());
|
|
2112
2174
|
}
|
|
2113
2175
|
}
|
|
2114
2176
|
}
|
|
@@ -2117,9 +2179,38 @@ async function lsAction(opts) {
|
|
|
2117
2179
|
console.log(JSON.stringify(rows, null, 2));
|
|
2118
2180
|
return;
|
|
2119
2181
|
}
|
|
2120
|
-
// Status icon
|
|
2121
|
-
const statusIcon = (s, idle) =>
|
|
2122
|
-
|
|
2182
|
+
// Status icon — prefer tri-state 'state' field, fall back to idle boolean
|
|
2183
|
+
const statusIcon = (s, idle, state) => {
|
|
2184
|
+
if (state === "stuck")
|
|
2185
|
+
return "\x1b[31m●\x1b[0m";
|
|
2186
|
+
if (state === "paused" || s === "paused")
|
|
2187
|
+
return "\x1b[2;33m●\x1b[0m";
|
|
2188
|
+
if (state === "working")
|
|
2189
|
+
return "\x1b[34m●\x1b[0m";
|
|
2190
|
+
if (state === "idle")
|
|
2191
|
+
return "\x1b[32m●\x1b[0m";
|
|
2192
|
+
// Fallback for when API is unreachable
|
|
2193
|
+
if (s === "running")
|
|
2194
|
+
return idle === false ? "\x1b[34m●\x1b[0m" : "\x1b[32m●\x1b[0m";
|
|
2195
|
+
if (s === "crashed")
|
|
2196
|
+
return "\x1b[31m●\x1b[0m";
|
|
2197
|
+
return "\x1b[90m○\x1b[0m";
|
|
2198
|
+
};
|
|
2199
|
+
const statusLabel = (s, idle, state) => {
|
|
2200
|
+
if (state === "stuck")
|
|
2201
|
+
return "Stuck";
|
|
2202
|
+
if (state === "paused" || s === "paused")
|
|
2203
|
+
return "Paused";
|
|
2204
|
+
if (state === "working")
|
|
2205
|
+
return "Working";
|
|
2206
|
+
if (state === "idle")
|
|
2207
|
+
return "Idle";
|
|
2208
|
+
if (s === "running")
|
|
2209
|
+
return idle === false ? "Busy" : "Idle";
|
|
2210
|
+
if (s === "crashed")
|
|
2211
|
+
return "Crashed";
|
|
2212
|
+
return "Stopped";
|
|
2213
|
+
};
|
|
2123
2214
|
/** Get display width accounting for fullwidth (CJK) characters */
|
|
2124
2215
|
const displayWidth = (s) => {
|
|
2125
2216
|
let w = 0;
|
|
@@ -2130,7 +2221,8 @@ async function lsAction(opts) {
|
|
|
2130
2221
|
return w;
|
|
2131
2222
|
};
|
|
2132
2223
|
const padDisplay = (s, width) => s + " ".repeat(Math.max(0, width - displayWidth(s)));
|
|
2133
|
-
const
|
|
2224
|
+
const displayName = (row) => row.classic ? `[C] ${row.name}` : row.name;
|
|
2225
|
+
const nameW = Math.max(20, ...rows.map(r => displayWidth(displayName(r)) + 2));
|
|
2134
2226
|
const backendW = 14;
|
|
2135
2227
|
const statusW = 12;
|
|
2136
2228
|
const teamW = 20;
|
|
@@ -2151,9 +2243,9 @@ async function lsAction(opts) {
|
|
|
2151
2243
|
const ctxStr = r.context != null ? `${Math.round(r.context)}%` : "-";
|
|
2152
2244
|
const memStr = r.memMb != null ? `${r.memMb}MB` : "-";
|
|
2153
2245
|
const actStr = r.lastActivity ?? "-";
|
|
2154
|
-
console.log(padDisplay(r
|
|
2246
|
+
console.log(padDisplay(displayName(r), nameW) +
|
|
2155
2247
|
r.backend.padEnd(backendW) +
|
|
2156
|
-
statusIcon(r.status, r.idle) + " " + statusLabel(r.status, r.idle).padEnd(statusW - 2) +
|
|
2248
|
+
statusIcon(r.status, r.idle, r.state) + " " + statusLabel(r.status, r.idle, r.state).padEnd(statusW - 2) +
|
|
2157
2249
|
padDisplay(teamStr, teamW) +
|
|
2158
2250
|
r.source.padEnd(srcW) +
|
|
2159
2251
|
ctxStr.padEnd(ctxW) +
|