@chainingintention/pi-web-cn 1.202606.11 → 1.202606.13
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 +14 -7
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/{CodeViewer-DzeGsHZ5.js → CodeViewer-D5OA_6r4.js} +1 -1
- package/dist/client/assets/{TerminalPanel-BghODb4T.js → TerminalPanel-kfPHfhUe.js} +9 -9
- package/dist/client/assets/index-MmspRbMF.js +2403 -0
- package/dist/client/index.html +1 -1
- package/dist/config.js +54 -3
- package/dist/config.js.map +1 -1
- package/dist/pi-web-plugins/updates/package.json +1 -1
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +61 -71
- package/dist/pi-web-plugins/updates/updatesLogic.js +65 -0
- package/dist/pi-web-plugins/workspace-tasks/tasksPanelElement.js +1 -5
- package/dist/server/app.js +14 -6
- package/dist/server/app.js.map +1 -1
- package/dist/server/configRoutes.js +10 -0
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/index.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +8 -0
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineRoutes.js +6 -0
- package/dist/server/machines/machineRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +97 -5
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/piWebPluginService.js +24 -4
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +149 -45
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/piWebStatusCache.js +32 -0
- package/dist/server/piWebStatusCache.js.map +1 -0
- package/dist/server/sessiond/sessionProxyRoutes.js +15 -1
- package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
- package/dist/server/sessiond.js +34 -9
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/attachmentService.js +61 -0
- package/dist/server/sessions/attachmentService.js.map +1 -0
- package/dist/server/sessions/builtinCommands.js +21 -21
- package/dist/server/sessions/builtinCommands.js.map +1 -1
- package/dist/server/sessions/oauthLoginFlowService.js +21 -14
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +96 -0
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -0
- package/dist/server/sessions/piSessionService.js +270 -452
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/sessionArchiveStore.js +16 -2
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +32 -28
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +157 -47
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/spawnSessionTool.js +36 -0
- package/dist/server/sessions/spawnSessionTool.js.map +1 -0
- package/dist/server/sessions/spawnTargetResolver.js +36 -0
- package/dist/server/sessions/spawnTargetResolver.js.map +1 -0
- package/dist/server/terminals/terminalRoutes.js +10 -4
- package/dist/server/terminals/terminalRoutes.js.map +1 -1
- package/dist/server/workingDirectory.js +44 -0
- package/dist/server/workingDirectory.js.map +1 -0
- package/dist/server/workspaces/fileSuggestions.js +96 -16
- package/dist/server/workspaces/fileSuggestions.js.map +1 -1
- package/dist/shared/apiTypes.d.ts +77 -5
- package/dist/shared/apiTypes.js +5 -1
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +27 -0
- package/dist/shared/capabilities.js.map +1 -0
- package/dist/shared/federatedRoutes.js +3 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +28 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/dist/shared/promptAttachments.js +73 -0
- package/dist/shared/promptAttachments.js.map +1 -0
- package/dist/shared/thinkingLevels.d.ts +27 -0
- package/dist/shared/thinkingLevels.js +31 -0
- package/dist/shared/thinkingLevels.js.map +1 -0
- package/dist/shared/workspaceDeletion.js +1 -1
- package/dist/shared/workspaceDeletion.js.map +1 -1
- package/docs/plugins.md +17 -10
- package/package.json +24 -13
- package/dist/client/assets/index-DATsMV4H.js +0 -2203
- package/dist/server/sessions/managementPermissionSystem.js +0 -94
- package/dist/server/sessions/managementPermissionSystem.js.map +0 -1
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { mkdir, realpath, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { formatDimensionNote, resizeImage } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import { extensionForImageMimeType } from "../../shared/promptAttachments.js";
|
|
5
|
+
import { normalizeRelativePath } from "../workspaces/pathSafety.js";
|
|
6
|
+
/**
|
|
7
|
+
* Default workspace-relative folder used when saving pasted/dropped
|
|
8
|
+
* attachments for the agent to read with its own tools.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_ATTACHMENT_FOLDER = ".pi-web/attachments";
|
|
11
|
+
/**
|
|
12
|
+
* Convert validated attachments into pi-compatible inline image content.
|
|
13
|
+
*
|
|
14
|
+
* Mirrors pi's own CLI/TUI behaviour: each image is run through pi's
|
|
15
|
+
* `resizeImage` so it fits within pi's max dimensions and inline byte budget
|
|
16
|
+
* (2000x2000, ~4.5MB base64). Images that cannot be resized below the limit
|
|
17
|
+
* are dropped, matching pi's `[Image omitted]` behaviour.
|
|
18
|
+
*/
|
|
19
|
+
export async function attachmentsToInlineImages(attachments) {
|
|
20
|
+
const results = [];
|
|
21
|
+
for (const attachment of attachments) {
|
|
22
|
+
const bytes = Buffer.from(attachment.data, "base64");
|
|
23
|
+
const resized = await resizeImage(bytes, attachment.mimeType);
|
|
24
|
+
if (resized === null)
|
|
25
|
+
continue;
|
|
26
|
+
const note = formatDimensionNote(resized);
|
|
27
|
+
results.push({
|
|
28
|
+
image: { type: "image", data: resized.data, mimeType: resized.mimeType },
|
|
29
|
+
...(note === undefined ? {} : { dimensionNote: note }),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return results;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write attachments into a workspace folder and return their relative paths.
|
|
36
|
+
* Filenames are collision-safe and stay inside the workspace root.
|
|
37
|
+
*/
|
|
38
|
+
export async function saveAttachmentsToWorkspace(cwd, attachments, options = {}) {
|
|
39
|
+
const folder = normalizeRelativePath(normalizeFolder(options.folder ?? DEFAULT_ATTACHMENT_FOLDER));
|
|
40
|
+
const now = options.now ?? (() => new Date());
|
|
41
|
+
const folderTarget = join(await realpath(cwd), folder);
|
|
42
|
+
await mkdir(folderTarget, { recursive: true });
|
|
43
|
+
const stamp = timestamp(now());
|
|
44
|
+
const saved = [];
|
|
45
|
+
for (const [index, attachment] of attachments.entries()) {
|
|
46
|
+
const bytes = Buffer.from(attachment.data, "base64");
|
|
47
|
+
const filename = `attachment-${stamp}-${String(index + 1)}.${extensionForImageMimeType(attachment.mimeType)}`;
|
|
48
|
+
const relativePath = `${folder}/${filename}`;
|
|
49
|
+
await writeFile(join(folderTarget, filename), bytes);
|
|
50
|
+
saved.push({ path: relativePath, mimeType: attachment.mimeType, size: bytes.byteLength });
|
|
51
|
+
}
|
|
52
|
+
return saved;
|
|
53
|
+
}
|
|
54
|
+
function normalizeFolder(folder) {
|
|
55
|
+
return folder.split(/[\\/]+/).filter((part) => part !== "" && part !== ".").join("/");
|
|
56
|
+
}
|
|
57
|
+
function timestamp(date) {
|
|
58
|
+
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
59
|
+
return `${String(date.getFullYear())}${pad(date.getMonth() + 1)}${pad(date.getDate())}-${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}-${pad(date.getMilliseconds(), 3)}`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=attachmentService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachmentService.js","sourceRoot":"","sources":["../../../src/server/sessions/attachmentService.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
export const BUILTIN_COMMANDS = [
|
|
2
|
-
{ name: "settings", description: "
|
|
3
|
-
{ name: "model", description: "
|
|
4
|
-
{ name: "scoped-models", description: "
|
|
5
|
-
{ name: "export", description: "
|
|
6
|
-
{ name: "import", description: "
|
|
7
|
-
{ name: "share", description: "
|
|
8
|
-
{ name: "copy", description: "
|
|
9
|
-
{ name: "name", description: "
|
|
10
|
-
{ name: "session", description: "
|
|
11
|
-
{ name: "changelog", description: "
|
|
12
|
-
{ name: "hotkeys", description: "
|
|
13
|
-
{ name: "fork", description: "
|
|
14
|
-
{ name: "clone", description: "
|
|
15
|
-
{ name: "tree", description: "
|
|
16
|
-
{ name: "login", description: "
|
|
17
|
-
{ name: "logout", description: "
|
|
18
|
-
{ name: "new", description: "
|
|
19
|
-
{ name: "compact", description: "
|
|
20
|
-
{ name: "resume", description: "
|
|
21
|
-
{ name: "reload", description: "
|
|
22
|
-
{ name: "quit", description: "
|
|
2
|
+
{ name: "settings", description: "打开设置菜单", source: "builtin" },
|
|
3
|
+
{ name: "model", description: "选择模型", source: "builtin" },
|
|
4
|
+
{ name: "scoped-models", description: "启用/禁用可循环切换的模型", source: "builtin" },
|
|
5
|
+
{ name: "export", description: "导出会话", source: "builtin" },
|
|
6
|
+
{ name: "import", description: "从 JSONL 导入并恢复会话", source: "builtin" },
|
|
7
|
+
{ name: "share", description: "将会话分享到私密 GitHub gist", source: "builtin" },
|
|
8
|
+
{ name: "copy", description: "复制上一条代理消息", source: "builtin" },
|
|
9
|
+
{ name: "name", description: "设置会话显示名称", source: "builtin" },
|
|
10
|
+
{ name: "session", description: "显示会话信息和统计", source: "builtin" },
|
|
11
|
+
{ name: "changelog", description: "显示更新日志条目", source: "builtin" },
|
|
12
|
+
{ name: "hotkeys", description: "显示键盘快捷键", source: "builtin" },
|
|
13
|
+
{ name: "fork", description: "从之前的用户消息创建新分叉", source: "builtin" },
|
|
14
|
+
{ name: "clone", description: "在当前位置复制当前会话", source: "builtin" },
|
|
15
|
+
{ name: "tree", description: "导航会话树", source: "builtin" },
|
|
16
|
+
{ name: "login", description: "配置提供商认证", source: "builtin" },
|
|
17
|
+
{ name: "logout", description: "移除提供商认证", source: "builtin" },
|
|
18
|
+
{ name: "new", description: "启动新会话", source: "builtin" },
|
|
19
|
+
{ name: "compact", description: "手动压缩会话上下文", source: "builtin" },
|
|
20
|
+
{ name: "resume", description: "恢复另一个会话", source: "builtin" },
|
|
21
|
+
{ name: "reload", description: "重新加载键位、扩展、技能、提示词和主题", source: "builtin" },
|
|
22
|
+
{ name: "quit", description: "退出 pi", source: "builtin" },
|
|
23
23
|
];
|
|
24
24
|
export function isBuiltinCommand(name) {
|
|
25
25
|
return BUILTIN_COMMANDS.some((command) => command.name === name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtinCommands.js","sourceRoot":"","sources":["../../../src/server/sessions/builtinCommands.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"builtinCommands.js","sourceRoot":"","sources":["../../../src/server/sessions/builtinCommands.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAoB;IAC/C,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE;IAC9D,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;IACzD,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE;IAC1E,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE;IAC1D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,EAAE,SAAS,EAAE;IACrE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,EAAE,SAAS,EAAE;IACzE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE;IAC7D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE;IAC5D,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE;IAChE,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE;IACjE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC9D,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE;IACjE,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAE,SAAS,EAAE;IAChE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;IACzD,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC5D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC7D,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;IACxD,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE;IAChE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE;IAC7D,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,EAAE,SAAS,EAAE;IACzE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE;CAC1D,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -32,8 +32,15 @@ export class OAuthLoginFlowService {
|
|
|
32
32
|
return;
|
|
33
33
|
this.updateState(record, { ...record.state, auth: info });
|
|
34
34
|
},
|
|
35
|
+
// Device-code flows have no redirect URL; reuse the auth field so the web UI
|
|
36
|
+
// shows the verification link and user code without a dedicated API shape.
|
|
37
|
+
onDeviceCode: (info) => {
|
|
38
|
+
if (!this.isCurrentRunning(record))
|
|
39
|
+
return;
|
|
40
|
+
this.updateState(record, { ...record.state, auth: { url: info.verificationUri, instructions: `输入代码:${info.userCode}` } });
|
|
41
|
+
},
|
|
35
42
|
onPrompt: (prompt) => this.waitForPrompt(record, prompt, "prompt"),
|
|
36
|
-
onManualCodeInput: () => this.waitForPrompt(record, { message: "
|
|
43
|
+
onManualCodeInput: () => this.waitForPrompt(record, { message: "粘贴回调 URL 或授权码", allowEmpty: false }, "manual"),
|
|
37
44
|
onSelect: (prompt) => this.waitForSelect(record, prompt),
|
|
38
45
|
onProgress: (message) => {
|
|
39
46
|
if (!this.isCurrentRunning(record))
|
|
@@ -46,7 +53,7 @@ export class OAuthLoginFlowService {
|
|
|
46
53
|
if (!this.isCurrentRunning(record))
|
|
47
54
|
return;
|
|
48
55
|
record.pending = undefined;
|
|
49
|
-
this.markTerminal(record, { ...withoutInteraction(record.state), status: "complete", progress: [...record.state.progress, "
|
|
56
|
+
this.markTerminal(record, { ...withoutInteraction(record.state), status: "complete", progress: [...record.state.progress, "登录完成"] });
|
|
50
57
|
options.onComplete?.();
|
|
51
58
|
})
|
|
52
59
|
.catch((error) => {
|
|
@@ -62,20 +69,20 @@ export class OAuthLoginFlowService {
|
|
|
62
69
|
get(flowId) {
|
|
63
70
|
const record = this.flows.get(flowId);
|
|
64
71
|
if (record === undefined)
|
|
65
|
-
throw new Error("OAuth
|
|
72
|
+
throw new Error("未找到 OAuth 登录流程");
|
|
66
73
|
return cloneState(record.state);
|
|
67
74
|
}
|
|
68
75
|
respond(flowId, requestId, value) {
|
|
69
76
|
const record = this.flows.get(flowId);
|
|
70
77
|
if (record === undefined)
|
|
71
|
-
throw new Error("OAuth
|
|
78
|
+
throw new Error("未找到 OAuth 登录流程");
|
|
72
79
|
if (record.state.status !== "running")
|
|
73
80
|
return cloneState(record.state);
|
|
74
81
|
const pending = record.pending;
|
|
75
82
|
if (pending?.requestId !== requestId)
|
|
76
|
-
throw new Error("OAuth
|
|
83
|
+
throw new Error("OAuth 登录请求已过期");
|
|
77
84
|
if (!pending.allowEmpty && value.trim() === "")
|
|
78
|
-
throw new Error("
|
|
85
|
+
throw new Error("必须填写一个值");
|
|
79
86
|
record.pending = undefined;
|
|
80
87
|
this.updateState(record, withoutInteraction(record.state));
|
|
81
88
|
pending.resolve(value);
|
|
@@ -84,13 +91,13 @@ export class OAuthLoginFlowService {
|
|
|
84
91
|
cancel(flowId) {
|
|
85
92
|
const record = this.flows.get(flowId);
|
|
86
93
|
if (record === undefined)
|
|
87
|
-
throw new Error("OAuth
|
|
94
|
+
throw new Error("未找到 OAuth 登录流程");
|
|
88
95
|
if (record.state.status === "running") {
|
|
89
96
|
record.abort.abort();
|
|
90
97
|
const pending = record.pending;
|
|
91
98
|
record.pending = undefined;
|
|
92
|
-
this.markTerminal(record, { ...withoutInteraction(record.state), status: "cancelled", error: "
|
|
93
|
-
pending?.reject(new Error("
|
|
99
|
+
this.markTerminal(record, { ...withoutInteraction(record.state), status: "cancelled", error: "登录已取消" });
|
|
100
|
+
pending?.reject(new Error("登录已取消"));
|
|
94
101
|
}
|
|
95
102
|
return cloneState(record.state);
|
|
96
103
|
}
|
|
@@ -100,14 +107,14 @@ export class OAuthLoginFlowService {
|
|
|
100
107
|
record.abort.abort();
|
|
101
108
|
const pending = record.pending;
|
|
102
109
|
record.pending = undefined;
|
|
103
|
-
pending?.reject(new Error("
|
|
110
|
+
pending?.reject(new Error("登录已取消"));
|
|
104
111
|
}
|
|
105
112
|
this.flows.clear();
|
|
106
113
|
}
|
|
107
114
|
waitForPrompt(record, prompt, kind) {
|
|
108
115
|
return new Promise((resolve, reject) => {
|
|
109
116
|
if (!this.isCurrentRunning(record)) {
|
|
110
|
-
reject(new Error("
|
|
117
|
+
reject(new Error("登录已取消"));
|
|
111
118
|
return;
|
|
112
119
|
}
|
|
113
120
|
const requestId = crypto.randomUUID();
|
|
@@ -128,7 +135,7 @@ export class OAuthLoginFlowService {
|
|
|
128
135
|
waitForSelect(record, prompt) {
|
|
129
136
|
return new Promise((resolve, reject) => {
|
|
130
137
|
if (!this.isCurrentRunning(record)) {
|
|
131
|
-
reject(new Error("
|
|
138
|
+
reject(new Error("登录已取消"));
|
|
132
139
|
return;
|
|
133
140
|
}
|
|
134
141
|
const requestId = crypto.randomUUID();
|
|
@@ -181,8 +188,8 @@ export class OAuthLoginFlowService {
|
|
|
181
188
|
record.abort.abort();
|
|
182
189
|
const pending = record.pending;
|
|
183
190
|
record.pending = undefined;
|
|
184
|
-
this.markTerminal(record, { ...withoutInteraction(record.state), status: "error", error: "OAuth
|
|
185
|
-
pending?.reject(new Error("OAuth
|
|
191
|
+
this.markTerminal(record, { ...withoutInteraction(record.state), status: "error", error: "OAuth 登录流程已过期" });
|
|
192
|
+
pending?.reject(new Error("OAuth 登录流程已过期"));
|
|
186
193
|
}
|
|
187
194
|
setTimer(record, delayMs, callback) {
|
|
188
195
|
this.clearTimer(record);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauthLoginFlowService.js","sourceRoot":"","sources":["../../../src/server/sessions/oauthLoginFlowService.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AA8BjC,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAC9C,MAAM,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C,MAAM,OAAO,qBAAqB;IAMhC,YAAY,UAAwC,EAAE;QALrC,UAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;QAM1D,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,uBAAuB,CAAC;QACtE,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,sBAAsB,CAAC;QACnE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,OAKL;QACC,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,MAAM,GAAoB;YAC9B,MAAM;YACN,KAAK;YACL,OAAO,EAAE,SAAS;YAClB,KAAK,EAAE;gBACL,MAAM;gBACN,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,EAAE;aACb;SACF,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QAEnC,MAAM,SAAS,GAAwB;YACrC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACf,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC;oBAAE,OAAO;gBAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC;YAClE,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"oauthLoginFlowService.js","sourceRoot":"","sources":["../../../src/server/sessions/oauthLoginFlowService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readdir } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { getAgentDir, SessionManager, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
5
|
+
import { canonicalizeStoredCwd, cwdPathsEqual } from "../workingDirectory.js";
|
|
6
|
+
export const PI_SESSION_DIR_ENV = "PI_CODING_AGENT_SESSION_DIR";
|
|
7
|
+
export class SessionDirResolver {
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.agentDir = options.agentDir ?? getAgentDir();
|
|
10
|
+
this.env = options.env ?? process.env;
|
|
11
|
+
}
|
|
12
|
+
defaultSessionsRoot() {
|
|
13
|
+
return defaultPiSessionsRoot(this.agentDir);
|
|
14
|
+
}
|
|
15
|
+
resolve(cwd) {
|
|
16
|
+
const envSessionDir = this.env[PI_SESSION_DIR_ENV];
|
|
17
|
+
if (envSessionDir !== undefined && envSessionDir !== "") {
|
|
18
|
+
return { source: "env", sessionDir: resolveConfiguredPath(envSessionDir, cwd), usesConfiguredSessionDir: true };
|
|
19
|
+
}
|
|
20
|
+
const settingsSessionDir = SettingsManager.create(cwd, this.agentDir).getSessionDir();
|
|
21
|
+
if (settingsSessionDir !== undefined && settingsSessionDir !== "") {
|
|
22
|
+
return { source: "settings", sessionDir: resolveConfiguredPath(settingsSessionDir, cwd), usesConfiguredSessionDir: true };
|
|
23
|
+
}
|
|
24
|
+
return { source: "pi-default", sessionDir: defaultPiSessionDir(cwd, this.agentDir), usesConfiguredSessionDir: false };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function createPiSessionManagerGateway(options = {}) {
|
|
28
|
+
return new SettingsAwarePiSessionManagerGateway(new SessionDirResolver(options));
|
|
29
|
+
}
|
|
30
|
+
class SettingsAwarePiSessionManagerGateway {
|
|
31
|
+
constructor(resolver) {
|
|
32
|
+
this.resolver = resolver;
|
|
33
|
+
}
|
|
34
|
+
async list(cwd) {
|
|
35
|
+
const resolution = this.resolver.resolve(cwd);
|
|
36
|
+
return filterSessionsForCwd(await listSessionsInDir(resolution.sessionDir), cwd);
|
|
37
|
+
}
|
|
38
|
+
create(cwd) {
|
|
39
|
+
const resolution = this.resolver.resolve(cwd);
|
|
40
|
+
return SessionManager.create(cwd, resolution.sessionDir);
|
|
41
|
+
}
|
|
42
|
+
listAll() {
|
|
43
|
+
return listSessionsInDefaultPiStore(this.resolver.defaultSessionsRoot());
|
|
44
|
+
}
|
|
45
|
+
open(path) {
|
|
46
|
+
return SessionManager.open(path, dirname(path));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export async function listSessionsInDir(sessionDir) {
|
|
50
|
+
// listAll(sessionDir) lists without the SDK's internal cwd filter, which would
|
|
51
|
+
// otherwise compare against this process's cwd and drop other projects' sessions.
|
|
52
|
+
// Cwd filtering is applied explicitly by filterSessionsForCwd where needed.
|
|
53
|
+
// Session file headers are written by external tools (Pi CLI, SDK consumers),
|
|
54
|
+
// so their cwd is canonicalized here before it enters pi-web.
|
|
55
|
+
const sessions = await SessionManager.listAll(sessionDir);
|
|
56
|
+
return sessions.map((session) => ({ ...session, cwd: canonicalizeStoredCwd(session.cwd) }));
|
|
57
|
+
}
|
|
58
|
+
export async function listSessionsInDefaultPiStore(storeRoot = defaultPiSessionsRoot()) {
|
|
59
|
+
let entries;
|
|
60
|
+
try {
|
|
61
|
+
entries = await readdir(storeRoot, { withFileTypes: true });
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const sessionDirs = entries.filter((entry) => entry.isDirectory()).map((entry) => join(storeRoot, entry.name));
|
|
67
|
+
const sessions = (await Promise.all(sessionDirs.map((dir) => listSessionsInDir(dir)))).flat();
|
|
68
|
+
return sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
69
|
+
}
|
|
70
|
+
export function filterSessionsForCwd(sessions, cwd) {
|
|
71
|
+
// Sessions with an empty cwd (old session files) are excluded: resolve("") would
|
|
72
|
+
// resolve to this process's cwd and produce false matches.
|
|
73
|
+
return sessions.filter((session) => session.cwd !== "" && cwdPathsEqual(session.cwd, cwd));
|
|
74
|
+
}
|
|
75
|
+
export function defaultPiSessionsRoot(agentDir = getAgentDir()) {
|
|
76
|
+
return join(agentDir, "sessions");
|
|
77
|
+
}
|
|
78
|
+
export function defaultPiSessionDir(cwd, agentDir = getAgentDir()) {
|
|
79
|
+
return sessionDirInDefaultPiStore(defaultPiSessionsRoot(agentDir), cwd);
|
|
80
|
+
}
|
|
81
|
+
export function sessionDirInDefaultPiStore(storeRoot, cwd) {
|
|
82
|
+
const safePath = `--${cwd.replace(/^[/\\]/u, "").replace(/[/\\:]/gu, "-")}--`;
|
|
83
|
+
return join(storeRoot, safePath);
|
|
84
|
+
}
|
|
85
|
+
export function resolveConfiguredPath(path, cwd) {
|
|
86
|
+
const expanded = expandTildePath(path);
|
|
87
|
+
return isAbsolute(expanded) ? expanded : resolve(cwd, expanded);
|
|
88
|
+
}
|
|
89
|
+
function expandTildePath(path) {
|
|
90
|
+
if (path === "~")
|
|
91
|
+
return homedir();
|
|
92
|
+
if (path.startsWith("~/"))
|
|
93
|
+
return join(homedir(), path.slice(2));
|
|
94
|
+
return path;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=piSessionManagerGateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"piSessionManagerGateway.js","sourceRoot":"","sources":["../../../src/server/sessions/piSessionManagerGateway.ts"],"names":[],"mappings":"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"}
|