@kolisachint/hoocode-agent 0.4.129 → 0.4.131
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/CHANGELOG.md +37 -0
- package/dist/cli/args.d.ts +7 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/context-gc.d.ts +14 -2
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +73 -22
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/extensions/plugins/authoring.d.ts +1 -2
- package/dist/core/extensions/plugins/authoring.d.ts.map +1 -1
- package/dist/core/extensions/plugins/authoring.js +5 -3
- package/dist/core/extensions/plugins/authoring.js.map +1 -1
- package/dist/core/extensions/plugins/formats/agents.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/agents.js +1 -0
- package/dist/core/extensions/plugins/formats/agents.js.map +1 -1
- package/dist/core/extensions/plugins/formats/claude.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/claude.js +1 -0
- package/dist/core/extensions/plugins/formats/claude.js.map +1 -1
- package/dist/core/extensions/plugins/formats/copilot.d.ts +24 -8
- package/dist/core/extensions/plugins/formats/copilot.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/copilot.js +85 -25
- package/dist/core/extensions/plugins/formats/copilot.js.map +1 -1
- package/dist/core/extensions/plugins/formats/index.d.ts +2 -1
- package/dist/core/extensions/plugins/formats/index.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/index.js +1 -0
- package/dist/core/extensions/plugins/formats/index.js.map +1 -1
- package/dist/core/extensions/plugins/formats/jsonManifest.d.ts +2 -0
- package/dist/core/extensions/plugins/formats/jsonManifest.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/jsonManifest.js +4 -2
- package/dist/core/extensions/plugins/formats/jsonManifest.js.map +1 -1
- package/dist/core/extensions/plugins/formats/platform-targets.d.ts +43 -0
- package/dist/core/extensions/plugins/formats/platform-targets.d.ts.map +1 -0
- package/dist/core/extensions/plugins/formats/platform-targets.js +74 -0
- package/dist/core/extensions/plugins/formats/platform-targets.js.map +1 -0
- package/dist/core/extensions/plugins/formats/shared.d.ts +13 -1
- package/dist/core/extensions/plugins/formats/shared.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/shared.js +36 -0
- package/dist/core/extensions/plugins/formats/shared.js.map +1 -1
- package/dist/core/extensions/plugins/formats/types.d.ts +17 -0
- package/dist/core/extensions/plugins/formats/types.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/types.js.map +1 -1
- package/dist/core/extensions/plugins/marketplace.d.ts.map +1 -1
- package/dist/core/extensions/plugins/marketplace.js +26 -9
- package/dist/core/extensions/plugins/marketplace.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +24 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +7 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/tools/propose-plugin.d.ts.map +1 -1
- package/dist/core/tools/propose-plugin.js +9 -4
- package/dist/core/tools/propose-plugin.js.map +1 -1
- package/dist/extensions/core/scaffold.d.ts +10 -2
- package/dist/extensions/core/scaffold.d.ts.map +1 -1
- package/dist/extensions/core/scaffold.js +111 -16
- package/dist/extensions/core/scaffold.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +25 -0
- package/dist/main.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* GitHub Copilot
|
|
2
|
+
* GitHub Copilot format.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* hoocode's preferred Copilot home is the `.github/plugin/` marker directory —
|
|
5
|
+
* the convention used by the real-world plugins indexed by
|
|
6
|
+
* github/copilot-plugins (e.g. microsoft/work-iq) and the documented location
|
|
7
|
+
* for GitHub-hosted marketplaces. The official Copilot CLI plugin reference
|
|
8
|
+
* (docs.github.com copilot/reference/copilot-cli-reference/cli-plugin-reference,
|
|
9
|
+
* "File locations"; verified 2026-07) accepts several locations for both files
|
|
10
|
+
* (`.plugin/`, plugin root, `.github/plugin/`, `.claude-plugin/`), so this
|
|
11
|
+
* adapter reads them all — `.github/plugin/` first, then root, then `.plugin/`,
|
|
12
|
+
* then the legacy hoocode layout — and writes `.github/plugin/`.
|
|
13
|
+
* (`.claude-plugin/` belongs to the Claude adapter, which wins precedence, so a
|
|
14
|
+
* `.claude-plugin`-only directory correctly parses as a Claude plugin; Copilot
|
|
15
|
+
* reads those natively anyway.) The capability tree matches the Claude layout:
|
|
7
16
|
*
|
|
8
|
-
* marker/manifest .github/plugin/plugin.json { name, version, description, skills?: "./skills/" }
|
|
9
|
-
* marketplace .github/plugin/marketplace.json (also accepts .github/marketplace.json)
|
|
10
17
|
* skills skills/<name>/SKILL.md (or the manifest's `skills` path override)
|
|
11
18
|
* commands commands/<name>.md
|
|
12
|
-
* subagents agents/<name>.md
|
|
13
|
-
* hooks hooks/hooks.json
|
|
19
|
+
* subagents agents/<name>.md (Copilot also emits/reads `.agent.md` names)
|
|
20
|
+
* hooks hooks.json or hooks/hooks.json ({ description?, hooks: { Event: [...] } })
|
|
14
21
|
* MCP servers .mcp.json ({ mcpServers } | { servers })
|
|
15
22
|
*
|
|
23
|
+
* Workspace-level (non-plugin) conventions, per the current GitHub Copilot
|
|
24
|
+
* customization docs (docs.github.com — agent skills, custom agents, prompt
|
|
25
|
+
* files; verified 2026-07):
|
|
26
|
+
*
|
|
27
|
+
* skills .github/skills/<name>/SKILL.md (agentskills.io open standard)
|
|
28
|
+
* custom agents .github/agents/<name>.agent.md (frontmatter: name, description,
|
|
29
|
+
* tools as a YAML list, model, ...)
|
|
30
|
+
* prompt files .github/prompts/<name>.prompt.md (VS Code / Copilot prompt files)
|
|
31
|
+
*
|
|
16
32
|
* Earlier hoocode releases authored a different Copilot mapping
|
|
17
33
|
* (`.github/copilot-plugin.json` + `.github/prompts/*.prompt.md` +
|
|
18
34
|
* `.github/chatmodes/*.chatmode.md`); the reader still accepts that layout as a
|
|
@@ -22,20 +38,32 @@
|
|
|
22
38
|
*/
|
|
23
39
|
import * as fs from "node:fs";
|
|
24
40
|
import * as path from "node:path";
|
|
25
|
-
import { authoredHooksToConfig, dirIfExists, emitJson, emitMarkdown, normalizeHooks, normalizeMcp, parseAuthor, readJson, resolveCapabilityDir, slug, } from "./shared.js";
|
|
41
|
+
import { authoredHooksToConfig, dirIfExists, emitJson, emitMarkdown, normalizeHooks, normalizeMcp, parseAuthor, readJson, resolveCapabilityDir, slug, toolsYamlList, } from "./shared.js";
|
|
26
42
|
const MARKER_DIR = ".github";
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Manifest probe order: `.github/plugin/plugin.json` first — hoocode's
|
|
45
|
+
* preferred Copilot home, matching the real-world plugins indexed by
|
|
46
|
+
* github/copilot-plugins (e.g. microsoft/work-iq) — then the Copilot CLI
|
|
47
|
+
* reference's other locations (root `plugin.json`, `.plugin/plugin.json`) and
|
|
48
|
+
* hoocode's legacy `.github/copilot-plugin.json`. (`.claude-plugin/plugin.json`,
|
|
49
|
+
* also probed by the CLI, belongs to the Claude adapter.)
|
|
50
|
+
*/
|
|
51
|
+
const MANIFEST_REL_PATHS = [
|
|
52
|
+
path.join(MARKER_DIR, "plugin", "plugin.json"),
|
|
53
|
+
"plugin.json",
|
|
54
|
+
path.join(".plugin", "plugin.json"),
|
|
55
|
+
path.join(MARKER_DIR, "copilot-plugin.json"),
|
|
56
|
+
];
|
|
57
|
+
/** Authored manifest location: the preferred `.github/plugin/` home. */
|
|
58
|
+
const emitManifestRelPath = path.join(MARKER_DIR, "plugin", "plugin.json");
|
|
31
59
|
// Legacy authored layout (read-only fallbacks).
|
|
32
60
|
const LEGACY_PROMPTS_DIR = path.join(MARKER_DIR, "prompts");
|
|
33
61
|
const LEGACY_CHATMODES_DIR = path.join(MARKER_DIR, "chatmodes");
|
|
34
62
|
const LEGACY_MCP_FILE = path.join(MARKER_DIR, "mcp.json");
|
|
35
63
|
const LEGACY_HOOKS_FILE = path.join(MARKER_DIR, "hooks", "hooks.json");
|
|
36
|
-
/** Read
|
|
37
|
-
function
|
|
38
|
-
const file = path.join(root,
|
|
64
|
+
/** Read a hooks JSON file (either `{ hooks: {...} }` or a bare event map). */
|
|
65
|
+
function readHooksFile(root, rel) {
|
|
66
|
+
const file = path.join(root, rel);
|
|
39
67
|
if (!fs.existsSync(file))
|
|
40
68
|
return undefined;
|
|
41
69
|
const raw = readJson(file);
|
|
@@ -45,7 +73,7 @@ function readLegacyHooks(root) {
|
|
|
45
73
|
return config && Object.keys(config).length > 0 ? config : undefined;
|
|
46
74
|
}
|
|
47
75
|
function manifestPathFor(root) {
|
|
48
|
-
for (const rel of
|
|
76
|
+
for (const rel of MANIFEST_REL_PATHS) {
|
|
49
77
|
if (readJson(path.join(root, rel)) != null)
|
|
50
78
|
return path.join(root, rel);
|
|
51
79
|
}
|
|
@@ -56,7 +84,34 @@ export const copilotFormat = {
|
|
|
56
84
|
platform: "github",
|
|
57
85
|
precedence: 2,
|
|
58
86
|
label: "GitHub Copilot (.github)",
|
|
59
|
-
|
|
87
|
+
// .github/plugin/ first (hoocode's preferred Copilot home and the documented
|
|
88
|
+
// location for GitHub-hosted marketplaces), then the legacy .github/ spot,
|
|
89
|
+
// then the Copilot CLI's other probe locations (root, .plugin/).
|
|
90
|
+
marketplaceFiles: [
|
|
91
|
+
path.join(MARKER_DIR, "plugin", "marketplace.json"),
|
|
92
|
+
path.join(MARKER_DIR, "marketplace.json"),
|
|
93
|
+
"marketplace.json",
|
|
94
|
+
path.join(".plugin", "marketplace.json"),
|
|
95
|
+
],
|
|
96
|
+
workspace: {
|
|
97
|
+
root: MARKER_DIR,
|
|
98
|
+
// Copilot reads repo skills from .github/skills (also .claude/skills and
|
|
99
|
+
// .agents/skills, which the sibling adapters cover).
|
|
100
|
+
emitSkill: (s) => ({
|
|
101
|
+
path: path.join(MARKER_DIR, "skills", slug(s.name), "SKILL.md"),
|
|
102
|
+
content: emitMarkdown({ name: s.name, description: s.description }, s.body),
|
|
103
|
+
}),
|
|
104
|
+
// Custom agents take `tools` as a YAML list (not the Claude comma string).
|
|
105
|
+
emitAgent: (a) => ({
|
|
106
|
+
path: path.join(MARKER_DIR, "agents", `${slug(a.name)}.agent.md`),
|
|
107
|
+
content: emitMarkdown({ name: a.name, description: a.description, tools: toolsYamlList(a.tools), model: a.model }, a.body),
|
|
108
|
+
}),
|
|
109
|
+
// The closest Copilot equivalent of a slash command is a prompt file.
|
|
110
|
+
emitCommand: (c) => ({
|
|
111
|
+
path: path.join(MARKER_DIR, "prompts", `${slug(c.name)}.prompt.md`),
|
|
112
|
+
content: emitMarkdown({ description: c.description }, c.body),
|
|
113
|
+
}),
|
|
114
|
+
},
|
|
60
115
|
detectPlugin(root) {
|
|
61
116
|
return manifestPathFor(root) !== undefined;
|
|
62
117
|
},
|
|
@@ -86,25 +141,30 @@ export const copilotFormat = {
|
|
|
86
141
|
commandsDir: resolveCapabilityDir(root, raw.commands, "commands") ?? dirIfExists(root, LEGACY_PROMPTS_DIR),
|
|
87
142
|
agentsDir: resolveCapabilityDir(root, raw.agents, "agents") ?? dirIfExists(root, LEGACY_CHATMODES_DIR),
|
|
88
143
|
themesDir: resolveCapabilityDir(root, raw.themes, "themes"),
|
|
89
|
-
|
|
144
|
+
// Copilot CLI plugins put hooks config at root `hooks.json`; normalizeHooks
|
|
145
|
+
// covers the Claude-mirror `hooks/hooks.json`, then the legacy location.
|
|
146
|
+
hooks: normalizeHooks(raw.hooks, root) ??
|
|
147
|
+
readHooksFile(root, "hooks.json") ??
|
|
148
|
+
readHooksFile(root, LEGACY_HOOKS_FILE),
|
|
90
149
|
mcpServers: normalizeMcp(raw.mcpServers, root) ?? normalizeMcp(undefined, root, LEGACY_MCP_FILE),
|
|
91
150
|
// Providers are a native-only concept.
|
|
92
151
|
providers: undefined,
|
|
93
152
|
};
|
|
94
153
|
},
|
|
95
154
|
emit(draft) {
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
//
|
|
155
|
+
// Only the manifest is Copilot-specific — the canonical location is root
|
|
156
|
+
// `plugin.json` (Copilot CLI spec) — and the capability tree mirrors the
|
|
157
|
+
// Claude layout, so a plugin authored for both platforms is one tree with a
|
|
158
|
+
// root manifest for Copilot and a .claude-plugin/ manifest for Claude.
|
|
100
159
|
const files = [];
|
|
101
160
|
files.push({
|
|
102
|
-
path:
|
|
161
|
+
path: emitManifestRelPath,
|
|
103
162
|
content: emitJson({
|
|
104
163
|
name: draft.id,
|
|
105
164
|
...(draft.version ? { version: draft.version } : {}),
|
|
106
165
|
...(draft.description ? { description: draft.description } : {}),
|
|
107
|
-
|
|
166
|
+
// Spec: `author` is an object with a required `name`.
|
|
167
|
+
...(draft.author ? { author: { name: draft.author } } : {}),
|
|
108
168
|
}),
|
|
109
169
|
});
|
|
110
170
|
for (const s of draft.skills ?? []) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot `.github` format.\n *\n * The real-world convention (see github/copilot-plugins and the plugins it\n * indexes, e.g. microsoft/work-iq) mirrors the Claude Code bundle layout and\n * differs only in the marker/manifest location:\n *\n * marker/manifest .github/plugin/plugin.json { name, version, description, skills?: \"./skills/\" }\n * marketplace .github/plugin/marketplace.json (also accepts .github/marketplace.json)\n * skills skills/<name>/SKILL.md (or the manifest's `skills` path override)\n * commands commands/<name>.md\n * subagents agents/<name>.md\n * hooks hooks/hooks.json ({ description?, hooks: { Event: [...] } })\n * MCP servers .mcp.json ({ mcpServers } | { servers })\n *\n * Earlier hoocode releases authored a different Copilot mapping\n * (`.github/copilot-plugin.json` + `.github/prompts/*.prompt.md` +\n * `.github/chatmodes/*.chatmode.md`); the reader still accepts that layout as a\n * legacy fallback so previously authored plugins keep loading. Copilot\n * conventions move quickly; this file is the single place that encodes them,\n * so tracking an upstream change never reaches beyond this adapter.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { NormalizedPlugin } from \"../manifest.js\";\nimport {\n\tauthoredHooksToConfig,\n\tdirIfExists,\n\temitJson,\n\temitMarkdown,\n\tnormalizeHooks,\n\tnormalizeMcp,\n\tparseAuthor,\n\ttype RawManifest,\n\treadJson,\n\tresolveCapabilityDir,\n\tslug,\n} from \"./shared.js\";\nimport type { EmittedFile, PluginDraft, PluginFormatAdapter } from \"./types.js\";\n\nconst MARKER_DIR = \".github\";\n/** Real-world manifest location (github/copilot-plugins convention). */\nconst manifestRelPath = path.join(MARKER_DIR, \"plugin\", \"plugin.json\");\n/** Legacy hoocode-authored manifest location, still read for compatibility. */\nconst legacyManifestRelPath = path.join(MARKER_DIR, \"copilot-plugin.json\");\n\n// Legacy authored layout (read-only fallbacks).\nconst LEGACY_PROMPTS_DIR = path.join(MARKER_DIR, \"prompts\");\nconst LEGACY_CHATMODES_DIR = path.join(MARKER_DIR, \"chatmodes\");\nconst LEGACY_MCP_FILE = path.join(MARKER_DIR, \"mcp.json\");\nconst LEGACY_HOOKS_FILE = path.join(MARKER_DIR, \"hooks\", \"hooks.json\");\n\n/** Read legacy `.github/hooks/hooks.json` into the shared hooks event-map shape. */\nfunction readLegacyHooks(root: string): NormalizedPlugin[\"hooks\"] {\n\tconst file = path.join(root, LEGACY_HOOKS_FILE);\n\tif (!fs.existsSync(file)) return undefined;\n\tconst raw = readJson<{ hooks?: Record<string, unknown> } | Record<string, unknown>>(file);\n\tif (!raw || typeof raw !== \"object\") return undefined;\n\tconst config = (\"hooks\" in raw && raw.hooks ? raw.hooks : raw) as NormalizedPlugin[\"hooks\"];\n\treturn config && Object.keys(config).length > 0 ? config : undefined;\n}\n\nfunction manifestPathFor(root: string): string | undefined {\n\tfor (const rel of [manifestRelPath, legacyManifestRelPath]) {\n\t\tif (readJson(path.join(root, rel)) != null) return path.join(root, rel);\n\t}\n\treturn undefined;\n}\n\nexport const copilotFormat: PluginFormatAdapter = {\n\tid: \"copilot\",\n\tplatform: \"github\",\n\tprecedence: 2,\n\tlabel: \"GitHub Copilot (.github)\",\n\tmarketplaceFiles: [path.join(MARKER_DIR, \"plugin\", \"marketplace.json\"), path.join(MARKER_DIR, \"marketplace.json\")],\n\n\tdetectPlugin(root: string): boolean {\n\t\treturn manifestPathFor(root) !== undefined;\n\t},\n\n\tparsePlugin(root: string): NormalizedPlugin | null {\n\t\tconst manifestPath = manifestPathFor(root);\n\t\tif (!manifestPath) return null;\n\t\tconst raw = readJson<RawManifest>(manifestPath);\n\t\tif (!raw) return null;\n\n\t\tconst id = (raw.name ?? path.basename(root)).trim();\n\t\tif (!id) return null;\n\n\t\treturn {\n\t\t\tid,\n\t\t\tversion: raw.version,\n\t\t\tdescription: raw.description,\n\t\t\tauthor: parseAuthor(raw.author),\n\t\t\troot,\n\t\t\tmanifestPath,\n\t\t\tformat: \"copilot\",\n\t\t\t// Single-format view; the registry widens this to every format present.\n\t\t\tsupportPlatform: [\"github\"],\n\t\t\t// Claude-mirror layout (manifest overrides honored), with the legacy\n\t\t\t// prompts/chatmodes locations as read-only fallbacks.\n\t\t\tskillsDir: resolveCapabilityDir(root, raw.skills, \"skills\"),\n\t\t\tcommandsDir: resolveCapabilityDir(root, raw.commands, \"commands\") ?? dirIfExists(root, LEGACY_PROMPTS_DIR),\n\t\t\tagentsDir: resolveCapabilityDir(root, raw.agents, \"agents\") ?? dirIfExists(root, LEGACY_CHATMODES_DIR),\n\t\t\tthemesDir: resolveCapabilityDir(root, raw.themes, \"themes\"),\n\t\t\thooks: normalizeHooks(raw.hooks, root) ?? readLegacyHooks(root),\n\t\t\tmcpServers: normalizeMcp(raw.mcpServers, root) ?? normalizeMcp(undefined, root, LEGACY_MCP_FILE),\n\t\t\t// Providers are a native-only concept.\n\t\t\tproviders: undefined,\n\t\t};\n\t},\n\n\temit(draft: PluginDraft): EmittedFile[] {\n\t\t// Real-world convention: only the marker manifest is Copilot-specific; the\n\t\t// capability tree mirrors the Claude layout, so a plugin authored for both\n\t\t// platforms is one tree plus two marker manifests (exactly how plugins in\n\t\t// github/copilot-plugins ship).\n\t\tconst files: EmittedFile[] = [];\n\n\t\tfiles.push({\n\t\t\tpath: manifestRelPath,\n\t\t\tcontent: emitJson({\n\t\t\t\tname: draft.id,\n\t\t\t\t...(draft.version ? { version: draft.version } : {}),\n\t\t\t\t...(draft.description ? { description: draft.description } : {}),\n\t\t\t\t...(draft.author ? { author: draft.author } : {}),\n\t\t\t}),\n\t\t});\n\n\t\tfor (const s of draft.skills ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"skills\", slug(s.name), \"SKILL.md\"),\n\t\t\t\tcontent: emitMarkdown({ name: s.name, description: s.description }, s.body),\n\t\t\t});\n\t\t}\n\t\tfor (const c of draft.commands ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"commands\", `${slug(c.name)}.md`),\n\t\t\t\tcontent: emitMarkdown({ description: c.description }, c.body),\n\t\t\t});\n\t\t}\n\t\tfor (const a of draft.agents ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"agents\", `${slug(a.name)}.md`),\n\t\t\t\tcontent: emitMarkdown({ name: a.name, description: a.description, tools: a.tools, model: a.model }, a.body),\n\t\t\t});\n\t\t}\n\t\tif (draft.mcpServers?.length) {\n\t\t\tfiles.push({\n\t\t\t\tpath: \".mcp.json\",\n\t\t\t\tcontent: emitJson({\n\t\t\t\t\tmcpServers: Object.fromEntries(\n\t\t\t\t\t\tdraft.mcpServers.map((s) => [\n\t\t\t\t\t\t\ts.name,\n\t\t\t\t\t\t\t{ command: s.command, ...(s.args ? { args: s.args } : {}), ...(s.env ? { env: s.env } : {}) },\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t\tif (draft.hooks?.length) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"hooks\", \"hooks.json\"),\n\t\t\t\tcontent: emitJson({ hooks: authoredHooksToConfig(draft.hooks) }),\n\t\t\t});\n\t\t}\n\t\treturn files;\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"copilot.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/copilot.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * GitHub Copilot format.\n *\n * hoocode's preferred Copilot home is the `.github/plugin/` marker directory —\n * the convention used by the real-world plugins indexed by\n * github/copilot-plugins (e.g. microsoft/work-iq) and the documented location\n * for GitHub-hosted marketplaces. The official Copilot CLI plugin reference\n * (docs.github.com copilot/reference/copilot-cli-reference/cli-plugin-reference,\n * \"File locations\"; verified 2026-07) accepts several locations for both files\n * (`.plugin/`, plugin root, `.github/plugin/`, `.claude-plugin/`), so this\n * adapter reads them all — `.github/plugin/` first, then root, then `.plugin/`,\n * then the legacy hoocode layout — and writes `.github/plugin/`.\n * (`.claude-plugin/` belongs to the Claude adapter, which wins precedence, so a\n * `.claude-plugin`-only directory correctly parses as a Claude plugin; Copilot\n * reads those natively anyway.) The capability tree matches the Claude layout:\n *\n * skills skills/<name>/SKILL.md (or the manifest's `skills` path override)\n * commands commands/<name>.md\n * subagents agents/<name>.md (Copilot also emits/reads `.agent.md` names)\n * hooks hooks.json or hooks/hooks.json ({ description?, hooks: { Event: [...] } })\n * MCP servers .mcp.json ({ mcpServers } | { servers })\n *\n * Workspace-level (non-plugin) conventions, per the current GitHub Copilot\n * customization docs (docs.github.com — agent skills, custom agents, prompt\n * files; verified 2026-07):\n *\n * skills .github/skills/<name>/SKILL.md (agentskills.io open standard)\n * custom agents .github/agents/<name>.agent.md (frontmatter: name, description,\n * tools as a YAML list, model, ...)\n * prompt files .github/prompts/<name>.prompt.md (VS Code / Copilot prompt files)\n *\n * Earlier hoocode releases authored a different Copilot mapping\n * (`.github/copilot-plugin.json` + `.github/prompts/*.prompt.md` +\n * `.github/chatmodes/*.chatmode.md`); the reader still accepts that layout as a\n * legacy fallback so previously authored plugins keep loading. Copilot\n * conventions move quickly; this file is the single place that encodes them,\n * so tracking an upstream change never reaches beyond this adapter.\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { NormalizedPlugin } from \"../manifest.js\";\nimport {\n\tauthoredHooksToConfig,\n\tdirIfExists,\n\temitJson,\n\temitMarkdown,\n\tnormalizeHooks,\n\tnormalizeMcp,\n\tparseAuthor,\n\ttype RawManifest,\n\treadJson,\n\tresolveCapabilityDir,\n\tslug,\n\ttoolsYamlList,\n} from \"./shared.js\";\nimport type { EmittedFile, PluginDraft, PluginFormatAdapter } from \"./types.js\";\n\nconst MARKER_DIR = \".github\";\n/**\n * Manifest probe order: `.github/plugin/plugin.json` first — hoocode's\n * preferred Copilot home, matching the real-world plugins indexed by\n * github/copilot-plugins (e.g. microsoft/work-iq) — then the Copilot CLI\n * reference's other locations (root `plugin.json`, `.plugin/plugin.json`) and\n * hoocode's legacy `.github/copilot-plugin.json`. (`.claude-plugin/plugin.json`,\n * also probed by the CLI, belongs to the Claude adapter.)\n */\nconst MANIFEST_REL_PATHS = [\n\tpath.join(MARKER_DIR, \"plugin\", \"plugin.json\"),\n\t\"plugin.json\",\n\tpath.join(\".plugin\", \"plugin.json\"),\n\tpath.join(MARKER_DIR, \"copilot-plugin.json\"),\n] as const;\n/** Authored manifest location: the preferred `.github/plugin/` home. */\nconst emitManifestRelPath = path.join(MARKER_DIR, \"plugin\", \"plugin.json\");\n\n// Legacy authored layout (read-only fallbacks).\nconst LEGACY_PROMPTS_DIR = path.join(MARKER_DIR, \"prompts\");\nconst LEGACY_CHATMODES_DIR = path.join(MARKER_DIR, \"chatmodes\");\nconst LEGACY_MCP_FILE = path.join(MARKER_DIR, \"mcp.json\");\nconst LEGACY_HOOKS_FILE = path.join(MARKER_DIR, \"hooks\", \"hooks.json\");\n\n/** Read a hooks JSON file (either `{ hooks: {...} }` or a bare event map). */\nfunction readHooksFile(root: string, rel: string): NormalizedPlugin[\"hooks\"] {\n\tconst file = path.join(root, rel);\n\tif (!fs.existsSync(file)) return undefined;\n\tconst raw = readJson<{ hooks?: Record<string, unknown> } | Record<string, unknown>>(file);\n\tif (!raw || typeof raw !== \"object\") return undefined;\n\tconst config = (\"hooks\" in raw && raw.hooks ? raw.hooks : raw) as NormalizedPlugin[\"hooks\"];\n\treturn config && Object.keys(config).length > 0 ? config : undefined;\n}\n\nfunction manifestPathFor(root: string): string | undefined {\n\tfor (const rel of MANIFEST_REL_PATHS) {\n\t\tif (readJson(path.join(root, rel)) != null) return path.join(root, rel);\n\t}\n\treturn undefined;\n}\n\nexport const copilotFormat: PluginFormatAdapter = {\n\tid: \"copilot\",\n\tplatform: \"github\",\n\tprecedence: 2,\n\tlabel: \"GitHub Copilot (.github)\",\n\t// .github/plugin/ first (hoocode's preferred Copilot home and the documented\n\t// location for GitHub-hosted marketplaces), then the legacy .github/ spot,\n\t// then the Copilot CLI's other probe locations (root, .plugin/).\n\tmarketplaceFiles: [\n\t\tpath.join(MARKER_DIR, \"plugin\", \"marketplace.json\"),\n\t\tpath.join(MARKER_DIR, \"marketplace.json\"),\n\t\t\"marketplace.json\",\n\t\tpath.join(\".plugin\", \"marketplace.json\"),\n\t],\n\n\tworkspace: {\n\t\troot: MARKER_DIR,\n\t\t// Copilot reads repo skills from .github/skills (also .claude/skills and\n\t\t// .agents/skills, which the sibling adapters cover).\n\t\temitSkill: (s) => ({\n\t\t\tpath: path.join(MARKER_DIR, \"skills\", slug(s.name), \"SKILL.md\"),\n\t\t\tcontent: emitMarkdown({ name: s.name, description: s.description }, s.body),\n\t\t}),\n\t\t// Custom agents take `tools` as a YAML list (not the Claude comma string).\n\t\temitAgent: (a) => ({\n\t\t\tpath: path.join(MARKER_DIR, \"agents\", `${slug(a.name)}.agent.md`),\n\t\t\tcontent: emitMarkdown(\n\t\t\t\t{ name: a.name, description: a.description, tools: toolsYamlList(a.tools), model: a.model },\n\t\t\t\ta.body,\n\t\t\t),\n\t\t}),\n\t\t// The closest Copilot equivalent of a slash command is a prompt file.\n\t\temitCommand: (c) => ({\n\t\t\tpath: path.join(MARKER_DIR, \"prompts\", `${slug(c.name)}.prompt.md`),\n\t\t\tcontent: emitMarkdown({ description: c.description }, c.body),\n\t\t}),\n\t},\n\n\tdetectPlugin(root: string): boolean {\n\t\treturn manifestPathFor(root) !== undefined;\n\t},\n\n\tparsePlugin(root: string): NormalizedPlugin | null {\n\t\tconst manifestPath = manifestPathFor(root);\n\t\tif (!manifestPath) return null;\n\t\tconst raw = readJson<RawManifest>(manifestPath);\n\t\tif (!raw) return null;\n\n\t\tconst id = (raw.name ?? path.basename(root)).trim();\n\t\tif (!id) return null;\n\n\t\treturn {\n\t\t\tid,\n\t\t\tversion: raw.version,\n\t\t\tdescription: raw.description,\n\t\t\tauthor: parseAuthor(raw.author),\n\t\t\troot,\n\t\t\tmanifestPath,\n\t\t\tformat: \"copilot\",\n\t\t\t// Single-format view; the registry widens this to every format present.\n\t\t\tsupportPlatform: [\"github\"],\n\t\t\t// Claude-mirror layout (manifest overrides honored), with the legacy\n\t\t\t// prompts/chatmodes locations as read-only fallbacks.\n\t\t\tskillsDir: resolveCapabilityDir(root, raw.skills, \"skills\"),\n\t\t\tcommandsDir: resolveCapabilityDir(root, raw.commands, \"commands\") ?? dirIfExists(root, LEGACY_PROMPTS_DIR),\n\t\t\tagentsDir: resolveCapabilityDir(root, raw.agents, \"agents\") ?? dirIfExists(root, LEGACY_CHATMODES_DIR),\n\t\t\tthemesDir: resolveCapabilityDir(root, raw.themes, \"themes\"),\n\t\t\t// Copilot CLI plugins put hooks config at root `hooks.json`; normalizeHooks\n\t\t\t// covers the Claude-mirror `hooks/hooks.json`, then the legacy location.\n\t\t\thooks:\n\t\t\t\tnormalizeHooks(raw.hooks, root) ??\n\t\t\t\treadHooksFile(root, \"hooks.json\") ??\n\t\t\t\treadHooksFile(root, LEGACY_HOOKS_FILE),\n\t\t\tmcpServers: normalizeMcp(raw.mcpServers, root) ?? normalizeMcp(undefined, root, LEGACY_MCP_FILE),\n\t\t\t// Providers are a native-only concept.\n\t\t\tproviders: undefined,\n\t\t};\n\t},\n\n\temit(draft: PluginDraft): EmittedFile[] {\n\t\t// Only the manifest is Copilot-specific — the canonical location is root\n\t\t// `plugin.json` (Copilot CLI spec) — and the capability tree mirrors the\n\t\t// Claude layout, so a plugin authored for both platforms is one tree with a\n\t\t// root manifest for Copilot and a .claude-plugin/ manifest for Claude.\n\t\tconst files: EmittedFile[] = [];\n\n\t\tfiles.push({\n\t\t\tpath: emitManifestRelPath,\n\t\t\tcontent: emitJson({\n\t\t\t\tname: draft.id,\n\t\t\t\t...(draft.version ? { version: draft.version } : {}),\n\t\t\t\t...(draft.description ? { description: draft.description } : {}),\n\t\t\t\t// Spec: `author` is an object with a required `name`.\n\t\t\t\t...(draft.author ? { author: { name: draft.author } } : {}),\n\t\t\t}),\n\t\t});\n\n\t\tfor (const s of draft.skills ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"skills\", slug(s.name), \"SKILL.md\"),\n\t\t\t\tcontent: emitMarkdown({ name: s.name, description: s.description }, s.body),\n\t\t\t});\n\t\t}\n\t\tfor (const c of draft.commands ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"commands\", `${slug(c.name)}.md`),\n\t\t\t\tcontent: emitMarkdown({ description: c.description }, c.body),\n\t\t\t});\n\t\t}\n\t\tfor (const a of draft.agents ?? []) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"agents\", `${slug(a.name)}.md`),\n\t\t\t\tcontent: emitMarkdown({ name: a.name, description: a.description, tools: a.tools, model: a.model }, a.body),\n\t\t\t});\n\t\t}\n\t\tif (draft.mcpServers?.length) {\n\t\t\tfiles.push({\n\t\t\t\tpath: \".mcp.json\",\n\t\t\t\tcontent: emitJson({\n\t\t\t\t\tmcpServers: Object.fromEntries(\n\t\t\t\t\t\tdraft.mcpServers.map((s) => [\n\t\t\t\t\t\t\ts.name,\n\t\t\t\t\t\t\t{ command: s.command, ...(s.args ? { args: s.args } : {}), ...(s.env ? { env: s.env } : {}) },\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t\tif (draft.hooks?.length) {\n\t\t\tfiles.push({\n\t\t\t\tpath: path.join(\"hooks\", \"hooks.json\"),\n\t\t\t\tcontent: emitJson({ hooks: authoredHooksToConfig(draft.hooks) }),\n\t\t\t});\n\t\t}\n\t\treturn files;\n\t},\n};\n"]}
|
|
@@ -37,5 +37,6 @@ export declare function parsePluginWithFormats(root: string): NormalizedPlugin |
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function emitForPlatforms(draft: PluginDraft, platforms?: MarketplacePlatform[]): EmittedFile[];
|
|
39
39
|
export { agentsFormat, claudeFormat, copilotFormat };
|
|
40
|
-
export
|
|
40
|
+
export { DEFAULT_AUTHORING_PLATFORMS, getSupportPlatforms, normalizePlatformToken, parseSupportPlatforms, resolveAuthoringPlatforms, type SupportPlatformParse, setSupportPlatforms, } from "./platform-targets.js";
|
|
41
|
+
export type { EmittedFile, MarketplacePlatform, PluginDraft, PluginFormatAdapter, PluginFormatId, WorkspaceLayout, } from "./types.js";
|
|
41
42
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErH,8EAA8E;AAC9E,eAAO,MAAM,cAAc,EAAE,SAAS,mBAAmB,EAEZ,CAAC;AAE9C,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,GAAG,mBAAmB,GAAG,SAAS,CAE7E;AAED,gFAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,CAElG;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAMnE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAY5E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,mBAAmB,EAAE,GAAG,WAAW,EAAE,CAWrG;AAED,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AACrD,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErH,8EAA8E;AAC9E,eAAO,MAAM,cAAc,EAAE,SAAS,mBAAmB,EAEZ,CAAC;AAE9C,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,GAAG,mBAAmB,GAAG,SAAS,CAE7E;AAED,gFAA8E;AAC9E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,CAElG;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAMnE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAY5E;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,mBAAmB,EAAE,GAAG,WAAW,EAAE,CAWrG;AAED,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AACrD,OAAO,EACN,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,oBAAoB,EACzB,mBAAmB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACX,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,GACf,MAAM,YAAY,CAAC","sourcesContent":["/**\n * Plugin format registry.\n *\n * The single ordered list of every supported plugin format. Readers, the\n * marketplace parser, and `ProposePlugin` all go through here instead of\n * branching on a format, so adding or evolving a vendor layout is a one-file\n * change (write/adjust an adapter, add it to {@link PLUGIN_FORMATS}).\n *\n * Order is precedence order — native `.agents-plugin` first, then Claude, then\n * Copilot — so \"first match wins\" when a directory carries more than one format.\n */\n\nimport type { NormalizedPlugin } from \"../manifest.js\";\nimport { agentsFormat } from \"./agents.js\";\nimport { claudeFormat } from \"./claude.js\";\nimport { copilotFormat } from \"./copilot.js\";\nimport type { EmittedFile, MarketplacePlatform, PluginDraft, PluginFormatAdapter, PluginFormatId } from \"./types.js\";\n\n/** All registered formats, in precedence order (lower `precedence` first). */\nexport const PLUGIN_FORMATS: readonly PluginFormatAdapter[] = [agentsFormat, claudeFormat, copilotFormat]\n\t.slice()\n\t.sort((a, b) => a.precedence - b.precedence);\n\n/** Look up an adapter by its internal format id. */\nexport function getFormat(id: PluginFormatId): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.id === id);\n}\n\n/** Look up an adapter by its public platform token (`\"github\"` → Copilot). */\nexport function getFormatByPlatform(platform: MarketplacePlatform): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.platform === platform);\n}\n\n/** Every platform present in a plugin directory, precedence winner first. */\nexport function detectPlatforms(root: string): MarketplacePlatform[] {\n\tconst platforms: MarketplacePlatform[] = [];\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root) && !platforms.includes(format.platform)) platforms.push(format.platform);\n\t}\n\treturn platforms;\n}\n\n/**\n * Parse a plugin directory using the highest-precedence format present.\n * Returns null when no registered format recognizes the directory.\n *\n * `supportPlatform` records *every* format present (not just the winner), so a\n * directory carrying more than one vendor layout reports all of them.\n */\nexport function parsePluginWithFormats(root: string): NormalizedPlugin | null {\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root)) {\n\t\t\tconst parsed = format.parsePlugin(root);\n\t\t\tif (parsed) {\n\t\t\t\t// Winner's platform is already first via precedence order; fold in the rest.\n\t\t\t\tconst supportPlatform = detectPlatforms(root);\n\t\t\t\treturn { ...parsed, supportPlatform };\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Render a draft into the on-disk files for the given platforms (defaulting to\n * the draft's own `supportPlatform`, then to every format). Files from different\n * formats live under distinct marker directories, so the merge never collides.\n */\nexport function emitForPlatforms(draft: PluginDraft, platforms?: MarketplacePlatform[]): EmittedFile[] {\n\tconst targets = platforms ?? draft.supportPlatform ?? PLUGIN_FORMATS.map((f) => f.platform);\n\tconst files: EmittedFile[] = [];\n\tconst seen = new Set<MarketplacePlatform>();\n\tfor (const platform of targets) {\n\t\tif (seen.has(platform)) continue;\n\t\tseen.add(platform);\n\t\tconst adapter = getFormatByPlatform(platform);\n\t\tif (adapter) files.push(...adapter.emit(draft));\n\t}\n\treturn files;\n}\n\nexport { agentsFormat, claudeFormat, copilotFormat };\nexport {\n\tDEFAULT_AUTHORING_PLATFORMS,\n\tgetSupportPlatforms,\n\tnormalizePlatformToken,\n\tparseSupportPlatforms,\n\tresolveAuthoringPlatforms,\n\ttype SupportPlatformParse,\n\tsetSupportPlatforms,\n} from \"./platform-targets.js\";\nexport type {\n\tEmittedFile,\n\tMarketplacePlatform,\n\tPluginDraft,\n\tPluginFormatAdapter,\n\tPluginFormatId,\n\tWorkspaceLayout,\n} from \"./types.js\";\n"]}
|
|
@@ -73,4 +73,5 @@ export function emitForPlatforms(draft, platforms) {
|
|
|
73
73
|
return files;
|
|
74
74
|
}
|
|
75
75
|
export { agentsFormat, claudeFormat, copilotFormat };
|
|
76
|
+
export { DEFAULT_AUTHORING_PLATFORMS, getSupportPlatforms, normalizePlatformToken, parseSupportPlatforms, resolveAuthoringPlatforms, setSupportPlatforms, } from "./platform-targets.js";
|
|
76
77
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,8EAA8E;AAC9E,MAAM,CAAC,MAAM,cAAc,GAAmC,CAAC,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC;KACvG,KAAK,EAAE;KACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AAE9C,oDAAoD;AACpD,MAAM,UAAU,SAAS,CAAC,EAAkB,EAAmC;IAC9E,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AAAA,CAC/C;AAED,gFAA8E;AAC9E,MAAM,UAAU,mBAAmB,CAAC,QAA6B,EAAmC;IACnG,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;AAAA,CAC3D;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,IAAY,EAAyB;IACpE,MAAM,SAAS,GAA0B,EAAE,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACrC,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAA2B;IAC7E,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;QACrC,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,MAAM,EAAE,CAAC;gBACZ,6EAA6E;gBAC7E,MAAM,eAAe,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBAC9C,OAAO,EAAE,GAAG,MAAM,EAAE,eAAe,EAAE,CAAC;YACvC,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACZ;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkB,EAAE,SAAiC,EAAiB;IACtG,MAAM,OAAO,GAAG,SAAS,IAAI,KAAK,CAAC,eAAe,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC5C,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnB,MAAM,OAAO,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,KAAK,CAAC;AAAA,CACb;AAED,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC","sourcesContent":["/**\n * Plugin format registry.\n *\n * The single ordered list of every supported plugin format. Readers, the\n * marketplace parser, and `ProposePlugin` all go through here instead of\n * branching on a format, so adding or evolving a vendor layout is a one-file\n * change (write/adjust an adapter, add it to {@link PLUGIN_FORMATS}).\n *\n * Order is precedence order — native `.agents-plugin` first, then Claude, then\n * Copilot — so \"first match wins\" when a directory carries more than one format.\n */\n\nimport type { NormalizedPlugin } from \"../manifest.js\";\nimport { agentsFormat } from \"./agents.js\";\nimport { claudeFormat } from \"./claude.js\";\nimport { copilotFormat } from \"./copilot.js\";\nimport type { EmittedFile, MarketplacePlatform, PluginDraft, PluginFormatAdapter, PluginFormatId } from \"./types.js\";\n\n/** All registered formats, in precedence order (lower `precedence` first). */\nexport const PLUGIN_FORMATS: readonly PluginFormatAdapter[] = [agentsFormat, claudeFormat, copilotFormat]\n\t.slice()\n\t.sort((a, b) => a.precedence - b.precedence);\n\n/** Look up an adapter by its internal format id. */\nexport function getFormat(id: PluginFormatId): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.id === id);\n}\n\n/** Look up an adapter by its public platform token (`\"github\"` → Copilot). */\nexport function getFormatByPlatform(platform: MarketplacePlatform): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.platform === platform);\n}\n\n/** Every platform present in a plugin directory, precedence winner first. */\nexport function detectPlatforms(root: string): MarketplacePlatform[] {\n\tconst platforms: MarketplacePlatform[] = [];\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root) && !platforms.includes(format.platform)) platforms.push(format.platform);\n\t}\n\treturn platforms;\n}\n\n/**\n * Parse a plugin directory using the highest-precedence format present.\n * Returns null when no registered format recognizes the directory.\n *\n * `supportPlatform` records *every* format present (not just the winner), so a\n * directory carrying more than one vendor layout reports all of them.\n */\nexport function parsePluginWithFormats(root: string): NormalizedPlugin | null {\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root)) {\n\t\t\tconst parsed = format.parsePlugin(root);\n\t\t\tif (parsed) {\n\t\t\t\t// Winner's platform is already first via precedence order; fold in the rest.\n\t\t\t\tconst supportPlatform = detectPlatforms(root);\n\t\t\t\treturn { ...parsed, supportPlatform };\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Render a draft into the on-disk files for the given platforms (defaulting to\n * the draft's own `supportPlatform`, then to every format). Files from different\n * formats live under distinct marker directories, so the merge never collides.\n */\nexport function emitForPlatforms(draft: PluginDraft, platforms?: MarketplacePlatform[]): EmittedFile[] {\n\tconst targets = platforms ?? draft.supportPlatform ?? PLUGIN_FORMATS.map((f) => f.platform);\n\tconst files: EmittedFile[] = [];\n\tconst seen = new Set<MarketplacePlatform>();\n\tfor (const platform of targets) {\n\t\tif (seen.has(platform)) continue;\n\t\tseen.add(platform);\n\t\tconst adapter = getFormatByPlatform(platform);\n\t\tif (adapter) files.push(...adapter.emit(draft));\n\t}\n\treturn files;\n}\n\nexport { agentsFormat, claudeFormat, copilotFormat };\nexport
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Plugin format registry.\n *\n * The single ordered list of every supported plugin format. Readers, the\n * marketplace parser, and `ProposePlugin` all go through here instead of\n * branching on a format, so adding or evolving a vendor layout is a one-file\n * change (write/adjust an adapter, add it to {@link PLUGIN_FORMATS}).\n *\n * Order is precedence order — native `.agents-plugin` first, then Claude, then\n * Copilot — so \"first match wins\" when a directory carries more than one format.\n */\n\nimport type { NormalizedPlugin } from \"../manifest.js\";\nimport { agentsFormat } from \"./agents.js\";\nimport { claudeFormat } from \"./claude.js\";\nimport { copilotFormat } from \"./copilot.js\";\nimport type { EmittedFile, MarketplacePlatform, PluginDraft, PluginFormatAdapter, PluginFormatId } from \"./types.js\";\n\n/** All registered formats, in precedence order (lower `precedence` first). */\nexport const PLUGIN_FORMATS: readonly PluginFormatAdapter[] = [agentsFormat, claudeFormat, copilotFormat]\n\t.slice()\n\t.sort((a, b) => a.precedence - b.precedence);\n\n/** Look up an adapter by its internal format id. */\nexport function getFormat(id: PluginFormatId): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.id === id);\n}\n\n/** Look up an adapter by its public platform token (`\"github\"` → Copilot). */\nexport function getFormatByPlatform(platform: MarketplacePlatform): PluginFormatAdapter | undefined {\n\treturn PLUGIN_FORMATS.find((f) => f.platform === platform);\n}\n\n/** Every platform present in a plugin directory, precedence winner first. */\nexport function detectPlatforms(root: string): MarketplacePlatform[] {\n\tconst platforms: MarketplacePlatform[] = [];\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root) && !platforms.includes(format.platform)) platforms.push(format.platform);\n\t}\n\treturn platforms;\n}\n\n/**\n * Parse a plugin directory using the highest-precedence format present.\n * Returns null when no registered format recognizes the directory.\n *\n * `supportPlatform` records *every* format present (not just the winner), so a\n * directory carrying more than one vendor layout reports all of them.\n */\nexport function parsePluginWithFormats(root: string): NormalizedPlugin | null {\n\tfor (const format of PLUGIN_FORMATS) {\n\t\tif (format.detectPlugin(root)) {\n\t\t\tconst parsed = format.parsePlugin(root);\n\t\t\tif (parsed) {\n\t\t\t\t// Winner's platform is already first via precedence order; fold in the rest.\n\t\t\t\tconst supportPlatform = detectPlatforms(root);\n\t\t\t\treturn { ...parsed, supportPlatform };\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Render a draft into the on-disk files for the given platforms (defaulting to\n * the draft's own `supportPlatform`, then to every format). Files from different\n * formats live under distinct marker directories, so the merge never collides.\n */\nexport function emitForPlatforms(draft: PluginDraft, platforms?: MarketplacePlatform[]): EmittedFile[] {\n\tconst targets = platforms ?? draft.supportPlatform ?? PLUGIN_FORMATS.map((f) => f.platform);\n\tconst files: EmittedFile[] = [];\n\tconst seen = new Set<MarketplacePlatform>();\n\tfor (const platform of targets) {\n\t\tif (seen.has(platform)) continue;\n\t\tseen.add(platform);\n\t\tconst adapter = getFormatByPlatform(platform);\n\t\tif (adapter) files.push(...adapter.emit(draft));\n\t}\n\treturn files;\n}\n\nexport { agentsFormat, claudeFormat, copilotFormat };\nexport {\n\tDEFAULT_AUTHORING_PLATFORMS,\n\tgetSupportPlatforms,\n\tnormalizePlatformToken,\n\tparseSupportPlatforms,\n\tresolveAuthoringPlatforms,\n\ttype SupportPlatformParse,\n\tsetSupportPlatforms,\n} from \"./platform-targets.js\";\nexport type {\n\tEmittedFile,\n\tMarketplacePlatform,\n\tPluginDraft,\n\tPluginFormatAdapter,\n\tPluginFormatId,\n\tWorkspaceLayout,\n} from \"./types.js\";\n"]}
|
|
@@ -11,6 +11,8 @@ interface JsonManifestOptions {
|
|
|
11
11
|
id: Extract<PluginFormatId, "agents" | "claude">;
|
|
12
12
|
/** Marker subdirectory, e.g. ".agents-plugin". */
|
|
13
13
|
manifestDir: string;
|
|
14
|
+
/** Workspace-level artifact root, e.g. ".agents" / ".claude" (skills/, agents/, commands/ live under it). */
|
|
15
|
+
workspaceRoot: string;
|
|
14
16
|
precedence: number;
|
|
15
17
|
label: string;
|
|
16
18
|
/** Native honors `providers`; the Claude-compat path ignores them. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonManifest.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/jsonManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"jsonManifest.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/jsonManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,KAAK,EAA4B,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIhG,UAAU,mBAAmB;IAC5B,EAAE,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;IACjD,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,6GAA6G;IAC7G,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,iBAAiB,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,mBAAmB,GAAG,mBAAmB,CAmGxF","sourcesContent":["/**\n * Factory for the `plugin.json`-style formats (native `.agents-plugin` and\n * Claude Code `.claude-plugin`). They share one on-disk layout — a JSON manifest\n * under a marker directory plus `skills/`, `commands/`, `agents/`, `themes/`,\n * `hooks/hooks.json` — and differ only in the marker directory, the format id,\n * and whether `providers` are honored (native-only). Both adapters are produced\n * from this factory so the shared reader/writer lives in one place.\n */\n\nimport * as path from \"node:path\";\nimport type { NormalizedPlugin, PluginProvider } from \"../manifest.js\";\nimport {\n\tauthoredHooksToConfig,\n\tclaudeStyleWorkspace,\n\temitJson,\n\temitMarkdown,\n\tnormalizeHooks,\n\tnormalizeMcp,\n\tparseAuthor,\n\ttype RawManifest,\n\treadJson,\n\tresolveCapabilityDir,\n\tslug,\n} from \"./shared.js\";\nimport type { EmittedFile, PluginDraft, PluginFormatAdapter, PluginFormatId } from \"./types.js\";\n\nconst MANIFEST_FILE = \"plugin.json\";\n\ninterface JsonManifestOptions {\n\tid: Extract<PluginFormatId, \"agents\" | \"claude\">;\n\t/** Marker subdirectory, e.g. \".agents-plugin\". */\n\tmanifestDir: string;\n\t/** Workspace-level artifact root, e.g. \".agents\" / \".claude\" (skills/, agents/, commands/ live under it). */\n\tworkspaceRoot: string;\n\tprecedence: number;\n\tlabel: string;\n\t/** Native honors `providers`; the Claude-compat path ignores them. */\n\tsupportsProviders: boolean;\n}\n\nexport function createJsonManifestAdapter(opts: JsonManifestOptions): PluginFormatAdapter {\n\tconst manifestRelPath = path.join(opts.manifestDir, MANIFEST_FILE);\n\n\treturn {\n\t\tid: opts.id,\n\t\tplatform: opts.id, // \"agents\" | \"claude\" map 1:1 to their platform token\n\t\tprecedence: opts.precedence,\n\t\tlabel: opts.label,\n\t\tmarketplaceFiles: [path.join(opts.manifestDir, \"marketplace.json\")],\n\t\tworkspace: claudeStyleWorkspace(opts.workspaceRoot),\n\n\t\tdetectPlugin(root: string): boolean {\n\t\t\treturn readJson(path.join(root, manifestRelPath)) != null;\n\t\t},\n\n\t\tparsePlugin(root: string): NormalizedPlugin | null {\n\t\t\tconst manifestPath = path.join(root, manifestRelPath);\n\t\t\tconst raw = readJson<RawManifest>(manifestPath);\n\t\t\tif (!raw) return null;\n\n\t\t\tconst id = (raw.name ?? path.basename(root)).trim();\n\t\t\tif (!id) return null;\n\n\t\t\tconst providers: PluginProvider[] | undefined =\n\t\t\t\topts.supportsProviders && Array.isArray(raw.providers) ? (raw.providers as PluginProvider[]) : undefined;\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tversion: raw.version,\n\t\t\t\tdescription: raw.description,\n\t\t\t\tauthor: parseAuthor(raw.author),\n\t\t\t\troot,\n\t\t\t\tmanifestPath,\n\t\t\t\tformat: opts.id,\n\t\t\t\t// Single-format view; the registry widens this to every format present.\n\t\t\t\tsupportPlatform: [opts.id],\n\t\t\t\tskillsDir: resolveCapabilityDir(root, raw.skills, \"skills\"),\n\t\t\t\tcommandsDir: resolveCapabilityDir(root, raw.commands, \"commands\"),\n\t\t\t\tagentsDir: resolveCapabilityDir(root, raw.agents, \"agents\"),\n\t\t\t\tthemesDir: resolveCapabilityDir(root, raw.themes, \"themes\"),\n\t\t\t\thooks: normalizeHooks(raw.hooks, root),\n\t\t\t\tmcpServers: normalizeMcp(raw.mcpServers, root),\n\t\t\t\tproviders,\n\t\t\t};\n\t\t},\n\n\t\temit(draft: PluginDraft): EmittedFile[] {\n\t\t\tconst files: EmittedFile[] = [];\n\t\t\tconst mcpServers = draft.mcpServers?.length\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tdraft.mcpServers.map((s) => [\n\t\t\t\t\t\t\ts.name,\n\t\t\t\t\t\t\t{ command: s.command, ...(s.args ? { args: s.args } : {}), ...(s.env ? { env: s.env } : {}) },\n\t\t\t\t\t\t]),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\n\t\t\tfiles.push({\n\t\t\t\tpath: manifestRelPath,\n\t\t\t\tcontent: emitJson({\n\t\t\t\t\tname: draft.id,\n\t\t\t\t\t...(draft.version ? { version: draft.version } : {}),\n\t\t\t\t\t...(draft.description ? { description: draft.description } : {}),\n\t\t\t\t\t// Claude Code's schema documents `author` as an object with `name`.\n\t\t\t\t\t...(draft.author ? { author: { name: draft.author } } : {}),\n\t\t\t\t\t...(mcpServers ? { mcpServers } : {}),\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tfor (const s of draft.skills ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"skills\", slug(s.name), \"SKILL.md\"),\n\t\t\t\t\tcontent: emitMarkdown({ name: s.name, description: s.description }, s.body),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const c of draft.commands ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"commands\", `${slug(c.name)}.md`),\n\t\t\t\t\tcontent: emitMarkdown({ description: c.description }, c.body),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const a of draft.agents ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"agents\", `${slug(a.name)}.md`),\n\t\t\t\t\tcontent: emitMarkdown(\n\t\t\t\t\t\t{ name: a.name, description: a.description, tools: a.tools, model: a.model },\n\t\t\t\t\t\ta.body,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (draft.hooks?.length) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"hooks\", \"hooks.json\"),\n\t\t\t\t\tcontent: emitJson({ hooks: authoredHooksToConfig(draft.hooks) }),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn files;\n\t\t},\n\t};\n}\n"]}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* from this factory so the shared reader/writer lives in one place.
|
|
8
8
|
*/
|
|
9
9
|
import * as path from "node:path";
|
|
10
|
-
import { authoredHooksToConfig, emitJson, emitMarkdown, normalizeHooks, normalizeMcp, parseAuthor, readJson, resolveCapabilityDir, slug, } from "./shared.js";
|
|
10
|
+
import { authoredHooksToConfig, claudeStyleWorkspace, emitJson, emitMarkdown, normalizeHooks, normalizeMcp, parseAuthor, readJson, resolveCapabilityDir, slug, } from "./shared.js";
|
|
11
11
|
const MANIFEST_FILE = "plugin.json";
|
|
12
12
|
export function createJsonManifestAdapter(opts) {
|
|
13
13
|
const manifestRelPath = path.join(opts.manifestDir, MANIFEST_FILE);
|
|
@@ -17,6 +17,7 @@ export function createJsonManifestAdapter(opts) {
|
|
|
17
17
|
precedence: opts.precedence,
|
|
18
18
|
label: opts.label,
|
|
19
19
|
marketplaceFiles: [path.join(opts.manifestDir, "marketplace.json")],
|
|
20
|
+
workspace: claudeStyleWorkspace(opts.workspaceRoot),
|
|
20
21
|
detectPlugin(root) {
|
|
21
22
|
return readJson(path.join(root, manifestRelPath)) != null;
|
|
22
23
|
},
|
|
@@ -62,7 +63,8 @@ export function createJsonManifestAdapter(opts) {
|
|
|
62
63
|
name: draft.id,
|
|
63
64
|
...(draft.version ? { version: draft.version } : {}),
|
|
64
65
|
...(draft.description ? { description: draft.description } : {}),
|
|
65
|
-
|
|
66
|
+
// Claude Code's schema documents `author` as an object with `name`.
|
|
67
|
+
...(draft.author ? { author: { name: draft.author } } : {}),
|
|
66
68
|
...(mcpServers ? { mcpServers } : {}),
|
|
67
69
|
}),
|
|
68
70
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonManifest.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/jsonManifest.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EACN,qBAAqB,EACrB,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,WAAW,EAEX,QAAQ,EACR,oBAAoB,EACpB,IAAI,GACJ,MAAM,aAAa,CAAC;AAGrB,MAAM,aAAa,GAAG,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"jsonManifest.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/jsonManifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Factory for the `plugin.json`-style formats (native `.agents-plugin` and\n * Claude Code `.claude-plugin`). They share one on-disk layout — a JSON manifest\n * under a marker directory plus `skills/`, `commands/`, `agents/`, `themes/`,\n * `hooks/hooks.json` — and differ only in the marker directory, the format id,\n * and whether `providers` are honored (native-only). Both adapters are produced\n * from this factory so the shared reader/writer lives in one place.\n */\n\nimport * as path from \"node:path\";\nimport type { NormalizedPlugin, PluginProvider } from \"../manifest.js\";\nimport {\n\tauthoredHooksToConfig,\n\tclaudeStyleWorkspace,\n\temitJson,\n\temitMarkdown,\n\tnormalizeHooks,\n\tnormalizeMcp,\n\tparseAuthor,\n\ttype RawManifest,\n\treadJson,\n\tresolveCapabilityDir,\n\tslug,\n} from \"./shared.js\";\nimport type { EmittedFile, PluginDraft, PluginFormatAdapter, PluginFormatId } from \"./types.js\";\n\nconst MANIFEST_FILE = \"plugin.json\";\n\ninterface JsonManifestOptions {\n\tid: Extract<PluginFormatId, \"agents\" | \"claude\">;\n\t/** Marker subdirectory, e.g. \".agents-plugin\". */\n\tmanifestDir: string;\n\t/** Workspace-level artifact root, e.g. \".agents\" / \".claude\" (skills/, agents/, commands/ live under it). */\n\tworkspaceRoot: string;\n\tprecedence: number;\n\tlabel: string;\n\t/** Native honors `providers`; the Claude-compat path ignores them. */\n\tsupportsProviders: boolean;\n}\n\nexport function createJsonManifestAdapter(opts: JsonManifestOptions): PluginFormatAdapter {\n\tconst manifestRelPath = path.join(opts.manifestDir, MANIFEST_FILE);\n\n\treturn {\n\t\tid: opts.id,\n\t\tplatform: opts.id, // \"agents\" | \"claude\" map 1:1 to their platform token\n\t\tprecedence: opts.precedence,\n\t\tlabel: opts.label,\n\t\tmarketplaceFiles: [path.join(opts.manifestDir, \"marketplace.json\")],\n\t\tworkspace: claudeStyleWorkspace(opts.workspaceRoot),\n\n\t\tdetectPlugin(root: string): boolean {\n\t\t\treturn readJson(path.join(root, manifestRelPath)) != null;\n\t\t},\n\n\t\tparsePlugin(root: string): NormalizedPlugin | null {\n\t\t\tconst manifestPath = path.join(root, manifestRelPath);\n\t\t\tconst raw = readJson<RawManifest>(manifestPath);\n\t\t\tif (!raw) return null;\n\n\t\t\tconst id = (raw.name ?? path.basename(root)).trim();\n\t\t\tif (!id) return null;\n\n\t\t\tconst providers: PluginProvider[] | undefined =\n\t\t\t\topts.supportsProviders && Array.isArray(raw.providers) ? (raw.providers as PluginProvider[]) : undefined;\n\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tversion: raw.version,\n\t\t\t\tdescription: raw.description,\n\t\t\t\tauthor: parseAuthor(raw.author),\n\t\t\t\troot,\n\t\t\t\tmanifestPath,\n\t\t\t\tformat: opts.id,\n\t\t\t\t// Single-format view; the registry widens this to every format present.\n\t\t\t\tsupportPlatform: [opts.id],\n\t\t\t\tskillsDir: resolveCapabilityDir(root, raw.skills, \"skills\"),\n\t\t\t\tcommandsDir: resolveCapabilityDir(root, raw.commands, \"commands\"),\n\t\t\t\tagentsDir: resolveCapabilityDir(root, raw.agents, \"agents\"),\n\t\t\t\tthemesDir: resolveCapabilityDir(root, raw.themes, \"themes\"),\n\t\t\t\thooks: normalizeHooks(raw.hooks, root),\n\t\t\t\tmcpServers: normalizeMcp(raw.mcpServers, root),\n\t\t\t\tproviders,\n\t\t\t};\n\t\t},\n\n\t\temit(draft: PluginDraft): EmittedFile[] {\n\t\t\tconst files: EmittedFile[] = [];\n\t\t\tconst mcpServers = draft.mcpServers?.length\n\t\t\t\t? Object.fromEntries(\n\t\t\t\t\t\tdraft.mcpServers.map((s) => [\n\t\t\t\t\t\t\ts.name,\n\t\t\t\t\t\t\t{ command: s.command, ...(s.args ? { args: s.args } : {}), ...(s.env ? { env: s.env } : {}) },\n\t\t\t\t\t\t]),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\n\t\t\tfiles.push({\n\t\t\t\tpath: manifestRelPath,\n\t\t\t\tcontent: emitJson({\n\t\t\t\t\tname: draft.id,\n\t\t\t\t\t...(draft.version ? { version: draft.version } : {}),\n\t\t\t\t\t...(draft.description ? { description: draft.description } : {}),\n\t\t\t\t\t// Claude Code's schema documents `author` as an object with `name`.\n\t\t\t\t\t...(draft.author ? { author: { name: draft.author } } : {}),\n\t\t\t\t\t...(mcpServers ? { mcpServers } : {}),\n\t\t\t\t}),\n\t\t\t});\n\n\t\t\tfor (const s of draft.skills ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"skills\", slug(s.name), \"SKILL.md\"),\n\t\t\t\t\tcontent: emitMarkdown({ name: s.name, description: s.description }, s.body),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const c of draft.commands ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"commands\", `${slug(c.name)}.md`),\n\t\t\t\t\tcontent: emitMarkdown({ description: c.description }, c.body),\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const a of draft.agents ?? []) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"agents\", `${slug(a.name)}.md`),\n\t\t\t\t\tcontent: emitMarkdown(\n\t\t\t\t\t\t{ name: a.name, description: a.description, tools: a.tools, model: a.model },\n\t\t\t\t\t\ta.body,\n\t\t\t\t\t),\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (draft.hooks?.length) {\n\t\t\t\tfiles.push({\n\t\t\t\t\tpath: path.join(\"hooks\", \"hooks.json\"),\n\t\t\t\t\tcontent: emitJson({ hooks: authoredHooksToConfig(draft.hooks) }),\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn files;\n\t\t},\n\t};\n}\n"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-wide artifact platform targeting (`--support-platform`).
|
|
3
|
+
*
|
|
4
|
+
* hoocode reads resources from every vendor convention, but when it *writes*
|
|
5
|
+
* artifacts — authored plugins via ProposePlugin, workspace scaffolds via
|
|
6
|
+
* /new-skill //new-agent //new-command — it needs a target layout. This module
|
|
7
|
+
* owns that choice for the whole process:
|
|
8
|
+
*
|
|
9
|
+
* token vocabulary `agents` (alias `native`), `claude`,
|
|
10
|
+
* `github` (aliases `copilot`, `gh`)
|
|
11
|
+
* session state set once at startup from the `--support-platform` flag
|
|
12
|
+
* or the `supportPlatform` setting (main.ts)
|
|
13
|
+
* resolution explicit per-call platforms → session targets →
|
|
14
|
+
* {@link DEFAULT_AUTHORING_PLATFORMS}
|
|
15
|
+
*
|
|
16
|
+
* Kept beside the format registry (and importing only `types.ts`) so the
|
|
17
|
+
* platform vocabulary and the adapters stay a one-directory concern: adding a
|
|
18
|
+
* vendor means a new adapter file plus a token here, nothing else.
|
|
19
|
+
*/
|
|
20
|
+
import type { MarketplacePlatform } from "./types.js";
|
|
21
|
+
/** Default authoring targets when neither the call nor the session picked any. */
|
|
22
|
+
export declare const DEFAULT_AUTHORING_PLATFORMS: readonly MarketplacePlatform[];
|
|
23
|
+
/** Canonicalize one platform token, folding the user-facing aliases. */
|
|
24
|
+
export declare function normalizePlatformToken(token: string): MarketplacePlatform | undefined;
|
|
25
|
+
export interface SupportPlatformParse {
|
|
26
|
+
/** Canonical platforms, deduped, in the order first mentioned. */
|
|
27
|
+
platforms: MarketplacePlatform[];
|
|
28
|
+
/** Tokens that matched no known platform (surfaced as diagnostics, never fatal). */
|
|
29
|
+
invalid: string[];
|
|
30
|
+
}
|
|
31
|
+
/** Parse raw `--support-platform` / `supportPlatform` tokens into canonical platforms. */
|
|
32
|
+
export declare function parseSupportPlatforms(tokens: readonly string[]): SupportPlatformParse;
|
|
33
|
+
/** Set (or clear, with undefined/empty) the session's artifact platform targets. */
|
|
34
|
+
export declare function setSupportPlatforms(platforms: readonly MarketplacePlatform[] | undefined): void;
|
|
35
|
+
/** The session's configured targets, or undefined when `--support-platform` was not given. */
|
|
36
|
+
export declare function getSupportPlatforms(): MarketplacePlatform[] | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve the platforms an authoring write should target: an explicit per-call
|
|
39
|
+
* selection wins, then the session's `--support-platform` targets, then
|
|
40
|
+
* {@link DEFAULT_AUTHORING_PLATFORMS}.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveAuthoringPlatforms(explicit?: readonly MarketplacePlatform[]): MarketplacePlatform[];
|
|
43
|
+
//# sourceMappingURL=platform-targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-targets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/platform-targets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,kFAAkF;AAClF,eAAO,MAAM,2BAA2B,EAAE,SAAS,mBAAmB,EAAyB,CAAC;AAEhG,wEAAwE;AACxE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAcrF;AAED,MAAM,WAAW,oBAAoB;IACpC,kEAAkE;IAClE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,oFAAoF;IACpF,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,0FAA0F;AAC1F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,oBAAoB,CAWrF;AAKD,oFAAoF;AACpF,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,SAAS,GAAG,IAAI,CAE/F;AAED,8FAA8F;AAC9F,wBAAgB,mBAAmB,IAAI,mBAAmB,EAAE,GAAG,SAAS,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,SAAS,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,CAG1G","sourcesContent":["/**\n * Session-wide artifact platform targeting (`--support-platform`).\n *\n * hoocode reads resources from every vendor convention, but when it *writes*\n * artifacts — authored plugins via ProposePlugin, workspace scaffolds via\n * /new-skill //new-agent //new-command — it needs a target layout. This module\n * owns that choice for the whole process:\n *\n * token vocabulary `agents` (alias `native`), `claude`,\n * `github` (aliases `copilot`, `gh`)\n * session state set once at startup from the `--support-platform` flag\n * or the `supportPlatform` setting (main.ts)\n * resolution explicit per-call platforms → session targets →\n * {@link DEFAULT_AUTHORING_PLATFORMS}\n *\n * Kept beside the format registry (and importing only `types.ts`) so the\n * platform vocabulary and the adapters stay a one-directory concern: adding a\n * vendor means a new adapter file plus a token here, nothing else.\n */\n\nimport type { MarketplacePlatform } from \"./types.js\";\n\n/** Default authoring targets when neither the call nor the session picked any. */\nexport const DEFAULT_AUTHORING_PLATFORMS: readonly MarketplacePlatform[] = [\"claude\", \"github\"];\n\n/** Canonicalize one platform token, folding the user-facing aliases. */\nexport function normalizePlatformToken(token: string): MarketplacePlatform | undefined {\n\tswitch (token.trim().toLowerCase()) {\n\t\tcase \"agents\":\n\t\tcase \"native\":\n\t\t\treturn \"agents\";\n\t\tcase \"claude\":\n\t\t\treturn \"claude\";\n\t\tcase \"github\":\n\t\tcase \"copilot\":\n\t\tcase \"gh\":\n\t\t\treturn \"github\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nexport interface SupportPlatformParse {\n\t/** Canonical platforms, deduped, in the order first mentioned. */\n\tplatforms: MarketplacePlatform[];\n\t/** Tokens that matched no known platform (surfaced as diagnostics, never fatal). */\n\tinvalid: string[];\n}\n\n/** Parse raw `--support-platform` / `supportPlatform` tokens into canonical platforms. */\nexport function parseSupportPlatforms(tokens: readonly string[]): SupportPlatformParse {\n\tconst platforms: MarketplacePlatform[] = [];\n\tconst invalid: string[] = [];\n\tfor (const token of tokens) {\n\t\tconst trimmed = token.trim();\n\t\tif (!trimmed) continue;\n\t\tconst canonical = normalizePlatformToken(trimmed);\n\t\tif (!canonical) invalid.push(trimmed);\n\t\telse if (!platforms.includes(canonical)) platforms.push(canonical);\n\t}\n\treturn { platforms, invalid };\n}\n\n/** Session-wide targets. Undefined = not configured (fall back to defaults). */\nlet sessionSupportPlatforms: MarketplacePlatform[] | undefined;\n\n/** Set (or clear, with undefined/empty) the session's artifact platform targets. */\nexport function setSupportPlatforms(platforms: readonly MarketplacePlatform[] | undefined): void {\n\tsessionSupportPlatforms = platforms && platforms.length > 0 ? [...platforms] : undefined;\n}\n\n/** The session's configured targets, or undefined when `--support-platform` was not given. */\nexport function getSupportPlatforms(): MarketplacePlatform[] | undefined {\n\treturn sessionSupportPlatforms ? [...sessionSupportPlatforms] : undefined;\n}\n\n/**\n * Resolve the platforms an authoring write should target: an explicit per-call\n * selection wins, then the session's `--support-platform` targets, then\n * {@link DEFAULT_AUTHORING_PLATFORMS}.\n */\nexport function resolveAuthoringPlatforms(explicit?: readonly MarketplacePlatform[]): MarketplacePlatform[] {\n\tif (explicit && explicit.length > 0) return [...explicit];\n\treturn [...(sessionSupportPlatforms ?? DEFAULT_AUTHORING_PLATFORMS)];\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-wide artifact platform targeting (`--support-platform`).
|
|
3
|
+
*
|
|
4
|
+
* hoocode reads resources from every vendor convention, but when it *writes*
|
|
5
|
+
* artifacts — authored plugins via ProposePlugin, workspace scaffolds via
|
|
6
|
+
* /new-skill //new-agent //new-command — it needs a target layout. This module
|
|
7
|
+
* owns that choice for the whole process:
|
|
8
|
+
*
|
|
9
|
+
* token vocabulary `agents` (alias `native`), `claude`,
|
|
10
|
+
* `github` (aliases `copilot`, `gh`)
|
|
11
|
+
* session state set once at startup from the `--support-platform` flag
|
|
12
|
+
* or the `supportPlatform` setting (main.ts)
|
|
13
|
+
* resolution explicit per-call platforms → session targets →
|
|
14
|
+
* {@link DEFAULT_AUTHORING_PLATFORMS}
|
|
15
|
+
*
|
|
16
|
+
* Kept beside the format registry (and importing only `types.ts`) so the
|
|
17
|
+
* platform vocabulary and the adapters stay a one-directory concern: adding a
|
|
18
|
+
* vendor means a new adapter file plus a token here, nothing else.
|
|
19
|
+
*/
|
|
20
|
+
/** Default authoring targets when neither the call nor the session picked any. */
|
|
21
|
+
export const DEFAULT_AUTHORING_PLATFORMS = ["claude", "github"];
|
|
22
|
+
/** Canonicalize one platform token, folding the user-facing aliases. */
|
|
23
|
+
export function normalizePlatformToken(token) {
|
|
24
|
+
switch (token.trim().toLowerCase()) {
|
|
25
|
+
case "agents":
|
|
26
|
+
case "native":
|
|
27
|
+
return "agents";
|
|
28
|
+
case "claude":
|
|
29
|
+
return "claude";
|
|
30
|
+
case "github":
|
|
31
|
+
case "copilot":
|
|
32
|
+
case "gh":
|
|
33
|
+
return "github";
|
|
34
|
+
default:
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Parse raw `--support-platform` / `supportPlatform` tokens into canonical platforms. */
|
|
39
|
+
export function parseSupportPlatforms(tokens) {
|
|
40
|
+
const platforms = [];
|
|
41
|
+
const invalid = [];
|
|
42
|
+
for (const token of tokens) {
|
|
43
|
+
const trimmed = token.trim();
|
|
44
|
+
if (!trimmed)
|
|
45
|
+
continue;
|
|
46
|
+
const canonical = normalizePlatformToken(trimmed);
|
|
47
|
+
if (!canonical)
|
|
48
|
+
invalid.push(trimmed);
|
|
49
|
+
else if (!platforms.includes(canonical))
|
|
50
|
+
platforms.push(canonical);
|
|
51
|
+
}
|
|
52
|
+
return { platforms, invalid };
|
|
53
|
+
}
|
|
54
|
+
/** Session-wide targets. Undefined = not configured (fall back to defaults). */
|
|
55
|
+
let sessionSupportPlatforms;
|
|
56
|
+
/** Set (or clear, with undefined/empty) the session's artifact platform targets. */
|
|
57
|
+
export function setSupportPlatforms(platforms) {
|
|
58
|
+
sessionSupportPlatforms = platforms && platforms.length > 0 ? [...platforms] : undefined;
|
|
59
|
+
}
|
|
60
|
+
/** The session's configured targets, or undefined when `--support-platform` was not given. */
|
|
61
|
+
export function getSupportPlatforms() {
|
|
62
|
+
return sessionSupportPlatforms ? [...sessionSupportPlatforms] : undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the platforms an authoring write should target: an explicit per-call
|
|
66
|
+
* selection wins, then the session's `--support-platform` targets, then
|
|
67
|
+
* {@link DEFAULT_AUTHORING_PLATFORMS}.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveAuthoringPlatforms(explicit) {
|
|
70
|
+
if (explicit && explicit.length > 0)
|
|
71
|
+
return [...explicit];
|
|
72
|
+
return [...(sessionSupportPlatforms ?? DEFAULT_AUTHORING_PLATFORMS)];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=platform-targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-targets.js","sourceRoot":"","sources":["../../../../../src/core/extensions/plugins/formats/platform-targets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,kFAAkF;AAClF,MAAM,CAAC,MAAM,2BAA2B,GAAmC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAEhG,wEAAwE;AACxE,MAAM,UAAU,sBAAsB,CAAC,KAAa,EAAmC;IACtF,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACpC,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ;YACZ,OAAO,QAAQ,CAAC;QACjB,KAAK,QAAQ;YACZ,OAAO,QAAQ,CAAC;QACjB,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,IAAI;YACR,OAAO,QAAQ,CAAC;QACjB;YACC,OAAO,SAAS,CAAC;IACnB,CAAC;AAAA,CACD;AASD,0FAA0F;AAC1F,MAAM,UAAU,qBAAqB,CAAC,MAAyB,EAAwB;IACtF,MAAM,SAAS,GAA0B,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,MAAM,SAAS,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aACjC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,CAC9B;AAED,gFAAgF;AAChF,IAAI,uBAA0D,CAAC;AAE/D,oFAAoF;AACpF,MAAM,UAAU,mBAAmB,CAAC,SAAqD,EAAQ;IAChG,uBAAuB,GAAG,SAAS,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CACzF;AAED,8FAA8F;AAC9F,MAAM,UAAU,mBAAmB,GAAsC;IACxE,OAAO,uBAAuB,CAAC,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAAA,CAC1E;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,QAAyC,EAAyB;IAC3G,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,2BAA2B,CAAC,CAAC,CAAC;AAAA,CACrE","sourcesContent":["/**\n * Session-wide artifact platform targeting (`--support-platform`).\n *\n * hoocode reads resources from every vendor convention, but when it *writes*\n * artifacts — authored plugins via ProposePlugin, workspace scaffolds via\n * /new-skill //new-agent //new-command — it needs a target layout. This module\n * owns that choice for the whole process:\n *\n * token vocabulary `agents` (alias `native`), `claude`,\n * `github` (aliases `copilot`, `gh`)\n * session state set once at startup from the `--support-platform` flag\n * or the `supportPlatform` setting (main.ts)\n * resolution explicit per-call platforms → session targets →\n * {@link DEFAULT_AUTHORING_PLATFORMS}\n *\n * Kept beside the format registry (and importing only `types.ts`) so the\n * platform vocabulary and the adapters stay a one-directory concern: adding a\n * vendor means a new adapter file plus a token here, nothing else.\n */\n\nimport type { MarketplacePlatform } from \"./types.js\";\n\n/** Default authoring targets when neither the call nor the session picked any. */\nexport const DEFAULT_AUTHORING_PLATFORMS: readonly MarketplacePlatform[] = [\"claude\", \"github\"];\n\n/** Canonicalize one platform token, folding the user-facing aliases. */\nexport function normalizePlatformToken(token: string): MarketplacePlatform | undefined {\n\tswitch (token.trim().toLowerCase()) {\n\t\tcase \"agents\":\n\t\tcase \"native\":\n\t\t\treturn \"agents\";\n\t\tcase \"claude\":\n\t\t\treturn \"claude\";\n\t\tcase \"github\":\n\t\tcase \"copilot\":\n\t\tcase \"gh\":\n\t\t\treturn \"github\";\n\t\tdefault:\n\t\t\treturn undefined;\n\t}\n}\n\nexport interface SupportPlatformParse {\n\t/** Canonical platforms, deduped, in the order first mentioned. */\n\tplatforms: MarketplacePlatform[];\n\t/** Tokens that matched no known platform (surfaced as diagnostics, never fatal). */\n\tinvalid: string[];\n}\n\n/** Parse raw `--support-platform` / `supportPlatform` tokens into canonical platforms. */\nexport function parseSupportPlatforms(tokens: readonly string[]): SupportPlatformParse {\n\tconst platforms: MarketplacePlatform[] = [];\n\tconst invalid: string[] = [];\n\tfor (const token of tokens) {\n\t\tconst trimmed = token.trim();\n\t\tif (!trimmed) continue;\n\t\tconst canonical = normalizePlatformToken(trimmed);\n\t\tif (!canonical) invalid.push(trimmed);\n\t\telse if (!platforms.includes(canonical)) platforms.push(canonical);\n\t}\n\treturn { platforms, invalid };\n}\n\n/** Session-wide targets. Undefined = not configured (fall back to defaults). */\nlet sessionSupportPlatforms: MarketplacePlatform[] | undefined;\n\n/** Set (or clear, with undefined/empty) the session's artifact platform targets. */\nexport function setSupportPlatforms(platforms: readonly MarketplacePlatform[] | undefined): void {\n\tsessionSupportPlatforms = platforms && platforms.length > 0 ? [...platforms] : undefined;\n}\n\n/** The session's configured targets, or undefined when `--support-platform` was not given. */\nexport function getSupportPlatforms(): MarketplacePlatform[] | undefined {\n\treturn sessionSupportPlatforms ? [...sessionSupportPlatforms] : undefined;\n}\n\n/**\n * Resolve the platforms an authoring write should target: an explicit per-call\n * selection wins, then the session's `--support-platform` targets, then\n * {@link DEFAULT_AUTHORING_PLATFORMS}.\n */\nexport function resolveAuthoringPlatforms(explicit?: readonly MarketplacePlatform[]): MarketplacePlatform[] {\n\tif (explicit && explicit.length > 0) return [...explicit];\n\treturn [...(sessionSupportPlatforms ?? DEFAULT_AUTHORING_PLATFORMS)];\n}\n"]}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* shared.ts`, with the back-reference to manifest types erased at compile time.
|
|
8
8
|
*/
|
|
9
9
|
import type { PluginHooksConfig } from "../manifest.js";
|
|
10
|
-
import type { AuthoredHook } from "./types.js";
|
|
10
|
+
import type { AuthoredHook, WorkspaceLayout } from "./types.js";
|
|
11
11
|
/** Raw manifest shape accepted by the `plugin.json`-style formats (agents/claude/copilot). */
|
|
12
12
|
export interface RawManifest {
|
|
13
13
|
name?: string;
|
|
@@ -65,4 +65,16 @@ export declare function emitJson(value: unknown): string;
|
|
|
65
65
|
export declare function authoredHooksToConfig(hooks: AuthoredHook[]): Record<string, unknown>;
|
|
66
66
|
/** Slug-safe filename component (no path separators, conservative charset). */
|
|
67
67
|
export declare function slug(name: string): string;
|
|
68
|
+
/**
|
|
69
|
+
* Render a comma-separated tool allowlist (Claude Code convention, e.g.
|
|
70
|
+
* "read, grep") as a YAML flow sequence (`['read', 'grep']`) for formats whose
|
|
71
|
+
* frontmatter takes tools as a list (Copilot custom agents / prompt files).
|
|
72
|
+
*/
|
|
73
|
+
export declare function toolsYamlList(tools: string | undefined): string | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* The workspace layout shared by the `.agents/` and `.claude/` conventions:
|
|
76
|
+
* `<root>/skills/<name>/SKILL.md`, `<root>/agents/<name>.md`,
|
|
77
|
+
* `<root>/commands/<name>.md`. Copilot's differs and lives in its adapter.
|
|
78
|
+
*/
|
|
79
|
+
export declare function claudeStyleWorkspace(root: string): WorkspaceLayout;
|
|
68
80
|
//# sourceMappingURL=shared.d.ts.map
|