slidemind 0.0.28 → 0.0.29
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/package.json +1 -1
- package/src/bridge/bundle.mjs +21 -10
- package/src/builders/resolve-skill.mjs +21 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "slidemind",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "Connect Claude Code, Codex & opencode to the slidemind PowerPoint add-in — let your coding agent build and edit native, on-brand PowerPoint decks against your active corporate design, from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/bridge/bundle.mjs
CHANGED
|
@@ -358,16 +358,27 @@ export function loadEnginesForDeck(deckDir) {
|
|
|
358
358
|
return readEnginesFromDir(resolveBundleDirForDeck(deckDir));
|
|
359
359
|
}
|
|
360
360
|
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
//
|
|
361
|
+
// Image-producing engine kinds — the modality "image" plus the finer image
|
|
362
|
+
// content kinds an authored bundle may carry. Excludes "slide" (a slide-search
|
|
363
|
+
// engine returns whole slides, not insertable bytes). Mirrors the add-in's
|
|
364
|
+
// local-bridge `engine_not_image` gate so the CLI never picks an engine the
|
|
365
|
+
// bridge would reject.
|
|
366
|
+
const IMAGE_ENGINE_KIND_RE = /^(image|icon|photo|illustration|vector)$/i;
|
|
367
|
+
|
|
368
|
+
// True when an engine produces insertable image bytes. Gates on the engine's
|
|
369
|
+
// real `kind` (its modality from the design bundle) — NOT a guess over its
|
|
370
|
+
// label/description.
|
|
371
|
+
export function isImageEngine(engine) {
|
|
372
|
+
return IMAGE_ENGINE_KIND_RE.test(engine?.kind ?? "");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Pick the default engine to search: the first image engine, by its real
|
|
376
|
+
// `kind`. Returns null when the CD exposes no image engine (e.g. only a
|
|
377
|
+
// slide-search engine) — callers surface a "wire an image engine" message
|
|
378
|
+
// rather than falling back to an engine the bridge can't insert. Single source
|
|
379
|
+
// of truth for the heuristic shared by the CLI dispatcher (`slidemind search`)
|
|
380
|
+
// and the MCP `slidemind_search_engine` tool.
|
|
364
381
|
export function pickImageEngine(engines) {
|
|
365
382
|
const list = Array.isArray(engines) ? engines : [];
|
|
366
|
-
return (
|
|
367
|
-
list.find((e) =>
|
|
368
|
-
/image|icon/i.test(`${e.kind ?? ""} ${e.label ?? ""} ${e.description ?? ""}`),
|
|
369
|
-
) ||
|
|
370
|
-
list[0] ||
|
|
371
|
-
null
|
|
372
|
-
);
|
|
383
|
+
return list.find(isImageEngine) ?? null;
|
|
373
384
|
}
|
|
@@ -44,6 +44,26 @@ function firstExisting(candidates) {
|
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Does a design root actually carry brand files? A root qualifies if it has the
|
|
48
|
+
// corporate-design CSS or a layouts dir that holds at least one real layout
|
|
49
|
+
// (a `*.jsx` or `layouts.css`). A bare/junk-only `layouts/` — e.g. one left
|
|
50
|
+
// behind on disk holding only a macOS `.DS_Store` — must NOT count, or it would
|
|
51
|
+
// mask the "materialize the bundle first" guidance for a deck that hasn't
|
|
52
|
+
// downloaded one yet.
|
|
53
|
+
function carriesDesign(root, cssName) {
|
|
54
|
+
if (!root) return false;
|
|
55
|
+
if (fs.existsSync(path.join(root, cssName))) return true;
|
|
56
|
+
const layoutsDir = path.join(root, "layouts");
|
|
57
|
+
if (!fs.existsSync(layoutsDir)) return false;
|
|
58
|
+
try {
|
|
59
|
+
return fs
|
|
60
|
+
.readdirSync(layoutsDir)
|
|
61
|
+
.some((f) => f.endsWith(".jsx") || f === "layouts.css");
|
|
62
|
+
} catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
// First existing candidate, or `fallback` when none exist. Encodes the
|
|
48
68
|
// deck-override → bundle → skill precedence in one place so every resolved path
|
|
49
69
|
// shares the same lookup rule.
|
|
@@ -73,12 +93,7 @@ export function resolveSkill(skillName, planMeta = {}, opts = {}) {
|
|
|
73
93
|
const designRoots = [
|
|
74
94
|
bundleDir,
|
|
75
95
|
fs.existsSync(skillDir) ? skillDir : null,
|
|
76
|
-
].filter(
|
|
77
|
-
(r) =>
|
|
78
|
-
r &&
|
|
79
|
-
(fs.existsSync(path.join(r, cssName)) ||
|
|
80
|
-
fs.existsSync(path.join(r, "layouts"))),
|
|
81
|
-
);
|
|
96
|
+
].filter((r) => carriesDesign(r, cssName));
|
|
82
97
|
if (designRoots.length === 0) {
|
|
83
98
|
throw new Error(
|
|
84
99
|
`No design source for skill "${skillName}". The corporate design now lives ` +
|