slidemind 0.1.6 → 0.1.7

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.
@@ -85,36 +85,10 @@ function configTomlFile() {
85
85
  return path.join(codexRoot(), "config.toml");
86
86
  }
87
87
 
88
- // Register the slidemind MCP server. Prefer Codex's own `codex mcp add`, which
89
- // is TOML-aware and idempotent: it sets `[mcp_servers.slidemind]` by key, so a
90
- // re-install/upgrade — or a pre-existing entry added manually or by an earlier
91
- // `codex mcp add` — is REPLACED in place rather than duplicated, while unrelated
92
- // tables, top-level keys, and comments survive.
93
- //
94
- // The previous hand-rolled writer wrapped its block in `# slidemind:begin/end`
95
- // comment markers and deduped by them; a `[mcp_servers.slidemind]` table that
96
- // lacked those markers (manual edit, or a Codex-side config rewrite that dropped
97
- // the comments) was invisible to it, so it appended a SECOND table — a
98
- // duplicate-key TOML that broke config.toml. Delegating to Codex removes that
99
- // whole failure mode.
100
- //
101
- // `codex mcp` landed around Codex 0.128. If the binary is missing or too old
102
- // (spawn error / non-zero exit) we fall back to a minimal, non-destructive
103
- // writer that never duplicates.
104
- export function registerMcpServer(packageRoot) {
105
- const mcpServer = path.join(packageRoot, "src", "mcp", "server.mjs");
106
- const viaCli = spawnSync(
107
- "codex",
108
- ["mcp", "add", NAMESPACE, "--", "node", mcpServer],
109
- { stdio: "ignore", shell: process.platform === "win32" },
110
- );
111
- if (!viaCli.error && viaCli.status === 0) {
112
- sweepLegacyMarkers();
113
- return "registered via codex mcp";
114
- }
115
- return fallbackWriteMcpServerBlock(mcpServer);
116
- }
117
-
88
+ // slidemind is a CLI steered by the skill — there is no MCP server. We only ever
89
+ // tear down a `[mcp_servers.slidemind]` table an older install registered.
90
+ // Prefer Codex's own `codex mcp remove` (TOML-aware); fall back to a marker strip
91
+ // when the binary is missing or too old.
118
92
  export function unregisterMcpServer() {
119
93
  const viaCli = spawnSync(
120
94
  "codex",
@@ -125,30 +99,6 @@ export function unregisterMcpServer() {
125
99
  return fallbackClearMcpServerBlock();
126
100
  }
127
101
 
128
- function mcpServerBlock(mcpServer) {
129
- return (
130
- `[mcp_servers.${NAMESPACE}]\n` +
131
- `command = "node"\n` +
132
- `args = ["${mcpServer.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"]\n`
133
- );
134
- }
135
-
136
- // Fallback for when `codex mcp` is unavailable. Minimal and non-destructive:
137
- // never append a second entry — if a `[mcp_servers.slidemind]` already exists
138
- // (ours or the user's) we leave it untouched; otherwise we append our block.
139
- export function fallbackWriteMcpServerBlock(mcpServer) {
140
- const file = configTomlFile();
141
- const existing = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
142
- if (existing.includes(`[mcp_servers.${NAMESPACE}]`)) {
143
- return "already registered (left as-is)";
144
- }
145
- const sep =
146
- existing.length && !existing.endsWith("\n") ? "\n\n" : existing.length ? "\n" : "";
147
- fs.mkdirSync(path.dirname(file), { recursive: true });
148
- fs.writeFileSync(file, existing + sep + mcpServerBlock(mcpServer));
149
- return "registered (fallback)";
150
- }
151
-
152
102
  // Fallback uninstall: strip a legacy marker-wrapped block if one is present;
153
103
  // otherwise point the user at `codex mcp remove` (we won't guess at the bounds
154
104
  // of a marker-less table without Codex's TOML parser).
@@ -165,24 +115,6 @@ export function fallbackClearMcpServerBlock() {
165
115
  return "run `codex mcp remove slidemind` to remove the entry";
166
116
  }
167
117
 
168
- // After Codex rewrites the `[mcp_servers.slidemind]` table, an upgrader's old
169
- // slidemind block can leave orphan `# slidemind:begin` / `# slidemind:end`
170
- // comment lines behind. Drop just those literal lines (valid TOML either way —
171
- // purely cosmetic).
172
- function sweepLegacyMarkers() {
173
- const file = configTomlFile();
174
- if (!fs.existsSync(file)) return;
175
- const before = fs.readFileSync(file, "utf8");
176
- const after = before
177
- .split("\n")
178
- .filter(
179
- (line) =>
180
- line.trim() !== TOML_MARK_BEGIN && line.trim() !== TOML_MARK_END,
181
- )
182
- .join("\n");
183
- if (after !== before) fs.writeFileSync(file, after);
184
- }
185
-
186
118
  function writeAgentsBlock() {
187
119
  const block =
188
120
  `${AGENTS_MARK_BEGIN}\n` +
@@ -260,12 +192,17 @@ export async function install({ packageRoot, flags }) {
260
192
  writeAgentsBlock();
261
193
  ui.step({ status: "ok", label: "AGENTS.md", value: agentsFile() });
262
194
 
263
- // Register the slidemind MCP server so agents can list/push into open
264
- // PowerPoint windows via slidemind_list_open_presentations / slidemind_push_deck.
265
- const mcpNote = registerMcpServer(packageRoot);
266
- ui.step({ status: "ok", label: "mcp server", value: mcpNote });
195
+ // slidemind is a CLI now — clean up any [mcp_servers.slidemind] table an older
196
+ // install registered so re-running init converges to the CLI-only setup.
197
+ if (
198
+ fs.existsSync(configTomlFile()) &&
199
+ fs.readFileSync(configTomlFile(), "utf8").includes(`[mcp_servers.${NAMESPACE}]`)
200
+ ) {
201
+ const mcpNote = unregisterMcpServer();
202
+ ui.step({ status: "remove", label: "mcp server", value: mcpNote });
203
+ }
267
204
 
268
- ui.note("restart Codex to pick up the skill + MCP server");
205
+ ui.note("restart Codex to pick up the skill");
269
206
  }
270
207
 
271
208
  export async function uninstall() {
@@ -71,28 +71,20 @@ function saveOpencodeConfig(cfg) {
71
71
  fs.writeFileSync(file, JSON.stringify(cfg, null, 2) + "\n");
72
72
  }
73
73
 
74
+ // slidemind is a CLI steered by the skill — there is no MCP server. This only
75
+ // tears down any `mcp.slidemind` entry an older install registered, so re-running
76
+ // `init` converges to the CLI-only setup. Returns whether it removed one.
74
77
  function unregisterMcpServer() {
75
78
  const file = opencodeConfigFile();
76
- if (!fs.existsSync(file)) return;
79
+ if (!fs.existsSync(file)) return false;
77
80
  const cfg = loadOpencodeConfig();
78
81
  if (cfg.mcp && cfg.mcp[NAMESPACE]) {
79
82
  delete cfg.mcp[NAMESPACE];
80
83
  if (Object.keys(cfg.mcp).length === 0) delete cfg.mcp;
81
84
  saveOpencodeConfig(cfg);
85
+ return true;
82
86
  }
83
- }
84
-
85
- function registerMcpServer(packageRoot) {
86
- const mcpServer = path.join(packageRoot, "src", "mcp", "server.mjs");
87
- const cfg = loadOpencodeConfig();
88
- if (!cfg["$schema"]) cfg["$schema"] = "https://opencode.ai/config.json";
89
- cfg.mcp = cfg.mcp || {};
90
- cfg.mcp[NAMESPACE] = {
91
- type: "local",
92
- command: ["node", mcpServer],
93
- enabled: true,
94
- };
95
- saveOpencodeConfig(cfg);
87
+ return false;
96
88
  }
97
89
 
98
90
  function removeLegacyArtifacts() {
@@ -153,10 +145,10 @@ export async function install({ packageRoot, flags }) {
153
145
  );
154
146
  }
155
147
 
156
- // Register the slidemind MCP server so agents can list/push into open
157
- // PowerPoint windows via slidemind_list_open_presentations / slidemind_push_deck.
158
- registerMcpServer(packageRoot);
159
- ui.step({ status: "ok", label: "mcp server", value: opencodeConfigFile() });
148
+ // slidemind is a CLI now — remove any MCP registration an older install left.
149
+ if (unregisterMcpServer()) {
150
+ ui.step({ status: "remove", label: "mcp server", value: "removed legacy registration (slidemind is a CLI)" });
151
+ }
160
152
  }
161
153
 
162
154
  export async function uninstall() {
@@ -1,9 +1,7 @@
1
1
  // Shared numeric-prefix + filename logic for folding reused slide-search
2
2
  // results into a deck as native one-slide .pptx (the "reuse → fold into a deck"
3
- // path). Both `slidemind add-slide` (bin/slidemind.mjs) and the
4
- // `slidemind_add_slide_to_deck` MCP tool (src/mcp/server.mjs) drive the SAME
5
- // math, so it lives here as one pure, tested unit — the callers keep the bridge
6
- // round-trip and the fs write.
3
+ // path behind `slidemind add-slide`, bin/slidemind.mjs). Kept here as one pure,
4
+ // tested unit — the caller keeps the bridge round-trip and the fs write.
7
5
  //
8
6
  // Play order over the CLI is filename order (see src/lib/slide-order.mjs): a
9
7
  // reused slide is named `NN-reused-<shortid>.pptx`, zero-padded to width 2, so