@agimon-ai/po-skill 0.0.0-alpha.0 → 0.0.0-stage
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 +2 -39
- package/package.json +3 -132
- package/LICENSE +0 -21
- package/dist/apiContracts.cjs +0 -17
- package/dist/apiContracts.cjs.map +0 -1
- package/dist/apiContracts.d.mts +0 -53
- package/dist/apiContracts.d.mts.map +0 -1
- package/dist/apiContracts.mjs +0 -13
- package/dist/apiContracts.mjs.map +0 -1
- package/dist/catalog.cjs +0 -186
- package/dist/catalog.cjs.map +0 -1
- package/dist/catalog.d.mts +0 -66
- package/dist/catalog.d.mts.map +0 -1
- package/dist/catalog.mjs +0 -181
- package/dist/catalog.mjs.map +0 -1
- package/dist/extensions/mcp-ui.mjs +0 -31
- package/dist/extensions/mcp-ui.mjs.map +0 -1
- package/dist/extensions/mcp.cjs +0 -130
- package/dist/extensions/mcp.cjs.map +0 -1
- package/dist/extensions/mcp.d.mts +0 -5
- package/dist/extensions/mcp.d.mts.map +0 -1
- package/dist/extensions/mcp.mjs +0 -125
- package/dist/extensions/mcp.mjs.map +0 -1
- package/dist/extensions/server.cjs +0 -528
- package/dist/extensions/server.cjs.map +0 -1
- package/dist/extensions/server.d.mts +0 -5
- package/dist/extensions/server.d.mts.map +0 -1
- package/dist/extensions/server.mjs +0 -519
- package/dist/extensions/server.mjs.map +0 -1
- package/dist/index.cjs +0 -5
- package/dist/index.d.mts +0 -6
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -2
- package/dist/rolldown-runtime-VH7oDXx4.cjs +0 -28
- package/dist/skills-Ccvg1Hcz.mjs +0 -8
- package/dist/skills-Ccvg1Hcz.mjs.map +0 -1
- package/dist/skills-ComtgYb1.cjs +0 -25
- package/dist/skills-ComtgYb1.cjs.map +0 -1
- package/llms.txt +0 -15
- package/src/prompts/po-author-skill/SKILL.md +0 -37
- package/src/prompts/po-use-skill/SKILL.md +0 -18
package/README.md
CHANGED
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Temporary Holding Version
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Pi loads skills from the directories it is given at startup. Po adds two things on top: skills
|
|
6
|
-
that are discovered lazily rather than loaded eagerly, and a registry where other extensions
|
|
7
|
-
publish their own skill directories.
|
|
8
|
-
|
|
9
|
-
## Deferred discovery
|
|
10
|
-
|
|
11
|
-
Scanning every skill directory is the slowest thing this package does, so it does not block the
|
|
12
|
-
session. Discovery starts on `session_start` as a numbered generation and is awaited only when
|
|
13
|
-
something needs the result. A reload starts a new generation; a snapshot that arrives from a
|
|
14
|
-
superseded one is discarded rather than shown, which is what keeps a fast reload from printing stale
|
|
15
|
-
diagnostics.
|
|
16
|
-
|
|
17
|
-
## Contributing skill directories
|
|
18
|
-
|
|
19
|
-
The package provides the session-owned `doom/skill-sources` Cordis service from
|
|
20
|
-
`@agimon-ai/po-core/skills`. Extensions register their directories inside
|
|
21
|
-
`ctx.inject([DOOM_SKILL_SOURCES_SERVICE], ...)`; the returned handle is disposed automatically when
|
|
22
|
-
either the contributor or provider unloads. Contributions are keyed by source, so a replacement
|
|
23
|
-
generation takes the previous package slot without doubling it.
|
|
24
|
-
|
|
25
|
-
## Help guidance
|
|
26
|
-
|
|
27
|
-
While the Help minor mode is active, this package contributes `po-author-skill` for creating
|
|
28
|
-
and distributing skills and `po-use-skill` for browsing, invoking, and diagnosing them. Both
|
|
29
|
-
prompts are published under `src/prompts` and routed through this package's [`llms.txt`](./llms.txt).
|
|
30
|
-
|
|
31
|
-
## Installation
|
|
32
|
-
|
|
33
|
-
Po depends on this package and activates it as fixed host core, so a Po install already has
|
|
34
|
-
it. It is not selectable from `.po/modes.yaml`.
|
|
35
|
-
|
|
36
|
-
## License
|
|
37
|
-
|
|
38
|
-
MIT
|
|
39
|
-
|
|
40
|
-
Plugin entries live in `src/extensions`, host events and commands in routed surfaces, and catalog and discovery logic in named `src/services` folders. `src/exports` contains public helpers and types. The server awaits its async declaration factory to discover named skill commands before registration and startup.
|
|
3
|
+
This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
|
package/package.json
CHANGED
|
@@ -1,135 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/po-skill",
|
|
3
|
-
"version": "0.0.0-
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"agent-skills",
|
|
7
|
-
"ai",
|
|
8
|
-
"coding-agent",
|
|
9
|
-
"developer-tools",
|
|
10
|
-
"pi-coding-agent",
|
|
11
|
-
"pi-extension",
|
|
12
|
-
"pi-package",
|
|
13
|
-
"po",
|
|
14
|
-
"skill-catalog",
|
|
15
|
-
"skill-discovery"
|
|
16
|
-
],
|
|
17
|
-
"homepage": "https://agimon.ai",
|
|
18
|
-
"bugs": {
|
|
19
|
-
"url": "https://github.com/AgiFlow/po/issues"
|
|
20
|
-
},
|
|
21
|
-
"license": "MIT",
|
|
22
|
-
"author": "Vuong Ngo",
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/AgiFlow/po.git",
|
|
26
|
-
"directory": "packages/foundations/po-skill"
|
|
27
|
-
},
|
|
28
|
-
"files": [
|
|
29
|
-
"dist",
|
|
30
|
-
"llms.txt",
|
|
31
|
-
"README.md",
|
|
32
|
-
"src/prompts",
|
|
33
|
-
"LICENSE",
|
|
34
|
-
"package.json"
|
|
35
|
-
],
|
|
36
|
-
"type": "module",
|
|
37
|
-
"main": "./dist/index.cjs",
|
|
38
|
-
"module": "./dist/index.mjs",
|
|
39
|
-
"types": "./dist/index.d.mts",
|
|
40
|
-
"jsnext:main": "./dist/index.mjs",
|
|
41
|
-
"exports": {
|
|
42
|
-
".": {
|
|
43
|
-
"types": "./dist/index.d.mts",
|
|
44
|
-
"import": "./dist/index.mjs",
|
|
45
|
-
"require": "./dist/index.cjs"
|
|
46
|
-
},
|
|
47
|
-
"./apiContracts": {
|
|
48
|
-
"types": "./dist/apiContracts.d.mts",
|
|
49
|
-
"import": "./dist/apiContracts.mjs",
|
|
50
|
-
"require": "./dist/apiContracts.cjs"
|
|
51
|
-
},
|
|
52
|
-
"./catalog": {
|
|
53
|
-
"types": "./dist/catalog.d.mts",
|
|
54
|
-
"import": "./dist/catalog.mjs",
|
|
55
|
-
"require": "./dist/catalog.cjs"
|
|
56
|
-
},
|
|
57
|
-
"./extensions/server": {
|
|
58
|
-
"types": "./dist/extensions/server.d.mts",
|
|
59
|
-
"import": "./dist/extensions/server.mjs",
|
|
60
|
-
"require": "./dist/extensions/server.cjs"
|
|
61
|
-
},
|
|
62
|
-
"./package.json": "./package.json"
|
|
63
|
-
},
|
|
64
|
-
"publishConfig": {
|
|
65
|
-
"access": "public"
|
|
66
|
-
},
|
|
67
|
-
"dependencies": {
|
|
68
|
-
"@agimon-ai/po-config": "0.0.0-alpha.0",
|
|
69
|
-
"@agimon-ai/po-core": "0.0.0-alpha.0",
|
|
70
|
-
"@agimon-ai/po-domain": "0.0.0-alpha.0",
|
|
71
|
-
"@agimon-ai/po-telemetry": "0.0.0-alpha.0",
|
|
72
|
-
"@agimon-ai/po-web-components": "0.0.0-alpha.0",
|
|
73
|
-
"@deepseek-ai/cordis": "4.0.4",
|
|
74
|
-
"gpt-tokenizer": "4.0.0",
|
|
75
|
-
"typebox": "1.3.34"
|
|
76
|
-
},
|
|
77
|
-
"devDependencies": {
|
|
78
|
-
"@agimon-ai/po-build": "0.0.0-alpha.0",
|
|
79
|
-
"@agimon-ai/vibe-lint-plugin-doom-extension": "0.0.0-alpha.0",
|
|
80
|
-
"@deepseek-ai/cordis": "4.0.4",
|
|
81
|
-
"@earendil-works/pi-coding-agent": "1.0.2",
|
|
82
|
-
"@types/node": "26.6.4",
|
|
83
|
-
"@types/react": "19.3.0",
|
|
84
|
-
"@vitest/coverage-v8": "5.0.3",
|
|
85
|
-
"react": "19.3.0",
|
|
86
|
-
"tsdown": "0.23.0",
|
|
87
|
-
"typescript": "7.0.2",
|
|
88
|
-
"vitest": "5.0.3"
|
|
89
|
-
},
|
|
90
|
-
"peerDependencies": {
|
|
91
|
-
"@earendil-works/pi-coding-agent": "1.0.2"
|
|
92
|
-
},
|
|
93
|
-
"peerDependenciesMeta": {
|
|
94
|
-
"@earendil-works/pi-coding-agent": {
|
|
95
|
-
"optional": true
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
"engines": {
|
|
99
|
-
"node": ">=24"
|
|
100
|
-
},
|
|
101
|
-
"poMcp": {
|
|
102
|
-
"entry": "./generated/mcp.ts",
|
|
103
|
-
"dist": "./dist/extensions/mcp.mjs",
|
|
104
|
-
"scopes": [
|
|
105
|
-
"session"
|
|
106
|
-
],
|
|
107
|
-
"ui": {
|
|
108
|
-
"entry": "./generated/mcp-ui.ts",
|
|
109
|
-
"dist": "./dist/extensions/mcp-ui.mjs",
|
|
110
|
-
"widgets": [
|
|
111
|
-
"@agimon-ai/po-skill/load_skill",
|
|
112
|
-
"@agimon-ai/po-skill/search_skills"
|
|
113
|
-
]
|
|
114
|
-
}
|
|
115
|
-
},
|
|
116
|
-
"poServer": {
|
|
117
|
-
"entry": "./generated/server.ts",
|
|
118
|
-
"dist": "./dist/extensions/server.mjs",
|
|
119
|
-
"scopes": [
|
|
120
|
-
"session"
|
|
121
|
-
],
|
|
122
|
-
"contracts": {
|
|
123
|
-
"entry": "./src/exports/apiContracts.ts",
|
|
124
|
-
"dist": "./dist/apiContracts.mjs"
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
"scripts": {
|
|
128
|
-
"build": "tsdown && pnpm build:mcp",
|
|
129
|
-
"build:mcp": "tsdown --config tsdown.mcp.config.ts",
|
|
130
|
-
"test": "vitest --run",
|
|
131
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.mcp.json",
|
|
132
|
-
"lint": "oxlint . && oxfmt . --check",
|
|
133
|
-
"fixcode": "oxlint . --fix && oxfmt ."
|
|
134
|
-
}
|
|
3
|
+
"version": "0.0.0-stage",
|
|
4
|
+
"stub": true,
|
|
5
|
+
"description": "Temporary package placeholder for staged publishing"
|
|
135
6
|
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
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/dist/apiContracts.cjs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
Object.defineProperties(exports, {
|
|
2
|
-
__esModule: { value: true },
|
|
3
|
-
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
-
});
|
|
5
|
-
//#region src/schemas/apiContracts.ts
|
|
6
|
-
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
7
|
-
const apiContracts = (0, require("@agimon-ai/po-core/apiContracts").defineApiContract)({
|
|
8
|
-
version: 1,
|
|
9
|
-
http: [],
|
|
10
|
-
sockets: [],
|
|
11
|
-
dynamic: []
|
|
12
|
-
});
|
|
13
|
-
//#endregion
|
|
14
|
-
exports.apiContracts = apiContracts;
|
|
15
|
-
exports.default = apiContracts;
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=apiContracts.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.cjs","names":["defineApiContract"],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;;;;AAGA,MAAa,gBAAA,4CAAeA,CAAAA,CAAAA,kBAAAA,CAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
package/dist/apiContracts.d.mts
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
//#region src/schemas/apiContracts.d.ts
|
|
2
|
-
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
3
|
-
export declare const apiContracts: {
|
|
4
|
-
version: 1;
|
|
5
|
-
protocols?: Record<string, string> | undefined;
|
|
6
|
-
schemas?: Record<string, boolean | object> | undefined;
|
|
7
|
-
http: {
|
|
8
|
-
id: string;
|
|
9
|
-
scope: "global" | "session" | "workspace";
|
|
10
|
-
basePath?: string | undefined;
|
|
11
|
-
path: string;
|
|
12
|
-
method: "DELETE" | "GET" | "HEAD" | "OPTIONS" | "PATCH" | "POST" | "PUT";
|
|
13
|
-
description: string;
|
|
14
|
-
availability?: string | undefined;
|
|
15
|
-
authentication: "device" | "none" | "owner";
|
|
16
|
-
parameters?: {
|
|
17
|
-
name: string;
|
|
18
|
-
in: "header" | "path" | "query";
|
|
19
|
-
required: boolean;
|
|
20
|
-
schema: boolean | object;
|
|
21
|
-
}[] | undefined;
|
|
22
|
-
body?: {
|
|
23
|
-
contentType: string;
|
|
24
|
-
contentTypes?: string[] | undefined;
|
|
25
|
-
required: boolean;
|
|
26
|
-
schema: boolean | object;
|
|
27
|
-
} | undefined;
|
|
28
|
-
responses: Record<string, {
|
|
29
|
-
description: string;
|
|
30
|
-
contentType?: string | undefined;
|
|
31
|
-
schema?: boolean | object | undefined;
|
|
32
|
-
events?: Record<string, boolean | object> | undefined;
|
|
33
|
-
}>;
|
|
34
|
-
}[];
|
|
35
|
-
sockets: {
|
|
36
|
-
id: string;
|
|
37
|
-
scope: "global" | "session" | "workspace";
|
|
38
|
-
description: string;
|
|
39
|
-
availability?: string | undefined;
|
|
40
|
-
service: string;
|
|
41
|
-
member: string;
|
|
42
|
-
direction: "client-to-server" | "server-to-client";
|
|
43
|
-
kind: "channel" | "method" | "state";
|
|
44
|
-
input: boolean | object;
|
|
45
|
-
output?: boolean | object | undefined;
|
|
46
|
-
errors?: boolean | object | undefined;
|
|
47
|
-
}[];
|
|
48
|
-
dynamic: string[];
|
|
49
|
-
gaps?: string[] | undefined;
|
|
50
|
-
};
|
|
51
|
-
//#endregion
|
|
52
|
-
export { apiContracts as default };
|
|
53
|
-
//# sourceMappingURL=apiContracts.d.mts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.d.mts","names":[],"sources":["../src/schemas/apiContracts.ts"],"mappings":";;qBAGa"}
|
package/dist/apiContracts.mjs
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineApiContract } from "@agimon-ai/po-core/apiContracts";
|
|
2
|
-
//#region src/schemas/apiContracts.ts
|
|
3
|
-
/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */
|
|
4
|
-
const apiContracts = defineApiContract({
|
|
5
|
-
version: 1,
|
|
6
|
-
http: [],
|
|
7
|
-
sockets: [],
|
|
8
|
-
dynamic: []
|
|
9
|
-
});
|
|
10
|
-
//#endregion
|
|
11
|
-
export { apiContracts, apiContracts as default };
|
|
12
|
-
|
|
13
|
-
//# sourceMappingURL=apiContracts.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"apiContracts.mjs","names":[],"sources":["../src/schemas/apiContracts.ts"],"sourcesContent":["import { defineApiContract } from '@agimon-ai/po-core/apiContracts';\n\n/** This facet contributes agent tools, commands or lifecycle only, with no separate HTTP or socket surface. */\nexport const apiContracts = defineApiContract({ version: 1, http: [], sockets: [], dynamic: [] });\nexport default apiContracts;\n"],"mappings":";;;AAGA,MAAa,eAAe,kBAAkB;CAAE,SAAS;CAAG,MAAM,CAAC;CAAG,SAAS,CAAC;CAAG,SAAS,CAAC;AAAE,CAAC"}
|
package/dist/catalog.cjs
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_rolldown_runtime = require("./rolldown-runtime-VH7oDXx4.cjs");
|
|
3
|
-
let node_fs = require("node:fs");
|
|
4
|
-
node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
5
|
-
let node_path = require("node:path");
|
|
6
|
-
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
7
|
-
let _agimon_ai_po_config_domains = require("@agimon-ai/po-config/domains");
|
|
8
|
-
let _agimon_ai_po_domain_plugins = require("@agimon-ai/po-domain/plugins");
|
|
9
|
-
let _earendil_works_pi_coding_agent = require("@earendil-works/pi-coding-agent");
|
|
10
|
-
//#region src/services/skillCatalog/index.ts
|
|
11
|
-
const SKILLS_DIRECTORY = "skills";
|
|
12
|
-
const SHARED_SKILLS_OWNER = ".claude/skills";
|
|
13
|
-
/**
|
|
14
|
-
* The tokenizer, loaded on first use rather than at import.
|
|
15
|
-
*
|
|
16
|
-
* `gpt-tokenizer` carries its whole vocabulary and costs about a tenth of a
|
|
17
|
-
* second to load. This module is reachable from the skills extension, which Pi
|
|
18
|
-
* loads at session start, so a top-level import would charge every session for
|
|
19
|
-
* a surface most of them never open.
|
|
20
|
-
*/
|
|
21
|
-
let tokenizer;
|
|
22
|
-
async function counter() {
|
|
23
|
-
tokenizer ??= import("gpt-tokenizer");
|
|
24
|
-
return (await tokenizer).countTokens;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Matches a directory against the active set.
|
|
28
|
-
*
|
|
29
|
-
* A domain that lists a plugin subset puts individual skill directories in the
|
|
30
|
-
* set rather than the plugin's `skills` root, so containment has to be checked
|
|
31
|
-
* both ways: the set may hold an ancestor of the directory, or a descendant of
|
|
32
|
-
* it.
|
|
33
|
-
*/
|
|
34
|
-
function createActiveMatcher(directories) {
|
|
35
|
-
const active = directories.map((directory) => node_path.default.resolve(directory));
|
|
36
|
-
return (directory) => {
|
|
37
|
-
const resolved = node_path.default.resolve(directory);
|
|
38
|
-
return active.some((entry) => entry === resolved || entry.startsWith(`${resolved}${node_path.default.sep}`) || resolved.startsWith(`${entry}${node_path.default.sep}`));
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
function collect(directory, group, owner, isActive, loaded, diagnostics, discovery = "recursive") {
|
|
42
|
-
const result = (0, _earendil_works_pi_coding_agent.loadSkillsFromDir)({
|
|
43
|
-
dir: directory,
|
|
44
|
-
source: owner
|
|
45
|
-
});
|
|
46
|
-
for (const diagnostic of result.diagnostics) diagnostics.push(`${diagnostic.path ?? directory}: ${diagnostic.message}`);
|
|
47
|
-
const root = node_path.default.resolve(directory);
|
|
48
|
-
const kept = result.skills.filter((skill) => {
|
|
49
|
-
const skillDirectory = node_path.default.dirname(skill.filePath);
|
|
50
|
-
if (discovery === "direct-children" && node_path.default.dirname(skillDirectory) !== root) return false;
|
|
51
|
-
return isActive(skillDirectory);
|
|
52
|
-
});
|
|
53
|
-
loaded.push(...kept);
|
|
54
|
-
return kept.map((skill) => ({
|
|
55
|
-
name: skill.name,
|
|
56
|
-
description: skill.description,
|
|
57
|
-
filePath: skill.filePath,
|
|
58
|
-
baseDir: skill.baseDir,
|
|
59
|
-
group,
|
|
60
|
-
owner,
|
|
61
|
-
modelInvocable: !skill.disableModelInvocation
|
|
62
|
-
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
63
|
-
}
|
|
64
|
-
function sortOwners(owners) {
|
|
65
|
-
return owners.sort((left, right) => left.owner.localeCompare(right.owner));
|
|
66
|
-
}
|
|
67
|
-
function collectHelpSkills(skills, loaded, diagnostics) {
|
|
68
|
-
const occupiedNames = new Set(loaded.map((skill) => skill.name));
|
|
69
|
-
const owners = /* @__PURE__ */ new Map();
|
|
70
|
-
const candidates = [...skills].sort((left, right) => left.sourceInfo.source.localeCompare(right.sourceInfo.source) || left.name.localeCompare(right.name) || left.filePath.localeCompare(right.filePath));
|
|
71
|
-
for (const skill of candidates) {
|
|
72
|
-
if (occupiedNames.has(skill.name)) {
|
|
73
|
-
diagnostics.push(`Help ${skill.sourceInfo.source} [HELP_SKILL_COLLISION]: '${skill.name}' was ignored because a normal skill wins.`);
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
occupiedNames.add(skill.name);
|
|
77
|
-
loaded.push(skill);
|
|
78
|
-
const owner = skill.sourceInfo.source;
|
|
79
|
-
const entries = owners.get(owner) ?? [];
|
|
80
|
-
entries.push({
|
|
81
|
-
name: skill.name,
|
|
82
|
-
description: skill.description,
|
|
83
|
-
filePath: skill.filePath,
|
|
84
|
-
baseDir: skill.baseDir,
|
|
85
|
-
group: "help",
|
|
86
|
-
owner,
|
|
87
|
-
modelInvocable: !skill.disableModelInvocation
|
|
88
|
-
});
|
|
89
|
-
owners.set(owner, entries);
|
|
90
|
-
}
|
|
91
|
-
return sortOwners([...owners.entries()].map(([owner, entries]) => ({
|
|
92
|
-
owner,
|
|
93
|
-
skills: entries.sort((left, right) => left.name.localeCompare(right.name))
|
|
94
|
-
})));
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Every skill this session actually loaded, grouped by where it comes from,
|
|
98
|
-
* priced in tokens.
|
|
99
|
-
*
|
|
100
|
-
* Discovery runs over `loadSkillsFromDir` from Pi rather than the harness's own
|
|
101
|
-
* walker so the listing matches what Pi would load, including its ignore-file
|
|
102
|
-
* handling; the same skills are then handed to Pi's `formatSkillsForPrompt` so
|
|
103
|
-
* the always-on figure is the real prompt block rather than a reconstruction of
|
|
104
|
-
* it.
|
|
105
|
-
*/
|
|
106
|
-
async function buildSkillCatalog(options) {
|
|
107
|
-
const { repoRoot } = options;
|
|
108
|
-
const isActive = createActiveMatcher(options.activeSkillDirectories);
|
|
109
|
-
const diagnostics = [...options.helpDiagnostics ?? []];
|
|
110
|
-
const loaded = [];
|
|
111
|
-
const extensionOwners = [];
|
|
112
|
-
for (const entry of options.extensionSources) {
|
|
113
|
-
const skills = entry.directories.flatMap((directory) => collect(directory, "extensions", entry.source, () => true, loaded, diagnostics));
|
|
114
|
-
if (skills.length > 0) extensionOwners.push({
|
|
115
|
-
owner: entry.source,
|
|
116
|
-
skills
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
const pluginOwners = [];
|
|
120
|
-
const domainPlugins = await (0, _agimon_ai_po_domain_plugins.materializePluginEntries)((0, _agimon_ai_po_config_domains.resolvePluginEntries)(repoRoot, (0, _agimon_ai_po_config_domains.listDomainNames)(repoRoot), []));
|
|
121
|
-
for (const entry of domainPlugins) {
|
|
122
|
-
const directory = node_path.default.join(entry.directory, SKILLS_DIRECTORY);
|
|
123
|
-
if (!node_fs.default.existsSync(directory)) continue;
|
|
124
|
-
const owner = node_path.default.basename(entry.directory);
|
|
125
|
-
const skills = collect(directory, "plugins", owner, isActive, loaded, diagnostics, entry.skillDiscovery);
|
|
126
|
-
if (skills.length > 0) pluginOwners.push({
|
|
127
|
-
owner,
|
|
128
|
-
skills
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
const sharedSkills = collect(node_path.default.join(repoRoot, ".claude", SKILLS_DIRECTORY), "default", SHARED_SKILLS_OWNER, isActive, loaded, diagnostics);
|
|
132
|
-
const defaultOwners = sharedSkills.length > 0 ? [{
|
|
133
|
-
owner: SHARED_SKILLS_OWNER,
|
|
134
|
-
skills: sharedSkills
|
|
135
|
-
}] : [];
|
|
136
|
-
const helpOwners = collectHelpSkills(options.helpSkills ?? [], loaded, diagnostics);
|
|
137
|
-
const groups = [
|
|
138
|
-
{
|
|
139
|
-
key: "extensions",
|
|
140
|
-
label: "extensions",
|
|
141
|
-
owners: sortOwners(extensionOwners)
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
key: "help",
|
|
145
|
-
label: "Help",
|
|
146
|
-
owners: helpOwners
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
key: "plugins",
|
|
150
|
-
label: "plugins",
|
|
151
|
-
owners: sortOwners(pluginOwners)
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
key: "default",
|
|
155
|
-
label: "default",
|
|
156
|
-
owners: defaultOwners
|
|
157
|
-
}
|
|
158
|
-
];
|
|
159
|
-
const countTokens = await counter();
|
|
160
|
-
const prompt = (0, _earendil_works_pi_coding_agent.formatSkillsForPrompt)(loaded);
|
|
161
|
-
const framingTokens = countTokens((0, _earendil_works_pi_coding_agent.formatSkillsForPrompt)([]));
|
|
162
|
-
const marginal = /* @__PURE__ */ new Map();
|
|
163
|
-
for (const skill of loaded) marginal.set(skill.name, Math.max(0, countTokens((0, _earendil_works_pi_coding_agent.formatSkillsForPrompt)([skill])) - framingTokens));
|
|
164
|
-
for (const group of groups) for (const owner of group.owners) for (const skill of owner.skills) {
|
|
165
|
-
const tokens = marginal.get(skill.name);
|
|
166
|
-
if (tokens !== void 0) skill.promptTokens = tokens;
|
|
167
|
-
}
|
|
168
|
-
let bodyTokens = 0;
|
|
169
|
-
for (const skill of loaded) try {
|
|
170
|
-
bodyTokens += countTokens(node_fs.default.readFileSync(skill.filePath, "utf8"));
|
|
171
|
-
} catch (error) {
|
|
172
|
-
diagnostics.push(`${skill.filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
groups,
|
|
176
|
-
skillCount: loaded.length,
|
|
177
|
-
promptTokens: prompt ? countTokens(prompt) : 0,
|
|
178
|
-
bodyTokens,
|
|
179
|
-
diagnostics
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
//#endregion
|
|
183
|
-
exports.buildSkillCatalog = buildSkillCatalog;
|
|
184
|
-
exports.counter = counter;
|
|
185
|
-
|
|
186
|
-
//# sourceMappingURL=catalog.cjs.map
|
package/dist/catalog.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.cjs","names":["path","loadSkillsFromDir","materializePluginEntries","resolvePluginEntries","listDomainNames","fs","formatSkillsForPrompt"],"sources":["../src/services/skillCatalog/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { listDomainNames, type PluginSkillDiscovery, resolvePluginEntries } from '@agimon-ai/po-config/domains';\nimport type { SkillSourceContribution } from '@agimon-ai/po-core/skills';\nimport { materializePluginEntries } from '@agimon-ai/po-domain/plugins';\nimport { formatSkillsForPrompt, loadSkillsFromDir, type Skill } from '@earendil-works/pi-coding-agent';\n\nconst SKILLS_DIRECTORY = 'skills';\nconst SHARED_SKILLS_OWNER = '.claude/skills';\n\nexport type SkillGroupKey = 'extensions' | 'help' | 'plugins' | 'default';\n\nexport interface SkillEntry {\n name: string;\n description: string;\n filePath: string;\n baseDir: string;\n group: SkillGroupKey;\n /** Package name for an extension, plugin directory name, or `.claude/skills`. */\n owner: string;\n modelInvocable: boolean;\n /**\n * What removing this skill would save from the `<available_skills>` block.\n *\n * Marginal rather than proportional: the block has fixed framing that no\n * single skill pays for, so the useful figure is what actually goes away.\n * Bodies are excluded because they load on demand and are not a resting cost.\n */\n promptTokens?: number;\n}\n\nexport interface SkillOwnerNode {\n owner: string;\n skills: SkillEntry[];\n}\n\nexport interface SkillGroup {\n key: SkillGroupKey;\n label: string;\n owners: SkillOwnerNode[];\n}\n\nexport interface SkillCatalog {\n groups: SkillGroup[];\n skillCount: number;\n /** Tokens the `<available_skills>` prompt block costs on every request. */\n promptTokens: number;\n /** Tokens every loaded SKILL.md costs in full, if all of them were read. */\n bodyTokens: number;\n /** Frontmatter and read failures, surfaced instead of thrown. */\n diagnostics: string[];\n}\n\nexport interface SkillCatalogOptions {\n repoRoot: string;\n /** Exact files the current selection resolved to, from `HarnessState.skillDirectories`. */\n activeSkillDirectories: readonly string[];\n extensionSources: readonly SkillSourceContribution[];\n /** Activation-gated wrappers already accepted by the merged active-skill view. */\n helpSkills?: readonly Skill[];\n /** Bounded Help activation and collision diagnostics. */\n helpDiagnostics?: readonly string[];\n}\n\n/**\n * The tokenizer, loaded on first use rather than at import.\n *\n * `gpt-tokenizer` carries its whole vocabulary and costs about a tenth of a\n * second to load. This module is reachable from the skills extension, which Pi\n * loads at session start, so a top-level import would charge every session for\n * a surface most of them never open.\n */\nlet tokenizer: Promise<typeof import('gpt-tokenizer')> | undefined;\n\nexport async function counter(): Promise<(text: string) => number> {\n tokenizer ??= import('gpt-tokenizer');\n return (await tokenizer).countTokens;\n}\n\n/**\n * Matches a directory against the active set.\n *\n * A domain that lists a plugin subset puts individual skill directories in the\n * set rather than the plugin's `skills` root, so containment has to be checked\n * both ways: the set may hold an ancestor of the directory, or a descendant of\n * it.\n */\nfunction createActiveMatcher(directories: readonly string[]): (directory: string) => boolean {\n const active = directories.map((directory) => path.resolve(directory));\n return (directory) => {\n const resolved = path.resolve(directory);\n return active.some(\n (entry) =>\n entry === resolved || entry.startsWith(`${resolved}${path.sep}`) || resolved.startsWith(`${entry}${path.sep}`),\n );\n };\n}\n\nfunction collect(\n directory: string,\n group: SkillGroupKey,\n owner: string,\n isActive: (directory: string) => boolean,\n loaded: Skill[],\n diagnostics: string[],\n discovery: PluginSkillDiscovery = 'recursive',\n): SkillEntry[] {\n const result = loadSkillsFromDir({ dir: directory, source: owner });\n for (const diagnostic of result.diagnostics) {\n diagnostics.push(`${diagnostic.path ?? directory}: ${diagnostic.message}`);\n }\n // Checked per skill, not per root: a subset domain selects some of a plugin's\n // skills and leaves the rest on disk, unloaded and therefore not listed.\n const root = path.resolve(directory);\n const kept = result.skills.filter((skill) => {\n const skillDirectory = path.dirname(skill.filePath);\n if (discovery === 'direct-children' && path.dirname(skillDirectory) !== root) return false;\n return isActive(skillDirectory);\n });\n // Kept in their loaded form as well, because the prompt-block cost is measured\n // by handing them back to Pi's own formatter.\n loaded.push(...kept);\n return kept\n .map((skill) => ({\n name: skill.name,\n description: skill.description,\n filePath: skill.filePath,\n baseDir: skill.baseDir,\n group,\n owner,\n modelInvocable: !skill.disableModelInvocation,\n }))\n .sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction sortOwners(owners: SkillOwnerNode[]): SkillOwnerNode[] {\n return owners.sort((left, right) => left.owner.localeCompare(right.owner));\n}\n\nfunction collectHelpSkills(skills: readonly Skill[], loaded: Skill[], diagnostics: string[]): SkillOwnerNode[] {\n const occupiedNames = new Set(loaded.map((skill) => skill.name));\n const owners = new Map<string, SkillEntry[]>();\n const candidates = [...skills].sort(\n (left, right) =>\n left.sourceInfo.source.localeCompare(right.sourceInfo.source) ||\n left.name.localeCompare(right.name) ||\n left.filePath.localeCompare(right.filePath),\n );\n for (const skill of candidates) {\n if (occupiedNames.has(skill.name)) {\n diagnostics.push(\n `Help ${skill.sourceInfo.source} [HELP_SKILL_COLLISION]: '${skill.name}' was ignored because a normal skill wins.`,\n );\n continue;\n }\n occupiedNames.add(skill.name);\n loaded.push(skill);\n const owner = skill.sourceInfo.source;\n const entries = owners.get(owner) ?? [];\n entries.push({\n name: skill.name,\n description: skill.description,\n filePath: skill.filePath,\n baseDir: skill.baseDir,\n group: 'help',\n owner,\n modelInvocable: !skill.disableModelInvocation,\n });\n owners.set(owner, entries);\n }\n return sortOwners(\n [...owners.entries()].map(([owner, entries]) => ({\n owner,\n skills: entries.sort((left, right) => left.name.localeCompare(right.name)),\n })),\n );\n}\n\n/**\n * Every skill this session actually loaded, grouped by where it comes from,\n * priced in tokens.\n *\n * Discovery runs over `loadSkillsFromDir` from Pi rather than the harness's own\n * walker so the listing matches what Pi would load, including its ignore-file\n * handling; the same skills are then handed to Pi's `formatSkillsForPrompt` so\n * the always-on figure is the real prompt block rather than a reconstruction of\n * it.\n */\nexport async function buildSkillCatalog(options: SkillCatalogOptions): Promise<SkillCatalog> {\n const { repoRoot } = options;\n const isActive = createActiveMatcher(options.activeSkillDirectories);\n const diagnostics: string[] = [...(options.helpDiagnostics ?? [])];\n const loaded: Skill[] = [];\n\n const extensionOwners: SkillOwnerNode[] = [];\n for (const entry of options.extensionSources) {\n const skills = entry.directories.flatMap((directory) =>\n collect(directory, 'extensions', entry.source, () => true, loaded, diagnostics),\n );\n if (skills.length > 0) extensionOwners.push({ owner: entry.source, skills });\n }\n\n const pluginOwners: SkillOwnerNode[] = [];\n const domainPlugins = await materializePluginEntries(resolvePluginEntries(repoRoot, listDomainNames(repoRoot), []));\n for (const entry of domainPlugins) {\n const directory = path.join(entry.directory, SKILLS_DIRECTORY);\n if (!fs.existsSync(directory)) continue;\n const owner = path.basename(entry.directory);\n const skills = collect(directory, 'plugins', owner, isActive, loaded, diagnostics, entry.skillDiscovery);\n if (skills.length > 0) pluginOwners.push({ owner, skills });\n }\n\n const sharedDirectory = path.join(repoRoot, '.claude', SKILLS_DIRECTORY);\n const sharedSkills = collect(sharedDirectory, 'default', SHARED_SKILLS_OWNER, isActive, loaded, diagnostics);\n const defaultOwners = sharedSkills.length > 0 ? [{ owner: SHARED_SKILLS_OWNER, skills: sharedSkills }] : [];\n const helpOwners = collectHelpSkills(options.helpSkills ?? [], loaded, diagnostics);\n\n const groups: SkillGroup[] = [\n { key: 'extensions', label: 'extensions', owners: sortOwners(extensionOwners) },\n { key: 'help', label: 'Help', owners: helpOwners },\n { key: 'plugins', label: 'plugins', owners: sortOwners(pluginOwners) },\n { key: 'default', label: 'default', owners: defaultOwners },\n ];\n\n const countTokens = await counter();\n const prompt = formatSkillsForPrompt(loaded);\n const framingTokens = countTokens(formatSkillsForPrompt([]));\n const marginal = new Map<string, number>();\n for (const skill of loaded) {\n marginal.set(skill.name, Math.max(0, countTokens(formatSkillsForPrompt([skill])) - framingTokens));\n }\n for (const group of groups) {\n for (const owner of group.owners) {\n for (const skill of owner.skills) {\n const tokens = marginal.get(skill.name);\n if (tokens !== undefined) skill.promptTokens = tokens;\n }\n }\n }\n let bodyTokens = 0;\n for (const skill of loaded) {\n try {\n bodyTokens += countTokens(fs.readFileSync(skill.filePath, 'utf8'));\n } catch (error) {\n diagnostics.push(`${skill.filePath}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n return {\n groups,\n skillCount: loaded.length,\n promptTokens: prompt ? countTokens(prompt) : 0,\n bodyTokens,\n diagnostics,\n };\n}\n\n/** The skills a name resolves to, used to decide what `enter` can invoke. */\nexport function findSkill(catalog: SkillCatalog, name: string): SkillEntry | undefined {\n for (const group of catalog.groups) {\n for (const owner of group.owners) {\n const match = owner.skills.find((skill) => skill.name === name);\n if (match) return match;\n }\n }\n return undefined;\n}\n"],"mappings":"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"}
|
package/dist/catalog.d.mts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { Skill } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import { SkillSourceContribution } from "@agimon-ai/po-core/skills";
|
|
3
|
-
//#region src/services/skillCatalog/index.d.ts
|
|
4
|
-
type SkillGroupKey = 'extensions' | 'help' | 'plugins' | 'default';
|
|
5
|
-
interface SkillEntry {
|
|
6
|
-
name: string;
|
|
7
|
-
description: string;
|
|
8
|
-
filePath: string;
|
|
9
|
-
baseDir: string;
|
|
10
|
-
group: SkillGroupKey;
|
|
11
|
-
/** Package name for an extension, plugin directory name, or `.claude/skills`. */
|
|
12
|
-
owner: string;
|
|
13
|
-
modelInvocable: boolean;
|
|
14
|
-
/**
|
|
15
|
-
* What removing this skill would save from the `<available_skills>` block.
|
|
16
|
-
*
|
|
17
|
-
* Marginal rather than proportional: the block has fixed framing that no
|
|
18
|
-
* single skill pays for, so the useful figure is what actually goes away.
|
|
19
|
-
* Bodies are excluded because they load on demand and are not a resting cost.
|
|
20
|
-
*/
|
|
21
|
-
promptTokens?: number;
|
|
22
|
-
}
|
|
23
|
-
interface SkillOwnerNode {
|
|
24
|
-
owner: string;
|
|
25
|
-
skills: SkillEntry[];
|
|
26
|
-
}
|
|
27
|
-
interface SkillGroup {
|
|
28
|
-
key: SkillGroupKey;
|
|
29
|
-
label: string;
|
|
30
|
-
owners: SkillOwnerNode[];
|
|
31
|
-
}
|
|
32
|
-
interface SkillCatalog {
|
|
33
|
-
groups: SkillGroup[];
|
|
34
|
-
skillCount: number;
|
|
35
|
-
/** Tokens the `<available_skills>` prompt block costs on every request. */
|
|
36
|
-
promptTokens: number;
|
|
37
|
-
/** Tokens every loaded SKILL.md costs in full, if all of them were read. */
|
|
38
|
-
bodyTokens: number;
|
|
39
|
-
/** Frontmatter and read failures, surfaced instead of thrown. */
|
|
40
|
-
diagnostics: string[];
|
|
41
|
-
}
|
|
42
|
-
interface SkillCatalogOptions {
|
|
43
|
-
repoRoot: string;
|
|
44
|
-
/** Exact files the current selection resolved to, from `HarnessState.skillDirectories`. */
|
|
45
|
-
activeSkillDirectories: readonly string[];
|
|
46
|
-
extensionSources: readonly SkillSourceContribution[];
|
|
47
|
-
/** Activation-gated wrappers already accepted by the merged active-skill view. */
|
|
48
|
-
helpSkills?: readonly Skill[];
|
|
49
|
-
/** Bounded Help activation and collision diagnostics. */
|
|
50
|
-
helpDiagnostics?: readonly string[];
|
|
51
|
-
}
|
|
52
|
-
export declare function counter(): Promise<(text: string) => number>;
|
|
53
|
-
/**
|
|
54
|
-
* Every skill this session actually loaded, grouped by where it comes from,
|
|
55
|
-
* priced in tokens.
|
|
56
|
-
*
|
|
57
|
-
* Discovery runs over `loadSkillsFromDir` from Pi rather than the harness's own
|
|
58
|
-
* walker so the listing matches what Pi would load, including its ignore-file
|
|
59
|
-
* handling; the same skills are then handed to Pi's `formatSkillsForPrompt` so
|
|
60
|
-
* the always-on figure is the real prompt block rather than a reconstruction of
|
|
61
|
-
* it.
|
|
62
|
-
*/
|
|
63
|
-
export declare function buildSkillCatalog(options: SkillCatalogOptions): Promise<SkillCatalog>;
|
|
64
|
-
//#endregion
|
|
65
|
-
export type { SkillCatalog, SkillCatalogOptions, SkillEntry, SkillGroup, SkillOwnerNode };
|
|
66
|
-
//# sourceMappingURL=catalog.d.mts.map
|
package/dist/catalog.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"catalog.d.mts","names":[],"sources":["../src/services/skillCatalog/index.ts"],"mappings":";;;KAWY;UAEK;EACf;EACA;EACA;EACA;EACA,OAAO;;EAEP;EACA;;;;;;;;EAQA;;UAGe;EACf;EACA,QAAQ;;UAGO;EACf,KAAK;EACL;EACA,QAAQ;;UAGO;EACf,QAAQ;EACR;;EAEA;;EAEA;;EAEA;;UAGe;EACf;;EAEA;EACA,2BAA2B;;EAE3B,sBAAsB;;EAEtB;;wBAaoB,WAAW,SAAS;;;;;;;;;;;wBAkHpB,kBAAkB,SAAS,sBAAsB,QAAQ"}
|