Skip to content

Conversation

@TabishB
Copy link
Contributor

@TabishB TabishB commented Jan 14, 2026

Summary

Implements the openspec feedback command that allows users and agents to submit feedback about OpenSpec directly from the CLI by creating GitHub Issues using the gh CLI.

This PR completes all tasks from the add-feedback-command change proposal (16/16 tasks complete).

What Changes

1. Feedback Command (src/commands/feedback.ts)

  • CLI Command: openspec feedback <message> [--body <text>]
  • Automatic gh CLI detection: Checks if gh is installed using which gh
  • Authentication check: Verifies gh auth status before submitting
  • Issue creation: Uses gh issue create to submit feedback to the OpenSpec repository
  • Graceful fallback: When gh is missing or unauthenticated:
    • Displays formatted feedback content with delimiters
    • Provides pre-filled GitHub issue URL for manual submission
    • Shows authentication instructions for future auto-submission
    • Exits with code 0 (successful fallback)

2. Metadata Inclusion

All feedback submissions automatically include:

  • OpenSpec CLI version
  • Platform (darwin, linux, win32)
  • Timestamp
  • "feedback" label on the GitHub Issue

3. Agent Skill (/feedback)

Added feedback skill template in src/core/templates/skill-templates.ts:

  • Context gathering: Collects relevant context from conversation history
  • Anonymization: Automatically redacts sensitive information:
    • File paths → <path>
    • API keys/secrets → <redacted>
    • Company names → <company>
    • Personal names → <user>
  • User confirmation required: Shows draft and requires explicit approval before submitting

4. Shell Completions

  • Added feedback command to command registry
  • Completions automatically generated for all supported shells (bash, zsh, fish, PowerShell)

5. Comprehensive Testing

Added test/commands/feedback.test.ts with 11 test cases covering:

  • Missing gh CLI with fallback
  • Unauthenticated gh with fallback
  • Successful feedback submission
  • Error handling for gh CLI failures
  • Quote escaping in titles and bodies
  • Metadata inclusion verification
  • Formatted feedback output structure

Test plan

  • All existing tests pass (919 tests)
  • New feedback command tests pass (11 tests)
  • Build succeeds with no TypeScript errors
  • Command registered in CLI index
  • Command added to completion registry
  • Feedback skill template exported

Implementation Notes

  • Uses subprocess execSync for gh CLI interactions
  • Proper error handling with exit codes matching gh CLI behavior
  • Quote escaping for safe shell command execution
  • Works regardless of telemetry settings
  • No sensitive metadata included (no file paths, env vars, etc.)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a top-level feedback command to submit feedback as GitHub issues.
    • Auto-includes metadata (version, platform, timestamp) and optional body text.
    • Cross-platform gh CLI detection and graceful fallback to a pre-filled manual submission URL when gh is missing or unauthenticated.
    • Requires the GitHub CLI to be installed and authenticated for automatic submissions.
  • Tests

    • Added comprehensive tests covering gh presence, authentication, submission, and fallback flows.

✏️ Tip: You can customize this high-level summary in your review settings.

Implement `openspec feedback` command that creates GitHub Issues using the gh CLI.
Includes graceful fallback to manual submission when gh is not available or
not authenticated.

Features:
- Automatic gh CLI detection and authentication check
- Graceful fallback with pre-filled issue URLs for manual submission
- Automatic metadata inclusion (version, platform, timestamp)
- /feedback skill for agent-assisted feedback with context enrichment
- Comprehensive test coverage with mocked gh CLI calls
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

Adds a new feedback CLI command that submits feedback as GitHub issues via the gh CLI, with metadata enrichment and a graceful fallback to a manual pre-filled issue URL when gh is missing or unauthenticated. Updates specs, templates, tests, and command registration.

Changes

