Commit Graph

8082 Commits

Author SHA1 Message Date
Connor Byrne
40c4fdae4c docs(ext-api): add JSDoc remarks for declare function exports (CR-FIX-4)
lifecycle.ts: clarify that defineNodeExtension, defineExtension, and
defineWidgetExtension are type-only exports for the npm package surface.
Runtime implementations are in extension-api-service.ts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
25c76b98cf test(I-WS.4): add lazy-serialize test framework triple
Four test files covering v1→v2 widget serialization migration:
- lazy-serialize.v1.test.ts: v1 sync serializeValue contract (8 tests)
- lazy-serialize.v2.test.ts: v2 lazy getter shape (3 tests + 17 Phase B stubs)
- lazy-serialize.migration.test.ts: null warning, index shift fallback (5 tests + 13 stubs)
- lazy-serialize.perf.test.ts: hot-path perf baselines (8 tests + 13 stubs)

Total: 24 passing tests + 43 Phase B stubs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
1975967a4e fix(ext-api/tests): TypeScript cleanup in lazy-serialize.v1
- Add V1Widget interface for proper typing
- Remove unused imports

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
77a7dee3af fix(ext-api/tests): partial TypeScript cleanup in BC tests
- Prefix unused variable with _ (cleanups → _cleanups)
- Use globalThis.setInterval for portable timer type
- Prefix unused nodeType param with _

Note: Pre-existing TS errors in other files remain (lazy-serialize, bc-04, etc.)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
ce9f61e99c test(extension-api): add lazy-serialize test stubs from I-WS.4
Phase A tests for lazy widget serialization patterns:
- v1: widget.serializeValue interception
- v2: WidgetHandle.on('beforeSerialize') contract
- migration: behavioral equivalence proofs
- perf: deferred serialization benchmarks (todo)

24 wired tests, 43 Phase B blocked todos.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
f25ef80f48 test(extension-api): improve BC test coverage and harness
- BC.02: add FIFO order test, error propagation behavior documentation
- BC.04: add positionChanged event tests (6 new tests)
- BC.07: add error isolation tests for event handlers
- BC.10: add reference equality tests for object/array values
- BC.13: implement positional drift test for serialize===false widgets
- v2Runtime: add addDOMWidget stub and widget handle improvements

Test count: 916 → 932 passed

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
b371bd97f1 fix(widget): proxy hidden to options.hidden (ADR 0010)
Change widget.hidden from a plain property to a getter/setter that
proxies to options.hidden. This ensures Vue and canvas renderers
see the same visibility state.

Fixes the dual-hidden bug where Vue renderer reads options.hidden
and canvas renderer reads widget.hidden, causing visibility desync.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
baa5af0ac8 test(bc-08): self-review improvements
- Remove unused _nextLinkId property from MockGraph interface
- Add test for out-of-bounds slot index edge case

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
89080d0a1e fix(ext-api/tf): relax knip + format pass for restacked tf
- knip.config.ts: drop `treatConfigHintsAsErrors` to false in tf only —
  tf adds test consumers of foundation's @publicAPI-tagged symbols
  (`_setDispatchImplForTesting`, `NodeExtensionOptions`, etc.) which
  makes those tags 'redundant' from knip's POV. The tags are still
  correct on foundation alone, so we keep the tag definition and just
  downgrade hint→warning here.
- knip.config.ts: extend vitest config glob to include .mts (project is
  "type": "module" so vitest configs use the .mts extension).
- bc-08/28/29/30 test files + ADR 0010: oxfmt formatting fixes after
  rebase onto restacked ext.

Cascade follow-up to STACK-HYGIENE restratification. --no-verify used
because pre-commit runs full typecheck on staged TS files and tf has 61
pre-existing typecheck errors (same count with or without this commit);
per AGENTS.md rule #8, only lint/format/knip must pass during Phase A
on the ext-api stack.
2026-05-21 14:05:22 -07:00
Connor Byrne
5638744ea7 test(extension-api): implement BC.08 v2 and migration tests for programmatic linking
Implement all 15 test stubs for BC.08 (programmatic linking) using synthetic
mock harnesses that verify the v2 API contract without requiring Phase B ECS:

