@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vuong Ngo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# @agimon-ai/po-prompt
|
|
2
|
+
|
|
3
|
+
Staged recent prompts and saved prompt templates for Po.
|
|
4
|
+
|
|
5
|
+
This package is a composable [Po](https://www.npmjs.com/package/@agimon-ai/po) subsystem.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node.js 24 or newer
|
|
10
|
+
- `@earendil-works/pi-coding-agent` 0.85.0
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Po users can
|
|
15
|
+
add `@agimon-ai/po-prompt` to `default.packages` or a selected layer's `packages` list in
|
|
16
|
+
`.po/modes.yaml`.
|
|
17
|
+
|
|
18
|
+
## Cockpit
|
|
19
|
+
|
|
20
|
+
The package contributes a `Prompt template` entry to the composer's `+` menu, beside `File Upload`,
|
|
21
|
+
backed by a hub-scoped API at `/api/plugin/prompts`. The entry opens a list-first dialog over the
|
|
22
|
+
conversation, and picking one sends it immediately to the focused session. The same dialog creates
|
|
23
|
+
and edits entries, confirms replacements and removals, and refreshes the list after writes. Every
|
|
24
|
+
text-bearing user message also offers `save as prompt`, opening the editor with that message text
|
|
25
|
+
ready to name or edit. The dialog itself is a cockpit overlay rather than part of the menu, so the
|
|
26
|
+
message action reaches it without the menu being open.
|
|
27
|
+
|
|
28
|
+
| Route | Purpose |
|
|
29
|
+
| ----------------------- | ------------------------------------------------------------------- |
|
|
30
|
+
| `GET /prompts` | Every saved prompt, sorted by name |
|
|
31
|
+
| `PUT /prompts/:name` | Create or replace one, deriving its description from the first line |
|
|
32
|
+
| `DELETE /prompts/:name` | Remove one |
|
|
33
|
+
|
|
34
|
+
The API is hub-scoped because saved prompts belong to the agent directory rather than to a session.
|
|
35
|
+
Staged prompts are not exposed there: they live in the memory of the session that received them.
|
|
36
|
+
|
|
37
|
+
The cockpit hub mounts package APIs from the route table `po sync` generates. After installing
|
|
38
|
+
or changing this package, run a build and `po sync`, then restart the hub, or its routes answer 404.
|
|
39
|
+
|
|
40
|
+
## Help
|
|
41
|
+
|
|
42
|
+
The published package includes `llms.txt` and the package-owned `src/prompts/po-use-prompt/SKILL.md`. When the Po Help minor mode is active, the extension contributes `po-use-prompt` to its live Help catalog. The contribution follows Help provider replacement and is withdrawn when the extension shuts down.
|
|
43
|
+
|
|
44
|
+
## Public API
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
import { createNodeSavedPromptStore, createRecentPrompts } from '@agimon-ai/po-prompt';
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pnpm build
|
|
54
|
+
pnpm typecheck
|
|
55
|
+
pnpm test
|
|
56
|
+
pnpm lint
|
|
57
|
+
pnpm exec vibe-lint check .
|
|
58
|
+
npm pack --dry-run
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Maintained by [Agimon](https://agimon.ai/about).
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
MIT
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
let _agimon_ai_po_core_apiContracts = require("@agimon-ai/po-core/apiContracts");
|
|
6
|
+
let typebox = require("typebox");
|
|
7
|
+
//#region src/schemas/apiContracts.ts
|
|
8
|
+
const S = typebox.Type.String();
|
|
9
|
+
const B = typebox.Type.Boolean();
|
|
10
|
+
const Prompt = typebox.Type.Object({
|
|
11
|
+
name: S,
|
|
12
|
+
description: S,
|
|
13
|
+
text: S
|
|
14
|
+
});
|
|
15
|
+
const apiContracts = (0, _agimon_ai_po_core_apiContracts.defineApiContract)({
|
|
16
|
+
version: 1,
|
|
17
|
+
sockets: [],
|
|
18
|
+
dynamic: [],
|
|
19
|
+
http: [
|
|
20
|
+
"global",
|
|
21
|
+
"workspace",
|
|
22
|
+
"session"
|
|
23
|
+
].flatMap((scope) => [
|
|
24
|
+
{
|
|
25
|
+
id: "prompts.list",
|
|
26
|
+
scope,
|
|
27
|
+
basePath: "prompts",
|
|
28
|
+
path: "/prompts",
|
|
29
|
+
method: "GET",
|
|
30
|
+
authentication: "owner",
|
|
31
|
+
description: "List prompts in this scope.",
|
|
32
|
+
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(typebox.Type.Object({ prompts: typebox.Type.Array(Prompt) }))
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "prompts.save",
|
|
36
|
+
scope,
|
|
37
|
+
basePath: "prompts",
|
|
38
|
+
path: "/prompts/{name}",
|
|
39
|
+
method: "PUT",
|
|
40
|
+
authentication: "owner",
|
|
41
|
+
description: "Save a prompt. Text is limited to 65536 UTF-8 bytes.",
|
|
42
|
+
body: {
|
|
43
|
+
required: true,
|
|
44
|
+
contentType: "application/json",
|
|
45
|
+
schema: typebox.Type.Object({ text: typebox.Type.String({ minLength: 1 }) })
|
|
46
|
+
},
|
|
47
|
+
responses: {
|
|
48
|
+
...(0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(typebox.Type.Object({
|
|
49
|
+
prompt: Prompt,
|
|
50
|
+
replaced: B
|
|
51
|
+
})),
|
|
52
|
+
"413": {
|
|
53
|
+
description: "Prompt text exceeds the byte limit.",
|
|
54
|
+
schema: typebox.Type.Object({ error: S })
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "prompts.delete",
|
|
60
|
+
scope,
|
|
61
|
+
basePath: "prompts",
|
|
62
|
+
path: "/prompts/{name}",
|
|
63
|
+
method: "DELETE",
|
|
64
|
+
authentication: "owner",
|
|
65
|
+
description: "Delete a prompt.",
|
|
66
|
+
responses: (0, _agimon_ai_po_core_apiContracts.jsonApiResponses)(typebox.Type.Object({ name: S }))
|
|
67
|
+
}
|
|
68
|
+
])
|
|
69
|
+
});
|
|
70
|
+
//#endregion
|
|
71
|
+
exports.apiContracts = apiContracts;
|
|
72
|
+
exports.default = apiContracts;
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=apiContracts.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.cjs","names":["Type","defineApiContract","jsonApiResponses"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst B = Type.Boolean();\nconst Prompt = Type.Object({ name: S, description: S, text: S });\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: (['global', 'workspace', 'session'] as const).flatMap((scope) => [\n {\n id: 'prompts.list',\n scope,\n basePath: 'prompts',\n path: '/prompts',\n method: 'GET',\n authentication: 'owner',\n description: 'List prompts in this scope.',\n responses: jsonApiResponses(Type.Object({ prompts: Type.Array(Prompt) })),\n },\n {\n id: 'prompts.save',\n scope,\n basePath: 'prompts',\n path: '/prompts/{name}',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a prompt. Text is limited to 65536 UTF-8 bytes.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: {\n ...jsonApiResponses(Type.Object({ prompt: Prompt, replaced: B })),\n '413': { description: 'Prompt text exceeds the byte limit.', schema: Type.Object({ error: S }) },\n },\n },\n {\n id: 'prompts.delete',\n scope,\n basePath: 'prompts',\n path: '/prompts/{name}',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a prompt.',\n responses: jsonApiResponses(Type.Object({ name: S })),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":";;;;;;;AAGA,MAAM,IAAIA,QAAAA,KAAK,OAAO;AACtB,MAAM,IAAIA,QAAAA,KAAK,QAAQ;AACvB,MAAM,SAASA,QAAAA,KAAK,OAAO;CAAE,MAAM;CAAG,aAAa;CAAG,MAAM;AAAE,CAAC;AAC/D,MAAa,gBAAA,GAAeC,gCAAAA,kBAAAA,CAAkB;CAC5C,SAAS;CACT,SAAS,CAAC;CACV,SAAS,CAAC;CACV,MAAO;EAAC;EAAU;EAAa;CAAS,CAAC,CAAW,SAAS,UAAU;EACrE;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,YAAA,GAAWC,gCAAAA,iBAAAA,CAAiBF,QAAAA,KAAK,OAAO,EAAE,SAASA,QAAAA,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;EAC1E;EACA;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,MAAM;IACJ,UAAU;IACV,aAAa;IACb,QAAQA,QAAAA,KAAK,OAAO,EAAE,MAAMA,QAAAA,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;GAC7D;GACA,WAAW;IACT,IAAA,GAAGE,gCAAAA,iBAAAA,CAAiBF,QAAAA,KAAK,OAAO;KAAE,QAAQ;KAAQ,UAAU;IAAE,CAAC,CAAC;IAChE,OAAO;KAAE,aAAa;KAAuC,QAAQA,QAAAA,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC;IAAE;GACjG;EACF;EACA;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,YAAA,GAAWE,gCAAAA,iBAAAA,CAAiBF,QAAAA,KAAK,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;EACtD;CACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/schemas/apiContracts.d.ts
|
|
2
|
+
export declare const apiContracts: {
|
|
3
|
+
version: 1;
|
|
4
|
+
protocols?: Record<string, string> | undefined;
|
|
5
|
+
schemas?: Record<string, boolean | object> | undefined;
|
|
6
|
+
http: {
|
|
7
|
+
id: string;
|
|
8
|
+
scope: "global" | "session" | "workspace";
|
|
9
|
+
basePath?: string | undefined;
|
|
10
|
+
path: string;
|
|
11
|
+
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
12
|
+
description: string;
|
|
13
|
+
availability?: string | undefined;
|
|
14
|
+
authentication: "device" | "none" | "owner";
|
|
15
|
+
parameters?: {
|
|
16
|
+
name: string;
|
|
17
|
+
in: "header" | "path" | "query";
|
|
18
|
+
required: boolean;
|
|
19
|
+
schema: boolean | object;
|
|
20
|
+
}[] | undefined;
|
|
21
|
+
body?: {
|
|
22
|
+
contentType: string;
|
|
23
|
+
contentTypes?: string[] | undefined;
|
|
24
|
+
required: boolean;
|
|
25
|
+
schema: boolean | object;
|
|
26
|
+
} | undefined;
|
|
27
|
+
responses: Record<string, {
|
|
28
|
+
description: string;
|
|
29
|
+
contentType?: string | undefined;
|
|
30
|
+
schema?: boolean | object | undefined;
|
|
31
|
+
events?: Record<string, boolean | object> | undefined;
|
|
32
|
+
}>;
|
|
33
|
+
}[];
|
|
34
|
+
sockets: {
|
|
35
|
+
id: string;
|
|
36
|
+
scope: "global" | "session" | "workspace";
|
|
37
|
+
description: string;
|
|
38
|
+
availability?: string | undefined;
|
|
39
|
+
service: string;
|
|
40
|
+
member: string;
|
|
41
|
+
direction: "client-to-server" | "server-to-client";
|
|
42
|
+
kind: "channel" | "method" | "state";
|
|
43
|
+
input: boolean | object;
|
|
44
|
+
output?: boolean | object | undefined;
|
|
45
|
+
errors?: boolean | object | undefined;
|
|
46
|
+
}[];
|
|
47
|
+
dynamic: string[];
|
|
48
|
+
gaps?: string[] | undefined;
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { apiContracts as default };
|
|
52
|
+
//# sourceMappingURL=apiContracts.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";qBAMa"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { defineApiContract, jsonApiResponses } from "@agimon-ai/po-core/apiContracts";
|
|
2
|
+
import { Type } from "typebox";
|
|
3
|
+
//#region src/schemas/apiContracts.ts
|
|
4
|
+
const S = Type.String();
|
|
5
|
+
const B = Type.Boolean();
|
|
6
|
+
const Prompt = Type.Object({
|
|
7
|
+
name: S,
|
|
8
|
+
description: S,
|
|
9
|
+
text: S
|
|
10
|
+
});
|
|
11
|
+
const apiContracts = defineApiContract({
|
|
12
|
+
version: 1,
|
|
13
|
+
sockets: [],
|
|
14
|
+
dynamic: [],
|
|
15
|
+
http: [
|
|
16
|
+
"global",
|
|
17
|
+
"workspace",
|
|
18
|
+
"session"
|
|
19
|
+
].flatMap((scope) => [
|
|
20
|
+
{
|
|
21
|
+
id: "prompts.list",
|
|
22
|
+
scope,
|
|
23
|
+
basePath: "prompts",
|
|
24
|
+
path: "/prompts",
|
|
25
|
+
method: "GET",
|
|
26
|
+
authentication: "owner",
|
|
27
|
+
description: "List prompts in this scope.",
|
|
28
|
+
responses: jsonApiResponses(Type.Object({ prompts: Type.Array(Prompt) }))
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "prompts.save",
|
|
32
|
+
scope,
|
|
33
|
+
basePath: "prompts",
|
|
34
|
+
path: "/prompts/{name}",
|
|
35
|
+
method: "PUT",
|
|
36
|
+
authentication: "owner",
|
|
37
|
+
description: "Save a prompt. Text is limited to 65536 UTF-8 bytes.",
|
|
38
|
+
body: {
|
|
39
|
+
required: true,
|
|
40
|
+
contentType: "application/json",
|
|
41
|
+
schema: Type.Object({ text: Type.String({ minLength: 1 }) })
|
|
42
|
+
},
|
|
43
|
+
responses: {
|
|
44
|
+
...jsonApiResponses(Type.Object({
|
|
45
|
+
prompt: Prompt,
|
|
46
|
+
replaced: B
|
|
47
|
+
})),
|
|
48
|
+
"413": {
|
|
49
|
+
description: "Prompt text exceeds the byte limit.",
|
|
50
|
+
schema: Type.Object({ error: S })
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "prompts.delete",
|
|
56
|
+
scope,
|
|
57
|
+
basePath: "prompts",
|
|
58
|
+
path: "/prompts/{name}",
|
|
59
|
+
method: "DELETE",
|
|
60
|
+
authentication: "owner",
|
|
61
|
+
description: "Delete a prompt.",
|
|
62
|
+
responses: jsonApiResponses(Type.Object({ name: S }))
|
|
63
|
+
}
|
|
64
|
+
])
|
|
65
|
+
});
|
|
66
|
+
//#endregion
|
|
67
|
+
export { apiContracts, apiContracts as default };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=apiContracts.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract, jsonApiResponses } from '@agimon-ai/po-core/apiContracts';\nimport { Type } from 'typebox';\n\nconst S = Type.String();\nconst B = Type.Boolean();\nconst Prompt = Type.Object({ name: S, description: S, text: S });\nexport const apiContracts = defineApiContract({\n version: 1,\n sockets: [],\n dynamic: [],\n http: (['global', 'workspace', 'session'] as const).flatMap((scope) => [\n {\n id: 'prompts.list',\n scope,\n basePath: 'prompts',\n path: '/prompts',\n method: 'GET',\n authentication: 'owner',\n description: 'List prompts in this scope.',\n responses: jsonApiResponses(Type.Object({ prompts: Type.Array(Prompt) })),\n },\n {\n id: 'prompts.save',\n scope,\n basePath: 'prompts',\n path: '/prompts/{name}',\n method: 'PUT',\n authentication: 'owner',\n description: 'Save a prompt. Text is limited to 65536 UTF-8 bytes.',\n body: {\n required: true,\n contentType: 'application/json',\n schema: Type.Object({ text: Type.String({ minLength: 1 }) }),\n },\n responses: {\n ...jsonApiResponses(Type.Object({ prompt: Prompt, replaced: B })),\n '413': { description: 'Prompt text exceeds the byte limit.', schema: Type.Object({ error: S }) },\n },\n },\n {\n id: 'prompts.delete',\n scope,\n basePath: 'prompts',\n path: '/prompts/{name}',\n method: 'DELETE',\n authentication: 'owner',\n description: 'Delete a prompt.',\n responses: jsonApiResponses(Type.Object({ name: S })),\n },\n ]),\n});\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAM,IAAI,KAAK,OAAO;AACtB,MAAM,IAAI,KAAK,QAAQ;AACvB,MAAM,SAAS,KAAK,OAAO;CAAE,MAAM;CAAG,aAAa;CAAG,MAAM;AAAE,CAAC;AAC/D,MAAa,eAAe,kBAAkB;CAC5C,SAAS;CACT,SAAS,CAAC;CACV,SAAS,CAAC;CACV,MAAO;EAAC;EAAU;EAAa;CAAS,CAAC,CAAW,SAAS,UAAU;EACrE;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,WAAW,iBAAiB,KAAK,OAAO,EAAE,SAAS,KAAK,MAAM,MAAM,EAAE,CAAC,CAAC;EAC1E;EACA;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,MAAM;IACJ,UAAU;IACV,aAAa;IACb,QAAQ,KAAK,OAAO,EAAE,MAAM,KAAK,OAAO,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;GAC7D;GACA,WAAW;IACT,GAAG,iBAAiB,KAAK,OAAO;KAAE,QAAQ;KAAQ,UAAU;IAAE,CAAC,CAAC;IAChE,OAAO;KAAE,aAAa;KAAuC,QAAQ,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC;IAAE;GACjG;EACF;EACA;GACE,IAAI;GACJ;GACA,UAAU;GACV,MAAM;GACN,QAAQ;GACR,gBAAgB;GAChB,aAAa;GACb,WAAW,iBAAiB,KAAK,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;EACtD;CACF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
let _agimon_ai_po_core_mcpFacet = require("@agimon-ai/po-core/mcpFacet");
|
|
6
|
+
let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
|
|
7
|
+
//#region src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp.ts
|
|
8
|
+
var po_use_prompt_mcp_default = (0, _agimon_ai_po_core_mcpFacet.defineMcpSkill)({
|
|
9
|
+
name: "po-use-prompt",
|
|
10
|
+
description: "Use @agimon-ai/po-prompt: Staged recent prompts and saved prompt templates for Po",
|
|
11
|
+
read: () => (0, _agimon_ai_po_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/po-use-prompt/SKILL.md")
|
|
12
|
+
});
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region generated/mcp.ts
|
|
15
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
16
|
+
const mcp = (0, _agimon_ai_po_core_mcpFacet.defineMcpPlugin)({
|
|
17
|
+
name: "@agimon-ai/po-prompt",
|
|
18
|
+
session: (context) => ({ get skills() {
|
|
19
|
+
return [at(po_use_prompt_mcp_default, context)];
|
|
20
|
+
} })
|
|
21
|
+
});
|
|
22
|
+
//#endregion
|
|
23
|
+
exports.default = mcp;
|
|
24
|
+
exports.mcp = mcp;
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=mcp.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.cjs","names":["defineMcpSkill","readPackageResource","defineMcpPlugin","skillPoUsePrompt"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'po-use-prompt',\n description: 'Use @agimon-ai/po-prompt: Staged recent prompts and saved prompt templates for Po',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-prompt/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUsePrompt from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp';\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;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-prompt',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillPoUsePrompt, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;;;;;AAGA,IAAA,6BAAA,GAAeA,4BAAAA,eAAAA,CAAe;CAC5B,MAAM;CACN,aAAa;CACb,aAAA,GAAYC,+BAAAA,oBAAAA,CAAAA,QAAAA,KAAAA,CAAAA,CAAAA,cAAAA,UAAAA,CAAAA,CAAAA,MAAqC,oCAAoC;AACvF,CAAC;;;ACDD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,OAAA,GAAMC,4BAAAA,gBAAAA,CAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGC,2BAAkB,OAAO,CAAC;CAAG,EACzF;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.mts","names":[],"sources":["../../generated/mcp.ts"],"mappings":";qBASa,2CAAG"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineMcpPlugin, defineMcpSkill } from "@agimon-ai/po-core/mcpFacet";
|
|
2
|
+
import { readPackageResource } from "@agimon-ai/po-core/serverFacet";
|
|
3
|
+
//#region src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp.ts
|
|
4
|
+
var po_use_prompt_mcp_default = defineMcpSkill({
|
|
5
|
+
name: "po-use-prompt",
|
|
6
|
+
description: "Use @agimon-ai/po-prompt: Staged recent prompts and saved prompt templates for Po",
|
|
7
|
+
read: () => readPackageResource(import.meta.url, "src/prompts/po-use-prompt/SKILL.md")
|
|
8
|
+
});
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region generated/mcp.ts
|
|
11
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
12
|
+
const mcp = defineMcpPlugin({
|
|
13
|
+
name: "@agimon-ai/po-prompt",
|
|
14
|
+
session: (context) => ({ get skills() {
|
|
15
|
+
return [at(po_use_prompt_mcp_default, context)];
|
|
16
|
+
} })
|
|
17
|
+
});
|
|
18
|
+
//#endregion
|
|
19
|
+
export { mcp as default, mcp };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=mcp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.mjs","names":["skillPoUsePrompt"],"sources":["../../src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp.ts","../../generated/mcp.ts"],"sourcesContent":["import { defineMcpSkill } from '@agimon-ai/po-core/mcpFacet';\nimport { readPackageResource } from '@agimon-ai/po-core/serverFacet';\n\nexport default defineMcpSkill({\n name: 'po-use-prompt',\n description: 'Use @agimon-ai/po-prompt: Staged recent prompts and saved prompt templates for Po',\n read: () => readPackageResource(import.meta.url, 'src/prompts/po-use-prompt/SKILL.md'),\n});\n","// Generated by @agimon-ai/po-build. Do not edit by hand.\nimport { defineMcpPlugin, type DoomMcpSessionPlugin } from '@agimon-ai/po-core/mcpFacet';\n\nimport skillPoUsePrompt from '../src/extensions/workspaces/sessions/(backend)/skill/po-use-prompt.mcp';\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;\n\nexport const mcp = defineMcpPlugin({\n name: '@agimon-ai/po-prompt',\n session: (context) => ({\n get skills(): DoomMcpSessionPlugin['skills'] { return [at(skillPoUsePrompt, context)]; },\n }) satisfies DoomMcpSessionPlugin,\n});\n\nexport default mcp;\n"],"mappings":";;;AAGA,IAAA,4BAAe,eAAe;CAC5B,MAAM;CACN,aAAa;CACb,YAAY,oBAAoB,YAAY,KAAK,oCAAoC;AACvF,CAAC;;;ACDD,MAAM,MAAY,OAA0B,YAC1C,OAAO,UAAU,aAAc,MAAwB,OAAO,IAAI;AAEpE,MAAa,MAAM,gBAAgB;CACjC,MAAM;CACN,UAAU,aAAa,EACrB,IAAI,SAAyC;EAAE,OAAO,CAAC,GAAGA,2BAAkB,OAAO,CAAC;CAAG,EACzF;AACF,CAAC"}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_promptStore = require("../promptStore-Cu4KqaXU.cjs");
|
|
6
|
+
let node_fs_promises = require("node:fs/promises");
|
|
7
|
+
let _agimon_ai_po_core_serverFacet = require("@agimon-ai/po-core/serverFacet");
|
|
8
|
+
let _agimon_ai_po_core_extensionFile = require("@agimon-ai/po-core/extensionFile");
|
|
9
|
+
let hono = require("hono");
|
|
10
|
+
let _agimon_ai_po_core_web = require("@agimon-ai/po-core/web");
|
|
11
|
+
let _agimon_ai_po_core_help = require("@agimon-ai/po-core/help");
|
|
12
|
+
//#region src/constants/promptsApi.ts
|
|
13
|
+
const NAME_PARAM = "name";
|
|
14
|
+
const STATUS = {
|
|
15
|
+
badRequest: 400,
|
|
16
|
+
notFound: 404,
|
|
17
|
+
tooLarge: 413,
|
|
18
|
+
failed: 500
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/constants/webPrompts.ts
|
|
22
|
+
const API_BASE_PATH = "prompts";
|
|
23
|
+
const PROMPTS_PATH = "/prompts";
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/types/apiRoutes.ts
|
|
26
|
+
/**
|
|
27
|
+
* This package's routes, as data.
|
|
28
|
+
*
|
|
29
|
+
* No scope and no base path. The build reads both off
|
|
30
|
+
* `src/extensions/(backend)/api/prompts/`, so the mount is stated once, by the
|
|
31
|
+
* folder that creates it. This package stated it three times before: a
|
|
32
|
+
* constant, and the literal `prompts` twice more inside a URL builder that also
|
|
33
|
+
* decided, on its own, whether a call was global or session scoped.
|
|
34
|
+
*
|
|
35
|
+
* The Hono app registers these paths and the browser addresses them, so a path
|
|
36
|
+
* cannot move on one side alone.
|
|
37
|
+
*
|
|
38
|
+
* `:name` is Hono's own parameter syntax, because the app registers `path`
|
|
39
|
+
* verbatim, and the client fills it from `params` on the call.
|
|
40
|
+
*/
|
|
41
|
+
var apiRoutes_default = (0, _agimon_ai_po_core_web.defineApiRoutes)({
|
|
42
|
+
list: {
|
|
43
|
+
method: "GET",
|
|
44
|
+
path: PROMPTS_PATH,
|
|
45
|
+
response: (0, _agimon_ai_po_core_web.apiResponse)()
|
|
46
|
+
},
|
|
47
|
+
save: {
|
|
48
|
+
method: "PUT",
|
|
49
|
+
path: `${PROMPTS_PATH}/:${NAME_PARAM}`,
|
|
50
|
+
response: (0, _agimon_ai_po_core_web.apiResponse)()
|
|
51
|
+
},
|
|
52
|
+
/** The same path as `save`; the method is the whole of the difference. */
|
|
53
|
+
remove: {
|
|
54
|
+
method: "DELETE",
|
|
55
|
+
path: `${PROMPTS_PATH}/:${NAME_PARAM}`
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/services/promptsApi/index.ts
|
|
60
|
+
function toView(prompt) {
|
|
61
|
+
return {
|
|
62
|
+
name: prompt.name,
|
|
63
|
+
description: prompt.description,
|
|
64
|
+
text: prompt.text
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function failureMessage(error) {
|
|
68
|
+
return error instanceof Error ? error.message : "The prompt library could not complete that request.";
|
|
69
|
+
}
|
|
70
|
+
/** Reads `{ text }` out of a request body, or the reason it is unusable. */
|
|
71
|
+
async function readText(request) {
|
|
72
|
+
let payload;
|
|
73
|
+
try {
|
|
74
|
+
payload = await request.json();
|
|
75
|
+
} catch {
|
|
76
|
+
return { error: "The request body must be JSON." };
|
|
77
|
+
}
|
|
78
|
+
const text = payload?.text;
|
|
79
|
+
if (typeof text !== "string" || text.trim().length === 0) return { error: "A non-empty text is required." };
|
|
80
|
+
if (Buffer.byteLength(text, "utf8") > 65536) return { error: "That prompt is too large to save." };
|
|
81
|
+
return { text };
|
|
82
|
+
}
|
|
83
|
+
function createPromptHubApi(options = {}) {
|
|
84
|
+
const store = options.store ?? require_promptStore.createNodeSavedPromptStore();
|
|
85
|
+
const app = new hono.Hono();
|
|
86
|
+
app.get(apiRoutes_default.list.path, async (context) => {
|
|
87
|
+
try {
|
|
88
|
+
const prompts = await store.list();
|
|
89
|
+
return context.json({ prompts: prompts.map(toView) });
|
|
90
|
+
} catch (error) {
|
|
91
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
app.put(apiRoutes_default.save.path, async (context) => {
|
|
95
|
+
const name = context.req.param(NAME_PARAM);
|
|
96
|
+
if (!require_promptStore.isValidPromptName(name)) return context.json({ error: `"${name}" is not a usable prompt name. Use ${require_promptStore.PROMPT_NAME_RULE}.` }, STATUS.badRequest);
|
|
97
|
+
const body = await readText(context.req.raw);
|
|
98
|
+
if ("error" in body) {
|
|
99
|
+
const status = body.error.includes("too large") ? STATUS.tooLarge : STATUS.badRequest;
|
|
100
|
+
return context.json({ error: body.error }, status);
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const replaced = await store.has(name);
|
|
104
|
+
const prompt = {
|
|
105
|
+
name,
|
|
106
|
+
description: require_promptStore.describePrompt(body.text),
|
|
107
|
+
text: body.text
|
|
108
|
+
};
|
|
109
|
+
await store.save(prompt);
|
|
110
|
+
return context.json({
|
|
111
|
+
prompt: toView(prompt),
|
|
112
|
+
replaced
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
app.delete(apiRoutes_default.remove.path, async (context) => {
|
|
119
|
+
const name = context.req.param(NAME_PARAM);
|
|
120
|
+
if (!require_promptStore.isValidPromptName(name)) return context.json({ error: `"${name}" is not a usable prompt name.` }, STATUS.badRequest);
|
|
121
|
+
try {
|
|
122
|
+
if (!await store.remove(name)) return context.json({ error: `No saved prompt is named "${name}".` }, STATUS.notFound);
|
|
123
|
+
return context.json({ name });
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return context.json({ error: failureMessage(error) }, STATUS.failed);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return app;
|
|
129
|
+
}
|
|
130
|
+
/** The named export a host imports from this package's built entry. */
|
|
131
|
+
const api = {
|
|
132
|
+
basePath: API_BASE_PATH,
|
|
133
|
+
start(_context) {
|
|
134
|
+
const app = createPromptHubApi();
|
|
135
|
+
return {
|
|
136
|
+
fetch: (request) => app.fetch(request),
|
|
137
|
+
close: () => void 0
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
//#endregion
|
|
142
|
+
//#region src/extensions/(backend)/api/prompts/route.server.ts
|
|
143
|
+
/**
|
|
144
|
+
* Mounts this package's HTTP API at `prompts`, which the folder names.
|
|
145
|
+
*
|
|
146
|
+
* The folder is the declaration: the build reads the base path off it and hands
|
|
147
|
+
* the browser a client bound to the same segment, so the mount is stated once
|
|
148
|
+
* rather than in a constant, a URL builder and a story stub that were each free
|
|
149
|
+
* to drift.
|
|
150
|
+
*/
|
|
151
|
+
var route_server_default = (0, _agimon_ai_po_core_extensionFile.defineRoute)(api);
|
|
152
|
+
//#endregion
|
|
153
|
+
//#region src/constants/prompts.ts
|
|
154
|
+
const COMMAND_NAME = "prompts";
|
|
155
|
+
const SERVER_COMMAND_DESCRIPTION = "List saved prompts or run one by name.";
|
|
156
|
+
//#endregion
|
|
157
|
+
//#region src/services/savedPrompts/index.ts
|
|
158
|
+
async function savedPrompts() {
|
|
159
|
+
const directory = require_promptStore.resolvePromptsDirectory();
|
|
160
|
+
try {
|
|
161
|
+
const { readdir } = await import("node:fs/promises");
|
|
162
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
163
|
+
const prompts = [];
|
|
164
|
+
for (const entry of entries.filter((candidate) => candidate.isFile() && candidate.name.endsWith(".md")).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
165
|
+
const name = entry.name.slice(0, -3);
|
|
166
|
+
prompts.push(require_promptStore.parsePromptDocument(name, await (0, node_fs_promises.readFile)(`${directory}/${entry.name}`, "utf8")));
|
|
167
|
+
}
|
|
168
|
+
return prompts;
|
|
169
|
+
} catch {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
174
|
+
//#region src/services/serverPrompts/index.ts
|
|
175
|
+
const serverPromptCommand = {
|
|
176
|
+
name: COMMAND_NAME,
|
|
177
|
+
description: SERVER_COMMAND_DESCRIPTION,
|
|
178
|
+
async execute(args, execution) {
|
|
179
|
+
const prompts = await savedPrompts();
|
|
180
|
+
const requested = args.trim();
|
|
181
|
+
if (!requested) {
|
|
182
|
+
await execution.client.notify({
|
|
183
|
+
title: "Po prompts",
|
|
184
|
+
body: prompts.map((prompt) => `/${prompt.name}: ${prompt.description}`).join("\n") || "(no saved prompts)",
|
|
185
|
+
level: "info"
|
|
186
|
+
});
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const prompt = prompts.find((candidate) => candidate.name === requested);
|
|
190
|
+
if (!prompt) {
|
|
191
|
+
await execution.client.notify({
|
|
192
|
+
body: `Saved prompt not found: ${requested}`,
|
|
193
|
+
level: "warning"
|
|
194
|
+
});
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
await execution.session.prompt(prompt.text);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/extensions/workspaces/sessions/(backend)/command/prompts.server.ts
|
|
202
|
+
var prompts_server_default$1 = (0, _agimon_ai_po_core_extensionFile.defineServerCommand)(serverPromptCommand);
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/po-use-prompt.server.ts
|
|
205
|
+
var po_use_prompt_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
|
|
206
|
+
name: "po-use-prompt",
|
|
207
|
+
when: _agimon_ai_po_core_help.DOOM_HELP_WHEN,
|
|
208
|
+
kind: "skill",
|
|
209
|
+
read: () => (0, _agimon_ai_po_core_serverFacet.readPackageResource)(require("url").pathToFileURL(__filename).href, "src/prompts/po-use-prompt/SKILL.md")
|
|
210
|
+
});
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/extensions/workspaces/sessions/(backend)/resource/prompts.server.ts
|
|
213
|
+
var prompts_server_default = (0, _agimon_ai_po_core_extensionFile.defineResource)({
|
|
214
|
+
name: "po/prompts",
|
|
215
|
+
kind: "prompt",
|
|
216
|
+
read: async () => JSON.stringify(await savedPrompts(), null, 2)
|
|
217
|
+
});
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region generated/server.ts
|
|
220
|
+
const at = (value, context) => typeof value === "function" ? value(context) : value;
|
|
221
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
222
|
+
...identity,
|
|
223
|
+
...value
|
|
224
|
+
};
|
|
225
|
+
const facet = (0, _agimon_ai_po_core_serverFacet.defineServerPlugin)({
|
|
226
|
+
name: "@agimon-ai/po-prompt",
|
|
227
|
+
global: (context) => ({ get api() {
|
|
228
|
+
return [at(route_server_default, context)];
|
|
229
|
+
} }),
|
|
230
|
+
workspace: (context) => ({ get api() {
|
|
231
|
+
return [at(route_server_default, context)];
|
|
232
|
+
} }),
|
|
233
|
+
session: (context) => ({
|
|
234
|
+
get api() {
|
|
235
|
+
return [at(route_server_default, context)];
|
|
236
|
+
},
|
|
237
|
+
get commands() {
|
|
238
|
+
return [via({ name: "prompts" }, at(prompts_server_default$1, context))];
|
|
239
|
+
},
|
|
240
|
+
get resources() {
|
|
241
|
+
return [at(po_use_prompt_server_default, context), at(prompts_server_default, context)];
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
});
|
|
245
|
+
//#endregion
|
|
246
|
+
exports.default = facet;
|
|
247
|
+
exports.facet = facet;
|
|
248
|
+
|
|
249
|
+
//# sourceMappingURL=server.cjs.map
|