Reanimation backlog: REV-001, REV-002, the cline-dev-tara merge, the dev-loop fix, and REV-008 - #16
Merged
Conversation
:wq Merge remote-tracking branch 'origin/cline-dev' into cline-dev-tara
TASK-010: Fixed critical P0 bug preventing new project creation Problem: - Programmatic project.json generation had incorrect structure - Missing 'graph' object wrapper - Missing 'comments' and 'connections' arrays - Error: Cannot read properties of undefined (reading 'comments') Solution: - Corrected project.json structure with proper graph object - Added component id field - Included all required arrays (roots, connections, comments) - Added debug logging for better error tracking Impact: - New users can now create projects successfully - Unblocks user onboarding - No more cryptic error messages Documentation: - Added comprehensive entry to LEARNINGS.md - Created detailed CHANGELOG.md - Updated README.md with completion status
- Add ProjectTemplate TypeScript interfaces for type-safe templates - Implement EmbeddedTemplateProvider for bundled templates - Create Hello World template (Router + Home page + Text) - Update LocalProjectsModel to use embedded templates by default - Remove programmatic project creation workaround - Fix: Add required fields (id, comments, metadata) per TASK-010 - Fix: Correct node type 'PageRouter' → 'Router' - Add comprehensive developer documentation Benefits: - No more path resolution issues (__dirname/process.cwd()) - Works identically in dev and production - Type-safe template definitions - Easy to add new templates Closes TASK-009 (Phase 3 - Editor UX Overhaul)
- Implemented StyleTokensModel for managing design tokens - Added StyleTokensInjector to inject tokens into viewer preview - 10 essential default tokens (primary, background, foreground, border, spacing, radius, shadows) - Token storage in project metadata (styleTokens field) - Real-time CSS variable injection in preview - Fixed bug: tokens now inject for legacy projects without styleTokens field - Tested and validated (see TEST-REPORT.md) MVP does NOT include: - UI panel for editing tokens - Token picker component - Import/export functionality - Full token set (only 10 essentials) These features are planned for STYLE-001 Full implementation.
…Config - Created ElementConfigTypes.ts with complete type definitions - Implemented ElementConfigRegistry singleton with full CRUD operations - Added ButtonConfig with 6 variants (primary, secondary, outline, ghost, destructive, link) - Added 4 size presets (sm, md, lg, xl) for buttons - All types compile without errors - Registry methods: register, get, applyDefaults, applyVariant, resolveStyles, validate - Token-based styling with var(--token-name) references Part of STYLE-002 MVP implementation. Next: TextConfig + Text sizing bug fix.
- 47 unit tests covering all Registry functionality - Tests: singleton, registration, validation, defaults, variants, sizes - Tests: style resolution, sources tracking, registry operations - Tests ButtonConfig structure (6 variants, 4 sizes, states) - Mock nodes for testing apply operations - All tests ready for execution with proper test runner Part of STYLE-002 MVP implementation.
- TextConfig with 10 semantic typography variants * display, h1, h2, h3, h4 (headings) * body, body-sm (body text) * caption, label, code (special text) - All variants use design tokens - Fix Text element bug: width 'auto' instead of stretching to 100% - Text now properly sizes to content with display: flex + width: auto Part of STYLE-002 MVP 1 implementation. Next: MVP 2 - Node Integration.
- Added initElementConfigs() function in ElementConfigs/index.ts - Calls registry.register() for ButtonConfig and TextConfig - Integrated into Router constructor (called after LessonTemplatesModel init) - Configs now load when editor starts - Console log shows '[ ElementConfigs] Initialized with X configs' Part of STYLE-002 MVP 2 implementation. Next: Hook into node creation to auto-apply defaults.
- Added ElementConfigRegistry import to NodeGraphNode - Modified constructor to call applyDefaults() for new nodes - Only applies when node has typename and no existing parameters - Completes MVP 2: Node Integration + Auto-defaults New nodes (Button, Text, etc.) now automatically get: - Sensible default values from their config - Token-based styling (e.g., var(--theme-color-primary)) - Proper sizing (Text gets display: flex, width: auto) Part of STYLE-002 MVP implementation. Next: Test in app, then MVP 3 (Variants + UI).
…t, Image configs - Add GroupConfig with 7 variants (default, card, section, inset, flex-row, flex-col, centered) - Add TextInputConfig with 2 variants (default, error) and 4 states - Add ImageConfig with 3 variants (default, rounded, circle) - Register all 5 configs in initElementConfigs() - Node creation hook already implemented in NodeGraphNode constructor - Total: 5 configs with 28 variants across all elements - All configs use design tokens for theming MVP 2 Status: ✅ Complete (ready for integration testing)
…tion Implements MVP2 of the ElementConfigs system, applying default styles to newly created nodes. ✅ Completed: - ElementConfigRegistry with singleton pattern - 5 node configs (Button, Text, Group, TextInput, Image) - 28 total style variants defined - Integration in router.tsx for app startup - Unit tests for registry ✅ Validated: - Button node: 100% defaults applied correctly - Text node: Partial defaults applied (fontSize, color work) - System initializes successfully at startup⚠️ Known Issues: - Text lineHeight and fontWeight not fully applied (likely interaction with legacy text style system) - Requires cache clear (npm run clean:all) for changes to take effect 📝 Documentation: - MVP2 validation report with test results - Detailed changelog of implementation steps 🚀 Next: MVP3 will add variant selector UI in Property Panel Ref: STYLE-002 Phase 9
Three shallow config/script bugs left the repo unbuildable since the 2026-02-18 stall, plus a fourth latent breakage found while verifying the fix end-to-end. - Add the missing @noodl-viewer-cloud/execution-history alias to tsconfig.json and webpack.shared.js — the module existed but was never wired up when the ExecutionHistory UI merged (11 TS2307 / 13 webpack errors). - Fix the off-by-one-level EventDispatcher import in ExecutionHistoryPanel.tsx (12th typecheck error). - Force CommonJS module mode in tsconfig.build.json so ts-node resolves the extensionless '../../../scripts/helper' import under Node 22's stricter ESM resolver — this was killing packages/noodl-editor/scripts/build.ts immediately after the viewer bundle succeeded. - Replace the dead absolute-path debug `ls` in scripts/build-editor.ts with a working app-builder-lib templates diagnostic. - Restore packages/noodl-editor/build/entitlements.mac.plist, deleted from the repo years ago but still referenced by package.json's build.mac.entitlements — without it electron-builder fails signing and `build:editor` can't complete. Not one of the three bugs named in the task doc, but required to hit the "packaged app produced" success criterion. Ajv v8 resolution was already deterministic via the committed lockfile (editor gets 8.18.0 nested, root stays 6.12.6); verified on a clean `rm -rf node_modules && npm install`, no lockfile surgery needed. Verified: typecheck:editor 12→0 errors (also 0 on clean install), renderer production webpack 13→0 errors, and the full root `npm run build:editor` now runs to completion producing a signed (ad-hoc) .dmg/.zip. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds the 2026-07-22 viability assessment and the task specifications it produced: Horizon 0 reanimation (REV-002…REV-007) plus the longer-horizon phases 13-20. These are planning documents only — no code changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The suite did not boot: `require('electron').app` was undefined at
test.js:51, so nothing ran and the ~149 project-format tests were
unverifiable.
Root cause was ELECTRON_RUN_AS_NODE=1 in the inherited environment. VS
Code sets it in integrated terminals and in the extension host, so the
Electron binary booted as plain Node and `require('electron')` returned
the CLI shim path rather than the API object. That is why the suite could
be reported green on another machine in February and be dead here.
- Add packages/noodl-editor/scripts/run-electron-tests.js, which spawns
the Electron binary directly with the variable stripped and propagates
the exit code. Strip it in scripts/test-editor.ts as well.
- Guard test.js so the failure names its own cause instead of throwing an
opaque TypeError.
The harness also had no results path at all — it could never have failed
a build. test.js now receives Jasmine results over IPC from a reporter in
SpecRunner.html and exits non-zero on failures, on zero specs, on a
renderer crash, if the window closes early, or after a 15-minute
watchdog. webpack.test.js carries the child's code out through the dev
server.
`test:ci` could never have worked either: webpack.test-ci.js inherited
the dev-server onListening Electron spawn, and SpecRunner.html hard-coded
the bundle URL to localhost:8081 with no server running. CI now builds to
disk and runs with a hidden window. Adds a root `test:ci` script.
Pin Jasmine to random: false. The suite shares global state
(ProjectModel.instance, NodeLibrary registration) and two export specs
passed or failed depending on the seed.
Test fixes surfaced once the harness ran:
- tests/utils/ParameterValueResolver.test.ts imported @jest/globals,
which throws at module load and was taking down the entire run.
- Two schema-validator specs used Jest's substring toThrow; Jasmine
compares the whole thrown value.
- ParameterValueResolver.toNumber(null) returned 0 against its own
documented contract, because Number(null) is 0. Real bug, no
production callers yet.
Quarantines one spec as xit: renaming a component port does not
propagate to instances in other graphs, which silently breaks every
existing wiring to that port. Genuine editor bug, tracked in
REV-002-NOTES.md along with the other follow-ups.
540 specs, 539 pass. Three consecutive runs at exit 0, and a
deliberately broken tests/io/ assertion was reported and exited 1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Brings in STYLE-001 style tokens and the TASK-009 embedded template system. Merged after REV-002 restored the test harness, so this is the first time the branch could be verified rather than assumed. Both branches independently implemented ElementConfigs, with different architectures and different consumers — 9 of the 14 conflicts were add/add on those files. Kept cline-dev's version, which compiles and is wired into the property-panel UI, and dropped tara's registry plus its two call sites: NodeGraphNode's applyDefaults-on-construction (cline-dev already applies defaults via NodePicker, so both would double-apply) and router.tsx's initElementConfigs (cline-dev's registry self-registers at module load). Dropped tara's ImageConfig: it is written against her type shape and would not typecheck. Porting it surfaced a pre-existing bug — net.noodl.visual.group and net.noodl.visual.image are not real node types, so cline-dev's GroupConfig is dead config that has never matched anything. Fixing that changes node-creation behaviour and belongs in its own task, not a merge commit. In LocalProjectsModel, took tara's embedded-template flow for new projects but kept cline-dev's runtimeVersion = 'react19', which her January branch predates and would otherwise have regressed. Undid tara's LEARNINGS.md -> LEARNINGS_TARA.md rename, which would have deleted a file that .clinerules and 10+ docs reference by path; her two unique sections were folded into LEARNINGS.md instead. Verified: typecheck:editor clean, and test:ci reports 540 specs, 0 failures, exit 0. Not verified: the editor was not launched against this tree. StyleTokens and the template system have no automated coverage. See dev-docs/reviews/MERGE-NOTES-cline-dev-tara.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ging
The editor opened a black window. Root cause was two layers of stale
build artefact, neither of which announced itself.
Renderer: src/editor/index.html picks its bundle at runtime —
const path = process.env.devMode !== 'yes' ? '.' : 'http://localhost:8080/src/editor';
Nothing in the repo ever set devMode to 'yes' (only test.js sets it, to
'test'), so the editor always loaded ./index.bundle.js from disk while
the webpack dev server served fresh code to nobody. HMR did nothing and
code changes were invisible. The bundle on disk happened to be a
production build, which pairs production react-dom with the externalised
development react, and that throws before first paint:
TypeError: dispatcher.getOwner is not a function
at getOwner (node_modules/react/cjs/react.development.js:416)
at createDialogLayer (router.tsx:59)
getOwner is dev-only ownership tracking; production react-dom never
installs it. main.js now sets devMode = 'yes' when --dev is passed.
Main process: src/main/main.bundle.js is the Electron entry point, and
the dev flow only ever ran webpack-dev-server for the renderer — there
was no dev config for main at all. The committed bundle was six months
old, so main-process edits did nothing in dev. Adds webpack.main.dev.js
and rebuilds it from scripts/start.ts on every dev launch.
Also strips ELECTRON_RUN_AS_NODE from the dev launch path. VS Code sets
it in integrated terminals and the extension host, and it makes the
Electron binary boot as plain Node so electron.app is undefined and no
window ever opens. REV-002 fixed this for the test harness; the dev path
had the same bug.
Debugging visibility, so this class of failure is diagnosable next time:
- scripts/devtools/cdp.js — DevTools Protocol client: health (is React
mounted?), eval, console streaming with uncaught exceptions,
screenshot, dom, wait, reload. Screenshots go through the compositor,
so they need no OS screen-recording permission.
- scripts/devtools/dev-debug.js + `npm run dev:debug` — launches the
stack with the CDP endpoint on and tees viewer, cloud runtime, editor
and renderer output to .logs/dev.log.
- main.js mirrors renderer console, crashes and load failures into main
process stdout in dev; previously a renderer that died on startup
looked identical to one that booted fine.
- .claude/skills/run-editor documents the workflow and the traps.
Verified: the launcher renders (CDP reports React mounted, screenshot
shows the projects list), typecheck:editor clean, test:ci 540 specs 0
failures.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Captures the follow-up work from the 2026-07-22 session in a form a fresh session can pick up cold, since none of this context survives otherwise. Four streams: A. Committed build artefacts (critical). 42 tracked *.bundle.js, 23.8 MB, including all three entry points — main, editor renderer, viewer frame. These are the root enabler of the stale-bundle bugs fixed in 1502581: generated files living in src/, indistinguishable from source. All three were last committed in 297dfe0, the same bulk commit that introduced the duplicate ElementConfigs. Untracking them touches packaging, so it needs clean-clone verification rather than a quick rm. B. Remaining visibility gaps: the viewer/preview frame, main-process --inspect, a service health check, click/type input for scripted UI verification, and automatic capture of startup exceptions. C. Screen-recording permission. A black `screencapture` frame is macOS withholding another app's window, not a failed render — it was misread as a crash during the session. Documents CDP-first (no permission needed) with the native-chrome escape hatch. D. cline-dev-tara verification debt. The suite is green but exercises none of what the merge brought in: StyleTokens and the embedded template system have never run, and LocalProjectsModel.newProject combines tara's template flow with cline-dev's react19 default in a combination that has never executed. Also the dead ElementConfigs node types (net.noodl.visual.group/image do not exist), the dropped ImageConfig, and three Jest specs stranded in a Jasmine runner. Also records the merge and dev-loop fix in the phase history, and adds REV-008 to the phase tracker and revival index. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stream A. packages/noodl-editor/src/main/main.bundle.js and src/editor/index.bundle.js were committed webpack output living in src/, indistinguishable from source. That is the root enabler for the black-window bug fixed in 1502581: a months-old bundle ran instead of the code beside it, and main-process edits did nothing in dev. Untracks 186 generated files (~24 MB): the three entry bundles, their split chunks, the Monaco workers and the file-loader SVGs webpack emits into the package root. All are regenerated by `npm run build:editor`; `npm run dev` rebuilds main. The vendored parse-dashboard bundles stay tracked — nothing in this repo rebuilds those. Adds `npm run check:artefacts` and a CI workflow so they cannot come back silently, and drops the `npm install electron-notarize` that every macOS build ran, which wrote a dependency into the root package.json and left the tree dirty for nothing (build/macos-notarize.js is a no-op stub).
…gaps Streams B and C, plus two packaging defects that Stream A's clean-clone verification uncovered. Both were pre-existing and both were invisible: the packaged app opened a black window and said nothing about why. Packaging: - react/react-dom are webpack externals, so the packaged app require()s them at runtime. react/index.js picks dev vs production from process.env.NODE_ENV, which is unset in a packaged Electron app, so *development* react was paired with the *production* react-dom the build produced. React 19's shared internals differ, and it throws `dispatcher.getOwner is not a function` before first paint. main.js now sets NODE_ENV=production when not in dev. - split2, crelt, style-mod and w3c-keyname are externalised (they are hoisted into the root node_modules) but were not declared by noodl-editor, so electron-builder never collected them. `Cannot find module 'split2'` killed the renderer at boot. They are transitive deps of the file: workspace packages @noodl/git and @noodl/noodl-core-ui. - main.js gains the ELECTRON_RUN_AS_NODE guard test.js already had. Without it the app exits 0 with no output when launched from a VS Code terminal, which looks exactly like a successful launch. Visibility (Stream B): - cdp.js takes --target=editor|viewer, so the preview window is inspectable. Asking for a viewer that is not running is an error, never a silent fall back. - `cdp services` probes every dev port plus the freshness of the viewer and cloud-runtime builds, which are watch builds with no port to probe. Both stacks are probed: the dev server binds localhost, which resolves to ::1 first on macOS, and an IPv4-only check calls a healthy server down. - `cdp click` and `cdp type` drive Input.dispatchMouseEvent / Input.insertText rather than synthetic DOM events, so React handlers and focus behave. - dev-debug.js attaches to each page over CDP as it appears and writes [renderer:exception] into .logs/dev.log, so a boot crash is recorded without anyone having to attach in time to see it. - The main process is debuggable at last: --inspect has to reach the Electron binary, so start:_dev goes through a launcher (scripts/start-electron-dev.js) driven by NOODL_MAIN_INSPECT_PORT. `npm run dev:debug -- --inspect-main`. Docs (Stream C): both DEBUG-INFRASTRUCTURE.md and the run-editor skill now say CDP-first for screenshots, and that a black `screencapture` frame is a macOS permission belonging to the capturing app — not a crashed editor. That misreading cost real time on 2026-07-22.
…d two specs The NODE_ENV assignment added in the previous commit never shipped. In a production build webpack's DefinePlugin substitutes the literal expression `process.env.NODE_ENV` at compile time, so the dotted form became `"production" = "production"` and the whole branch was dropped as dead code — the packaged app still opened black. Computed member access is not substituted. Caught by `cdp health` against a clean-clone packaged build, which is the point of having it. Also converts the Jest-only specs under tests/models to Jasmine and starts re-enabling them one at a time: expression-parameter and ElementConfigRegistry are in, 540 -> 595 specs, 0 failures. Contrary to the merge notes, ElementConfigRegistry.test targets the registry that survived the merge, not tara's class API, so it needed no rewrite.
Stream D4. 540 -> 695 specs, 0 failures. Enabled one at a time with test:ci
between each, since a bad import takes down the whole Electron run.
Conversions beyond dropping the @jest/globals import:
- toHaveLength -> toHaveSize (Jasmine 3.7 has no toHaveLength).
- it.each -> a generated loop; Jasmine has no equivalent.
- StyleAnalyzer used jest.mock on the projectmodel module. Jasmine has no module
mocking, and assigning ProjectModel.instance is not viable either — its setter
registers the value with NodeLibrary and would do real work on a fake. It only
ever reads the getter at call time, so spyOnProperty is enough.
Two specs were not merely stranded but wrong, which is what six months of never
running buys you:
- UBAConditions built its fixture from flat dotted keys ('auth.type': 'bearer'),
but evaluateCondition resolves the field with getNestedValue, which needs a
nested object. Six specs failed on first run. Fixture fixed; the
implementation is correct.
- ProjectCreationWizard defined its own copies of getStepSequence and isStepValid
and asserted against those — it never imported WizardContext, so it could not
have caught any regression. The two helpers are now exported from
WizardContext and the copies are gone.
Contrary to the merge notes, ElementConfigRegistry.test targets the registry that
survived the merge, not tara's class API, and needed no rewrite.
…fault Stream D1. 695 -> 704 specs. The embedded template system and the runtimeVersion new projects get both arrived with the cline-dev-tara merge with zero coverage, and the specific combination had never executed: the merge took tara's template flow in newProject while keeping cline-dev's react19, which her January branch predates. Verified: the provider writes a project.json with components, a root component, and a graph object on every component — the missing-graph case is the crash recorded in LEARNINGS.md — and runtimeVersion round-trips through ProjectModel.
…REV-009
Stream D2/D3. GroupConfig keyed on 'net.noodl.visual.group', which is not a node
type — the real one is 'Group' — so it had never applied to anything. Deleted
rather than repointed, and tara's ImageConfig not ported, because activating
either would stamp var(--surface), var(--space-4) and friends onto new nodes and
nothing defines those.
That is the wider finding, written up as REV-009: the style-token system was
never connected. StyleTokensInjector is not constructed anywhere, so no tokens
reach a preview; the ten tokens that did ship use a different vocabulary from the
one ElementConfigs references, which exists only in the phase-9 design docs. And
ElementConfigs is live — every new Text node is persisted with
fontFamily: var(--font-sans) and four more values that resolve to nothing.
ElementConfigRegistry.test had the same identifier confusion: its TEXT_TYPE was
'net.noodl.visual.text', matching no config, so its 'no sizes' assertion passed
for the wrong reason. Now split into a registered-type case ('Text') and an
unregistered-type case.
705 specs, 0 failures. typecheck:editor clean.
Ticks the REV-008 checklist, updates the phase-12 tracker, and adds REV-009 to it. Two findings the task spec could not have anticipated are called out at the top of REV-008: the packaged app had never launched (found by insisting on a genuinely clean-clone verification), and D1's style-token verification is impossible because the injector is never constructed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Everything on local
cline-devsinced1dacbd. Merging this brings the remote up to date with work that was verified locally but never pushed.What's included, oldest first
45ac274, see MERGE-NOTES-cline-dev-tara.md1502581)cline-devSuite at the tip: 705 specs, 0 failures.
typecheck:editorclean.REV-008 — trustworthy dev loop, visibility, and merge verification debt
The most substantial piece, implementing REV-008. Suite 540 → 705 specs.
Stream A — committed build artefacts
186 generated files (~24 MB) untracked: the three entry bundles, their split chunks, the Monaco workers, and the file-loader SVGs webpack emits into the package root. These were committed build output living in
src/, indistinguishable from source — the root enabler for the black-window bug fixed in1502581, and the reason every dev run left the working tree dirty. The vendored parse-dashboard bundles stay tracked; nothing in this repo rebuilds those.npm run check:artefactsplus a CI workflow stop it coming back.The packaged app had never launched
Verifying Stream A from a genuinely clean clone — which the task insisted on — surfaced two pre-existing defects with nothing to do with tracked bundles:
dispatcher.getOwner is not a function.react/react-domare webpack externals, so the packaged apprequire()s them at runtime.react/index.jspicks dev vs production fromprocess.env.NODE_ENV, unset in a packaged Electron app, so development react was paired with the production react-dom the build had just produced. React 19's shared internals differ, and it throws before first paint. This is the same error the REV-008 background attributes to a stale bundle in dev — but here in a fresh production build, which means the packaged app was equally broken all along.Cannot find module 'split2'.split2,crelt,style-modandw3c-keynameare externalised (hoisted to the rootnode_modulesas transitive deps of thefile:workspace packages@noodl/gitand@noodl/noodl-core-ui) but never declared bynoodl-editor, so electron-builder did not collect them.The
NODE_ENVfix nearly shipped as a no-op: webpack's DefinePlugin constant-folds the dottedprocess.env.NODE_ENV, so the branch was dropped as dead code.cdp healthagainst the packaged build caught it — which is the point of having it. Computed member access survives.A clean clone now produces a
.dmgwhose app renders, verified via CDP.Stream B — visibility
cdp.jstakes--target=editor|viewer, so the preview window is inspectable. Requesting a viewer that isn't running is an error, never a silent fall back to the editor.cdp servicesprobes every dev port plus the freshness of the viewer/cloud-runtime watch builds. Both IP stacks are probed — the dev server bindslocalhost, which resolves to::1first on macOS, and an IPv4-only check reports a healthy server as down.cdp click/cdp typedriveInput.dispatchMouseEventandInput.insertTextrather than synthetic DOM events, so React handlers and focus behave as they do for a user.dev-debug.jsattaches over CDP as each page appears and writes[renderer:exception]into.logs/dev.log, so a boot crash is recorded without anyone attaching in time to see it.--inspecthas to reach the Electron binary, sostart:_devgoes through a launcher.npm run dev:debug -- --inspect-main.main.jsgains theELECTRON_RUN_AS_NODEguardtest.jsalready had. Without it the app exits 0 with no output when launched from a VS Code terminal — indistinguishable from a successful launch.Stream C — screenshots
Both
DEBUG-INFRASTRUCTURE.mdand therun-editorskill now say CDP-first, and that a blackscreencaptureframe is a macOS permission belonging to the capturing app, not a crashed editor.Stream D — merge verification debt
runtimeVersion = 'react19'). Style-token injection was also meant to be verified here; it cannot be, because nothing ever constructsStyleTokensInjector. See below.GroupConfigkeyed onnet.noodl.visual.group, which is not a node type. Deleted rather than repointed, and tara'sImageConfignot ported: activating either would stampvar(--surface),var(--space-4)and friends onto new nodes, and nothing defines those.@jest/globalsimport:toHaveLength→toHaveSize,it.each→ a generated loop, andjest.mock→spyOnProperty(assigningProjectModel.instanceis not viable — its setter registers the value withNodeLibrary).Two specs were not merely stranded but wrong, which is what six months of never running buys you:
UBAConditionsbuilt its fixture from flat dotted keys ('auth.type': 'bearer'), butevaluateConditionresolves fields withgetNestedValue, which needs a nested object. Six specs failed on first run; the implementation is correct, the fixture was not.ProjectCreationWizarddefined its own copies ofgetStepSequenceandisStepValidand asserted against those, with a comment saying "if the context logic changes, update both files". It never importedWizardContext, so it could not have caught any regression. The two helpers are now exported and the copies are gone.Contrary to the merge notes,
ElementConfigRegistry.testtargets the registry that survived the merge, not tara's class API, and needed no rewrite.Follow-up opened
REV-009 — the style-token system was never connected to anything.
StyleTokensInjectoris never constructed, so no tokens reach a preview; the ten tokens that did ship use a different vocabulary from the oneElementConfigsreferences (which exists only in the phase-9 design docs); andElementConfigsis live, persistingfontFamily: var(--font-sans)and four more unresolvable values into every new Text node. Needs a product decision, not a mechanical fix.Verification
npm run test:ci— 705 specs, 0 failures, exit 0npm run typecheck:editor— cleannpm install→npm run build:editor→.dmg+.app; launched withcdp health→reactMounted: truenpm run dev:debug -- --inspect-main→cdp healthreactMounted: true,cdp servicesall up, and the working tree stays clean after a dev runWorkflow change
.clinerulesnow says to work directly oncline-dev— single developer, so a task branch plus a PR adds a merge step and a review round-trip with nobody on the other end. The not-yet-started phase-12 specs have theirBranch:field and "open PR" checklist items updated to match. This is expected to be the last PR of this kind.🤖 Generated with Claude Code