@agimon-ai/po-prompt 0.0.0-alpha.0
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/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/apiContracts.cjs +74 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +52 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +69 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +26 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +21 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +249 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +239 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +646 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +46 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +36 -0
- package/dist/index.mjs.map +1 -0
- package/dist/promptStore-CChLO_3L.mjs +172 -0
- package/dist/promptStore-CChLO_3L.mjs.map +1 -0
- package/dist/promptStore-Cu4KqaXU.cjs +242 -0
- package/dist/promptStore-Cu4KqaXU.cjs.map +1 -0
- package/llms.txt +11 -0
- package/package.json +133 -0
- package/src/prompts/po-use-prompt/SKILL.md +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs","names":["defineApiRoutes","apiResponse","createNodeSavedPromptStore","Hono","routes","isValidPromptName","PROMPT_NAME_RULE","describePrompt","defineRoute","resolvePromptsDirectory","parsePromptDocument","readFile","defineServerCommand","defineResource","DOOM_HELP_WHEN","readPackageResource","defineResource","defineServerPlugin","apiRoute","commandPrompts","resourcePoUsePrompt","resourcePrompts"],"sources":["../../src/constants/promptsApi.ts","../../src/constants/webPrompts.ts","../../src/types/apiRoutes.ts","../../src/services/promptsApi/index.ts","../../src/extensions/(backend)/api/prompts/route.server.ts","../../src/constants/prompts.ts","../../src/services/savedPrompts/index.ts","../../src/services/serverPrompts/index.ts","../../src/extensions/workspaces/sessions/(backend)/command/prompts.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/prompts.server.ts","../../generated/server.ts"],"sourcesContent":["export const NAME_PARAM = 'name';\nexport const MAX_PROMPT_BYTES = 65_536;\nexport const STATUS = { badRequest: 400, notFound: 404, tooLarge: 413, failed: 500 } as const;\n","export const API_BASE_PATH = 'prompts';\nexport const PROMPTS_PATH = '/prompts';\n","import { apiResponse, defineApiRoutes } from '@agimon-ai/po-core/web';\n\nimport { NAME_PARAM } from '../constants/promptsApi';\nimport { PROMPTS_PATH } from '../constants/webPrompts';\nimport type { SavedPromptListResponse, SavedPromptWriteResponse } from './webPrompts';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/prompts/`, so the mount is stated once, by the\n * folder that creates it. This package stated it three times before: a\n * constant, and the literal `prompts` twice more inside a URL builder that also\n * decided, on its own, whether a call was global or session scoped.\n *\n * The Hono app registers these paths and the browser addresses them, so a path\n * cannot move on one side alone.\n *\n * `:name` is Hono's own parameter syntax, because the app registers `path`\n * verbatim, and the client fills it from `params` on the call.\n */\nexport default defineApiRoutes({\n list: {\n method: 'GET',\n path: PROMPTS_PATH,\n response: apiResponse<SavedPromptListResponse>(),\n },\n save: {\n method: 'PUT',\n path: `${PROMPTS_PATH}/:${NAME_PARAM}`,\n response: apiResponse<SavedPromptWriteResponse>(),\n },\n /** The same path as `save`; the method is the whole of the difference. */\n remove: {\n method: 'DELETE',\n path: `${PROMPTS_PATH}/:${NAME_PARAM}`,\n },\n});\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { NAME_PARAM, MAX_PROMPT_BYTES, STATUS } from '../../constants/promptsApi';\nimport { PROMPT_NAME_RULE } from '../../constants/savedPromptDocument';\nimport { API_BASE_PATH } from '../../constants/webPrompts';\nimport { createNodeSavedPromptStore } from '../../services/promptStore';\nimport { describePrompt, isValidPromptName } from '../../services/savedPromptDocument';\nimport routes from '../../types/apiRoutes';\nimport type { SavedPrompt, SavedPromptStore } from '../../types/prompt';\nimport {\n type SavedPromptListResponse,\n type SavedPromptView,\n type SavedPromptWriteResponse,\n} from '../../types/webPrompts';\n\n/**\n * This package's HTTP surface, served by the cockpit hub.\n *\n * DESIGN PATTERNS:\n * - Hub scope, not session scope: saved prompts live in the agent directory and\n * belong to the machine, so no route names a session.\n * - The store is injected. The same port the Pi commands write through answers\n * the browser, so the two surfaces cannot disagree about the format on disk.\n * - Paths come from src/types/apiRoutes, the one table the browser reads too,\n * so this app and the cockpit cannot disagree about where a route lives.\n * They stay relative to the mount the host strips.\n *\n * AVOID:\n * - Validating names here by hand. The rule lives in src/services with the\n * document format it protects.\n */\n\nexport interface HubApiOptions {\n store?: SavedPromptStore;\n}\n\nfunction toView(prompt: SavedPrompt): SavedPromptView {\n return { name: prompt.name, description: prompt.description, text: prompt.text };\n}\n\nfunction failureMessage(error: unknown): string {\n return error instanceof Error ? error.message : 'The prompt library could not complete that request.';\n}\n\n/** Reads `{ text }` out of a request body, or the reason it is unusable. */\nasync function readText(request: Request): Promise<{ text: string } | { error: string }> {\n let payload: unknown;\n try {\n payload = await request.json();\n } catch {\n // A body that is not JSON is a client mistake, reported as one.\n return { error: 'The request body must be JSON.' };\n }\n const text = (payload as { text?: unknown } | null)?.text;\n if (typeof text !== 'string' || text.trim().length === 0) return { error: 'A non-empty text is required.' };\n if (Buffer.byteLength(text, 'utf8') > MAX_PROMPT_BYTES) return { error: 'That prompt is too large to save.' };\n return { text };\n}\n\nexport function createPromptHubApi(options: HubApiOptions = {}): Hono {\n const store = options.store ?? createNodeSavedPromptStore();\n const app = new Hono();\n\n app.get(routes.list.path, async (context) => {\n try {\n const prompts = await store.list();\n return context.json<SavedPromptListResponse>({ prompts: prompts.map(toView) });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n app.put(routes.save.path, async (context) => {\n const name = context.req.param(NAME_PARAM);\n if (!isValidPromptName(name)) {\n return context.json(\n { error: `\"${name}\" is not a usable prompt name. Use ${PROMPT_NAME_RULE}.` },\n STATUS.badRequest,\n );\n }\n\n const body = await readText(context.req.raw);\n if ('error' in body) {\n const status = body.error.includes('too large') ? STATUS.tooLarge : STATUS.badRequest;\n return context.json({ error: body.error }, status);\n }\n\n try {\n const replaced = await store.has(name);\n const prompt: SavedPrompt = { name, description: describePrompt(body.text), text: body.text };\n await store.save(prompt);\n return context.json<SavedPromptWriteResponse>({ prompt: toView(prompt), replaced });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n app.delete(routes.remove.path, async (context) => {\n const name = context.req.param(NAME_PARAM);\n if (!isValidPromptName(name)) {\n return context.json({ error: `\"${name}\" is not a usable prompt name.` }, STATUS.badRequest);\n }\n\n try {\n const removed = await store.remove(name);\n if (!removed) return context.json({ error: `No saved prompt is named \"${name}\".` }, STATUS.notFound);\n return context.json({ name });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n return app;\n}\n\n/** The named export a host imports from this package's built entry. */\nexport const api: DoomApi = {\n basePath: API_BASE_PATH,\n start(_context: DoomApiContext): DoomApiHandler {\n const app = createPromptHubApi();\n return {\n fetch: (request) => app.fetch(request),\n // Nothing outlives a request here; the store holds no handles.\n close: () => undefined,\n };\n },\n};\n","import { defineRoute } from '@agimon-ai/po-core/extensionFile';\n\nimport { api } from '../../../../services/promptsApi';\n\n/**\n * Mounts this package's HTTP API at `prompts`, which the folder names.\n *\n * The folder is the declaration: the build reads the base path off it and hands\n * the browser a client bound to the same segment, so the mount is stated once\n * rather than in a constant, a URL builder and a story stub that were each free\n * to drift.\n */\nexport default defineRoute(api);\n","export const COMMAND_NAME = 'prompts';\nexport const COMMAND_DESCRIPTION = 'Browse staged and saved prompts';\nexport const SERVER_COMMAND_DESCRIPTION = 'List saved prompts or run one by name.';\n","import { readFile } from 'node:fs/promises';\n\nimport { resolvePromptsDirectory } from '../promptStore';\nimport { parsePromptDocument } from '../savedPromptDocument';\n\nexport async function savedPrompts(): Promise<readonly { name: string; text: string; description: string }[]> {\n const directory = resolvePromptsDirectory();\n try {\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(directory, { withFileTypes: true });\n const prompts = [] as { name: string; text: string; description: string }[];\n for (const entry of entries\n .filter((candidate) => candidate.isFile() && candidate.name.endsWith('.md'))\n .sort((a, b) => a.name.localeCompare(b.name))) {\n const name = entry.name.slice(0, -3);\n prompts.push(parsePromptDocument(name, await readFile(`${directory}/${entry.name}`, 'utf8')));\n }\n return prompts;\n } catch {\n return [];\n }\n}\n","import type { DoomHeadlessCommand } from '@agimon-ai/po-core/headless';\n\nimport { COMMAND_NAME, SERVER_COMMAND_DESCRIPTION } from '../../constants/prompts';\nimport { savedPrompts } from '../../services/savedPrompts';\nexport const serverPromptCommand: DoomHeadlessCommand = {\n name: COMMAND_NAME,\n description: SERVER_COMMAND_DESCRIPTION,\n async execute(args, execution) {\n const prompts = await savedPrompts();\n const requested = args.trim();\n if (!requested) {\n await execution.client.notify({\n title: 'Po prompts',\n body: prompts.map((prompt) => `/${prompt.name}: ${prompt.description}`).join('\\n') || '(no saved prompts)',\n level: 'info',\n });\n return;\n }\n const prompt = prompts.find((candidate) => candidate.name === requested);\n if (!prompt) {\n await execution.client.notify({ body: `Saved prompt not found: ${requested}`, level: 'warning' });\n return;\n }\n await execution.session.prompt(prompt.text);\n },\n};\n","import { defineServerCommand } from '@agimon-ai/po-core/extensionFile';\n\nimport { serverPromptCommand } from '../../../../../services/serverPrompts';\nexport default defineServerCommand(serverPromptCommand);\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/po-core/help';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-use-prompt',\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-prompt/SKILL.md'),\n});\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\n\nimport { savedPrompts } from '../../../../../services/savedPrompts';\nexport default defineResource({\n name: 'po/prompts',\n kind: 'prompt' as const,\n read: async () => JSON.stringify(await savedPrompts(), null, 2),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\n\nimport apiRoute from '../src/extensions/(backend)/api/prompts/route.server';\nimport commandPrompts from '../src/extensions/workspaces/sessions/(backend)/command/prompts.server';\nimport resourcePoUsePrompt from '../src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server';\nimport resourcePrompts from '../src/extensions/workspaces/sessions/(backend)/resource/prompts.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 facet = defineServerPlugin({\n name: '@agimon-ai/po-prompt',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n session: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'prompts' }, at(commandPrompts, context))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoUsePrompt, context), at(resourcePrompts, context)]; },\n }),\n});\n\nexport default facet;\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.mts","names":[],"sources":["../../generated/server.ts"],"mappings":";qBAca,gDAAK"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { c as PROMPT_NAME_RULE, i as describePrompt, n as resolvePromptsDirectory, o as isValidPromptName, s as parsePromptDocument, t as createNodeSavedPromptStore } from "../promptStore-CChLO_3L.mjs";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { defineServerPlugin, readPackageResource } from "@agimon-ai/po-core/serverFacet";
|
|
4
|
+
import { defineResource, defineRoute, defineServerCommand } from "@agimon-ai/po-core/extensionFile";
|
|
5
|
+
import { Hono } from "hono";
|
|
6
|
+
import { apiResponse, defineApiRoutes } from "@agimon-ai/po-core/web";
|
|
7
|
+
import { DOOM_HELP_WHEN } from "@agimon-ai/po-core/help";
|
|
8
|
+
//#region src/constants/promptsApi.ts
|
|
9
|
+
const NAME_PARAM = "name";
|
|
10
|
+
const STATUS = {
|
|
11
|
+
badRequest: 400,
|
|
12
|
+
notFound: 404,
|
|
13
|
+
tooLarge: 413,
|
|
14
|
+
failed: 500
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/constants/webPrompts.ts
|
|
18
|
+
const API_BASE_PATH = "prompts";
|
|
19
|
+
const PROMPTS_PATH = "/prompts";
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/types/apiRoutes.ts
|
|
22
|
+
/**
|
|
23
|
+
* This package's routes, as data.
|
|
24
|
+
*
|
|
25
|
+
* No scope and no base path. The build reads both off
|
|
26
|
+
* `src/extensions/(backend)/api/prompts/`, so the mount is stated once, by the
|
|
27
|
+
* folder that creates it. This package stated it three times before: a
|
|
28
|
+
* constant, and the literal `prompts` twice more inside a URL builder that also
|
|
29
|
+
* decided, on its own, whether a call was global or session scoped.
|
|
30
|
+
*
|
|
31
|
+
* The Hono app registers these paths and the browser addresses them, so a path
|
|
32
|
+
* cannot move on one side alone.
|
|
33
|
+
*
|
|
34
|
+
* `:name` is Hono's own parameter syntax, because the app registers `path`
|
|
35
|
+
* verbatim, and the client fills it from `params` on the call.
|
|
36
|
+
*/
|
|
37
|
+
var apiRoutes_default = defineApiRoutes({
|
|
38
|
+
list: {
|
|
39
|
+
method: "GET",
|
|
40
|
+
path: PROMPTS_PATH,
|
|
41
|
+
response: apiResponse()
|
|
42
|
+
},
|
|
43
|
+
save: {
|
|
44
|
+
method: "PUT",
|
|
45
|
+
path: `${PROMPTS_PATH}/:${NAME_PARAM}`,
|
|
46
|
+
response: apiResponse()
|
|
47
|
+
},
|
|
48
|
+
/** The same path as `save`; the method is the whole of the difference. */
|
|
49
|
+
remove: {
|
|
50
|
+
method: "DELETE",
|
|
51
|
+
path: `${PROMPTS_PATH}/:${NAME_PARAM}`
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/services/promptsApi/index.ts
|
|
56
|
+
function toView(prompt) {
|
|
57
|
+
return {
|
|
58
|
+
name: prompt.name,
|
|
59
|
+
description: prompt.description,
|
|
60
|
+
text: prompt.text
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function failureMessage(error) {
|
|
64
|
+
return error instanceof Error ? error.message : "The prompt library could not complete that request.";
|
|
65
|
+
}
|
|
66
|
+
/** Reads `{ text }` out of a request body, or the reason it is unusable. */
|
|
67
|
+
async function readText(request) {
|
|
68
|
+
let payload;
|
|
69
|
+
try {
|
|
70
|
+
payload = await request.json();
|
|
71
|
+
} catch {
|
|
72
|
+
return { error: "The request body must be JSON." };
|
|
73
|
+
}
|
|
74
|
+
const text = payload?.text;
|
|
75
|
+
if (typeof text !== "string" || text.trim().length === 0) return { error: "A non-empty text is required." };
|
|
76
|
+
if (Buffer.byteLength(text, "utf8") > 65536) return { error: "That prompt is too large to save." };
|
|
77
|
+
return { text };
|
|
78
|
+
}
|
|
79
|
+
function createPromptHubApi(options = {}) {
|
|
80
|
+
const store = options.store ?? createNodeSavedPromptStore();
|
|
81
|
+
const app = new Hono();
|
|
82
|
+
app.get(apiRoutes_default.list.path, async (context) => {
|
|
83
|
+
try {
|
|
84
|
+
const prompts = await store.list();
|
|
85
|
+
return context.json({ prompts: prompts.map(toView) });
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
app.put(apiRoutes_default.save.path, async (context) => {
|
|
91
|
+
const name = context.req.param(NAME_PARAM);
|
|
92
|
+
if (!isValidPromptName(name)) return context.json({ error: `"${name}" is not a usable prompt name. Use ${PROMPT_NAME_RULE}.` }, STATUS.badRequest);
|
|
93
|
+
const body = await readText(context.req.raw);
|
|
94
|
+
if ("error" in body) {
|
|
95
|
+
const status = body.error.includes("too large") ? STATUS.tooLarge : STATUS.badRequest;
|
|
96
|
+
return context.json({ error: body.error }, status);
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const replaced = await store.has(name);
|
|
100
|
+
const prompt = {
|
|
101
|
+
name,
|
|
102
|
+
description: describePrompt(body.text),
|
|
103
|
+
text: body.text
|
|
104
|
+
};
|
|
105
|
+
await store.save(prompt);
|
|
106
|
+
return context.json({
|
|
107
|
+
prompt: toView(prompt),
|
|
108
|
+
replaced
|
|
109
|
+
});
|
|
110
|
+
} catch (error) {
|
|
111
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
app.delete(apiRoutes_default.remove.path, async (context) => {
|
|
115
|
+
const name = context.req.param(NAME_PARAM);
|
|
116
|
+
if (!isValidPromptName(name)) return context.json({ error: `"${name}" is not a usable prompt name.` }, STATUS.badRequest);
|
|
117
|
+
try {
|
|
118
|
+
if (!await store.remove(name)) return context.json({ error: `No saved prompt is named "${name}".` }, STATUS.notFound);
|
|
119
|
+
return context.json({ name });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
return app;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/extensions/(backend)/api/prompts/route.server.ts
|
|
128
|
+
/**
|
|
129
|
+
* Mounts this package's HTTP API at `prompts`, which the folder names.
|
|
130
|
+
*
|
|
131
|
+
* The folder is the declaration: the build reads the base path off it and hands
|
|
132
|
+
* the browser a client bound to the same segment, so the mount is stated once
|
|
133
|
+
* rather than in a constant, a URL builder and a story stub that were each free
|
|
134
|
+
* to drift.
|
|
135
|
+
*/
|
|
136
|
+
var route_server_default = defineRoute({
|
|
137
|
+
basePath: API_BASE_PATH,
|
|
138
|
+
start(_context) {
|
|
139
|
+
const app = createPromptHubApi();
|
|
140
|
+
return {
|
|
141
|
+
fetch: (request) => app.fetch(request),
|
|
142
|
+
close: () => void 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
//#endregion
|
|
147
|
+
//#region src/constants/prompts.ts
|
|
148
|
+
const COMMAND_NAME = "prompts";
|
|
149
|
+
const SERVER_COMMAND_DESCRIPTION = "List saved prompts or run one by name.";
|
|
150
|
+
//#endregion
|
|
151
|
+
//#region src/services/savedPrompts/index.ts
|
|
152
|
+
async function savedPrompts() {
|
|
153
|
+
const directory = resolvePromptsDirectory();
|
|
154
|
+
try {
|
|
155
|
+
const { readdir } = await import("node:fs/promises");
|
|
156
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
157
|
+
const prompts = [];
|
|
158
|
+
for (const entry of entries.filter((candidate) => candidate.isFile() && candidate.name.endsWith(".md")).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
159
|
+
const name = entry.name.slice(0, -3);
|
|
160
|
+
prompts.push(parsePromptDocument(name, await readFile(`${directory}/${entry.name}`, "utf8")));
|
|
161
|
+
}
|
|
162
|
+
return prompts;
|
|
163
|
+
} catch {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//#endregion
|
|
168
|
+
//#region src/extensions/workspaces/sessions/(backend)/command/prompts.server.ts
|
|
169
|
+
var prompts_server_default$1 = defineServerCommand({
|
|
170
|
+
name: COMMAND_NAME,
|
|
171
|
+
description: SERVER_COMMAND_DESCRIPTION,
|
|
172
|
+
async execute(args, execution) {
|
|
173
|
+
const prompts = await savedPrompts();
|
|
174
|
+
const requested = args.trim();
|
|
175
|
+
if (!requested) {
|
|
176
|
+
await execution.client.notify({
|
|
177
|
+
title: "Po prompts",
|
|
178
|
+
body: prompts.map((prompt) => `/${prompt.name}: ${prompt.description}`).join("\n") || "(no saved prompts)",
|
|
179
|
+
level: "info"
|
|
180
|
+
});
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const prompt = prompts.find((candidate) => candidate.name === requested);
|
|
184
|
+
if (!prompt) {
|
|
185
|
+
await execution.client.notify({
|
|
186
|
+
body: `Saved prompt not found: ${requested}`,
|
|
187
|
+
level: "warning"
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
await execution.session.prompt(prompt.text);
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server.ts
|
|
196
|
+
var po_use_prompt_server_default = defineResource({
|
|
197
|
+
name: "po-use-prompt",
|
|
198
|
+
when: DOOM_HELP_WHEN,
|
|
199
|
+
kind: "skill",
|
|
200
|
+
read: () => readPackageResource(import.meta.url, "src/prompts/po-use-prompt/SKILL.md")
|
|
201
|
+
});
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/prompts.server.ts
|
|
204
|
+
var prompts_server_default = defineResource({
|
|
205
|
+
name: "po/prompts",
|
|
206
|
+
kind: "prompt",
|
|
207
|
+
read: async () => JSON.stringify(await savedPrompts(), null, 2)
|
|
208
|
+
});
|
|
209
|
+
//#endregion
|
|
210
|
+
//#region generated/server.ts
|
|
211
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
212
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
213
|
+
...identity,
|
|
214
|
+
...value
|
|
215
|
+
};
|
|
216
|
+
const facet = defineServerPlugin({
|
|
217
|
+
name: "@agimon-ai/po-prompt",
|
|
218
|
+
global: (context) => ({ get api() {
|
|
219
|
+
return [at(route_server_default, context)];
|
|
220
|
+
} }),
|
|
221
|
+
workspace: (context) => ({ get api() {
|
|
222
|
+
return [at(route_server_default, context)];
|
|
223
|
+
} }),
|
|
224
|
+
session: (context) => ({
|
|
225
|
+
get api() {
|
|
226
|
+
return [at(route_server_default, context)];
|
|
227
|
+
},
|
|
228
|
+
get commands() {
|
|
229
|
+
return [via({ name: "prompts" }, at(prompts_server_default$1, context))];
|
|
230
|
+
},
|
|
231
|
+
get resources() {
|
|
232
|
+
return [at(po_use_prompt_server_default, context), at(prompts_server_default, context)];
|
|
233
|
+
}
|
|
234
|
+
})
|
|
235
|
+
});
|
|
236
|
+
//#endregion
|
|
237
|
+
export { facet as default, facet };
|
|
238
|
+
|
|
239
|
+
//# sourceMappingURL=server.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.mjs","names":["routes","apiRoute","commandPrompts","resourcePoUsePrompt","resourcePrompts"],"sources":["../../src/constants/promptsApi.ts","../../src/constants/webPrompts.ts","../../src/types/apiRoutes.ts","../../src/services/promptsApi/index.ts","../../src/extensions/(backend)/api/prompts/route.server.ts","../../src/constants/prompts.ts","../../src/services/savedPrompts/index.ts","../../src/services/serverPrompts/index.ts","../../src/extensions/workspaces/sessions/(backend)/command/prompts.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server.ts","../../src/extensions/workspaces/sessions/(backend)/resource/prompts.server.ts","../../generated/server.ts"],"sourcesContent":["export const NAME_PARAM = 'name';\nexport const MAX_PROMPT_BYTES = 65_536;\nexport const STATUS = { badRequest: 400, notFound: 404, tooLarge: 413, failed: 500 } as const;\n","export const API_BASE_PATH = 'prompts';\nexport const PROMPTS_PATH = '/prompts';\n","import { apiResponse, defineApiRoutes } from '@agimon-ai/po-core/web';\n\nimport { NAME_PARAM } from '../constants/promptsApi';\nimport { PROMPTS_PATH } from '../constants/webPrompts';\nimport type { SavedPromptListResponse, SavedPromptWriteResponse } from './webPrompts';\n\n/**\n * This package's routes, as data.\n *\n * No scope and no base path. The build reads both off\n * `src/extensions/(backend)/api/prompts/`, so the mount is stated once, by the\n * folder that creates it. This package stated it three times before: a\n * constant, and the literal `prompts` twice more inside a URL builder that also\n * decided, on its own, whether a call was global or session scoped.\n *\n * The Hono app registers these paths and the browser addresses them, so a path\n * cannot move on one side alone.\n *\n * `:name` is Hono's own parameter syntax, because the app registers `path`\n * verbatim, and the client fills it from `params` on the call.\n */\nexport default defineApiRoutes({\n list: {\n method: 'GET',\n path: PROMPTS_PATH,\n response: apiResponse<SavedPromptListResponse>(),\n },\n save: {\n method: 'PUT',\n path: `${PROMPTS_PATH}/:${NAME_PARAM}`,\n response: apiResponse<SavedPromptWriteResponse>(),\n },\n /** The same path as `save`; the method is the whole of the difference. */\n remove: {\n method: 'DELETE',\n path: `${PROMPTS_PATH}/:${NAME_PARAM}`,\n },\n});\n","import type { DoomApi, DoomApiContext, DoomApiHandler } from '@agimon-ai/po-core/packageApi';\nimport { Hono } from 'hono';\n\nimport { NAME_PARAM, MAX_PROMPT_BYTES, STATUS } from '../../constants/promptsApi';\nimport { PROMPT_NAME_RULE } from '../../constants/savedPromptDocument';\nimport { API_BASE_PATH } from '../../constants/webPrompts';\nimport { createNodeSavedPromptStore } from '../../services/promptStore';\nimport { describePrompt, isValidPromptName } from '../../services/savedPromptDocument';\nimport routes from '../../types/apiRoutes';\nimport type { SavedPrompt, SavedPromptStore } from '../../types/prompt';\nimport {\n type SavedPromptListResponse,\n type SavedPromptView,\n type SavedPromptWriteResponse,\n} from '../../types/webPrompts';\n\n/**\n * This package's HTTP surface, served by the cockpit hub.\n *\n * DESIGN PATTERNS:\n * - Hub scope, not session scope: saved prompts live in the agent directory and\n * belong to the machine, so no route names a session.\n * - The store is injected. The same port the Pi commands write through answers\n * the browser, so the two surfaces cannot disagree about the format on disk.\n * - Paths come from src/types/apiRoutes, the one table the browser reads too,\n * so this app and the cockpit cannot disagree about where a route lives.\n * They stay relative to the mount the host strips.\n *\n * AVOID:\n * - Validating names here by hand. The rule lives in src/services with the\n * document format it protects.\n */\n\nexport interface HubApiOptions {\n store?: SavedPromptStore;\n}\n\nfunction toView(prompt: SavedPrompt): SavedPromptView {\n return { name: prompt.name, description: prompt.description, text: prompt.text };\n}\n\nfunction failureMessage(error: unknown): string {\n return error instanceof Error ? error.message : 'The prompt library could not complete that request.';\n}\n\n/** Reads `{ text }` out of a request body, or the reason it is unusable. */\nasync function readText(request: Request): Promise<{ text: string } | { error: string }> {\n let payload: unknown;\n try {\n payload = await request.json();\n } catch {\n // A body that is not JSON is a client mistake, reported as one.\n return { error: 'The request body must be JSON.' };\n }\n const text = (payload as { text?: unknown } | null)?.text;\n if (typeof text !== 'string' || text.trim().length === 0) return { error: 'A non-empty text is required.' };\n if (Buffer.byteLength(text, 'utf8') > MAX_PROMPT_BYTES) return { error: 'That prompt is too large to save.' };\n return { text };\n}\n\nexport function createPromptHubApi(options: HubApiOptions = {}): Hono {\n const store = options.store ?? createNodeSavedPromptStore();\n const app = new Hono();\n\n app.get(routes.list.path, async (context) => {\n try {\n const prompts = await store.list();\n return context.json<SavedPromptListResponse>({ prompts: prompts.map(toView) });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n app.put(routes.save.path, async (context) => {\n const name = context.req.param(NAME_PARAM);\n if (!isValidPromptName(name)) {\n return context.json(\n { error: `\"${name}\" is not a usable prompt name. Use ${PROMPT_NAME_RULE}.` },\n STATUS.badRequest,\n );\n }\n\n const body = await readText(context.req.raw);\n if ('error' in body) {\n const status = body.error.includes('too large') ? STATUS.tooLarge : STATUS.badRequest;\n return context.json({ error: body.error }, status);\n }\n\n try {\n const replaced = await store.has(name);\n const prompt: SavedPrompt = { name, description: describePrompt(body.text), text: body.text };\n await store.save(prompt);\n return context.json<SavedPromptWriteResponse>({ prompt: toView(prompt), replaced });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n app.delete(routes.remove.path, async (context) => {\n const name = context.req.param(NAME_PARAM);\n if (!isValidPromptName(name)) {\n return context.json({ error: `\"${name}\" is not a usable prompt name.` }, STATUS.badRequest);\n }\n\n try {\n const removed = await store.remove(name);\n if (!removed) return context.json({ error: `No saved prompt is named \"${name}\".` }, STATUS.notFound);\n return context.json({ name });\n } catch (error) {\n return context.json({ error: failureMessage(error) }, STATUS.failed);\n }\n });\n\n return app;\n}\n\n/** The named export a host imports from this package's built entry. */\nexport const api: DoomApi = {\n basePath: API_BASE_PATH,\n start(_context: DoomApiContext): DoomApiHandler {\n const app = createPromptHubApi();\n return {\n fetch: (request) => app.fetch(request),\n // Nothing outlives a request here; the store holds no handles.\n close: () => undefined,\n };\n },\n};\n","import { defineRoute } from '@agimon-ai/po-core/extensionFile';\n\nimport { api } from '../../../../services/promptsApi';\n\n/**\n * Mounts this package's HTTP API at `prompts`, which the folder names.\n *\n * The folder is the declaration: the build reads the base path off it and hands\n * the browser a client bound to the same segment, so the mount is stated once\n * rather than in a constant, a URL builder and a story stub that were each free\n * to drift.\n */\nexport default defineRoute(api);\n","export const COMMAND_NAME = 'prompts';\nexport const COMMAND_DESCRIPTION = 'Browse staged and saved prompts';\nexport const SERVER_COMMAND_DESCRIPTION = 'List saved prompts or run one by name.';\n","import { readFile } from 'node:fs/promises';\n\nimport { resolvePromptsDirectory } from '../promptStore';\nimport { parsePromptDocument } from '../savedPromptDocument';\n\nexport async function savedPrompts(): Promise<readonly { name: string; text: string; description: string }[]> {\n const directory = resolvePromptsDirectory();\n try {\n const { readdir } = await import('node:fs/promises');\n const entries = await readdir(directory, { withFileTypes: true });\n const prompts = [] as { name: string; text: string; description: string }[];\n for (const entry of entries\n .filter((candidate) => candidate.isFile() && candidate.name.endsWith('.md'))\n .sort((a, b) => a.name.localeCompare(b.name))) {\n const name = entry.name.slice(0, -3);\n prompts.push(parsePromptDocument(name, await readFile(`${directory}/${entry.name}`, 'utf8')));\n }\n return prompts;\n } catch {\n return [];\n }\n}\n","import type { DoomHeadlessCommand } from '@agimon-ai/po-core/headless';\n\nimport { COMMAND_NAME, SERVER_COMMAND_DESCRIPTION } from '../../constants/prompts';\nimport { savedPrompts } from '../../services/savedPrompts';\nexport const serverPromptCommand: DoomHeadlessCommand = {\n name: COMMAND_NAME,\n description: SERVER_COMMAND_DESCRIPTION,\n async execute(args, execution) {\n const prompts = await savedPrompts();\n const requested = args.trim();\n if (!requested) {\n await execution.client.notify({\n title: 'Po prompts',\n body: prompts.map((prompt) => `/${prompt.name}: ${prompt.description}`).join('\\n') || '(no saved prompts)',\n level: 'info',\n });\n return;\n }\n const prompt = prompts.find((candidate) => candidate.name === requested);\n if (!prompt) {\n await execution.client.notify({ body: `Saved prompt not found: ${requested}`, level: 'warning' });\n return;\n }\n await execution.session.prompt(prompt.text);\n },\n};\n","import { defineServerCommand } from '@agimon-ai/po-core/extensionFile';\n\nimport { serverPromptCommand } from '../../../../../services/serverPrompts';\nexport default defineServerCommand(serverPromptCommand);\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\nimport { DOOM_HELP_WHEN } from '@agimon-ai/po-core/help';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineResource({\n name: 'po-use-prompt',\n when: DOOM_HELP_WHEN,\n kind: 'skill' as const,\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-prompt/SKILL.md'),\n});\n","import { defineResource } from '@agimon-ai/po-core/extensionFile';\n\nimport { savedPrompts } from '../../../../../services/savedPrompts';\nexport default defineResource({\n name: 'po/prompts',\n kind: 'prompt' as const,\n read: async () => JSON.stringify(await savedPrompts(), null, 2),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineServerPlugin, type DoomServerSessionPlugin } from '@agimon-ai/po-core/serverFacet';\n\nimport apiRoute from '../src/extensions/(backend)/api/prompts/route.server';\nimport commandPrompts from '../src/extensions/workspaces/sessions/(backend)/command/prompts.server';\nimport resourcePoUsePrompt from '../src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server';\nimport resourcePrompts from '../src/extensions/workspaces/sessions/(backend)/resource/prompts.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 facet = defineServerPlugin({\n name: '@agimon-ai/po-prompt',\n global: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n workspace: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n }),\n session: (context) => ({\n get api(): DoomServerSessionPlugin['api'] { return [at(apiRoute, context)]; },\n get commands(): DoomServerSessionPlugin['commands'] { return [via({ name: 'prompts' }, at(commandPrompts, context))]; },\n get resources(): DoomServerSessionPlugin['resources'] { return [at(resourcePoUsePrompt, context), at(resourcePrompts, context)]; },\n }),\n});\n\nexport default facet;\n"],"mappings":"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"}
|