Skip to content

feat(cli): add alternative authentication for link command#24

Merged
jwfing merged 3 commits intoInsForge:mainfrom
git112:main
Mar 19, 2026
Merged

feat(cli): add alternative authentication for link command#24
jwfing merged 3 commits intoInsForge:mainfrom
git112:main

Conversation

@git112
Copy link
Contributor

@git112 git112 commented Mar 15, 2026

Closes #20

Added --api-base-url and --api-key options to the insforge link command to bypass OAuth. This enables direct project linking for OSS/self-hosted instances, remote servers, CI, headless environments, and TUI tools.

Summary by CodeRabbit

  • New Features

    • CLI: Added direct linking to self-hosted / OSS instances via API base URL and API key (bypasses OAuth).
    • Project creation: Template bootstrap now invokes the latest create-insforge-app with automatic confirmation and improved cross-platform quoting.
  • Chores

    • Updated .gitignore to exclude various AI agent and related tool directories.

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f389a5da-e8c2-4ad4-a06b-b088c5d25364

📥 Commits

Reviewing files that changed from the base of the PR and between e27d940 and 754e8b7.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • .gitignore
  • src/commands/create.ts
  • src/commands/projects/link.ts
  • src/lib/credentials.ts
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/credentials.ts

Walkthrough

Adds direct linking via CLI options --api-base-url and --api-key, an OSS bypass path for credentials, tweaks template download invocation, and updates .gitignore with new tool/IDE patterns.

Changes

