Skip to content

Spec: Claude Code session topic tags in cmd-p switcher#1087

Open
apollow wants to merge 2 commits intomanaflow-ai:mainfrom
apollow:spec/cmd-p-session-tags-v2
Open

Spec: Claude Code session topic tags in cmd-p switcher#1087
apollow wants to merge 2 commits intomanaflow-ai:mainfrom
apollow:spec/cmd-p-session-tags-v2

Conversation

@apollow
Copy link

@apollow apollow commented Mar 9, 2026

Summary

  • Adds a spec for making Claude Code session topics searchable in cmd-p
  • When a Claude session discusses a topic (e.g. "open claw"), typing that in cmd-p will surface the workspace
  • Tags flow from Claude hook notifications into workspace search metadata

Changes from v1 (#1086)

  • Decoupled from workspace-color-api — clean branch off main, only the spec file
  • Disabled by default — new cmdPSessionTags setting, users opt in explicitly
  • Tag namespacing — tags stored per source (claude:<sessionId>, manual) so Claude hooks never overwrite manual tags
  • PII sanitization — tag extraction strips secrets/sensitive patterns before persisting

Details

See docs/specs/cmd-p-session-tags.md for full spec including data flow, code changes, edge cases, and UI mockup.

Test plan

  • Review spec for completeness and feasibility
  • Validate tag namespacing design
  • Confirm settings toggle approach
  • Review PII sanitization requirements

Supersedes #1086

Generated with Claude Code


Summary by cubic

Spec to make Claude Code session topics searchable in cmd‑p by indexing topic tags from Claude hook notifications into workspace search metadata. Opt‑in via cmdPSessionTags, with namespaced and sanitized tags to avoid conflicts and protect sensitive data.

  • New Features
    • Add tags to CommandPaletteSwitcherSearchMetadata; index as search keywords and show as faint footnotes in cmd‑p.
    • Define tag tokenizer and fix indexing: keep full phrase and split on delimiters; include tokens and add context keywords (“tag”, “topic”, “claude”).
    • Store tags per source (claude:<sessionId>, manual) with caps; validate sessionId (^[a-zA-Z0-9_-]{1,128}$); persist in workspace snapshot.
    • Socket/CLI: workspace.set_tags, workspace.clear_tags, and cmux workspace set-tags; --source required for ownership.
    • Gate at extraction: when cmdPSessionTags is off, no Claude tags are pushed; manual tags always work. Cleanup: clear a session’s tags on stop; disabling doesn’t auto‑purge—use cmux workspace clear-tags if needed.

Written for commit 01c749f. Summary will update on new commits.

Summary by CodeRabbit

  • Documentation
    • Added specification for topic tags from Claude Code sessions in command palette search, enabling tags from Claude contexts to be searchable and displayable in session results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link

vercel bot commented Mar 9, 2026

@apollow is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

A design specification document is introduced for implementing topic tags from Claude Code session contexts within Cmd-P session search. The spec outlines data structures, persistence mechanisms via socket commands, tag indexing, extraction pipelines, gating configuration, and UI presentation details.

Changes

Cohort / File(s) Summary
Session Tags Specification
docs/specs/cmd-p-session-tags.md
New design document detailing the architecture for integrating Claude-sourced topic tags into Cmd-P session search, including data models (tagsBySource, searchTags), socket commands (workspace.set_tags, workspace.clear_tags), extraction pipeline with validation, a cmdPSessionTags feature gate, and UI presentation via footnotes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

🐰 Tags now hop through sessions bright,
Claude's wisdom labeled just right,
From hook to workspace they fly,
Searchable beneath Cmd-P's sky,
Context captured, organized delight!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: introducing a specification for Claude Code session topic tags in the cmd-p switcher.
Description check ✅ Passed The description covers the Summary, Testing, and key Details sections, though the Demo Video section is not applicable (spec document) and some checklist items are incomplete or testing-focused rather than completion-focused.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="docs/specs/cmd-p-session-tags.md">

<violation number="1" location="docs/specs/cmd-p-session-tags.md:92">
P1: The pseudocode computes `tagTokens` but never appends them to `contextKeywords`, so actual tag content would not be searchable. Only the static labels `"tag"`, `"topic"`, `"claude"` are added. Add `contextKeywords.append(contentsOf: tagTokens)` before or after the static-label append.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@greptile-apps
Copy link

greptile-apps bot commented Mar 9, 2026

Greptile Summary

This PR adds a spec for surfacing Claude Code session topics as searchable tags in the cmd-p workspace switcher. The design is well-structured with thoughtful defaults (opt-in, namespaced tag sources, PII sanitization, caps on tag storage), but the spec has one critical logic defect and several underspecified areas that would produce a broken or ambiguous implementation.

Key findings:

  • Critical logic bug (section 2): tagTokens is computed but never appended to the returned keyword list — only the generic labels ["tag", "topic", "claude"] are added. As written, searching for a specific topic like "open claw" would not match, defeating the feature's purpose.

  • Session ID injection risk (section 6): The source key claude:<sessionId> is embedded directly into the socket command string. Since sessionId is externally supplied from Claude's hook stdin, unsanitized values containing spaces or command-delimiter characters could malform or inject into the socket command.

  • Gating ambiguity (sections 4 and Settings): The comment // gated on cmdPSessionTags setting for display conflicts with the Settings section (which says the feature gates keyword indexing, not just display). The spec should clarify whether gating occurs at extraction only, metadata construction, or both.

  • Stale tags on feature disable: Because tagsBySource is persisted in workspace snapshots, disabling the feature after use leaves Claude-sourced tags in the model. The spec does not specify expected cleanup behavior.

  • tagTokensForSearch is undefined: The spec references this helper without defining its signature or tokenization rules (split on delimiters? include the original multi-word phrase?).

Not ready to implement — the spec contains a critical logic defect that would silently ship a non-functional feature, plus several underspecified areas.

Confidence Score: 2/5

  • Not safe to implement — the spec contains a critical logic defect (tag tokens never indexed), an injection risk (unsanitized session IDs in socket commands), and multiple ambiguities around feature gating and stale-tag cleanup that would cause implementation errors or broken behavior.
  • The spec has sound architecture and good defaults (opt-in, namespacing, sanitization), but the indexer snippet has a clear bug where tag tokens are computed but never appended to the returned keywords, making topics unsearchable. Additionally, session IDs from external input are embedded directly into socket commands without validation, the gating logic is ambiguous across two different code paths, stale-tag behavior after feature disable is unspecified, and a key helper function (tagTokensForSearch) is referenced but never defined. These five issues, especially the logic bug and injection risk, must be fixed before implementation begins.
  • docs/specs/cmd-p-session-tags.md — sections 2 (indexer logic), 4 (gating comment), 6 (session ID sanitization), Edge Cases (stale tag cleanup), and the tag tokenization helper definition

Sequence Diagram

sequenceDiagram
    participant Claude as Claude Code
    participant Hook as cmux claude-hook CLI
    participant Store as claude-hook-sessions.json
    participant Socket as cmux Socket
    participant WS as Workspace Model (tagsBySource)
    participant Indexer as CommandPaletteSwitcherSearchIndexer
    participant UI as Cmd-P Switcher

    Claude->>Hook: notification (stdin JSON)
    Hook->>Store: upsert lastSubtitle / lastBody
    Hook->>Hook: check cmdPSessionTags setting
    alt setting enabled
        Hook->>Hook: extract + sanitize topic tags
        Hook->>Socket: workspace.set_tags <id> --source claude:<sessionId> [tags]
        Socket->>WS: update tagsBySource["claude:<sessionId>"]
    end

    Claude->>Hook: stop event
    Hook->>Socket: workspace.clear_tags <id> --source claude:<sessionId>
    Socket->>WS: delete tagsBySource["claude:<sessionId>"]

    Note over WS: Manual tags via CLI<br/>always stored under "manual" source

    WS-->>Indexer: workspace.searchTags (flattened)
    Indexer-->>UI: keywords include tag tokens + ["tag","topic","claude"]
    UI-->>UI: user types "open claw" → workspace surfaces
Loading

Last reviewed commit: 83482c2

Comment on lines +91 to +97
```swift
let tagTokens = metadata.tags.flatMap { tagTokensForSearch($0) }
// Split on delimiters like branches, so "open-claw" matches "open", "claw", "open-claw"
if !tagTokens.isEmpty {
contextKeywords.append(contentsOf: ["tag", "topic", "claude"])
}
```
Copy link

Choose a reason for hiding this comment

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

tagTokens is computed but never appended to the returned keywords, so searching for a specific topic like "open claw" would not surface the workspace.

The code computes tagTokens from the metadata but only uses the non-empty check to add generic labels ["tag", "topic", "claude"]. The actual tag content is never included in the keyword list.

The return statement needs to include tagTokens:

return contextKeywords + directoryTokens + branchTokens + portTokens + tagTokens

Without this, the indexer would silently pass all wiring tests while never making topics searchable — the core purpose of the feature would be broken.

Copy link
Author

Choose a reason for hiding this comment

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

Addressed in 01c749f — added the missing append and return line.

- **Check setting**: skip tag extraction if `cmdPSessionTags` is disabled
- Extract topic keywords from `summary.subtitle` and `summary.body` (simple word tokenization, filter stopwords, keep meaningful tokens)
- **Sanitize**: strip tokens that look like secrets, file paths, UUIDs, emails, or other PII patterns before persisting
- Send `workspace.set_tags --source claude:<sessionId>` with the extracted tags
Copy link

Choose a reason for hiding this comment

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

sessionId is embedded directly in the socket command string without validation, creating a command-injection risk.

The spec shows workspace.set_tags --source claude:<sessionId> where sessionId comes from Claude's hook stdin JSON via parsedInput.sessionId. If this contains spaces, -- prefixes, or other shell/command-parsing characters, the resulting command string can be malformed or hijacked by the socket command parser.

The spec should require that sessionId values are validated/sanitized before being embedded in the source key — for example, restricting to alphanumeric characters and hyphens, with a maximum length. This is especially critical because the session ID originates from external tool output.

Copy link
Author

Choose a reason for hiding this comment

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

Addressed in 01c749f — spec now requires sessionId validation against ^[a-zA-Z0-9_-]{1,128}$ before embedding in source key. Malformed IDs skip tag push silently.

Comment on lines +110 to +117
```swift
return CommandPaletteSwitcherSearchMetadata(
directories: directories,
branches: branches,
ports: ports,
tags: workspace.searchTags // NEW — gated on cmdPSessionTags setting for display
)
```
Copy link

Choose a reason for hiding this comment

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

The comment // gated on cmdPSessionTags setting for display is ambiguous and conflicts with how gating is described elsewhere in the spec.

The Settings section states that when disabled, "No tags are extracted from Claude notifications" — implying extraction-level gating. But this comment suggests gating only affects display, not extraction. There are two possible interpretations:

  1. Gating at extraction (section 6): Claude hooks skip tag extraction when disabled, so tagsBySource stays empty for Claude-sourced tags.
  2. Gating at metadata construction (section 4): workspace.searchTags is conditionally passed based on the setting, even if tags were previously extracted.

The spec should clarify which is the single source of truth, and explain whether double-gating is needed (e.g., to handle users who had the feature enabled, accumulated tags, then disabled it).

Copy link
Author

Choose a reason for hiding this comment

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

Addressed in 01c749f — removed ambiguous comment. Spec now clearly states: single gate at extraction time (section 6). Metadata construction always passes tags through, ensuring manual tags work regardless of setting.

Comment on lines +170 to +177
### Edge Cases

- **Multiple Claude sessions per workspace**: each session writes to its own `claude:<sessionId>` source — no conflicts
- **Session ends**: only that session's tags are cleared; manual and other session tags persist
- **Tag overflow**: caps enforced per source (20 tags, 100 chars each); oldest dropped if exceeded
- **No Claude session**: tags field is empty, no UI change
- **Feature disabled** (default): no automatic tag extraction, socket commands still work for manual use
- **Sensitive data**: tag extraction sanitizes secrets/PII patterns before persisting
Copy link

Choose a reason for hiding this comment

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

The edge cases section does not address what happens when the feature is disabled after use.

Since tagsBySource is persisted in workspace snapshots, if a user enables the feature, accumulates Claude-sourced tags, and then disables it, those stale tags remain in the model and workspace snapshots. The expected behavior is unspecified:

  • Should toggling the feature off clear previously accumulated Claude-sourced tags automatically?
  • If tags persist, should the gating behavior (whether at extraction or metadata construction) prevent them from surfacing in cmd-p search?
  • Are stale tags acceptable, or should there be a migration/cleanup path when the setting is toggled?

The spec should define the intended behavior so users and implementations agree on what happens after disabling the feature.

Copy link
Author

Choose a reason for hiding this comment

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

Addressed in 01c749f — edge cases now define stale tag behavior: Claude-sourced tags are not auto-purged on toggle-off (they decay as sessions end). Users can run cmux workspace clear-tags for immediate cleanup.

Comment on lines +92 to +93
let tagTokens = metadata.tags.flatMap { tagTokensForSearch($0) }
// Split on delimiters like branches, so "open-claw" matches "open", "claw", "open-claw"
Copy link

Choose a reason for hiding this comment

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

tagTokensForSearch is referenced but never defined.

The snippet calls metadata.tags.flatMap { tagTokensForSearch($0) } but this function doesn't exist in the codebase (the existing helpers are directoryTokensForSearch, branchTokensForSearch, portTokensForSearch). The spec should define:

  • The function signature: func tagTokensForSearch(_ tag: String) -> [String]
  • Tokenization rules: should it split on metadataDelimiters the same way branchTokensForSearch does?
  • Whether the original unsplit tag should be included as a keyword (important for multi-word phrases like "open claw")
  • Whether it should be detail-aware

Without this definition, the tag tokenization behavior is underspecified.

Copy link
Author

Choose a reason for hiding this comment

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

Addressed in 01c749f — full tagTokensForSearch definition added with signature, tokenization rules (splits on metadataDelimiters, includes original multi-word tag), and documented as not detail-aware.

…essionId validation, clarify gating, define stale cleanup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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: 3

🧹 Nitpick comments (1)
docs/specs/cmd-p-session-tags.md (1)

65-67: Make tag ordering explicit instead of relying on dictionary flattening.

tagsBySource.values.flatMap { $0 } does not encode the priority order described later, so footnote/search ordering will depend on map iteration rather than the spec. Consider defining searchTags from an explicit source precedence list to keep display and indexing deterministic.

Also applies to: 183-187

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

In `@docs/specs/cmd-p-session-tags.md` around lines 65 - 67, The current
searchTags computed property uses tagsBySource.values.flatMap { $0 } which
relies on dictionary iteration order; change searchTags to build its array by
iterating an explicit source-precedence list (e.g., let sourcePrecedence =
[...]) and appending/flatMapping tagsBySource[source] in that order so ordering
is deterministic; update the same pattern elsewhere where
tagsBySource.values.flatMap { $0 } appears (the other occurrence that controls
footnote/search ordering) to use the same explicit precedence-driven
construction.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/specs/cmd-p-session-tags.md`:
- Around line 135-136: The spec currently only gates Claude tag extraction via
cmdPSessionTags, but previously persisted Claude tags still surface through
workspace.searchTags, metadata construction, the search indexer, and rendering
(footnotes); update the behavior so Claude-sourced tags are also suppressed when
cmdPSessionTags is false by either (A) filtering out or hiding tags with source
"claude"/the relevant source key at read/index/render time (where
workspace.searchTags, metadata construction, and the search indexer consume
tags), or (B) explicitly purging/hiding persisted Claude tags when
cmdPSessionTags is disabled; ensure the change references cmdPSessionTags,
tagsBySource, workspace.searchTags, and the search indexer/rendering paths and
documents the chosen gating strategy.
- Around line 92-100: The spec currently promises preserved multi-word tags but
the extractor behavior is underspecified; update the documentation around
tagTokensForSearch (which trims, splits by metadataDelimiters, and calls
uniqueNormalizedPreservingOrder) to explicitly state whether Claude-extracted
tags can be multi-word or are always single-tokenized, and if multi-word phrases
must be preserved ensure the extractor output format is described (e.g., emit
full phrase tags before tokenization) so tagTokensForSearch will index the
phrase as the first element; alternatively, narrow the guarantee to token-based
matching and adjust the wording wherever similar claims appear (also update the
equivalent paragraphs referenced at lines ~150-153) to avoid promising phrase
matching that the extractor may not supply.
- Around line 137-146: The CLI examples contradict the socket API
ownership/namespace rule: update the docs for the workspace.set_tags and
workspace.clear_tags commands so that the CLI explicitly requires --source in
every example (e.g., "workspace.set_tags <workspace-id> --source <source-key>
[...]" and "workspace.clear_tags <workspace-id> --source <source-key>") and
clarify that these operate only on the given source; alternatively, if you
intend a global/administrator operation, add and document a distinct command
(e.g., workspace.clear_all_tags <workspace-id> --admin) and mark it as
admin-only — update the description lines that reference these commands to state
the chosen contract (per-source required or separate admin-clear) and ensure the
“callers declare ownership” rule is reflected verbatim for workspace.set_tags
and workspace.clear_tags.

---

Nitpick comments:
In `@docs/specs/cmd-p-session-tags.md`:
- Around line 65-67: The current searchTags computed property uses
tagsBySource.values.flatMap { $0 } which relies on dictionary iteration order;
change searchTags to build its array by iterating an explicit source-precedence
list (e.g., let sourcePrecedence = [...]) and appending/flatMapping
tagsBySource[source] in that order so ordering is deterministic; update the same
pattern elsewhere where tagsBySource.values.flatMap { $0 } appears (the other
occurrence that controls footnote/search ordering) to use the same explicit
precedence-driven construction.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11ebc8ff-2655-4578-94dc-bd4df8160539

📥 Commits

Reviewing files that changed from the base of the PR and between 0f29735 and 01c749f.

📒 Files selected for processing (1)
  • docs/specs/cmd-p-session-tags.md

Comment on lines +92 to +100
/// Tokenizes a single tag string into searchable keywords.
/// Includes the original tag (for multi-word phrase matching like "open claw")
/// plus individual components split on standard delimiters.
/// Not detail-aware — tags are always fully tokenized regardless of workspace/surface context.
private static func tagTokensForSearch(_ rawTag: String) -> [String] {
let trimmed = rawTag.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else { return [] }
let components = trimmed.components(separatedBy: metadataDelimiters).filter { !$0.isEmpty }
return uniqueNormalizedPreservingOrder([trimmed] + components)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Phrase matching is underspecified for Claude-extracted tags.

The indexer is designed to preserve multi-word tags, but the extractor is described as “simple word tokenization.” If Claude-generated tags are only single tokens, the "open claw" example is no longer guaranteed by the data model. The spec should define how phrase tags are formed before indexing, or narrow the promised behavior to token-based matching.

Also applies to: 150-153

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

In `@docs/specs/cmd-p-session-tags.md` around lines 92 - 100, The spec currently
promises preserved multi-word tags but the extractor behavior is underspecified;
update the documentation around tagTokensForSearch (which trims, splits by
metadataDelimiters, and calls uniqueNormalizedPreservingOrder) to explicitly
state whether Claude-extracted tags can be multi-word or are always
single-tokenized, and if multi-word phrases must be preserved ensure the
extractor output format is described (e.g., emit full phrase tags before
tokenization) so tagTokensForSearch will index the phrase as the first element;
alternatively, narrow the guarantee to token-based matching and adjust the
wording wherever similar claims appear (also update the equivalent paragraphs
referenced at lines ~150-153) to avoid promising phrase matching that the
extractor may not supply.

Comment on lines +135 to +136
**Gating strategy**: The single gate is at **extraction time** (section 6). When `cmdPSessionTags` is disabled, no Claude-sourced tags are extracted or pushed, so `tagsBySource` stays empty for Claude sources. The metadata construction and search indexer always include whatever tags exist — this ensures manual tags (which bypass the setting) always work, and avoids double-gating complexity.

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Disabled mode still leaks previously persisted Claude tags.

This gating model only stops new extraction. Previously stored Claude tags would still flow through workspace.searchTags, get indexed, and render as footnotes, so they are not actually “inert” after the setting is turned off. The spec should either gate Claude-sourced tags at read/index/render time as well, or explicitly purge/hide them when cmdPSessionTags is disabled.

Also applies to: 195-196

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

In `@docs/specs/cmd-p-session-tags.md` around lines 135 - 136, The spec currently
only gates Claude tag extraction via cmdPSessionTags, but previously persisted
Claude tags still surface through workspace.searchTags, metadata construction,
the search indexer, and rendering (footnotes); update the behavior so
Claude-sourced tags are also suppressed when cmdPSessionTags is false by either
(A) filtering out or hiding tags with source "claude"/the relevant source key at
read/index/render time (where workspace.searchTags, metadata construction, and
the search indexer consume tags), or (B) explicitly purging/hiding persisted
Claude tags when cmdPSessionTags is disabled; ensure the change references
cmdPSessionTags, tagsBySource, workspace.searchTags, and the search
indexer/rendering paths and documents the chosen gating strategy.

Comment on lines +137 to +146
#### 5. Socket command: `workspace.set_tags`

```text
workspace.set_tags <workspace-id> --source <source-key> ["tag1","tag2","tag3"]
workspace.clear_tags <workspace-id> --source <source-key>
```

- Replaces tags **for the given source only** — other sources are untouched
- `--source` is required; callers declare ownership
- Off-main parsing, `DispatchQueue.main.async` for the model update (per socket threading policy)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

CLI ownership semantics contradict the namespacing model.

The socket API requires --source, but the CLI examples omit it and clear-tags 1 reads like a global delete. That undermines the “callers declare ownership” rule and makes it unclear whether manual commands operate on manual only or on every source. Please make the CLI contract explicit: require --source everywhere, or define a separate admin-only “clear all tags” command.

Also applies to: 158-165, 196-196

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

In `@docs/specs/cmd-p-session-tags.md` around lines 137 - 146, The CLI examples
contradict the socket API ownership/namespace rule: update the docs for the
workspace.set_tags and workspace.clear_tags commands so that the CLI explicitly
requires --source in every example (e.g., "workspace.set_tags <workspace-id>
--source <source-key> [...]" and "workspace.clear_tags <workspace-id> --source
<source-key>") and clarify that these operate only on the given source;
alternatively, if you intend a global/administrator operation, add and document
a distinct command (e.g., workspace.clear_all_tags <workspace-id> --admin) and
mark it as admin-only — update the description lines that reference these
commands to state the chosen contract (per-source required or separate
admin-clear) and ensure the “callers declare ownership” rule is reflected
verbatim for workspace.set_tags and workspace.clear_tags.

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