Skip to content

feat(package): scaffold search capability starters - #333

Merged
unbraind merged 6 commits into
mainfrom
feat/package-search-scaffold-pm-pwai
Jun 21, 2026
Merged

unbraind merged 6 commits into
mainfrom
feat/package-search-scaffold-pm-pwai

Conversation

@unbraind

Copy link
Copy Markdown
Owner

Summary

  • add pm package/extension init --capability search starter generation with a command, search provider, vector-store adapter, and generated SDK node:test coverage
  • normalize generated scaffold command paths to space-separated words so package commands generated from hyphenated directory names invoke after install
  • update docs, completions, changelog, and PM tracking for pm-pwai

Verification

  • PM_RUN_TESTS_SKIP_BUILD=1 node scripts/run-tests.mjs test -- tests/unit/extensions/extension-command.spec.ts tests/unit/commands/completion-command.spec.ts tests/unit/commands/contracts-command.spec.ts tests/unit/sdk/sdk-index.spec.ts => 4 files, 309 tests passed
  • pnpm build
  • pnpm contracts:check
  • pnpm quality:static
  • pnpm security:scan
  • manual temp smoke in /tmp/tmp.hP0BuKj8Gw: pm init, pm package init ./search-package --capability search, local SDK install, npm test, pm install, package doctor deep trace warning_count=0, pm search package ping --json
  • node scripts/run-tests.mjs coverage => 242 files, 4,832 tests, 100/100/100/100
  • pnpm changelog:pm:check
  • pm health --check-only --summary --json
  • pm validate --check-resolution --check-history-drift => history_drift ok; pre-existing resolution warnings remain on unrelated closed items
  • pnpm audit --audit-level low
  • Sentry/telemetry gate passed: critical=0, high=0

Add pm package/extension init --capability search so package authors get a runnable starter command, search provider, vector-store adapter, and SDK testing coverage.

Normalize generated scaffold command paths from hyphenated directory names to space-separated command words so installed starter commands can be invoked manually after package install.

Update docs, completions, CHANGELOG, and PM evidence for pm-pwai.

@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

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

@coderabbitai

coderabbitai Bot commented Jun 21, 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 35 minutes and 43 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 refill rate.

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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

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: 0967434e-1f14-4922-87d5-3c5417673d41

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc596a and 397389d.

📒 Files selected for processing (12)
  • .agents/pm/features/pm-pwai.toon
  • .agents/pm/history/pm-pwai.jsonl
  • CHANGELOG.md
  • docs/EXTENSIONS.md
  • docs/SDK.md
  • scripts/dogfood-package-first.mjs
  • src/cli/commands/completion.ts
  • src/cli/commands/extension/scaffold.ts
  • src/cli/help-content.ts
  • tests/unit/commands/completion-command.spec.ts
  • tests/unit/extensions/extension-command.spec.ts
  • tests/unit/scripts/dogfood-package-first.spec.ts
📝 Walkthrough

Walkthrough

Adds --capability search to pm package init and pm extension init, generating a search provider and vector-store adapter scaffold with runnable SDK tests. Also normalizes scaffolded starter command names from hyphenated form (my-ext ping) to space-separated form (my ext ping). Shell completions, help text, docs, tests, and a dogfood script are updated accordingly.

Changes

Search Capability Scaffold + Command Name Normalization

