@kolisachint/hoocode-agent 0.4.111 → 0.4.112

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 (39) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/cli/args.d.ts +1 -0
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +8 -3
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/extensions/loader.d.ts +10 -1
  7. package/dist/core/extensions/loader.d.ts.map +1 -1
  8. package/dist/core/extensions/loader.js +17 -2
  9. package/dist/core/extensions/loader.js.map +1 -1
  10. package/dist/core/extensions/plugins/marketplace.d.ts +36 -5
  11. package/dist/core/extensions/plugins/marketplace.d.ts.map +1 -1
  12. package/dist/core/extensions/plugins/marketplace.js +63 -17
  13. package/dist/core/extensions/plugins/marketplace.js.map +1 -1
  14. package/dist/core/scheduler.d.ts +8 -2
  15. package/dist/core/scheduler.d.ts.map +1 -1
  16. package/dist/core/scheduler.js +9 -3
  17. package/dist/core/scheduler.js.map +1 -1
  18. package/dist/core/settings-defaults.d.ts +1 -1
  19. package/dist/core/settings-defaults.d.ts.map +1 -1
  20. package/dist/core/settings-defaults.js +2 -2
  21. package/dist/core/settings-defaults.js.map +1 -1
  22. package/dist/core/settings-types.d.ts.map +1 -1
  23. package/dist/core/settings-types.js.map +1 -1
  24. package/dist/core/tools/subagent.d.ts +15 -3
  25. package/dist/core/tools/subagent.d.ts.map +1 -1
  26. package/dist/core/tools/subagent.js +27 -14
  27. package/dist/core/tools/subagent.js.map +1 -1
  28. package/dist/extensions/core/loop.d.ts.map +1 -1
  29. package/dist/extensions/core/loop.js +4 -1
  30. package/dist/extensions/core/loop.js.map +1 -1
  31. package/dist/extensions/core/marketplace.d.ts +5 -3
  32. package/dist/extensions/core/marketplace.d.ts.map +1 -1
  33. package/dist/extensions/core/marketplace.js +37 -15
  34. package/dist/extensions/core/marketplace.js.map +1 -1
  35. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  36. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  37. package/examples/extensions/sandbox/package.json +1 -1
  38. package/examples/extensions/with-deps/package.json +1 -1
  39. package/package.json +4 -4
@@ -2,9 +2,11 @@
2
2
  * /plugin — marketplace add/list + plugin install/list/remove.
3
3
  *
4
4
  * `/plugin` installs plugins from marketplaces (a git repo or local dir with a
5
- * Claude `.claude-plugin/marketplace.json` or Copilot-style `.github/marketplace.json`
6
- * index). Installed plugins are placed in `.hoocode/plugins/<name>` and loaded by the
7
- * plugin loader after a reload.
5
+ * native `.agents-plugin/marketplace.json`, Claude `.claude-plugin/marketplace.json`,
6
+ * or Copilot-style `.github/marketplace.json` index). Installed plugins are placed in
7
+ * `.agents/plugins/<name>` (the primary, cross-vendor home) and loaded by the plugin
8
+ * loader after a reload. Plugins hand-placed under `.hoocode/plugins/` are still
9
+ * discovered and can be removed, but new installs go to `.agents/`.
8
10
  *
9
11
  * /plugin marketplace add <git-url|path>
10
12
  * /plugin marketplace list
@@ -22,11 +24,24 @@ function isGitSource(loc) {
22
24
  return /^https?:\/\//.test(loc) || loc.startsWith("git@") || loc.endsWith(".git");
23
25
  }
