Skip to content

feat(cli): polymorfa link and project use|list|current - #19

Merged
purpshell merged 4 commits into
devfrom
feat/project-context
Sep 20, 2026
Merged

purpshell merged 4 commits into
devfrom
feat/project-context

Conversation

@purpshell

@purpshell purpshell commented Sep 19, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds project linking and context switching.

  • polymorfa link [--project <uuid|slug>] [--force] writes polymorfa.json ({"version":1,"project":"<uuid>"}) in the current directory. No credentials in the file; strict schema, so unknown keys are rejected.
  • polymorfa project use <uuid|slug> stores the canonical project UUID on the active (or --profile) profile's metadata (owner: project, project).
  • polymorfa project list lists the credential's projects and marks the current one; project current reports the project and its source (flag, link, profile, none).
  • Resolution: --project > nearest link file (walks up parents) > profile project. Organization-owned commands ignore links. --verbose prints the link in use. listen --project is now optional and falls back to the link or profile project.

Keyring rules are unchanged: profile config holds metadata only, credentials stay in the OS keyring, and there is no plaintext fallback. Project-token profiles stay bound: project use rejects other projects, and developer commands fail closed when a directory link names a different project than the token's.

No conflict with open PRs #10–#16 (none touch src/context/environment.ts, src/base-command.ts link resolution, or project commands). #12 touches src/base-command.ts in the error path only.

Five-part assessment

  • API — unaffected. Uses existing GET project list via Client.projects.list() for slug resolution. No contract change.
  • SDK — unaffected. Existing Client.projects.list only.
  • CLI — updated. New link, project use|list|current, project topic, link-aware developer/QuickLink/listen resolution, README section, help text and examples.
  • Docs — unaffected. The CLI is unpublished and the public Mintlify site has no CLI page. README is the CLI reference; no monorepo docs PR.
  • Feature releases — unaffected. Local CLI behavior; no flags, entitlements or server enforcement change.

Verification

  • npm run verify passes (format, lint, typecheck, tests, build, pack, audit).
  • test/services/projects.test.ts (14): per-profile storage, no secret in config/link, token binding, --force, parent-directory discovery, precedence, env credentials hiding profile context, organization-owned bypass, token/link mismatch failing closed, listener fallback.
  • test/commands/project-context.test.ts: link --project <slug> against a stub API and project current.
  • Not exercised: real OS keyring and live project list.

Summary by CodeRabbit

  • New Features

    • Added project commands to list, view the current project, and select a project.
    • Added directory-based project linking through polymorfa.json, including optional forced replacement.
    • Commands can automatically use the linked or profile-selected project.
    • Added structured and human-readable project context output.
  • Enhancements

    • The listen command no longer requires an explicit project when one can be resolved automatically.
    • Added safeguards for invalid project links and project-token mismatches.
  • Documentation

    • Documented project selection, linking, precedence, and command behavior.

@purpshell

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Warning

Review limit reached

  • Ask an admin to enable usage-based reviews

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Next included review available in 36 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 89 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

The included review limit has been reached and this organization has disabled usage-based review continuation. Wait for reviews to reset or ask a billing admin to change After included review limits.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 3dc92062-5820-424c-9d0b-940d62b0bd22

📥 Commits

Reviewing files that changed from the base of the PR and between a854256 and bc73f5c.

📒 Files selected for processing (3)
  • src/config/project-link.ts
  • src/services/projects.ts
  • test/services/projects.test.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: efe06525-ea82-4e8c-90ef-59200a981559

📥 Commits

Reviewing files that changed from the base of the PR and between 5a0eb46 and a854256.

📒 Files selected for processing (4)
  • docs/superpowers/specs/2026-08-19-polymorfa-cli-design.md
  • package.json
  • src/services/projects.ts
  • test/services/projects.test.ts

Included review availability: 0 reviews are currently available. Your included PR review attempts over the past 7 days set your current allowance at 1 review per hour.


📝 Walkthrough

Walkthrough

The CLI adds project context management through directory links, profiles, credentials, and project commands. Commands resolve projects from explicit flags, linked directories, or profiles. Developer and listener environment resolution now accepts linked projects.

Changes

Project context

