slidemind 0.3.13 → 0.3.14
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 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +86 -21
- package/README.md +14 -17
- package/bin/slidemind.mjs +65 -4969
- package/package.json +1 -1
- package/skills/create-slides/SKILL.md +113 -74
- package/skills/search/SKILL.md +25 -7
- package/src/bridge/build-and-push.mjs +108 -15
- package/src/bridge/bundle.mjs +69 -0
- package/src/bridge/capture.mjs +19 -0
- package/src/bridge/client/brands.mjs +622 -0
- package/src/bridge/client/engine-routing.mjs +237 -0
- package/src/bridge/client/engine-search.mjs +310 -0
- package/src/bridge/client/engine-slides.mjs +435 -0
- package/src/bridge/client/pane-ops.mjs +335 -0
- package/src/bridge/client/presentations.mjs +587 -0
- package/src/bridge/client/render.mjs +317 -0
- package/src/bridge/client/transport.mjs +695 -0
- package/src/bridge/client.mjs +80 -3452
- package/src/bridge/config.mjs +1 -1
- package/src/bridge/engine-download.mjs +15 -2
- package/src/builders/build.mjs +11 -804
- package/src/builders/draft-check.mjs +376 -0
- package/src/builders/lint.mjs +38 -2
- package/src/builders/preview.html +799 -0
- package/src/builders/review.mjs +23 -4
- package/src/builders/visual-families.mjs +6 -8
- package/src/cli/common.mjs +179 -0
- package/src/cli/concepts.mjs +310 -0
- package/src/cli/connection.mjs +147 -0
- package/src/cli/deck.mjs +608 -0
- package/src/cli/designs.mjs +113 -0
- package/src/cli/diagnose.mjs +141 -0
- package/src/cli/download-bundle.mjs +144 -0
- package/src/cli/engine-helpers.mjs +429 -0
- package/src/cli/engine-results.mjs +320 -0
- package/src/cli/help.mjs +201 -0
- package/src/cli/install.mjs +257 -0
- package/src/cli/read.mjs +120 -0
- package/src/cli/ready.mjs +805 -0
- package/src/cli/search.mjs +608 -0
- package/src/cli/session.mjs +177 -0
- package/src/cli/setup.mjs +282 -0
- package/src/cli/slide-reuse.mjs +334 -0
- package/src/cli/status.mjs +118 -0
- package/src/cli/workspace.mjs +302 -0
- package/src/installers/codex.mjs +1 -1
- package/src/update-check.mjs +231 -0
package/src/bridge/bundle.mjs
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
getDesignBundle,
|
|
51
51
|
getDesignBundleForBrand,
|
|
52
52
|
getDesignBundleForBrandAnyBackend,
|
|
53
|
+
listBrands,
|
|
53
54
|
} from "./client.mjs";
|
|
54
55
|
import { updateCliInstruction } from "../install-channel.mjs";
|
|
55
56
|
|
|
@@ -655,6 +656,74 @@ export function readDeckBundleRef(deckDir) {
|
|
|
655
656
|
// Resolve the materialized bundle directory a deck should read its design files
|
|
656
657
|
// from (via the deck's .bundle-ref.json). Returns null when no bundle has been
|
|
657
658
|
// materialized for the deck's CD yet.
|
|
659
|
+
// Re-sync a bound deck's design bundle to the design as it stands right now.
|
|
660
|
+
//
|
|
661
|
+
// `ready` materializes at session start, but a corporate design can change
|
|
662
|
+
// while a session runs, and every local step afterwards (HTML build, lint,
|
|
663
|
+
// capture, the draft checks, and the etag the server render is validated
|
|
664
|
+
// against) reads this cached copy. So the deck commands call this first: the
|
|
665
|
+
// sync is etag-gated and incremental, so an unchanged design downloads nothing.
|
|
666
|
+
//
|
|
667
|
+
// Returns { result, changed } — `changed` is true when the design's etag moved,
|
|
668
|
+
// in which case the deck's ref is rewritten to the new one. Returns null when
|
|
669
|
+
// the deck is unbound or the backend cannot be reached: a stale-but-present
|
|
670
|
+
// bundle is what keeps the host-free steps host-free.
|
|
671
|
+
export async function refreshDeckBundle(deckDir) {
|
|
672
|
+
if (!deckDir) return null;
|
|
673
|
+
const ref = readDeckBundleRef(deckDir);
|
|
674
|
+
if (!ref?.presFP) return null; // unbound — `ready <deck>` binds it
|
|
675
|
+
// A refresh must never make a host-free step wait like a render does: a dead
|
|
676
|
+
// backend has to fall back to the cached bundle in seconds, not the 35s
|
|
677
|
+
// default plus retries. A negative delay list filters to empty, which also
|
|
678
|
+
// turns the transient retry off — the next command retries anyway.
|
|
679
|
+
const prev = {
|
|
680
|
+
SLIDEMIND_BRIDGE_TIMEOUT_MS: process.env.SLIDEMIND_BRIDGE_TIMEOUT_MS,
|
|
681
|
+
SLIDEMIND_BRIDGE_RETRY_DELAYS_MS: process.env.SLIDEMIND_BRIDGE_RETRY_DELAYS_MS,
|
|
682
|
+
};
|
|
683
|
+
process.env.SLIDEMIND_BRIDGE_TIMEOUT_MS ??=
|
|
684
|
+
process.env.SLIDEMIND_BUNDLE_REFRESH_TIMEOUT_MS || "6000";
|
|
685
|
+
process.env.SLIDEMIND_BRIDGE_RETRY_DELAYS_MS ??= "-1";
|
|
686
|
+
try {
|
|
687
|
+
const result = await materializeBundle(null, { brandId: ref.presFP });
|
|
688
|
+
if (!result) return null;
|
|
689
|
+
const changed = Boolean(result.etag) && result.etag !== ref.etag;
|
|
690
|
+
if (changed) {
|
|
691
|
+
writeDeckBundleRef(deckDir, { presFP: result.presFP, etag: result.etag });
|
|
692
|
+
}
|
|
693
|
+
return { result, changed };
|
|
694
|
+
} catch {
|
|
695
|
+
return null; // offline / unconnected / design withdrawn — keep the cache
|
|
696
|
+
} finally {
|
|
697
|
+
for (const [k, v] of Object.entries(prev)) {
|
|
698
|
+
if (v === undefined) delete process.env[k];
|
|
699
|
+
else process.env[k] = v;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
// The design an UNBOUND deck can be rendered/previewed against WITHOUT a
|
|
705
|
+
// PowerPoint window — the same ladder `ready` walks once no window is in play:
|
|
706
|
+
// the deck's own binding → the one design cached on this machine → the one
|
|
707
|
+
// design the connected backends list. Returns the presFP, or null when nothing
|
|
708
|
+
// answers unambiguously (0 or several of either; no brand route) — the caller
|
|
709
|
+
// then falls back to the window registry, which is the only remaining source
|
|
710
|
+
// of a design (an open presentation's active corporate design) and the one
|
|
711
|
+
// place that legitimately needs the pane.
|
|
712
|
+
export async function resolveWindowlessBrand(deckDir) {
|
|
713
|
+
const bound = readDeckBundleRef(deckDir)?.presFP;
|
|
714
|
+
if (bound) return bound;
|
|
715
|
+
const cached = listCachedBundles();
|
|
716
|
+
if (cached.length === 1) return cached[0].presFP;
|
|
717
|
+
if (cached.length > 1) return null;
|
|
718
|
+
let brands = [];
|
|
719
|
+
try {
|
|
720
|
+
brands = await listBrands();
|
|
721
|
+
} catch {
|
|
722
|
+
brands = [];
|
|
723
|
+
}
|
|
724
|
+
return brands.length === 1 ? brands[0].presFP : null;
|
|
725
|
+
}
|
|
726
|
+
|
|
658
727
|
export function resolveBundleDirForDeck(deckDir) {
|
|
659
728
|
const ref = readDeckBundleRef(deckDir);
|
|
660
729
|
if (!ref?.presFP) return null;
|
package/src/bridge/capture.mjs
CHANGED
|
@@ -276,6 +276,25 @@ export async function loadConnectorPreview(bundleDir) {
|
|
|
276
276
|
return { globalName: String(preview.globalName || "SlidemindConnectorDerive"), source: preview.source };
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
+
/**
|
|
280
|
+
* The measured draft checks (`draftChecks: { fill, typeScale, typeScaleTokens,
|
|
281
|
+
* overlap }`) exported from the same artifact — the rules the add-in's own
|
|
282
|
+
* see_draft runs. view-draft calls them on its local capture so both harnesses
|
|
283
|
+
* teach one contract. The CLI ships no draft-check rule of its own; null when
|
|
284
|
+
* the bundle has no engine or the engine predates the export.
|
|
285
|
+
*/
|
|
286
|
+
export async function loadDraftChecks(bundleDir) {
|
|
287
|
+
if (!bundleDir || !bundleHasCaptureEngine(bundleDir)) return null;
|
|
288
|
+
const enginePath = path.join(bundleDir, "capture-engine.mjs");
|
|
289
|
+
const version = readBundleMeta(bundleDir).captureEngineVersion ?? "0";
|
|
290
|
+
const engine = await import(
|
|
291
|
+
`${pathToFileURL(enginePath).href}?v=${encodeURIComponent(version)}`
|
|
292
|
+
);
|
|
293
|
+
const checks = engine.draftChecks;
|
|
294
|
+
if (!checks || typeof checks.fill !== "function") return null;
|
|
295
|
+
return checks;
|
|
296
|
+
}
|
|
297
|
+
|
|
279
298
|
export async function loadChartPreview(bundleDir) {
|
|
280
299
|
if (!bundleDir || !bundleHasCaptureEngine(bundleDir)) return null;
|
|
281
300
|
const enginePath = path.join(bundleDir, "capture-engine.mjs");
|