@syrkos/filaxis 0.1.0-alpha.10

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 (85) hide show
  1. package/AGENTS.md +46 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +10 -0
  4. package/README.md +61 -0
  5. package/bin/filaxis.ts +112 -0
  6. package/dist/agent-toolkit.d.ts +99 -0
  7. package/dist/dialect.d.ts +31 -0
  8. package/dist/driver.d.ts +130 -0
  9. package/dist/events.d.ts +26 -0
  10. package/dist/factory.d.ts +16 -0
  11. package/dist/file-edit.d.ts +43 -0
  12. package/dist/file-transfer.d.ts +44 -0
  13. package/dist/index.d.ts +38 -0
  14. package/dist/index.js +4200 -0
  15. package/dist/layer-discovery.d.ts +30 -0
  16. package/dist/layer-env.d.ts +95 -0
  17. package/dist/local-driver.d.ts +47 -0
  18. package/dist/local-session-manager.d.ts +98 -0
  19. package/dist/logger.d.ts +12 -0
  20. package/dist/remote-session-manager.d.ts +64 -0
  21. package/dist/runtime-stack.d.ts +52 -0
  22. package/dist/session-buffer.d.ts +73 -0
  23. package/dist/session-types.d.ts +74 -0
  24. package/dist/shell-discovery.d.ts +4 -0
  25. package/dist/ssh-helpers.d.ts +88 -0
  26. package/dist/ssh-pty-driver.d.ts +74 -0
  27. package/dist/stream-session-manager.d.ts +83 -0
  28. package/dist/stream-window.d.ts +124 -0
  29. package/dist/terminal/command-executer.d.ts +73 -0
  30. package/dist/terminal/output-buffer.d.ts +49 -0
  31. package/dist/terminal/session-launcher.d.ts +28 -0
  32. package/dist/terminal/session-registry.d.ts +29 -0
  33. package/dist/terminal/tmux-invoker.d.ts +8 -0
  34. package/dist/terminal/types.d.ts +56 -0
  35. package/dist/terminal-manager.d.ts +30 -0
  36. package/dist/tmux-driver.d.ts +49 -0
  37. package/dist/vt100-screen.d.ts +46 -0
  38. package/docs/DEVELOPMENT.md +38 -0
  39. package/docs/KNOWN-ISSUES.md +35 -0
  40. package/docs/implementation-notes.md +57 -0
  41. package/docs/skills/cross-host-diagnosis.md +21 -0
  42. package/docs/skills/file-sync.md +22 -0
  43. package/docs/skills/longrun-observe.md +20 -0
  44. package/docs/skills/stream-window.md +28 -0
  45. package/docs//345/256/214/346/225/264/345/267/241/346/243/200/346/212/245/345/221/212.md +141 -0
  46. package/docs//346/265/213/350/257/2252.md +112 -0
  47. package/docs//346/265/213/350/257/2253.md +73 -0
  48. package/docs//346/265/213/350/257/2254.md +138 -0
  49. package/docs//346/265/213/350/257/2255.md +124 -0
  50. package/docs//347/254/254/344/272/214/344/273/275/345/267/241/346/243/200/346/212/245/345/221/212.md +103 -0
  51. package/examples/agent-tools.ts +74 -0
  52. package/examples/cross-host-diagnosis.ts +49 -0
  53. package/examples/longrun-observe.ts +46 -0
  54. package/package.json +47 -0
  55. package/src/agent-toolkit.ts +247 -0
  56. package/src/dialect.ts +100 -0
  57. package/src/driver.ts +142 -0
  58. package/src/events.ts +96 -0
  59. package/src/factory.ts +51 -0
  60. package/src/file-edit.ts +195 -0
  61. package/src/file-transfer.ts +196 -0
  62. package/src/index.ts +38 -0
  63. package/src/layer-discovery.ts +79 -0
  64. package/src/layer-env.ts +331 -0
  65. package/src/local-driver.ts +325 -0
  66. package/src/local-session-manager.ts +397 -0
  67. package/src/logger.ts +19 -0
  68. package/src/remote-session-manager.ts +286 -0
  69. package/src/runtime-stack.ts +128 -0
  70. package/src/session-buffer.ts +183 -0
  71. package/src/session-types.ts +78 -0
  72. package/src/shell-discovery.ts +52 -0
  73. package/src/ssh-helpers.ts +225 -0
  74. package/src/ssh-pty-driver.ts +655 -0
  75. package/src/stream-session-manager.ts +296 -0
  76. package/src/stream-window.ts +309 -0
  77. package/src/terminal/command-executer.ts +374 -0
  78. package/src/terminal/output-buffer.ts +126 -0
  79. package/src/terminal/session-launcher.ts +146 -0
  80. package/src/terminal/session-registry.ts +98 -0
  81. package/src/terminal/tmux-invoker.ts +65 -0
  82. package/src/terminal/types.ts +85 -0
  83. package/src/terminal-manager.ts +83 -0
  84. package/src/tmux-driver.ts +167 -0
  85. package/src/vt100-screen.ts +166 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * driver.ts — RuntimeDriver 统一契约(多 Transport 执行内核)
