@pasko70/pibo 1.7.6 → 1.7.8
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/apps/chat/chat-user-skill-routes.js +51 -19
- package/dist/apps/chat/model-catalog.js +2 -0
- package/dist/apps/chat/web-app.js +2 -2
- package/dist/apps/chat-ui/assets/{dist-BhCflw5L.js → dist-BLQTYmgi.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-C2wdpulS.js → dist-BLYDOjGT.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-BUfawaFa.js → dist-Bg2k47fY.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-iblHo9vw.js → dist-Bv912fTl.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-NDLYTRqO.js → dist-CCOZbHCt.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-ChMCJ0Xh.js → dist-D6ImmtZ3.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-C5S2MWeq.js → dist-DDQWCHTh.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-XR2wwVeo.js → dist-DTJJ5-iA.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-COMZszUx.js → dist-Daom6uMW.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CqZsX_X9.js → dist-Dgs6LwMW.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CJOnkhP1.js → dist-LRUZKp77.js} +1 -1
- package/dist/apps/chat-ui/assets/index-BnZ0V5cJ.js +173 -0
- package/dist/apps/chat-ui/assets/index-DbRZGRDd.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/index-CiQZTRZH.js +41 -0
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/cli.js +12 -3
- package/dist/core/context-guard.js +126 -0
- package/dist/core/gateway-resource-guard.js +215 -0
- package/dist/core/routed-session.js +76 -1
- package/dist/core/runtime.js +40 -2
- package/dist/core/session-router.js +2 -0
- package/dist/debug/index.js +40 -0
- package/dist/gateway/web.js +2 -0
- package/dist/mcp/output.js +19 -4
- package/dist/plugins/chat-custom-agents.js +20 -0
- package/dist/plugins/registry.js +1 -0
- package/dist/providers/openai-gpt56.js +91 -0
- package/dist/ralph/cli.js +49 -5
- package/dist/ralph/service.js +5 -2
- package/dist/session-ui/terminalRows.js +59 -0
- package/dist/skills/cli.js +33 -23
- package/dist/tools/guides.js +17 -0
- package/dist/user-skills/manager.js +106 -8
- package/package.json +1 -1
- package/dist/apps/chat-ui/assets/index-BStUapSa.css +0 -1
- package/dist/apps/chat-ui/assets/index-BYqOi32B.js +0 -173
- package/dist/apps/chat-vscode-web/assets/index-B4Jk2P5o.js +0 -41
- package/dist/apps/vscode-artifacts/latest.vsix +0 -0
- package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.7.6.vsix +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeUserSkillScope, normalizeWritableUserSkillScope } from "../../user-skills/manager.js";
|
|
1
2
|
import { PiboWebHttpError, readJsonBody, responseJson } from "../../web/http.js";
|
|
2
3
|
import { CHAT_WEB_API_PREFIX, userSkillResourceId } from "./chat-api-routes.js";
|
|
3
4
|
import { normalizeUserSkillDescription, normalizeUserSkillEnabled, normalizeUserSkillMarkdown, normalizeUserSkillName, normalizeUserSkillUrl, } from "./chat-request-normalizers.js";
|
|
@@ -26,13 +27,19 @@ export function syncChatUserSkills(options) {
|
|
|
26
27
|
const unregisterSkill = channelContext.unregisterSkill;
|
|
27
28
|
if (!registerSkill || !unregisterSkill)
|
|
28
29
|
return;
|
|
29
|
-
const userSkills = userSkillManager.list();
|
|
30
|
+
const userSkills = userSkillManager.list("all");
|
|
30
31
|
const catalogSkills = channelContext.getCapabilityCatalog?.().skills ?? [];
|
|
31
32
|
const catalogSkillByName = new Map(catalogSkills.map((skill) => [skill.name, skill]));
|
|
32
33
|
const reservedSkillNames = new Set(catalogSkills.filter((skill) => skill.kind !== "user").map((skill) => skill.name));
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const enabledSkillByName = new Map();
|
|
35
|
+
for (const skill of userSkills) {
|
|
36
|
+
if (!skill.enabled || reservedSkillNames.has(skill.name))
|
|
37
|
+
continue;
|
|
38
|
+
const existing = enabledSkillByName.get(skill.name);
|
|
39
|
+
if (!existing || skill.scope === "workspace")
|
|
40
|
+
enabledSkillByName.set(skill.name, skill);
|
|
41
|
+
}
|
|
42
|
+
const enabledNames = new Set(enabledSkillByName.keys());
|
|
36
43
|
const syncedNames = previouslySyncedNames ?? new Set();
|
|
37
44
|
// Unregister disabled, removed, or now built-in user skills. Avoid removing a
|
|
38
45
|
// built-in/plugin skill if a promoted user skill has the same name.
|
|
@@ -43,10 +50,16 @@ export function syncChatUserSkills(options) {
|
|
|
43
50
|
unregisterSkill(name);
|
|
44
51
|
}
|
|
45
52
|
}
|
|
46
|
-
// Register
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
// Register the winning enabled skill per name. Workspace-local skills take
|
|
54
|
+
// precedence over global user skills with the same name; if the winning path
|
|
55
|
+
// changes, re-register the user skill so runtime context loads the right body.
|
|
56
|
+
for (const skill of enabledSkillByName.values()) {
|
|
57
|
+
const catalogSkill = catalogSkillByName.get(skill.name);
|
|
58
|
+
if (catalogSkill?.kind === "user" && catalogSkill.path !== skill.path) {
|
|
59
|
+
unregisterSkill(skill.name);
|
|
60
|
+
registerSkill({ name: skill.name, path: skill.path, enabled: true, kind: "user" });
|
|
61
|
+
}
|
|
62
|
+
else if (!syncedNames.has(skill.name)) {
|
|
50
63
|
registerSkill({ name: skill.name, path: skill.path, enabled: true, kind: "user" });
|
|
51
64
|
}
|
|
52
65
|
}
|
|
@@ -55,7 +68,7 @@ export function syncChatUserSkills(options) {
|
|
|
55
68
|
function assertUserSkillNameIsAvailable(options) {
|
|
56
69
|
const { userSkillManager, channelContext, name, currentSkillId } = options;
|
|
57
70
|
const currentSkill = currentSkillId ? userSkillManager.get(currentSkillId) : undefined;
|
|
58
|
-
const conflict = (channelContext.getCapabilityCatalog?.().skills ?? []).find((skill) => (skill.name === name && (!currentSkill || currentSkill.name !== name)));
|
|
71
|
+
const conflict = (channelContext.getCapabilityCatalog?.().skills ?? []).find((skill) => (skill.name === name && skill.kind !== "user" && (!currentSkill || currentSkill.name !== name)));
|
|
59
72
|
if (conflict) {
|
|
60
73
|
throw new PiboWebHttpError(`Skill name "${name}" conflicts with an existing registered skill`, 409);
|
|
61
74
|
}
|
|
@@ -69,45 +82,63 @@ function syncAndInvalidate(options) {
|
|
|
69
82
|
});
|
|
70
83
|
options.invalidateBootstrapCatalogCache();
|
|
71
84
|
}
|
|
85
|
+
function requestScope(request, fallback = "all") {
|
|
86
|
+
return normalizeUserSkillScope(new URL(request.url).searchParams.get("scope") ?? undefined, fallback);
|
|
87
|
+
}
|
|
88
|
+
function bodyScope(body, fallback = "global") {
|
|
89
|
+
if (body.scope !== undefined && typeof body.scope !== "string") {
|
|
90
|
+
throw new PiboWebHttpError("Skill scope must be a string", 400);
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
return normalizeWritableUserSkillScope(body.scope, fallback);
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
throw new PiboWebHttpError(error instanceof Error ? error.message : String(error), 400);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
72
99
|
export async function handleChatUserSkillRoute(options) {
|
|
73
100
|
const { route, request, userSkillManager, channelContext } = options;
|
|
74
101
|
switch (route.kind) {
|
|
75
102
|
case "user-skills-list":
|
|
76
|
-
return responseJson({ skills: userSkillManager.list() });
|
|
103
|
+
return responseJson({ skills: userSkillManager.list(requestScope(request)) });
|
|
77
104
|
case "user-skills-create": {
|
|
78
105
|
const body = await readJsonBody(request);
|
|
106
|
+
const scope = bodyScope(body);
|
|
79
107
|
const name = normalizeUserSkillName(body.name);
|
|
80
108
|
assertUserSkillNameIsAvailable({ userSkillManager, channelContext, name });
|
|
81
109
|
const skill = userSkillManager.create({
|
|
82
110
|
name,
|
|
83
111
|
description: normalizeUserSkillDescription(body.description ?? ""),
|
|
84
112
|
markdown: normalizeUserSkillMarkdown(body.markdown ?? ""),
|
|
85
|
-
});
|
|
113
|
+
}, scope);
|
|
86
114
|
syncAndInvalidate(options);
|
|
87
115
|
return responseJson({ skill }, { status: 201 });
|
|
88
116
|
}
|
|
89
117
|
case "user-skills-install": {
|
|
90
118
|
const body = await readJsonBody(request);
|
|
91
|
-
const
|
|
119
|
+
const scope = bodyScope(body);
|
|
120
|
+
const skill = await userSkillManager.installFromUrl(normalizeUserSkillUrl(body.url), scope);
|
|
92
121
|
try {
|
|
93
122
|
assertUserSkillNameIsAvailable({ userSkillManager, channelContext, name: skill.name, currentSkillId: skill.id });
|
|
94
123
|
}
|
|
95
124
|
catch (error) {
|
|
96
|
-
userSkillManager.remove(skill.id);
|
|
125
|
+
userSkillManager.remove(skill.id, scope);
|
|
97
126
|
throw error;
|
|
98
127
|
}
|
|
99
128
|
syncAndInvalidate(options);
|
|
100
129
|
return responseJson({ skill }, { status: 201 });
|
|
101
130
|
}
|
|
102
131
|
case "user-skill-read": {
|
|
103
|
-
const
|
|
132
|
+
const scope = requestScope(request);
|
|
133
|
+
const skill = userSkillManager.get(route.skillId, scope);
|
|
104
134
|
if (!skill)
|
|
105
135
|
throw new PiboWebHttpError("Skill not found", 404);
|
|
106
|
-
const markdown = userSkillManager.getSkillMarkdown(skill.id);
|
|
136
|
+
const markdown = userSkillManager.getSkillMarkdown(skill.id, scope);
|
|
107
137
|
return responseJson({ skill, markdown });
|
|
108
138
|
}
|
|
109
139
|
case "user-skill-update": {
|
|
110
|
-
const
|
|
140
|
+
const scope = requestScope(request);
|
|
141
|
+
const existing = userSkillManager.get(route.skillId, scope);
|
|
111
142
|
if (!existing)
|
|
112
143
|
throw new PiboWebHttpError("Skill not found", 404);
|
|
113
144
|
const body = await readJsonBody(request);
|
|
@@ -133,15 +164,16 @@ export async function handleChatUserSkillRoute(options) {
|
|
|
133
164
|
currentSkillId: existing.id,
|
|
134
165
|
});
|
|
135
166
|
}
|
|
136
|
-
const skill = userSkillManager.update(existing.id, input);
|
|
167
|
+
const skill = userSkillManager.update(existing.id, input, scope);
|
|
137
168
|
syncAndInvalidate(options);
|
|
138
169
|
return responseJson({ skill });
|
|
139
170
|
}
|
|
140
171
|
case "user-skill-delete": {
|
|
141
|
-
const
|
|
172
|
+
const scope = requestScope(request);
|
|
173
|
+
const existing = userSkillManager.get(route.skillId, scope);
|
|
142
174
|
if (!existing)
|
|
143
175
|
throw new PiboWebHttpError("Skill not found", 404);
|
|
144
|
-
userSkillManager.remove(existing.id);
|
|
176
|
+
userSkillManager.remove(existing.id, scope);
|
|
145
177
|
syncAndInvalidate(options);
|
|
146
178
|
return responseJson({ removedSkillId: existing.id });
|
|
147
179
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createAgentSessionServices } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { registerMiniMaxProvider } from "../../providers/minimax.js";
|
|
3
3
|
import { registerGlmProvider } from "../../providers/glm.js";
|
|
4
|
+
import { registerOpenAiGpt56Models } from "../../providers/openai-gpt56.js";
|
|
4
5
|
export function buildModelCatalogFromRegistry(registry) {
|
|
5
6
|
const providers = new Map();
|
|
6
7
|
for (const model of registry.getAll()) {
|
|
@@ -45,6 +46,7 @@ export async function loadModelCatalogWithServices(createServices, cwd = process
|
|
|
45
46
|
}
|
|
46
47
|
export async function loadModelCatalog(cwd = process.cwd()) {
|
|
47
48
|
return loadModelCatalogWithServices(createAgentSessionServices, cwd, (registry) => {
|
|
49
|
+
registerOpenAiGpt56Models(registry);
|
|
48
50
|
registerMiniMaxProvider(registry);
|
|
49
51
|
registerGlmProvider(registry);
|
|
50
52
|
});
|
|
@@ -22,7 +22,7 @@ import { createDefaultPiboReliabilityStore, PiboReliabilityStore } from "../../r
|
|
|
22
22
|
import { listMcpServerInfos } from "../../mcp/agent-context.js";
|
|
23
23
|
import { getDefaultPiboWorkspace } from "../../core/workspace.js";
|
|
24
24
|
import { findPiPackage, listPiPackages } from "../../pi-packages/store.js";
|
|
25
|
-
import {
|
|
25
|
+
import { ScopedUserSkillManager } from "../../user-skills/manager.js";
|
|
26
26
|
import { ChatDataIngestService } from "../../data/ingest-service.js";
|
|
27
27
|
import { ChatEventCommandService } from "./data/event-command-service.js";
|
|
28
28
|
import { ChatReadStateService } from "./data/read-state-service.js";
|
|
@@ -3029,7 +3029,7 @@ export function createChatWebApp(options = {}) {
|
|
|
3029
3029
|
persistenceMetrics: createPersistenceMetrics(),
|
|
3030
3030
|
resourceMetrics: createResourceMetrics(),
|
|
3031
3031
|
eventLoopDelay,
|
|
3032
|
-
userSkillManager: new
|
|
3032
|
+
userSkillManager: new ScopedUserSkillManager({ globalRoot: os.homedir(), workspaceRoot: process.cwd() }),
|
|
3033
3033
|
workflowDraftStore: new ChatWorkflowDraftStore(dataStore),
|
|
3034
3034
|
workflowPublishedVersionStore: new ChatWorkflowPublishedVersionStore(dataStore),
|
|
3035
3035
|
workflowArchiveStore: new ChatWorkflowArchiveStore(dataStore),
|