slidemind 0.1.6 → 0.1.8
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 +21 -15
- package/README.md +21 -10
- package/bin/slidemind.mjs +836 -35
- package/package.json +2 -5
- package/skills/create-slides/SKILL.md +85 -60
- package/skills/search/SKILL.md +27 -27
- package/src/bridge/build-and-push.mjs +166 -55
- package/src/bridge/bundle.mjs +49 -7
- package/src/bridge/capture.mjs +2 -2
- package/src/bridge/client.mjs +374 -44
- package/src/bridge/engine-download.mjs +89 -0
- package/src/{mcp → bridge}/recolor.mjs +10 -9
- package/src/builders/build.mjs +261 -23
- package/src/builders/gate-server.mjs +223 -0
- package/src/builders/lint.mjs +2 -2
- package/src/builders/plan-md.mjs +216 -0
- package/src/builders/plan-overlay.js +747 -0
- package/src/builders/plan.mjs +575 -0
- package/src/builders/resolve-skill.mjs +40 -5
- package/src/builders/review-overlay.js +172 -16
- package/src/builders/review.mjs +139 -80
- package/src/installers/claude.mjs +10 -17
- package/src/installers/codex.mjs +14 -77
- package/src/installers/opencode.mjs +10 -18
- package/src/lib/reused-slides.mjs +2 -4
- package/src/mcp/server.mjs +0 -958
package/src/installers/codex.mjs
CHANGED
|
@@ -85,36 +85,10 @@ function configTomlFile() {
|
|
|
85
85
|
return path.join(codexRoot(), "config.toml");
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
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
|
-
//
|
|
264
|
-
//
|
|
265
|
-
|
|
266
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|