Skip to content

feat: your skill and knowledge review requests in Claude Code — /altimate-code:rules, decision toasts, publish relays the review - #22

Open
saravmajestic wants to merge 1 commit into
mainfrom
feat/workspace-review-status
Open

saravmajestic wants to merge 1 commit into
mainfrom
feat/workspace-review-status

Conversation

@saravmajestic

Copy link
Copy Markdown
Contributor

Summary

Your own skill and knowledge requests to a linked workspace, and the owner's or an admin's decisions on them, now show in Claude Code sessions. This is read-only: withdrawing and removing happen in the Altimate web app, the altimate-code TUI or the VS Code extension. It needs altimate-code with AltimateAI/altimate-code#1716 (stacked on #1708). Merge and release this after the first altimate-code release that includes it. With an older altimate-code, the new parts stay quiet.

  • /altimate-code:rules adds "Your skill and knowledge requests" after your proposals, from workspace review status --json.
    • Each request shows its status, whether it's an update, the reviewer and reason, and "waiting past 14 days".
    • Replaced requests are counted, not listed.
  • Publish guidance: the altimate-code skill now runs skill publish "<name>" --json and relays the review outcome: "sent for review to ", "already waiting", "already approved", or the refusal message, then points to /altimate-code:rules.
  • A direct toast for decisions (hooks/review-notices.ts, started from integrations.tsx in interactive sessions):
    • It runs workspace review decisions --json --unseen --mark-seen --host claude-ui at session start and every 15 minutes.
    • Each decision gets one toast ("◆ altimate · Your skill "X" was approved by Y…", or rejected or removed with the reason), at most 3 per check with the rest counted.
    • It stops asking for the session on signed_out, not_linked, unsupported, or a CLI without the command.
    • Its seen state is its own (claude-ui), apart from the session-start context. altimate-code adds the decisions and the waiting count to that context with no change here.
  • Version 1.6.0, with the CHANGELOG and README updated.

Verification

  • The mod tests pass (196, 7 new for the toast logic: one-time display, the cap, stopping on final statuses, older CLIs). Removing each of the 5 key fixes made a test fail.
  • Shell tests and the 65 Python tests pass.
  • The CLI side was tested end to end through the VS Code extension: AltimateAI/vscode-altimate-mcp-server#545 has screenshots. I haven't run this plugin in a live Claude Code session.
    • To try it: install from this branch's marketplace and start an interactive session in a linked project. Run /altimate-code:rules, and ask Claude to publish a project skill. Have the owner approve it in the web app, then wait for the toast or start a new session. The same decision isn't toasted again.

🤖 Generated with Claude Code

…d in /altimate-code:rules, decisions as toasts, publish relays the review (1.6.0)

- `/altimate-code:rules` also lists the person's skill and knowledge requests to the linked workspace
  (`workspace review status --json`): status, update, reviewer, reason, waiting over 14 days; replaced ones counted,
  not listed. Read-only: withdraw and remove happen in the web app, altimate-code's TUI or VS Code extension.
- `hooks/review-notices.ts`: in an interactive session, at start and every 15 minutes, asks altimate-code for
  decisions this host has not toasted (`workspace review decisions --json --unseen --mark-seen --host claude-ui
  --directory <cwd>`) and toasts each once (three at most per check, the rest counted). A CLI without the command, or
  a project that is not linked or signed in, stops the checks for the session.
- The skill's publish guidance uses `skill publish --json` and relays `review` (sent for review to the owner, already
  waiting, already approved) or the refusal.
- Tests: the toast module (wording, overflow, the CLI call, re-asking, stopping, -p sessions); the resolver check
  counts the new block.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
} catch (error) {
// No CLI at all, or it did not answer in time: try again next time.
$.ui.log(`review-notices · check failed: ${String(error)}`, { to: 'debug' })
return !/not found|ENOENT/i.test(String(error))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SUGGESTION]: Reuse MISSING_BINARY instead of a second, narrower regex

altimate-cli.ts already exports MISSING_BINARY for exactly this decision (integrations.tsx:114 uses it), and runAltimate only rethrows an error when that regex did not match, after trying both binary names. A start failure whose message says "no such file", "cannot start" or "failed to spawn" passes MISSING_BINARY, is rethrown here, but does not match this narrower /not found|ENOENT/, so checkOnce returns true and the hook keeps spawning the CLI every 15 minutes for the rest of the session. Using the shared regex keeps both places in agreement; this catch branch also has no test.

if (await checkOnce($, cwd)) $.clock.after(POLL_MS, () => void tick().catch(() => {}))
}
// Off the start's path: the first check runs once the session is up.
$.clock.after(0, () => void tick().catch(() => {}))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SUGGESTION]: One unexpected failure silently ends the checks for the whole session

