@hraness/slopcamera 3.8.0 → 3.9.0
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/NOTICE.md +14 -0
- package/README.md +294 -298
- package/apps/desktop/application/html-overlay-integrity.ts +27 -4
- package/apps/desktop/application/operation.ts +1 -1
- package/apps/desktop/application/operations/spatial-render.ts +1 -1
- package/apps/desktop/cli/capability-manifest.ts +15 -2
- package/apps/desktop/cli/commands.ts +1 -1
- package/apps/desktop/cli/help.ts +23 -4
- package/apps/desktop/cli/portable-surface.ts +1 -0
- package/apps/desktop/cli/verbs.ts +4 -0
- package/apps/desktop/dist/cli/main.js +306 -284
- package/dist/cli.js +24 -4
- package/dist/{index-842t02pp.js → index-m6g0ca9b.js} +1 -1
- package/dist/{index-y8spxs77.js → index-mgychzh3.js} +6 -3
- package/dist/{index-k9bjw80z.js → index-rxx27q8b.js} +4 -4
- package/dist/index.js +1 -1
- package/dist/operations.js +1 -1
- package/dist/workflow.js +1 -1
- package/docs/README.md +4 -1
- package/package.json +5 -3
- package/skills/slopcamera/SKILL.md +2 -0
- package/skills/slopcamera/references/customization.md +8 -1
- package/skills/slopcamera/references/icon-place.md +76 -0
- package/skills/slopcamera/references/install.md +2 -2
- package/skills/slopcamera/references/music-video.md +10 -2
- package/skills/slopcamera/references/soundtracks.md +58 -0
- package/src/bounded-file.ts +135 -0
- package/src/cli.ts +191 -0
- package/src/icon-scene.ts +695 -0
- package/src/index.ts +2 -0
- package/src/mcp/tools.ts +311 -0
- package/src/mcp/types.ts +4 -0
- package/src/operations.ts +306 -0
- package/src/soundtrack.ts +489 -0
- package/src/version.ts +1 -1
|
@@ -24,6 +24,9 @@ import {
|
|
|
24
24
|
} from "./html-overlay-browser-runtime";
|
|
25
25
|
|
|
26
26
|
const Sha256Schema = z.string().regex(/^[a-f0-9]{64}$/u);
|
|
27
|
+
const ExecutionContractVersionSchema = z.union([z.literal(1), z.literal(2)]);
|
|
28
|
+
export type HtmlOverlayExecutionContractVersion = z.infer<typeof ExecutionContractVersionSchema>;
|
|
29
|
+
|
|
27
30
|
const IntegrityLeafSchema = z.strictObject({
|
|
28
31
|
key: z.string().min(1).max(512),
|
|
29
32
|
sha256: Sha256Schema,
|
|
@@ -44,7 +47,7 @@ export const HtmlOverlayExecutionIntegritySchema = z.strictObject({
|
|
|
44
47
|
}),
|
|
45
48
|
rootSha256: Sha256Schema,
|
|
46
49
|
runtimeSha256: Sha256Schema,
|
|
47
|
-
schemaVersion:
|
|
50
|
+
schemaVersion: ExecutionContractVersionSchema,
|
|
48
51
|
});
|
|
49
52
|
export type HtmlOverlayExecutionIntegrity = Readonly<
|
|
50
53
|
z.infer<typeof HtmlOverlayExecutionIntegritySchema>
|
|
@@ -185,7 +188,7 @@ function legacyHtmlOverlayRendererContract(profileInput?: HtmlOverlayExecutionPr
|
|
|
185
188
|
}
|
|
186
189
|
|
|
187
190
|
/** Fetch opt-in grants only the exact declared private paths and changes execution identity. */
|
|
188
|
-
|
|
191
|
+
function historicalHtmlOverlayRendererContract(
|
|
189
192
|
profileInput?: HtmlOverlayExecutionProfile,
|
|
190
193
|
resourcesInput: readonly HtmlOverlayDeclaredResource[] = [],
|
|
191
194
|
) {
|
|
@@ -204,6 +207,25 @@ export function htmlOverlayRendererContract(
|
|
|
204
207
|
});
|
|
205
208
|
}
|
|
206
209
|
|
|
210
|
+
/** Historical receipts select v1 explicitly; all new execution binds clone prevention. */
|
|
211
|
+
export function htmlOverlayRendererContract(
|
|
212
|
+
profileInput?: HtmlOverlayExecutionProfile,
|
|
213
|
+
resourcesInput: readonly HtmlOverlayDeclaredResource[] = [],
|
|
214
|
+
version: HtmlOverlayExecutionContractVersion = 2,
|
|
215
|
+
) {
|
|
216
|
+
const contract = historicalHtmlOverlayRendererContract(profileInput, resourcesInput);
|
|
217
|
+
if (ExecutionContractVersionSchema.parse(version) === 1) return contract;
|
|
218
|
+
return Object.freeze({
|
|
219
|
+
...contract,
|
|
220
|
+
launch: Object.freeze({
|
|
221
|
+
...contract.launch,
|
|
222
|
+
args: Object.freeze(contract.launch.args.map(argument => argument.startsWith("--disable-features=")
|
|
223
|
+
? `${argument},PaintHolding,MacAppCodeSignClone` : argument)),
|
|
224
|
+
}),
|
|
225
|
+
schemaVersion: 4,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
|
|
207
229
|
export function assertHtmlOverlayExecutionProfileLibraries(
|
|
208
230
|
libraries: readonly string[], profile?: HtmlOverlayExecutionProfile,
|
|
209
231
|
): void {
|
|
@@ -258,6 +280,7 @@ export function createHtmlOverlayExecutionBundle(
|
|
|
258
280
|
authoringInput: HtmlOverlayAuthoringInput,
|
|
259
281
|
browserRuntimeInput: HtmlOverlayBrowserRuntimeBinding,
|
|
260
282
|
executionProfile?: HtmlOverlayExecutionProfile,
|
|
283
|
+
contractVersion: HtmlOverlayExecutionContractVersion = 2,
|
|
261
284
|
): HtmlOverlayExecutionBundle {
|
|
262
285
|
const authoring = HtmlOverlayAuthoringInputSchema.parse(authoringInput);
|
|
263
286
|
assertHtmlOverlayExecutionProfileLibraries(authoring.libraries, executionProfile);
|
|
@@ -290,7 +313,7 @@ export function createHtmlOverlayExecutionBundle(
|
|
|
290
313
|
},
|
|
291
314
|
},
|
|
292
315
|
{ key: "browser-runtime", value: browserRuntime },
|
|
293
|
-
{ key: "renderer-contract", value: htmlOverlayRendererContract(executionProfile, authoring.resources) },
|
|
316
|
+
{ key: "renderer-contract", value: htmlOverlayRendererContract(executionProfile, authoring.resources, contractVersion) },
|
|
294
317
|
{
|
|
295
318
|
key: "document",
|
|
296
319
|
value: {
|
|
@@ -326,7 +349,7 @@ export function createHtmlOverlayExecutionBundle(
|
|
|
326
349
|
leaves,
|
|
327
350
|
rootSha256: merkleRoot(leaves),
|
|
328
351
|
runtimeSha256,
|
|
329
|
-
schemaVersion:
|
|
352
|
+
schemaVersion: contractVersion,
|
|
330
353
|
});
|
|
331
354
|
return Object.freeze({
|
|
332
355
|
importMap,
|
|
@@ -4,7 +4,7 @@ import type { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
import type { ApplicationContext } from "./context";
|
|
6
6
|
|
|
7
|
-
export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.
|
|
7
|
+
export const SLOPCAMERA_APPLICATION_TOOL_VERSION = "slopcamera-3.9.0" as const;
|
|
8
8
|
|
|
9
9
|
export const OPERATION_KINDS = [
|
|
10
10
|
"scene.audit",
|
|
@@ -381,7 +381,7 @@ export async function recoverSpatialRenderOutput(application: ApplicationContext
|
|
|
381
381
|
mode: plan.request.mode, frameRate: plan.request.selection.kind === "video" ? plan.request.selection.frameRate : { numerator: 1, denominator: 1 }, preparedAssets: batch.preparedAssets });
|
|
382
382
|
equal(batch.metadata, expectedBatch.metadata, "Spatial batch metadata differs from the exact scene samples.");
|
|
383
383
|
equal(batch.metadataSha256, expectedBatch.metadataSha256, "Spatial batch metadata digest is invalid.");
|
|
384
|
-
const execution = createHtmlOverlayExecutionBundle(expectedBatch.authoring, input.browserRuntime, plan.request.executionProfile);
|
|
384
|
+
const execution = createHtmlOverlayExecutionBundle(expectedBatch.authoring, input.browserRuntime, plan.request.executionProfile, batch.executionIntegrity.schemaVersion);
|
|
385
385
|
assertHtmlOverlayGpuEvidenceProfile(plan.request.executionProfile, batch.gpuEvidence);
|
|
386
386
|
equal(batch.gpuEvidence, receipt.runtime.gpuEvidence, "Spatial batch hardware identity differs from its completion receipt.");
|
|
387
387
|
equal(batch.executionIntegrity, execution.integrity, "Spatial batch execution integrity differs from its exact authored runtime.");
|
|
@@ -127,8 +127,12 @@ const capabilityModules = Object.freeze([
|
|
|
127
127
|
{ effect: "local-read", name: "diagram sheets check" },
|
|
128
128
|
{ effect: "local-derived-write", name: "diagram sheets render" },
|
|
129
129
|
{ effect: "local-derived-write", name: "image vectorize" },
|
|
130
|
+
{ effect: "local-derived-write", name: "image icon compose" },
|
|
131
|
+
{ effect: "local-derived-write", name: "image icon render" },
|
|
132
|
+
{ effect: "local-derived-write", name: "media soundtrack compose" },
|
|
133
|
+
{ effect: "local-derived-write", name: "media soundtrack grid" },
|
|
130
134
|
],
|
|
131
|
-
description: "Portable diagrams, CLI/SDK drawing sheets, local vectorization, and the bounded semantic operation projection.",
|
|
135
|
+
description: "Portable diagrams, CLI/SDK drawing sheets, local vectorization, deterministic icon scenes and soundtrack beat grids, and the bounded semantic operation projection.",
|
|
132
136
|
moduleId: "slopcamera.capability.diagram-image",
|
|
133
137
|
operationKeys: diagramImageOperations,
|
|
134
138
|
profiles: [{
|
|
@@ -139,7 +143,16 @@ const capabilityModules = Object.freeze([
|
|
|
139
143
|
}],
|
|
140
144
|
stability: "stable",
|
|
141
145
|
title: "Diagrams and images",
|
|
142
|
-
toolNames: [
|
|
146
|
+
toolNames: [
|
|
147
|
+
"check_diagram",
|
|
148
|
+
"compose_icon",
|
|
149
|
+
"compose_soundtrack",
|
|
150
|
+
"derive_soundtrack_grid",
|
|
151
|
+
"execute_slopcamera",
|
|
152
|
+
"render_diagram",
|
|
153
|
+
"render_icon",
|
|
154
|
+
"search_slopcamera",
|
|
155
|
+
],
|
|
143
156
|
trust: "portable",
|
|
144
157
|
version: 1,
|
|
145
158
|
workflowKeys: [],
|
|
@@ -365,7 +365,7 @@ import {
|
|
|
365
365
|
workflowRunStore,
|
|
366
366
|
} from "./workflow-runs";
|
|
367
367
|
|
|
368
|
-
export const SLOPCAMERA_VERSION = "3.
|
|
368
|
+
export const SLOPCAMERA_VERSION = "3.9.0";
|
|
369
369
|
|
|
370
370
|
// Legacy direct renders predate per-target output contracts. Keep them
|
|
371
371
|
// bounded generously enough for long-form production while preventing one
|
package/apps/desktop/cli/help.ts
CHANGED
|
@@ -37,7 +37,7 @@ Commands:
|
|
|
37
37
|
Discover and run Vercel AI Gateway media models
|
|
38
38
|
credits status|topup|wait|forget
|
|
39
39
|
Buy and inspect hosted generation credits
|
|
40
|
-
media audio|color
|
|
40
|
+
media audio|color|soundtrack Apply local audio and video effects; derive soundtrack beat grids
|
|
41
41
|
outputs Print the agent outputs directory
|
|
42
42
|
outputs list|open|reveal List the newest outputs or open one on this Mac
|
|
43
43
|
status What Slopcamera is doing, credits and newest outputs
|
|
@@ -293,6 +293,10 @@ compliance. Drawing sheets are exposed through this CLI and the root SDK, not co
|
|
|
293
293
|
slopcamera image icon --set <file.json> --output-dir <directory>
|
|
294
294
|
[--context <card|hero|inline>] [--candidates <1-4>]
|
|
295
295
|
[--set-rounds <1-4>] [--keep-raster] [--json]
|
|
296
|
+
slopcamera image icon compose <source.json> [--output <file.json>] [--json]
|
|
297
|
+
slopcamera image icon render <source.json> --output <file.svg> [--recipe <file.json>]
|
|
298
|
+
[--size <16-1024>] [--background] [--palette <original|ink|earth|night>]
|
|
299
|
+
[--language <language>] [--json]
|
|
296
300
|
|
|
297
301
|
Explicit --output file commands delegate to @hraness/slopcamera. Vectorization is local,
|
|
298
302
|
bounded, checksum-pinned, and emits inert SVG. File generation uses Vercel AI Gateway with the
|
|
@@ -308,7 +312,13 @@ variation axes or an explicit candidate list — keeps every candidate with its
|
|
|
308
312
|
composes a labelled contact sheet plus receipt for agent review. Texture cells repeat the
|
|
309
313
|
candidate 2×2 so seams are inspectable (--tile/--no-tile overrides). It never replaces existing
|
|
310
314
|
outputs and never promotes a candidate into authored source; review the sheet and select
|
|
311
|
-
explicitly
|
|
315
|
+
explicitly.
|
|
316
|
+
|
|
317
|
+
Icon compose and render are local and deterministic, with no model or network. They solve and
|
|
318
|
+
draw icon.place scenes, collections, construction programs, and recipes into inert SVG; a recipe
|
|
319
|
+
replays only when its recorded digests match. Construction-program languages: outline, sketch,
|
|
320
|
+
pen, crosshatch, engraving, stipple, halftone, glyph, flat, shaded, figure, cutpaper, woodcut,
|
|
321
|
+
offset.`,
|
|
312
322
|
style: `Usage:
|
|
313
323
|
slopcamera style list [--json]
|
|
314
324
|
slopcamera style show <id> [--json]
|
|
@@ -616,6 +626,15 @@ argv, receipts, or logs. When a configured wallet runs out, paid calls fail with
|
|
|
616
626
|
[--output <relative-path>] [--json]
|
|
617
627
|
slopcamera media color <video-path> [grade] [--video-stream <index>]
|
|
618
628
|
[--output <relative-path>] [--json]
|
|
629
|
+
slopcamera media soundtrack compose <score> [--output <file.json>]
|
|
630
|
+
[--format <compose|song|json|midi>] [--json]
|
|
631
|
+
slopcamera media soundtrack grid <score> [--output <file.json>] [--start-us <n>]
|
|
632
|
+
[--format <compose|song|json|midi>] [--json]
|
|
633
|
+
|
|
634
|
+
Soundtrack verbs delegate to @hraness/slopcamera. They verify a Soundfish loop or song (compose
|
|
635
|
+
text, song text, score JSON, or a Standard MIDI file) and derive the {bpm, beatOffsetUs,
|
|
636
|
+
beatsPerBar} music timing that HTML scene requests accept, plus section cue times. They render
|
|
637
|
+
no audio; pair the grid with the track you mix.
|
|
619
638
|
|
|
620
639
|
Audio effects may be combined in one deterministic chain:
|
|
621
640
|
--volume-db <-60..24>
|
|
@@ -725,7 +744,7 @@ export function completions(words: readonly string[]): readonly string[] {
|
|
|
725
744
|
if (command === "diagram") return words[1] === "sheets"
|
|
726
745
|
? ["init", "check", "render"]
|
|
727
746
|
: ["init", "check", "render", "sheets"];
|
|
728
|
-
if (command === "image") return ["vectorize", "generate", "gallery", "icon"];
|
|
747
|
+
if (command === "image") return words[1] === "icon" ? ["compose", "render"] : ["vectorize", "generate", "gallery", "icon"];
|
|
729
748
|
if (command === "workflows") return ["list", "show", "plan", "run"];
|
|
730
749
|
if (command === "code") return ["init", "check", "plan", "run"];
|
|
731
750
|
if (command === "runs") return ["list", "show", "resume", "approve", "cancel"];
|
|
@@ -748,7 +767,7 @@ export function completions(words: readonly string[]): readonly string[] {
|
|
|
748
767
|
if (command === "fillers") return ["list", "apply"];
|
|
749
768
|
if (command === "ai") return ["models", "provider-options", "image", "video", "speech", "transcribe"];
|
|
750
769
|
if (command === "credits") return ["status", "topup", "wait", "forget"];
|
|
751
|
-
if (command === "media") return ["audio", "color"];
|
|
770
|
+
if (command === "media") return words[1] === "soundtrack" ? ["compose", "grid"] : ["audio", "color", "soundtrack"];
|
|
752
771
|
if (command === "render") return ["plan", "run"];
|
|
753
772
|
if (command === "assets") return ["emoji"];
|
|
754
773
|
if (command === "outputs") return ["list", "open", "reveal"];
|
|
@@ -96,6 +96,8 @@ export const CLI_VERBS: readonly VerbRow[] = [
|
|
|
96
96
|
row("image generate", "operate", "Generate an image with Vercel AI Gateway"),
|
|
97
97
|
row("image gallery", "operate", "Generate a review gallery of image candidates"),
|
|
98
98
|
row("image icon", "operate", "Generate a line-art SVG icon"),
|
|
99
|
+
row("image icon compose", "operate", "Solve a vector icon scene and report its digests"),
|
|
100
|
+
row("image icon render", "operate", "Draw a vector icon scene or recipe to inert SVG"),
|
|
99
101
|
|
|
100
102
|
row("html catalog", "read", "List HTML scene profiles"),
|
|
101
103
|
row("html scaffold", "operate", "Write a new HTML scene"),
|
|
@@ -138,6 +140,8 @@ export const CLI_VERBS: readonly VerbRow[] = [
|
|
|
138
140
|
|
|
139
141
|
row("media audio", "operate", "Apply audio effects into a new file"),
|
|
140
142
|
row("media color", "operate", "Apply a color grade into a new file"),
|
|
143
|
+
row("media soundtrack compose", "operate", "Verify a loop or song score"),
|
|
144
|
+
row("media soundtrack grid", "operate", "Derive music timing and section cues from a score"),
|
|
141
145
|
|
|
142
146
|
row("outputs", "read", "Print the outputs folder"),
|
|
143
147
|
row("outputs list", "read", "List the files in the outputs folder, newest first"),
|