Skip to content

feat(#45): dashboard-only project creation; manual Project ID as sole remote path - #135

Merged
AndresL230 merged 7 commits into
mainfrom
feat/dashboard-only-project-id
Jun 10, 2026
Merged

feat(#45): dashboard-only project creation; manual Project ID as sole remote path#135
AndresL230 merged 7 commits into
mainfrom
feat/dashboard-only-project-id

Conversation

@AndresL230

@AndresL230 AndresL230 commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #45 (reframed). Inverts the project-ID model: projects are created only in the web dashboard, and a user-supplied Project ID is the single path to remote scan enrichment. The extension and CLI no longer auto-create projects.

  • Extension scan flowresolveScanProjectTarget() now returns a manual target or null; deleted getOrCreateProject(), the 404→auto-recreate recovery, and the recost.projectId globalState. No Project ID → local-only results + a nudge.
  • Chat contextgetProjectId() now reads the manual Project ID instead of the retired auto-persisted field.
  • CLI (src/cli/scan.ts) — takes --project-id <id> / RECOST_PROJECT_ID; no auto-creation; prints a stderr nudge and runs local-only without one.
  • API client — removed now-unused createProject / findProjectByName.
  • Keys tab — copy now states remote sync requires a dashboard-created Project ID, plus an "Open dashboard" link.
  • Docs — spec + plan under docs/superpowers/, CLAUDE.md auth section updated.

Behavior matrix

State Result
No API key local-only + existing notice
Key, no Project ID local-only + "add a Project ID" nudge
Key + invalid Project ID (404) local-only; saved ID retained; "not found" notice
Key + valid Project ID remote submit to that project

Test Plan

  • npm run build (dashboard + webview + extension) succeeds
  • npm test passes, including two new scan-publishing-handler tests: null target → no submitScan + nudge; manual target → submitScan with that ID
  • Regression grep: no getOrCreateProject / createProject / findProjectByName / recost.projectId remain
  • node dist/cli/scan.js --help documents --project-id
  • Manual smoke: extension scan with a pasted dashboard Project ID syncs; without one shows local-only + nudge

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added --project-id CLI argument and RECOST_PROJECT_ID environment variable support for remote scan syncing
    • Updated Project ID settings with dashboard link and clearer setup instructions
  • Refactor

    • Modified project ID resolution to require manual user input; remote syncing now proceeds only when Project ID is configured

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR shifts project creation from automatic (extension-driven) to manual (dashboard-first). Projects are no longer auto-created; instead, users must create them in the ReCost dashboard and supply the Project ID to the extension or CLI. Remote scan enrichment only runs when both an API key and a valid Project ID are present; otherwise scans execute locally with a user nudge.

Changes

Dashboard-Only Project ID Model

Layer / File(s) Summary
Design & Specification
CLAUDE.md, docs/superpowers/specs/2026-06-09-dashboard-only-project-id-design.md, docs/superpowers/plans/2026-06-10-dashboard-only-project-id.md
Defines the new dashboard-only model: projects created only in the web dashboard, no auto-creation in extension/CLI. Remote enrichment requires both an API key and a user-supplied Project ID; otherwise defaults to local-only with nudge notification.
API Client Contract
src/api-client.ts
Removes exported createProject and findProjectByName functions that previously handled auto-creation via POST /projects and project lookup.
CLI Project ID Support
src/cli/scan.ts
Adds --project-id flag and RECOST_PROJECT_ID environment variable parsing; remote enrichment only proceeds when project ID is set, otherwise prints nudge message directing user to configure it.
Extension Provider Refactor
src/webview-provider.ts
Removes internal stored/generated projectId state and getOrCreateProject helper; refactors resolveScanProjectTarget to return manual Project ID when available or null otherwise; removes globalState persistence loading.
Scan Handler Context & Wiring
src/webview/scan-publishing-handler.ts
Tightens ScanPublishingHandlerContext interface by removing setProjectId/getProjectId methods and narrowing resolveScanProjectTarget return type to null | { projectId, source: "manual" }; updates chat and scan handler wiring accordingly.
Scan Handler Flow & Fallbacks
src/webview/scan-publishing-handler.ts
Implements null-safe project target handling with notification nudge when remote sync is blocked by missing Project ID; updates all local-only publication paths to use manualProjectId ?? "local"; removes auto-create recovery on 404.
Tests
src/test/scan-publishing-handler.test.ts
Removes createProject from mocked API client; updates test context scaffolding; adds test cases covering null target (local-only with nudge, no remote call) and manual target (successful remote submission with project ID).
Keys Page UI
webview/src/components/KeysPage.tsx
Updates Project ID helper text to direct users to create projects in the ReCost dashboard, paste the ID to enable remote syncing, and provides "Open dashboard" button for quick access.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • recost-dev/extension#123: Both PRs modify src/webview/scan-publishing-handler.ts including local/remote routing logic and error/notification flows, so this PR's null-safe project target handling and nudge notification refactor directly impact that prior status/error UX work.

Poem

🐰 Dashboard-born projects now lead the way,
No more creation at scan-time—hooray!
Manual IDs guide the remote flow,
Local nudges help users know,
Cleaner contracts make the code okay! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR deviates significantly from issue #45's opt-in model with persistence; instead it implements a dashboard-only mandate where auto-creation is entirely removed and projects are never created by the extension/CLI. Issue #45 requires an opt-in persistence mode (default false) with auto-creation as fallback; this PR removes auto-creation entirely and makes dashboard-created IDs mandatory, violating the acceptance criteria and proposed behavior of the linked issue.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 clearly and specifically describes the main change: shifting to dashboard-only project creation with manual Project ID as the sole remote path, directly addressing issue #45.
Out of Scope Changes check ✅ Passed All changes align with the stated PR objectives to implement dashboard-only project creation; no unrelated modifications detected across docs, source files, or tests.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/dashboard-only-project-id

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.

@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.

🧹 Nitpick comments (1)
src/cli/scan.ts (1)

105-119: 💤 Low value

Trim CLI flag value for consistency with env var handling.

The env var is trimmed on line 119, but the CLI flag value is used as-is. A whitespace-only --project-id " " would pass validation and be treated as a valid ID, causing an API error later (gracefully caught, but confusing).

🔧 Suggested fix
    if (arg === "--project-id") {
      const value = args.shift();
-     if (!value) throw new Error("--project-id requires a value");
-     projectId = value;
+     const trimmed = value?.trim();
+     if (!trimmed) throw new Error("--project-id requires a value");
+     projectId = trimmed;
      continue;
    }

Then simplify line 119:

-  return { target, format, projectId: (projectId ?? process.env.RECOST_PROJECT_ID?.trim()) || undefined };
+  return { target, format, projectId: projectId ?? process.env.RECOST_PROJECT_ID?.trim() || undefined };
🤖 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 `@src/cli/scan.ts` around lines 105 - 119, The CLI parsing currently assigns
the raw flag string to projectId when handling "--project-id" (in the argument
loop in scan.ts) but trims only the env var later; change the assignment so you
trim the CLI value (e.g., set projectId = value.trim()) and then keep the final
return simplification that uses projectId ??
process.env.RECOST_PROJECT_ID?.trim() || undefined so both CLI and env values
are normalized and whitespace-only inputs become undefined.
🤖 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.

Nitpick comments:
In `@src/cli/scan.ts`:
- Around line 105-119: The CLI parsing currently assigns the raw flag string to
projectId when handling "--project-id" (in the argument loop in scan.ts) but
trims only the env var later; change the assignment so you trim the CLI value
(e.g., set projectId = value.trim()) and then keep the final return
simplification that uses projectId ?? process.env.RECOST_PROJECT_ID?.trim() ||
undefined so both CLI and env values are normalized and whitespace-only inputs
become undefined.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 283a85fc-e73d-4759-99ed-65b3e6f02826

📥 Commits

Reviewing files that changed from the base of the PR and between e0916b6 and e371268.

📒 Files selected for processing (9)
  • CLAUDE.md
  • docs/superpowers/plans/2026-06-10-dashboard-only-project-id.md
  • docs/superpowers/specs/2026-06-09-dashboard-only-project-id-design.md
  • src/api-client.ts
  • src/cli/scan.ts
  • src/test/scan-publishing-handler.test.ts
  • src/webview-provider.ts
  • src/webview/scan-publishing-handler.ts
  • webview/src/components/KeysPage.tsx
💤 Files with no reviewable changes (1)
  • src/api-client.ts

@AndresL230

Copy link
Copy Markdown
Contributor Author

Verification (CLI surface) — PASS

Drove the built CLI (dist/cli/scan.js) against a sample workspace containing a real outbound call (fetch("https://api.openai.com/v1/chat/completions", …)). For HTTP-level proof, RECOST_API_BASE_URL was pointed at a local request-logging server.

Scenario Result
No API key detects endpoint, local-only, no nudge ✅
Key, no Project ID prints Set RECOST_PROJECT_ID (or --project-id) to sync scans remotely. Showing local-only results., local-only
Key + --project-id proj_verify123 server logged one request POST /projects/proj_verify123/scans — uses supplied ID, no POST /projects auto-create; degrades to local-only on error ✅

Probes:

  • --project-id with no value → --project-id requires a value, exit 1 ✅
  • empty RECOST_PROJECT_ID="" → treated as absent → nudge ✅
  • --project-id flag_proj + RECOST_PROJECT_ID=env_proj → wire-level POST /projects/flag_proj/scans (flag beats env) ✅
  • --help documents the flag ✅

Decisive evidence (request the CLI sent with a supplied ID — no auto-create call precedes it):

POST /projects/proj_verify123/scans

Not yet runtime-verified

  • Extension webview path (sidebar no-ID nudge + Keys-tab "Open dashboard" link). It runs only inside the VS Code Extension Development Host (GUI), not drivable headlessly here. Covered by the two new scan-publishing-handler unit tests; needs a manual F5 click-through to fully confirm.

Updating the test-plan checkboxes accordingly: build, suite, regression grep, --help, and the CLI no-ID/with-ID behavior are all confirmed.

@AndresL230
AndresL230 merged commit cc187d1 into main Jun 10, 2026
3 checks passed
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.

Extension: Opt-in Project ID Persistence

1 participant