@hraness/slopcamera 3.2.7 → 3.2.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.
Files changed (67) hide show
  1. package/NOTICE.md +1 -7
  2. package/PRIVACY.md +16 -7
  3. package/README.md +37 -12
  4. package/apps/desktop/README.md +14 -130
  5. package/apps/desktop/application/context.ts +0 -9
  6. package/apps/desktop/application/default-registry.ts +0 -10
  7. package/apps/desktop/application/operation.ts +1 -5
  8. package/apps/desktop/application/operations/index.ts +0 -1
  9. package/apps/desktop/cli/args.ts +14 -86
  10. package/apps/desktop/cli/command-host-resources.ts +2 -1
  11. package/apps/desktop/cli/commands.ts +28 -67
  12. package/apps/desktop/cli/help.ts +12 -18
  13. package/apps/desktop/cli/html-scene.ts +139 -28
  14. package/apps/desktop/cli/io.ts +2 -1
  15. package/apps/desktop/cli/main.ts +23 -47
  16. package/apps/desktop/cli/menubar.ts +244 -0
  17. package/apps/desktop/cli/music-analysis-service.ts +61 -0
  18. package/apps/desktop/cli/portable-surface.ts +12 -4
  19. package/apps/desktop/code/application-node-planner.ts +0 -47
  20. package/apps/desktop/code/host-source-layout.ts +46 -0
  21. package/apps/desktop/code/public.ts +0 -1
  22. package/apps/desktop/code/runtime-identity.ts +50 -8
  23. package/apps/desktop/code/semantic-builder.ts +0 -43
  24. package/apps/desktop/code/source-bundle.ts +23 -6
  25. package/apps/desktop/code/source-typecheck.ts +131 -43
  26. package/apps/desktop/code/worker-client.ts +14 -2
  27. package/apps/desktop/core/music-analysis.ts +124 -1
  28. package/apps/desktop/dist/cli/main.js +244 -250
  29. package/apps/desktop/html-overlay/audio-reactivity.ts +127 -0
  30. package/apps/desktop/html-overlay/index.ts +9 -0
  31. package/apps/desktop/html-overlay/runtime.ts +2 -0
  32. package/apps/desktop/html-overlay/scene.ts +29 -0
  33. package/dist/cli.js +83 -81
  34. package/dist/{index-rvghzt7b.js → index-7131pg1c.js} +43 -236
  35. package/dist/{index-mcy8z0br.js → index-fava6pge.js} +1 -1
  36. package/dist/{index-z7239b4h.js → index-h1k0fnjq.js} +1 -1
  37. package/dist/{index-p63wavx0.js → index-zfnddgay.js} +1 -1
  38. package/dist/index.js +4 -18
  39. package/dist/operations.js +2 -2
  40. package/dist/vectorize/worker.js +1 -1
  41. package/dist/workflow.js +3 -3
  42. package/docs/README.md +1 -1
  43. package/docs/studio.md +1 -1
  44. package/package.json +6 -21
  45. package/skills/slopcamera/SKILL.md +8 -0
  46. package/skills/slopcamera/references/diagrams.md +5 -14
  47. package/skills/slopcamera/references/install.md +1 -1
  48. package/skills/slopcamera/references/music-video.md +23 -3
  49. package/skills/slopcamera/references/reference-led-3d.md +1 -1
  50. package/skills/slopcamera/references/support.md +25 -0
  51. package/skills/slopcamera/references/web-media-excerpts.md +120 -0
  52. package/src/cli.ts +28 -98
  53. package/src/index.ts +0 -23
  54. package/src/support-completion.ts +16 -0
  55. package/src/support.ts +42 -0
  56. package/src/version.ts +1 -1
  57. package/apps/desktop/application/operations/recording/index.ts +0 -5
  58. package/apps/desktop/application/operations/recording/pause.ts +0 -34
  59. package/apps/desktop/application/operations/recording/resume.ts +0 -34
  60. package/apps/desktop/application/operations/recording/shared.ts +0 -199
  61. package/apps/desktop/application/operations/recording/start.ts +0 -169
  62. package/apps/desktop/application/operations/recording/stop.ts +0 -34
  63. package/apps/desktop/capture/protocol.ts +0 -689
  64. package/apps/desktop/cli/capture-bundle.ts +0 -1117
  65. package/apps/desktop/cli/recording-controller.ts +0 -1567
  66. package/apps/desktop/cli/recording-daemon.ts +0 -931
  67. package/src/desktop.ts +0 -253
