Skip to content

Add 'create' command for modules with optional fields#3

Merged
backslash-ux merged 9 commits intomainfrom
feat/modules
Mar 31, 2026
Merged

Add 'create' command for modules with optional fields#3
backslash-ux merged 9 commits intomainfrom
feat/modules

Conversation

@backslash-ux
Copy link
Copy Markdown
Owner

@backslash-ux backslash-ux commented Mar 31, 2026

Summary

Introduce a new command to create modules with optional fields such as description, status, start date, target date, and lead. This enhancement allows users to manage modules more flexibly and efficiently.

Related Issue

No public tracking item was needed.

Changes

  • Added plane modules create command with optional parameters.

Validation

  • bun run typecheck
  • relevant bun test coverage for the touched area
  • bun run check:all if shared command behavior, schemas, or output changed

Docs

  • README.md updated if CLI usage changed
  • SKILL.md updated if AI-agent usage changed
  • CHANGELOG.md updated if there is a notable user-facing change

Risks Or Follow-Ups

Summary by CodeRabbit

  • New Features

    • Added plane modules create to create modules with optional description, status, dates, and lead (accepts display name, email, or UUID); status inputs are normalized.
    • plane init --local can now prompt to import the SKILL guide into AGENTS.md and updates that section idempotently.
  • Behavior Changes

    • issue create, labels create, modules create, and pages create now prefer named flags (--title/--name), letting PROJECT be omitted to use the saved project.
  • Documentation

    • Updated CLI examples, help text, badges, and repo links.
  • Tests

    • Added/updated tests for modules, CLI parsing, SKILL import behavior, and env cleanup.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

Warning

Rate limit exceeded

@backslash-ux has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 17 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 14 minutes and 17 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1d3f2dca-c8d0-43aa-9d0a-a6e9e8e98535

📥 Commits

Reviewing files that changed from the base of the PR and between feb405c and 078cf67.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • package.json
  • src/app.ts
  • src/project-agents.ts
📝 Walkthrough

Walkthrough

