Skip to content

feat(sdk): pm package init --declarative scaffolds a composeExtension blueprint starter - #358

Merged
unbraind merged 2 commits into
mainfrom
feat/package-init-declarative-blueprint-starter
Jun 24, 2026
Merged

unbraind merged 2 commits into
mainfrom
feat/package-init-declarative-blueprint-starter

Conversation

@unbraind

Copy link
Copy Markdown
Owner

Summary

pm package init scaffolded only the imperative defineExtension({ activate }) authoring style across all 9 --capability variants. The SDK's flagship declarative loop (defineExtensionBlueprint → composeExtension) and the author-time preflight capstone (assertExtensionPreflight) — which docs/SDK.md calls "the capstone of the author → register → test loop" — were demonstrated by no generated starter. A new author running pm package init never discovered the easiest, best-practice path.

This was found by dogfooding the full scaffold matrix in a temp workspace: all 9 imperative starters typecheck cleanly and pass their generated node:test suites, but none exercises composeExtension/assertExtensionPreflight/createExtensionTestHarness.

What this adds — pm package init <path> --declarative

  • index.ts: defineCommand → defineExtensionBlueprint({ commands, deactivate }) → export default composeExtension(blueprint) (exports pingCommand/blueprint/default module).
  • index.test.ts: author-time assertExtensionPreflight(blueprint, { identity, target }) (asserts the derived + synthesized capabilities) and the ergonomic runtime createExtensionTestHarness (assertCommandContract / runCommand / deactivate).
  • README.md: a "Declarative Authoring" section; package.json/manifest.json/tsconfig.json/.gitignore stay byte-identical to the imperative commands starter, so only the authoring style differs.

Scope & constraints (each a clear USAGE error)

  • Package-mode only — composeExtension is a runtime SDK value import, so it belongs where the SDK is a linked dependency; the import-free extension-only starters must load without it. pm extension init --declarative → error.
  • Commands capability only — the canonical composeExtension example. --declarative --capability search → error. Full capability-matrix generalization is tracked in pm-lfdv.
  • --declarative is scaffold-only — using it outside --init/--scaffold → error.

Wiring

register-setup.ts (commander option on the lifecycle + init sub-command, options reader), extension.ts (option type, validation, passthrough, style in the result), completion.ts (bash/zsh/fish), cli-contracts.ts (EXTENSION_FLAG_CONTRACTS + EXTENSION_INIT_FLAG_CONTRACTS) + regenerated tests/fixtures/contracts/full.json, and docs/SDK.md.

Verification

  • 5049 tests, 100/100/100/100 coverage; typecheck (src + packages + examples), quality:static (100% docstrings), quality:docs-skills, and contracts snapshot gates all green.
  • Manual dogfood in an isolated temp workspace: scaffold → tsc --noEmit clean → node --test 2/2 pass → pm install --project → pm <cmd> ping dispatches the composed module (SDK linked). All three error paths return exit code 2 with actionable messages.

pm items

  • Closes pm-8mxg (Feature, epic pm-ugqx — Extension & package platform maturity).
  • Follow-up pm-lfdv (Task): extend --declarative to the full capability matrix.

🤖 Generated with Claude Code

…on blueprint starter

The scaffold matrix only demonstrated imperative `defineExtension({ activate })`
authoring + the runtime test helpers. The SDK's flagship declarative loop
(`defineExtensionBlueprint` → `composeExtension`) and the author-time preflight
capstone (`assertExtensionPreflight`) — which SDK.md calls "the capstone of the
author → register → test loop" — were demonstrated by no generated starter, so a
new author running `pm package init` never discovered the easiest, best-practice
path. Discovered by dogfooding the full 9-capability matrix in a temp workspace
(every imperative starter typechecks and passes its generated tests).

Add `pm package init <path> --declarative`:
- `index.ts`: `defineCommand` → `defineExtensionBlueprint({ commands, deactivate })`
  → `export default composeExtension(blueprint)`.
- `index.test.ts`: author-time `assertExtensionPreflight(blueprint, { identity,
  target })` (asserts derived + synthesized capabilities) + runtime
  `createExtensionTestHarness` (`assertCommandContract`/`runCommand`/`deactivate`).
- README documents the declarative loop; manifest/package.json/tsconfig/.gitignore
  stay byte-identical to the imperative commands starter.

Scoped to package-mode (composeExtension is a runtime SDK *value* import; the
import-free extension-only starters must load without it) and the commands
capability (the canonical composeExtension example). Extension-mode, non-commands
`--capability`, and non-init use each return a clear USAGE error. Full
capability-matrix generalization is tracked in pm-lfdv.

Wired the flag through register-setup (commander + options reader),
extension.ts (validation, passthrough, `style` in result), completion
(bash/zsh/fish), and cli-contracts (+regenerated contracts snapshot); documented
in SDK.md. pm-8mxg (epic pm-ugqx).

5049 tests, 100/100/100/100 coverage; typecheck/static-quality/docs-skills/
contracts gates green. Manually dogfooded end-to-end: scaffold → `tsc --noEmit`
→ `node --test` → `pm install --project` → command dispatches the composed module.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEUoAbSunPoG3Xt83VYd4k

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @unbraind, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@unbraind

Copy link
Copy Markdown
Owner Author

@coderabbitai full review
/gemini review
@gemini-code-assist please review
@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jun 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@unbraind, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 51 minutes and 11 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 3b70c18e-882b-4227-97d0-cdb5274f8552

📥 Commits

Reviewing files that changed from the base of the PR and between e1fd7b1 and 21f98dd.

📒 Files selected for processing (2)
  • docs/SDK.md
  • tests/unit/extensions/extension-command.spec.ts
📝 Walkthrough

Walkthrough

Adds a --declarative extension/package scaffold mode that generates blueprint-based composeExtension package starters, wires the flag through CLI setup and contracts, enforces package-mode commands-only usage, and updates tests and docs.

Changes

Declarative extension scaffolding

Layer / File(s) Summary
CLI flag surface
src/cli/commands/extension.ts, src/cli/register-setup.ts, src/sdk/cli-contracts.ts, src/cli/commands/completion.ts
Adds the declarative option, exposes --declarative in lifecycle setup, flag contracts, and shell completion output.
Declarative scaffold generation
src/cli/commands/extension/scaffold.ts
Adds declarative scaffold types, blueprint-based entrypoints and tests, conditional file generation, and style on scaffold results.
Init command integration
src/cli/commands/extension.ts
Validates --declarative usage for init, forwards it into scaffolding, and returns the scaffold style in init details.
Scaffold and completion tests
tests/fixtures/contracts/full.json, tests/unit/commands/completion-command.spec.ts, tests/unit/extensions/*.spec.ts
Updates the CLI contract fixture and adds coverage for completion output, generated scaffold contents, runtime execution, and invalid flag combinations.
Docs and work-item records
docs/SDK.md, CHANGELOG.md, .agents/pm/features/pm-8mxg.toon, .agents/pm/tasks/pm-lfdv.toon, .agents/pm/history/*.jsonl
Adds SDK guidance, changelog text, feature/task records, and history entries for the declarative scaffold work.

Sequence Diagram(s)

sequenceDiagram
  participant indexTestTs
  participant assertExtensionPreflight
  participant createExtensionTestHarness
  indexTestTs->>assertExtensionPreflight: validate the exported blueprint
  indexTestTs->>createExtensionTestHarness: run the generated starter
  createExtensionTestHarness-->>indexTestTs: execute command behavior
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • unbraind/pm-cli#332: Updates the same extension scaffolding path to branch starter generation by capability and scaffold mode.
  • unbraind/pm-cli#352: Introduces the blueprint composition APIs that the generated declarative index.ts imports and uses.
  • unbraind/pm-cli#351: Adds the author-time preflight APIs that the generated index.test.ts exercises.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: adding a declarative composeExtension scaffold for pm package init.
Description check ✅ Passed The description is directly related and accurately summarizes the new declarative scaffolding, constraints, wiring, and verification.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds a --declarative flag to pm package init to scaffold a declarative composeExtension blueprint starter for the commands capability in package-mode. It wires the flag through the CLI options, completion scripts, and contracts, and updates the documentation. Feedback on the changes includes a recommendation to use 'junction' instead of 'dir' for directory symlinks on Windows in the test suite to ensure compatibility without requiring administrator privileges.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

// resolve the subpath, then prove the module loads and dispatches for real.
const sdkLinkDir = path.join(context.pmPath, "node_modules", "@unbrained");
await mkdir(sdkLinkDir, { recursive: true });
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), "dir");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

On Windows, creating a directory symlink using 'dir' requires administrator privileges or Developer Mode. Using 'junction' as the symlink type when running on Windows allows the test suite to run reliably across all developer environments and CI platforms without requiring special privileges.

Suggested change
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), "dir");
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), process.platform === "win32" ? "junction" : "dir");

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== PR Info ==="
gh pr view 358 --repo unbraind/pm-cli --json title,body,files,additions,deletions,changedFiles 2>/dev/null | jq '{title, additions, deletions, changedFiles, files: [.files[].path]}' || true

echo ""
echo "=== Changed Files ==="
gh pr diff 358 --repo unbraind/pm-cli 2>/dev/null | head -3000 || true

Length of output: 68579



@unbraind: Here is the full review of PR #358.


Review: pm package init --declarative scaffolds a composeExtension blueprint starter

Summary

The implementation is solid and well-scoped. The three-layer constraint (package-mode only → commands only → scaffold-only) is correctly enforced with clear USAGE errors, all three shells get completion entries, the contract snapshot is regenerated, and the integration test goes all the way to a real spawnSync dispatch with the SDK symlinked. A few findings below.


Issues

1. Missing blank line in docs/SDK.md — paragraph break lost

File: docs/SDK.md, around the new paragraph inserted at line 567.

+Each `--capability` starter authors an imperative `activate` body. To scaffold the
+declarative `composeExtension` form instead, pass `--declarative` (package-mode,
+commands capability) — see [Declarative Authoring](`#declarative-authoring`).
 See [EXTENSIONS.md](EXTENSIONS.md) for the manifest-field reference.

There is no blank line between the new paragraph and the existing See [EXTENSIONS.md]… sentence. In rendered Markdown these will merge into a single run-on paragraph. Add a blank line:

 commands capability) — see [Declarative Authoring](`#declarative-authoring`).
+
 See [EXTENSIONS.md](EXTENSIONS.md) for the manifest-field reference.

2. buildStarterExtensionScaffoldFiles silently ignores declarative=true for "extension" vocabulary

File: src/cli/commands/extension/scaffold.ts, buildStarterExtensionScaffoldFiles.

When vocabulary === "extension" and declarative === true, the flag reaches the function but is never applied — the extension branch always produces the imperative starter. scaffoldExtensionProject rejects this case before calling the builder, so no bad output ever escapes to disk. However, a future caller who invokes buildStarterExtensionScaffoldFiles directly (e.g. in a new test or a follow-up capability) might be surprised. A defensive early-return guard or a comment at the top of the function (not just in the package branch) would make the intent explicit:

// `declarative` is only meaningful in the package branch; scaffoldExtensionProject
// rejects extension-mode + declarative before reaching here, so this is always
// false for extension vocabulary in practice.

The existing test "ignores the declarative flag for extension-mode scaffolds" covers this, which is appreciated.


3. buildDeclarativeSampleTestSource hardcodes report.manifest?.capabilities assertion

File: src/cli/commands/extension/scaffold.ts, buildDeclarativeSampleTestSource.

The generated test asserts both:

assert.deepEqual(report.capabilities, ["commands"]);
assert.deepEqual(report.manifest?.capabilities, ["commands"]);

The optional-chain on report.manifest?.capabilities means if manifest is absent (e.g. a future API change returns null/undefined), the assertion silently passes against undefined rather than failing loudly. Consider generating it with a non-optional chain and a preceding existence check, or use assert.ok(report.manifest) first. This is a minor DX concern in the generated test, not a bug in the scaffolder itself.


4. --declarative description wording in register-setup.ts omits "only"

File: src/cli/register-setup.ts, both .option("--declarative", ...) registrations.

.option("--declarative", "Scaffold the composeExtension blueprint starter (package-mode, commands capability)")

The parenthetical correctly states the constraints, but the --capability option description uses the word default to signal the default value. For discoverability, adding "only" would make the constraints clearer in --help output:

--declarative   Scaffold the composeExtension blueprint starter (package-mode + commands only)

Minor — the error messages are already actionable.


Nitpicks

  • buildDeclarativePackageReadme references TSCONFIG_BULLET, SCAFFOLD_MANIFEST_VERSION, and SCAFFOLD_PM_MIN_VERSION — all expected to be module-level constants. Not visible in the diff but consistent with the imperative builder's usage. ✓
  • "currently" in the capability error message ("--declarative currently scaffolds the commands-capability blueprint starter") — intentionally signals the temporary scope, which is good given pm-lfdv tracks the follow-up. ✓
  • style in the command output — a clean addition; programmatic consumers can branch on "imperative" | "declarative" without parsing file content. ✓
  • Symlink pattern in the integration test to make @unbrained/pm-cli/sdk resolvable for the runtime value import — the comment explaining why this is required (value import vs. erased type import) is excellent. ✓
  • Validation ordering in scaffoldExtensionProject: vocabulary check before capability check — the more fundamental constraint is checked first, producing the most actionable error. ✓

Verdict

One real rendering bug (missing blank line in SDK.md, item 1), one latent defensive-coding gap (item 2), and one mild DX improvement in the generated test (item 3). Everything else is well-executed. The constraint model, completion wiring, contract snapshot, and test coverage are all consistent and thorough.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds a --declarative flag to pm package init to scaffold a declarative composeExtension blueprint starter with an author-time preflight test and a runtime test harness. The flag is wired through CLI commands, autocompletion scripts, and SDK contracts, and is fully documented and tested. Feedback on the test suite suggests using a directory junction instead of a standard directory symlink to ensure compatibility on Windows without requiring elevated privileges.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

// resolve the subpath, then prove the module loads and dispatches for real.
const sdkLinkDir = path.join(context.pmPath, "node_modules", "@unbrained");
await mkdir(sdkLinkDir, { recursive: true });
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), "dir");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

On Windows, creating directory symbolic links using the 'dir' type requires administrative privileges or Developer Mode to be enabled. Using 'junction' instead allows the directory link to be created without elevated privileges, making the test suite more robust and developer-friendly across different Windows environments.

Suggested change
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), "dir");
await symlink(process.cwd(), path.join(sdkLinkDir, "pm-cli"), "junction");

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/SDK.md`:
- Around line 568-570: Clarify that `--declarative` is only supported for `pm
package init`/`--scaffold` flows, not as a general `--capability` toggle. Update
the usage note near the `composeExtension` guidance to explicitly mention the
`pm package init` scope and keep the wording aligned with the CLI contract.
Refer to the `--declarative`, `--init`, and `--scaffold` options in the
`Declarative Authoring` note so readers understand where the flag applies.

In `@tests/unit/extensions/extension-command.spec.ts`:
- Around line 2184-2186: The workspace link creation in the extension command
test is using a directory symlink type that can fail on Windows CI. Update the
symlink call in the test setup around sdkLinkDir to use a Windows-safe directory
link, such as a junction, or add a platform-specific fallback so the fixture
works on windows-latest. Keep the change localized to the test helper logic near
the symlink invocation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: f66b18fc-f952-43b0-aaf8-1b1780dbdbb8

📥 Commits

Reviewing files that changed from the base of the PR and between 37d2633 and e1fd7b1.

📒 Files selected for processing (15)
  • .agents/pm/features/pm-8mxg.toon
  • .agents/pm/history/pm-8mxg.jsonl
  • .agents/pm/history/pm-lfdv.jsonl
  • .agents/pm/tasks/pm-lfdv.toon
  • CHANGELOG.md
  • docs/SDK.md
  • src/cli/commands/completion.ts
  • src/cli/commands/extension.ts
  • src/cli/commands/extension/scaffold.ts
  • src/cli/register-setup.ts
  • src/sdk/cli-contracts.ts
  • tests/fixtures/contracts/full.json
  • tests/unit/commands/completion-command.spec.ts
  • tests/unit/extensions/extension-command.spec.ts
  • tests/unit/extensions/extension-scaffold-define-guidance.spec.ts

Comment thread docs/SDK.md Resolved
… + SDK.md flag scope

- Use a Windows junction (over the absolute cwd) instead of a "dir" symlink in the
  declarative end-to-end test so it does not need admin / Developer Mode on Windows;
  Node ignores the type argument on POSIX, so Linux/macOS are unchanged.
  (Gemini + CodeRabbit, tests/unit/extensions/extension-command.spec.ts)
- Clarify in SDK.md that `--declarative` is a `pm package init`/`pm package scaffold`
  flag (package-mode, commands capability), not a general `--capability` toggle.
  (CodeRabbit, docs/SDK.md)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HEUoAbSunPoG3Xt83VYd4k
@unbraind

Copy link
Copy Markdown
Owner Author

Thanks for the reviews! Addressed in 21f98dd:

  • Windows symlink (Gemini + CodeRabbit): switched the declarative e2e test from a "dir" symlink to a "junction" so it needs no admin/Developer Mode on Windows. Node ignores the type arg on POSIX, so Linux/macOS behavior is unchanged (test still green).
  • SDK.md scope (CodeRabbit): clarified that --declarative is a pm package init / pm package scaffold flag (package-mode, commands capability), not a general --capability toggle.

Re-requesting review:
@coderabbitai full review
/gemini review
@gemini-code-assist please review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== PR Diff (latest) ==="
gh pr diff 358 --repo unbraind/pm-cli 2>/dev/null | head -5000 || true

echo ""
echo "=== Commit 21f98dd7 details ==="
gh api repos/unbraind/pm-cli/commits/21f98dd7 2>/dev/null | jq '{sha, commit: {message: .commit.message}, files: [.files[] | {filename, additions, deletions, patch}]}' | head -300 || true

Length of output: 70952



@unbraind: Thanks for the fixes in 21f98dd — the "junction" symlink change is correct and the SDK.md scope wording is clearer. Here's the updated review.


Review Update — post-21f98dd7

✅ Addressed

  • Windows junction ("dir" → "junction") with explanatory comment — correct on all three platforms.
  • SDK.md scope — the new sentence now explicitly says pm package init / pm package scaffold and "it is an init/scaffold flag", which removes the ambiguity.

🔴 Still open: missing blank line in docs/SDK.md

My original Issue #1 was not picked up by the fix commit. The paragraph break between the new --declarative sentence and the existing See [EXTENSIONS.md]… line is still absent:

  and commands capability only) — see [Declarative Authoring](`#declarative-authoring`).
+ 
  See [EXTENSIONS.md](EXTENSIONS.md) for the manifest-field reference.

Without the blank line these two sentences render as a single run-on paragraph in GitHub/any Markdown renderer. One blank line fixes it.


ℹ️ Remaining minor findings (unchanged from initial review)

These are low-severity and don't block the PR, but noting them for completeness:

  • Issue #2 — buildStarterExtensionScaffoldFiles silently ignores declarative=true for "extension" vocabulary (guarded upstream, covered by test, but no in-function comment).
  • Issue #3 — Generated index.test.ts uses report.manifest?.capabilities (optional chain); a silent pass if manifest is undefined.
  • Issue #4 — --declarative help text could say "package-mode + commands only" for slightly tighter discoverability.

Verdict

One confirmed rendering bug left (blank line). Everything else — constraint enforcement, completion wiring, contract snapshot, style field, integration test — is solid. Fix the blank line and this is good to go.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the --declarative flag to pm package init and pm package scaffold, allowing developers to scaffold a declarative composeExtension blueprint starter package. This starter generates an index.ts using defineExtensionBlueprint and composeExtension, an index.test.ts utilizing assertExtensionPreflight and createExtensionTestHarness, and an updated README.md. The flag is restricted to package-mode and the commands capability, with appropriate validation and usage errors implemented. The changes also include updates to shell completions, CLI contracts, documentation, and comprehensive unit tests. There are no review comments, so no feedback is provided.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@unbraind
unbraind merged commit 3ba8729 into main Jun 24, 2026
15 checks passed
@unbraind
unbraind deleted the feat/package-init-declarative-blueprint-starter branch June 24, 2026 19:05
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.

1 participant