Skip to content

feat: janee overview command + auto-create capability on janee add#141

Closed
rsdouglas wants to merge 2 commits intofeat/per-capability-accessfrom
feat/overview-and-add-defaults
Closed

feat: janee overview command + auto-create capability on janee add#141
rsdouglas wants to merge 2 commits intofeat/per-capability-accessfrom
feat/overview-and-add-defaults

Conversation

@rsdouglas
Copy link
Copy Markdown
Owner

Summary

Based on feat/per-capability-access (#140).

  • janee overview -- One-screen summary showing services, capabilities, per-agent access, and unreachable capabilities. Extracts known agents from allowedAgents and ownership.sharedWith across the config, evaluates access for each, and presents a concise view. Supports --json.
  • janee add always creates a default capability -- Running janee add resend --key re_xxx now creates both the service AND a ready-to-use capability (resend, 1h TTL, auto-approve) in one step. The old flow had a split: fully non-interactive mode auto-created, but partially interactive mode (e.g. prompted for test path) asked "Create a capability?" separately. Now it always creates one. Removes ~80 lines of branching logic in add.ts.
  • Fix: diagnose access respects cap.access override -- The CLI diagnose access command wasn't checking the per-capability access field introduced in feat: per-capability access override (open/restricted) #140. Fixed to match the MCP explain_access tool behavior.

Example output of janee overview:

  2 services, 3 capabilities    (defaultAccess: restricted)

  billing-bot: stripe (allowed), serp (open)
  cursor: serp (open)

  Unreachable: slack
  (restricted with no allowedAgents — no agent can use these)

Test plan

  • 7 new tests for overview command (counts, per-agent access, unreachable detection, JSON output, edge cases)
  • All 540 tests pass
  • tsc --noEmit clean

Made with Cursor

- Add `janee overview`: one-screen summary of services, capabilities,
  and per-agent access. Shows unreachable capabilities (restricted
  with no allowedAgents). Supports --json.

- Simplify `janee add`: always creates a default capability (1h TTL,
  auto-approve) alongside the service. No more "Create a capability?"
  prompt — it just happens. Customize with `janee cap edit` afterward.

- Fix `diagnose access` to respect per-capability `access` override.

Made-with: Cursor
Copy link
Copy Markdown
Collaborator

@lucamorettibuilds lucamorettibuilds left a comment

Choose a reason for hiding this comment

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

Solid PR — the overview output is exactly the kind of command I wish every CLI had. The add simplification removing ~80 lines of branching is a big readability win. A few notes:

Unreachable detection vs resolveEffectiveAccess mismatch

The per-agent resolution in resolveEffectiveAccess checks three things: allowedAgents, effective access policy, AND canAgentAccess(agentId, service?.ownership). But the unreachable filter at line 89-93 only checks two:

const unreachable = caps.filter(cap => {
  if (cap.allowedAgents.length > 0) return false;
  const effective = cap.access ?? globalDefault;
  if (effective === 'restricted') return true;
  return false;
});

If a capability is restricted with no allowedAgents but the backing service has ownership.sharedWith: [some-agent], that agent would actually get through resolveEffectiveAccess (since canAgentAccess returns true for shared agents). But the unreachable check would still flag it as unreachable.

Edge case, but the two code paths should agree. Either the unreachable filter should call resolveEffectiveAccess for all known agents, or it should note that ownership-based access is a separate path.

diagnose access fix

Clean fix. The source annotation ("capability access" vs "global defaultAccess") in the trace output is a nice touch — makes it immediately obvious which policy is driving the decision.

add simplification

Removing the interactive capability prompting is a good UX trade-off. The Customize with: janee cap edit <name> hint makes the escape hatch discoverable. One thought: if the service already has an existing capability (e.g., user runs janee add stripe twice after removing/re-adding the service), the if (!config.capabilities[serviceName]) guard silently skips creation. That's correct but the CLI output still says "Added capability" — might be worth a conditional message there so users aren't confused about why their capability config didn't reset.

… output

Addresses review feedback:
- Unreachable filter now evaluates resolveEffectiveAccess for all known
  agents instead of a simplified check, so ownership-based access is
  correctly considered.
- janee add output is conditional: shows "Added capability" only when
  one was actually created, "Existing capability unchanged" otherwise.
- Add test for ownership-based access not flagged as unreachable.

Made-with: Cursor
Copy link
Copy Markdown
Owner Author

@rsdouglas rsdouglas left a comment

Choose a reason for hiding this comment

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

Both points fixed in dfa4f5e.

Unreachable detection mismatch — fixed. The unreachable filter now evaluates resolveEffectiveAccess for all known agents instead of the simplified restricted + no allowedAgents check. This means if a capability is restricted but the backing service has ownership.sharedWith: [some-agent], that agent shows up as having access and the capability isn't flagged as unreachable. Added a dedicated test for this case.

The unreachable list now reports "no known agent can access these" rather than the old wording about allowedAgents, since the evaluation is fully general.

Conditional add output — fixed. The capCreated flag controls both the console output and the JSON response. When a capability already exists, human output shows Existing capability "foo" unchanged and JSON omits the capability field.

Copy link
Copy Markdown
Collaborator

@lucamorettibuilds lucamorettibuilds left a comment

Choose a reason for hiding this comment

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

Both fixes look right — using resolveEffectiveAccess for the unreachable check eliminates the ownership blind spot, and the capCreated flag is clean. Approved.

@rsdouglas rsdouglas deleted the branch feat/per-capability-access March 17, 2026 05:31
@rsdouglas rsdouglas closed this Mar 17, 2026
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.

2 participants