@ken-jo/agent-connector 0.4.99 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +28 -7
  2. package/dist/{action-5OEM3QC4.js → action-LEYTHNIU.js} +2 -2
  3. package/dist/{audit-BO7JQYIH.js → audit-HPKCUCES.js} +2 -2
  4. package/dist/{chunk-BV5WK6VQ.js → chunk-T5AI3AW3.js} +18 -18
  5. package/dist/chunk-T5AI3AW3.js.map +1 -0
  6. package/dist/{chunk-N4STCQGP.js → chunk-U2XJWG7N.js} +448 -70
  7. package/dist/chunk-U2XJWG7N.js.map +1 -0
  8. package/dist/{chunk-KLZBRNFP.js → chunk-WZMSSIDN.js} +51 -34
  9. package/dist/chunk-WZMSSIDN.js.map +1 -0
  10. package/dist/cli/sdk.js +1 -1
  11. package/dist/cli.js +1 -1
  12. package/dist/{detect-ALP4G7WG.js → detect-USP5JMWM.js} +2 -2
  13. package/dist/{doctor-YEQWCWZJ.js → doctor-VSW5KHBM.js} +4 -4
  14. package/dist/{hook-F63I3SD5.js → hook-QRW3ON6C.js} +2 -2
  15. package/dist/{install-23WRRFBY.js → install-ASTAUZKB.js} +4 -4
  16. package/dist/{leaderboard-YBD3IKC2.js → leaderboard-3XSVSGAJ.js} +2 -2
  17. package/dist/{package-TAUTPP7Z.js → package-VWBPHCLA.js} +20 -12
  18. package/dist/package-VWBPHCLA.js.map +1 -0
  19. package/dist/{serve-6MDLRQS2.js → serve-IQGHE4SJ.js} +2 -2
  20. package/dist/{status-IUP75XHP.js → status-BVLY6XDL.js} +2 -2
  21. package/dist/{telemetry-X4PLZEDB.js → telemetry-UU4SHJ23.js} +2 -2
  22. package/dist/{uninstall-BSIJ4QXN.js → uninstall-WI5YLDCT.js} +4 -4
  23. package/dist/{upgrade-ZSICU3NE.js → upgrade-L45BTG6X.js} +4 -4
  24. package/dist/{usage-EQUNVSCT.js → usage-K3NQTAJP.js} +2 -2
  25. package/package.json +1 -1
  26. package/dist/chunk-BV5WK6VQ.js.map +0 -1
  27. package/dist/chunk-KLZBRNFP.js.map +0 -1
  28. package/dist/chunk-N4STCQGP.js.map +0 -1
  29. package/dist/package-TAUTPP7Z.js.map +0 -1
  30. /package/dist/{action-5OEM3QC4.js.map → action-LEYTHNIU.js.map} +0 -0
  31. /package/dist/{audit-BO7JQYIH.js.map → audit-HPKCUCES.js.map} +0 -0
  32. /package/dist/{detect-ALP4G7WG.js.map → detect-USP5JMWM.js.map} +0 -0
  33. /package/dist/{doctor-YEQWCWZJ.js.map → doctor-VSW5KHBM.js.map} +0 -0
  34. /package/dist/{hook-F63I3SD5.js.map → hook-QRW3ON6C.js.map} +0 -0
  35. /package/dist/{install-23WRRFBY.js.map → install-ASTAUZKB.js.map} +0 -0
  36. /package/dist/{leaderboard-YBD3IKC2.js.map → leaderboard-3XSVSGAJ.js.map} +0 -0
  37. /package/dist/{serve-6MDLRQS2.js.map → serve-IQGHE4SJ.js.map} +0 -0
  38. /package/dist/{status-IUP75XHP.js.map → status-BVLY6XDL.js.map} +0 -0
  39. /package/dist/{telemetry-X4PLZEDB.js.map → telemetry-UU4SHJ23.js.map} +0 -0
  40. /package/dist/{uninstall-BSIJ4QXN.js.map → uninstall-WI5YLDCT.js.map} +0 -0
  41. /package/dist/{upgrade-ZSICU3NE.js.map → upgrade-L45BTG6X.js.map} +0 -0
  42. /package/dist/{usage-EQUNVSCT.js.map → usage-K3NQTAJP.js.map} +0 -0
