@visiblebase/manager 0.1.1

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 (98) hide show
  1. package/README.md +33 -0
  2. package/bin/admin/auth-error.d.ts +30 -0
  3. package/bin/admin/auth-error.d.ts.map +1 -0
  4. package/bin/admin/auth-error.js +45 -0
  5. package/bin/admin/auth-error.js.map +1 -0
  6. package/bin/admin/commands/accounts.d.ts +6 -0
  7. package/bin/admin/commands/accounts.d.ts.map +1 -0
  8. package/bin/admin/commands/accounts.js +44 -0
  9. package/bin/admin/commands/accounts.js.map +1 -0
  10. package/bin/admin/commands/balance.d.ts +6 -0
  11. package/bin/admin/commands/balance.d.ts.map +1 -0
  12. package/bin/admin/commands/balance.js +100 -0
  13. package/bin/admin/commands/balance.js.map +1 -0
  14. package/bin/admin/commands/config.d.ts +9 -0
  15. package/bin/admin/commands/config.d.ts.map +1 -0
  16. package/bin/admin/commands/config.js +55 -0
  17. package/bin/admin/commands/config.js.map +1 -0
  18. package/bin/admin/commands/custom.d.ts +6 -0
  19. package/bin/admin/commands/custom.d.ts.map +1 -0
  20. package/bin/admin/commands/custom.js +47 -0
  21. package/bin/admin/commands/custom.js.map +1 -0
  22. package/bin/admin/commands/models.d.ts +14 -0
  23. package/bin/admin/commands/models.d.ts.map +1 -0
  24. package/bin/admin/commands/models.js +56 -0
  25. package/bin/admin/commands/models.js.map +1 -0
  26. package/bin/admin/commands/payment.d.ts +6 -0
  27. package/bin/admin/commands/payment.d.ts.map +1 -0
  28. package/bin/admin/commands/payment.js +33 -0
  29. package/bin/admin/commands/payment.js.map +1 -0
  30. package/bin/admin/commands/plugin-env.d.ts +11 -0
  31. package/bin/admin/commands/plugin-env.d.ts.map +1 -0
  32. package/bin/admin/commands/plugin-env.js +283 -0
  33. package/bin/admin/commands/plugin-env.js.map +1 -0
  34. package/bin/admin/commands/products.d.ts +6 -0
  35. package/bin/admin/commands/products.d.ts.map +1 -0
  36. package/bin/admin/commands/products.js +77 -0
  37. package/bin/admin/commands/products.js.map +1 -0
  38. package/bin/admin/commands/usage.d.ts +6 -0
  39. package/bin/admin/commands/usage.d.ts.map +1 -0
  40. package/bin/admin/commands/usage.js +44 -0
  41. package/bin/admin/commands/usage.js.map +1 -0
  42. package/bin/admin/loop.d.ts +6 -0
  43. package/bin/admin/loop.d.ts.map +1 -0
  44. package/bin/admin/loop.js +75 -0
  45. package/bin/admin/loop.js.map +1 -0
  46. package/bin/agent/pi-agent.d.ts +15 -0
  47. package/bin/agent/pi-agent.d.ts.map +1 -0
  48. package/bin/agent/pi-agent.js +136 -0
  49. package/bin/agent/pi-agent.js.map +1 -0
  50. package/bin/app.d.ts +13 -0
  51. package/bin/app.d.ts.map +1 -0
  52. package/bin/app.js +67 -0
  53. package/bin/app.js.map +1 -0
  54. package/bin/auth/admin.d.ts +8 -0
  55. package/bin/auth/admin.d.ts.map +1 -0
  56. package/bin/auth/admin.js +24 -0
  57. package/bin/auth/admin.js.map +1 -0
  58. package/bin/auth/mode-select.d.ts +12 -0
  59. package/bin/auth/mode-select.d.ts.map +1 -0
  60. package/bin/auth/mode-select.js +30 -0
  61. package/bin/auth/mode-select.js.map +1 -0
  62. package/bin/auth/server-switch.d.ts +16 -0
  63. package/bin/auth/server-switch.d.ts.map +1 -0
  64. package/bin/auth/server-switch.js +98 -0
  65. package/bin/auth/server-switch.js.map +1 -0
  66. package/bin/auth/user.d.ts +21 -0
  67. package/bin/auth/user.d.ts.map +1 -0
  68. package/bin/auth/user.js +223 -0
  69. package/bin/auth/user.js.map +1 -0
  70. package/bin/core/env.d.ts +15 -0
  71. package/bin/core/env.d.ts.map +1 -0
  72. package/bin/core/env.js +67 -0
  73. package/bin/core/env.js.map +1 -0
  74. package/bin/core/session.d.ts +53 -0
  75. package/bin/core/session.d.ts.map +1 -0
  76. package/bin/core/session.js +118 -0
  77. package/bin/core/session.js.map +1 -0
  78. package/bin/core/ui.d.ts +29 -0
  79. package/bin/core/ui.d.ts.map +1 -0
  80. package/bin/core/ui.js +58 -0
  81. package/bin/core/ui.js.map +1 -0
  82. package/bin/user/balance.d.ts +19 -0
  83. package/bin/user/balance.d.ts.map +1 -0
  84. package/bin/user/balance.js +62 -0
  85. package/bin/user/balance.js.map +1 -0
  86. package/bin/user/chat.d.ts +12 -0
  87. package/bin/user/chat.d.ts.map +1 -0
  88. package/bin/user/chat.js +70 -0
  89. package/bin/user/chat.js.map +1 -0
  90. package/bin/user/loop.d.ts +13 -0
  91. package/bin/user/loop.d.ts.map +1 -0
  92. package/bin/user/loop.js +87 -0
  93. package/bin/user/loop.js.map +1 -0
  94. package/bin/user/models.d.ts +10 -0
  95. package/bin/user/models.d.ts.map +1 -0
  96. package/bin/user/models.js +39 -0
  97. package/bin/user/models.js.map +1 -0
  98. package/package.json +52 -0
