talon-agent 3.32.0 → 3.33.0
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/package.json +4 -3
- package/src/backend/claude-sdk/constants.ts +1 -6
- package/src/backend/claude-sdk/index.ts +2 -11
- package/src/backend/claude-sdk/models/parsing.ts +2 -2
- package/src/backend/claude-sdk/plan-usage.ts +0 -5
- package/src/backend/claude-sdk/stream.ts +1 -1
- package/src/backend/codex/auth.ts +2 -2
- package/src/backend/codex/constants.ts +0 -21
- package/src/backend/codex/handler/index.ts +0 -1
- package/src/backend/codex/mcp-config.ts +2 -2
- package/src/backend/codex/plan-usage.ts +0 -5
- package/src/backend/codex/state.ts +1 -1
- package/src/backend/codex/token-usage.ts +1 -1
- package/src/backend/kilo/index.ts +0 -6
- package/src/backend/kilo/server.ts +2 -22
- package/src/backend/kilo/sessions.ts +0 -3
- package/src/backend/openai-agents/handler/index.ts +0 -1
- package/src/backend/openai-agents/handler/state.ts +0 -5
- package/src/backend/openai-agents/init.ts +1 -18
- package/src/backend/opencode/index.ts +0 -4
- package/src/backend/opencode/server.ts +1 -10
- package/src/backend/opencode/sessions.ts +0 -3
- package/src/backend/remote-server/client.ts +1 -1
- package/src/backend/remote-server/events.ts +1 -1
- package/src/backend/remote-server/index.ts +4 -27
- package/src/backend/remote-server/mcp.ts +1 -4
- package/src/backend/remote-server/model-catalog/catalog.ts +1 -1
- package/src/backend/remote-server/model-catalog/index.ts +1 -15
- package/src/backend/remote-server/model-catalog/provider.ts +0 -1
- package/src/backend/remote-server/sse-stream.ts +1 -3
- package/src/backend/remote-server/turn-timeout.ts +1 -1
- package/src/backend/shared/index.ts +7 -43
- package/src/cli/logs.ts +1 -1
- package/src/cli/status.ts +1 -1
- package/src/core/agent-runtime/backend-registry.ts +1 -1
- package/src/core/agent-runtime/capabilities.ts +1 -1
- package/src/core/agent-runtime/events.ts +1 -1
- package/src/core/background/heartbeat/agent.ts +1 -1
- package/src/core/background/heartbeat/index.ts +1 -2
- package/src/core/background/isolated-agent.ts +1 -1
- package/src/core/background/triggers/exit.ts +1 -1
- package/src/core/background/triggers/index.ts +1 -1
- package/src/core/bus/events.ts +2 -2
- package/src/core/doctor.ts +1 -1
- package/src/core/engine/backend-controller/index.ts +1 -3
- package/src/core/engine/backend-controller/rebind.ts +2 -2
- package/src/core/engine/dispatcher.ts +1 -15
- package/src/core/engine/gateway-actions/index.ts +0 -3
- package/src/core/engine/gateway-actions/types.ts +1 -1
- package/src/core/frontend-runtime/capabilities.ts +0 -2
- package/src/core/frontend-runtime/index.ts +1 -6
- package/src/core/frontend-runtime/routing.ts +0 -1
- package/src/core/mcp-hub/children.ts +0 -5
- package/src/core/mesh/index.ts +1 -18
- package/src/core/models/active-model.ts +0 -19
- package/src/core/plugin/index.ts +0 -1
- package/src/core/plugin/registry.ts +1 -1
- package/src/core/prompt/templates.ts +0 -5
- package/src/core/scripting/lua-runner.ts +1 -1
- package/src/core/scripts/runner.ts +1 -1
- package/src/core/soul/critic.ts +1 -1
- package/src/core/soul/embedder.ts +2 -2
- package/src/core/soul/governance.ts +1 -1
- package/src/core/soul/hdc.ts +1 -1
- package/src/core/soul/reflex.ts +2 -2
- package/src/core/soul/retrieve.ts +1 -1
- package/src/core/soul/signals.ts +4 -4
- package/src/core/soul/types.ts +1 -1
- package/src/core/tasks/index.ts +0 -4
- package/src/core/tasks/types.ts +1 -1
- package/src/core/tools/index.ts +1 -6
- package/src/core/tools/mcp-env.ts +3 -33
- package/src/core/types.ts +1 -1
- package/src/core/update/self-update.ts +1 -1
- package/src/core/vfs/fusefs.ts +1 -1
- package/src/core/vfs/types.ts +1 -1
- package/src/core/weaver/index.ts +1 -1
- package/src/core/weaver/typing-loop.ts +1 -1
- package/src/frontend/discord/actions/types.ts +1 -1
- package/src/frontend/discord/commands/definitions.ts +1 -1
- package/src/frontend/discord/handlers/access.ts +0 -5
- package/src/frontend/discord/handlers/index.ts +2 -15
- package/src/frontend/discord/handlers/registry.ts +0 -6
- package/src/frontend/native/protocol.ts +1 -4
- package/src/frontend/native/server.ts +1 -1
- package/src/frontend/shared/status-context.ts +1 -1
- package/src/frontend/telegram/actions/types.ts +1 -1
- package/src/frontend/telegram/commands/index.ts +1 -1
- package/src/frontend/telegram/commands/state.ts +1 -1
- package/src/frontend/telegram/handlers/index.ts +0 -1
- package/src/frontend/telegram/helpers/menu.ts +1 -1
- package/src/frontend/terminal/commands.ts +1 -4
- package/src/frontend/terminal/renderer.ts +1 -1
- package/src/frontend/whatsapp/actions/chat-info.ts +0 -3
- package/src/frontend/whatsapp/actions/messaging.ts +1 -7
- package/src/frontend/whatsapp/actions/shared.ts +1 -1
- package/src/frontend/whatsapp/actions/types.ts +1 -1
- package/src/frontend/whatsapp/formatting.ts +1 -1
- package/src/frontend/whatsapp/media-store.ts +1 -1
- package/src/frontend/whatsapp/pins.ts +0 -5
- package/src/native/fusefs.ts +3 -3
- package/src/native/scheduler-core.ts +1 -1
- package/src/native/warden.ts +2 -2
- package/src/plugins/mempalace/provision.ts +1 -5
- package/src/plugins/playwright/provision.ts +1 -1
- package/src/storage/db.ts +1 -1
- package/src/storage/goal-store.ts +1 -5
- package/src/storage/metrics.ts +0 -5
- package/src/storage/repositories/scripts-repo.ts +0 -5
- package/src/storage/scheduled-store.ts +1 -5
- package/src/storage/script-store.ts +5 -13
- package/src/storage/sessions.ts +0 -3
- package/src/storage/skill-store.ts +3 -3
- package/src/util/exec-output.ts +1 -1
- package/src/util/mcp-launcher.ts +3 -0
|
@@ -16,15 +16,11 @@
|
|
|
16
16
|
* talon.json — carried to the subprocess as comma-separated env vars.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { dirname, resolve } from "node:path";
|
|
20
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
21
|
-
import { isBunRuntime } from "../../util/runtime.js";
|
|
22
|
-
|
|
23
19
|
// ── Env-var names (shared constants, not stringly-typed call sites) ────────
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
const ENV_BRIDGE_URL = "TALON_BRIDGE_URL";
|
|
22
|
+
const ENV_CHAT_ID = "TALON_CHAT_ID";
|
|
23
|
+
const ENV_FRONTEND = "TALON_FRONTEND";
|
|
28
24
|
export const ENV_DISABLED_TOOLS = "TALON_DISABLED_TOOLS";
|
|
29
25
|
export const ENV_DISABLED_TOOL_TAGS = "TALON_DISABLED_TOOL_TAGS";
|
|
30
26
|
|
|
@@ -62,32 +58,6 @@ export function buildTalonMcpEnv(
|
|
|
62
58
|
|
|
63
59
|
// ── Spawn spec ──────────────────────────────────────────────────────────────
|
|
64
60
|
|
|
65
|
-
/**
|
|
66
|
-
* The command line that launches Talon's unified MCP tool server.
|
|
67
|
-
*
|
|
68
|
-
* tsx as a Node loader is passed via `--import <file-url>`: Node
|
|
69
|
-
* accepts URLs or absolute paths, but on Windows a raw backslash path
|
|
70
|
-
* is ambiguous between path and URL — `pathToFileURL` always parses
|
|
71
|
-
* as a loader URL. `node --import` (vs spawning `npx`/`tsx` directly)
|
|
72
|
-
* also sidesteps the Node 20.19+ refusal to spawn `.cmd` shims
|
|
73
|
-
* without `shell: true` (CVE-2024-27980 mitigation).
|
|
74
|
-
*
|
|
75
|
-
* Returns a fresh array: callers wrap it in their own supervisor
|
|
76
|
-
* (`wrapMcpServer` / `wrapMcpCommand`) and may mutate it.
|
|
77
|
-
*/
|
|
78
|
-
export function talonMcpServerCommand(): string[] {
|
|
79
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
80
|
-
// Bun executes the TS entry natively — no loader, and use the running
|
|
81
|
-
// bun binary itself so the child matches the daemon's runtime.
|
|
82
|
-
if (isBunRuntime()) {
|
|
83
|
-
return [process.execPath, resolve(here, "mcp-server.ts")];
|
|
84
|
-
}
|
|
85
|
-
const tsxImport = pathToFileURL(
|
|
86
|
-
resolve(here, "../../../node_modules/tsx/dist/esm/index.mjs"),
|
|
87
|
-
).href;
|
|
88
|
-
return ["node", "--import", tsxImport, resolve(here, "mcp-server.ts")];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
61
|
// ── Parser (server side) ────────────────────────────────────────────────────
|
|
92
62
|
|
|
93
63
|
/** Parse a comma-separated env var into a trimmed, de-blanked list. */
|
package/src/core/types.ts
CHANGED
|
@@ -202,7 +202,7 @@ export interface ContextManager {
|
|
|
202
202
|
* oversized-message), and a successful one by returning. This keeps
|
|
203
203
|
* the ack settled even when no `onEvent` is supplied at all.
|
|
204
204
|
*/
|
|
205
|
-
|
|
205
|
+
type StreamEventSink = {
|
|
206
206
|
onEvent?: (
|
|
207
207
|
event: import("./agent-runtime/events.js").AgentEvent,
|
|
208
208
|
) => void | Promise<void>;
|
package/src/core/vfs/fusefs.ts
CHANGED
|
@@ -91,7 +91,7 @@ export function namespaceFsStatus(): FuseStatus {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/** Test seam — force a status without a real mount. */
|
|
94
|
-
|
|
94
|
+
function _setNamespaceFsStatusForTesting(next: FuseStatus): void {
|
|
95
95
|
status = next;
|
|
96
96
|
}
|
|
97
97
|
|
package/src/core/vfs/types.ts
CHANGED
package/src/core/weaver/index.ts
CHANGED
|
@@ -17,7 +17,7 @@ import type { TalonConfig } from "../../../util/config.js";
|
|
|
17
17
|
import { log, logError, logWarn } from "../../../util/log.js";
|
|
18
18
|
import { getRepoRoot } from "../../../core/update/self-update.js";
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
function buildCommandDefinitions(devBuild = false): unknown[] {
|
|
21
21
|
return [
|
|
22
22
|
new SlashCommandBuilder()
|
|
23
23
|
.setName("start")
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
userMessageTimestamps,
|
|
20
20
|
RATE_LIMIT_WINDOW_MS,
|
|
21
21
|
RATE_LIMIT_MAX_MESSAGES,
|
|
22
|
-
type AccessConfig,
|
|
23
22
|
} from "./state.js";
|
|
24
23
|
|
|
25
24
|
export function setAccessControl(cfg: {
|
|
@@ -42,10 +41,6 @@ export function isAdmin(userId: string): boolean {
|
|
|
42
41
|
return accessState.access.adminUserIds.has(userId);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
export function getAccessSnapshot(): AccessConfig {
|
|
46
|
-
return accessState.access;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
44
|
export function trackDmUser(
|
|
50
45
|
senderId: string,
|
|
51
46
|
senderName: string,
|
|
@@ -15,20 +15,7 @@
|
|
|
15
15
|
* Re-exports the same public surface the old single-file module exposed.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
export
|
|
19
|
-
export {
|
|
20
|
-
registerDiscordChat,
|
|
21
|
-
lookupDiscordChat,
|
|
22
|
-
lookupDiscordChatByString,
|
|
23
|
-
} from "./registry.js";
|
|
24
|
-
export {
|
|
25
|
-
setAccessControl,
|
|
26
|
-
isAdmin,
|
|
27
|
-
getAccessSnapshot,
|
|
28
|
-
isAccessAllowed,
|
|
29
|
-
isInteractionAllowed,
|
|
30
|
-
shouldHandleInGuild,
|
|
31
|
-
isUserRateLimited,
|
|
32
|
-
} from "./access.js";
|
|
18
|
+
export { registerDiscordChat, lookupDiscordChat } from "./registry.js";
|
|
19
|
+
export { setAccessControl, isAdmin, isInteractionAllowed } from "./access.js";
|
|
33
20
|
export { getSenderName, sendChunked } from "./context.js";
|
|
34
21
|
export { handleMessage } from "./messages.js";
|
|
@@ -21,9 +21,3 @@ export function lookupDiscordChat(
|
|
|
21
21
|
): DiscordChatInfo | undefined {
|
|
22
22
|
return chatRegistry.get(numericChatId);
|
|
23
23
|
}
|
|
24
|
-
|
|
25
|
-
export function lookupDiscordChatByString(
|
|
26
|
-
chatId: string,
|
|
27
|
-
): DiscordChatInfo | undefined {
|
|
28
|
-
return chatRegistryByString.get(chatId);
|
|
29
|
-
}
|
|
@@ -26,7 +26,7 @@ export const BOT_SENDER_ID = 0;
|
|
|
26
26
|
/** History sender id used for the human on the other end of a native chat. */
|
|
27
27
|
export const USER_SENDER_ID = 1;
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
type ClientRole = "user" | "assistant" | "system";
|
|
30
30
|
|
|
31
31
|
/** An inline button. `url` opens a link; `data` is an opaque callback token. */
|
|
32
32
|
export type ClientButton = { text: string; url?: string; data?: string };
|
|
@@ -238,7 +238,6 @@ export type {
|
|
|
238
238
|
DeviceCommandResult,
|
|
239
239
|
DeviceInfo,
|
|
240
240
|
DeviceLocation,
|
|
241
|
-
DevicePlatform,
|
|
242
241
|
} from "../../core/mesh/types.js";
|
|
243
242
|
import type { DeviceCommand as MeshDeviceCommand } from "../../core/mesh/types.js";
|
|
244
243
|
|
|
@@ -323,5 +322,3 @@ export function historyToClientMessage(
|
|
|
323
322
|
ts: m.timestamp,
|
|
324
323
|
};
|
|
325
324
|
}
|
|
326
|
-
|
|
327
|
-
export { toDeviceInfo, toDeviceLocation } from "../../core/mesh/types.js";
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
import type { ConfigSnapshot } from "./settings.js";
|
|
49
49
|
|
|
50
50
|
/** Optional attachment references carried alongside a sent message. */
|
|
51
|
-
|
|
51
|
+
type SendOptions = {
|
|
52
52
|
/** Relative bridge path to render inline (e.g. `/media?id=…`). */
|
|
53
53
|
imagePath?: string;
|
|
54
54
|
/** Absolute on-disk path handed to the model so it can read the file. */
|
|
@@ -292,7 +292,7 @@ export function buildCacheDisplay(input: {
|
|
|
292
292
|
/** Figures older than this are labelled with their age in /status. */
|
|
293
293
|
const PLAN_STALE_AFTER_MS = 5 * 60_000;
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
interface PlanWindowDisplay {
|
|
296
296
|
label: string;
|
|
297
297
|
percent: number;
|
|
298
298
|
bar: string;
|
|
@@ -20,7 +20,7 @@ export interface TelegramActionContext {
|
|
|
20
20
|
scheduledMessages: Map<string, ReturnType<typeof setTimeout>>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
type TelegramActionHandler = (
|
|
24
24
|
body: Record<string, unknown>,
|
|
25
25
|
chatId: number,
|
|
26
26
|
ctx: TelegramActionContext,
|
|
@@ -24,7 +24,7 @@ import { registerSettingsCommands } from "./settings.js";
|
|
|
24
24
|
import { registerAdminCommands } from "./admin.js";
|
|
25
25
|
import { registerWhatsAppPairingCommand } from "./whatsapp-pairing.js";
|
|
26
26
|
|
|
27
|
-
export {
|
|
27
|
+
export { telegramCommandMenu } from "./definitions.js";
|
|
28
28
|
export { setAdminUserId } from "./state.js";
|
|
29
29
|
|
|
30
30
|
export function registerCommands(
|
|
@@ -11,7 +11,7 @@ import type { Context } from "grammy";
|
|
|
11
11
|
import type { Backend } from "../../../core/agent-runtime/capabilities.js";
|
|
12
12
|
|
|
13
13
|
/** Admin user ID is set via talon.json or TALON_ADMIN_USER_ID env var. */
|
|
14
|
-
|
|
14
|
+
const adminState = { adminUserId: 0 };
|
|
15
15
|
|
|
16
16
|
/** Set the admin user ID (called from config at startup). */
|
|
17
17
|
export function setAdminUserId(id: number | undefined): void {
|
|
@@ -75,7 +75,7 @@ export interface SettingsPager {
|
|
|
75
75
|
* callback for disabled-edge buttons (Telegram requires every inline
|
|
76
76
|
* button to carry callback data).
|
|
77
77
|
*/
|
|
78
|
-
|
|
78
|
+
function renderModelPickerControlRows(
|
|
79
79
|
pager: SettingsPager,
|
|
80
80
|
navPrefix: string,
|
|
81
81
|
noopData: string,
|
|
@@ -62,10 +62,7 @@ export type CommandContext = {
|
|
|
62
62
|
backend?: Backend | null;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
args: string,
|
|
67
|
-
ctx: CommandContext,
|
|
68
|
-
) => Promise<void>;
|
|
65
|
+
type CommandHandler = (args: string, ctx: CommandContext) => Promise<void>;
|
|
69
66
|
|
|
70
67
|
export type Command = {
|
|
71
68
|
name: string;
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* assembled from the registry and the profile endpoints.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import { downloadMediaMessage } from "baileys";
|
|
10
9
|
import { lookupMessage } from "../message-store.js";
|
|
11
10
|
import { toUserJid, tryAction } from "./shared.js";
|
|
12
11
|
import type { WhatsAppActionHandlers } from "./types.js";
|
|
@@ -224,5 +223,3 @@ export const chatInfoHandlers: WhatsAppActionHandlers = {
|
|
|
224
223
|
};
|
|
225
224
|
}),
|
|
226
225
|
};
|
|
227
|
-
|
|
228
|
-
export { downloadMediaMessage };
|
|
@@ -11,11 +11,7 @@ import { randomUUID } from "node:crypto";
|
|
|
11
11
|
import { proto } from "baileys";
|
|
12
12
|
import { log } from "../../../util/log.js";
|
|
13
13
|
import { toWhatsAppText } from "../formatting.js";
|
|
14
|
-
import {
|
|
15
|
-
lookupMessage,
|
|
16
|
-
rememberMessage,
|
|
17
|
-
resolveKey,
|
|
18
|
-
} from "../message-store.js";
|
|
14
|
+
import { lookupMessage, resolveKey } from "../message-store.js";
|
|
19
15
|
import { recordPin, listPins, forgetPin } from "../pins.js";
|
|
20
16
|
import {
|
|
21
17
|
resolveQuoted,
|
|
@@ -293,5 +289,3 @@ export const messagingHandlers: WhatsAppActionHandlers = {
|
|
|
293
289
|
};
|
|
294
290
|
},
|
|
295
291
|
};
|
|
296
|
-
|
|
297
|
-
export { rememberMessage };
|
|
@@ -177,7 +177,7 @@ function outboundTextMarker(content: AnyMessageContent): string {
|
|
|
177
177
|
const SEND_TIMEOUT_MS = 60_000;
|
|
178
178
|
let sendTail: Promise<unknown> = Promise.resolve();
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
class WhatsAppSendTimeoutError extends Error {
|
|
181
181
|
constructor(operation: string) {
|
|
182
182
|
super(
|
|
183
183
|
`WhatsApp ${operation} timed out after ${SEND_TIMEOUT_MS / 1000}s — ` +
|
|
@@ -25,7 +25,7 @@ export interface WhatsAppActionContext {
|
|
|
25
25
|
scheduledMessages: Map<string, ReturnType<typeof setTimeout>>;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
type WhatsAppActionHandler = (
|
|
29
29
|
body: Record<string, unknown>,
|
|
30
30
|
chatId: number,
|
|
31
31
|
ctx: WhatsAppActionContext,
|
|
@@ -17,7 +17,7 @@ import { marked, type Token, type Tokens } from "marked";
|
|
|
17
17
|
import { splitMessage } from "../telegram/formatting.js";
|
|
18
18
|
|
|
19
19
|
/** WhatsApp accepts far more, but long bubbles read badly on a phone. */
|
|
20
|
-
|
|
20
|
+
const WHATSAPP_MAX_TEXT = 4096;
|
|
21
21
|
|
|
22
22
|
/** Rendered width of a table cell, for the monospace fallback. */
|
|
23
23
|
const MAX_TABLE_CELL = 24;
|
|
@@ -45,8 +45,3 @@ export function forgetPin(chatId: string, msgId: number): void {
|
|
|
45
45
|
export function listPins(chatId: string): PinnedMessage[] {
|
|
46
46
|
return pinsByChat.get(chatId) ?? [];
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
/** Test seam: forget every recorded pin. */
|
|
50
|
-
export function resetPins(): void {
|
|
51
|
-
pinsByChat.clear();
|
|
52
|
-
}
|
package/src/native/fusefs.ts
CHANGED
|
@@ -20,7 +20,7 @@ import { createRequire } from "node:module";
|
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
|
|
22
22
|
/** One root symlink entry the mount serves (a file-backed mount). */
|
|
23
|
-
|
|
23
|
+
interface FuseSymlinkSpec {
|
|
24
24
|
name: string;
|
|
25
25
|
target: string;
|
|
26
26
|
}
|
|
@@ -32,7 +32,7 @@ export interface FuseSymlinkSpec {
|
|
|
32
32
|
* namespace-relative ("proc/tasks/7"). The reply JSON shapes are
|
|
33
33
|
* defined by `serveNamespaceRequest` in core/vfs/fusefs.ts.
|
|
34
34
|
*/
|
|
35
|
-
|
|
35
|
+
type FuseBridgeHandler = (id: number, op: string, path: string) => void;
|
|
36
36
|
|
|
37
37
|
/** The N-API surface exported by native/talon-fusefs. */
|
|
38
38
|
export interface NativeFuseFs {
|
|
@@ -92,6 +92,6 @@ function loadNativeFuseFs(): NativeFuseFs | null {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/** Tests swap addons via TALON_FUSEFS_NODE and need the memo dropped. */
|
|
95
|
-
|
|
95
|
+
function _resetNativeFuseFsForTesting(): void {
|
|
96
96
|
addon = undefined;
|
|
97
97
|
}
|
|
@@ -37,7 +37,7 @@ export function backoffDelayMs(
|
|
|
37
37
|
|
|
38
38
|
// ── Circuit breaker ─────────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
type BreakerState = "closed" | "open" | "half-open";
|
|
41
41
|
|
|
42
42
|
export type Breaker = {
|
|
43
43
|
state: BreakerState;
|
package/src/native/warden.ts
CHANGED
|
@@ -28,13 +28,13 @@ import { accessSync, constants } from "node:fs";
|
|
|
28
28
|
import { createInterface } from "node:readline";
|
|
29
29
|
import { fileURLToPath } from "node:url";
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
interface WardenStartEvent {
|
|
32
32
|
pid: number;
|
|
33
33
|
/** Linux /proc/<pid>/stat field 22 (jiffies since boot); null off-Linux. */
|
|
34
34
|
pidStarttime: number | null;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
interface WardenLineEvent {
|
|
38
38
|
stream: "stdout" | "stderr";
|
|
39
39
|
text: string;
|
|
40
40
|
/** True when the line exceeded the byte cap and its tail was dropped. */
|
|
@@ -148,11 +148,7 @@ export function classifyExternalInstall(pythonPath: string): string {
|
|
|
148
148
|
* version, per flavor. Works in both directions (a newer-than-pin
|
|
149
149
|
* install reconciles down), hence the neutral name.
|
|
150
150
|
*/
|
|
151
|
-
|
|
152
|
-
kind: string,
|
|
153
|
-
python: string,
|
|
154
|
-
target: string,
|
|
155
|
-
): string {
|
|
151
|
+
function reconcileHint(kind: string, python: string, target: string): string {
|
|
156
152
|
if (kind === "uv-tool") {
|
|
157
153
|
return `uv tool install --force 'mempalace==${target}'`;
|
|
158
154
|
}
|
|
@@ -57,7 +57,7 @@ export interface PlaywrightProvisionDeps {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
/** One entry of playwright-core's browsers.json. */
|
|
60
|
-
|
|
60
|
+
interface BrowserDescriptor {
|
|
61
61
|
name: string;
|
|
62
62
|
revision: string;
|
|
63
63
|
/** Per-host-platform revisions (e.g. webkit on older macOS). */
|
package/src/storage/db.ts
CHANGED
|
@@ -37,7 +37,7 @@ import { SCHEMA, dbSql } from "./sql/statements.generated.js";
|
|
|
37
37
|
* statements with positional params, identical row object shapes,
|
|
38
38
|
* multi-statement exec, FTS5 virtual tables).
|
|
39
39
|
*/
|
|
40
|
-
|
|
40
|
+
type SqlStatement = {
|
|
41
41
|
get(...params: unknown[]): unknown;
|
|
42
42
|
all(...params: unknown[]): unknown[];
|
|
43
43
|
run(...params: unknown[]): unknown;
|
|
@@ -34,11 +34,7 @@ export const GOAL_STATUSES: readonly GoalStatus[] = [
|
|
|
34
34
|
"completed",
|
|
35
35
|
"abandoned",
|
|
36
36
|
];
|
|
37
|
-
|
|
38
|
-
"low",
|
|
39
|
-
"normal",
|
|
40
|
-
"high",
|
|
41
|
-
];
|
|
37
|
+
const GOAL_PRIORITIES: readonly GoalPriority[] = ["low", "normal", "high"];
|
|
42
38
|
|
|
43
39
|
/** Statuses that count as "open" — shown to the heartbeat and listings. */
|
|
44
40
|
export const OPEN_GOAL_STATUSES: readonly GoalStatus[] = ["active", "paused"];
|
package/src/storage/metrics.ts
CHANGED
|
@@ -24,11 +24,6 @@ export function incrementCounter(name: string, amount = 1): void {
|
|
|
24
24
|
legacyCounters.set(name, (legacyCounters.get(name) ?? 0) + amount);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export function recordHistogram(_name: string, _value: number): void {
|
|
28
|
-
// The old global histogram ring is intentionally gone. Chat-turn
|
|
29
|
-
// histograms are now latency aggregates on SessionMetrics.
|
|
30
|
-
}
|
|
31
|
-
|
|
32
27
|
function addCounter(
|
|
33
28
|
counters: Record<string, number>,
|
|
34
29
|
name: string,
|
|
@@ -79,11 +79,6 @@ export function all(): Script[] {
|
|
|
79
79
|
return rows.map(rowToScript);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
export function count(): number {
|
|
83
|
-
const row = getDatabase().prepare(scriptsSql.count).get() as { n: number };
|
|
84
|
-
return row.n;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
82
|
export function recordUse(name: string, when: number): void {
|
|
88
83
|
getDatabase().prepare(scriptsSql.recordUse).run(when, name);
|
|
89
84
|
}
|
|
@@ -24,7 +24,7 @@ const KEY = "scheduled.messages";
|
|
|
24
24
|
* "dinner in an hour" reminder is noise, not delivery. */
|
|
25
25
|
export const MAX_OVERDUE_MS = 24 * 60 * 60 * 1000;
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
type ScheduledButtonRow = Array<{
|
|
28
28
|
text: string;
|
|
29
29
|
url?: string;
|
|
30
30
|
callback_data?: string;
|
|
@@ -67,10 +67,6 @@ export function deleteScheduled(id: string): boolean {
|
|
|
67
67
|
return true;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
export function getScheduled(id: string): ScheduledMessage | undefined {
|
|
71
|
-
return readAll()[id];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
70
|
/** All pending entries for a frontend, soonest first. */
|
|
75
71
|
export function listScheduled(frontend: string): ScheduledMessage[] {
|
|
76
72
|
return Object.values(readAll())
|
|
@@ -25,11 +25,7 @@ import * as repo from "./repositories/scripts-repo.js";
|
|
|
25
25
|
export type { Script, ScriptLanguage } from "./repositories/scripts-repo.js";
|
|
26
26
|
import type { Script, ScriptLanguage } from "./repositories/scripts-repo.js";
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
"bash",
|
|
30
|
-
"python",
|
|
31
|
-
"node",
|
|
32
|
-
];
|
|
28
|
+
const SCRIPT_LANGUAGES: readonly ScriptLanguage[] = ["bash", "python", "node"];
|
|
33
29
|
|
|
34
30
|
/**
|
|
35
31
|
* Stricter than the trigger name rule: a script name doubles as its
|
|
@@ -81,16 +77,16 @@ export function validateScriptDescription(description: string): string | null {
|
|
|
81
77
|
|
|
82
78
|
// ── Script files ────────────────────────────────────────────────────────────
|
|
83
79
|
|
|
84
|
-
|
|
80
|
+
function scriptsDir(): string {
|
|
85
81
|
return dirs.scripts;
|
|
86
82
|
}
|
|
87
83
|
|
|
88
|
-
|
|
84
|
+
function scriptFilePath(name: string, lang: ScriptLanguage): string {
|
|
89
85
|
return resolve(scriptsDir(), `${name}.${EXTENSIONS[lang]}`);
|
|
90
86
|
}
|
|
91
87
|
|
|
92
88
|
/** Write a script's body, creating the scripts dir as needed. */
|
|
93
|
-
|
|
89
|
+
function writeScriptFile(
|
|
94
90
|
name: string,
|
|
95
91
|
lang: ScriptLanguage,
|
|
96
92
|
body: string,
|
|
@@ -104,7 +100,7 @@ export function writeScriptFile(
|
|
|
104
100
|
|
|
105
101
|
// ── CRUD ────────────────────────────────────────────────────────────────────
|
|
106
102
|
|
|
107
|
-
|
|
103
|
+
function generateScriptId(): string {
|
|
108
104
|
return `script_${randomUUID()}`;
|
|
109
105
|
}
|
|
110
106
|
|
|
@@ -152,10 +148,6 @@ export function getAllScripts(): Script[] {
|
|
|
152
148
|
return repo.all();
|
|
153
149
|
}
|
|
154
150
|
|
|
155
|
-
export function countScripts(): number {
|
|
156
|
-
return repo.count();
|
|
157
|
-
}
|
|
158
|
-
|
|
159
151
|
export function recordScriptUse(name: string): void {
|
|
160
152
|
repo.recordUse(name, Date.now());
|
|
161
153
|
}
|
package/src/storage/sessions.ts
CHANGED
|
@@ -28,11 +28,8 @@ export type {
|
|
|
28
28
|
MetricsCounterSet,
|
|
29
29
|
MetricsGrain,
|
|
30
30
|
MetricsLatencyAgg,
|
|
31
|
-
SessionMetrics,
|
|
32
31
|
SessionState,
|
|
33
|
-
SessionUsage,
|
|
34
32
|
} from "./session-record.js";
|
|
35
|
-
export { emptyMetrics, normaliseMetrics } from "./session-record.js";
|
|
36
33
|
import {
|
|
37
34
|
emptyCounters,
|
|
38
35
|
emptyGrain,
|
|
@@ -66,15 +66,15 @@ const BODY_MAX_BYTES = 128 * 1024;
|
|
|
66
66
|
const PROMPT_LIST_LIMIT = 25;
|
|
67
67
|
const SEARCH_RESULT_LIMIT = 10;
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
function skillsDir(): string {
|
|
70
70
|
return dirs.skills;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
73
|
+
function skillDir(name: string): string {
|
|
74
74
|
return resolve(skillsDir(), name);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
function skillFilePath(name: string): string {
|
|
78
78
|
return resolve(skillDir(name), SKILL_FILE);
|
|
79
79
|
}
|
|
80
80
|
|
package/src/util/exec-output.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/** In-memory cap while capturing one child-process output stream. */
|
|
14
|
-
|
|
14
|
+
const MAX_EXEC_CAPTURE_BYTES = 4 * 1024 * 1024;
|
|
15
15
|
|
|
16
16
|
/** Ceiling on each rendered exec stream (stdout, stderr independently). */
|
|
17
17
|
export const MAX_EXEC_RENDER_CHARS = 30_000;
|
package/src/util/mcp-launcher.ts
CHANGED
|
@@ -83,6 +83,9 @@ export const MCP_LAUNCH_SUBCOMMAND = "_mcp-launch";
|
|
|
83
83
|
* `[command, ...argsPrefix]` that launches an entry which DOES dispatch
|
|
84
84
|
* (e.g. `["node", "--import", "<tsx esm url>",
|
|
85
85
|
* "<abs path to src/cli.ts>"]`).
|
|
86
|
+
*
|
|
87
|
+
* @public — consumed by embedders (and the integration probe), not by
|
|
88
|
+
* Talon's own graph, so knip must not report it.
|
|
86
89
|
*/
|
|
87
90
|
export const SUPERVISOR_CMD_ENV = "TALON_MCP_SUPERVISOR_CMD";
|
|
88
91
|
|