Adds a new modules create CLI subcommand with optional fields and member resolution, changes several create commands to use --title/--name options with optional project positional, extends Module schema, adds SKILL.md import into AGENTS.md on init --local, and updates docs and tests accordingly.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md, README.md, SKILL.md
Documented plane modules create, updated examples to use --title/--name, described --lead resolution and --status in_progressin-progress normalization; updated repo/CI badges and clone URL.
CLI help/registration
src/app.ts
Inserted create into modules subcommands and updated help/examples for flag-based title/name usage and modules quick-start.
Modules command (new feature)
src/commands/modules.ts
Added modules create command and exported modulesCreate/modulesCreateHandler: resolves project, checks module_view feature, validates/normalizes inputs (status, YYYY‑MM‑DD dates), resolves --lead to member id, POSTs to projects/{id}/modules/, decodes ModuleSchema, logs created module. Attention: date validation, status mapping, member resolution logic.
Schema changes
src/config.ts
Extended ModuleSchema/Module type with optional identifier, created_at, `start_date?: string
Issue/Labels/Pages wiring
src/commands/issue.ts, src/commands/labels.ts, src/commands/pages.ts
Rewired issue create to use --title option (project opt-in), changed labels create to --name option and Option-based color handling, made pages create project arg optional (listProjectArg).
Init / AGENTS.md SKILL import
src/commands/init.ts, src/project-agents.ts
Added SKILL.md reading and idempotent import/upsert into AGENTS.md with new helper functions and prompt flow; updated local init description.
Tests
tests/modules.test.ts, tests/project-features.test.ts, tests/issue-commands.test.ts
Added module creation tests (MSW member fixture, status mapping, lead resolution, date validation), SKILL import tests (idempotency and prompts), adjusted issue tests to use --title and updated test env cleanup and helper runner.
Repo metadata & templates
.github/ISSUE_TEMPLATE/config.yml, package.json
Fixed repository/issue URLs to backslash-ux/plane-cli and adjusted ISSUE_TEMPLATE links.
Small CLI docs wiring
src/app.ts, src/commands/...
Help text/examples changed across commands to reflect new flag-first usage and optional project positional behavior.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant CLI as CLI Handler
    participant Validator as Project Validator
    participant Resolver as Member Resolver
    participant API as Projects API

    User->>CLI: plane modules create --name "Sprint 3" --lead "Alice" --status in_progress --start-date 2026-03-01
    CLI->>Validator: resolve project id & check feature "module_view"
    Validator-->>CLI: feature enabled
    CLI->>Resolver: getMemberId("Alice")
    Resolver-->>CLI: return member id (mem1)
    CLI->>CLI: validate dates, normalize status "in_progress" → "in-progress"
    CLI->>API: POST /projects/{id}/modules {name, status, description?, start_date?, target_date?, lead: mem1}
    API-->>CLI: 201 {id, name, ...}
    CLI-->>User: log "Created module: Sprint 3 (<id>)"
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped to the CLI with a tiny cheer,
New modules sprout when the Sprint draws near,
Leads found by name, statuses set just right,
Dates checked and logged into the night,
Hooray — a sprint takes flight ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% 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
Title check ✅ Passed The title clearly summarizes the primary change: adding a new 'create' command for modules with optional fields, which directly aligns with the main objective of the changeset.
Description check ✅ Passed The description follows the template with all required sections completed: summary, related issue, changes, validation (all checkboxes marked), docs (all checkboxes marked), and risks/follow-ups.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/modules

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
Copy Markdown

@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 (2)
tests/modules.test.ts (1)

163-263: Add one parser-level test for plane modules create.

These cases call modulesCreateHandler directly, so they won't catch regressions in the public CLI wiring—e.g. the create subcommand registration or the --start-date / --target-date mapping into startDate / targetDate. One test through modulesCreate or cli would cover the actual entrypoint this PR adds.

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

In `@tests/modules.test.ts` around lines 163 - 263, Add a parser-level test that
exercises the public entrypoint instead of calling modulesCreateHandler
directly: invoke the CLI entry (modulesCreate or cli command) with arguments
equivalent to "plane modules create --project ACME --name 'Design System
Rollout' --description 'Ship tokens and docs' --status in_progress --start-date
2026-04-01 --target-date 2026-04-30 --lead 'Jane Doe'" so the test verifies the
flag-to-field mapping (startDate/targetDate) and lead resolution end-to-end;
locate the test harness near the existing modulesCreateHandler tests and assert
the HTTP request body and console output like the existing expectations
(postedBody contains start_date/target_date and lead resolved to mem1, logs
contain "Created module...").
src/commands/modules.ts (1)

59-65: Validate --start-date and --target-date before posting.

Both flags are documented as YYYY-MM-DD, but any string is forwarded to the API right now. A small CLI-side check here would fail fast and keep simple input typos from turning into backend-only errors.

Also applies to: 153-157

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

In `@src/commands/modules.ts` around lines 59 - 65, The start-date and target-date
option definitions (startDateOption and targetDateOption) currently accept any
string; add a CLI-side validation step in their Options pipeline to enforce the
YYYY-MM-DD pattern (e.g., strict regex like /^\d{4}-\d{2}-\d{2}$/ and/or attempt
a Date parse to ensure valid month/day) and return a user-facing validation
error if it fails; apply the same validation to the duplicate option definitions
later in the file (the ones around lines 153–157) so both places reject invalid
dates before calling the API, and ensure the validation message clearly
references the offending flag name.
🤖 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/commands/modules.ts`:
- Around line 59-65: The start-date and target-date option definitions
(startDateOption and targetDateOption) currently accept any string; add a
CLI-side validation step in their Options pipeline to enforce the YYYY-MM-DD
pattern (e.g., strict regex like /^\d{4}-\d{2}-\d{2}$/ and/or attempt a Date
parse to ensure valid month/day) and return a user-facing validation error if it
fails; apply the same validation to the duplicate option definitions later in
the file (the ones around lines 153–157) so both places reject invalid dates
before calling the API, and ensure the validation message clearly references the
offending flag name.

