@agimon-ai/po-codemode 0.0.1-alpha.1 → 0.0.1-alpha.3
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 +3 -3
- package/dist/{codemodeTools-CSYUxIeA.mjs → codemodeTools-BdwOARH8.mjs} +55 -10
- package/dist/codemodeTools-BdwOARH8.mjs.map +1 -0
- package/dist/{codemodeTools-BX2qieCR.cjs → codemodeTools-CLgSDqfU.cjs} +55 -10
- package/dist/codemodeTools-CLgSDqfU.cjs.map +1 -0
- package/dist/extensions/server.cjs +8 -9
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +8 -9
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +295 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/llms.txt +1 -1
- package/package.json +22 -5
- package/src/prompts/{po-use-codemode → how-to-codemode}/SKILL.md +3 -1
- package/dist/codemodeTools-BX2qieCR.cjs.map +0 -1
- package/dist/codemodeTools-CSYUxIeA.mjs.map +0 -1
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { n as createCodemodeRegistry, t as createCodemodeTools } from "../codemodeTools-
|
|
1
|
+
import { n as createCodemodeRegistry, t as createCodemodeTools } from "../codemodeTools-BdwOARH8.mjs";
|
|
2
2
|
import { PO_CODEMODE_CONTRACT, PO_CODEMODE_SERVICE } from "@agimon-ai/po-core/codemode";
|
|
3
3
|
import { PO_SERVER_SCOPE_SERVICE, composeServerProviderOverrides, defineServerPlugin, packageResourcePath, readPackageResource, requirePoServerScope } from "@agimon-ai/po-core/serverPlugin";
|
|
4
4
|
import { composeRootHooks, composeRootInjects, defineResource, defineRoot, defineServerTool, defineServiceContract } from "@agimon-ai/po-core/extensionFile";
|
|
5
5
|
import { BACKGROUND_CONTEXT, PO_SESSION_FILES_SERVICE, getOrThrow, readPoFs, readPoIsolate } from "@agimon-ai/po-core/platform";
|
|
6
|
-
import { PO_HELP_WHEN } from "@agimon-ai/po-core/help";
|
|
7
6
|
//#region src/services/codemodeScripts/index.ts
|
|
8
7
|
const SESSION_FOLDER = "codemode";
|
|
9
8
|
const SESSION_PREFIX = "session:";
|
|
@@ -147,14 +146,14 @@ var root_server_default = defineRoot(root);
|
|
|
147
146
|
//#region src/extensions/workspaces/sessions/(backend)/contract/codemode.server.ts
|
|
148
147
|
var codemode_server_default = defineServiceContract(PO_CODEMODE_SERVICE, { scope: "session" });
|
|
149
148
|
//#endregion
|
|
150
|
-
//#region src/extensions/workspaces/sessions/(backend)/resource/
|
|
151
|
-
var
|
|
152
|
-
name: "
|
|
149
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/how-to-codemode.server.ts
|
|
150
|
+
var how_to_codemode_server_default = defineResource({
|
|
151
|
+
name: "how-to-codemode",
|
|
153
152
|
description: "Use @agimon-ai/po-codemode: Code mode for Po sessions: discover and exec over namespaces other packages contribute",
|
|
154
|
-
|
|
153
|
+
pinned: true,
|
|
155
154
|
kind: "skill",
|
|
156
|
-
path: packageResourcePath(import.meta.url, "src/prompts/
|
|
157
|
-
read: () => readPackageResource(import.meta.url, "src/prompts/
|
|
155
|
+
path: packageResourcePath(import.meta.url, "src/prompts/how-to-codemode/SKILL.md"),
|
|
156
|
+
read: () => readPackageResource(import.meta.url, "src/prompts/how-to-codemode/SKILL.md")
|
|
158
157
|
});
|
|
159
158
|
//#endregion
|
|
160
159
|
//#region src/extensions/workspaces/sessions/(backend)/tool/discover.server.ts
|
|
@@ -183,7 +182,7 @@ const serverPlugin = defineServerPlugin({
|
|
|
183
182
|
return {
|
|
184
183
|
...composeRootHooks(scopeSession),
|
|
185
184
|
get resources() {
|
|
186
|
-
return [at(
|
|
185
|
+
return [at(how_to_codemode_server_default, contextSession)];
|
|
187
186
|
},
|
|
188
187
|
get tools() {
|
|
189
188
|
return [via({ name: "discover" }, at(discover_server_default, contextSession)), via({ name: "exec" }, at(exec_server_default, contextSession))];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.mjs","names":["contribution","rootSession","contractCodemode","resourcePoUseCodemode","toolDiscover","toolExec"],"sources":["../../src/services/codemodeScripts/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/contract/codemode.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-use-codemode.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/discover.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/exec.server.ts","../../generated/server.ts"],"sourcesContent":["import type { PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport { BACKGROUND_CONTEXT, getOrThrow, type FileSystem } from '@agimon-ai/po-core/platform';\n\nimport type { CodemodeScriptEntry, CodemodeScriptsPort } from './type';\n\nconst SESSION_FOLDER = 'codemode';\nconst SESSION_PREFIX = 'session:';\nconst EXTENSION = '.ts';\nconst EXEC_FILE = /^exec-(\\d+)\\.ts$/u;\nconst DOC_COMMENT = /^\\s*\\/\\*\\*([\\s\\S]*?)\\*\\//u;\nconst MAX_DESCRIPTION_CHARS = 160;\nconst DEFAULT_LIST_LIMIT = 200;\n\nexport interface CodemodeScriptsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so services bound after the root still work. */\n readonly fs: () => FileSystem | undefined;\n /** The session's `po/session-files` temporary directory. */\n readonly temporaryDirectory: () => string | undefined;\n}\n\nconst withExtension = (name: string): string => (name.endsWith(EXTENSION) ? name : `${name}${EXTENSION}`);\n\n/** First paragraph of a leading `/** ... *\\/` comment, else the first line of code, on one line. */\nexport function describeScript(source: string): string {\n const doc = DOC_COMMENT.exec(source)?.[1];\n const lines = doc === undefined ? source.split('\\n') : doc.split('\\n').map((line) => line.replace(/^\\s*\\*\\s?/u, ''));\n const paragraph: string[] = [];\n for (const line of lines.map((item) => item.trim())) {\n if (line) paragraph.push(line);\n else if (paragraph.length > 0) break;\n if (doc === undefined && paragraph.length > 0) break;\n }\n const text = paragraph.join(' ');\n return text.length <= MAX_DESCRIPTION_CHARS ? text : `${text.slice(0, MAX_DESCRIPTION_CHARS - 3)}...`;\n}\n\n/** Session scripts live in `<temporaryDirectory>/codemode`; domain scripts in registered folders. */\nexport class FileSystemCodemodeScriptsService implements CodemodeScriptsPort {\n constructor(private readonly options: CodemodeScriptsOptions) {}\n\n private sessionDirectory(): string | undefined {\n const base = this.options.temporaryDirectory();\n return base === undefined ? undefined : `${base}/${SESSION_FOLDER}`;\n }\n\n private requireFs(): FileSystem {\n const fs = this.options.fs();\n if (!fs) throw new Error('Saved scripts need a file system, which this host does not provide.');\n return fs;\n }\n\n private sources(domains?: readonly string[]) {\n return this.options.registry.listScripts().filter((source) => !domains || domains.includes(source.domain));\n }\n\n /** `.ts` file names in a folder; a missing folder has none. */\n private async names(fs: FileSystem, directory: string): Promise<string[]> {\n const listed = await fs.listDir(directory, BACKGROUND_CONTEXT);\n if (!listed.ok && listed.error.code === 'not_found') return [];\n return getOrThrow(listed)\n .filter((info) => info.kind === 'file' && info.name.endsWith(EXTENSION))\n .map((info) => info.name)\n .sort((left, right) => left.localeCompare(right, undefined, { numeric: true }));\n }\n\n async save(code: string) {\n const fs = this.options.fs();\n const directory = this.sessionDirectory();\n if (!fs || directory === undefined) return undefined;\n getOrThrow(await fs.createDir(directory, { recursive: true }, BACKGROUND_CONTEXT));\n const taken = (await this.names(fs, directory)).map((name) => Number(EXEC_FILE.exec(name)?.[1] ?? 0));\n const name = `exec-${Math.max(0, ...taken) + 1}`;\n const path = `${directory}/${name}${EXTENSION}`;\n getOrThrow(await fs.writeFile(path, code, BACKGROUND_CONTEXT));\n return { specifier: `${SESSION_PREFIX}${name}`, path };\n }\n\n private candidates(specifier: string, domains?: readonly string[]): string[] {\n if (specifier.startsWith('/')) return [specifier];\n const session = this.sessionDirectory();\n if (specifier.startsWith(SESSION_PREFIX)) {\n return session === undefined ? [] : [`${session}/${withExtension(specifier.slice(SESSION_PREFIX.length))}`];\n }\n const slash = specifier.indexOf('/');\n const domain = slash > 0 ? specifier.slice(0, slash) : undefined;\n const folders = this.sources(domains).filter((source) => source.domain === domain);\n if (folders.length > 0) {\n return folders.map((source) => `${source.directory}/${withExtension(specifier.slice(slash + 1))}`);\n }\n if (session !== undefined && (specifier.startsWith('.') || specifier.endsWith(EXTENSION))) {\n return [`${session}/${withExtension(specifier.replace(/^\\.\\//u, ''))}`];\n }\n return [];\n }\n\n async resolve(specifier: string, domains?: readonly string[]) {\n const fs = this.requireFs();\n for (const path of this.candidates(specifier, domains)) {\n const read = await fs.readTextFile(path, BACKGROUND_CONTEXT);\n if (read.ok) return { id: path, source: read.value };\n if (read.error.code !== 'not_found') getOrThrow(read);\n }\n const available = (await this.list(domains)).map((entry) => entry.specifier).join(', ') || 'none';\n throw new Error(`Unknown script \"${specifier}\". Available: ${available}.`);\n }\n\n async list(domains?: readonly string[], limit = DEFAULT_LIST_LIMIT): Promise<CodemodeScriptEntry[]> {\n const fs = this.options.fs();\n if (!fs) return [];\n const found: { specifier: string; path: string }[] = [];\n for (const source of this.sources(domains)) {\n for (const name of await this.names(fs, source.directory)) {\n found.push({\n specifier: `${source.domain}/${name.slice(0, -EXTENSION.length)}`,\n path: `${source.directory}/${name}`,\n });\n }\n }\n const session = this.sessionDirectory();\n if (session !== undefined) {\n for (const name of (await this.names(fs, session)).reverse()) {\n found.push({ specifier: `${SESSION_PREFIX}${name.slice(0, -EXTENSION.length)}`, path: `${session}/${name}` });\n }\n }\n const entries: CodemodeScriptEntry[] = [];\n for (const entry of found.slice(0, limit)) {\n const read = await fs.readTextFile(entry.path, BACKGROUND_CONTEXT);\n entries.push({ ...entry, description: read.ok ? describeScript(read.value) : '' });\n }\n return entries;\n }\n}\n","import { PO_CODEMODE_CONTRACT } from '@agimon-ai/po-core/codemode';\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { PO_SESSION_FILES_SERVICE, readPoFs, readPoIsolate } from '@agimon-ai/po-core/platform';\nimport {\n PO_SERVER_SCOPE_SERVICE,\n requirePoServerScope,\n type PoServerPluginContext,\n} from '@agimon-ai/po-core/serverPlugin';\n\nimport { createCodemodeRegistry } from '../../../../../services/codemodeRegistry';\nimport { FileSystemCodemodeScriptsService } from '../../../../../services/codemodeScripts';\nimport { createCodemodeTools } from '../../../../../services/codemodeTools';\n\n/** One registry per session: contributors register into it, `discover` and `exec` read it. */\nexport function createCodemodeSession({ context }: PoServerPluginContext) {\n const registry = createCodemodeRegistry();\n // The binding unwinds with this injected fiber, so the root needs no withdraw of its own.\n context.inject([PO_SERVER_SCOPE_SERVICE], (scoped) =>\n requirePoServerScope(scoped).provide(PO_CODEMODE_CONTRACT, registry),\n );\n let temporaryDirectory: string | undefined;\n context.inject([PO_SESSION_FILES_SERVICE], (scoped) => {\n temporaryDirectory = scoped.get(PO_SESSION_FILES_SERVICE)?.temporaryDirectory;\n return () => {\n temporaryDirectory = undefined;\n };\n });\n const scripts = new FileSystemCodemodeScriptsService({\n registry,\n fs: () => readPoFs(context),\n temporaryDirectory: () => temporaryDirectory,\n });\n const tools = createCodemodeTools({ registry, isolate: () => readPoIsolate(context), scripts });\n return { value: { registry, ...tools } };\n}\n\nconst root = defineRoot(createCodemodeSession);\nexport type CodemodeServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import { PO_CODEMODE_SERVICE, type PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport { defineServiceContract } from '@agimon-ai/po-core/extensionFile';\n\nexport default defineServiceContract<PoCodemodeService>(PO_CODEMODE_SERVICE, { scope: 'session' });\n","// @scaffold-generated\nimport { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { PO_HELP_WHEN } from '@agimon-ai/po-core/help';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineResource({\n name: 'po-use-codemode',\n description:\n 'Use @agimon-ai/po-codemode: Code mode for Po sessions: discover and exec over namespaces other packages contribute',\n when: PO_HELP_WHEN,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/po-use-codemode/SKILL.md'),\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-codemode/SKILL.md'),\n});\n","import { defineServerTool, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { CodemodeServerScope } from '../_lib/root.server';\n\nexport default defineServerTool(\n (context: WithRoot<PoServerPluginContext, CodemodeServerScope>) => context.root.discover,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { CodemodeServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<PoServerPluginContext, CodemodeServerScope>) => context.root.exec);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport contractCodemode from '../src/extensions/workspaces/sessions/(backend)/contract/codemode.server';\nimport resourcePoUseCodemode from '../src/extensions/workspaces/sessions/(backend)/resource/po-use-codemode.server';\nimport toolDiscover from '../src/extensions/workspaces/sessions/(backend)/tool/discover.server';\nimport toolExec from '../src/extensions/workspaces/sessions/(backend)/tool/exec.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-codemode',\n providerOverrides: composeServerProviderOverrides(rootSession),\n provides: {\n session: [contractCodemode],\n },\n injects: composeRootInjects({ session: [rootSession] }),\n session: async (context) => {\n const scopeSession = await context.scopeRoot('session', rootSession, context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get resources(): PoServerSessionPlugin['resources'] { return [at(resourcePoUseCodemode, contextSession)]; },\n get tools(): PoServerSessionPlugin['tools'] { return [via({ name: 'discover' }, at(toolDiscover, contextSession)), via({ name: 'exec' }, at(toolExec, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["contribution","rootSession","contractCodemode","resourceHowToCodemode","toolDiscover","toolExec"],"sources":["../../src/services/codemodeScripts/index.ts","../../src/extensions/workspaces/sessions/(backend)/_lib/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/root.server.ts","../../src/extensions/workspaces/sessions/(backend)/contract/codemode.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/how-to-codemode.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/discover.server.ts","../../src/extensions/workspaces/sessions/(backend)/tool/exec.server.ts","../../generated/server.ts"],"sourcesContent":["import type { PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport { BACKGROUND_CONTEXT, getOrThrow, type FileSystem } from '@agimon-ai/po-core/platform';\n\nimport type { CodemodeScriptEntry, CodemodeScriptsPort } from './type';\n\nconst SESSION_FOLDER = 'codemode';\nconst SESSION_PREFIX = 'session:';\nconst EXTENSION = '.ts';\nconst EXEC_FILE = /^exec-(\\d+)\\.ts$/u;\nconst DOC_COMMENT = /^\\s*\\/\\*\\*([\\s\\S]*?)\\*\\//u;\nconst MAX_DESCRIPTION_CHARS = 160;\nconst DEFAULT_LIST_LIMIT = 200;\n\nexport interface CodemodeScriptsOptions {\n readonly registry: PoCodemodeService;\n /** Resolved per call, so services bound after the root still work. */\n readonly fs: () => FileSystem | undefined;\n /** The session's `po/session-files` temporary directory. */\n readonly temporaryDirectory: () => string | undefined;\n}\n\nconst withExtension = (name: string): string => (name.endsWith(EXTENSION) ? name : `${name}${EXTENSION}`);\n\n/** First paragraph of a leading `/** ... *\\/` comment, else the first line of code, on one line. */\nexport function describeScript(source: string): string {\n const doc = DOC_COMMENT.exec(source)?.[1];\n const lines = doc === undefined ? source.split('\\n') : doc.split('\\n').map((line) => line.replace(/^\\s*\\*\\s?/u, ''));\n const paragraph: string[] = [];\n for (const line of lines.map((item) => item.trim())) {\n if (line) paragraph.push(line);\n else if (paragraph.length > 0) break;\n if (doc === undefined && paragraph.length > 0) break;\n }\n const text = paragraph.join(' ');\n return text.length <= MAX_DESCRIPTION_CHARS ? text : `${text.slice(0, MAX_DESCRIPTION_CHARS - 3)}...`;\n}\n\n/** Session scripts live in `<temporaryDirectory>/codemode`; domain scripts in registered folders. */\nexport class FileSystemCodemodeScriptsService implements CodemodeScriptsPort {\n constructor(private readonly options: CodemodeScriptsOptions) {}\n\n private sessionDirectory(): string | undefined {\n const base = this.options.temporaryDirectory();\n return base === undefined ? undefined : `${base}/${SESSION_FOLDER}`;\n }\n\n private requireFs(): FileSystem {\n const fs = this.options.fs();\n if (!fs) throw new Error('Saved scripts need a file system, which this host does not provide.');\n return fs;\n }\n\n private sources(domains?: readonly string[]) {\n return this.options.registry.listScripts().filter((source) => !domains || domains.includes(source.domain));\n }\n\n /** `.ts` file names in a folder; a missing folder has none. */\n private async names(fs: FileSystem, directory: string): Promise<string[]> {\n const listed = await fs.listDir(directory, BACKGROUND_CONTEXT);\n if (!listed.ok && listed.error.code === 'not_found') return [];\n return getOrThrow(listed)\n .filter((info) => info.kind === 'file' && info.name.endsWith(EXTENSION))\n .map((info) => info.name)\n .sort((left, right) => left.localeCompare(right, undefined, { numeric: true }));\n }\n\n async save(code: string) {\n const fs = this.options.fs();\n const directory = this.sessionDirectory();\n if (!fs || directory === undefined) return undefined;\n getOrThrow(await fs.createDir(directory, { recursive: true }, BACKGROUND_CONTEXT));\n const taken = (await this.names(fs, directory)).map((name) => Number(EXEC_FILE.exec(name)?.[1] ?? 0));\n const name = `exec-${Math.max(0, ...taken) + 1}`;\n const path = `${directory}/${name}${EXTENSION}`;\n getOrThrow(await fs.writeFile(path, code, BACKGROUND_CONTEXT));\n return { specifier: `${SESSION_PREFIX}${name}`, path };\n }\n\n private candidates(specifier: string, domains?: readonly string[]): string[] {\n if (specifier.startsWith('/')) return [specifier];\n const session = this.sessionDirectory();\n if (specifier.startsWith(SESSION_PREFIX)) {\n return session === undefined ? [] : [`${session}/${withExtension(specifier.slice(SESSION_PREFIX.length))}`];\n }\n const slash = specifier.indexOf('/');\n const domain = slash > 0 ? specifier.slice(0, slash) : undefined;\n const folders = this.sources(domains).filter((source) => source.domain === domain);\n if (folders.length > 0) {\n return folders.map((source) => `${source.directory}/${withExtension(specifier.slice(slash + 1))}`);\n }\n if (session !== undefined && (specifier.startsWith('.') || specifier.endsWith(EXTENSION))) {\n return [`${session}/${withExtension(specifier.replace(/^\\.\\//u, ''))}`];\n }\n return [];\n }\n\n async resolve(specifier: string, domains?: readonly string[]) {\n const fs = this.requireFs();\n for (const path of this.candidates(specifier, domains)) {\n const read = await fs.readTextFile(path, BACKGROUND_CONTEXT);\n if (read.ok) return { id: path, source: read.value };\n if (read.error.code !== 'not_found') getOrThrow(read);\n }\n const available = (await this.list(domains)).map((entry) => entry.specifier).join(', ') || 'none';\n throw new Error(`Unknown script \"${specifier}\". Available: ${available}.`);\n }\n\n async list(domains?: readonly string[], limit = DEFAULT_LIST_LIMIT): Promise<CodemodeScriptEntry[]> {\n const fs = this.options.fs();\n if (!fs) return [];\n const found: { specifier: string; path: string }[] = [];\n for (const source of this.sources(domains)) {\n for (const name of await this.names(fs, source.directory)) {\n found.push({\n specifier: `${source.domain}/${name.slice(0, -EXTENSION.length)}`,\n path: `${source.directory}/${name}`,\n });\n }\n }\n const session = this.sessionDirectory();\n if (session !== undefined) {\n for (const name of (await this.names(fs, session)).reverse()) {\n found.push({ specifier: `${SESSION_PREFIX}${name.slice(0, -EXTENSION.length)}`, path: `${session}/${name}` });\n }\n }\n const entries: CodemodeScriptEntry[] = [];\n for (const entry of found.slice(0, limit)) {\n const read = await fs.readTextFile(entry.path, BACKGROUND_CONTEXT);\n entries.push({ ...entry, description: read.ok ? describeScript(read.value) : '' });\n }\n return entries;\n }\n}\n","import { PO_CODEMODE_CONTRACT } from '@agimon-ai/po-core/codemode';\nimport { defineRoot } from '@agimon-ai/po-core/extensionFile';\nimport { PO_SESSION_FILES_SERVICE, readPoFs, readPoIsolate } from '@agimon-ai/po-core/platform';\nimport {\n PO_SERVER_SCOPE_SERVICE,\n requirePoServerScope,\n type PoServerPluginContext,\n} from '@agimon-ai/po-core/serverPlugin';\n\nimport { createCodemodeRegistry } from '../../../../../services/codemodeRegistry';\nimport { FileSystemCodemodeScriptsService } from '../../../../../services/codemodeScripts';\nimport { createCodemodeTools } from '../../../../../services/codemodeTools';\n\n/** One registry per session: contributors register into it, `discover` and `exec` read it. */\nexport function createCodemodeSession({ context }: PoServerPluginContext) {\n const registry = createCodemodeRegistry();\n // The binding unwinds with this injected fiber, so the root needs no withdraw of its own.\n context.inject([PO_SERVER_SCOPE_SERVICE], (scoped) =>\n requirePoServerScope(scoped).provide(PO_CODEMODE_CONTRACT, registry),\n );\n let temporaryDirectory: string | undefined;\n context.inject([PO_SESSION_FILES_SERVICE], (scoped) => {\n temporaryDirectory = scoped.get(PO_SESSION_FILES_SERVICE)?.temporaryDirectory;\n return () => {\n temporaryDirectory = undefined;\n };\n });\n const scripts = new FileSystemCodemodeScriptsService({\n registry,\n fs: () => readPoFs(context),\n temporaryDirectory: () => temporaryDirectory,\n });\n const tools = createCodemodeTools({ registry, isolate: () => readPoIsolate(context), scripts });\n return { value: { registry, ...tools } };\n}\n\nconst root = defineRoot(createCodemodeSession);\nexport type CodemodeServerScope = Awaited<ReturnType<typeof root>>['value'];\nexport default root;\n","import { defineRoot } from '@agimon-ai/po-core/extensionFile';\n\nimport contribution from './_lib/root.server';\n\nexport default defineRoot(contribution);\n","import { PO_CODEMODE_SERVICE, type PoCodemodeService } from '@agimon-ai/po-core/codemode';\nimport { defineServiceContract } from '@agimon-ai/po-core/extensionFile';\n\nexport default defineServiceContract<PoCodemodeService>(PO_CODEMODE_SERVICE, { scope: 'session' });\n","// @scaffold-generated\nimport { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { packageResourcePath, readPackageResource } from '@agimon-ai/po-core/serverPlugin';\n\nexport default defineResource({\n name: 'how-to-codemode',\n description:\n 'Use @agimon-ai/po-codemode: Code mode for Po sessions: discover and exec over namespaces other packages contribute',\n pinned: true,\n kind: 'skill' as const,\n path: packageResourcePath(import.meta.url, 'src/prompts/how-to-codemode/SKILL.md'),\n read: () => readPackageResource(import.meta.url, 'src/prompts/how-to-codemode/SKILL.md'),\n});\n","import { defineServerTool, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { CodemodeServerScope } from '../_lib/root.server';\n\nexport default defineServerTool(\n (context: WithRoot<PoServerPluginContext, CodemodeServerScope>) => context.root.discover,\n);\n","import { defineServerTool, type WithRoot } from '@agimon-ai/po-core/extensionFile';\nimport type { PoServerPluginContext } from '@agimon-ai/po-core/serverPlugin';\n\nimport type { CodemodeServerScope } from '../_lib/root.server';\n\nexport default defineServerTool((context: WithRoot<PoServerPluginContext, CodemodeServerScope>) => context.root.exec);\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type PoServerSessionPlugin } from '@agimon-ai/po-core/serverPlugin';\nimport { composeServerProviderOverrides } from '@agimon-ai/po-core/serverPlugin';\nimport { composeRootHooks, composeRootInjects } from '@agimon-ai/po-core/extensionFile';\n\nimport rootSession from '../src/extensions/workspaces/sessions/(backend)/root.server';\nimport contractCodemode from '../src/extensions/workspaces/sessions/(backend)/contract/codemode.server';\nimport resourceHowToCodemode from '../src/extensions/workspaces/sessions/(backend)/resource/how-to-codemode.server';\nimport toolDiscover from '../src/extensions/workspaces/sessions/(backend)/tool/discover.server';\nimport toolExec from '../src/extensions/workspaces/sessions/(backend)/tool/exec.server';\n\ntype Factory<T, C> = (context: C) => T;\nconst at = <T, C>(value: T | Factory<T, C>, context: C): T =>\n typeof value === 'function' ? (value as Factory<T, C>)(context) : value;\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const serverPlugin = defineServerPlugin({\n name: '@agimon-ai/po-codemode',\n providerOverrides: composeServerProviderOverrides(rootSession),\n provides: {\n session: [contractCodemode],\n },\n injects: composeRootInjects({ session: [rootSession] }),\n session: async (context) => {\n const scopeSession = await context.scopeRoot('session', rootSession, context);\n const contextSession = { ...context, root: scopeSession.value };\n return {\n ...composeRootHooks(scopeSession),\n get resources(): PoServerSessionPlugin['resources'] { return [at(resourceHowToCodemode, contextSession)]; },\n get tools(): PoServerSessionPlugin['tools'] { return [via({ name: 'discover' }, at(toolDiscover, contextSession)), via({ name: 'exec' }, at(toolExec, contextSession))]; },\n services: [...(scopeSession.services ?? [])],\n get activities(): PoServerSessionPlugin['activities'] { return [...(scopeSession.activities ?? [])]; },\n };\n },\n});\n\nexport default serverPlugin;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { defineToolRenderer, defineWebPlugin, toolResultTextLines } from "@agimon-ai/po-core/web";
|
|
2
|
+
import { CodeBlock, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, toolTone } from "@agimon-ai/po-web-components";
|
|
3
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts
|
|
5
|
+
/** Tool names this package registers (registerTool's `name`). */
|
|
6
|
+
const execToolName = "exec";
|
|
7
|
+
const discoverToolName = "discover";
|
|
8
|
+
const SUMMARY_MAX = 120;
|
|
9
|
+
const ARGS_MAX = 160;
|
|
10
|
+
const CALLS_MAX = 50;
|
|
11
|
+
const IMAGE_TYPES = /^image\/(?:png|jpeg|webp|gif)$/u;
|
|
12
|
+
const SAVED_LINE = /^Saved as (\S+) \((.+)\)$/u;
|
|
13
|
+
function record(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
|
|
15
|
+
}
|
|
16
|
+
function clip(text, max) {
|
|
17
|
+
return text.length <= max ? text : `${text.slice(0, max - 1)}…`;
|
|
18
|
+
}
|
|
19
|
+
/** The script the call ran, exactly as the agent wrote it. */
|
|
20
|
+
function execCode(args) {
|
|
21
|
+
return typeof args.code === "string" ? args.code : "";
|
|
22
|
+
}
|
|
23
|
+
/** The header line: the script's first line, with a leading `//` comment marker dropped. */
|
|
24
|
+
function execSummary(args) {
|
|
25
|
+
const first = execCode(args).split("\n").map((line) => line.trim()).find((line) => line !== "");
|
|
26
|
+
if (first === void 0) return "script";
|
|
27
|
+
return clip(first.replace(/^\/\/+\s*/u, ""), SUMMARY_MAX);
|
|
28
|
+
}
|
|
29
|
+
function callOf(value) {
|
|
30
|
+
const call = record(value);
|
|
31
|
+
if (call === void 0 || typeof call.name !== "string" || call.name === "") return void 0;
|
|
32
|
+
const result = record(call.result);
|
|
33
|
+
return {
|
|
34
|
+
name: call.name,
|
|
35
|
+
args: record(call.args) ?? {},
|
|
36
|
+
ok: call.ok !== false,
|
|
37
|
+
ms: typeof call.ms === "number" && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,
|
|
38
|
+
...typeof call.tool === "string" && call.tool !== "" ? { tool: call.tool } : {},
|
|
39
|
+
...typeof call.error === "string" && call.error !== "" ? { error: call.error } : {},
|
|
40
|
+
...result !== void 0 && Array.isArray(result.content) ? { result: {
|
|
41
|
+
content: result.content,
|
|
42
|
+
details: result.details
|
|
43
|
+
} } : {}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** The nested calls recorded in a result's details; anything malformed is skipped. */
|
|
47
|
+
function execCalls(details) {
|
|
48
|
+
const calls = record(details)?.calls;
|
|
49
|
+
if (!Array.isArray(calls)) return [];
|
|
50
|
+
return calls.slice(0, CALLS_MAX).map(callOf).filter((call) => call !== void 0);
|
|
51
|
+
}
|
|
52
|
+
/** A call's arguments on one line, for a row that has no card of its own. */
|
|
53
|
+
function callArgsSummary(args) {
|
|
54
|
+
return Object.keys(args).length === 0 ? "" : clip(JSON.stringify(args), ARGS_MAX);
|
|
55
|
+
}
|
|
56
|
+
/** What a result holds, with the saved-script footer and the pictures taken out of the text. */
|
|
57
|
+
function execResultView(result) {
|
|
58
|
+
if (result === null) return {
|
|
59
|
+
lines: [],
|
|
60
|
+
images: []
|
|
61
|
+
};
|
|
62
|
+
let saved;
|
|
63
|
+
const content = [];
|
|
64
|
+
for (const block of result.content) {
|
|
65
|
+
const text = record(block)?.type === "text" ? record(block)?.text : void 0;
|
|
66
|
+
const match = typeof text === "string" ? SAVED_LINE.exec(text.trim()) : null;
|
|
67
|
+
if (match?.[1] !== void 0 && match[2] !== void 0) saved = {
|
|
68
|
+
id: match[1],
|
|
69
|
+
path: match[2]
|
|
70
|
+
};
|
|
71
|
+
else content.push(block);
|
|
72
|
+
}
|
|
73
|
+
const images = content.flatMap((block) => {
|
|
74
|
+
const image = record(block);
|
|
75
|
+
return image?.type === "image" && typeof image.data === "string" && typeof image.mimeType === "string" && IMAGE_TYPES.test(image.mimeType) ? [{
|
|
76
|
+
mimeType: image.mimeType,
|
|
77
|
+
data: image.data
|
|
78
|
+
}] : [];
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
lines: toolResultTextLines(content),
|
|
82
|
+
...saved === void 0 ? {} : { saved },
|
|
83
|
+
images
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/** The header line for discover: what was asked for. */
|
|
87
|
+
function discoverSummary(args) {
|
|
88
|
+
if (typeof args.namespace === "string" && args.namespace !== "") return args.namespace;
|
|
89
|
+
if (typeof args.query === "string" && args.query !== "") return `find "${clip(args.query, SUMMARY_MAX)}"`;
|
|
90
|
+
return "namespaces and scripts";
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx
|
|
94
|
+
/** The discover tool's timeline item: folded to what was asked for, open to what came back. */
|
|
95
|
+
function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }) {
|
|
96
|
+
const declarations = typeof args.namespace === "string" && args.namespace !== "" && !isError;
|
|
97
|
+
return /* @__PURE__ */ jsx(MessageItem, {
|
|
98
|
+
tone: toolTone({
|
|
99
|
+
running,
|
|
100
|
+
isError
|
|
101
|
+
}),
|
|
102
|
+
expandable: true,
|
|
103
|
+
defaultExpanded,
|
|
104
|
+
children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
|
|
105
|
+
title: discoverToolName,
|
|
106
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
107
|
+
"data-testid": `tool-call-${discoverToolName}`,
|
|
108
|
+
className: "min-w-0 flex-1 truncate text-po-text",
|
|
109
|
+
children: discoverSummary(args)
|
|
110
|
+
})
|
|
111
|
+
}), expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
|
|
112
|
+
"data-testid": `tool-result-${discoverToolName}`,
|
|
113
|
+
className: "flex flex-col gap-2",
|
|
114
|
+
children: [running && output === "" ? /* @__PURE__ */ jsx(MessageItemStatus, {
|
|
115
|
+
tone: "running",
|
|
116
|
+
children: "running"
|
|
117
|
+
}) : null, output === "" ? null : declarations ? /* @__PURE__ */ jsx("div", {
|
|
118
|
+
className: "max-h-96 overflow-auto",
|
|
119
|
+
children: /* @__PURE__ */ jsx(CodeBlock, {
|
|
120
|
+
text: output,
|
|
121
|
+
className: "language-ts"
|
|
122
|
+
})
|
|
123
|
+
}) : /* @__PURE__ */ jsx("pre", {
|
|
124
|
+
"data-testid": "tool-output",
|
|
125
|
+
className: `max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? "text-po-red" : "text-po-text"}`,
|
|
126
|
+
children: output
|
|
127
|
+
})]
|
|
128
|
+
}) : null] })
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//#endregion
|
|
132
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx
|
|
133
|
+
var discover_web_default = defineToolRenderer({ message: DiscoverToolCard });
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx
|
|
136
|
+
/** A labelled part of an expanded card body. */
|
|
137
|
+
function ToolSection({ label, children }) {
|
|
138
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
139
|
+
className: "flex flex-col gap-1.5",
|
|
140
|
+
children: [/* @__PURE__ */ jsx("h4", {
|
|
141
|
+
className: "text-sm font-medium text-po-dim",
|
|
142
|
+
children: label
|
|
143
|
+
}), children]
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx
|
|
148
|
+
function CallRow({ call }) {
|
|
149
|
+
const args = callArgsSummary(call.args);
|
|
150
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
151
|
+
"data-testid": "exec-call",
|
|
152
|
+
className: "flex flex-col gap-0.5",
|
|
153
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
154
|
+
className: "flex items-center gap-2 text-sm",
|
|
155
|
+
children: [
|
|
156
|
+
/* @__PURE__ */ jsx("span", {
|
|
157
|
+
className: "shrink-0 font-mono text-po-text",
|
|
158
|
+
children: call.name
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ jsx("span", {
|
|
161
|
+
className: "min-w-0 flex-1 truncate font-mono text-po-dim",
|
|
162
|
+
children: args
|
|
163
|
+
}),
|
|
164
|
+
/* @__PURE__ */ jsx("span", {
|
|
165
|
+
"aria-hidden": true,
|
|
166
|
+
className: `w-3 shrink-0 text-center ${call.ok ? "text-po-green" : "text-po-red"}`,
|
|
167
|
+
children: call.ok ? "✓" : "✗"
|
|
168
|
+
}),
|
|
169
|
+
/* @__PURE__ */ jsxs("span", {
|
|
170
|
+
className: "w-16 shrink-0 text-right tabular-nums text-po-dim",
|
|
171
|
+
children: [call.ms, " ms"]
|
|
172
|
+
})
|
|
173
|
+
]
|
|
174
|
+
}), call.error === void 0 ? null : /* @__PURE__ */ jsx("p", {
|
|
175
|
+
className: "pl-5 text-sm break-words text-po-red",
|
|
176
|
+
children: call.error
|
|
177
|
+
})]
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function Calls({ calls, renderTool }) {
|
|
181
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
182
|
+
className: "flex flex-col gap-2",
|
|
183
|
+
children: calls.map((call, index) => {
|
|
184
|
+
const card = call.tool === void 0 || renderTool === void 0 ? null : renderTool({
|
|
185
|
+
toolName: call.tool,
|
|
186
|
+
args: call.args,
|
|
187
|
+
result: call.result ?? null,
|
|
188
|
+
isError: !call.ok
|
|
189
|
+
});
|
|
190
|
+
return /* @__PURE__ */ jsx("li", { children: card ?? /* @__PURE__ */ jsx(CallRow, { call }) }, `${String(index)}-${call.name}`);
|
|
191
|
+
})
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* The exec tool's timeline item. It stays folded until opened: the script is the
|
|
196
|
+
* point of the call, so opening shows the code, every namespace call it made
|
|
197
|
+
* (as the owning tool's card when one exists), then what it returned.
|
|
198
|
+
*/
|
|
199
|
+
function ExecToolCard({ args, result, running, isError, defaultExpanded = false, renderTool }) {
|
|
200
|
+
const code = execCode(args);
|
|
201
|
+
const view = execResultView(result);
|
|
202
|
+
const calls = execCalls(result?.details);
|
|
203
|
+
return /* @__PURE__ */ jsx(MessageItem, {
|
|
204
|
+
tone: toolTone({
|
|
205
|
+
running,
|
|
206
|
+
isError
|
|
207
|
+
}),
|
|
208
|
+
expandable: true,
|
|
209
|
+
defaultExpanded,
|
|
210
|
+
children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(MessageItemHeader, {
|
|
211
|
+
title: execToolName,
|
|
212
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
213
|
+
"data-testid": `tool-call-${execToolName}`,
|
|
214
|
+
className: "min-w-0 flex-1 truncate text-po-text",
|
|
215
|
+
children: execSummary(args)
|
|
216
|
+
}), calls.length > 0 ? /* @__PURE__ */ jsxs("span", {
|
|
217
|
+
className: "shrink-0 text-sm text-po-dim",
|
|
218
|
+
children: [
|
|
219
|
+
calls.length,
|
|
220
|
+
" ",
|
|
221
|
+
calls.length === 1 ? "call" : "calls"
|
|
222
|
+
]
|
|
223
|
+
}) : null]
|
|
224
|
+
}), expanded ? /* @__PURE__ */ jsxs(MessageItemBody, {
|
|
225
|
+
"data-testid": `tool-result-${execToolName}`,
|
|
226
|
+
className: "flex flex-col gap-4",
|
|
227
|
+
children: [
|
|
228
|
+
code === "" ? null : /* @__PURE__ */ jsx(ToolSection, {
|
|
229
|
+
label: "Code",
|
|
230
|
+
children: /* @__PURE__ */ jsx(CodeBlock, {
|
|
231
|
+
text: code,
|
|
232
|
+
className: "language-ts"
|
|
233
|
+
})
|
|
234
|
+
}),
|
|
235
|
+
calls.length === 0 ? null : /* @__PURE__ */ jsx(ToolSection, {
|
|
236
|
+
label: "Calls",
|
|
237
|
+
children: /* @__PURE__ */ jsx(Calls, {
|
|
238
|
+
calls,
|
|
239
|
+
renderTool
|
|
240
|
+
})
|
|
241
|
+
}),
|
|
242
|
+
running && view.lines.length === 0 ? /* @__PURE__ */ jsx(MessageItemStatus, {
|
|
243
|
+
tone: "running",
|
|
244
|
+
children: "running"
|
|
245
|
+
}) : /* @__PURE__ */ jsxs(ToolSection, {
|
|
246
|
+
label: isError ? "Error" : "Result",
|
|
247
|
+
children: [
|
|
248
|
+
view.lines.length === 0 && view.images.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
249
|
+
className: "text-sm text-po-dim",
|
|
250
|
+
children: "No output."
|
|
251
|
+
}) : null,
|
|
252
|
+
view.lines.length === 0 ? null : /* @__PURE__ */ jsx("pre", {
|
|
253
|
+
"data-testid": "tool-output",
|
|
254
|
+
className: `max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? "text-po-red" : "text-po-text"}`,
|
|
255
|
+
children: view.lines.join("\n")
|
|
256
|
+
}),
|
|
257
|
+
view.images.map((image, index) => /* @__PURE__ */ jsx("img", {
|
|
258
|
+
src: `data:${image.mimeType};base64,${image.data}`,
|
|
259
|
+
alt: `Script image ${String(index + 1)}`,
|
|
260
|
+
"data-testid": "tool-output-image",
|
|
261
|
+
className: "max-h-96 max-w-full self-start rounded-md border border-po-border-soft"
|
|
262
|
+
}, `${image.mimeType}-${String(index)}`))
|
|
263
|
+
]
|
|
264
|
+
}),
|
|
265
|
+
view.saved === void 0 ? null : /* @__PURE__ */ jsxs("p", {
|
|
266
|
+
className: "text-sm text-po-dim",
|
|
267
|
+
title: view.saved.path,
|
|
268
|
+
children: ["Saved as ", /* @__PURE__ */ jsx("span", {
|
|
269
|
+
className: "font-mono text-po-text",
|
|
270
|
+
children: view.saved.id
|
|
271
|
+
})]
|
|
272
|
+
})
|
|
273
|
+
]
|
|
274
|
+
}) : null] })
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx
|
|
279
|
+
var exec_web_default = defineToolRenderer({ message: ExecToolCard });
|
|
280
|
+
//#endregion
|
|
281
|
+
//#region generated/web.ts
|
|
282
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
283
|
+
...identity,
|
|
284
|
+
...value
|
|
285
|
+
};
|
|
286
|
+
const webPlugin = defineWebPlugin({
|
|
287
|
+
id: "codemode",
|
|
288
|
+
session: { get toolRenderers() {
|
|
289
|
+
return [via({ tools: ["discover"] }, discover_web_default), via({ tools: ["exec"] }, exec_web_default)];
|
|
290
|
+
} }
|
|
291
|
+
});
|
|
292
|
+
//#endregion
|
|
293
|
+
export { webPlugin };
|
|
294
|
+
|
|
295
|
+
//# sourceMappingURL=web.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.mjs","names":["toolDiscover","toolExec"],"sources":["../../src/extensions/workspaces/sessions/(frontend)/tool/_lib/execToolView.ts","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/DiscoverToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/discover.web.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ToolSection.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/_components/ExecToolCard.tsx","../../src/extensions/workspaces/sessions/(frontend)/tool/exec.web.tsx","../../generated/web.ts"],"sourcesContent":["import { type ToolResultView, toolResultTextLines } from '@agimon-ai/po-core/web';\n\n/** Tool names this package registers (registerTool's `name`). */\nexport const execToolName = 'exec' as const;\nexport const discoverToolName = 'discover' as const;\n\nconst SUMMARY_MAX = 120;\nconst ARGS_MAX = 160;\nconst CALLS_MAX = 50;\nconst IMAGE_TYPES = /^image\\/(?:png|jpeg|webp|gif)$/u;\nconst SAVED_LINE = /^Saved as (\\S+) \\((.+)\\)$/u;\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\nfunction clip(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n}\n\n/** The script the call ran, exactly as the agent wrote it. */\nexport function execCode(args: Readonly<Record<string, unknown>>): string {\n return typeof args.code === 'string' ? args.code : '';\n}\n\n/** The header line: the script's first line, with a leading `//` comment marker dropped. */\nexport function execSummary(args: Readonly<Record<string, unknown>>): string {\n const first = execCode(args)\n .split('\\n')\n .map((line) => line.trim())\n .find((line) => line !== '');\n if (first === undefined) return 'script';\n return clip(first.replace(/^\\/\\/+\\s*/u, ''), SUMMARY_MAX);\n}\n\n/** One namespace call the script made, as exec reports it in the result's details. */\nexport interface ExecCall {\n /** The member called, such as `browser.click` or `mcp.github.search_issues`. */\n name: string;\n args: Record<string, unknown>;\n ok: boolean;\n ms: number;\n /** The tool name whose own card shows this call, when another package has one. */\n tool?: string;\n error?: string;\n result?: ToolResultView;\n}\n\nfunction callOf(value: unknown): ExecCall | undefined {\n const call = record(value);\n if (call === undefined || typeof call.name !== 'string' || call.name === '') return undefined;\n const result = record(call.result);\n return {\n name: call.name,\n args: record(call.args) ?? {},\n ok: call.ok !== false,\n ms: typeof call.ms === 'number' && Number.isFinite(call.ms) && call.ms >= 0 ? Math.round(call.ms) : 0,\n ...(typeof call.tool === 'string' && call.tool !== '' ? { tool: call.tool } : {}),\n ...(typeof call.error === 'string' && call.error !== '' ? { error: call.error } : {}),\n ...(result !== undefined && Array.isArray(result.content)\n ? { result: { content: result.content, details: result.details } }\n : {}),\n };\n}\n\n/** The nested calls recorded in a result's details; anything malformed is skipped. */\nexport function execCalls(details: unknown): ExecCall[] {\n const calls = record(details)?.calls;\n if (!Array.isArray(calls)) return [];\n return calls\n .slice(0, CALLS_MAX)\n .map(callOf)\n .filter((call): call is ExecCall => call !== undefined);\n}\n\n/** A call's arguments on one line, for a row that has no card of its own. */\nexport function callArgsSummary(args: Readonly<Record<string, unknown>>): string {\n return Object.keys(args).length === 0 ? '' : clip(JSON.stringify(args), ARGS_MAX);\n}\n\nexport interface ExecImage {\n mimeType: string;\n data: string;\n}\n\nexport interface ExecResultView {\n lines: string[];\n /** The saved-script footer exec appends: the id to import it by, and where it lives. */\n saved?: { id: string; path: string };\n images: ExecImage[];\n}\n\n/** What a result holds, with the saved-script footer and the pictures taken out of the text. */\nexport function execResultView(result: ToolResultView | null): ExecResultView {\n if (result === null) return { lines: [], images: [] };\n let saved: ExecResultView['saved'];\n const content: unknown[] = [];\n for (const block of result.content) {\n const text = record(block)?.type === 'text' ? record(block)?.text : undefined;\n const match = typeof text === 'string' ? SAVED_LINE.exec(text.trim()) : null;\n if (match?.[1] !== undefined && match[2] !== undefined) saved = { id: match[1], path: match[2] };\n else content.push(block);\n }\n const images = content.flatMap((block): ExecImage[] => {\n const image = record(block);\n return image?.type === 'image' &&\n typeof image.data === 'string' &&\n typeof image.mimeType === 'string' &&\n IMAGE_TYPES.test(image.mimeType)\n ? [{ mimeType: image.mimeType, data: image.data }]\n : [];\n });\n return { lines: toolResultTextLines(content), ...(saved === undefined ? {} : { saved }), images };\n}\n\n/** The header line for discover: what was asked for. */\nexport function discoverSummary(args: Readonly<Record<string, unknown>>): string {\n if (typeof args.namespace === 'string' && args.namespace !== '') return args.namespace;\n if (typeof args.query === 'string' && args.query !== '') return `find \"${clip(args.query, SUMMARY_MAX)}\"`;\n return 'namespaces and scripts';\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport { discoverSummary, discoverToolName } from '../_lib/execToolView';\n\nexport type DiscoverToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\n/** The discover tool's timeline item: folded to what was asked for, open to what came back. */\nexport function DiscoverToolCard({ args, output, running, isError, defaultExpanded = false }: DiscoverToolCardProps) {\n const declarations = typeof args.namespace === 'string' && args.namespace !== '' && !isError;\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={discoverToolName}>\n <span data-testid={`tool-call-${discoverToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {discoverSummary(args)}\n </span>\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${discoverToolName}`} className=\"flex flex-col gap-2\">\n {running && output === '' ? <MessageItemStatus tone=\"running\">running</MessageItemStatus> : null}\n {output === '' ? null : declarations ? (\n <div className=\"max-h-96 overflow-auto\">\n <CodeBlock text={output} className=\"language-ts\" />\n </div>\n ) : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-96 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {output}\n </pre>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { DiscoverToolCard } from './_components/DiscoverToolCard';\n\nexport default defineToolRenderer({ message: DiscoverToolCard });\n","import type { ReactNode } from 'react';\n\n/** A labelled part of an expanded card body. */\nexport function ToolSection({ label, children }: { label: string; children: ReactNode }) {\n return (\n <section className=\"flex flex-col gap-1.5\">\n <h4 className=\"text-sm font-medium text-po-dim\">{label}</h4>\n {children}\n </section>\n );\n}\n","import type { ToolMessageRenderProps } from '@agimon-ai/po-core/web';\nimport {\n CodeBlock,\n MessageItem,\n MessageItemBody,\n MessageItemHeader,\n MessageItemStatus,\n toolTone,\n} from '@agimon-ai/po-web-components';\n\nimport {\n callArgsSummary,\n execCalls,\n execCode,\n execResultView,\n execSummary,\n execToolName,\n type ExecCall,\n} from '../_lib/execToolView';\nimport { ToolSection } from './ToolSection';\n\n/** Draws another tool's own card for a nested call, or nothing when no package owns one. */\nexport type RenderNestedTool = NonNullable<ToolMessageRenderProps['renderTool']>;\n\nexport type ExecToolCardProps = ToolMessageRenderProps & { defaultExpanded?: boolean };\n\nfunction CallRow({ call }: { call: ExecCall }) {\n const args = callArgsSummary(call.args);\n return (\n <div data-testid=\"exec-call\" className=\"flex flex-col gap-0.5\">\n <div className=\"flex items-center gap-2 text-sm\">\n <span className=\"shrink-0 font-mono text-po-text\">{call.name}</span>\n <span className=\"min-w-0 flex-1 truncate font-mono text-po-dim\">{args}</span>\n <span aria-hidden className={`w-3 shrink-0 text-center ${call.ok ? 'text-po-green' : 'text-po-red'}`}>\n {call.ok ? '✓' : '✗'}\n </span>\n <span className=\"w-16 shrink-0 text-right tabular-nums text-po-dim\">{call.ms} ms</span>\n </div>\n {call.error === undefined ? null : <p className=\"pl-5 text-sm break-words text-po-red\">{call.error}</p>}\n </div>\n );\n}\n\nfunction Calls({ calls, renderTool }: { calls: readonly ExecCall[]; renderTool: RenderNestedTool | undefined }) {\n return (\n <ul className=\"flex flex-col gap-2\">\n {calls.map((call, index) => {\n const card =\n call.tool === undefined || renderTool === undefined\n ? null\n : renderTool({\n toolName: call.tool,\n args: call.args,\n result: call.result ?? null,\n isError: !call.ok,\n });\n return <li key={`${String(index)}-${call.name}`}>{card ?? <CallRow call={call} />}</li>;\n })}\n </ul>\n );\n}\n\n/**\n * The exec tool's timeline item. It stays folded until opened: the script is the\n * point of the call, so opening shows the code, every namespace call it made\n * (as the owning tool's card when one exists), then what it returned.\n */\nexport function ExecToolCard({\n args,\n result,\n running,\n isError,\n defaultExpanded = false,\n renderTool,\n}: ExecToolCardProps) {\n const code = execCode(args);\n const view = execResultView(result);\n const calls = execCalls(result?.details);\n return (\n <MessageItem tone={toolTone({ running, isError })} expandable defaultExpanded={defaultExpanded}>\n {({ expanded }) => (\n <>\n <MessageItemHeader title={execToolName}>\n <span data-testid={`tool-call-${execToolName}`} className=\"min-w-0 flex-1 truncate text-po-text\">\n {execSummary(args)}\n </span>\n {calls.length > 0 ? (\n <span className=\"shrink-0 text-sm text-po-dim\">\n {calls.length} {calls.length === 1 ? 'call' : 'calls'}\n </span>\n ) : null}\n </MessageItemHeader>\n {expanded ? (\n <MessageItemBody data-testid={`tool-result-${execToolName}`} className=\"flex flex-col gap-4\">\n {code === '' ? null : (\n <ToolSection label=\"Code\">\n <CodeBlock text={code} className=\"language-ts\" />\n </ToolSection>\n )}\n {calls.length === 0 ? null : (\n <ToolSection label=\"Calls\">\n <Calls calls={calls} renderTool={renderTool} />\n </ToolSection>\n )}\n {running && view.lines.length === 0 ? (\n <MessageItemStatus tone=\"running\">running</MessageItemStatus>\n ) : (\n <ToolSection label={isError ? 'Error' : 'Result'}>\n {view.lines.length === 0 && view.images.length === 0 ? (\n <p className=\"text-sm text-po-dim\">No output.</p>\n ) : null}\n {view.lines.length === 0 ? null : (\n <pre\n data-testid=\"tool-output\"\n className={`max-h-72 overflow-auto font-mono text-sm break-words whitespace-pre-wrap ${isError ? 'text-po-red' : 'text-po-text'}`}\n >\n {view.lines.join('\\n')}\n </pre>\n )}\n {view.images.map((image, index) => (\n <img\n key={`${image.mimeType}-${String(index)}`}\n src={`data:${image.mimeType};base64,${image.data}`}\n alt={`Script image ${String(index + 1)}`}\n data-testid=\"tool-output-image\"\n className=\"max-h-96 max-w-full self-start rounded-md border border-po-border-soft\"\n />\n ))}\n </ToolSection>\n )}\n {view.saved === undefined ? null : (\n <p className=\"text-sm text-po-dim\" title={view.saved.path}>\n Saved as <span className=\"font-mono text-po-text\">{view.saved.id}</span>\n </p>\n )}\n </MessageItemBody>\n ) : null}\n </>\n )}\n </MessageItem>\n );\n}\n","import { defineToolRenderer } from '@agimon-ai/po-core/web';\n\nimport { ExecToolCard } from './_components/ExecToolCard';\n\nexport default defineToolRenderer({ message: ExecToolCard });\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineWebPlugin, type WebPluginContributions } from '@agimon-ai/po-core/web';\n\nimport toolDiscover from '../src/extensions/workspaces/sessions/(frontend)/tool/discover.web';\nimport toolExec from '../src/extensions/workspaces/sessions/(frontend)/tool/exec.web';\n\nconst via = <T>(identity: Record<string, unknown>, value: unknown): T =>\n (value === undefined ? undefined : { ...identity, ...(value as object) }) as T;\n\nexport const webPlugin = defineWebPlugin({\n id: 'codemode',\n session: {\n get toolRenderers(): WebPluginContributions['toolRenderers'] { return [via({ tools: ['discover'] }, toolDiscover), via({ tools: ['exec'] }, toolExec)]; },\n },\n});\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_codemodeTools = require("./codemodeTools-
|
|
2
|
+
const require_codemodeTools = require("./codemodeTools-CLgSDqfU.cjs");
|
|
3
3
|
exports.createCodemodeRegistry = require_codemodeTools.createCodemodeRegistry;
|
|
4
4
|
exports.createCodemodeTools = require_codemodeTools.createCodemodeTools;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PoCodemodeService } from "@agimon-ai/po-core/codemode";
|
|
2
|
+
import { PoHeadlessTool } from "@agimon-ai/po-core/headless";
|
|
2
3
|
import { Type } from "typebox";
|
|
3
4
|
import { PoIsolateService } from "@agimon-ai/po-core/platform";
|
|
4
|
-
import { PoHeadlessTool } from "@agimon-ai/po-core/headless";
|
|
5
5
|
//#region src/services/codemodeRegistry/index.d.ts
|
|
6
6
|
/** The session's namespaces and script folders, in registration order. One name per session. */
|
|
7
7
|
export declare function createCodemodeRegistry(): PoCodemodeService;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;;;;UCPV;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/services/codemodeRegistry/index.ts","../src/schemas/codemodeTools.ts","../src/services/codemodeScripts/type.ts","../src/services/codemodeTools/index.ts"],"mappings":";;;;;;wBASgB,0BAA0B;;;cCP7B,oBAAkB,KAAA;;;;cAMlB,gBAAc,KAAA;;;;;;;UCPV;;WAEN;WACA;;WAEA;;;UAIM;;EAEf,KAAK,eAAe;aAAmB;aAA4B;;;EAEnE,QAAQ,mBAAmB,8BAA8B;aAAmB;aAAqB;;;EAEjG,KAAK,6BAA6B,iBAAiB,QAAQ;;;;UCiC5C;WACN,UAAU;;WAEV,eAAe;;WAEf,UAAU;;UAGJ;WACN,UAAU,sBAAsB;WAChC,MAAM,sBAAsB;;;wBA+JvB,sBAAsB,UAAU,SAAS,WAAW,uBAAuB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-
|
|
1
|
+
export { n as createCodemodeRegistry, t as createCodemodeTools } from "./codemodeTools-BdwOARH8.mjs";
|
package/llms.txt
CHANGED
|
@@ -4,7 +4,7 @@ Package-owned guidance for Code mode for Po sessions: discover and exec over nam
|
|
|
4
4
|
|
|
5
5
|
## How to use
|
|
6
6
|
|
|
7
|
-
- [Use code mode](./src/prompts/
|
|
7
|
+
- [Use code mode](./src/prompts/how-to-codemode/SKILL.md): The discover and exec tools, script globals, limits and trust.
|
|
8
8
|
|
|
9
9
|
## Resources
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/po-codemode",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.3",
|
|
4
4
|
"description": "Code mode for Po sessions: discover and exec over namespaces other packages contribute",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -43,22 +43,31 @@
|
|
|
43
43
|
"import": "./dist/extensions/server.mjs",
|
|
44
44
|
"require": "./dist/extensions/server.cjs"
|
|
45
45
|
},
|
|
46
|
+
"./extensions/web": {
|
|
47
|
+
"import": "./dist/extensions/web.mjs"
|
|
48
|
+
},
|
|
46
49
|
"./package.json": "./package.json"
|
|
47
50
|
},
|
|
48
51
|
"publishConfig": {
|
|
49
52
|
"access": "public"
|
|
50
53
|
},
|
|
51
54
|
"dependencies": {
|
|
52
|
-
"@agimon-ai/po-core": "0.0.0-alpha.
|
|
55
|
+
"@agimon-ai/po-core": "0.0.0-alpha.30",
|
|
56
|
+
"@agimon-ai/po-web-components": "0.0.0-alpha.30",
|
|
53
57
|
"@deepseek-ai/cordis": "4.0.5",
|
|
58
|
+
"react": "19.3.0",
|
|
54
59
|
"typebox": "1.3.37"
|
|
55
60
|
},
|
|
56
61
|
"devDependencies": {
|
|
57
|
-
"@agimon-ai/po-build": "0.0.0-alpha.
|
|
58
|
-
"@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.
|
|
62
|
+
"@agimon-ai/po-build": "0.0.0-alpha.30",
|
|
63
|
+
"@agimon-ai/vibe-lint-plugin-po-extension": "0.0.0-alpha.30",
|
|
64
|
+
"@agimon-ai/vibe-lint-plugin-po-web": "0.0.0-alpha.30",
|
|
59
65
|
"@earendil-works/pi-coding-agent": "1.3.0",
|
|
60
66
|
"@types/node": "26.6.5",
|
|
67
|
+
"@types/react": "19.3.0",
|
|
68
|
+
"@types/react-dom": "19.3.0",
|
|
61
69
|
"@vitest/coverage-v8": "5.0.4",
|
|
70
|
+
"react-dom": "19.3.0",
|
|
62
71
|
"tsdown": "0.23.1",
|
|
63
72
|
"typescript": "7.0.2",
|
|
64
73
|
"vitest": "5.0.4"
|
|
@@ -90,10 +99,18 @@
|
|
|
90
99
|
]
|
|
91
100
|
}
|
|
92
101
|
},
|
|
102
|
+
"poWeb": {
|
|
103
|
+
"pluginId": "codemode",
|
|
104
|
+
"channels": [],
|
|
105
|
+
"client": "./dist/extensions/web.mjs",
|
|
106
|
+
"scopes": [
|
|
107
|
+
"session"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
93
110
|
"scripts": {
|
|
94
111
|
"build": "tsdown",
|
|
95
112
|
"test": "vitest --run",
|
|
96
|
-
"typecheck": "tsc --noEmit",
|
|
113
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.web.json",
|
|
97
114
|
"lint": "oxlint . && oxfmt . --check",
|
|
98
115
|
"fixcode": "oxlint . --fix && oxfmt ."
|
|
99
116
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: how-to-codemode
|
|
3
3
|
description: 'Use @agimon-ai/po-codemode: run TypeScript against live Po objects with the discover and exec tools. Use when a task needs several steps on a namespace such as browser in one call.'
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -9,6 +9,7 @@ Code mode gives you two tools.
|
|
|
9
9
|
|
|
10
10
|
- `discover`: with no arguments, lists the namespaces this session has (for example `browser`) and their members, plus reusable scripts from the active domains and this session's saved scripts (capped, newest first). `discover({ namespace })` shows full TypeScript declarations; `discover({ query })` finds members, script names and script descriptions.
|
|
11
11
|
- `exec`: runs a TypeScript async function body. Namespaces are in scope as globals. `return` a value, use `console.log` for notes, `image(data, mimeType)` to send back a screenshot, and `sleep(ms)` to wait.
|
|
12
|
+
- Read the return type before relying on a result. `Promise<string>` is text, not an object. A doc such as `JSON text: Browser.ExpectResult` means `JSON.parse(text) as Browser.ExpectResult`, and its fields tell you what a success looks like (for example `success` only says the check ran, `passed` is the outcome). A failed call rejects with the tool's message. An MCP tool that declares an output schema returns it typed in `structuredContent`.
|
|
12
13
|
|
|
13
14
|
```ts
|
|
14
15
|
// exec({ code })
|
|
@@ -42,3 +43,4 @@ To keep a useful script, copy the saved file with normal file tools to `plugins/
|
|
|
42
43
|
- Objects you get from a namespace are live. Listeners you add and the objects themselves stop working when the run ends; keep state in the namespace, not in script variables.
|
|
43
44
|
- `exec` runs inside the Po server with full trust, like `bash`. Do not use it to bypass a blocked tool.
|
|
44
45
|
- There is no `eval`, `Function`, `setTimeout`, `fetch`, `require` or `process` inside a script.
|
|
46
|
+
- Subagents have `exec` too, and up to 8 runs can overlap across you and them. Namespaces are shared, so a run sees the pages and tasks another agent made.
|