psyclaw 0.30.3 → 0.30.5
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 +7 -6
- package/dist/apps/panel/index.html +27 -1
- package/dist/src/adapters/pi/extension.js +79 -5
- package/dist/src/adapters/pi/extension.js.map +1 -1
- package/dist/src/adapters/pi/model.d.ts +1 -0
- package/dist/src/adapters/pi/model.js +2 -16
- package/dist/src/adapters/pi/model.js.map +1 -1
- package/dist/src/core/provider-endpoint.d.ts +4 -0
- package/dist/src/core/provider-endpoint.js +23 -0
- package/dist/src/core/provider-endpoint.js.map +1 -0
- package/dist/src/panel/server.js +64 -3
- package/dist/src/panel/server.js.map +1 -1
- package/dist/src/session/help.js +1 -1
- package/dist/src/session/help.js.map +1 -1
- package/dist/src/setup.d.ts +1 -0
- package/dist/src/setup.js +4 -8
- package/dist/src/setup.js.map +1 -1
- package/dist/src/style/cli-ui.js +1 -1
- package/dist/src/style/cli-ui.js.map +1 -1
- package/dist/src/tui/provider-picker.d.ts +22 -0
- package/dist/src/tui/provider-picker.js +58 -0
- package/dist/src/tui/provider-picker.js.map +1 -1
- package/dist/src/tui/skill-manager.d.ts +2 -0
- package/dist/src/tui/skill-manager.js +29 -3
- package/dist/src/tui/skill-manager.js.map +1 -1
- package/package.json +1 -1
- package/skills/recommended/catalog.json +61 -25
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/adapters/pi/model.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,GAEb,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../src/adapters/pi/model.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Shared http(s) provider endpoint rules for catalog, setup, and panel saves. */
|
|
2
|
+
export declare function normalizeEndpoint(value: string): string;
|
|
3
|
+
/** Empty submitted URL falls back to the preset/catalog endpoint. */
|
|
4
|
+
export declare function resolveProviderBaseUrl(submitted: unknown, fallback?: string): string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Shared http(s) provider endpoint rules for catalog, setup, and panel saves. */
|
|
2
|
+
export function normalizeEndpoint(value) {
|
|
3
|
+
let url;
|
|
4
|
+
try {
|
|
5
|
+
url = new URL(value);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
throw new Error("Provider endpoint must be a valid URL");
|
|
9
|
+
}
|
|
10
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
11
|
+
throw new Error("Provider endpoint must use http or https");
|
|
12
|
+
}
|
|
13
|
+
if (url.username || url.password || url.hash) {
|
|
14
|
+
throw new Error("Provider endpoint must not contain credentials or a fragment");
|
|
15
|
+
}
|
|
16
|
+
return url.toString().replace(/\/$/, "");
|
|
17
|
+
}
|
|
18
|
+
/** Empty submitted URL falls back to the preset/catalog endpoint. */
|
|
19
|
+
export function resolveProviderBaseUrl(submitted, fallback = "") {
|
|
20
|
+
const value = (typeof submitted === "string" ? submitted.trim() : "") || fallback.trim();
|
|
21
|
+
return value ? normalizeEndpoint(value) : "";
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=provider-endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-endpoint.js","sourceRoot":"","sources":["../../../src/core/provider-endpoint.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAElF,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,SAAkB,EAAE,QAAQ,GAAG,EAAE;IACtE,MAAM,KAAK,GAAG,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;IACzF,OAAO,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/C,CAAC"}
|
package/dist/src/panel/server.js
CHANGED
|
@@ -15,6 +15,7 @@ import { recommendedAgentsForPanel } from "../agents/recommended-personas.js";
|
|
|
15
15
|
import { planAgentInstall } from "../install/installer.js";
|
|
16
16
|
import { deepSeekProviderSpec, PiModelGateway } from "../adapters/pi/model.js";
|
|
17
17
|
import { PROVIDER_PRESETS, saveProviderConfig } from "../setup.js";
|
|
18
|
+
import { resolveProviderBaseUrl } from "../core/provider-endpoint.js";
|
|
18
19
|
import { assertSafeProjectPath, projectPaths } from "../project/paths.js";
|
|
19
20
|
import { readManuscript } from "../project/manuscript.js";
|
|
20
21
|
import { appendJsonlIfMissing, atomicWriteFile, readJsonl } from "../project/jsonl.js";
|
|
@@ -429,6 +430,41 @@ async function readPanelProjectFile(root, relative) {
|
|
|
429
430
|
: /\.(md|markdown)$/i.test(normalized) ? "markdown" : "text";
|
|
430
431
|
return { path: normalized, content: await readFile(target, "utf8"), format };
|
|
431
432
|
}
|
|
433
|
+
/** Map a project-file read failure to a single HTTP status. Missing and blocked paths are 404. */
|
|
434
|
+
function panelProjectFileErrorStatus(error) {
|
|
435
|
+
const code = error?.code;
|
|
436
|
+
if (code === "ENOENT")
|
|
437
|
+
return 404;
|
|
438
|
+
if (code === "EACCES" || code === "EPERM")
|
|
439
|
+
return 403;
|
|
440
|
+
const message = error instanceof Error ? error.message : "";
|
|
441
|
+
if (message.includes("too large"))
|
|
442
|
+
return 413;
|
|
443
|
+
if (message.includes("outside the Panel read-only allowlist")
|
|
444
|
+
|| message.includes("must be a regular file")
|
|
445
|
+
|| message.includes("Path escapes")
|
|
446
|
+
|| message.includes("Protected project path")
|
|
447
|
+
|| message.includes("Symlink")
|
|
448
|
+
|| message.includes("Resolved path escapes")) {
|
|
449
|
+
return 404;
|
|
450
|
+
}
|
|
451
|
+
return 500;
|
|
452
|
+
}
|
|
453
|
+
function panelProjectFileErrorPayload(error) {
|
|
454
|
+
const status = panelProjectFileErrorStatus(error);
|
|
455
|
+
const message = error instanceof Error ? error.message : "";
|
|
456
|
+
if (status === 403)
|
|
457
|
+
return { status, body: { error: "project file unreadable" } };
|
|
458
|
+
if (status === 413)
|
|
459
|
+
return { status, body: { error: "project file is too large for Panel preview" } };
|
|
460
|
+
if (status === 404) {
|
|
461
|
+
const errorText = message.includes("outside the Panel read-only allowlist") || message.includes("must be a regular file")
|
|
462
|
+
? message
|
|
463
|
+
: "project file not found";
|
|
464
|
+
return { status, body: { error: errorText } };
|
|
465
|
+
}
|
|
466
|
+
return { status, body: { error: "panel request failed", reasonCode: "panel.request-failed" } };
|
|
467
|
+
}
|
|
432
468
|
function publicInstallPlan(plan) {
|
|
433
469
|
// `projectRoot` is an internal containment anchor. It is not needed by a
|
|
434
470
|
// read-only browser and would disclose a local filesystem path.
|
|
@@ -1144,8 +1180,23 @@ export function createPanelServer(root, options = {}) {
|
|
|
1144
1180
|
}
|
|
1145
1181
|
if (url.pathname === "/api/project-file") {
|
|
1146
1182
|
const relative = url.searchParams.get("path") ?? "";
|
|
1147
|
-
|
|
1148
|
-
|
|
1183
|
+
if (!relative.trim()) {
|
|
1184
|
+
response.writeHead(400, { "content-type": "application/json" });
|
|
1185
|
+
response.end(JSON.stringify({ error: "path query parameter is required" }));
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
1188
|
+
// Read before writeHead so a missing/unreadable file cannot commit 200
|
|
1189
|
+
// and then a second 500 from the outer catch.
|
|
1190
|
+
try {
|
|
1191
|
+
const file = await readPanelProjectFile(root, relative);
|
|
1192
|
+
response.writeHead(200, { "content-type": "application/json" });
|
|
1193
|
+
response.end(JSON.stringify({ schemaVersion: "psyclaw/panel-project-file/v1", ...file }));
|
|
1194
|
+
}
|
|
1195
|
+
catch (error) {
|
|
1196
|
+
const { status, body } = panelProjectFileErrorPayload(error);
|
|
1197
|
+
response.writeHead(status, { "content-type": "application/json" });
|
|
1198
|
+
response.end(JSON.stringify(body));
|
|
1199
|
+
}
|
|
1149
1200
|
return;
|
|
1150
1201
|
}
|
|
1151
1202
|
if (url.pathname === "/api/config") {
|
|
@@ -2010,7 +2061,15 @@ export function createPanelServer(root, options = {}) {
|
|
|
2010
2061
|
const id = String(body.id ?? "").trim();
|
|
2011
2062
|
const preset = PROVIDER_PRESETS.find((candidate) => candidate.id === id);
|
|
2012
2063
|
const name = String(body.name ?? preset?.name ?? id).trim();
|
|
2013
|
-
|
|
2064
|
+
let baseUrl = "";
|
|
2065
|
+
try {
|
|
2066
|
+
baseUrl = resolveProviderBaseUrl(body.baseUrl, preset?.baseUrl ?? "");
|
|
2067
|
+
}
|
|
2068
|
+
catch (error) {
|
|
2069
|
+
response.writeHead(400, { "content-type": "application/json" });
|
|
2070
|
+
response.end(JSON.stringify({ error: error instanceof Error ? error.message : "Provider endpoint must use http or https" }));
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2014
2073
|
const api = body.api === "anthropic-messages" ? "anthropic-messages" : "openai-completions";
|
|
2015
2074
|
const apiKeyEnv = String(body.apiKeyEnv ?? preset?.apiKeyEnv ?? `PSYCLAW_${id.toUpperCase().replace(/[^A-Z0-9]/g, "_")}_API_KEY`).trim();
|
|
2016
2075
|
const modelId = String(body.modelId ?? "").trim();
|
|
@@ -2092,6 +2151,8 @@ export function createPanelServer(root, options = {}) {
|
|
|
2092
2151
|
response.end(JSON.stringify({ error: "not found" }));
|
|
2093
2152
|
}
|
|
2094
2153
|
catch {
|
|
2154
|
+
if (response.headersSent)
|
|
2155
|
+
return;
|
|
2095
2156
|
response.writeHead(500, { "content-type": "application/json" });
|
|
2096
2157
|
response.end(JSON.stringify({ error: "panel request failed", reasonCode: "panel.request-failed" }));
|
|
2097
2158
|
}
|