Cohort / File(s) Summary
Specs & Docs
openspec/changes/add-feedback-command/proposal.md, openspec/changes/add-feedback-command/specs/cli-feedback/spec.md, openspec/changes/add-feedback-command/tasks.md
Replace OAuth device-flow design with gh CLI-based workflow; add fallback scenarios for missing/unauthenticated gh; update metadata format and agent flow; document testing and cross-platform detection.
CLI Registration
src/cli/index.ts, src/core/completions/command-registry.ts
Register new top-level feedback <message> command with --body option and add command registry entry for completions.
Command Implementation
src/commands/feedback.ts
New FeedbackCommand export: detects gh availability/auth, generates metadata (version/platform/timestamp), formats title/body, submits via gh issue create using safe exec, handles gh errors, and provides manual submission fallback URL and formatted output.
Skill Template
src/core/templates/skill-templates.ts
Add getFeedbackSkillTemplate() export describing feedback skill workflow (context collection, anonymization, approval, submission).
Tests
test/commands/feedback.test.ts
Add comprehensive tests mocking execSync/execFileSync across platforms: gh detection, auth fallback, successful submission, error propagation, metadata injection, and manual URL output.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant CLI as openspec CLI
    participant Cmd as FeedbackCommand
    participant Detect as gh Detection (which/where, gh auth)
    participant GH as gh CLI (execFileSync)
    participant Manual as Manual Submission URL

    User->>CLI: feedback "message" --body "details"
    CLI->>Cmd: execute(message, options)
    Cmd->>Detect: isGhInstalled()?
    alt gh not installed
        Detect-->>Cmd: false
        Cmd->>Manual: generateManualSubmissionUrl()
        Cmd->>User: display fallback + formatted body
    else gh installed
        Detect-->>Cmd: true
        Cmd->>Detect: isGhAuthenticated()?
        alt unauthenticated
            Detect-->>Cmd: false
            Cmd->>Manual: generateManualSubmissionUrl()
            Cmd->>User: display auth guidance + URL
        else authenticated
            Detect-->>Cmd: true
            Cmd->>Cmd: generateMetadata() & formatBody()/formatTitle()
            Cmd->>GH: execFileSync("gh", ["issue","create", ...])
            alt gh succeeds
                GH-->>Cmd: returns issue URL
                Cmd->>User: print issue URL
            else gh fails
                GH-->>Cmd: error + exit code
                Cmd->>User: print error, exit with gh status
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
I hopped through code with nimble toes,
A feedback path for highs and woes;
If gh is here, your issue flies,
If not, a URL for manual ties;
A carrot-shaped thank-you—cheers and bows! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a feedback command for submitting user feedback to GitHub Issues via the gh CLI, which is the primary feature across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
test/commands/feedback.test.ts (2)

19-27: vi.clearAllMocks() after spy setup clears mock implementations.

Calling vi.clearAllMocks() on line 26 after setting up mockExecSync and mockExecFileSync assignments (lines 16-17) will clear any default mock implementations. Since the actual .mockImplementation() calls happen inside each test, this works, but the placement is misleading. Consider moving vi.clearAllMocks() to the start of beforeEach for clarity.

♻️ Suggested improvement
   beforeEach(() => {
+    vi.clearAllMocks();
     feedbackCommand = new FeedbackCommand();
     consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
     consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
     processExitSpy = vi.spyOn(process, 'exit').mockImplementation((code?: string | number | null) => {
       throw new Error(`process.exit(${code})`);
     });
-    vi.clearAllMocks();
   });

34-58: Platform restore may be skipped if test assertion fails.

If an assertion fails before line 57, process.platform won't be restored, potentially affecting subsequent tests. Consider using a try/finally block or storing/restoring in beforeEach/afterEach.