bc-08.v2.test.ts (8 tests):
- NodeHandle.connect() creates links between output/input slots
- LinkHandle with stable id and isValid() tracking
- Replacing occupied input slot invalidates old LinkHandle
- TypeMismatchError thrown for incompatible slot types
- on('connectionChange') fires on both source and target handles
- disconnectInput() removes link and invalidates handle
- disconnectInput() on empty slot is no-op

bc-08.migration.test.ts (7 tests):
- v1/v2 connect() produce identical graph state
- Link IDs match between v1 and v2
- v2 throws TypeMismatchError where v1 returns null
- v1/v2 disconnectInput() leave identical state
- onConnectionsChange/connectionChange fire with equivalent payloads
- NodeHandle-based API vs raw node references
- Handle wraps same conceptual node as v1

This brings the test suite from 800 passed / 101 failed to 916 passed / 0 failed.

Note: --no-verify used because 207 pre-existing typecheck errors in other
test files (documented in RFR-12145) would fail the hook. Tests all pass.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
74ce30a2b7 docs(adr): add 0010 widget state categories
Propose Schema/Props categorization for widget state:
- Schema: immutable (type, name, constraint presence, defaults)
- Props: mutable per-instance (value, disabled, hidden, constraint values)

Aligns with Vue's component model and simplifies the mental model
for extension authors. ECS component granularity remains an
implementation detail behind the WidgetHandle facade.

Slack discussion context included. Status: Proposed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
937f3428ab test(bc-08): implement v1 programmatic linking tests
Fill 8 todo stubs with synthetic mock tests for:
- node.connect(srcSlot, targetNode, dstSlot) contract
- node.disconnectInput(slot) contract
- onConnectionsChange callback firing
- wildcard type slot compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
5eb64a9e04 test(extension-api): implement BC.28-30 test bodies for virtual nodes, graph ops, reactivity
BC.28 (S9.SG1 virtual nodes):
- v2 contract: defineVirtualNodeExtension with virtual: true and resolveConnections
- v1 contract: isVirtualNode flag + graphToPrompt rewriting patterns
- migration: mechanical rename + UWF Phase 3 resolution path

BC.29 (S11.G2, S14.ID1 graph enumeration + identity):
- v2 contract: graph.findByType/addNode/removeNode + NodeLocatorId/NodeExecutionId
- v1 contract: LiteGraph findNodesByType/add/remove/serialize/configure
- Real tests against nodeIdentification.ts implementation

BC.30 (S11.G1/G3/G4 change tracking + batching):
- v2 contract: Vue reactivity replaces _version, batchUpdate replaces beforeChange/afterChange
- v1 contract: _version polling, ref-counted batching, setDirtyCanvas
- migration: deprecation shims documented

89 real tests passing, 13 Phase B it.todo stubs for ECS-dependent cases.

Closes I-TF.8.G1

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
GitHub Action
96bb939a69 [automated] Apply ESLint and Oxfmt fixes 2026-05-21 14:05:22 -07:00
Connor Byrne
ce5910217d fix(ext-api/tf): remove duplicate test:extension-api script
Remove stub script that was pulled in from foundation rebase.
The tf branch has the real test script that runs vitest.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
c023e29d86 fix(ext-api/tf): update BC.05 test for DOM widget side table pattern
The CR-12142-3 fix moved DOM element storage from command options to a
side table for serializability. Update test to verify:
- Element NOT in command options (__domElement undefined)
- Element retrievable via getDOMWidgetElement(widgetId)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
daa4da6619 fix(v2-tests): remove unused variables for noUnusedLocals compliance
- Delete truly unused variables and functions
- Prefix intentionally unused parameters with underscore
- Use void for side-effect-only expressions

Build now passes with vue-tsc --noEmit.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
9adfa9efc2 fix(v2-tests): resolve type errors in BC pattern tests
- Fix Size type usage (tuple [width, height] not object)
- Fix entity ID branded types (strings not numbers)
- Fix WidgetValueChangeEvent<unknown> generics throughout
- Fix vi.fn() mock typing for argument counts
- Fix EventListener cast through unknown
- Fix NodeBeforeSerializeEvent.replace callable issue
- Fix VirtualNode.isVirtualNode prototype assignment
- Fix NodeExecutedEvent.output property access casts
- Update handler types in mock interfaces

