slidemind 0.1.5 → 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.
- package/.claude-plugin/plugin.json +1 -7
- package/CLAUDE.md +22 -14
- package/README.md +33 -15
- package/bin/slidemind.mjs +1124 -34
- package/package.json +2 -5
- package/skills/create-slides/SKILL.md +95 -47
- package/skills/search/SKILL.md +29 -26
- package/src/bridge/build-and-push.mjs +353 -66
- package/src/bridge/bundle.mjs +49 -7
- package/src/bridge/capture.mjs +2 -2
- package/src/bridge/client.mjs +572 -43
- package/src/bridge/engine-download.mjs +89 -0
- package/src/{mcp → bridge}/recolor.mjs +10 -9
- package/src/builders/build.mjs +209 -13
- package/src/builders/lint.mjs +2 -2
- package/src/builders/review-overlay.js +22 -7
- package/src/builders/review.mjs +8 -15
- package/src/installers/claude.mjs +10 -17
- package/src/installers/codex.mjs +41 -36
- package/src/installers/opencode.mjs +10 -18
- package/src/lib/reused-slides.mjs +2 -4
- package/src/mcp/server.mjs +0 -810
package/src/installers/codex.mjs
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
import fs from "node:fs";
|
|
25
25
|
import path from "node:path";
|
|
26
|
+
import { spawnSync } from "node:child_process";
|
|
26
27
|
import {
|
|
27
28
|
expandHome,
|
|
28
29
|
installDir,
|
|
@@ -40,7 +41,10 @@ const TOML_MARK_BEGIN = "# slidemind:begin";
|
|
|
40
41
|
const TOML_MARK_END = "# slidemind:end";
|
|
41
42
|
|
|
42
43
|
function codexRoot() {
|
|
43
|
-
|
|
44
|
+
// Codex reads everything (skills, AGENTS.md, config.toml) from $CODEX_HOME
|
|
45
|
+
// when set, defaulting to ~/.codex — mirror that so our artifacts land where
|
|
46
|
+
// it actually looks.
|
|
47
|
+
return process.env.CODEX_HOME || expandHome("~/.codex");
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
function promptsDir() {
|
|
@@ -81,38 +85,34 @@ function configTomlFile() {
|
|
|
81
85
|
return path.join(codexRoot(), "config.toml");
|
|
82
86
|
}
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const file = configTomlFile();
|
|
94
|
-
let existing = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : "";
|
|
95
|
-
const re = new RegExp(
|
|
96
|
-
`${TOML_MARK_BEGIN}[\\s\\S]*?${TOML_MARK_END}\\n?`,
|
|
97
|
-
"g",
|
|
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.
|
|
92
|
+
export function unregisterMcpServer() {
|
|
93
|
+
const viaCli = spawnSync(
|
|
94
|
+
"codex",
|
|
95
|
+
["mcp", "remove", NAMESPACE],
|
|
96
|
+
{ stdio: "ignore", shell: process.platform === "win32" },
|
|
98
97
|
);
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
const sep = existing.length && !existing.endsWith("\n") ? "\n\n" : existing.length ? "\n" : "";
|
|
103
|
-
fs.writeFileSync(file, existing + sep + block);
|
|
98
|
+
if (!viaCli.error && viaCli.status === 0) return "unregistered via codex mcp";
|
|
99
|
+
return fallbackClearMcpServerBlock();
|
|
104
100
|
}
|
|
105
101
|
|
|
106
|
-
|
|
102
|
+
// Fallback uninstall: strip a legacy marker-wrapped block if one is present;
|
|
103
|
+
// otherwise point the user at `codex mcp remove` (we won't guess at the bounds
|
|
104
|
+
// of a marker-less table without Codex's TOML parser).
|
|
105
|
+
export function fallbackClearMcpServerBlock() {
|
|
107
106
|
const file = configTomlFile();
|
|
108
|
-
if (!fs.existsSync(file)) return;
|
|
109
|
-
|
|
110
|
-
const re = new RegExp(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
if (!fs.existsSync(file)) return "unregistered";
|
|
108
|
+
const existing = fs.readFileSync(file, "utf8");
|
|
109
|
+
const re = new RegExp(`${TOML_MARK_BEGIN}[\\s\\S]*?${TOML_MARK_END}\\n?`, "g");
|
|
110
|
+
const stripped = existing.replace(re, "");
|
|
111
|
+
if (stripped !== existing) {
|
|
112
|
+
fs.writeFileSync(file, stripped);
|
|
113
|
+
return "unregistered (fallback)";
|
|
114
|
+
}
|
|
115
|
+
return "run `codex mcp remove slidemind` to remove the entry";
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
function writeAgentsBlock() {
|
|
@@ -192,12 +192,17 @@ export async function install({ packageRoot, flags }) {
|
|
|
192
192
|
writeAgentsBlock();
|
|
193
193
|
ui.step({ status: "ok", label: "AGENTS.md", value: agentsFile() });
|
|
194
194
|
|
|
195
|
-
//
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
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
|
+
}
|
|
199
204
|
|
|
200
|
-
ui.note("restart Codex to pick up the skill
|
|
205
|
+
ui.note("restart Codex to pick up the skill");
|
|
201
206
|
}
|
|
202
207
|
|
|
203
208
|
export async function uninstall() {
|
|
@@ -224,6 +229,6 @@ export async function uninstall() {
|
|
|
224
229
|
}
|
|
225
230
|
clearAgentsBlock();
|
|
226
231
|
ui.step({ status: "remove", label: "AGENTS.md", value: agentsFile() });
|
|
227
|
-
|
|
228
|
-
ui.step({ status: "info", label: "mcp server", value:
|
|
232
|
+
const mcpNote = unregisterMcpServer();
|
|
233
|
+
ui.step({ status: "info", label: "mcp server", value: mcpNote });
|
|
229
234
|
}
|
|
@@ -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
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
4
|
-
//
|
|
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
|