♻️ Safer platform mocking pattern
     it('should use which command on Unix/macOS platforms', async () => {
       // Mock platform as darwin
       const originalPlatform = process.platform;
       Object.defineProperty(process, 'platform', { value: 'darwin' });
 
-      mockExecSync.mockImplementation((cmd: string) => {
-        if (cmd === 'which gh') {
-          return Buffer.from('/usr/local/bin/gh');
-        }
-        if (cmd === 'gh auth status') {
-          return Buffer.from('Logged in');
-        }
-        return '';
-      });
-
-      mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/123\n');
-
-      await feedbackCommand.execute('Test');
-
-      // Verify 'which gh' was called
-      expect(mockExecSync).toHaveBeenCalledWith('which gh', expect.any(Object));
-
-      // Restore original platform
-      Object.defineProperty(process, 'platform', { value: originalPlatform });
+      try {
+        mockExecSync.mockImplementation((cmd: string) => {
+          if (cmd === 'which gh') {
+            return Buffer.from('/usr/local/bin/gh');
+          }
+          if (cmd === 'gh auth status') {
+            return Buffer.from('Logged in');
+          }
+          return '';
+        });
+
+        mockExecFileSync.mockReturnValue('https://github.com/Fission-AI/OpenSpec/issues/123\n');
+
+        await feedbackCommand.execute('Test');
+
+        // Verify 'which gh' was called
+        expect(mockExecSync).toHaveBeenCalledWith('which gh', expect.any(Object));
+      } finally {
+        // Restore original platform
+        Object.defineProperty(process, 'platform', { value: originalPlatform });
+      }
     });

Apply the same pattern to the Windows platform test (lines 60-84).


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5032152 and 1f4e4a9.

📒 Files selected for processing (5)
  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
  • openspec/changes/add-feedback-command/tasks.md
  • src/commands/feedback.ts
  • test/commands/feedback.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/commands/feedback.ts
🧰 Additional context used
📓 Path-based instructions (5)
openspec/changes/*/proposal.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Create proposal.md with Why, What Changes (with BREAKING markers), and Impact sections

Files:

  • openspec/changes/add-feedback-command/proposal.md
openspec/changes/*/{proposal,design,tasks}.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Use direct file references in format file.ts:42 and reference specs as specs/auth/spec.md for clarity

Files:

  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/tasks.md