Remaining 14 items are unused variable warnings (TS6133/TS6196),
not blocking compilation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
9c4fab20d9 wip(ext-api/tf): partial fix for test type errors (61 remaining)
Fixes applied:
- defineNodeExtension → defineNode (all test files)
- widgetCreated → created (WidgetExtensionOptions hook name)
- Added apiVersion field to ExtensionOptions
- Fixed entity ID casts (number → as unknown as NodeEntityId/SlotEntityId)
- Harness barrel re-exports all types from harness/index.ts

Remaining errors (~61):
- Size type mismatch ([number,number] vs {width,height})
- WidgetValue/Handler type mismatches
- Unused variable warnings
- AppEvents constraint issues
- VirtualNode.isVirtualNode property access

See I-TF.9.K* tasks in todo.md for detailed breakdown.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:05:22 -07:00
Connor Byrne
9cba5cd08a fix(ext-api/tf): apply lint:fix + oxfmt across bc-* test files
Resolves remaining lint errors blocking lint-and-format CI on PR #12145:
- Removes unused vitest imports (afterEach, beforeEach, vi) flagged by
  unused-imports/no-unused-imports across ~12 bc-*.test.ts files
- Replaces let with const where reassignment never occurred (prefer-const)
- Applies oxfmt line-width reflow across bc-* test files

CI's lint-and-format step runs lint:fix then tries to auto-commit through
husky, which triggers the full-repo typecheck. By committing the auto-fixes
locally, 'Check for changes' returns false in CI, skipping the broken
auto-commit step.

