Skip to content

Consume deterministic lookupId to simplify wizard provider resolution - #20

Closed
nicolehaugen wants to merge 12 commits into
github:nicolehaugen-wizard-composition-artifact-clifrom
nicolehaugen:nicolehaugen-lookupid-wizard-simplification-d12
Closed

Consume deterministic lookupId to simplify wizard provider resolution#20
nicolehaugen wants to merge 12 commits into
github:nicolehaugen-wizard-composition-artifact-clifrom
nicolehaugen:nicolehaugen-lookupid-wizard-simplification-d12

Conversation

@nicolehaugen

Copy link
Copy Markdown
Contributor

Summary

Consumes the deterministic lookupId field carried on composition stack layers (preset:<presetId>:<kind>:<name> / extension:<extId>:<kind>:<name> / null for core) to replace ad-hoc string-parsing and multi-field OR fallbacks across the wizard with a single, well-tested parsing path.

Stacked on this repo's wizard composition/artifact-cli PR — base ref is intentionally that branch, not main.

Changes (in migration order, each commit independently green)

  1. New ui/lookup-id.mjs — pure parseLookupId(str) and findLayerByLookupId(compArtifact, lookupId) helpers.
  2. Split lookupActiveLayer into lookupActiveLayerForCommand(p) and lookupLayerByLookupId(lookupId); migrated commandSourcePath to the new name.
  3. Attached lookupId additively to phase objects at all phase-construction sites (core branch, extension branch, synthesizeCanonicalPhase).
  4. Switched commandSourcePath's preset-path derivation from string-parsing p.source to parseLookupId-based provider extraction (still preset-kind-only, matching prior behavior).
  5. Switched computeProviderContributions's 4-way OR (presetId || extensionId || presetName || extensionName) to parseLookupId(layer.lookupId)?.providerId, falling back to presetId ?? extensionId for wizard-synthesized hook layers (which intentionally carry lookupId: null).
  6. Upgraded the two pass-through equality asserts in test/artifact-cli.test.mjs to behavioral coverage.
  7. Dropped the one-commit lookupActiveLayer deprecation shim once its single caller was migrated.

Out of scope (deliberately, tracked separately)

  • Removing the .specify/presets/<presetId>/commands/<commandName>.md filesystem-path construction in commandSourcePath.
  • Rewriting accumulateProvidesCounts / summarizeInstalled.
  • Deleting applyHookAttributions, or synthesizing hook lookupIds client-side — hook layers keep lookupId: null and rely on the presetId ?? extensionId fallback until the CLI exposes hook artifacts with real lookupIds and the wizard migrates off applyHookAttributions entirely.
  • Dropping presetName / extensionName display fallbacks.
  • Dropping the legacy p.source field globally (kept as additive-legacy).

Testing

  • npm test — 225/225 passing.
  • New test files: test/lookup-id.test.mjs, test/phase-runtime-command-source-path.test.mjs, test/compute-provider-contributions.test.mjs, plus behavioral upgrades in test/artifact-cli.test.mjs. Each test targets a distinct code branch (reviewed for redundancy, one duplicate trimmed).

@nicolehaugen
nicolehaugen requested a review from mnriem as a code owner August 26, 2026 20:34
Copilot AI balanced review requested due to automatic review settings August 26, 2026 20:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Centralizes deterministic composition-layer lookup IDs for provider resolution and command source paths.

Changes:

  • Adds lookup ID parsing and layer lookup helpers.
  • Propagates lookup IDs through synthesized phases and provider calculations.
  • Adds focused behavioral tests.
Show a summary per file
File Description
ui/phase-runtime.js Migrates phase and source-path lookup logic.
ui/phase-card.js Adds core phase lookup ID.
ui/lookup-id.mjs Adds lookup ID helpers.
ui/composition.js Resolves contribution providers from lookup IDs.
test/phase-runtime-command-source-path.test.mjs Tests command path resolution.
test/lookup-id.test.mjs Tests lookup ID helpers.
test/compute-provider-contributions.test.mjs Tests provider bucketing.
test/artifact-cli.test.mjs Adds behavioral layer lookup coverage.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 8/8 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment on lines +907 to +908
const parsedActive = parseLookupId(activeLayer?.lookupId);
const parsedPhase = parseLookupId(p.lookupId);
…ommands

snapshot-builder.mjs's buildCommands forwards cmd.source ("preset:<id>")
onto snapshot.commands but never attaches a lookupId - that field only
exists on composition-artifact stack layers, a separate producer. The
lookupId-only fallback added in this PR made commandSourcePath return
null for real preset-only command tiles, breaking the on-disk source
link. Restore the string-parse fallback as a third tier after the
lookupId-based derivations, and add a scanner-to-buildStateSnapshot
integration test proving the real command shape resolves correctly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 06f1c8e8-17cf-4754-ab7c-9f583bdb876f
@nicolehaugen

Copy link
Copy Markdown
Contributor Author

Superseded by #21 — recreated as a same-repo PR (head branch pushed to github/spec-kit-copilot directly instead of a fork) so Copilot can work on it. Same commits, same base (nicolehaugen-wizard-composition-artifact-cli).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants