Files
orca/src/shared/skill-install-capability.ts
T
Neil 25a8418018 feat(skills): silently update unedited Orca skills per skill; prompt only for the rest (#36889)
* feat(skills): auto-update unedited Orca skills; ask only for edited copies

Planner already hashes each installed SKILL.md against every shipped release
digest (legacy installs included). When a plan's only writes replace such
hash-verified copies, the freshness nudge now applies it silently. Edited
copies and repairs still go through the consent toast; edited copies now raise
it too instead of only showing attention in settings.

* feat(skills): decide silent skill updates per skill and per location

Add skills.autoUpdateBundledOrca (capability-gated): the host plans the named
installed skills under their locks and applies only hash-verified released-copy
updates, re-checking each location before writing. The nudge auto-updates each
unedited skill and names only edited, unknown or repair-needing skills; the
try-once guard is keyed per skill and observed state, so one failure falls back
to the toast for that skill alone.

* fix(skills): surface preserved edits, share run ownership, re-show retracted nudges

- A silent update that moved a racing edit to a backup now shows a warning
  naming the skill and backup path instead of passing as success.
- Silent updates run under skill-update-run-store's per-target ownership, so
  manual and automatic runs never interleave and the dialog shows busy.
- Programmatic toast retraction releases its session marker; only a user
  dismissal suppresses the nudge.

* fix(skills): report stranded edits, isolate silent runs, bound attempt memory

- An old copy whose late edits cannot be backed up now fails the op with
  strandedPath naming where the edits remain; the silent caller warns with that
  path, and the next plan's backup cleanup is nudged, never deleted.
- Silent runs never start over a running or unacknowledged foreground result
  and never surface in the status bar.
- Auto-update attempts are keyed per target and pruned to the states the
  current scan observes; unchanged states stay suppressed.

* fix(skills): warn when a silent update's result is lost

Any rejected or timed-out auto-update request may follow a committed swap
whose racing edit went to a backup. Show a persistent warning naming the
target and its skill backup directory, and settle the attempt so the same
state is handed to the nudge instead of retried.

* test(skills): guard version skippers; ledger also walks release tags

Audit of every v* tag and HEAD history found no SKILL.md bytes missing from
released-digests.json. The generator now also walks release tags (falling back
to HEAD) so a release cut off-branch can never ship unrecognized bytes. Add a
real-disk test that installs the oldest shipped orchestration (v1.3.24-rc.2) in
the npx-skills and agent-folder layouts and auto-updates it silently.

* test(skills): type the nudge mock's error without an assertion

* chore(i18n): add the silent skill update warnings to the English catalog
2026-11-01 00:31:23 -07:00

47 lines
2.3 KiB
TypeScript

export const SKILL_INSTALL_CAPABILITY = 'skills.install.v1' as const
export const SKILL_INSTALL_RESULT_V2_CAPABILITY = 'skills.install-result.v2' as const
export const SKILL_INSTALL_CANCEL_CAPABILITY = 'skills.install-cancel.v1' as const
export const SKILL_UPLOAD_CAPABILITY = 'skills.upload.v1' as const
export const SKILL_MANAGEMENT_CAPABILITY = 'skills.manage.v1' as const
export const SKILL_BUNDLE_INSTALL_CAPABILITY = 'skills.install.bundle.v1' as const
export const SKILL_INSTALL_PROGRESS_CAPABILITY = 'skills.install-progress.v1' as const
/** Gate providers because strict older hosts reject the whole request instead of ignoring the new field. */
export const SKILL_INSTALL_PROVIDERS_CAPABILITY = 'skills.install-providers.v1' as const
export const SKILL_INSTALL_UPDATE_REQUIRED_MESSAGE =
'Update Orca on the selected machine to install shared skills.'
/** Gate the new method so old hosts show a disabled action rather than a method-not-found failure. */
export const SKILL_DELETE_CAPABILITY = 'skills.delete.v1' as const
export const SKILL_DELETE_UPDATE_REQUIRED_MESSAGE =
'Update Orca on the selected machine to delete skills.'
/** skills.planBundledOrca/executeBundledOrca v1 freezes op/reason enums; unknown values render “Needs attention”. */
export const BUNDLED_ORCA_SKILL_CAPABILITY = 'skills.bundled-orca.v1' as const
/** Gates skills.autoUpdateBundledOrca; older hosts fall back to asking before every update. */
export const BUNDLED_ORCA_SKILL_AUTO_UPDATE_CAPABILITY =
'skills.bundled-orca-auto-update.v1' as const
export const BUNDLED_ORCA_SKILL_UPDATE_REQUIRED_MESSAGE =
'Update Orca on the server to update its Orca skills.'
/** skills.discover scans a workspace named only by worktreeId, so phones without its folder can ask. */
export const SKILL_DISCOVER_WORKSPACE_CAPABILITY = 'skills.discover-workspace.v1' as const
export const SKILL_RUNTIME_CAPABILITIES = [
SKILL_INSTALL_CAPABILITY,
SKILL_BUNDLE_INSTALL_CAPABILITY,
SKILL_INSTALL_CANCEL_CAPABILITY,
SKILL_INSTALL_PROGRESS_CAPABILITY,
SKILL_INSTALL_RESULT_V2_CAPABILITY,
SKILL_UPLOAD_CAPABILITY,
SKILL_MANAGEMENT_CAPABILITY,
SKILL_INSTALL_PROVIDERS_CAPABILITY,
SKILL_DELETE_CAPABILITY,
BUNDLED_ORCA_SKILL_CAPABILITY,
BUNDLED_ORCA_SKILL_AUTO_UPDATE_CAPABILITY,
SKILL_DISCOVER_WORKSPACE_CAPABILITY
] as const