--no-verify used because husky pre-commit runs the full-repo typecheck
which still has 192 pre-existing errors documented as out-of-scope for
this PR.
2026-05-21 14:05:22 -07:00
Connor Byrne
8ee8bf6d61 fix(ext-api/tf): whitelist vitest.extension-api.config.mts in eslint allowDefaultProject (review #12145) 2026-05-21 14:05:22 -07:00
Connor Byrne
1a2c6ac8f3 fix(ext-api/tf): satisfy CI eslint:fix on test files (review #12145)
CI's pnpm lint:fix step exits non-zero on:
- bc-02.migration.test.ts: prefer-const on v1Handle (assigned once)
- bc-35.v1.test.ts: typescript-eslint/no-unsafe-function-type on the
  Function cast — replace with an explicit signature

Both errors block the [automated] auto-format push back to the PR.
2026-05-21 14:05:22 -07:00
Connor Byrne
77954e3913 fix(ext-api/tf): merge duplicate vitest imports (review #12145)
oxlint's import/no-duplicates rule errored on bc-12, bc-31, bc-32
(both .v2 and .migration variants) because describe/it/expect and
expectTypeOf were imported from 'vitest' on separate lines. The CI
lint:fix step exits non-zero on these errors, blocking the
[automated] auto-format push back to the PR branch.
2026-05-21 14:05:22 -07:00
Connor Byrne
134b0a69f3 fix(ext-api/tf): ignore harness/** in knip (review #12145) 2026-05-21 14:05:22 -07:00
Connor Byrne
ef4d6ca1b8 fix(ext-api/tf): resolve 10 pre-existing typecheck errors
Targeted fixes for typecheck errors in 3 files. The remaining ~193
pre-existing errors live in other bc-* test files and are out of scope
for this branch (they will be addressed by sibling PRs in the stack).

- harness/runV2.ts: import WidgetExtensionOptions from
  @/extension-api/lifecycle (the deprecated re-export shim in
  @/types/extensionV2 doesn't include it).
- bc-37.migration.test.ts: prefix unused 'event' param with underscore;
  widen 'eagerVueRef' literal-null type to VueComponentRef|null so the
  optional-chain access type-checks; tighten 'intervalId' to const to
  satisfy prefer-const lint that flagged after the file was touched.
- bc-36.v2.test.ts: drop unused 'beforeEach' import; drop unused
  InputTextOptions interface; convert SelectOptions/SliderOptions to
  type aliases that intersect Record<string, unknown> so the
  'as unknown as ...Options' casts are assignable to setOptions().

Net: 10 typecheck errors removed (203 -> 193). Test intent preserved.
Pre-commit hook bypassed (--no-verify) because it runs full-repo
typecheck, which fails on pre-existing errors in non-scoped files.
2026-05-21 14:05:22 -07:00
Connor Byrne
5929987578 test(extension-api-v2): drop unused harness exports flagged by knip
Internal-only types were exported but never consumed outside their
source modules. Tighten the surface to satisfy `pnpm exec knip` so
the pre-push hook stays green:

- worldMocks: drop unused createWorldMockHandles helper (vi.hoisted
  block is inlined per-consumer); demote WorldMockHandles to internal.
- v1App: demote V1NodeLike / V1Extension / V1App to internal types.
- v2Runtime: demote NodeRecord / V2Runtime / V2RuntimeOptions to
  internal types.
2026-05-21 14:05:22 -07:00
Connor Byrne
08fdd0ff29 test(extension-api-v2): pilot shared v2Runtime/v1App harness on bc-01
F2: ~96 BC test files inline near-identical `createTestRuntime` /
`createV2Runtime` blocks (and ~30 `*.migration.test.ts` files inline
`createV1App`). Land the shared harness with bc-01 as the pilot:

- harness/v2Runtime.ts — canonical createV2Runtime({ idPrefix }) with
  register / addNode / mountNode(id) / clear surface.
- harness/v1App.ts — canonical createV1App with simulateNodeCreated.
- harness/README.md — incremental migration tracker (which files have
  adopted, which surfaces remain) and conventions for hoist-safe
  vi.mock / vi.hoisted use against this harness.

bc-01.v2 keeps a thin local createTestRuntime alias to minimise churn
inside the test bodies; bc-01.migration bridges the legacy
`mountNode(comfyClass)` shape to the canonical `addNode + mountNode(id)`
without rewriting every assertion.

Verified: bc-01.v2 (13/14) + bc-01.migration (6/7) pass under vitest run
(1 it.todo each, pre-existing).
2026-05-21 14:05:22 -07:00
Connor Byrne
1f8fc26019 test(extension-api-v2): extract shared world mock factories to harness/worldMocks.ts
F3: bc-05.v2, bc-05.migration, bc-11.v2, bc-11.migration each duplicated
the same vi.mock('@/world/...') block (worldInstance + widgetComponents +
entityIds + componentKey + 3 extension-api stubs). Centralise the factory
bodies in src/extension-api-v2/__tests__/harness/worldMocks.ts and have
the four files consume them.

vi.hoisted handles stay inline because the hoisted factory runs before
imports resolve; vi.mock factories wrap the imported helpers in arrows
so the import binding is read lazily.

Verified: 4/4 files pass under vitest run with the shared module.
2026-05-21 14:05:21 -07:00
Connor Byrne
9412716b27 test(extension-api-v2): relabel [Phase B] todos as [Phase B/C] per D9
F5: D9 places several deferred behaviors in Phase C (canvas/menu
extension points), not strictly Phase B. Single-pass cosmetic relabel
to keep todos honest about which phase unblocks them.
2026-05-21 14:05:21 -07:00
Connor Byrne
12a170363d fix(extension-api-v2): mark MiniComfyApp.world as @internal
F6: harness World was exposed without provenance, encouraging tests to
reach past the v1 `app` shape. Mark with @internal JSDoc so the
escape-hatch is documented and discouraged from public use. Existing
test usages (bc-15.*) continue to compile.
2026-05-21 14:05:21 -07:00
Connor Byrne
b1d149f660 fix(extension-api-v2): rename evidenceIndex param to rowIndex; correct .yaml→.json in error
F1a: param at loadEvidenceSnippet.ts:65 shadowed module-level evidenceIndex Map.
F1b: error string mentioned .yaml; fixture is .json.
2026-05-21 14:05:21 -07:00
Connor Byrne
13e2e3a607 feat(extension-api): test framework — harness + bc-XX triplet test bodies
Restratified i-tf. Adds:
- src/extension-api-v2/__tests__/bc-XX.{v1,v2,migration}.test.ts triplets
  for 41 behavior categories (BC.01-41) — real test bodies, not stubs
- src/extension-api-v2/harness/{comfyApp,index,loadEvidenceSnippet,runV1,
  runV2,world}.ts and __fixtures__/touch-point-database.json
- vitest.extension-api.config.mts (test runner config)
- package.json — adds test:extension-api{,:watch,:coverage} scripts

Original (pre-restratify) branch tip backed up at
refs/backup/restratify-20260511/ext-api-i-tf.
2026-05-21 14:05:21 -07:00
Christian Byrne
a337d1cfbb fix(ext-api): add idempotency guard for v2 demo extensions per RFR-12144-1
Per workspace executive decision (option a) on F-12144-1: v1 + v2 conversions
in dynamicPrompts/imageCrop/previewAny coexist as Phase A demos following the
strangler-fig migration pattern (D6). Both register, but only one path runs
per node — guards skip v2 when v1 is already registered to prevent:

- dynamicPrompts: double processDynamicPrompt() on serialize
- previewAny: duplicate preview_markdown/preview_text/previewMode widgets
- imageCrop: redundant setSize call (idempotent but cleaner)

Guard pattern: 1-line useExtensionStore().isExtensionInstalled('<v1-name>') check
at the top of nodeCreated.

See workspace AGENTS.md rule #8 — CI failures on the ext-api stack do not
block flips during Phase A; full CI green required only at rebase point onto
PR #11939.
2026-05-21 14:05:21 -07:00
Connor Byrne
d6aa562e7a chore(ext-api): regen api-snapshot after NodeMode doc fix
Cascades the foundation fix (8564a19dc7) into the published API
snapshot. NodeMode JSDoc now correctly maps numeric slots to
LGraphEventMode names (was wrong for slots 1-4 in prior snapshot).
Other diff churn is whitespace/format-only from a fresh dts build.
2026-05-21 14:05:21 -07:00
Connor Byrne
909bbb660b feat(ext-api/pkg): commit reviewable .d.ts snapshot of public surface
Adds `packages/extension-api/api-snapshot/` containing the generated
`.d.ts` files for every module re-exported from
`@comfyorg/extension-api`:

  index.d.ts       — barrel / entry point
  events.d.ts      — event payload types
  identifiers.d.ts — branded entity ID types
  lifecycle.d.ts   — defineExtension / defineNodeExtension / defineWidgetExtension
  node.d.ts        — NodeHandle and DOM widget options
  shell.d.ts       — sidebar, bottom panel, command, toast types
  types.d.ts       — extension option contracts
  widget.d.ts      — WidgetHandle

`build/` stays gitignored. Snapshot is a separate stable path so
reviewers see exactly what extension authors will consume on a public
API change, without polluting git with runtime `.js` / per-module
internal declaration files. Regenerate via:

  pnpm --filter @comfyorg/extension-api build
  cp packages/extension-api/build/extension-api/*.d.ts \
     packages/extension-api/api-snapshot/

eslint.config.ts: ignore `api-snapshot/**` so the generated declarations
do not need to live in any tsconfig project.

See `packages/extension-api/api-snapshot/README.md` for the contract.
2026-05-21 14:05:21 -07:00
Connor Byrne
2cc1457596 fix(ext): stub dynamicPrompts.v2 pending defineWidgetAugmenter
Per D-no-node-widget-access (2026-05-19, bilateral A1 closure), nodes
can no longer enumerate widgets — `node.getWidgets()` was removed
from NodeHandle. The previous dynamicPrompts.v2 implementation
iterated node widgets to attach per-widget `beforeSerialize`
handlers; that pattern is now forbidden.

Stubbed pending a follow-up public API (`defineWidgetAugmenter` or
per-widget `setup` on `defineWidget`) that lets extensions attach
behavior to existing widget types matching a predicate. v1
(`Comfy.DynamicPrompts`) continues to work — this is a v2 surface
gap only, not a user-visible regression.

Refs: decisions/D-no-node-widget-access.md
2026-05-21 14:04:40 -07:00
Connor Byrne
616a30ddb3 feat(ext): add coordSpaceDemo.v2 canary for D-coord-space (W6.P4.D / A13)
Strangler-pattern v2 example demonstrating the single-coordinate-space policy from D-coord-space (ACCEPTED 2026-05-18, option iii) and Axiom A13 (Single Coordinate Space — Canvas).

Three sections: (1) default path — every NodeHandle spatial accessor speaks canvas units; (2) escape-hatch path — globalThis.app.canvas.{ds,canvas} + window.devicePixelRatio with the required '// escape-hatch — see D-coord-space.md' annotation comment on every use site; (3) cliff documentation — what's NOT on the public surface (no getScreenPosition, no space param, no branded ClientPoint type).

Serves as the executable canary that the documented pattern actually works. Authors and AI agents reading the v2 extensions/core/*.v2.ts directory see the policy demonstrated alongside the existing dynamicPrompts/previewAny/imageCrop/noteNode/slotDefaults/rerouteNode/webcamCapture examples.

knip.config.ts: add new file to strangler ignore list. Phase A gates: format clean / lint 0 errors 3 pre-existing warnings / knip 6 pre-existing tag hints + 1 pre-existing config hint.
2026-05-21 14:04:40 -07:00
Connor Byrne
f182d1ff96 feat(ext): add webcamCapture.v2 example exercising defineWidget+mount (W6.P3.D)
Strangler-pattern port of the WEBCAM custom widget type from the v1 webcamCapture extension to the v2 mount-lifecycle seam (Axiom A12 / D-widget-converge §Decision).

- Registers WEBCAM via defineWidget({type:'WEBCAM',mount}). The mount body constructs the <video> + container, captures them via closure (no widget.element accessor exposed per A12), and returns a cleanup that stops MediaStream tracks on widget destruction. - Uses ctx.onAfterRemount to re-attach the cached container when the host is swapped (graph ↔ app mode swap, subgraph promotion) per D-widget-converge §Clarification 1 — mount body is NOT re-invoked. - Companion defineNode stays a placeholder: GAP-2 (no type-construction addWidget('button',…)) and GAP-11 (no async setSerializedValue path; v2's WidgetBeforeSerializeEvent doesn't yet promise async resolution) block the full node-side port. v1 webcamCapture.ts remains authoritative until those gaps close.

knip.config.ts: add the new file to ignore list (matches existing v2 strangler entries; not wired into bootstrap).

Phase A gates: lint 0 errors / 3 pre-existing warnings; format:check clean; knip 6 pre-existing tag hints + 1 pre-existing config hint / 0 new failures.
2026-05-21 14:04:40 -07:00
Connor Byrne
524830023d docs(ext-api): document v1+v2 parallel loading (F-12144-1) 2026-05-21 14:04:40 -07:00
Connor Byrne
d70ead814d fix(ext): update v2 example extensions to current API
- defineNodeExtension → defineNode
- widgets() → getWidgets()
- Add explicit types for event handlers
- Add extension-api scripts entry to knip config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-05-21 14:04:40 -07:00
Connor Byrne
542256eeec style(ext-api/ext): apply CodeRabbit polish (F-12144-2/3/4/10/11)
F-12144-2: rewrite shell.ts header to say 're-exported from' (matches the
re-export code; the original 'moved from' wording was ambiguous).

F-12144-3: tag SlotDefaults v2 extension as '(DEMO — incomplete migration)'
and add a JSDoc @remarks block listing the v1 features (beforeRegisterNodeDef
node metadata, settings-dialog contribution, slot-type registry mutation)
that remain TBD. Intentionally NOT porting them — staging-demo intent per the
GAP-4/5/6 feedback to Simon/Austin.

F-12144-4: drop the redundant 'as string' cast in dynamicPrompts.v2; the
immediate 'typeof value === "string"' check makes the cast self-contradicting.
Defensive runtime check stays.

F-12144-10: add a 3-line @example to defineWidgetExtension JSDoc to match the
defineNodeExtension/defineExtension docs.

F-12144-11: reorder DOMWidgetOptions and NodeHandle JSDoc blocks so each
docblock immediately precedes its declaration.
2026-05-21 14:04:40 -07:00
GitHub Action
5df5ee1d0b [automated] Apply ESLint and Oxfmt fixes 2026-05-21 14:04:40 -07:00
Connor Byrne
2f76a931a8 fix(ext-api/ext): ignore strangler v2 extensions in knip (review #12144) 2026-05-21 14:04:40 -07:00
Connor Byrne
dcdc9e7bfa chore(ext-api/ext): tag rerouteNode globalThis.app accesses with strangler-bridge:Phase-B (review #12144.1.6)
Per D9 strangler-bridge taxonomy, every direct globalThis.app access in
v2 conversion files must carry a 'strangler-bridge:Phase-B' marker so
the bridge audit can enumerate remaining touch-points before Phase-B
removes the global.

Tag the three sites in rerouteNode.v2.ts (configuringGraph guard in
onConnectionsChange, configuringGraph guard in updateLink, and the
canvas.setDirty call from the context-menu callback).
2026-05-21 14:04:40 -07:00
Connor Byrne
3f639da07d fix(ext-api/ext): warn on node.on stub-channel registration (review #12144.1.5)
Known-stubbed channels (executed/connected/disconnected/configured)
dispatch to a Phase-A stub bus that does not deliver events. Previously
these registrations were silent — extensions saw no warning that their
handlers were dead until #11939 lands the dispatch substrate.

Add a DEV console.warn (eslint-disable-next-line no-console, matching
the established pattern in this file) for each known-stubbed channel
registration so authors know to wait on #11939.
2026-05-21 14:04:40 -07:00
GitHub Action
d66f989a96 [automated] Apply ESLint and Oxfmt fixes 2026-05-21 14:04:40 -07:00
Connor Byrne
de7730b67b feat(extension-api): core extension v2 conversions
Restratified i-ext. Adds v2 conversions for 6 core extensions:
- dynamicPrompts.v2.ts
- imageCrop.v2.ts
- previewAny.v2.ts
- noteNode.v2.ts
- rerouteNode.v2.ts
- slotDefaults.v2.ts
And registers the first 3 in src/extensions/core/index.ts.

Note: noteNode.v2, rerouteNode.v2, slotDefaults.v2 are NOT yet
registered in index.ts (pre-existing issue from original i-ext branch).
Filed as a follow-up TODO.

Original (pre-restratify) branch tip backed up at
refs/backup/restratify-20260511/ext-api-i-ext.
2026-05-21 14:04:40 -07:00
Connor Byrne
528d014e15 build(extension-api): regenerate .d.ts for hygiene cleanup (wave-11)
Hand-patched mirror of foundation hygiene cleanup per AGENTS.md Rule 8
(Node 20 vs vite blocks `pnpm build` in this worktree):

- Strip HR-style section dividers
- Strip parenthetical decision archaeology
  ((per D5), (D-immutability-enforcement, Hybrid C),
  D-bootstrap-hooks (W6.P6.C), D-shell-ui-entrypoints (W6.P5.C), etc.)
  from per-export JSDoc — preserve AXIOMS.md §A1/A14/A15/A16/A12 refs
  and PHASE_A_EXCLUDED axiom blocks (functional content).
- Strip "W6.P8.UNMIGRATABLE / D-input-output-shape" todo refs.
- One stale `defineWidgetExtension` JSDoc example fixed (was already
  on foundation; rebase carried the fix through).

Mirrors foundation commit `ee0537fdb5`.

ADR: decisions/D-design-review-hygiene-cleanup.md
Zero published-surface change (no types added/removed/renamed).
2026-05-21 14:01:37 -07:00
Connor Byrne
b4fe848527 build(extension-api): regenerate .d.ts for D-ban-runtime-addwidget (wave-10)
Hand-patched mirror of foundation surface changes per AGENTS.md Rule 8
(Node 20 vs vite blocks `pnpm build` in this worktree):

- Remove `NodeHandle.addWidget(...)` method declaration (A15 closure)
- Scrub 5 JSDoc references to `node.addWidget(...)` across NodeHandle
  getWidgets doc, NodeBeforeSerialize migration example, defineWidget
  options doc, WidgetHandle name doc, WidgetHandle label doc,
  WidgetOptions doc
- Add A15 / D-ban-runtime-addwidget cross-references

Mirrors foundation commit `d5d5692928`.
2026-05-21 14:01:37 -07:00
Connor Byrne
e4f2feb6f8 chore(ext-api/pkg): rebuild .d.ts for D-widget-serialization-simplification (wave-9)
Hand-patched packages/extension-api/build/index.d.ts to match the
foundation surface after A16 closure:

- Drop `isSerializeEnabled` / `setSerializeEnabled` from WidgetHandle
- Drop `WidgetBeforeSerializeEvent.context` 4-way discriminator
- Drop `WidgetBeforeSerializeEvent.skip()`
- Drop `on('propertyChange', handler)` overload
- Drop entire `WidgetPropertyChangeEvent` interface
- Drop `WidgetOptions.serialize?: boolean` key
- Update JSDoc on `WidgetBeforeSerializeEvent` / `options` / `serializeValue`
  to reference A16 / drop transport-discriminator examples

`NodeBeforeSerializeEvent.context` is intentionally retained — the
node-level surface stays `@deprecated` + runtime-warned per ADR-0010
(not banned by D-widget-serialization-simplification).

Hand-edit pattern because pnpm build is blocked by Node 20 vs vite
requirement per AGENTS.md Rule 8. Surface verified to match foundation
HEAD e56187adf3.

Refs: decisions/D-widget-serialization-simplification.md, AXIOMS.md §A15+A16
2026-05-21 14:01:37 -07:00