@@ -0,0 +1,136 @@
1
+ import { AuthStorage, createAgentSession, createExtensionRuntime, ModelRegistry, SessionManager, SettingsManager, } from "@mariozechner/pi-coding-agent";
2
+ // ============================================================
3
+ // 会话创建
4
+ // ============================================================
5
+ /** 创建 pi-agent 会话,通过 server 端点调用 AI */
6
+ export async function createPiAgentSession(options) {
7
+ const { model: handle, tools: toolsOpt, onText, onToolStart, onToolEnd } = options;
8
+ if (!handle.token) {
9
+ throw new Error("User token is required for agent. Please login first.");
10
+ }
11
+ const authStorage = AuthStorage.inMemory();
12
+ authStorage.setRuntimeApiKey("openai-compatible", handle.token);
13
+ const tools = resolveTools(toolsOpt);
14
+ const { session } = await createAgentSession({
15
+ cwd: process.cwd(),
16
+ model: createModel(handle),
17
+ thinkingLevel: "off",
18
+ authStorage,
19
+ modelRegistry: ModelRegistry.inMemory(authStorage),
20
+ resourceLoader: createMinimalResourceLoader(),
21
+ sessionManager: SessionManager.inMemory(process.cwd()),
22
+ settingsManager: SettingsManager.inMemory({
23
+ compaction: { enabled: false },
24
+ retry: { enabled: false },
25
+ }),
26
+ noTools: tools.length === 0 ? "all" : undefined,
27
+ tools: tools.length > 0 ? tools : undefined,
28
+ });
29
+ let activeTurn;
30
+ session.subscribe((event) => {
31
+ if (!activeTurn)
32
+ return;
33
+ if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta") {
34
+ activeTurn.text += event.assistantMessageEvent.delta;
35
+ activeTurn.streamedText = true;
36
+ onText?.(event.assistantMessageEvent.delta);
37
+ return;
38
+ }
39
+ if (event.type === "message_end") {
40
+ activeTurn.assistantError = extractAssistantError(event.message) ?? activeTurn.assistantError;
41
+ const finalText = extractAssistantText(event.message);
42
+ if (finalText) {
43
+ activeTurn.text = finalText;
44
+ if (!activeTurn.streamedText)
45
+ onText?.(finalText);
46
+ }
47
+ return;
48
+ }
49
+ if (event.type === "tool_execution_start") {
50
+ onToolStart?.(event.toolName, event.args);
51
+ return;
52
+ }
53
+ if (event.type === "tool_execution_end") {
54
+ onToolEnd?.(event.toolName, event.isError);
55
+ }
56
+ });
57
+ return {
58
+ ask: async (prompt) => {
59
+ activeTurn = { text: "", streamedText: false };
60
+ await session.prompt(prompt, { expandPromptTemplates: false });
61
+ const completedTurn = activeTurn;
62
+ activeTurn = undefined;
63
+ if (completedTurn?.assistantError) {
64
+ throw new Error(`Pi agent request failed: ${completedTurn.assistantError}`);
65
+ }
66
+ return completedTurn?.text.trim() ?? "";
67
+ },
68
+ };
69
+ }
70
+ // ============================================================
71
+ // 内部函数
72
+ // ============================================================
73
+ function createModel(handle) {
74
+ return {
75
+ id: handle.id,
76
+ name: handle.name,
77
+ api: "openai-completions",
78
+ provider: "openai-compatible",
79
+ baseUrl: handle.endpoint,
80
+ reasoning: false,
81
+ input: ["text"],
82
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
83
+ contextWindow: 262144,
84
+ maxTokens: 4096,
85
+ compat: {
86
+ supportsStore: false,
87
+ supportsDeveloperRole: false,
88
+ supportsReasoningEffort: false,
89
+ supportsStrictMode: false,
90
+ maxTokensField: "max_tokens",
91
+ },
92
+ };
93
+ }
94
+ function resolveTools(value) {
95
+ const mode = value ?? "agent";
96
+ if (mode === "none")
97
+ return [];
98
+ if (mode === "read-only")
99
+ return ["read", "grep", "find", "ls"];
100
+ if (mode === "agent")
101
+ return ["read", "grep", "find", "ls", "bash"];
102
+ if (mode === "coding")
103
+ return ["read", "grep", "find", "ls", "bash", "edit", "write"];
104
+ return mode.split(",").map((t) => t.trim()).filter(Boolean);
105
+ }
106
+ function extractAssistantText(message) {
107
+ if (!isRecord(message) || message.role !== "assistant" || !Array.isArray(message.content))
108
+ return "";
109
+ return message.content
110
+ .filter(isRecord)
111
+ .filter((c) => c.type === "text" && typeof c.text === "string")
112
+ .map((c) => String(c.text))
113
+ .join("");
114
+ }
115
+ function extractAssistantError(message) {
116
+ if (!isRecord(message) || message.role !== "assistant" || message.stopReason !== "error")
117
+ return undefined;
118
+ return typeof message.errorMessage === "string" ? message.errorMessage : "unknown error";
119
+ }
120
+ function createMinimalResourceLoader() {
121
+ return {
122
+ getExtensions: () => ({ extensions: [], errors: [], runtime: createExtensionRuntime() }),
123
+ getSkills: () => ({ skills: [], diagnostics: [] }),
124
+ getPrompts: () => ({ prompts: [], diagnostics: [] }),
125
+ getThemes: () => ({ themes: [], diagnostics: [] }),
126
+ getAgentsFiles: () => ({ agentsFiles: [] }),
127
+ getSystemPrompt: () => "You are a minimal test assistant. Answer the user directly.",
128
+ getAppendSystemPrompt: () => [],
129
+ extendResources: () => { },
130
+ reload: async () => { },
131
+ };
132
+ }
133
+ function isRecord(value) {
134
+ return typeof value === "object" && value !== null;
135
+ }
136
+ //# sourceMappingURL=pi-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-agent.js","sourceRoot":"","sources":["../../src/agent/pi-agent.ts"],"names":[],"mappings":"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"}
package/bin/app.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * VisibleBase Agent 入口与状态机调度。
4
+ *
5
+ * 状态流转:
6
+ * selectIdentity → Admin → adminLoop → selectIdentity (switch identity)
7
+ * selectIdentity → User → userLoop → selectIdentity (switch identity)
8
+ * selectIdentity → Switch Server → selectIdentity
9
+ *
10
+ * 不再持有 config 快照,每次需要时从磁盘 readConfig()。
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
package/bin/app.js ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * VisibleBase Agent 入口与状态机调度。
4
+ *
5
+ * 状态流转:
6
+ * selectIdentity → Admin → adminLoop → selectIdentity (switch identity)
7
+ * selectIdentity → User → userLoop → selectIdentity (switch identity)
8
+ * selectIdentity → Switch Server → selectIdentity
9
+ *
10
+ * 不再持有 config 快照,每次需要时从磁盘 readConfig()。
11
+ */
12
+ import { intro } from "./core/ui.js";
13
+ import { readConfig, writeConfig } from "./core/session.js";
14
+ import { parseArgs } from "./core/env.js";
15
+ import { selectIdentity } from "./auth/mode-select.js";
16
+ import { adminAuth } from "./auth/admin.js";
17
+ import { userAuth } from "./auth/user.js";
18
+ import { switchServerMenu } from "./auth/server-switch.js";
19
+ import { userLoop } from "./user/loop.js";
20
+ import { adminLoop } from "./admin/loop.js";
21
+ main().finally(() => process.exit(0));
22
+ async function main() {
23
+ parseArgs(process.argv.slice(2));
24
+ intro("VisibleBase Agent (Esc to go back, Ctrl+C to exit)");
25
+ let identity = await selectIdentity();
26
+ while (identity !== "quit") {
27
+ if (identity === "switch") {
28
+ await switchServerMenu();
29
+ identity = await selectIdentity();
30
+ continue;
31
+ }
32
+ // 每次从磁盘读取最新 config,不持快照
33
+ const cfg = readConfig();
34
+ writeConfig({ ...cfg, last_identity: identity });
35
+ if (identity === "admin") {
36
+ const session = await adminAuth(cfg.base_url);
37
+ if (!session) {
38
+ identity = await selectIdentity();
39
+ continue;
40
+ }
41
+ const result = await adminLoop(session);
42
+ if (result === "quit")
43
+ break;
44
+ if (result === "switch_identity") {
45
+ identity = await selectIdentity();
46
+ continue;
47
+ }
48
+ identity = await selectIdentity();
49
+ continue;
50
+ }
51
+ // identity === "user"
52
+ const ctx = await userAuth(cfg.base_url);
53
+ if (!ctx) {
54
+ identity = await selectIdentity();
55
+ continue;
56
+ }
57
+ const result = await userLoop(ctx);
58
+ if (result === "quit")
59
+ break;
60
+ if (result === "switch_identity") {
61
+ identity = await selectIdentity();
62
+ continue;
63
+ }
64
+ identity = await selectIdentity();
65
+ }
66
+ }
67
+ //# sourceMappingURL=app.js.map
package/bin/app.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEtC,KAAK,UAAU,IAAI;IACjB,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACjC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAE5D,IAAI,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;IAEtC,OAAO,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC3B,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,gBAAgB,EAAE,CAAC;YACzB,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QAED,wBAAwB;QACxB,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,GAAG,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEjD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAC,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,MAAM,KAAK,MAAM;gBAAE,MAAM;YAC7B,IAAI,MAAM,KAAK,iBAAiB,EAAE,CAAC;gBAAC,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;gBAAC,SAAS;YAAC,CAAC;YAClF,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;YAClC,SAAS;QACX,CAAC;QAED,sBAAsB;QACtB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,GAAG,EAAE,CAAC;YAAC,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM;QAC7B,IAAI,MAAM,KAAK,iBAAiB,EAAE,CAAC;YAAC,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;YAAC,SAAS;QAAC,CAAC;QAClF,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Admin 鉴权模块。
3
+ *
4
+ * 已有 session 直接返回,否则让用户输入 admin_secret_key。
5
+ */
6
+ import { type AdminSession } from "../core/session.js";
7
+ export declare function adminAuth(baseUrl: string): Promise<AdminSession | undefined>;
8
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/auth/admin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAuC,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG5F,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAalF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Admin 鉴权模块。
3
+ *
4
+ * 已有 session 直接返回,否则让用户输入 admin_secret_key。
5
+ */
6
+ import { normalizeBaseUrl } from "../core/env.js";
7
+ import { readAdminSession, writeAdminSession } from "../core/session.js";
8
+ import { askSecret, showSuccess } from "../core/ui.js";
9
+ export async function adminAuth(baseUrl) {
10
+ const existing = readAdminSession(normalizeBaseUrl(baseUrl));
11
+ if (existing)
12
+ return existing;
13
+ const key = await askSecret("admin_secret_key");
14
+ if (!key)
15
+ return undefined;
16
+ const normalizedKey = key.trim();
17
+ if (!normalizedKey)
18
+ return undefined;
19
+ const session = { base_url: normalizeBaseUrl(baseUrl), admin_token: normalizedKey };
20
+ writeAdminSession(session);
21
+ showSuccess("admin session saved");
22
+ return session;
23
+ }
24
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/auth/admin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAqB,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,CAAC;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,aAAa,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,aAAa;QAAE,OAAO,SAAS,CAAC;IAErC,MAAM,OAAO,GAAiB,EAAE,QAAQ,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;IAClG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3B,WAAW,CAAC,qBAAqB,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * 身份选择模块。
3
+ *
4
+ * 始终显示菜单,已有 session 的身份加 ★ 标记。
5
+ * 选项:Admin / User / Switch Server / Quit。
6
+ */
7
+ export type Identity = "admin" | "user" | "switch" | "quit";
8
+ /**
9
+ * 选择身份。始终显示菜单,已有 session 的身份标注 ★。
10
+ */
11
+ export declare function selectIdentity(): Promise<Identity>;
12
+ //# sourceMappingURL=mode-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-select.d.ts","sourceRoot":"","sources":["../../src/auth/mode-select.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5D;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAoBxD"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 身份选择模块。
3
+ *
4
+ * 始终显示菜单,已有 session 的身份加 ★ 标记。
5
+ * 选项:Admin / User / Switch Server / Quit。
6
+ */
7
+ import { readConfig, readAdminSession, readUserSession } from "../core/session.js";
8
+ import { select, isCancel } from "@clack/prompts";
9
+ /**
10
+ * 选择身份。始终显示菜单,已有 session 的身份标注 ★。
11
+ */
12
+ export async function selectIdentity() {
13
+ const config = readConfig();
14
+ const hasAdmin = !!readAdminSession(config.base_url);
15
+ const hasUser = !!readUserSession(config.base_url);
16
+ const serverName = config.servers.find((s) => s.url === config.base_url)?.name ?? config.base_url;
17
+ const selected = await select({
18
+ message: `Identity [${serverName}]`,
19
+ options: [
20
+ { label: hasAdmin ? "★ Admin" : " Admin", value: "admin", hint: hasAdmin ? "session active" : "Admin management" },
21
+ { label: hasUser ? "★ User" : " User", value: "user", hint: hasUser ? "session active" : "Login or register" },
22
+ { label: "Switch Server", value: "switch", hint: config.servers.length > 1 ? `${config.servers.length} servers` : "Change server URL" },
23
+ { label: "Quit", value: "quit" },
24
+ ],
25
+ });
26
+ if (!selected || isCancel(selected))
27
+ return "quit";
28
+ return selected;
29
+ }
30
+ //# sourceMappingURL=mode-select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-select.js","sourceRoot":"","sources":["../../src/auth/mode-select.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAIlD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,MAAM,QAAQ,GAAG,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC;IAElG,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,aAAa,UAAU,GAAG;QACnC,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,EAAE;YACpH,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,mBAAmB,EAAE;YAChH,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,mBAAmB,EAAE;YACvI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;SACjC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,MAAM,CAAC;IACnD,OAAO,QAAoB,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 服务端切换模块。
3
+ *
4
+ * 列出已保存的服务端,支持切换、添加新服务端,以及维护当前服务端的 admin key。
5
+ * 切换后 caller 负责重新 selectIdentity。
6
+ */
7
+ /**
8
+ * 显示服务端列表,支持切换/添加。
9
+ */
10
+ export declare function switchServerMenu(): Promise<void>;
11
+ /**
12
+ * 交互式添加服务端。
13
+ * 供 server-switch 和 admin config 复用。
14
+ */
15
+ export declare function promptAddServer(): Promise<void>;
16
+ //# sourceMappingURL=server-switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-switch.d.ts","sourceRoot":"","sources":["../../src/auth/server-switch.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsDtD;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAgBrD"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * 服务端切换模块。
3
+ *
4
+ * 列出已保存的服务端,支持切换、添加新服务端,以及维护当前服务端的 admin key。
5
+ * 切换后 caller 负责重新 selectIdentity。
6
+ */
7
+ import { readConfig, switchServer, addServer, readAdminSession, writeAdminSession, clearAdminSession, } from "../core/session.js";
8
+ import { select, isCancel, text, password } from "@clack/prompts";
9
+ import { showError, showSuccess } from "../core/ui.js";
10
+ /**
11
+ * 显示服务端列表,支持切换/添加。
12
+ */
13
+ export async function switchServerMenu() {
14
+ const config = readConfig();
15
+ const hasAdmin = !!readAdminSession(config.base_url);
16
+ const choices = config.servers.map((s) => ({
17
+ label: s.url === config.base_url ? `★ ${s.name}` : ` ${s.name}`,
18
+ value: s.url,
19
+ hint: s.url,
20
+ }));
21
+ choices.push({
22
+ label: hasAdmin ? "Update admin key for current server..." : "Set admin key for current server...",
23
+ value: "__set_admin__",
24
+ hint: config.base_url,
25
+ }, {
26
+ label: "Clear admin key for current server...",
27
+ value: "__clear_admin__",
28
+ hint: hasAdmin ? config.base_url : "No saved admin key",
29
+ });
30
+ choices.push({ label: "Add new server...", value: "__add__", hint: "" });
31
+ const selected = await select({
32
+ message: "Switch Server (★ current)",
33
+ options: choices,
34
+ });
35
+ if (!selected || isCancel(selected))
36
+ return;
37
+ if (selected === "__add__") {
38
+ await promptAddServer();
39
+ return;
40
+ }
41
+ if (selected === "__set_admin__") {
42
+ await promptSetAdminKey(config.base_url);
43
+ return;
44
+ }
45
+ if (selected === "__clear_admin__") {
46
+ if (!hasAdmin) {
47
+ showError("No saved admin key for current server.");
48
+ return;
49
+ }
50
+ clearAdminSession(config.base_url);
51
+ showSuccess("Cleared admin key for current server.");
52
+ return;
53
+ }
54
+ if (selected !== config.base_url) {
55
+ switchServer(selected);
56
+ showSuccess(`Switched to ${selected}`);
57
+ }
58
+ }
59
+ /**
60
+ * 交互式添加服务端。
61
+ * 供 server-switch 和 admin config 复用。
62
+ */
63
+ export async function promptAddServer() {
64
+ const url = await text({
65
+ message: "Server URL",
66
+ placeholder: "https://visiblebase.wangenius.workers.dev",
67
+ });
68
+ if (!url || isCancel(url) || !url.trim())
69
+ return;
70
+ const name = await text({
71
+ message: "Display name",
72
+ placeholder: "production",
73
+ });
74
+ if (!name || isCancel(name))
75
+ return;
76
+ const displayName = name.trim() || new URL(url.trim()).hostname;
77
+ addServer(displayName, url.trim());
78
+ showSuccess(`Added: ${displayName} (${url.trim()})`);
79
+ }
80
+ /**
81
+ * 为当前服务端写入 admin key。
82
+ */
83
+ async function promptSetAdminKey(baseUrl) {
84
+ const key = await password({ message: "admin_secret_key" });
85
+ if (!key || isCancel(key))
86
+ return;
87
+ const normalizedKey = String(key).trim();
88
+ if (!normalizedKey) {
89
+ showError("admin_secret_key cannot be empty.");
90
+ return;
91
+ }
92
+ // 关键说明(中文)
93
+ // - admin key 按服务端 URL 隔离保存。
94
+ // - 后续进入 Admin 身份时,会直接复用这里写入的 session。
95
+ writeAdminSession({ base_url: baseUrl, admin_token: normalizedKey });
96
+ showSuccess("Saved admin key for current server.");
97
+ }
98
+ //# sourceMappingURL=server-switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-switch.js","sourceRoot":"","sources":["../../src/auth/server-switch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * User 鉴权模块。
3
+ *
4
+ * 支持四种登录方式:
5
+ * 1. Email Login — 邮箱 + 密码直接登录
6
+ * 2. Email Register — 邮箱 + 密码注册 → 验证码 → 完成
7
+ * 3. GitHub OAuth — 浏览器授权
8
+ * 4. Google OAuth — 浏览器授权
9
+ *
10
+ * 已有有效 session 直接返回,不重复鉴权。
11
+ */
12
+ import { type UserSession } from "../core/session.js";
13
+ export interface UserContext {
14
+ session: UserSession;
15
+ config: {
16
+ base_url: string;
17
+ model: string;
18
+ };
19
+ }
20
+ export declare function userAuth(baseUrl: string): Promise<UserContext | undefined>;
21
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/auth/user.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,EAAiD,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGrG,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAQD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAWhF"}