Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1591 commits
Select commit Hold shift + click to select a range
00adecd
fix(code editor): one linter, Noodl. completes, and a selection you c…
richardosborne14 Aug 5, 2026
607d443
docs(phase 42): TALK-003 had — Record moves to the canvas, and the tr…
richardosborne14 Aug 5, 2026
b3ec357
docs(TALK-007): a cloud function is a Node 22 script — measured, not …
richardosborne14 Aug 5, 2026
ab41b7f
docs(phase 42): TALK-004 had — there is no URL, and the door we drew …
richardosborne14 Aug 5, 2026
b1c895f
docs(TALK-005): had — a standalone Subscribe To Changes node, and no …
richardosborne14 Aug 5, 2026
eadee1b
docs(TALK-006): had — both ports stay, and the ports get a tab of the…
richardosborne14 Aug 5, 2026
942f53e
fix(cloud runtime): the shared node list can finally subtract (TALK-0…
richardosborne14 Aug 5, 2026
9665156
docs(phase 42): the cloud-function half of the CWF track — ten tasks,…
richardosborne14 Aug 5, 2026
7a9ddc3
fix(core-ui): the selected list row is a surface now, not an inverted…
richardosborne14 Aug 5, 2026
f018eb4
test(cloud): the array loop already works — and the drive found a hang
richardosborne14 Aug 5, 2026
4bf7536
fix(props panel): a select no longer hides its own current value, and…
richardosborne14 Aug 5, 2026
5270e34
fix(canvas): an expression-valued node name now reads as the expressi…
richardosborne14 Aug 5, 2026
664ac15
fix(viewer): Block Pointer Events now actually blocks a Button's click
richardosborne14 Aug 5, 2026
2ad567b
fix(popouts): the code and JSON editors are measured before they are …
richardosborne14 Aug 5, 2026
b8cb27f
fix(props panel): labels wrap and the label column grows with the panel
richardosborne14 Aug 5, 2026
68b2671
fix(library): the whole shipped library wore Roboto, and one import p…
richardosborne14 Aug 5, 2026
f35601c
feat(viewer): a click now stops at the node that is using it
richardosborne14 Aug 5, 2026
469ddb4
feat(object node): the Object node now outputs the object, not just i…
richardosborne14 Aug 5, 2026
3e7918e
fix(execution overlay): pinning another workflow's run now takes you …
richardosborne14 Aug 5, 2026
21e1cbb
fix(canvas): a wire label chip can be grabbed anywhere it is painted,…
richardosborne14 Aug 5, 2026
ed50e36
fix(explain): the Explain panel can hold the node you selected
richardosborne14 Aug 5, 2026
5738263
feat(outcome contract): Completed now says when it is the same pulse …
richardosborne14 Aug 5, 2026
328a025
fix(counter): Reset now reports Unchanged instead of pretending it mo…
richardosborne14 Aug 5, 2026
9b1e8ca
fix(observe): the MCP server survives an editor restart instead of dy…
richardosborne14 Aug 5, 2026
41e32bd
fix(version control): the Create/Connect Repository dialog opens over…
richardosborne14 Aug 5, 2026
ad78d3a
feat(property panel): a Ports tab, so you can read what every port on…
richardosborne14 Aug 5, 2026
5b5ac1c
fix(ports tab): drop a listener for an event that never changes the list
richardosborne14 Aug 5, 2026
2d86376
feat(cwf-017): you can say who may call each cloud function, and how …
richardosborne14 Aug 5, 2026
bc6a981
feat(cwf-017): the Permissions panel now shows who can call each clou…
richardosborne14 Aug 5, 2026
d0d74a9
docs(cwf-017): correct three mechanisms the task doc had wrong
richardosborne14 Aug 5, 2026
097cecb
feat(packaging): ship both MCP servers in the packaged app — and actu…
richardosborne14 Aug 5, 2026
6df2d28
fix(provenance): Record now records — the buffer is pulled while you …
richardosborne14 Aug 5, 2026
e307276
fix(canvas specs): the comment-stripe specs stub the node title the p…
richardosborne14 Aug 5, 2026
045eb7f
feat(cloud runtime): a cloud function can finally build, filter and r…
richardosborne14 Aug 5, 2026
9b2de48
feat(cloud runtime): a cloud function can call an API with the modern…
richardosborne14 Aug 5, 2026
24b25be
docs(phase 42): the register catches up — twelve tasks, then eight mo…
richardosborne14 Aug 6, 2026
958444a
fix(backend): the config endpoint no longer hands every caller every …
richardosborne14 Aug 6, 2026
54298d5
feat(settings): a "Connect an AI agent" section that hands you the tw…
richardosborne14 Aug 6, 2026
ed372ae
docs(mcp): both server READMEs now tell the same story as the Copy bu…
richardosborne14 Aug 6, 2026
424c6f6
feat(record): Record is now a control on the canvas, and it tells you…
richardosborne14 Aug 6, 2026
290e694
fix(cloud functions): a function that never answers now says so inste…
richardosborne14 Aug 6, 2026
8768449
docs(cwf-018): say precisely which of the doc's premises was wrong
richardosborne14 Aug 6, 2026
407a953
feat(code editor): autocomplete that knows your project
richardosborne14 Aug 6, 2026
8246c95
feat(record): the nodes light up as they fire while you are recording
richardosborne14 Aug 6, 2026
16ddc70
feat(FH-021): a standalone Subscribe To Changes node, and the filter …
richardosborne14 Aug 6, 2026
dbd3116
feat(config node): the Config node is gone, and so is the browser pat…
richardosborne14 Aug 6, 2026
c61c173
docs(node audit): the Config rows are closed by deleting the node, no…
richardosborne14 Aug 6, 2026
3fb06d0
feat(cloud functions): a cloud function can ask for a secret by name,…
richardosborne14 Aug 6, 2026
f73af14
feat(crypto): hash, random bytes, UUID, HMAC and JWT as nodes, with n…
richardosborne14 Aug 6, 2026
51f0031
feat(dates): Now, Date Add, Date Difference, Date Compare and Date Pa…
richardosborne14 Aug 6, 2026
53e1d4c
test(email): the Send Email specs wire ports that exist, and stop han…
richardosborne14 Aug 6, 2026
0592c3d
docs(phase 42): the register catches up with the third batch, and wha…
richardosborne14 Aug 6, 2026
a3c9248
feat(record): expand the recording pill to see what you just did, and…
richardosborne14 Aug 6, 2026
37aa8c9
docs(FH-023): the four prefabs that lost their keys, and what the bri…
richardosborne14 Aug 6, 2026
4b3c95f
feat(FH-023): the four prefabs read their keys from the backend again…
richardosborne14 Aug 6, 2026
ef774c1
feat(cwf-015): a cloud function can create and administer accounts as…
richardosborne14 Aug 6, 2026
ea4ad24
feat(CSV): Parse CSV and To CSV, on the parser Static Array has had a…
richardosborne14 Aug 6, 2026
d3b7f15
feat(workflow return): a workflow can say what it answers with, and t…
richardosborne14 Aug 6, 2026
97b3fc0
feat(call function): say what a step passes the function, in a row yo…
richardosborne14 Aug 6, 2026
ed6ff14
docs(CWF-001): the task doc says what it got wrong, and closes
richardosborne14 Aug 6, 2026
89155d8
feat(cloud functions): a Request parameter can say what it is, and a …
richardosborne14 Aug 6, 2026
85662cc
fix(tests): the workflow catalog suite compiles again, so every other…
richardosborne14 Aug 6, 2026
33fe96a
feat(log): a cloud function can log, the line carries the request id,…
richardosborne14 Aug 6, 2026
1451bce
fix(retry): the attempt count says it counts the first call, and the …
richardosborne14 Aug 6, 2026
d10c5a3
feat(retry): retrying is something a Call Function does, not a card o…
richardosborne14 Aug 6, 2026
7f8c213
docs(CWF-005): the task doc records the four things it got wrong, and…
richardosborne14 Aug 6, 2026
784d946
fix(record): an agent starting a trace no longer destroys the recordi…
richardosborne14 Aug 6, 2026
1456c78
fix(log): register the Log node the catalog already advertises
richardosborne14 Aug 6, 2026
a8a5b30
fix(workflow review): a proposal is reviewed as the backend would sto…
richardosborne14 Aug 6, 2026
71e80e2
docs(CWF-005): the third reader the fold's migration note missed
richardosborne14 Aug 6, 2026
29fdd0c
docs(phase 42): the register closes the day — 23 tasks, and the six t…
richardosborne14 Aug 6, 2026
8270fab
docs: one handover across phases 39, 40 and 42 — and phase 39's is ma…
richardosborne14 Aug 6, 2026
d7258ae
docs(phase 39): the register said 16 of 16 and 15 in the same breath …
richardosborne14 Aug 6, 2026
80daf4c
docs: four decisions Richard took on 2026-08-06, and a register put b…
richardosborne14 Aug 6, 2026
edb8661
fix(backend): the three phase-42 loose ends where something was writt…
richardosborne14 Aug 6, 2026
3172f84
docs(phase 42): three filed-not-fixed rows struck, and the two the do…
richardosborne14 Aug 6, 2026
766a4db
docs(live QA): the twenty-three tasks are driven — and two register r…
richardosborne14 Aug 6, 2026
240bf0c
feat(AAQ-011/F10): a spawned backend is recorded on disk, and the nex…
richardosborne14 Aug 6, 2026
e45bc02
feat(AAQ-011/F13): the durable spawn record and the reaper that makes…
richardosborne14 Aug 6, 2026
1e20488
fix(AAQ-011 F1): the drag ghost's background was a primitive, its tex…
richardosborne14 Aug 6, 2026
47a5987
fix(POL-017): Shy text was muted text, and the criterion asked for mo…
richardosborne14 Aug 6, 2026
7b9440b
docs(POL-017): the harness re-run criterion 4 names has not been done
richardosborne14 Aug 6, 2026
339b300
fix(router): the warning that outlived the fault it described
richardosborne14 Aug 6, 2026
6157963
fix(review): the built-in backend's collections are readable, so say …
richardosborne14 Aug 6, 2026
2994e48
feat(AAQ-011/F10): the project's backend follows the project — start …
richardosborne14 Aug 6, 2026
460f17e
feat(AAQ-011/F13): noodl-mcp provisions backends — an agent can build…
richardosborne14 Aug 6, 2026
8adc083
docs(AAQ-011): F13 closed — the design, and the orphan mechanism the …
richardosborne14 Aug 6, 2026
7e76c70
feat(AAQ-011/F10): the auto-start is visible — delayed spinner, silen…
richardosborne14 Aug 6, 2026
1c9fb9d
docs(AAQ-011): F8 and F9 closed, and the contradiction that made F9 l…
richardosborne14 Aug 6, 2026
be28f6c
fix(NDA-017): a saved untick is applied before the value it governs
richardosborne14 Aug 6, 2026
a4c9b87
feat(NDA-017): projects authored before §2 are migrated on load
richardosborne14 Aug 6, 2026
6640dfc
fix(AAQ-011/F10): one spawn record, not two — converge the editor ont…
richardosborne14 Aug 6, 2026
14c9395
docs(NDA-017): §4 — the migration, built, and two premises that did n…
richardosborne14 Aug 6, 2026
fc7f5b3
docs(NDA-017): correct the node counts in the blast-radius table
richardosborne14 Aug 6, 2026
b4af5ab
fix(AAQ-011/F13): a pid is not a session — the reaper was skipping th…
richardosborne14 Aug 6, 2026
1da7a13
fix(AAQ-011 F11): a missing backend SELECTION is not a broken backend
richardosborne14 Aug 6, 2026
fc62391
fix(POL-019): the topbar's left group painted over its right cluster
richardosborne14 Aug 6, 2026
840a0d1
docs(handover): the second session — the live QA is paid, and three r…
richardosborne14 Aug 6, 2026
a249c78
docs(POL-017): the register outlived its own fix, for the fourth time
richardosborne14 Aug 6, 2026
4aba4eb
feat(CWF-009): the secrets door an editor panel can call, names out a…
richardosborne14 Aug 6, 2026
25e9696
feat(CWF-018): the time limit gets its row beside the rate limit
richardosborne14 Aug 6, 2026
9809616
fix(CWF-013): the Execution History empty state was true for half the…
richardosborne14 Aug 6, 2026
46ce9f6
docs(phase-42): close three filed-not-fixed rows, and the task docs t…
richardosborne14 Aug 6, 2026
9446e6f
fix(phase 42): Array Map refused to run the script the editor was sho…
richardosborne14 Aug 6, 2026
25bee50
docs(phase 42): close the inert-defaults row — and correct the half o…
richardosborne14 Aug 6, 2026
0553049
docs(handover): the same three rows, closed in NEXT-SESSION too
richardosborne14 Aug 6, 2026
4d1520f
perf(AAQ-011 F6): the 6m51s was the fixture's setTimeout in an occlud…
richardosborne14 Aug 6, 2026
594d651
docs(AAQ-011): close F6 — the register's own number was wall clock, n…
richardosborne14 Aug 6, 2026
6b631b6
docs(AAQ-011 F6): say what the intensive tier measured, not what it i…
richardosborne14 Aug 6, 2026
d2b1077
fix(AAQ-011 F7): a page with no Page node is a refusal, not a warning
richardosborne14 Aug 6, 2026
d7f169d
docs(AAQ-011 F7): closed — and the row's own fixture count was 3.5x t…
richardosborne14 Aug 6, 2026
54d94fc
feat(CWF-004): reshaping a payload is workflow work — the transform step
richardosborne14 Aug 6, 2026
d5a24e6
docs(FH-024): loopback is not a trust boundary against a browser
richardosborne14 Aug 6, 2026
0f88b09
docs(handover): four more rows that outlived their fixes, and FH-024 …
richardosborne14 Aug 6, 2026
db53cd0
docs(handover): the third session — a phase gate that was never real,…
richardosborne14 Aug 6, 2026
8868d74
docs(phase-42): record Richard's last three owed decisions — FH-024, …
richardosborne14 Aug 6, 2026
c87c120
docs(CWF-016): slice 1 — the design decided, and a trap that pointed …
richardosborne14 Aug 6, 2026
390b880
docs(CWF-007): the trap that decides whether layer 2 exists, measured
richardosborne14 Aug 6, 2026
029711f
fix(AAQ-011 F12): a node id written through noodl-mcp cannot collide
richardosborne14 Aug 6, 2026
4c53950
fix(AAQ-011 F3): recording is not a question — the turn ends at recor…
richardosborne14 Aug 6, 2026
e49a1fd
docs(AAQ-011 F3): closed — the row's own remedy was the wrong one
richardosborne14 Aug 6, 2026
fb0f047
fix(FH-024): loopback is not a trust boundary, and the drive proved i…
richardosborne14 Aug 6, 2026
0e7a8df
feat(CWF-004): slice 2 — the rest of the declarative data family
richardosborne14 Aug 6, 2026
e6a9242
docs(phase-42): the fifth batch — register consolidated on the settle…
richardosborne14 Aug 6, 2026
28cf428
docs(handover): the fourth session — every owed decision taken, and a…
richardosborne14 Aug 6, 2026
77ff683
fix(CWF-015): impersonate() minted a session no reader on this backen…
richardosborne14 Aug 6, 2026
9b40260
feat(CWF-004 S6): the plan behind "new function from this step", in p…
richardosborne14 Aug 6, 2026
bd597a4
docs(FH-025): the row was stale — the prefabs are fixed, the tables a…
richardosborne14 Aug 6, 2026
f6a22fc
feat(CWF-016): slice 2 — the claim IS the row, and the test that prov…
richardosborne14 Aug 6, 2026
9227928
fix(FH-025): the deleted node type had two rows, and the guard that k…
richardosborne14 Aug 6, 2026
4ab54f3
feat(CWF-004 S6): create the function a broken step is asking for, an…
richardosborne14 Aug 6, 2026
e92e18e
docs(CWF-007): the last three streaming questions decided — and the g…
richardosborne14 Aug 6, 2026
b71807f
docs(FH-025): close the row — stale on arrival, and the tail it hid i…
richardosborne14 Aug 6, 2026
793ac90
refactor(CWF-004 S6): which node carries a function's interface is a …
richardosborne14 Aug 6, 2026
94b2b5e
feat(CWF-016): slice 3 — the endpoint claims before it runs, and a 50…
richardosborne14 Aug 6, 2026
ff72d6c
test(CWF-004 S6): the document half — what is created, what is retarg…
richardosborne14 Aug 6, 2026
7f933c1
fix(runtime): a node id of `add` failed the whole bundle, and the id …
richardosborne14 Aug 6, 2026
ef95e9b
test(AAQ-011 F12 editor): drive the AI apply path — the collision is …
richardosborne14 Aug 6, 2026
ad55f1f
docs(phase-42): two filed-not-fixed rows closed, both with a correction
richardosborne14 Aug 6, 2026
2b2ad2a
feat(CWF-016): slice 4 — one field on the seam CWF-017 built
richardosborne14 Aug 6, 2026
af0182a
docs(CWF-004): S6 shipped, Aggregate DECIDED, and two more premises c…
richardosborne14 Aug 6, 2026
361826e
docs(CWF-016): closed — what each slice found, and the premise the bu…
richardosborne14 Aug 6, 2026
cd64462
fix(FH-024): the Execution History panel was the one admin caller tha…
richardosborne14 Aug 6, 2026
d15c841
fix(AAQ-011 F12 editor): allocate node ids at the AI apply seam, not …
richardosborne14 Aug 6, 2026
bdccb1e
docs(AAQ-011 F12): the editor half is measured and closed — allocatio…
richardosborne14 Aug 6, 2026
c30d9c2
docs(POL-017): the owed measurement, taken — the harness grades the g…
richardosborne14 Aug 6, 2026
604b66f
docs(phase-42): the second live-QA pass — FH-024 through the editor, …
richardosborne14 Aug 6, 2026
5caf366
docs(phase-42): the light-theme half of the second live-QA pass
richardosborne14 Aug 6, 2026
b5599a9
feat(AAQ-005 c3): a scripted multi-component session, applied and und…
richardosborne14 Aug 6, 2026
1cd1a01
docs(AAQ-005): criterion 3 met, with the boundary and two wrong premi…
richardosborne14 Aug 6, 2026
97415b9
chore(AAQ-005 c3): export the plan token writer from the authoring ba…
richardosborne14 Aug 6, 2026
9dc30c0
test(WFA-007): the suite that has not compiled since CWF-005, and wha…
richardosborne14 Aug 6, 2026
66e5fad
docs(phase-42): the sixth batch consolidated — gates re-run on the se…
richardosborne14 Aug 6, 2026
5e108f2
docs(handover): point the next session at the alpha, because six sess…
richardosborne14 Aug 6, 2026
251a90f
feat(AAQ-008): components by default — the two instructions that said…
richardosborne14 Aug 6, 2026
618b49a
merge: ALPHA-006 and ALPHA-007 onto cline-dev, 215 commits later
richardosborne14 Aug 6, 2026
8ff3c21
docs(ALPHA-006/007): four premises that stopped being true while the …
richardosborne14 Aug 6, 2026
194c084
style(HelpCenter): prettier, after the merge resolution
richardosborne14 Aug 6, 2026
9d98093
docs(reviews): the counter-review, and what it corrected in my own work
richardosborne14 Aug 6, 2026
80d221c
merge(ALPHA-006/007): land the alpha work that was built in a worktre…
richardosborne14 Aug 6, 2026
1bc2687
fix(F65): delete the Noodl Cloud endpoints that ship in every build a…
richardosborne14 Aug 6, 2026
21f1aaa
fix(F63): the GitHub client secret was a literal in a public repo — d…
richardosborne14 Aug 6, 2026
c1e8a76
feat(ALPHA-003 §1): scope the log that packaged builds have always wr…
richardosborne14 Aug 6, 2026
8f6c16b
fix(ALPHA-002): the extraResources check could not see the failure it…
richardosborne14 Aug 6, 2026
1acc185
feat(ALPHA-003 §2, §3): bound the diagnostic directories, and let a u…
richardosborne14 Aug 6, 2026
c12caca
fix(ALPHA-002): the Windows leg signs with the Apple certificate once…
richardosborne14 Aug 6, 2026
89cb6a1
feat(F63): show the device code, or the sign-in cannot complete
richardosborne14 Aug 6, 2026
5a93e0e
chore(F63): stop shipping the OAuth handler as readable source
richardosborne14 Aug 6, 2026
2ca1ff3
feat(ALPHA-002): a partially-published draft release is now a failing…
richardosborne14 Aug 6, 2026
3051de1
docs(reviews): what NodeGX is actually for — the fitness envelope
richardosborne14 Aug 6, 2026
1cacb3d
docs(F63): the code is fixed; the leak is not, until a human revokes …
richardosborne14 Aug 6, 2026
3d58f10
docs(ALPHA-002): the install guide sent Mac testers after a file that…
richardosborne14 Aug 6, 2026
a8e9f13
docs(ALPHA-002): the static pre-flight, and the old-name edit list
richardosborne14 Aug 6, 2026
17cc185
feat(ALPHA-003 crit. 2): a main-process crash leaves a record, and PR…
richardosborne14 Aug 6, 2026
083fa8d
docs(ALPHA-003): the premise the task was built on was wrong, at file…
richardosborne14 Aug 6, 2026
ecf399a
fix(ALPHA-002): the README sent a new reader to install OpenNoodl 1.1.0
richardosborne14 Aug 6, 2026
959f58f
docs(phase-33): the register re-measured — four rows had outlived the…
richardosborne14 Aug 6, 2026
4e5ed24
docs(phase-33): two human-gated items were asking questions the tree …
richardosborne14 Aug 6, 2026
8c37ddc
fix(ALPHA-003): the dev/packaged split in the logger has never existed
richardosborne14 Aug 6, 2026
38cf493
fix(F63): the two main.js references the device flow left behind
richardosborne14 Aug 6, 2026
42db349
docs(phase-33): ALPHA-003 closed, F78-F80 filed, and the sweep on the…
richardosborne14 Aug 6, 2026
d541e1d
docs(phase-33): the handover for the first-hour run and the go/no-go
richardosborne14 Aug 6, 2026
4235437
feat(v2): new projects are created in the decomposed format
richardosborne14 Aug 6, 2026
4d6559e
fix(v2): the version control panel could not diff a v2 project
richardosborne14 Aug 6, 2026
5046764
chore: the lockfile catches up with POL-002's Algolia removal
richardosborne14 Aug 6, 2026
2570c05
chore(observe): the CLI entrypoint was not executable
richardosborne14 Aug 6, 2026
dfbfa08
test(ERG-005): park the §1 contract specs — they describe unbuilt work
richardosborne14 Aug 6, 2026
91fcd68
docs: the task specs written alongside phases 17, 26, 37 and 41
richardosborne14 Aug 6, 2026
cb0b460
docs(phases 50-53): the four that widen the boundary, not the middle
richardosborne14 Aug 6, 2026
eabc44e
docs(phase-54): the thirteen findings from an hour of real driving
richardosborne14 Aug 6, 2026
5bf95ce
docs(phase-33): F81 filed, and ALPHA-001 Part A's §1 result
richardosborne14 Aug 6, 2026
93c22ad
fix(F89): the backend Search page says why anyone would come here
richardosborne14 Aug 6, 2026
f271204
docs(SPR-001 §1): F87 — write the ACL answer where the question gets …
richardosborne14 Aug 6, 2026
dce2110
fix(F89): don't title the intro section 'Search' under a header sayin…
richardosborne14 Aug 6, 2026
51e15f5
feat(SPR-001 §3): the rule vocabulary as a selection, not as text
richardosborne14 Aug 6, 2026
8aeea2a
fix(SPR-001/F84): the /api write path accepted a mis-shaped ACL
richardosborne14 Aug 6, 2026
72c3265
docs: renumber the alpha driving sprint 54 -> 42bis
richardosborne14 Aug 6, 2026
10973fc
fix(SPR-003 F82): the Ports tab stops calling 139 settings connectable
richardosborne14 Aug 6, 2026
f02d7fb
fix(F88): the schema Edit button had no edit path behind it
richardosborne14 Aug 6, 2026
882930c
fix(SPR-003 F92, F93): sidebar tabs claim their row; port name and ty…
richardosborne14 Aug 6, 2026
e9aab7b
feat(F86): a cloud function can put a user in a role
richardosborne14 Aug 6, 2026
9997879
feat(SPR-001 §3): collection permissions are a matrix, not five text …
richardosborne14 Aug 6, 2026
34da2ea
feat(SPR-001/F84): the data browser shows and edits the ACL
richardosborne14 Aug 6, 2026
3382742
fix(SPR-001 §3): a <p> is not allowed inside a <button>
richardosborne14 Aug 6, 2026
5db43f8
feat(F86): Add User To Role, Remove User From Role, Get User Roles
richardosborne14 Aug 6, 2026
58a48bf
feat(SPR-005): the cloud function door, made visible (F83)
richardosborne14 Aug 6, 2026
486d006
refactor(SPR-001/F84): parseAclInput answers one shape, not a union
richardosborne14 Aug 6, 2026
c6bd343
feat(SPR-004 F91/F90): a recording ends with a count and a door, and …
richardosborne14 Aug 6, 2026
7be63c1
test(SPR-001/F84): the node-creates / browser-reads round trip
richardosborne14 Aug 6, 2026
29c1fab
test(SPR-005): pin the create menu's offer, and its refusals
richardosborne14 Aug 6, 2026
15759aa
fix(SPR-003 F94): the port explainer is placed against the port it ex…
richardosborne14 Aug 6, 2026
feec4e8
fix(SPR-004 F90): re-ground the provenance pane on the signal it actu…
richardosborne14 Aug 6, 2026
c666031
fix(SPR-004 F91): count the receipt's interactions with hasTrace, not…
richardosborne14 Aug 6, 2026
5266440
docs(SPR-003 F93): the enum cap's comment outlived its reason
richardosborne14 Aug 6, 2026
0167a11
test(F86): the finding closed, driven through a real backend
richardosborne14 Aug 6, 2026
5bd7f79
fix(SPR-005): the two cloud function doors, one naming rule
richardosborne14 Aug 6, 2026
5c7b7e9
docs(F86): the role half of the model is reachable now
richardosborne14 Aug 6, 2026
3916153
fix(core-ui): unbreak the hex ratchet — it counts comments
richardosborne14 Aug 6, 2026
a41537b
fix(SPR-005): the All row gets the same glyph slot as every other sheet
richardosborne14 Aug 6, 2026
c127ffd
chore(catalog): regenerate for F86's three role nodes and F87's ACL d…
richardosborne14 Aug 6, 2026
439fdfb
fix(SPR-003 F82): the shared port helper narrowed every row to { name }
richardosborne14 Aug 6, 2026
0caec03
fix(SPR-001 F86): classify the three role nodes in the backend-requir…
richardosborne14 Aug 6, 2026
f7e20e1
docs(phase-42bis): the sprint closed — 13 findings, 8 driven, 7 new o…
richardosborne14 Aug 6, 2026
a53c014
fix(AIX-012): name the empty-plan case as loudly as the full one
richardosborne14 Aug 6, 2026
e697279
fix(PNL): the disabled cloud-function row can now take you there, and…
richardosborne14 Aug 6, 2026
e053847
fix(BCN): sort backends by newest first, let you rename one, and say …
richardosborne14 Aug 6, 2026
e8a53c9
fix(B3): point the publish target and every canonical repo link at No…
richardosborne14 Aug 6, 2026
a875f6c
docs(phase-33): close out B3/B4/B7 in the register
richardosborne14 Aug 6, 2026
642187c
fix(B6): the "only three dropdowns" correction was itself stale
richardosborne14 Aug 6, 2026
fb0cc18
docs(ALPHA-004): stage the concept set, getting-started and troublesh…
richardosborne14 Aug 7, 2026
e0894ad
docs(ALPHA-001): record the 2026-08-07 resume — partial, no bugs found
richardosborne14 Aug 7, 2026
ba682c1
docs(phase-33): handover for the next session, superseding 2026-08-06
richardosborne14 Aug 7, 2026
9ad5d71
docs(ALPHA-001): close Part A — §4/§5/§6 all walked, F102/F103 filed
richardosborne14 Aug 7, 2026
307967a
feat(ALPHA-006 §5): split getContentEndpoint() from getDocsEndpoint()
richardosborne14 Aug 7, 2026
84b4934
feat(ALPHA-006 §2/§3): a real docs-site/ and the generated node refer…
richardosborne14 Aug 7, 2026
c5c5a78
fix(node-catalog): close the enrichment coverage gap, 172/175 -> 175/175
richardosborne14 Aug 7, 2026
6165691
docs(ALPHA-006 B5): payload repo stays separate, docs publish from th…
richardosborne14 Aug 7, 2026
e3922d5
docs(ALPHA-006 §4): the migration table, all 431 files classified
richardosborne14 Aug 7, 2026
4f4d0b2
docs(phase-33): handover for the next session, superseding 2026-08-07…
richardosborne14 Aug 7, 2026
d7c3f13
fix(help-center): repoint stale OpenNoodl repo URL to NodeGX
richardosborne14 Aug 7, 2026
022fb20
fix(base-dialog): make tall dialogs scroll instead of clipping content
richardosborne14 Aug 7, 2026
fa377cc
docs(phase-33): record ALPHA-007's first live drive and F104
richardosborne14 Aug 7, 2026
7d64049
docs(phase-33): correct a stale claim in my own prior commit
richardosborne14 Aug 7, 2026
f9f6f70
docs(phase-33): handover for the next session, superseding this morni…
richardosborne14 Aug 7, 2026
b83a464
docs(phase-33): ALPHA-007 criterion 4 demonstrated live, not argued
richardosborne14 Aug 7, 2026
7493d3b
docs(phase-33): handover for getting the alpha done and live
richardosborne14 Aug 7, 2026
07e59c8
fix(ci): repair typecheck:backend-tests and TSFixme regressions found…
richardosborne14 Aug 7, 2026
6fc0439
docs(phase-33): D4 was already fixed, correct the stale row
richardosborne14 Aug 7, 2026
129a46e
fix(ci): build noodl-preview's prerequisites before test-packages run…
richardosborne14 Aug 7, 2026
e4e865e
feat(docs): add GitHub Pages deploy workflow for docs-site/ (B5)
richardosborne14 Aug 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
166 changes: 166 additions & 0 deletions .claude/skills/run-editor/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
name: run-editor
description: Launch the OpenNoodl Electron editor and inspect it headlessly — evaluate JS in the renderer, stream console output and uncaught exceptions, capture screenshots, query the DOM. Use whenever asked to run, start, debug, or screenshot the editor, or to confirm a change works in the real app rather than only in tests.
---

# Running and debugging the OpenNoodl editor

The editor is an Electron app. You can drive and inspect it entirely from the
terminal — you do not need to look at the window, and you do not need macOS
screen-recording permission.

## Launch

```bash
npm run dev:debug # full stack + CDP endpoint, logs to .logs/dev.log
npm run dev:debug -- --quiet # same, file logging only
npm run dev:debug -- --inspect-main # also open a main-process inspector on :9229
```

Always launch in the background and wait for the compile — it takes 60-90s:

```bash
nohup npm run dev:debug -- --quiet > /dev/null 2>&1 &
until grep -q "launching Electron" .logs/dev.log; do sleep 15; done
sleep 30 # renderer bundle still has to load
```

`npm run dev` also works and now behaves correctly, but has no CDP endpoint.

## Stopping

```bash
npm run dev:stop # kill the whole stack: webpack, lerna, Electron, backend
npm run dev:stop -- --list # show what is running, kill nothing
```

The stack cleans up after itself on every exit path, including `kill -9` of the
launcher — a detached watchdog polls the launcher and reaps the stack when it
dies, and `start.ts` sweeps leftovers before starting more. `dev:stop` is the
manual escape hatch for when you just want to be certain.

**Always stop the stack when you are done with it.** Three webpack watchers keep
recompiling on every file change; a stack left running for hours is the reason
this tooling exists. `dev:stop` only ever touches processes belonging to *this*
checkout, so it is safe to run with a sibling worktree's stack up.

## Inspect

```bash
npm run cdp -- health # is React mounted? one-shot verdict
npm run cdp -- services # are the dev servers and builds up?
npm run cdp -- eval "document.title" # run JS in the renderer
npm run cdp -- console 20000 # stream console + uncaught exceptions
npm run cdp -- screenshot shot.png # PNG via the compositor
npm run cdp -- dom ".launcher" html # innerText or outerHTML of a selector
npm run cdp -- wait ".project-list" 30000 # block until a selector appears
npm run cdp -- click "button.create" # real trusted click, React handlers fire
npm run cdp -- type "input[name=x]" "hi" # focus + insert text, fires onChange
npm run cdp -- reload # reload, e.g. to catch startup errors
npm run cdp -- targets # list CDP targets
```

**Start with `health`.** It reports whether the mount point has children. A window
that opens but renders nothing is the failure mode this app is prone to, and
`health` catches it in one call.

**Two renderers.** The editor and the project preview are separate windows, so
separate CDP targets. Every command takes `--target`:

```bash
npm run cdp -- health --target=viewer # the preview window
npm run cdp -- screenshot preview.png --target=viewer
```

`--target=editor` is the default. The viewer target only exists while a preview
is running; asking for it otherwise is an error rather than a silent fall back to
the editor.

`click` and `type` go through `Input.dispatchMouseEvent` / `Input.insertText`, not
synthetic DOM events, so React's handlers, focus and `:active` behave as they do
for a real user. `el.click()` from `eval` bypasses most of that — prefer these.

Startup exceptions are captured automatically: `dev:debug` attaches to each page
as it appears and writes `[renderer:exception]` lines into `.logs/dev.log`, so a
boot crash is in the log before you get there. `console` + `reload` is still the
way to watch them live.

## Screenshots — use CDP, not `screencapture`

`npm run cdp -- screenshot` renders through the browser compositor. It needs **no
OS permission**, works when the window is behind others, and covers everything
inside the window — which is nearly all of an Electron app.

**A black rectangle from macOS `screencapture` means a missing permission, not a
crashed app.** macOS gates screen capture behind Privacy & Security → Screen &
System Audio Recording, and the permission belongs to the *capturing* process —
your terminal or VS Code — not to OpenNoodl. The desktop and dock still render
normally, so the result looks exactly like an app that failed to paint. This has
already cost one session several steps chasing a crash that never happened.

If you have a black frame and are unsure which it is, run `npm run cdp -- health`.
`reactMounted: true` means the app is fine and your capture path is not.

Reach for the native path only for things outside the renderer — the OS window
frame, native menus, native dialogs, multi-window layout. That needs the
permission granted to Terminal / VS Code (then restart that app), and
Playwright's `_electron` driver is the better tool if you need it repeatedly.

Read screenshots back with the Read tool. A blank frame from *CDP* is a real
failure.

## Logs

`.logs/dev.log` holds everything: viewer, cloud runtime, editor main process, and
the renderer console (mirrored into main process stdout in dev). Grep it rather
than scrolling:

```bash
grep -iE "error|exception|failed" .logs/dev.log | grep -viE "sass|deprecat"
```

Services: web server on 8574, cloud functions on 8577, renderer dev server on
8080, CDP on 9222, main-process inspector on 9229 when asked for.
`npm run cdp -- services` probes all of them, plus the freshness of the viewer
and cloud-runtime builds in `src/external` — those are webpack watch builds
rather than servers, so they have no port to probe.

## Traps specific to this repo

**`ELECTRON_RUN_AS_NODE`** — VS Code sets this in integrated terminals and the
extension host. With it set, the Electron binary boots as plain Node,
`require('electron').app` is `undefined`, and the app dies before opening a
window. `scripts/start.ts` and the webpack dev config both strip it now, but if
you invoke `electron` yourself, strip it: `env -u ELECTRON_RUN_AS_NODE ...`.

**Stale bundles.** Two entry points are built artefacts:

- `src/editor/index.bundle.js` (renderer) — only loaded when
`process.env.devMode !== 'yes'`. `main.js` sets that in dev so the webpack dev
server is used instead. If you ever see production React in a dev stack trace,
the app is running the stale disk bundle.
- `src/main/main.bundle.js` (main process) — the actual Electron entry.
`scripts/start.ts` rebuilds it on every dev launch. Before that existed, main
process edits did nothing in dev.

Both are gitignored now, and `npm run check:artefacts` fails if they are ever
committed again — a tracked bundle is what let a months-old build masquerade as
source. If a change appears to have no effect, suspect a stale bundle before
suspecting the change.

**Single instance.** The app takes a single-instance lock; a second launch exits
with "Noodl is already running". Kill the old one first:

```bash
pkill -f "OpenNoodl/node_modules/electron/dist"
pkill -f "lerna exec"
```

Use those precise patterns. `pkill -f Electron` also matches VS Code, Discord and
any other Electron app the user is running.

## Tests

`npm run test:editor` (windowed) and `npm run test:ci` (headless) run the Jasmine
suite inside Electron. Both exit non-zero on failure. See
`dev-docs/reference/DEBUG-INFRASTRUCTURE.md`.
151 changes: 151 additions & 0 deletions .clineignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# =============================================================================
# OpenNoodl .clineignore
# =============================================================================
# This file tells Cline which folders/files to ignore when indexing the codebase.
# Place this file at the root of the OpenNoodl repository.
# =============================================================================

# -----------------------------------------------------------------------------
# Specific heavy file locations that Cline doesn't need
# -----------------------------------------------------------------------------

packages/noodl-editor/src/assets/
packages/noodl-core-ui/src/assets/
packages/noodl-editor/build/icons/
packages/noodl-editor/src/assets/
packages/noodl-editor/tests/testfs/
packages/noodl-editor/tests/recordings/

# -----------------------------------------------------------------------------
# Dependencies (MASSIVE - always ignore)
# -----------------------------------------------------------------------------
node_modules/
**/node_modules/

# -----------------------------------------------------------------------------
# Build & Distribution Output
# -----------------------------------------------------------------------------
build/
dist/
**/build/
**/dist/
publish/
**/publish/
bundles/
**/bundles/

# -----------------------------------------------------------------------------
# External Dependencies (Parse Dashboard, etc.)
# -----------------------------------------------------------------------------
deps/

# -----------------------------------------------------------------------------
# Git
# -----------------------------------------------------------------------------
.git/

# -----------------------------------------------------------------------------
# Compiled/Bundled JavaScript (not source code)
# -----------------------------------------------------------------------------
*.bundle.js
*.min.js
*.min.css
**/*.bundle.js
**/*.min.js

# Specific bundled/minified files
packages/noodl-viewer-react/static/

# -----------------------------------------------------------------------------
# Static Assets (images, fonts, etc.)
# -----------------------------------------------------------------------------
**/assets/fonts/
**/assets/images/
**/public/fonts/
**/public/images/
**/*.png
**/*.jpg
**/*.jpeg
**/*.gif
**/*.ico
**/*.woff
**/*.woff2
**/*.ttf
**/*.eot
**/*.svg
!packages/noodl-core-ui/src/**/*.svg

# -----------------------------------------------------------------------------
# Test Artifacts
# -----------------------------------------------------------------------------
coverage/
**/coverage/
**/__snapshots__/
*.snap

# -----------------------------------------------------------------------------
# IDE & Editor Configs (not needed for code understanding)
# -----------------------------------------------------------------------------
.idea/
.vscode/
*.code-workspace

# -----------------------------------------------------------------------------
# OS Generated Files
# -----------------------------------------------------------------------------
.DS_Store
Thumbs.db
*.log

# -----------------------------------------------------------------------------
# Temporary & Cache Files
# -----------------------------------------------------------------------------
.cache/
**/.cache/
*.tmp
*.temp
.eslintcache
.prettiercache

# -----------------------------------------------------------------------------
# Environment & Secrets
# -----------------------------------------------------------------------------
.env
.env.*
*.pem
*.key

# -----------------------------------------------------------------------------
# Electron Build Artifacts
# -----------------------------------------------------------------------------
packages/noodl-editor/release/
packages/noodl-editor/out/

# -----------------------------------------------------------------------------
# Storybook Build Output
# -----------------------------------------------------------------------------
storybook-static/
**/storybook-static/

# -----------------------------------------------------------------------------
# Generated Type Declarations (if separate from source)
# -----------------------------------------------------------------------------
**/*.d.ts.map

# -----------------------------------------------------------------------------
# Lock Files (package structure is in package.json)
# -----------------------------------------------------------------------------
package-lock.json
yarn.lock
pnpm-lock.yaml

# -----------------------------------------------------------------------------
# Miscellaneous Large/Unneeded Files
# -----------------------------------------------------------------------------
*.dmg
*.exe
*.AppImage
*.deb
*.rpm
*.zip
*.tar.gz
Loading
Loading