Layer / File(s) Summary
Scaffold generator: search capability + command name normalization
src/cli/commands/extension/scaffold.ts
SCAFFOLD_CAPABILITIES and ExtensionScaffoldCapability are expanded to include "search". buildActivateBodyLines adds a search branch that registers a deterministic search provider and vector-store adapter. buildSampleTestSource adds a node:test block asserting both registrations and validating query/embed outputs. Manifest and README generation switches from inline hooks conditionals to capability lookup tables. Scaffolded starter command names are normalized from hyphenated directory names to space-separated words (e.g., my-ext → my ext ping).
CLI completion and help-content wiring
src/cli/commands/completion.ts, src/cli/help-content.ts
search is added to zsh and fish --capability choice lists. package init and extension init help payloads gain a --capability search example and a corresponding tip.
Unit tests: scaffold output, completion, and dogfood
tests/unit/extensions/extension-command.spec.ts, tests/unit/commands/completion-command.spec.ts, tests/unit/scripts/dogfood-package-first.spec.ts, scripts/dogfood-package-first.mjs
All existing scaffold tests are updated to expect space-separated command names. New tests cover search-capability package and standalone extension scaffolding. The completion test is updated for the expanded capability annotation. Dogfood script and its mock are updated from scaffold-package to scaffold package invocation.
Documentation and changelog
CHANGELOG.md, docs/EXTENSIONS.md, docs/SDK.md
Changelog entry added for pm package init --capability search. EXTENSIONS.md documents the search scaffold and SDK test helpers. SDK.md extends the scaffolding guide with a --capability search example.
Agent feature record and history log
.agents/pm/features/pm-pwai.toon, .agents/pm/history/pm-pwai.jsonl
New pm-pwai feature record and JSONL history log created, capturing the full implementation lifecycle including test evidence, coverage results, and closure metadata.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • unbraind/pm-cli#125: Introduces assertRegisteredVectorStoreAdapter, which this PR's generated scaffold code and tests rely on directly.
  • unbraind/pm-cli#330: Introduces runRegisteredSearchProviderForTest and runRegisteredVectorStoreAdapterForTest SDK helpers that this PR's generated index.test.js scaffold exercises.
  • unbraind/pm-cli#332: Extends the same pm package init/pm extension init --capability scaffolding mechanism in scaffold.ts that this PR further builds on to add the search capability.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'feat(package): scaffold search capability starters' directly and specifically describes the main change: adding search capability scaffold support for package initialization.
Description check ✅ Passed The PR description comprehensively relates to the changeset, detailing the search capability feature addition, command path normalization, documentation updates, and extensive verification across unit tests, integration tests, build checks, and smoke tests.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% 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 and usage tips.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of this PR right away!

✅ Action performed

Full review finished.

@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 new "search" capability to the package and extension scaffolding commands (pm package init and pm extension init), enabling authors to scaffold a deterministic in-memory search provider and vector-store adapter with runnable SDK tests. Additionally, it normalizes generated command paths to use space-separated words instead of hyphens to prevent dynamic dispatch failures in Commander. Feedback on the changes highlights a redundant optional chaining guard on document.metadata in the generated search provider query logic, which should be simplified for consistency.

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.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
" const needle = context.query.toLowerCase();",
" const hits = context.documents",
" .filter((document) => {",
" const title = String(document.metadata?.title ?? \"\").toLowerCase();",

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

Avoid adding redundant defensive checks (such as optional chaining guards) for fields that are typed as non-optional and guaranteed to be populated by the system. Since document.metadata is guaranteed to be populated (and is accessed unguarded as document.metadata.id in the subsequent .map call), the optional chaining operator ?. on metadata is redundant and introduces inconsistency.

          const title = String(document.metadata.title ?? "").toLowerCase();
References
  1. Avoid adding redundant defensive checks (such as null/undefined guards or type checks) for fields that are typed as non-optional and guaranteed to be populated by the system. Doing so introduces unreachable branches and inconsistency with the rest of the codebase where the field is consumed unguarded.

@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 search capability to pm package init and pm extension init, allowing developers to scaffold starter packages with a registered search provider and vector-store adapter. It also normalizes generated command names to use space-separated words instead of hyphens to ensure compatibility with Commander's dynamic dispatch. The feedback suggests removing a redundant optional chaining check on document.metadata when retrieving the document title, as metadata is guaranteed to be populated.

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.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
" const needle = context.query.toLowerCase();",
" const hits = context.documents",
" .filter((document) => {",
" const title = String(document.metadata?.title ?? \"\").toLowerCase();",

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

Avoid adding redundant optional chaining (?.) on document.metadata when accessing title, as metadata is typed as non-optional and guaranteed to be populated by the system. This is consistent with how document.metadata.id is accessed unguarded later in the same function.

          const title = String(document.metadata.title ?? "").toLowerCase();
References
  1. Avoid adding redundant defensive checks (such as null/undefined guards or type checks) for fields that are typed as non-optional and guaranteed to be populated by the system. Doing so introduces unreachable branches and inconsistency with the rest of the codebase where the field is consumed unguarded.

