Repository navigation
feat: your skill and knowledge review requests in Claude Code — /altimate-code:rules, decision toasts, publish relays the review - #22
Conversation
…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)) |
There was a problem hiding this comment.
[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(() => {})) |
There was a problem hiding this comment.
[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`. |
There was a problem hiding this comment.
[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 |
There was a problem hiding this comment.
[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.
Code Review SummaryStatus: 4 Issues Found | Recommendation: Address before merge Overview
The core logic is sound: Issue Details (click to expand)SUGGESTION
Files Reviewed (10 files)
Fix these issues in Kilo Cloud Reviewed by deepseek-v4.1-flash-1017 · Input: 172.1K · Output: 27.4K · Cached: 1.7M |
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:rulesadds "Your skill and knowledge requests" after your proposals, fromworkspace review status --json.altimate-codeskill now runsskill publish "<name>" --jsonand relays the review outcome: "sent for review to ", "already waiting", "already approved", or the refusal message, then points to/altimate-code:rules.hooks/review-notices.ts, started fromintegrations.tsxin interactive sessions):workspace review decisions --json --unseen --mark-seen --host claude-uiat session start and every 15 minutes.signed_out,not_linked,unsupported, or a CLI without the command.claude-ui), apart from the session-start context. altimate-code adds the decisions and the waiting count to that context with no change here.Verification
/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