tick() reschedules only after checkOnce resolves, and both .catch(() => {}) handlers swallow everything: a single throw ($.ui.toast on a session that just ended, $.clock.after on a dead engine) stops the 15-minute checks for the rest of the session with no log line. later() in altimate-cli.ts:41 already exists for "schedule this off the caller's path and log failures"; using it, and rescheduling from a path that runs even when a check fails, keeps the checks alive and debuggable. startReviewNotices also keeps no handle, so a second session.start on the same engine (resume, /clear) starts a second chain — lineage.tsx cancels its per-session work on session.end, which this loop has no equivalent for.

[ -n "$ALTIMATE_BIN" ] || { echo "altimate-code CLI not found (tried altimate, altimate-code)" >&2; exit 127; }
"$ALTIMATE_BIN" workspace review status --json < /dev/null
```
- Exit 0 answers JSON with `workspace_name`, `items`, `skipped` and `complete`. Each item has `kind` (`skill` or `knowledge`), `name`, `status` (`pending`, `active`, `rejected`, `superseded`, `withdrawn` or `retired`), `change` (`add` or `edit`), `reviewed_by_name`, `review_reason` and `expired`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SUGGESTION]: complete and skipped are named but never used

The contract says exit 0 answers workspace_name, items, skipped and complete, but the workflow only describes items, so a partial answer (complete: false, or a non-empty skipped) would be presented to the user as the whole list of requests. Say what to do with them, e.g. "when complete is false, say some requests may be missing". Step 1 now produces two different JSON documents and step 2 ("The JSON has workspace …") reads as if it described this one; naming each answer (proposals vs review status) would keep the model from mixing them.

/** The host name altimate-code keeps this toast's seen state under: apart from the session-start context's. */
export const HOST = 'claude-ui'
/** How often a running session asks again: decisions arrive while people work. */
export const POLL_MS = 15 * 60_000

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[SUGGESTION]: The new periodic backend call is not reflected in PRIVACY.md

This hook asks the Altimate backend at every interactive session start and then every 15 minutes (POLL_MS) through workspace review decisions, and shows reviewer names and reasons. PRIVACY.md keeps a dated log of what the plugin sends and still reads "Last revised: November 10, 2026" with the plugin 1.5.0 entry, so this release's new requests are undocumented; add a 1.6.0 entry and bump the revised date.

@kilo-code-bot

kilo-code-bot Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: 4 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 4

The core logic is sound: toastsFor caps and counts correctly, decisionText covers approved/rejected/retired, the poll stops on final statuses, and the 7 new tests match the module. Findings are about duplicated error handling, the poller's failure path, and documentation the release does not yet carry.

Issue Details (click to expand)

SUGGESTION

File Line Issue
plugins/altimate-code/hooks/review-notices.ts 66 Inline /not found|ENOENT/ re-implements MISSING_BINARY from altimate-cli.ts; a start failure matched by the shared regex ("no such file", "failed to spawn") is retried every 15 min forever. Branch is untested.
plugins/altimate-code/hooks/review-notices.ts 82 .catch(() => {}) on the tick and the reschedule swallows any unexpected throw, silently stopping the checks for the session; later() already exists for this. No handle to cancel, so a second session.start on the same engine adds a chain.
plugins/altimate-code/commands/rules.md 30 complete and skipped from workspace review status --json are named but never used, so a partial list reads as complete; step 2's "The JSON has …" is now ambiguous between the two JSON answers.
plugins/altimate-code/hooks/review-notices.ts 27 New backend polling (session start, then every 15 min) is not in PRIVACY.md's dated log, which still shows the 1.5.0 entry and a November 10 revised date.
Files Reviewed (10 files)
  • .claude-plugin/marketplace.json - version 1.6.0, consistent with plugin.json
  • plugins/altimate-code/.claude-plugin/plugin.json - version 1.6.0
  • plugins/altimate-code/CHANGELOG.md - 1.6.0 entry matches the code and README
  • plugins/altimate-code/README.md - 1 issue context (privacy log); wording matches the hook
  • plugins/altimate-code/commands/rules.md - 1 issue
  • plugins/altimate-code/hooks/integrations.tsx - wiring is correct (e.isInteractive, e.cwd), no issues
  • plugins/altimate-code/hooks/review-notices.test.ts - 7 tests, follow the harness conventions; no issues
  • plugins/altimate-code/hooks/review-notices.ts - 3 issues
  • plugins/altimate-code/skills/altimate-code/SKILL.md - skill publish --json guidance is consistent with the described contract; no issues
  • tests/resolve-cli.sh - rules.md now has 3 resolver blocks, matching the new block; no issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash-1017 · Input: 172.1K · Output: 27.4K · Cached: 1.7M

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