sliccy 6.160.0 → 6.162.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ui/.vite/manifest.json +182 -182
- package/dist/ui/assets/CLAUDE-BMBoR1hd.js +1 -0
- package/dist/ui/assets/CLAUDE-Bzu6oiWk.js +1 -0
- package/dist/ui/assets/MEMORY-Dr4c78r_.js +166 -0
- package/dist/ui/assets/SKILL-3ejR48eL.js +1 -0
- package/dist/ui/assets/{SKILL--iIJifMo.js → SKILL-C8DJkgFD.js} +1 -1
- package/dist/ui/assets/{SKILL-C9vwCrkC.js → SKILL-DYIL6DC-.js} +1 -1
- package/dist/ui/assets/{account-store-DPAcrOEJ.js → account-store-BwJF_V2e.js} +1 -1
- package/dist/ui/assets/{account-store-CePsk1tE.js → account-store-D-2d-wgE.js} +1 -1
- package/dist/ui/assets/{adobe-F53GCc9n.js → adobe-CjbAgmPl.js} +1 -1
- package/dist/ui/assets/{adobe-Bvqv_vJm.js → adobe-CwwqYoOU.js} +1 -1
- package/dist/ui/assets/{agent-bridge-DpJWjVUx.js → agent-bridge-BVKW1qEQ.js} +1 -1
- package/dist/ui/assets/{agent-panels-Bpvd01mi.js → agent-panels-CgbsDe7X.js} +1 -1
- package/dist/ui/assets/{apply-layout-CmnuIkY2.js → apply-layout-DwcfGHFm.js} +1 -1
- package/dist/ui/assets/{apps-8FivzUqm.js → apps-DevRtS09.js} +1 -1
- package/dist/ui/assets/{azure-openai-B2sC1XOD.js → azure-openai-BliiJJ3h.js} +1 -1
- package/dist/ui/assets/{azure-openai-Cn7AH3A6.js → azure-openai-JgQOdxTB.js} +1 -1
- package/dist/ui/assets/{backend-hostfs-DqmJEcF_.js → backend-hostfs-BeGMZ35g.js} +1 -1
- package/dist/ui/assets/{budget-usage-source-BihSbvk7.js → budget-usage-source-DtWNqYUy.js} +1 -1
- package/dist/ui/assets/{safe-buffer-OLJ0qaLt.js → buffer-B5d1xHaH.js} +1 -3
- package/dist/ui/assets/{safe-buffer-iah92gQe.js → buffer-DvhmllZ2.js} +1 -1
- package/dist/ui/assets/{bunny-probe-BVjp9oI9.js → bunny-probe-6xn_IAte.js} +1 -1
- package/dist/ui/assets/{bunny-run-E1D0_zTi.js → bunny-run-Czew2bZ0.js} +1 -1
- package/dist/ui/assets/{cdp-D3UrQPUf.js → cdp-Bt4Tc7Bs.js} +1 -1
- package/dist/ui/assets/{cerebras-DhjIiWyi.js → cerebras-B22qDyni.js} +1 -1
- package/dist/ui/assets/{cerebras-ByMgPfBR.js → cerebras-CjBby1u2.js} +1 -1
- package/dist/ui/assets/{composer-speech-CCafIYaS.js → composer-speech-BYeMN2uA.js} +1 -1
- package/dist/ui/assets/cone-memory-budget-Cmi9vXV5.js +15 -0
- package/dist/ui/assets/{connect-surface-BtbKFUb5.js → connect-surface-CHdfpKbm.js} +1 -1
- package/dist/ui/assets/{directed-approval-B4L-vOCr.js → directed-approval-DgyI3qOn.js} +1 -1
- package/dist/ui/assets/dist-BF1NH9lB.js +12 -0
- package/dist/ui/assets/dist-DQ0MhOxL.js +18 -0
- package/dist/ui/assets/{ensure-speech-assets-CqXifaHm.js → ensure-speech-assets-B3Nm2ohf.js} +1 -1
- package/dist/ui/assets/{fast-path-CbwpSWFJ.js → fast-path-CYxpDuii.js} +1 -1
- package/dist/ui/assets/{fs-DTEzNGFj.js → fs-CAQbIrYC.js} +1 -1
- package/dist/ui/assets/{fs-C2PDa-R-.js → fs-CCWZwfa6.js} +2 -2
- package/dist/ui/assets/{gelatiere-store-DA2wk9nw.js → gelatiere-store-BEP-eJ5h.js} +1 -1
- package/dist/ui/assets/{gelatiere-unit-DnbLwJqw.js → gelatiere-unit-yX_VWKxi.js} +1 -1
- package/dist/ui/assets/{github-BrfLcXzp.js → github-CUN_AUAu.js} +2 -2
- package/dist/ui/assets/{github-Ch77E2eB.js → github-DqE3SYB2.js} +1 -1
- package/dist/ui/assets/{github-auth-Bl0cyP8q.js → github-auth-E8mpeEdU.js} +1 -1
- package/dist/ui/assets/{github-copilot-Byhq1asv.js → github-copilot-BuEa5EIS.js} +1 -1
- package/dist/ui/assets/{github-copilot-g_xQkEpH.js → github-copilot-u9f-sT4d.js} +1 -1
- package/dist/ui/assets/{github-install-CR-EXBOY.js → github-install-BO46TS1H.js} +1 -1
- package/dist/ui/assets/{github-zip-CZFONhEX.js → github-zip-DeYRWuaP.js} +1 -1
- package/dist/ui/assets/{hear-BqVRH3XT.js → hear-Ow1sQFnW.js} +1 -1
- package/dist/ui/assets/{help-CeQBO5ly.js → help-7-ZCR2Cf.js} +1 -1
- package/dist/ui/assets/{installer-CscPxUWv.js → installer-DoomA9a4.js} +1 -1
- package/dist/ui/assets/{instruction-frontmatter-Bk64dayp.js → instruction-frontmatter-B48EsYtA.js} +1 -1
- package/dist/ui/assets/isomorphic-git-B7et_8Xe.js +69 -0
- package/dist/ui/assets/isomorphic-git-D2fV6xS-.js +86 -0
- package/dist/ui/assets/js-realm-worker-DRvMA0wv.js +50 -0
- package/dist/ui/assets/jsh-runtime-extensions-CBxhvxKk.js +1 -0
- package/dist/ui/assets/{just-bash-compat-_TMo8UnL.js → just-bash-compat-BwD6SoTi.js} +1 -1
- package/dist/ui/assets/{kernel-worker-D5e27k_H.js → kernel-worker-BOn7PAWS.js} +592 -589
- package/dist/ui/assets/{local-llm-BxA-EjNc.js → local-llm-B7QocwR-.js} +1 -1
- package/dist/ui/assets/{local-llm-DVwaDboP.js → local-llm-ws8kUvz8.js} +1 -1
- package/dist/ui/assets/{main-C8zDPux3.js → main-C3kY4qwt.js} +3 -3
- package/dist/ui/assets/{main-cherry-1oiJGSBV.js → main-cherry-CXJmoiKT.js} +1 -1
- package/dist/ui/assets/memory-budget-Bcf7Eolo.js +1 -0
- package/dist/ui/assets/memory-curation-seam-BeoDnTPF.js +1 -0
- package/dist/ui/assets/memory-write-execute-BOjUkUIG.js +1 -0
- package/dist/ui/assets/{mount-BlETha9u.js → mount-DLXo0YLf.js} +3 -3
- package/dist/ui/assets/{mount-Q9lauj2u.js → mount-eaKpsekX.js} +1 -1
- package/dist/ui/assets/{mount-recovery-CU6Z8MmL.js → mount-recovery-LNDCBESm.js} +1 -1
- package/dist/ui/assets/{mv-B4NndPT_.js → mv-DRuZuDHt.js} +1 -1
- package/dist/ui/assets/{new-session-D-Zk9tIn.js → new-session-BR07Cwue.js} +2 -2
- package/dist/ui/assets/{oauth-bootstrap-BGs1unaJ.js → oauth-bootstrap-CU5n9CrT.js} +2 -2
- package/dist/ui/assets/{onboarding-orchestrator-OioRQySZ.js → onboarding-orchestrator-DlvPySOw.js} +1 -1
- package/dist/ui/assets/{openai-codex-BdoYi7iZ.js → openai-codex-DVTuUFEt.js} +1 -1
- package/dist/ui/assets/{openai-codex-Ct104eE-.js → openai-codex-zNStwguM.js} +1 -1
- package/dist/ui/assets/{openrouter-BIaQ_JPl.js → openrouter-AATG6x2d.js} +1 -1
- package/dist/ui/assets/{openrouter-CcjhTCut.js → openrouter-RXJx-CYE.js} +1 -1
- package/dist/ui/assets/{openrouter-free-yA8q16HI.js → openrouter-free-3g-OS9Vd.js} +1 -1
- package/dist/ui/assets/{openrouter-free-DYDeRUsd.js → openrouter-free-BgEXTfii.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-DHnxPM5g.js → openrouter-oauth-6T6RMMKm.js} +1 -1
- package/dist/ui/assets/{openrouter-oauth-Uz0CNKvE.js → openrouter-oauth-BrunARs4.js} +1 -1
- package/dist/ui/assets/{opfs-mount-BdgSw31f.js → opfs-mount-Bs3Og1U8.js} +1 -1
- package/dist/ui/assets/{opfs-mount-DPyMX6Hw.js → opfs-mount-DqcCV6-e.js} +1 -1
- package/dist/ui/assets/{panel-rpc-handlers-IKhcZB2s.js → panel-rpc-handlers-C-ZrezVh.js} +2 -2
- package/dist/ui/assets/{panelize-shell-CfVDQ-qe.js → panelize-shell-Dqtsa7Xq.js} +1 -1
- package/dist/ui/assets/{pi-edit-execution-BO0Lb6Bm.js → pi-edit-execution-DqI6084r.js} +1 -1
- package/dist/ui/assets/{provider-CLIT77GF.js → provider-BzyjK17E.js} +2 -2
- package/dist/ui/assets/{provider-CgB8UlPB.js → provider-DEvcJ1Rc.js} +1 -1
- package/dist/ui/assets/provider-settings-CnvkRFSY.js +1 -0
- package/dist/ui/assets/provider-store-access-DFdeZeqD.js +1 -0
- package/dist/ui/assets/provider-store-access-Dwd6xV_i.js +1 -0
- package/dist/ui/assets/{providers-B5Xll24v.js → providers-DgV0i5wM.js} +1 -1
- package/dist/ui/assets/{providers-rH3sC6oE.js → providers-yJqf8FSl.js} +2 -2
- package/dist/ui/assets/{quick-llm-COj8uXB2.js → quick-llm-C0pknm6K.js} +1 -1
- package/dist/ui/assets/{recovery-screen-CcMWjF2S.js → recovery-screen-Drmpqp_Z.js} +1 -1
- package/dist/ui/assets/run-BCXMG6On.js +51 -0
- package/dist/ui/assets/{run-CTBcQwZc.js → run-BaLqrV2X.js} +1 -1
- package/dist/ui/assets/{run-DlNq_C45.js → run-BhxHz3xC.js} +1 -1
- package/dist/ui/assets/{run-BscXvZLR.js → run-CokQiUCf.js} +2 -2
- package/dist/ui/assets/{run-hAyl9Ys1.js → run-DWBPrvVI.js} +1 -1
- package/dist/ui/assets/{run-B5YOTTPD.js → run-Dfw_vahy.js} +2 -2
- package/dist/ui/assets/{run-DZd7hQTI.js → run-Dmi_q7LV.js} +1 -1
- package/dist/ui/assets/{run-C2zohVN-.js → run-DsHniFDx.js} +1 -1
- package/dist/ui/assets/{run-EhsZ6l-Q.js → run-iJ1NIefU.js} +2 -2
- package/dist/ui/assets/{session-jsonl-BD9cCIxh.js → session-jsonl-r3PC72gG.js} +1 -1
- package/dist/ui/assets/{setup-feature-flags-remote-BaDtxdhu.js → setup-feature-flags-remote-DvyEZpD7.js} +1 -1
- package/dist/ui/assets/{silent-renew-backoff-lXJyJbee.js → silent-renew-backoff-GAYBElLu.js} +1 -1
- package/dist/ui/assets/{skills-D9k7heyN.js → skills-83dSm0AA.js} +2 -2
- package/dist/ui/assets/slicc-version-C0gkt5sw.js +1 -0
- package/dist/ui/assets/{snapshot-D9frRFAl.js → snapshot-DIIE5zIj.js} +1 -1
- package/dist/ui/assets/{snapshot-features-CY1ojLDt.js → snapshot-features-CH_5YuGq.js} +1 -1
- package/dist/ui/assets/{soundscape-PjAXFwP2.js → soundscape-CzP0cXwy.js} +1 -1
- package/dist/ui/assets/{speak-BW-CzB9F.js → speak-BYzFS7Ty.js} +1 -1
- package/dist/ui/assets/{sprinkle-manager-AAdiFto8.js → sprinkle-manager-BLUZduNz.js} +1 -1
- package/dist/ui/assets/{sprinkle-renderer-Cko0du4q.js → sprinkle-renderer-Cb03w_WD.js} +1 -1
- package/dist/ui/assets/{src-D-Mukt_a.js → src-Dt9AZ03D.js} +72 -72
- package/dist/ui/assets/{state-CKVexu66.js → state-Bj9Ub2SV.js} +1 -1
- package/dist/ui/assets/{store-Bs0ibRcP.js → store-8BTj1fD_.js} +1 -1
- package/dist/ui/assets/{store-CYOzMNQy.js → store-tmEfD0Rj.js} +1 -1
- package/dist/ui/assets/{sudo-5OEj45QA.js → sudo-DAoppDTf.js} +1 -1
- package/dist/ui/assets/{sync-dialog-Du0XIfD-.js → sync-dialog-BWiv-UZX.js} +1 -1
- package/dist/ui/assets/{transformers-env-DGjj5kTt.js → transformers-env-CZ7GObfi.js} +1 -1
- package/dist/ui/assets/{tray-sidecar-A9Q-zHbK.js → tray-sidecar-2VKSK6f1.js} +1 -1
- package/dist/ui/assets/{upgrade-detection-E2JgYQa5.js → upgrade-detection-CPCrBCMa.js} +1 -1
- package/dist/ui/assets/{upskill-lick-skip-DbVexxZ4.js → upskill-lick-skip-CfQOyKFq.js} +1 -1
- package/dist/ui/assets/{voice-reply-FtqAqhy7.js → voice-reply-CkUBH04W.js} +1 -1
- package/dist/ui/assets/{wc-attach-DRll9Q8i.js → wc-attach-LnXYOiuQ.js} +2 -2
- package/dist/ui/assets/{wc-extension-B-yWHpR3.js → wc-extension-BiiJ1PC-.js} +2 -2
- package/dist/ui/assets/{wc-follower-8rcv-JrF.js → wc-follower-BPYn7Q3s.js} +3 -3
- package/dist/ui/assets/{wc-follower-oauth-CRapUStT.js → wc-follower-oauth-CCa8xLk0.js} +1 -1
- package/dist/ui/assets/{wc-gelatiere-CDF-kir7.js → wc-gelatiere-C1nVt4q0.js} +1 -1
- package/dist/ui/assets/{wc-live-D6R6V53U.js → wc-live-yBrQM63g.js} +66 -46
- package/dist/ui/assets/{wc-nav-oZP2a0A6.js → wc-nav-DwwSSgiM.js} +2 -2
- package/dist/ui/assets/{wc-onboarding-BXrB58p3.js → wc-onboarding-COGCiwOu.js} +2 -2
- package/dist/ui/assets/{wc-placeholder-SK_3lU2F.js → wc-placeholder-DYKS2mOy.js} +3 -3
- package/dist/ui/assets/{wc-secret-request-CoDENWqo.js → wc-secret-request-5YT8-1DJ.js} +1 -1
- package/dist/ui/assets/{wc-settings-Cg7k2K63.js → wc-settings-C91SZgPn.js} +3 -3
- package/dist/ui/assets/{wc-shell-fKAJRrUB.js → wc-shell-Bk_epkuk.js} +5 -5
- package/dist/ui/assets/{wc-shortcut-config-DtC8GuwC.js → wc-shortcut-config-Bs4LcqFL.js} +1 -1
- package/dist/ui/assets/{wc-shortcuts-Cxkm0n34.js → wc-shortcuts-CkiPB7Y_.js} +2 -2
- package/dist/ui/assets/{wc-sprinkles-C8Aqfch9.js → wc-sprinkles-B8NqZJDQ.js} +2 -2
- package/dist/ui/assets/{wc-transcript-export-u6ksMoo8.js → wc-transcript-export-BU4kXlKC.js} +2 -2
- package/dist/ui/assets/{wc-tray-ClOYh25L.js → wc-tray-DZnAKRIm.js} +4 -4
- package/dist/ui/assets/welcome-detection-Cd3WyOoe.js +1 -0
- package/dist/ui/assets/{whisper-session-CxYUomzX.js → whisper-session-BetvCfEP.js} +2 -2
- package/dist/ui/assets/{xai-grok-DjNkGSkX.js → xai-grok-BF8jP9SN.js} +1 -1
- package/dist/ui/assets/{xai-grok-BmowpkDG.js → xai-grok-DjlUbdZA.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/packages/webapp/index.html +3 -3
- package/package.json +4 -3
- package/dist/ui/assets/CLAUDE-DT25ppH5.js +0 -1
- package/dist/ui/assets/CLAUDE-I9G_dHp6.js +0 -1
- package/dist/ui/assets/DREAMING-DKcamfu0.js +0 -74
- package/dist/ui/assets/MEMORY-C8tCnvqV.js +0 -146
- package/dist/ui/assets/SKILL-BkCuZ1rT.js +0 -1
- package/dist/ui/assets/cone-memory-budget-ieIsscyt.js +0 -15
- package/dist/ui/assets/dist-0AIPb7H_.js +0 -12
- package/dist/ui/assets/dist-xOOa94QU.js +0 -18
- package/dist/ui/assets/isomorphic-git-Cgji39_P.js +0 -69
- package/dist/ui/assets/isomorphic-git-DRUhmZ5u.js +0 -84
- package/dist/ui/assets/js-realm-worker-CEmMP54m.js +0 -50
- package/dist/ui/assets/jsh-runtime-extensions-Bz5AwpQL.js +0 -1
- package/dist/ui/assets/memory-budget-CIVoqHgl.js +0 -1
- package/dist/ui/assets/memory-curation-seam-DlAyIfCr.js +0 -1
- package/dist/ui/assets/provider-settings-OCnlAtDl.js +0 -1
- package/dist/ui/assets/provider-store-access-CyRQ8v9r.js +0 -1
- package/dist/ui/assets/provider-store-access-I5hKcP3f.js +0 -1
- package/dist/ui/assets/run-DAdFvQnN.js +0 -50
- package/dist/ui/assets/slicc-version-Cd9e4zUy.js +0 -1
- package/dist/ui/assets/welcome-detection-BKAK_ts0.js +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e="# CLAUDE.md\n\n`packages/vfs-root/` is the default VFS payload — content, not runtime code — copied into the app's\nVFS on init/reset. Paths below are relative to `packages/vfs-root/`.\n\n## Directory Structure\n\n| Path | Becomes / purpose |\n| --------------------- | -------------------------------------------------------------------------------- |\n| `shared/` | `/shared/` — shared content |\n| `workspace/` | `/workspace/` — default workspace content |\n| `shared/CLAUDE.md` | Agent-facing runtime instructions → `/shared/CLAUDE.md` |\n| `etc/MEMORY.md` | User-editable memory pass (curator + dreamer) config → `/etc/MEMORY.md` |\n| `shared/GELATIERE.md` | User-editable gelatiere pass instructions + config → `/shared/GELATIERE.md` |\n| `shared/wiki/` | Shared knowledge-base scaffold (`WIKI.md` schema, empty `index.md`/`log.md`) |\n| `shared/sprinkles/` | Built-in sprinkle UIs |\n| `shared/sounds/` | Shared notification sounds |\n| `workspace/skills/` | Default installable workspace skills |\n| `etc/` | System config → `/etc/` (`models`, `sudoers`, `APPROVALS.md`, `slicc/keys.json`) |\n\n## Adding Default Content\n\n### Gelatiere\n\nDesign, pieces table, and sprinkle details: `docs/gelatiere.md`.\n\n- `shared/GELATIERE.md` is the gelatiere's twin of `MEMORY.md`: the store's build-time fallback and\n the seeded `/shared/GELATIERE.md`, seeded only when absent, user-edited only. Same frontmatter\n dialect (`base/instruction-frontmatter.ts`); keys `intervalHours`, `nightly` (5-field cron),\n `maxSuggestions` (≤10), `allowedCommands` (bare names, ADDITIVE over the built-in set). No placeholders: the unit `cat`s it every pass, so keep it self-contained\n (literal paths, `date` for today).\n- The gelatiere is a persistent SCOOP under a synthetic owner (`scoops/gelatiere-unit.ts`), not a\n spawned agent: charter is the record's `systemPromptAppend`, the pass recipe is this file.\n Deliverable is `gelatiere suggest <candidates.json> && gelatiere deliver`. Keep recipe commands on\n `GELATIERE_BASE_ALLOWED_COMMANDS` (a child escalates the rest; the file's `allowedCommands` extends\n it and is re-applied to the persisted record at boot / `gelatiere init`); cross-pass memory\n `/shared/.gelatiere/notes.md`.\n- `shared/sprinkles/suggestions/suggestions.shtml` is the suggestion stream, split from the\n onboarding-only `shared/sprinkles/welcome/welcome.shtml` so follower/extension welcome-dip\n handling can never mask or restart it; re-posted as a dip on every delivery, rail-pickable under\n Memory v2. Card buttons and lick verbs (`gelatiere-install`/`-try`/`-dismiss`): the doc.\n\n### Memory curator\n\n- `etc/MEMORY.md` is the single source for the runner's build-time fallback and the seeded\n `/etc/MEMORY.md`, seeded only when absent so customizations survive later boots. ONE document\n drives both passes — the per-session curation pass and the nightly consolidation (\"dreaming\")\n pass; the runtime fills `{{TASK}}` with which one this is, and `timeoutSeconds` /\n `dreamTimeoutSeconds` bound them separately (the dream has no one waiting and gets the long\n one). User-edited only: the pass cannot rewrite its own instructions. It may rewrite the whole\n memory file; the hard char budget covers the file — no protected region. The pre-merge\n `/shared/MEMORY.md` + `/shared/DREAMING.md` are no longer read; `memory status` flags a\n surviving copy.\n- Frontmatter is a strict YAML subset: block-array items may have `#` comment tails; inline entries\n with commas must be quoted; a bare `/` is rejected from `writablePaths`. `allowedCommands` extend\n the built-in base set, never replace it.\n- **The curator edits a staged draft, never the live file.** `{{MEMORY_PATH}}` resolves to\n `/sessions/.curation/<archive>/draft.md`; the agent bridge three-way-merges it onto the live file\n on exit 0, so a killed/failed run leaves live memory untouched and per-archive keying keeps\n parallel curators from sharing state. Merge/ledger mechanics (`mergeOnSuccess`, `status.json`,\n `memoryCuratedAt`/`memoryFailed`): `docs/webapp-details.md`.\n- Every `##`/`###` section ends with a `YYYY-MM-DD` last-verified date (UTC, matching archive\n timestamps). Each pass re-verifies oldest first; undated sections are maximally stale.\n- Entries follow the provenance/supersession grammar (MEMORY.md \"Entry grammar\"): `human:`/\n `process:` actor prefixes, version pins instead of confidence scores, `stale_after: YYYY-MM-DD` as\n an absolute instant, corrections that REPLACE claims, and a `## Not true` block for refuted claims\n kept as traps. Every pass enforces the grammar and reports contradiction-pair counts\n before/after so an unproductive pass is visible.\n- Write grant is `/workspace/CLAUDE.md` alone, not `/workspace/`: a directory-wide grant would also\n let it install into `/workspace/skills/` (it can still `upskill`). Reads still cover `/workspace/`.\n Single-file `writablePaths` work because `generateScoopSudoers` emits the bare path + `/**`.\n- The pass is detached, so it spawns with `notifyOnComplete`; its closing message reaches the cone\n on `scoop-notify` (where skill suggestions land), else the report is lost.\n- Turn count is the cost (every turn re-reads the whole context as a cache read). Two prompt-side\n levers keep it down: `thinkingLevel` (default `medium`; spawned agents otherwise resolve to `off`)\n so the curator plans the cut rather than converging by trial and error, and archive-reading\n recipes so it never `cat`s a huge archive whose `slicc:session-data` block is one line.\n\n### Approver agent\n\nFull policy reference: `docs/approvals.md`.\n\n- `etc/APPROVALS.md` is the single source for the runner's build-time fallback and the seeded\n `/etc/APPROVALS.md`. `SudoManager.ensureDefaults()` seeds it when absent, on the ungated handle —\n same place and reason as `/etc/sudoers`: it is self-protected, so anything else creating it (the\n `upgrade apply` merge) would prompt the owner to approve a default already in force.\n- It lives in `/etc/` because it is POLICY, next to `sudoers` — not `/shared/` (agent-visible\n content). Writes are self-protected in `base/sudoers.ts` (`isSelfProtectedWrite`): it decides what\n a GUEST may do, so a cone acting on a guest's message must not rewrite the rules gating that guest\n without an owner prompt.\n- Re-read on EVERY decision, not cached; missing/unreadable falls back to the bundled default rather\n than wedging approvals shut. The optional ```yaml block tunes `timeoutSeconds` (clamped), `model`,\n `thinkingLevel`; unreadable values fall back. The approver never reads the file: the runtime puts\n it in the prompt; the agent has no write grant.\n\n### Skills, Sprinkles, Sounds\n\n- **Skills**: add under `workspace/skills/<skill-name>/` with a `SKILL.md` plus any companion assets\n or `.jsh` scripts.\n- **Sprinkles**: add under `shared/sprinkles/<name>/`; name the main file `<name>.shtml` to match\n discovery.\n- **Sounds**: add under `shared/sounds/`; prefer stable filenames since shell commands and docs\n reference them directly.\n\n### Wiki\n\n- `shared/wiki/` seeds the shared KB at `/shared/wiki/`: `WIKI.md` is the schema contract\n (upgrade-merged like `MEMORY.md`); `index.md`/`log.md` are user data seeded once.\n- The read-only CLI is `workspace/skills/wiki/wiki.jsh`, adapted from `ai-ecoverse/skills` →\n `skills/llm-wiki/wiki.jsh` with the wiki root pinned to `/shared/wiki`; keep it synced with\n upstream and keep the Tier-0 behavior (fs bound via `require`, zero scans fail loudly) — both\n pinned by `tests/shell/wiki-jsh.test.ts`.\n- The memory pass (`etc/MEMORY.md`, consolidation step 5) holds the write path: over-budget\n reference knowledge moves from memory files into wiki pages, leaving a pointer.\n\n### Keyboard shortcuts\n\n- `etc/slicc/keys.json` is the user's OVERRIDE file for keyboard mode, seeded on first boot by\n `ui/wc/wc-shortcut-config.ts` with `\"trigger\": \"auto\"` and `\"bindings\": {}` — the keymap itself is\n `DEFAULT_KEYMAP` in `ui/wc/wc-shortcuts.ts` (a test asserts the file binds nothing). `trigger` is\n `auto`|`esc`|`null` (Theme settings switches it live).\n- **Never list a binding in the seed again.** An empty bindings object is what makes the shipped map\n — and every future change to it — inheritable; a seed pinning the whole map would freeze every\n booted install to it, so no later map or new command could reach anyone.\n- The one write beyond seeding is a one-shot migration: a file still holding the v1 map exactly\n (`isUntouchedV1Document`) is replaced once; anything else is the user's and left alone. Theme\n settings may also rewrite `trigger`.\n- The `//` comment must name every `CommandId` (a test asserts it) and carries the v1 keymap as a\n paste-back block, where `s` maps to `sprinkles` (not a cycle).\n\n## External Handoffs\n\nProtocol reference: `docs/slicc-handoff.md`. Agent-facing flow: `workspace/skills/handoff/SKILL.md`\n(bundled to `/workspace/skills/handoff/SKILL.md`), reached through the injected skill index — not\nthrough `shared/CLAUDE.md`, which only states handoffs are human-gated. Mechanism: RFC 8288 `Link`\nheader carrying `https://www.sliccy.ai/rel/handoff` or `.../rel/upskill` on a main-frame response →\n`navigate` lick → cone approval card. On behavior changes keep skill and doc aligned; don't\nduplicate their content here or in `shared/CLAUDE.md`.\n\n## Important Distinction\n\n`packages/vfs-root/shared/CLAUDE.md` is **agent-facing runtime content** bundled into the VFS —\ndistinct from the developer-facing `CLAUDE.md` files in the repo. Don't merge the roles.\n";export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e='# sliccy\n\nSLICC is a browser-native runtime for coding, browsing, automation, and parallel agents.\n\n## Roles\n\nYour injected role, policy, workspace and tools are authoritative; this file is not. Cone: a root work unit. Scoop: a delegated child. Root cones may coexist — never assume a singleton `cone`.\n\nSprinkles are persistent `.shtml` panels owned by a long-lived scoop; dips are ephemeral inline `shtml`; licks are events addressed to a work unit; trays are remote runtimes (`host` lists, `--runtime=<id>` targets).\n\n## Explore first\n\n100+ commands. Never say "I can\'t" without checking: `commands`, `<cmd> --help`, `man <topic>`, `skill list`, `upskill search "<query>"`, `upskill tabs`. Read manuals and skills before concluding something is missing.\n\nNew capability = a skill, not a feature: `/workspace/skills/skill-authoring/SKILL.md`.\n\n## Media\n\n`` renders inline in chat: images, video, audio; 2+ per paragraph is a gallery. Absolute paths only. Raw HTML renders too (sanitized), but a fenced html block only shows source.\n\n## Licks\n\nEvents arrive as `[<Event>: <name>]` with a JSON body. Route each to the work unit it addresses; never handle another unit\'s lick yourself. Discovery events are informational; acting is optional. Handoffs and other privileged actions are human-gated.\n\n## Operating\n\nOn failure, preserve the evidence, read the output, and try another path. After an ambiguous failure verify state before repeating a mutation. A policy denial surfaces as exit 1 or `EACCES`, not a prompt; request the least privilege. `rg` exit 1 is no match; exit 2 is the searchable-byte limit (stderr names the budget) — later commands still run. Local `chmod +x` persists; mounts may return `ENOSYS`. Use `bash file` when direct execution fails. Verify results and artifacts before claiming completion.\n\nKeep memory to durable facts; prune stale entries. Write memory files only with `memory_write`; it reports the remaining budget, so skip `wc -c`.\n\n## Style\n\nProfessional tool, not a chatbot. No emoji.\n';export{e as default};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Dd_uD5pT.js";var t=e({default:()=>n}),n=`---
|
|
2
|
+
writablePaths:
|
|
3
|
+
- /workspace/CLAUDE.md
|
|
4
|
+
- /shared/wiki/
|
|
5
|
+
visiblePaths:
|
|
6
|
+
- /sessions/
|
|
7
|
+
- /shared/
|
|
8
|
+
- /workspace/
|
|
9
|
+
allowedCommands:
|
|
10
|
+
- awk
|
|
11
|
+
- cat
|
|
12
|
+
- cp
|
|
13
|
+
- cut
|
|
14
|
+
- echo
|
|
15
|
+
- file
|
|
16
|
+
- find
|
|
17
|
+
- grep
|
|
18
|
+
- head
|
|
19
|
+
- jq # structured reads of JSON stores such as /shared/loose-ends.json and /sessions/index.json
|
|
20
|
+
- ls
|
|
21
|
+
- mkdir
|
|
22
|
+
- mv
|
|
23
|
+
- od # read-only byte inspection of corrupted stores
|
|
24
|
+
- printf
|
|
25
|
+
- rg # recursive, .gitignore-aware search; what the pass actually uses over find|xargs grep. Exit 1 = no match (\`-c\` prints nothing, not \`0\`); exit 2 = searchable-byte limit (stderr names the budget). Later commands still run.
|
|
26
|
+
- sed
|
|
27
|
+
- sort
|
|
28
|
+
- tail
|
|
29
|
+
- tr
|
|
30
|
+
- uniq
|
|
31
|
+
- upskill
|
|
32
|
+
- wc
|
|
33
|
+
timeoutSeconds: 1200
|
|
34
|
+
dreamTimeoutSeconds: 3600
|
|
35
|
+
thinkingLevel: medium
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
# Memory pass
|
|
39
|
+
|
|
40
|
+
You maintain one cone's durable memory: the file at {{MEMORY_PATH}}. Today's date is {{TODAY}}; {{SESSION_COUNT}} sessions are archived. The whole file has a hard budget of {{BUDGET_CHARS}} characters, with no exempt region.
|
|
41
|
+
|
|
42
|
+
## This pass
|
|
43
|
+
|
|
44
|
+
{{TASK}}
|
|
45
|
+
|
|
46
|
+
Read the entire current memory at {{MEMORY_PATH}} first. Every part of the file is editable and counts toward the budget.
|
|
47
|
+
|
|
48
|
+
## Mining the session archive (curation passes only)
|
|
49
|
+
|
|
50
|
+
Three things carry across sessions, and each has its own place in the archive:
|
|
51
|
+
|
|
52
|
+
| Look for | Where it lives |
|
|
53
|
+
| --------------- | ---------------------------------------------------------------------- |
|
|
54
|
+
| **Preferences** | the user's own messages — how they want things done, and what to avoid |
|
|
55
|
+
| **Projects** | tool-call arguments — the paths, repos and files actually worked on |
|
|
56
|
+
| **Pitfalls** | failed tool calls — what broke, and the error that proves it |
|
|
57
|
+
|
|
58
|
+
Pitfalls are the highest-value and most-often-lost category: a failure that cost half an hour is worth one line next time. Keep the error text that identifies it, not the stack trace.
|
|
59
|
+
|
|
60
|
+
**Never \`cat\` the archive and never \`head\` it.** Archives reach several megabytes, and the machine-readable \`<!-- slicc:session-data ... -->\` block is a _single line_ holding the whole session as JSON — roughly half the file. Reading it costs a fortune and tells you nothing the prose below it does not. Whole \`### Tool\` result bodies are the other half and are equally not worth reading.
|
|
61
|
+
|
|
62
|
+
Check the size first, then pull the three signals separately. Together they run about 1% of the archive, so these work on a 2.5 MB file as happily as on a small one.
|
|
63
|
+
|
|
64
|
+
\`\`\`bash
|
|
65
|
+
wc -c {{SESSION_ARCHIVE_PATH}}
|
|
66
|
+
|
|
67
|
+
# Preferences — what the user asked for, in their words.
|
|
68
|
+
sed '/^<!-- slicc:session-data$/,/^-->$/d' {{SESSION_ARCHIVE_PATH}} \\
|
|
69
|
+
| awk '/^## User/{p=1;next} /^## (Assistant|Summary)/{p=0} /^### Tool/{p=0} p'
|
|
70
|
+
|
|
71
|
+
# Projects — the paths touched most, which name the work.
|
|
72
|
+
sed '/^<!-- slicc:session-data$/,/^-->$/d' {{SESSION_ARCHIVE_PATH}} \\
|
|
73
|
+
| grep -o '/[A-Za-z0-9_][A-Za-z0-9_./-]\\{3,\\}' \\
|
|
74
|
+
| sort | uniq -c | sort -rn | head -40
|
|
75
|
+
|
|
76
|
+
# Pitfalls — failed calls with the input that caused them.
|
|
77
|
+
sed '/^<!-- slicc:session-data$/,/^-->$/d' {{SESSION_ARCHIVE_PATH}} \\
|
|
78
|
+
| grep -B6 '^Result:.*\\(rror\\|not found\\|failed\\|denied\\|ENOENT\\|fatal\\)' \\
|
|
79
|
+
| cut -c1-200
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
Only if something is still missing, reach into one specific block with \`grep -n\` plus a bounded \`sed -n 'START,ENDp'\`. Never widen these to the whole file.
|
|
83
|
+
|
|
84
|
+
### Suggesting a skill
|
|
85
|
+
|
|
86
|
+
A recurring pitfall is often a missing skill. Once you know what broke and what the work was, spend **one** lookup on it — no more, and skip it entirely when the session had no failures:
|
|
87
|
+
|
|
88
|
+
\`\`\`bash
|
|
89
|
+
upskill search <a few words from the pitfall>
|
|
90
|
+
upskill list # what is already installed — never suggest a duplicate
|
|
91
|
+
\`\`\`
|
|
92
|
+
|
|
93
|
+
\`upskill ai-ecoverse/skills\` and \`upskill adobe/skills\` list a repo's skills without installing anything. **Never install.** You have no write access to the skills tree, so an install attempt will fail or interrupt the user for approval; recommending is your job, deciding is theirs. Put any suggestion in your closing message, with the pitfall it addresses — that message is delivered to the main agent.
|
|
94
|
+
|
|
95
|
+
## Consolidating (every pass)
|
|
96
|
+
|
|
97
|
+
The file accumulates under time pressure; every pass leaves it better than it found it:
|
|
98
|
+
|
|
99
|
+
1. **Merge duplicates.** Across weeks the same preference or project fact accumulates near-identical phrasings. Keep one — the most recent, most specific version.
|
|
100
|
+
2. **Supersede contradictions.** When two lines contradict, the newer-dated one wins; rewrite in place so only one version stands — a claim and its correction must never survive together as prose. When the refuted claim is a trap worth remembering, record it under a \`## Not true\` section as \`- not: <refuted claim> — why: <evidence> — instead: <correction> (YYYY-MM-DD)\`. A fact contradicted by the session titles in the index (a project renamed, a tool replaced) goes too. Count contradictory claim pairs before and after the rewrite and put both numbers in the closing report; if the pass could not reduce the count, say so.
|
|
101
|
+
3. **Retire stale ephemera.** An entry whose \`stale_after: YYYY-MM-DD\` date has passed is unverified — re-verify it against the index or drop it. Sections whose last-verified date is old AND whose subject no longer appears in recent session titles are candidates for deletion — check before deleting:
|
|
102
|
+
|
|
103
|
+
\`\`\`bash
|
|
104
|
+
# Recent activity, to test whether an old section still matters.
|
|
105
|
+
jq -r '.[] | "\\(.frozenAt[0:10]) \\(.cone // "cone") \\(.title)"' /sessions/index.json | tail -40
|
|
106
|
+
\`\`\`
|
|
107
|
+
|
|
108
|
+
4. **Reorganize.** Fold orphan bullets into the per-topic section they belong to; split a section that has become two topics; order sections so the most-used topics lead. Every \`##\` and \`###\` heading keeps (or gains) its last-verified date in \`YYYY-MM-DD\` form.
|
|
109
|
+
5. **Move knowledge to the wiki.** When the file is over budget and a section is reference knowledge — facts about a domain, a system, a person — rather than working preferences or pitfalls, move it to a page under \`/shared/wiki/\` following \`/shared/wiki/WIKI.md\` (update \`index.md\`, append an \`ingest\` entry to \`log.md\`), and replace the section with one line naming the page. Move at most a couple of sections per pass; the memory file must keep working standalone.
|
|
110
|
+
6. **Land under budget.** The hard budget is {{BUDGET_CHARS}} characters for the whole file, no exempt region. When over budget, compact or remove the oldest-dated sections first.
|
|
111
|
+
|
|
112
|
+
A pass never adds facts that are not in the session archive, the file or the wiki, never installs anything, and never touches any file other than {{MEMORY_PATH}} and the wiki.
|
|
113
|
+
|
|
114
|
+
## Entry grammar: provenance and supersession
|
|
115
|
+
|
|
116
|
+
Facts age. Write every entry so a later pass can tell whether it still holds:
|
|
117
|
+
|
|
118
|
+
- Prefix entries with their actor: \`human:\` for what the user said, \`process:\` for what you inferred from tool output. Example: \`- human: prefers rebase over merge (2026-09-11)\`.
|
|
119
|
+
- Version-pin claims that can rot: name the version, commit, or file the claim was verified against, e.g. \`- process: coverage floor is 83% (coverage-thresholds.json @ 6.146.2)\`. Never record a confidence score — what ages is the pin, not a probability.
|
|
120
|
+
- A claim with a known expiry carries \`stale_after: YYYY-MM-DD\`, an absolute date, never a duration. Past that date the claim counts as unverified.
|
|
121
|
+
- **Supersede, never append.** When a session proves a stored claim wrong, rewrite the claim in place — a claim and its correction must never both stand as prose (see step 2 above for the \`## Not true\` form).
|
|
122
|
+
|
|
123
|
+
## Working within the budget
|
|
124
|
+
|
|
125
|
+
Measure, decide, then write. Do not converge on the budget by trial and error — each attempt re-reads your whole context and is billed accordingly.
|
|
126
|
+
|
|
127
|
+
1. \`wc -c {{MEMORY_PATH}}\` to get the current size, and subtract {{BUDGET_CHARS}} to get the exact surplus. Per-section costs come out of \`awk\`: \`awk '/^## /{h=$0} {c[h]+=length($0)+1} END{for(k in c) printf "%7d %s\\n", c[k], k}' {{MEMORY_PATH}} | sort -rn\` tells you which sections pay for the surplus.
|
|
128
|
+
2. Decide up front which sections absorb that surplus, oldest-dated first, and roughly what each one costs. Budget the whole cut before editing anything.
|
|
129
|
+
3. Write with the \`memory_write\` tool (\`path: {{MEMORY_PATH}}\`). It is the only tool that can write the memory file — \`write_file\`, \`edit\`, \`cp\` and \`cat >\` are refused on it — and it refuses any write that would leave the file over budget without shrinking it. Prefer \`edits\` (exact replacements, one section at a time) so finished sections land as you go and a stopped run never discards them; use \`content\` for a whole-file rewrite at most once, already inside the budget, and never draft the whole file elsewhere first — emitting it twice is what runs a pass out of time. Never write a version you know to be over budget «to fix in the next step»: the pass can be killed at any moment, and the file you leave behind is the one the next session inherits.
|
|
130
|
+
4. Read the size and the remaining room from the tool's result — it reports both, so do not spend a turn on \`wc -c\` afterwards. If it says you are still over, cut a whole section rather than shaving a few characters at a time.
|
|
131
|
+
|
|
132
|
+
Scratch for notes (not for drafting the whole file) is \`{{SCRATCH_DIR}}/\`: your own folder, writable without a grant and without an approval prompt, private to this pass, and deleted when the pass ends.
|
|
133
|
+
|
|
134
|
+
If the pass is running long, drop the oldest-dated section wholesale and write. An under-budget file missing one stale section is a good outcome; an over-budget file is a broken one.
|
|
135
|
+
|
|
136
|
+
## Rules
|
|
137
|
+
|
|
138
|
+
- Keep durable preferences, stable project facts, validated approaches, named resources, and the pitfalls worth not repeating.
|
|
139
|
+
- Organize retained information into concise per-topic sections rather than one flat list. Let the topic lead the heading; preferences, projects and pitfalls are what to look for, not a required table of contents.
|
|
140
|
+
- Never write next to the memory file: backups and scratch copies beside it are noise. Do not draft in the shared \`/tmp/\` root either — every other unit can read and overwrite what you leave there.
|
|
141
|
+
- Shell tools only. Interpreters such as \`python3\` and \`node -e\` are not on your allow-list, so reaching for one costs an approval round-trip and may fail even when approved — \`awk\`, \`sed\`, \`wc\` and \`sort\` cover every measurement this pass needs.
|
|
142
|
+
- End every \`##\` and \`###\` section heading with its last-verified date in \`YYYY-MM-DD\` form, for example \`## Deployment pipeline (2026-08-06)\`. Dates are UTC, matching the session archive timestamps, so a late-evening freeze west of UTC stamps the next day.
|
|
143
|
+
- Re-stamp a heading with {{TODAY}} only when you wrote or actually re-verified its content this pass; otherwise keep its existing date. Treat undated headings as maximally stale and date them on this pass.
|
|
144
|
+
- Prioritize re-verifying the oldest-dated sections. Drop ephemera and duplicates; delete or merge sections that are stale, superseded, or unverifiable.
|
|
145
|
+
- Preserve concrete identifiers such as file paths, URLs, IDs, and names verbatim.
|
|
146
|
+
- Write the result to {{MEMORY_PATH}}; do not merely return it in your response.
|
|
147
|
+
- Close with a two-or-three-line report of what you kept, merged and dropped (plus any skill worth suggesting, and the contradiction-pair counts before and after) — that report is delivered to the cone.
|
|
148
|
+
|
|
149
|
+
<!-- How to customize
|
|
150
|
+
Add instructions here, for example: never drop sections mentioning a named project, or also consolidate a knowledge base at /path (extend visiblePaths or writablePaths above to grant access to extra stores). One document drives both passes: the per-session curation pass the freezer runs after a chat ends, and the nightly consolidation ("dreaming") pass the gelatiere starts with \`memory dream --all\` (\`memory dream\` runs one by hand). The runtime fills {{TASK}} with which pass this is; everything else in the document applies to both.
|
|
151
|
+
|
|
152
|
+
timeoutSeconds bounds a curation pass and dreamTimeoutSeconds a consolidation pass — the run is hard-stopped at the bound, and a rewrite only lands through the merge below, which is why the budget section asks for section-wise edits. The nightly has no time pressure, so its bound is generous; the curation pass runs while the user waits for memory to settle.
|
|
153
|
+
|
|
154
|
+
{{MEMORY_PATH}} resolves to a staged draft under /sessions/.curation/, not the live memory file: the pass snapshots the live file when it spawns, rewrites the draft, and on a successful exit the runtime three-way-merges the rewrite back onto the live file. Edits the cone or the user makes to the live memory while the pass runs survive; where both sides changed the same lines the pass's version wins. An entry in writablePaths naming the memory file is substituted with the draft automatically, so this file keeps working unchanged. A failed or killed run leaves the live memory untouched and its outcome recorded at /sessions/.curation/<key>/status.json. Writes under /shared/wiki/ are NOT staged — a wiki page lands immediately — which is safe because wiki moves are additive; the pointer line replacing the moved section only lands if the pass completes.
|
|
155
|
+
|
|
156
|
+
writablePaths defaults to the memory file plus the wiki rather than /workspace/, because the pass can run upskill and a directory-wide grant would also let it install skills into /workspace/skills. Widen it only as far as a task genuinely needs; a single file is a valid entry, not just a directory.
|
|
157
|
+
|
|
158
|
+
Scratch space needs no entry here. Each pass spawns under a fixed per-cone name (memory-curator / memory-dreamer for the primary cone, -<folder> suffixed for extra cones), so the bridge grants it {{SCRATCH_DIR}} — private to the run, writable without a prompt, and removed when the pass ends. Parallel passes over DIFFERENT memory files never collide; two passes over the SAME file serialize. $TMPDIR is writable too and is this unit's own directory, but it outlives the run and stays readable by the cone, so durable memory does not belong there.
|
|
159
|
+
|
|
160
|
+
thinkingLevel accepts off, minimal, low, medium, high, or xhigh. Curation is cheaper with reasoning than without: an unreasoned pass converges on the budget by trial and error, and because every turn re-reads the whole context, turn count is what the pass costs. Lower it to off only if you also shrink the prompt to a single mechanical instruction.
|
|
161
|
+
|
|
162
|
+
This file is user-edited only: the pass intentionally cannot rewrite its own instructions. A bare / is rejected in writablePaths. It is seeded only when absent, so edits survive later boots; \`upgrade\` three-way-merges a changed bundled version onto your edits.
|
|
163
|
+
|
|
164
|
+
Frontmatter supports a strict YAML subset. Arrays may use the block form above (with optional # comment tails) or inline form such as [cat, grep]. \`allowedCommands\` is additive: listed commands extend the built-in base set without replacing it. Inline entries containing commas must be quoted, for example ["/knowledge/lars,rebecca/"].
|
|
165
|
+
-->
|
|
166
|
+
`;export{t as n,n as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var e='---\nname: upgrade\ndescription: |\n Use this when you receive an `[Upgrade Event: x.y.z→a.b.c]` lick — fired on\n boot whenever the bundled SLICC version differs from the previous run. The\n lick renders a binary action card: `lick_confirm` to Update workspace files\n (three-way merge of bundled `vfs-root` files against the user\'s local edits)\n or `lick_dismiss` to clear it. Reviewing the changelog from GitHub, and\n checking installed skills for updates with `upskill list --outdated`, are\n separate steps you can run first. Never auto-applies; the user resolves the\n card.\nallowed-tools: bash, read_file, write_file, edit\n---\n\n# Upgrade\n\nWhen SLICC boots and discovers that the bundled version (baked into the build at release time from the root `package.json`) differs from the version it was last seen running, it emits an `upgrade` lick to the cone. This skill describes how to react.\n\n## Event shape\n\nYou receive a message like:\n\n```text\n[Upgrade Event: 0.4.1→0.5.0]\n\nSLICC was upgraded from `0.4.1` to `0.5.0`.\nReleased: 2026-04-15T12:00:00Z\n\nUse the **upgrade** skill (...)\n```\n\nThe two version strings (`from`, `to`) are valid git tags on `https://github.com/ai-ecoverse/slicc` — the public source repository. The lick message carries a `Lick ID:` line — you resolve the card with that id.\n\n## What to do when you receive an upgrade lick\n\nThe runtime renders the upgrade lick as a binary action card automatically — you do not render a sprinkle. The card has exactly two outcomes, which you drive with the lick tools using the `Lick ID` from the message:\n\n- **`lick_confirm` → Update workspace files.** This runs `upgrade apply` with the stored release versions. Only confirm once the user has decided to pull the new files.\n- **`lick_dismiss` → clear the card.** Use this when the user wants to skip the merge; nothing is changed and the card mutes (✗). The lick will not fire again until the next upgrade.\n\nThe card flips to ✓ on confirm / muted ✗ on dismiss. Never auto-run the merge — the user must choose. Reviewing the changelog is **not** a card action; it is a separate step you can run first to help the user decide.\n\n**Before `lick_confirm` or `lick_dismiss`, check `list_scoops`.** A scoop that is `processing` may lose its in-flight work when the runtime moves to the new version. There is **no notification** — the scoop can look `ready` / finished, indistinguishable from a clean completion. Wait until every scoop is idle, or expect to re-feed any that were still working. Idle scoops survive.\n\n## Which version am I running?\n\n`uname -r` prints the running version. `upgrade status` adds the last-booted one, whether a merge is pending, and the exact `upgrade apply` line to run when it is — that is where `--from`/`--to` come from without a card on screen. Realm scripts read `globalThis.SLICC_VERSION`.\n\n## Changelog review (separate step — not a card action)\n\nBefore the user decides, you can fetch the GitHub compare API for the two tags and summarize the result. This is optional and independent of the card; it does not resolve the lick.\n\n```bash\n# The repo is public — no auth required for the compare endpoint.\n# stdin here is fully buffered, so read() drains the whole response in one shot.\ncurl -sSL "https://api.github.com/repos/ai-ecoverse/slicc/compare/v${FROM_VERSION}...v${TO_VERSION}" \\\n | node -e \'const j=JSON.parse(process.stdin.read()||"{}");console.log((j.commits||[]).map(c=>"- "+c.commit.message.split("\\n")[0]).join("\\n"))\'\n```\n\nShow the conventional-commit messages grouped by type (`feat`, `fix`, `chore`, ...). If the compare returns 404 (tags missing), fall back to the GitHub releases page URL: `https://github.com/ai-ecoverse/slicc/releases/tag/v${TO_VERSION}`.\n\n## Applying workspace files (the `lick_confirm` action)\n\n`lick_confirm` runs the browser-native command below through the cone shell using the versions stored with the lick. Do not run a second merge after confirming.\n\n```bash\nupgrade apply --from="${FROM_VERSION}" --to="${TO_VERSION}"\n```\n\nThe command discovers bundled files at both release refs under `/workspace/skills`, `/shared/sprinkles`, `/shared/sounds`, and `/etc`, prefetches and preflights every path; then applies safe updates with `VirtualFS` and the built-in three-way merge. `/etc/MEMORY.md` (the memory-pass contract) and the `/etc` policy files (`sudoers`, `models`, `llmstxtignore`) are seeded only when absent, so this merge is the only way a rule change in them reaches an existing profile — including approval rules such as the `Write /etc/models` gate. Applying a change to `/etc/sudoers` still raises its own approval prompt: the card authorizes the merge, not the policy edit. Its JSON output classifies every bundled path as `auto-applied`, `merged-clean`, `kept-local`, `needs-review`, `unchanged`, or `added-new`.\n\nAn exit code of `1` means discovery/fetch failed or at least one path needs review. Conflicts are written to the reported collision-safe sidecar while the live file remains unchanged. Show the JSON summary and sidecar paths to the user; never copy conflict markers into the live file automatically. The command never deletes local-only files.\n\nThe command can also be run directly with explicit release versions for manual recovery, but an upgrade card still requires the user\'s confirmation before changing files.\n\n## Also check installed skills (separate step — not a card action)\n\nThe card only covers **bundled** files (`/workspace/skills`, `/shared/sprinkles`, `/shared/sounds`, `/etc`). Skills the user installed themselves with `upskill` are never touched by it, and they drift silently — a stale one can sit months behind upstream while still loading fine.\n\nA new SLICC release is a good moment to check them. This is read-only:\n\n```bash\nupskill list --outdated\n```\n\nIt reuses the same classification as `upskill update --dry-run`: each skill\'s `.upskill` provenance record (source repo, ref, resolved commit, file list) compared against the latest commit that touched the recorded upstream path. Only skills a bare `upskill update` would actually change are listed. Skills with no record are omitted with a skipped count — they are not printed as current. Exit 0 whether or not anything is stale; a skill whose check itself failed still exits 1. Use `upskill update --dry-run` when you want the per-file `unchanged` / `updated` / `added` / `removed` / `kept-local` breakdown.\n\nReport what would change and let the user decide. To apply:\n\n```bash\nupskill update # every skill with provenance\nupskill update <skill> # just one\n```\n\nNotes worth knowing:\n\n- **Dotfiles are never touched.** `upskill` will not modify or delete a dotfile in a skill directory, so credentials (`scripts/.config`) and the `.upskill` record survive updates and `--force` reinstalls. Never hand-copy a credential file "to be safe" — it is already safe, and moving it can break the skill.\n- **`kept-local` is not a failure.** It marks dotfiles and files the user added themselves; leaving them is the correct outcome.\n- A skill installed before provenance tracking reports `no install provenance`. If the user knows where it came from, record it in place — `upskill update <skill> --from <owner>/<repo> --dry-run` first, then without `--dry-run`. That first update never deletes anything, because nothing is attributable to a previous install yet.\n- **The sweep tells you what it did not check.** Skills with no `.upskill` record are listed under `Skipped <n> skills with no install provenance` and the closing line is scoped to the ones it checked (`All 13 skills with provenance are current.`). That is not a failure and the exit code stays 0: the runtime-bundled skills legitimately have no record and `upgrade apply` keeps those current. Pass the rest on to the user — one `--from` per skill is all it takes for the sweep to cover them from then on. Do not read an unqualified `All skills are current.` into a run that printed a skipped list.\n\n## Do not\n\n- Do not call `lick_confirm` or `lick_dismiss` while `list_scoops` shows a scoop `processing`. In-flight work can drop to `ready` with no notification; wait until scoops are idle, or expect to re-feed them.\n- Do not run `upgrade apply` before the user confirms. Confirmation runs it automatically; dismissal runs nothing.\n- Do not delete files that no longer exist in the new release — many users name-collide their own scripts with bundled ones; deletion is too dangerous to automate.\n- Do not modify files outside `/workspace/skills/`, `/shared/sprinkles/`, `/shared/sounds/`, and `/etc/` without the user explicitly extending the scope.\n- Do not run `upskill update` (without `--dry-run`) unless the user asks for it — `upskill list --outdated` (or `upskill update --dry-run`) is the safe default when you are volunteering the check.\n- Do not advance the bundled version marker yourself. The runtime advances it automatically once this lick has been routed; if the user dismisses, the lick will not fire again until the next upgrade.\n';export{e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e="---\nname: skill-authoring\ndescription: |\n Use this when the user wants to write a new skill, edit an existing one, or\n understand SLICC's skill system. Covers SKILL.md frontmatter (name,\n description, allowed-tools), how to write a description that triggers\n reliably, native `/workspace/skills/` vs compatibility `.agents/` /\n `.claude/skills/` discovery, and when to ship companion files like `.jsh`\n scripts or `.bsh` browser hooks.\nallowed-tools: bash, read_file, write_file, edit\n---\n\n# Skill authoring\n\nA skill is a folder with a `SKILL.md` (and optional companion files) that loads into the agent's system prompt when the description matches the user's intent. This skill is about authoring those folders well.\n\n## Discovery\n\nSLICC discovers five kinds of skill roots:\n\n| Root | Source | Mutability |\n| ------------------------------------------------------------ | -------------------------------------------- | ----------------------------------- |\n| `/workspace/skills/<name>/SKILL.md` | Bundled or installed via `upskill` | Install-managed; you can edit them |\n| `.agents/skills/<name>/SKILL.md` (anywhere) | Compatibility (Cursor / SuperClaude) | Read-only (discovered, not managed) |\n| `.claude/skills/<name>/SKILL.md` (anywhere) | Compatibility (Claude Code) | Read-only (discovered, not managed) |\n| `<mount>/.claude-plugin/marketplace.json` → plugin `skills/` | Claude Code marketplace (mounted repos) | Read-only (discovered, not managed) |\n| `<plugin-root>/skills/<name>/SKILL.md` | Agent Plugins installed via `plugin install` | Read-only (discovered, not managed) |\n\nSkills under `/workspace/skills/` installed with `upskill` carry a `.upskill` provenance record (source, ref, commit, file list) that `upskill list --outdated` consults and `upskill update [--dry-run]` uses to refresh them. `upskill` never modifies or deletes a **dotfile** in a skill directory, so that is where a skill should keep its credentials and local state (`scripts/.config`) — everything else is replaced on update.\n\nThe marketplace root is auto-discovered: when a mounted directory contains `.claude-plugin/marketplace.json`, SLICC reads the manifest, resolves each plugin's `source` path, and discovers skills at `<plugin-source>/skills/<name>/SKILL.md`. No install step needed — mount the repo and the skills are live immediately. Agent Plugins (agent-plugins.org packages with a `plugin.json` manifest) require an explicit `plugin install <path|repo>` — `<repo>` may be a local directory or a GitHub reference (`owner/repo`, `owner/repo@branch`, or a `https://github.com/owner/repo[/tree/branch[/dir]]` URL, downloaded into `/workspace/.plugins/sources/`); their skills then surface automatically. Precedence: native > agents > claude > marketplace > plugin.\n\nWhen you create a new skill **for SLICC**, put it in `/workspace/skills/<name>/`. The `.agents/`, `.claude/`, and marketplace paths exist so SLICC can pick up skills authored for other agents without modification — don't create new skills there.\n\n## SKILL.md structure\n\n```markdown\n---\nname: <slug>\ndescription: |\n Use this when ...\n ... (1–3 sentences explaining trigger conditions, what's covered, and what's\n NOT covered if there's a sibling skill that handles related topics.)\nallowed-tools: bash, read_file, write_file, edit\n---\n\n# Title (matches `name`)\n\n... body ...\n```\n\n### Frontmatter fields\n\n- **`name`** — lowercase, kebab-case. Must match the folder name. This is what `skill list` shows.\n- **`description`** — the trigger string. The agent uses this to decide whether to load the skill. Get this right; everything else is secondary.\n- **`allowed-tools`** — comma-separated list of tools the skill needs. Without this, the agent may load the skill but find it can't execute the steps. Common values:\n - `bash` — almost every skill.\n - `read_file, write_file, edit` — for skills that author files (sprinkles, config edits, three-way merges).\n - Omit only for purely informational skills.\n\n### Writing a good description\n\nThe description is a trigger, not a summary. It runs through the agent at every turn — too vague and the skill loads when irrelevant; too narrow and it doesn't load when needed.\n\n**Pattern that works**: \"Use this when \\<user-facing trigger\\>. Covers \\<topics\\>. \\[For \\<adjacent topic\\> use \\<sibling skill\\>.\\]\"\n\nCompare:\n\n- ❌ `description: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding`\n Keyword soup. The agent has to guess what \"licks\" or \"screencapture\" mean for this user.\n- ✅ `description: Use this when setting up event-driven automation in SLICC — webhooks, cron tasks, or filesystem watchers that route events to scoops. Covers webhook, crontask, and fswatch. Read this BEFORE wiring anything that should fire on a schedule, an HTTP call, or a VFS change.`\n Names the user intent (\"setting up event-driven automation\"), names the commands the agent will reach for, and tells the agent when to load it.\n\nRules of thumb:\n\n- Lead with **\"Use this when...\"** or **\"Use this whenever...\"**.\n- Name the **user-facing trigger** (what the user said), not just the implementation.\n- If there's a closely-named sibling skill (dips vs sprinkles, mount vs other storage), say which is which inside the description so the agent doesn't load both.\n- Multi-line YAML scalars are fine for longer descriptions — use the `|` block style.\n\n## Body conventions\n\n- Lead with one sentence stating what the skill is. No preamble.\n- Use tables for option matrices (commands × flags, tradeoffs, etc.).\n- Code blocks are bash unless otherwise needed.\n- Include a \"Don't\" or \"Common errors\" section near the end if the skill is failure-prone — the agent will read it before acting.\n- If the skill is large (> ~150 lines), split a reference table or example gallery into a companion `<topic>.md` and have the SKILL.md `read_file` it on demand. The `sprinkles/` skill (style-guide.md) and `dips/` skill (patterns.md) follow this pattern.\n\n## Companion files\n\n### `.jsh` — JavaScript shell scripts\n\n`.jsh` files on the shell's `$PATH` search roots are auto-discovered as shell commands. **Full reference: `./jsh-runtime-extensions.md`.**\n\n- **Auto-discovery**: registered as callable commands by filename (without the extension), from the `$PATH` roots — `/workspace/skills`, `/workspace/.mcp/aliases`, `/workspace/bin`, `/shared/bin` by default. A skill can ship its own commands by including a `.jsh` next to `SKILL.md`. Earlier roots win basename collisions, so `/workspace/skills/` wins. For commands elsewhere, add their dir to the PATH: `echo 'export PATH=\"$PATH:/my/tools\"' >> ~/.profile`.\n- **Direct execution**: run any script by path with `jsh /tmp/tool.jsh [args…]`. `jsh` is an alias for the Node shim, including `sliccy:` module resolution and argument passthrough; `process.argv[0]` remains `node` for Node compatibility.\n- **Dual-mode**: works in both the CLI server and the Chrome extension (sandbox iframe). Don't rely on CLI-only Node modules.\n- **Top-level `await`**: scripts are wrapped in `AsyncFunction`, so `await` at the top level works. Prefer it — errors surface instead of becoming unhandled rejections. Fire-and-forget `.then()`, unawaited `main()`, `setTimeout`, and `await fetch(…).json()` / `.text()` also keep the realm alive: like Node, the process stays up while I/O (fs/exec/fetch, including reading the response body) or timers are outstanding, and `process.exit()` skips the rest. A Promise with no handle (`new Promise(() => {})`) does **not** keep it alive. `node --check` / `-c` syntax-checks without executing (top-level `await` and ESM `import`/`export` are valid — the same entry transpile `node file.mjs` uses). `node --input-type=module` treats `-e` / stdin / `.js` as ESM.\n\n#### Runtime surface (use these — don't reinvent)\n\nNode-standard bare globals:\n\n| Global | Use for |\n| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `process` | `argv`, `env`, `cwd()`, `exit(code)`, `exitCode` (deferred status; honoured after the event-loop drain), `stdout.write`, `stderr.write`; `stdin` is one-shot buffered (no streaming) — `read()`, events, or async iterator, drain once |\n| `console` | `log`/`info`/`debug`/`dirxml`/`table`/`dir` → stdout; `warn`/`error`/`assert`/`trace` → stderr (`assert` does not throw); `group*` indent; `time*`/`count*` labeled; `clear` no-op |\n| `fetch` | Standard `fetch` routed through SLICC's proxied transport (cookies + CORS handled). |\n| `require(p)` | Synchronous CJS `require`. Use `require('sliccy:<name>')` for capability bridges and `require('fs')` for the VFS bridge (see below). |\n| `__dirname` / `__filename` | CJS scope vars — the script's own directory and absolute path. |\n\nCapability bridges via `require('sliccy:<name>')` (full reference: `./jsh-runtime-extensions.md`):\n\n| `require('sliccy:<name>')` | Use for |\n| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `sliccy:exec` | Callable `exec(cmd)` + `.spawn(argv[])`. Composes with any supplemental command or `.jsh` script. |\n| `sliccy:agent` | Callable `agent(prompt, opts?)` → sub-scoop final text (parsed when `schema` set) + `.spawn(...)` → `{ finalText, exitCode, stderr }`. `opts`: `model`, `thinking`, `cwd`, `allowedCommands`, `readOnly`, `schema`. |\n| `sliccy:skill` | `dir` / `root` / `refs` / `assets` / `config()` / `token(providerId)` — skill-root `references/` and `assets/`, script-dir `.config`, provider tokens. |\n| `sliccy:http` | `http.client({ baseUrl, token, headers, retry, timeoutMs })` — standard API-client builder. |\n| `sliccy:browser` | `findTab`, `ensureTab`, `eval`, `evalAsync`, `cookie`, `localStorage`, `fetch`, `websocket.on(...)`. |\n| `sliccy:usb` / `sliccy:serial` / `sliccy:hid` | `list()` / `request()` + device methods. Chromium-only. |\n| `sliccy:cli` | `die(msg, opts?)`, `out(value)`, `warn(msg, opts?)`, `help(text)`. |\n| `sliccy:color` | ANSI helpers (`green`, `red`, `bold`, `dim`, …) auto-disabled on non-TTY / `NO_COLOR`. |\n| `sliccy:time` | `parseDuration`, `ago`, `range`, `future`, `gmailDate`. |\n| `sliccy:fmt` | `trunc`, `col`, `table`, `date`. |\n| `sliccy:pool` | `pool(n, items, fn)` — bounded concurrency runner. |\n\nVFS bridge:\n\n| `require('fs')` / `require('node:fs')` | `readFile`, `writeFile`, `readFileBinary`, `writeFileBinary`, `readDir`, `exists`, `stat`, `mkdir`, `rm`, `fetchToFile` — all paths are VFS, async. There is no bare `fs` global. |\n| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n\n#### Runtime extensions (live — prefer these over hand-rolled equivalents)\n\nReach these via `require('sliccy:<name>')`. Full reference: `./jsh-runtime-extensions.md`. Use them instead of reimplementing the cross-skill patterns they replace.\n\n- **`process.argv.parseFlags()`** — returns `{ positional, flags, subcommand }`. Replaces the per-skill `--flag=val` / `--flag val` parsing loop.\n- **`require('sliccy:browser')`** — `findTab({ domain | urlMatch })`, `ensureTab(url)`, `eval(tab, fn)`, `evalAsync(tab, fn)`, `cookie(tab, name)`, `localStorage(tab, key)`. Replaces shelling out to `playwright-cli tab-list` and regex-parsing its output.\n- **`browser.fetch(tab, url, opts)`** — page-context fetch (runs inside the tab's origin, so cookies + same-origin headers are automatic). Replaces the `eval-file` temp-file + double-JSON-unwrap dance.\n- **`browser.websocket.on(tab, …).filter({…}).forward({ sink })`** — declarative WebSocket observer with a closed sink set (`webhook` / `scoop` / `vfs` / `log`). **Required** for any new WS-watch use case; do not author page-context `WebSocket.prototype` patches in skill code.\n- **`require('sliccy:http').client({ baseUrl, token, headers, retry })`** — `get`/`post`/`put`/`delete` with merged headers, lazy token resolution, and Retry-After-aware backoff for `retry.on` statuses.\n- **`require('sliccy:skill')`** — `dir` / `root` / `refs` / `assets` / `config()` / `token(providerId)`: replace the per-skill `process.argv[1]` dirname math, ad-hoc `.config` JSON readers, and bespoke `oauth-token` shell-outs. `refs`/`assets` resolve from the skill root (parent of the `scripts/` path segment, including nested helpers).\n\nShip a `.jsh` when the skill needs deterministic, parameterizable behavior the agent shouldn't have to re-derive each time (e.g. a `slicc-handoff` helper, a custom diff formatter, a domain-specific lint).\n\n### `.bsh` — browser shell scripts\n\n`.bsh` files auto-execute when the browser navigates to a matching URL:\n\n- **Filename = hostname pattern**: `-.okta.com.bsh` matches `*.okta.com`.\n- **`// @match` directive**: restrict to specific URL patterns in the first 10 lines.\n- Same execution engine as `.jsh`.\n\nUse `.bsh` for site-specific automations — auto-fillers, lick-emitters, or page transforms that should run whenever the user lands on a particular host.\n\n## Filesystem at a glance\n\nThe VFS is stored in IndexedDB; it survives tab closes and refreshes. The `mount` shell command bridges remote storage (local folders, S3-compatible, Adobe DA) into VFS paths — see `/workspace/skills/mount/SKILL.md`.\n\nThe VFS supports symbolic links transparently:\n\n```bash\nln -s /workspace/skills /workspace/skill-link # Create symlink\nreadlink /workspace/skill-link # Read link target\nls -la /workspace/ # Shows symlinks with -> target\n```\n\n`cat`, `read_file`, `write_file` etc. follow symlinks automatically.\n\n**Mount points must be empty.** Mounting over existing files is blocked so built-in skills and scripts stay discoverable. `ln -s` mounted files into the place where you need them.\n\n## Don't\n\n- Don't ship a skill without a description that starts with \"Use this when...\" — the trigger field IS the skill from the agent's perspective.\n- Don't put `name:` in Title Case. Lowercase kebab-case. Match the folder.\n- Don't dump shell-command catalogs into a SKILL.md just because they're related — `commands` already lists them. Skills are for **patterns and policy**, not reference material.\n- Don't author skills under `.agents/skills/` or `.claude/skills/`. Those roots are for compatibility discovery from other agents.\n";export{e as default};
|
|
1
|
+
var e="---\nname: skill-authoring\ndescription: |\n Use this when the user wants to write a new skill, edit an existing one, or\n understand SLICC's skill system. Covers SKILL.md frontmatter (name,\n description, allowed-tools), how to write a description that triggers\n reliably, native `/workspace/skills/` vs compatibility `.agents/` /\n `.claude/skills/` discovery, and when to ship companion files like `.jsh`\n scripts or `.bsh` browser hooks.\nallowed-tools: bash, read_file, write_file, edit\n---\n\n# Skill authoring\n\nA skill is a folder with a `SKILL.md` (and optional companion files) that loads into the agent's system prompt when the description matches the user's intent. This skill is about authoring those folders well.\n\n## Discovery\n\nSLICC discovers five kinds of skill roots:\n\n| Root | Source | Mutability |\n| ------------------------------------------------------------ | -------------------------------------------- | ----------------------------------- |\n| `/workspace/skills/<name>/SKILL.md` | Bundled or installed via `upskill` | Install-managed; you can edit them |\n| `.agents/skills/<name>/SKILL.md` (anywhere) | Compatibility (Cursor / SuperClaude) | Read-only (discovered, not managed) |\n| `.claude/skills/<name>/SKILL.md` (anywhere) | Compatibility (Claude Code) | Read-only (discovered, not managed) |\n| `<mount>/.claude-plugin/marketplace.json` → plugin `skills/` | Claude Code marketplace (mounted repos) | Read-only (discovered, not managed) |\n| `<plugin-root>/skills/<name>/SKILL.md` | Agent Plugins installed via `plugin install` | Read-only (discovered, not managed) |\n\nSkills under `/workspace/skills/` installed with `upskill` carry a `.upskill` provenance record (source, ref, commit, file list) that `upskill list --outdated` consults and `upskill update [--dry-run]` uses to refresh them. `upskill` never modifies or deletes a **dotfile** in a skill directory, so that is where a skill should keep its credentials and local state (`scripts/.config`) — everything else is replaced on update.\n\nThe marketplace root is auto-discovered: when a mounted directory contains `.claude-plugin/marketplace.json`, SLICC reads the manifest, resolves each plugin's `source` path, and discovers skills at `<plugin-source>/skills/<name>/SKILL.md`. No install step needed — mount the repo and the skills are live immediately. Agent Plugins (agent-plugins.org packages with a `plugin.json` manifest) require an explicit `plugin install <path|repo>` — `<repo>` may be a local directory or a GitHub reference (`owner/repo`, `owner/repo@branch`, or a `https://github.com/owner/repo[/tree/branch[/dir]]` URL, downloaded into `/workspace/.plugins/sources/`); their skills then surface automatically. Precedence: native > agents > claude > marketplace > plugin.\n\nWhen you create a new skill **for SLICC**, put it in `/workspace/skills/<name>/`. The `.agents/`, `.claude/`, and marketplace paths exist so SLICC can pick up skills authored for other agents without modification — don't create new skills there.\n\n## SKILL.md structure\n\n```markdown\n---\nname: <slug>\ndescription: |\n Use this when ...\n ... (1–3 sentences explaining trigger conditions, what's covered, and what's\n NOT covered if there's a sibling skill that handles related topics.)\nallowed-tools: bash, read_file, write_file, edit\n---\n\n# Title (matches `name`)\n\n... body ...\n```\n\n### Frontmatter fields\n\n- **`name`** — lowercase, kebab-case. Must match the folder name. This is what `skill list` shows.\n- **`description`** — the trigger string. The agent uses this to decide whether to load the skill. Get this right; everything else is secondary.\n- **`allowed-tools`** — comma-separated list of tools the skill needs. Without this, the agent may load the skill but find it can't execute the steps. Common values:\n - `bash` — almost every skill.\n - `read_file, write_file, edit` — for skills that author files (sprinkles, config edits, three-way merges).\n - Omit only for purely informational skills.\n\n### Writing a good description\n\nThe description is a trigger, not a summary. It runs through the agent at every turn — too vague and the skill loads when irrelevant; too narrow and it doesn't load when needed.\n\n**Pattern that works**: \"Use this when \\<user-facing trigger\\>. Covers \\<topics\\>. \\[For \\<adjacent topic\\> use \\<sibling skill\\>.\\]\"\n\nCompare:\n\n- ❌ `description: Licks, webhooks, cron tasks, viewing pages/images, screencapture, onboarding`\n Keyword soup. The agent has to guess what \"licks\" or \"screencapture\" mean for this user.\n- ✅ `description: Use this when setting up event-driven automation in SLICC — webhooks, cron tasks, or filesystem watchers that route events to scoops. Covers webhook, crontask, and fswatch. Read this BEFORE wiring anything that should fire on a schedule, an HTTP call, or a VFS change.`\n Names the user intent (\"setting up event-driven automation\"), names the commands the agent will reach for, and tells the agent when to load it.\n\nRules of thumb:\n\n- Lead with **\"Use this when...\"** or **\"Use this whenever...\"**.\n- Name the **user-facing trigger** (what the user said), not just the implementation.\n- If there's a closely-named sibling skill (dips vs sprinkles, mount vs other storage), say which is which inside the description so the agent doesn't load both.\n- Multi-line YAML scalars are fine for longer descriptions — use the `|` block style.\n\n## Body conventions\n\n- Lead with one sentence stating what the skill is. No preamble.\n- Use tables for option matrices (commands × flags, tradeoffs, etc.).\n- Code blocks are bash unless otherwise needed.\n- Include a \"Don't\" or \"Common errors\" section near the end if the skill is failure-prone — the agent will read it before acting.\n- If the skill is large (> ~150 lines), split a reference table or example gallery into a companion `<topic>.md` and have the SKILL.md `read_file` it on demand. The `sprinkles/` skill (style-guide.md) and `dips/` skill (patterns.md) follow this pattern.\n\n## Companion files\n\n### `.jsh` — JavaScript shell scripts\n\n`.jsh` files on the shell's `$PATH` search roots are auto-discovered as shell commands. **Full reference: `./jsh-runtime-extensions.md`.**\n\n- **Auto-discovery**: registered as callable commands by filename (without the extension), from the `$PATH` roots — `/workspace/skills`, `/workspace/.mcp/aliases`, `/workspace/bin`, `/shared/bin` by default. A skill can ship its own commands by including a `.jsh` next to `SKILL.md`. Earlier roots win basename collisions, so `/workspace/skills/` wins. For commands elsewhere, add their dir to the PATH: `echo 'export PATH=\"$PATH:/my/tools\"' >> ~/.profile`.\n- **Direct execution**: run any script by path with `jsh /tmp/tool.jsh [args…]`. `jsh` is an alias for the Node shim, including `sliccy:` module resolution and argument passthrough; `process.argv[0]` remains `node` for Node compatibility.\n- **Dual-mode**: works in both the CLI server and the Chrome extension (sandbox iframe). Don't rely on CLI-only Node modules.\n- **Top-level `await`**: scripts are wrapped in `AsyncFunction`, so `await` at the top level works. Prefer it — errors surface instead of becoming unhandled rejections. Fire-and-forget `.then()`, unawaited `main()`, `setTimeout`, and `await fetch(…).json()` / `.text()` also keep the realm alive: like Node, the process stays up while I/O (fs/exec/fetch, including reading the response body) or timers are outstanding, and `process.exit()` skips the rest. A Promise with no handle (`new Promise(() => {})`) does **not** keep it alive. `node --check` / `-c` syntax-checks without executing (top-level `await` and ESM `import`/`export` are valid — the same entry transpile `node file.mjs` uses). `node --input-type=module` treats `-e` / stdin / `.js` as ESM.\n\n#### Runtime surface (use these — don't reinvent)\n\nNode-standard bare globals:\n\n| Global | Use for |\n| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `process` | `argv`, `env`, `cwd()`, `exit(code)`, `exitCode` (deferred status; honoured after the event-loop drain), `stdout.write`, `stderr.write`; `stdin` is one-shot buffered (no streaming) — `read()`, events, or async iterator, drain once |\n| `console` | `log`/`info`/`debug`/`dirxml`/`table`/`dir` → stdout; `warn`/`error`/`assert`/`trace` → stderr (`assert` does not throw); `group*` indent; `time*`/`count*` labeled; `clear` no-op |\n| `fetch` | Standard `fetch` routed through SLICC's proxied transport (cookies + CORS handled). |\n| `require(p)` | Synchronous CJS `require`. Use `require('sliccy:<name>')` for capability bridges and `require('fs')` for the VFS bridge (see below). |\n| `__dirname` / `__filename` | CJS scope vars — the script's own directory and absolute path. |\n\nCapability bridges via `require('sliccy:<name>')` (full reference: `./jsh-runtime-extensions.md`):\n\n| `require('sliccy:<name>')` | Use for |\n| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `sliccy:exec` | Callable `exec(cmd)` + `.spawn(argv[])`. Composes with any supplemental command or `.jsh` script. |\n| `sliccy:agent` | Callable `agent(prompt, opts?)` → sub-scoop final text (parsed when `schema` set) + `.spawn(...)` → `{ finalText, exitCode, stderr }`. `opts`: `model`, `thinking`, `cwd`, `allowedCommands`, `readOnly`, `schema`. |\n| `sliccy:skill` | `dir` / `root` / `refs` / `assets` / `config()` / `token(providerId)` — skill-root `references/` and `assets/`, script-dir `.config`, provider tokens. |\n| `sliccy:http` | `http.client({ baseUrl, token, headers, retry, timeoutMs })` — standard API-client builder. |\n| `sliccy:browser` | `findTab`, `ensureTab`, `eval`, `evalAsync`, `cookie`, `localStorage`, `fetch`, `websocket.on(...)`. |\n| `sliccy:usb` / `sliccy:serial` / `sliccy:hid` | `list()` / `request()` + device methods. Chromium-only. |\n| `sliccy:cli` | `die(msg, opts?)`, `out(value)`, `warn(msg, opts?)`, `help(text)`. |\n| `sliccy:color` | ANSI helpers (`green`, `red`, `bold`, `dim`, …) auto-disabled on non-TTY / `NO_COLOR`. |\n| `sliccy:time` | `parseDuration`, `ago`, `range`, `future`, `gmailDate`. |\n| `sliccy:fmt` | `trunc`, `col`, `table`, `date`. |\n| `sliccy:pool` | `pool(n, items, fn)` — bounded concurrency runner. |\n\nVFS bridge:\n\n| `require('fs')` / `require('node:fs')` | `readFile`, `writeFile`, `readFileBinary`, `writeFileBinary`, `appendFile`, `readDir`, `exists`, `stat`, `mkdir`, `rm`, `fetchToFile` — all paths are VFS, async. There is no bare `fs` global. |\n| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n\n#### Runtime extensions (live — prefer these over hand-rolled equivalents)\n\nReach these via `require('sliccy:<name>')`. Full reference: `./jsh-runtime-extensions.md`. Use them instead of reimplementing the cross-skill patterns they replace.\n\n- **`process.argv.parseFlags()`** — returns `{ positional, flags, subcommand }`. Replaces the per-skill `--flag=val` / `--flag val` parsing loop.\n- **`require('sliccy:browser')`** — `findTab({ domain | urlMatch })`, `ensureTab(url)`, `eval(tab, fn)`, `evalAsync(tab, fn)`, `cookie(tab, name)`, `localStorage(tab, key)`. Replaces shelling out to `playwright-cli tab-list` and regex-parsing its output.\n- **`browser.fetch(tab, url, opts)`** — page-context fetch (runs inside the tab's origin, so cookies + same-origin headers are automatic). Replaces the `eval-file` temp-file + double-JSON-unwrap dance.\n- **`browser.websocket.on(tab, …).filter({…}).forward({ sink })`** — declarative WebSocket observer with a closed sink set (`webhook` / `scoop` / `vfs` / `log`). **Required** for any new WS-watch use case; do not author page-context `WebSocket.prototype` patches in skill code.\n- **`require('sliccy:http').client({ baseUrl, token, headers, retry })`** — `get`/`post`/`put`/`delete` with merged headers, lazy token resolution, and Retry-After-aware backoff for `retry.on` statuses.\n- **`require('sliccy:skill')`** — `dir` / `root` / `refs` / `assets` / `config()` / `token(providerId)`: replace the per-skill `process.argv[1]` dirname math, ad-hoc `.config` JSON readers, and bespoke `oauth-token` shell-outs. `refs`/`assets` resolve from the skill root (parent of the `scripts/` path segment, including nested helpers).\n\nShip a `.jsh` when the skill needs deterministic, parameterizable behavior the agent shouldn't have to re-derive each time (e.g. a `slicc-handoff` helper, a custom diff formatter, a domain-specific lint).\n\n### `.bsh` — browser shell scripts\n\n`.bsh` files auto-execute when the browser navigates to a matching URL:\n\n- **Filename = hostname pattern**: `-.okta.com.bsh` matches `*.okta.com`.\n- **`// @match` directive**: restrict to specific URL patterns in the first 10 lines.\n- Same execution engine as `.jsh`.\n\nUse `.bsh` for site-specific automations — auto-fillers, lick-emitters, or page transforms that should run whenever the user lands on a particular host.\n\n## Filesystem at a glance\n\nThe VFS is stored in IndexedDB; it survives tab closes and refreshes. The `mount` shell command bridges remote storage (local folders, S3-compatible, Adobe DA) into VFS paths — see `/workspace/skills/mount/SKILL.md`.\n\nThe VFS supports symbolic links transparently:\n\n```bash\nln -s /workspace/skills /workspace/skill-link # Create symlink\nreadlink /workspace/skill-link # Read link target\nls -la /workspace/ # Shows symlinks with -> target\n```\n\n`cat`, `read_file`, `write_file` etc. follow symlinks automatically.\n\n**Mount points must be empty.** Mounting over existing files is blocked so built-in skills and scripts stay discoverable. `ln -s` mounted files into the place where you need them.\n\n## Don't\n\n- Don't ship a skill without a description that starts with \"Use this when...\" — the trigger field IS the skill from the agent's perspective.\n- Don't put `name:` in Title Case. Lowercase kebab-case. Match the folder.\n- Don't dump shell-command catalogs into a SKILL.md just because they're related — `commands` already lists them. Skills are for **patterns and policy**, not reference material.\n- Don't author skills under `.agents/skills/` or `.claude/skills/`. Those roots are for compatibility discovery from other agents.\n";export{e as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var e="---\nname: memory\ndescription: |\n Use this when the user asks what SLICC remembers, why a remembered fact is\n missing or stale, whether memory curation ran, to re-run curation for an\n archived session, or to consolidate a bloated memory file. Covers the\n `memory` shell command (`show`, `status`, `log`, `curate`, `dream`), the\n per-cone memory files, and the curation ledger in /sessions/index.json.\n Requires the memory-v2 feature flag for everything except `memory status`.\nallowed-tools: bash\n---\n\n# memory — inspect and manage durable cone memory\n\nDurable memory is one markdown file per cone — `/workspace/CLAUDE.md` for the primary cone, `/cones/<folder>/CLAUDE.md` for extra cones. After a chat freezes, a memory-curator scoop rewrites that file from the archived session; `/sessions/index.json` is the per-archive ledger of whether that pass succeeded (`memoryCuratedAt`), failed (`memoryFailed`), is still owed (`memoryPending`), or was skipped by the user (`memorySkipped`).\n\n## Usage\n\n```bash\nmemory show [--cone <folder>] # the cone's memory file, verbatim\nmemory status [--json] [--check] # files, budget, curation tally, health\nmemory log [--limit N] # per-archive ledger, newest first\nmemory curate [--archive <file>] [--cone <folder>] # run a curator pass now\nmemory dream [--cone <folder>] [--all] [--wait] # consolidate memory (dreamer pass)\n```\n\n## When to reach for it\n\n- \"What do you remember about me / this project?\" → `memory show`.\n- A fact you expected to be remembered is missing → `memory log` to see whether the session that established it was ever curated; `memory status --check` for systemic failures.\n- After a failed curation (`memoryFailed` in the log) → fix the cause if visible (usually a missing provider or a timeout), then `memory curate --archive <that-file>`.\n- The memory file has grown duplicated, contradictory, or over budget → `memory dream` (add `--wait` to see the dreamer's report; `--all` for every cone with a memory file). The gelatiere's nightly already runs `memory dream --all`, so reach for this manually only when it cannot wait.\n- Extra cones keep separate memory: pass `--cone <folder>` to `show`, `curate`, and `dream`. The folder must exist (`cone`, or a `/cones/<folder>`); `curate` without it targets the cone the archive was frozen from.\n\n## Reading `memory status`\n\n- **Budget** grows logarithmically with the archived-session count; the curator is told to stay under it.\n- **Curation tally** counts index entries by ledger state: curated / failed / pending / skipped / unmarked (pre-ledger or freshly frozen).\n- **`--check`** exits non-zero on the two lying-memory shapes: any archive whose last curation attempt failed, or archives reporting success while the primary memory file is missing or empty. A clean run exits 0.\n- **`Scheduled:`** shows the runtime's own health check — the kernel runs the same checks ~90s after boot and daily without being asked, persisting the numbers to `/sessions/.curation/health.json`. If that line says `never ran` long after boot, or names failures, the memory system needs attention even if nobody asked about it.\n\n## Notes\n\n- `memory curate` runs the exact pass the session freezer runs (snapshot → curator scoop → three-way merge), so concurrent edits to the memory file merge instead of being clobbered. It can take several minutes; the curator's closing report is printed when it lands.\n- `memory dream` reads no session archive — the dreamer consolidates the memory file itself under `/
|
|
1
|
+
var e="---\nname: memory\ndescription: |\n Use this when the user asks what SLICC remembers, why a remembered fact is\n missing or stale, whether memory curation ran, to re-run curation for an\n archived session, or to consolidate a bloated memory file. Covers the\n `memory` shell command (`show`, `status`, `log`, `curate`, `dream`), the\n per-cone memory files, and the curation ledger in /sessions/index.json.\n Requires the memory-v2 feature flag for everything except `memory status`.\nallowed-tools: bash\n---\n\n# memory — inspect and manage durable cone memory\n\nDurable memory is one markdown file per cone — `/workspace/CLAUDE.md` for the primary cone, `/cones/<folder>/CLAUDE.md` for extra cones. Agents write these files only through the `memory_write` tool, which enforces the budget (over budget, a write must shrink the file) and reports the remaining room; other writers are refused. After a chat freezes, a memory-curator scoop rewrites that file from the archived session; `/sessions/index.json` is the per-archive ledger of whether that pass succeeded (`memoryCuratedAt`), failed (`memoryFailed`), is still owed (`memoryPending`), or was skipped by the user (`memorySkipped`).\n\n## Usage\n\n```bash\nmemory show [--cone <folder>] # the cone's memory file, verbatim\nmemory status [--json] [--check] # files, budget, curation tally, health\nmemory log [--limit N] # per-archive ledger, newest first\nmemory curate [--archive <file>] [--cone <folder>] # run a curator pass now\nmemory dream [--cone <folder>] [--all] [--wait] # consolidate memory (dreamer pass)\n```\n\n## When to reach for it\n\n- \"What do you remember about me / this project?\" → `memory show`.\n- A fact you expected to be remembered is missing → `memory log` to see whether the session that established it was ever curated; `memory status --check` for systemic failures.\n- After a failed curation (`memoryFailed` in the log) → fix the cause if visible (usually a missing provider or a timeout), then `memory curate --archive <that-file>`.\n- The memory file has grown duplicated, contradictory, or over budget → `memory dream` (add `--wait` to see the dreamer's report; `--all` for every cone with a memory file). The gelatiere's nightly already runs `memory dream --all`, so reach for this manually only when it cannot wait.\n- Extra cones keep separate memory: pass `--cone <folder>` to `show`, `curate`, and `dream`. The folder must exist (`cone`, or a `/cones/<folder>`); `curate` without it targets the cone the archive was frozen from.\n\n## Reading `memory status`\n\n- **Budget** grows logarithmically with the archived-session count; the curator is told to stay under it.\n- **Curation tally** counts index entries by ledger state: curated / failed / pending / skipped / unmarked (pre-ledger or freshly frozen).\n- **`--check`** exits non-zero on the two lying-memory shapes: any archive whose last curation attempt failed, or archives reporting success while the primary memory file is missing or empty. A clean run exits 0.\n- **`Scheduled:`** shows the runtime's own health check — the kernel runs the same checks ~90s after boot and daily without being asked, persisting the numbers to `/sessions/.curation/health.json`. If that line says `never ran` long after boot, or names failures, the memory system needs attention even if nobody asked about it.\n\n## Notes\n\n- `memory curate` runs the exact pass the session freezer runs (snapshot → curator scoop → three-way merge), so concurrent edits to the memory file merge instead of being clobbered. It can take several minutes; the curator's closing report is printed when it lands.\n- `memory dream` reads no session archive — the dreamer consolidates the memory file itself under the same `/etc/MEMORY.md` instructions as curation (its own `dreamTimeoutSeconds` bound), through the same staged draft and merge. Detached by default; the outcome lands in `/sessions/.curation/dream-<date>-<cone>.md/status.json`.\n- When consolidation cannot fit everything, the dreamer moves reference knowledge into the shared wiki at `/shared/wiki/` (schema: `/shared/wiki/WIKI.md`; browse it with the `wiki` skill) and leaves a pointer line in the memory file.\n- The command does not edit the ledger itself; a manual pass on a still-pending archive is reconciled by the boot catch-up through the bridge's receipt.\n- Everything except `status` requires the **Memory v2** flag (Settings → Experimental).\n";export{e as default};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/oauth-service-BsW9nY_u.js","assets/preload-helper-Czpn1I53.js","assets/proxied-fetch-DyBveeCl.js","assets/rolldown-runtime-Dd_uD5pT.js","assets/base64-DJRlyqZu.js","assets/fetch-body-1l9I58Vk.js","assets/api-endpoint-DGxXvrur.js","assets/runtime-env-Dlaokqg1.js","assets/panel-rpc-B3MSVImO.js","assets/permissions-surface-registry-CilCRwhh.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{n as e,t}from"./rolldown-runtime-Dd_uD5pT.js";import{t as n}from"./preload-helper-Czpn1I53.js";import{c as r,l as i,o as a,s as o,u as s}from"./claude-model-version-CSATLzrT.js";import"./libesm-BypnjKEL.js";import{t as c}from"./logger-DDBAeTLF.js";import{n as l}from"./base64-DJRlyqZu.js";import"./proxied-fetch-DyBveeCl.js";import{a as u,t as d}from"./api-endpoint-DGxXvrur.js";import{n as f}from"./float-topology-YtctpJaG.js";import"./secret-topology-DLJBhHOi.js";import{n as p}from"./secrets-bridge-client--VZ3E0yk.js";import"./tool-ui-eSQ1g2I1.js";import{n as m,o as h,t as g}from"./providers-rH3sC6oE.js";import{n as _,t as v}from"./panel-rpc-B3MSVImO.js";import{i as y,r as b,t as x}from"./bedrock-camp-compat-BeCSBUrZ.js";var S={assign:0,create:0,clone:0,discard:0,update:0};function ee(e){return Array.isArray(e)}function te(e){return C(e,null)}function ne(e){return C(typeof e,`object`)&&!te(e)}function C(e,t){return e===t}function re(e){if(!ne(e))return!1;let t=globalThis.Object.getPrototypeOf(e);return!te(t)&&C(typeof t.constructor,`function`)&&!(C(t.constructor,globalThis.Object)||C(t.constructor.name,`Object`))}function ie(e){return C(e,`__proto__`)||C(e,`constructor`)||C(e,`prototype`)}function ae(e,t){return ie(t)?Object.prototype.hasOwnProperty.call(e,t):t in e}function w(e){return Object.getOwnPropertyNames(e)}function oe(e){return Object.getOwnPropertySymbols(e)}function se(e){return globalThis.ArrayBuffer.isView(e)}function ce(e){return e instanceof globalThis.RegExp}function le(e){return e instanceof globalThis.Set}function ue(e){return e instanceof globalThis.Map}function de(e){return e}function fe(e){return ae(e,`~kind`)||ae(e,`~unsafe`)}function pe(e){let t={},n=Object.getOwnPropertyDescriptors(e);for(let e of Object.keys(n)){if(ie(e))continue;let r=n[e];ae(r,`value`)&&Object.defineProperty(t,e,{...r,value:T(r.value)})}return t}function me(e){let t={};for(let n of w(e))ie(n)||(t[n]=T(e[n]));for(let n of oe(e))t[n]=T(e[n]);return t}function he(e){return re(e)?de(e):fe(e)?pe(e):me(e)}function ge(e){return e.map(e=>T(e))}function _e(e){return e.slice()}function ve(e){return new RegExp(e.source,e.flags)}function ye(e){return new Map(T([...e.entries()]))}function be(e){return new Set(T([...e.values()]))}function T(e){return se(e)?_e(e):ce(e)?ve(e):ue(e)?ye(e):le(e)?be(e):ee(e)?ge(e):ne(e)?he(e):e}function xe(e){return S.clone+=1,T(e)}var Se={immutableTypes:!1,maxErrors:8,useAcceleration:!0,exactOptionalPropertyTypes:!1,enumerableKind:!1,correctiveParse:!1,unionPrioritySort:!0};function Ce(){return Se}function we(e,t){for(let n of Object.keys(t))Object.defineProperty(e,n,{configurable:!0,writable:!0,enumerable:!1,value:t[n]});return e}function Te(e,t){return{...e,...t}}function Ee(e,t,n={}){S.create+=1;let r=Ce(),i=Te(t,n),a=r.enumerableKind?Te(i,e):we(i,e);return r.immutableTypes?Object.freeze(a):a}function De(e,t,n){S.update+=1;let r=Ce(),i=xe(e);for(let e of Object.keys(t))Object.defineProperty(i,e,{configurable:!0,writable:!0,enumerable:r.enumerableKind,value:t[e]});for(let e of Object.keys(n))Object.defineProperty(i,e,{configurable:!0,enumerable:!0,writable:!0,value:n[e]});return i}function Oe(e){return ne(e)}function ke(e){return De(e,{"~optional":!0},{})}function Ae(e,t){return De(ke(e),{},t)}function je(e,t){return Ee({"~kind":`Array`},{type:`array`,items:e},t)}function Me(e,t={}){return Ae(e,t)}function Ne(e){return Me(e)}function Pe(e){return Oe(e)&&ae(e,`~optional`)}function Fe(e){return w(e).filter(t=>!Pe(e[t]))}function Ie(e,t={}){let n=Fe(e);return Ee({"~kind":`Object`},{type:`object`,...n.length>0?{required:n}:{},properties:e},t)}var Le;(function(e){e[e.Array=0]=`Array`,e[e.BigInt=1]=`BigInt`,e[e.Boolean=2]=`Boolean`,e[e.Date=3]=`Date`,e[e.Constructor=4]=`Constructor`,e[e.Function=5]=`Function`,e[e.Null=6]=`Null`,e[e.Number=7]=`Number`,e[e.Object=8]=`Object`,e[e.RegExp=9]=`RegExp`,e[e.String=10]=`String`,e[e.Symbol=11]=`Symbol`,e[e.TypeArray=12]=`TypeArray`,e[e.Undefined=13]=`Undefined`})(Le||={}),Array.from({length:256}).map((e,t)=>BigInt(t));var Re=new Float64Array(1);new DataView(Re.buffer),new Uint8Array(Re.buffer),new TextEncoder;var ze=`-?(?:0|[1-9][0-9]*)`,Be=`-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?`;function Ve(e){return Ee({"~kind":`Number`},{type:`number`},e)}function E(e){return Ee({"~kind":`String`},{type:`string`},e)}var He=`^${ze}$`;`${Be}`;function Ue(e,t){return Array.from({length:t-e+1},(t,n)=>String.fromCharCode(e+n))}var We=[...Ue(97,122),...Ue(65,90)],Ge=[`0`,...Ue(49,57)];[...Ge],[...We,...Ge],[...Ge],new RegExp(He);function Ke(e,t){try{return Promise.resolve(t(qe))}catch(e){return Promise.reject(e)}}var qe={startSpan:Ke,addEvent:()=>{},setAttributes:()=>{},setStatus:()=>{}};Object.freeze(qe);var Je=Symbol.for(`yaml.alias`),Ye=Symbol.for(`yaml.document`),D=Symbol.for(`yaml.map`),Xe=Symbol.for(`yaml.pair`),Ze=Symbol.for(`yaml.scalar`),Qe=Symbol.for(`yaml.seq`),O=Symbol.for(`yaml.node.type`),k=e=>!!e&&typeof e==`object`&&e[O]===Je,$e=e=>!!e&&typeof e==`object`&&e[O]===Ye,et=e=>!!e&&typeof e==`object`&&e[O]===D,A=e=>!!e&&typeof e==`object`&&e[O]===Xe,j=e=>!!e&&typeof e==`object`&&e[O]===Ze,tt=e=>!!e&&typeof e==`object`&&e[O]===Qe;function M(e){if(e&&typeof e==`object`)switch(e[O]){case D:case Qe:return!0}return!1}function N(e){if(e&&typeof e==`object`)switch(e[O]){case Je:case D:case Ze:case Qe:return!0}return!1}var nt=e=>(j(e)||M(e))&&!!e.anchor,P=Symbol(`break visit`),rt=Symbol(`skip children`),it=Symbol(`remove node`);function at(e,t){let n=st(t);$e(e)?ot(null,e.contents,n,Object.freeze([e]))===it&&(e.contents=null):ot(null,e,n,Object.freeze([]))}at.BREAK=P,at.SKIP=rt,at.REMOVE=it;function ot(e,t,n,r){let i=ct(e,t,n,r);if(N(i)||A(i))return lt(e,r,i),ot(e,i,n,r);if(typeof i!=`symbol`){if(M(t)){r=Object.freeze(r.concat(t));for(let e=0;e<t.items.length;++e){let i=ot(e,t.items[e],n,r);if(typeof i==`number`)e=i-1;else if(i===P)return P;else i===it&&(t.items.splice(e,1),--e)}}else if(A(t)){r=Object.freeze(r.concat(t));let e=ot(`key`,t.key,n,r);if(e===P)return P;e===it&&(t.key=null);let i=ot(`value`,t.value,n,r);if(i===P)return P;i===it&&(t.value=null)}}return i}function st(e){return typeof e==`object`&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function ct(e,t,n,r){if(typeof n==`function`)return n(e,t,r);if(et(t))return n.Map?.(e,t,r);if(tt(t))return n.Seq?.(e,t,r);if(A(t))return n.Pair?.(e,t,r);if(j(t))return n.Scalar?.(e,t,r);if(k(t))return n.Alias?.(e,t,r)}function lt(e,t,n){let r=t[t.length-1];if(M(r))r.items[e]=n;else if(A(r))e===`key`?r.key=n:r.value=n;else if($e(r))r.contents=n;else{let e=k(r)?`alias`:`scalar`;throw Error(`Cannot replace node with ${e} parent`)}}function ut(e){if(/[\x00-\x19\s,[\]{}]/.test(e)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(e)}`;throw Error(t)}return!0}function dt(e,t,n,r){if(r&&typeof r==`object`){if(Array.isArray(r))for(let t=0,n=r.length;t<n;++t){let n=r[t],i=dt(e,r,String(t),n);i===void 0?delete r[t]:i!==n&&(r[t]=i)}else if(r instanceof Map)for(let t of Array.from(r.keys())){let n=r.get(t),i=dt(e,r,t,n);i===void 0?r.delete(t):i!==n&&r.set(t,i)}else if(r instanceof Set)for(let t of Array.from(r)){let n=dt(e,r,t,t);n===void 0?r.delete(t):n!==t&&(r.delete(t),r.add(n))}else for(let[t,n]of Object.entries(r)){let i=dt(e,r,t,n);i===void 0?delete r[t]:i!==n&&(r[t]=i)}}return e.call(t,n,r)}function F(e,t,n){if(Array.isArray(e))return e.map((e,t)=>F(e,String(t),n));if(e&&typeof e.toJSON==`function`){if(!n||!nt(e))return e.toJSON(t,n);let r={aliasCount:0,count:1,res:void 0};n.anchors.set(e,r),n.onCreate=e=>{r.res=e,delete n.onCreate};let i=e.toJSON(t,n);return n.onCreate&&n.onCreate(i),i}return typeof e==`bigint`&&!n?.keep?Number(e):e}var ft=class{constructor(e){Object.defineProperty(this,O,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:n,onAnchor:r,reviver:i}={}){if(!$e(e))throw TypeError(`A document argument is required`);let a={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof n==`number`?n:100},o=F(this,``,a);if(typeof r==`function`)for(let{count:e,res:t}of a.anchors.values())r(t,e);return typeof i==`function`?dt(i,{"":o},``,o):o}},pt=class extends ft{constructor(e){super(Je),this.source=e,Object.defineProperty(this,"tag",{set(){throw Error(`Alias nodes cannot have tags`)}})}resolve(e,t){if(t?.maxAliasCount===0)throw ReferenceError(`Alias resolution is disabled`);let n;t?.aliasResolveCache?n=t.aliasResolveCache:(n=[],at(e,{Node:(e,t)=>{(k(t)||nt(t))&&n.push(t)}}),t&&(t.aliasResolveCache=n));let r;for(let e of n){if(e===this)break;e.anchor===this.source&&(r=e)}return r}toJSON(e,t){if(!t)return{source:this.source};let{anchors:n,doc:r,maxAliasCount:i}=t,a=this.resolve(r,t);if(!a){let e=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw ReferenceError(e)}let o=n.get(a);if(o||=(F(a,null,t),n.get(a)),o?.res===void 0)throw ReferenceError(`This should not happen: Alias anchor was not resolved?`);if(i>=0&&(o.count+=1,o.aliasCount===0&&(o.aliasCount=mt(r,a,n)),o.count*o.aliasCount>i))throw ReferenceError(`Excessive alias count indicates a resource exhaustion attack`);return o.res}toString(e,t,n){let r=`*${this.source}`;if(e){if(ut(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let e=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw Error(e)}if(e.implicitKey)return`${r} `}return r}};function mt(e,t,n){if(k(t)){let r=t.resolve(e),i=n&&r&&n.get(r);return i?i.count*i.aliasCount:0}if(M(t)){let r=0;for(let i of t.items){let t=mt(e,i,n);t>r&&(r=t)}return r}if(A(t)){let r=mt(e,t.key,n),i=mt(e,t.value,n);return Math.max(r,i)}return 1}var ht=e=>!e||typeof e!=`function`&&typeof e!=`object`,I=class extends ft{constructor(e){super(Ze),this.value=e}toJSON(e,t){return t?.keep?this.value:F(this.value,e,t)}toString(){return String(this.value)}};I.BLOCK_FOLDED=`BLOCK_FOLDED`,I.BLOCK_LITERAL=`BLOCK_LITERAL`,I.PLAIN=`PLAIN`,I.QUOTE_DOUBLE=`QUOTE_DOUBLE`,I.QUOTE_SINGLE=`QUOTE_SINGLE`;var gt=`tag:yaml.org,2002:`;function _t(e,t,n){if(t){let e=n.filter(e=>e.tag===t),r=e.find(e=>!e.format)??e[0];if(!r)throw Error(`Tag ${t} not found`);return r}return n.find(t=>t.identify?.(e)&&!t.format)}function vt(e,t,n){if($e(e)&&(e=e.contents),N(e))return e;if(A(e)){let t=n.schema[D].createNode?.(n.schema,null,n);return t.items.push(e),t}(e instanceof String||e instanceof Number||e instanceof Boolean||typeof BigInt<`u`&&e instanceof BigInt)&&(e=e.valueOf());let{aliasDuplicateObjects:r,onAnchor:i,onTagObj:a,schema:o,sourceObjects:s}=n,c;if(r&&e&&typeof e==`object`){if(c=s.get(e),c)return c.anchor??(c.anchor=i(e)),new pt(c.anchor);c={anchor:null,node:null},s.set(e,c)}t?.startsWith(`!!`)&&(t=gt+t.slice(2));let l=_t(e,t,o.tags);if(!l){if(e&&typeof e.toJSON==`function`&&(e=e.toJSON()),!e||typeof e!=`object`){let t=new I(e);return c&&(c.node=t),t}l=e instanceof Map?o[D]:Symbol.iterator in Object(e)?o[Qe]:o[D]}a&&(a(l),delete n.onTagObj);let u=l?.createNode?l.createNode(n.schema,e,n):typeof l?.nodeClass?.from==`function`?l.nodeClass.from(n.schema,e,n):new I(e);return t?u.tag=t:l.default||(u.tag=l.tag),c&&(c.node=u),u}function yt(e,t,n){let r=n;for(let e=t.length-1;e>=0;--e){let n=t[e];if(typeof n==`number`&&Number.isInteger(n)&&n>=0){let e=[];e[n]=r,r=e}else r=new Map([[n,r]])}return vt(r,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw Error(`This should not happen, please report a bug.`)},schema:e,sourceObjects:new Map})}var bt=e=>e==null||typeof e==`object`&&!!e[Symbol.iterator]().next().done,xt=class extends ft{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(t=>N(t)||A(t)?t.clone(e):t),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(bt(e))this.add(t);else{let[n,...r]=e,i=this.get(n,!0);if(M(i))i.addIn(r,t);else if(i===void 0&&this.schema)this.set(n,yt(this.schema,r,t));else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`)}}deleteIn(e){let[t,...n]=e;if(n.length===0)return this.delete(t);let r=this.get(t,!0);if(M(r))return r.deleteIn(n);throw Error(`Expected YAML collection at ${t}. Remaining path: ${n}`)}getIn(e,t){let[n,...r]=e,i=this.get(n,!0);return r.length===0?!t&&j(i)?i.value:i:M(i)?i.getIn(r,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!A(t))return!1;let n=t.value;return n==null||e&&j(n)&&n.value==null&&!n.commentBefore&&!n.comment&&!n.tag})}hasIn(e){let[t,...n]=e;if(n.length===0)return this.has(t);let r=this.get(t,!0);return M(r)?r.hasIn(n):!1}setIn(e,t){let[n,...r]=e;if(r.length===0)this.set(n,t);else{let e=this.get(n,!0);if(M(e))e.setIn(r,t);else if(e===void 0&&this.schema)this.set(n,yt(this.schema,r,t));else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`)}}},St=e=>e.replace(/^(?!$)(?: $)?/gm,`#`);function Ct(e,t){return/^\n+$/.test(e)?e.substring(1):t?e.replace(/^(?! *$)/gm,t):e}var L=(e,t,n)=>e.endsWith(`
|
|
2
|
+
import{n as e,t}from"./rolldown-runtime-Dd_uD5pT.js";import{t as n}from"./preload-helper-Czpn1I53.js";import{c as r,l as i,o as a,s as o,u as s}from"./claude-model-version-CSATLzrT.js";import"./libesm-BypnjKEL.js";import{t as c}from"./logger-DDBAeTLF.js";import{n as l}from"./base64-DJRlyqZu.js";import"./proxied-fetch-DyBveeCl.js";import{a as u,t as d}from"./api-endpoint-DGxXvrur.js";import{n as f}from"./float-topology-YtctpJaG.js";import"./secret-topology-DLJBhHOi.js";import{n as p}from"./secrets-bridge-client--VZ3E0yk.js";import"./tool-ui-eSQ1g2I1.js";import{n as m,o as h,t as g}from"./providers-yJqf8FSl.js";import{n as _,t as v}from"./panel-rpc-B3MSVImO.js";import{i as y,r as b,t as x}from"./bedrock-camp-compat-BeCSBUrZ.js";var S={assign:0,create:0,clone:0,discard:0,update:0};function ee(e){return Array.isArray(e)}function te(e){return C(e,null)}function ne(e){return C(typeof e,`object`)&&!te(e)}function C(e,t){return e===t}function re(e){if(!ne(e))return!1;let t=globalThis.Object.getPrototypeOf(e);return!te(t)&&C(typeof t.constructor,`function`)&&!(C(t.constructor,globalThis.Object)||C(t.constructor.name,`Object`))}function ie(e){return C(e,`__proto__`)||C(e,`constructor`)||C(e,`prototype`)}function ae(e,t){return ie(t)?Object.prototype.hasOwnProperty.call(e,t):t in e}function w(e){return Object.getOwnPropertyNames(e)}function oe(e){return Object.getOwnPropertySymbols(e)}function se(e){return globalThis.ArrayBuffer.isView(e)}function ce(e){return e instanceof globalThis.RegExp}function le(e){return e instanceof globalThis.Set}function ue(e){return e instanceof globalThis.Map}function de(e){return e}function fe(e){return ae(e,`~kind`)||ae(e,`~unsafe`)}function pe(e){let t={},n=Object.getOwnPropertyDescriptors(e);for(let e of Object.keys(n)){if(ie(e))continue;let r=n[e];ae(r,`value`)&&Object.defineProperty(t,e,{...r,value:T(r.value)})}return t}function me(e){let t={};for(let n of w(e))ie(n)||(t[n]=T(e[n]));for(let n of oe(e))t[n]=T(e[n]);return t}function he(e){return re(e)?de(e):fe(e)?pe(e):me(e)}function ge(e){return e.map(e=>T(e))}function _e(e){return e.slice()}function ve(e){return new RegExp(e.source,e.flags)}function ye(e){return new Map(T([...e.entries()]))}function be(e){return new Set(T([...e.values()]))}function T(e){return se(e)?_e(e):ce(e)?ve(e):ue(e)?ye(e):le(e)?be(e):ee(e)?ge(e):ne(e)?he(e):e}function xe(e){return S.clone+=1,T(e)}var Se={immutableTypes:!1,maxErrors:8,useAcceleration:!0,exactOptionalPropertyTypes:!1,enumerableKind:!1,correctiveParse:!1,unionPrioritySort:!0};function Ce(){return Se}function we(e,t){for(let n of Object.keys(t))Object.defineProperty(e,n,{configurable:!0,writable:!0,enumerable:!1,value:t[n]});return e}function Te(e,t){return{...e,...t}}function Ee(e,t,n={}){S.create+=1;let r=Ce(),i=Te(t,n),a=r.enumerableKind?Te(i,e):we(i,e);return r.immutableTypes?Object.freeze(a):a}function De(e,t,n){S.update+=1;let r=Ce(),i=xe(e);for(let e of Object.keys(t))Object.defineProperty(i,e,{configurable:!0,writable:!0,enumerable:r.enumerableKind,value:t[e]});for(let e of Object.keys(n))Object.defineProperty(i,e,{configurable:!0,enumerable:!0,writable:!0,value:n[e]});return i}function Oe(e){return ne(e)}function ke(e){return De(e,{"~optional":!0},{})}function Ae(e,t){return De(ke(e),{},t)}function je(e,t){return Ee({"~kind":`Array`},{type:`array`,items:e},t)}function Me(e,t={}){return Ae(e,t)}function Ne(e){return Me(e)}function Pe(e){return Oe(e)&&ae(e,`~optional`)}function Fe(e){return w(e).filter(t=>!Pe(e[t]))}function Ie(e,t={}){let n=Fe(e);return Ee({"~kind":`Object`},{type:`object`,...n.length>0?{required:n}:{},properties:e},t)}var Le;(function(e){e[e.Array=0]=`Array`,e[e.BigInt=1]=`BigInt`,e[e.Boolean=2]=`Boolean`,e[e.Date=3]=`Date`,e[e.Constructor=4]=`Constructor`,e[e.Function=5]=`Function`,e[e.Null=6]=`Null`,e[e.Number=7]=`Number`,e[e.Object=8]=`Object`,e[e.RegExp=9]=`RegExp`,e[e.String=10]=`String`,e[e.Symbol=11]=`Symbol`,e[e.TypeArray=12]=`TypeArray`,e[e.Undefined=13]=`Undefined`})(Le||={}),Array.from({length:256}).map((e,t)=>BigInt(t));var Re=new Float64Array(1);new DataView(Re.buffer),new Uint8Array(Re.buffer),new TextEncoder;var ze=`-?(?:0|[1-9][0-9]*)`,Be=`-?(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?`;function Ve(e){return Ee({"~kind":`Number`},{type:`number`},e)}function E(e){return Ee({"~kind":`String`},{type:`string`},e)}var He=`^${ze}$`;`${Be}`;function Ue(e,t){return Array.from({length:t-e+1},(t,n)=>String.fromCharCode(e+n))}var We=[...Ue(97,122),...Ue(65,90)],Ge=[`0`,...Ue(49,57)];[...Ge],[...We,...Ge],[...Ge],new RegExp(He);function Ke(e,t){try{return Promise.resolve(t(qe))}catch(e){return Promise.reject(e)}}var qe={startSpan:Ke,addEvent:()=>{},setAttributes:()=>{},setStatus:()=>{}};Object.freeze(qe);var Je=Symbol.for(`yaml.alias`),Ye=Symbol.for(`yaml.document`),D=Symbol.for(`yaml.map`),Xe=Symbol.for(`yaml.pair`),Ze=Symbol.for(`yaml.scalar`),Qe=Symbol.for(`yaml.seq`),O=Symbol.for(`yaml.node.type`),k=e=>!!e&&typeof e==`object`&&e[O]===Je,$e=e=>!!e&&typeof e==`object`&&e[O]===Ye,et=e=>!!e&&typeof e==`object`&&e[O]===D,A=e=>!!e&&typeof e==`object`&&e[O]===Xe,j=e=>!!e&&typeof e==`object`&&e[O]===Ze,tt=e=>!!e&&typeof e==`object`&&e[O]===Qe;function M(e){if(e&&typeof e==`object`)switch(e[O]){case D:case Qe:return!0}return!1}function N(e){if(e&&typeof e==`object`)switch(e[O]){case Je:case D:case Ze:case Qe:return!0}return!1}var nt=e=>(j(e)||M(e))&&!!e.anchor,P=Symbol(`break visit`),rt=Symbol(`skip children`),it=Symbol(`remove node`);function at(e,t){let n=st(t);$e(e)?ot(null,e.contents,n,Object.freeze([e]))===it&&(e.contents=null):ot(null,e,n,Object.freeze([]))}at.BREAK=P,at.SKIP=rt,at.REMOVE=it;function ot(e,t,n,r){let i=ct(e,t,n,r);if(N(i)||A(i))return lt(e,r,i),ot(e,i,n,r);if(typeof i!=`symbol`){if(M(t)){r=Object.freeze(r.concat(t));for(let e=0;e<t.items.length;++e){let i=ot(e,t.items[e],n,r);if(typeof i==`number`)e=i-1;else if(i===P)return P;else i===it&&(t.items.splice(e,1),--e)}}else if(A(t)){r=Object.freeze(r.concat(t));let e=ot(`key`,t.key,n,r);if(e===P)return P;e===it&&(t.key=null);let i=ot(`value`,t.value,n,r);if(i===P)return P;i===it&&(t.value=null)}}return i}function st(e){return typeof e==`object`&&(e.Collection||e.Node||e.Value)?Object.assign({Alias:e.Node,Map:e.Node,Scalar:e.Node,Seq:e.Node},e.Value&&{Map:e.Value,Scalar:e.Value,Seq:e.Value},e.Collection&&{Map:e.Collection,Seq:e.Collection},e):e}function ct(e,t,n,r){if(typeof n==`function`)return n(e,t,r);if(et(t))return n.Map?.(e,t,r);if(tt(t))return n.Seq?.(e,t,r);if(A(t))return n.Pair?.(e,t,r);if(j(t))return n.Scalar?.(e,t,r);if(k(t))return n.Alias?.(e,t,r)}function lt(e,t,n){let r=t[t.length-1];if(M(r))r.items[e]=n;else if(A(r))e===`key`?r.key=n:r.value=n;else if($e(r))r.contents=n;else{let e=k(r)?`alias`:`scalar`;throw Error(`Cannot replace node with ${e} parent`)}}function ut(e){if(/[\x00-\x19\s,[\]{}]/.test(e)){let t=`Anchor must not contain whitespace or control characters: ${JSON.stringify(e)}`;throw Error(t)}return!0}function dt(e,t,n,r){if(r&&typeof r==`object`){if(Array.isArray(r))for(let t=0,n=r.length;t<n;++t){let n=r[t],i=dt(e,r,String(t),n);i===void 0?delete r[t]:i!==n&&(r[t]=i)}else if(r instanceof Map)for(let t of Array.from(r.keys())){let n=r.get(t),i=dt(e,r,t,n);i===void 0?r.delete(t):i!==n&&r.set(t,i)}else if(r instanceof Set)for(let t of Array.from(r)){let n=dt(e,r,t,t);n===void 0?r.delete(t):n!==t&&(r.delete(t),r.add(n))}else for(let[t,n]of Object.entries(r)){let i=dt(e,r,t,n);i===void 0?delete r[t]:i!==n&&(r[t]=i)}}return e.call(t,n,r)}function F(e,t,n){if(Array.isArray(e))return e.map((e,t)=>F(e,String(t),n));if(e&&typeof e.toJSON==`function`){if(!n||!nt(e))return e.toJSON(t,n);let r={aliasCount:0,count:1,res:void 0};n.anchors.set(e,r),n.onCreate=e=>{r.res=e,delete n.onCreate};let i=e.toJSON(t,n);return n.onCreate&&n.onCreate(i),i}return typeof e==`bigint`&&!n?.keep?Number(e):e}var ft=class{constructor(e){Object.defineProperty(this,O,{value:e})}clone(){let e=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return this.range&&(e.range=this.range.slice()),e}toJS(e,{mapAsMap:t,maxAliasCount:n,onAnchor:r,reviver:i}={}){if(!$e(e))throw TypeError(`A document argument is required`);let a={anchors:new Map,doc:e,keep:!0,mapAsMap:t===!0,mapKeyWarned:!1,maxAliasCount:typeof n==`number`?n:100},o=F(this,``,a);if(typeof r==`function`)for(let{count:e,res:t}of a.anchors.values())r(t,e);return typeof i==`function`?dt(i,{"":o},``,o):o}},pt=class extends ft{constructor(e){super(Je),this.source=e,Object.defineProperty(this,"tag",{set(){throw Error(`Alias nodes cannot have tags`)}})}resolve(e,t){if(t?.maxAliasCount===0)throw ReferenceError(`Alias resolution is disabled`);let n;t?.aliasResolveCache?n=t.aliasResolveCache:(n=[],at(e,{Node:(e,t)=>{(k(t)||nt(t))&&n.push(t)}}),t&&(t.aliasResolveCache=n));let r;for(let e of n){if(e===this)break;e.anchor===this.source&&(r=e)}return r}toJSON(e,t){if(!t)return{source:this.source};let{anchors:n,doc:r,maxAliasCount:i}=t,a=this.resolve(r,t);if(!a){let e=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw ReferenceError(e)}let o=n.get(a);if(o||=(F(a,null,t),n.get(a)),o?.res===void 0)throw ReferenceError(`This should not happen: Alias anchor was not resolved?`);if(i>=0&&(o.count+=1,o.aliasCount===0&&(o.aliasCount=mt(r,a,n)),o.count*o.aliasCount>i))throw ReferenceError(`Excessive alias count indicates a resource exhaustion attack`);return o.res}toString(e,t,n){let r=`*${this.source}`;if(e){if(ut(this.source),e.options.verifyAliasOrder&&!e.anchors.has(this.source)){let e=`Unresolved alias (the anchor must be set before the alias): ${this.source}`;throw Error(e)}if(e.implicitKey)return`${r} `}return r}};function mt(e,t,n){if(k(t)){let r=t.resolve(e),i=n&&r&&n.get(r);return i?i.count*i.aliasCount:0}if(M(t)){let r=0;for(let i of t.items){let t=mt(e,i,n);t>r&&(r=t)}return r}if(A(t)){let r=mt(e,t.key,n),i=mt(e,t.value,n);return Math.max(r,i)}return 1}var ht=e=>!e||typeof e!=`function`&&typeof e!=`object`,I=class extends ft{constructor(e){super(Ze),this.value=e}toJSON(e,t){return t?.keep?this.value:F(this.value,e,t)}toString(){return String(this.value)}};I.BLOCK_FOLDED=`BLOCK_FOLDED`,I.BLOCK_LITERAL=`BLOCK_LITERAL`,I.PLAIN=`PLAIN`,I.QUOTE_DOUBLE=`QUOTE_DOUBLE`,I.QUOTE_SINGLE=`QUOTE_SINGLE`;var gt=`tag:yaml.org,2002:`;function _t(e,t,n){if(t){let e=n.filter(e=>e.tag===t),r=e.find(e=>!e.format)??e[0];if(!r)throw Error(`Tag ${t} not found`);return r}return n.find(t=>t.identify?.(e)&&!t.format)}function vt(e,t,n){if($e(e)&&(e=e.contents),N(e))return e;if(A(e)){let t=n.schema[D].createNode?.(n.schema,null,n);return t.items.push(e),t}(e instanceof String||e instanceof Number||e instanceof Boolean||typeof BigInt<`u`&&e instanceof BigInt)&&(e=e.valueOf());let{aliasDuplicateObjects:r,onAnchor:i,onTagObj:a,schema:o,sourceObjects:s}=n,c;if(r&&e&&typeof e==`object`){if(c=s.get(e),c)return c.anchor??(c.anchor=i(e)),new pt(c.anchor);c={anchor:null,node:null},s.set(e,c)}t?.startsWith(`!!`)&&(t=gt+t.slice(2));let l=_t(e,t,o.tags);if(!l){if(e&&typeof e.toJSON==`function`&&(e=e.toJSON()),!e||typeof e!=`object`){let t=new I(e);return c&&(c.node=t),t}l=e instanceof Map?o[D]:Symbol.iterator in Object(e)?o[Qe]:o[D]}a&&(a(l),delete n.onTagObj);let u=l?.createNode?l.createNode(n.schema,e,n):typeof l?.nodeClass?.from==`function`?l.nodeClass.from(n.schema,e,n):new I(e);return t?u.tag=t:l.default||(u.tag=l.tag),c&&(c.node=u),u}function yt(e,t,n){let r=n;for(let e=t.length-1;e>=0;--e){let n=t[e];if(typeof n==`number`&&Number.isInteger(n)&&n>=0){let e=[];e[n]=r,r=e}else r=new Map([[n,r]])}return vt(r,void 0,{aliasDuplicateObjects:!1,keepUndefined:!1,onAnchor:()=>{throw Error(`This should not happen, please report a bug.`)},schema:e,sourceObjects:new Map})}var bt=e=>e==null||typeof e==`object`&&!!e[Symbol.iterator]().next().done,xt=class extends ft{constructor(e,t){super(e),Object.defineProperty(this,"schema",{value:t,configurable:!0,enumerable:!1,writable:!0})}clone(e){let t=Object.create(Object.getPrototypeOf(this),Object.getOwnPropertyDescriptors(this));return e&&(t.schema=e),t.items=t.items.map(t=>N(t)||A(t)?t.clone(e):t),this.range&&(t.range=this.range.slice()),t}addIn(e,t){if(bt(e))this.add(t);else{let[n,...r]=e,i=this.get(n,!0);if(M(i))i.addIn(r,t);else if(i===void 0&&this.schema)this.set(n,yt(this.schema,r,t));else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`)}}deleteIn(e){let[t,...n]=e;if(n.length===0)return this.delete(t);let r=this.get(t,!0);if(M(r))return r.deleteIn(n);throw Error(`Expected YAML collection at ${t}. Remaining path: ${n}`)}getIn(e,t){let[n,...r]=e,i=this.get(n,!0);return r.length===0?!t&&j(i)?i.value:i:M(i)?i.getIn(r,t):void 0}hasAllNullValues(e){return this.items.every(t=>{if(!A(t))return!1;let n=t.value;return n==null||e&&j(n)&&n.value==null&&!n.commentBefore&&!n.comment&&!n.tag})}hasIn(e){let[t,...n]=e;if(n.length===0)return this.has(t);let r=this.get(t,!0);return M(r)?r.hasIn(n):!1}setIn(e,t){let[n,...r]=e;if(r.length===0)this.set(n,t);else{let e=this.get(n,!0);if(M(e))e.setIn(r,t);else if(e===void 0&&this.schema)this.set(n,yt(this.schema,r,t));else throw Error(`Expected YAML collection at ${n}. Remaining path: ${r}`)}}},St=e=>e.replace(/^(?!$)(?: $)?/gm,`#`);function Ct(e,t){return/^\n+$/.test(e)?e.substring(1):t?e.replace(/^(?! *$)/gm,t):e}var L=(e,t,n)=>e.endsWith(`
|
|
3
3
|
`)?Ct(n,t):n.includes(`
|
|
4
4
|
`)?`
|
|
5
5
|
`+Ct(n,t):(e.endsWith(` `)?``:` `)+n,wt=`flow`,Tt=`block`,Et=`quoted`;function Dt(e,t,n=`flow`,{indentAtStart:r,lineWidth:i=80,minContentWidth:a=20,onFold:o,onOverflow:s}={}){if(!i||i<0)return e;i<a&&(a=0);let c=Math.max(1+a,1+i-t.length);if(e.length<=c)return e;let l=[],u={},d=i-t.length;typeof r==`number`&&(r>i-Math.max(2,a)?l.push(0):d=i-r);let f,p,m=!1,h=-1,g=-1,_=-1;n===`block`&&(h=Ot(e,h,t.length),h!==-1&&(d=h+c));for(let r;r=e[h+=1];){if(n===`quoted`&&r===`\\`){switch(g=h,e[h+1]){case`x`:h+=3;break;case`u`:h+=5;break;case`U`:h+=9;break;default:h+=1}_=h}if(r===`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./logger-LESFN7Hj.js";import{n,r}from"./panel-rpc-BPwAqRch.js";import{n as i,o as a,t as o}from"./providers-B5Xll24v.js";import"./proxied-fetch-DEK8DT-z.js";import{o as s,t as c}from"./api-endpoint-3qEcn7BY.js";import{i as l,n as ee,r as u}from"./compat-uEPf6-XW.js";import{u as d}from"./core-DP-MJcag.js";import{t as f}from"./secrets-bridge-client-ZpBL1Zhl.js";import{i as te,r as ne,t as re}from"./bedrock-camp-compat-99DjWBHV.js";import{o as ie}from"./claude-model-version-m5AAX9Oe.js";const ae=`slicc_oauth_extra_domains`;function p(e){try{let t=e.getItem(ae);if(!t)return{};let n=JSON.parse(t);if(typeof n!=`object`||!n||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n)){if(typeof e!=`string`||!Array.isArray(t))continue;let n=t.filter(e=>typeof e==`string`&&e.length>0);n.length>0&&(r[e]=n)}return r}catch{return{}}}function oe(e,t){try{e.setItem(ae,JSON.stringify(t))}catch(e){throw Error(`Failed to persist OAuth extras (localStorage quota exceeded?): ${e instanceof Error?e.message:String(e)}`)}}function se(e,t){let n={input:0,output:0,cacheRead:0,cacheWrite:0},r=ie(e);if(!r)return n;let i;for(let e of t.values()){let t=ie(e.id);!t||t.family!==r.family||(!i||t.major>i.major||t.major===i.major&&t.minor>i.minor)&&(i={major:t.major,minor:t.minor,cost:e.cost})}return i?.cost??n}const ce=t(`model-policy`),m=`/etc/models`;function h(){return{sections:{}}}function le(e){let t=e.indexOf(`#`);return(t===-1?e:e.slice(0,t)).trim()}function ue(e){let t=h();if(typeof e!=`string`)return t;let n=null;for(let r of e.split(/\r?\n/)){let e=le(r);if(!e)continue;let i=/^\[([^\]]+)\]$/.exec(e);if(i){n=i[1].trim(),t.sections[n]??=[];continue}if(n===null){ce.warn(`model policy entry before any [provider] section — ignored`,{entry:e});continue}let a=e.startsWith(`-`),o=a?e.slice(1).trim():e,s=o.indexOf(`:`);if(s<=0||s===o.length-1){ce.warn(`model policy entry is not provider:model — ignored`,{entry:e});continue}t.sections[n].push({providerId:o.slice(0,s).trim(),modelId:o.slice(s+1).trim(),deny:a})}return t}function g(e,t,n){return e.providerId===t?e.modelId===`*`||e.modelId===n:!1}function de(e,t){return e.sections[t]??[]}function fe(e,t,n,r){return de(e,t).some(e=>e.deny&&g(e,n,r))}function pe(e,t,n,r){let i=de(e,t);return i.some(e=>e.deny&&g(e,n,r))?!1:n===t||i.some(e=>!e.deny&&g(e,n,r))}let me=h();function he(e){me=e}function _(){return me}function ge(e,t,n){return`add \`${t}:${n}\` (or \`${t}:*\`) under \`[${e}]\` in ${m}`}var _e=e({ACCOUNTS_KEY:()=>b,__test__:()=>Ce,addAccount:()=>P,applyProviderDefaults:()=>Ee,clearAllSettings:()=>lt,clearApiKey:()=>it,clearBaseUrl:()=>st,clearSelectedProvider:()=>tt,ensureOAuthMaskReplica:()=>qe,exportProviders:()=>ct,getAccounts:()=>M,getAllAvailableModels:()=>Ae,getAllExtraOAuthDomains:()=>Fe,getAlternativeModelProviders:()=>je,getApiKey:()=>nt,getApiKeyForProvider:()=>B,getApiVersionForProvider:()=>Ze,getAvailableProviders:()=>w,getBaseUrl:()=>at,getBaseUrlForProvider:()=>V,getDeploymentForProvider:()=>Xe,getExtraOAuthDomains:()=>Me,getOAuthAccountInfo:()=>k,getProviderConfig:()=>E,getProviderModels:()=>O,getRawApiKeyForProvider:()=>z,getSelectedModelId:()=>H,getSelectedProvider:()=>U,isModelHiddenFromPicker:()=>j,isUsableOAuthMaskReplica:()=>L,logoutOAuthAccount:()=>Re,maskOAuthTokenWithRetry:()=>ze,migrateLegacyAuthOnlySelection:()=>xe,modelRunsOnProvider:()=>mt,persistOAuthMaskViaServiceWorker:()=>R,policyVisible:()=>ke,providerOffersLlmModels:()=>T,removeAccount:()=>F,resolveCurrentModel:()=>q,resolveModelById:()=>K,resolveModelByShorthand:()=>ht,resolveModelIdForScoop:()=>St,resolveModelSelectionForScoop:()=>Z,saveOAuthAccount:()=>Ye,setApiKey:()=>rt,setBaseUrl:()=>ot,setExtraOAuthDomains:()=>Ne,setExtraOAuthDomainsAsync:()=>Pe,setSelectedModelId:()=>Qe,setSelectedProvider:()=>et});const v=ee,y=u,b=`slicc_accounts`,x=`selected-model`,ve=[`slicc_provider`,`slicc_api_key`,`slicc_base_url`,`anthropic_api_key`,`api_provider`,`azure_resource`,`bedrock_region`],ye=new Set([`github`]);function S(e){let t;try{t=l()}catch{return!1}return t.includes(e)&&!a(e)}let C=!1;function be(){if(!C){C=!0;for(let e of ve)try{localStorage.removeItem(e)}catch{}xe()}}function xe(){try{let e=localStorage.getItem(x);if(e){let t=e.indexOf(`:`);if(t>0){let n=e.slice(0,t);(ye.has(n)||S(n))&&localStorage.removeItem(x)}}}catch{}try{let e=localStorage.getItem(b);if(!e)return;let t=JSON.parse(e);if(!Array.isArray(t))return;let n=t.filter(e=>!(typeof e==`object`&&e&&typeof e.providerId==`string`&&S(e.providerId)));n.length!==t.length&&localStorage.setItem(b,JSON.stringify(n))}catch{}}function Se(){C=!1}const Ce={_resetLegacyCleanup:Se};function w(){let e=l().filter(a),t=i();return[...new Set([...e,...t])].filter(e=>!o(e)?.hidden)}function T(e){try{if(O(e).length>0)return!0}catch{}try{if(u(e).length>0)return!0}catch{}let t=o(e);return!!(t?.modelOverrides&&Object.keys(t.modelOverrides).length>0)}function we(e,t){try{if(O(e).some(e=>e.id===t))return!0}catch{}try{if(u(e).some(e=>e.id===t))return!0}catch{}let n=o(e);return!!(n?.modelOverrides&&Object.hasOwn(n.modelOverrides,t))}function E(e){return o(e)||{id:e,name:e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `),description:`${e} provider`,requiresApiKey:!0,requiresBaseUrl:!1}}function D(e,t){t.context_window!==void 0&&(e.contextWindow=t.context_window),t.max_tokens!==void 0&&(e.maxTokens=t.max_tokens),t.reasoning!==void 0&&(e.reasoning=t.reasoning),t.input!==void 0&&(e.input=t.input),t.cost!==void 0&&(e.cost=t.cost,e.inputCost=t.cost.input,e.outputCost=t.cost.output,e.cacheReadCost=t.cost.cacheRead,e.cacheWriteCost=t.cost.cacheWrite),t.compat!==void 0&&(e.compat={...e.compat??{},...t.compat}),t.thinkingLevelMap!==void 0&&(e.thinkingLevelMap={...e.thinkingLevelMap??{},...t.thinkingLevelMap})}function O(e){try{if(e===`bedrock-camp`){let e=re(V(`bedrock-camp`));return y(`amazon-bedrock`).filter(t=>te(t,e)).map(e=>({...e,api:`bedrock-camp-converse`,provider:`bedrock-camp`,reasoning:e.reasoning===!0&&ne(e)}))}let t=E(e);if(t.getModelIds){let n;try{n=t.getModelIds()}catch(t){return A.error(`Provider getModelIds callback failed`,{providerId:e,error:t instanceof Error?t.message:String(t)}),[]}let r=new Map;for(let e of l())try{for(let t of y(e))r.set(t.id,t)}catch{}return n.map(n=>{let i=n.api===`openai`?`openai`:`anthropic`,a=`${e}-${i}`,o=r.get(n.id),s;if(o)s={...o,api:a,provider:e};else if(s=W(e,n.id,``,a),n.name&&(s.name=n.name),i===`anthropic`){let e=se(n.id,r);s.cost=e,s.inputCost=e.input,s.outputCost=e.output,s.cacheReadCost=e.cacheRead,s.cacheWriteCost=e.cacheWrite}let c=t.modelOverrides?.[n.id];return c&&D(s,c),D(s,n),s})}if(t.isOAuth){let n=y(`anthropic`),r=`${e}-anthropic`;return n.map(n=>{let i={...n,api:r,provider:e},a=t.modelOverrides?.[n.id];return a&&D(i,a),i})}return y(e===`azure-ai-foundry`?`anthropic`:e)}catch(t){return A.error(`Failed to load models`,{providerId:e,error:t instanceof Error?t.message:String(t)}),[]}}function k(e){let t=M().find(t=>t.providerId===e);if(!t?.accessToken)return null;let n=!!t.tokenExpiresAt&&Date.now()>t.tokenExpiresAt-6e4;return{token:t.accessToken,maskedValue:t.maskedValue,expiresAt:t.tokenExpiresAt,userName:t.userName,userAvatar:t.userAvatar,scopes:t.scopes,expired:n}}const Te=Object.assign({})[`/packages/webapp/providers.json`]??[],A=t(`provider-settings`);function Ee(e=Te){if(e.length===0||M().length>0)return;let t=new Set(w());for(let n of e)if(!(!n.providerId||!n.apiKey)){if(!t.has(n.providerId)){A.warn(`Unknown provider "${n.providerId}" in providers.json — skipping`);continue}P(n.providerId,n.apiKey,n.baseUrl)}let n=e.find(e=>e.providerId&&e.apiKey&&t.has(e.providerId));n?.model&&!localStorage.getItem(x)&&localStorage.setItem(x,`${n.providerId}:${n.model}`)}const De=[/haiku/i];function j(e){return De.some(t=>t.test(e))}function Oe(e){return e.filter(e=>!j(e.id))}function ke(e,t){let n=Q();if(n===null)return e;let r=_();return e.filter(e=>!fe(r,n,t,e.id))}function Ae(){let e=M();if(e.length===0)return[];let t=new Map;for(let n of e){if(t.has(n.providerId))continue;let e=E(n.providerId);if(e.hidden||S(n.providerId))continue;let r=ke(Oe(O(n.providerId)),n.providerId);if(r.length===0)continue;let i={providerId:n.providerId,providerName:e.name,models:r};t.set(n.providerId,i)}return[...t.values()]}function je(e){return Ae().map(e=>e.providerId).filter(t=>t!==e)}function M(){be();let e=localStorage.getItem(b);if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`object`&&!!e&&typeof e.providerId==`string`&&typeof e.apiKey==`string`):[]}catch{return[]}}function Me(e){return p(localStorage)[e]??[]}function Ne(e,t){let n=p(localStorage),r=t.map(e=>e.trim()).filter(e=>e.length>0);r.length===0?delete n[e]:n[e]=r,oe(localStorage,n)}async function Pe(e,t){if(r()){Ne(e,t);return}let i=n();if(!i)throw Error(`setExtraOAuthDomainsAsync: no DOM and no panel-rpc client — cannot persist to page localStorage`);let{storeAfter:a}=await i.call(`oauth-extras-set`,{providerId:e,domains:t});try{oe(localStorage,a)}catch(t){A.warn(`worker-shim mirror failed after successful page write — reload to refresh`,{providerId:e,error:t instanceof Error?t.message:String(t)})}}function Fe(){return p(localStorage)}function Ie(e){localStorage.setItem(b,JSON.stringify(e))}async function N(e){if(r()){Ie(e);return}let t=n();if(!t)throw Error(`saveAccountsAsync: no DOM and no panel-rpc client — cannot persist to page localStorage`);let i=JSON.stringify(e),{storedJson:a}=await t.call(`save-oauth-accounts`,{accountsJson:i});try{localStorage.setItem(b,a)}catch(e){A.warn(`worker-shim mirror failed after successful page write — reload to refresh`,{error:e instanceof Error?e.message:String(e)})}}function P(e,t,n,r,i){let a=M().filter(t=>t.providerId!==e),o={providerId:e,apiKey:t};n&&(o.baseUrl=n),r&&(o.deployment=r),i&&(o.apiVersion=i),a.push(o),Ie(a)}async function Le(e){let t=d();try{if(t===`extension-direct`){let t=await new Promise(t=>{chrome.runtime.sendMessage({type:`secrets.delete`,name:`oauth.${e}.token`},n=>{chrome.runtime.lastError&&A.error(`SW secrets.delete transport failed`,{providerId:e,error:chrome.runtime.lastError.message}),t(n??{})})});t.error&&A.error(`SW secrets.delete returned error`,{providerId:e,error:t.error})}else if(t===`extension-delegate`){let t=await f(`secrets.delete`,{name:`oauth.${e}.token`});t?.error&&A.error(`Bridge secrets.delete returned error`,{providerId:e,error:t.error})}else if(t!==`connect`){let t=await fetch(s(`/api/secrets/oauth/${e}`),{method:`DELETE`,headers:c()});!t.ok&&t.status!==404&&A.warn(`OAuth replica DELETE non-ok`,{providerId:e,status:t.status})}}catch(n){A.error(`OAuth replica removal failed`,{providerId:e,topology:t,error:n instanceof Error?n.message:String(n)})}}async function F(e){let t=M().find(t=>t.providerId===e),n=E(e);t&&n?.isOAuth&&await Re(e),await Le(e),await N(M().filter(t=>t.providerId!==e));let r=localStorage.getItem(x)??``,i=r.indexOf(`:`);i>0&&r.slice(0,i)===e&&localStorage.removeItem(x)}async function Re(e){let t=M().find(t=>t.providerId===e);if(!t)return;let n=E(e);if(n?.isOAuth){if(n.onOAuthLogout)try{await n.onOAuthLogout()}catch(t){A.warn(`onOAuthLogout failed`,{providerId:e,error:t instanceof Error?t.message:String(t)})}if(n.getOAuthLogoutUrl){let r=n.getOAuthLogoutUrl(t);if(r){let{openIdpLogoutUrl:t}=await import(`./oauth-service-IlBYPvwr.js`);await t(r).catch(t=>{A.warn(`IdP logout popup failed`,{providerId:e,error:t instanceof Error?t.message:String(t)})})}}await N(M().map(t=>t.providerId===e?{providerId:t.providerId,apiKey:``,baseUrl:t.baseUrl,userName:t.userName,userAvatar:t.userAvatar,loggedOut:!0}:t)),await Le(e)}}async function ze(e,t={}){let n=Math.max(1,t.attempts??3),r=t.delayMs??150,i=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),a;for(let t=0;t<n;t++){let o=await e();if(o.maskedValue)return{maskedValue:o.maskedValue};o.error&&(a=o.error),t<n-1&&await i(r)}return{lastError:a}}const Be=`access token rotated during mask write`;function I(e,t,n,r){let i=r.find(t=>t.providerId===e);return i?.accessToken?i.accessToken===t?(i.maskedValue=n,{maskedValue:n}):(A.warn(`OAuth mask write raced with token rotation; discarding replica`,{providerId:e}),{error:Be}):{error:`account gone after mask write`}}function L(e,t){return!!e&&e!==t}async function R(e,t,n){let r={providerId:e.providerId,accessToken:e.accessToken,domains:e.domains.join(`,`)},{maskedValue:i,lastError:a}=await ze(()=>t.sendMaskRequest(r),n);if(!L(i,e.accessToken)){let t=i?`mask replica equals the access token`:a??`no error reported (cold SW or empty reply)`;return A.error(`OAuth mask give-up: no masked value after retries`,{providerId:e.providerId,reason:t}),{error:t}}let o=t.getAccounts(),s=I(e.providerId,e.accessToken,i,o);return s.maskedValue&&await t.saveAccounts(o),s}function Ve(e){let t=E(e).oauthTokenDomains??[],n=Me(e),r=new Set,i=[];for(let e of[...t,...n]){let t=e.toLowerCase();r.has(t)||(r.add(t),i.push(e))}return i}function He(e){return new Promise(t=>{chrome.runtime.sendMessage({type:`secrets.mask-oauth-token`,...e},n=>{chrome.runtime.lastError&&A.error(`SW mask-oauth-token transport failed`,{providerId:e.providerId,error:chrome.runtime.lastError.message});let r=typeof n==`object`&&n?n:void 0;r?.error&&A.warn(`SW mask-oauth-token returned error`,{providerId:e.providerId,error:r.error}),t(r??{})})})}function Ue(e){return f(`secrets.mask-oauth-token`,e).then(t=>(t?.error&&A.warn(`Bridge mask-oauth-token returned error`,{providerId:e.providerId,error:t.error}),t??{})).catch(t=>(A.error(`Bridge mask-oauth-token transport failed`,{providerId:e.providerId,error:t instanceof Error?t.message:String(t)}),{}))}async function We(e,t,n){let r=s(`/api/secrets/oauth-update`),i=await fetch(r,{method:`POST`,headers:c({"Content-Type":`application/json`}),body:JSON.stringify({providerId:e,accessToken:t,domains:n})});if(!i.ok)return A.warn(`OAuth replica POST non-ok`,{providerId:e,status:i.status,url:r}),{error:`OAuth replica POST HTTP ${i.status}`};let a=await i.json();if(typeof a.maskedValue!=`string`)return A.warn(`OAuth replica POST ok but missing maskedValue`,{providerId:e,url:r}),{error:`OAuth replica POST ok but missing maskedValue`};if(!L(a.maskedValue,t))return A.error(`OAuth mask replica equals the access token; refusing to persist`,{providerId:e}),{error:`mask replica equals the access token`};let o=M(),l=I(e,t,a.maskedValue,o);return l.maskedValue&&await N(o),l}async function Ge(e,t){let n=await Ke(e,t);if(n.error!==Be)return n;let r=M().find(t=>t.providerId===e)?.accessToken;return!r||r===t?n:Ke(e,r)}async function Ke(e,t){let n=Ve(e);if(n.length===0)return{error:`no oauth token domains configured`};let r=d();try{return r===`extension-direct`?R({providerId:e,accessToken:t,domains:n},{sendMaskRequest:He,getAccounts:M,saveAccounts:N}):r===`extension-delegate`?R({providerId:e,accessToken:t,domains:n},{sendMaskRequest:Ue,getAccounts:M,saveAccounts:N}):r===`connect`?{error:`no replica store in connect mode`}:await We(e,t,n)}catch(t){let n=t instanceof Error?t.message:String(t);return A.error(`OAuth replica sync failed`,{providerId:e,topology:r,error:n}),{error:n}}}async function qe(e){let t=M().find(t=>t.providerId===e);return t?.accessToken?L(t.maskedValue,t.accessToken)?{maskedValue:t.maskedValue}:Ge(e,t.accessToken):{error:`no access token held`}}function Je(e,t){if(e.accessToken)return`scopes`in e?e.scopes:t?.scopes}async function Ye(e){let t=M().find(t=>t.providerId===e.providerId),n=M().filter(t=>t.providerId!==e.providerId);n.push({providerId:e.providerId,apiKey:``,accessToken:e.accessToken,refreshToken:e.refreshToken,tokenExpiresAt:e.tokenExpiresAt,userName:e.userName,userAvatar:e.userAvatar,baseUrl:e.baseUrl??t?.baseUrl,scopes:Je(e,t)}),await N(n),await Ge(e.providerId,e.accessToken)}function z(e){let t=M().find(t=>t.providerId===e);return t&&(t.accessToken||t.apiKey)||null}function B(e){let t=M().find(t=>t.providerId===e);return t?t.accessToken||t.apiKey||(E(e).optionalApiKey?`local`:null):null}function V(e){return M().find(t=>t.providerId===e)?.baseUrl??null}function Xe(e){return M().find(t=>t.providerId===e)?.deployment??null}function Ze(e){return M().find(t=>t.providerId===e)?.apiVersion??null}function H(){let e=localStorage.getItem(x)||``,t=e.indexOf(`:`);return t>=0?e.slice(t+1):e}function Qe(e){let t=e.indexOf(`:`);if(t>0){let n=e.slice(0,t),r=new Set([...i(),...w()]),a=n.includes(`.`);if(r.has(n)||!a){localStorage.setItem(x,e);return}}let n=U();localStorage.setItem(x,`${n}:${e}`)}function $e(){return localStorage.getItem(x)||``}function U(){let e=$e(),t=e.indexOf(`:`);if(t>0)return e.slice(0,t);let n=M(),r=H();if(r){let e=n.find(e=>T(e.providerId)&&we(e.providerId,r));if(e)return e.providerId}let i=n.find(e=>T(e.providerId));return i?i.providerId:n.length>0?n[0].providerId:`anthropic`}function et(e){let t=H();localStorage.setItem(x,`${e}:${t}`)}function tt(){let e=H();localStorage.setItem(x,e)}function nt(){return B(U())}function rt(e){let t=U();P(t,e,V(t)??void 0)}async function it(){await F(U())}function at(){return V(U())}function ot(e){let t=U(),n=z(t);n&&P(t,n,e||void 0)}function st(){let e=U(),t=z(e);t&&P(e,t)}function ct(){let e=M(),t=U(),n=H();return e.map(e=>{let r={providerId:e.providerId,apiKey:e.apiKey};return e.baseUrl&&(r.baseUrl=e.baseUrl),e.providerId===t&&n&&(r.model=n),r})}async function lt(){let e=M();await Promise.allSettled(e.map(e=>F(e.providerId))),localStorage.removeItem(b),localStorage.removeItem(x);for(let e of ve)localStorage.removeItem(e)}function ut(e){return/^(?:gpt[-.]?|o[0-9]|chatgpt)/i.test(e)?`openai`:`anthropic`}function W(e,t,n,r){return{id:t,name:t,provider:e,api:r??`${e}-${ut(t)}`,baseUrl:n??``,contextWindow:2e5,maxTokens:16384,input:[`text`,`image`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},reasoning:!0}}function G(e,t){return t.isOAuth||e===`azure-ai-foundry`?`anthropic`:e===`bedrock-camp`?`amazon-bedrock`:e}function dt(e,t,n){let r=O(e).find(e=>e.id===t);return r?n?{...r,baseUrl:n}:r:null}function ft(e,t,n,r){return n.isOAuth?O(t).find(e=>e.id===r)||{...e,api:`${t}-anthropic`,provider:t}:t===`bedrock-camp`?{...e,api:`bedrock-camp-converse`,provider:`bedrock-camp`}:e}function pt(e,t,n,r,i){if(t.isOAuth)return dt(e,n,r)??W(e,n,r);if(i)throw Error(`Model ${n} is not available from provider ${e}`);return q()}function K(e,t){if(!e)return q();let n=t??U(),r=V(n),i=E(n);if(t!==void 0){let t=dt(n,e,r);if(t)return t}try{let t=G(n,i),a=v(t,e);if(!a?.id)throw Error(`Model ${e} not found`);let o=ft(a,n,i,e);return r?{...o,baseUrl:r}:o}catch(a){return A.debug(`resolveModelById: pi-ai lookup miss, using provider fallback`,{providerId:n,modelId:e,error:a instanceof Error?a.message:String(a)}),pt(n,i,e,r,t!==void 0)}}function mt(e,t){return e.provider===t||e.provider===G(t,E(t))}function q(){let e=U(),t=H(),n=V(e),r=O(e),i=E(e),a=i.defaultModelId?r.find(e=>e.id.toLowerCase().includes(i.defaultModelId.toLowerCase()))?.id:void 0,o=t||a||r[0]?.id||`claude-sonnet-4-6`;try{let t=G(e,i),a=v(t,o);if(!a?.id)throw Error(`Model ${o} not found in ${t} registry`);let s=a;return i.isOAuth?s=r.find(e=>e.id===o)||{...s,api:`${e}-anthropic`,provider:e}:e===`bedrock-camp`&&(s={...s,api:`bedrock-camp-converse`,provider:`bedrock-camp`}),n&&(s={...s,baseUrl:n}),s}catch(t){A.debug(`resolveCurrentModel: pi-ai lookup miss, using provider fallback`,{providerId:e,effectiveModelId:o,error:t instanceof Error?t.message:String(t)});let a=r.find(e=>e.id===o);return a?n?{...a,baseUrl:n}:a:i.isOAuth?W(e,o,n):v(`anthropic`,`claude-sonnet-4-0`)}}function ht(e){let t=e.toLowerCase();if(!t)return null;let n=null;try{n=U()}catch{}if(n!==null){let e=J(t,[n]);if(e!==null)return e}return J(t,M().map(e=>e.providerId))}function J(e,t){let n=null,r=-1;for(let i of t)for(let t of O(i)){let i=t.id.toLowerCase(),a=(t.name??``).toLowerCase();if(!i.includes(e)&&!a.includes(e))continue;let o=t.contextWindow??0;(o>r||o===r&&Ct(t.id,n??``)>0)&&(r=o,n=t.id)}return n}function Y(){let e=[];try{for(let t of M())e.includes(t.providerId)||e.push(t.providerId)}catch{}try{let t=U();e.includes(t)||e.push(t)}catch{}return e}function gt(e){let t=e.indexOf(`:`);if(t<=0||t===e.length-1)return null;let n=e.slice(0,t),r=e.slice(t+1),i=Y().includes(n);if(i)return{providerId:n,modelId:r,configured:i};let a=!1;try{a=w().includes(n)}catch{}return a?{providerId:n,modelId:r,configured:!1}:null}function X(e,t,n=!0){let r=[e],i=n?J(e.toLowerCase(),[t]):null;i!==null&&i!==e&&r.push(i);let a=[];try{a=O(t)}catch{}for(let n of r)if(!(a.length>0&&!a.some(e=>e.id===n)))try{if(K(n,t).id===n)return{modelId:n,providerId:t}}catch(r){A.debug(`selectModelFromProvider: candidate did not resolve`,{input:e,candidate:n,providerId:t,error:r instanceof Error?r.message:String(r)})}return null}function _t(e){return e.map(e=>`${e.providerId}:${e.modelId}`).join(`, `)}function Z(e){if(!e)return{ok:!1,error:`unknown model: (empty)`};let t=gt(e);if(t)return bt(e,t);let n=null;try{n=U()}catch{}if(n!==null){let t=X(e,n);if(t)return $(t)}return xt(e,n)}function Q(){try{return U()}catch{return null}}function vt(e){let t=Q();return t===null||pe(_(),t,e.providerId,e.modelId)}function yt(e){let t=Q()??`<none>`;return{ok:!1,error:`model not allowed: ${`${e.providerId}:${e.modelId}`} is blocked by ${m} while "${t}" is selected — ${ge(t,e.providerId,e.modelId)}`}}function $(e){return vt(e)?{ok:!0,selection:e}:yt(e)}function bt(e,t){if(!t.configured){let n=Y();return{ok:!1,error:`unknown model: ${e} (provider "${t.providerId}" is not configured${n.length>0?`; configured: ${n.join(`, `)}`:``})`}}let n=X(t.modelId,t.providerId);return n?$(n):{ok:!1,error:`unknown model: ${e} (provider "${t.providerId}" does not offer "${t.modelId}")`}}function xt(e,t){let n=Y().filter(e=>e!==t);for(let t of[`exact`,`shorthand`]){let r=[];for(let i of n){let n=t===`exact`?e:J(e.toLowerCase(),[i]);if(n===null)continue;let a=X(n,i,!1);a&&r.push(a)}let i=r.filter(vt);if(i.length===0&&r.length>0)return yt(r[0]);if(i.length===1)return{ok:!0,selection:i[0]};if(i.length>1)return{ok:!1,error:`ambiguous model: ${e} matches ${_t(i)} — qualify it as provider:model`}}return{ok:!1,error:`unknown model: ${e}`}}function St(e){let t=Z(e);return t.ok?t.selection.modelId:null}function Ct(e,t){let n=e.match(/\d+/g)?.map(Number)??[],r=t.match(/\d+/g)?.map(Number)??[],i=Math.max(n.length,r.length);for(let e=0;e<i;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t}return 0}export{se as S,Ye as _,B as a,ue as b,Xe as c,H as d,U as f,Z as g,K as h,nt as i,k as l,q as m,qe as n,Ze as o,mt as p,M as r,V as s,_e as t,O as u,m as v,he as x,h as y};
|
|
1
|
+
import{n as e}from"./rolldown-runtime-Dd_uD5pT.js";import{t}from"./logger-LESFN7Hj.js";import{n,r}from"./panel-rpc-BPwAqRch.js";import{n as i,o as a,t as o}from"./providers-DgV0i5wM.js";import"./proxied-fetch-DEK8DT-z.js";import{o as s,t as c}from"./api-endpoint-3qEcn7BY.js";import{i as l,n as ee,r as u}from"./compat-uEPf6-XW.js";import{u as d}from"./core-DP-MJcag.js";import{t as f}from"./secrets-bridge-client-ZpBL1Zhl.js";import{i as te,r as ne,t as re}from"./bedrock-camp-compat-99DjWBHV.js";import{o as ie}from"./claude-model-version-m5AAX9Oe.js";const ae=`slicc_oauth_extra_domains`;function p(e){try{let t=e.getItem(ae);if(!t)return{};let n=JSON.parse(t);if(typeof n!=`object`||!n||Array.isArray(n))return{};let r={};for(let[e,t]of Object.entries(n)){if(typeof e!=`string`||!Array.isArray(t))continue;let n=t.filter(e=>typeof e==`string`&&e.length>0);n.length>0&&(r[e]=n)}return r}catch{return{}}}function oe(e,t){try{e.setItem(ae,JSON.stringify(t))}catch(e){throw Error(`Failed to persist OAuth extras (localStorage quota exceeded?): ${e instanceof Error?e.message:String(e)}`)}}function se(e,t){let n={input:0,output:0,cacheRead:0,cacheWrite:0},r=ie(e);if(!r)return n;let i;for(let e of t.values()){let t=ie(e.id);!t||t.family!==r.family||(!i||t.major>i.major||t.major===i.major&&t.minor>i.minor)&&(i={major:t.major,minor:t.minor,cost:e.cost})}return i?.cost??n}const ce=t(`model-policy`),m=`/etc/models`;function h(){return{sections:{}}}function le(e){let t=e.indexOf(`#`);return(t===-1?e:e.slice(0,t)).trim()}function ue(e){let t=h();if(typeof e!=`string`)return t;let n=null;for(let r of e.split(/\r?\n/)){let e=le(r);if(!e)continue;let i=/^\[([^\]]+)\]$/.exec(e);if(i){n=i[1].trim(),t.sections[n]??=[];continue}if(n===null){ce.warn(`model policy entry before any [provider] section — ignored`,{entry:e});continue}let a=e.startsWith(`-`),o=a?e.slice(1).trim():e,s=o.indexOf(`:`);if(s<=0||s===o.length-1){ce.warn(`model policy entry is not provider:model — ignored`,{entry:e});continue}t.sections[n].push({providerId:o.slice(0,s).trim(),modelId:o.slice(s+1).trim(),deny:a})}return t}function g(e,t,n){return e.providerId===t?e.modelId===`*`||e.modelId===n:!1}function de(e,t){return e.sections[t]??[]}function fe(e,t,n,r){return de(e,t).some(e=>e.deny&&g(e,n,r))}function pe(e,t,n,r){let i=de(e,t);return i.some(e=>e.deny&&g(e,n,r))?!1:n===t||i.some(e=>!e.deny&&g(e,n,r))}let me=h();function he(e){me=e}function _(){return me}function ge(e,t,n){return`add \`${t}:${n}\` (or \`${t}:*\`) under \`[${e}]\` in ${m}`}var _e=e({ACCOUNTS_KEY:()=>b,__test__:()=>Ce,addAccount:()=>P,applyProviderDefaults:()=>Ee,clearAllSettings:()=>lt,clearApiKey:()=>it,clearBaseUrl:()=>st,clearSelectedProvider:()=>tt,ensureOAuthMaskReplica:()=>qe,exportProviders:()=>ct,getAccounts:()=>M,getAllAvailableModels:()=>Ae,getAllExtraOAuthDomains:()=>Fe,getAlternativeModelProviders:()=>je,getApiKey:()=>nt,getApiKeyForProvider:()=>B,getApiVersionForProvider:()=>Ze,getAvailableProviders:()=>w,getBaseUrl:()=>at,getBaseUrlForProvider:()=>V,getDeploymentForProvider:()=>Xe,getExtraOAuthDomains:()=>Me,getOAuthAccountInfo:()=>k,getProviderConfig:()=>E,getProviderModels:()=>O,getRawApiKeyForProvider:()=>z,getSelectedModelId:()=>H,getSelectedProvider:()=>U,isModelHiddenFromPicker:()=>j,isUsableOAuthMaskReplica:()=>L,logoutOAuthAccount:()=>Re,maskOAuthTokenWithRetry:()=>ze,migrateLegacyAuthOnlySelection:()=>xe,modelRunsOnProvider:()=>mt,persistOAuthMaskViaServiceWorker:()=>R,policyVisible:()=>ke,providerOffersLlmModels:()=>T,removeAccount:()=>F,resolveCurrentModel:()=>q,resolveModelById:()=>K,resolveModelByShorthand:()=>ht,resolveModelIdForScoop:()=>St,resolveModelSelectionForScoop:()=>Z,saveOAuthAccount:()=>Ye,setApiKey:()=>rt,setBaseUrl:()=>ot,setExtraOAuthDomains:()=>Ne,setExtraOAuthDomainsAsync:()=>Pe,setSelectedModelId:()=>Qe,setSelectedProvider:()=>et});const v=ee,y=u,b=`slicc_accounts`,x=`selected-model`,ve=[`slicc_provider`,`slicc_api_key`,`slicc_base_url`,`anthropic_api_key`,`api_provider`,`azure_resource`,`bedrock_region`],ye=new Set([`github`]);function S(e){let t;try{t=l()}catch{return!1}return t.includes(e)&&!a(e)}let C=!1;function be(){if(!C){C=!0;for(let e of ve)try{localStorage.removeItem(e)}catch{}xe()}}function xe(){try{let e=localStorage.getItem(x);if(e){let t=e.indexOf(`:`);if(t>0){let n=e.slice(0,t);(ye.has(n)||S(n))&&localStorage.removeItem(x)}}}catch{}try{let e=localStorage.getItem(b);if(!e)return;let t=JSON.parse(e);if(!Array.isArray(t))return;let n=t.filter(e=>!(typeof e==`object`&&e&&typeof e.providerId==`string`&&S(e.providerId)));n.length!==t.length&&localStorage.setItem(b,JSON.stringify(n))}catch{}}function Se(){C=!1}const Ce={_resetLegacyCleanup:Se};function w(){let e=l().filter(a),t=i();return[...new Set([...e,...t])].filter(e=>!o(e)?.hidden)}function T(e){try{if(O(e).length>0)return!0}catch{}try{if(u(e).length>0)return!0}catch{}let t=o(e);return!!(t?.modelOverrides&&Object.keys(t.modelOverrides).length>0)}function we(e,t){try{if(O(e).some(e=>e.id===t))return!0}catch{}try{if(u(e).some(e=>e.id===t))return!0}catch{}let n=o(e);return!!(n?.modelOverrides&&Object.hasOwn(n.modelOverrides,t))}function E(e){return o(e)||{id:e,name:e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `),description:`${e} provider`,requiresApiKey:!0,requiresBaseUrl:!1}}function D(e,t){t.context_window!==void 0&&(e.contextWindow=t.context_window),t.max_tokens!==void 0&&(e.maxTokens=t.max_tokens),t.reasoning!==void 0&&(e.reasoning=t.reasoning),t.input!==void 0&&(e.input=t.input),t.cost!==void 0&&(e.cost=t.cost,e.inputCost=t.cost.input,e.outputCost=t.cost.output,e.cacheReadCost=t.cost.cacheRead,e.cacheWriteCost=t.cost.cacheWrite),t.compat!==void 0&&(e.compat={...e.compat??{},...t.compat}),t.thinkingLevelMap!==void 0&&(e.thinkingLevelMap={...e.thinkingLevelMap??{},...t.thinkingLevelMap})}function O(e){try{if(e===`bedrock-camp`){let e=re(V(`bedrock-camp`));return y(`amazon-bedrock`).filter(t=>te(t,e)).map(e=>({...e,api:`bedrock-camp-converse`,provider:`bedrock-camp`,reasoning:e.reasoning===!0&&ne(e)}))}let t=E(e);if(t.getModelIds){let n;try{n=t.getModelIds()}catch(t){return A.error(`Provider getModelIds callback failed`,{providerId:e,error:t instanceof Error?t.message:String(t)}),[]}let r=new Map;for(let e of l())try{for(let t of y(e))r.set(t.id,t)}catch{}return n.map(n=>{let i=n.api===`openai`?`openai`:`anthropic`,a=`${e}-${i}`,o=r.get(n.id),s;if(o)s={...o,api:a,provider:e};else if(s=W(e,n.id,``,a),n.name&&(s.name=n.name),i===`anthropic`){let e=se(n.id,r);s.cost=e,s.inputCost=e.input,s.outputCost=e.output,s.cacheReadCost=e.cacheRead,s.cacheWriteCost=e.cacheWrite}let c=t.modelOverrides?.[n.id];return c&&D(s,c),D(s,n),s})}if(t.isOAuth){let n=y(`anthropic`),r=`${e}-anthropic`;return n.map(n=>{let i={...n,api:r,provider:e},a=t.modelOverrides?.[n.id];return a&&D(i,a),i})}return y(e===`azure-ai-foundry`?`anthropic`:e)}catch(t){return A.error(`Failed to load models`,{providerId:e,error:t instanceof Error?t.message:String(t)}),[]}}function k(e){let t=M().find(t=>t.providerId===e);if(!t?.accessToken)return null;let n=!!t.tokenExpiresAt&&Date.now()>t.tokenExpiresAt-6e4;return{token:t.accessToken,maskedValue:t.maskedValue,expiresAt:t.tokenExpiresAt,userName:t.userName,userAvatar:t.userAvatar,scopes:t.scopes,expired:n}}const Te=Object.assign({})[`/packages/webapp/providers.json`]??[],A=t(`provider-settings`);function Ee(e=Te){if(e.length===0||M().length>0)return;let t=new Set(w());for(let n of e)if(!(!n.providerId||!n.apiKey)){if(!t.has(n.providerId)){A.warn(`Unknown provider "${n.providerId}" in providers.json — skipping`);continue}P(n.providerId,n.apiKey,n.baseUrl)}let n=e.find(e=>e.providerId&&e.apiKey&&t.has(e.providerId));n?.model&&!localStorage.getItem(x)&&localStorage.setItem(x,`${n.providerId}:${n.model}`)}const De=[/haiku/i];function j(e){return De.some(t=>t.test(e))}function Oe(e){return e.filter(e=>!j(e.id))}function ke(e,t){let n=Q();if(n===null)return e;let r=_();return e.filter(e=>!fe(r,n,t,e.id))}function Ae(){let e=M();if(e.length===0)return[];let t=new Map;for(let n of e){if(t.has(n.providerId))continue;let e=E(n.providerId);if(e.hidden||S(n.providerId))continue;let r=ke(Oe(O(n.providerId)),n.providerId);if(r.length===0)continue;let i={providerId:n.providerId,providerName:e.name,models:r};t.set(n.providerId,i)}return[...t.values()]}function je(e){return Ae().map(e=>e.providerId).filter(t=>t!==e)}function M(){be();let e=localStorage.getItem(b);if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>typeof e==`object`&&!!e&&typeof e.providerId==`string`&&typeof e.apiKey==`string`):[]}catch{return[]}}function Me(e){return p(localStorage)[e]??[]}function Ne(e,t){let n=p(localStorage),r=t.map(e=>e.trim()).filter(e=>e.length>0);r.length===0?delete n[e]:n[e]=r,oe(localStorage,n)}async function Pe(e,t){if(r()){Ne(e,t);return}let i=n();if(!i)throw Error(`setExtraOAuthDomainsAsync: no DOM and no panel-rpc client — cannot persist to page localStorage`);let{storeAfter:a}=await i.call(`oauth-extras-set`,{providerId:e,domains:t});try{oe(localStorage,a)}catch(t){A.warn(`worker-shim mirror failed after successful page write — reload to refresh`,{providerId:e,error:t instanceof Error?t.message:String(t)})}}function Fe(){return p(localStorage)}function Ie(e){localStorage.setItem(b,JSON.stringify(e))}async function N(e){if(r()){Ie(e);return}let t=n();if(!t)throw Error(`saveAccountsAsync: no DOM and no panel-rpc client — cannot persist to page localStorage`);let i=JSON.stringify(e),{storedJson:a}=await t.call(`save-oauth-accounts`,{accountsJson:i});try{localStorage.setItem(b,a)}catch(e){A.warn(`worker-shim mirror failed after successful page write — reload to refresh`,{error:e instanceof Error?e.message:String(e)})}}function P(e,t,n,r,i){let a=M().filter(t=>t.providerId!==e),o={providerId:e,apiKey:t};n&&(o.baseUrl=n),r&&(o.deployment=r),i&&(o.apiVersion=i),a.push(o),Ie(a)}async function Le(e){let t=d();try{if(t===`extension-direct`){let t=await new Promise(t=>{chrome.runtime.sendMessage({type:`secrets.delete`,name:`oauth.${e}.token`},n=>{chrome.runtime.lastError&&A.error(`SW secrets.delete transport failed`,{providerId:e,error:chrome.runtime.lastError.message}),t(n??{})})});t.error&&A.error(`SW secrets.delete returned error`,{providerId:e,error:t.error})}else if(t===`extension-delegate`){let t=await f(`secrets.delete`,{name:`oauth.${e}.token`});t?.error&&A.error(`Bridge secrets.delete returned error`,{providerId:e,error:t.error})}else if(t!==`connect`){let t=await fetch(s(`/api/secrets/oauth/${e}`),{method:`DELETE`,headers:c()});!t.ok&&t.status!==404&&A.warn(`OAuth replica DELETE non-ok`,{providerId:e,status:t.status})}}catch(n){A.error(`OAuth replica removal failed`,{providerId:e,topology:t,error:n instanceof Error?n.message:String(n)})}}async function F(e){let t=M().find(t=>t.providerId===e),n=E(e);t&&n?.isOAuth&&await Re(e),await Le(e),await N(M().filter(t=>t.providerId!==e));let r=localStorage.getItem(x)??``,i=r.indexOf(`:`);i>0&&r.slice(0,i)===e&&localStorage.removeItem(x)}async function Re(e){let t=M().find(t=>t.providerId===e);if(!t)return;let n=E(e);if(n?.isOAuth){if(n.onOAuthLogout)try{await n.onOAuthLogout()}catch(t){A.warn(`onOAuthLogout failed`,{providerId:e,error:t instanceof Error?t.message:String(t)})}if(n.getOAuthLogoutUrl){let r=n.getOAuthLogoutUrl(t);if(r){let{openIdpLogoutUrl:t}=await import(`./oauth-service-IlBYPvwr.js`);await t(r).catch(t=>{A.warn(`IdP logout popup failed`,{providerId:e,error:t instanceof Error?t.message:String(t)})})}}await N(M().map(t=>t.providerId===e?{providerId:t.providerId,apiKey:``,baseUrl:t.baseUrl,userName:t.userName,userAvatar:t.userAvatar,loggedOut:!0}:t)),await Le(e)}}async function ze(e,t={}){let n=Math.max(1,t.attempts??3),r=t.delayMs??150,i=t.sleep??(e=>new Promise(t=>setTimeout(t,e))),a;for(let t=0;t<n;t++){let o=await e();if(o.maskedValue)return{maskedValue:o.maskedValue};o.error&&(a=o.error),t<n-1&&await i(r)}return{lastError:a}}const Be=`access token rotated during mask write`;function I(e,t,n,r){let i=r.find(t=>t.providerId===e);return i?.accessToken?i.accessToken===t?(i.maskedValue=n,{maskedValue:n}):(A.warn(`OAuth mask write raced with token rotation; discarding replica`,{providerId:e}),{error:Be}):{error:`account gone after mask write`}}function L(e,t){return!!e&&e!==t}async function R(e,t,n){let r={providerId:e.providerId,accessToken:e.accessToken,domains:e.domains.join(`,`)},{maskedValue:i,lastError:a}=await ze(()=>t.sendMaskRequest(r),n);if(!L(i,e.accessToken)){let t=i?`mask replica equals the access token`:a??`no error reported (cold SW or empty reply)`;return A.error(`OAuth mask give-up: no masked value after retries`,{providerId:e.providerId,reason:t}),{error:t}}let o=t.getAccounts(),s=I(e.providerId,e.accessToken,i,o);return s.maskedValue&&await t.saveAccounts(o),s}function Ve(e){let t=E(e).oauthTokenDomains??[],n=Me(e),r=new Set,i=[];for(let e of[...t,...n]){let t=e.toLowerCase();r.has(t)||(r.add(t),i.push(e))}return i}function He(e){return new Promise(t=>{chrome.runtime.sendMessage({type:`secrets.mask-oauth-token`,...e},n=>{chrome.runtime.lastError&&A.error(`SW mask-oauth-token transport failed`,{providerId:e.providerId,error:chrome.runtime.lastError.message});let r=typeof n==`object`&&n?n:void 0;r?.error&&A.warn(`SW mask-oauth-token returned error`,{providerId:e.providerId,error:r.error}),t(r??{})})})}function Ue(e){return f(`secrets.mask-oauth-token`,e).then(t=>(t?.error&&A.warn(`Bridge mask-oauth-token returned error`,{providerId:e.providerId,error:t.error}),t??{})).catch(t=>(A.error(`Bridge mask-oauth-token transport failed`,{providerId:e.providerId,error:t instanceof Error?t.message:String(t)}),{}))}async function We(e,t,n){let r=s(`/api/secrets/oauth-update`),i=await fetch(r,{method:`POST`,headers:c({"Content-Type":`application/json`}),body:JSON.stringify({providerId:e,accessToken:t,domains:n})});if(!i.ok)return A.warn(`OAuth replica POST non-ok`,{providerId:e,status:i.status,url:r}),{error:`OAuth replica POST HTTP ${i.status}`};let a=await i.json();if(typeof a.maskedValue!=`string`)return A.warn(`OAuth replica POST ok but missing maskedValue`,{providerId:e,url:r}),{error:`OAuth replica POST ok but missing maskedValue`};if(!L(a.maskedValue,t))return A.error(`OAuth mask replica equals the access token; refusing to persist`,{providerId:e}),{error:`mask replica equals the access token`};let o=M(),l=I(e,t,a.maskedValue,o);return l.maskedValue&&await N(o),l}async function Ge(e,t){let n=await Ke(e,t);if(n.error!==Be)return n;let r=M().find(t=>t.providerId===e)?.accessToken;return!r||r===t?n:Ke(e,r)}async function Ke(e,t){let n=Ve(e);if(n.length===0)return{error:`no oauth token domains configured`};let r=d();try{return r===`extension-direct`?R({providerId:e,accessToken:t,domains:n},{sendMaskRequest:He,getAccounts:M,saveAccounts:N}):r===`extension-delegate`?R({providerId:e,accessToken:t,domains:n},{sendMaskRequest:Ue,getAccounts:M,saveAccounts:N}):r===`connect`?{error:`no replica store in connect mode`}:await We(e,t,n)}catch(t){let n=t instanceof Error?t.message:String(t);return A.error(`OAuth replica sync failed`,{providerId:e,topology:r,error:n}),{error:n}}}async function qe(e){let t=M().find(t=>t.providerId===e);return t?.accessToken?L(t.maskedValue,t.accessToken)?{maskedValue:t.maskedValue}:Ge(e,t.accessToken):{error:`no access token held`}}function Je(e,t){if(e.accessToken)return`scopes`in e?e.scopes:t?.scopes}async function Ye(e){let t=M().find(t=>t.providerId===e.providerId),n=M().filter(t=>t.providerId!==e.providerId);n.push({providerId:e.providerId,apiKey:``,accessToken:e.accessToken,refreshToken:e.refreshToken,tokenExpiresAt:e.tokenExpiresAt,userName:e.userName,userAvatar:e.userAvatar,baseUrl:e.baseUrl??t?.baseUrl,scopes:Je(e,t)}),await N(n),await Ge(e.providerId,e.accessToken)}function z(e){let t=M().find(t=>t.providerId===e);return t&&(t.accessToken||t.apiKey)||null}function B(e){let t=M().find(t=>t.providerId===e);return t?t.accessToken||t.apiKey||(E(e).optionalApiKey?`local`:null):null}function V(e){return M().find(t=>t.providerId===e)?.baseUrl??null}function Xe(e){return M().find(t=>t.providerId===e)?.deployment??null}function Ze(e){return M().find(t=>t.providerId===e)?.apiVersion??null}function H(){let e=localStorage.getItem(x)||``,t=e.indexOf(`:`);return t>=0?e.slice(t+1):e}function Qe(e){let t=e.indexOf(`:`);if(t>0){let n=e.slice(0,t),r=new Set([...i(),...w()]),a=n.includes(`.`);if(r.has(n)||!a){localStorage.setItem(x,e);return}}let n=U();localStorage.setItem(x,`${n}:${e}`)}function $e(){return localStorage.getItem(x)||``}function U(){let e=$e(),t=e.indexOf(`:`);if(t>0)return e.slice(0,t);let n=M(),r=H();if(r){let e=n.find(e=>T(e.providerId)&&we(e.providerId,r));if(e)return e.providerId}let i=n.find(e=>T(e.providerId));return i?i.providerId:n.length>0?n[0].providerId:`anthropic`}function et(e){let t=H();localStorage.setItem(x,`${e}:${t}`)}function tt(){let e=H();localStorage.setItem(x,e)}function nt(){return B(U())}function rt(e){let t=U();P(t,e,V(t)??void 0)}async function it(){await F(U())}function at(){return V(U())}function ot(e){let t=U(),n=z(t);n&&P(t,n,e||void 0)}function st(){let e=U(),t=z(e);t&&P(e,t)}function ct(){let e=M(),t=U(),n=H();return e.map(e=>{let r={providerId:e.providerId,apiKey:e.apiKey};return e.baseUrl&&(r.baseUrl=e.baseUrl),e.providerId===t&&n&&(r.model=n),r})}async function lt(){let e=M();await Promise.allSettled(e.map(e=>F(e.providerId))),localStorage.removeItem(b),localStorage.removeItem(x);for(let e of ve)localStorage.removeItem(e)}function ut(e){return/^(?:gpt[-.]?|o[0-9]|chatgpt)/i.test(e)?`openai`:`anthropic`}function W(e,t,n,r){return{id:t,name:t,provider:e,api:r??`${e}-${ut(t)}`,baseUrl:n??``,contextWindow:2e5,maxTokens:16384,input:[`text`,`image`],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},reasoning:!0}}function G(e,t){return t.isOAuth||e===`azure-ai-foundry`?`anthropic`:e===`bedrock-camp`?`amazon-bedrock`:e}function dt(e,t,n){let r=O(e).find(e=>e.id===t);return r?n?{...r,baseUrl:n}:r:null}function ft(e,t,n,r){return n.isOAuth?O(t).find(e=>e.id===r)||{...e,api:`${t}-anthropic`,provider:t}:t===`bedrock-camp`?{...e,api:`bedrock-camp-converse`,provider:`bedrock-camp`}:e}function pt(e,t,n,r,i){if(t.isOAuth)return dt(e,n,r)??W(e,n,r);if(i)throw Error(`Model ${n} is not available from provider ${e}`);return q()}function K(e,t){if(!e)return q();let n=t??U(),r=V(n),i=E(n);if(t!==void 0){let t=dt(n,e,r);if(t)return t}try{let t=G(n,i),a=v(t,e);if(!a?.id)throw Error(`Model ${e} not found`);let o=ft(a,n,i,e);return r?{...o,baseUrl:r}:o}catch(a){return A.debug(`resolveModelById: pi-ai lookup miss, using provider fallback`,{providerId:n,modelId:e,error:a instanceof Error?a.message:String(a)}),pt(n,i,e,r,t!==void 0)}}function mt(e,t){return e.provider===t||e.provider===G(t,E(t))}function q(){let e=U(),t=H(),n=V(e),r=O(e),i=E(e),a=i.defaultModelId?r.find(e=>e.id.toLowerCase().includes(i.defaultModelId.toLowerCase()))?.id:void 0,o=t||a||r[0]?.id||`claude-sonnet-4-6`;try{let t=G(e,i),a=v(t,o);if(!a?.id)throw Error(`Model ${o} not found in ${t} registry`);let s=a;return i.isOAuth?s=r.find(e=>e.id===o)||{...s,api:`${e}-anthropic`,provider:e}:e===`bedrock-camp`&&(s={...s,api:`bedrock-camp-converse`,provider:`bedrock-camp`}),n&&(s={...s,baseUrl:n}),s}catch(t){A.debug(`resolveCurrentModel: pi-ai lookup miss, using provider fallback`,{providerId:e,effectiveModelId:o,error:t instanceof Error?t.message:String(t)});let a=r.find(e=>e.id===o);return a?n?{...a,baseUrl:n}:a:i.isOAuth?W(e,o,n):v(`anthropic`,`claude-sonnet-4-0`)}}function ht(e){let t=e.toLowerCase();if(!t)return null;let n=null;try{n=U()}catch{}if(n!==null){let e=J(t,[n]);if(e!==null)return e}return J(t,M().map(e=>e.providerId))}function J(e,t){let n=null,r=-1;for(let i of t)for(let t of O(i)){let i=t.id.toLowerCase(),a=(t.name??``).toLowerCase();if(!i.includes(e)&&!a.includes(e))continue;let o=t.contextWindow??0;(o>r||o===r&&Ct(t.id,n??``)>0)&&(r=o,n=t.id)}return n}function Y(){let e=[];try{for(let t of M())e.includes(t.providerId)||e.push(t.providerId)}catch{}try{let t=U();e.includes(t)||e.push(t)}catch{}return e}function gt(e){let t=e.indexOf(`:`);if(t<=0||t===e.length-1)return null;let n=e.slice(0,t),r=e.slice(t+1),i=Y().includes(n);if(i)return{providerId:n,modelId:r,configured:i};let a=!1;try{a=w().includes(n)}catch{}return a?{providerId:n,modelId:r,configured:!1}:null}function X(e,t,n=!0){let r=[e],i=n?J(e.toLowerCase(),[t]):null;i!==null&&i!==e&&r.push(i);let a=[];try{a=O(t)}catch{}for(let n of r)if(!(a.length>0&&!a.some(e=>e.id===n)))try{if(K(n,t).id===n)return{modelId:n,providerId:t}}catch(r){A.debug(`selectModelFromProvider: candidate did not resolve`,{input:e,candidate:n,providerId:t,error:r instanceof Error?r.message:String(r)})}return null}function _t(e){return e.map(e=>`${e.providerId}:${e.modelId}`).join(`, `)}function Z(e){if(!e)return{ok:!1,error:`unknown model: (empty)`};let t=gt(e);if(t)return bt(e,t);let n=null;try{n=U()}catch{}if(n!==null){let t=X(e,n);if(t)return $(t)}return xt(e,n)}function Q(){try{return U()}catch{return null}}function vt(e){let t=Q();return t===null||pe(_(),t,e.providerId,e.modelId)}function yt(e){let t=Q()??`<none>`;return{ok:!1,error:`model not allowed: ${`${e.providerId}:${e.modelId}`} is blocked by ${m} while "${t}" is selected — ${ge(t,e.providerId,e.modelId)}`}}function $(e){return vt(e)?{ok:!0,selection:e}:yt(e)}function bt(e,t){if(!t.configured){let n=Y();return{ok:!1,error:`unknown model: ${e} (provider "${t.providerId}" is not configured${n.length>0?`; configured: ${n.join(`, `)}`:``})`}}let n=X(t.modelId,t.providerId);return n?$(n):{ok:!1,error:`unknown model: ${e} (provider "${t.providerId}" does not offer "${t.modelId}")`}}function xt(e,t){let n=Y().filter(e=>e!==t);for(let t of[`exact`,`shorthand`]){let r=[];for(let i of n){let n=t===`exact`?e:J(e.toLowerCase(),[i]);if(n===null)continue;let a=X(n,i,!1);a&&r.push(a)}let i=r.filter(vt);if(i.length===0&&r.length>0)return yt(r[0]);if(i.length===1)return{ok:!0,selection:i[0]};if(i.length>1)return{ok:!1,error:`ambiguous model: ${e} matches ${_t(i)} — qualify it as provider:model`}}return{ok:!1,error:`unknown model: ${e}`}}function St(e){let t=Z(e);return t.ok?t.selection.modelId:null}function Ct(e,t){let n=e.match(/\d+/g)?.map(Number)??[],r=t.match(/\d+/g)?.map(Number)??[],i=Math.max(n.length,r.length);for(let e=0;e<i;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t}return 0}export{se as S,Ye as _,B as a,ue as b,Xe as c,H as d,U as f,Z as g,K as h,nt as i,k as l,q as m,qe as n,Ze as o,mt as p,M as r,V as s,_e as t,O as u,m as v,he as x,h as y};
|