@sleep2agi/agent-network 2.3.0-preview.7 → 2.3.0-preview.71
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 +35 -324
- package/dist/bin/anet.cjs +101 -0
- package/dist/bin/cli.d.ts +1 -0
- package/dist/bin/cli.js +20 -1
- package/dist/bin/goal-wake-log-render.d.ts +31 -0
- package/dist/src/batch-workdir.d.ts +9 -0
- package/dist/src/bootstrap-password-db.d.ts +13 -0
- package/dist/src/channel-attachments.d.ts +29 -0
- package/dist/src/channel-meta.d.ts +10 -0
- package/dist/src/channel-task-trace.d.ts +10 -0
- package/dist/src/claude-vendor-env.d.ts +28 -0
- package/dist/src/cli-args.d.ts +8 -0
- package/dist/src/client-task-trace.d.ts +9 -0
- package/dist/src/client.js +1 -1
- package/dist/src/codex-copresence-preflight.d.ts +65 -0
- package/dist/src/codex-copresence-profile.d.ts +125 -0
- package/dist/src/codex-copresence-recovery.d.ts +43 -0
- package/dist/src/codex-copresence-thread.d.ts +13 -0
- package/dist/src/codex-model-default.d.ts +6 -0
- package/dist/src/codex-tui-client-health.d.ts +17 -0
- package/dist/src/commhub-response.d.ts +1 -0
- package/dist/src/controlled-upload.d.ts +83 -0
- package/dist/src/copresence-deps.d.ts +22 -0
- package/dist/src/copresence-identity.d.ts +339 -0
- package/dist/src/copresence-startup-diagnosis.d.ts +17 -0
- package/dist/src/daemon-capability-display.d.ts +58 -0
- package/dist/src/daemon-capability-display.js +9 -0
- package/dist/src/dashboard-managed-process.d.ts +35 -0
- package/dist/src/environ-alias.d.ts +14 -0
- package/dist/src/grok-attach-client.d.ts +129 -0
- package/dist/src/grok-copresence-disclosure.d.ts +11 -0
- package/dist/src/grok-copresence-orchestration.d.ts +70 -0
- package/dist/src/grok-copresence-profile.d.ts +65 -0
- package/dist/src/im/correlation-store.d.ts +34 -0
- package/dist/src/im/feishu/adapter.d.ts +118 -1
- package/dist/src/im/feishu/bridge.d.ts +85 -14
- package/dist/src/im/feishu/config.d.ts +31 -0
- package/dist/src/im/feishu/hub-upload.d.ts +88 -0
- package/dist/src/im/feishu/markdown-image-renderer.d.ts +61 -0
- package/dist/src/im/feishu/outbound-marker.d.ts +140 -0
- package/dist/src/im/feishu/outbound-paths.d.ts +50 -0
- package/dist/src/im/feishu/outbound-route.d.ts +62 -0
- package/dist/src/im/feishu/worker-lifecycle.d.ts +13 -0
- package/dist/src/im/feishu/worker.js +403 -28
- package/dist/src/im/types.d.ts +38 -1
- package/dist/src/locale-diagnostic.d.ts +12 -0
- package/dist/src/mock-llm.d.ts +12 -0
- package/dist/src/node-activity-log.d.ts +4 -0
- package/dist/src/node-server-payload.d.ts +66 -0
- package/dist/src/node-server.js +7 -1
- package/dist/src/normalize-runtime.d.ts +29 -2
- package/dist/src/opencode-agent-node-pair.d.ts +25 -0
- package/dist/src/opencode-auth-login.d.ts +43 -0
- package/dist/src/opencode-launch-env.d.ts +13 -0
- package/dist/src/opencode-owner-mode.d.ts +6 -0
- package/dist/src/opencode-package-binary.d.ts +21 -0
- package/dist/src/opencode-pin.d.ts +44 -0
- package/dist/src/opencode-preset.d.ts +73 -0
- package/dist/src/opencode-runtime-binding.d.ts +30 -0
- package/dist/src/opencode-safe-root.d.ts +27 -0
- package/dist/src/opencode-smoke-env.d.ts +1 -0
- package/dist/src/outbound-tool-names.d.ts +1 -0
- package/dist/src/owned-roots.d.ts +58 -0
- package/dist/src/owner-env-file.d.ts +2 -0
- package/dist/src/package-mode-preflight.d.ts +41 -0
- package/dist/src/posix-codex-copresence.d.ts +8 -0
- package/dist/src/posix-modes.d.ts +36 -0
- package/dist/src/primary-network.d.ts +23 -0
- package/dist/src/private-state.d.ts +10 -0
- package/dist/src/profile-serialize.d.ts +1 -0
- package/dist/src/project-key.d.ts +1 -0
- package/dist/src/reply-originator.d.ts +20 -0
- package/dist/src/resume-runtime-infer.d.ts +18 -0
- package/dist/src/secret-shell-guidance.d.ts +3 -0
- package/dist/src/stale-socket.d.ts +118 -0
- package/dist/src/task-trace.d.ts +33 -0
- package/dist/src/tmux-attach.d.ts +8 -0
- package/dist/src/tmux-capability.d.ts +58 -0
- package/dist/src/tmux-exact-target.d.ts +34 -0
- package/dist/src/tmux-pane-prompt.d.ts +22 -0
- package/dist/src/token-cli.d.ts +13 -0
- package/dist/src/tool-allowlist.d.ts +28 -0
- package/dist/src/unsafe-package-path-reason.d.ts +17 -0
- package/dist/src/win-launcher.d.ts +20 -0
- package/dist/src/windows-codex-copresence.d.ts +41 -0
- package/package.json +14 -6
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
export interface StaleSocketProbes {
|
|
2
|
+
/** 读 /proc/net/unix 全文;读不到就 throw(调用方按 fail-closed 处理)。 */
|
|
3
|
+
procNetUnix(): string;
|
|
4
|
+
/** 路径不存在返回 null。 */
|
|
5
|
+
lstat(path: string): {
|
|
6
|
+
dev: number;
|
|
7
|
+
ino: number;
|
|
8
|
+
uid: number;
|
|
9
|
+
isSocket: boolean;
|
|
10
|
+
} | null;
|
|
11
|
+
unlink(path: string): void;
|
|
12
|
+
/** 当前进程 uid —— 只回收自己拥有的 socket。 */
|
|
13
|
+
currentUid(): number;
|
|
14
|
+
}
|
|
15
|
+
export interface ReapScope {
|
|
16
|
+
/**
|
|
17
|
+
* 只允许回收这个目录**之下**的路径。
|
|
18
|
+
* 🔴 这一格防的不是文件系统竞态,是**被污染的 identity**:socket 路径来自
|
|
19
|
+
* profile,如果 profile 被写坏成 `/run/systemd/private` 之类,前面所有
|
|
20
|
+
* "无监听者"检查都会照常通过,然后 unlink 掉一个不属于这个节点的东西。
|
|
21
|
+
* 删除不可逆,所以范围校验必须在**所有**其它检查之前。
|
|
22
|
+
*/
|
|
23
|
+
allowedRoot: string;
|
|
24
|
+
}
|
|
25
|
+
export type ReapOutcome =
|
|
26
|
+
/** 路径已经不在了 —— 正常的成功拆卸,无事可做。 */
|
|
27
|
+
{
|
|
28
|
+
kind: "absent";
|
|
29
|
+
}
|
|
30
|
+
/** 确认无人引用,已删除。 */
|
|
31
|
+
| {
|
|
32
|
+
kind: "removed";
|
|
33
|
+
}
|
|
34
|
+
/** /proc/net/unix 里仍能找到这个路径 ⇒ 有人在用,**不删**,调用方应判红。 */
|
|
35
|
+
| {
|
|
36
|
+
kind: "in-use";
|
|
37
|
+
}
|
|
38
|
+
/** /proc/net/unix 读不到 ⇒ fail-closed,不删。 */
|
|
39
|
+
| {
|
|
40
|
+
kind: "unreadable";
|
|
41
|
+
detail: string;
|
|
42
|
+
}
|
|
43
|
+
/** 检查与删除之间文件身份变了(dev/ino/uid),或已不是 socket ⇒ 不删。 */
|
|
44
|
+
| {
|
|
45
|
+
kind: "changed";
|
|
46
|
+
}
|
|
47
|
+
/** 路径不在该节点自己的 runtime 目录之下 ⇒ 一律不删。 */
|
|
48
|
+
| {
|
|
49
|
+
kind: "out-of-scope";
|
|
50
|
+
detail: string;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* `/proc/net/unix` 的每一行以路径结尾(没有绑定路径的行就没有这一列)。
|
|
54
|
+
* 这里只问「这个路径出现过没有」,不解释 flags/type/state。
|
|
55
|
+
*/
|
|
56
|
+
export declare function unixSocketPathInUse(procNetUnix: string, path: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* 属主进程**已被证明消失之后**,回收一个陈旧的 socket 路径名。
|
|
59
|
+
* 任何一种不确定都不删 —— 删文件不可逆,而留下一个 socket 只是让 stop 判红,
|
|
60
|
+
* 那正是本函数之前的行为。
|
|
61
|
+
*/
|
|
62
|
+
export declare function reapStaleSocket(path: string, probes: StaleSocketProbes, scope: ReapScope): ReapOutcome;
|
|
63
|
+
/**
|
|
64
|
+
* 从「本次 stop 看到的残留路径」里挑出**允许回收**的那些。
|
|
65
|
+
*
|
|
66
|
+
* 🔴 判据是「与重新算出来的规范路径**完全相等**」,不是前缀、不是包含。
|
|
67
|
+
* profile 里存的 socket 路径是**被写坏就会跟着坏**的数据;
|
|
68
|
+
* grokCopresenceSocketPaths 是纯函数,同样的 nodeId + home 永远算出同一个值。
|
|
69
|
+
* 所以这里不问「这条路径看起来对不对」,只问「它是不是我自己算出来的那两个之一」。
|
|
70
|
+
* ——一个被污染的 profile 因此一条都带不进来。
|
|
71
|
+
*/
|
|
72
|
+
export declare function planReapableSockets(canonical: {
|
|
73
|
+
leaderSocket: string;
|
|
74
|
+
attachSocket: string;
|
|
75
|
+
}, residualPaths: readonly (string | undefined)[]): string[];
|
|
76
|
+
export interface CanonicalSocketProfile {
|
|
77
|
+
node_id?: string;
|
|
78
|
+
grokLeaderSocket?: string;
|
|
79
|
+
grokAttachSocket?: string;
|
|
80
|
+
}
|
|
81
|
+
export type CanonicalSocketsOutcome = {
|
|
82
|
+
kind: "ok";
|
|
83
|
+
leaderSocket: string;
|
|
84
|
+
attachSocket: string;
|
|
85
|
+
}
|
|
86
|
+
/** profile 里没有 node_id —— 算不出来,不动手。 */
|
|
87
|
+
| {
|
|
88
|
+
kind: "no-node-id";
|
|
89
|
+
}
|
|
90
|
+
/** 重新算出来的与 profile 存的不一致 —— profile 被写坏、HOME 变了、或**调用方喂错了 id**。 */
|
|
91
|
+
| {
|
|
92
|
+
kind: "mismatch";
|
|
93
|
+
recomputedLeader: string;
|
|
94
|
+
storedLeader: string;
|
|
95
|
+
}
|
|
96
|
+
/** 路径算不出来(grokCopresenceSocketPaths 抛错)—— 不动手,但也不该把 stop 整个弄失败。 */
|
|
97
|
+
| {
|
|
98
|
+
kind: "uncomputable";
|
|
99
|
+
detail: string;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* 从 profile 推出规范 socket 路径,并**与 profile 里存的那份交叉校验**。
|
|
103
|
+
*
|
|
104
|
+
* 🔴 这个交叉校验是一次真实缺陷催生的,不是补全性写的:
|
|
105
|
+
* 我第一版在 cli.ts 里写的是 `grokCopresenceSocketPaths(resolved.id)`,而
|
|
106
|
+
* `resolveNodeRef` 返回的 `id` 是**目录名(别名)**,socket 路径却是
|
|
107
|
+
* `anet node create` 用 **node_id** 算的。两者哈希不同 ⇒ 算出的路径永远对不上 ⇒
|
|
108
|
+
* 可回收集合恒为空 ⇒ **一条都回收不了,而且完全静默**(循环体一次都不进)。
|
|
109
|
+
* 12 轮验收里 4 次红、0 次回收,红话与修复前逐字相同 —— 从外面看,
|
|
110
|
+
* 「守卫拒绝了一切」和「这个修复不存在」是同一个样子。
|
|
111
|
+
*
|
|
112
|
+
* 所以判据不能只是「算一个路径出来」,必须是「算出来的和存着的对得上」。
|
|
113
|
+
* 对不上就说出来,别静默跳过。
|
|
114
|
+
*/
|
|
115
|
+
export declare function canonicalSocketsForProfile(profile: CanonicalSocketProfile, compute: (nodeId: string) => {
|
|
116
|
+
leaderSocket: string;
|
|
117
|
+
attachSocket: string;
|
|
118
|
+
}): CanonicalSocketsOutcome;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type TaskTraceTransport = "mcp_http" | "sdk_mcp_proxy" | "channel_mcp_proxy";
|
|
2
|
+
export type TaskTraceStatus = "sending" | "delivered" | "failed" | "acked" | "started" | "replied" | "expired";
|
|
3
|
+
export interface TaskTraceEvent {
|
|
4
|
+
event: string;
|
|
5
|
+
from_alias: string;
|
|
6
|
+
to_alias: string;
|
|
7
|
+
task_id: string | null;
|
|
8
|
+
parent_task_id: string | null;
|
|
9
|
+
network_id: string | null;
|
|
10
|
+
transport: TaskTraceTransport;
|
|
11
|
+
status: TaskTraceStatus;
|
|
12
|
+
duration_ms: number;
|
|
13
|
+
lifecycle_tracking: "tracked" | "not_tracked";
|
|
14
|
+
error_code?: string;
|
|
15
|
+
error_message?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function safeTaskTraceError(value: unknown): string;
|
|
18
|
+
export declare function renderTaskTrace(event: TaskTraceEvent, json?: boolean): string;
|
|
19
|
+
export declare function taskTraceEvent(input: Omit<TaskTraceEvent, "event">): TaskTraceEvent;
|
|
20
|
+
export interface SendTaskTraceInput {
|
|
21
|
+
fromAlias: string;
|
|
22
|
+
toAlias: string;
|
|
23
|
+
parentTaskId: string | null;
|
|
24
|
+
networkId: string | null;
|
|
25
|
+
transport: TaskTraceTransport;
|
|
26
|
+
lifecycleTracking: "tracked" | "not_tracked";
|
|
27
|
+
}
|
|
28
|
+
export interface SendTaskTraceDependencies {
|
|
29
|
+
send: () => Promise<any>;
|
|
30
|
+
log: (line: string) => void;
|
|
31
|
+
now?: () => number;
|
|
32
|
+
}
|
|
33
|
+
export declare function sendTaskWithTrace(input: SendTaskTraceInput, dependencies: SendTaskTraceDependencies): Promise<any>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type TmuxSession = {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function parseTmuxSessions(output: string): TmuxSession[];
|
|
6
|
+
/** Resolve by exact decoded session name, then attach by tmux's opaque ID.
|
|
7
|
+
* This avoids tmux target prefix matching and works for Unicode names. */
|
|
8
|
+
export declare function findExactTmuxSession(output: string, expectedName: string): TmuxSession | null;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Lowest tmux version whose `new-session` understands `-e KEY=VALUE`. */
|
|
2
|
+
export declare const MIN_TMUX_MAJOR = 3;
|
|
3
|
+
export declare const MIN_TMUX_MINOR = 2;
|
|
4
|
+
export interface TmuxVersion {
|
|
5
|
+
major: number;
|
|
6
|
+
minor: number;
|
|
7
|
+
/** Trailing letter suffix, e.g. the "a" of "3.0a". Not used for ordering. */
|
|
8
|
+
suffix: string;
|
|
9
|
+
raw: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Parse the output of `tmux -V`, e.g.:
|
|
13
|
+
* "tmux 3.2a" → { major: 3, minor: 2, suffix: "a" }
|
|
14
|
+
* "tmux 3.0a" → { major: 3, minor: 0, suffix: "a" }
|
|
15
|
+
* "tmux 3.4" → { major: 3, minor: 4, suffix: "" }
|
|
16
|
+
* "tmux next-3.4" → { major: 3, minor: 4, suffix: "" }
|
|
17
|
+
* "tmux 2.9" → { major: 2, minor: 9, suffix: "" }
|
|
18
|
+
*
|
|
19
|
+
* Returns null when no version can be extracted (unknown build, empty
|
|
20
|
+
* output, `tmux master` with no numbers). Callers must treat null as
|
|
21
|
+
* "unknown" and NOT as "too old" — refusing to start on an unparseable
|
|
22
|
+
* version string would break hosts whose tmux is perfectly capable.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parseTmuxVersion(raw: string): TmuxVersion | null;
|
|
25
|
+
/**
|
|
26
|
+
* True when this version's `new-session` supports `-e KEY=VALUE` (>= 3.2).
|
|
27
|
+
* Note 3.0a / 3.1c sort BELOW 3.2 — the letter suffix is a patch marker,
|
|
28
|
+
* never a minor bump, so it must not participate in the comparison.
|
|
29
|
+
*/
|
|
30
|
+
export declare function tmuxSupportsSessionEnv(v: TmuxVersion): boolean;
|
|
31
|
+
export type TmuxCapabilityVerdict = {
|
|
32
|
+
kind: "ok";
|
|
33
|
+
version: TmuxVersion;
|
|
34
|
+
} | {
|
|
35
|
+
kind: "unknown";
|
|
36
|
+
detail: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: "too_old";
|
|
39
|
+
version: TmuxVersion;
|
|
40
|
+
detail: string;
|
|
41
|
+
remedy: string[];
|
|
42
|
+
} | {
|
|
43
|
+
kind: "missing";
|
|
44
|
+
detail: string;
|
|
45
|
+
remedy: string[];
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Pure decision function — `runVersionCmd` returns `tmux -V` output, or
|
|
49
|
+
* throws if tmux is absent/unrunnable. Split from the printing/exiting
|
|
50
|
+
* wrapper so tests drive every branch without a tmux binary.
|
|
51
|
+
*/
|
|
52
|
+
export declare function checkTmuxCapability(runVersionCmd: () => string): TmuxCapabilityVerdict;
|
|
53
|
+
/**
|
|
54
|
+
* cli.ts wrapper: run the check, print an actionable message, and exit
|
|
55
|
+
* non-zero when tmux cannot carry the marker. `unknown` is deliberately
|
|
56
|
+
* permissive — we log and continue.
|
|
57
|
+
*/
|
|
58
|
+
export declare function assertTmuxSupportsSessionEnv(runVersionCmd: () => string, log: (msg: string) => void, fail: (msg: string) => never): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact-match tmux target for a session name.
|
|
3
|
+
*
|
|
4
|
+
* tmux treats a leading `=` as "this exact name, no prefix matching". Names are
|
|
5
|
+
* passed to tmux as argv entries, never through a shell, so no quoting belongs
|
|
6
|
+
* here — callers that build a copy-pasteable command for a human should shell-
|
|
7
|
+
* quote the result themselves.
|
|
8
|
+
*/
|
|
9
|
+
export declare function exactSession(name: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* True when this target is already pinned to an exact session.
|
|
12
|
+
*
|
|
13
|
+
* Applying the prefix twice would look for a session literally named `=x`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isExactTarget(target: string): boolean;
|
|
16
|
+
/** Idempotent form, for call sites that may receive either shape. */
|
|
17
|
+
export declare function ensureExactSession(nameOrTarget: string): string;
|
|
18
|
+
/** One row of `tmux list-panes -a -F '#{session_name}\t#{window_index}.#{pane_index}'`. */
|
|
19
|
+
export interface PaneRow {
|
|
20
|
+
session: string;
|
|
21
|
+
/** `window.pane`, e.g. `0.0`. */
|
|
22
|
+
coord: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function parsePaneRows(listOutput: string): PaneRow[];
|
|
25
|
+
/**
|
|
26
|
+
* Pane target for a session, or null when that exact session has no pane.
|
|
27
|
+
*
|
|
28
|
+
* Matching is exact string equality on the session name — the whole point is to
|
|
29
|
+
* not hand tmux a name it might prefix-match, and to not hand it a `=` form it
|
|
30
|
+
* cannot resolve for non-ASCII names.
|
|
31
|
+
*/
|
|
32
|
+
export declare function paneTargetFor(listOutput: string, sessionName: string): string | null;
|
|
33
|
+
/** The format string the two functions above expect. */
|
|
34
|
+
export declare const PANE_LIST_FORMAT = "#{session_name}::ANET_PANE::#{window_index}.#{pane_index}";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** A prompt the watcher knows how to answer, or null. */
|
|
2
|
+
export type PanePrompt = "dev-channels" | "folder-trust";
|
|
3
|
+
/**
|
|
4
|
+
* Which known prompt (if any) the pane is currently blocking on.
|
|
5
|
+
*
|
|
6
|
+
* Dev-channels is checked FIRST, even though it appears second in time. The two
|
|
7
|
+
* prompts are sequential — trust, then channels — so a capture showing both
|
|
8
|
+
* means the trust prompt is already answered and only its text is still sitting
|
|
9
|
+
* in the pane. Classifying that as "folder-trust" would make a watcher that has
|
|
10
|
+
* already answered trust ignore the prompt it was waiting for, and the node
|
|
11
|
+
* would hang exactly as if the fix had never been made. Preferring the later
|
|
12
|
+
* prompt keeps a stale line of scrollback from outranking the live prompt.
|
|
13
|
+
*/
|
|
14
|
+
export declare function classifyPanePrompt(pane: string): PanePrompt | null;
|
|
15
|
+
/**
|
|
16
|
+
* Best-effort one-line explanation of why a detached start died, taken from the
|
|
17
|
+
* dead pane's own output.
|
|
18
|
+
*
|
|
19
|
+
* Returns null when the pane holds nothing that looks like a refusal — the
|
|
20
|
+
* caller must then fall back to a generic message rather than inventing one.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractStartFailureReason(pane: string): string | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TokenCreateNameResult = {
|
|
2
|
+
ok: true;
|
|
3
|
+
name: string;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
/** Parse only `anet token create` operands.
|
|
9
|
+
*
|
|
10
|
+
* The legacy positional form stays supported, while flag parsing is strict so
|
|
11
|
+
* a typo cannot become the name of a newly issued credential.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseTokenCreateName(argv: readonly string[]): TokenCreateNameResult;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare const CLAUDE_KNOWN_TOOLS: readonly string[];
|
|
2
|
+
type Runtime = string;
|
|
3
|
+
/** Parse the comma-joined --tools string, validate each token, return the
|
|
4
|
+
* trimmed list. Runtime-scoped:
|
|
5
|
+
*
|
|
6
|
+
* Claude-lineage → each token must be in CLAUDE_KNOWN_TOOLS OR match
|
|
7
|
+
* the MCP pattern (mcp__<server>__<tool>).
|
|
8
|
+
* Other runtimes → only the basic per-token format check runs, so grok /
|
|
9
|
+
* codex / opencode tools flow through unchanged and get
|
|
10
|
+
* validated by their own downstream layers.
|
|
11
|
+
*
|
|
12
|
+
* Throws on the first offense with a message naming the bad token and,
|
|
13
|
+
* for Claude-side violations, the expected set. Never returns a
|
|
14
|
+
* partially-cleaned list — a typo must surface, not silently reshape the
|
|
15
|
+
* persisted profile.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseAndValidateTools(raw: string, runtime: Runtime): string[];
|
|
18
|
+
/** Minimal --model validation: non-empty after trim, no whitespace inside.
|
|
19
|
+
*
|
|
20
|
+
* We do NOT enforce a known-model allowlist — models are vendor-defined,
|
|
21
|
+
* evolve independently, and a strict list would break the first time
|
|
22
|
+
* MiniMax/DeepSeek/GLM/etc. ships a new variant. This catches the obvious
|
|
23
|
+
* user-side typos (`--model " claude-3 " `, `--model ""`) without
|
|
24
|
+
* over-restricting legitimate values. Vendor-side model resolution
|
|
25
|
+
* (defaultCodexModelForRuntime etc.) already validates its own contract.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateModel(raw: string): string;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface PathModeFacts {
|
|
2
|
+
/** Owner uid of the path. */
|
|
3
|
+
uid: number;
|
|
4
|
+
/** Permission bits (st_mode & 0o777). */
|
|
5
|
+
mode: number;
|
|
6
|
+
/** uid of the process doing the check. */
|
|
7
|
+
processUid: number;
|
|
8
|
+
}
|
|
9
|
+
export type UnsafePathReason = "owner" | "group-writable" | "world-writable" | null;
|
|
10
|
+
/** Which condition makes this path unsafe to execute from, if any. */
|
|
11
|
+
export declare function classifyUnsafePath(facts: PathModeFacts): UnsafePathReason;
|
|
12
|
+
/**
|
|
13
|
+
* Operator-facing explanation. Names the path, the offending bits, and the
|
|
14
|
+
* command that fixes it — a message that says only "unsafe" leaves the reader
|
|
15
|
+
* guessing between four different conditions.
|
|
16
|
+
*/
|
|
17
|
+
export declare function describeUnsafePath(path: string, facts: PathModeFacts): string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ExecFileSyncOptions, type ExecFileSyncOptionsWithStringEncoding, type SpawnOptions } from "child_process";
|
|
2
|
+
/** Windows needs a command interpreter to run a .cmd; POSIX runs the file. */
|
|
3
|
+
export declare function launcherNeedsShell(platform?: NodeJS.Platform): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Quote one argument for `cmd.exe /c`.
|
|
6
|
+
*
|
|
7
|
+
* cmd's rules are not the shell's: a double quote is escaped by doubling it,
|
|
8
|
+
* and the metacharacters below must be quoted or cmd will act on them. Anything
|
|
9
|
+
* safe is left bare, so the common case stays readable in a process listing.
|
|
10
|
+
*/
|
|
11
|
+
export declare function quoteForCmd(arg: string): string;
|
|
12
|
+
/** The argv to hand to execFile/spawn so `cmd args…` runs on this platform. */
|
|
13
|
+
export declare function launcherArgv(cmd: string, args: readonly string[], platform?: NodeJS.Platform, comspec?: string | undefined): {
|
|
14
|
+
file: string;
|
|
15
|
+
argv: string[];
|
|
16
|
+
};
|
|
17
|
+
export declare function runLauncherSync(cmd: string, args: readonly string[], options: ExecFileSyncOptionsWithStringEncoding): string;
|
|
18
|
+
export declare function runLauncherSync(cmd: string, args: readonly string[], options?: ExecFileSyncOptions): Buffer;
|
|
19
|
+
/** spawn for a launcher, correct on Windows. */
|
|
20
|
+
export declare function spawnLauncher(cmd: string, args: readonly string[], options?: SpawnOptions): import("node:child_process").ChildProcess;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type WindowsCopresenceRole = "appsrv" | "bridge";
|
|
2
|
+
export interface WindowsManagedProcess {
|
|
3
|
+
role: WindowsCopresenceRole;
|
|
4
|
+
pid: number;
|
|
5
|
+
creationDate: string;
|
|
6
|
+
logPath: string;
|
|
7
|
+
}
|
|
8
|
+
export interface WindowsCopresenceRecord {
|
|
9
|
+
version: 1 | 2;
|
|
10
|
+
nodeId: string;
|
|
11
|
+
createdAt: string;
|
|
12
|
+
marker?: string;
|
|
13
|
+
processes: WindowsManagedProcess[];
|
|
14
|
+
}
|
|
15
|
+
export declare function windowsCopresenceRecordPath(nodesDir: string, nodeId: string): string;
|
|
16
|
+
export declare function windowsCopresenceLogPath(nodesDir: string, nodeId: string, role: WindowsCopresenceRole): string;
|
|
17
|
+
export declare function openPrivateAppendLog(path: string): number;
|
|
18
|
+
/** Protect credential-bearing state with native Windows ACLs. */
|
|
19
|
+
export declare function ensureWindowsPrivateDirectory(path: string): void;
|
|
20
|
+
export declare function closeLog(fd: number): void;
|
|
21
|
+
export type CreationDateProbe = (pid: number) => string | null;
|
|
22
|
+
/** Uses CIM instead of locale-dependent tasklist output. */
|
|
23
|
+
export declare function probeWindowsCreationDate(pid: number): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* Attribute an ESTABLISHED loopback connection to the launched TUI process
|
|
26
|
+
* tree. This is deliberately stronger than counting listeners/connections:
|
|
27
|
+
* an unrelated local client cannot satisfy it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function probeWindowsOwnedLoopbackConnection(rootPid: number, expectedCreationDate: string, port: number, runPowerShell?: (script: string) => string): boolean;
|
|
30
|
+
export declare function writeWindowsCopresenceRecord(nodesDir: string, nodeId: string, processes: WindowsManagedProcess[], marker?: string): void;
|
|
31
|
+
export declare function readWindowsCopresenceRecord(nodesDir: string, nodeId: string): WindowsCopresenceRecord | null;
|
|
32
|
+
export interface WindowsStopDecision {
|
|
33
|
+
safe: WindowsManagedProcess[];
|
|
34
|
+
refused: Array<{
|
|
35
|
+
process: WindowsManagedProcess;
|
|
36
|
+
reason: "missing" | "pid-reused";
|
|
37
|
+
}>;
|
|
38
|
+
}
|
|
39
|
+
/** PID alone is never authority: Windows reuses PIDs, so CreationDate must match. */
|
|
40
|
+
export declare function decideWindowsManagedStop(record: WindowsCopresenceRecord, probe: CreationDateProbe): WindowsStopDecision;
|
|
41
|
+
export declare function taskkillWindowsProcessTree(pid: number): void;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleep2agi/agent-network",
|
|
3
|
-
"version": "2.3.0-preview.
|
|
4
|
-
"description": "AI Agent Network CLI
|
|
3
|
+
"version": "2.3.0-preview.71",
|
|
4
|
+
"description": "AI Agent Network CLI — Local-first multi-agent orchestration across 6 runtimes (Claude Code CLI / Claude Agent SDK / Codex SDK / Codex app-server / Grok Build ACP / OpenCode CLI) and 8+ LLM providers. Apache 2.0.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/client.js",
|
|
7
7
|
"types": "dist/client.d.ts",
|
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"import": "./dist/src/client.js",
|
|
11
11
|
"types": "./dist/client.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./daemon-capability-display": {
|
|
14
|
+
"import": "./dist/src/daemon-capability-display.js",
|
|
15
|
+
"types": "./dist/src/daemon-capability-display.d.ts"
|
|
12
16
|
}
|
|
13
17
|
},
|
|
14
18
|
"bin": {
|
|
15
|
-
"anet": "dist/bin/
|
|
19
|
+
"anet": "dist/bin/anet.cjs"
|
|
16
20
|
},
|
|
17
21
|
"files": [
|
|
18
22
|
"dist"
|
|
@@ -20,7 +24,7 @@
|
|
|
20
24
|
"scripts": {
|
|
21
25
|
"typecheck": "tsc --noEmit",
|
|
22
26
|
"test:feishu-bridge": "bun tests/feishu-bridge-ackplaceholder.test.ts",
|
|
23
|
-
"build": "bun build src/client.ts --outdir dist/src --target node --minify && bun build bin/cli.ts --outdir dist/bin --target node --minify --external @sleep2agi/commhub-server --external bun:sqlite --external '../../server/*' && bun build src/node-server.ts --outdir dist/src --target node --minify
|
|
27
|
+
"build": "bun build src/client.ts --outdir dist/src --target node --minify && bun build src/daemon-capability-display.ts --outdir dist/src --target browser --minify && bun build bin/cli.ts --outdir dist/bin --target node --minify --external @sleep2agi/commhub-server --external bun:sqlite --external '../../server/*' && bun build src/node-server.ts --outdir dist/src --target node --minify && bun build src/im/feishu/worker.ts --outdir dist/src/im/feishu --target node --minify --external @larksuiteoapi/node-sdk && tsc --emitDeclarationOnly --declaration --outDir dist && npx javascript-obfuscator dist/bin/cli.js --output dist/bin/cli.js --compact true --string-array true --string-array-encoding base64 && npx javascript-obfuscator dist/src/client.js --output dist/src/client.js --compact true --string-array true && npx javascript-obfuscator dist/src/node-server.js --output dist/src/node-server.js --compact true --string-array true && cp bin/anet.cjs dist/bin/anet.cjs",
|
|
24
28
|
"prepublishOnly": "npm run build"
|
|
25
29
|
},
|
|
26
30
|
"keywords": [
|
|
@@ -54,7 +58,8 @@
|
|
|
54
58
|
"directory": "agent-network"
|
|
55
59
|
},
|
|
56
60
|
"publishConfig": {
|
|
57
|
-
"access": "public"
|
|
61
|
+
"access": "public",
|
|
62
|
+
"tag": "preview"
|
|
58
63
|
},
|
|
59
64
|
"bugs": {
|
|
60
65
|
"url": "https://github.com/sleep2agi/agent-network/issues"
|
|
@@ -65,10 +70,13 @@
|
|
|
65
70
|
},
|
|
66
71
|
"dependencies": {
|
|
67
72
|
"@inquirer/prompts": "^8.4.3",
|
|
68
|
-
"@larksuiteoapi/node-sdk": "^1.42.0"
|
|
73
|
+
"@larksuiteoapi/node-sdk": "^1.42.0",
|
|
74
|
+
"markdown-it": "^14.1.0",
|
|
75
|
+
"puppeteer-core": "^24.10.2"
|
|
69
76
|
},
|
|
70
77
|
"devDependencies": {
|
|
71
78
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
79
|
+
"@types/markdown-it": "^14.1.2",
|
|
72
80
|
"@types/node": "^25.0.0",
|
|
73
81
|
"javascript-obfuscator": "^5.4.1",
|
|
74
82
|
"node-pty": "^1.1.0",
|