Address Gemini review feedback by removing redundant optional chaining from the generated search-provider title read.

Record post-review verification on pm-pwai, including focused tests, build, static quality, and full 100/100/100/100 coverage.
@unbraind

Copy link
Copy Markdown
Owner Author

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

Re-triggering after follow-up commit ba54807 addressed Gemini feedback.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of the PR including the changes from commit ba54807!

✅ Action performed

Full review finished.

@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 a new --capability search option to the pm package init and pm extension init commands, enabling developers to scaffold starter packages with an in-memory search provider, a vector-store adapter, and runnable SDK tests. Additionally, it normalizes generated command names by replacing hyphens with spaces to prevent dynamic dispatch failures in Commander, and updates shell completions, help content, and documentation. The review feedback suggests refactoring nested conditional blocks and ternary operators in scaffold.ts to simplify the code, as well as removing redundant defensive checks on the guaranteed title metadata field.

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.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
Comment on lines 91 to 131
if (capability !== "hooks") {
return commandLines;
if (capability !== "search") {
return commandLines;
}
return [
...commandLines,
"",
" // Search providers let packages customize how pm ranks and retrieves",
" // project context. This starter is deterministic and dependency-free:",
" // replace the scoring with your domain retrieval, embedding, or rerank",
" // logic as the package grows.",
" api.registerSearchProvider({",
` name: ${JSON.stringify(searchProviderName)},`,
" query: async (context) => {",
" const needle = context.query.toLowerCase();",
" const hits = context.documents",
" .filter((document) => {",
" const title = String(document.metadata.title ?? \"\").toLowerCase();",
" return title.includes(needle);",
" })",
" .map((document) => ({",
" id: document.metadata.id,",
" score: 1,",
' matched_fields: ["title"],',
" }));",
" return { hits };",
" },",
" embed: async (context) => [context.input.length],",
" });",
"",
" // Vector-store adapters let packages own semantic index storage. This",
" // starter returns a stable in-memory hit so generated tests can exercise",
" // the adapter without external services.",
" api.registerVectorStoreAdapter({",
` name: ${JSON.stringify(vectorAdapterName)},`,
" query: async (context) => [{ id: \"starter-vector-hit\", score: context.limit }],",
" upsert: async (context) => ({ upserted: context.points.length }),",
" delete: async (context) => ({ deleted: context.ids.length }),",
" });",
];
}

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

Refactor the nested if statements into a cleaner structure and remove the redundant defensive checks on document.metadata.title. Since title is a non-optional string guaranteed to be populated by the system, using String(document.metadata.title ?? "") is unnecessary and introduces unreachable branches.

  if (capability === "commands") {
    return commandLines;
  }
  if (capability === "search") {
    return [
      ...commandLines,
      "",
      "  // Search providers let packages customize how pm ranks and retrieves",
      "  // project context. This starter is deterministic and dependency-free:",
      "  // replace the scoring with your domain retrieval, embedding, or rerank",
      "  // logic as the package grows.",
      "  api.registerSearchProvider({",
      "    name: " + JSON.stringify(searchProviderName) + ",",
      "    query: async (context) => {",
      "      const needle = context.query.toLowerCase();",
      "      const hits = context.documents",
      "        .filter((document) => {",
      "          const title = document.metadata.title.toLowerCase();",
      "          return title.includes(needle);",
      "        })",
      "        .map((document) => ({",
      "          id: document.metadata.id,",
      "          score: 1,",
      "          matched_fields: [\"title\"],",
      "        }));",
      "      return { hits };",
      "    },",
      "    embed: async (context) => [context.input.length],",
      "  });",
      "",
      "  // Vector-store adapters let packages own semantic index storage. This",
      "  // starter returns a stable in-memory hit so generated tests can exercise",
      "  // the adapter without external services.",
      "  api.registerVectorStoreAdapter({",
      "    name: " + JSON.stringify(vectorAdapterName) + ",",
      "    query: async (context) => [{ id: \"starter-vector-hit\", score: context.limit }],",
      "    upsert: async (context) => ({ upserted: context.points.length }),",
      "    delete: async (context) => ({ deleted: context.ids.length }),",
      "  });",
    ];
  }
