@hraness/slopcamera 3.2.7 → 3.3.1
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 +1 -7
- package/PRIVACY.md +16 -7
- package/README.md +65 -20
- package/apps/desktop/README.md +14 -130
- package/apps/desktop/application/context.ts +6 -9
- package/apps/desktop/application/default-registry.ts +26 -10
- package/apps/desktop/application/operation.ts +14 -5
- package/apps/desktop/application/operations/index.ts +4 -1
- package/apps/desktop/application/operations/spatial-behavior.ts +151 -0
- package/apps/desktop/application/operations/spatial-direction.ts +222 -0
- package/apps/desktop/application/operations/spatial-rendered-audit.ts +174 -0
- package/apps/desktop/application/operations/spatial-review.ts +194 -0
- package/apps/desktop/application/operations/spatial-scene.ts +25 -1
- package/apps/desktop/application/registry.ts +2 -2
- package/apps/desktop/application/spatial-asset-admission.ts +201 -0
- package/apps/desktop/application/spatial-assets.ts +160 -31
- package/apps/desktop/application/spatial-render.ts +217 -20
- package/apps/desktop/application/spatial-rendered-audit.ts +273 -0
- package/apps/desktop/application/spatial-review.ts +361 -0
- package/apps/desktop/application/spatial-spz.ts +48 -3
- package/apps/desktop/application/spatial-world-import.ts +26 -5
- package/apps/desktop/application/spatial-world-metadata.ts +105 -0
- package/apps/desktop/cli/args.ts +528 -97
- package/apps/desktop/cli/capability-manifest.ts +374 -0
- package/apps/desktop/cli/cinema-renderer.ts +608 -0
- package/apps/desktop/cli/command-host-resources.ts +31 -2
- package/apps/desktop/cli/commands.ts +1215 -70
- package/apps/desktop/cli/gateway-review-provider.ts +334 -0
- package/apps/desktop/cli/help.ts +183 -23
- package/apps/desktop/cli/html-scene.ts +139 -28
- package/apps/desktop/cli/io.ts +2 -1
- package/apps/desktop/cli/main.ts +26 -50
- package/apps/desktop/cli/menubar.ts +244 -0
- package/apps/desktop/cli/music-analysis-service.ts +61 -0
- package/apps/desktop/cli/portable-surface.ts +18 -5
- package/apps/desktop/cli/spatial-asset-service.ts +124 -0
- package/apps/desktop/cli/spatial-design-service.ts +237 -0
- package/apps/desktop/cli/spatial-generate-service.ts +370 -0
- package/apps/desktop/cli/spatial-scene-service.ts +268 -4
- package/apps/desktop/cli/workflow-code.ts +1 -1
- package/apps/desktop/code/application-node-planner.ts +0 -47
- package/apps/desktop/code/host-source-layout.ts +46 -0
- package/apps/desktop/code/public.ts +0 -1
- package/apps/desktop/code/runtime-identity.ts +50 -8
- package/apps/desktop/code/semantic-builder.ts +24 -43
- package/apps/desktop/code/source-bundle.ts +23 -6
- package/apps/desktop/code/source-typecheck.ts +131 -43
- package/apps/desktop/code/worker-client.ts +14 -2
- package/apps/desktop/contracts/cinema.ts +736 -0
- package/apps/desktop/contracts/index.ts +1 -0
- package/apps/desktop/contracts/spatial-asset.ts +16 -0
- package/apps/desktop/contracts/spatial-world.ts +26 -3
- package/apps/desktop/core/cinema-plan.ts +1320 -0
- package/apps/desktop/core/index.ts +1 -0
- package/apps/desktop/core/music-analysis.ts +124 -1
- package/apps/desktop/core/storage.ts +75 -0
- package/apps/desktop/dist/cli/main.js +737 -291
- package/apps/desktop/html-overlay/audio-reactivity.ts +127 -0
- package/apps/desktop/html-overlay/index.ts +9 -0
- package/apps/desktop/html-overlay/runtime.ts +2 -0
- package/apps/desktop/html-overlay/scene.ts +29 -0
- package/apps/desktop/html-overlay/spatial.ts +619 -57
- package/apps/desktop/workflows/cinematic-world.ts +127 -0
- package/apps/desktop/workflows/index.ts +6 -0
- package/dist/cli.js +32 -434
- package/dist/code/advanced.js +1 -269
- package/dist/code/index.js +16 -2239
- package/dist/generate.js +1 -23
- package/dist/host-resources.js +1 -25
- package/dist/index-0bbesn4m.js +35 -0
- package/dist/index-296qhpf2.js +3 -0
- package/dist/index-3cxf2c58.js +3 -0
- package/dist/index-77fjfg9f.js +3 -0
- package/dist/index-80a36bc0.js +3 -0
- package/dist/index-a3vvs3rf.js +3 -0
- package/dist/index-b3geqczn.js +5 -0
- package/dist/index-cgpkyjqa.js +3 -0
- package/dist/index-f0ptv8dm.js +7 -0
- package/dist/index-grk47tgs.js +3 -0
- package/dist/index-qry58nj2.js +10 -0
- package/dist/index.js +1 -240
- package/dist/operations.js +1 -28
- package/dist/skill-install-gx7afxsd.js +2 -0
- package/dist/vectorize/worker.js +1 -141
- package/dist/workflow.js +1 -15
- package/docs/README.md +5 -1
- package/docs/studio.md +1 -1
- package/package.json +11 -24
- package/skills/slopcamera/SKILL.md +14 -1
- package/skills/slopcamera/references/diagrams.md +5 -14
- package/skills/slopcamera/references/directed-scenes.md +22 -2
- package/skills/slopcamera/references/gateway-media.md +15 -1
- package/skills/slopcamera/references/image-galleries.md +166 -0
- package/skills/slopcamera/references/install.md +2 -2
- package/skills/slopcamera/references/music-video.md +23 -3
- package/skills/slopcamera/references/parametric-design.md +14 -0
- package/skills/slopcamera/references/reference-led-3d.md +1 -1
- package/skills/slopcamera/references/scene-building.md +32 -0
- package/skills/slopcamera/references/social-collage-banners.md +204 -0
- package/skills/slopcamera/references/support.md +25 -0
- package/skills/slopcamera/references/web-media-excerpts.md +120 -0
- package/skills/slopcamera/references/workflows-sdk.md +3 -3
- package/skills/slopcamera/scripts/compose-social-collage-banner.ts +728 -0
- package/src/capability-manifest.ts +361 -0
- package/src/cli.ts +250 -102
- package/src/code/canonical-json.ts +9 -0
- package/src/generate.ts +2 -2
- package/src/icon.ts +1111 -0
- package/src/image-gallery.ts +1049 -0
- package/src/index.ts +11 -23
- package/src/mcp/boundary.ts +11 -11
- package/src/mcp/index.ts +3 -0
- package/src/mcp/server.ts +2 -1
- package/src/mcp/tools.ts +1642 -130
- package/src/mcp/types.ts +19 -0
- package/src/operations.ts +412 -0
- package/src/portable-capability-manifest.ts +67 -0
- package/src/scene-gallery.ts +184 -0
- package/src/spatial-scene/asset-admission.ts +183 -0
- package/src/spatial-scene/audit-rendered.ts +692 -0
- package/src/spatial-scene/audit.ts +617 -0
- package/src/spatial-scene/behavior-audit.ts +252 -0
- package/src/spatial-scene/behavior-bake.ts +233 -0
- package/src/spatial-scene/behavior-fns.ts +585 -0
- package/src/spatial-scene/behavior-gallery.ts +109 -0
- package/src/spatial-scene/behavior-stdlib.ts +323 -0
- package/src/spatial-scene/behavior-trace.ts +325 -0
- package/src/spatial-scene/behavior.ts +618 -0
- package/src/spatial-scene/build.ts +632 -0
- package/src/spatial-scene/camera-rig.ts +125 -0
- package/src/spatial-scene/camera-track.ts +4 -2
- package/src/spatial-scene/character.ts +124 -0
- package/src/spatial-scene/contracts.ts +75 -7
- package/src/spatial-scene/design-templates.ts +351 -0
- package/src/spatial-scene/design.ts +327 -0
- package/src/spatial-scene/direction-compile.ts +584 -0
- package/src/spatial-scene/direction.ts +122 -0
- package/src/spatial-scene/effects.ts +149 -0
- package/src/spatial-scene/evaluate.ts +109 -29
- package/src/spatial-scene/gallery.ts +277 -0
- package/src/spatial-scene/generate.ts +239 -0
- package/src/spatial-scene/geometry-native.ts +165 -0
- package/src/spatial-scene/geometry.ts +1216 -0
- package/src/spatial-scene/gltf.ts +600 -77
- package/src/spatial-scene/identity.ts +55 -2
- package/src/spatial-scene/index.ts +36 -0
- package/src/spatial-scene/inspect.ts +35 -6
- package/src/spatial-scene/material-lighting.ts +609 -0
- package/src/spatial-scene/math.ts +21 -4
- package/src/spatial-scene/motion-evidence.ts +88 -0
- package/src/spatial-scene/parametric.ts +765 -0
- package/src/spatial-scene/particle-preparation.ts +183 -0
- package/src/spatial-scene/particle.ts +195 -0
- package/src/spatial-scene/patch.ts +109 -15
- package/src/spatial-scene/performance.ts +1613 -0
- package/src/spatial-scene/probe.ts +137 -0
- package/src/spatial-scene/recipe-pack.ts +86 -0
- package/src/spatial-scene/render-effects.ts +240 -0
- package/src/spatial-scene/review.ts +639 -0
- package/src/spatial-scene/simulation-bake.ts +206 -0
- package/src/spatial-scene/simulation.ts +187 -0
- package/src/spatial-scene/solve.ts +366 -0
- package/src/spatial-scene/temporal-audit.ts +354 -0
- package/src/support-completion.ts +16 -0
- package/src/support.ts +42 -0
- package/src/version.ts +1 -1
- package/apps/desktop/application/operations/recording/index.ts +0 -5
- package/apps/desktop/application/operations/recording/pause.ts +0 -34
- package/apps/desktop/application/operations/recording/resume.ts +0 -34
- package/apps/desktop/application/operations/recording/shared.ts +0 -199
- package/apps/desktop/application/operations/recording/start.ts +0 -169
- package/apps/desktop/application/operations/recording/stop.ts +0 -34
- package/apps/desktop/capture/protocol.ts +0 -689
- package/apps/desktop/cli/capture-bundle.ts +0 -1117
- package/apps/desktop/cli/recording-controller.ts +0 -1567
- package/apps/desktop/cli/recording-daemon.ts +0 -931
- package/dist/index-42zsesc1.js +0 -2257
- package/dist/index-7308egqr.js +0 -48
- package/dist/index-8txs6fkn.js +0 -712
- package/dist/index-mcy8z0br.js +0 -192
- package/dist/index-p63wavx0.js +0 -2029
- package/dist/index-r7gdhmsp.js +0 -424
- package/dist/index-rvghzt7b.js +0 -2013
- package/dist/index-sh6xbav6.js +0 -1219
- package/dist/index-z1w83f81.js +0 -4
- package/dist/index-z7239b4h.js +0 -2363
- package/dist/skill-install-dh0ntqba.js +0 -10
- package/src/desktop.ts +0 -253
package/src/mcp/types.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SlopcameraGenerateDependencies } from "../generate.js"
|
|
2
|
+
import type { HostResourceCoordinator } from "../host-resources.js"
|
|
2
3
|
|
|
3
4
|
export type JsonRpcId = string | number
|
|
4
5
|
export type JsonRpcResponseId = JsonRpcId | null
|
|
@@ -37,6 +38,19 @@ export interface McpToolDefinition {
|
|
|
37
38
|
| "render_diagram"
|
|
38
39
|
| "search_slopcamera"
|
|
39
40
|
| "execute_slopcamera"
|
|
41
|
+
| "check_scene"
|
|
42
|
+
| "inspect_scene"
|
|
43
|
+
| "audit_scene"
|
|
44
|
+
| "diff_scenes"
|
|
45
|
+
| "evaluate_scene"
|
|
46
|
+
| "check_scene_direction"
|
|
47
|
+
| "plan_scene_direction"
|
|
48
|
+
| "plan_scene_gallery"
|
|
49
|
+
| "check_scene_effects"
|
|
50
|
+
| "plan_scene_effects"
|
|
51
|
+
| "check_scene_behavior"
|
|
52
|
+
| "audit_scene_behavior"
|
|
53
|
+
| "audit_scene_temporal"
|
|
40
54
|
readonly title: string
|
|
41
55
|
readonly description: string
|
|
42
56
|
readonly inputSchema: Readonly<Record<string, unknown>>
|
|
@@ -68,4 +82,9 @@ export interface McpServerOptions {
|
|
|
68
82
|
readonly serverVersion?: string
|
|
69
83
|
/** Injectable Gateway runtime, environment, and fixed-origin fetch seams. */
|
|
70
84
|
readonly generateDependencies?: SlopcameraGenerateDependencies
|
|
85
|
+
/**
|
|
86
|
+
* Injectable host-resource admission coordinator. Defaults to the
|
|
87
|
+
* machine-global coordinator; tests inject a process-local stand-in.
|
|
88
|
+
*/
|
|
89
|
+
readonly hostResourceCoordinator?: HostResourceCoordinator
|
|
71
90
|
}
|
package/src/operations.ts
CHANGED
|
@@ -14,6 +14,19 @@ import {
|
|
|
14
14
|
type SlopcameraGenerateDependencies,
|
|
15
15
|
type SlopcameraImageModel,
|
|
16
16
|
} from "./generate.js"
|
|
17
|
+
import {
|
|
18
|
+
generateSlopcameraIcon,
|
|
19
|
+
slopcameraIconMaximumRounds,
|
|
20
|
+
slopcameraIconSubjectMaximumBytes,
|
|
21
|
+
type SlopcameraIconReceipt,
|
|
22
|
+
} from "./icon.js"
|
|
23
|
+
import {
|
|
24
|
+
generateSlopcameraImageGallery,
|
|
25
|
+
slopcameraGalleryAxes,
|
|
26
|
+
slopcameraGalleryKinds,
|
|
27
|
+
slopcameraGalleryLimits,
|
|
28
|
+
type SlopcameraGalleryReceipt,
|
|
29
|
+
} from "./image-gallery.js"
|
|
17
30
|
import {
|
|
18
31
|
vectorizeImage,
|
|
19
32
|
type VectorizeReceipt,
|
|
@@ -30,6 +43,8 @@ export const slopcameraOperationCodes = [
|
|
|
30
43
|
"slopcamera.diagram.render",
|
|
31
44
|
"slopcamera.image.vectorize",
|
|
32
45
|
"slopcamera.image.generate",
|
|
46
|
+
"slopcamera.image.icon",
|
|
47
|
+
"slopcamera.image.gallery",
|
|
33
48
|
] as const
|
|
34
49
|
|
|
35
50
|
export type SlopcameraOperationCode = (typeof slopcameraOperationCodes)[number]
|
|
@@ -209,6 +224,157 @@ export const slopcameraOperationRegistry: readonly SlopcameraOperationDescriptor
|
|
|
209
224
|
retry: "never",
|
|
210
225
|
},
|
|
211
226
|
},
|
|
227
|
+
{
|
|
228
|
+
code: "slopcamera.image.icon",
|
|
229
|
+
title: "Generate line-art icon",
|
|
230
|
+
description:
|
|
231
|
+
"Generate one isometric line-art SVG icon: a style-locked Vercel AI Gateway raster normalized to canonical ink-on-transparent pixels, traced locally, and optionally critiqued by a vision model across bounded rounds.",
|
|
232
|
+
execution: "gateway",
|
|
233
|
+
authentication: "environment",
|
|
234
|
+
destructive: true,
|
|
235
|
+
idempotent: false,
|
|
236
|
+
inputSchema: {
|
|
237
|
+
type: "object",
|
|
238
|
+
additionalProperties: false,
|
|
239
|
+
required: ["subject", "outputPath"],
|
|
240
|
+
properties: {
|
|
241
|
+
subject: {
|
|
242
|
+
type: "string",
|
|
243
|
+
minLength: 1,
|
|
244
|
+
maxLength: slopcameraIconSubjectMaximumBytes,
|
|
245
|
+
},
|
|
246
|
+
outputPath: pathSchema,
|
|
247
|
+
model: modelSchema,
|
|
248
|
+
critiqueModel: modelSchema,
|
|
249
|
+
ink: {
|
|
250
|
+
type: "string",
|
|
251
|
+
pattern: "^#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$",
|
|
252
|
+
},
|
|
253
|
+
purpose: { type: "string", enum: ["mark", "illustration"] },
|
|
254
|
+
rounds: {
|
|
255
|
+
type: "integer",
|
|
256
|
+
minimum: 1,
|
|
257
|
+
maximum: slopcameraIconMaximumRounds,
|
|
258
|
+
},
|
|
259
|
+
keepRaster: { type: "boolean" },
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
resources: [
|
|
263
|
+
{ resource: "cpu", amount: 1 },
|
|
264
|
+
{ resource: "local-io", amount: 1 },
|
|
265
|
+
{ resource: "network", amount: 1 },
|
|
266
|
+
{ resource: "paid-call", amount: 1 },
|
|
267
|
+
],
|
|
268
|
+
transport: {
|
|
269
|
+
method: "POST",
|
|
270
|
+
authority: "https://ai-gateway.vercel.sh/v4/ai",
|
|
271
|
+
authorization: "bearer",
|
|
272
|
+
retry: "never",
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
code: "slopcamera.image.gallery",
|
|
277
|
+
title: "Generate image gallery",
|
|
278
|
+
description:
|
|
279
|
+
"Generate several bounded Vercel AI Gateway image candidates in parallel and compose a labelled contact sheet with per-candidate provenance for explicit review and selection.",
|
|
280
|
+
execution: "gateway",
|
|
281
|
+
authentication: "environment",
|
|
282
|
+
destructive: true,
|
|
283
|
+
idempotent: false,
|
|
284
|
+
inputSchema: {
|
|
285
|
+
type: "object",
|
|
286
|
+
additionalProperties: false,
|
|
287
|
+
required: ["subject", "outputDir"],
|
|
288
|
+
properties: {
|
|
289
|
+
subject: {
|
|
290
|
+
type: "string",
|
|
291
|
+
minLength: 1,
|
|
292
|
+
maxLength: slopcameraGalleryLimits.subjectBytes,
|
|
293
|
+
},
|
|
294
|
+
outputDir: pathSchema,
|
|
295
|
+
kind: { type: "string", enum: [...slopcameraGalleryKinds] },
|
|
296
|
+
model: modelSchema,
|
|
297
|
+
count: {
|
|
298
|
+
type: "integer",
|
|
299
|
+
minimum: 1,
|
|
300
|
+
maximum: slopcameraGalleryLimits.candidates,
|
|
301
|
+
},
|
|
302
|
+
vary: {
|
|
303
|
+
type: "array",
|
|
304
|
+
maxItems: slopcameraGalleryAxes.length,
|
|
305
|
+
items: {
|
|
306
|
+
anyOf: [
|
|
307
|
+
{ type: "string", enum: [...slopcameraGalleryAxes] },
|
|
308
|
+
{
|
|
309
|
+
type: "object",
|
|
310
|
+
additionalProperties: false,
|
|
311
|
+
required: ["axis"],
|
|
312
|
+
properties: {
|
|
313
|
+
axis: { type: "string", enum: [...slopcameraGalleryAxes] },
|
|
314
|
+
values: {
|
|
315
|
+
type: "array",
|
|
316
|
+
minItems: 1,
|
|
317
|
+
maxItems: slopcameraGalleryLimits.candidates,
|
|
318
|
+
items: {
|
|
319
|
+
type: "string",
|
|
320
|
+
minLength: 1,
|
|
321
|
+
maxLength: slopcameraGalleryLimits.variantBytes,
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
],
|
|
327
|
+
},
|
|
328
|
+
},
|
|
329
|
+
candidates: {
|
|
330
|
+
type: "array",
|
|
331
|
+
minItems: 1,
|
|
332
|
+
maxItems: slopcameraGalleryLimits.candidates,
|
|
333
|
+
items: {
|
|
334
|
+
type: "object",
|
|
335
|
+
additionalProperties: false,
|
|
336
|
+
required: ["id"],
|
|
337
|
+
properties: {
|
|
338
|
+
id: {
|
|
339
|
+
type: "string",
|
|
340
|
+
minLength: 1,
|
|
341
|
+
maxLength: slopcameraGalleryLimits.idLength,
|
|
342
|
+
},
|
|
343
|
+
prompt: {
|
|
344
|
+
type: "string",
|
|
345
|
+
minLength: 1,
|
|
346
|
+
maxLength: slopcameraGalleryLimits.candidatePromptBytes,
|
|
347
|
+
},
|
|
348
|
+
variant: {
|
|
349
|
+
type: "string",
|
|
350
|
+
minLength: 1,
|
|
351
|
+
maxLength: slopcameraGalleryLimits.variantBytes,
|
|
352
|
+
},
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
},
|
|
356
|
+
cellEdge: {
|
|
357
|
+
type: "integer",
|
|
358
|
+
minimum: slopcameraGalleryLimits.cellEdgeMin,
|
|
359
|
+
maximum: slopcameraGalleryLimits.cellEdgeMax,
|
|
360
|
+
},
|
|
361
|
+
tiled: { type: "boolean" },
|
|
362
|
+
timeoutMs: { type: "integer", minimum: 1_000, maximum: 30 * 60_000 },
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
resources: [
|
|
366
|
+
{ resource: "cpu", amount: 1 },
|
|
367
|
+
{ resource: "local-io", amount: 1 },
|
|
368
|
+
{ resource: "network", amount: 1 },
|
|
369
|
+
{ resource: "paid-call", amount: 1 },
|
|
370
|
+
],
|
|
371
|
+
transport: {
|
|
372
|
+
method: "POST",
|
|
373
|
+
authority: "https://ai-gateway.vercel.sh/v4/ai",
|
|
374
|
+
authorization: "bearer",
|
|
375
|
+
retry: "never",
|
|
376
|
+
},
|
|
377
|
+
},
|
|
212
378
|
] satisfies readonly SlopcameraOperationDescriptor[])
|
|
213
379
|
|
|
214
380
|
export interface CheckSlopcameraOperationInput {
|
|
@@ -234,11 +400,37 @@ export interface GenerateSlopcameraOperationInput {
|
|
|
234
400
|
readonly outputPath: string
|
|
235
401
|
}
|
|
236
402
|
|
|
403
|
+
export interface IconSlopcameraOperationInput {
|
|
404
|
+
readonly subject: string
|
|
405
|
+
readonly outputPath: string
|
|
406
|
+
readonly model?: SlopcameraImageModel
|
|
407
|
+
readonly critiqueModel?: string
|
|
408
|
+
readonly ink?: string
|
|
409
|
+
readonly purpose?: "illustration" | "mark"
|
|
410
|
+
readonly rounds?: number
|
|
411
|
+
readonly keepRaster?: boolean
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export interface GallerySlopcameraOperationInput {
|
|
415
|
+
readonly subject: string
|
|
416
|
+
readonly outputDir: string
|
|
417
|
+
readonly kind?: string
|
|
418
|
+
readonly model?: SlopcameraImageModel
|
|
419
|
+
readonly count?: number
|
|
420
|
+
readonly vary?: readonly unknown[]
|
|
421
|
+
readonly candidates?: readonly unknown[]
|
|
422
|
+
readonly cellEdge?: number
|
|
423
|
+
readonly tiled?: boolean
|
|
424
|
+
readonly timeoutMs?: number
|
|
425
|
+
}
|
|
426
|
+
|
|
237
427
|
export interface SlopcameraOperationInputMap {
|
|
238
428
|
readonly "slopcamera.diagram.check": CheckSlopcameraOperationInput
|
|
239
429
|
readonly "slopcamera.diagram.render": RenderSlopcameraOperationInput
|
|
240
430
|
readonly "slopcamera.image.vectorize": VectorizeSlopcameraOperationInput
|
|
241
431
|
readonly "slopcamera.image.generate": GenerateSlopcameraOperationInput
|
|
432
|
+
readonly "slopcamera.image.icon": IconSlopcameraOperationInput
|
|
433
|
+
readonly "slopcamera.image.gallery": GallerySlopcameraOperationInput
|
|
242
434
|
}
|
|
243
435
|
|
|
244
436
|
export interface SlopcameraOperationResultMap {
|
|
@@ -256,6 +448,8 @@ export interface SlopcameraOperationResultMap {
|
|
|
256
448
|
readonly receipt: VectorizeReceipt
|
|
257
449
|
}
|
|
258
450
|
readonly "slopcamera.image.generate": GeneratedSlopcameraImageFile
|
|
451
|
+
readonly "slopcamera.image.icon": SlopcameraIconReceipt
|
|
452
|
+
readonly "slopcamera.image.gallery": SlopcameraGalleryReceipt
|
|
259
453
|
}
|
|
260
454
|
|
|
261
455
|
function operationFailure(message: string): never {
|
|
@@ -401,6 +595,190 @@ function parseGenerate(value: unknown): GenerateSlopcameraOperationInput {
|
|
|
401
595
|
}
|
|
402
596
|
}
|
|
403
597
|
|
|
598
|
+
function parseIcon(value: unknown): IconSlopcameraOperationInput {
|
|
599
|
+
const input = record(value, [
|
|
600
|
+
"subject",
|
|
601
|
+
"outputPath",
|
|
602
|
+
"model",
|
|
603
|
+
"critiqueModel",
|
|
604
|
+
"ink",
|
|
605
|
+
"rounds",
|
|
606
|
+
"keepRaster",
|
|
607
|
+
])
|
|
608
|
+
if (
|
|
609
|
+
typeof input.subject !== "string" ||
|
|
610
|
+
input.subject.trim().length < 1 ||
|
|
611
|
+
/[\u0000-\u001f\u007f]/u.test(input.subject) ||
|
|
612
|
+
Buffer.byteLength(input.subject, "utf8") > slopcameraIconSubjectMaximumBytes
|
|
613
|
+
) {
|
|
614
|
+
operationFailure(
|
|
615
|
+
`subject must be non-empty and no more than ${slopcameraIconSubjectMaximumBytes} UTF-8 bytes.`,
|
|
616
|
+
)
|
|
617
|
+
}
|
|
618
|
+
const outputPath = pathValue(input.outputPath, "outputPath")
|
|
619
|
+
if (!outputPath.toLowerCase().endsWith(".svg")) {
|
|
620
|
+
operationFailure("outputPath must end in .svg.")
|
|
621
|
+
}
|
|
622
|
+
for (const name of ["model", "critiqueModel"] as const) {
|
|
623
|
+
const model = input[name]
|
|
624
|
+
if (
|
|
625
|
+
model !== undefined &&
|
|
626
|
+
(typeof model !== "string" ||
|
|
627
|
+
model.length > 256 ||
|
|
628
|
+
!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._:-]*$/iu.test(model))
|
|
629
|
+
) {
|
|
630
|
+
operationFailure(`${name} must be a bounded Vercel AI Gateway provider/model id.`)
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (
|
|
634
|
+
input.ink !== undefined &&
|
|
635
|
+
(typeof input.ink !== "string" ||
|
|
636
|
+
!/^#[a-f0-9]{3}(?:[a-f0-9]{3})?$/iu.test(input.ink))
|
|
637
|
+
) {
|
|
638
|
+
operationFailure("ink must be a #rgb or #rrggbb color.")
|
|
639
|
+
}
|
|
640
|
+
const rounds = input.rounds
|
|
641
|
+
if (
|
|
642
|
+
rounds !== undefined &&
|
|
643
|
+
(!Number.isInteger(rounds) ||
|
|
644
|
+
(rounds as number) < 1 ||
|
|
645
|
+
(rounds as number) > slopcameraIconMaximumRounds)
|
|
646
|
+
) {
|
|
647
|
+
operationFailure(
|
|
648
|
+
`rounds must be an integer from 1 through ${slopcameraIconMaximumRounds}.`,
|
|
649
|
+
)
|
|
650
|
+
}
|
|
651
|
+
if (
|
|
652
|
+
input.keepRaster !== undefined &&
|
|
653
|
+
typeof input.keepRaster !== "boolean"
|
|
654
|
+
) {
|
|
655
|
+
operationFailure("keepRaster must be a boolean.")
|
|
656
|
+
}
|
|
657
|
+
return {
|
|
658
|
+
subject: input.subject,
|
|
659
|
+
outputPath,
|
|
660
|
+
...(input.model === undefined
|
|
661
|
+
? {}
|
|
662
|
+
: { model: input.model as SlopcameraImageModel }),
|
|
663
|
+
...(input.critiqueModel === undefined
|
|
664
|
+
? {}
|
|
665
|
+
: { critiqueModel: input.critiqueModel as string }),
|
|
666
|
+
...(input.ink === undefined ? {} : { ink: input.ink as string }),
|
|
667
|
+
...(rounds === undefined ? {} : { rounds: rounds as number }),
|
|
668
|
+
...(input.keepRaster === undefined
|
|
669
|
+
? {}
|
|
670
|
+
: { keepRaster: input.keepRaster as boolean }),
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
function parseGallery(value: unknown): GallerySlopcameraOperationInput {
|
|
675
|
+
const input = record(value, [
|
|
676
|
+
"subject",
|
|
677
|
+
"outputDir",
|
|
678
|
+
"kind",
|
|
679
|
+
"model",
|
|
680
|
+
"count",
|
|
681
|
+
"vary",
|
|
682
|
+
"candidates",
|
|
683
|
+
"cellEdge",
|
|
684
|
+
"tiled",
|
|
685
|
+
"timeoutMs",
|
|
686
|
+
])
|
|
687
|
+
if (
|
|
688
|
+
typeof input.subject !== "string" ||
|
|
689
|
+
input.subject.trim().length < 1 ||
|
|
690
|
+
/[\u0000-\u001f\u007f]/u.test(input.subject) ||
|
|
691
|
+
Buffer.byteLength(input.subject, "utf8") > slopcameraGalleryLimits.subjectBytes
|
|
692
|
+
) {
|
|
693
|
+
operationFailure(
|
|
694
|
+
`subject must be non-empty and no more than ${slopcameraGalleryLimits.subjectBytes} UTF-8 bytes.`,
|
|
695
|
+
)
|
|
696
|
+
}
|
|
697
|
+
if (
|
|
698
|
+
input.kind !== undefined &&
|
|
699
|
+
(typeof input.kind !== "string" || !slopcameraGalleryKinds.includes(input.kind as never))
|
|
700
|
+
) {
|
|
701
|
+
operationFailure(`kind must be one of: ${slopcameraGalleryKinds.join(", ")}.`)
|
|
702
|
+
}
|
|
703
|
+
if (
|
|
704
|
+
input.model !== undefined &&
|
|
705
|
+
(typeof input.model !== "string" ||
|
|
706
|
+
input.model.length > 256 ||
|
|
707
|
+
!/^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._:-]*$/iu.test(input.model))
|
|
708
|
+
) {
|
|
709
|
+
operationFailure("model must be a bounded Vercel AI Gateway provider/model id.")
|
|
710
|
+
}
|
|
711
|
+
if (
|
|
712
|
+
input.count !== undefined &&
|
|
713
|
+
(!Number.isInteger(input.count) ||
|
|
714
|
+
(input.count as number) < 1 ||
|
|
715
|
+
(input.count as number) > slopcameraGalleryLimits.candidates)
|
|
716
|
+
) {
|
|
717
|
+
operationFailure(`count must be an integer from 1 through ${slopcameraGalleryLimits.candidates}.`)
|
|
718
|
+
}
|
|
719
|
+
if (
|
|
720
|
+
input.vary !== undefined &&
|
|
721
|
+
(!Array.isArray(input.vary) || input.vary.length < 1 || input.vary.length > slopcameraGalleryAxes.length)
|
|
722
|
+
) {
|
|
723
|
+
operationFailure(`vary must be a list of at most ${slopcameraGalleryAxes.length} axes.`)
|
|
724
|
+
}
|
|
725
|
+
if (
|
|
726
|
+
input.candidates !== undefined &&
|
|
727
|
+
(!Array.isArray(input.candidates) ||
|
|
728
|
+
input.candidates.length < 1 ||
|
|
729
|
+
input.candidates.length > slopcameraGalleryLimits.candidates)
|
|
730
|
+
) {
|
|
731
|
+
operationFailure(`candidates must contain 1 through ${slopcameraGalleryLimits.candidates} entries.`)
|
|
732
|
+
}
|
|
733
|
+
if (
|
|
734
|
+
input.vary !== undefined &&
|
|
735
|
+
input.candidates !== undefined
|
|
736
|
+
) {
|
|
737
|
+
operationFailure("vary and candidates are mutually exclusive.")
|
|
738
|
+
}
|
|
739
|
+
if (
|
|
740
|
+
input.count !== undefined &&
|
|
741
|
+
input.candidates !== undefined
|
|
742
|
+
) {
|
|
743
|
+
operationFailure("count and candidates are mutually exclusive.")
|
|
744
|
+
}
|
|
745
|
+
const cellEdge = input.cellEdge
|
|
746
|
+
if (
|
|
747
|
+
cellEdge !== undefined &&
|
|
748
|
+
(!Number.isInteger(cellEdge) ||
|
|
749
|
+
(cellEdge as number) < slopcameraGalleryLimits.cellEdgeMin ||
|
|
750
|
+
(cellEdge as number) > slopcameraGalleryLimits.cellEdgeMax)
|
|
751
|
+
) {
|
|
752
|
+
operationFailure(
|
|
753
|
+
`cellEdge must be an integer from ${slopcameraGalleryLimits.cellEdgeMin} through ${slopcameraGalleryLimits.cellEdgeMax}.`,
|
|
754
|
+
)
|
|
755
|
+
}
|
|
756
|
+
const timeoutMs = input.timeoutMs
|
|
757
|
+
if (
|
|
758
|
+
timeoutMs !== undefined &&
|
|
759
|
+
(!Number.isInteger(timeoutMs) ||
|
|
760
|
+
(timeoutMs as number) < 1_000 ||
|
|
761
|
+
(timeoutMs as number) > 30 * 60_000)
|
|
762
|
+
) {
|
|
763
|
+
operationFailure("timeoutMs must be an integer from 1000 through 1800000.")
|
|
764
|
+
}
|
|
765
|
+
if (input.tiled !== undefined && typeof input.tiled !== "boolean") {
|
|
766
|
+
operationFailure("tiled must be a boolean when set.")
|
|
767
|
+
}
|
|
768
|
+
return {
|
|
769
|
+
subject: input.subject as string,
|
|
770
|
+
outputDir: pathValue(input.outputDir, "outputDir"),
|
|
771
|
+
...(input.kind === undefined ? {} : { kind: input.kind as string }),
|
|
772
|
+
...(input.model === undefined ? {} : { model: input.model as SlopcameraImageModel }),
|
|
773
|
+
...(input.count === undefined ? {} : { count: input.count as number }),
|
|
774
|
+
...(input.vary === undefined ? {} : { vary: input.vary as readonly unknown[] }),
|
|
775
|
+
...(input.candidates === undefined ? {} : { candidates: input.candidates as readonly unknown[] }),
|
|
776
|
+
...(cellEdge === undefined ? {} : { cellEdge: cellEdge as number }),
|
|
777
|
+
...(input.tiled === undefined ? {} : { tiled: input.tiled as boolean }),
|
|
778
|
+
...(timeoutMs === undefined ? {} : { timeoutMs: timeoutMs as number }),
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
|
|
404
782
|
export function parseSlopcameraOperationInput<C extends SlopcameraOperationCode>(
|
|
405
783
|
code: C,
|
|
406
784
|
input: unknown,
|
|
@@ -414,6 +792,10 @@ export function parseSlopcameraOperationInput<C extends SlopcameraOperationCode>
|
|
|
414
792
|
return parseVectorize(input) as SlopcameraOperationInputMap[C]
|
|
415
793
|
case "slopcamera.image.generate":
|
|
416
794
|
return parseGenerate(input) as SlopcameraOperationInputMap[C]
|
|
795
|
+
case "slopcamera.image.icon":
|
|
796
|
+
return parseIcon(input) as SlopcameraOperationInputMap[C]
|
|
797
|
+
case "slopcamera.image.gallery":
|
|
798
|
+
return parseGallery(input) as SlopcameraOperationInputMap[C]
|
|
417
799
|
default:
|
|
418
800
|
throw new SlopcameraOperationError(
|
|
419
801
|
"INVALID_OPERATION",
|
|
@@ -698,6 +1080,36 @@ async function executeSlopcameraOperationUncoordinated<
|
|
|
698
1080
|
dependencies,
|
|
699
1081
|
)) as SlopcameraOperationResultMap[C]
|
|
700
1082
|
}
|
|
1083
|
+
case "slopcamera.image.icon": {
|
|
1084
|
+
const options = input as IconSlopcameraOperationInput
|
|
1085
|
+
return (await generateSlopcameraIcon(
|
|
1086
|
+
{
|
|
1087
|
+
...options,
|
|
1088
|
+
...(dependencies.signal === undefined
|
|
1089
|
+
? {}
|
|
1090
|
+
: { signal: dependencies.signal }),
|
|
1091
|
+
...(dependencies.inheritedFileDescriptors === undefined
|
|
1092
|
+
? {}
|
|
1093
|
+
: {
|
|
1094
|
+
inheritedFileDescriptors:
|
|
1095
|
+
dependencies.inheritedFileDescriptors,
|
|
1096
|
+
}),
|
|
1097
|
+
},
|
|
1098
|
+
dependencies,
|
|
1099
|
+
)) as SlopcameraOperationResultMap[C]
|
|
1100
|
+
}
|
|
1101
|
+
case "slopcamera.image.gallery": {
|
|
1102
|
+
const options = input as GallerySlopcameraOperationInput
|
|
1103
|
+
return (await generateSlopcameraImageGallery(
|
|
1104
|
+
{
|
|
1105
|
+
...options,
|
|
1106
|
+
...(dependencies.signal === undefined
|
|
1107
|
+
? {}
|
|
1108
|
+
: { signal: dependencies.signal }),
|
|
1109
|
+
},
|
|
1110
|
+
dependencies,
|
|
1111
|
+
)) as SlopcameraOperationResultMap[C]
|
|
1112
|
+
}
|
|
701
1113
|
default:
|
|
702
1114
|
throw new SlopcameraOperationError(
|
|
703
1115
|
"INVALID_OPERATION",
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compileSlopcameraCapabilityManifest,
|
|
3
|
+
defineSlopcameraCapabilityModule,
|
|
4
|
+
type SlopcameraCapabilityManifest,
|
|
5
|
+
type SlopcameraCapabilityOperation,
|
|
6
|
+
} from "./capability-manifest.js"
|
|
7
|
+
import {
|
|
8
|
+
PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS,
|
|
9
|
+
PORTABLE_SLOPCAMERA_OPERATION_KINDS,
|
|
10
|
+
type PortableSlopcameraOperationKind,
|
|
11
|
+
} from "./code/public-operations.js"
|
|
12
|
+
|
|
13
|
+
export const SLOPCAMERA_PORTABLE_CAPABILITY_VERSION = "slopcamera-portable-v1" as const
|
|
14
|
+
|
|
15
|
+
const portableModule = defineSlopcameraCapabilityModule({
|
|
16
|
+
commands: [],
|
|
17
|
+
description: "The fixed portable diagram and image operation projection for Bun SDK consumers.",
|
|
18
|
+
moduleId: "slopcamera.capability.portable-diagram-image",
|
|
19
|
+
operationKeys: PORTABLE_SLOPCAMERA_OPERATION_KINDS.map(kind => `${kind}@2`),
|
|
20
|
+
profiles: [{
|
|
21
|
+
id: "portable-bun-v1",
|
|
22
|
+
kind: "authoring",
|
|
23
|
+
qualification: { evidence: ["src/code/public-operations.ts"], level: "unit", status: "qualified" },
|
|
24
|
+
requirements: [{ description: "Bun 1.3.14 or newer.", id: "bun", optional: false }],
|
|
25
|
+
}],
|
|
26
|
+
stability: "stable",
|
|
27
|
+
title: "Portable diagrams and images",
|
|
28
|
+
toolNames: [],
|
|
29
|
+
trust: "portable",
|
|
30
|
+
version: 1,
|
|
31
|
+
workflowKeys: [],
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
function operationProjection(kind: PortableSlopcameraOperationKind): SlopcameraCapabilityOperation {
|
|
35
|
+
const operation = PORTABLE_SLOPCAMERA_OPERATION_CONTRACTS[kind]
|
|
36
|
+
return {
|
|
37
|
+
cache: operation.policy.cache,
|
|
38
|
+
cancellable: operation.policy.cancellable,
|
|
39
|
+
effect: operation.policy.effect,
|
|
40
|
+
inputSchemaId: operation.inputSchemaId,
|
|
41
|
+
key: `${operation.kind}@${operation.version}`,
|
|
42
|
+
kind: operation.kind,
|
|
43
|
+
lifecycle: operation.lifecycle,
|
|
44
|
+
maxDurationMs: operation.policy.maxDurationMs,
|
|
45
|
+
maxFanOut: operation.policy.maxFanOut,
|
|
46
|
+
maxInputBytes: operation.policy.maxInputBytes,
|
|
47
|
+
maxOutputBytes: operation.policy.maxOutputBytes,
|
|
48
|
+
outputSchemaId: operation.outputSchemaId,
|
|
49
|
+
preparation: [...operation.policy.preparation],
|
|
50
|
+
resources: operation.policy.resources.map(claim => ({ ...claim })),
|
|
51
|
+
resume: operation.policy.resume,
|
|
52
|
+
version: operation.version,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function createPortableSlopcameraCapabilityManifest(): SlopcameraCapabilityManifest {
|
|
57
|
+
return compileSlopcameraCapabilityManifest({
|
|
58
|
+
host: "portable",
|
|
59
|
+
modules: [portableModule],
|
|
60
|
+
operations: PORTABLE_SLOPCAMERA_OPERATION_KINDS.map(operationProjection),
|
|
61
|
+
tools: [],
|
|
62
|
+
toolVersion: SLOPCAMERA_PORTABLE_CAPABILITY_VERSION,
|
|
63
|
+
workflows: [],
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const slopcameraPortableCapabilityManifest = createPortableSlopcameraCapabilityManifest()
|