Layer / File(s) Summary
Project context service
src/services/projects.ts, src/config/project-link.ts, src/config/project-service.ts, test/services/projects.test.ts
Adds project resolution, listing, selection, linking, credential handling, UUID validation, and atomic polymorfa.json link management.
Project commands and link command
package.json, src/commands/link.ts, src/commands/project/*, test/commands/project-context.test.ts, README.md, docs/superpowers/specs/2026-08-19-polymorfa-cli-design.md
Adds project CLI commands, registers the project topic, documents project context behavior, and updates the link-file format.
Linked-project environment integration
src/base-command.ts, src/commands/listen.ts, src/context/environment.ts, src/developer/client.ts, test/services/projects.test.ts
Passes linked projects into developer and listener environment resolution. listen now falls back to linked or profile project values, with project-token mismatch checks.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant ProjectContextService
  participant project-link
  participant EnvironmentResolver
  CLI->>ProjectContextService: resolve project context
  ProjectContextService->>project-link: discover linked project
  ProjectContextService-->>CLI: return selected project
  CLI->>EnvironmentResolver: pass linked project
  EnvironmentResolver-->>CLI: resolve developer or listener environment
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 13 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: project linking and the new project use, list, and current commands.
Full details: Docstring Coverage

Explanation

Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 13 files. (2 skipped: 2 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@purpshell

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@purpshell

Copy link
Copy Markdown
Member Author

Reviewed locally because CodeRabbit is rate-limited (it answered @coderabbitai review with "Review rate limited" on the current head). Ran the CodeRabbit CLI against dev plus a separate local code review.

Fixed:

  • polymorfa link --project <uuid> was unusable with POLYMORFA_PROJECT_TOKEN. link() resolved the principal before looking at input.project, and the env project-token branch threw unconditionally — telling the user to "pass --project with the exact project UUID" when they already had. principal() now accepts an explicit UUID in that branch. A slug still throws, since it cannot be resolved without an organization credential. Test added.
  • Corrected the polymorfa.json sentence in the design note: the shipped file holds only the version and project UUID, with no gitignore handling and no unlink command.

Left unfixed:

  • "link should add polymorfa.json to .gitignore by default" — declined. The file is credential-free by design and is meant to be committed so a team shares project context.
  • Minor robustness nits (unchecked as string on tokenProject, parent-directory links shadowed without --force, a --verbose notice on organization-owned runs) are unreachable or as-designed given the isProfile invariants.

@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@purpshell Thanks for the detailed local review.

The explicit UUID path for POLYMORFA_PROJECT_TOKEN is valid. A slug still requires an organization credential for resolution.

The decision to commit polymorfa.json is consistent with its credential-free, shared project-context purpose. The design-note correction also aligns the documentation with the shipped format.

🐇


✏️ Learnings added
Learnt from: purpshell
URL: https://github.com/polymorfa/cli/pull/19

Timestamp: 2026-09-20T07:05:25.430Z
Learning: In this CLI, `polymorfa.json` contains only metadata: version `1` and the project UUID. It contains no credentials and is intended to be committed so that a team can share directory project context. The CLI does not add this file to `.gitignore` and does not provide an `unlink` command.

Learnt from: purpshell
URL: https://github.com/polymorfa/cli/pull/19

Timestamp: 2026-09-20T07:05:25.430Z
Learning: In `ProjectContextService`, when `POLYMORFA_PROJECT_TOKEN` supplies the principal, an explicit `--project` UUID may select the token-bound project. A project slug cannot be resolved in this case because slug lookup requires an organization credential.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

Directory links in .polymorfa/project.json and per-profile project context.
Resolution order is --project, nearest link, then profile project;
project-token profiles stay bound to their project.
polymorfa link resolved the principal before reading --project, so a
POLYMORFA_PROJECT_TOKEN user hit an error telling them to pass --project
even when they had. Accept an explicit UUID in that branch, and correct
the design note to the shipped polymorfa.json contract.
@purpshell

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@purpshell

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. Your current included review allowance is based on your included PR review attempts over the past 7 days. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 50 minutes.

readProjectLink accepted any non-empty string while writeProjectLink only
ever stores a resolved UUID. polymorfa.json is hand-editable, so enforce
the same shape at both boundaries with one shared validator.
@purpshell

Copy link
Copy Markdown
Member Author

Rebased onto dev after #18 merged, then re-reviewed. CodeRabbit is still rate-limited ("Your included review limit is currently reached under our Fair Usage Limits Policy"), including after @coderabbitai full review, so this was reviewed locally again with the CodeRabbit CLI plus a local code review.

One further fix:

  • readProjectLink accepted any non-empty string as project, while writeProjectLink only ever stores a resolved canonical UUID and ProjectContextService enforces that shape everywhere else. Since polymorfa.json is hand-editable and meant to be committed, a typo'd or hand-written id flowed straight into API calls. Both boundaries now share one exported PROJECT_UUID validator. Test added.

Also checked the #18 interaction explicitly: the linked-project precedence added here feeds only resolveDeveloperEnvironment/resolveListenerEnvironment, while #18's message-send and group-mutation commands resolve through resolveCommandEnvironment, which has no project scoping. No precedence conflict.

Nothing left unfixed. (Note: coderabbit review --plain no longer exists in the installed CLI — plain text is the default and --agent gives structured findings.)

@coderabbitai

coderabbitai Bot commented Sep 20, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@purpshell Thanks for the update.

The shared PROJECT_UUID validation makes readProjectLink consistent with writeProjectLink and ProjectContextService. It prevents invalid hand-edited link data from reaching project-scoped API resolution.

The #18 check also confirms that project-link precedence does not affect message-send or group-mutation commands. Those commands use resolveCommandEnvironment, which has no project context.

I also considered the existing project-link guidance: polymorfa.json is credential-free and is intended for commits. The new validation is appropriate for that editable, shared file.

The review-limit result is understood. Your local review and added test cover the reported change.

🐇🔍


✏️ Learnings added
Learnt from: purpshell
URL: https://github.com/polymorfa/cli/pull/19

Timestamp: 2026-09-20T14:07:38.040Z
Learning: In pull request `#19`, linked-project precedence applies only through `resolveDeveloperEnvironment` and `resolveListenerEnvironment`. The message-send and group-mutation commands introduced by pull request `#18` use `resolveCommandEnvironment`, which has no project scoping; therefore project-link precedence does not affect those commands.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: purpshell
URL: https://github.com/polymorfa/cli/pull/19

Timestamp: 2026-09-20T07:05:25.503Z
Learning: In this CLI, `polymorfa.json` contains only metadata: version `1` and the project UUID. It contains no credentials and is intended to be committed so that a team can share directory project context. The CLI does not add this file to `.gitignore` and does not provide an `unlink` command.

You are interacting with an AI system.

@purpshell
purpshell merged commit 15ba6a7 into dev Sep 20, 2026
3 checks passed
@purpshell
purpshell deleted the feat/project-context branch September 20, 2026 14:09
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