Skip to content

feat(cli): add native QuickAdd Obsidian CLI handlers#1129

Merged
chhoumann merged 4 commits intomasterfrom
feat/quickadd-cli-handlers
Feb 28, 2026
Merged

feat(cli): add native QuickAdd Obsidian CLI handlers#1129
chhoumann merged 4 commits intomasterfrom
feat/quickadd-cli-handlers

Conversation

@chhoumann
Copy link
Owner

@chhoumann chhoumann commented Feb 28, 2026

Add first-class Obsidian CLI support for QuickAdd choices.

This introduces native plugin CLI handlers so shell workflows can run QuickAdd choices directly and safely in non-interactive mode.

What changed:

  • Added CLI commands:
    • quickadd and quickadd:run (execute a choice by choice=<name> or id=<id>)
    • quickadd:list (list flattened choice inventory)
    • quickadd:check (preflight unresolved required inputs)
  • Added robust variable ingestion for CLI:
    • value-<name>=... (URI-compatible)
    • extra key=value params
    • vars=<json-object>
  • Added non-interactive run behavior:
    • preflight unresolved requirements before execution
    • return structured JSON with missing and missingFlags suggestions
  • Refactored preflight collection into reusable module to keep one-page input and CLI checks consistent.
  • Added unit tests for handler registration and run/list/check behavior.
  • Added docs for new CLI commands and linked from URI docs.

Notes:

  • CLI handler registration is gated by runtime API availability (registerCliHandler) to preserve compatibility on older Obsidian versions.
  • Handler registration is deferred until layout is ready, matching observed CLI handler availability timing.

Open with Devin

Summary by CodeRabbit

  • New Features

    • CLI: run, list, and check QuickAdd choices from the terminal; CLI registers on startup once the workspace is ready.
    • Unified preflight/input collection with one-page input modal and seeding from capture selection when available.
  • Documentation

    • Added detailed QuickAdd CLI docs with usage examples and variable-passing guidance; linked from URI/shell-scripting docs.
  • Tests

    • Added tests covering CLI handlers and preflight requirement collection.
  • Chores

    • Exposed CLI-related types/signatures to enable plugin CLI registration.

@vercel
Copy link

vercel bot commented Feb 28, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
quickadd Ready Ready Preview Feb 28, 2026 8:56pm

@coderabbitai
Copy link

coderabbitai bot commented Feb 28, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9a0b50 and 68a7127.

📒 Files selected for processing (2)
  • src/preflight/collectChoiceRequirements.test.ts
  • src/preflight/collectChoiceRequirements.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/preflight/collectChoiceRequirements.test.ts

📝 Walkthrough

Walkthrough

Adds a new QuickAdd CLI (run/list/check), centralized preflight requirement collection, related tests and docs, CLI type declarations, and registers CLI handlers during plugin startup after workspace layout readiness.

Changes

Cohort / File(s) Summary
Documentation
docs/docs/Advanced/CLI.md, docs/docs/Advanced/ObsidianUri.md
Adds QuickAdd CLI documentation and a link/note in Obsidian URI docs.
CLI Implementation
src/cli/registerQuickAddCliHandlers.ts
New module registering CLI commands; argument parsing, vars handling (strict JSON, value-*), choice resolution, non-interactive missing-field detection, execution flow, and JSON responses.
CLI Tests
src/cli/registerQuickAddCliHandlers.test.ts
Tests for CLI registration and handlers (run/list/check), variable parsing, flattened choice resolution, missing-input behavior, and executor interactions.
Type Definitions
src/global.d.ts
Adds CLI-related types (CliData, CliFlag, CliFlags, CliHandler) and optional Plugin.registerCliHandler; switches plugin maps to use ObsidianPlugin.
Plugin Startup
src/main.ts
Defers/registers CLI handlers after workspace layout readiness (run immediately if layoutReady or onLayoutReady).
Preflight Collection Module
src/preflight/collectChoiceRequirements.ts
New centralized collector for FieldRequirement objects across Template/Capture/Macro; exports collectChoiceRequirements and getUnresolvedRequirements.
Preflight Refactor
src/preflight/runOnePagePreflight.ts
Refactored to delegate requirement gathering to collectChoiceRequirements and use getUnresolvedRequirements; removed inline collectors.
Preflight Tests
src/preflight/collectChoiceRequirements.test.ts
Tests for script-derived inputs, malformed script inputs handling, capture target normalization, and related preflight behaviors.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Client
    participant Handler as QuickAdd CLI Handler
    participant Executor as ChoiceExecutor
    participant Preflight as collectChoiceRequirements
    participant Choice as Choice Engine

    CLI->>Handler: quickadd:run (params + vars)
    Handler->>Handler: parse params, parse vars JSON, apply value-* overrides
    Handler->>Executor: create/set up executor and apply variables
    Handler->>Preflight: request FieldRequirements (choice, executor, options)
    Preflight-->>Handler: FieldRequirements list
    Handler->>Preflight: request unresolved inputs (requirements, variables)
    Preflight-->>Handler: unresolved inputs list

    alt non-interactive & unresolved inputs
        Handler-->>CLI: JSON payload with missingFields and missingFlags
    else all inputs resolved
        Handler->>Executor: execute choice
        Executor->>Choice: run choice
        Choice-->>Executor: result (duration, success)
        Executor-->>Handler: execution result
        Handler-->>CLI: JSON success response
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

released

Poem

🐇 I hopped through code, all quick and spry,
Commands now listen when you call "quickadd" — hi!
I gather fields, flatten choices neat,
Run, list, check — a terminal treat.
Hooray for carrots and JSON sweet!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
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 'feat(cli): add native QuickAdd Obsidian CLI handlers' accurately and concisely summarizes the main change: adding first-class Obsidian CLI support with native plugin CLI handlers.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/quickadd-cli-handlers

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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 28, 2026

