creative-pipeline-mcp 0.2.14-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +18 -0
- package/NOTICE +9 -0
- package/README.md +205 -0
- package/SECURITY.md +19 -0
- package/docs/API_TOOLS.md +74 -0
- package/docs/ARCHITECTURE.md +28 -0
- package/docs/ARTIFACT_SCHEMA.md +43 -0
- package/docs/BLENDER_BRIDGE_STATUS_SCHEMA.md +42 -0
- package/docs/CEP_STATUS_SCHEMA.md +35 -0
- package/docs/COMPATIBILITY_MATRIX.md +36 -0
- package/docs/GPL_ADAPTERS.md +19 -0
- package/docs/INSTALL_BLENDER.md +39 -0
- package/docs/INSTALL_DASHBOARD.md +47 -0
- package/docs/INSTALL_PREMIERE.md +62 -0
- package/docs/LICENSING.md +19 -0
- package/docs/PREMIERE_E2E_TEST.md +55 -0
- package/docs/RELEASE_PROCESS.md +74 -0
- package/docs/ROADMAP.md +53 -0
- package/docs/SAFETY.md +21 -0
- package/docs/SECURITY.md +14 -0
- package/docs/TROUBLESHOOTING.md +46 -0
- package/docs/examples/adapter_check_report.sample.json +60 -0
- package/docs/examples/delivery_qc_report.sample.json +30 -0
- package/examples/blender-bridge-queue.mjs +42 -0
- package/examples/blender-e2e.mjs +53 -0
- package/examples/brief.txt +2 -0
- package/examples/minimal.gltf +23 -0
- package/examples/premiere-project-delivery.mjs +72 -0
- package/examples/premiere-qc-e2e.mjs +77 -0
- package/examples/sample-tool-call.json +2 -0
- package/package.json +77 -0
- package/packages/blender-gpl-adapters/LICENSE +6 -0
- package/packages/blender-gpl-adapters/dist/index.d.ts +10 -0
- package/packages/blender-gpl-adapters/dist/index.js +28 -0
- package/packages/blender-gpl-adapters/dist/index.js.map +1 -0
- package/packages/blender-gpl-adapters/package.json +15 -0
- package/packages/blender-gpl-adapters/src/index.ts +38 -0
- package/packages/blender-pro-mcp/dist/adapters/blenderBridge.d.ts +34 -0
- package/packages/blender-pro-mcp/dist/adapters/blenderBridge.js +79 -0
- package/packages/blender-pro-mcp/dist/adapters/blenderBridge.js.map +1 -0
- package/packages/blender-pro-mcp/dist/adapters/cli.d.ts +11 -0
- package/packages/blender-pro-mcp/dist/adapters/cli.js +121 -0
- package/packages/blender-pro-mcp/dist/adapters/cli.js.map +1 -0
- package/packages/blender-pro-mcp/dist/adapters/gltf.d.ts +21 -0
- package/packages/blender-pro-mcp/dist/adapters/gltf.js +99 -0
- package/packages/blender-pro-mcp/dist/adapters/gltf.js.map +1 -0
- package/packages/blender-pro-mcp/dist/adapters/preview.d.ts +1 -0
- package/packages/blender-pro-mcp/dist/adapters/preview.js +11 -0
- package/packages/blender-pro-mcp/dist/adapters/preview.js.map +1 -0
- package/packages/blender-pro-mcp/dist/index.d.ts +3 -0
- package/packages/blender-pro-mcp/dist/index.js +4 -0
- package/packages/blender-pro-mcp/dist/index.js.map +1 -0
- package/packages/blender-pro-mcp/dist/server.d.ts +1 -0
- package/packages/blender-pro-mcp/dist/server.js +4 -0
- package/packages/blender-pro-mcp/dist/server.js.map +1 -0
- package/packages/blender-pro-mcp/dist/tools/assetTools.d.ts +2 -0
- package/packages/blender-pro-mcp/dist/tools/assetTools.js +646 -0
- package/packages/blender-pro-mcp/dist/tools/assetTools.js.map +1 -0
- package/packages/blender-pro-mcp/dist/tools/shared.d.ts +3 -0
- package/packages/blender-pro-mcp/dist/tools/shared.js +94 -0
- package/packages/blender-pro-mcp/dist/tools/shared.js.map +1 -0
- package/packages/blender-pro-mcp/package.json +18 -0
- package/packages/blender-pro-mcp/src/adapters/blenderBridge.ts +106 -0
- package/packages/blender-pro-mcp/src/adapters/cli.ts +130 -0
- package/packages/blender-pro-mcp/src/adapters/gltf.ts +132 -0
- package/packages/blender-pro-mcp/src/adapters/preview.ts +11 -0
- package/packages/blender-pro-mcp/src/index.ts +3 -0
- package/packages/blender-pro-mcp/src/server.ts +4 -0
- package/packages/blender-pro-mcp/src/tools/assetTools.ts +663 -0
- package/packages/blender-pro-mcp/src/tools/shared.ts +99 -0
- package/packages/core/dist/approvalPolicy.d.ts +13 -0
- package/packages/core/dist/approvalPolicy.js +48 -0
- package/packages/core/dist/approvalPolicy.js.map +1 -0
- package/packages/core/dist/artifactStore.d.ts +14 -0
- package/packages/core/dist/artifactStore.js +77 -0
- package/packages/core/dist/artifactStore.js.map +1 -0
- package/packages/core/dist/coreTools.d.ts +2 -0
- package/packages/core/dist/coreTools.js +34 -0
- package/packages/core/dist/coreTools.js.map +1 -0
- package/packages/core/dist/index.d.ts +11 -0
- package/packages/core/dist/index.js +12 -0
- package/packages/core/dist/index.js.map +1 -0
- package/packages/core/dist/jobQueue.d.ts +11 -0
- package/packages/core/dist/jobQueue.js +14 -0
- package/packages/core/dist/jobQueue.js.map +1 -0
- package/packages/core/dist/licenseManifest.d.ts +7 -0
- package/packages/core/dist/licenseManifest.js +42 -0
- package/packages/core/dist/licenseManifest.js.map +1 -0
- package/packages/core/dist/mcpServer.d.ts +19 -0
- package/packages/core/dist/mcpServer.js +120 -0
- package/packages/core/dist/mcpServer.js.map +1 -0
- package/packages/core/dist/qcReport.d.ts +21 -0
- package/packages/core/dist/qcReport.js +25 -0
- package/packages/core/dist/qcReport.js.map +1 -0
- package/packages/core/dist/router.d.ts +7 -0
- package/packages/core/dist/router.js +55 -0
- package/packages/core/dist/router.js.map +1 -0
- package/packages/core/dist/schemaValidator.d.ts +8 -0
- package/packages/core/dist/schemaValidator.js +21 -0
- package/packages/core/dist/schemaValidator.js.map +1 -0
- package/packages/core/dist/server.d.ts +1 -0
- package/packages/core/dist/server.js +3 -0
- package/packages/core/dist/server.js.map +1 -0
- package/packages/core/dist/toolRegistry.d.ts +8 -0
- package/packages/core/dist/toolRegistry.js +25 -0
- package/packages/core/dist/toolRegistry.js.map +1 -0
- package/packages/core/dist/types.d.ts +58 -0
- package/packages/core/dist/types.js +2 -0
- package/packages/core/dist/types.js.map +1 -0
- package/packages/core/package.json +18 -0
- package/packages/core/src/approvalPolicy.ts +51 -0
- package/packages/core/src/artifactStore.ts +93 -0
- package/packages/core/src/coreTools.ts +36 -0
- package/packages/core/src/index.ts +11 -0
- package/packages/core/src/jobQueue.ts +22 -0
- package/packages/core/src/licenseManifest.ts +47 -0
- package/packages/core/src/mcpServer.ts +131 -0
- package/packages/core/src/qcReport.ts +53 -0
- package/packages/core/src/router.ts +61 -0
- package/packages/core/src/schemaValidator.ts +26 -0
- package/packages/core/src/server.ts +3 -0
- package/packages/core/src/toolRegistry.ts +31 -0
- package/packages/core/src/types.ts +78 -0
- package/packages/dashboard/dist/server.d.ts +1 -0
- package/packages/dashboard/dist/server.js +486 -0
- package/packages/dashboard/dist/server.js.map +1 -0
- package/packages/dashboard/package.json +18 -0
- package/packages/dashboard/src/server.ts +539 -0
- package/packages/director-agent/dist/index.d.ts +1 -0
- package/packages/director-agent/dist/index.js +2 -0
- package/packages/director-agent/dist/index.js.map +1 -0
- package/packages/director-agent/dist/server.d.ts +1 -0
- package/packages/director-agent/dist/server.js +4 -0
- package/packages/director-agent/dist/server.js.map +1 -0
- package/packages/director-agent/dist/tools.d.ts +2 -0
- package/packages/director-agent/dist/tools.js +115 -0
- package/packages/director-agent/dist/tools.js.map +1 -0
- package/packages/director-agent/package.json +18 -0
- package/packages/director-agent/src/index.ts +2 -0
- package/packages/director-agent/src/server.ts +4 -0
- package/packages/director-agent/src/tools.ts +116 -0
- package/packages/premiere-cep-panel/CSXS/manifest.xml +43 -0
- package/packages/premiere-cep-panel/README.md +21 -0
- package/packages/premiere-cep-panel/index.html +26 -0
- package/packages/premiere-cep-panel/js/main.js +107 -0
- package/packages/premiere-cep-panel/jsx/host.jsx +208 -0
- package/packages/premiere-cep-panel/package.json +8 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffmpegQc.d.ts +21 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffmpegQc.js +78 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffmpegQc.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffprobe.d.ts +25 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffprobe.js +73 -0
- package/packages/premiere-pro-mcp/dist/adapters/ffprobe.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/adapters/optionalTools.d.ts +11 -0
- package/packages/premiere-pro-mcp/dist/adapters/optionalTools.js +82 -0
- package/packages/premiere-pro-mcp/dist/adapters/optionalTools.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/adapters/premiereCep.d.ts +34 -0
- package/packages/premiere-pro-mcp/dist/adapters/premiereCep.js +79 -0
- package/packages/premiere-pro-mcp/dist/adapters/premiereCep.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/adapters/srt.d.ts +8 -0
- package/packages/premiere-pro-mcp/dist/adapters/srt.js +37 -0
- package/packages/premiere-pro-mcp/dist/adapters/srt.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/index.d.ts +2 -0
- package/packages/premiere-pro-mcp/dist/index.js +3 -0
- package/packages/premiere-pro-mcp/dist/index.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/server.d.ts +1 -0
- package/packages/premiere-pro-mcp/dist/server.js +4 -0
- package/packages/premiere-pro-mcp/dist/server.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/tools/mediaTools.d.ts +2 -0
- package/packages/premiere-pro-mcp/dist/tools/mediaTools.js +935 -0
- package/packages/premiere-pro-mcp/dist/tools/mediaTools.js.map +1 -0
- package/packages/premiere-pro-mcp/dist/tools/shared.d.ts +3 -0
- package/packages/premiere-pro-mcp/dist/tools/shared.js +136 -0
- package/packages/premiere-pro-mcp/dist/tools/shared.js.map +1 -0
- package/packages/premiere-pro-mcp/package.json +18 -0
- package/packages/premiere-pro-mcp/src/adapters/ffmpegQc.ts +106 -0
- package/packages/premiere-pro-mcp/src/adapters/ffprobe.ts +105 -0
- package/packages/premiere-pro-mcp/src/adapters/optionalTools.ts +94 -0
- package/packages/premiere-pro-mcp/src/adapters/premiereCep.ts +106 -0
- package/packages/premiere-pro-mcp/src/adapters/srt.ts +46 -0
- package/packages/premiere-pro-mcp/src/index.ts +3 -0
- package/packages/premiere-pro-mcp/src/server.ts +4 -0
- package/packages/premiere-pro-mcp/src/tools/mediaTools.ts +961 -0
- package/packages/premiere-pro-mcp/src/tools/shared.ts +147 -0
- package/packages/premiere-windows-adapter/dist/index.d.ts +12 -0
- package/packages/premiere-windows-adapter/dist/index.js +17 -0
- package/packages/premiere-windows-adapter/dist/index.js.map +1 -0
- package/packages/premiere-windows-adapter/package.json +12 -0
- package/packages/premiere-windows-adapter/src/index.ts +25 -0
- package/scripts/blender-bridge-worker.mjs +311 -0
- package/scripts/check-adapters.mjs +57 -0
- package/scripts/install-premiere-cep.mjs +43 -0
- package/scripts/package-premiere-cep.mjs +236 -0
- package/scripts/release-assets.mjs +146 -0
- package/scripts/simulate-premiere-cep.mjs +194 -0
- package/third_party_licenses/README.md +19 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Premiere Install Notes
|
|
2
|
+
|
|
3
|
+
The alpha QC path can inspect media with `ffprobe` and FFmpeg without Premiere installed.
|
|
4
|
+
|
|
5
|
+
For timeline mutation and exports, install Premiere Pro and use a trusted CEP/ExtendScript bridge. `premiere.build_timeline_from_otio` queues a file-based IPC command under `CREATIVE_MCP_PREMIERE_IPC_DIR` for a CEP panel to consume. A minimal panel scaffold is included in `packages/premiere-cep-panel`. Raw ExtendScript execution should remain approval-gated. The Windows adapter package contains guardrails inspired by Windows CEP/WebSocket bridges, but it is not an installer.
|
|
6
|
+
|
|
7
|
+
Recommended external tools:
|
|
8
|
+
|
|
9
|
+
- FFmpeg / ffprobe
|
|
10
|
+
- MediaInfo
|
|
11
|
+
- OpenTimelineIO
|
|
12
|
+
- WhisperX, faster-whisper, or whisper.cpp
|
|
13
|
+
- PySceneDetect
|
|
14
|
+
- Auto-Editor
|
|
15
|
+
- pyloudnorm
|
|
16
|
+
- FFmpeg with `libvmaf` for reference-based quality scoring
|
|
17
|
+
|
|
18
|
+
MCP tools:
|
|
19
|
+
|
|
20
|
+
- `premiere.transcribe_media`: uses WhisperX when available, otherwise writes an adapter manifest
|
|
21
|
+
- `premiere.detect_scenes`: uses PySceneDetect when available, otherwise writes an adapter manifest
|
|
22
|
+
- `premiere.measure_loudness`: uses pyloudnorm when available, otherwise writes an adapter manifest
|
|
23
|
+
- `premiere.measure_vmaf`: uses FFmpeg `libvmaf` when available, otherwise writes an adapter report
|
|
24
|
+
- `premiere.build_timeline_from_otio`: writes a CEP queue command for the panel scaffold
|
|
25
|
+
- `premiere.build_project_delivery`: writes a project-specific template, OTIO timeline, brand package, export plan, and queues CEP commands
|
|
26
|
+
- `premiere.export_video`: writes an export plan and queues `export_sequence`
|
|
27
|
+
- `premiere.apply_brand_package`: writes a brand package manifest and queues `apply_brand_package`
|
|
28
|
+
- `premiere.read_cep_status`: reads status JSON written by the CEP panel scaffold
|
|
29
|
+
- `premiere.await_cep_status`: polls for a matching CEP status by command id or command type
|
|
30
|
+
- `premiere.finalize_export_qc`: resolves an export status and runs delivery QC after the exported file exists
|
|
31
|
+
|
|
32
|
+
Generated sample:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run build
|
|
36
|
+
node examples/premiere-qc-e2e.mjs
|
|
37
|
+
node examples/premiere-project-delivery.mjs
|
|
38
|
+
npm run simulate:premiere-cep -- --queue artifacts/examples/premiere-project-delivery/cep_queue --status artifacts/examples/premiere-project-delivery/cep_status
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
For a real Premiere project walkthrough, see `docs/PREMIERE_E2E_TEST.md`.
|
|
42
|
+
For CEP status records, see `docs/CEP_STATUS_SCHEMA.md`.
|
|
43
|
+
|
|
44
|
+
CEP simulator:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm run simulate:premiere-cep -- --queue artifacts/premiere/cep_queue --status artifacts/premiere/cep_status
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The simulator loads `packages/premiere-cep-panel/jsx/host.jsx` into a Node VM with a fake Premiere app, dispatches queued commands through the same host functions, writes normalized status JSON, and archives processed command files. It is not a replacement for a real Premiere run, but it verifies host-side command parsing, OTIO clip collection, sequence creation, brand package status, export status, and queue/status file behavior before live testing.
|
|
51
|
+
|
|
52
|
+
CEP packaging:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm run package:premiere-cep -- --verify
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This writes an unsigned package and checksums under `dist/premiere-cep`. To produce a signed ZXP, install Adobe `ZXPSignCmd` and provide a project signing certificate:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
ZXPSIGNCMD_BIN=/path/to/ZXPSignCmd CEP_SIGN_CERT=/path/to/cert.p12 CEP_SIGN_PASSWORD=secret npm run package:premiere-cep -- --sign
|
|
62
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Licensing
|
|
2
|
+
|
|
3
|
+
Core packages are Apache-2.0.
|
|
4
|
+
|
|
5
|
+
GPL tools are not imported into the Apache-2.0 packages. They are represented as optional external adapter manifests and should be installed, run, and distributed according to their own licenses.
|
|
6
|
+
|
|
7
|
+
## Included Policy
|
|
8
|
+
|
|
9
|
+
- `creative-mcp-core`: Apache-2.0
|
|
10
|
+
- `blender-pro-mcp`: Apache-2.0
|
|
11
|
+
- `premiere-pro-mcp`: Apache-2.0
|
|
12
|
+
- `premiere-windows-adapter`: Apache-2.0
|
|
13
|
+
- `dashboard`: Apache-2.0
|
|
14
|
+
- `blender-gpl-adapters`: GPL-3.0-or-later package boundary
|
|
15
|
+
|
|
16
|
+
## Excluded
|
|
17
|
+
|
|
18
|
+
3D-Agent is excluded. Do not copy its product, UI, workflow, model, branding, or proprietary implementation into this repository.
|
|
19
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Premiere E2E Test
|
|
2
|
+
|
|
3
|
+
This guide verifies the alpha CEP bridge with a real Premiere project.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
1. Install the CEP panel from `packages/premiere-cep-panel`.
|
|
8
|
+
2. Enable CEP debug mode for your Adobe/Premiere version.
|
|
9
|
+
3. Open a new Premiere project.
|
|
10
|
+
4. Set the panel queue directory to:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
artifacts/premiere/cep_queue
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Run
|
|
17
|
+
|
|
18
|
+
Build the package and create a generated MP4 sample:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm run build
|
|
22
|
+
node examples/premiere-qc-e2e.mjs
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then run the CEP panel poll action in Premiere.
|
|
26
|
+
|
|
27
|
+
Expected result:
|
|
28
|
+
|
|
29
|
+
- media is imported once
|
|
30
|
+
- an active or new sequence receives the clip
|
|
31
|
+
- the clip is inserted at the OTIO timeline position
|
|
32
|
+
- a status JSON file is written under `artifacts/premiere/cep_status`
|
|
33
|
+
|
|
34
|
+
Read the status:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
CREATIVE_MCP_PERMISSION=project_write npm run start:premiere
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Call `premiere.read_cep_status` or `premiere.await_cep_status` from the MCP client.
|
|
41
|
+
|
|
42
|
+
## Export Queue
|
|
43
|
+
|
|
44
|
+
`premiere.export_video` writes an `export_sequence` command with:
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"outputPath": "artifacts/premiere/exports/final.mp4",
|
|
49
|
+
"presetPath": ""
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The CEP host script attempts `app.encoder.encodeSequence`. If Adobe Media Encoder is unavailable, it records an accepted status instead of claiming a completed export.
|
|
54
|
+
|
|
55
|
+
After the CEP panel writes an `export_sequence` status, call `premiere.finalize_export_qc` with the `commandId`. The tool resolves `details.outputPath` from the status file, checks that the exported file exists, and writes an export delivery QC report. If the file is still missing, it writes a pending artifact instead of reporting a false pass.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Release Process
|
|
2
|
+
|
|
3
|
+
## Local Gates
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm test
|
|
7
|
+
npm run check:adapters -- --json
|
|
8
|
+
node examples/blender-e2e.mjs
|
|
9
|
+
node examples/premiere-qc-e2e.mjs
|
|
10
|
+
node examples/premiere-project-delivery.mjs
|
|
11
|
+
npm run simulate:premiere-cep -- --queue artifacts/examples/premiere-project-delivery/cep_queue --status artifacts/examples/premiere-project-delivery/cep_status
|
|
12
|
+
npm run package:premiere-cep -- --verify
|
|
13
|
+
npm pack --dry-run
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Assets
|
|
17
|
+
|
|
18
|
+
Generate release assets:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm run release:assets
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This writes:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
dist/release/
|
|
28
|
+
creative-pipeline-mcp-<version>.tgz
|
|
29
|
+
creative-pipeline-mcp-example-artifacts-<version>.zip
|
|
30
|
+
checksums.txt
|
|
31
|
+
dist/premiere-cep/
|
|
32
|
+
creative-pipeline-mcp-premiere-cep-panel-<version>.zip
|
|
33
|
+
premiere-cep-checksums.txt
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Upload:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
gh release upload v<version> dist/release/* --clobber
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## npm Publish Readiness
|
|
43
|
+
|
|
44
|
+
Check name and package metadata:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm view creative-pipeline-mcp version
|
|
48
|
+
npm pack --dry-run
|
|
49
|
+
npm publish --dry-run --provenance
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Local publishing requires an authenticated npm session:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm publish --provenance --access public
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
GitHub Actions publishing uses npm trusted publishing. Configure npmjs.com with:
|
|
59
|
+
|
|
60
|
+
```text
|
|
61
|
+
Owner: taiyuhiga
|
|
62
|
+
Repository: creative-pipeline-mcp
|
|
63
|
+
Workflow: npm-publish.yml
|
|
64
|
+
Environment: leave empty unless a GitHub environment is added
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Then set the repository variable `NPM_TRUSTED_PUBLISHING_ENABLED=true`. The workflow publishes from release tags only after tests, adapter checks, Premiere project-delivery example, CEP package verification, npm pack dry-run, and package-version/tag matching pass.
|
|
68
|
+
|
|
69
|
+
## Semver
|
|
70
|
+
|
|
71
|
+
- `0.2.x-alpha`: scaffold, safety, docs, adapter gates
|
|
72
|
+
- `0.3.x-alpha`: real Blender/Premiere E2E
|
|
73
|
+
- `0.4.x-beta`: installers, stable docs, schema tightening
|
|
74
|
+
- `1.0.0`: stable tool schemas and artifact schemas
|
package/docs/ROADMAP.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
## Completed In This Alpha
|
|
4
|
+
|
|
5
|
+
- Phase 0 design and licensing posture
|
|
6
|
+
- Phase 1 core registry/router/artifact/QC/approval infrastructure
|
|
7
|
+
- Phase 2 QC-first MVP
|
|
8
|
+
- Phase 3 Blender Pro MCP MVP surface with QC/export fallbacks
|
|
9
|
+
- Phase 4 Premiere Pro MCP MVP surface with ingest/index/rough-cut/caption/audio/export/QC plans
|
|
10
|
+
- Phase 5 macro tool surface
|
|
11
|
+
- Phase 6 optional GPL adapter package boundary
|
|
12
|
+
- Phase 9 safety policy
|
|
13
|
+
- Phase 10 dashboard
|
|
14
|
+
- Phase 11 public repository files
|
|
15
|
+
- Phase 15 v2.0+ manifests for USD/MaterialX/engine profiles, brand packages, social variants, multilingual subtitles, thumbnails, podcast repurposing, Director Agent handoff, production report, and multi-agent review
|
|
16
|
+
- server-side JSON Schema validation
|
|
17
|
+
- artifact path traversal hardening
|
|
18
|
+
- workspace input allowlist
|
|
19
|
+
- symlink realpath escape rejection by default
|
|
20
|
+
- pending approval artifact queue
|
|
21
|
+
- Dashboard localhost bind and token-protected API
|
|
22
|
+
- adapter availability JSON report
|
|
23
|
+
- headless Blender, glTF optimizer, FFmpeg QC, thumbnail, and Premiere CEP queue adapters
|
|
24
|
+
- Blender bridge queue/status adapter surface
|
|
25
|
+
- Blender bridge worker process for queue draining, status writing, processed-command archival, and headless Blender script execution
|
|
26
|
+
- Blender QC coverage for normals, primary UVs, material count, and texture slots
|
|
27
|
+
- Blender optimization size metrics and safe generated Blender script artifacts
|
|
28
|
+
- template-based Blender basic repair for scale, normals, triangulation, and GLB export
|
|
29
|
+
- Blender GLB e2e sample
|
|
30
|
+
- optional WhisperX, PySceneDetect, and pyloudnorm adapter tools
|
|
31
|
+
- optional FFmpeg libvmaf adapter tool
|
|
32
|
+
- Dashboard approval queue UI, artifact previews, and job history
|
|
33
|
+
- Premiere CEP panel MVP for OTIO media import, duplicate import avoidance, sequence creation attempts, timeline-positioned clip insertion attempts, export command handling, brand package command handling, and standardized status JSON
|
|
34
|
+
- Dashboard approval-to-rerun flow for approved elevated tool requests
|
|
35
|
+
- Premiere CEP status reader
|
|
36
|
+
- Premiere CEP status polling and export delivery QC finalization
|
|
37
|
+
- generated-MP4 Premiere QC/CEP queue e2e sample
|
|
38
|
+
- Premiere project-specific delivery builder for template, OTIO timeline, brand package, export plan, and CEP command queue generation
|
|
39
|
+
- Premiere CEP host simulator for queue draining, host.jsx dispatch, status writing, processed-command archival, and project-delivery preflight validation
|
|
40
|
+
- split CI jobs for Node.js 20/22/24 unit tests, package dry-run, adapter check, optional Blender e2e, and Premiere QC e2e
|
|
41
|
+
- dashboard and Premiere real-project e2e docs
|
|
42
|
+
- release asset generation script and npm publish readiness docs
|
|
43
|
+
- npm trusted-publishing workflow with OIDC, release tag/package version guard, and publish gates
|
|
44
|
+
- CEP status, artifact schema, and troubleshooting docs
|
|
45
|
+
- strict public top-level tool schemas with enum and length guards
|
|
46
|
+
- API tool list and compatibility matrix docs
|
|
47
|
+
- Premiere CEP development install/uninstall script
|
|
48
|
+
- Premiere CEP unsigned package generation, manifest validation, checksum output, ZIP verification, and optional ZXP signing hook
|
|
49
|
+
- Premiere CEP queue watcher UI for selected/all pending commands
|
|
50
|
+
|
|
51
|
+
## External Adapter Work
|
|
52
|
+
|
|
53
|
+
- project certificate-backed signed Premiere CEP installer and live Premiere runtime validation
|
package/docs/SAFETY.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Safety
|
|
2
|
+
|
|
3
|
+
Permission levels:
|
|
4
|
+
|
|
5
|
+
- `read_only`: inspect, index, QC
|
|
6
|
+
- `safe_write`: new files, reports, manifests, copies
|
|
7
|
+
- `project_write`: edits to current project or export plans
|
|
8
|
+
- `destructive`: delete, overwrite, final delivery export, publish
|
|
9
|
+
- `admin`: shell, plugin install, system settings
|
|
10
|
+
|
|
11
|
+
Set the level with `CREATIVE_MCP_PERMISSION`. Default is `safe_write`.
|
|
12
|
+
If a tool requires more permission than the current level, the router writes an approval request under `artifacts/approvals/pending/` instead of running the tool.
|
|
13
|
+
Approval requests include the action, risk, requested input, artifact root, workspace roots, an expiry timestamp, and a one-time approval token for auditability.
|
|
14
|
+
The dashboard exposes those pending approval records, can move them to resolved approval records with an approve/reject decision, and reruns approved tool calls only with the risk level that was approved.
|
|
15
|
+
|
|
16
|
+
Set readable input roots with `CREATIVE_MCP_WORKSPACE_ROOTS`. Multiple roots use the platform path delimiter (`:` on macOS/Linux, `;` on Windows). By default only the current working directory is readable.
|
|
17
|
+
Symlinks resolving outside those roots are rejected by default. Set `CREATIVE_MCP_ALLOW_SYMLINKS=true` only for trusted workspaces.
|
|
18
|
+
|
|
19
|
+
The dashboard is local-only. It binds to `127.0.0.1`, requires `CREATIVE_MCP_DASHBOARD_TOKEN`, and can rerun approved elevated tool calls. Do not expose it outside the local machine.
|
|
20
|
+
|
|
21
|
+
Always test against copies of production files.
|
package/docs/SECURITY.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
See [../SECURITY.md](../SECURITY.md).
|
|
4
|
+
|
|
5
|
+
Key controls:
|
|
6
|
+
|
|
7
|
+
- small macro tool surface
|
|
8
|
+
- approval policy
|
|
9
|
+
- server-side JSON Schema validation
|
|
10
|
+
- workspace input allowlists
|
|
11
|
+
- approval request artifacts for elevated tools
|
|
12
|
+
- artifact logs
|
|
13
|
+
- external adapter separation
|
|
14
|
+
- raw script blocking in the Windows CEP helper
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
## Adapter Check
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm run check:adapters -- --json
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Missing adapters are allowed unless the workflow explicitly depends on them.
|
|
10
|
+
|
|
11
|
+
If `ffmpeg-libvmaf` is missing, install an FFmpeg build that includes the `libvmaf` filter. `premiere.measure_vmaf` still writes an adapter report when the filter is unavailable.
|
|
12
|
+
|
|
13
|
+
## Dashboard
|
|
14
|
+
|
|
15
|
+
If the dashboard refuses API requests, confirm the token:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
CREATIVE_MCP_DASHBOARD_TOKEN=change-me npm run start:dashboard
|
|
19
|
+
curl -H "x-creative-mcp-dashboard-token: change-me" http://127.0.0.1:4173/api/reports
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The dashboard only accepts localhost host headers.
|
|
23
|
+
|
|
24
|
+
## Workspace Paths
|
|
25
|
+
|
|
26
|
+
If an input path is rejected:
|
|
27
|
+
|
|
28
|
+
- confirm it is under `CREATIVE_MCP_WORKSPACE_ROOTS`
|
|
29
|
+
- avoid symlinks to files outside the workspace
|
|
30
|
+
- set `CREATIVE_MCP_ALLOW_SYMLINKS=true` only for trusted workspaces
|
|
31
|
+
|
|
32
|
+
## Premiere CEP
|
|
33
|
+
|
|
34
|
+
If a command remains pending:
|
|
35
|
+
|
|
36
|
+
- confirm the panel queue directory points to `artifacts/premiere/cep_queue`
|
|
37
|
+
- click refresh queue in the CEP panel
|
|
38
|
+
- run selected or all pending commands
|
|
39
|
+
- inspect `artifacts/premiere/cep_status`
|
|
40
|
+
|
|
41
|
+
## Release Assets
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run release:assets
|
|
45
|
+
gh release upload v<version> dist/release/* --clobber
|
|
46
|
+
```
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"generatedAt": "2026-01-01T00:00:00.000Z",
|
|
3
|
+
"summary": {
|
|
4
|
+
"available": 3,
|
|
5
|
+
"total": 9
|
|
6
|
+
},
|
|
7
|
+
"adapters": {
|
|
8
|
+
"ffprobe": {
|
|
9
|
+
"available": true,
|
|
10
|
+
"command": "ffprobe",
|
|
11
|
+
"status": 0
|
|
12
|
+
},
|
|
13
|
+
"ffmpeg": {
|
|
14
|
+
"available": true,
|
|
15
|
+
"command": "ffmpeg",
|
|
16
|
+
"status": 0
|
|
17
|
+
},
|
|
18
|
+
"ffmpeg-libvmaf": {
|
|
19
|
+
"available": false,
|
|
20
|
+
"command": "ffmpeg",
|
|
21
|
+
"status": 0,
|
|
22
|
+
"requiredOutput": "libvmaf"
|
|
23
|
+
},
|
|
24
|
+
"blender": {
|
|
25
|
+
"available": false,
|
|
26
|
+
"command": "blender",
|
|
27
|
+
"status": null,
|
|
28
|
+
"stderr": ""
|
|
29
|
+
},
|
|
30
|
+
"gltf-transform": {
|
|
31
|
+
"available": true,
|
|
32
|
+
"command": "gltf-transform",
|
|
33
|
+
"status": 0
|
|
34
|
+
},
|
|
35
|
+
"gltfpack": {
|
|
36
|
+
"available": false,
|
|
37
|
+
"command": "gltfpack",
|
|
38
|
+
"status": null,
|
|
39
|
+
"stderr": ""
|
|
40
|
+
},
|
|
41
|
+
"whisperx": {
|
|
42
|
+
"available": false,
|
|
43
|
+
"command": "whisperx",
|
|
44
|
+
"status": null,
|
|
45
|
+
"stderr": ""
|
|
46
|
+
},
|
|
47
|
+
"scenedetect": {
|
|
48
|
+
"available": false,
|
|
49
|
+
"command": "scenedetect",
|
|
50
|
+
"status": null,
|
|
51
|
+
"stderr": ""
|
|
52
|
+
},
|
|
53
|
+
"pyloudnorm+soundfile": {
|
|
54
|
+
"available": false,
|
|
55
|
+
"command": "python3",
|
|
56
|
+
"status": 1,
|
|
57
|
+
"stderr": "ModuleNotFoundError: No module named 'pyloudnorm'"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "media",
|
|
3
|
+
"target": "examples/source.mp4",
|
|
4
|
+
"summary": {
|
|
5
|
+
"status": "pass",
|
|
6
|
+
"pass": 8,
|
|
7
|
+
"warn": 0,
|
|
8
|
+
"fail": 0
|
|
9
|
+
},
|
|
10
|
+
"checks": [
|
|
11
|
+
{
|
|
12
|
+
"id": "probe.ffprobe_available",
|
|
13
|
+
"status": "pass",
|
|
14
|
+
"message": "ffprobe metadata captured",
|
|
15
|
+
"value": true
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "delivery.duration",
|
|
19
|
+
"status": "pass",
|
|
20
|
+
"message": "1s; max 2s",
|
|
21
|
+
"value": 1
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "video.vmaf",
|
|
25
|
+
"status": "not_applicable",
|
|
26
|
+
"message": "No reference media supplied for VMAF",
|
|
27
|
+
"value": null
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const queueDir = resolve(root, "artifacts", "examples", "blender-bridge", "queue");
|
|
7
|
+
const statusDir = resolve(root, "artifacts", "examples", "blender-bridge", "status");
|
|
8
|
+
mkdirSync(queueDir, { recursive: true });
|
|
9
|
+
mkdirSync(statusDir, { recursive: true });
|
|
10
|
+
|
|
11
|
+
callTool("blender.create_asset", { prompt: "low-poly bridge sample" }, {
|
|
12
|
+
CREATIVE_MCP_BLENDER_IPC_DIR: queueDir,
|
|
13
|
+
CREATIVE_MCP_BLENDER_STATUS_DIR: statusDir
|
|
14
|
+
});
|
|
15
|
+
callTool("blender.read_bridge_status", {}, {
|
|
16
|
+
CREATIVE_MCP_BLENDER_IPC_DIR: queueDir,
|
|
17
|
+
CREATIVE_MCP_BLENDER_STATUS_DIR: statusDir
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function callTool(name, args, extraEnv = {}) {
|
|
21
|
+
const request = JSON.stringify({
|
|
22
|
+
jsonrpc: "2.0",
|
|
23
|
+
id: 1,
|
|
24
|
+
method: "tools/call",
|
|
25
|
+
params: { name, arguments: args }
|
|
26
|
+
});
|
|
27
|
+
const result = spawnSync("node", ["packages/blender-pro-mcp/dist/server.js"], {
|
|
28
|
+
cwd: root,
|
|
29
|
+
input: `${request}\n`,
|
|
30
|
+
encoding: "utf8",
|
|
31
|
+
env: { ...process.env, ...extraEnv }
|
|
32
|
+
});
|
|
33
|
+
if (result.status !== 0) {
|
|
34
|
+
throw new Error(result.stderr || `Tool failed: ${name}`);
|
|
35
|
+
}
|
|
36
|
+
process.stdout.write(result.stdout);
|
|
37
|
+
const response = JSON.parse(result.stdout);
|
|
38
|
+
if (!response.result?.structuredContent?.ok && name !== "blender.read_bridge_status") {
|
|
39
|
+
throw new Error(`Tool returned not ok: ${name}`);
|
|
40
|
+
}
|
|
41
|
+
return response.result;
|
|
42
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const artifacts = resolve(root, "artifacts", "examples", "blender-e2e");
|
|
7
|
+
mkdirSync(artifacts, { recursive: true });
|
|
8
|
+
|
|
9
|
+
const cubeScript = resolve(artifacts, "create-cube.py");
|
|
10
|
+
const cubePath = resolve(artifacts, "cube.glb");
|
|
11
|
+
writeFileSync(
|
|
12
|
+
cubeScript,
|
|
13
|
+
`
|
|
14
|
+
import bpy
|
|
15
|
+
bpy.ops.object.select_all(action='SELECT')
|
|
16
|
+
bpy.ops.object.delete()
|
|
17
|
+
bpy.ops.mesh.primitive_cube_add(size=1)
|
|
18
|
+
bpy.context.object.name = "CreativePipelineCube"
|
|
19
|
+
bpy.ops.export_scene.gltf(filepath=${JSON.stringify(cubePath)}, export_format='GLB')
|
|
20
|
+
`,
|
|
21
|
+
"utf8"
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
run("blender", ["--background", "--factory-startup", "--python", cubeScript]);
|
|
25
|
+
callTool("blender.render_preview", { path: cubePath });
|
|
26
|
+
callTool("blender.optimize_asset", { path: cubePath });
|
|
27
|
+
callTool("blender.validate_asset", { path: cubePath, maxTriangles: 1000 });
|
|
28
|
+
|
|
29
|
+
function callTool(name, args) {
|
|
30
|
+
const request = JSON.stringify({
|
|
31
|
+
jsonrpc: "2.0",
|
|
32
|
+
id: 1,
|
|
33
|
+
method: "tools/call",
|
|
34
|
+
params: { name, arguments: args }
|
|
35
|
+
});
|
|
36
|
+
const result = spawnSync("node", ["packages/blender-pro-mcp/dist/server.js"], {
|
|
37
|
+
cwd: root,
|
|
38
|
+
input: `${request}\n`,
|
|
39
|
+
encoding: "utf8"
|
|
40
|
+
});
|
|
41
|
+
if (result.status !== 0) {
|
|
42
|
+
throw new Error(result.stderr || `Tool failed: ${name}`);
|
|
43
|
+
}
|
|
44
|
+
process.stdout.write(result.stdout);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function run(command, args) {
|
|
48
|
+
const result = spawnSync(command, args, { cwd: root, encoding: "utf8" });
|
|
49
|
+
if (result.status !== 0) {
|
|
50
|
+
throw new Error(result.stderr || `${command} failed`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"asset": { "version": "2.0", "generator": "creative-pipeline-mcp-test" },
|
|
3
|
+
"nodes": [{ "mesh": 0 }],
|
|
4
|
+
"meshes": [
|
|
5
|
+
{
|
|
6
|
+
"primitives": [
|
|
7
|
+
{
|
|
8
|
+
"attributes": { "POSITION": 0 },
|
|
9
|
+
"indices": 1,
|
|
10
|
+
"material": 0
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"accessors": [
|
|
16
|
+
{ "count": 3, "min": [0, 0, 0], "max": [1, 1, 0] },
|
|
17
|
+
{ "count": 3 }
|
|
18
|
+
],
|
|
19
|
+
"materials": [{ "name": "Default" }],
|
|
20
|
+
"textures": [],
|
|
21
|
+
"images": []
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const root = process.cwd();
|
|
6
|
+
const mediaDir = resolve(root, "artifacts", "examples", "premiere-project-delivery");
|
|
7
|
+
const queueDir = resolve(root, "artifacts", "examples", "premiere-project-delivery", "cep_queue");
|
|
8
|
+
const statusDir = resolve(root, "artifacts", "examples", "premiere-project-delivery", "cep_status");
|
|
9
|
+
rmSync(queueDir, { recursive: true, force: true });
|
|
10
|
+
rmSync(statusDir, { recursive: true, force: true });
|
|
11
|
+
mkdirSync(mediaDir, { recursive: true });
|
|
12
|
+
mkdirSync(queueDir, { recursive: true });
|
|
13
|
+
mkdirSync(statusDir, { recursive: true });
|
|
14
|
+
|
|
15
|
+
const mediaPath = join(mediaDir, "source.mp4");
|
|
16
|
+
writeFileSync(mediaPath, new Uint8Array([0]));
|
|
17
|
+
|
|
18
|
+
callTool("premiere.build_project_delivery", {
|
|
19
|
+
path: mediaPath,
|
|
20
|
+
template: "youtube_16x9",
|
|
21
|
+
sequenceName: "Creative Pipeline Project Delivery",
|
|
22
|
+
targetDuration: 30,
|
|
23
|
+
brand: {
|
|
24
|
+
primaryColor: "#1f6feb",
|
|
25
|
+
fontFamily: "Inter",
|
|
26
|
+
titleStyle: "clean_lower_third"
|
|
27
|
+
},
|
|
28
|
+
outputPath: join(mediaDir, "final.mp4")
|
|
29
|
+
}, {
|
|
30
|
+
CREATIVE_MCP_PERMISSION: "project_write",
|
|
31
|
+
CREATIVE_MCP_PREMIERE_IPC_DIR: queueDir,
|
|
32
|
+
CREATIVE_MCP_WORKSPACE_ROOTS: root
|
|
33
|
+
});
|
|
34
|
+
run("node", [
|
|
35
|
+
"scripts/simulate-premiere-cep.mjs",
|
|
36
|
+
"--queue",
|
|
37
|
+
queueDir,
|
|
38
|
+
"--status",
|
|
39
|
+
statusDir
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
function callTool(name, args, extraEnv = {}) {
|
|
43
|
+
const request = JSON.stringify({
|
|
44
|
+
jsonrpc: "2.0",
|
|
45
|
+
id: 1,
|
|
46
|
+
method: "tools/call",
|
|
47
|
+
params: { name, arguments: args }
|
|
48
|
+
});
|
|
49
|
+
const result = spawnSync("node", ["packages/premiere-pro-mcp/dist/server.js"], {
|
|
50
|
+
cwd: root,
|
|
51
|
+
input: `${request}\n`,
|
|
52
|
+
encoding: "utf8",
|
|
53
|
+
env: { ...process.env, ...extraEnv }
|
|
54
|
+
});
|
|
55
|
+
if (result.status !== 0) {
|
|
56
|
+
throw new Error(result.stderr || `Tool failed: ${name}`);
|
|
57
|
+
}
|
|
58
|
+
process.stdout.write(result.stdout);
|
|
59
|
+
const response = JSON.parse(result.stdout);
|
|
60
|
+
if (!response.result?.structuredContent?.ok) {
|
|
61
|
+
throw new Error(`Tool returned not ok: ${name}`);
|
|
62
|
+
}
|
|
63
|
+
return response.result;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function run(command, args) {
|
|
67
|
+
const result = spawnSync(command, args, { cwd: root, encoding: "utf8" });
|
|
68
|
+
if (result.status !== 0) {
|
|
69
|
+
throw new Error(result.stderr || `${command} failed`);
|
|
70
|
+
}
|
|
71
|
+
process.stdout.write(result.stdout);
|
|
72
|
+
}
|