24
26
  export function setupMarketplace(pi) {
25
- const storePath = (cwd) => join(cwd, ".hoocode", "marketplaces.json");
26
- const pluginsDir = (cwd) => join(cwd, ".hoocode", "plugins");
27
- const cacheDir = (cwd) => join(cwd, ".hoocode", "marketplace-cache");
27
+ // `.agents/` is the primary, cross-vendor home for installed plugins and the
28
+ // added-marketplace registry, matching the "`.agents/` first" policy. Legacy
29
+ // `.hoocode/plugins/` is still discovered and honored by `remove`.
30
+ const storePath = (cwd) => join(cwd, ".agents", "marketplaces.json");
31
+ const legacyStorePath = (cwd) => join(cwd, ".hoocode", "marketplaces.json");
32
+ const pluginsDir = (cwd) => join(cwd, ".agents", "plugins");
33
+ const legacyPluginsDir = (cwd) => join(cwd, ".hoocode", "plugins");
34
+ const cacheDir = (cwd) => join(cwd, ".agents", "marketplace-cache");
35
+ // Read the registry from `.agents/` first, falling back to the legacy
36
+ // `.hoocode/` location so marketplaces added before the move stay visible.
37
+ const readStore = (cwd) => {
38
+ const primary = readMarketplaceStore(storePath(cwd));
39
+ if (primary.length > 0 || existsSync(storePath(cwd)))
40
+ return primary;
41
+ return readMarketplaceStore(legacyStorePath(cwd));
42
+ };
28
43
  const findPlugin = (cwd, name) => {
29
- for (const record of readMarketplaceStore(storePath(cwd))) {
44
+ for (const record of readStore(cwd)) {
30
45
  const market = parseMarketplaceDir(record.dir);
31
46
  const entry = market?.plugins.find((p) => p.name === name);
32
47
  if (market && entry)
@@ -46,14 +61,15 @@ export function setupMarketplace(pi) {
46
61
  if (trimmed.startsWith("marketplace")) {
47
62
  const sub = trimmed.slice("marketplace".length).trim();
48
63
  if (sub === "list" || sub === "") {
49
- const records = readMarketplaceStore(storePath(cwd));
64
+ const records = readStore(cwd);
50
65
  if (records.length === 0) {
51
66
  ctx.ui.notify("No marketplaces. Add one with /plugin marketplace add <git-url|path>.", "info");
52
67
  return;
53
68
  }
54
69
  const lines = records.map((r) => {
55
70
  const market = parseMarketplaceDir(r.dir);
56
- return `${market?.name ?? r.location} ${market?.plugins.length ?? 0} plugin(s) [${r.location}]`;
71
+ const platforms = market && market.supportPlatform.length > 1 ? ` · ${market.supportPlatform.join(", ")}` : "";
72
+ return `${market?.name ?? r.location} — ${market?.plugins.length ?? 0} plugin(s)${platforms} [${r.location}]`;
57
73
  });
58
74
  ctx.ui.notify(lines.join("\n"), "info");
59
75
  return;
@@ -84,10 +100,10 @@ export function setupMarketplace(pi) {
84
100
  }
85
101
  const market = parseMarketplaceDir(dir);
86
102
  if (!market) {
87
- ctx.ui.notify("No marketplace manifest found (.claude-plugin/ or .github/marketplace.json).", "error");
103
+ ctx.ui.notify("No marketplace manifest found (.agents-plugin/, .claude-plugin/, or .github/marketplace.json).", "error");
88
104
  return;
89
105
  }
90
- const records = readMarketplaceStore(storePath(cwd)).filter((r) => r.location !== loc);
106
+ const records = readStore(cwd).filter((r) => r.location !== loc);
91
107
  records.push({ location: loc, dir });
92
108
  writeMarketplaceStore(storePath(cwd), records);
93
109
  ctx.ui.notify(`Added marketplace "${market.name}" (${market.plugins.length} plugin(s)).`, "info");
@@ -98,7 +114,7 @@ export function setupMarketplace(pi) {
98
114
  }
99
115
  // ── list available plugins ──────────────────────────────────────────
100
116
  if (trimmed === "list" || trimmed === "") {
101
- const records = readMarketplaceStore(storePath(cwd));
117
+ const records = readStore(cwd);
102
118
  const lines = [];
103
119
  for (const record of records) {
104
120
  const market = parseMarketplaceDir(record.dir);
@@ -150,12 +166,18 @@ export function setupMarketplace(pi) {
150
166
  ctx.ui.notify("Usage: /plugin remove <name>", "warning");
151
167
  return;
152
168
  }
153
- const dest = join(pluginsDir(cwd), sanitizeForDir(name));
154
- if (!existsSync(dest)) {
169
+ // Remove from `.agents/` first, then the legacy `.hoocode/` location.
170
+ const candidates = [
171
+ join(pluginsDir(cwd), sanitizeForDir(name)),
172
+ join(legacyPluginsDir(cwd), sanitizeForDir(name)),
173
+ ];
174
+ const installed = candidates.filter((p) => existsSync(p));
175
+ if (installed.length === 0) {
155
176
  ctx.ui.notify(`Plugin "${name}" is not installed.`, "info");
156
177
  return;
157
178
  }
158
- rmSync(dest, { recursive: true, force: true });
179
+ for (const p of installed)
180
+ rmSync(p, { recursive: true, force: true });
159
181
  ctx.ui.notify(`Removed "${name}" — reloading…`, "info");
160
182
  await ctx.reload();
161
183
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../../src/extensions/core/marketplace.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /plugin — marketplace add/list + plugin install/list/remove.\n *\n * `/plugin` installs plugins from marketplaces (a git repo or local dir with a\n * Claude `.claude-plugin/marketplace.json` or Copilot-style `.github/marketplace.json`\n * index). Installed plugins are placed in `.hoocode/plugins/<name>` and loaded by the\n * plugin loader after a reload.\n *\n * /plugin marketplace add <git-url|path>\n * /plugin marketplace list\n * /plugin list list available plugins across marketplaces\n * /plugin install <name>\n * /plugin remove <name>\n */\n\nimport { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n\tparseMarketplaceDir,\n\treadMarketplaceStore,\n\tresolvePluginSource,\n\twriteMarketplaceStore,\n} from \"../../core/extensions/plugins/marketplace.js\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.js\";\n\nfunction sanitizeForDir(s: string): string {\n\treturn s.replace(/[^a-zA-Z0-9._-]+/g, \"_\").slice(0, 80);\n}\n\nfunction isGitSource(loc: string): boolean {\n\treturn /^https?:\\/\\//.test(loc) || loc.startsWith(\"git@\") || loc.endsWith(\".git\");\n}\n\nexport function setupMarketplace(pi: ExtensionAPI): void {\n\tconst storePath = (cwd: string) => join(cwd, \".hoocode\", \"marketplaces.json\");\n\tconst pluginsDir = (cwd: string) => join(cwd, \".hoocode\", \"plugins\");\n\tconst cacheDir = (cwd: string) => join(cwd, \".hoocode\", \"marketplace-cache\");\n\n\tconst findPlugin = (cwd: string, name: string) => {\n\t\tfor (const record of readMarketplaceStore(storePath(cwd))) {\n\t\t\tconst market = parseMarketplaceDir(record.dir);\n\t\t\tconst entry = market?.plugins.find((p) => p.name === name);\n\t\t\tif (market && entry) return { market, entry };\n\t\t}\n\t\treturn undefined;\n\t};\n\n\tpi.registerCommand(\"plugin\", {\n\t\tdescription:\n\t\t\t\"Manage plugin marketplaces. /plugin marketplace add <git-url|path> | /plugin marketplace list | /plugin list | /plugin install <name> | /plugin remove <name>\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\t[\"marketplace\", \"list\", \"install\", \"remove\"]\n\t\t\t\t.filter((s) => s.startsWith(prefix))\n\t\t\t\t.map((s) => ({ value: s, label: s })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst cwd = ctx.cwd;\n\n\t\t\t// ── marketplace add / list ──────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"marketplace\")) {\n\t\t\t\tconst sub = trimmed.slice(\"marketplace\".length).trim();\n\n\t\t\t\tif (sub === \"list\" || sub === \"\") {\n\t\t\t\t\tconst records = readMarketplaceStore(storePath(cwd));\n\t\t\t\t\tif (records.length === 0) {\n\t\t\t\t\t\tctx.ui.notify(\"No marketplaces. Add one with /plugin marketplace add <git-url|path>.\", \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst lines = records.map((r) => {\n\t\t\t\t\t\tconst market = parseMarketplaceDir(r.dir);\n\t\t\t\t\t\treturn `${market?.name ?? r.location} — ${market?.plugins.length ?? 0} plugin(s) [${r.location}]`;\n\t\t\t\t\t});\n\t\t\t\t\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (sub.startsWith(\"add\")) {\n\t\t\t\t\tconst loc = sub.slice(\"add\".length).trim();\n\t\t\t\t\tif (!loc) {\n\t\t\t\t\t\tctx.ui.notify(\"Usage: /plugin marketplace add <git-url|path>\", \"warning\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet dir: string;\n\t\t\t\t\tif (isGitSource(loc)) {\n\t\t\t\t\t\tdir = join(cacheDir(cwd), sanitizeForDir(loc));\n\t\t\t\t\t\trmSync(dir, { recursive: true, force: true });\n\t\t\t\t\t\tmkdirSync(cacheDir(cwd), { recursive: true });\n\t\t\t\t\t\tconst res = await pi.exec(\"git\", [\"clone\", \"--depth\", \"1\", loc, dir]);\n\t\t\t\t\t\tif (res.code !== 0) {\n\t\t\t\t\t\t\tctx.ui.notify(`Clone failed: ${res.stderr || res.stdout}`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdir = resolvePluginSource(loc, cwd).kind === \"local\" ? join(cwd, loc) : loc;\n\t\t\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\t\t\tctx.ui.notify(`Path not found: ${dir}`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst market = parseMarketplaceDir(dir);\n\t\t\t\t\tif (!market) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\"No marketplace manifest found (.claude-plugin/ or .github/marketplace.json).\",\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst records = readMarketplaceStore(storePath(cwd)).filter((r) => r.location !== loc);\n\t\t\t\t\trecords.push({ location: loc, dir });\n\t\t\t\t\twriteMarketplaceStore(storePath(cwd), records);\n\t\t\t\t\tctx.ui.notify(`Added marketplace \"${market.name}\" (${market.plugins.length} plugin(s)).`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tctx.ui.notify(\"Usage: /plugin marketplace add <git-url|path> | /plugin marketplace list\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── list available plugins ──────────────────────────────────────────\n\t\t\tif (trimmed === \"list\" || trimmed === \"\") {\n\t\t\t\tconst records = readMarketplaceStore(storePath(cwd));\n\t\t\t\tconst lines: string[] = [];\n\t\t\t\tfor (const record of records) {\n\t\t\t\t\tconst market = parseMarketplaceDir(record.dir);\n\t\t\t\t\tfor (const p of market?.plugins ?? []) {\n\t\t\t\t\t\tlines.push(`${p.name} — ${p.description ?? p.source}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tctx.ui.notify(lines.length ? lines.join(\"\\n\") : \"No plugins available. Add a marketplace first.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── install <name> ──────────────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"install\")) {\n\t\t\t\tconst name = trimmed.slice(\"install\".length).trim();\n\t\t\t\tif (!name) {\n\t\t\t\t\tctx.ui.notify(\"Usage: /plugin install <name>\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst found = findPlugin(cwd, name);\n\t\t\t\tif (!found) {\n\t\t\t\t\tctx.ui.notify(`Plugin \"${name}\" not found in any marketplace.`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst resolved = resolvePluginSource(found.entry.source, found.market.root);\n\t\t\t\tconst dest = join(pluginsDir(cwd), sanitizeForDir(name));\n\t\t\t\trmSync(dest, { recursive: true, force: true });\n\t\t\t\tmkdirSync(pluginsDir(cwd), { recursive: true });\n\n\t\t\t\tif (resolved.kind === \"local\") {\n\t\t\t\t\tcpSync(resolved.path, dest, { recursive: true });\n\t\t\t\t} else if (resolved.kind === \"git\") {\n\t\t\t\t\tconst res = await pi.exec(\"git\", [\"clone\", \"--depth\", \"1\", resolved.url, dest]);\n\t\t\t\t\tif (res.code !== 0) {\n\t\t\t\t\t\tctx.ui.notify(`Clone failed: ${res.stderr || res.stdout}`, \"error\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tctx.ui.notify(`npm plugin sources are not supported yet (${resolved.spec}).`, \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tctx.ui.notify(`Installed \"${name}\" — reloading…`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── remove <name> ───────────────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"remove\")) {\n\t\t\t\tconst name = trimmed.slice(\"remove\".length).trim();\n\t\t\t\tif (!name) {\n\t\t\t\t\tctx.ui.notify(\"Usage: /plugin remove <name>\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst dest = join(pluginsDir(cwd), sanitizeForDir(name));\n\t\t\t\tif (!existsSync(dest)) {\n\t\t\t\t\tctx.ui.notify(`Plugin \"${name}\" is not installed.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trmSync(dest, { recursive: true, force: true });\n\t\t\t\tctx.ui.notify(`Removed \"${name}\" — reloading…`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.ui.notify(\n\t\t\t\t\"Usage: /plugin marketplace add|list | /plugin list | /plugin install <name> | /plugin remove <name>\",\n\t\t\t\t\"warning\",\n\t\t\t);\n\t\t},\n\t});\n}\n"]}
1
+ {"version":3,"file":"marketplace.js","sourceRoot":"","sources":["../../../src/extensions/core/marketplace.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /plugin — marketplace add/list + plugin install/list/remove.\n *\n * `/plugin` installs plugins from marketplaces (a git repo or local dir with a\n * native `.agents-plugin/marketplace.json`, Claude `.claude-plugin/marketplace.json`,\n * or Copilot-style `.github/marketplace.json` index). Installed plugins are placed in\n * `.agents/plugins/<name>` (the primary, cross-vendor home) and loaded by the plugin\n * loader after a reload. Plugins hand-placed under `.hoocode/plugins/` are still\n * discovered and can be removed, but new installs go to `.agents/`.\n *\n * /plugin marketplace add <git-url|path>\n * /plugin marketplace list\n * /plugin list list available plugins across marketplaces\n * /plugin install <name>\n * /plugin remove <name>\n */\n\nimport { cpSync, existsSync, mkdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n\tparseMarketplaceDir,\n\treadMarketplaceStore,\n\tresolvePluginSource,\n\twriteMarketplaceStore,\n} from \"../../core/extensions/plugins/marketplace.js\";\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.js\";\n\nfunction sanitizeForDir(s: string): string {\n\treturn s.replace(/[^a-zA-Z0-9._-]+/g, \"_\").slice(0, 80);\n}\n\nfunction isGitSource(loc: string): boolean {\n\treturn /^https?:\\/\\//.test(loc) || loc.startsWith(\"git@\") || loc.endsWith(\".git\");\n}\n\nexport function setupMarketplace(pi: ExtensionAPI): void {\n\t// `.agents/` is the primary, cross-vendor home for installed plugins and the\n\t// added-marketplace registry, matching the \"`.agents/` first\" policy. Legacy\n\t// `.hoocode/plugins/` is still discovered and honored by `remove`.\n\tconst storePath = (cwd: string) => join(cwd, \".agents\", \"marketplaces.json\");\n\tconst legacyStorePath = (cwd: string) => join(cwd, \".hoocode\", \"marketplaces.json\");\n\tconst pluginsDir = (cwd: string) => join(cwd, \".agents\", \"plugins\");\n\tconst legacyPluginsDir = (cwd: string) => join(cwd, \".hoocode\", \"plugins\");\n\tconst cacheDir = (cwd: string) => join(cwd, \".agents\", \"marketplace-cache\");\n\n\t// Read the registry from `.agents/` first, falling back to the legacy\n\t// `.hoocode/` location so marketplaces added before the move stay visible.\n\tconst readStore = (cwd: string) => {\n\t\tconst primary = readMarketplaceStore(storePath(cwd));\n\t\tif (primary.length > 0 || existsSync(storePath(cwd))) return primary;\n\t\treturn readMarketplaceStore(legacyStorePath(cwd));\n\t};\n\n\tconst findPlugin = (cwd: string, name: string) => {\n\t\tfor (const record of readStore(cwd)) {\n\t\t\tconst market = parseMarketplaceDir(record.dir);\n\t\t\tconst entry = market?.plugins.find((p) => p.name === name);\n\t\t\tif (market && entry) return { market, entry };\n\t\t}\n\t\treturn undefined;\n\t};\n\n\tpi.registerCommand(\"plugin\", {\n\t\tdescription:\n\t\t\t\"Manage plugin marketplaces. /plugin marketplace add <git-url|path> | /plugin marketplace list | /plugin list | /plugin install <name> | /plugin remove <name>\",\n\t\tgetArgumentCompletions: (prefix: string) =>\n\t\t\t[\"marketplace\", \"list\", \"install\", \"remove\"]\n\t\t\t\t.filter((s) => s.startsWith(prefix))\n\t\t\t\t.map((s) => ({ value: s, label: s })),\n\t\thandler: async (args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\tconst trimmed = args.trim();\n\t\t\tconst cwd = ctx.cwd;\n\n\t\t\t// ── marketplace add / list ──────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"marketplace\")) {\n\t\t\t\tconst sub = trimmed.slice(\"marketplace\".length).trim();\n\n\t\t\t\tif (sub === \"list\" || sub === \"\") {\n\t\t\t\t\tconst records = readStore(cwd);\n\t\t\t\t\tif (records.length === 0) {\n\t\t\t\t\t\tctx.ui.notify(\"No marketplaces. Add one with /plugin marketplace add <git-url|path>.\", \"info\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst lines = records.map((r) => {\n\t\t\t\t\t\tconst market = parseMarketplaceDir(r.dir);\n\t\t\t\t\t\tconst platforms =\n\t\t\t\t\t\t\tmarket && market.supportPlatform.length > 1 ? ` · ${market.supportPlatform.join(\", \")}` : \"\";\n\t\t\t\t\t\treturn `${market?.name ?? r.location} — ${market?.plugins.length ?? 0} plugin(s)${platforms} [${r.location}]`;\n\t\t\t\t\t});\n\t\t\t\t\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (sub.startsWith(\"add\")) {\n\t\t\t\t\tconst loc = sub.slice(\"add\".length).trim();\n\t\t\t\t\tif (!loc) {\n\t\t\t\t\t\tctx.ui.notify(\"Usage: /plugin marketplace add <git-url|path>\", \"warning\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet dir: string;\n\t\t\t\t\tif (isGitSource(loc)) {\n\t\t\t\t\t\tdir = join(cacheDir(cwd), sanitizeForDir(loc));\n\t\t\t\t\t\trmSync(dir, { recursive: true, force: true });\n\t\t\t\t\t\tmkdirSync(cacheDir(cwd), { recursive: true });\n\t\t\t\t\t\tconst res = await pi.exec(\"git\", [\"clone\", \"--depth\", \"1\", loc, dir]);\n\t\t\t\t\t\tif (res.code !== 0) {\n\t\t\t\t\t\t\tctx.ui.notify(`Clone failed: ${res.stderr || res.stdout}`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdir = resolvePluginSource(loc, cwd).kind === \"local\" ? join(cwd, loc) : loc;\n\t\t\t\t\t\tif (!existsSync(dir)) {\n\t\t\t\t\t\t\tctx.ui.notify(`Path not found: ${dir}`, \"error\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst market = parseMarketplaceDir(dir);\n\t\t\t\t\tif (!market) {\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\t\"No marketplace manifest found (.agents-plugin/, .claude-plugin/, or .github/marketplace.json).\",\n\t\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst records = readStore(cwd).filter((r) => r.location !== loc);\n\t\t\t\t\trecords.push({ location: loc, dir });\n\t\t\t\t\twriteMarketplaceStore(storePath(cwd), records);\n\t\t\t\t\tctx.ui.notify(`Added marketplace \"${market.name}\" (${market.plugins.length} plugin(s)).`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tctx.ui.notify(\"Usage: /plugin marketplace add <git-url|path> | /plugin marketplace list\", \"warning\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── list available plugins ──────────────────────────────────────────\n\t\t\tif (trimmed === \"list\" || trimmed === \"\") {\n\t\t\t\tconst records = readStore(cwd);\n\t\t\t\tconst lines: string[] = [];\n\t\t\t\tfor (const record of records) {\n\t\t\t\t\tconst market = parseMarketplaceDir(record.dir);\n\t\t\t\t\tfor (const p of market?.plugins ?? []) {\n\t\t\t\t\t\tlines.push(`${p.name} — ${p.description ?? p.source}`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tctx.ui.notify(lines.length ? lines.join(\"\\n\") : \"No plugins available. Add a marketplace first.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── install <name> ──────────────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"install\")) {\n\t\t\t\tconst name = trimmed.slice(\"install\".length).trim();\n\t\t\t\tif (!name) {\n\t\t\t\t\tctx.ui.notify(\"Usage: /plugin install <name>\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst found = findPlugin(cwd, name);\n\t\t\t\tif (!found) {\n\t\t\t\t\tctx.ui.notify(`Plugin \"${name}\" not found in any marketplace.`, \"error\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst resolved = resolvePluginSource(found.entry.source, found.market.root);\n\t\t\t\tconst dest = join(pluginsDir(cwd), sanitizeForDir(name));\n\t\t\t\trmSync(dest, { recursive: true, force: true });\n\t\t\t\tmkdirSync(pluginsDir(cwd), { recursive: true });\n\n\t\t\t\tif (resolved.kind === \"local\") {\n\t\t\t\t\tcpSync(resolved.path, dest, { recursive: true });\n\t\t\t\t} else if (resolved.kind === \"git\") {\n\t\t\t\t\tconst res = await pi.exec(\"git\", [\"clone\", \"--depth\", \"1\", resolved.url, dest]);\n\t\t\t\t\tif (res.code !== 0) {\n\t\t\t\t\t\tctx.ui.notify(`Clone failed: ${res.stderr || res.stdout}`, \"error\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tctx.ui.notify(`npm plugin sources are not supported yet (${resolved.spec}).`, \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tctx.ui.notify(`Installed \"${name}\" — reloading…`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// ── remove <name> ───────────────────────────────────────────────────\n\t\t\tif (trimmed.startsWith(\"remove\")) {\n\t\t\t\tconst name = trimmed.slice(\"remove\".length).trim();\n\t\t\t\tif (!name) {\n\t\t\t\t\tctx.ui.notify(\"Usage: /plugin remove <name>\", \"warning\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// Remove from `.agents/` first, then the legacy `.hoocode/` location.\n\t\t\t\tconst candidates = [\n\t\t\t\t\tjoin(pluginsDir(cwd), sanitizeForDir(name)),\n\t\t\t\t\tjoin(legacyPluginsDir(cwd), sanitizeForDir(name)),\n\t\t\t\t];\n\t\t\t\tconst installed = candidates.filter((p) => existsSync(p));\n\t\t\t\tif (installed.length === 0) {\n\t\t\t\t\tctx.ui.notify(`Plugin \"${name}\" is not installed.`, \"info\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const p of installed) rmSync(p, { recursive: true, force: true });\n\t\t\t\tctx.ui.notify(`Removed \"${name}\" — reloading…`, \"info\");\n\t\t\t\tawait ctx.reload();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tctx.ui.notify(\n\t\t\t\t\"Usage: /plugin marketplace add|list | /plugin list | /plugin install <name> | /plugin remove <name>\",\n\t\t\t\t\"warning\",\n\t\t\t);\n\t\t},\n\t});\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.2.108",
4
+ "version": "0.2.109",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.2.108",
4
+ "version": "0.2.109",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-sandbox",
3
3
  "private": true,
4
- "version": "0.2.108",
4
+ "version": "0.2.109",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.2.108",
4
+ "version": "0.2.109",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-agent",
3
- "version": "0.4.111",
3
+ "version": "0.4.112",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "hoocodeConfig": {
@@ -45,9 +45,9 @@
45
45
  "prepublishOnly": "npm run clean && npm run build"
46
46
  },
47
47
  "dependencies": {
48
- "@kolisachint/hoocode-agent-core": "^0.4.111",
49
- "@kolisachint/hoocode-ai": "^0.4.111",
50
- "@kolisachint/hoocode-tui": "^0.4.111",
48
+ "@kolisachint/hoocode-agent-core": "^0.4.112",
49
+ "@kolisachint/hoocode-ai": "^0.4.112",
50
+ "@kolisachint/hoocode-tui": "^0.4.112",
51
51
  "@silvia-odwyer/photon-node": "^0.3.4",
52
52
  "chalk": "^5.5.0",
53
53
  "cli-highlight": "^2.1.11",