ai-fly 0.3.2 → 0.4.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.
- package/dist/ai-fly.js +23 -6
- package/dist/app/main.js +9047 -0
- package/dist/{common-CqxqIg6D.mjs → common-C51SAE5f.mjs} +17 -6
- package/dist/{common-CgxCXeTt.mjs → common-CanLn0Qt.mjs} +1 -1
- package/dist/{daemon-ZWUSWAgM.mjs → daemon-BWgyJMyB.mjs} +3 -3
- package/dist/{forget-BXL2x4Wv.mjs → forget-B3KRkHho.mjs} +2 -2
- package/dist/{frames-BDqvhB2Y.mjs → frames-BDz8buix.mjs} +1 -0
- package/dist/{group-B96IKEDF.mjs → group-BdnvRD2t.mjs} +1 -1
- package/dist/hook-CvAMGts4.mjs +228 -0
- package/dist/hooks-DUrXA7PL.mjs +142 -0
- package/dist/{import-rpBFh_pa.mjs → import-CTkKGPsa.mjs} +4 -4
- package/dist/{join-u1DqTU3U.mjs → join-BRow9_3-.mjs} +3 -3
- package/dist/{join-CaFx5yoF.mjs → join-d-pqyf8e.mjs} +3 -3
- package/dist/{key-BiEp995L.mjs → key-CTL_AXOh.mjs} +24 -8
- package/dist/{key-KcUU3yhJ.mjs → key-D_66hrWW.mjs} +3 -3
- package/dist/{local-test-C3HGjGY3.mjs → local-test-BZHGo22F.mjs} +1 -1
- package/dist/{models-dev-2UfQoIpQ.mjs → models-dev-CDEyd2k3.mjs} +21 -1
- package/dist/{mux-CS1zhF4W.mjs → mux-BaIDugDq.mjs} +2 -2
- package/dist/{ports-BRXd5UXh.mjs → ports-TQ4tWmiJ.mjs} +2 -2
- package/dist/{presets-C73CAMZ6.mjs → presets-DleOUQiT.mjs} +2 -2
- package/dist/{revoke-CkpvK33Q.mjs → revoke-DTFW_EF1.mjs} +2 -2
- package/dist/{rewrite-xZHWnyJk.mjs → rewrite-CEzfYH9n.mjs} +45 -26
- package/dist/{route-test-Oew0CO1U.mjs → route-test-D2LQyX7c.mjs} +4 -4
- package/dist/{rpc-contract-5qyWzT5t.mjs → rpc-contract-cB5SuyQ_.mjs} +64 -9
- package/dist/{run-3pdPsD8e.mjs → run-D8kgXdId.mjs} +3 -3
- package/dist/{runtime-DNs9GtGp.mjs → runtime-C_pLA5F0.mjs} +3 -3
- package/dist/{secret-COdVHzjH.mjs → secret-P2RgHy2h.mjs} +2 -2
- package/dist/{secrets-BYI6ooTJ.mjs → secrets-1Hmddmwy.mjs} +2 -2
- package/dist/secrets-C9IYp93v.mjs +2 -0
- package/dist/{serve-DSBlodTF.mjs → serve-B51lmr9M.mjs} +2 -2
- package/dist/{serve-Be4zdKVj.mjs → serve-CY7ZFOFM.mjs} +6 -6
- package/dist/{service-B5uORhl3.mjs → service-D6TNolyh.mjs} +36 -9
- package/dist/{settings-DU0YqNDt.mjs → settings-Rq1zLoxY.mjs} +1 -1
- package/dist/{settings-C1Hb4zwd.mjs → settings-XCvAzDK8.mjs} +2 -2
- package/dist/{share-Cug0944N.mjs → share-DdtbAylA.mjs} +28 -13
- package/dist/{status-SkNsxGnk.mjs → status-DSVQ3YHm.mjs} +3 -3
- package/dist/{status-Bttb9aPj.mjs → status-uE2-kOyK.mjs} +3 -3
- package/dist/{store-CQShpYar.mjs → store-DOFDy1rY.mjs} +2 -2
- package/dist/{store-CrTUwskE.mjs → store-EGzVd-dn.mjs} +29 -4
- package/dist/{test-mlaZC1y5.mjs → test-DW4BF7xJ.mjs} +2 -2
- package/hooks/codex.cjs +12 -0
- package/hooks/env.cjs +10 -0
- package/hooks/file.cjs +27 -0
- package/hooks/secret.cjs +11 -0
- package/package.json +6 -2
- package/resources/app-icons/app-icon.icns +0 -0
- package/resources/app-icons/app-icon.ico +0 -0
- package/resources/app-icons/app-icon.json +84 -0
- package/resources/app-icons/app-icon.png +0 -0
- package/resources/app-icons/linux/128x128/app-icon.png +0 -0
- package/resources/app-icons/linux/16x16/app-icon.png +0 -0
- package/resources/app-icons/linux/256x256/app-icon.png +0 -0
- package/resources/app-icons/linux/32x32/app-icon.png +0 -0
- package/resources/app-icons/linux/48x48/app-icon.png +0 -0
- package/resources/app-icons/linux/512x512/app-icon.png +0 -0
- package/resources/app-icons/linux/64x64/app-icon.png +0 -0
- package/resources/app-icons/tray-icon.png +0 -0
- package/webui/dist/assets/index-8MLhHHM0.js +74 -0
- package/webui/dist/assets/index-ihWSPzNq.css +2 -0
- package/webui/dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/webui/dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/webui/dist/assets/share-tech-mono-latin-400-normal-15MgdvEM.woff +0 -0
- package/webui/dist/assets/share-tech-mono-latin-400-normal-CCqdbj5z.woff2 +0 -0
- package/webui/dist/icons/presets/anthropic.svg +5 -0
- package/webui/dist/icons/presets/codex.svg +5 -0
- package/webui/dist/icons/presets/deepseek.svg +5 -0
- package/webui/dist/icons/presets/openai.svg +5 -0
- package/webui/dist/index.html +13 -0
- package/dist/secrets-u19-8EyW.mjs +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ROUTE_LOCAL_PREFIX, s as randomZ32 } from "./rpc-contract-
|
|
1
|
+
import { n as ROUTE_LOCAL_PREFIX, s as randomZ32 } from "./rpc-contract-cB5SuyQ_.mjs";
|
|
2
2
|
import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -189,7 +189,11 @@ const SERVICE_REWRITE_STORE_SCHEMA = z.strictObject({
|
|
|
189
189
|
hostHeader: z.string().min(1).max(2048).optional(),
|
|
190
190
|
pathPrefixStrip: z.string().min(1).max(2048).optional(),
|
|
191
191
|
pathPrefixAppend: z.string().min(1).max(2048).optional(),
|
|
192
|
-
headerSet: z.record(z.string().min(1).max(1024), z.string().max(8192)
|
|
192
|
+
headerSet: z.record(z.string().min(1).max(1024), z.union([z.string().max(8192), z.strictObject({
|
|
193
|
+
hook: z.string().min(1).max(128),
|
|
194
|
+
args: z.record(z.string().min(1).max(128), z.string().max(2048)).optional(),
|
|
195
|
+
bearer: z.boolean().optional()
|
|
196
|
+
})])).optional(),
|
|
193
197
|
headerRemove: z.array(z.string().min(1).max(1024)).max(32).optional()
|
|
194
198
|
});
|
|
195
199
|
/** 路径路由(M3-r7):按声明顺序命中的转发规则——prefix 模式(默认,
|
|
@@ -213,6 +217,8 @@ const SERVICE_STORE_SCHEMA = z.strictObject({
|
|
|
213
217
|
match: z.array(SERVICE_MATCH_STORE_SCHEMA).max(64),
|
|
214
218
|
upstream: z.string().min(1).max(2048),
|
|
215
219
|
rewrite: SERVICE_REWRITE_STORE_SCHEMA.optional(),
|
|
220
|
+
/** 选中的 hooks 脚本名(内建库或 ~/.aifly/hooks/<name>.cjs)。 */
|
|
221
|
+
hooks: z.string().regex(/^[a-z][a-z0-9_-]{0,63}$/).optional(),
|
|
216
222
|
routes: z.array(SERVICE_ROUTE_STORE_SCHEMA).max(3).optional(),
|
|
217
223
|
defaultPort: z.number().int().min(1).max(65535)
|
|
218
224
|
});
|
|
@@ -229,9 +235,17 @@ const KEY_STORE_SCHEMA = z.strictObject({
|
|
|
229
235
|
keyId: z.string().min(1).max(128),
|
|
230
236
|
group: z.string().min(1).max(256),
|
|
231
237
|
hash: z.string().regex(/^[0-9a-f]{64}$/, "key hash must be 64 hex chars"),
|
|
238
|
+
/** key 名(Owner 裁决 2026-09-13:签发时必填,GUI 分组视图按名展示;
|
|
239
|
+
* 旧记录无此字段——迁移容忍,GUI 显示为未命名)。 */
|
|
240
|
+
name: z.string().min(1).max(128).optional(),
|
|
241
|
+
/** key 原文(Owner 裁决 2026-09-13:可随时复制取代仅签发时可见——本机
|
|
242
|
+
* 个人工具与密钥库明文同一威胁模型;旧记录只存哈希,无法补录)。 */
|
|
243
|
+
key: z.string().min(8).max(256).optional(),
|
|
232
244
|
createdAt: z.number().int().min(0),
|
|
233
245
|
revokedAt: z.number().int().min(0).optional()
|
|
234
246
|
});
|
|
247
|
+
/** key 名规则(同 SECRET_NAME_SCHEMA 词汇:小写开头,点横杠下划线)。 */
|
|
248
|
+
const KEY_NAME_SCHEMA = /^[a-z0-9][a-z0-9._-]*$/;
|
|
235
249
|
const STORE_FILE_SCHEMA = z.strictObject({
|
|
236
250
|
revision: z.number().int().min(0),
|
|
237
251
|
meta: z.strictObject({ alias: z.string().min(1).max(256).optional() }).optional(),
|
|
@@ -364,6 +378,7 @@ var ProviderStore = class ProviderStore {
|
|
|
364
378
|
match: input.match.map((m) => ({ ...m })),
|
|
365
379
|
upstream: upstreamUrl.href,
|
|
366
380
|
rewrite,
|
|
381
|
+
...input.hooks !== void 0 ? { hooks: input.hooks } : {},
|
|
367
382
|
...routes !== void 0 ? { routes } : {},
|
|
368
383
|
defaultPort
|
|
369
384
|
};
|
|
@@ -466,9 +481,11 @@ var ProviderStore = class ProviderStore {
|
|
|
466
481
|
listKeys() {
|
|
467
482
|
return this.data.keys.map((k) => ({ ...k }));
|
|
468
483
|
}
|
|
469
|
-
/**
|
|
470
|
-
|
|
484
|
+
/** 签发:name 缺省 "default";原文随记录落库(Owner 2026-09-13:随时
|
|
485
|
+
* 可复制)。name 是展示标签非身份(keyId 唯一),同组可重名。 */
|
|
486
|
+
issueKey(groupName, name = "default") {
|
|
471
487
|
if (this.getGroup(groupName) === void 0) throw new StoreError("not-found", `error: group '${groupName}' not found`);
|
|
488
|
+
if (!KEY_NAME_SCHEMA.test(name)) throw new StoreError("invalid", "error: key name must match /^[a-z0-9][a-z0-9._-]*$/");
|
|
472
489
|
let keyId;
|
|
473
490
|
do
|
|
474
491
|
keyId = randomZ32(8);
|
|
@@ -479,6 +496,8 @@ var ProviderStore = class ProviderStore {
|
|
|
479
496
|
keyId,
|
|
480
497
|
group: groupName,
|
|
481
498
|
hash: hashKeyMaterial(key),
|
|
499
|
+
name,
|
|
500
|
+
key,
|
|
482
501
|
createdAt
|
|
483
502
|
});
|
|
484
503
|
this.save();
|
|
@@ -488,6 +507,12 @@ var ProviderStore = class ProviderStore {
|
|
|
488
507
|
createdAt
|
|
489
508
|
};
|
|
490
509
|
}
|
|
510
|
+
/** key 原文取回(旧记录只存哈希 → undefined;撤销/不存在 → undefined)。 */
|
|
511
|
+
getKeyMaterial(keyId) {
|
|
512
|
+
const found = this.data.keys.find((k) => k.keyId === keyId);
|
|
513
|
+
if (found === void 0 || found.revokedAt !== void 0) return void 0;
|
|
514
|
+
return found.key;
|
|
515
|
+
}
|
|
491
516
|
/** 撤销(幂等:已撤销为 no-op)。 */
|
|
492
517
|
revokeKey(keyId) {
|
|
493
518
|
const found = this.data.keys.find((k) => k.keyId === keyId);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { n as UsageError, r as reportCliError } from "./errors-BGtxPkM7.mjs";
|
|
2
2
|
import { n as parseArgv } from "./args-CSxXW9eD.mjs";
|
|
3
|
-
import { n as consumersRoot, s as listKeyrings } from "./store-
|
|
3
|
+
import { n as consumersRoot, s as listKeyrings } from "./store-DOFDy1rY.mjs";
|
|
4
4
|
import { n as desiredPortFor } from "./ports-pI59MtmI.mjs";
|
|
5
|
-
import { n as testLocalService } from "./local-test-
|
|
5
|
+
import { n as testLocalService } from "./local-test-BZHGo22F.mjs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
//#region src/cli/commands/consumer/test.ts
|
|
8
8
|
const SPEC = {
|
package/hooks/codex.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// 内建 hooks 脚本:codex —— 读 codex CLI 登录态(~/.codex/auth.json)。
|
|
2
|
+
// 钩子清单(按函数名命名规范被发现):
|
|
3
|
+
// - authHeader(ctx) -> string:ChatGPT Codex backend 的 Bearer 认证头(去前缀裸值,
|
|
4
|
+
// 框架按需拼 "Bearer " 由 headerSet 配置的 bearer 决定——本脚本返回裸 token)。
|
|
5
|
+
module.exports.authHeader = function authHeader({ homedir }) {
|
|
6
|
+
const { readFileSync } = require("node:fs");
|
|
7
|
+
const { join } = require("node:path");
|
|
8
|
+
const auth = JSON.parse(readFileSync(join(homedir, ".codex", "auth.json"), "utf8"));
|
|
9
|
+
const token = auth && auth.tokens && auth.tokens.access_token;
|
|
10
|
+
if (typeof token !== "string" || token === "") throw new Error("codex auth.json missing access_token");
|
|
11
|
+
return token;
|
|
12
|
+
};
|
package/hooks/env.cjs
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// 内建 hooks 脚本:env —— 环境变量桥。
|
|
2
|
+
// 钩子清单:
|
|
3
|
+
// - authHeader(ctx) -> string:读 args.var 指定的环境变量(OPENAI_API_KEY 等)。
|
|
4
|
+
module.exports.authHeader = function authHeader({ args, env: ctxEnv }) {
|
|
5
|
+
const name = args && args.var;
|
|
6
|
+
if (typeof name !== "string" || name === "") throw new Error("env hook requires args.var");
|
|
7
|
+
const value = (ctxEnv && ctxEnv(name)) || process.env[name];
|
|
8
|
+
if (value === undefined || value === "") throw new Error(`env '${name}' unset`);
|
|
9
|
+
return value;
|
|
10
|
+
};
|
package/hooks/file.cjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// 内建 hooks 脚本:file —— JSON 文件取值(点径)。
|
|
2
|
+
// 钩子清单:
|
|
3
|
+
// - authHeader(ctx) -> string:读 args.path(支持 ~)+ args.jsonPath(.a.b 风格);
|
|
4
|
+
// args.bearer 为 "true"/"1" 时返回值拼 "Bearer " 前缀。
|
|
5
|
+
// watch 模式示例(返回 AsyncIterable):unwatchOnClose 实现见文档。
|
|
6
|
+
module.exports.authHeader = function authHeader({ homedir, args }) {
|
|
7
|
+
const { readFileSync } = require("node:fs");
|
|
8
|
+
const { join } = require("node:path");
|
|
9
|
+
const path = args && args.path;
|
|
10
|
+
const jsonPath = (args && args.jsonPath) || ".";
|
|
11
|
+
if (typeof path !== "string" || path === "") throw new Error("file hook requires args.path");
|
|
12
|
+
const abs = path.startsWith("~/") ? join(homedir, path.slice(1)) : path;
|
|
13
|
+
let doc;
|
|
14
|
+
try {
|
|
15
|
+
doc = JSON.parse(readFileSync(abs, "utf8"));
|
|
16
|
+
} catch {
|
|
17
|
+
throw new Error("file unreadable or invalid JSON");
|
|
18
|
+
}
|
|
19
|
+
let cur = doc;
|
|
20
|
+
for (const seg of jsonPath.split(".").filter(Boolean)) {
|
|
21
|
+
if (cur === null || cur === undefined) throw new Error("json path miss");
|
|
22
|
+
cur = cur[seg];
|
|
23
|
+
}
|
|
24
|
+
if (typeof cur !== "string" || cur === "") throw new Error("json path value missing");
|
|
25
|
+
const bearer = args && (args.bearer === "true" || args.bearer === "1");
|
|
26
|
+
return bearer ? `Bearer ${cur}` : cur;
|
|
27
|
+
};
|
package/hooks/secret.cjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// 内建 hooks 脚本:secret —— 密钥库(SecretsStore)桥。
|
|
2
|
+
// 钩子清单:
|
|
3
|
+
// - authHeader(ctx) -> string:读 args.name 指定的密钥(ctx.secrets 访问器;
|
|
4
|
+
// 值只进头不回显——$secret 法则不变)。
|
|
5
|
+
module.exports.authHeader = function authHeader({ args, secrets }) {
|
|
6
|
+
const name = args && args.name;
|
|
7
|
+
if (typeof name !== "string" || name === "") throw new Error("secret hook requires args.name");
|
|
8
|
+
const value = secrets && secrets(name);
|
|
9
|
+
if (value === undefined || value === "") throw new Error(`secret '${name}' not found`);
|
|
10
|
+
return value;
|
|
11
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-fly",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-alpha.10",
|
|
4
4
|
"description": "ai-fly — peer-to-peer HTTP/WebSocket bridge with AI-ready presets, over OpenDWeb fabric",
|
|
5
5
|
"license": "MIT OR Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -58,7 +58,11 @@
|
|
|
58
58
|
"files": [
|
|
59
59
|
"dist/*.js",
|
|
60
60
|
"dist/*.mjs",
|
|
61
|
-
"dist/*.d.ts"
|
|
61
|
+
"dist/*.d.ts",
|
|
62
|
+
"dist/app/**",
|
|
63
|
+
"hooks",
|
|
64
|
+
"webui/dist",
|
|
65
|
+
"resources/app-icons"
|
|
62
66
|
],
|
|
63
67
|
"repository": {
|
|
64
68
|
"type": "git",
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"appIcon": [
|
|
4
|
+
{
|
|
5
|
+
"platform": "darwin",
|
|
6
|
+
"format": "icns",
|
|
7
|
+
"source": {
|
|
8
|
+
"type": "file",
|
|
9
|
+
"path": "app-icon.icns"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"platform": "windows",
|
|
14
|
+
"format": "ico",
|
|
15
|
+
"source": {
|
|
16
|
+
"type": "file",
|
|
17
|
+
"path": "app-icon.ico"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"platform": "linux",
|
|
22
|
+
"format": "png",
|
|
23
|
+
"size": 16,
|
|
24
|
+
"source": {
|
|
25
|
+
"type": "file",
|
|
26
|
+
"path": "linux/16x16/app-icon.png"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"platform": "linux",
|
|
31
|
+
"format": "png",
|
|
32
|
+
"size": 32,
|
|
33
|
+
"source": {
|
|
34
|
+
"type": "file",
|
|
35
|
+
"path": "linux/32x32/app-icon.png"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"platform": "linux",
|
|
40
|
+
"format": "png",
|
|
41
|
+
"size": 48,
|
|
42
|
+
"source": {
|
|
43
|
+
"type": "file",
|
|
44
|
+
"path": "linux/48x48/app-icon.png"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"platform": "linux",
|
|
49
|
+
"format": "png",
|
|
50
|
+
"size": 64,
|
|
51
|
+
"source": {
|
|
52
|
+
"type": "file",
|
|
53
|
+
"path": "linux/64x64/app-icon.png"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"platform": "linux",
|
|
58
|
+
"format": "png",
|
|
59
|
+
"size": 128,
|
|
60
|
+
"source": {
|
|
61
|
+
"type": "file",
|
|
62
|
+
"path": "linux/128x128/app-icon.png"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"platform": "linux",
|
|
67
|
+
"format": "png",
|
|
68
|
+
"size": 256,
|
|
69
|
+
"source": {
|
|
70
|
+
"type": "file",
|
|
71
|
+
"path": "linux/256x256/app-icon.png"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"platform": "linux",
|
|
76
|
+
"format": "png",
|
|
77
|
+
"size": 512,
|
|
78
|
+
"source": {
|
|
79
|
+
"type": "file",
|
|
80
|
+
"path": "linux/512x512/app-icon.png"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|