@nodetool-ai/agents 0.8.4-a24.2 → 0.8.4

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 (135) hide show
  1. package/dist/.nodetool-build-stamp +1 -1
  2. package/dist/_skills/LICENSE-iart-motion-design-skills +21 -0
  3. package/dist/_skills/README.md +211 -0
  4. package/dist/_skills/api-agents/SKILL.md +58 -0
  5. package/dist/_skills/api-apps/SKILL.md +54 -0
  6. package/dist/_skills/api-assets/SKILL.md +66 -0
  7. package/dist/_skills/api-collections/SKILL.md +33 -0
  8. package/dist/_skills/api-games/SKILL.md +81 -0
  9. package/dist/_skills/api-media/SKILL.md +131 -0
  10. package/dist/_skills/api-memory/SKILL.md +72 -0
  11. package/dist/_skills/api-models/SKILL.md +78 -0
  12. package/dist/_skills/api-scripts/SKILL.md +79 -0
  13. package/dist/_skills/api-settings/SKILL.md +49 -0
  14. package/dist/_skills/api-sketches/SKILL.md +61 -0
  15. package/dist/_skills/api-storyboards/SKILL.md +94 -0
  16. package/dist/_skills/api-timelines/SKILL.md +151 -0
  17. package/dist/_skills/api-web/SKILL.md +57 -0
  18. package/dist/_skills/api-workflows/SKILL.md +123 -0
  19. package/dist/_skills/beat-sync-editing/SKILL.md +208 -0
  20. package/dist/_skills/caption-titles/SKILL.md +94 -0
  21. package/dist/_skills/color-motion/SKILL.md +185 -0
  22. package/dist/_skills/commercial-beat-sheet/SKILL.md +338 -0
  23. package/dist/_skills/elevenlabs-audio-prompting/SKILL.md +163 -0
  24. package/dist/_skills/explainer-storyboard/SKILL.md +63 -0
  25. package/dist/_skills/flux-2-klein-prompting/SKILL.md +107 -0
  26. package/dist/_skills/frame-composition/SKILL.md +291 -0
  27. package/dist/_skills/game-direction/SKILL.md +99 -0
  28. package/dist/_skills/gpt-image-2-prompting/SKILL.md +161 -0
  29. package/dist/_skills/hailuo-prompting/SKILL.md +107 -0
  30. package/dist/_skills/kling-video-prompting/SKILL.md +188 -0
  31. package/dist/_skills/launch-commercial/SKILL.md +267 -0
  32. package/dist/_skills/launch-kit/SKILL.md +120 -0
  33. package/dist/_skills/logo-reveal/SKILL.md +225 -0
  34. package/dist/_skills/manimgx/SKILL.md +123 -0
  35. package/dist/_skills/minimax-h3-prompting/SKILL.md +134 -0
  36. package/dist/_skills/motion-ad/SKILL.md +281 -0
  37. package/dist/_skills/motion-background/SKILL.md +145 -0
  38. package/dist/_skills/motion-curves/SKILL.md +302 -0
  39. package/dist/_skills/motion-direction/SKILL.md +259 -0
  40. package/dist/_skills/motion-graphics/SKILL.md +217 -0
  41. package/dist/_skills/motion-principles/SKILL.md +255 -0
  42. package/dist/_skills/music-video-treatment/SKILL.md +40 -0
  43. package/dist/_skills/nano-banana-pro-prompting/SKILL.md +133 -0
  44. package/dist/_skills/native-game/SKILL.md +310 -0
  45. package/dist/_skills/native-game-reference/SKILL.md +879 -0
  46. package/dist/_skills/nodetool-3d-scene/SKILL.md +110 -0
  47. package/dist/_skills/nodetool-api-reference/SKILL.md +338 -0
  48. package/dist/_skills/nodetool-app-builder/SKILL.md +291 -0
  49. package/dist/_skills/nodetool-browser-agent/SKILL.md +119 -0
  50. package/dist/_skills/nodetool-chat-cli/SKILL.md +184 -0
  51. package/dist/_skills/nodetool-custom-node-developer/SKILL.md +294 -0
  52. package/dist/_skills/nodetool-deployment/SKILL.md +195 -0
  53. package/dist/_skills/nodetool-js-scripting/SKILL.md +223 -0
  54. package/dist/_skills/nodetool-model-provider-config/SKILL.md +348 -0
  55. package/dist/_skills/nodetool-rag-indexing/SKILL.md +153 -0
  56. package/dist/_skills/nodetool-sketch/SKILL.md +138 -0
  57. package/dist/_skills/nodetool-skill-author/SKILL.md +125 -0
  58. package/dist/_skills/nodetool-troubleshooter/SKILL.md +370 -0
  59. package/dist/_skills/nodetool-video-post/SKILL.md +149 -0
  60. package/dist/_skills/nodetool-workflow-builder/SKILL.md +295 -0
  61. package/dist/_skills/product-commercial/SKILL.md +132 -0
  62. package/dist/_skills/qwen-image-prompting/SKILL.md +122 -0
  63. package/dist/_skills/script-video/SKILL.md +106 -0
  64. package/dist/_skills/seedance-2-prompting/SKILL.md +194 -0
  65. package/dist/_skills/seedream-prompting/SKILL.md +117 -0
  66. package/dist/_skills/short-film/SKILL.md +123 -0
  67. package/dist/_skills/stable-audio-prompting/SKILL.md +130 -0
  68. package/dist/_skills/storyboard-core/SKILL.md +716 -0
  69. package/dist/_skills/timeline-edit-ops/SKILL.md +736 -0
  70. package/dist/_skills/trailer-template/SKILL.md +291 -0
  71. package/dist/_skills/ugc-video/SKILL.md +186 -0
  72. package/dist/_skills/veo-3-prompting/SKILL.md +140 -0
  73. package/dist/_skills/video-audio-continuity/SKILL.md +90 -0
  74. package/dist/_skills/video-clone/SKILL.md +96 -0
  75. package/dist/_skills/video-workflow/SKILL.md +119 -0
  76. package/dist/_skills/wan-2-6-prompting/SKILL.md +107 -0
  77. package/dist/app-build/bridge.d.ts.map +1 -1
  78. package/dist/app-build/bridge.js +44 -17
  79. package/dist/app-build/bridge.js.map +1 -1
  80. package/dist/capabilities/apps.d.ts.map +1 -1
  81. package/dist/capabilities/apps.js +55 -13
  82. package/dist/capabilities/apps.js.map +1 -1
  83. package/dist/capabilities/apps.specs.d.ts.map +1 -1
  84. package/dist/capabilities/apps.specs.js +5 -3
  85. package/dist/capabilities/apps.specs.js.map +1 -1
  86. package/dist/capabilities/game-asset-browser.d.ts.map +1 -1
  87. package/dist/capabilities/game-asset-browser.js +6 -1
  88. package/dist/capabilities/game-asset-browser.js.map +1 -1
  89. package/dist/capabilities/game.d.ts +1 -1
  90. package/dist/capabilities/game.d.ts.map +1 -1
  91. package/dist/capabilities/game.js +71 -56
  92. package/dist/capabilities/game.js.map +1 -1
  93. package/dist/capabilities/game.specs.js +1 -1
  94. package/dist/capabilities/game.specs.js.map +1 -1
  95. package/dist/capabilities/game3d.d.ts.map +1 -1
  96. package/dist/capabilities/game3d.js +14 -19
  97. package/dist/capabilities/game3d.js.map +1 -1
  98. package/dist/capabilities/gameAssertions.d.ts +52 -0
  99. package/dist/capabilities/gameAssertions.d.ts.map +1 -0
  100. package/dist/capabilities/gameAssertions.js +32 -0
  101. package/dist/capabilities/gameAssertions.js.map +1 -0
  102. package/dist/capabilities/models.d.ts.map +1 -1
  103. package/dist/capabilities/models.js +9 -0
  104. package/dist/capabilities/models.js.map +1 -1
  105. package/dist/capabilities/storyboards.d.ts.map +1 -1
  106. package/dist/capabilities/storyboards.js +36 -11
  107. package/dist/capabilities/storyboards.js.map +1 -1
  108. package/dist/capabilities/storyboards.specs.d.ts.map +1 -1
  109. package/dist/capabilities/storyboards.specs.js +11 -1
  110. package/dist/capabilities/storyboards.specs.js.map +1 -1
  111. package/dist/capabilities/workflows.d.ts.map +1 -1
  112. package/dist/capabilities/workflows.js +1 -0
  113. package/dist/capabilities/workflows.js.map +1 -1
  114. package/dist/capabilities/workflows.specs.d.ts.map +1 -1
  115. package/dist/capabilities/workflows.specs.js +4 -3
  116. package/dist/capabilities/workflows.specs.js.map +1 -1
  117. package/dist/evals/surfaces/game.d.ts.map +1 -1
  118. package/dist/evals/surfaces/game.js +29 -1
  119. package/dist/evals/surfaces/game.js.map +1 -1
  120. package/dist/game-authoring.d.ts +120 -0
  121. package/dist/game-authoring.d.ts.map +1 -1
  122. package/dist/game-build-integrity.d.ts +12 -0
  123. package/dist/game-build-integrity.d.ts.map +1 -0
  124. package/dist/game-build-integrity.js +78 -0
  125. package/dist/game-build-integrity.js.map +1 -0
  126. package/dist/game-examples.d.ts +44 -3
  127. package/dist/game-examples.d.ts.map +1 -1
  128. package/dist/game-examples.js +60 -10
  129. package/dist/game-examples.js.map +1 -1
  130. package/dist/system-skills.d.ts +1 -1
  131. package/dist/system-skills.js +1 -1
  132. package/dist/tools/builtin-tools.d.ts.map +1 -1
  133. package/dist/tools/builtin-tools.js +2 -0
  134. package/dist/tools/builtin-tools.js.map +1 -1
  135. package/package.json +19 -19