Deploying quickadd with  Cloudflare Pages  Cloudflare Pages

Latest commit: 68a7127
Status: ✅  Deploy successful!
Preview URL: https://7ac8658c.quickadd.pages.dev
Branch Preview URL: https://feat-quickadd-cli-handlers.quickadd.pages.dev

View logs

@chhoumann chhoumann marked this pull request as ready for review February 28, 2026 18:36
chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

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.

🧹 Nitpick comments (3)
src/global.d.ts (1)

8-10: Redundant type union in CliData.

The type string | "true" is redundant since "true" is a subset of string. The literal "true" provides no additional type safety here.

💡 Simplified type definition
 interface CliData {
-  [key: string]: string | "true";
+  [key: string]: string;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/global.d.ts` around lines 8 - 10, The CliData interface currently types
values as `string | "true"`, which is redundant because the string literal
"true" is already encompassed by string; update the CliData declaration
(interface CliData) to use a single string type for values (e.g., change the
union to just string) so the type is simplified and consistent.
src/preflight/collectChoiceRequirements.ts (1)

242-244: Silent error swallowing may hide script configuration issues.

Catching and ignoring all errors from getUserScript during preflight may hide legitimate configuration problems. Consider logging at debug level to aid troubleshooting.

💡 Optional: Add debug logging for script errors
 		} catch {
-			// Ignore script spec errors in preflight collection.
+			// Ignore script spec errors in preflight collection.
+			// Uncomment for debugging: log.logMessage(`Preflight: skipped script ${userScriptCommand.path}`);
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/preflight/collectChoiceRequirements.ts` around lines 242 - 244, The catch
block that silently swallows errors from getUserScript in
collectChoiceRequirements.ts should at minimum log the caught error at debug
level instead of ignoring it; update the catch to accept an error (e.g., err)
and call the module’s logger/debug method (or processLogger.debug) with a
concise message referencing getUserScript and the error details so
configuration/script failures are visible during troubleshooting while still not
failing preflight.
src/cli/registerQuickAddCliHandlers.test.ts (1)

203-232: Consider adding a test for vars JSON parsing.

The test suite covers value-<name> and extra key=value patterns but doesn't exercise the vars=<json> parameter. Consider adding coverage for JSON variable ingestion.

💡 Suggested test case for vars JSON parsing
it("parses vars JSON parameter correctly", async () => {
  const { plugin, handlers } = createPlugin([templateChoice]);
  registerQuickAddCliHandlers(plugin);
  const run = handlers.find((handler) => handler.command === "quickadd:run");

  const output = await Promise.resolve(
    run!.handler({
      choice: templateChoice.name,
      vars: '{"project":"QA","sprint":42}',
    }),
  );
  const payload = JSON.parse(String(output));

  expect(payload.ok).toBe(true);
  expect(executors[0].variables.get("project")).toBe("QA");
  expect(executors[0].variables.get("sprint")).toBe(42);
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/cli/registerQuickAddCliHandlers.test.ts` around lines 203 - 232, Add a
unit test that exercises JSON parsing of the vars CLI parameter: after calling
registerQuickAddCliHandlers and finding the "quickadd:run" handler, invoke
run!.handler with a vars string like '{"project":"QA","sprint":42}' and assert
payload.ok is true and that the executor received those variables (check
executors[0].variables.get("project") === "QA" and .get("sprint") === 42). This
test should live alongside the existing non-interactive tests that use
templateChoice and should verify that registerQuickAddCliHandlers correctly
parses the vars JSON into executor variables.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/cli/registerQuickAddCliHandlers.test.ts`:
- Around line 203-232: Add a unit test that exercises JSON parsing of the vars
CLI parameter: after calling registerQuickAddCliHandlers and finding the
"quickadd:run" handler, invoke run!.handler with a vars string like
'{"project":"QA","sprint":42}' and assert payload.ok is true and that the
executor received those variables (check executors[0].variables.get("project")
=== "QA" and .get("sprint") === 42). This test should live alongside the
existing non-interactive tests that use templateChoice and should verify that
registerQuickAddCliHandlers correctly parses the vars JSON into executor
variables.

In `@src/global.d.ts`:
- Around line 8-10: The CliData interface currently types values as `string |
"true"`, which is redundant because the string literal "true" is already
encompassed by string; update the CliData declaration (interface CliData) to use
a single string type for values (e.g., change the union to just string) so the
type is simplified and consistent.

In `@src/preflight/collectChoiceRequirements.ts`:
- Around line 242-244: The catch block that silently swallows errors from
getUserScript in collectChoiceRequirements.ts should at minimum log the caught
error at debug level instead of ignoring it; update the catch to accept an error
(e.g., err) and call the module’s logger/debug method (or processLogger.debug)
with a concise message referencing getUserScript and the error details so
configuration/script failures are visible during troubleshooting while still not
failing preflight.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8597905 and 6935b29.

📒 Files selected for processing (8)
  • docs/docs/Advanced/CLI.md
  • docs/docs/Advanced/ObsidianUri.md
  • src/cli/registerQuickAddCliHandlers.test.ts
  • src/cli/registerQuickAddCliHandlers.ts
  • src/global.d.ts
  • src/main.ts
  • src/preflight/collectChoiceRequirements.ts
  • src/preflight/runOnePagePreflight.ts

coderabbitai[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@chhoumann chhoumann merged commit 8102d47 into master Feb 28, 2026
5 checks passed
@chhoumann chhoumann deleted the feat/quickadd-cli-handlers branch February 28, 2026 21:33
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