@agimon-ai/po-help 0.0.0-alpha.105 → 0.0.0-alpha.107
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/extensions/server.cjs +185 -3
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +185 -3
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +568 -321
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +35 -9
- package/src/prompts/codemode-how-to-brain/SKILL.md +26 -7
- package/src/prompts/codemode-how-to-self-improve/SKILL.md +2 -0
|
@@ -63,6 +63,145 @@ var root_server_default$1 = (0, _agimon_ai_po_core_extensionFile.defineRoot)((co
|
|
|
63
63
|
services: context.host.scope === "workspace" ? [brainSimulationProvider] : []
|
|
64
64
|
}));
|
|
65
65
|
//#endregion
|
|
66
|
+
//#region src/types/brainGraph.ts
|
|
67
|
+
const BRAIN_GRAPH_KINDS = [
|
|
68
|
+
"backend",
|
|
69
|
+
"web",
|
|
70
|
+
"native"
|
|
71
|
+
];
|
|
72
|
+
const CODEMODE_SERVICE = "po/codemode";
|
|
73
|
+
const PLUMBING_SERVICES = /* @__PURE__ */ new Set([
|
|
74
|
+
"po/server-scope",
|
|
75
|
+
"po/server-host",
|
|
76
|
+
"po/headless-host",
|
|
77
|
+
"po/global-services"
|
|
78
|
+
]);
|
|
79
|
+
function graphOf(nodes, links) {
|
|
80
|
+
const linked = new Set([...links.values()].flatMap((link) => [link.source, link.target]));
|
|
81
|
+
return {
|
|
82
|
+
nodes: [...nodes.values()].filter((node) => linked.has(node.id)).sort((a, b) => a.id.localeCompare(b.id)),
|
|
83
|
+
links: [...links.values()].sort((a, b) => `${a.source}\0${a.target}`.localeCompare(`${b.source}\0${b.target}`))
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Public services, services a code-mode contributor can call (every service a plugin that injects
|
|
88
|
+
* po/codemode resolves), and the plugins that consume them. Nodes collapse by name across scopes.
|
|
89
|
+
* A nested fiber is an intermediary, so its injections fold into the plugin that owns it; unowned
|
|
90
|
+
* fibers, unresolved injections and scope plumbing are left out.
|
|
91
|
+
*/
|
|
92
|
+
function backendGraph(snapshot) {
|
|
93
|
+
const plugins = new Map(snapshot.consumers.flatMap((consumer) => consumer.owner.kind === "package" && consumer.owner.packageName ? [[consumer.id, {
|
|
94
|
+
name: consumer.owner.packageName,
|
|
95
|
+
origin: consumer.owner.origin
|
|
96
|
+
}]] : []));
|
|
97
|
+
const services = new Map(snapshot.services.map((service) => [service.id, service]));
|
|
98
|
+
const uses = snapshot.edges.flatMap((edge) => {
|
|
99
|
+
const plugin = plugins.get(edge.consumer);
|
|
100
|
+
const service = edge.service === null ? void 0 : services.get(edge.service);
|
|
101
|
+
return plugin && service && !PLUMBING_SERVICES.has(service.name) ? [{
|
|
102
|
+
plugin,
|
|
103
|
+
service
|
|
104
|
+
}] : [];
|
|
105
|
+
});
|
|
106
|
+
const contributors = new Set(uses.filter((use) => use.service.name === CODEMODE_SERVICE).map((use) => use.plugin.name));
|
|
107
|
+
const reachable = new Set(uses.filter((use) => contributors.has(use.plugin.name)).map((use) => use.service.name));
|
|
108
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
109
|
+
const links = /* @__PURE__ */ new Map();
|
|
110
|
+
for (const { plugin, service } of uses) {
|
|
111
|
+
if (!service.public && !reachable.has(service.name)) continue;
|
|
112
|
+
const serviceId = `service:${service.name}`;
|
|
113
|
+
const previous = nodes.get(serviceId);
|
|
114
|
+
if (!previous || service.description && previous.detail.endsWith("No description.")) nodes.set(serviceId, {
|
|
115
|
+
id: serviceId,
|
|
116
|
+
label: service.name,
|
|
117
|
+
role: reachable.has(service.name) ? "codemode" : "public",
|
|
118
|
+
detail: `${service.public ? "Public" : "Private"} service${reachable.has(service.name) ? ", callable from code mode" : ""}. Provided by ${service.owner.packageName ?? service.owner.kind}. ${service.description ?? "No description."}`
|
|
119
|
+
});
|
|
120
|
+
const pluginId = `plugin:${plugin.name}`;
|
|
121
|
+
nodes.set(pluginId, {
|
|
122
|
+
id: pluginId,
|
|
123
|
+
label: plugin.name,
|
|
124
|
+
role: plugin.origin === "personal" ? "personal" : "plugin",
|
|
125
|
+
detail: `Plugin${contributors.has(plugin.name) ? " that contributes to code mode" : ""}.`
|
|
126
|
+
});
|
|
127
|
+
links.set(`${pluginId}\0${serviceId}`, {
|
|
128
|
+
source: pluginId,
|
|
129
|
+
target: serviceId,
|
|
130
|
+
label: "consumes"
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return graphOf(nodes, links);
|
|
134
|
+
}
|
|
135
|
+
/** Each plugin and the slots it fills or declares, for one client host. */
|
|
136
|
+
function clientGraph(packages, target, hostSlots = {}) {
|
|
137
|
+
const hostDescriptions = new Map(Object.values(hostSlots).map((slot) => [slot.slot, slot.description]));
|
|
138
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
139
|
+
const links = /* @__PURE__ */ new Map();
|
|
140
|
+
const slot = (name, description) => {
|
|
141
|
+
const id = `slot:${name}`;
|
|
142
|
+
if (!nodes.has(id) || description) nodes.set(id, {
|
|
143
|
+
id,
|
|
144
|
+
label: name,
|
|
145
|
+
role: "slot",
|
|
146
|
+
detail: `Slot. ${description ?? hostDescriptions.get(name) ?? "No description."}`
|
|
147
|
+
});
|
|
148
|
+
return id;
|
|
149
|
+
};
|
|
150
|
+
for (const pkg of packages) {
|
|
151
|
+
const metadata = target === "web" ? pkg.web : pkg.native;
|
|
152
|
+
if (!metadata || !pkg.owner.packageName) continue;
|
|
153
|
+
const pluginId = `plugin:${pkg.owner.packageName}`;
|
|
154
|
+
nodes.set(pluginId, {
|
|
155
|
+
id: pluginId,
|
|
156
|
+
label: pkg.owner.packageName,
|
|
157
|
+
role: pkg.owner.origin === "personal" ? "personal" : "plugin",
|
|
158
|
+
detail: `Plugin with a ${target} half.`
|
|
159
|
+
});
|
|
160
|
+
for (const declared of metadata.slots) {
|
|
161
|
+
const slotId = slot(declared.name, declared.description);
|
|
162
|
+
links.set(`${pluginId}\0${slotId}`, {
|
|
163
|
+
source: pluginId,
|
|
164
|
+
target: slotId,
|
|
165
|
+
label: "declares"
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
for (const fill of metadata.fills) {
|
|
169
|
+
if (fill.slot === null) continue;
|
|
170
|
+
const slotId = slot(fill.slot);
|
|
171
|
+
links.set(`${pluginId}\0${slotId}`, {
|
|
172
|
+
source: pluginId,
|
|
173
|
+
target: slotId,
|
|
174
|
+
label: "fills"
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return graphOf(nodes, links);
|
|
179
|
+
}
|
|
180
|
+
/** One essential graph. Web prefers the exact browser mount inventory; native reads installed packages. */
|
|
181
|
+
function brainGraph(snapshot, kind, hostSlots) {
|
|
182
|
+
if (kind === "backend") return backendGraph(snapshot);
|
|
183
|
+
return clientGraph(kind === "web" ? snapshot.clientPackages ?? snapshot.packages : snapshot.packages, kind, hostSlots);
|
|
184
|
+
}
|
|
185
|
+
/** A node and its direct connections in one graph, or undefined when the graph lacks it. */
|
|
186
|
+
function brainNodeView(graph, kind, id) {
|
|
187
|
+
const byId = new Map(graph.nodes.map((node) => [node.id, node]));
|
|
188
|
+
const node = byId.get(id);
|
|
189
|
+
if (!node) return void 0;
|
|
190
|
+
return {
|
|
191
|
+
kind,
|
|
192
|
+
node,
|
|
193
|
+
links: graph.links.flatMap((link) => link.source === id ? [{
|
|
194
|
+
label: link.label,
|
|
195
|
+
direction: "out",
|
|
196
|
+
node: byId.get(link.target)
|
|
197
|
+
}] : link.target === id ? [{
|
|
198
|
+
label: link.label,
|
|
199
|
+
direction: "in",
|
|
200
|
+
node: byId.get(link.source)
|
|
201
|
+
}] : [])
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
//#endregion
|
|
66
205
|
//#region src/services/brain/index.ts
|
|
67
206
|
function createBrain(options) {
|
|
68
207
|
const services = (signal) => {
|
|
@@ -154,14 +293,39 @@ function createBrain(options) {
|
|
|
154
293
|
const DECLARATIONS$1 = `type Scope = { id: string; level: 'global' | 'workspace' | 'session' };
|
|
155
294
|
type Owner = { kind: 'host' | 'package' | 'unknown'; packageName: string | null; origin: 'po' | 'personal' | 'unknown' };
|
|
156
295
|
interface WebMetadata { version: 1; slots: { name: string; scope: Scope['level']; description?: string; parent?: string; kind: 'data' | 'component' }[]; fills: { id: string; slot: string | null; scope: Scope['level']; placement: 'verified' | 'unverified' }[]; diagnostics: string[] }
|
|
157
|
-
interface PackageMetadata { scope: Scope; owner: Owner; web: WebMetadata | null }
|
|
296
|
+
interface PackageMetadata { scope: Scope; owner: Owner; web: WebMetadata | null; native?: WebMetadata | null }
|
|
158
297
|
interface ServicesSnapshot { scope: Scope; scopes: Scope[]; packages: PackageMetadata[]; clientPackages?: PackageMetadata[]; services: { id: string; name: string; scope: Scope; visibleFrom: Scope; owner: Owner; public: boolean; description: string | null }[]; consumers: { id: string; name: string; scope: Scope; owner: Owner }[]; edges: { consumer: string; service: string | null; name: string; status: 'resolved' | 'waiting' }[]; diagnostics: string[] }
|
|
159
298
|
interface SlotsSnapshot { scope: Scope; scopes: Scope[]; slots: { id: string; name: string; scope: Scope; owner: Owner; description: string | null; parent: string | null; kind: 'data' | 'component' }[]; fills: { id: string; slot: string | null; scope: Scope; owner: Owner; placement: 'verified' | 'unverified' }[]; diagnostics: string[] }
|
|
160
|
-
|
|
299
|
+
type GraphKind = 'backend' | 'web' | 'native';
|
|
300
|
+
type Role = 'public' | 'codemode' | 'plugin' | 'personal' | 'slot';
|
|
301
|
+
interface GraphNode { id: string; label: string; role: Role; detail: string }
|
|
302
|
+
/** backend: plugin -consumes-> service. web/native: plugin -fills|declares-> slot. */
|
|
303
|
+
interface Graph { kind: GraphKind; nodes: GraphNode[]; links: { source: string; target: string; label: string }[] }
|
|
304
|
+
interface NodeView { kind: GraphKind; node: GraphNode; links: { label: string; direction: 'out' | 'in'; node: GraphNode }[] }
|
|
305
|
+
declare const brain: {
|
|
306
|
+
/** The essential map the Brain page draws. Ids look like 'plugin:@scope/name', 'service:po/fs', 'slot:page'. */
|
|
307
|
+
graph(input?: { kind?: GraphKind }): Promise<Graph>;
|
|
308
|
+
/** One node and its direct links in every graph that has it, or only in kind. Empty when absent. */
|
|
309
|
+
node(input: { id: string; kind?: GraphKind }): Promise<NodeView[]>;
|
|
310
|
+
/** Raw snapshot with fibers, private services, waiting injections and diagnostics. */
|
|
311
|
+
services(): Promise<ServicesSnapshot>;
|
|
312
|
+
/** Raw web slot declarations, parent links and fill placements. */
|
|
313
|
+
slots(): Promise<SlotsSnapshot>;
|
|
314
|
+
};`;
|
|
315
|
+
function graphKind(value) {
|
|
316
|
+
if (value === void 0) return "backend";
|
|
317
|
+
if (BRAIN_GRAPH_KINDS.includes(value)) return value;
|
|
318
|
+
throw new Error(`kind must be one of ${BRAIN_GRAPH_KINDS.join(", ")}.`);
|
|
319
|
+
}
|
|
320
|
+
function input(value) {
|
|
321
|
+
if (value === void 0) return {};
|
|
322
|
+
if (value !== null && typeof value === "object" && !Array.isArray(value)) return value;
|
|
323
|
+
throw new Error("Expected an options object.");
|
|
324
|
+
}
|
|
161
325
|
function createBrainNamespace(options) {
|
|
162
326
|
return {
|
|
163
327
|
name: "brain",
|
|
164
|
-
summary: "
|
|
328
|
+
summary: "Explore the essential service and slot graphs (backend, web, native) and raw service and slot snapshots. Read-only, Help mode.",
|
|
165
329
|
declarations: DECLARATIONS$1,
|
|
166
330
|
bind(run) {
|
|
167
331
|
if (run.sessionId !== options.sessionId) throw new Error("The brain namespace belongs to another session.");
|
|
@@ -170,6 +334,24 @@ function createBrainNamespace(options) {
|
|
|
170
334
|
options.assertActive();
|
|
171
335
|
};
|
|
172
336
|
return {
|
|
337
|
+
graph: async (options_) => {
|
|
338
|
+
check();
|
|
339
|
+
const kind = graphKind(input(options_).kind);
|
|
340
|
+
return {
|
|
341
|
+
kind,
|
|
342
|
+
...brainGraph(options.service.services(run.signal), kind, _agimon_ai_po_core_serverPlugin.HOST_SLOT_METADATA)
|
|
343
|
+
};
|
|
344
|
+
},
|
|
345
|
+
node: async (options_) => {
|
|
346
|
+
check();
|
|
347
|
+
const { id, kind } = input(options_);
|
|
348
|
+
if (typeof id !== "string" || !id.trim() || id.length > 1024) throw new Error("id must be a node id string.");
|
|
349
|
+
const snapshot = options.service.services(run.signal);
|
|
350
|
+
return (kind === void 0 ? BRAIN_GRAPH_KINDS : [graphKind(kind)]).flatMap((each) => {
|
|
351
|
+
const view = brainNodeView(brainGraph(snapshot, each, _agimon_ai_po_core_serverPlugin.HOST_SLOT_METADATA), each, id);
|
|
352
|
+
return view ? [view] : [];
|
|
353
|
+
});
|
|
354
|
+
},
|
|
173
355
|
services: async () => {
|
|
174
356
|
check();
|
|
175
357
|
return options.service.services(run.signal);
|