In `@tests/modules.test.ts`:
- Around line 163-263: Add a parser-level test that exercises the public
entrypoint instead of calling modulesCreateHandler directly: invoke the CLI
entry (modulesCreate or cli command) with arguments equivalent to "plane modules
create --project ACME --name 'Design System Rollout' --description 'Ship tokens
and docs' --status in_progress --start-date 2026-04-01 --target-date 2026-04-30
--lead 'Jane Doe'" so the test verifies the flag-to-field mapping
(startDate/targetDate) and lead resolution end-to-end; locate the test harness
near the existing modulesCreateHandler tests and assert the HTTP request body
and console output like the existing expectations (postedBody contains
start_date/target_date and lead resolved to mem1, logs contain "Created
module...").

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0b7f518e-76df-4cb4-98e7-4e11edf11088

📥 Commits

Reviewing files that changed from the base of the PR and between 2d0cf02 and c7559b6.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • README.md
  • SKILL.md
  • src/app.ts
  • src/commands/modules.ts
  • src/config.ts
  • tests/modules.test.ts

Copy link
Copy Markdown

@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 (2)
src/commands/labels.ts (1)

72-80: Consider using Option.Option<string> for type consistency.

The color parameter uses a raw tagged union type { _tag: "Some"; value: string } | { _tag: "None" } while other handlers in this PR (e.g., modulesCreateHandler, pagesCreateHandler) use Option.Option<string>. Using the Effect type alias would be more consistent and provide better type safety.

♻️ Suggested change
 export function labelsCreateHandler({
 	project,
 	name,
 	color,
 }: {
 	project: string;
 	name: string;
-	color: { _tag: "Some"; value: string } | { _tag: "None" };
+	color: Option.Option<string>;
 }) {
 	return Effect.gen(function* () {
 		const { id } = yield* resolveProject(project);
 		interface LabelPayload {
 			name: string;
 			color?: string;
 		}
 		const body: LabelPayload = { name };
-		if (color._tag === "Some") body.color = color.value;
+		if (Option.isSome(color)) body.color = color.value;

You'll also need to import Option from effect:

-import { Console, Effect } from "effect";
+import { Console, Effect, Option } from "effect";
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/labels.ts` around lines 72 - 80, Change the color parameter of
labelsCreateHandler to use the Effect Option type for consistency and safety:
replace the raw tagged-union type on the color parameter with
Option.Option<string> and add an import for Option from 'effect'; update the
function signature for labelsCreateHandler and any call sites within this diff
to accept Option.Option<string> instead of the manual { _tag: "Some" | "None" }
union.
src/commands/modules.ts (1)

59-65: Consider validating date format before API call.

The options describe YYYY-MM-DD format, but no validation is performed. Invalid dates will be passed to the API, which may reject them with a less helpful error message. Consider adding client-side validation for better UX.

♻️ Optional validation helper
+function validateDateFormat(date: string, fieldName: string): Effect.Effect<string, Error> {
+	if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
+		return Effect.fail(new Error(`${fieldName} must be in YYYY-MM-DD format`));
+	}
+	return Effect.succeed(date);
+}

Then in modulesCreateHandler:

 		if (Option.isSome(startDate)) {
-			body.start_date = startDate.value;
+			body.start_date = yield* validateDateFormat(startDate.value, "--start-date");
 		}
 		if (Option.isSome(targetDate)) {
-			body.target_date = targetDate.value;
+			body.target_date = yield* validateDateFormat(targetDate.value, "--target-date");
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/modules.ts` around lines 59 - 65, The startDateOption and
targetDateOption declare a YYYY-MM-DD format but lack validation, so add
client-side validation (e.g., regex /^\d{4}-\d{2}-\d{2}$/ plus a semantic check
for valid month/day or Date parsing) before calling the API in
modulesCreateHandler: validate the parsed option values, return a user-friendly
error if the format or date is invalid, and only proceed to build the API
payload when both startDateOption and targetDateOption pass validation;
reference the option names (startDateOption, targetDateOption) and the handler
(modulesCreateHandler) when adding the checks.
🤖 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/commands/labels.ts`:
- Around line 72-80: Change the color parameter of labelsCreateHandler to use
the Effect Option type for consistency and safety: replace the raw tagged-union
type on the color parameter with Option.Option<string> and add an import for
Option from 'effect'; update the function signature for labelsCreateHandler and
any call sites within this diff to accept Option.Option<string> instead of the
manual { _tag: "Some" | "None" } union.

In `@src/commands/modules.ts`:
- Around line 59-65: The startDateOption and targetDateOption declare a
YYYY-MM-DD format but lack validation, so add client-side validation (e.g.,
regex /^\d{4}-\d{2}-\d{2}$/ plus a semantic check for valid month/day or Date
parsing) before calling the API in modulesCreateHandler: validate the parsed
option values, return a user-friendly error if the format or date is invalid,
and only proceed to build the API payload when both startDateOption and
targetDateOption pass validation; reference the option names (startDateOption,
targetDateOption) and the handler (modulesCreateHandler) when adding the checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0de6ea6-77e3-4ab5-b7b9-1e797ff86a65

📥 Commits

Reviewing files that changed from the base of the PR and between c7559b6 and 47fe800.

📒 Files selected for processing (9)
  • CHANGELOG.md
  • README.md
  • SKILL.md
  • src/app.ts
  • src/commands/issue.ts
  • src/commands/labels.ts
  • src/commands/modules.ts
  • src/commands/pages.ts
  • tests/issue-commands.test.ts
✅ Files skipped from review due to trivial changes (2)
  • src/app.ts
  • SKILL.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Copy link
Copy Markdown

@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 (1)
src/commands/modules.ts (1)

179-193: Add a cross-field guard for start/target date ordering.

Both dates are validated independently, but --target-date can still be earlier than --start-date. Adding a local check will give users a faster, clearer error.

Suggested patch
 		if (Option.isSome(targetDate)) {
 			body.target_date = yield* validateModuleDateInput(
 				targetDate.value,
 				"--target-date",
 			);
 		}
+		if (
+			body.start_date !== undefined &&
+			body.target_date !== undefined &&
+			body.target_date < body.start_date
+		) {
+			return yield* Effect.fail(
+				new Error("--target-date must be on or after --start-date"),
+			);
+		}
 		if (Option.isSome(lead)) {
 			body.lead = yield* getMemberId(lead.value);
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/modules.ts` around lines 179 - 193, After independently
validating startDate and targetDate using validateModuleDateInput and assigning
to body.start_date and body.target_date, add a cross-field guard that, when both
Option.isSome(startDate) and Option.isSome(targetDate) are present, compares the
parsed dates (body.start_date and body.target_date) and throws/returns a clear
user-facing error if body.target_date is earlier than body.start_date; update
the code around the startDate/targetDate handling in modules.ts (the
Option.isSome(startDate)/Option.isSome(targetDate) blocks) to perform this check
immediately after both assignments so users receive a fast, descriptive
validation error.
🤖 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/commands/modules.ts`:
- Around line 179-193: After independently validating startDate and targetDate
using validateModuleDateInput and assigning to body.start_date and
body.target_date, add a cross-field guard that, when both
Option.isSome(startDate) and Option.isSome(targetDate) are present, compares the
parsed dates (body.start_date and body.target_date) and throws/returns a clear
user-facing error if body.target_date is earlier than body.start_date; update
the code around the startDate/targetDate handling in modules.ts (the
Option.isSome(startDate)/Option.isSome(targetDate) blocks) to perform this check
immediately after both assignments so users receive a fast, descriptive
validation error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d8b7ced9-7fc5-4cec-8942-94d6a861e9c0

📥 Commits

Reviewing files that changed from the base of the PR and between 47fe800 and f5af416.

📒 Files selected for processing (3)
  • src/commands/labels.ts
  • src/commands/modules.ts
  • tests/modules.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/modules.test.ts

Copy link
Copy Markdown

@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

🤖 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/project-agents.ts`:
- Around line 148-153: hasSkillSectionInAgentsFile currently returns true when
only SKILL_SECTION_START is present, which allows malformed files to get
duplicated sections; update the function (referencing
hasSkillSectionInAgentsFile, SKILL_SECTION_START, and SKILL_SECTION_END) to
detect the presence of both delimiters before returning true (e.g., require
content.includes(SKILL_SECTION_START) && content.includes(SKILL_SECTION_END) or
equivalent regex), so upsert/replacement logic only runs when a complete skill
section exists.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4a416c36-e671-4f1c-9b13-8c5fdb9db680

📥 Commits

Reviewing files that changed from the base of the PR and between f5af416 and feb405c.

📒 Files selected for processing (7)
  • .github/ISSUE_TEMPLATE/config.yml
  • CHANGELOG.md
  • README.md
  • package.json
  • src/commands/init.ts
  • src/project-agents.ts
  • tests/project-features.test.ts
✅ Files skipped from review due to trivial changes (2)
  • .github/ISSUE_TEMPLATE/config.yml
  • package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Comment thread src/project-agents.ts
@backslash-ux backslash-ux merged commit 3f7d3b2 into main Mar 31, 2026
4 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 participant