openspec/changes/*/tasks.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Create tasks.md with numbered implementation sections and checkboxes in format - [ ] X.Y Task description

Files:

  • openspec/changes/add-feedback-command/tasks.md
openspec/changes/*/specs/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/changes/*/specs/**/spec.md: Use ## ADDED|MODIFIED|REMOVED|RENAMED Requirements headers in spec delta files with at least one #### Scenario: per requirement
Format scenarios with exactly four hashtags (#### Scenario:) followed by bullet points with **WHEN** and **THEN** syntax
In MODIFIED Requirements, copy the entire existing requirement block and paste under ## MODIFIED Requirements, then edit to reflect new behavior
Use ADDED for new orthogonal capabilities; use MODIFIED for behavior/scope/criteria changes; use RENAMED for name-only changes
In spec deltas, include a **Reason** field for REMOVED requirements and a **Migration** field explaining how to handle the removal

Files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
openspec/**/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/**/**/spec.md: Use SHALL/MUST for normative requirements in specs; avoid should/may unless intentionally non-normative
Ensure every requirement in spec files has at least one #### Scenario: with WHEN/THEN structure

Files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
🧠 Learnings (5)
📚 Learning: 2025-11-25T01:08:02.839Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T01:08:02.839Z
Learning: Use `@/openspec/AGENTS.md` to learn how to create and apply change proposals, spec format and conventions, and project structure and guidelines

Applied to files:

  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/tasks.md : Create `tasks.md` with numbered implementation sections and checkboxes in format `- [ ] X.Y Task description`

Applied to files:

  • openspec/changes/add-feedback-command/tasks.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements` headers in spec delta files with at least one `#### Scenario:` per requirement

Applied to files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ADDED for new orthogonal capabilities; use MODIFIED for behavior/scope/criteria changes; use RENAMED for name-only changes

Applied to files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/{proposal,design,tasks}.md : Use direct file references in format `file.ts:42` and reference specs as `specs/auth/spec.md` for clarity

Applied to files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
🧬 Code graph analysis (1)
test/commands/feedback.test.ts (1)
src/commands/feedback.ts (1)
  • FeedbackCommand (187-208)
🔇 Additional comments (7)
openspec/changes/add-feedback-command/proposal.md (1)

1-20: LGTM!

The proposal follows the required structure with Why, What Changes, and Impact sections. The file references in the Impact section are clear, and the external dependency on gh CLI is properly documented.

openspec/changes/add-feedback-command/tasks.md (1)

1-30: LGTM!

The tasks file follows the required format with numbered sections and X.Y checkbox notation. All implementation tasks are properly organized and marked complete.

test/commands/feedback.test.ts (3)

152-201: LGTM!

Comprehensive test for successful feedback submission. The test properly verifies the execFileSync call with the correct arguments including repo, title prefix, body with metadata, and feedback label.


343-371: Good coverage for shell injection prevention.

This test correctly validates that execFileSync passes quotes as literal text without shell interpretation, confirming the security improvement mentioned in the PR objectives.


374-428: LGTM!

Good coverage for the fallback flow, verifying both the structured output format and the manual submission URL with proper query parameters.

openspec/changes/add-feedback-command/specs/cli-feedback/spec.md (2)

1-102: LGTM!

The spec follows the required format with ## ADDED Requirements header, proper #### Scenario: formatting, and **WHEN**/**THEN** structure. Each requirement has at least one scenario, and normative language (SHALL) is used appropriately.


137-175: LGTM!

The feedback skill specification properly defines the agent workflow including context gathering, anonymization rules, and mandatory user confirmation before submission. The anonymization scenario provides clear replacement patterns for sensitive data.

✏️ Tip: You can disable this entire section by setting review_details to false in your review 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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/commands/feedback.ts`:
- Around line 10-17: The isGhInstalled function incorrectly uses the Unix-only
"which" command; replace its logic to run a cross-platform validation like
executing "gh --version" via execSync inside isGhInstalled and return true only
if the command succeeds (capture stdout/stderr with stdio:'pipe'), otherwise
catch the error and return false; keep the function signature isGhInstalled():
boolean and ensure the catch block handles any thrown error from execSync rather
than relying on "which".
- Around line 122-143: The submitViaGhCli function currently builds a single
shell string and only escapes double quotes, leaving it vulnerable to shell
metacharacter interpretation; replace execSync with execFileSync (or spawnSync)
and pass the gh executable and an args array (e.g., ['issue', 'create',
'--repo', 'Fission-AI/OpenSpec', '--title', title, '--body', body, '--label',
'feedback']) so user input is passed as argv elements rather than interpolated
into a shell command, capture stdout/stderr via stdio/options to read the
returned issue URL, and preserve the existing error handling behavior by using
the child error.status (defaulting to 1) for process.exit.
🧹 Nitpick comments (2)
src/commands/feedback.ts (1)

172-195: Consider extracting title/body formatting to reduce duplication.

The formatTitle and formatBody calls are repeated in all three branches. Moving them before the conditionals would reduce duplication and make the code easier to maintain.

♻️ Proposed refactor
 export class FeedbackCommand {
   async execute(message: string, options?: { body?: string }): Promise<void> {
+    const title = formatTitle(message);
+    const body = formatBody(options?.body);
+
     // Check if gh CLI is installed
     if (!isGhInstalled()) {
-      const title = formatTitle(message);
-      const body = formatBody(options?.body);
       handleFallback(title, body, 'missing');
       return;
     }

     // Check if gh CLI is authenticated
     if (!isGhAuthenticated()) {
-      const title = formatTitle(message);
-      const body = formatBody(options?.body);
       handleFallback(title, body, 'unauthenticated');
       return;
     }

     // Submit via gh CLI
-    const title = formatTitle(message);
-    const body = formatBody(options?.body);
     submitViaGhCli(title, body);
   }
 }
openspec/changes/add-feedback-command/specs/cli-feedback/spec.md (1)

47-48: Minor: Consider "in the future" for American English consistency.

The phrase "in future" is British English. For consistency, consider changing to "in the future".

-- **AND** displays authentication instructions: "To auto-submit in future: gh auth login"
+- **AND** displays authentication instructions: "To auto-submit in the future: gh auth login"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf4bc24 and 5032152.

📒 Files selected for processing (8)
  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
  • openspec/changes/add-feedback-command/tasks.md
  • src/cli/index.ts
  • src/commands/feedback.ts
  • src/core/completions/command-registry.ts
  • src/core/templates/skill-templates.ts
  • test/commands/feedback.test.ts
🧰 Additional context used
📓 Path-based instructions (5)
openspec/changes/*/proposal.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Create proposal.md with Why, What Changes (with BREAKING markers), and Impact sections

Files:

  • openspec/changes/add-feedback-command/proposal.md
openspec/changes/*/{proposal,design,tasks}.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Use direct file references in format file.ts:42 and reference specs as specs/auth/spec.md for clarity

Files:

  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/tasks.md
openspec/changes/*/tasks.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

Create tasks.md with numbered implementation sections and checkboxes in format - [ ] X.Y Task description

Files:

  • openspec/changes/add-feedback-command/tasks.md
openspec/changes/*/specs/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/changes/*/specs/**/spec.md: Use ## ADDED|MODIFIED|REMOVED|RENAMED Requirements headers in spec delta files with at least one #### Scenario: per requirement
Format scenarios with exactly four hashtags (#### Scenario:) followed by bullet points with **WHEN** and **THEN** syntax
In MODIFIED Requirements, copy the entire existing requirement block and paste under ## MODIFIED Requirements, then edit to reflect new behavior
Use ADDED for new orthogonal capabilities; use MODIFIED for behavior/scope/criteria changes; use RENAMED for name-only changes
In spec deltas, include a **Reason** field for REMOVED requirements and a **Migration** field explaining how to handle the removal

Files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
openspec/**/**/spec.md

📄 CodeRabbit inference engine (openspec/AGENTS.md)

openspec/**/**/spec.md: Use SHALL/MUST for normative requirements in specs; avoid should/may unless intentionally non-normative
Ensure every requirement in spec files has at least one #### Scenario: with WHEN/THEN structure

Files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
🧠 Learnings (6)
📚 Learning: 2025-11-25T01:08:02.839Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T01:08:02.839Z
Learning: Use `@/openspec/AGENTS.md` to learn how to create and apply change proposals, spec format and conventions, and project structure and guidelines

Applied to files:

  • openspec/changes/add-feedback-command/proposal.md
  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/tasks.md : Create `tasks.md` with numbered implementation sections and checkboxes in format `- [ ] X.Y Task description`

Applied to files:

  • openspec/changes/add-feedback-command/tasks.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Complete all tasks sequentially from `tasks.md` and update every task to `- [x]` before marking proposal as complete

Applied to files:

  • openspec/changes/add-feedback-command/tasks.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use ADDED for new orthogonal capabilities; use MODIFIED for behavior/scope/criteria changes; use RENAMED for name-only changes

Applied to files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Applies to openspec/changes/*/specs/**/spec.md : Use `## ADDED|MODIFIED|REMOVED|RENAMED Requirements` headers in spec delta files with at least one `#### Scenario:` per requirement

Applied to files:

  • openspec/changes/add-feedback-command/specs/cli-feedback/spec.md
📚 Learning: 2026-01-13T22:51:14.330Z
Learnt from: CR
Repo: Fission-AI/OpenSpec PR: 0
File: openspec/AGENTS.md:0-0
Timestamp: 2026-01-13T22:51:14.330Z
Learning: Scaffold `proposal.md`, `tasks.md`, optional `design.md`, and delta specs under `openspec/changes/<id>/` when creating a change proposal

Applied to files:

  • src/core/completions/command-registry.ts
🧬 Code graph analysis (2)
src/cli/index.ts (1)
src/commands/feedback.ts (1)
  • FeedbackCommand (172-195)
test/commands/feedback.test.ts (1)
src/commands/feedback.ts (1)
  • FeedbackCommand (172-195)
🪛 Gitleaks (8.30.0)
src/core/templates/skill-templates.ts

[high] 2374-2374: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 LanguageTool
openspec/changes/add-feedback-command/specs/cli-feedback/spec.md

[locale-violation] ~47-~47: The phrase ‘in future’ is British English. Did you mean: “in the future”?
Context: ...ntication instructions: "To auto-submit in future: gh auth login" - AND exits with ze...

(IN_FUTURE)

🔇 Additional comments (12)
src/core/completions/command-registry.ts (1)

158-169: LGTM - feedback command registration looks correct.

The command definition aligns with the CLI implementation. Minor observation: other commands with acceptsPositional: true typically specify a positionalType (e.g., 'path', 'change-id'). Consider adding positionalType: 'message' or similar for consistency in shell completion hints, though this is optional since completions likely won't suggest message content.

src/core/templates/skill-templates.ts (1)

2304-2411: Well-structured feedback skill template with comprehensive privacy guidance.

The template provides clear instructions for context gathering, anonymization, and user confirmation before submission. The anonymization examples effectively demonstrate what sensitive data patterns to redact.

Regarding the static analysis hint about the API key at line 2374: this is a false positive. The sk_live_abc123xyz string is intentionally placed within a "Before:" example block to illustrate what sensitive data looks like before anonymization. The "After:" block shows it properly replaced with <redacted>. This is documentation, not an actual credential.

openspec/changes/add-feedback-command/proposal.md (1)

1-19: Proposal structure follows conventions.

The proposal correctly includes Why, What Changes, and Impact sections as per coding guidelines. The external dependency on gh CLI is appropriately documented. File references are clear and match the actual implementation paths.

src/cli/index.ts (2)

16-16: Import correctly added.


297-311: Feedback command integration follows established patterns.

The command registration is consistent with other commands in the file:

  • Proper error handling with try/catch
  • Uses ora().fail() for error display
  • Exits with code 1 on failure
  • Awaits the async execute() method
test/commands/feedback.test.ts (4)

1-29: Test setup looks solid.

The mock setup for execSync, console spies, and process.exit follows standard Vitest patterns. The process.exit mock that throws an error is a common technique to prevent actual process termination while still being able to assert on exit codes.


98-223: Comprehensive coverage for successful submission scenarios.

Tests verify:

  • gh issue create invocation
  • Success message display
  • Body flag inclusion
  • Title formatting with "Feedback:" prefix
  • Metadata injection (version, platform, timestamp)
  • Label addition

Good coverage of the happy path.


225-275: Error handling tests are thorough.

Good coverage of:

  • gh CLI execution failures with proper exit code propagation
  • Quote escaping to prevent shell injection

The quote escaping test at lines 255-274 is particularly important for security, ensuring user input with quotes doesn't break the shell command.


277-331: Fallback output tests validate manual submission guidance.

Tests confirm that when gh CLI is unavailable, users receive:

  • Formatted feedback display with clear delimiters
  • Pre-filled GitHub issue URL with proper parameters
  • Title, body, and labels properly encoded in the URL
openspec/changes/add-feedback-command/tasks.md (1)

1-27: LGTM!

The tasks file follows the required format with numbered implementation sections and checkboxes in the - [x] X.Y Task description format. All tasks are properly organized and marked complete, aligning with the PR objectives. Based on learnings, this matches the expected structure.

openspec/changes/add-feedback-command/specs/cli-feedback/spec.md (2)

105-110: Spec/implementation mismatch: network connectivity suggestion not implemented.

The spec states the system "suggests checking network connectivity" on network failure, but the implementation in feedback.ts only displays the error from gh CLI without adding this additional guidance. Either update the implementation to add this suggestion, or adjust the spec to match the current behavior.


1-163: Spec follows required format conventions.

The spec correctly uses ## ADDED Requirements headers, #### Scenario: format with exactly four hashtags, and **WHEN**/**THEN** syntax throughout. Each requirement has at least one scenario. Based on learnings, this aligns with the expected spec delta format.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

- Add Windows compatibility: use 'where gh' on Windows, 'which gh' on Unix/macOS
- Fix shell injection vulnerability: replace execSync with execFileSync and argument arrays
- Fix British English phrasing: "in future" → "in the future"
- Reduce code duplication: extract formatTitle/formatBody to single location
- Update tests to verify execFileSync usage and cross-platform command detection
- Add spec scenarios for safe command execution and cross-platform support
@TabishB TabishB merged commit c86985d into main Jan 14, 2026
7 checks passed
@TabishB TabishB deleted the TabishB/managua-v1 branch January 14, 2026 23:48
@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

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