@@ -33,7 +33,7 @@ import {
33
33
 
34
34
  // src/core/package.ts
35
35
  import { existsSync as existsSync2, readFileSync } from "fs";
36
- import { join as join7, resolve as resolve4 } from "path";
36
+ import { join as join8, resolve as resolve4 } from "path";
37
37
 
38
38
  // src/core/package-formats/claude-family.ts
39
39
  import { join } from "path";
@@ -41,6 +41,21 @@ import { join } from "path";
41
41
  // src/core/package-formats/shared.ts
42
42
  import { dirname, relative, resolve, sep } from "path";
43
43
  import { writeFileSync } from "fs";
44
+ import { createRequire } from "module";
45
+ var AGENT_CONNECTOR_PACKAGE_NAME = "@ken-jo/agent-connector";
46
+ function resolveFrameworkDependencyRange() {
47
+ const req = createRequire(import.meta.url);
48
+ for (const rel of ["../../../package.json", "../../package.json", "../package.json"]) {
49
+ try {
50
+ const pkg = req(rel);
51
+ if (pkg.name === AGENT_CONNECTOR_PACKAGE_NAME && typeof pkg.version === "string" && /^\d+\.\d+\.\d+/.test(pkg.version)) {
52
+ return `^${pkg.version}`;
53
+ }
54
+ } catch {
55
+ }
56
+ }
57
+ return "*";
58
+ }
44
59
  function createEmitter(dryRun) {
45
60
  const files = [];
46
61
  return {
@@ -143,29 +158,6 @@ var SPECS = {
143
158
  schemaUrl: "https://json.schemastore.org/claude-code-plugin-manifest.json",
144
159
  marketplace: { dir: ".claude-plugin", file: "marketplace.json", shape: "claude" }
145
160
  },
146
- "codex-plugin": {
147
- platformId: "codex",
148
- manifestDir: ".codex-plugin",
149
- subagentDir: "agents",
150
- mcpFile: ".mcp.json",
151
- marketplace: {
152
- dir: join(".agents", "plugins"),
153
- file: "marketplace.json",
154
- shape: "claude"
155
- }
156
- },
157
- "copilot-plugin": {
158
- // copilot-cli accepts a Claude-shaped bundle as-is; the ONLY difference from
159
- // claude-plugin is the --host stamp so the wrapped MCP + hook commands route
160
- // telemetry to the copilot host. Same `.claude-plugin/` manifest dir + schema
161
- // + `.claude-plugin/marketplace.json` catalog (live-verified on CLI 1.0.63).
162
- platformId: "copilot-cli",
163
- manifestDir: ".claude-plugin",
164
- subagentDir: "agents",
165
- mcpFile: ".mcp.json",
166
- schemaUrl: "https://json.schemastore.org/claude-code-plugin-manifest.json",
167
- marketplace: { dir: ".claude-plugin", file: "marketplace.json", shape: "claude" }
168
- },
169
161
  "factory-plugin": {
170
162
  platformId: "droid",
171
163
  manifestDir: ".factory-plugin",
@@ -247,9 +239,7 @@ function emitClaudeFamily(connector, ctx, format) {
247
239
  return { files, pluginDir, marketplacePath };
248
240
  }
249
241
  var emitClaudePlugin = (connector, ctx) => emitClaudeFamily(connector, ctx, "claude-plugin");
250
- var emitCodexPlugin = (connector, ctx) => emitClaudeFamily(connector, ctx, "codex-plugin");
251
242
  var emitFactoryPlugin = (connector, ctx) => emitClaudeFamily(connector, ctx, "factory-plugin");
252
- var emitCopilotPlugin = (connector, ctx) => emitClaudeFamily(connector, ctx, "copilot-plugin");
253
243
 
254
244
  // src/core/package-formats/cursor.ts
255
245
  import { existsSync } from "fs";
@@ -506,27 +496,12 @@ var emitKimiPlugin = (connector, ctx) => {
506
496
  };
507
497
 
508
498
  // src/core/package-formats/npm.ts
509
- import { createRequire } from "module";
510
499
  import { join as join6 } from "path";
511
- var AGENT_CONNECTOR_PACKAGE_NAME = "@ken-jo/agent-connector";
512
500
  var EVENT_TO_OPENCODE = {
513
501
  PreToolUse: "tool.execute.before",
514
502
  PostToolUse: "tool.execute.after",
515
503
  SessionStart: "experimental.chat.system.transform"
516
504
  };
517
- function resolveFrameworkDependencyRange() {
518
- const req = createRequire(import.meta.url);
519
- for (const rel of ["../../../package.json", "../../package.json", "../package.json"]) {
520
- try {
521
- const pkg = req(rel);
522
- if (pkg.name === AGENT_CONNECTOR_PACKAGE_NAME && typeof pkg.version === "string" && /^\d+\.\d+\.\d+/.test(pkg.version)) {
523
- return `^${pkg.version}`;
524
- }
525
- } catch {
526
- }
527
- }
528
- return "*";
529
- }
530
505
  function buildPackageJson(connector) {
531
506
  const pkgName = connector.id.startsWith("opencode-") ? connector.id : `opencode-${connector.id}`;
532
507
  const version = connector.version && connector.version !== "0.0.0" ? connector.version : "0.0.1";
@@ -719,6 +694,400 @@ connector declared \`publish.author\` \u2014 set them to YOUR terms before \`npm
719
694
  return { files, pluginDir, ...notes.length > 0 ? { notes } : {} };
720
695
  };
721
696
 
697
+ // src/core/package-formats/agent-plugin.ts
698
+ import { join as join7 } from "path";
699
+ var AGENT_PLUGIN_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
700
+ var AGENT_PLUGIN_MCP_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json";
701
+ var AGENT_PLUGIN_SPEC_VERSION = "1.0.0";
702
+ var AGENT_PLUGIN_LAUNCHER = "bin/agent-connector.mjs";
703
+ var CATALOG_NAME = "agent-connector";
704
+ var CLIENT_NAMESPACES = [
705
+ {
706
+ namespace: "com.github.copilot",
707
+ label: "GitHub Copilot (CLI, VS Code, JetBrains)",
708
+ platform: "copilot-cli",
709
+ readers: ["copilot-cli", "vscode-copilot", "jetbrains-copilot"],
710
+ hookStyle: "plugin-root-launcher",
711
+ agentFile: (name) => `${name}.agent.md`,
712
+ commandFile: (name) => `${name}.md`,
713
+ manifestExtension: null
714
+ },
715
+ {
716
+ namespace: "com.openai",
717
+ label: "Codex / ChatGPT",
718
+ platform: "codex",
719
+ readers: ["codex"],
720
+ hookStyle: "home-bin",
721
+ agentFile: null,
722
+ commandFile: null,
723
+ manifestExtension: ({ hooks }) => hooks ? { hooks } : {}
724
+ }
725
+ ];
726
+ var RESERVED_ENV_KEYS = /* @__PURE__ */ new Set(["PLUGIN_ROOT", "PLUGIN_DATA"]);
727
+ function toAgentPluginName(id) {
728
+ let name = id.trim().toLowerCase().replace(/[^a-z0-9.-]+/g, "-").replace(/-{2,}/g, "-").replace(/\.{2,}/g, ".").replace(/(?:-\.|\.-)+/g, "-").replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, "");
729
+ if (name.length > 64) {
730
+ name = name.slice(0, 64).replace(/[^a-z0-9]+$/g, "");
731
+ }
732
+ return name.length > 0 ? name : "connector";
733
+ }
734
+ function isConformantCwd(cwd) {
735
+ return cwd.startsWith("./") || cwd === "${PLUGIN_ROOT}" || cwd.startsWith("${PLUGIN_ROOT}/") || cwd === "${PLUGIN_DATA}" || cwd.startsWith("${PLUGIN_DATA}/");
736
+ }
737
+ function isConformantCommand(command) {
738
+ if (command.startsWith("./")) return true;
739
+ return !command.includes("/") && !command.includes("\\");
740
+ }
741
+ var LAUNCHER_AT_ROOT = `\${PLUGIN_ROOT}/${AGENT_PLUGIN_LAUNCHER}`;
742
+ function hookCommand(style, homeBin, platform, event, connectorId) {
743
+ if (style === "home-bin") {
744
+ return buildHomeBinHookCommand(homeBin, platform, event, connectorId);
745
+ }
746
+ return `node "${LAUNCHER_AT_ROOT}" hook ${platform} ${event} --connector ${connectorId}`;
747
+ }
748
+ function buildServerEntry(connector, hostHint, notes) {
749
+ const server = connector.server;
750
+ if (!server) return null;
751
+ const serverName = connector.id;
752
+ if (server.transport === "stdio") {
753
+ const realCommand = server.command ?? "";
754
+ if (realCommand === "") return null;
755
+ const realArgs = [...server.args ?? []];
756
+ let entry2;
757
+ let wrapped = false;
758
+ if (shouldWrapForTelemetry(server, connector.telemetry)) {
759
+ const flags = ["serve", "--connector", connector.id];
760
+ if (hostHint !== void 0) flags.push("--host", hostHint);
761
+ entry2 = {
762
+ type: "stdio",
763
+ command: "node",
764
+ args: [LAUNCHER_AT_ROOT, ...flags, "--", realCommand, ...realArgs]
765
+ };
766
+ wrapped = true;
767
+ } else {
768
+ entry2 = { type: "stdio", command: realCommand };
769
+ if (realArgs.length > 0) entry2.args = realArgs;
770
+ if (!isConformantCommand(realCommand)) {
771
+ notes.push(
772
+ `agent-plugin: server command "${realCommand}" is neither a bare executable name nor a plugin-relative ./ path \u2014 conforming clients may reject it (spec \xA77.2.1)`
773
+ );
774
+ }
775
+ }
776
+ const env = renderEnv(server.env);
777
+ if (env) {
778
+ const kept = {};
779
+ for (const [key, value] of Object.entries(env)) {
780
+ if (RESERVED_ENV_KEYS.has(key)) {
781
+ notes.push(
782
+ `agent-plugin: dropped env "${key}" \u2014 PLUGIN_ROOT / PLUGIN_DATA are reserved runtime variables a plugin cannot set`
783
+ );
784
+ continue;
785
+ }
786
+ kept[key] = value;
787
+ }
788
+ if (Object.keys(kept).length > 0) entry2.env = kept;
789
+ }
790
+ if (server.cwd) {
791
+ if (isConformantCwd(server.cwd)) {
792
+ entry2.cwd = server.cwd;
793
+ } else {
794
+ notes.push(
795
+ `agent-plugin: dropped cwd "${server.cwd}" \u2014 must be ./-relative, \${PLUGIN_ROOT}\u2026 or \${PLUGIN_DATA}\u2026 (the plugin root is used instead)`
796
+ );
797
+ }
798
+ }
799
+ return { serverName, entry: entry2, wrapped };
800
+ }
801
+ const url = server.url ?? "";
802
+ if (url === "") return null;
803
+ if (server.transport === "ws") {
804
+ notes.push(
805
+ `agent-plugin: dropped the "ws" server \u2014 Agent Plugins 1.0.0 defines only stdio, streamable-http and (legacy) sse transports`
806
+ );
807
+ return null;
808
+ }
809
+ const entry = {
810
+ type: server.transport === "sse" ? "sse" : "streamable-http",
811
+ url
812
+ };
813
+ const headers = renderEnv(server.headers);
814
+ if (headers) entry.headers = headers;
815
+ if (server.auth) {
816
+ notes.push(
817
+ `agent-plugin: the server's \`auth\` block is not portable \u2014 Agent Plugins carries only literal HTTP headers; the client handles authentication`
818
+ );
819
+ }
820
+ if (!/^https:\/\//i.test(url) && !/^http:\/\/(localhost|127\.\d+\.\d+\.\d+|\[::1\])(?:[:/]|$)/i.test(url)) {
821
+ notes.push(
822
+ `agent-plugin: remote url "${url}" is not HTTPS \u2014 the spec requires HTTPS for non-loopback endpoints`
823
+ );
824
+ }
825
+ return { serverName, entry, wrapped: false };
826
+ }
827
+ function buildNamespaceHooks(connector, ns, platform, homeBin) {
828
+ const events = connector.hookEvents.filter((e) => CLAUDE_MAPPED_EVENTS.has(e));
829
+ if (events.length === 0) return null;
830
+ const hooks = {};
831
+ for (const event of events) {
832
+ const matcher = connector.hooks[event]?.matcher ?? "";
833
+ const command = {
834
+ type: "command",
835
+ command: hookCommand(ns.hookStyle, homeBin, platform, event, connector.id)
836
+ };
837
+ hooks[event] = [matcher ? { matcher, hooks: [command] } : { hooks: [command] }];
838
+ }
839
+ return { hooks };
840
+ }
841
+ function buildManifest6(connector, extensions) {
842
+ const manifest = {
843
+ $schema: AGENT_PLUGIN_SCHEMA,
844
+ name: toAgentPluginName(connector.id)
845
+ };
846
+ if (connector.version && connector.version !== "0.0.0") {
847
+ manifest.version = connector.version;
848
+ }
849
+ manifest.description = `${connector.displayName} \u2014 connector emitted by agent-connector`;
850
+ const author = connector.publish?.author;
851
+ if (author?.name) {
852
+ const a = { name: author.name };
853
+ if (author.email) a.email = author.email;
854
+ if (author.url) a.url = author.url;
855
+ manifest.author = a;
856
+ }
857
+ if (Object.keys(extensions).length > 0) manifest.extensions = extensions;
858
+ return manifest;
859
+ }
860
+ function renderLauncher() {
861
+ const range = resolveFrameworkDependencyRange();
862
+ const spec = range === "*" ? AGENT_CONNECTOR_PACKAGE_NAME : `${AGENT_CONNECTOR_PACKAGE_NAME}@${range}`;
863
+ return `#!/usr/bin/env node
864
+ /**
865
+ * AUTO-GENERATED by agent-connector \u2014 DO NOT EDIT.
866
+ *
867
+ * Portable launcher for the agent-connector runtime. Agent Plugins packages
868
+ * must not embed absolute paths, so this file resolves the runtime at run time:
869
+ * 1. $AGENT_CONNECTOR_HOME_BIN (explicit override)
870
+ * 2. <$AGENT_CONNECTOR_DATA_DIR | ~/.agent-connector>/bin/agent-connector (the stable home binary)
871
+ * 3. \`agent-connector\` on PATH (a global install)
872
+ * 4. npx -y ${spec} (network; last resort)
873
+ * stdio is inherited so the MCP stdio proxy and hook JSON pass straight through.
874
+ */
875
+ import { spawn } from "node:child_process";
876
+ import { existsSync } from "node:fs";
877
+ import { homedir } from "node:os";
878
+ import { delimiter, join } from "node:path";
879
+
880
+ const win = process.platform === "win32";
881
+ const argv = process.argv.slice(2);
882
+
883
+ function onPath(name) {
884
+ const exts = win ? [".cmd", ".exe", ".bat", ""] : [""];
885
+ for (const dir of (process.env.PATH ?? "").split(delimiter)) {
886
+ if (!dir) continue;
887
+ for (const ext of exts) {
888
+ const candidate = join(dir, name + ext);
889
+ if (existsSync(candidate)) return candidate;
890
+ }
891
+ }
892
+ return null;
893
+ }
894
+
895
+ const dataRoot = process.env.AGENT_CONNECTOR_DATA_DIR || join(homedir(), ".agent-connector");
896
+ const homeBin = join(dataRoot, "bin", win ? "agent-connector.cmd" : "agent-connector");
897
+ const explicit = process.env.AGENT_CONNECTOR_HOME_BIN;
898
+
899
+ let command;
900
+ let args;
901
+ const local = [explicit, homeBin].find((p) => p && existsSync(p)) ?? onPath("agent-connector");
902
+ if (local) {
903
+ command = local;
904
+ args = argv;
905
+ } else {
906
+ command = win ? "npx.cmd" : "npx";
907
+ args = ["-y", ${JSON.stringify(spec)}, ...argv];
908
+ }
909
+
910
+ // .cmd/.bat wrappers need the shell on Windows; everything else spawns directly.
911
+ const shell = win && /\\.(cmd|bat)$/i.test(command);
912
+ const child = spawn(command, args, { stdio: "inherit", windowsHide: true, shell });
913
+ for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
914
+ process.on(signal, () => child.kill(signal));
915
+ }
916
+ child.on("error", (err) => {
917
+ process.stderr.write(\`agent-connector launcher: cannot start \${command}: \${err.message}\\n\`);
918
+ process.exit(1);
919
+ });
920
+ child.on("exit", (code, signal) => {
921
+ if (signal) process.kill(process.pid, signal);
922
+ process.exit(code ?? 1);
923
+ });
924
+ `;
925
+ }
926
+ function buildCatalog(connector) {
927
+ return {
928
+ name: CATALOG_NAME,
929
+ owner: { name: connector.publish?.author?.name ?? CATALOG_NAME },
930
+ plugins: [
931
+ {
932
+ name: connector.id,
933
+ source: `./${connector.id}`,
934
+ description: `${connector.displayName} \u2014 connector emitted by agent-connector`
935
+ }
936
+ ]
937
+ };
938
+ }
939
+ function buildReadme(connector, has) {
940
+ const lines = [
941
+ `# ${connector.displayName} \u2014 Agent Plugin`,
942
+ "",
943
+ `An [Agent Plugins ${AGENT_PLUGIN_SPEC_VERSION}](https://agent-plugins.org) package for the`,
944
+ `\`${connector.id}\` connector, emitted by agent-connector.`,
945
+ "",
946
+ "## Contents",
947
+ "",
948
+ "- `plugin.json` \u2014 the plugin manifest"
949
+ ];
950
+ if (has.mcp) lines.push("- `mcp.json` \u2014 the MCP server entry");
951
+ if (has.skills) lines.push("- `skills/<name>/SKILL.md` \u2014 Agent Skills");
952
+ for (const ns of has.namespaces) {
953
+ lines.push(
954
+ `- \`${ns.namespace}/\` \u2014 client extension namespace for ${ns.label} (other clients ignore it)`
955
+ );
956
+ }
957
+ if (has.launcher) {
958
+ lines.push(
959
+ `- \`${AGENT_PLUGIN_LAUNCHER}\` \u2014 portable launcher that locates the agent-connector runtime (home binary \u2192 PATH \u2192 npx) so per-tool token telemetry carries through without any absolute path in the bundle`
960
+ );
961
+ }
962
+ lines.push(
963
+ "",
964
+ "## Install",
965
+ "",
966
+ "Locally, the directory ABOVE this one is a marketplace root \u2014 register it and",
967
+ `install by name: \`copilot plugin marketplace add <root> && copilot plugin install ${connector.id}@${CATALOG_NAME}\``,
968
+ `or \`codex plugin marketplace add <root> && codex plugin add ${connector.id}@${CATALOG_NAME}\`.`,
969
+ "",
970
+ "To share it, push this directory to a git repository and install it from",
971
+ "source with your client's plugin flow \u2014 in VS Code run **Chat: Install Plugin",
972
+ "From Source** from the Command Palette and enter the repository URL. Every",
973
+ "Agent Plugins client has an equivalent: https://agent-plugins.org/compatible-clients",
974
+ ""
975
+ );
976
+ return lines.join("\n");
977
+ }
978
+ function readAgentPluginManifest(manifestJson) {
979
+ try {
980
+ const parsed = JSON.parse(manifestJson);
981
+ if (parsed.$schema !== AGENT_PLUGIN_SCHEMA) return null;
982
+ return parsed;
983
+ } catch {
984
+ return null;
985
+ }
986
+ }
987
+ var emitAgentPlugin = (connector, ctx) => {
988
+ const { emit, files } = createEmitter(ctx.dryRun);
989
+ const pluginDir = join7(ctx.outDir, connector.id);
990
+ const notes = [];
991
+ const hostHint = ctx.hostHint;
992
+ const hasHooks = connector.hookEvents.some((e) => CLAUDE_MAPPED_EVENTS.has(e));
993
+ const populated = [];
994
+ const extensions = {};
995
+ const namespaceFiles = [];
996
+ let launcherHooks = false;
997
+ let homeBinHooks = false;
998
+ for (const ns of CLIENT_NAMESPACES) {
999
+ const extDir = join7(pluginDir, ns.namespace);
1000
+ const platform = hostHint !== void 0 && ns.readers.includes(hostHint) ? hostHint : ns.platform;
1001
+ const hooksRel = `${ns.namespace}/hooks/hooks.json`;
1002
+ let wrote = false;
1003
+ const hooksJson = hasHooks ? buildNamespaceHooks(connector, ns, platform, ctx.homeBinPath) : null;
1004
+ if (hooksJson) {
1005
+ namespaceFiles.push({ path: join7(extDir, "hooks", "hooks.json"), contents: json(hooksJson) });
1006
+ if (ns.hookStyle === "plugin-root-launcher") launcherHooks = true;
1007
+ else homeBinHooks = true;
1008
+ wrote = true;
1009
+ }
1010
+ if (ns.commandFile) {
1011
+ for (const cmd of connector.commands) {
1012
+ namespaceFiles.push({
1013
+ path: join7(extDir, "commands", ns.commandFile(cmd.name)),
1014
+ contents: renderCommandMd(cmd)
1015
+ });
1016
+ wrote = true;
1017
+ }
1018
+ }
1019
+ if (ns.agentFile) {
1020
+ for (const agent of connector.subagents) {
1021
+ namespaceFiles.push({
1022
+ path: join7(extDir, "agents", ns.agentFile(agent.name)),
1023
+ contents: renderSubagentMd(agent)
1024
+ });
1025
+ wrote = true;
1026
+ }
1027
+ }
1028
+ if (!wrote) continue;
1029
+ populated.push(ns);
1030
+ if (ns.manifestExtension) {
1031
+ const ext = ns.manifestExtension({ hooks: hooksJson ? `./${hooksRel}` : void 0 });
1032
+ if (Object.keys(ext).length > 0) extensions[ns.namespace] = ext;
1033
+ }
1034
+ }
1035
+ emit(join7(pluginDir, "plugin.json"), json(buildManifest6(connector, extensions)));
1036
+ const mcp = buildServerEntry(connector, hostHint, notes);
1037
+ if (mcp) {
1038
+ emit(
1039
+ join7(pluginDir, "mcp.json"),
1040
+ json({
1041
+ $schema: AGENT_PLUGIN_MCP_SCHEMA,
1042
+ mcpServers: { [mcp.serverName]: mcp.entry }
1043
+ })
1044
+ );
1045
+ }
1046
+ for (const skill of connector.skills) {
1047
+ const skillDir = join7(pluginDir, "skills", skill.name);
1048
+ emit(join7(skillDir, "SKILL.md"), renderSkillMd(skill));
1049
+ for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
1050
+ const target = resolveWithin(skillDir, rel);
1051
+ if (target === null) continue;
1052
+ emit(target, contents);
1053
+ }
1054
+ }
1055
+ for (const f of namespaceFiles) emit(f.path, f.contents);
1056
+ if (populated.length > 0) {
1057
+ notes.push(
1058
+ `agent-plugin: hooks/commands/subagents are not portable Agent Plugins 1.0 components \u2014 emitted under the ${populated.map((ns) => `${ns.namespace}/`).join(", ")} client extension namespace(s); clients ignore namespaces they do not own`
1059
+ );
1060
+ }
1061
+ const launcher = launcherHooks || mcp !== null && mcp.wrapped;
1062
+ if (launcher) {
1063
+ emit(join7(pluginDir, AGENT_PLUGIN_LAUNCHER), renderLauncher());
1064
+ notes.push(
1065
+ `agent-plugin: the MCP entry${launcherHooks ? " and Copilot hooks" : ""} run through the bundled launcher ${AGENT_PLUGIN_LAUNCHER} (no absolute path \u2014 resolves the home binary, then PATH, then npx ${AGENT_CONNECTOR_PACKAGE_NAME})`
1066
+ );
1067
+ }
1068
+ if (homeBinHooks) {
1069
+ notes.push(
1070
+ `agent-plugin: com.openai/ hooks call this machine's agent-connector launcher (${ctx.homeBinPath}) \u2014 Codex documents no plugin-root token for hook commands; valid for a local install, re-run \`package\` per machine to share`
1071
+ );
1072
+ }
1073
+ emit(
1074
+ join7(pluginDir, "README.md"),
1075
+ buildReadme(connector, {
1076
+ mcp: mcp !== null,
1077
+ skills: connector.skills.length > 0,
1078
+ namespaces: populated,
1079
+ launcher
1080
+ })
1081
+ );
1082
+ const catalog = json(buildCatalog(connector));
1083
+ const marketplacePath = join7(ctx.outDir, ".claude-plugin", "marketplace.json");
1084
+ emit(marketplacePath, catalog);
1085
+ emit(join7(ctx.outDir, ".agents", "plugins", "marketplace.json"), catalog);
1086
+ const result = { files, pluginDir, marketplacePath };
1087
+ if (notes.length > 0) result.notes = notes;
1088
+ return result;
1089
+ };
1090
+
722
1091
  // src/core/package-formats/mcp-server.ts
723
1092
  import { resolve as resolve2 } from "path";
724
1093
  function buildEnvVars(server) {
@@ -960,10 +1329,14 @@ var emitMcpbBundle = (connector, ctx) => {
960
1329
  };
961
1330
 
962
1331
  // src/core/package.ts
1332
+ var DEFAULT_PACKAGE_FORMAT = "agent-plugin";
1333
+ var LEGACY_FORMAT_ALIASES = {
1334
+ "codex-plugin": "agent-plugin",
1335
+ "copilot-plugin": "agent-plugin"
1336
+ };
963
1337
  var EMITTERS = {
1338
+ "agent-plugin": emitAgentPlugin,
964
1339
  "claude-plugin": emitClaudePlugin,
965
- "codex-plugin": emitCodexPlugin,
966
- "copilot-plugin": emitCopilotPlugin,
967
1340
  "factory-plugin": emitFactoryPlugin,
968
1341
  "gemini-extension": emitGeminiExtension,
969
1342
  "qwen-extension": emitQwenExtension,
@@ -975,9 +1348,8 @@ var EMITTERS = {
975
1348
  mcpb: emitMcpbBundle
976
1349
  };
977
1350
  var ALL_FORMATS = [
1351
+ "agent-plugin",
978
1352
  "claude-plugin",
979
- "codex-plugin",
980
- "copilot-plugin",
981
1353
  "factory-plugin",
982
1354
  "gemini-extension",
983
1355
  "qwen-extension",
@@ -989,9 +1361,8 @@ var ALL_FORMATS = [
989
1361
  "mcpb"
990
1362
  ];
991
1363
  var FEASIBLE_FORMATS = [
1364
+ "agent-plugin",
992
1365
  "claude-plugin",
993
- "codex-plugin",
994
- "copilot-plugin",
995
1366
  "factory-plugin",
996
1367
  "gemini-extension",
997
1368
  "qwen-extension",
@@ -1003,10 +1374,17 @@ var FEASIBLE_FORMATS = [
1003
1374
  function isPackageFormat(s) {
1004
1375
  return Object.prototype.hasOwnProperty.call(EMITTERS, s);
1005
1376
  }
1377
+ function resolvePackageFormat(s) {
1378
+ if (isPackageFormat(s)) return { format: s };
1379
+ const replacement = Object.prototype.hasOwnProperty.call(LEGACY_FORMAT_ALIASES, s) ? LEGACY_FORMAT_ALIASES[s] : void 0;
1380
+ if (replacement === void 0) return null;
1381
+ return {
1382
+ format: replacement,
1383
+ deprecation: `--format ${s} is retired \u2014 emitting ${replacement} instead (the Agent Plugins 1.0.0 bundle both Codex and GitHub Copilot install natively)`
1384
+ };
1385
+ }
1006
1386
  var HOME_BIN_EMBED_FORMATS = /* @__PURE__ */ new Set([
1007
1387
  "claude-plugin",
1008
- "codex-plugin",
1009
- "copilot-plugin",
1010
1388
  "factory-plugin",
1011
1389
  "gemini-extension",
1012
1390
  "qwen-extension",
@@ -1015,7 +1393,7 @@ var HOME_BIN_EMBED_FORMATS = /* @__PURE__ */ new Set([
1015
1393
  "kimi-plugin"
1016
1394
  ]);
1017
1395
  function packageConnector(connector, opts) {
1018
- const format = opts.format ?? "claude-plugin";
1396
+ const format = opts.format ?? DEFAULT_PACKAGE_FORMAT;
1019
1397
  const emitter = EMITTERS[format];
1020
1398
  if (!emitter) {
1021
1399
  throw new Error(`unsupported package format: ${format}`);
@@ -1025,6 +1403,7 @@ function packageConnector(connector, opts) {
1025
1403
  homeBinPath: opts.homeBinPath ?? homeBinPath(),
1026
1404
  dryRun: opts.dryRun ?? false
1027
1405
  };
1406
+ if (opts.hostHint !== void 0) ctx.hostHint = opts.hostHint;
1028
1407
  const result = emitter(connector, ctx);
1029
1408
  if (HOME_BIN_EMBED_FORMATS.has(format)) {
1030
1409
  const note = `bundle embeds this machine's agent-connector launcher path (${ctx.homeBinPath}) \u2014 valid for LOCAL install; for a shared marketplace, consumers need agent-connector at the same home path (run \`agent-connector upgrade\` there) or re-run \`package\` per machine`;
@@ -1048,46 +1427,43 @@ function packageConnectorAll(connector, opts) {
1048
1427
  }
1049
1428
  function installInstructions(format, id, outDir) {
1050
1429
  switch (format) {
1430
+ case "agent-plugin":
1431
+ return [
1432
+ `copilot plugin marketplace add ${outDir} && copilot plugin install ${id}@agent-connector`,
1433
+ `codex plugin marketplace add ${outDir} && codex plugin add ${id}@agent-connector`,
1434
+ `(share: push ${join8(outDir, id)} to a git repo, then VS Code \u2192 "Chat: Install Plugin From Source" <repo url>;`,
1435
+ ` Kiro / Hermes / Cursor / other clients: https://agent-plugins.org/compatible-clients)`
1436
+ ];
1051
1437
  case "claude-plugin":
1052
1438
  return [
1053
1439
  `/plugin marketplace add ${outDir}`,
1054
1440
  `/plugin install ${id}@agent-connector`,
1055
1441
  `(CLI: claude plugin marketplace add ${outDir} && claude plugin install ${id}@agent-connector)`
1056
1442
  ];
1057
- case "codex-plugin":
1058
- return [
1059
- `codex plugin marketplace add ${outDir}`,
1060
- `codex plugin add ${id}@agent-connector`
1061
- ];
1062
- case "copilot-plugin":
1063
- return [
1064
- `copilot plugin marketplace add ${outDir}`,
1065
- `copilot plugin install ${id}@agent-connector`
1066
- ];
1067
1443
  case "factory-plugin":
1068
1444
  return [
1069
1445
  `droid plugin marketplace add ${outDir}`,
1070
1446
  `droid plugin install ${id}@agent-connector`
1071
1447
  ];
1072
1448
  case "gemini-extension":
1073
- return [`gemini extensions install ${join7(outDir, id)}`];
1449
+ return [`gemini extensions install ${join8(outDir, id)}`];
1074
1450
  case "qwen-extension":
1075
- return [`qwen extensions install ${join7(outDir, id)}`];
1451
+ return [`qwen extensions install ${join8(outDir, id)}`];
1076
1452
  case "agy-plugin":
1077
1453
  return [
1078
- `agy plugin install ${join7(outDir, id)}`,
1079
- `(validate: agy plugin validate ${join7(outDir, id)})`
1454
+ `agy plugin install ${join8(outDir, id)}`,
1455
+ `(validate: agy plugin validate ${join8(outDir, id)})`
1080
1456
  ];
1081
1457
  case "cursor-plugin":
1082
1458
  return [
1083
- `link ${join7(outDir, id)} into ~/.cursor/plugins/local/${id}/ then Developer: Reload Window`,
1459
+ `link ${join8(outDir, id)} into ~/.cursor/plugins/local/${id}/ then Developer: Reload Window`,
1084
1460
  `(or publish ${outDir} as a Cursor marketplace repo)`
1085
1461
  ];
1086
1462
  case "kimi-plugin":
1087
- return [`kimi plugin install ${join7(outDir, id)}`];
1463
+ return [`kimi plugin install ${join8(outDir, id)}`];
1088
1464
  case "npm-plugin":
1089
1465
  return [
1090
- `npm publish ${join7(outDir, id)} (then: opencode plugin install <pkg> | kilo plugin <pkg> | pi install npm:<pkg>)`
1466
+ `npm publish ${join8(outDir, id)} (then: opencode plugin install <pkg> | kilo plugin <pkg> | pi install npm:<pkg>)`
1091
1467
  ];
1092
1468
  case "mcp-server-json":
1093
1469
  return [
@@ -1096,7 +1472,7 @@ function installInstructions(format, id, outDir) {
1096
1472
  ];
1097
1473
  case "mcpb":
1098
1474
  return [
1099
- `vendor your built server under ${join7(outDir, "server")}/ (see the emitted README)`,
1475
+ `vendor your built server under ${join8(outDir, "server")}/ (see the emitted README)`,
1100
1476
  `npx @anthropic-ai/mcpb pack ${outDir} (then optionally: mcpb sign)`
1101
1477
  ];
1102
1478
  default:
@@ -1105,11 +1481,13 @@ function installInstructions(format, id, outDir) {
1105
1481
  }
1106
1482
 
1107
1483
  export {
1484
+ readAgentPluginManifest,
1485
+ DEFAULT_PACKAGE_FORMAT,
1108
1486
  ALL_FORMATS,
1109
1487
  FEASIBLE_FORMATS,
1110
- isPackageFormat,
1488
+ resolvePackageFormat,
1111
1489
  packageConnector,
1112
1490
  packageConnectorAll,
1113
1491
  installInstructions
1114
1492
  };
1115
- //# sourceMappingURL=chunk-N4STCQGP.js.map
1493
+ //# sourceMappingURL=chunk-U2XJWG7N.js.map