package/src/index.ts CHANGED
@@ -4,15 +4,6 @@ import {
4
4
  readDiagramFile,
5
5
  renderDiagramFile,
6
6
  } from "./artifacts.js"
7
- import {
8
- desktopDownloadPage,
9
- desktopStatus,
10
- findDesktopApplication,
11
- getLatestDesktopRelease,
12
- installDesktop,
13
- openInDesktop,
14
- selectDesktopAsset,
15
- } from "./desktop.js"
16
7
  import {
17
8
  generateSlopcameraImage,
18
9
  generateSlopcameraImageFile,
@@ -64,27 +55,21 @@ export const slopcameraApi = Object.freeze({
64
55
  builtInIcons,
65
56
  bundledSkillPath,
66
57
  checkDiagramFile,
67
- desktopDownloadPage,
68
- desktopStatus,
69
58
  defineSlopcameraWorkflow,
70
59
  DiagramValidationError,
71
- findDesktopApplication,
72
60
  generateSlopcameraImage,
73
61
  generateSlopcameraImageFile,
74
- getLatestDesktopRelease,
75
62
  slopcameraGatewayCredentialStatus,
76
63
  slopcameraMcpProtocolVersion,
77
64
  slopcameraMcpServerName,
78
65
  slopcameraMcpTools,
79
66
  slopcameraOperationRegistry,
80
67
  SlopcameraMcpToolRuntime,
81
- installDesktop,
82
68
  installSkill,
83
69
  lintDiagram,
84
70
  mcpMaximumRenderedPixels,
85
71
  mcpMaximumScale,
86
72
  mcpSourceByteLimit,
87
- openInDesktop,
88
73
  parseDiagramSource,
89
74
  parseDiagramSpec,
90
75
  readDiagramFile,
@@ -97,7 +82,6 @@ export const slopcameraApi = Object.freeze({
97
82
  runSlopcameraWorkflow,
98
83
  runMcpServer,
99
84
  searchSlopcameraOperations,
100
- selectDesktopAsset,
101
85
  serializeTldr,
102
86
  stackLayoutDefaults,
103
87
  StackLayoutError,
@@ -116,26 +100,20 @@ export {
116
100
  builtInIcons,
117
101
  bundledSkillPath,
118
102
  checkDiagramFile,
119
- desktopDownloadPage,
120
- desktopStatus,
121
103
  DiagramValidationError,
122
- findDesktopApplication,
123
104
  generateSlopcameraImage,
124
105
  generateSlopcameraImageFile,
125
- getLatestDesktopRelease,
126
106
  slopcameraGatewayCredentialStatus,
127
107
  slopcameraMcpProtocolVersion,
128
108
  slopcameraMcpServerName,
129
109
  slopcameraMcpTools,
130
110
  slopcameraOperationRegistry,
131
111
  SlopcameraMcpToolRuntime,
132
- installDesktop,
133
112
  installSkill,
134
113
  lintDiagram,
135
114
  mcpMaximumRenderedPixels,
136
115
  mcpMaximumScale,
137
116
  mcpSourceByteLimit,
138
- openInDesktop,
139
117
  parseDiagramSource,
140
118
  parseDiagramSpec,
141
119
  readDiagramFile,
@@ -147,7 +125,6 @@ export {
147
125
  resolveStackLayout,
148
126
  runMcpServer,
149
127
  searchSlopcameraOperations,
150
- selectDesktopAsset,
151
128
  serializeTldr,
152
129
  stackLayoutDefaults,
153
130
  StackLayoutError,
@@ -0,0 +1,16 @@
1
+ /** Content-free notification after useful output and owned cleanup complete. */
2
+ export type UsefulResultObserver = () => void | Promise<void>
3
+
4
+ export function reportUsefulResult(observer: UsefulResultObserver | undefined): void {
5
+ try {
6
+ if (observer !== undefined) void Promise.resolve(observer()).catch(() => undefined)
7
+ } catch {
8
+ // Optional presentation cannot change a completed operation's outcome.
9
+ }
10
+ }
11
+
12
+ export function quietSupportChildEnvironment(
13
+ env: Readonly<Record<string, string | undefined>>,
14
+ ): Record<string, string | undefined> {
15
+ return { ...env, HRANESS_SUPPORT_AUDIENCE: "off", HRANESS_SUPPORT_EMAIL: "off" }
16
+ }
package/src/support.ts ADDED
@@ -0,0 +1,42 @@
1
+ import {
2
+ maybeShowSupportInvitation,
3
+ runSupportCommand,
4
+ type SupportCommandOptions,
5
+ } from "@hraness/support-foundation/node"
6
+
7
+ export const supportProfile = {
8
+ id: "slopcamera",
9
+ name: "Slopcamera",
10
+ valueProposition: "Support ongoing development of local visual tools for agents.",
11
+ updates: false,
12
+ } as const
13
+
14
+ /** Called only by the real process entrypoint; imported CLI and SDK calls stay inert. */
15
+ export function standaloneSupportEnvironment(): Readonly<Record<string, string | undefined>> {
16
+ const env = { ...process.env }
17
+ process.env.HRANESS_SUPPORT_AUDIENCE = "off"
18
+ process.env.HRANESS_SUPPORT_EMAIL = "off"
19
+ return env
20
+ }
21
+
22
+ export async function runProductSupportCommand(
23
+ args: readonly string[],
24
+ options: SupportCommandOptions = {},
25
+ ): Promise<number> {
26
+ const result = await runSupportCommand(supportProfile, args, {
27
+ command: ["slopcamera"], ...options, gitEmail: false,
28
+ })
29
+ if (result.stdout !== "") process.stdout.write(result.stdout)
30
+ if (result.stderr !== "") process.stderr.write(result.stderr)
31
+ return result.exitCode
32
+ }
33
+
34
+ export async function showProductSupportInvitation(options: SupportCommandOptions = {}): Promise<void> {
35
+ try {
36
+ await maybeShowSupportInvitation(supportProfile, {
37
+ usefulResult: true, command: ["slopcamera"], ...options, gitEmail: false,
38
+ })
39
+ } catch {
40
+ // Optional support must not alter the completed task or its stdout.
41
+ }
42
+ }
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const SLOPCAMERA_VERSION = "3.2.7" as const
1
+ export const SLOPCAMERA_VERSION = "3.2.8" as const
@@ -1,5 +0,0 @@
1
- export * from "./pause";
2
- export * from "./resume";
3
- export * from "./shared";
4
- export * from "./start";
5
- export * from "./stop";
@@ -1,34 +0,0 @@
1
- import type { OperationDefinition } from "../../operation";
2
- import {
3
- EmptyRecordingOperationInputSchema,
4
- type EmptyRecordingOperationInput,
5
- executeRecordingControl,
6
- RecordingOperationOutputSchema,
7
- type RecordingOperationOutput,
8
- recordingTransitionPolicy,
9
- summarizeRecordingControl,
10
- } from "./shared";
11
-
12
- export const RecordingPauseInputSchema = EmptyRecordingOperationInputSchema;
13
- export const RecordingPauseOutputSchema = RecordingOperationOutputSchema;
14
- export type RecordingPauseInput = EmptyRecordingOperationInput;
15
- export type RecordingPauseOutput = RecordingOperationOutput;
16
-
17
- export const recordingPauseOperationDefinition: OperationDefinition<
18
- "recording.pause",
19
- RecordingPauseInput,
20
- RecordingPauseOutput
21
- > = {
22
- inputSchema: RecordingPauseInputSchema,
23
- inputSchemaId: "slopcamera.operation.recording.pause.input/v1",
24
- kind: "recording.pause",
25
- lifecycle: {
26
- kind: "live-control",
27
- execute: async context => await executeRecordingControl(context, "pause"),
28
- },
29
- outputSchema: RecordingPauseOutputSchema,
30
- outputSchemaId: "slopcamera.operation.recording.pause.output/v1",
31
- policy: recordingTransitionPolicy,
32
- summarize: output => summarizeRecordingControl("recording.pause", output),
33
- version: 1,
34
- };
@@ -1,34 +0,0 @@
1
- import type { OperationDefinition } from "../../operation";
2
- import {
3
- EmptyRecordingOperationInputSchema,
4
- type EmptyRecordingOperationInput,
5
- executeRecordingControl,
6
- RecordingOperationOutputSchema,
7
- type RecordingOperationOutput,
8
- recordingTransitionPolicy,
9
- summarizeRecordingControl,
10
- } from "./shared";
11
-
12
- export const RecordingResumeInputSchema = EmptyRecordingOperationInputSchema;
13
- export const RecordingResumeOutputSchema = RecordingOperationOutputSchema;
14
- export type RecordingResumeInput = EmptyRecordingOperationInput;
15
- export type RecordingResumeOutput = RecordingOperationOutput;
16
-
17
- export const recordingResumeOperationDefinition: OperationDefinition<
18
- "recording.resume",
19
- RecordingResumeInput,
20
- RecordingResumeOutput
21
- > = {
22
- inputSchema: RecordingResumeInputSchema,
23
- inputSchemaId: "slopcamera.operation.recording.resume.input/v1",
24
- kind: "recording.resume",
25
- lifecycle: {
26
- kind: "live-control",
27
- execute: async context => await executeRecordingControl(context, "resume"),
28
- },
29
- outputSchema: RecordingResumeOutputSchema,
30
- outputSchemaId: "slopcamera.operation.recording.resume.output/v1",
31
- policy: recordingTransitionPolicy,
32
- summarize: output => summarizeRecordingControl("recording.resume", output),
33
- version: 1,
34
- };
@@ -1,199 +0,0 @@
1
- import { z } from "zod";
2
-
3
- import {
4
- CapturePermissionsSchema,
5
- IsoTimestampSchema,
6
- MicrosecondsSchema,
7
- RecordingIdSchema,
8
- } from "../../../contracts";
9
- import type {
10
- ApplicationContext,
11
- ApplicationRecordingController,
12
- } from "../../context";
13
- import { ApplicationError } from "../../errors";
14
- import type {
15
- BoundedOperationSummary,
16
- OperationExecutionContext,
17
- OperationKind,
18
- OperationPolicy,
19
- } from "../../operation";
20
- import { throwIfAborted } from "../shared";
21
-
22
- export const MAX_RECORDING_OPERATION_DISPLAYS = 16;
23
-
24
- const DisplayIdSchema = z.string().min(1).max(64);
25
- const DeviceIdSchema = z.string().min(1).max(256);
26
-
27
- const ExplicitDisplayIdsSchema = z.array(DisplayIdSchema)
28
- .min(1)
29
- .max(MAX_RECORDING_OPERATION_DISPLAYS)
30
- .superRefine((displayIds, context) => {
31
- if (new Set(displayIds).size !== displayIds.length) {
32
- context.addIssue({
33
- code: "custom",
34
- message: "Explicit recording display IDs must be unique.",
35
- });
36
- }
37
- });
38
-
39
- export const RecordingDisplaySelectionSchema = z.discriminatedUnion("kind", [
40
- z.strictObject({
41
- kind: z.literal("all"),
42
- }),
43
- z.strictObject({
44
- displayIds: ExplicitDisplayIdsSchema,
45
- kind: z.literal("selected"),
46
- }),
47
- ]);
48
-
49
- export const RecordingDeviceSelectionSchema = z.discriminatedUnion("kind", [
50
- z.strictObject({ kind: z.literal("disabled") }),
51
- z.strictObject({ kind: z.literal("default") }),
52
- z.strictObject({ deviceId: DeviceIdSchema, kind: z.literal("device") }),
53
- ]);
54
-
55
- const RecordingStartFields = {
56
- camera: RecordingDeviceSelectionSchema,
57
- displays: RecordingDisplaySelectionSchema,
58
- microphone: RecordingDeviceSelectionSchema,
59
- strictInputs: z.boolean(),
60
- systemAudio: z.boolean(),
61
- typedText: z.boolean(),
62
- } as const;
63
-
64
- export const RecordingStartInputSchema = z.strictObject(
65
- RecordingStartFields,
66
- );
67
-
68
- export const EffectiveRecordingConfigSchema = z.strictObject({
69
- ...RecordingStartFields,
70
- metadata: z.literal(true),
71
- });
72
-
73
- const RecordingOperationOutputFields = {
74
- completedSegmentCount: z.number().int().safe().nonnegative(),
75
- effectiveConfig: EffectiveRecordingConfigSchema.nullable(),
76
- logicalTimeUs: MicrosecondsSchema,
77
- permissions: CapturePermissionsSchema.nullable(),
78
- recordingId: RecordingIdSchema.nullable(),
79
- state: z.enum(["idle", "recording", "paused"]),
80
- updatedAt: IsoTimestampSchema.max(64),
81
- } as const;
82
-
83
- export const RecordingOperationOutputSchema = z.strictObject(
84
- RecordingOperationOutputFields,
85
- );
86
-
87
- const ControllerRecordingSnapshotSchema = z.strictObject({
88
- ...RecordingOperationOutputFields,
89
- recordingRoot: z.string().min(1).max(4_096).nullable(),
90
- });
91
-
92
- export const EmptyRecordingOperationInputSchema = z.strictObject({});
93
-
94
- export type RecordingStartInput = z.infer<typeof RecordingStartInputSchema>;
95
- export type RecordingOperationOutput = z.infer<
96
- typeof RecordingOperationOutputSchema
97
- >;
98
- export type EmptyRecordingOperationInput = z.infer<
99
- typeof EmptyRecordingOperationInputSchema
100
- >;
101
-
102
- export const recordingStartPolicy = {
103
- cache: "none",
104
- cancellable: false,
105
- effect: "live-control",
106
- maxDurationMs: 5 * 60_000,
107
- maxFanOut: 0,
108
- maxInputBytes: 32 * 1_024,
109
- maxOutputBytes: 64 * 1_024,
110
- preparation: [
111
- "recording-metadata",
112
- "screen-capture",
113
- "camera",
114
- "microphone",
115
- "system-audio",
116
- "typed-text",
117
- "window-metadata",
118
- ],
119
- resources: [{ amount: 1, resource: "capture-device" }],
120
- resume: "non-resumable-live",
121
- } as const satisfies OperationPolicy;
122
-
123
- export const recordingTransitionPolicy = {
124
- cache: "none",
125
- cancellable: false,
126
- effect: "live-control",
127
- maxDurationMs: 5 * 60_000,
128
- maxFanOut: 0,
129
- maxInputBytes: 64,
130
- maxOutputBytes: 64 * 1_024,
131
- preparation: [],
132
- resources: [{ amount: 1, resource: "capture-device" }],
133
- resume: "non-resumable-live",
134
- } as const satisfies OperationPolicy;
135
-
136
- function requireRecordingController(
137
- application: ApplicationContext,
138
- ): ApplicationRecordingController {
139
- const controller = application.recordingController;
140
- if (controller === undefined) {
141
- throw new ApplicationError(
142
- "unavailable",
143
- "Recording controller is unavailable.",
144
- );
145
- }
146
- return controller;
147
- }
148
-
149
- export function parseRecordingOperationOutput(
150
- value: unknown,
151
- ): RecordingOperationOutput {
152
- const parsed = ControllerRecordingSnapshotSchema.safeParse(value);
153
- if (!parsed.success) {
154
- throw new ApplicationError(
155
- "invalid-data",
156
- "Recording controller returned an invalid bounded snapshot.",
157
- );
158
- }
159
- const snapshot = parsed.data;
160
- return RecordingOperationOutputSchema.parse({
161
- completedSegmentCount: snapshot.completedSegmentCount,
162
- effectiveConfig: snapshot.effectiveConfig,
163
- logicalTimeUs: snapshot.logicalTimeUs,
164
- permissions: snapshot.permissions,
165
- recordingId: snapshot.recordingId,
166
- state: snapshot.state,
167
- updatedAt: snapshot.updatedAt,
168
- });
169
- }
170
-
171
- export async function executeRecordingControl(
172
- context: OperationExecutionContext,
173
- action: "pause" | "resume" | "start" | "stop",
174
- options?: RecordingStartInput,
175
- ): Promise<RecordingOperationOutput> {
176
- throwIfAborted(context.abortSignal);
177
- const controller = requireRecordingController(context.application);
178
- await context.workflow?.beforePublication();
179
- const snapshot = options === undefined
180
- ? await controller.execute(action)
181
- : await controller.execute(action, options);
182
- return parseRecordingOperationOutput(snapshot);
183
- }
184
-
185
- export function summarizeRecordingControl(
186
- kind: Extract<OperationKind, `recording.${string}`>,
187
- output: RecordingOperationOutput,
188
- ): BoundedOperationSummary {
189
- return {
190
- fields: {
191
- completedSegmentCount: output.completedSegmentCount,
192
- logicalTimeUs: output.logicalTimeUs,
193
- recordingId: output.recordingId,
194
- state: output.state,
195
- updatedAt: output.updatedAt,
196
- },
197
- kind,
198
- };
199
- }
@@ -1,169 +0,0 @@
1
- import { z } from "zod";
2
-
3
- import {
4
- CapturePermissionsSchema,
5
- IsoTimestampSchema,
6
- MicrosecondsSchema,
7
- RecordingIdSchema,
8
- } from "../../../contracts";
9
- import type { OperationDefinition } from "../../operation";
10
- import {
11
- executeRecordingControl,
12
- MAX_RECORDING_OPERATION_DISPLAYS,
13
- RecordingOperationOutputSchema,
14
- type RecordingOperationOutput,
15
- RecordingStartInputSchema,
16
- type RecordingStartInput,
17
- recordingStartPolicy,
18
- summarizeRecordingControl,
19
- } from "./shared";
20
-
21
- export const RecordingStartOutputSchema = RecordingOperationOutputSchema;
22
- export type RecordingStartOutput = RecordingOperationOutput;
23
-
24
- const RecordingDisplaySelectionV1Schema = z.discriminatedUnion("kind", [
25
- z.strictObject({ kind: z.literal("all-current") }),
26
- z.strictObject({
27
- displayIds: z.array(z.string().min(1).max(256))
28
- .min(1)
29
- .max(MAX_RECORDING_OPERATION_DISPLAYS)
30
- .superRefine((displayIds, context) => {
31
- if (new Set(displayIds).size !== displayIds.length) {
32
- context.addIssue({
33
- code: "custom",
34
- message: "Explicit recording display IDs must be unique.",
35
- });
36
- }
37
- }),
38
- kind: z.literal("explicit"),
39
- }),
40
- ]);
41
-
42
- export const RecordingStartInputV1Schema = z.strictObject({
43
- displaySelection: RecordingDisplaySelectionV1Schema,
44
- microphone: z.boolean(),
45
- strictInputs: z.boolean(),
46
- systemAudio: z.boolean(),
47
- typedText: z.boolean(),
48
- webcam: z.boolean(),
49
- });
50
-
51
- const EffectiveRecordingConfigV1Schema = z.strictObject({
52
- ...RecordingStartInputV1Schema.shape,
53
- metadata: z.literal(true),
54
- });
55
-
56
- export const RecordingStartOutputV1Schema = z.strictObject({
57
- completedSegmentCount: z.number().int().safe().nonnegative(),
58
- effectiveConfig: EffectiveRecordingConfigV1Schema.nullable(),
59
- logicalTimeUs: MicrosecondsSchema,
60
- permissions: CapturePermissionsSchema.nullable(),
61
- recordingId: RecordingIdSchema.nullable(),
62
- state: z.enum(["idle", "recording", "paused"]),
63
- updatedAt: IsoTimestampSchema.max(64),
64
- });
65
-
66
- export type RecordingStartInputV1 = z.infer<
67
- typeof RecordingStartInputV1Schema
68
- >;
69
- export type RecordingStartOutputV1 = z.infer<
70
- typeof RecordingStartOutputV1Schema
71
- >;
72
-
73
- function upgradeRecordingStartInput(
74
- input: RecordingStartInputV1,
75
- ): RecordingStartInput {
76
- return RecordingStartInputSchema.parse({
77
- camera: { kind: input.webcam ? "default" : "disabled" },
78
- displays: input.displaySelection.kind === "all-current"
79
- ? { kind: "all" }
80
- : {
81
- displayIds: input.displaySelection.displayIds,
82
- kind: "selected",
83
- },
84
- microphone: { kind: input.microphone ? "default" : "disabled" },
85
- strictInputs: input.strictInputs,
86
- systemAudio: input.systemAudio,
87
- typedText: input.typedText,
88
- });
89
- }
90
-
91
- function downgradeRecordingStartOutput(
92
- output: RecordingStartOutput,
93
- ): RecordingStartOutputV1 {
94
- const effectiveConfig = output.effectiveConfig === null
95
- ? null
96
- : {
97
- displaySelection: output.effectiveConfig.displays.kind === "all"
98
- ? { kind: "all-current" as const }
99
- : {
100
- displayIds: output.effectiveConfig.displays.displayIds,
101
- kind: "explicit" as const,
102
- },
103
- metadata: true as const,
104
- microphone: output.effectiveConfig.microphone.kind !== "disabled",
105
- strictInputs: output.effectiveConfig.strictInputs,
106
- systemAudio: output.effectiveConfig.systemAudio,
107
- typedText: output.effectiveConfig.typedText,
108
- webcam: output.effectiveConfig.camera.kind !== "disabled",
109
- };
110
- return RecordingStartOutputV1Schema.parse({
111
- ...output,
112
- effectiveConfig,
113
- });
114
- }
115
-
116
- export const recordingStartOperationDefinitionV1: OperationDefinition<
117
- "recording.start",
118
- RecordingStartInputV1,
119
- RecordingStartOutputV1
120
- > = {
121
- inputSchema: RecordingStartInputV1Schema,
122
- inputSchemaId: "slopcamera.operation.recording.start.input/v1",
123
- kind: "recording.start",
124
- lifecycle: {
125
- kind: "live-control",
126
- execute: async (context, input) => downgradeRecordingStartOutput(
127
- await executeRecordingControl(
128
- context,
129
- "start",
130
- upgradeRecordingStartInput(input),
131
- ),
132
- ),
133
- },
134
- outputSchema: RecordingStartOutputV1Schema,
135
- outputSchemaId: "slopcamera.operation.recording.start.output/v1",
136
- policy: recordingStartPolicy,
137
- summarize: output => ({
138
- fields: {
139
- completedSegmentCount: output.completedSegmentCount,
140
- logicalTimeUs: output.logicalTimeUs,
141
- recordingId: output.recordingId,
142
- state: output.state,
143
- updatedAt: output.updatedAt,
144
- },
145
- kind: "recording.start",
146
- }),
147
- version: 1,
148
- };
149
-
150
- export const recordingStartOperationDefinition: OperationDefinition<
151
- "recording.start",
152
- RecordingStartInput,
153
- RecordingStartOutput
154
- > = {
155
- inputSchema: RecordingStartInputSchema,
156
- inputSchemaId: "slopcamera.operation.recording.start.input/v2",
157
- kind: "recording.start",
158
- lifecycle: {
159
- kind: "live-control",
160
- execute: async (context, input) => (
161
- await executeRecordingControl(context, "start", input)
162
- ),
163
- },
164
- outputSchema: RecordingStartOutputSchema,
165
- outputSchemaId: "slopcamera.operation.recording.start.output/v2",
166
- policy: recordingStartPolicy,
167
- summarize: output => summarizeRecordingControl("recording.start", output),
168
- version: 2,
169
- };
@@ -1,34 +0,0 @@
1
- import type { OperationDefinition } from "../../operation";
2
- import {
3
- EmptyRecordingOperationInputSchema,
4
- type EmptyRecordingOperationInput,
5
- executeRecordingControl,
6
- RecordingOperationOutputSchema,
7
- type RecordingOperationOutput,
8
- recordingTransitionPolicy,
9
- summarizeRecordingControl,
10
- } from "./shared";
11
-
12
- export const RecordingStopInputSchema = EmptyRecordingOperationInputSchema;
13
- export const RecordingStopOutputSchema = RecordingOperationOutputSchema;
14
- export type RecordingStopInput = EmptyRecordingOperationInput;
15
- export type RecordingStopOutput = RecordingOperationOutput;
16
-
17
- export const recordingStopOperationDefinition: OperationDefinition<
18
- "recording.stop",
19
- RecordingStopInput,
20
- RecordingStopOutput
21
- > = {
22
- inputSchema: RecordingStopInputSchema,
23
- inputSchemaId: "slopcamera.operation.recording.stop.input/v1",
24
- kind: "recording.stop",
25
- lifecycle: {
26
- kind: "live-control",
27
- execute: async context => await executeRecordingControl(context, "stop"),
28
- },
29
- outputSchema: RecordingStopOutputSchema,
30
- outputSchemaId: "slopcamera.operation.recording.stop.output/v1",
31
- policy: recordingTransitionPolicy,
32
- summarize: output => summarizeRecordingControl("recording.stop", output),
33
- version: 1,
34
- };