wicked-crew 0.16.11 → 0.16.13
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/README.md +28 -8
- package/dist/api/artifact-outline.d.ts +64 -0
- package/dist/api/artifact-outline.d.ts.map +1 -0
- package/dist/api/artifact-outline.js +254 -0
- package/dist/api/artifact-outline.js.map +1 -0
- package/dist/api/beneath.d.ts +76 -0
- package/dist/api/beneath.d.ts.map +1 -0
- package/dist/api/beneath.js +214 -0
- package/dist/api/beneath.js.map +1 -0
- package/dist/api/capture.d.ts +2 -2
- package/dist/api/chat-citations.d.ts +25 -1
- package/dist/api/chat-citations.d.ts.map +1 -1
- package/dist/api/chat-citations.js +186 -61
- package/dist/api/chat-citations.js.map +1 -1
- package/dist/api/chat-context.d.ts +236 -0
- package/dist/api/chat-context.d.ts.map +1 -0
- package/dist/api/chat-context.js +808 -0
- package/dist/api/chat-context.js.map +1 -0
- package/dist/api/chat-history.d.ts +20 -0
- package/dist/api/chat-history.d.ts.map +1 -1
- package/dist/api/chat-history.js +46 -1
- package/dist/api/chat-history.js.map +1 -1
- package/dist/api/chat-proposals.d.ts +534 -0
- package/dist/api/chat-proposals.d.ts.map +1 -0
- package/dist/api/chat-proposals.js +1562 -0
- package/dist/api/chat-proposals.js.map +1 -0
- package/dist/api/chat-scope.d.ts +41 -0
- package/dist/api/chat-scope.d.ts.map +1 -1
- package/dist/api/chat-scope.js +87 -15
- package/dist/api/chat-scope.js.map +1 -1
- package/dist/api/chat-transcripts.d.ts +27 -2
- package/dist/api/chat-transcripts.d.ts.map +1 -1
- package/dist/api/chat-transcripts.js +105 -4
- package/dist/api/chat-transcripts.js.map +1 -1
- package/dist/api/diagnostics.d.ts +15 -0
- package/dist/api/diagnostics.d.ts.map +1 -1
- package/dist/api/diagnostics.js +56 -0
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/api/elicitation-cache.d.ts +13 -0
- package/dist/api/elicitation-cache.d.ts.map +1 -1
- package/dist/api/elicitation-cache.js +12 -0
- package/dist/api/elicitation-cache.js.map +1 -1
- package/dist/api/eval-sample.d.ts +12 -12
- package/dist/api/frame-guard.d.ts +62 -0
- package/dist/api/frame-guard.d.ts.map +1 -0
- package/dist/api/frame-guard.js +97 -0
- package/dist/api/frame-guard.js.map +1 -0
- package/dist/api/governance-steering.d.ts +4 -4
- package/dist/api/multiscope.d.ts +3 -0
- package/dist/api/multiscope.d.ts.map +1 -1
- package/dist/api/multiscope.js +13 -0
- package/dist/api/multiscope.js.map +1 -1
- package/dist/api/needs.d.ts +6 -0
- package/dist/api/needs.d.ts.map +1 -1
- package/dist/api/needs.js +31 -4
- package/dist/api/needs.js.map +1 -1
- package/dist/api/product.d.ts.map +1 -1
- package/dist/api/product.js +13 -2
- package/dist/api/product.js.map +1 -1
- package/dist/api/project-aggregates.d.ts +6 -6
- package/dist/api/project-aggregates.d.ts.map +1 -1
- package/dist/api/project-aggregates.js +16 -24
- package/dist/api/project-aggregates.js.map +1 -1
- package/dist/api/requirements.d.ts +261 -6
- package/dist/api/requirements.d.ts.map +1 -1
- package/dist/api/requirements.js +344 -64
- package/dist/api/requirements.js.map +1 -1
- package/dist/api/routes.d.ts +156 -4
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +851 -78
- package/dist/api/routes.js.map +1 -1
- package/dist/api/run-brief.d.ts +78 -0
- package/dist/api/run-brief.d.ts.map +1 -0
- package/dist/api/run-brief.js +318 -0
- package/dist/api/run-brief.js.map +1 -0
- package/dist/api/run-files.d.ts.map +1 -1
- package/dist/api/run-files.js +5 -1
- package/dist/api/run-files.js.map +1 -1
- package/dist/api/run-timing-index.d.ts +27 -0
- package/dist/api/run-timing-index.d.ts.map +1 -1
- package/dist/api/run-timing-index.js +65 -0
- package/dist/api/run-timing-index.js.map +1 -1
- package/dist/api/seat-images.d.ts +102 -0
- package/dist/api/seat-images.d.ts.map +1 -0
- package/dist/api/seat-images.js +333 -0
- package/dist/api/seat-images.js.map +1 -0
- package/dist/api/server.d.ts +3 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +265 -2
- package/dist/api/server.js.map +1 -1
- package/dist/api/steering-landing.d.ts +48 -1
- package/dist/api/steering-landing.d.ts.map +1 -1
- package/dist/api/steering-landing.js +116 -42
- package/dist/api/steering-landing.js.map +1 -1
- package/dist/api/system-snapshot.d.ts +51 -2
- package/dist/api/system-snapshot.d.ts.map +1 -1
- package/dist/api/system-snapshot.js +151 -15
- package/dist/api/system-snapshot.js.map +1 -1
- package/dist/api/testing.d.ts +4 -4
- package/dist/api/testing.js +2 -2
- package/dist/api/testing.js.map +1 -1
- package/dist/apps/spec.d.ts +3009 -0
- package/dist/apps/spec.d.ts.map +1 -0
- package/dist/apps/spec.js +870 -0
- package/dist/apps/spec.js.map +1 -0
- package/dist/campaigns/routes.js +1 -1
- package/dist/campaigns/routes.js.map +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/adapter.d.ts +12 -0
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +36 -1
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/deliver-text.d.ts.map +1 -1
- package/dist/core/deliver-text.js +22 -10
- package/dist/core/deliver-text.js.map +1 -1
- package/dist/core/estate-mcp-client.d.ts +7 -1
- package/dist/core/estate-mcp-client.d.ts.map +1 -1
- package/dist/core/estate-mcp-client.js +10 -2
- package/dist/core/estate-mcp-client.js.map +1 -1
- package/dist/core/exec.d.ts +12 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +23 -0
- package/dist/core/exec.js.map +1 -1
- package/dist/core/reassign-refusal.d.ts.map +1 -1
- package/dist/core/reassign-refusal.js +23 -3
- package/dist/core/reassign-refusal.js.map +1 -1
- package/dist/core/repoPaths.d.ts +32 -7
- package/dist/core/repoPaths.d.ts.map +1 -1
- package/dist/core/repoPaths.js +56 -9
- package/dist/core/repoPaths.js.map +1 -1
- package/dist/core/requirements-graph-setting.d.ts +32 -0
- package/dist/core/requirements-graph-setting.d.ts.map +1 -0
- package/dist/core/requirements-graph-setting.js +84 -0
- package/dist/core/requirements-graph-setting.js.map +1 -0
- package/dist/core/run-boot-resume.d.ts +4 -1
- package/dist/core/run-boot-resume.d.ts.map +1 -1
- package/dist/core/run-boot-resume.js +6 -1
- package/dist/core/run-boot-resume.js.map +1 -1
- package/dist/core/run-identity.d.ts.map +1 -1
- package/dist/core/run-identity.js +6 -0
- package/dist/core/run-identity.js.map +1 -1
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/decisions/chat-recorder.d.ts +14 -3
- package/dist/decisions/chat-recorder.d.ts.map +1 -1
- package/dist/decisions/chat-recorder.js +54 -9
- package/dist/decisions/chat-recorder.js.map +1 -1
- package/dist/editors/csp.d.ts +24 -4
- package/dist/editors/csp.d.ts.map +1 -1
- package/dist/editors/csp.js +35 -8
- package/dist/editors/csp.js.map +1 -1
- package/dist/editors/registry.d.ts +46 -21
- package/dist/editors/registry.d.ts.map +1 -1
- package/dist/editors/registry.js +13 -2
- package/dist/editors/registry.js.map +1 -1
- package/dist/editors/routes.d.ts +4 -1
- package/dist/editors/routes.d.ts.map +1 -1
- package/dist/editors/routes.js +30 -3
- package/dist/editors/routes.js.map +1 -1
- package/dist/editors/visuals.d.ts +51 -0
- package/dist/editors/visuals.d.ts.map +1 -0
- package/dist/editors/visuals.js +164 -0
- package/dist/editors/visuals.js.map +1 -0
- package/dist/editors/webrtc-guard.d.ts +94 -0
- package/dist/editors/webrtc-guard.d.ts.map +1 -0
- package/dist/editors/webrtc-guard.js +506 -0
- package/dist/editors/webrtc-guard.js.map +1 -0
- package/dist/inspect/reading.d.ts +110 -0
- package/dist/inspect/reading.d.ts.map +1 -0
- package/dist/inspect/reading.js +325 -0
- package/dist/inspect/reading.js.map +1 -0
- package/dist/inspect/routes.d.ts +14 -0
- package/dist/inspect/routes.d.ts.map +1 -0
- package/dist/inspect/routes.js +44 -0
- package/dist/inspect/routes.js.map +1 -0
- package/dist/inspect/service.d.ts +161 -0
- package/dist/inspect/service.d.ts.map +1 -0
- package/dist/inspect/service.js +466 -0
- package/dist/inspect/service.js.map +1 -0
- package/dist/interactive/bridge-pool.d.ts +11 -2
- package/dist/interactive/bridge-pool.d.ts.map +1 -1
- package/dist/interactive/bridge-pool.js +10 -1
- package/dist/interactive/bridge-pool.js.map +1 -1
- package/dist/interactive/doc-binding.d.ts +156 -0
- package/dist/interactive/doc-binding.d.ts.map +1 -0
- package/dist/interactive/doc-binding.js +277 -0
- package/dist/interactive/doc-binding.js.map +1 -0
- package/dist/interactive/doc-delete-routes.d.ts +3 -0
- package/dist/interactive/doc-delete-routes.d.ts.map +1 -1
- package/dist/interactive/doc-delete-routes.js +4 -0
- package/dist/interactive/doc-delete-routes.js.map +1 -1
- package/dist/interactive/draft-events.d.ts +89 -3
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +441 -30
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/draft-skill.d.ts +7 -0
- package/dist/interactive/draft-skill.d.ts.map +1 -1
- package/dist/interactive/draft-skill.js +10 -3
- package/dist/interactive/draft-skill.js.map +1 -1
- package/dist/interactive/edit-events.d.ts +2 -0
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +11 -0
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/proposal-create.d.ts +143 -0
- package/dist/interactive/proposal-create.d.ts.map +1 -0
- package/dist/interactive/proposal-create.js +318 -0
- package/dist/interactive/proposal-create.js.map +1 -0
- package/dist/interactive/proxy-routes.d.ts +60 -3
- package/dist/interactive/proxy-routes.d.ts.map +1 -1
- package/dist/interactive/proxy-routes.js +217 -3
- package/dist/interactive/proxy-routes.js.map +1 -1
- package/dist/interactive/source-packet.d.ts +126 -0
- package/dist/interactive/source-packet.d.ts.map +1 -0
- package/dist/interactive/source-packet.js +482 -0
- package/dist/interactive/source-packet.js.map +1 -0
- package/dist/learnings/estate.d.ts +16 -0
- package/dist/learnings/estate.d.ts.map +1 -0
- package/dist/learnings/estate.js +68 -0
- package/dist/learnings/estate.js.map +1 -0
- package/dist/learnings/extract.d.ts +56 -0
- package/dist/learnings/extract.d.ts.map +1 -0
- package/dist/learnings/extract.js +252 -0
- package/dist/learnings/extract.js.map +1 -0
- package/dist/learnings/recall.d.ts +43 -0
- package/dist/learnings/recall.d.ts.map +1 -0
- package/dist/learnings/recall.js +104 -0
- package/dist/learnings/recall.js.map +1 -0
- package/dist/learnings/service.d.ts +183 -0
- package/dist/learnings/service.d.ts.map +1 -0
- package/dist/learnings/service.js +571 -0
- package/dist/learnings/service.js.map +1 -0
- package/dist/mcp/ask-server.d.ts.map +1 -1
- package/dist/mcp/ask-server.js +37 -4
- package/dist/mcp/ask-server.js.map +1 -1
- package/dist/mcp/broker.d.ts +12 -1
- package/dist/mcp/broker.d.ts.map +1 -1
- package/dist/mcp/broker.js +24 -5
- package/dist/mcp/broker.js.map +1 -1
- package/dist/mcp/invoke.d.ts +26 -2
- package/dist/mcp/invoke.d.ts.map +1 -1
- package/dist/mcp/invoke.js +51 -5
- package/dist/mcp/invoke.js.map +1 -1
- package/dist/persona/routes.d.ts +92 -0
- package/dist/persona/routes.d.ts.map +1 -0
- package/dist/persona/routes.js +69 -0
- package/dist/persona/routes.js.map +1 -0
- package/dist/persona/store.d.ts +104 -0
- package/dist/persona/store.d.ts.map +1 -0
- package/dist/persona/store.js +176 -0
- package/dist/persona/store.js.map +1 -0
- package/dist/persona/voice.d.ts +4 -0
- package/dist/persona/voice.d.ts.map +1 -0
- package/dist/persona/voice.js +58 -0
- package/dist/persona/voice.js.map +1 -0
- package/dist/projects/routes.d.ts +2 -2
- package/dist/setup/known.d.ts +56 -0
- package/dist/setup/known.d.ts.map +1 -0
- package/dist/setup/known.js +159 -0
- package/dist/setup/known.js.map +1 -0
- package/dist/setup/routes.d.ts +13 -0
- package/dist/setup/routes.d.ts.map +1 -0
- package/dist/setup/routes.js +20 -0
- package/dist/setup/routes.js.map +1 -0
- package/dist/standing-orders/history.d.ts +2 -0
- package/dist/standing-orders/history.d.ts.map +1 -1
- package/dist/standing-orders/history.js +1 -0
- package/dist/standing-orders/history.js.map +1 -1
- package/dist/studio/assets/WickedSans-Regular-fb698rcD.woff2 +0 -0
- package/dist/studio/assets/WickedSans-SemiBold-CD53n1AC.woff2 +0 -0
- package/dist/studio/assets/WickedScript-Regular-CY5juO6I.woff2 +0 -0
- package/dist/studio/assets/WickedSerif-Regular-mdPEjaVZ.woff2 +0 -0
- package/dist/studio/assets/index-BUZ_-Syk.css +32 -0
- package/dist/studio/assets/index-u4O_7N-b.js +986 -0
- package/dist/studio/editors/wicked-deck/editor.json +6 -1
- package/dist/studio/editors/wicked-deck/icon.svg +1 -0
- package/dist/studio/editors/wicked-deck/index.html +1 -1
- package/dist/studio/editors/wicked-doc/editor.json +6 -1
- package/dist/studio/editors/wicked-doc/icon.svg +1 -0
- package/dist/studio/editors/wicked-doc/index.html +1 -1
- package/dist/studio/editors/wicked-insights/editor.json +6 -1
- package/dist/studio/editors/wicked-insights/icon.svg +1 -0
- package/dist/studio/editors/wicked-insights/index.html +1 -1
- package/dist/studio/editors/wicked-page/editor.json +6 -1
- package/dist/studio/editors/wicked-page/icon.svg +1 -0
- package/dist/studio/editors/wicked-page/index.html +1 -1
- package/dist/studio/editors/wicked-video/editor.json +6 -1
- package/dist/studio/editors/wicked-video/icon.svg +1 -0
- package/dist/studio/editors/wicked-video/index.html +1 -1
- package/dist/studio/index.html +2 -2
- package/dist/studio/testid-inventory.json +5155 -2707
- package/dist/voice/dashboard.d.ts +376 -0
- package/dist/voice/dashboard.d.ts.map +1 -0
- package/dist/voice/dashboard.js +92 -0
- package/dist/voice/dashboard.js.map +1 -0
- package/dist/voice/inject-input.d.ts +51 -0
- package/dist/voice/inject-input.d.ts.map +1 -0
- package/dist/voice/inject-input.js +126 -0
- package/dist/voice/inject-input.js.map +1 -0
- package/dist/voice/routes.d.ts +41 -0
- package/dist/voice/routes.d.ts.map +1 -0
- package/dist/voice/routes.js +116 -0
- package/dist/voice/routes.js.map +1 -0
- package/dist/voice/service.d.ts +177 -0
- package/dist/voice/service.d.ts.map +1 -0
- package/dist/voice/service.js +400 -0
- package/dist/voice/service.js.map +1 -0
- package/dist/workflow-catalog/build.d.ts +35 -0
- package/dist/workflow-catalog/build.d.ts.map +1 -0
- package/dist/workflow-catalog/build.js +229 -0
- package/dist/workflow-catalog/build.js.map +1 -0
- package/dist/workflow-catalog/catalog-data.d.ts +36 -0
- package/dist/workflow-catalog/catalog-data.d.ts.map +1 -0
- package/dist/workflow-catalog/catalog-data.js +430 -0
- package/dist/workflow-catalog/catalog-data.js.map +1 -0
- package/dist/working-doc/event-lines.d.ts +76 -0
- package/dist/working-doc/event-lines.d.ts.map +1 -0
- package/dist/working-doc/event-lines.js +247 -0
- package/dist/working-doc/event-lines.js.map +1 -0
- package/dist/working-doc/routes.d.ts +1 -1
- package/dist/working-doc/routes.d.ts.map +1 -1
- package/dist/working-doc/routes.js +2 -1
- package/dist/working-doc/routes.js.map +1 -1
- package/dist/working-doc/sections.d.ts +3 -1
- package/dist/working-doc/sections.d.ts.map +1 -1
- package/dist/working-doc/sections.js +4 -2
- package/dist/working-doc/sections.js.map +1 -1
- package/dist/working-doc/service.d.ts +66 -1
- package/dist/working-doc/service.d.ts.map +1 -1
- package/dist/working-doc/service.js +298 -22
- package/dist/working-doc/service.js.map +1 -1
- package/dist/working-doc/store.d.ts +8 -2
- package/dist/working-doc/store.d.ts.map +1 -1
- package/dist/working-doc/store.js.map +1 -1
- package/endpoint-manifest.json +205 -2
- package/package.json +5 -4
- package/workflows/distill-learnings.json +27 -0
- package/workflows/inspect-unit.json +27 -0
- package/dist/studio/assets/index-B-f_VEL2.css +0 -32
- package/dist/studio/assets/index-DhkxIK-0.js +0 -845
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VOICE MODE, PHASE 1 (program DES-VOICE §3): speech to text on THIS machine.
|
|
3
|
+
*
|
|
4
|
+
* Studio records the person's speech in the browser, encodes it as a 16 kHz mono WAV, and posts it to
|
|
5
|
+
* `POST /voice/transcribe`. Crew hands the bytes to whisper.cpp's CLI on stdin (`-f -`) and answers with the
|
|
6
|
+
* text. The audio is held in memory for that one call and dropped: it is never written to disk, never kept with
|
|
7
|
+
* a run, never sent off the machine.
|
|
8
|
+
*
|
|
9
|
+
* Two local pieces, each said plainly in `GET /voice/status`:
|
|
10
|
+
* - the whisper.cpp CLI (`whisper-cli`): found on PATH, or named by `WICKED_CREW_WHISPER_BIN`. Crew does not
|
|
11
|
+
* install it; the status names the install command for this platform.
|
|
12
|
+
* - one model file (`ggml-base.en.bin`, 142 MiB): downloaded ONLY when the person consents
|
|
13
|
+
* (`POST /voice/model {consent: true}`), checked against its published SHA-1, kept in the voice cache dir
|
|
14
|
+
* (`WICKED_CREW_VOICE_DIR`, default the OS cache dir). Not under the state home: the worker fence classifies
|
|
15
|
+
* every top-level entry there, and a model directory is not one of them.
|
|
16
|
+
*
|
|
17
|
+
* One transcription runs at a time and one may wait; a third is refused with 429 `voice_busy` (a streaming
|
|
18
|
+
* partial just skips that beat).
|
|
19
|
+
*/
|
|
20
|
+
import { spawn as nodeSpawn, spawnSync } from 'node:child_process';
|
|
21
|
+
import { createHash } from 'node:crypto';
|
|
22
|
+
import { createWriteStream, existsSync, mkdirSync, renameSync, rmSync, statSync } from 'node:fs';
|
|
23
|
+
import { Readable, Transform } from 'node:stream';
|
|
24
|
+
import { pipeline } from 'node:stream/promises';
|
|
25
|
+
import { childEnvWithBootEstateDb } from '../core/governance-store.js';
|
|
26
|
+
import { homedir, platform as osPlatform } from 'node:os';
|
|
27
|
+
import { delimiter, join } from 'node:path';
|
|
28
|
+
/** The one model phase 1 ships with. Published by whisper.cpp (models/README.md: 142 MiB, this SHA-1). */
|
|
29
|
+
export const VOICE_MODEL = Object.freeze({
|
|
30
|
+
name: 'base.en',
|
|
31
|
+
file: 'ggml-base.en.bin',
|
|
32
|
+
url: 'https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin',
|
|
33
|
+
sha1: '137c40403d78fd54d454da0f9bd998f78703390c',
|
|
34
|
+
/** What the consent says before anything is fetched. */
|
|
35
|
+
approxBytes: 142 * 1024 * 1024,
|
|
36
|
+
source: 'huggingface.co/ggerganov/whisper.cpp',
|
|
37
|
+
});
|
|
38
|
+
/** A WAV over this is refused (about 4 minutes of 16 kHz mono 16-bit speech). */
|
|
39
|
+
export const VOICE_MAX_AUDIO_BYTES = 8 * 1024 * 1024;
|
|
40
|
+
/** One transcription that runs longer than this is killed and answered 504. */
|
|
41
|
+
export const TRANSCRIBE_TIMEOUT_MS = 60_000;
|
|
42
|
+
/** Threads whisper.cpp may use (the host runs seats and checks too). */
|
|
43
|
+
export const TRANSCRIBE_THREADS = 4;
|
|
44
|
+
export class VoiceError extends Error {
|
|
45
|
+
status;
|
|
46
|
+
code;
|
|
47
|
+
constructor(status, code, message) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.status = status;
|
|
50
|
+
this.code = code;
|
|
51
|
+
}
|
|
52
|
+
body() {
|
|
53
|
+
return { error: this.message, code: this.code };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** The OS cache dir for crew's voice files (`WICKED_CREW_VOICE_DIR` wins). */
|
|
57
|
+
export function defaultVoiceDir(env = process.env, plat = osPlatform(), home = homedir()) {
|
|
58
|
+
const set = env['WICKED_CREW_VOICE_DIR'];
|
|
59
|
+
if (set !== undefined && set.trim() !== '')
|
|
60
|
+
return set;
|
|
61
|
+
if (plat === 'darwin')
|
|
62
|
+
return join(home, 'Library', 'Caches', 'wicked-crew', 'voice');
|
|
63
|
+
if (plat === 'win32')
|
|
64
|
+
return join(env['LOCALAPPDATA'] ?? join(home, 'AppData', 'Local'), 'wicked-crew', 'voice');
|
|
65
|
+
return join(env['XDG_CACHE_HOME'] ?? join(home, '.cache'), 'wicked-crew', 'voice');
|
|
66
|
+
}
|
|
67
|
+
/** How to install whisper.cpp here, in one line. */
|
|
68
|
+
export function installHint(plat) {
|
|
69
|
+
if (plat === 'darwin')
|
|
70
|
+
return 'Install whisper.cpp with Homebrew: brew install whisper-cpp (it provides whisper-cli).';
|
|
71
|
+
if (plat === 'win32')
|
|
72
|
+
return 'Download whisper.cpp for Windows from github.com/ggml-org/whisper.cpp/releases, then set WICKED_CREW_WHISPER_BIN to whisper-cli.exe.';
|
|
73
|
+
return 'Install whisper.cpp from your package manager or build it from github.com/ggml-org/whisper.cpp, so whisper-cli is on PATH (or set WICKED_CREW_WHISPER_BIN).';
|
|
74
|
+
}
|
|
75
|
+
/** The oldest engine voice runs: it must report `--version` (whisper.cpp 1.8.0 does not), and be at least this. */
|
|
76
|
+
export const MIN_WHISPER = [1, 8, 0];
|
|
77
|
+
/** `whisper.cpp version: 1.9.5` → `1.9.5`; anything else → null. */
|
|
78
|
+
export function parseWhisperVersion(out) {
|
|
79
|
+
const m = out === null ? null : /version:?\s*v?(\d+)\.(\d+)\.(\d+)/i.exec(out);
|
|
80
|
+
return m === null ? null : `${m[1]}.${m[2]}.${m[3]}`;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Is this engine safe to hand audio on stdin? From whisper.cpp 1.8.0 a stdin run (`-f -`) writes its `-otxt` output
|
|
84
|
+
* to stdout; 1.7.x writes it to a FILE named `-.txt` in the working directory, which would keep a transcript on disk.
|
|
85
|
+
* 1.8.0 itself cannot say its version, so voice asks for an engine that reports one (`--version`) at 1.8.0 or later,
|
|
86
|
+
* and refuses the rest before any audio is sent.
|
|
87
|
+
*/
|
|
88
|
+
export function whisperSupported(version) {
|
|
89
|
+
if (version === null)
|
|
90
|
+
return false;
|
|
91
|
+
const v = version.split('.').map(Number);
|
|
92
|
+
for (let i = 0; i < 3; i++) {
|
|
93
|
+
if ((v[i] ?? 0) !== MIN_WHISPER[i])
|
|
94
|
+
return (v[i] ?? 0) > MIN_WHISPER[i];
|
|
95
|
+
}
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
function runVersion(bin) {
|
|
99
|
+
try {
|
|
100
|
+
const r = spawnSync(bin, ['--version'], { encoding: 'utf8', timeout: 5000, windowsHide: true, env: childEnvWithBootEstateDb(process.env) });
|
|
101
|
+
return r.status === 0 ? `${r.stdout ?? ''}${r.stderr ?? ''}` : null;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** How to upgrade whisper.cpp here, in one line. */
|
|
108
|
+
export function upgradeHint(plat) {
|
|
109
|
+
if (plat === 'darwin')
|
|
110
|
+
return 'Upgrade it: brew upgrade whisper-cpp.';
|
|
111
|
+
return 'Install a current whisper.cpp from github.com/ggml-org/whisper.cpp (or set WICKED_CREW_WHISPER_BIN to one).';
|
|
112
|
+
}
|
|
113
|
+
/** Find the whisper.cpp CLI: `WICKED_CREW_WHISPER_BIN`, else `whisper-cli` (or the older `whisper-cpp`) on PATH. */
|
|
114
|
+
export function findWhisper(env, plat, exists) {
|
|
115
|
+
const set = env['WICKED_CREW_WHISPER_BIN'];
|
|
116
|
+
if (set !== undefined && set.trim() !== '')
|
|
117
|
+
return exists(set) ? set : null;
|
|
118
|
+
const names = plat === 'win32' ? ['whisper-cli.exe', 'whisper-cpp.exe'] : ['whisper-cli', 'whisper-cpp'];
|
|
119
|
+
for (const dir of (env['PATH'] ?? '').split(delimiter)) {
|
|
120
|
+
if (dir === '')
|
|
121
|
+
continue;
|
|
122
|
+
for (const n of names) {
|
|
123
|
+
const p = join(dir, n);
|
|
124
|
+
if (exists(p))
|
|
125
|
+
return p;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Is it the WAV studio sends: RIFF/WAVE with a PCM `fmt ` chunk (16 kHz, mono, 16-bit) and a non-empty `data`
|
|
132
|
+
* chunk, every chunk inside the buffer? Anything else is refused before the engine is started.
|
|
133
|
+
*/
|
|
134
|
+
export function wavProblem(buf) {
|
|
135
|
+
if (buf.length < 12 || buf.toString('ascii', 0, 4) !== 'RIFF' || buf.toString('ascii', 8, 12) !== 'WAVE')
|
|
136
|
+
return 'not a RIFF/WAVE file';
|
|
137
|
+
let at = 12;
|
|
138
|
+
let fmt = null;
|
|
139
|
+
let data = 0;
|
|
140
|
+
while (at + 8 <= buf.length) {
|
|
141
|
+
const id = buf.toString('ascii', at, at + 4);
|
|
142
|
+
const size = buf.readUInt32LE(at + 4);
|
|
143
|
+
const body = at + 8;
|
|
144
|
+
if (body + size > buf.length)
|
|
145
|
+
return `the ${id.trim() || 'unnamed'} chunk runs past the end of the file`;
|
|
146
|
+
if (id === 'fmt ') {
|
|
147
|
+
if (size < 16)
|
|
148
|
+
return 'the fmt chunk is too short';
|
|
149
|
+
fmt = { format: buf.readUInt16LE(body), channels: buf.readUInt16LE(body + 2), rate: buf.readUInt32LE(body + 4), bits: buf.readUInt16LE(body + 14) };
|
|
150
|
+
}
|
|
151
|
+
else if (id === 'data') {
|
|
152
|
+
data += size;
|
|
153
|
+
}
|
|
154
|
+
at = body + size + (size % 2);
|
|
155
|
+
}
|
|
156
|
+
if (fmt === null)
|
|
157
|
+
return 'no fmt chunk';
|
|
158
|
+
if (fmt.format !== 1 || fmt.channels !== 1 || fmt.rate !== 16_000 || fmt.bits !== 16) {
|
|
159
|
+
return `expected 16 kHz mono 16-bit PCM, got format ${fmt.format}, ${fmt.channels} channel(s), ${fmt.rate} Hz, ${fmt.bits}-bit`;
|
|
160
|
+
}
|
|
161
|
+
if (data === 0)
|
|
162
|
+
return 'no audio in the data chunk';
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
/** Is it a WAV this route takes? */
|
|
166
|
+
export function isWav(buf) {
|
|
167
|
+
return wavProblem(buf) === null;
|
|
168
|
+
}
|
|
169
|
+
/** whisper.cpp's plain-text output as one line: no timestamps, no non-speech tags ([BLANK_AUDIO], (music)). */
|
|
170
|
+
export function cleanTranscript(raw) {
|
|
171
|
+
return raw
|
|
172
|
+
.replace(/\[[^\]]*\]/g, ' ')
|
|
173
|
+
.replace(/\((?:[a-z ]*(?:music|noise|silence|applause|laughter|inaudible|blank)[a-z ]*)\)/gi, ' ')
|
|
174
|
+
.replace(/\s+/g, ' ')
|
|
175
|
+
.trim();
|
|
176
|
+
}
|
|
177
|
+
export class VoiceService {
|
|
178
|
+
deps;
|
|
179
|
+
env;
|
|
180
|
+
plat;
|
|
181
|
+
exists;
|
|
182
|
+
fetchImpl;
|
|
183
|
+
spawnImpl;
|
|
184
|
+
timeoutMs;
|
|
185
|
+
model;
|
|
186
|
+
versionOf;
|
|
187
|
+
/** `--version` per engine path, read once. */
|
|
188
|
+
versions = new Map();
|
|
189
|
+
download = null;
|
|
190
|
+
/** The download in flight: removal aborts it and bumps the generation, so it can never land afterwards. */
|
|
191
|
+
inflight = null;
|
|
192
|
+
gen = 0;
|
|
193
|
+
/** One transcription holds the slot; one waits for it (the slot is handed over, never re-contested). */
|
|
194
|
+
busy = false;
|
|
195
|
+
waiting = [];
|
|
196
|
+
constructor(deps) {
|
|
197
|
+
this.deps = deps;
|
|
198
|
+
this.env = deps.env ?? process.env;
|
|
199
|
+
this.plat = deps.platform ?? osPlatform();
|
|
200
|
+
this.exists = deps.exists ?? existsSync;
|
|
201
|
+
this.fetchImpl = deps.fetch ?? fetch;
|
|
202
|
+
this.spawnImpl = deps.spawn ?? nodeSpawn;
|
|
203
|
+
this.timeoutMs = deps.timeoutMs ?? TRANSCRIBE_TIMEOUT_MS;
|
|
204
|
+
this.model = deps.model ?? VOICE_MODEL;
|
|
205
|
+
this.versionOf = deps.versionOf ?? runVersion;
|
|
206
|
+
}
|
|
207
|
+
modelPath() {
|
|
208
|
+
return join(this.deps.dir, this.model.file);
|
|
209
|
+
}
|
|
210
|
+
bin() {
|
|
211
|
+
if (this.deps.bin !== undefined && this.deps.bin !== null)
|
|
212
|
+
return this.exists(this.deps.bin) ? this.deps.bin : null;
|
|
213
|
+
return findWhisper(this.env, this.plat, this.exists);
|
|
214
|
+
}
|
|
215
|
+
engineVersion(bin) {
|
|
216
|
+
if (!this.versions.has(bin))
|
|
217
|
+
this.versions.set(bin, parseWhisperVersion(this.versionOf(bin)));
|
|
218
|
+
return this.versions.get(bin) ?? null;
|
|
219
|
+
}
|
|
220
|
+
tooOld(bin) {
|
|
221
|
+
return `whisper.cpp at ${bin} is too old for voice: it needs 1.8.0 or later (one that answers --version), so a transcription never writes a file. ${upgradeHint(this.plat)}`;
|
|
222
|
+
}
|
|
223
|
+
modelBytes() {
|
|
224
|
+
const p = this.modelPath();
|
|
225
|
+
if (!this.exists(p))
|
|
226
|
+
return null;
|
|
227
|
+
try {
|
|
228
|
+
return statSync(p).size;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
status() {
|
|
235
|
+
const path = this.bin();
|
|
236
|
+
const bytes = this.modelBytes();
|
|
237
|
+
const version = path !== null ? this.engineVersion(path) : null;
|
|
238
|
+
const supported = path !== null && whisperSupported(version);
|
|
239
|
+
return {
|
|
240
|
+
local: true,
|
|
241
|
+
ready: supported && bytes !== null,
|
|
242
|
+
engine: {
|
|
243
|
+
name: 'whisper.cpp', found: path !== null, path, version, supported,
|
|
244
|
+
install: path === null ? installHint(this.plat) : supported ? null : this.tooOld(path),
|
|
245
|
+
},
|
|
246
|
+
model: {
|
|
247
|
+
name: this.model.name, present: bytes !== null, bytes, approxBytes: this.model.approxBytes,
|
|
248
|
+
source: this.model.source, download: this.download === null ? null : { ...this.download },
|
|
249
|
+
},
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Fetch the model, once, with the person's consent. Returns at once; the download runs on and
|
|
254
|
+
* `status().model.download` reports it. The file lands under a `.part` name, is checked against the published
|
|
255
|
+
* SHA-1, and only then takes its real name; a failed or mismatched download leaves nothing behind.
|
|
256
|
+
*/
|
|
257
|
+
startDownload() {
|
|
258
|
+
if (this.modelBytes() !== null)
|
|
259
|
+
return { started: false };
|
|
260
|
+
if (this.inflight !== null)
|
|
261
|
+
throw new VoiceError(409, 'voice_download_running', 'The speech model is already downloading.');
|
|
262
|
+
const gen = ++this.gen;
|
|
263
|
+
const abort = new AbortController();
|
|
264
|
+
this.inflight = { gen, abort };
|
|
265
|
+
this.download = { state: 'running', receivedBytes: 0, totalBytes: null, startedAt: new Date().toISOString(), error: null };
|
|
266
|
+
void this.fetchModel(gen, abort.signal).then(() => { if (this.gen === gen)
|
|
267
|
+
this.download = null; }, (e) => {
|
|
268
|
+
if (this.gen !== gen)
|
|
269
|
+
return; // removed meanwhile: nothing to report
|
|
270
|
+
this.download = {
|
|
271
|
+
...(this.download ?? { receivedBytes: 0, totalBytes: null, startedAt: new Date().toISOString() }),
|
|
272
|
+
state: 'failed', error: e instanceof Error ? e.message : String(e),
|
|
273
|
+
};
|
|
274
|
+
}).finally(() => { if (this.inflight?.gen === gen)
|
|
275
|
+
this.inflight = null; });
|
|
276
|
+
return { started: true };
|
|
277
|
+
}
|
|
278
|
+
async fetchModel(gen, signal) {
|
|
279
|
+
mkdirSync(this.deps.dir, { recursive: true });
|
|
280
|
+
const part = `${this.modelPath()}.part`;
|
|
281
|
+
rmSync(part, { force: true });
|
|
282
|
+
try {
|
|
283
|
+
const res = await this.fetchImpl(this.model.url, { redirect: 'follow', signal });
|
|
284
|
+
if (!res.ok || res.body === null)
|
|
285
|
+
throw new Error(`the model download answered ${res.status}`);
|
|
286
|
+
const len = Number(res.headers.get('content-length'));
|
|
287
|
+
if (this.download !== null && Number.isFinite(len) && len > 0)
|
|
288
|
+
this.download.totalBytes = len;
|
|
289
|
+
const hash = createHash('sha1');
|
|
290
|
+
const count = new Transform({
|
|
291
|
+
transform: (chunk, _enc, cb) => {
|
|
292
|
+
hash.update(chunk);
|
|
293
|
+
if (this.gen === gen && this.download !== null)
|
|
294
|
+
this.download.receivedBytes += chunk.length;
|
|
295
|
+
cb(null, chunk);
|
|
296
|
+
},
|
|
297
|
+
});
|
|
298
|
+
// One pipeline: a read, write or disk error (EACCES, ENOSPC) rejects here, never an unhandled 'error'.
|
|
299
|
+
await pipeline(Readable.fromWeb(res.body), count, createWriteStream(part), { signal });
|
|
300
|
+
const got = hash.digest('hex');
|
|
301
|
+
if (got !== this.model.sha1)
|
|
302
|
+
throw new Error(`the downloaded model did not match its published checksum (got sha1 ${got}); nothing was kept`);
|
|
303
|
+
if (this.gen !== gen || signal.aborted)
|
|
304
|
+
throw new Error('the download was cancelled');
|
|
305
|
+
renameSync(part, this.modelPath());
|
|
306
|
+
}
|
|
307
|
+
catch (e) {
|
|
308
|
+
rmSync(part, { force: true });
|
|
309
|
+
throw e;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/** Remove the model (the person's "Remove the speech model"). A download in flight is cancelled first. */
|
|
313
|
+
removeModel() {
|
|
314
|
+
this.gen += 1;
|
|
315
|
+
this.inflight?.abort.abort();
|
|
316
|
+
this.inflight = null;
|
|
317
|
+
this.download = null;
|
|
318
|
+
const p = this.modelPath();
|
|
319
|
+
const had = this.exists(p);
|
|
320
|
+
rmSync(p, { force: true });
|
|
321
|
+
rmSync(`${p}.part`, { force: true });
|
|
322
|
+
return { removed: had };
|
|
323
|
+
}
|
|
324
|
+
/** Transcribe one WAV held in memory. The bytes go to whisper.cpp on stdin and are dropped after. */
|
|
325
|
+
async transcribe(audio) {
|
|
326
|
+
if (audio.length > VOICE_MAX_AUDIO_BYTES) {
|
|
327
|
+
throw new VoiceError(413, 'voice_audio_too_large', `The recording is over ${Math.round(VOICE_MAX_AUDIO_BYTES / 1048576)} MiB; speak in shorter turns.`);
|
|
328
|
+
}
|
|
329
|
+
const problem = wavProblem(audio);
|
|
330
|
+
if (problem !== null)
|
|
331
|
+
throw new VoiceError(400, 'voice_audio_invalid', `Send the recording as a 16 kHz mono 16-bit WAV (${problem}).`);
|
|
332
|
+
this.ready();
|
|
333
|
+
if (this.busy && this.waiting.length >= 1)
|
|
334
|
+
throw new VoiceError(429, 'voice_busy', 'Still transcribing the last thing you said.');
|
|
335
|
+
if (this.busy)
|
|
336
|
+
await new Promise((r) => this.waiting.push(r)); // the slot is handed to us
|
|
337
|
+
this.busy = true;
|
|
338
|
+
const started = Date.now();
|
|
339
|
+
try {
|
|
340
|
+
// Checked again with the slot held: the model may have been removed while this one waited.
|
|
341
|
+
const bin = this.ready();
|
|
342
|
+
const raw = await this.run(bin, audio);
|
|
343
|
+
return { text: cleanTranscript(raw), ms: Date.now() - started, model: this.model.name };
|
|
344
|
+
}
|
|
345
|
+
finally {
|
|
346
|
+
const next = this.waiting.shift();
|
|
347
|
+
if (next !== undefined)
|
|
348
|
+
next(); // hand the slot over: `busy` stays true, nobody can slip in between
|
|
349
|
+
else
|
|
350
|
+
this.busy = false;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
/** The engine and the model, or the refusal that names the missing one. */
|
|
354
|
+
ready() {
|
|
355
|
+
const bin = this.bin();
|
|
356
|
+
if (bin === null)
|
|
357
|
+
throw new VoiceError(409, 'voice_engine_missing', `whisper.cpp is not installed on this machine. ${installHint(this.plat)}`);
|
|
358
|
+
if (!whisperSupported(this.engineVersion(bin)))
|
|
359
|
+
throw new VoiceError(409, 'voice_engine_outdated', this.tooOld(bin));
|
|
360
|
+
if (this.modelBytes() === null)
|
|
361
|
+
throw new VoiceError(409, 'voice_model_missing', 'The speech model is not on this machine yet; download it first (it needs your consent).');
|
|
362
|
+
return bin;
|
|
363
|
+
}
|
|
364
|
+
run(bin, audio) {
|
|
365
|
+
// `-f -` reads the WAV from stdin; with stdin as the input, whisper-cli (1.8.0 and later, checked in `ready()`)
|
|
366
|
+
// writes its output "file" to stdout, and `-otxt` is the format it writes there (without it a stdin run prints
|
|
367
|
+
// nothing: 1.9.5, seen live). No file is written. An older engine would write `-.txt`, so it never gets here.
|
|
368
|
+
const args = ['-m', this.modelPath(), '-f', '-', '-otxt', '-nt', '-np', '-l', 'en', '-t', String(TRANSCRIBE_THREADS)];
|
|
369
|
+
return new Promise((resolve, reject) => {
|
|
370
|
+
const child = this.spawnImpl(bin, args, { stdio: ['pipe', 'pipe', 'pipe'], windowsHide: true, env: childEnvWithBootEstateDb(this.env) });
|
|
371
|
+
let out = '';
|
|
372
|
+
let err = '';
|
|
373
|
+
let settled = false;
|
|
374
|
+
const done = (f) => { if (!settled) {
|
|
375
|
+
settled = true;
|
|
376
|
+
clearTimeout(timer);
|
|
377
|
+
f();
|
|
378
|
+
} };
|
|
379
|
+
const timer = setTimeout(() => {
|
|
380
|
+
child.kill('SIGKILL');
|
|
381
|
+
done(() => reject(new VoiceError(504, 'voice_timeout', `Transcription took longer than ${Math.round(this.timeoutMs / 1000)} s and was stopped.`)));
|
|
382
|
+
}, this.timeoutMs);
|
|
383
|
+
child.stdout?.setEncoding('utf8');
|
|
384
|
+
child.stderr?.setEncoding('utf8');
|
|
385
|
+
child.stdout?.on('data', (d) => { out += d; });
|
|
386
|
+
child.stderr?.on('data', (d) => { if (err.length < 4000)
|
|
387
|
+
err += d; });
|
|
388
|
+
child.on('error', (e) => done(() => reject(new VoiceError(500, 'voice_failed', `whisper.cpp could not start: ${e.message}`))));
|
|
389
|
+
child.on('close', (code) => done(() => {
|
|
390
|
+
if (code === 0)
|
|
391
|
+
resolve(out);
|
|
392
|
+
else
|
|
393
|
+
reject(new VoiceError(500, 'voice_failed', `whisper.cpp exited ${code}: ${err.trim().split('\n').slice(-2).join(' ') || 'no message'}`));
|
|
394
|
+
}));
|
|
395
|
+
child.stdin?.on('error', () => undefined);
|
|
396
|
+
child.stdin?.end(audio);
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/voice/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `GET /workflows/catalog` (lane wf-catalog): join the catalog seeds with what the engine serves and
|
|
3
|
+
* with the requesting operator's runs. Pure: the route gathers the inputs, this shapes the answer.
|
|
4
|
+
*
|
|
5
|
+
* Usage is derived, never stored: a run counts for an entry when its resolved workflow
|
|
6
|
+
* (`run_identity.name`) is the entry's, its `run.launched` trail entry names THIS principal (the system
|
|
7
|
+
* of record for who launched a run), and it is not a retry. Runs the daemon or a schedule launched
|
|
8
|
+
* (actor kind `system`) are not the operator's use.
|
|
9
|
+
*/
|
|
10
|
+
import type { Preset, WorkflowCatalogResponse, WorkflowDef } from '../core/types.js';
|
|
11
|
+
/** One run as the catalog reads it. Times are unix SECONDS (the served run's `created_at`/`ended_at`). */
|
|
12
|
+
export interface CatalogRun {
|
|
13
|
+
id: string;
|
|
14
|
+
/** The resolved workflow/preset name (`run_identity.name`), null for a user plan or free text. */
|
|
15
|
+
workflow: string | null;
|
|
16
|
+
projectId: string | null;
|
|
17
|
+
status: string;
|
|
18
|
+
createdAt?: number | undefined;
|
|
19
|
+
endedAt?: number | undefined;
|
|
20
|
+
retryOf?: string | undefined;
|
|
21
|
+
/** The `run.launched` entry's principal (`Actor.id`), absent when the daemon holds no launch record. */
|
|
22
|
+
principal?: string | undefined;
|
|
23
|
+
}
|
|
24
|
+
export interface CatalogInputs {
|
|
25
|
+
/** `GET /workflows`'s served defs (built-ins carry their C2 descriptor). */
|
|
26
|
+
defs: readonly WorkflowDef[];
|
|
27
|
+
/** `GET /presets` for the scope (built-in rows and the operator's saved ones). */
|
|
28
|
+
presets: readonly Preset[];
|
|
29
|
+
runs: readonly CatalogRun[];
|
|
30
|
+
actorId: string;
|
|
31
|
+
projectId: string | null;
|
|
32
|
+
}
|
|
33
|
+
export declare const TOP_MAX = 6;
|
|
34
|
+
export declare function buildWorkflowCatalog(input: CatalogInputs): WorkflowCatalogResponse;
|
|
35
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/workflow-catalog/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EACV,MAAM,EAGN,uBAAuB,EAEvB,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAK1B,0GAA0G;AAC1G,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,kGAAkG;IAClG,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,wGAAwG;IACxG,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IAC7B,kFAAkF;IAClF,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,IAAI,EAAE,SAAS,UAAU,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,eAAO,MAAM,OAAO,IAAI,CAAC;AA6CzB,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,aAAa,GAAG,uBAAuB,CA0LlF"}
|