stylegallery 0.1.14 → 0.1.16

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.
@@ -3,6 +3,12 @@
3
3
  // Claude Code: ~/.claude/skills/<name>/SKILL.md and the user-scope "mcpServers"
4
4
  // map in ~/.claude.json. Codex: ~/.agents/skills/<name>/SKILL.md and the
5
5
  // [mcp_servers.<name>] table in $CODEX_HOME/config.toml (default ~/.codex).
6
+ // OmO: ~/.agents/skills/<name>/SKILL.md (shared with Codex) and the
7
+ // "mcpServers" map in <agentDir>/mcp.json, where agentDir is
8
+ // $OMO_CODING_AGENT_DIR (default ~/.omo/agent).
9
+ // A skill file shared by several agents is written or removed once. Uninstall
10
+ // keeps a shared skill while another agent that uses it is still installed
11
+ // (detected) and not part of the same uninstall run.
6
12
  import fs from "node:fs";
7
13
  import os from "node:os";
8
14
  import path from "node:path";
@@ -13,7 +19,7 @@ const SKILL_NAME = "stylegallery-search";
13
19
  const SERVER_NAME = "stylegallery";
14
20
  export const MCP_COMMAND = "npx";
15
21
  export const MCP_ARGS = ["-y", "--package", "stylegallery", "stylegallery-mcp"];
16
- const AGENTS = ["claude", "codex"];
22
+ const AGENTS = ["claude", "codex", "omo"];
17
23
  const PARTS = ["skill", "mcp"];
18
24
 
19
25
  function onPath(binary, env) {
@@ -35,6 +41,11 @@ function locations(home, env) {
35
41
  skill: path.join(home, ".agents", "skills", SKILL_NAME, "SKILL.md"),
36
42
  mcp: path.join(codexHome, "config.toml"),
37
43
  },
44
+ omo: {
45
+ detect: [path.join(home, ".omo")],
46
+ skill: path.join(home, ".agents", "skills", SKILL_NAME, "SKILL.md"),
47
+ mcp: path.join(env.OMO_CODING_AGENT_DIR || path.join(home, ".omo", "agent"), "mcp.json"),
48
+ },
38
49
  };
39
50
  }
40
51
 
@@ -42,12 +53,13 @@ const readText = (file) => (fs.existsSync(file) ? fs.readFileSync(file, "utf8")
42
53
 
43
54
  // --- Claude Code ~/.claude.json -------------------------------------------
44
55
  const claudeEntry = () => ({ type: "stdio", command: MCP_COMMAND, args: [...MCP_ARGS], env: {} });
56
+ const omoEntry = () => ({ command: MCP_COMMAND, args: [...MCP_ARGS] });
45
57
  const sameClaudeEntry = (entry) => entry && entry.command === MCP_COMMAND
46
58
  && JSON.stringify(entry.args) === JSON.stringify(MCP_ARGS)
47
59
  && (entry.type === undefined || entry.type === "stdio")
48
60
  && Object.keys(entry.env ?? {}).length === 0;
49
61
 
50
- function planClaudeMcp(text, uninstall, force) {
62
+ function planJsonMcp(text, uninstall, force, entry) {
51
63
  let config = {};
52
64
  if (text !== null && text.trim() !== "") {
53
65
  try { config = JSON.parse(text); } catch { return { status: "error", message: "existing file is not valid JSON; left untouched" }; }
@@ -63,7 +75,7 @@ function planClaudeMcp(text, uninstall, force) {
63
75
  }
64
76
  if (sameClaudeEntry(current)) return { status: "unchanged" };
65
77
  if (current !== undefined && !force) return { status: "conflict", message: `mcpServers.${SERVER_NAME} already exists with different settings; rerun with --force to replace it` };
66
- return { status: current === undefined ? (text === null ? "created" : "updated") : "replaced", content: `${JSON.stringify({ ...config, mcpServers: { ...servers, [SERVER_NAME]: claudeEntry() } }, null, 2)}\n` };
78
+ return { status: current === undefined ? (text === null ? "created" : "updated") : "replaced", content: `${JSON.stringify({ ...config, mcpServers: { ...servers, [SERVER_NAME]: entry() } }, null, 2)}\n` };
67
79
  }
68
80
 
69
81
  // --- Codex config.toml ----------------------------------------------------
@@ -184,22 +196,34 @@ export function runSetup(args, { env = process.env, home = env.HOME || os.homedi
184
196
  const stamp = now.toISOString().replace(/[:.]/g, "-");
185
197
  const changes = [];
186
198
  const failures = [];
199
+ const handled = new Map();
187
200
  for (const agent of agents) {
188
201
  for (const kind of parts) {
189
202
  const file = where[agent][kind];
190
- const plan = kind === "skill" ? planSkill(file, skillText, options.uninstall, options.force)
191
- : agent === "claude" ? planClaudeMcp(readText(file), options.uninstall, options.force)
192
- : planCodexMcp(readText(file), options.uninstall, options.force);
203
+ const first = handled.get(file);
204
+ if (first) {
205
+ changes.push({ agent, kind, path: file, action: first.action, shared_with: first.agent });
206
+ continue;
207
+ }
208
+ const keeper = options.uninstall && kind === "skill"
209
+ ? detected.find((other) => !agents.includes(other) && where[other].skill === file) : undefined;
210
+ const plan = keeper ? { status: "kept", message: `still used by ${keeper}` }
211
+ : kind === "skill" ? planSkill(file, skillText, options.uninstall, options.force)
212
+ : agent === "claude" ? planJsonMcp(readText(file), options.uninstall, options.force, claudeEntry)
213
+ : agent === "omo" ? planJsonMcp(readText(file), options.uninstall, options.force, omoEntry)
214
+ : planCodexMcp(readText(file), options.uninstall, options.force);
193
215
  const change = { agent, kind, path: file, action: plan.status };
216
+ handled.set(file, change);
194
217
  if (plan.message) change.message = plan.message;
195
218
  if (plan.status === "conflict" || plan.status === "error") failures.push({ code: `setup_${plan.status}`, message: `${file}: ${plan.message}` });
196
- else if (plan.status !== "unchanged" && !options.dryRun) Object.assign(change, apply(kind, file, plan, stamp));
219
+ else if (plan.status !== "unchanged" && plan.status !== "kept" && !options.dryRun) Object.assign(change, apply(kind, file, plan, stamp));
197
220
  changes.push(change);
198
221
  }
199
222
  }
200
223
  const next = options.uninstall ? [] : [
201
224
  ...(agents.includes("claude") && parts.includes("mcp") ? ["claude mcp list"] : []),
202
225
  ...(agents.includes("codex") && parts.includes("mcp") ? ["codex mcp list"] : []),
226
+ ...(agents.includes("omo") && parts.includes("mcp") ? ["restart omo to load mcp.json"] : []),
203
227
  ];
204
228
  return {
205
229
  ok: failures.length === 0,
@@ -209,7 +233,7 @@ export function runSetup(args, { env = process.env, home = env.HOME || os.homedi
209
233
  agents,
210
234
  mcp: { name: SERVER_NAME, command: MCP_COMMAND, args: MCP_ARGS },
211
235
  changes,
212
- ...(agents.length === 0 ? { hint: "No Claude Code or Codex installation detected; pass --agent claude, codex, or all." } : {}),
236
+ ...(agents.length === 0 ? { hint: "No Claude Code, Codex, or OmO installation detected; pass --agent claude, codex, omo, or all." } : {}),
213
237
  ...(next.length && !options.dryRun && failures.length === 0 ? { next } : {}),
214
238
  failures,
215
239
  };