References
  1. Avoid adding redundant defensive checks (such as null/undefined guards or type checks) for fields that are typed as non-optional and guaranteed to be populated by the system.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
Comment on lines +165 to +169
const capabilitiesLiteral = hooksEnabled
? '["commands", "hooks"]'
: searchEnabled
? '["commands", "search"]'
: '["commands"]';

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

Simplify the nested ternary operators by directly interpolating the capability variable when it is not 'commands'.

  const capabilitiesLiteral = capability === "commands"
    ? '["commands"]'
    : '["commands", "' + capability + '"]';

Comment thread src/cli/commands/extension/scaffold.ts Outdated
Comment on lines +326 to +327
const capabilities =
capability === "hooks" ? ["commands", "hooks"] : capability === "search" ? ["commands", "search"] : ["commands"];

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

Simplify the nested ternary operators by using a direct check on 'commands' and appending the capability.

Suggested change
const capabilities =
capability === "hooks" ? ["commands", "hooks"] : capability === "search" ? ["commands", "search"] : ["commands"];
const capabilities =
capability === "commands" ? ["commands"] : ["commands", capability];

@unbraind

Copy link
Copy Markdown
Owner Author

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

Re-triggering after follow-up commit e81788f addressed Gemini feedback by simplifying scaffold branching and generated metadata handling.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of the PR including the changes from commit e81788fe!

✅ Action performed

Full review finished.

@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 search capability to the package and extension scaffolding system (pm package init --capability search). This scaffolds a starter package or extension containing a deterministic, in-memory search provider and vector-store adapter pair, along with runnable SDK tests. Additionally, the PR normalizes generated command names to use space-separated words instead of hyphenated names to prevent dynamic dispatch failures in Commander. Shell completions, help content, and documentation have been updated accordingly, and new unit tests have been added to verify the scaffolding output and completions. There are no review comments, so I have no feedback to provide.

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

Copy link
Copy Markdown
Owner Author

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

Re-triggering after follow-up commit a0b31d8 fixed the current-head Gates (smokes) failure by aligning dogfood-package-first with the normalized scaffold command path.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of the PR including the changes from commit a0b31d89!

✅ Action performed

Full review finished.

@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 a new --capability search option to the pm package init and pm extension init commands, allowing users to scaffold search provider and vector-store adapter starter packages with runnable SDK tests. It also normalizes generated command names by replacing hyphens with spaces to prevent dynamic dispatch failures in Commander. Feedback on the changes points out a potential runtime crash in the scaffolded search provider if a document's metadata lacks a title property, suggesting the use of optional chaining and a fallback value.

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.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
" const needle = context.query.toLowerCase();",
" const hits = context.documents",
" .filter((document) => {",
" const title = document.metadata.title.toLowerCase();",

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

In the scaffolded search provider, document.metadata.title is accessed and .toLowerCase() is called directly on it. However, document metadata is dynamic, and some documents might not have a title property (or it might be null/undefined). This would cause a runtime TypeError: Cannot read properties of undefined (reading 'toLowerCase') and crash the search provider.

To make the scaffolded code robust and production-ready, we should safely access the title property using optional chaining and a fallback value.

          const title = (document.metadata?.title ?? "").toLowerCase();

@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 `@src/cli/help-content.ts`:
- Around line 213-215: The example paths in the install commands are
inconsistent with their preceding init examples. In the first flow, the init
command uses "./my-search-package" but the install command uses "./my-package".
Similarly, in the second flow (lines 253-255), the paths do not align. Update
the install example paths to match the package names and paths established by
their corresponding preceding init examples so users can follow the examples
sequentially without confusion.

In `@tests/unit/extensions/extension-command.spec.ts`:
- Line 2196: There is a duplicated expect assertion on line 2196 in the test
file that matches the expect call checking scaffold.details files mapping.
Locate both instances of the identical expect((scaffold.details as { files?:
Array<{ path: string }> }).files?.map((file) => file.path)).toEqual([ assertion
and remove one of the duplicate lines to ensure the test parses correctly with a
single matched assertion pair.
🪄 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: be399da6-a1d4-4409-bedd-67e1080949ee

📥 Commits

Reviewing files that changed from the base of the PR and between 4fc596a and a0b31d8.

📒 Files selected for processing (12)
  • .agents/pm/features/pm-pwai.toon
  • .agents/pm/history/pm-pwai.jsonl
  • CHANGELOG.md
  • docs/EXTENSIONS.md
  • docs/SDK.md
  • scripts/dogfood-package-first.mjs
  • src/cli/commands/completion.ts
  • src/cli/commands/extension/scaffold.ts
  • src/cli/help-content.ts
  • tests/unit/commands/completion-command.spec.ts
  • tests/unit/extensions/extension-command.spec.ts
  • tests/unit/scripts/dogfood-package-first.spec.ts

Comment thread src/cli/help-content.ts Resolved
command: "starter search ext ping",
},
});
expect((scaffold.details as { files?: Array<{ path: string }> }).files?.map((file) => file.path)).toEqual([

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove the duplicated assertion line (test parse break risk).

Line 2196 appears duplicated with the same expect(...).toEqual([ call. If both exist in the file, this leaves an unmatched call and breaks test parsing.

Proposed fix
-      expect((scaffold.details as { files?: Array<{ path: string }> }).files?.map((file) => file.path)).toEqual([
       expect((scaffold.details as { files?: Array<{ path: string }> }).files?.map((file) => file.path)).toEqual([
🤖 Prompt for 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.

In `@tests/unit/extensions/extension-command.spec.ts` at line 2196, There is a
duplicated expect assertion on line 2196 in the test file that matches the
expect call checking scaffold.details files mapping. Locate both instances of
the identical expect((scaffold.details as { files?: Array<{ path: string }>
}).files?.map((file) => file.path)).toEqual([ assertion and remove one of the
duplicate lines to ensure the test parses correctly with a single matched
assertion pair.

@unbraind

Copy link
Copy Markdown
Owner Author

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

Re-triggering after follow-up commit 3a2dffb addressed current-head review feedback: aligned help examples and made generated search title access defensive. CodeRabbit duplicate assertion note was verified as a false positive against the current file and covered by focused tests.

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of the PR including the changes from commit 3a2dffb0!

✅ Action performed

Full review finished.

@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 --capability search option for pm package init and pm extension init, allowing developers to scaffold starter packages with an in-memory search provider and vector-store adapter along with runnable SDK tests. It also normalizes generated command paths from hyphenated names to space-separated words to ensure proper dynamic dispatch. Documentation, shell completions, and unit tests have been updated accordingly. Feedback on the changes suggests removing a redundant optional chaining guard on document.metadata in the generated search provider code to maintain consistency with other direct property accesses.

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.

Comment thread src/cli/commands/extension/scaffold.ts Outdated
" const needle = context.query.toLowerCase();",
" const hits = context.documents",
" .filter((document) => {",
" const title = String(document.metadata?.title ?? \"\").toLowerCase();",

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

According to the general rules, we should avoid adding redundant defensive checks (such as optional chaining guards) for fields that are guaranteed to be populated by the system. Since document.metadata is consumed unguarded on line 177 (document.metadata.id), using optional chaining document.metadata?.title on line 173 is redundant and inconsistent. Please remove the optional chaining on metadata to keep the property access consistent and avoid unreachable branches.

          const title = String(document.metadata.title ?? "").toLowerCase();
References
  1. Avoid adding redundant defensive checks (such as null/undefined guards or type checks) for fields that are typed as non-optional and guaranteed to be populated by the system.

@unbraind

Copy link
Copy Markdown
Owner Author

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

Re-triggering after follow-up commit 397389d removed optional chaining on the guaranteed metadata object while keeping a title fallback for dynamic document metadata.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@chatgpt-codex-connector

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Jun 21, 2026 •

Copy link
Copy Markdown

@unbraind Sure, I'll kick off a full review of the PR including the changes from commit 397389dd!

✅ Action performed

Full review finished.

@unbraind
unbraind merged commit bebb6b4 into main Jun 21, 2026
16 checks passed
@unbraind
unbraind deleted the feat/package-search-scaffold-pm-pwai branch June 21, 2026 23:02
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