3
+ *
4
+ * 净室平移自 Aethelum-Nexus `src/core/tools/runtime/driver.ts`
5
+ * (源锚点:Aethelum-Nexus dev @ 8977ff3),按 REQ-0001 OSS 化改造:
6
+ * - ExecResult 新增 stderr(FEAT-03:exec 通道 stdout/stderr 物理分离;源版无此字段)
7
+ * - ExecOptions 新增 channel(FEAT-03:通道显式化 "exec" | "pty",缺省 exec)
8
+ * - 剔除 interactionManager/sessionId(凭据交互策略属 FEAT-12,M1 后续批次设计后进契约)
9
+ * - capabilities 保留为纯数据标签(语义解释权归消费方;源注释中的策略引擎字样改为通用表述)
10
+ *
11
+ * 已知 driver 快捷方式(可自动生成 launchCmd):
12
+ * "local" — 进程内原生执行,唯一特殊值
13
+ * "ssh" — ssh [-options] <target>
14
+ * "docker" — <runtime> exec -i <target> <shell> -i (runtime 默认 docker,可换 podman/nerdctl 等)
15
+ * "k8s" — <runtime> exec -i [-n ns] <target> -- <shell> -i (runtime 默认 kubectl,可换 oc/k3s 等)
16
+ * "teleport" — tsh ssh [--cluster=c] [login@]<target>
17
+ *
18
+ * 任意字符串也合法(e.g. "nix-shell", "conda", "distrobox"),
19
+ * 但必须在 config.launchCmd 中提供完整的启动命令。
20
+ */
21
+ export type RuntimeDriverType = "local" | "browser" | "ssh" | "docker" | "k8s" | (string & {});
22
+ export interface RuntimeDescriptor {
23
+ driver: RuntimeDriverType;
24
+ /** 连接目标(ssh: user@host;container: 容器名/ID;自定义: 任意标签) */
25
+ target?: string;
26
+ /** 驱动配置:sshOptions / shell / runtime / namespace / launchCmd 等 */
27
+ config?: Record<string, unknown>;
28
+ /** 持久会话 ID(tmux 后端管理的长连接标识,跨重启恢复用) */
29
+ terminalId?: string;
30
+ /**
31
+ * 持久化的工作目录。调用方执行 cd 后异步更新,跨重启恢复时用于重建上下文。
32
+ */
33
+ cwd?: string;
34
+ /**
35
+ * 该运行时环境的能力标签列表(纯数据——消费方可据此做环境感知策略,
36
+ * 内核不解释)。内置约定示例:
37
+ * "read-only" — 禁止写操作
38
+ * "production" — 生产环境,高危操作从严
39
+ * "sandbox" — 沙箱环境,可放宽检查
40
+ */
41
+ capabilities?: string[];
42
+ }
43
+ /**
44
+ * 执行通道(FEAT-03):
45
+ * - "exec"(缺省)——非 PTY 通道:stdout/stderr 物理分离;层上下文经
46
+ * cwd/env/enterSteps 管线重放拼装(独立 channel 复现层进入路径)
47
+ * - "pty"——层内 PTY marker 协议:天然继承层内交互状态(su 身份/cd/export),
48
+ * stderr 混流为终端语义(不承诺分离)
49
+ */
50
+ export type ExecChannel = "exec" | "pty";
51
+ export interface ExecOptions {
52
+ timeoutMs?: number;
53
+ env?: Record<string, string>;
54
+ /** 临时覆盖命令执行路径 */
55
+ cwd?: string;
56
+ /** 执行通道(缺省 "exec") */
57
+ channel?: ExecChannel;
58
+ /** AbortSignal 硬中断子进程:abort 时子进程立即 SIGTERM,Promise 以 AbortError reject */
59
+ signal?: AbortSignal;
60
+ }
61
+ export interface ExecResult {
62
+ stdout: string;
63
+ /** exec 通道物理分离的 stderr;pty 通道下并入 stdout(终端语义) */
64
+ stderr: string;
65
+ exitCode: number;
66
+ /** 执行完成时该通道命令上下文的有效用户(marker 尾缀 id -un 实测——层内 su/sudo 变更可追踪) */
67
+ effectiveUser?: string;
68
+ }
69
+ export interface FileEntry {
70
+ name: string;
71
+ isDirectory: boolean;
72
+ size?: number;
73
+ mtime?: number;
74
+ }
75
+ export interface FileStat {
76
+ mtimeMs: number;
77
+ size: number;
78
+ }
79
+ export interface FileSystemDriver {
80
+ readFile(path: string): Promise<string>;
81
+ writeFile(path: string, content: string): Promise<void>;
82
+ exists(path: string): Promise<boolean>;
83
+ readdir(path: string): Promise<FileEntry[]>;
84
+ rm(path: string, options?: {
85
+ recursive?: boolean;
86
+ force?: boolean;
87
+ }): Promise<void>;
88
+ mkdir(path: string, options?: {
89
+ recursive?: boolean;
90
+ }): Promise<void>;
91
+ /** 可选 stat(mtimeMs/size)——先读后写闸的数据依赖 */
92
+ stat?(path: string): Promise<FileStat | null>;
93
+ /**
94
+ * 可选 readBase64——二进制安全读取。readFile 返回 UTF-8 字符串会破坏
95
+ * 二进制字节;本方法返回裸 base64。local 层实现;远端层无此方法时
96
+ * 调用方应显式处理「该层不支持二进制读取」。
97
+ */
98
+ readBase64?(path: string): Promise<string>;
99
+ }
100
+ import type { SessionStartOptions, SessionHandleInfo, WatchOptions, ReadLogOptions } from "./session-types.js";
101
+ export interface RuntimeDriver {
102
+ descriptor: RuntimeDescriptor;
103
+ exec(command: string, options?: ExecOptions): Promise<ExecResult>;
104
+ /** 启动长跑会话(立即返回) */
105
+ execSession(command: string, opts?: SessionStartOptions): Promise<SessionHandleInfo>;
106
+ /** 热窗口快照:最近 n 行 */
107
+ tailSession(sessionId: string, lines?: number): Promise<string[]>;
108
+ /** 读会话日志文件(全量/大范围) */
109
+ readSessionLog(sessionId: string, opts?: ReadLogOptions): Promise<string>;
110
+ /** 注册 watcher:命中 → 会话事件(内核事件接口,见 FEAT-09) */
111
+ watchSession(sessionId: string, opts: WatchOptions): {
112
+ cancel(): void;
113
+ };
114
+ /** 停止会话(SIGTERM→SIGKILL 升级;发出后核实终态) */
115
+ stopSession(sessionId: string): Promise<{
116
+ exitCode?: number | null;
117
+ }>;
118
+ /** 会话列表 */
119
+ listSessions(): Array<{
120
+ sessionId: string;
121
+ command: string;
122
+ running: boolean;
123
+ startedAt: number;
124
+ }>;
125
+ getCwd(): Promise<string>;
126
+ getEnv(key: string): Promise<string | undefined>;
127
+ fs: FileSystemDriver;
128
+ init(): Promise<void>;
129
+ destroy(): Promise<void>;
130
+ }
@@ -0,0 +1,26 @@
1
+ export interface EventBusOptions {
2
+ /** iterable 形态的每订阅队列上限(满丢最旧并计数) */
3
+ queueMax?: number;
4
+ }
5
+ type Handler<E> = (ev: E) => void;
6
+ export declare class EventBus<E extends {
7
+ type: string;
8
+ }> {
9
+ private emitter;
10
+ private readonly queueMax;
11
+ /** 每个迭代订阅一份独立队列:{queue, dropped, active} */
12
+ private iterables;
13
+ constructor(opts?: EventBusOptions);
14
+ /** 订阅(可按 type 过滤);返回退订函数 */
15
+ on(type: E["type"] | "*", handler: Handler<E>): () => void;
16
+ once(type: E["type"], handler: Handler<E>): void;
17
+ off(type: E["type"] | "*", handler: Handler<E>): void;
18
+ /** 发布:同步分发到订阅者与迭代队列 */
19
+ emit(ev: E): void;
20
+ /** AsyncIterable 形态句柄:可 for-await 消费(可按 type 过滤),dropped() 查溢出丢弃数 */
21
+ iterable(type?: E["type"]): AsyncIterable<E> & {
22
+ dropped(): number;
23
+ };
24
+ listenerCount(type?: E["type"]): number;
25
+ }
26
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * factory.ts — Transport 工厂与开放注册表(FEAT-01/FEAT-09:AC-09 第三方 driver 同权接入)
3
+ *
4
+ * 净室平移自 Aethelum-Nexus `src/core/tools/runtime/factory.ts`(源锚 8977ff3),
5
+ * OSS 化:注册表对外开放(registerDriver);内置 local,其余 Transport 分批落位。
6
+ */
7
+ import type { RuntimeDriver, RuntimeDescriptor } from "./driver.js";
8
+ export type DriverFactory = (descriptor: RuntimeDescriptor) => RuntimeDriver;
9
+ export declare class RuntimeFactory {
10
+ private custom;
11
+ /** 开放注册:第三方 Transport 与内置同权;重复注册拒绝(FEAT-01 异常策略) */
12
+ registerDriver(type: string, factory: DriverFactory): void;
13
+ unregisterDriver(type: string): boolean;
14
+ registeredTypes(): string[];
15
+ create(descriptor: RuntimeDescriptor, fallbackCwd?: string): RuntimeDriver;
16
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * file-edit.ts — 受控文件编辑(远端 CAS 原子写回 + 合成 SSH 往返)
3
+ *
4
+ * 第六季盲测实锤:SKILL 教了受控编辑但 SDK 无一级导出——Agent 读 7 轮源码自研
5
+ * 20 行样板(50 万 cache tokens);裸 SSH 组则 sed -i 两翻车并写坏远端配置。
6
+ *
7
+ * 第七季盲测反馈(B2 逐秒拆解):旧实现一次 editFile = 5 次串行 SSH 往返
8
+ * (stat/read/stat/write/stat),Windows 无 ControlMaster 下放大到 15s+。
9
+ * 本版:合成 **2 次往返**(读+戳 1 次;**远端 CAS 原子写回** 1 次——GPT 并发
10
+ * 安全意见采纳:「最后一次校验与写入放进同一个远端受控操作」——戳比对与写回
11
+ * 在远端一条命令内原子完成,杜绝 A/B 丢失更新)+ 方言适配(stat/base64 三族,
12
+ * 每 driver 缓存一次探测)。大文件(base64>30KB)自动回落旧 5 次路径(fs 层)。
13
+ *
14
+ * **仅适用 UTF-8 文本**(readFile 返回 UTF-8 字符串;二进制文件的编辑走
15
+ * readBase64 + 消费方自行改写 + writeFile)。
16
+ */
17
+ import type { RuntimeDriver } from "./driver.js";
18
+ export interface EditFileOptions {
19
+ /** 多处命中时全替换(缺省 false——多处命中报错,精确替换语义) */
20
+ all?: boolean;
21
+ }
22
+ export interface EditFileResult {
23
+ path: string;
24
+ occurrences: number;
25
+ bytesBefore: number;
26
+ bytesAfter: number;
27
+ /** 写前锁核验的 mtimeMs(CAS 远端原子比对用) */
28
+ lockedAtMtimeMs: number;
29
+ }
30
+ export declare class EditConflictError extends Error {
31
+ constructor(message: string);
32
+ }
33
+ /**
34
+ * 受控编辑(合成 2 次往返 + 远端 CAS 原子写回):
35
+ * ① 读+戳(1 次往返):`stat 戳; __FXS__; base64 读` —— 拿 (mtime,size)+全文
36
+ * ② 精确替换(本地):0 命中/多处命中(未开 all)拒绝
37
+ * ③ CAS 原子写回(1 次往返):远端一条命令内完成「戳比对 + tmp 写 + mv 原子替换 + 新戳回执」
38
+ * —— 戳不符(他人先写)→ EditConflictError;写后回执新戳
39
+ *
40
+ * @throws EditConflictError TOCTOU 冲突(CAS 戳不符)
41
+ * @throws Error 未命中 / 多处命中(未开 all)/ 远端层无 stat 能力
42
+ */
43
+ export declare function editFile(drv: RuntimeDriver, path: string, oldStr: string, newStr: string, opts?: EditFileOptions): Promise<EditFileResult>;
@@ -0,0 +1,44 @@
1
+ import type { RemoteDialect } from "./dialect.js";
2
+ /** 远端执行回调(通常是 driver 的 exec 通道) */
3
+ export type TransferExec = (command: string) => Promise<{
4
+ stdout: string;
5
+ exitCode: number;
6
+ }>;
7
+ export interface TransferResult {
8
+ bytes: number;
9
+ /** 远端回读核实的 sha256(与本地一致才返回成功) */
10
+ sha256: string;
11
+ /** 校验是否通过 */
12
+ verified: boolean;
13
+ }
14
+ export declare class TransferVerificationError extends Error {
15
+ constructor(op: "put" | "get", detail: string);
16
+ }
17
+ /**
18
+ * 上行 put:本地 → 远端。分块 base64 append 到远端临时文件 → 方言 decode 落位
19
+ * → size + sha256 回读双校验。任何一步退出码非零 → 抛错(落位原子性:先临时
20
+ * 文件后 mv 语义——失败不污染目标)。
21
+ */
22
+ export declare function putFile(exec: TransferExec, dialect: RemoteDialect, localPath: string, remotePath: string): Promise<TransferResult>;
23
+ /**
24
+ * 下行 get:远端 → 本地。方言 base64 编码回传 → 本地落盘 → sha256 对核。
25
+ */
26
+ export declare function getFile(exec: TransferExec, dialect: RemoteDialect, remotePath: string, localPath: string): Promise<TransferResult>;
27
+ export type SftpSpawnImpl = (argv: string[], batch: string) => Promise<{
28
+ exitCode: number | null;
29
+ stderr: string;
30
+ }>;
31
+ export interface SftpOptions {
32
+ /** 连接参数(host key 策略/端口/密钥——与 ssh 通道同源) */
33
+ connArgs: string[];
34
+ /** spawn 注入(缺省真实 sftp 子进程 + `-b -` batch 模式)——mock 全测关键 */
35
+ spawnImpl?: SftpSpawnImpl;
36
+ }
37
+ /**
38
+ * sftp 快路径 put:`sftp -b -` batch 模式(stdin 喂 `put` 命令)。
39
+ * 成功后仍走 size/sha256 双校验(与 base64 路径同一信任标准——快路径不豁免校验)。
40
+ * 缺席/失败由调用方捕获后降级 base64 管道(PRD FEAT-14 降级链)。
41
+ */
42
+ export declare function sftpPutFile(exec: TransferExec, dialect: RemoteDialect, localPath: string, remotePath: string, opts: SftpOptions): Promise<TransferResult>;
43
+ /** sftp 快路径 get(batch `get`;校验同 put) */
44
+ export declare function sftpGetFile(exec: TransferExec, dialect: RemoteDialect, remotePath: string, localPath: string, opts: SftpOptions): Promise<TransferResult>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 牵丝 Filaxis — 面向自动化与 Agent 的远程执行运行时 SDK
3
+ * 千里一线,执行有迹。—— Connect · Execute · Observe · Reattach
4
+ *
5
+ * M1 第一批出口:契约与纯逻辑件。驱动实现(ssh/local/tmux)、会话管理器、
6
+ * 事件总线按里程碑分批落位(REQ-0001 M1-M4)。
7
+ */
8
+ export * from "./driver.js";
9
+ export * from "./session-types.js";
10
+ export * from "./session-buffer.js";
11
+ export * from "./logger.js";
12
+ export * from "./local-session-manager.js";
13
+ export * from "./local-driver.js";
14
+ export * from "./events.js";
15
+ export * from "./factory.js";
16
+ export * from "./runtime-stack.js";
17
+ export * from "./dialect.js";
18
+ export * from "./ssh-helpers.js";
19
+ export * from "./remote-session-manager.js";
20
+ export * from "./ssh-pty-driver.js";
21
+ export * from "./tmux-driver.js";
22
+ export * from "./terminal-manager.js";
23
+ export { DEFAULT_TERMINAL_CONFIG, compilePromptPatterns, TmuxError } from "./terminal/types.js";
24
+ export type { TerminalConfig, PromptPayload, PromptResponder, TmuxResult } from "./terminal/types.js";
25
+ export * from "./terminal/output-buffer.js";
26
+ export * from "./stream-session-manager.js";
27
+ export * from "./file-transfer.js";
28
+ export * from "./layer-env.js";
29
+ export { resolveLocalShell } from "./shell-discovery.js";
30
+ export { createAgentToolkit } from "./agent-toolkit.js";
31
+ export type { AgentToolkit, AgentToolDef, AgentToolHandlers, AgentToolkitOptions } from "./agent-toolkit.js";
32
+ export { discoverLayer } from "./layer-discovery.js";
33
+ export type { DiscoverLayerOptions, DiscoverLayerResult } from "./layer-discovery.js";
34
+ export * from "./stream-window.js";
35
+ export { Vt100Screen } from "./vt100-screen.js";
36
+ export type { Vt100ScreenOptions } from "./vt100-screen.js";
37
+ export { editFile, EditConflictError } from "./file-edit.js";
38
+ export type { EditFileOptions, EditFileResult } from "./file-edit.js";