Cohort / File(s) Summary
Git ignore updates
\.gitignore
Added ignore patterns for InsForge/AI agent tooling and various assistant-related directories (.insforge, .agent, .agents, .augment, .claude, .cline, .github/copilot*, .kilocode, .qoder, .qwen, .roo, .trae, .windsurf).
Link command & direct OSS flow
src/commands/projects/link.ts
Added --api-base-url and --api-key options; implemented direct linking path that validates URL, requires both flags, constructs/saves a synthetic ProjectConfig (oss-project, oss-org, etc.), performs install/telemetry, outputs JSON or message, and short-circuits the OAuth/org/project selection flow with its own error handling.
Credentials OSS bypass
src/lib/credentials.ts
Extended requireAuth(apiUrl?: string, allowOssBypass = true) to early-return hard-coded StoredCredentials when current project config has project_id === 'oss-project', preserving existing interactive OAuth behavior otherwise.
Template download invocation
src/commands/create.ts
Changed downloadTemplate shell quoting to be platform-aware, and updated the npm invocation to npx --yes create-insforge-app@latest ... (pins @latest and adds --yes).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I hopped in with keys and a URL bright,
Skipped the OAuth tunnel, darted to the light.
Templates fetched clean, installs did their part,
Gitignore tucked secrets, safe from the start.
Cheers from a rabbit — small, nimble, and spry!

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements the core requirement from #20: adding --api-base-url and --api-key options to enable direct linking without OAuth. However, the changes introduced a regression in insforge create that breaks existing OAuth behavior. Fix the insforge create regression by ensuring requireAuth() in create.ts maintains proper OAuth behavior. The fix has been acknowledged but needs completion and verification.
Out of Scope Changes check ⚠️ Warning The PR includes out-of-scope changes: modifications to create.ts and credentials.ts that altered the default authentication behavior, causing a regression in insforge create that doesn't relate to the link command functionality. Limit changes to src/commands/projects/link.ts and src/lib/credentials.ts OSS bypass logic. Revert unnecessary modifications to create.ts or ensure create command maintains independent OAuth flow without side effects.
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 (2 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 feature added: alternative authentication for the link command via new CLI options.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

You can generate walkthrough in a markdown collapsible section to save space.

Enable the reviews.collapse_walkthrough setting to generate walkthrough in a markdown collapsible section.

Copy link

@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: 2

🧹 Nitpick comments (2)
src/commands/projects/link.ts (1)

39-40: Consider validating --api-base-url format.

The apiBaseUrl is used directly in oss_host and later in reportCliUsage for HTTP requests. A malformed URL will cause runtime failures. Consider basic validation (e.g., URL constructor check).

Proposed validation
         if (opts.apiBaseUrl && opts.apiKey) {
+          // Validate URL format
+          try {
+            new URL(opts.apiBaseUrl);
+          } catch {
+            throw new CLIError('Invalid --api-base-url: must be a valid URL.');
+          }
+
           // Direct OSS/Self-hosted linking bypasses OAuth
           const projectConfig: ProjectConfig = {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/projects/link.ts` around lines 39 - 40, Validate the
--api-base-url value before assigning it to oss_host and before calling
reportCliUsage: in the code handling opts (where api_key: opts.apiKey and
oss_host: opts.apiBaseUrl are set) add a basic URL validation (e.g., attempt to
construct new URL(opts.apiBaseUrl) and catch errors) and reject/throw or surface
a clear CLI error if invalid; ensure reportCliUsage and any HTTP client only run
when opts.apiBaseUrl passes this check so malformed URLs cannot be used.
.gitignore (1)

4-4: Minor redundancy: .insforge/ and .insforge both present.

Line 4 already ignores .insforge/ (directory), and line 9 adds .insforge (without slash), which matches both files and directories. The second pattern subsumes the first. Consider removing the duplicate on line 4, or keep both if intentional for clarity.

Also applies to: 9-9

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore at line 4, The .gitignore contains duplicate patterns for the
same path (".insforge/" and ".insforge"); remove the redundancy by deleting one
of them—prefer keeping the simpler ".insforge" pattern and remove ".insforge/"
(or vice versa if you prefer explicit directory notation) so only a single
ignore entry for insforge remains; update the .gitignore accordingly to
eliminate the duplicate entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/projects/link.ts`:
- Around line 31-56: The direct linking branch (where opts.apiBaseUrl &&
opts.apiKey creates projectConfig and calls saveProjectConfig,
installCliGlobally, installSkills, and reportCliUsage) needs its own try-catch
so failures report the correct telemetry; wrap the entire direct-link block in a
try/catch, and in the catch call reportCliUsage('cli.link_direct', false,
<error-code-or-default>) and rethrow or surface the error, while preserving the
existing success path that calls reportCliUsage('cli.link_direct', true, 6).
Ensure the catch references the same symbols: saveProjectConfig,
installCliGlobally, installSkills, and reportCliUsage.
- Around line 31-41: The code currently treats only the case where both
opts.apiBaseUrl and opts.apiKey are present; add a guard to detect when exactly
one is provided (i.e., XOR) and throw a CLIError with a clear message like "Both
--api-base-url and --api-key must be provided for direct linking" to avoid
silently falling back to OAuth; update the block around the existing check of
opts.apiBaseUrl and opts.apiKey (the ProjectConfig construction) to first if
(opts.apiBaseUrl && opts.apiKey) { ... } else if (opts.apiBaseUrl ||
opts.apiKey) { throw new CLIError('Both --api-base-url and --api-key must be
provided for direct linking'); } and ensure CLIError is imported where used.

---

Nitpick comments:
In @.gitignore:
- Line 4: The .gitignore contains duplicate patterns for the same path
(".insforge/" and ".insforge"); remove the redundancy by deleting one of
them—prefer keeping the simpler ".insforge" pattern and remove ".insforge/" (or
vice versa if you prefer explicit directory notation) so only a single ignore
entry for insforge remains; update the .gitignore accordingly to eliminate the
duplicate entry.

In `@src/commands/projects/link.ts`:
- Around line 39-40: Validate the --api-base-url value before assigning it to
oss_host and before calling reportCliUsage: in the code handling opts (where
api_key: opts.apiKey and oss_host: opts.apiBaseUrl are set) add a basic URL
validation (e.g., attempt to construct new URL(opts.apiBaseUrl) and catch
errors) and reject/throw or surface a clear CLI error if invalid; ensure
reportCliUsage and any HTTP client only run when opts.apiBaseUrl passes this
check so malformed URLs cannot be used.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f402beac-2f9b-44a3-aefe-6a99b5a2bec6

📥 Commits

Reviewing files that changed from the base of the PR and between 9c3bebc and 572e89b.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • .gitignore
  • skills-lock.json
  • src/commands/projects/link.ts

skills-lock.json Outdated
@@ -0,0 +1,15 @@
{
Copy link
Member

Choose a reason for hiding this comment

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

This file is involved by the execution of insforge link command, right? I don't think we need add it to repo.

await reportCliUsage('cli.link_direct', true, 6);
return;
}

Copy link
Member

Choose a reason for hiding this comment

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

Missing validation when only one of the two flags is provided

try {
if (opts.apiBaseUrl && opts.apiKey) {
// Direct OSS/Self-hosted linking bypasses OAuth
const projectConfig: ProjectConfig = {
Copy link
Member

Choose a reason for hiding this comment

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

No URL validation on --api-base-url

.insforge/
.env
.env.*

Copy link
Member

Choose a reason for hiding this comment

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

should not be involved here.

Copy link
Member

@jwfing jwfing left a comment

Choose a reason for hiding this comment

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

After linked a project with --api-key and --api-base-url, you run any of commands:

  • insforge db tables
  • insforge docs
  • insforge storage
  • etc.
    It always requests to OAuth login first.

@jwfing
Copy link
Member

jwfing commented Mar 15, 2026

It's not a simple setting update, I think testing all commands is necessary for new initialized mothod(link with project metadata directly).
Thanks for you effort again!

@tonychang04
Copy link
Contributor

Please tell us how you tested it! and address the ai concerns!

@git112
Copy link
Contributor Author

git112 commented Mar 16, 2026

Thanks for the review! @jwfing @tonychang04

I addressed the feedback:

• Added validation to ensure both --api-base-url and --api-key must be provided together
• Added URL validation for --api-base-url
• Updated requireAuth() to bypass OAuth when project_id === "oss-project"
• Removed unintended files from the repository

Testing performed:

  1. Built CLI using npm run build

  2. Linked project using:
    insforge link --api-base-url --api-key

  3. Verified the following commands work without OAuth login:

    • insforge db tables
    • insforge docs
    • insforge storage

Please let me know if additional changes are needed.

Copy link

@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: 1

🧹 Nitpick comments (1)
src/lib/credentials.ts (1)

8-21: Consider adding a clarifying comment for the OSS credential bypass.

The null-safe access via projConfig?.project_id correctly handles the case when getProjectConfig() returns null. The hardcoded credentials approach is reasonable for OSS projects that authenticate via api_key instead of OAuth tokens.

Adding a brief comment explaining why these placeholder values are acceptable (i.e., OSS commands use api_key from project config rather than these tokens) would help future maintainers understand the design intent.

Suggested documentation
   const projConfig = getProjectConfig();
   if (projConfig?.project_id === 'oss-project') {
+    // OSS/self-hosted projects authenticate via api_key from project config,
+    // not OAuth tokens. Return placeholder credentials to satisfy the type contract.
     return {
       access_token: 'oss-token',
       refresh_token: 'oss-refresh',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/credentials.ts` around lines 8 - 21, Add a short clarifying comment
above the OSS bypass block that explains why getProjectConfig() is null-safe
checked and why hardcoded placeholder tokens (returned when
projConfig?.project_id === 'oss-project') are acceptable: note that OSS projects
authenticate via api_key in project config (not OAuth tokens), so these
access_token/refresh_token/user values are dummies used only for compatibility
with callers; reference projConfig, getProjectConfig, and the 'oss-project'
project_id so maintainers know the intent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/projects/link.ts`:
- Around line 31-71: Move the validation and direct-link flow into a single
try-catch so all errors for the direct-link path are handled and reported only
as 'cli.link_direct' (avoid letting CLIError thrown by validation bubble to the
outer catch). Specifically, include the checks of opts.apiBaseUrl and
opts.apiKey and the new URL() validation inside the same try block that creates
ProjectConfig, calls saveProjectConfig, installCliGlobally, installSkills, and
reportCliUsage('cli.link_direct', ...); in the catch for that block call
reportCliUsage('cli.link_direct', false) and then either handle/exit (so you
don’t re-throw into the outer catch) or re-throw a transformed error that the
outer handler will ignore for telemetry — the key is to ensure only
reportCliUsage('cli.link_direct', false) runs for direct-link errors and remove
the duplicate reporting from the outer 'cli.link' path.

---

Nitpick comments:
In `@src/lib/credentials.ts`:
- Around line 8-21: Add a short clarifying comment above the OSS bypass block
that explains why getProjectConfig() is null-safe checked and why hardcoded
placeholder tokens (returned when projConfig?.project_id === 'oss-project') are
acceptable: note that OSS projects authenticate via api_key in project config
(not OAuth tokens), so these access_token/refresh_token/user values are dummies
used only for compatibility with callers; reference projConfig,
getProjectConfig, and the 'oss-project' project_id so maintainers know the
intent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91fe6d56-4f1d-47ca-989d-693aacb1dfc6

📥 Commits

Reviewing files that changed from the base of the PR and between 572e89b and e27d940.

📒 Files selected for processing (2)
  • src/commands/projects/link.ts
  • src/lib/credentials.ts

@jwfing
Copy link
Member

jwfing commented Mar 17, 2026

@git112 I think you changed the default behavior for create command:

$ insforge create
┌  Create a new InsForge project
Error: Not authenticated. Run `insforge login` first.

@jwfing
Copy link
Member

jwfing commented Mar 18, 2026

@git112 any updates? we can't change the behavior of insforge create command.
insforge link --api-base-url --api-key is for self-hosted project, but insforge create is for cloud-hosted project, and is recommendating on our homepage, so keeping consistence really matters.

@git112
Copy link
Contributor Author

git112 commented Mar 19, 2026

@jwfing

I’ve identified the issue and I’m updating the auth handling.
I’ll push a fix shortly. Thank you

@jwfing jwfing merged commit 78880cb into InsForge:main Mar 19, 2026
2 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.

[1 point]Allow cli to link based on api base url and api key

3 participants