@@ -0,0 +1,370 @@
1
+ ---
2
+ name: nodetool-troubleshooter
3
+ description: "Diagnose a failing NodeTool run on any surface: workflows, mini apps, timelines, sketches, scripts, storyboards, stuck media generations, provider keys and server auth errors."
4
+ featured: true
5
+ ---
6
+
7
+ You are a NodeTool troubleshooter. Diagnose issues systematically using this guide.
8
+
9
+ # Read the run summary first
10
+
11
+ For an app operation, workflow job or chat turn with a recorded run, start
12
+ with `get_run`. In `execute_code`, call `nodetool.runs.get(run_id)`. When the
13
+ id is unknown, use `nodetool.runs.list({kind, status, app_id, workflow_id,
14
+ thread_id})` with the relevant filters.
15
+
16
+ Read the summary's first failed span and ancestor path before replaying work.
17
+ For saved app inputs and outputs, call `nodetool.runs.get(run_id,
18
+ {include_content: true})` after the summary identifies the relevant run.
19
+ Inspect that span with `nodetool.runs.trace(run_id, {focus_span_id,
20
+ include_content: true})`, then read its events with
21
+ `nodetool.runs.logs(run_id, {span_id, include_content: true})`. The same tools
22
+ read runs that a person started and runs that an agent started. A failed run
23
+ is a readable outcome. Expired, excluded or truncated content is reported by
24
+ the reader, so do not recover it from older job logs.
25
+
26
+ With shell access, use the same readers:
27
+
28
+ ```bash
29
+ nodetool runs list --status failed --json
30
+ nodetool runs show <run_id> --json
31
+ nodetool runs trace <run_id> --focus <span_id> --include-content --json
32
+ nodetool runs logs <run_id> --span <span_id> --include-content --json
33
+ nodetool runs tail <run_id>
34
+ ```
35
+
36
+ Resource ids accept the full id or its exact 12-character prefix. Keep trace
37
+ and span ids in full. Use the checks and replay harnesses below after the
38
+ stored trace identifies the failing surface, or when an older execution has
39
+ no run trace.
40
+
41
+ # Name the surface first
42
+
43
+ A failure belongs to one document kind, and each kind has its own static check
44
+ and its own replay harness. Checking the wrong one wastes the run.
45
+
46
+ | Symptom sits in | Static check | Replay | Skill for the fix |
47
+ |---|---|---|---|
48
+ | A workflow graph | `validate_workflow` | `debug_workflow` | `nodetool-workflow-builder` |
49
+ | A mini app: dead button, blank widget | `debug_app {run: false}` | `debug_app {interact}` | `nodetool-app-builder` |
50
+ | A timeline: wrong length, missing clip, bad font | `validate_timeline` | `timeline debug` | `timeline-edit-ops` |
51
+ | A sketch: empty layer, wrong blend | `validate_sketch` | `sketch debug` | `nodetool-sketch` |
52
+ | A JS script or Code node | `validate_js_script`, `validate_code` | `run_js_script`, `test_js_script` | `nodetool-js-scripting` |
53
+ | A 3D model | `validate_model3d` | `render_model3d` | `nodetool-3d-scene` |
54
+ | A storyboard: a shot that will not render | `get_storyboard` | re-render one target | `storyboard-core` |
55
+ | A media call that never came back | `generations get` | `generations await` | below, under **Stuck generation** |
56
+
57
+ A run that spans surfaces fails at one of them. A mini app over a broken
58
+ workflow reports that the app is broken: debug the graph as a graph first.
59
+
60
+ # CLI Debug Harnesses
61
+
62
+ These run in the user's shell. The in-product agent uses the tools in the table
63
+ above instead. From a NodeTool checkout the same commands run as
64
+ `npm run dev:nodetool -- <command>`. Escalate in cost order:
65
+
66
+ ```bash
67
+ # 1. Static check (<1s, no run, no DB for file targets): unknown node types,
68
+ # missing required props, unselected models, dangling/mis-typed edges
69
+ nodetool validate <workflow_id|workflow.json|workflow.ts>
70
+
71
+ # 2. Single node in isolation — no workflow authoring needed
72
+ nodetool node run nodetool.text.Concat --props '{"a":"hi"}' --no-secrets
73
+
74
+ # 3. Full server-side run → self-contained debug bundle (messages, logs,
75
+ # outputs, errors) + agent-friendly verdict. --json prints the full report.
76
+ nodetool debug <workflow_id|workflow.json> --params '{"prompt":"hi"}'
77
+ nodetool debug workflow.json --watch # re-run on save, print verdict diff
78
+
79
+ # 4. Opt-in expensive surfaces
80
+ nodetool debug <id> --trace # OTel spans: timing, tokens, cost
81
+ nodetool debug <id> --browser --stages # real browser + per-stage screenshots
82
+
83
+ # Mini apps: binding validation, then a headless run of every operation
84
+ nodetool app debug <id> --no-run # free wiring check
85
+ nodetool app debug <id> --json
86
+
87
+ # The other document surfaces — same shape: validate, then replay a scripted session
88
+ nodetool timeline validate <timeline_id|sequence.json> --json
89
+ nodetool sketch validate <image_document_id|sketch.json> --json
90
+ nodetool jsscript validate <id|file.json> --json
91
+ nodetool timeline debug <id> --interact '[…]'
92
+ nodetool sketch debug <id> --interact '[…]'
93
+ nodetool jsscript debug <id> --interact '[…]'
94
+ ```
95
+
96
+ For every one of these, a path that exists on disk wins over an id, and a file
97
+ target needs no database. Each `debug` writes a bundle under `nodetool-debug/`
98
+ and exits non-zero on a bad verdict. Read the report's `notSimulated` list
99
+ before concluding that a green verdict means the surface works.
100
+
101
+ The bundle lands in `nodetool-debug/<id>-<ts>/` (`report.md`, `server/messages.jsonl`, …). Loop: run `debug` → read the verdict → edit → re-run. Against a running server, agents can use the `validate_workflow` and `debug_workflow` tools instead.
102
+
103
+ For an older agent execution without stored spans, an external trace can help
104
+ inspect timing and cost. External copies exclude prompts and responses by
105
+ default. Use the owned run readers above for recorded content.
106
+
107
+ ```bash
108
+ NODETOOL_TRACE_FILE=/tmp/trace.jsonl nodetool chat
109
+ nodetool --trace-file trace.jsonl run workflow.ts
110
+ ```
111
+
112
+ # Quick Diagnostic Checklist
113
+
114
+ When a user reports a problem, work through this in order:
115
+
116
+ - [ ] **Connections**: Are all required inputs connected? `validate_workflow` reports the missing ones
117
+ - [ ] **Types**: Do connected types match? `validate_workflow` reports mis-typed edges
118
+ - [ ] **Preview nodes**: Add Preview nodes at each stage to inspect data
119
+ - [ ] **Error messages**: Read red node error text carefully
120
+ - [ ] **Model availability**: Is the model downloaded, and is its provider key set?
121
+ - [ ] **File paths**: Do referenced files exist and have correct permissions?
122
+ - [ ] **API keys**: `list_secrets` shows which keys are configured
123
+ - [ ] **Logs**: The desktop log file (§ Log Inspection), or a server started with `NODETOOL_LOG_LEVEL=debug`
124
+
125
+ # Node Status Colors
126
+
127
+ | Color | Status | Action |
128
+ |-------|--------|--------|
129
+ | **Gray** | Not started | Waiting for inputs or not yet reached |
130
+ | **Yellow** | Running | Currently processing, wait |
131
+ | **Green** | Completed | Working correctly |
132
+ | **Red** | Failed | Click node to see error message |
133
+
134
+ # Common Issues & Solutions
135
+
136
+ ## Workflow Stuck / Not Progressing
137
+
138
+ **Symptoms**: Yellow nodes that never turn green, no output
139
+
140
+ **Check**:
141
+ 1. Is a model downloading? (first run can be slow)
142
+ 2. Is there an infinite loop? (check for cycles in connections)
143
+ 3. Is a node waiting on an input whose upstream never emits?
144
+ 4. Is the server running? (`nodetool serve` in the user's shell)
145
+ 5. Network timeout on API call?
146
+
147
+ **Fix**: Add Preview nodes before stuck node. Check server logs. Kill and restart if needed.
148
+
149
+ ## Type Mismatch
150
+
151
+ **Symptoms**: Red edge, error about incompatible types
152
+
153
+ **Fix**:
154
+ - Hover over the edge to see source/target types
155
+ - Insert a conversion node (`search_nodes` finds one for the type pair), or a `nodetool.code.Code` node for anything else
156
+ - Check `metadataOutputTypes` of source node matches expected input type
157
+
158
+ ## Empty / Null Output
159
+
160
+ **Symptoms**: Downstream nodes receive nothing, Preview shows null
161
+
162
+ **Check**:
163
+ 1. Add Preview node immediately after the suspect node
164
+ 2. Is the upstream node actually completing? (should be green)
165
+ 3. Are optional inputs that are actually needed left unconnected?
166
+ 4. Is the node returning the correct output key?
167
+
168
+ ## Stuck Generation
169
+
170
+ **Symptoms**: An image, video, audio or 3D call never returns. The surface shows
171
+ a pending take with no error.
172
+
173
+ Every provider media call is one `predictions` row, opened before the call and
174
+ closed with its outcome, so a hung call is visible without reading logs.
175
+
176
+ ```bash
177
+ nodetool generations list --status running --json
178
+ nodetool generations get <generation_id> --json
179
+ nodetool generations await <generation_id> --timeout 300 # exit 1 while running
180
+ nodetool generations cancel <generation_id>
181
+ nodetool generations sweep # close orphaned rows after a restart
182
+ nodetool generations reconcile <generation_id> # ask the provider what it billed
183
+ ```
184
+
185
+ A row reading `interrupted` means a restart orphaned it, not that the provider
186
+ failed. `provider-list` and `provider-get` ask the provider's own record instead
187
+ of the local table, for a run started on another machine. Agents reach the same
188
+ record through `list_generations`, `get_generation`, `await_generation`,
189
+ `cancel_generation` and `reconcile_generation`.
190
+
191
+ ## Mini App Shows Nothing
192
+
193
+ **Symptoms**: The button does nothing, or a widget stays blank after a run.
194
+
195
+ **Check**, in this order:
196
+
197
+ 1. `debug_app {application_id, run: false}` — free. A binding pointing at a
198
+ missing input, output or variable is the usual answer.
199
+ 2. Does the app have a run trigger at all? A Button needs a `run` action.
200
+ 3. Is anything bound to `op:<id>/exec#error`? A failed operation with no error
201
+ binding leaves the app looking idle.
202
+ 4. Did the run actually complete? `debug_app {interact}` reports each widget's
203
+ final state and each invocation's policy decision, so a run that was
204
+ replaced, queued or timed out says so.
205
+ 5. Is the widget bound to the right kind? A Sketch or Timeline reference bound
206
+ to an Image or Video widget renders nothing.
207
+
208
+ ## Timeline Renders Wrong
209
+
210
+ **Symptoms**: The cut runs longer than planned, a font differs from the editor,
211
+ an animation does not play.
212
+
213
+ 1. `validate_timeline` first. It catches overlaps, fades longer than their clip,
214
+ unknown presets, incomplete bindings and non-portable fonts.
215
+ 2. A shot is as long as its render, not as long as its directed duration. Check
216
+ `retimed_shots` from the assembly call.
217
+ 3. A CSS generic family (`sans-serif`, `serif`, `system-ui`) is refused where a
218
+ clip is authored, because the editor, the render and the frame preview would
219
+ each pick a different typeface. Use a bundled family.
220
+ 4. `preview_timeline_frame` before `render_timeline`. Rendering to check an edit
221
+ is the expensive way to be wrong.
222
+
223
+ ## LLM Poor Quality
224
+
225
+ **Symptoms**: Agent output is wrong, irrelevant, or garbled
226
+
227
+ **Fix**:
228
+ - Improve the prompt (be specific, add examples)
229
+ - Use a more capable model (`find_model`, or the ids the provider registry lists)
230
+ - Lower temperature for factual tasks (0.0–0.3)
231
+ - Add few-shot examples in system prompt
232
+ - Use RAG to ground answers in source documents
233
+
234
+ ## RAG / Vector Search Returns Nothing
235
+
236
+ **Symptoms**: HybridSearch or TextSearch returns empty results
237
+
238
+ **Check**:
239
+ 1. Was the collection actually indexed? Inspect it with a `vector.Count` / `vector.Peek` node, or the editor's collection view.
240
+ 2. Does the embedding model match between indexing and search?
241
+ 3. Test search directly with a simple query
242
+ 4. Review chunking — very small or very large chunks reduce quality
243
+
244
+ ## API Key Errors
245
+
246
+ **Symptoms**: 401, 403, "API key invalid", "authentication failed"
247
+
248
+ **Fix**: call `list_secrets` to see which keys are set, then `request_secret`
249
+ with the missing name. It opens a dialog where the user types the value, so
250
+ never ask for a key in chat. From a shell, the user can run
251
+ `nodetool secrets store OPENAI_API_KEY` or export the variable instead.
252
+
253
+ **Provider key names**: `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `GEMINI_API_KEY`, `HF_TOKEN`, `FAL_API_KEY`
254
+
255
+ A `401` from the NodeTool server itself, not from a provider, is server auth
256
+ (§ Server Returns 401).
257
+
258
+ ## Model Not Found
259
+
260
+ **Symptoms**: "Model not found", "model does not exist"
261
+
262
+ **Check**:
263
+ 1. For local models: Is the model downloaded? (Models → Model Manager)
264
+ 2. For Ollama: Is Ollama running? (`ollama list`)
265
+ 3. For cloud: Is the model ID real? Take ids from `find_model` or `list_provider_models`, never from memory
266
+ 4. For HuggingFace gated models: Accept terms on HF Hub
267
+
268
+ ## Memory Issues
269
+
270
+ **Symptoms**: OOM errors, slow processing, system unresponsive
271
+
272
+ **Fix**:
273
+ - Use quantized models (INT4/FP4) for local inference
274
+ - Enable CPU offload for large models
275
+ - Reduce batch sizes
276
+ - Use smaller model variants
277
+ - For Docker: increase `--memory` limit
278
+
279
+ ## Server Returns 401
280
+
281
+ **Symptoms**: The UI loads but API or WebSocket calls fail with `401`, or a
282
+ client gets "Remote access requires authentication".
283
+
284
+ The server picks its auth mode from `SUPABASE_URL` and `SUPABASE_KEY` alone. It
285
+ reads neither `AUTH_PROVIDER` nor `NODETOOL_SERVER_MODE`.
286
+
287
+ | Mode | Enabled by | Accepted credentials |
288
+ |------|------------|----------------------|
289
+ | Local | Default, with the Supabase variables unset | Loopback connections run as user `"1"` with no token. `NODETOOL_TRUST_LOCALHOST=false` turns that off. Sources in `NODETOOL_TRUST_LOCAL_NETWORKS` (comma-separated CIDRs) also run as user `"1"` with no token. A bearer equal to `SERVER_AUTH_TOKEN` runs as user `"1"`. A token minted by `nodetool deploy users-add` runs as that API user. Anything else gets `401`. |
290
+ | Supabase | `SUPABASE_URL` and `SUPABASE_KEY` both set | Every non-public request needs a valid Supabase JWT. `SERVER_AUTH_TOKEN`, `NODETOOL_TRUST_LOCAL_NETWORKS` and API-user tokens are ignored. Loopback is trusted only with `NODETOOL_TRUST_LOCALHOST=true`. |
291
+
292
+ In both modes, an access token (`ntk_…`) created in **Settings → MCP → Connect
293
+ an agent remotely** authenticates as the person who created it. Send any token
294
+ as `Authorization: Bearer <token>`. A WebSocket client that cannot set headers
295
+ passes `?api_key=<token>` on the `/ws` URL.
296
+
297
+ In Docker, the published port arrives from the bridge gateway, not loopback, so
298
+ Local mode refuses it until that range is in `NODETOOL_TRUST_LOCAL_NETWORKS` or
299
+ the client sends a token. Setup steps are in `nodetool-deployment`.
300
+
301
+ ## Deployment Failures
302
+
303
+ **Symptoms**: Deploy command fails, server won't start
304
+
305
+ **Check** (the user runs these in their shell):
306
+ 1. `nodetool deploy show <name>` parses `deployment.yaml` without a remote call
307
+ 2. `nodetool deploy plan <name>` before `apply`
308
+ 3. Docker running on the host? (`docker ps`)
309
+ 4. Port already in use? (`lsof -i :7777`)
310
+ 5. Volume mount paths exist?
311
+ 6. SSH key permissions correct? (600)
312
+
313
+ # Debugging Techniques
314
+
315
+ ## Preview Node Strategy
316
+ ```
317
+ Input → Preview(1) → Transform → Preview(2) → LLM → Preview(3) → Output
318
+ ```
319
+ Add Preview nodes at each stage to isolate where data breaks.
320
+
321
+ ## Log Inspection
322
+
323
+ The desktop app writes `nodetool.log` to `~/.local/share/nodetool/logs/` on
324
+ macOS and Linux, and to `%LOCALAPPDATA%\nodetool\logs\` on Windows.
325
+
326
+ In the user's shell, `NODETOOL_LOG_LEVEL=debug nodetool serve` starts a server
327
+ with verbose logs. Logging is set by that env var, not a `serve` flag. Browser
328
+ errors are in the DevTools console (View → Developer Tools).
329
+
330
+ ## JSON Export
331
+ Export workflow as JSON (`File → Export`) to inspect:
332
+ - Node `data` fields for property values
333
+ - Edge `sourceHandle`/`targetHandle` names
334
+ - Node `type` strings for correctness
335
+
336
+ ## Network Debugging
337
+
338
+ In the user's shell:
339
+
340
+ ```bash
341
+ # Check server health
342
+ curl http://localhost:7777/health
343
+
344
+ # Test API auth
345
+ curl -H "Authorization: Bearer TOKEN" http://localhost:7777/v1/models
346
+
347
+ # Check WebSocket
348
+ wscat -c ws://localhost:7777/ws
349
+ ```
350
+
351
+ # Performance Optimization
352
+
353
+ | Issue | Solution |
354
+ |-------|----------|
355
+ | Slow LLM responses | Use local models for simple tasks, cloud for complex |
356
+ | Large file processing | Batch processing, stream with `genProcess` |
357
+ | Multiple independent tasks | Use parallel execution paths in workflow |
358
+ | Repeated computations | Cache results, avoid redundant nodes |
359
+ | Model loading time | Keep models in memory (server mode), pre-download |
360
+ | High memory usage | Right-size models, use quantized variants |
361
+ | Slow vector search | Optimize chunk size (200-500 tokens) |
362
+
363
+ # Error Recovery Patterns
364
+
365
+ 1. **Read the error message carefully** — most errors are self-explanatory
366
+ 2. **Check the simplest explanation first** — missing connection, wrong type, no API key
367
+ 3. **Isolate with Preview nodes** — find exactly where data breaks
368
+ 4. **Check logs** — server logs have full stack traces
369
+ 5. **Restart if stuck** — kill server, clear cache, restart
370
+ 6. **Reduce complexity** — test with a minimal workflow first, then add nodes
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: nodetool-video-post
3
+ description: "Repair or re-generate footage already on a NodeTool timeline: cutouts, tracking, outpainting, upscaling, generated sound, voice replacement, lip sync. Covers the candidate review protocol these return."
4
+ featured: true
5
+ ---
6
+
7
+ # Post on a saved timeline
8
+
9
+ Footage already exists and something about it has to change. These tools act on
10
+ one clip of a **saved** timeline sequence, not on a storyboard shot and not on a
11
+ loose asset.
12
+
13
+ Directing a new piece belongs to `storyboard-core`
14
+ and its job skills. Cutting, animating, transitions and titles go through
15
+ `edit_timeline`, whose op list, presets and preview contract live in
16
+ `timeline-edit-ops`: load it with `load_skill {name: "timeline-edit-ops"}`
17
+ before the first `edit_timeline` call. Building a new cut belongs to
18
+ `motion-graphics`.
19
+
20
+ ## Pick the operation
21
+
22
+ | The problem | Tool | What it writes |
23
+ |---|---|---|
24
+ | Replace what is behind the subject | `isolate_subject` | A `generatedMatte` on that clip |
25
+ | Make another clip follow a moving subject | `track_object` | A document-level track others `bind_to_track` |
26
+ | The frame is the wrong aspect ratio | `expand_frame` | An inactive video candidate |
27
+ | The footage is too soft or too small | `upscale_video` | An inactive video candidate |
28
+ | The shot has no sound | `video_to_audio` | An aligned inactive audio candidate |
29
+ | The recorded voice is wrong | `recorded_voice_replacement` | An inactive audio candidate |
30
+ | The mouth does not match the new audio | `lip_sync` | An inactive video candidate |
31
+ | A title or shape should move with the music | `bake_audio_animation` | A `custom` animation on the target clip |
32
+
33
+ `isolate_subject` always runs FAL's BiRefNet video endpoint. It takes no
34
+ `provider`, and its optional `model` is that endpoint's own enum (default
35
+ `"General Use (Light)"`, `"Matting"` for hair, `"Portrait"` for people), not a
36
+ `find_model` id. A clip with a current matte gets it back for free unless
37
+ `regenerate: true`.
38
+
39
+ Every other tool above except `bake_audio_animation` takes `provider` and
40
+ `model` from `find_model`. There is no default: an unset model fails the call
41
+ rather than spending on a model nobody chose.
42
+
43
+ ## Nothing is applied until it is accepted
44
+
45
+ `expand_frame`, `upscale_video`, `video_to_audio`, `recorded_voice_replacement`
46
+ and `lip_sync` all return an **inactive candidate** with its provenance. None of
47
+ them changes the accepted take, the sequence dimensions, or the existing
48
+ framing. Applying the result is a separate, explicit step:
49
+
50
+ 1. `inspect_video_production_candidates {candidates, preview?}` refreshes their
51
+ state and optionally builds a Preview take or draft from an explicit
52
+ destination-to-candidate `selection`. Inspection writes nothing.
53
+ 2. `accept_video_production_candidates {action, batch_id, document_id,
54
+ project_id, candidates, selection, targets}` applies one atomic manifest.
55
+ `action` is `use_take` or `use_draft`. Each entry in `targets` carries
56
+ `expected_target_revision`, which the server rechecks before the apply, so a
57
+ document that moved underneath is refused rather than overwritten.
58
+
59
+ Report the candidate ids and what each one is, then let the user choose. Never
60
+ describe a candidate as applied before an `accept` returned.
61
+
62
+ ## Generating a new take for a slot
63
+
64
+ A slot that needs fresh footage rather than a repair goes through the reviewed
65
+ production path, which covers all three document kinds:
66
+ `timeline_clip`, `storyboard_shot` and `script_line`.
67
+
68
+ `prepare_video_production` → `submit_video_production` → inspect → accept.
69
+
70
+ `prepare` is non-mutating. It resolves linked script speech, verifies owner,
71
+ project, target, references, capability route and timing, then freezes one to
72
+ three stable candidate identities **before** any provider spend. It requires
73
+ `review: {status: "reviewed", plan_fingerprint}` — the fingerprint of every
74
+ authoring input the reviewed plan read. The `route` is
75
+ `reference_to_video`, `text_to_video`, or `audio_driven_performance`, and
76
+ on-camera speech (`speech_mode: "on_camera"`) requires
77
+ `audio_driven_performance`. `submit` re-runs preflight and authorization and
78
+ recovers an existing request id instead of resubmitting it, so a retry after a
79
+ dropped connection does not pay twice.
80
+
81
+ ## Per-tool notes
82
+
83
+ **`isolate_subject`** sends the clip's *whole* source asset and reads the mask
84
+ back at the clip's own source time, which is what lets a later trim, split or
85
+ speed change keep the cutout aligned. A clip with a current cutout is handed it
86
+ back for free unless `regenerate: true`, and a failed regenerate leaves the
87
+ working matte in place. Tune the result with the free `set_generated_matte` op
88
+ (invert, strength, feather, or an earlier version). Use `set_matte` instead for
89
+ a keyhole authored from another clip.
90
+
91
+ **`track_object`** needs `initial_region` normalized 0..1 over the source frame
92
+ plus `start_ms` and `end_ms` in absolute source milliseconds. The initial box
93
+ sits at `start_ms` for `forward` and `both`, at `end_ms` for `backward`. Box
94
+ tracks only in this build. A new run is refused before saving or spending when
95
+ the provider does not implement `track_object`.
96
+
97
+ **`lip_sync`** consumes an **accepted** `recorded_voice_replacement` candidate:
98
+ `replacement_audio {asset_id, status, provenance}`. Run the voice replacement,
99
+ accept it, then sync.
100
+
101
+ **`bake_audio_animation`** measures a clip's audio, with an envelope follower or
102
+ one pulse per onset in `mode: "beats"`, and writes a source-anchored `custom`
103
+ animation on another clip's property, commonly `scale`. The write is additive: a
104
+ hand-authored `pop` or `slide` on the same channel composes with it rather than
105
+ being replaced. A re-bake replaces only the curve it produced before.
106
+
107
+ **`source_asset_id`** on the native media tools is an optional pin captured
108
+ before the call. A mismatch is stale and the call is refused. Pass it when
109
+ anything else may be editing the document.
110
+
111
+ ## Check the result
112
+
113
+ - `validate_timeline {timeline_id}` after every edit pass.
114
+ - `preview_timeline_frame {timeline_id, ...}` composites one or more timecodes
115
+ and returns a per-layer report. It is the cheap way to see a matte, a bake or
116
+ an accepted take without rendering. A `model3d` layer needs headless Chromium:
117
+ with none on the host the layer is left out and reported as a
118
+ `model3d_unavailable` degradation, never as an empty clip.
119
+ - `compare_timeline_frames` puts before and after side by side.
120
+ - `render_timeline` is the paid, final pass. Do not render to check an edit.
121
+ - Snapshot before a destructive pass with `create_timeline_version`.
122
+ `restore_timeline_version` snapshots the pre-restore state first and
123
+ re-validates against today's schema, so an old document may fail what it used
124
+ to pass.
125
+
126
+ ## Verify from a shell
127
+
128
+ These are the `nodetool` CLI. From a NodeTool checkout the same commands run
129
+ as `npm run dev:nodetool -- <command>`.
130
+
131
+ ```bash
132
+ nodetool timeline validate <timeline_id|sequence.json> --json
133
+ nodetool timeline debug <id> --interact '[{"tool":"add_track","input":{"type":"audio","name":"Music"}}]'
134
+ nodetool timeline versions list <timeline_id> --save-type manual
135
+ ```
136
+
137
+ Rendering, playback, decode and generation are not simulated by the harness. The
138
+ report says so under `notSimulated`.
139
+
140
+ ## Reference
141
+
142
+ - The `storyboard-core` system skill, § Timeline of its tool contract —
143
+ `load_skill` it for the board-to-timeline calls.
144
+
145
+ In a NodeTool checkout, these repository sources go further:
146
+
147
+ - `docs/harnesses.md` § nodetool timeline validate / debug
148
+ - `docs/harnesses.md` § Generated mattes
149
+ - `docs/harnesses.md` § Audio-driven timeline motion