agent-policy-kit 0.1.0 → 0.3.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/AGENT_INSTALL.md +11 -7
- package/CHANGELOG.md +81 -0
- package/README.md +18 -40
- package/bin/agent-policy.mjs +28 -13
- package/docs/architecture.md +1 -1
- package/docs/assets/configurator.png +0 -0
- package/docs/assets/subagent-limits.svg +44 -0
- package/docs/compatibility.md +23 -5
- package/docs/configuration-page.md +15 -9
- package/docs/deployment.md +33 -0
- package/docs/design/2026-11-01-grok-build-support.md +30 -0
- package/docs/development.md +11 -1
- package/docs/installation.md +10 -2
- package/docs/limits-evidence.md +24 -0
- package/docs/model-catalog.md +49 -41
- package/docs/npm-release.md +4 -2
- package/docs/policy.md +3 -3
- package/docs/releases.md +4 -4
- package/docs/use-cases.md +3 -3
- package/docs/verification.md +39 -2
- package/models/catalog.json +49 -5
- package/package.json +12 -4
- package/policies/balanced.json +25 -2
- package/policies/fast.json +14 -3
- package/policies/quality.json +30 -9
- package/schema/policy.schema.json +100 -2
- package/site/index.html +294 -102
- package/src/detect.mjs +62 -13
- package/src/explicit.mjs +15 -8
- package/src/inspect.mjs +203 -0
- package/src/install.mjs +24 -8
- package/src/native.mjs +13 -9
- package/src/output.mjs +108 -0
- package/src/policy.mjs +4 -3
- package/src/release.mjs +1 -1
- package/src/setup.mjs +1 -1
- package/src/share.mjs +47 -16
package/site/index.html
CHANGED
|
@@ -4,8 +4,12 @@
|
|
|
4
4
|
<meta charset="utf-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
6
|
<meta name="color-scheme" content="light">
|
|
7
|
-
<meta name="description" content="Configure subagent models
|
|
8
|
-
<
|
|
7
|
+
<meta name="description" content="Configure local subagent roles, models and effort with Agent Policy Kit, an open source tool by Mykola Maksymenko.">
|
|
8
|
+
<meta name="author" content="Mykola Maksymenko">
|
|
9
|
+
<link rel="author" href="https://www.linkedin.com/in/nick-maximenko/">
|
|
10
|
+
<link rel="canonical" href="https://agent-policy-kit.trymenow.io/v/0.3.0/">
|
|
11
|
+
<title>Agent Policy Kit — by Mykola Maksymenko</title>
|
|
12
|
+
<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Person","@id":"https://www.linkedin.com/in/nick-maximenko/#person","name":"Mykola Maksymenko","url":"https://www.linkedin.com/in/nick-maximenko/"},{"@type":"SoftwareSourceCode","@id":"https://github.com/automatis-tools/agent-policy-kit#software","name":"Agent Policy Kit","description":"Configure native subagent settings across AI assistants, then exit","url":"https://agent-policy-kit.trymenow.io/","codeRepository":"https://github.com/automatis-tools/agent-policy-kit","author":{"@id":"https://www.linkedin.com/in/nick-maximenko/#person"}},{"@type":"WebPage","@id":"https://agent-policy-kit.trymenow.io/v/0.3.0/#webpage","name":"Agent Policy Kit — by Mykola Maksymenko","url":"https://agent-policy-kit.trymenow.io/v/0.3.0/","author":{"@id":"https://www.linkedin.com/in/nick-maximenko/#person"},"mainEntity":{"@id":"https://github.com/automatis-tools/agent-policy-kit#software"},"mentions":[{"@type":"SoftwareSourceCode","name":"Agents Can Communicate","codeRepository":"https://github.com/automatis-tools/agents-can-communicate"},{"@type":"SoftwareSourceCode","name":"Automatis Skills","codeRepository":"https://github.com/automatis-tools/automatis-skills"}]}]}</script>
|
|
9
13
|
<!-- Public Sans is embedded under the SIL Open Font License.
|
|
10
14
|
Copyright 2015 The Public Sans Project Authors (https://github.com/uswds/public-sans)
|
|
11
15
|
|
|
@@ -214,7 +218,7 @@ pre:has(.code-copy) { padding-top: 46px; }
|
|
|
214
218
|
@font-face{font-family:'Public Sans';font-style:normal;font-weight:400 700;font-display:swap;src:url('data:font/woff2;base64,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') format('woff2')}
|
|
215
219
|
:root{--mono:ui-monospace,SFMono-Regular,Consolas,monospace;--text-hero:36px;--text-section:20px;--text-ui:15px;--text-support:15px;--text-meta:13px;--success:#237347;--success-paper:#edf7f0;--success-line:#c4dfce}
|
|
216
220
|
*{box-sizing:border-box}body{background:var(--white)}button,input,select{font:inherit}button{cursor:pointer}button:disabled{cursor:default}:focus-visible{outline:2px solid var(--accent);outline-offset:4px}[hidden]{display:none!important}::selection{color:var(--ink);background:var(--selection)}
|
|
217
|
-
header,main,footer{width:min(calc(100% - 64px),920px);margin-inline:auto}header{min-height:74px;display:flex;align-items:center;gap:12px;border-bottom:1px solid var(--line)}.mark{display:grid;place-items:center;min-width:42px;height:34px;background:var(--brand-blue);border-bottom:3px solid var(--brand-yellow);border-radius:5px;color:var(--white);font-size:14px;font-weight:650;letter-spacing:-.5px}.brand{font-size:16px;font-weight:600;letter-spacing:-.2px}.
|
|
221
|
+
header,main,footer{width:min(calc(100% - 64px),920px);margin-inline:auto}header{min-height:74px;display:flex;align-items:center;gap:12px;border-bottom:1px solid var(--line)}.mark{display:grid;place-items:center;min-width:42px;height:34px;background:var(--brand-blue);border-bottom:3px solid var(--brand-yellow);border-radius:5px;color:var(--white);font-size:14px;font-weight:650;letter-spacing:-.5px}.brand{font-size:16px;font-weight:600;letter-spacing:-.2px}.repo-link{margin-left:auto;display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border:1px solid var(--line);border-radius:5px;color:var(--ink);font-size:var(--text-meta);font-weight:500;line-height:1.3;text-decoration:none}.repo-link:hover{background:var(--control-hover);color:var(--accent)}.repo-link svg{flex-shrink:0}
|
|
218
222
|
.intro{margin:32px 0}.intro h1{margin:0 0 12px;font-size:var(--text-hero);font-weight:650;line-height:1.2;letter-spacing:-.035em}.intro p{margin:0;color:var(--muted);font-size:var(--text-ui);line-height:1.7;max-width:70ch}
|
|
219
223
|
.builder{--step-gap:32px;display:grid;gap:var(--step-gap)}.builder>section{position:relative;padding-left:34px}.builder>section:not(:last-child)::before{content:"";position:absolute;left:10px;top:13px;width:2px;height:calc(100% + var(--step-gap));background:var(--line);pointer-events:none}.builder>section>.step-heading>.step-number{position:absolute;left:0;top:2px;z-index:1}.step-heading{display:flex;align-items:center;gap:10px;margin-bottom:12px}.step-heading h2{margin:0;font-size:var(--text-section);line-height:1.4;font-weight:600;letter-spacing:-.015em}.step-number{display:grid;place-items:center;width:22px;height:22px;background:var(--paper);border:1px solid var(--line);border-radius:50%;color:var(--muted);font:400 var(--text-meta)/1 var(--mono)}.step-hint{margin-left:auto;padding:3px 6px;border-radius:4px;color:var(--accent);font-size:var(--text-meta);line-height:1.4;font-weight:500}.step-hint[data-success=true]{color:var(--success);font-weight:600}
|
|
220
224
|
.tag-box{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:56px;padding:10px 12px;background:var(--white);border:1px solid var(--line);border-radius:7px}.tag-box:focus-within{outline:2px solid var(--accent);outline-offset:2px}.empty{padding:5px 1px;font-size:var(--text-ui);color:var(--muted)}.suggestions{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;min-height:34px}.suggestion{padding:6px 11px;border:1px dashed var(--line);border-radius:5px;background:var(--white);color:var(--ink);font-size:var(--text-ui);line-height:1.4;font-weight:400}.suggestion:hover{border-color:var(--brand-blue);background:var(--control-hover);color:var(--accent)}.plus{color:var(--accent);margin-right:5px}
|
|
@@ -222,11 +226,12 @@ header,main,footer{width:min(calc(100% - 64px),920px);margin-inline:auto}header{
|
|
|
222
226
|
.tool-group{display:flex;gap:4px;min-height:54px;padding:4px;border:1px solid var(--line);border-radius:7px;background:var(--paper)}.tool-group .tool-scope{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-width:0;min-height:44px;padding:8px 28px 8px 13px;border:0;border-radius:5px;background:transparent;color:var(--ink);font-size:var(--text-ui);font-weight:500;line-height:1.4}.tool-group .tool-scope small{border-radius:3px;font-size:var(--text-meta);font-weight:400;line-height:1.5;color:var(--muted)}.tool-group .tool-scope:hover{background:var(--control-hover);color:var(--accent)}.tool-item.active .tool-scope{background:transparent;color:var(--accent);font-weight:600}.tool-item.active{box-shadow:inset 0 -2px 0 var(--brand-blue)}.tool-item{position:relative;display:flex;flex:1;min-width:0;border:1px solid var(--line);border-radius:5px;background:var(--control-hover)}.tool-item .tool-scope{width:100%}.tool-remove{position:absolute;right:4px;top:50%;transform:translateY(-50%);display:grid;place-items:center;width:24px;height:30px;border:0;border-radius:4px;background:transparent;color:var(--muted);font-size:15px;opacity:.8}.tool-item.active .tool-remove{color:var(--muted)}.tool-remove:hover{background:var(--control-hover);opacity:1}.tool-item.active .tool-remove:hover{background:var(--control-hover);color:var(--accent)}
|
|
223
227
|
.mode-heading{display:flex;align-items:center;justify-content:space-between;margin:0 0 16px}.scope-label{display:inline-block;padding:3px 6px;margin-left:-6px;border-radius:4px;color:var(--muted);font-size:var(--text-support);line-height:1.5}.mode-placeholder{padding:20px;border:1px dashed var(--line);border-radius:7px;color:var(--muted);font-size:var(--text-support)}#mode-options{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));margin:0 0 16px}#mode-options::before{content:"";position:absolute;top:13px;left:12.5%;right:12.5%;height:2px;background:var(--line)}.mode-option{position:relative;z-index:1;display:grid;grid-template-rows:20px auto;align-content:start;align-items:center;justify-items:center;gap:10px;padding:4px;text-align:center;font-size:var(--text-ui);font-weight:400;line-height:1.5;cursor:pointer}.mode-option input{appearance:none;position:relative;z-index:1;width:10px;height:10px;margin:0;border:0;border-radius:50%;background:var(--muted);cursor:pointer}.mode-option input:checked{width:18px;height:18px;border:3px solid var(--white);box-shadow:0 0 0 2px var(--brand-blue);background:var(--brand-blue)}.mode-option input:checked+span{color:var(--accent);font-weight:600}.mode-option:has(input:disabled){cursor:default}.notice{padding:0;margin:0 0 14px;color:var(--muted);font-size:var(--text-support);line-height:1.6}
|
|
224
228
|
.advanced{border-top:1px solid var(--line);padding-top:12px}.advanced summary{width:fit-content;color:var(--accent);font-size:var(--text-support);line-height:1.5;cursor:pointer}.editor{display:grid;grid-template-columns:140px minmax(0,1fr) minmax(0,1fr);gap:16px;align-items:end;margin-top:16px}.editor label{display:block;margin-bottom:7px;color:var(--muted);font-size:var(--text-support);line-height:1.4}.editor select{appearance:none;width:100%;min-width:0;height:42px;padding:0 32px 0 10px;border:1px solid var(--line);border-radius:5px;background:var(--white) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m4 6 4 4 4-4' stroke='%2359657a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 10px center/16px 16px;color:var(--ink);font-size:var(--text-ui)}.efforts{display:flex;gap:3px;align-items:center;min-height:42px;padding:3px;border:1px solid var(--line);border-radius:6px;background:var(--paper)}.efforts button{flex:1;min-height:32px;padding:5px;border:0;border-radius:4px;background:transparent;color:var(--muted);font-size:var(--text-support)}.efforts button[aria-pressed=true]{background:var(--control-hover);color:var(--accent);font-weight:600;box-shadow:inset 0 0 0 1px var(--brand-blue)}.unavailable{width:100%;text-align:center;color:var(--muted);font-size:var(--text-support)}.role-description{margin:10px 0 0;color:var(--muted);font-size:var(--text-support);line-height:1.6}
|
|
225
|
-
.output{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:12px 20px;padding:18px 20px;border:1px solid var(--line);border-radius:6px;background:var(--paper)}.output[data-ready=true]{border-color:var(--brand-blue)}.output strong{font-size:var(--text-ui);font-weight:600;line-height:1.5}.output p{margin:5px 0 0;color:var(--muted);font-size:var(--text-support);line-height:1.6}.output p a{color:var(--accent);text-underline-offset:3px}.output[data-ready=false] .primary{background:var(--line);border-color:var(--line);color:var(--muted);opacity:1}.primary{white-space:nowrap}
|
|
226
|
-
footer{display:
|
|
229
|
+
.output{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:start;gap:12px 20px;padding:18px 20px;border:1px solid var(--line);border-radius:6px;background:var(--paper)}.output[data-ready=true]{border-color:var(--brand-blue)}.output strong{font-size:var(--text-ui);font-weight:600;line-height:1.5}.output p{margin:5px 0 0;color:var(--muted);font-size:var(--text-support);line-height:1.6}.output p:empty{display:none}.output p a{color:var(--accent);text-underline-offset:3px}.output[data-ready=false] .primary{background:var(--line);border-color:var(--line);color:var(--muted);opacity:1}.primary{white-space:nowrap}
|
|
230
|
+
footer{display:grid;gap:14px;margin-top:20px;padding:16px 0 24px;border-top:1px solid var(--line);color:var(--muted);font-size:var(--text-meta);line-height:1.6}.footer-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px 24px;flex-wrap:wrap}.footer-attribution{display:flex;align-items:baseline;gap:4px 24px;flex-wrap:wrap;font-size:var(--text-meta)}.footer-attribution nav{display:flex;align-items:baseline;gap:4px 10px;flex-wrap:wrap}
|
|
227
231
|
@media(forced-colors:active){.tag,.suggestion{border-color:ButtonText}.tool-group .tool-scope[aria-pressed=true],.efforts button[aria-pressed=true]{outline:2px solid ButtonText;outline-offset:-3px}.mode-option input{appearance:auto}#mode-options::before{height:0;border-top:2px solid CanvasText}.editor select{appearance:auto;background-image:none}}
|
|
228
232
|
|
|
229
233
|
html{scrollbar-gutter:stable}body{overflow-anchor:none}
|
|
234
|
+
.suggestion.add-all{border-style:solid;background:var(--paper)}.suggestion.add-all:hover{background:var(--control-hover)}
|
|
230
235
|
.helper-option{display:inline-flex;align-items:stretch;border:1px dashed var(--line);border-radius:5px;background:var(--white)}.helper-option>.suggestion{border:0;background:transparent;border-radius:4px 0 0 4px;padding-right:5px}.helper-option:hover{border-color:var(--brand-blue);background:var(--control-hover)}.helper-option:hover>.suggestion{color:var(--accent)}
|
|
231
236
|
.helper-info{display:grid;place-items:center;align-self:stretch;flex-shrink:0;width:27px;min-height:28px;border:0;padding:0 5px;background:transparent;color:var(--accent);cursor:help;border-radius:4px}.helper-info:hover{background:var(--control-hover)}.info-dot{display:grid;place-items:center;width:16px;height:16px;border:1px solid currentColor;border-radius:50%;font-size:10px;line-height:1;font-weight:600}.tag .helper-info{margin-right:3px}.tag .tag-label{padding-right:4px}
|
|
232
237
|
.role-tooltip{position:fixed;z-index:1000;width:min(420px,calc(100vw - 32px));padding:16px;border:1px solid var(--line);border-radius:8px;background:var(--white);color:var(--ink);box-shadow:0 6px 15px #19283e07;opacity:0;transform:translateY(3px);transition:opacity 120ms ease,transform 120ms ease;view-transition-name:role-tooltip}.role-tooltip.visible{opacity:1;transform:none}.role-tooltip strong{font-size:14px;font-weight:600}.role-tooltip p{font-size:var(--text-ui);line-height:1.7;margin:9px 0 14px;color:var(--muted)}.role-tooltip .definition-label{font-size:var(--text-meta);font-weight:600;color:var(--muted);margin:0 0 7px}.role-tooltip pre{margin:0;padding:11px;border:1px solid var(--line);border-radius:5px;background:var(--paper);white-space:pre-wrap;font:var(--text-meta)/1.7 var(--mono)}.role-tooltip .definition-note{margin:10px 0 0;font-size:var(--text-meta)}
|
|
@@ -245,40 +250,84 @@ section[aria-labelledby=helpers-heading]{view-transition-name:step-helpers}secti
|
|
|
245
250
|
|
|
246
251
|
|
|
247
252
|
.advanced h3{margin:0 0 12px;font-size:var(--text-ui);font-weight:600;line-height:1.5;color:var(--ink)}
|
|
248
|
-
.setup-result{display:contents}.setup-result>[aria-live]{grid-column:1;grid-row:1;min-width:0}.output>.primary{grid-column:2;grid-row:1;align-self:start}#copy-feedback{grid-column:1/-1;grid-row:3}.setup-command{grid-column:1/-1;grid-row:2;display:block;width:100%;min-width:0;margin-top:0;padding:9px 10px;border:1px solid var(--line);border-radius:5px;background:var(--white);color:var(--ink);font:var(--text-meta)/1.7 var(--mono);field-sizing:content;white-space:pre-wrap;overflow-wrap:anywhere;overflow:hidden;resize:none}.release-status{margin:9px 0 0;color:var(--muted);font-size:var(--text-meta);line-height:1.5}.model-control{min-width:0}.custom-model{display:block;width:100%;margin-top:7px;padding:8px 10px;border:1px solid var(--line);border-radius:5px;background:var(--white);color:var(--ink);font-size:var(--text-ui)}.custom-model[aria-invalid=true]{border-color:var(--amber)}
|
|
253
|
+
.concurrency{margin-top:16px;padding-top:12px;border-top:1px solid var(--line)}.concurrency-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.concurrency label{color:var(--ink);font-size:var(--text-ui);font-weight:400;line-height:1.5}.concurrency-stepper{display:inline-flex;flex-shrink:0;align-items:stretch;border:1px solid var(--line);border-radius:5px;background:var(--paper)}.concurrency-stepper button{display:grid;place-items:center;width:42px;min-height:42px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--ink);font-size:var(--text-ui);font-weight:400;line-height:1.5}.concurrency-stepper button:hover:not(:disabled){background:var(--control-hover);color:var(--accent)}.concurrency-stepper button:disabled{color:var(--muted);opacity:.4}.concurrency input{appearance:textfield;width:56px;min-width:0;margin:0;padding:8px 4px;border:0;border-inline:1px solid var(--line);border-radius:0;background:var(--white);color:var(--ink);font:inherit;font-size:var(--text-ui);font-weight:400;line-height:1.5;font-variant-numeric:tabular-nums;text-align:center}.concurrency input::-webkit-inner-spin-button,.concurrency input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.concurrency input:focus-visible{outline-offset:-2px}.concurrency input[aria-invalid=true]{box-shadow:inset 0 0 0 1px var(--amber)}.concurrency .field-error{margin:8px 0 0;color:var(--muted);font-size:var(--text-support);line-height:1.6}.concurrency .field-error{color:var(--ink)}.setup-result{display:contents}.setup-result>[aria-live]{grid-column:1;grid-row:1;min-width:0}.output>.primary{grid-column:2;grid-row:1;align-self:start}#copy-feedback{grid-column:1/-1;grid-row:3}.setup-command{grid-column:1/-1;grid-row:2;display:block;width:100%;min-width:0;margin-top:0;padding:9px 10px;border:1px solid var(--line);border-radius:5px;background:var(--white);color:var(--ink);font:var(--text-meta)/1.7 var(--mono);field-sizing:content;white-space:pre-wrap;overflow-wrap:anywhere;overflow:hidden;resize:none}.quiet-button{margin-left:6px;padding:1px 8px;border:1px solid var(--line);border-radius:4px;background:transparent;color:var(--muted);font-size:var(--text-meta);line-height:1.5}.quiet-button:hover{background:var(--control-hover);color:var(--accent)}.show-settings{display:inline-flex;align-items:center;flex-wrap:wrap;gap:0 2px;font-size:var(--text-ui)}.show-settings .quiet-button{padding:2px 10px;font-size:var(--text-ui)}.show-settings code:not([hidden]){flex-basis:100%;margin-top:4px;font-family:var(--mono);color:var(--ink);overflow-wrap:anywhere;user-select:all}.setup-footer{display:flex;align-items:baseline;justify-content:space-between;gap:16px;margin-top:9px}.setup-footer .release-status{margin:0}.release-status{margin:9px 0 0;color:var(--muted);font-size:var(--text-meta);line-height:1.5}.model-control{min-width:0}.custom-model{display:block;width:100%;margin-top:7px;padding:8px 10px;border:1px solid var(--line);border-radius:5px;background:var(--white);color:var(--ink);font-size:var(--text-ui)}.custom-model[aria-invalid=true]{border-color:var(--amber)}
|
|
249
254
|
|
|
250
255
|
|
|
251
256
|
#selected-tools[hidden]+#tool-options{margin-top:0}
|
|
252
257
|
|
|
253
258
|
.tool-group .empty{align-self:center;padding:8px 9px}
|
|
259
|
+
.tool-group.is-empty{min-height:56px;padding:10px 12px;background:var(--white)}.tool-group.is-empty .empty{padding:5px 1px}
|
|
260
|
+
.top-models{margin-top:14px}.top-models [role=switch]{display:inline-flex;align-items:center;gap:10px;padding:2px 0;border:0;background:transparent;color:var(--ink);font-size:var(--text-ui);text-align:left;cursor:pointer}.switch-track{position:relative;flex-shrink:0;width:34px;height:20px;border-radius:10px;background:var(--line);transition:background-color .15s}.switch-track::before{content:'';position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--white);box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .15s}.top-models [aria-checked=true] .switch-track,.top-models [data-mixed] .switch-track{background:var(--accent)}.top-models [aria-checked=true] .switch-track::before{transform:translateX(14px)}.top-models [data-mixed] .switch-track::before{transform:translateX(7px)}@media(forced-colors:active){.switch-track{border:1px solid ButtonText}.switch-track::before{background:ButtonText;box-shadow:none}}
|
|
254
261
|
.tool-group>.scope-all{padding:8px 13px}.tool-group>.scope-all[aria-pressed=true]{background:var(--control-hover);color:var(--accent);font-weight:600;box-shadow:inset 0 -2px 0 var(--brand-blue)}
|
|
255
262
|
|
|
256
263
|
.reset-form{padding:4px 0;border:0;background:transparent;color:var(--muted);font-size:var(--text-support);text-decoration:underline;text-underline-offset:3px}.reset-form:hover{color:var(--accent)}.intro .link-error{margin-top:12px;color:var(--amber);font-size:var(--text-support)}.builder>section[data-complete=true]>.step-heading>.step-number{background:var(--success-paper);border-color:var(--success-line);color:var(--success);font-size:14px;font-weight:600}.builder>section[data-complete=true]::before{background:var(--success-line)}
|
|
257
264
|
|
|
258
|
-
.how-it-works{margin-top:18px;border:1px solid var(--line);border-radius:7px;background:var(--paper);interpolate-size:allow-keywords}.how-it-works summary{padding:14px 16px;color:var(--accent);font-size:var(--text-ui);font-weight:500;line-height:1.5;cursor:pointer}.how-it-works summary:hover{background:var(--control-hover);border-radius:6px}.how-it-works::details-content{height:0;overflow:hidden;opacity:0;transition:height 200ms ease,opacity 180ms ease,content-visibility 200ms allow-discrete}.how-it-works[open]::details-content{height:auto;opacity:1}.how-it-works .explanation{padding:2px 16px 18px;display:grid;gap:14px}.intro .how-it-works p{max-width:70ch;font-size:var(--text-ui);line-height:1.7}.how-it-works strong{color:var(--ink);font-weight:600}@media(prefers-reduced-motion:reduce){.how-it-works::details-content{transition:none}}
|
|
259
|
-
@media(max-width:600px){header,main,footer{width:calc(100% - 32px)}.intro h1{font-size:30px}.step-heading{flex-wrap:wrap;gap:6px 10px}.step-hint{flex-basis:100%;margin-left:0;padding-left:0}.output{grid-template-columns:minmax(0,1fr);padding:16px}.output>.primary{grid-column:1;grid-row:2;justify-self:start}.setup-command{grid-row:3}#copy-feedback{grid-row:4}.editor-head{display:none}.editor-row{grid-template-columns:minmax(0,1fr);gap:10px;padding:16px 0}.editor-name{font-weight:600}.tool-group{flex-wrap:wrap}.tool-item{flex-basis:calc(50% - 4px)}.tool-group>.scope-all{flex-basis:100%}.tool-group .tool-scope{padding-left:8px;padding-right:24px}.mode-option{font-size:var(--text-meta);gap:12px}.brand{font-size:15px}header{gap:9px}footer{
|
|
265
|
+
.how-it-works{margin-top:18px;border:1px solid var(--line);border-radius:7px;background:var(--paper);interpolate-size:allow-keywords}.how-it-works summary{padding:14px 16px;color:var(--accent);font-size:var(--text-ui);font-weight:500;line-height:1.5;cursor:pointer}.how-it-works summary:hover{background:var(--control-hover);border-radius:6px}.how-it-works::details-content{height:0;overflow:hidden;opacity:0;transition:height 200ms ease,opacity 180ms ease,content-visibility 200ms allow-discrete}.how-it-works[open]::details-content{height:auto;opacity:1}.how-it-works .explanation{padding:2px 16px 18px;display:grid;gap:14px}.intro .how-it-works p{max-width:70ch;font-size:var(--text-ui);line-height:1.7}.how-it-works strong{color:var(--ink);font-weight:600}.limits-chart{overflow-x:auto}.limits-chart svg{display:block;width:100%;min-width:560px;height:auto;border:1px solid var(--line);border-radius:12px}@media(prefers-reduced-motion:reduce){.how-it-works::details-content{transition:none}}
|
|
266
|
+
@media(max-width:600px){header,main,footer{width:calc(100% - 32px)}.intro h1{font-size:30px}.step-heading{flex-wrap:wrap;gap:6px 10px}.step-hint{flex-basis:100%;margin-left:0;padding-left:0}.output{grid-template-columns:minmax(0,1fr);padding:16px}.output>.primary{grid-column:1;grid-row:2;justify-self:start}.setup-command{grid-row:3}#copy-feedback{grid-row:4}.editor-head{display:none}.editor-row{grid-template-columns:minmax(0,1fr);gap:10px;padding:16px 0}.editor-name{font-weight:600}.tool-group{flex-wrap:wrap}.tool-item{flex-basis:calc(50% - 4px)}.tool-group>.scope-all{flex-basis:100%}.tool-group .tool-scope{padding-left:8px;padding-right:24px}.mode-option{font-size:var(--text-meta);gap:12px}.brand{font-size:15px}header{gap:9px}footer{gap:14px}}
|
|
260
267
|
</style></head><body>
|
|
261
|
-
<header><span class="mark" aria-hidden="true">apk</span><span class="brand">Agent Policy Kit</span><
|
|
268
|
+
<header><span class="mark" aria-hidden="true">apk</span><span class="brand">Agent Policy Kit</span><a class="repo-link" href="https://github.com/automatis-tools/agent-policy-kit" target="_blank" rel="noopener noreferrer" aria-label="Agent Policy Kit on GitHub"><svg viewBox="0 0 16 16" width="16" height="16" aria-hidden="true" focusable="false"><path fill="currentColor" d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"/></svg><span>GitHub</span></a></header>
|
|
262
269
|
<main>
|
|
263
|
-
<div class="intro"><h1>
|
|
264
|
-
<
|
|
265
|
-
<
|
|
270
|
+
<div class="intro"><h1>Stop subagents from burning your plan limits.</h1><p>Give each subagent role a model that fits the task and your plan. Four steps, one command.</p><details class="how-it-works"><summary>Why: one weekly limit lasted 5.3 h of work without APK and 25 h with it</summary><div class="explanation">
|
|
271
|
+
<div class="limits-chart"><svg xmlns="http://www.w3.org/2000/svg" class="apk-limits" viewBox="0 0 880 322" width="880" height="322" role="img" aria-labelledby="apk-limits-title">
|
|
272
|
+
<title id="apk-limits-title">One weekly Codex limit lasted 5.3 h of my work without APK and 25 h with APK</title>
|
|
273
|
+
<defs>
|
|
274
|
+
<pattern id="apk-limits-hatch" width="8" height="8" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
|
|
275
|
+
<rect width="8" height="8" class="hb"/><line x1="0" y1="0" x2="0" y2="8" class="hl"/>
|
|
276
|
+
</pattern>
|
|
277
|
+
</defs>
|
|
278
|
+
<style>
|
|
279
|
+
.apk-limits { --bg:#ffffff; --ink:#0b0b0b; --ink2:#52514e; --ink3:#8a8984; --hb:#f4f3ef; --hl:#e2e0d9; --before:#eb6834; --after:#2a78d6; }
|
|
280
|
+
.apk-limits text { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; fill: var(--ink); }
|
|
281
|
+
.apk-limits .bg { fill: var(--bg); }
|
|
282
|
+
.apk-limits .h1 { font-size: 24px; font-weight: 700; }
|
|
283
|
+
.apk-limits .sub { font-size: 14px; fill: var(--ink2); }
|
|
284
|
+
.apk-limits .day { font-size: 12px; font-weight: 600; fill: var(--ink3); }
|
|
285
|
+
.apk-limits .hb { fill: var(--hb); } .apk-limits .hl { stroke: var(--hl); stroke-width: 3; }
|
|
286
|
+
.apk-limits .before { fill: var(--before); } .apk-limits .after { fill: var(--after); }
|
|
287
|
+
.apk-limits .sep { stroke: var(--bg); stroke-width: 2; }
|
|
288
|
+
.apk-limits .rl { font-size: 15px; font-weight: 650; }
|
|
289
|
+
.apk-limits .rn { font-size: 14px; font-weight: 400; fill: var(--ink2); }
|
|
290
|
+
.apk-limits .val { font-size: 18px; font-weight: 700; }
|
|
291
|
+
.apk-limits .chip { fill: var(--bg); }
|
|
292
|
+
</style>
|
|
293
|
+
<rect class="bg" width="880" height="322" rx="12"/>
|
|
294
|
+
<text class="h1" x="32" y="48">One weekly limit: 5.3 h vs 25 h of work</text>
|
|
295
|
+
<text class="sub" x="32" y="74">My own Codex work on the same plan, in 8-hour workdays. Hatched: limit used up.</text>
|
|
296
|
+
<text class="day" x="113.6" y="114" text-anchor="middle">Mon</text><text class="day" x="276.8" y="114" text-anchor="middle">Tue</text><text class="day" x="440.0" y="114" text-anchor="middle">Wed</text><text class="day" x="603.2" y="114" text-anchor="middle">Thu</text><text class="day" x="766.4" y="114" text-anchor="middle">Fri</text>
|
|
297
|
+
|
|
298
|
+
<text class="rl" x="32" y="140">Without APK<tspan class="rn"> · half of subagent work ran on the top model</tspan></text>
|
|
299
|
+
<rect fill="url(#apk-limits-hatch)" x="32" y="152" width="816" height="48" rx="8"/>
|
|
300
|
+
<rect class="before" x="32" y="152" width="108.8" height="48" rx="8"/>
|
|
301
|
+
<line class="sep" x1="195.2" x2="195.2" y1="152" y2="200"/><line class="sep" x1="358.4" x2="358.4" y1="152" y2="200"/><line class="sep" x1="521.6" x2="521.6" y1="152" y2="200"/><line class="sep" x1="684.8" x2="684.8" y1="152" y2="200"/>
|
|
302
|
+
<rect class="chip" x="150.8" y="161" width="71" height="30" rx="6"/>
|
|
303
|
+
<text class="val" x="158.8" y="183">5.3 h</text>
|
|
304
|
+
|
|
305
|
+
<text class="rl" x="32" y="228">With APK<tspan class="rn"> · each role ran on a model that fits the task and the plan</tspan></text>
|
|
306
|
+
<rect fill="url(#apk-limits-hatch)" x="32" y="240" width="816" height="48" rx="8"/>
|
|
307
|
+
<rect class="after" x="32" y="240" width="510.0" height="48" rx="8"/>
|
|
308
|
+
<line class="sep" x1="195.2" x2="195.2" y1="240" y2="288"/><line class="sep" x1="358.4" x2="358.4" y1="240" y2="288"/><line class="sep" x1="521.6" x2="521.6" y1="240" y2="288"/><line class="sep" x1="684.8" x2="684.8" y1="240" y2="288"/>
|
|
309
|
+
<rect class="chip" x="552.0" y="249" width="60" height="30" rx="6"/>
|
|
310
|
+
<text class="val" x="560.0" y="271">25 h</text>
|
|
311
|
+
</svg>
|
|
312
|
+
</div>
|
|
313
|
+
<p>From my own Codex logs; tasks differed between the runs. <a href="https://github.com/automatis-tools/agent-policy-kit/blob/main/docs/limits-evidence.md" target="_blank" rel="noopener noreferrer">How it was measured</a>. APK writes your AI assistants’ native settings, then exits. Your main agent and its model stay unchanged.</p>
|
|
266
314
|
</div></details><p class="link-error" id="link-error" role="status" hidden></p></div>
|
|
267
315
|
<div class="builder">
|
|
268
|
-
<section aria-labelledby="helpers-heading"><div class="step-heading"><span class="step-number">1</span><h2 id="helpers-heading" tabindex="-1">Subagent roles</h2
|
|
269
|
-
<section aria-labelledby="tools-heading"><div class="step-heading"><span class="step-number">2</span><h2 id="tools-heading" tabindex="-1">
|
|
270
|
-
<section aria-labelledby="mode-heading"><div class="step-heading"><span class="step-number">3</span><h2 id="mode-heading" tabindex="-1">Work mode</h2
|
|
271
|
-
|
|
316
|
+
<section aria-labelledby="helpers-heading"><div class="step-heading"><span class="step-number">1</span><h2 id="helpers-heading" tabindex="-1">Subagent roles</h2></div><div class="tag-box" id="selected-helpers" role="group" aria-label="Selected subagent roles"></div><div class="suggestions" id="helper-options" role="group" aria-label="Available subagent roles"></div></section>
|
|
317
|
+
<section aria-labelledby="tools-heading"><div class="step-heading"><span class="step-number">2</span><h2 id="tools-heading" tabindex="-1">AI assistants</h2></div><div class="tool-group" id="selected-tools" role="group" aria-label="Selected AI assistants"></div><div class="suggestions" id="tool-options" role="group" aria-label="Available AI assistants"></div></section>
|
|
318
|
+
<section aria-labelledby="mode-heading"><div class="step-heading"><span class="step-number">3</span><h2 id="mode-heading" tabindex="-1">Work mode</h2></div><div id="mode-empty" class="mode-placeholder">Choose subagent roles and AI assistants above.</div><div id="mode-panel" hidden><div class="mode-heading"><span class="scope-label" id="scope-label">All selected AI assistants</span></div><div id="mode-options" role="radiogroup" aria-label="Work mode"></div><p class="notice" id="mode-notice" hidden></p><div class="top-models" id="top-models" hidden><button type="button" role="switch" id="top-models-toggle" aria-checked="false"><span class="switch-track" aria-hidden="true"></span><span id="top-models-label">Use top models for code, review and tests</span></button></div><section class="advanced" id="advanced" aria-label="Models and effort"><h3>Models & effort</h3><div id="editor"></div><div class="concurrency" id="concurrency-panel" hidden><h3>Parallel subagents</h3><div class="concurrency-row"><label for="max-concurrent" id="concurrency-label">Max per session</label><div class="concurrency-stepper" role="group" aria-label="Maximum concurrent subagents"><button id="decrease-concurrency" type="button" aria-label="Decrease maximum concurrent subagents">−</button><input id="max-concurrent" type="number" min="1" max="32" step="1" value="3" inputmode="numeric" aria-describedby="concurrency-error"><button id="increase-concurrency" type="button" aria-label="Increase maximum concurrent subagents">+</button></div></div><p class="field-error" id="concurrency-error" role="status" hidden>Enter a whole number from 1 to 32.</p></div></section></div></section>
|
|
319
|
+
|
|
320
|
+
<section aria-labelledby="setup-heading"><div class="step-heading"><span class="step-number">4</span><h2 id="setup-heading">Copy setup command</h2><span class="step-hint" id="step-hint-4" role="status" aria-live="polite" aria-atomic="true" hidden></span></div><div class="output" data-ready="false"><div class="setup-result"><div aria-live="polite" aria-atomic="true"><strong id="setup-summary">Complete the steps above.</strong><p id="setup-description">Choose a subagent role in step 1 and an AI assistant in step 2.</p></div><textarea class="setup-command" id="setup-command" readonly aria-label="Setup command" wrap="soft" rows="1" hidden></textarea><p id="copy-feedback" role="status" hidden></p></div><button class="button primary" id="copy" type="button" aria-describedby="setup-description" disabled>Copy command</button></div><div class="setup-footer"><p class="release-status" id="release-status"></p><button type="button" class="reset-form" id="reset-form">Reset form</button></div></section>
|
|
272
321
|
</div>
|
|
273
322
|
</main>
|
|
274
323
|
<div id="role-tooltip" class="role-tooltip" role="tooltip" hidden></div>
|
|
275
|
-
<footer><span>
|
|
324
|
+
<footer><div class="footer-row footer-details"><span class="show-settings">Check current settings <button type="button" class="quiet-button" id="copy-show" aria-label="Copy the command that shows current settings">Copy</button><code id="show-command" hidden></code></span><div class="footer-attribution"><span>by <a rel="author" href="https://www.linkedin.com/in/nick-maximenko/">Mykola Maksymenko</a></span><nav aria-label="Related projects"><span>More tools:</span><a href="https://github.com/automatis-tools/agents-can-communicate">Agents Can Communicate</a> <a href="https://github.com/automatis-tools/automatis-skills">Automatis Skills</a></nav></div></div></footer>
|
|
276
325
|
<script>
|
|
277
326
|
'use strict';
|
|
278
|
-
const RELEASE = {"schemaVersion":1,"version":"0.1.0","preset":"balanced","presets":[{"id":"fast","label":"Fast & economical","description":"For small, well-defined tasks. Lighter models, with extra reasoning for review and tests.","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"codex":{"code":{"model":"gpt-6-luna","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6-luna","effort":"high"}},"avoidModels":[]},"claude":{"code":{"model":"claude-haiku-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-haiku-5-5","effort":"high"},"tester":{"model":"claude-haiku-5-5","effort":"high"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/kimi-for-coding","effort":"low"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"avoidModels":[]},"agy":{"code":{"model":"flash","effort":null},"light":{"model":"flash_lite","effort":null},"avoidModels":[]}}}},{"id":"balanced","label":"Balanced","description":"Stronger coding and verification, lighter exploration and mechanical work.","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"codex":{"code":{"model":"gpt-6.1-sol","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6.1-sol","effort":"high"},"explorer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"medium"}},"avoidModels":[]},"claude":{"code":{"model":"claude-sonnet-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-sonnet-5-5","effort":"high"},"explorer":{"model":"claude-haiku-5-5","effort":"medium"},"tester":{"model":"claude-sonnet-5-5","effort":"high"},"writer":{"model":"claude-sonnet-5-5","effort":"medium"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3-256k","effort":"high"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"avoidModels":[]},"agy":{"code":{"model":"pro","effort":null},"light":{"model":"flash_lite","effort":null},"roles":{"explorer":{"model":"flash","effort":null},"writer":{"model":"flash","effort":null}},"avoidModels":[]}}}},{"id":"quality","label":"Quality first","description":"For demanding implementation and verification. Prioritizes capability over response time and usage.","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"codex":{"code":{"model":"gpt-6-astra","effort":"xhigh"},"light":{"model":"gpt-6.1-sol","effort":"medium"},"roles":{"explorer":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"high"}},"avoidModels":[]},"claude":{"code":{"model":"claude-fable-5-1","effort":"xhigh"},"light":{"model":"claude-sonnet-5-5","effort":"medium"},"roles":{"explorer":{"model":"claude-opus-5-5","effort":"high"},"writer":{"model":"claude-opus-5-5","effort":"high"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3.1-pro","effort":"max"},"light":{"model":"kimi-code/kimi-for-coding","effort":"high"},"roles":{"explorer":{"model":"kimi-code/k3","effort":"high"},"writer":{"model":"kimi-code/k3","effort":"high"}},"avoidModels":[]},"agy":{"code":{"model":"pro","effort":null},"light":{"model":"flash","effort":null},"roles":{"explorer":{"model":"pro","effort":null},"writer":{"model":"pro","effort":null}},"avoidModels":[]}}}}],"catalogReviewedAt":"2026-10-30","preferencesHash":"d7783c6514ee952314de2f55a4d39d2db055b4d3da4e8139c2c6f7f5b17cb40d","notes":"# Changelog\n\nEach npm version is one configuration release: its presets, native role definitions, instructions and configuration page. Published versions are not rewritten. Applying another release is explicit; package installation alone changes no settings.\n\n## 0.1.0 — 2026-10-30\n\n### Why this release\n\nUse a common approach to optional delegation across Codex, Claude Code, Kimi and Antigravity, without an extra process in normal agent operation. Configure once and remove the installer afterward.\n\n### What it configures\n\nSix focused roles cover implementation, read-only review, code discovery, test creation, documentation and prescribed execution. Each preset assigns a model and supported effort to every role; the [preset matrix](docs/model-catalog.md#how-the-presets-are-designed) explains the choices.\n\nThese are starting preferences, not model-quality benchmarks. Native model formats and alias behavior were reviewed against the official sources linked in [support](docs/compatibility.md) and [model maintenance](docs/model-updates.md). Model availability must be checked before applying. Provider aliases and tiers may resolve differently over time.\n\n### Presets and model catalog\n\nAll three presets were rebuilt for public use. Personal Astra/Opus/Fable and other avoid lists were removed. Fast gives review and testing more reasoning than simple execution. Balanced separates implementation, verification, discovery, documentation and mechanics. Quality uses Astra/Fable for demanding work and regular K3.1 Pro at max for Kimi code/review/tests. Claude recommendations pin current versioned IDs; Kimi Balanced uses the quota-conscious K3 256K variant. These are editable recommendations, not benchmark results.\n\nThe release contains a dated model/effort catalog from official documentation and native selector observations, including native-default effort and account-dependent availability. Antigravity role choices are native tiers, with no invented per-role effort setting.\n\nCatalog audit, 2026-10-30 UTC: Kimi now lists all six current models, including K3.1 Pro and Pro Highspeed. Quality first now uses regular K3.1 Pro at max effort for implementation/review/tests; other roles have separate choices described in the preset matrix. Highspeed remains optional because its faster output consumes about twice regular Pro's quota, according to Kimi. Setup requires provisioned access and does not silently fall back to another model.\n\nBoth Pro variants require compatible thinking settings. Even with unpinned effort, setup refuses an explicit thinking-disabled setting without modifying it.\n\nCodex effort choices/defaults now follow CLI 0.166.0 rather than API defaults; API metadata remains separate, and Ultra stays separate from ordinary effort. Claude Opus 4.5 no longer advertises an API-only native effort override. Existing custom inputs using levels outside the current native catalog require review before reapplication; owned inspection/removal remains independent of current recommendations. Sonnet 4.5 remains selectable with its Anthropic deprecation status marked. Antigravity CLI's four tier choices are unchanged.\n\n### What changed\n\n- Added Test writer and Docs writer; clarified Code explorer and Task runner. Old four-role native v2/v3 receipts remain supported, including explicit expansion to six, owned removal, drift refusal and late rollback. New v4 snapshots support six independently configured Kimi aliases.\n\n- Readable type uses a compact 36/20/15/13 px scale with more spacing; narrow layouts stack model controls and command actions.\n- A short collapsible explanation introduces role-specific models, native setup and optional delegation, using the same wording as the README.\n- The builder now starts with no roles, tools or chosen modes. Green checks track completed selections and successful copy, and Reset form restores a blank state. URL fragments restore visible settings without a backend. Conditional section hints and changed step markers use a two-second highlight hold plus two-second fade, respecting reduced motion. Selection controls share a soft treatment; Copy remains the primary action.\n- Page commands always list every selected role/model/effort under its tool, including presets. Explicit --roles, --max-concurrent and optional --avoid-TOOL preserve the existing selection, cap and guidance. :native represents unpinned effort; Antigravity remains tier-only. The shared codec validates complete role maps and rejects duplicate/mixed input before writes. Legacy release/config/policy inputs remain supported.\n- The four-step page now selects subagent roles and coding tools before mode/model/effort configuration. It generates and copies a real pinned command. Tool additions preserve All or a manually selected view. Role help uses the same prompt definitions as native generation.\n- Optional selectedRoles creates only the requested native roles. Receipt v4 binds that role set to owned files and supports safe expansion, reduction and removal. Earlier v2/v3 native receipts retain their historical four-role ownership boundary. Unselected Kimi aliases do not need provisioning or effort pins.\n- Native role files and routing instructions apply only when the main agent chooses delegation. Main models and disabled delegation features are preserved.\n- A static page lets each tool use its own mode and per-task models/effort. All shows mixed settings as Custom and can apply one preset to every tool. Scope warnings protect individual and global replacements; the page generates one pinned command.\n- Explicit release application supports safe upgrade/downgrade of owned settings; per-client receipts record the actual applied version and custom choices.\n- Ownership/drift checks, private backups and rollback preserve unrelated settings and earlier user values.\n- No custom hooks, proxy, plugin, launcher, daemon or normal-operation runtime is installed.\n\n### Who should use it\n\nPeople who want consistent subagent preferences across their installed coding tools. You can keep the recommendations or select different native models in the configuration page.\n\n### Applying this version\n\n```sh\nnpx --yes --ignore-scripts --package agent-policy-kit@0.1.0 agent-policy setup --release --apply\n```\n\nWithout --apply the same command previews the changes. The page-generated explicit tool arguments apply the visible choices using this release's native templates. See [release usage](docs/releases.md).\n\n### Migration and limits\n\nThis is the first public release. Synthetic versions in tests are not real releases. Experimental runtime receipts from older development commits require their original owned removal. Supported native snapshot formats can be updated safely; unknown future formats/layouts are refused.\n\nKimi/Antigravity concurrency guidance and native tier/precedence limits remain explicit. A pinned release reproduces declared configuration, not provider weights, entitlement or model quality.\n","packageSpec":"agent-policy-kit@0.1.0","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"codex":{"code":{"model":"gpt-6.1-sol","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6.1-sol","effort":"high"},"explorer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"medium"}},"avoidModels":[]},"claude":{"code":{"model":"claude-sonnet-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-sonnet-5-5","effort":"high"},"explorer":{"model":"claude-haiku-5-5","effort":"medium"},"tester":{"model":"claude-sonnet-5-5","effort":"high"},"writer":{"model":"claude-sonnet-5-5","effort":"medium"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3-256k","effort":"high"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"avoidModels":[]},"agy":{"code":{"model":"pro","effort":null},"light":{"model":"flash_lite","effort":null},"roles":{"explorer":{"model":"flash","effort":null},"writer":{"model":"flash","effort":null}},"avoidModels":[]}}},"catalog":{"schemaVersion":1,"reviewedAt":"2026-10-30","scope":"Documented/native coding-tool selectors at this release; account access and custom deployment IDs vary.","clients":{"codex":{"label":"Codex","efforts":["none","minimal","low","medium","high","xhigh","max"],"observedClientVersion":"0.166.0","observation":"codex debug models --bundled: 9 visible selectors; 3 hidden specialized/utility entries excluded","models":[{"id":"gpt-6-astra","label":"GPT-6 Astra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6-astra","kind":"model","apiEfforts":["low","medium","high","xhigh","max"],"apiDefaultEffort":null,"nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6.1-sol","label":"GPT-6.1 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6.1-sol","kind":"model","apiEfforts":["low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6.1-terra","label":"GPT-6.1 Terra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6.1-terra","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6-sol","label":"GPT-6 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-6-sol","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6-luna","label":"GPT-6 Luna","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-6-luna","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"},{"id":"gpt-5.6-sol","label":"GPT-5.6 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-5.6-sol","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-5.6-terra","label":"GPT-5.6 Terra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.6-terra","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-5.6-luna","label":"GPT-5.6 Luna","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.6-luna","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"},{"id":"gpt-5.5","label":"GPT-5.5","efforts":["low","medium","high","xhigh"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.5","kind":"model","apiEfforts":["none","low","medium","high","xhigh"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"}],"excluded":[{"id":"gpt-daybreak-blue-latest","reason":"hidden specialized selector"},{"id":"gpt-daybreak-red-latest","reason":"hidden specialized selector"},{"id":"codex-auto-review","reason":"hidden internal utility selector"}],"note":"Efforts and defaults follow the bundled Codex CLI 0.166.0 catalog. API capabilities are separate apiEfforts/apiDefaultEffort metadata. Ultra is a delegating execution mode, recorded separately and not offered as ordinary subagent effort. An API-supported level absent from the native catalog is unverified for manual per-role configuration, not proven runtime-rejected."},"claude":{"label":"Claude Code","efforts":["low","medium","high","xhigh","max"],"observedClientVersion":"2.1.312","models":[{"id":"sonnet","label":"Sonnet (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"opus","label":"Opus (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"haiku","label":"Haiku (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"fable","label":"Fable (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/sub-agents#choose-a-model","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"claude-fable-5-1","label":"Fable 5.1","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-5-5","label":"Opus 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-5-5","label":"Sonnet 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-haiku-5-5","label":"Haiku 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-fable-5","label":"Fable 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-5","label":"Opus 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-5","label":"Sonnet 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-8","label":"Opus 4.8","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-7","label":"Opus 4.7","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"xhigh","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-6","label":"Opus 4.6","efforts":["low","medium","high","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-4-6","label":"Sonnet 4.6","efforts":["low","medium","high","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-5-20251101","label":"Opus 4.5","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config#adjust-effort-level","kind":"model","apiEfforts":["low","medium","high"],"apiDefaultEffort":null,"apiSource":"https://platform.claude.com/docs/en/build-with-claude/effort"},{"id":"claude-sonnet-4-5-20250929","label":"Sonnet 4.5 (deprecated)","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"model","lifecycle":{"status":"deprecated","retirementDate":"2026-11-30","scope":"Anthropic-operated platforms; partner lifecycles differ","source":"https://platform.claude.com/docs/en/about-claude/model-deprecations"}},{"id":"claude-haiku-4-5-20251001","label":"Haiku 4.5","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"inherit","label":"Inherit main model","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/sub-agents","kind":"inherit","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."}],"note":"Full model IDs use the current Claude Code native effort table, which differs from API support for Opus 4.5. Alias/inherit efforts are possible requested levels, not a guarantee for every resolved provider model; unsupported levels can clamp or be ignored. Current account access and provider alias resolution vary.","excluded":[{"id":"best","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"default","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"opus[1m]","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"opusplan","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"sonnet[1m]","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"}]},"kimi":{"label":"Kimi","efforts":["low","medium","high","xhigh","max"],"models":[{"id":"kimi-code/k3.1-pro","label":"K3.1 Pro","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3.1-pro","thinkingRequired":true},{"id":"kimi-code/k3.1-pro-highspeed","label":"K3.1 Pro Highspeed","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3.1-pro-highspeed","thinkingRequired":true},{"id":"kimi-code/k3","label":"K3","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3"},{"id":"kimi-code/k3-256k","label":"K3 · 256K","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3-256k"},{"id":"kimi-code/kimi-for-coding","label":"K2.8 Preview","efforts":["low","high","max"],"defaultEffort":"max","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"kimi-for-coding"},{"id":"kimi-code/kimi-for-coding-highspeed","label":"K2.7 Code HighSpeed","efforts":[],"defaultEffort":null,"source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"kimi-for-coding-highspeed"}],"note":"Current Kimi Code docs list six model IDs; the older kimi.ai/help page still lists four. K3.1 Pro and Highspeed require thinking and support low/high/max, default high. These are preferred native aliases: setup resolves a missing preferred alias only to a unique provisioned match; no provider identity is invented. Account tier controls access.","observedClientVersion":"2.4.0","observation":"Kimi Code CLI 2.4.0: all six documented preferred aliases and native effort/default capabilities corroborated through whitelisted provisioned metadata; no credentials or custom account aliases retained."},"agy":{"label":"Antigravity","efforts":[],"observedClientVersion":"1.4.10","models":[{"id":"pro","label":"Pro","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"flash","label":"Flash","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"flash_lite","label":"Flash Lite","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"inherit","label":"Inherit main model","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"}],"note":"Native per-subagent selectors are tiers, not the session model inventory. CLI 1.4.10 parser explicitly accepts inherit/flash_lite/flash/pro, including Flash Lite absent from the shared docs App table. Per-role effort is not exposed by the agent-file schema."}}},"roles":[{"id":"worker","name":"Coder","kind":"code","assignment":"scoped implementation and fixes","description":"Implements scoped changes, preserves peers' edits, and verifies the result.","prompt":"Implement the assigned change or fix within the assigned files. You share the workspace with other agents: preserve their edits. Verify the result and report changes, checks, and remaining limitations. Do not create child agents; return any need for further delegation to the parent."},{"id":"reviewer","name":"Reviewer","kind":"code","assignment":"read-only correctness, security and regression review","description":"Reviews correctness, security and regressions without edits; reports actionable evidence.","prompt":"Review the assigned change without editing files. Find actionable correctness, security, and regression issues. Report each finding with file and line evidence and explain its impact; distinguish confirmed issues from uncertainty. Do not create child agents; return any need for further delegation to the parent."},{"id":"explorer","name":"Code explorer","kind":"light","assignment":"read-only code and documentation discovery","description":"Maps code and documentation, cites sources, and separates facts from uncertainty.","prompt":"Explore the assigned code and documentation without editing files. Return a concise map or factual answer with source paths or citations. Distinguish verified facts from assumptions and unknowns. Do not create child agents; return any need for further delegation to the parent."},{"id":"tester","name":"Test writer","kind":"code","assignment":"test creation and targeted execution","description":"Writes behavior and edge-case tests, reproduces issues, and runs targeted checks.","prompt":"Own the assigned tests and targeted execution. Reproduce the issue or establish a baseline, then test observable behavior and edge cases. Never weaken checks to make them pass. Do not edit application code unless explicitly assigned. Preserve peers' edits and report results and limitations. Do not create child agents; return any need for further delegation to the parent."},{"id":"writer","name":"Docs writer","kind":"light","assignment":"assigned documentation, examples and release notes","description":"Updates assigned docs and examples, verifies claims, and keeps terminology consistent.","prompt":"Update only the assigned documentation, examples, or release notes. Verify claims against code or cited sources and use consistent terminology. Do not edit application code. Preserve peers' edits and report changes and unknowns. Do not create child agents; return any need for further delegation to the parent."},{"id":"routine","name":"Task runner","kind":"light","assignment":"explicit commands and mechanical edits","description":"Runs prescribed commands and mechanical edits; returns ambiguous decisions to the parent.","prompt":"Execute only the prescribed commands or clearly specified mechanical edits. Preserve other agents' work and report the outcome. Do not make ambiguous design or behavior decisions; return those decisions to the parent. Do not create child agents; return any need for further delegation to the parent."}],"unreleased":false};
|
|
327
|
+
const RELEASE = {"schemaVersion":1,"version":"0.3.0","preset":"balanced","presets":[{"id":"fast","label":"Light","description":"Light models for every role. Limits last longest.","preferences":{"schemaVersion":1,"maxConcurrent":2,"clients":{"chatgpt":{"code":{"model":"gpt-6-luna","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6-luna","effort":"high"}},"avoidModels":[]},"claude":{"code":{"model":"claude-haiku-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-haiku-5-5","effort":"high"},"tester":{"model":"claude-haiku-5-5","effort":"high"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/kimi-for-coding","effort":"low"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"avoidModels":[]},"gemini":{"code":{"model":"flash","effort":null},"light":{"model":"flash_lite","effort":null},"avoidModels":[]},"grok":{"code":{"model":"grok-build-0.1","effort":null},"light":{"model":"grok-build-0.1","effort":null},"avoidModels":[]}}}},{"id":"balanced","label":"Standard","description":"Stronger models for code, review, tests and docs. Fits most plans.","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"chatgpt":{"code":{"model":"gpt-6.1-sol","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6.1-sol","effort":"high"},"explorer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"medium"}},"avoidModels":[]},"claude":{"code":{"model":"claude-sonnet-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-sonnet-5-5","effort":"high"},"explorer":{"model":"claude-haiku-5-5","effort":"medium"},"tester":{"model":"claude-sonnet-5-5","effort":"high"},"writer":{"model":"claude-sonnet-5-5","effort":"medium"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3-256k","effort":"high"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"roles":{"writer":{"model":"kimi-code/k3-256k","effort":"high"}},"avoidModels":[]},"gemini":{"code":{"model":"pro","effort":null},"light":{"model":"flash_lite","effort":null},"roles":{"explorer":{"model":"flash","effort":null},"writer":{"model":"flash","effort":null}},"avoidModels":[]},"grok":{"code":{"model":"grok-4.7","effort":null},"light":{"model":"grok-build-0.1","effort":null},"roles":{"writer":{"model":"grok-4.7","effort":null}},"avoidModels":[]}}}},{"id":"quality","label":"Top-tier","description":"High-end models for most roles. Uses limits fastest.","topModels":{"chatgpt":"gpt-6-astra","claude":"claude-fable-5-1","kimi":"kimi-code/k3.1-pro"},"preferences":{"schemaVersion":1,"maxConcurrent":2,"clients":{"chatgpt":{"code":{"model":"gpt-6.1-sol","effort":"high"},"light":{"model":"gpt-6.1-sol","effort":"medium"},"roles":{"explorer":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"high"}},"avoidModels":[]},"claude":{"code":{"model":"claude-opus-5-5","effort":"high"},"light":{"model":"claude-sonnet-5-5","effort":"medium"},"roles":{"explorer":{"model":"claude-opus-5-5","effort":"high"},"writer":{"model":"claude-opus-5-5","effort":"high"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3","effort":"high"},"light":{"model":"kimi-code/kimi-for-coding","effort":"high"},"roles":{"explorer":{"model":"kimi-code/k3","effort":"high"},"writer":{"model":"kimi-code/k3","effort":"high"}},"avoidModels":[]},"gemini":{"code":{"model":"pro","effort":null},"light":{"model":"flash","effort":null},"roles":{"explorer":{"model":"pro","effort":null},"writer":{"model":"pro","effort":null}},"avoidModels":[]},"grok":{"code":{"model":"grok-4.7","effort":null},"light":{"model":"grok-build-0.1","effort":null},"roles":{"explorer":{"model":"grok-4.7","effort":null},"writer":{"model":"grok-4.7","effort":null}},"avoidModels":[]}}}}],"catalogReviewedAt":"2026-10-30","preferencesHash":"808e505cbbff97d0356fa2c31408e7c13de8369ad10ccc767df6b748e347a022","notes":"# Changelog\n\nEach npm version is one configuration release: its presets, native role definitions, instructions and configuration page. Published versions are not rewritten. Applying another release is explicit; package installation alone changes no settings.\n\n## 0.3.0 — 2026-11-01\n\n### Why this release\n\nPeople know their assistants as ChatGPT, Claude, Kimi, Gemini and Grok, not by the names of the coding agents inside them. The configurator and the CLI now use those names. Some people use only the desktop apps, and they have no CLI on PATH. Before this release, setup found nothing for them.\n\n### Who should update\n\n- Anyone who uses Codex in ChatGPT Desktop or Claude Code in the Code tab of Claude Desktop on macOS without a separate CLI.\n- Anyone who wants the general assistant names on the page and in the terminal.\n\nPreset values do not change, so an installation of 0.2.0 keeps working without an update.\n\n### Breaking change\n\nAI assistants now have general names: ChatGPT, Claude, Kimi, Gemini and Grok. APK still configures their coding agents: Codex, Claude Code, Kimi Code, Antigravity and Grok Build. Two technical IDs changed, and there is no migration:\n\n- `codex` is now `chatgpt`: `--chatgpt`, `--chatgpt-max-concurrent`, `--avoid-chatgpt`, `--client chatgpt` and the `clients.chatgpt` policy key.\n- `agy` is now `gemini`: `--gemini`, `--gemini-max-concurrent`, `--avoid-gemini`, `--client gemini` and the `clients.gemini` policy key.\n- Warning and error codes follow the new IDs, for example `chatgpt-native-precedence-limits` and `CHATGPT_CAP_ALIAS_CONFLICT`.\n\nBefore you use this version, remove the APK settings for these two assistants with the version that created them: `npx --yes --ignore-scripts --package agent-policy-kit@0.2.0 agent-policy uninstall --apply`. This version does not read the old `codex` and `agy` installation receipts, so its setup refuses the existing `apk-*` files as unowned. Policy files and share links that use the old IDs are refused too. Claude, Kimi and Grok keep their IDs.\n\n### Migration and rollback\n\nThe two renamed IDs set a migration boundary. These results come from tests with the published 0.2.0 package and this release:\n\n- **ChatGPT (Codex) and Gemini (Antigravity):** remove the APK settings with the version that created them before you set up with the other version. A move in either direction without removal reports `OWNERSHIP_CONFLICT` and changes nothing. After removal, setup with the other version succeeds.\n- **Claude, Kimi and Grok:** their IDs and receipt format v4 are unchanged. In the tests, setup with 0.3.0 upgraded 0.2.0 installations of Claude and Grok in place, and setup with 0.2.0 moved Claude back. Kimi uses the same receipt format, but it was not tested with a provisioned model pool.\n\n`uninstall --apply` removes the settings of every assistant. Run setup again afterwards for the assistants you use.\n\n### Presets and model catalog\n\nPreset models, effort levels and parallel limits are the same as in 0.2.0. Only the keys `codex` and `agy` became `chatgpt` and `gemini`, and the catalog labels became the general names. The model catalog snapshot is still dated 2026-10-30, with the Grok entries checked on 2026-11-01. Configuration checks are not model-quality evaluations.\n\n### What changed\n\n- The configurator calls the second step \"AI assistants\" and shows the general names. Readable CLI output uses the same names.\n- On macOS, setup finds the Codex that ChatGPT Desktop includes and the Claude Code in the Code tab of Claude Desktop, also when no CLI is on PATH. Both apps read the same settings as their CLIs. A CLI on PATH or in a conventional location still has priority. Detect output reports these clients with `origin: \"desktop_app\"`. Claude Cowork reads its settings from the Claude account, so APK does not configure it.\n\n## 0.2.0 — 2026-11-01\n\n### Why this release\n\nSubagents draw on the same plan limits as the main session, and every parallel session adds to that usage. Without explicit choices, subagents can inherit the most expensive model and use up a weekly limit within days. This release names the work modes by how much of a plan subagents may use, adds per-tool parallel limits, a read-only settings check and Grok Build support.\n\n### Who should update\n\nAnyone who wants Grok Build roles, per-tool parallel limits or the renamed modes. Re-running setup with 0.2.0 applies the new preset values: Top-tier now uses Opus 5.5, GPT-6.1 Sol and K3 at high effort, with top models behind an opt-in switch, and Kimi's Standard Docs writer uses K3 256K. Installations of 0.1.0 keep working unchanged until setup is run again.\n\n### Migration and rollback\n\nPreset ids (`fast`, `balanced`, `quality`), receipt format v4 and ownership, drift and rollback behavior are unchanged. Version 1 share links still open; new links use version 2 and carry each tool's parallel limit. Applying 0.1.0 again restores its owned settings, as the synthetic upgrade/downgrade gate verifies. Grok Build is new, so it has nothing to migrate.\n\n### Presets and model catalog\n\nThe model catalog snapshot is dated 2026-10-30; Grok Build entries were checked on 2026-11-01 against the Grok Build 1.0.70 user guide and the xAI model list. An independent audit compared every preset, tool and role with the catalog and the documentation tables, and a test now keeps those tables in sync. Configuration checks are not model-quality evaluations.\n\n### What changed\n\n- Add Grok Build as a fifth coding tool, listed after Antigravity. APK writes `agents/apk-\u003crole>.md` role files (Reviewer and Code explorer use the read-only `permission_mode: plan`), per-role models and a `general-purpose` fallback copied from the first selected role (the Coder when selected) in `config.toml` `[subagents.models]`, a native `[subagents] max_concurrent` cap and a delegation block in `AGENTS.md` under `$GROK_HOME` (default `~/.grok`). Per-role effort is not configurable, so every Grok choice has effort null and the page shows no effort controls. Presets use Grok Build 0.1, xAI's fast coding model, for light work and Grok 4.7 for stronger roles; Grok 4.6 and 4.5 stay available in Custom. Explicit commands use `--grok`, `--grok-max-concurrent` and `--avoid-grok`. Removal restores the original settings and refuses on local edits.\n\n- Rename work modes to Light, Standard and Top-tier and describe them by how much of a plan's limits subagents use. Preset ids and share-link ids are unchanged. Top-tier now uses Opus 5.5, GPT-6.1 Sol and K3 at high effort for code, review and tests. A per-tool switch under Top-tier opts those roles into Fable 5.1, GPT-6 Astra or K3.1 Pro; it is off by default. Top models no longer run at xhigh/max, because native default subagent settings copy the first selected role (the Coder when selected) to subagents started without a named role.\n\n- Explain each configuration step with a short ? note, and stop repeating vendor billing or version documentation in the work-mode notice.\n\n- Start a fresh or reset form with every subagent role selected, and give the empty coding-tool field the same appearance as the empty role field.\n\n- Automatically deploy the latest website from verified main while preserving exact tagged release pages and older share links. Configuration guards keep commands pinned to published package capabilities; npm releases remain explicit.\n\n- Credit Mykola Maksymenko in the configuration page and package metadata. Link the supplied LinkedIn profile and related projects, with static author/project structured data and a release-specific canonical URL.\n\n- Interactive terminals get readable setup, doctor, release and show output; captured output keeps the existing JSON contract, and `--json` forces JSON.\n\n- `agent-policy show` reads the current user-level subagent settings of every tool, before or after APK installation, without writing files. The page footer offers it as \"Check current settings\" with a copy button.\n\n- Each tool has its own parallel limit from 1 to 32, set in its details on the page or with `--TOOL-max-concurrent`; policies accept `clients[tool].maxConcurrent`.\n\n- The page adds Add all for roles and tools, a GitHub link in the header, Reset form beside the release line, and preset switching for a single selected tool without a needless confirmation.\n\n## 0.1.0 — 2026-10-30\n\n### Why this release\n\nUse a common approach to optional delegation across Codex, Claude Code, Kimi and Antigravity, without an extra process in normal agent operation. Configure once and remove the installer afterward.\n\n### What it configures\n\nSix focused roles cover implementation, read-only review, code discovery, test creation, documentation and prescribed execution. Each preset assigns a model and supported effort to every role; the [preset matrix](docs/model-catalog.md#how-the-presets-are-designed) explains the choices.\n\nThese are starting preferences, not model-quality benchmarks. Native model formats and alias behavior were reviewed against the official sources linked in [support](docs/compatibility.md) and [model maintenance](docs/model-updates.md). Model availability must be checked before applying. Provider aliases and tiers may resolve differently over time.\n\n### Presets and model catalog\n\nAll three presets were rebuilt for public use. Personal Astra/Opus/Fable and other avoid lists were removed. Fast gives review and testing more reasoning than simple execution. Balanced separates implementation, verification, discovery, documentation and mechanics. Quality uses Astra/Fable for demanding work and regular K3.1 Pro at max for Kimi code/review/tests. Claude recommendations pin current versioned IDs; Kimi Balanced uses the quota-conscious K3 256K variant. These are editable recommendations, not benchmark results.\n\nThe release contains a dated model/effort catalog from official documentation and native selector observations, including native-default effort and account-dependent availability. Antigravity role choices are native tiers, with no invented per-role effort setting.\n\nCatalog audit, 2026-10-30 UTC: Kimi now lists all six current models, including K3.1 Pro and Pro Highspeed. Quality first now uses regular K3.1 Pro at max effort for implementation/review/tests; other roles have separate choices described in the preset matrix. Highspeed remains optional because its faster output consumes about twice regular Pro's quota, according to Kimi. Setup requires provisioned access and does not silently fall back to another model.\n\nBoth Pro variants require compatible thinking settings. Even with unpinned effort, setup refuses an explicit thinking-disabled setting without modifying it.\n\nCodex effort choices/defaults now follow CLI 0.166.0 rather than API defaults; API metadata remains separate, and Ultra stays separate from ordinary effort. Claude Opus 4.5 no longer advertises an API-only native effort override. Existing custom inputs using levels outside the current native catalog require review before reapplication; owned inspection/removal remains independent of current recommendations. Sonnet 4.5 remains selectable with its Anthropic deprecation status marked. Antigravity CLI's four tier choices are unchanged.\n\n### What changed\n\n- Added Test writer and Docs writer; clarified Code explorer and Task runner. Old four-role native v2/v3 receipts remain supported, including explicit expansion to six, owned removal, drift refusal and late rollback. New v4 snapshots support six independently configured Kimi aliases.\n\n- Readable type uses a compact 36/20/15/13 px scale with more spacing; narrow layouts stack model controls and command actions.\n- A short collapsible explanation introduces role-specific models, native setup and optional delegation, using the same wording as the README.\n- The builder now starts with no roles, tools or chosen modes. Green checks track completed selections and successful copy, and Reset form restores a blank state. URL fragments restore visible settings without a backend. Conditional section hints and changed step markers use a two-second highlight hold plus two-second fade, respecting reduced motion. Selection controls share a soft treatment; Copy remains the primary action.\n- Page commands always list every selected role/model/effort under its tool, including presets. Explicit --roles, --max-concurrent and optional --avoid-TOOL preserve the existing selection, cap and guidance. :native represents unpinned effort; Antigravity remains tier-only. The shared codec validates complete role maps and rejects duplicate/mixed input before writes. Legacy release/config/policy inputs remain supported.\n- The four-step page now selects subagent roles and coding tools before mode/model/effort configuration. It generates and copies a real pinned command. Tool additions preserve All or a manually selected view. Role help uses the same prompt definitions as native generation.\n- Optional selectedRoles creates only the requested native roles. Receipt v4 binds that role set to owned files and supports safe expansion, reduction and removal. Earlier v2/v3 native receipts retain their historical four-role ownership boundary. Unselected Kimi aliases do not need provisioning or effort pins.\n- Native role files and routing instructions apply only when the main agent chooses delegation. Main models and disabled delegation features are preserved.\n- A static page lets each tool use its own mode and per-task models/effort. All shows mixed settings as Custom and can apply one preset to every tool. Scope warnings protect individual and global replacements; the page generates one pinned command.\n- Explicit release application supports safe upgrade/downgrade of owned settings; per-client receipts record the actual applied version and custom choices.\n- Ownership/drift checks, private backups and rollback preserve unrelated settings and earlier user values.\n- No custom hooks, proxy, plugin, launcher, daemon or normal-operation runtime is installed.\n\n### Who should use it\n\nPeople who want consistent subagent preferences across their installed coding tools. You can keep the recommendations or select different native models in the configuration page.\n\n### Applying this version\n\n```sh\nnpx --yes --ignore-scripts --package agent-policy-kit@0.1.0 agent-policy setup --release --apply\n```\n\nWithout --apply the same command previews the changes. The page-generated explicit tool arguments apply the visible choices using this release's native templates. See [release usage](docs/releases.md).\n\n### Migration and limits\n\nThis is the first public release. Synthetic versions in tests are not real releases. Experimental runtime receipts from older development commits require their original owned removal. Supported native snapshot formats can be updated safely; unknown future formats/layouts are refused.\n\nKimi/Antigravity concurrency guidance and native tier/precedence limits remain explicit. A pinned release reproduces declared configuration, not provider weights, entitlement or model quality.\n","packageSpec":"agent-policy-kit@0.3.0","preferences":{"schemaVersion":1,"maxConcurrent":3,"clients":{"chatgpt":{"code":{"model":"gpt-6.1-sol","effort":"medium"},"light":{"model":"gpt-6-luna","effort":"low"},"roles":{"reviewer":{"model":"gpt-6.1-sol","effort":"high"},"explorer":{"model":"gpt-6-luna","effort":"high"},"tester":{"model":"gpt-6.1-sol","effort":"high"},"writer":{"model":"gpt-6.1-sol","effort":"medium"}},"avoidModels":[]},"claude":{"code":{"model":"claude-sonnet-5-5","effort":"medium"},"light":{"model":"claude-haiku-5-5","effort":"low"},"roles":{"reviewer":{"model":"claude-sonnet-5-5","effort":"high"},"explorer":{"model":"claude-haiku-5-5","effort":"medium"},"tester":{"model":"claude-sonnet-5-5","effort":"high"},"writer":{"model":"claude-sonnet-5-5","effort":"medium"}},"avoidModels":[]},"kimi":{"code":{"model":"kimi-code/k3-256k","effort":"high"},"light":{"model":"kimi-code/kimi-for-coding","effort":"low"},"roles":{"writer":{"model":"kimi-code/k3-256k","effort":"high"}},"avoidModels":[]},"gemini":{"code":{"model":"pro","effort":null},"light":{"model":"flash_lite","effort":null},"roles":{"explorer":{"model":"flash","effort":null},"writer":{"model":"flash","effort":null}},"avoidModels":[]},"grok":{"code":{"model":"grok-4.7","effort":null},"light":{"model":"grok-build-0.1","effort":null},"roles":{"writer":{"model":"grok-4.7","effort":null}},"avoidModels":[]}}},"hostedReleases":[],"catalog":{"schemaVersion":1,"reviewedAt":"2026-10-30","scope":"Documented/native coding-tool selectors at this release; account access and custom deployment IDs vary.","clients":{"chatgpt":{"label":"ChatGPT","efforts":["none","minimal","low","medium","high","xhigh","max"],"observedClientVersion":"0.166.0","observation":"codex debug models --bundled: 9 visible selectors; 3 hidden specialized/utility entries excluded","models":[{"id":"gpt-6-astra","label":"GPT-6 Astra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6-astra","kind":"model","apiEfforts":["low","medium","high","xhigh","max"],"apiDefaultEffort":null,"nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6.1-sol","label":"GPT-6.1 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6.1-sol","kind":"model","apiEfforts":["low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6.1-terra","label":"GPT-6.1 Terra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-6.1-terra","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6-sol","label":"GPT-6 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-6-sol","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-6-luna","label":"GPT-6 Luna","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-6-luna","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"},{"id":"gpt-5.6-sol","label":"GPT-5.6 Sol","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"low","source":"https://developers.openai.com/api/docs/models/gpt-5.6-sol","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-5.6-terra","label":"GPT-5.6 Terra","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.6-terra","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models","delegationModes":["ultra"]},{"id":"gpt-5.6-luna","label":"GPT-5.6 Luna","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.6-luna","kind":"model","apiEfforts":["none","low","medium","high","xhigh","max"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"},{"id":"gpt-5.5","label":"GPT-5.5","efforts":["low","medium","high","xhigh"],"defaultEffort":"medium","source":"https://developers.openai.com/api/docs/models/gpt-5.5","kind":"model","apiEfforts":["none","low","medium","high","xhigh"],"apiDefaultEffort":"medium","nativeSource":"https://learn.chatgpt.com/docs/models"}],"excluded":[{"id":"gpt-daybreak-blue-latest","reason":"hidden specialized selector"},{"id":"gpt-daybreak-red-latest","reason":"hidden specialized selector"},{"id":"codex-auto-review","reason":"hidden internal utility selector"}],"note":"Efforts and defaults follow the bundled Codex CLI 0.166.0 catalog. API capabilities are separate apiEfforts/apiDefaultEffort metadata. Ultra is a delegating execution mode, recorded separately and not offered as ordinary subagent effort. An API-supported level absent from the native catalog is unverified for manual per-role configuration, not proven runtime-rejected."},"claude":{"label":"Claude","efforts":["low","medium","high","xhigh","max"],"observedClientVersion":"2.1.312","models":[{"id":"sonnet","label":"Sonnet (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"opus","label":"Opus (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"haiku","label":"Haiku (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"fable","label":"Fable (alias)","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/sub-agents#choose-a-model","kind":"alias","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."},{"id":"claude-fable-5-1","label":"Fable 5.1","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-5-5","label":"Opus 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-5-5","label":"Sonnet 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-haiku-5-5","label":"Haiku 5.5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"medium","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-fable-5","label":"Fable 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-5","label":"Opus 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-5","label":"Sonnet 5","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-8","label":"Opus 4.8","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-7","label":"Opus 4.7","efforts":["low","medium","high","xhigh","max"],"defaultEffort":"xhigh","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-6","label":"Opus 4.6","efforts":["low","medium","high","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-sonnet-4-6","label":"Sonnet 4.6","efforts":["low","medium","high","max"],"defaultEffort":"high","source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"claude-opus-4-5-20251101","label":"Opus 4.5","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config#adjust-effort-level","kind":"model","apiEfforts":["low","medium","high"],"apiDefaultEffort":null,"apiSource":"https://platform.claude.com/docs/en/build-with-claude/effort"},{"id":"claude-sonnet-4-5-20250929","label":"Sonnet 4.5 (deprecated)","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"model","lifecycle":{"status":"deprecated","retirementDate":"2026-11-30","scope":"Anthropic-operated platforms; partner lifecycles differ","source":"https://platform.claude.com/docs/en/about-claude/model-deprecations"}},{"id":"claude-haiku-4-5-20251001","label":"Haiku 4.5","efforts":[],"defaultEffort":null,"source":"https://code.claude.com/docs/en/model-config","kind":"model"},{"id":"inherit","label":"Inherit main model","efforts":["low","medium","high","xhigh","max"],"defaultEffort":null,"source":"https://code.claude.com/docs/en/sub-agents","kind":"inherit","effortResolution":"Depends on the resolved model and provider; requested levels can be clamped or ignored by Claude Code."}],"note":"Full model IDs use the current Claude Code native effort table, which differs from API support for Opus 4.5. Alias/inherit efforts are possible requested levels, not a guarantee for every resolved provider model; unsupported levels can clamp or be ignored. Current account access and provider alias resolution vary.","excluded":[{"id":"best","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"default","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"opus[1m]","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"opusplan","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"},{"id":"sonnet[1m]","reason":"session/context selector rather than a distinct documented subagent model; custom native ID remains available"}]},"kimi":{"label":"Kimi","efforts":["low","medium","high","xhigh","max"],"models":[{"id":"kimi-code/k3.1-pro","label":"K3.1 Pro","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3.1-pro","thinkingRequired":true},{"id":"kimi-code/k3.1-pro-highspeed","label":"K3.1 Pro Highspeed","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3.1-pro-highspeed","thinkingRequired":true},{"id":"kimi-code/k3","label":"K3","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3"},{"id":"kimi-code/k3-256k","label":"K3 · 256K","efforts":["low","high","max"],"defaultEffort":"high","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"k3-256k"},{"id":"kimi-code/kimi-for-coding","label":"K2.8 Preview","efforts":["low","high","max"],"defaultEffort":"max","source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"kimi-for-coding"},{"id":"kimi-code/kimi-for-coding-highspeed","label":"K2.7 Code HighSpeed","efforts":[],"defaultEffort":null,"source":"https://www.kimi.com/code/docs/en/kimi-code/models","kind":"native-alias","upstreamModelId":"kimi-for-coding-highspeed"}],"note":"Current Kimi Code docs list six model IDs; the older kimi.ai/help page still lists four. K3.1 Pro and Highspeed require thinking and support low/high/max, default high. These are preferred native aliases: setup resolves a missing preferred alias only to a unique provisioned match; no provider identity is invented. Account tier controls access.","observedClientVersion":"2.4.0","observation":"Kimi Code CLI 2.4.0: all six documented preferred aliases and native effort/default capabilities corroborated through whitelisted provisioned metadata; no credentials or custom account aliases retained."},"gemini":{"label":"Gemini","efforts":[],"observedClientVersion":"1.4.10","models":[{"id":"pro","label":"Pro","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"flash","label":"Flash","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"flash_lite","label":"Flash Lite","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"},{"id":"inherit","label":"Inherit main model","efforts":[],"defaultEffort":null,"source":"https://antigravity.google/docs/subagents?tab=cli","kind":"tier"}],"note":"Native per-subagent selectors are tiers, not the session model inventory. CLI 1.4.10 parser explicitly accepts inherit/flash_lite/flash/pro, including Flash Lite absent from the shared docs App table. Per-role effort is not exposed by the agent-file schema."},"grok":{"label":"Grok","efforts":[],"observedClientVersion":"1.0.70","models":[{"id":"grok-4.7","label":"Grok 4.7","efforts":[],"defaultEffort":null,"source":"https://docs.x.ai/developers/models","nativeSource":"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/16-subagents.md","kind":"model"},{"id":"grok-4.6","label":"Grok 4.6","efforts":[],"defaultEffort":null,"source":"https://docs.x.ai/developers/models","nativeSource":"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/16-subagents.md","kind":"model"},{"id":"grok-4.5","label":"Grok 4.5","efforts":[],"defaultEffort":null,"source":"https://docs.x.ai/developers/models","nativeSource":"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/16-subagents.md","kind":"model"},{"id":"grok-build-0.1","label":"Grok Build 0.1","efforts":[],"defaultEffort":null,"source":"https://docs.x.ai/developers/models","nativeSource":"https://github.com/xai-org/grok-build/blob/main/crates/codegen/xai-grok-pager/docs/user-guide/16-subagents.md","kind":"model"}],"note":"Per-subagent models are set in config.toml [subagents.models]; model IDs follow the documented xAI model list and account access varies. Per-role effort is not exposed by the agent-file schema, so subagents use the main session effort. [subagents] max_concurrent is a native cap."}}},"roles":[{"id":"worker","name":"Coder","kind":"code","assignment":"scoped implementation and fixes","description":"Implements scoped changes, preserves peers' edits, and verifies the result.","prompt":"Implement the assigned change or fix within the assigned files. You share the workspace with other agents: preserve their edits. Verify the result and report changes, checks, and remaining limitations. Do not create child agents; return any need for further delegation to the parent."},{"id":"reviewer","name":"Reviewer","kind":"code","assignment":"read-only correctness, security and regression review","description":"Reviews correctness, security and regressions without edits; reports actionable evidence.","prompt":"Review the assigned change without editing files. Find actionable correctness, security, and regression issues. Report each finding with file and line evidence and explain its impact; distinguish confirmed issues from uncertainty. Do not create child agents; return any need for further delegation to the parent."},{"id":"explorer","name":"Code explorer","kind":"light","assignment":"read-only code and documentation discovery","description":"Maps code and documentation, cites sources, and separates facts from uncertainty.","prompt":"Explore the assigned code and documentation without editing files. Return a concise map or factual answer with source paths or citations. Distinguish verified facts from assumptions and unknowns. Do not create child agents; return any need for further delegation to the parent."},{"id":"tester","name":"Test writer","kind":"code","assignment":"test creation and targeted execution","description":"Writes behavior and edge-case tests, reproduces issues, and runs targeted checks.","prompt":"Own the assigned tests and targeted execution. Reproduce the issue or establish a baseline, then test observable behavior and edge cases. Never weaken checks to make them pass. Do not edit application code unless explicitly assigned. Preserve peers' edits and report results and limitations. Do not create child agents; return any need for further delegation to the parent."},{"id":"writer","name":"Docs writer","kind":"light","assignment":"assigned documentation, examples and release notes","description":"Updates assigned docs and examples, verifies claims, and keeps terminology consistent.","prompt":"Update only the assigned documentation, examples, or release notes. Verify claims against code or cited sources and use consistent terminology. Do not edit application code. Preserve peers' edits and report changes and unknowns. Do not create child agents; return any need for further delegation to the parent."},{"id":"routine","name":"Task runner","kind":"light","assignment":"explicit commands and mechanical edits","description":"Runs prescribed commands and mechanical edits; returns ambiguous decisions to the parent.","prompt":"Execute only the prescribed commands or clearly specified mechanical edits. Preserve other agents' work and report the outcome. Do not make ambiguous design or behavior decisions; return those decisions to the parent. Do not create child agents; return any need for further delegation to the parent."}],"unreleased":false};
|
|
279
328
|
// Pure command codec, also embedded in the offline configuration page.
|
|
280
|
-
const TOOL_FLAGS=Object.freeze({
|
|
281
|
-
const EXPLICIT_FIELDS=Object.freeze(['roles','max-concurrent',...Object.keys(TOOL_FLAGS),...Object.keys(TOOL_FLAGS).map(flag=>'avoid-'+flag)]);
|
|
329
|
+
const TOOL_FLAGS=Object.freeze({chatgpt:'chatgpt',claude:'claude',kimi:'kimi',gemini:'gemini',grok:'grok'});
|
|
330
|
+
const EXPLICIT_FIELDS=Object.freeze(['roles','max-concurrent',...Object.keys(TOOL_FLAGS),...Object.keys(TOOL_FLAGS).map(flag=>'avoid-'+flag),...Object.keys(TOOL_FLAGS).map(flag=>flag+'-max-concurrent')]);
|
|
282
331
|
const EXPLICIT_MODEL=/^[A-Za-z0-9][A-Za-z0-9._:@/\[\]-]{0,127}$/;
|
|
283
332
|
const EXPLICIT_EFFORTS=['none','minimal','low','medium','high','xhigh','max'];
|
|
284
333
|
function invalidExplicit(){throw Object.assign(new Error('Invalid explicit configuration.'),{code:'INVALID_EXPLICIT_CONFIG'});}
|
|
@@ -289,6 +338,8 @@ function explicitList(value,limit){
|
|
|
289
338
|
return list;
|
|
290
339
|
}
|
|
291
340
|
|
|
341
|
+
// Grok has no per-role effort, so its value is the whole model id; a trailing ':<effort>' would be ambiguous and is refused.
|
|
342
|
+
const grokEffortSuffix=model=>{const colon=model.lastIndexOf(':');return colon>=0&&['native',...EXPLICIT_EFFORTS].includes(model.slice(colon+1));};
|
|
292
343
|
function parseExplicitOptions(options,roleIds){
|
|
293
344
|
if(!options||typeof options!=='object'||Array.isArray(options))invalidExplicit();
|
|
294
345
|
const fields=Object.getOwnPropertyDescriptors(options);
|
|
@@ -299,7 +350,7 @@ function parseExplicitOptions(options,roleIds){
|
|
|
299
350
|
if(requested.some(role=>!roleIds.includes(role)))invalidExplicit();
|
|
300
351
|
const roles=roleIds.filter(role=>requested.includes(role)),maxConcurrent=Number(options['max-concurrent']);
|
|
301
352
|
if(!/^[1-9]\d*$/.test(options['max-concurrent'])||!Number.isInteger(maxConcurrent)||maxConcurrent>32)invalidExplicit();
|
|
302
|
-
for(const flag of Object.keys(TOOL_FLAGS))if(options['avoid-'+flag]!==undefined&&options[flag]===undefined)invalidExplicit();
|
|
353
|
+
for(const flag of Object.keys(TOOL_FLAGS))if((options['avoid-'+flag]!==undefined||options[flag+'-max-concurrent']!==undefined)&&options[flag]===undefined)invalidExplicit();
|
|
303
354
|
const clients={};
|
|
304
355
|
for(const flag of Object.keys(options).filter(flag=>Object.hasOwn(TOOL_FLAGS,flag))){
|
|
305
356
|
const client=TOOL_FLAGS[flag],choices={};
|
|
@@ -307,7 +358,8 @@ function parseExplicitOptions(options,roleIds){
|
|
|
307
358
|
const at=entry.indexOf('='),role=entry.slice(0,at).trim(),value=entry.slice(at+1).trim();
|
|
308
359
|
if(at<1||!roles.includes(role)||Object.hasOwn(choices,role))invalidExplicit();
|
|
309
360
|
let model=value,effort=null;
|
|
310
|
-
if(client==='
|
|
361
|
+
if(client==='gemini'){if(!['pro','flash','flash_lite','inherit'].includes(model))invalidExplicit();}
|
|
362
|
+
else if(client==='grok'){if(grokEffortSuffix(value))invalidExplicit();}
|
|
311
363
|
else{
|
|
312
364
|
const colon=value.lastIndexOf(':');if(colon<1)invalidExplicit();
|
|
313
365
|
model=value.slice(0,colon);const level=value.slice(colon+1);
|
|
@@ -319,7 +371,9 @@ function parseExplicitOptions(options,roleIds){
|
|
|
319
371
|
const avoidModels=options['avoid-'+flag]===undefined?[]:explicitList(options['avoid-'+flag],32);
|
|
320
372
|
if(avoidModels.some(model=>!EXPLICIT_MODEL.test(model)))invalidExplicit();
|
|
321
373
|
const first=choices[roles[0]];
|
|
322
|
-
|
|
374
|
+
const limit=options[flag+'-max-concurrent'];
|
|
375
|
+
if(limit!==undefined&&(!/^[1-9]\d*$/.test(limit)||Number(limit)>32))invalidExplicit();
|
|
376
|
+
clients[client]={...(limit===undefined?{}:{maxConcurrent:Number(limit)}),code:{...first},light:{...first},roles:Object.fromEntries(roles.map(role=>[role,choices[role]])),avoidModels};
|
|
323
377
|
}
|
|
324
378
|
if(!Object.keys(clients).length)invalidExplicit();
|
|
325
379
|
return {schemaVersion:1,maxConcurrent,...(roles.length===roleIds.length?{}:{selectedRoles:roles}),clients};
|
|
@@ -341,9 +395,11 @@ function explicitOptions(config,roleCatalog){
|
|
|
341
395
|
options[flag]=roles.map(role=>{
|
|
342
396
|
const selected=preferences.roles?.[role]??preferences[kinds.get(role)];
|
|
343
397
|
if(!selected||typeof selected.model!=='string'||!EXPLICIT_MODEL.test(selected.model)||(selected.effort!==null&&!EXPLICIT_EFFORTS.includes(selected.effort)))invalidExplicit();
|
|
344
|
-
if(
|
|
345
|
-
|
|
398
|
+
if(['gemini','grok'].includes(client)&&selected.effort!==null)invalidExplicit();
|
|
399
|
+
if(client==='grok'&&grokEffortSuffix(selected.model))invalidExplicit();
|
|
400
|
+
return `${role}=${selected.model}${['gemini','grok'].includes(client)?'':':'+(selected.effort??'native')}`;
|
|
346
401
|
}).join(',');
|
|
402
|
+
if(preferences.maxConcurrent!==undefined)options[flag+'-max-concurrent']=String(preferences.maxConcurrent);
|
|
347
403
|
if(!Array.isArray(preferences.avoidModels)||preferences.avoidModels.some(model=>typeof model!=='string'||!EXPLICIT_MODEL.test(model)))invalidExplicit();
|
|
348
404
|
if(preferences.avoidModels.length)options['avoid-'+flag]=preferences.avoidModels.join(',');
|
|
349
405
|
}
|
|
@@ -355,13 +411,13 @@ function formatExplicitCommand(config,version,roleCatalog){
|
|
|
355
411
|
if(typeof version!=='string'||!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version))throw new Error('Invalid release version.');
|
|
356
412
|
const options=explicitOptions(config,roleCatalog),quote=value=>"'"+value.replaceAll("'","'\"'\"'")+"'";
|
|
357
413
|
const lines=[`npx --yes --ignore-scripts --package agent-policy-kit@${version} agent-policy setup`];
|
|
358
|
-
for(const [name,value]of Object.entries(options))lines.push(`--${name} ${name==='max-concurrent'?value:quote(value)}`);
|
|
414
|
+
for(const [name,value]of Object.entries(options))lines.push(`--${name} ${name==='max-concurrent'||name.endsWith('-max-concurrent')?value:quote(value)}`);
|
|
359
415
|
lines.push('--apply');return lines.join(' \\\n ');
|
|
360
416
|
}
|
|
361
417
|
|
|
362
418
|
// Pure URL state codec, also embedded in the offline configuration page.
|
|
363
419
|
const SHARE_BYTES=65536,SHARE_TOKEN=87384;
|
|
364
|
-
const SHARE_VERSION
|
|
420
|
+
const SHARE_VERSION=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?$/;
|
|
365
421
|
const SHARE_UNSAFE=new Set(['__proto__','constructor','prototype']);
|
|
366
422
|
function invalidShare(){throw Object.assign(new Error('Invalid shared configuration link.'),{code:'INVALID_SHARE_LINK'});}
|
|
367
423
|
|
|
@@ -407,46 +463,67 @@ function shareRelease(release){
|
|
|
407
463
|
}
|
|
408
464
|
for(const preset of release.presets){
|
|
409
465
|
shareRecord(preset);if(typeof preset.id!=='string'||!preset.id||preset.id==='custom'||SHARE_UNSAFE.has(preset.id)||presets.has(preset.id))invalidShare();
|
|
410
|
-
shareRecord(shareRecord(preset.preferences).clients);
|
|
466
|
+
shareRecord(shareRecord(preset.preferences).clients);
|
|
467
|
+
if(preset.topModels!==undefined&&Object.values(shareRecord(preset.topModels)).some(model=>typeof model!=='string'))invalidShare();
|
|
468
|
+
presets.set(preset.id,preset);
|
|
411
469
|
}
|
|
412
470
|
if(!presets.has(release.preset))invalidShare();
|
|
413
471
|
return {clients,roles,presets,catalog};
|
|
414
472
|
}
|
|
415
473
|
function shareChoice(choice,id,metadata){
|
|
416
474
|
shareRecord(choice,['model','effort']);
|
|
417
|
-
if(typeof choice.model!=='string'||choice.model.length>128||(choice.effort!==null&&(
|
|
475
|
+
if(typeof choice.model!=='string'||choice.model.length>128||(choice.effort!==null&&(['gemini','grok'].includes(id)||!metadata.catalog[id].efforts.includes(choice.effort))))invalidShare();
|
|
418
476
|
return {model:choice.model,effort:choice.effort};
|
|
419
477
|
}
|
|
420
478
|
function sharePayload(payload,release,metadata){
|
|
421
|
-
shareRecord(payload
|
|
422
|
-
if(payload.v!==
|
|
423
|
-
|
|
424
|
-
if(
|
|
479
|
+
shareRecord(payload);const legacy=payload.v===1;
|
|
480
|
+
if(!legacy&&payload.v!==2)invalidShare();
|
|
481
|
+
shareRecord(payload,legacy?['v','release','roles','tools','scope','maxConcurrent']:['v','release','roles','tools','scope']);
|
|
482
|
+
if(typeof payload.release!=='string'||payload.release.length>128||!SHARE_VERSION.test(payload.release))invalidShare();
|
|
483
|
+
if(legacy&&(!Number.isInteger(payload.maxConcurrent)||payload.maxConcurrent<1||payload.maxConcurrent>32))invalidShare();
|
|
484
|
+
if(payload.release!==release.version){
|
|
485
|
+
// Validate the wire shape without imposing today's models or preset values on
|
|
486
|
+
// an older release. Invalid links must never turn into navigation.
|
|
487
|
+
const identifier=value=>typeof value==='string'&&/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(value);
|
|
488
|
+
if(!Array.isArray(payload.roles)||payload.roles.length>1000||payload.roles.some(role=>!identifier(role)))invalidShare();
|
|
489
|
+
const roles=shareList(payload.roles,payload.roles),ids=[];
|
|
490
|
+
if(!Array.isArray(payload.tools)||payload.tools.length>32)invalidShare();
|
|
491
|
+
for(const tool of payload.tools){
|
|
492
|
+
shareRecord(tool,legacy?['id','mode','base','choices']:['id','mode','base','choices','maxConcurrent']);if(!legacy&&(!Number.isInteger(tool.maxConcurrent)||tool.maxConcurrent<1||tool.maxConcurrent>32))invalidShare();if(!identifier(tool.id)||ids.includes(tool.id)||!identifier(tool.base)||(tool.mode!==null&&!identifier(tool.mode)))invalidShare();ids.push(tool.id);
|
|
493
|
+
shareRecord(tool.choices,roles);for(const role of roles){const choice=shareRecord(tool.choices[role],['model','effort']);if(typeof choice.model!=='string'||choice.model.length>128||(choice.effort!==null&&(typeof choice.effort!=='string'||choice.effort.length>32)))invalidShare();}
|
|
494
|
+
}
|
|
495
|
+
if(payload.scope!==null&&(typeof payload.scope!=='string'||(payload.scope==='all'?ids.length<2:!ids.includes(payload.scope))))invalidShare();
|
|
496
|
+
throw Object.assign(new Error('This link uses a different release.'),{code:'SHARE_RELEASE_MISMATCH',releaseVersion:payload.release});
|
|
497
|
+
}
|
|
425
498
|
const roles=shareList(payload.roles,[...metadata.roles.keys()]);
|
|
426
499
|
if(!Array.isArray(payload.tools)||payload.tools.length>metadata.clients.length)invalidShare();
|
|
427
500
|
const selected=[];
|
|
428
501
|
const tools=payload.tools.map(tool=>{
|
|
429
|
-
shareRecord(tool,['id','mode','base','choices']);
|
|
502
|
+
shareRecord(tool,legacy?['id','mode','base','choices']:['id','mode','base','choices','maxConcurrent']);if(!legacy&&(!Number.isInteger(tool.maxConcurrent)||tool.maxConcurrent<1||tool.maxConcurrent>32))invalidShare();
|
|
430
503
|
const {id,mode,base}=tool;
|
|
431
504
|
if(!metadata.clients.includes(id)||selected.includes(id)||!metadata.presets.has(base)||(mode!==null&&mode!=='custom'&&!metadata.presets.has(mode)))invalidShare();
|
|
432
505
|
selected.push(id);shareRecord(tool.choices,roles);
|
|
433
506
|
const choices=Object.fromEntries(roles.map(role=>[role,shareChoice(tool.choices[role],id,metadata)]));
|
|
434
507
|
if(mode!==null&&mode!=='custom'){
|
|
435
508
|
if(mode!==base)invalidShare();
|
|
436
|
-
const
|
|
509
|
+
const named=metadata.presets.get(mode),preset=named.preferences,clients=preset.clients;
|
|
510
|
+
if(!legacy&&tool.maxConcurrent!==(clients[id]?.maxConcurrent??preset.maxConcurrent))invalidShare();
|
|
437
511
|
if(!Object.hasOwn(clients,id))invalidShare();
|
|
438
|
-
const preferences=shareRecord(clients[id]);
|
|
512
|
+
const preferences=shareRecord(clients[id]),own=role=>preferences.roles&&Object.hasOwn(preferences.roles,role);
|
|
513
|
+
// A preset's optional top model replaces every shared code role that has no role-specific choice, or none of them.
|
|
514
|
+
const top=named.topModels&&Object.hasOwn(named.topModels,id)?named.topModels[id]:null;
|
|
515
|
+
const topRoles=roles.filter(role=>metadata.roles.get(role).kind==='code'&&!own(role)),topped=top!==null&&topRoles.some(role=>choices[role].model===top);
|
|
439
516
|
for(const role of roles){
|
|
440
|
-
const expected=
|
|
441
|
-
const choice=shareChoice(expected,id,metadata);
|
|
517
|
+
const expected=own(role)?preferences.roles[role]:preferences[metadata.roles.get(role).kind];
|
|
518
|
+
const choice=shareChoice(expected,id,metadata);if(topped&&topRoles.includes(role))choice.model=top;
|
|
442
519
|
if(choice.model!==choices[role].model||choice.effort!==choices[role].effort)invalidShare();
|
|
443
520
|
}
|
|
444
521
|
}
|
|
445
|
-
return {id,mode,base,choices};
|
|
522
|
+
return {id,mode,base,choices,...(legacy?{}:{maxConcurrent:tool.maxConcurrent})};
|
|
446
523
|
});
|
|
447
524
|
const scope=payload.scope;
|
|
448
525
|
if(scope!==null&&(typeof scope!=='string'||(scope==='all'?tools.length<2:!selected.includes(scope))))invalidShare();
|
|
449
|
-
return {v:
|
|
526
|
+
return {v:payload.v,release:payload.release,roles,tools,scope,...(legacy?{maxConcurrent:payload.maxConcurrent}:{})};
|
|
450
527
|
}
|
|
451
528
|
function shareBase64(bytes){return btoa(Array.from(bytes,byte=>String.fromCharCode(byte)).join('')).replaceAll('+','-').replaceAll('/','_').replace(/=+$/,'');}
|
|
452
529
|
function shareJson(text){
|
|
@@ -472,15 +549,16 @@ function encodeFormState(snapshot,release){
|
|
|
472
549
|
shareData(snapshot);shareRecord(snapshot);
|
|
473
550
|
const metadata=shareRelease(release),state=shareRecord(snapshot.state),profiles=shareRecord(state.profiles),jobs=shareRecord(state.jobs);
|
|
474
551
|
const roles=shareList(snapshot.helpers,[...metadata.roles.keys()]),selected=shareList(snapshot.pickedTools,metadata.clients);
|
|
552
|
+
const modern=Object.values(profiles).some(profile=>Object.hasOwn(profile,'maxConcurrent'));
|
|
475
553
|
const tools=selected.map(id=>{
|
|
476
554
|
if(!Object.hasOwn(profiles,id)||!Object.hasOwn(jobs,id))invalidShare();
|
|
477
555
|
const profile=shareRecord(profiles[id]),choices=shareRecord(jobs[id]);
|
|
478
556
|
if(typeof profile.custom!=='boolean'||(profile.modeSelected!==undefined&&typeof profile.modeSelected!=='boolean'))invalidShare();
|
|
479
|
-
return {id,mode:profile.modeSelected===false?null:profile.custom?'custom':profile.presetId,base:profile.presetId,choices:Object.fromEntries(roles.map(role=>{
|
|
557
|
+
return {id,...(modern?{maxConcurrent:Object.hasOwn(profile,'maxConcurrent')?profile.maxConcurrent:state.maxConcurrent}:{}),mode:profile.modeSelected===false?null:profile.custom?'custom':profile.presetId,base:profile.presetId,choices:Object.fromEntries(roles.map(role=>{
|
|
480
558
|
if(!Object.hasOwn(choices,role))invalidShare();return [role,shareChoice(choices[role],id,metadata)];
|
|
481
559
|
}))};
|
|
482
560
|
});
|
|
483
|
-
const payload=sharePayload({v:1,release:release.version,roles,tools,scope:snapshot.selectedScope
|
|
561
|
+
const payload=sharePayload({v:modern?2:1,release:release.version,roles,tools,scope:snapshot.selectedScope,...(modern?{}:{maxConcurrent:state.maxConcurrent})},release,metadata);
|
|
484
562
|
if(!roles.length&&!tools.length)return '';
|
|
485
563
|
const bytes=new TextEncoder().encode(JSON.stringify(payload));if(bytes.length>SHARE_BYTES)invalidShare();
|
|
486
564
|
const token=shareBase64(bytes);if(token.length>SHARE_TOKEN)invalidShare();return '#setup='+token;
|
|
@@ -501,25 +579,63 @@ function decodeFormState(fragment,release){
|
|
|
501
579
|
}catch(error){if(error?.code==='INVALID_SHARE_LINK'||error?.code==='SHARE_RELEASE_MISMATCH')throw error;invalidShare();}
|
|
502
580
|
}
|
|
503
581
|
|
|
582
|
+
function archivedReleaseUrl(error,href,hostedReleases=[]){
|
|
583
|
+
if(error?.code!=='SHARE_RELEASE_MISMATCH'||typeof error.releaseVersion!=='string'||error.releaseVersion.length>128||!SHARE_VERSION.test(error.releaseVersion)||!Array.isArray(hostedReleases)||!hostedReleases.includes(error.releaseVersion))return null;
|
|
584
|
+
try{
|
|
585
|
+
const current=new URL(href);if(!['http:','https:'].includes(current.protocol)||current.username||current.password||current.pathname!=='/'||!current.hash.startsWith('#setup='))return null;
|
|
586
|
+
const target=new URL(`/v/${error.releaseVersion}/`,current.origin);target.hash=current.hash;
|
|
587
|
+
return target.origin===current.origin?target.href:null;
|
|
588
|
+
}catch{return null;}
|
|
589
|
+
}
|
|
590
|
+
|
|
504
591
|
(() => {
|
|
505
|
-
const CLIENTS = ['
|
|
592
|
+
const CLIENTS = ['chatgpt', 'claude', 'kimi', 'gemini', 'grok'];
|
|
506
593
|
const ROLES = RELEASE.roles.map(role=>role.id);
|
|
507
594
|
const ROLE_KINDS=Object.fromEntries(RELEASE.roles.map(role=>[role.id,role.kind]));
|
|
508
595
|
const TIERS = ['pro', 'flash', 'flash_lite', 'inherit'];
|
|
509
596
|
const IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:@/\[\]-]{0,127}$/;
|
|
510
|
-
const LABELS = {
|
|
597
|
+
const LABELS = {chatgpt: 'ChatGPT', claude: 'Claude', kimi: 'Kimi', gemini: 'Gemini', grok: 'Grok'};
|
|
511
598
|
const TASKS = Object.fromEntries(RELEASE.roles.map(role=>[role.id,role.name]));
|
|
512
|
-
const NOTES = {
|
|
599
|
+
const NOTES = {chatgpt: '', claude: '', kimi: 'Effort changes apply to every task using the same alias.', gemini: 'Native tiers only; per-task effort is unavailable.', grok: 'Per-task effort is unavailable; subagents use the main session effort.'};
|
|
513
600
|
const clone = value => JSON.parse(JSON.stringify(value));
|
|
601
|
+
const addAll = (selected, available) => [...selected, ...available.filter(id => !selected.includes(id))];
|
|
514
602
|
function effective(config, role) {
|
|
515
603
|
return config.roles?.[role] ?? config[ROLE_KINDS[role]];
|
|
516
604
|
}
|
|
517
605
|
function initialState(preferences, presetId = 'balanced', {empty=false}={}) {
|
|
518
606
|
const available = CLIENTS.filter(client => preferences.clients[client]),selected=empty?[]:available;
|
|
519
|
-
return {selected, active: empty?null:'all', maxConcurrent: preferences.maxConcurrent,...(empty?{selectedRoles:[]}:{}),
|
|
520
|
-
profiles: Object.fromEntries(available.map(client => [client, {presetId, custom: false, modeSelected:!empty,presetCap:preferences.maxConcurrent,preferences: clone(preferences.clients[client])}])),
|
|
607
|
+
return {selected, active: empty?null:'all', maxConcurrent: preferences.maxConcurrent,...(empty?{selectedRoles:[...ROLES]}:{}),
|
|
608
|
+
profiles: Object.fromEntries(available.map(client => [client, {presetId, custom: false, modeSelected:!empty,top:topModelFor(RELEASE.presets?.find(preset=>preset.id===presetId),client),presetCap:preferences.clients[client].maxConcurrent??preferences.maxConcurrent,maxConcurrent:preferences.clients[client].maxConcurrent??preferences.maxConcurrent,preferences: clone(preferences.clients[client])}])),
|
|
521
609
|
jobs: Object.fromEntries(available.map(client => [client, Object.fromEntries(ROLES.map(role => [role, clone(effective(preferences.clients[client], role))]))]))};
|
|
522
610
|
}
|
|
611
|
+
function topModelFor(preset, client) {return typeof preset?.topModels?.[client]==='string'?preset.topModels[client]:null;}
|
|
612
|
+
// Code roles without a role-specific preset choice can switch to the preset's optional top model.
|
|
613
|
+
function topModelRoles(state, client) {
|
|
614
|
+
const profile=state.profiles?.[client];
|
|
615
|
+
if(!profile?.top||profile.custom||profile.modeSelected===false)return [];
|
|
616
|
+
return ROLES.filter(role=>ROLE_KINDS[role]==='code'&&!profile.preferences.roles?.[role]);
|
|
617
|
+
}
|
|
618
|
+
function topModelsOn(state, client) {
|
|
619
|
+
const roles=topModelRoles(state,client).filter(role=>(state.selectedRoles??ROLES).includes(role));
|
|
620
|
+
return roles.length>0&&roles.every(role=>state.jobs?.[client]?.[role]?.model===state.profiles[client].top);
|
|
621
|
+
}
|
|
622
|
+
function setTopModels(state, clients, on) {
|
|
623
|
+
for(const client of clients){
|
|
624
|
+
const profile=state.profiles[client];
|
|
625
|
+
for(const role of topModelRoles(state,client)){const base=effective(profile.preferences,role);state.jobs[client][role]={model:on?profile.top:base.model,effort:base.effort};}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function presetJob(state, client, role) {
|
|
629
|
+
const profile=state.profiles[client],base=effective(profile.preferences,role);
|
|
630
|
+
return topModelsOn(state,client)&&topModelRoles(state,client).includes(role)?{model:profile.top,effort:base.effort}:base;
|
|
631
|
+
}
|
|
632
|
+
// Tools whose presets choose identical role models differ only by parallel limits.
|
|
633
|
+
function presetModelSummary(presets, client) {
|
|
634
|
+
const choices=presets.map(preset=>{const config=preset.preferences?.clients?.[client];return config?ROLES.map(role=>effective(config,role)):null;});
|
|
635
|
+
if(!choices.length||choices.some(value=>value===null))return {same:false,model:null};
|
|
636
|
+
const first=JSON.stringify(choices[0]),same=choices.every(value=>JSON.stringify(value)===first),models=new Set(choices[0].map(choice=>choice.model));
|
|
637
|
+
return {same,model:same&&models.size===1?[...models][0]:null};
|
|
638
|
+
}
|
|
523
639
|
function modeFor(state, client = state.active) {
|
|
524
640
|
if (client !== 'all') {const profile=state.profiles[client];return !profile||profile.modeSelected===false?null:profile.custom?'custom':profile.presetId;}
|
|
525
641
|
const modes = (Array.isArray(state.selected)?state.selected:[]).map(client => modeFor(state, client));
|
|
@@ -533,18 +649,49 @@ function decodeFormState(fragment,release){
|
|
|
533
649
|
const mixed=new Set(chosen.map(client=>state.profiles[client].presetId)).size>1,pending=chosen.length<targets.length;
|
|
534
650
|
const edited=chosen.some(client=>{
|
|
535
651
|
const profile=state.profiles[client];
|
|
536
|
-
return (
|
|
652
|
+
return concurrencyFor(state,client)!==profile.presetCap||ROLES.some(role=>{const current=state.jobs?.[client]?.[role],base=presetJob(state,client,role);return current?.model!==base.model||current?.effort!==base.effort;});
|
|
537
653
|
});
|
|
538
|
-
|
|
654
|
+
// The scope warning only matters when other selected tools keep their choices; otherwise ask only before losing edits.
|
|
655
|
+
const scoped=!all&&(Array.isArray(state.selected)?state.selected.length:0)>1;
|
|
656
|
+
if(replacing&&(scoped||mixed||pending||edited)&&!confirmReplace())return state;
|
|
539
657
|
const next = clone(state);
|
|
540
658
|
for (const client of targets) {
|
|
541
659
|
const preferences = preset.preferences.clients[client];
|
|
542
|
-
next.profiles[client] = {presetId: preset.id ?? 'balanced', custom: false, modeSelected:true,presetCap:preset.preferences.maxConcurrent,preferences: clone(preferences)};
|
|
660
|
+
next.profiles[client] = {presetId: preset.id ?? 'balanced', custom: false, modeSelected:true,top:topModelFor(preset,client),presetCap:preferences.maxConcurrent??preset.preferences.maxConcurrent,maxConcurrent:preferences.maxConcurrent??preset.preferences.maxConcurrent,preferences: clone(preferences)};
|
|
543
661
|
next.jobs[client] = Object.fromEntries(ROLES.map(role => [role, clone(effective(preferences, role))]));
|
|
544
662
|
}
|
|
545
|
-
if (all) next.maxConcurrent = preset.preferences.maxConcurrent;
|
|
546
663
|
return next;
|
|
547
664
|
}
|
|
665
|
+
function concurrencyFor(state, client) {
|
|
666
|
+
const profile=state.profiles?.[client];
|
|
667
|
+
return profile&&Object.hasOwn(profile,'maxConcurrent')?profile.maxConcurrent:state.maxConcurrent;
|
|
668
|
+
}
|
|
669
|
+
function updateConcurrency(state, client, value) {
|
|
670
|
+
const profile=state.profiles[client];
|
|
671
|
+
if(!profile)throw new Error('Choose one AI assistant.');
|
|
672
|
+
const count=Number(value),next=value===''?'':Number.isFinite(count)?count:String(value);
|
|
673
|
+
if(next!==concurrencyFor(state,client)){profile.custom=true;profile.modeSelected=true;}
|
|
674
|
+
profile.maxConcurrent=next;
|
|
675
|
+
}
|
|
676
|
+
function stepConcurrency(state, client, step) {
|
|
677
|
+
const current=concurrencyFor(state,client),value=Number(current);
|
|
678
|
+
updateConcurrency(state,client,current!==''&&Number.isInteger(value)?Math.max(1,Math.min(32,value+step)):1);
|
|
679
|
+
}
|
|
680
|
+
function restoreState(data, preferences, presets, presetId='balanced') {
|
|
681
|
+
const state=initialState(preferences,presetId,{empty:true});
|
|
682
|
+
if(data.v===1){state.maxConcurrent=data.maxConcurrent;for(const profile of Object.values(state.profiles))profile.maxConcurrent=data.maxConcurrent;}
|
|
683
|
+
state.selected=data.tools.map(tool=>tool.id);state.selectedRoles=[...data.roles];
|
|
684
|
+
state.active=data.scope??(state.selected.length>=2?'all':state.selected[0]??null);
|
|
685
|
+
for(const tool of data.tools){
|
|
686
|
+
const base=presets.find(preset=>preset.id===tool.base),selected=clone(base.preferences.clients[tool.id]);
|
|
687
|
+
const presetCap=selected.maxConcurrent??base.preferences.maxConcurrent,maxConcurrent=data.v===1?data.maxConcurrent:tool.maxConcurrent;
|
|
688
|
+
state.profiles[tool.id]={presetId:tool.base,custom:tool.mode==='custom'||tool.mode!==null&&maxConcurrent!==presetCap,modeSelected:tool.mode!==null,top:topModelFor(base,tool.id),presetCap,maxConcurrent,preferences:selected};
|
|
689
|
+
state.jobs[tool.id]=Object.fromEntries(ROLES.map(role=>[role,clone(effective(selected,role))]));
|
|
690
|
+
for(const [role,choice]of Object.entries(tool.choices))state.jobs[tool.id][role]={...choice};
|
|
691
|
+
if(topModelRoles(state,tool.id).some(role=>tool.choices[role]?.model===state.profiles[tool.id].top))setTopModels(state,[tool.id],true);
|
|
692
|
+
}
|
|
693
|
+
return state;
|
|
694
|
+
}
|
|
548
695
|
function allowedEfforts(catalog, model) {
|
|
549
696
|
const supported = catalog?.models?.find(choice => choice.id === model)?.efforts ?? catalog?.efforts ?? [];
|
|
550
697
|
return [null, ...new Set(supported.filter(effort => effort !== null))];
|
|
@@ -554,7 +701,7 @@ function decodeFormState(fragment,release){
|
|
|
554
701
|
const config = preferences.clients[client];
|
|
555
702
|
const recommendations = [config.code, config.light, ...Object.values(config.roles ?? {})];
|
|
556
703
|
const efforts = [...new Set(recommendations.map(choice => choice.effort).filter(effort => effort !== null))];
|
|
557
|
-
const ids = client === '
|
|
704
|
+
const ids = client === 'gemini' ? TIERS : [...new Set(recommendations.map(choice => choice.model))];
|
|
558
705
|
return {label: LABELS[client], efforts, models: ids.map(id => ({id, label: id, efforts, defaultEffort: recommendations.find(choice => choice.model === id)?.effort ?? null}))};
|
|
559
706
|
}
|
|
560
707
|
function preferenceForModel(config, role, model, jobs = {}, catalog, syncAliases = false) {
|
|
@@ -578,10 +725,11 @@ function decodeFormState(fragment,release){
|
|
|
578
725
|
}
|
|
579
726
|
function buildConfig(state, preferences, catalog = RELEASE.catalog) {
|
|
580
727
|
const errors = [];
|
|
581
|
-
const
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
728
|
+
const selectedTools=(Array.isArray(state.selected)?state.selected:[]).filter(client=>CLIENTS.includes(client));
|
|
729
|
+
const limits=selectedTools.map(client=>concurrencyFor(state,client));
|
|
730
|
+
const maxConcurrent=limits.length&&limits.every(limit=>limit===limits[0])&&Number.isInteger(limits[0])&&limits[0]>=1&&limits[0]<=32?limits[0]:preferences.maxConcurrent;
|
|
731
|
+
if (!Array.isArray(state.selected) || !state.selected.length) errors.push('Choose at least one AI assistant.');
|
|
732
|
+
else if(new Set(state.selected).size!==state.selected.length||state.selected.some(client=>!CLIENTS.includes(client)))errors.push('Choose supported AI assistants.');
|
|
585
733
|
const selection=state.selectedRoles===undefined?ROLES:Array.isArray(state.selectedRoles)?state.selectedRoles:[];
|
|
586
734
|
if(!selection.length||new Set(selection).size!==selection.length||selection.some(role=>!ROLES.includes(role)))errors.push('Choose valid subagent roles.');
|
|
587
735
|
const selectedRoles=ROLES.filter(role=>selection.includes(role));
|
|
@@ -590,7 +738,9 @@ function decodeFormState(fragment,release){
|
|
|
590
738
|
if(state.profiles?.[client]?.modeSelected===false){errors.push(`${LABELS[client]}: choose a work mode.`);continue;}
|
|
591
739
|
const defaults = state.profiles?.[client]?.preferences ?? preferences.clients[client];
|
|
592
740
|
if (!defaults) { errors.push(`${LABELS[client]} has no release defaults.`); continue; }
|
|
593
|
-
const config = clone(defaults);
|
|
741
|
+
const config = clone(defaults),limit=concurrencyFor(state,client);
|
|
742
|
+
if(!Number.isInteger(limit)||limit<1||limit>32)errors.push(`${LABELS[client]}: enter a whole number from 1 to 32 for parallel subagents.`);
|
|
743
|
+
if(limit===maxConcurrent)delete config.maxConcurrent;else config.maxConcurrent=limit;
|
|
594
744
|
const roles = {};
|
|
595
745
|
const choices = [];
|
|
596
746
|
for (const role of selectedRoles) {
|
|
@@ -598,10 +748,10 @@ function decodeFormState(fragment,release){
|
|
|
598
748
|
if (!choice || typeof choice.model !== 'string' || !IDENTIFIER.test(choice.model)) {
|
|
599
749
|
errors.push(`${LABELS[client]} ${TASKS[role]}: enter a valid model ID (1–128 ASCII characters, no spaces).`); continue;
|
|
600
750
|
}
|
|
601
|
-
if (client === '
|
|
602
|
-
errors.push(`
|
|
751
|
+
if (client === 'gemini' && (!TIERS.includes(choice.model) || choice.effort !== null)) {
|
|
752
|
+
errors.push(`Gemini ${TASKS[role]}: choose a supported native tier.`); continue;
|
|
603
753
|
}
|
|
604
|
-
if (client !== '
|
|
754
|
+
if (client !== 'gemini' && !allowedEfforts(clientCatalog(client, {clients: {[client]: defaults}}, catalog), choice.model).includes(choice.effort)) {
|
|
605
755
|
errors.push(`${LABELS[client]} ${TASKS[role]}: choose a supported effort.`); continue;
|
|
606
756
|
}
|
|
607
757
|
if (client === 'kimi' && choice.model === 'primary') {
|
|
@@ -637,7 +787,7 @@ function decodeFormState(fragment,release){
|
|
|
637
787
|
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
638
788
|
}
|
|
639
789
|
function buildCommand(config, release) {return formatExplicitCommand(config,release.version,RELEASE.roles);}
|
|
640
|
-
globalThis.APKConfigurator = Object.freeze({initialState, modeFor, applyPreset, effective, allowedEfforts, preferenceForModel, updateEffort, buildConfig, encodeConfig, buildCommand});
|
|
790
|
+
globalThis.APKConfigurator = Object.freeze({initialState, modeFor, presetModelSummary, topModelRoles, topModelsOn, setTopModels, applyPreset, effective, allowedEfforts, preferenceForModel, updateEffort, updateConcurrency, stepConcurrency, concurrencyFor, restoreState, addAll, buildConfig, encodeConfig, buildCommand});
|
|
641
791
|
if (typeof document === 'undefined') return;
|
|
642
792
|
|
|
643
793
|
(() => {
|
|
@@ -646,7 +796,7 @@ function decodeFormState(fragment,release){
|
|
|
646
796
|
const clients=Object.keys(RELEASE.preferences.clients),toolName=id=>RELEASE.catalog.clients[id].label;
|
|
647
797
|
const presets=RELEASE.presets,initial=presets.find(p=>p.id==='balanced')??presets[0];
|
|
648
798
|
let state=A.initialState(initial.preferences,initial.id,{empty:true});
|
|
649
|
-
let helpers=[],pickedTools=[];
|
|
799
|
+
let helpers=[...state.selectedRoles],pickedTools=[];
|
|
650
800
|
let selectedScope=null;
|
|
651
801
|
function syncTargets(){
|
|
652
802
|
state.selected=[...pickedTools];state.selectedRoles=[...helpers];
|
|
@@ -656,11 +806,15 @@ function decodeFormState(fragment,release){
|
|
|
656
806
|
syncTargets();
|
|
657
807
|
const modeName=id=>id===null?'Choose mode':presets.find(p=>p.id===id)?.label??'Custom';
|
|
658
808
|
function el(tag,attrs={},text){const n=document.createElement(tag);for(const[k,v]of Object.entries(attrs))n.setAttribute(k,v);if(text!==undefined)n.textContent=text;return n;}
|
|
659
|
-
let mounted=false,activeTransition=null,motionCount=0,motionReady=0,lastAnimationCount=0,currentCommand='',commandRevision=0,lastCopiedCommand=null,linkError='',lastAddress=location.hash;
|
|
660
|
-
$
|
|
809
|
+
let mounted=false,archiveNavigation=false,activeTransition=null,motionCount=0,motionReady=0,lastAnimationCount=0,currentCommand='',commandRevision=0,lastCopiedCommand=null,linkError='',lastAddress=location.hash;
|
|
810
|
+
const showCommand=`npx --yes --ignore-scripts --package ${RELEASE.packageSpec} agent-policy show`;
|
|
811
|
+
$('show-command').textContent=showCommand;
|
|
812
|
+
$('copy-show').addEventListener('click',async()=>{
|
|
813
|
+
const button=$('copy-show');
|
|
814
|
+
try{if(!navigator.clipboard?.writeText)throw new Error('Clipboard unavailable');await navigator.clipboard.writeText(showCommand);button.textContent='Copied';setTimeout(()=>{button.textContent='Copy';},1600);}
|
|
815
|
+
catch{$('show-command').hidden=false;getSelection()?.selectAllChildren($('show-command'));}
|
|
816
|
+
});
|
|
661
817
|
$('release-status').textContent=RELEASE.unreleased?'Release candidate · npm command available after publication.':`Configuration release ${RELEASE.version}`;
|
|
662
|
-
const guideBase=location.protocol==='file:'?new URL('../',location.href).href:`https://unpkg.com/agent-policy-kit@${RELEASE.version}/`;
|
|
663
|
-
$('agent-guide').href=guideBase+'AGENT_INSTALL.md';$('release-notes').href=guideBase+'CHANGELOG.md';
|
|
664
818
|
const reducedMotion=matchMedia('(prefers-reduced-motion:reduce)');
|
|
665
819
|
function animateUpdate(update){
|
|
666
820
|
hideRoleInfo(true);
|
|
@@ -676,21 +830,33 @@ function decodeFormState(fragment,release){
|
|
|
676
830
|
if(immediate)tip.hidden=true;else tipTimer=setTimeout(()=>{tip.hidden=true;},130);
|
|
677
831
|
}
|
|
678
832
|
function scheduleHide(){clearTimeout(tipTimer);tipTimer=setTimeout(()=>{if(!tip.matches(':hover')&&document.activeElement!==tipTrigger)hideRoleInfo();},100);}
|
|
679
|
-
function
|
|
833
|
+
function showTip(trigger,...content){
|
|
680
834
|
clearTimeout(tipTimer);tipTrigger?.removeAttribute('aria-describedby');tipTrigger=trigger;
|
|
681
|
-
tip.replaceChildren(
|
|
835
|
+
tip.replaceChildren(...content);
|
|
682
836
|
tip.hidden=false;trigger.setAttribute('aria-describedby','role-tooltip');
|
|
683
837
|
const anchor=trigger.getBoundingClientRect(),box=tip.getBoundingClientRect();
|
|
684
838
|
tip.style.left=Math.max(16,Math.min(anchor.left-12,innerWidth-box.width-16))+'px';
|
|
685
839
|
const below=anchor.bottom+8;tip.style.top=(below+box.height<innerHeight-16?below:Math.max(16,anchor.top-box.height-8))+'px';
|
|
686
840
|
requestAnimationFrame(()=>{if(tipTrigger===trigger)tip.classList.add('visible');});
|
|
687
841
|
}
|
|
688
|
-
function
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
842
|
+
function showRoleInfo(role,trigger){
|
|
843
|
+
showTip(trigger,el('strong',{},role.name),el('p',{},role.description),el('div',{class:'definition-label'},'Base role prompt'),el('pre',{},role.prompt),el('p',{class:'definition-note'},'APK saves this description and prompt as a native role. Model and effort are configured separately.'));
|
|
844
|
+
}
|
|
845
|
+
function infoButton(name,show){
|
|
846
|
+
const button=el('button',{type:'button',class:'helper-info','aria-label':'About '+name});button.append(el('span',{class:'info-dot','aria-hidden':'true'},'?'));
|
|
847
|
+
button.addEventListener('pointerenter',()=>show(button));button.addEventListener('pointerleave',scheduleHide);
|
|
848
|
+
button.addEventListener('focus',()=>show(button));button.addEventListener('blur',scheduleHide);button.addEventListener('click',event=>{event.stopPropagation();show(button);});
|
|
692
849
|
return button;
|
|
693
850
|
}
|
|
851
|
+
function roleInfo(role){return infoButton(role.name,button=>showRoleInfo(role,button));}
|
|
852
|
+
const stepInfo={
|
|
853
|
+
'helpers-heading':'Helpers your main agent can hand work to. Each role gets its own model and effort, so routine work does not run on your most expensive model.',
|
|
854
|
+
'tools-heading':'The AI assistants you use. Only their coding agents, such as Codex in ChatGPT, get settings, and only when installed. With several, click one to adjust it separately.',
|
|
855
|
+
'mode-heading':'How much of your plan’s limits subagents may use. Light suits entry plans or many parallel sessions; Top-tier suits top plans with few.',
|
|
856
|
+
'setup-heading':'Run it in a terminal. It writes native settings for installed AI assistants once and exits. Your main model stays unchanged.'
|
|
857
|
+
};
|
|
858
|
+
$('copy-show').before(infoButton('current settings',button=>showTip(button,el('strong',{},'Check current settings'),el('p',{},'Copies a read-only command. Run it in a terminal to see the roles, models, effort and parallel limits your AI assistants use now. It changes nothing.'),el('pre',{},showCommand))));
|
|
859
|
+
for(const [id,text]of Object.entries(stepInfo)){const heading=$(id),name=heading.textContent;heading.after(infoButton(name,button=>showTip(button,el('strong',{},name),el('p',{},text))));}
|
|
694
860
|
tip.addEventListener('pointerenter',()=>clearTimeout(tipTimer));tip.addEventListener('pointerleave',scheduleHide);
|
|
695
861
|
document.addEventListener('keydown',event=>{if(event.key==='Escape')hideRoleInfo();});
|
|
696
862
|
document.addEventListener('pointerdown',event=>{if(!tip.contains(event.target)&&!tipTrigger?.contains(event.target))hideRoleInfo();});
|
|
@@ -716,9 +882,15 @@ function decodeFormState(fragment,release){
|
|
|
716
882
|
for(const kind of ['helpers','tools']){
|
|
717
883
|
const isRole=kind==='helpers',chosen=isRole?helpers:pickedTools,available=isRole?roles:clients.map(id=>({id,name:toolName(id)}));
|
|
718
884
|
const box=$(isRole?'selected-helpers':'selected-tools'),options=$(isRole?'helper-options':'tool-options');box.replaceChildren();options.replaceChildren();box.hidden=false;
|
|
885
|
+
if(available.some(item=>!chosen.includes(item.id))){
|
|
886
|
+
const all=el('button',{type:'button',class:'suggestion add-all','aria-label':isRole?'Add all subagent roles':'Add all AI assistants'},'Add all');
|
|
887
|
+
all.addEventListener('click',()=>{const next=A.addAll(chosen,available.map(item=>item.id));if(isRole)helpers=next;else pickedTools=next;render();});
|
|
888
|
+
options.append(all);
|
|
889
|
+
}
|
|
890
|
+
box.classList.toggle('is-empty',!chosen.length);
|
|
719
891
|
if(isRole&&!chosen.length)box.append(el('span',{class:'empty'},'Add roles from below'));
|
|
720
|
-
if(!isRole&&!chosen.length)box.append(el('span',{class:'empty'},'Add
|
|
721
|
-
if(!isRole&&chosen.length>=2){const all=el('button',{type:'button',class:'tool-scope scope-all','aria-label':'Configure all selected
|
|
892
|
+
if(!isRole&&!chosen.length)box.append(el('span',{class:'empty'},'Add AI assistants from below'));
|
|
893
|
+
if(!isRole&&chosen.length>=2){const all=el('button',{type:'button',class:'tool-scope scope-all','aria-label':'Configure all selected AI assistants','aria-pressed':String(state.active==='all')},'All');all.style.viewTransitionName='tool-all';all.addEventListener('click',()=>{selectedScope='all';render();});box.append(all);}
|
|
722
894
|
const ordered=isRole?available:[...chosen.map(id=>available.find(item=>item.id===id)).filter(Boolean),...available.filter(item=>!chosen.includes(item.id))];
|
|
723
895
|
for(const item of ordered){
|
|
724
896
|
if(!chosen.includes(item.id)){
|
|
@@ -735,25 +907,35 @@ function decodeFormState(fragment,release){
|
|
|
735
907
|
|
|
736
908
|
}
|
|
737
909
|
function apply(preset){
|
|
738
|
-
const message=state.active==='all'?`Apply ${preset.label} to all selected
|
|
910
|
+
const message=state.active==='all'?`Apply ${preset.label} to all selected AI assistants? This replaces their individual modes, models and effort.`:state.selected.length>1?`Apply ${preset.label} to ${toolName(state.active)} only? Other AI assistants keep their choices.`:`Replace your changes to ${toolName(state.active)} with ${preset.label}?`;
|
|
739
911
|
const next=A.applyPreset(state,preset,()=>window.confirm(message));if(next!==state){state=next;}render();
|
|
740
912
|
}
|
|
741
913
|
function renderModes(){
|
|
742
914
|
const ready=helpers.length>0&&state.selected.length>0;$('mode-empty').hidden=ready;$('mode-panel').hidden=!ready;if(!ready){$('editor').replaceChildren();return;}
|
|
743
|
-
const all=state.active==='all',mode=A.modeFor(state),scope=all?'All selected
|
|
915
|
+
const all=state.active==='all',mode=A.modeFor(state),scope=all?'All selected AI assistants':toolName(state.active);if($('scope-label').textContent!==scope){$('scope-label').textContent=scope;flashLabel($('scope-label'));}
|
|
744
916
|
const options=$('mode-options');options.replaceChildren();
|
|
745
917
|
for(const p of [...presets,{id:'custom',label:'Custom'}]){const label=el('label',{class:'mode-option'}),radio=el('input',{type:'radio',name:'mode',value:p.id,'aria-label':p.label});label.style.viewTransitionName='mode-'+p.id;radio.checked=mode===p.id;radio.addEventListener('change',()=>{if(p.id==='custom'){for(const client of (all?state.selected:[state.active])){state.profiles[client].custom=true;state.profiles[client].modeSelected=true;}render();}else apply(p);});label.append(radio,el('span',{},p.label));options.append(label);}
|
|
746
|
-
renderModeNotice();
|
|
918
|
+
renderModeNotice();renderTopModels();
|
|
747
919
|
$('advanced').hidden=all||mode===null;renderEditor();
|
|
748
920
|
}
|
|
921
|
+
function topTargets(){
|
|
922
|
+
if(A.modeFor(state)!=='quality')return [];
|
|
923
|
+
return (state.active==='all'?state.selected:[state.active]).filter(client=>A.topModelRoles(state,client).some(role=>helpers.includes(role)));
|
|
924
|
+
}
|
|
925
|
+
function renderTopModels(){
|
|
926
|
+
const targets=topTargets(),toggle=$('top-models-toggle');$('top-models').hidden=!targets.length;if(!targets.length)return;
|
|
927
|
+
const names=targets.map(client=>{const top=state.profiles[client].top;return RELEASE.catalog.clients[client].models.find(model=>model.id===top)?.label??top;});
|
|
928
|
+
const text=state.active==='all'?`Use top models (${names.join(', ')}) for code, review and tests`:`Use ${names[0]} for code, review and tests`;
|
|
929
|
+
if($('top-models-label').textContent!==text)$('top-models-label').textContent=text;
|
|
930
|
+
const on=targets.filter(client=>A.topModelsOn(state,client)).length;toggle.setAttribute('aria-checked',String(on===targets.length));toggle.toggleAttribute('data-mixed',on>0&&on<targets.length);
|
|
931
|
+
}
|
|
749
932
|
function renderModeNotice(){
|
|
750
933
|
const all=state.active==='all',mode=A.modeFor(state),notice=$('mode-notice');
|
|
751
|
-
const
|
|
752
|
-
const
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
notice.hidden=!text;
|
|
934
|
+
const shared=!all&&mode!==null&&mode!=='custom'?A.presetModelSummary(presets,state.active):{same:false,model:null};
|
|
935
|
+
const sharedModel=shared.model?RELEASE.catalog.clients[state.active].models.find(model=>model.id===shared.model)?.label??shared.model:'the same models';
|
|
936
|
+
const message=mode==='custom'?(all?'Open an AI assistant to customize its models and effort.':`Custom models and effort for ${toolName(state.active)}.`):shared.same?`${toolName(state.active)} uses ${sharedModel} for every role in every mode. Modes change only how many subagents run at once.`:(presets.find(p=>p.id===mode)?.description??'');
|
|
937
|
+
if(notice.textContent!==message){notice.replaceChildren();if(mode==='custom'&&all)notice.append('Open an ',el('strong',{},'AI assistant'),' to customize its models and effort.');else notice.append(message);}
|
|
938
|
+
notice.hidden=!message;
|
|
757
939
|
}
|
|
758
940
|
function renderEditor(){
|
|
759
941
|
const parent=$('editor');parent.replaceChildren();if(!helpers.length||!state.active||state.active==='all'||state.profiles[state.active].modeSelected===false)return;
|
|
@@ -763,7 +945,7 @@ function decodeFormState(fragment,release){
|
|
|
763
945
|
const choice=state.jobs[client][role.id],row=el('div',{class:'editor editor-row','data-helper-id':role.id,role:'group','aria-label':`${role.name} settings for ${toolName(client)}`});
|
|
764
946
|
row.style.viewTransitionName=`config-${client}-${role.id}`;
|
|
765
947
|
const name=el('div',{class:'editor-name'});name.append(el('span',{},role.name),roleInfo(role));row.append(name);
|
|
766
|
-
const modelControl=el('div',{class:'model-control'}),modelSelect=el('select',{'aria-label':`${role.name} model`,'data-model-role':role.id});catalog.models.forEach(model=>modelSelect.append(el('option',{value:model.id},model.label)));if(client!=='
|
|
948
|
+
const modelControl=el('div',{class:'model-control'}),modelSelect=el('select',{'aria-label':`${role.name} model`,'data-model-role':role.id});catalog.models.forEach(model=>modelSelect.append(el('option',{value:model.id},model.label)));if(client!=='gemini')modelSelect.append(el('option',{value:'__custom__'},'Custom model…'));
|
|
767
949
|
const known=catalog.models.some(model=>model.id===choice.model);modelSelect.value=known?choice.model:'__custom__';
|
|
768
950
|
const custom=el('input',{type:'text',class:'custom-model','aria-label':`${role.name} custom model ID`,placeholder:'Native model ID',autocomplete:'off',spellcheck:'false',maxlength:'128'});custom.hidden=known;custom.value=known?'':choice.model;
|
|
769
951
|
modelSelect.addEventListener('change',()=>{if(modelSelect.value==='__custom__'){state.jobs[client][role.id]={model:'',effort:choice.effort};state.profiles[client].custom=true;state.profiles[client].modeSelected=true;render();const focus=()=>{if(state.active===client)document.querySelector(`[aria-label="${role.name} custom model ID"]`)?.focus();};if(activeTransition)activeTransition.finished.then(focus);else focus();return;}state.jobs[client][role.id]=A.preferenceForModel(profile,role.id,modelSelect.value,state.jobs[client],catalog,client==='kimi');state.profiles[client].custom=true;state.profiles[client].modeSelected=true;render();});
|
|
@@ -780,22 +962,21 @@ function decodeFormState(fragment,release){
|
|
|
780
962
|
}
|
|
781
963
|
}
|
|
782
964
|
function freshForm(){
|
|
783
|
-
state=A.initialState(initial.preferences,initial.id,{empty:true});helpers=[];pickedTools=[];selectedScope=null;lastCopiedCommand=null;commandRevision++;for(const node of toolModeLabels.values())node.getAnimations?.().forEach(animation=>animation.cancel());toolModeLabels.clear();
|
|
965
|
+
state=A.initialState(initial.preferences,initial.id,{empty:true});helpers=[...state.selectedRoles];pickedTools=[];selectedScope=null;lastCopiedCommand=null;commandRevision++;for(const node of toolModeLabels.values())node.getAnimations?.().forEach(animation=>animation.cancel());toolModeLabels.clear();
|
|
784
966
|
}
|
|
785
967
|
function loadAddress(first=false){
|
|
786
968
|
try{
|
|
787
969
|
const data=decodeFormState(location.hash,RELEASE);
|
|
788
970
|
if(data){
|
|
789
|
-
freshForm();helpers=[...data.roles];pickedTools=data.tools.map(tool=>tool.id);selectedScope=data.scope;
|
|
790
|
-
|
|
791
|
-
const base=presets.find(preset=>preset.id===tool.base),preferences=JSON.parse(JSON.stringify(base.preferences.clients[tool.id]));
|
|
792
|
-
state.profiles[tool.id]={presetId:tool.base,custom:tool.mode==='custom',modeSelected:tool.mode!==null,presetCap:base.preferences.maxConcurrent,preferences};
|
|
793
|
-
state.jobs[tool.id]=Object.fromEntries(roles.map(role=>[role.id,JSON.parse(JSON.stringify(A.effective(preferences,role.id)))]));
|
|
794
|
-
for(const [role,choice]of Object.entries(tool.choices))state.jobs[tool.id][role]={...choice};
|
|
795
|
-
}
|
|
971
|
+
freshForm();helpers=[...data.roles];pickedTools=data.tools.map(tool=>tool.id);selectedScope=data.scope;
|
|
972
|
+
state=A.restoreState(data,initial.preferences,presets,initial.id);
|
|
796
973
|
}else if(!first)freshForm();
|
|
797
974
|
linkError='';
|
|
798
|
-
}catch(error){
|
|
975
|
+
}catch(error){
|
|
976
|
+
const archived=archivedReleaseUrl(error,location.href,RELEASE.hostedReleases??[]);
|
|
977
|
+
if(archived){archiveNavigation=true;location.replace(archived);return;}
|
|
978
|
+
freshForm();linkError=error?.code==='SHARE_RELEASE_MISMATCH'?'Open this setup link with its matching APK release, or reset the form.':'This setup link is invalid. Reset the form to start again.';
|
|
979
|
+
}
|
|
799
980
|
}
|
|
800
981
|
function publishAddress(){
|
|
801
982
|
let message=linkError;
|
|
@@ -803,7 +984,7 @@ function decodeFormState(fragment,release){
|
|
|
803
984
|
const fragment=encodeFormState({state,helpers,pickedTools,selectedScope},RELEASE);
|
|
804
985
|
if(location.hash!==fragment)history.replaceState(history.state,'',location.pathname+location.search+fragment);
|
|
805
986
|
lastAddress=fragment;
|
|
806
|
-
}catch{message='Check your model IDs before sharing this setup.';}
|
|
987
|
+
}catch{message=pickedTools.some(client=>{const cap=A.concurrencyFor(state,client);return !Number.isInteger(cap)||cap<1||cap>32;})?'Check parallel limits in the AI assistant details.':'Check your model IDs before sharing this setup.';}
|
|
807
988
|
$('link-error').textContent=message;$('link-error').hidden=!message;
|
|
808
989
|
}
|
|
809
990
|
function setStepHint(number,message){
|
|
@@ -838,9 +1019,6 @@ function decodeFormState(fragment,release){
|
|
|
838
1019
|
const marker=section.querySelector('.step-number'),value=String(complete[index]),changed=marker.dataset.complete!==undefined&&marker.dataset.complete!==value;section.dataset.complete=value;marker.dataset.complete=value;
|
|
839
1020
|
const text=complete[index]?'✓':String(index+1);if(marker.textContent!==text)marker.textContent=text;marker.setAttribute('role','img');marker.setAttribute('aria-label',`Step ${index+1}${complete[index]?' complete':''}`);if(changed)flashStep(marker,complete[index]);
|
|
840
1021
|
});
|
|
841
|
-
setStepHint(1,helpers.length?(helpers.length<roles.length?'You can add more roles.':'All available roles added.'):'');
|
|
842
|
-
setStepHint(2,pickedTools.length===1?'You can add more coding tools.':pickedTools.length>=2?'Click a coding tool to configure it individually.':'');
|
|
843
|
-
setStepHint(3,helpers.length&&pickedTools.length?'Click a mode to select it.':'');
|
|
844
1022
|
setStepHint(4,copied?'Copied':'');
|
|
845
1023
|
}
|
|
846
1024
|
function stepLink(id,text){
|
|
@@ -848,15 +1026,25 @@ function decodeFormState(fragment,release){
|
|
|
848
1026
|
}
|
|
849
1027
|
function renderResult(){
|
|
850
1028
|
renderModeNotice();
|
|
1029
|
+
const client=state.active,visible=clients.includes(client)&&pickedTools.includes(client)&&helpers.length>0&&state.profiles[client].modeSelected!==false;
|
|
1030
|
+
$('concurrency-panel').hidden=!visible;
|
|
1031
|
+
if(visible){
|
|
1032
|
+
const cap=A.concurrencyFor(state,client),validCap=Number.isInteger(cap)&&cap>=1&&cap<=32,capInput=$('max-concurrent');
|
|
1033
|
+
if(document.activeElement!==capInput||capInput.dataset.client!==client)capInput.value=cap;
|
|
1034
|
+
capInput.dataset.client=client;capInput.setAttribute('aria-invalid',String(!validCap));
|
|
1035
|
+
$('concurrency-label').textContent=['kimi','gemini'].includes(client)?'Max per session (advisory)':'Max per session';
|
|
1036
|
+
$('concurrency-error').hidden=validCap;
|
|
1037
|
+
$('decrease-concurrency').disabled=validCap&&cap===1;$('increase-concurrency').disabled=validCap&&cap===32;
|
|
1038
|
+
}
|
|
851
1039
|
let next='',summary='Complete the steps above.',detail='',missing=[];
|
|
852
1040
|
if(!helpers.length)missing.push(['helpers-heading','a subagent role in step 1']);
|
|
853
|
-
if(!pickedTools.length)missing.push(['tools-heading','
|
|
1041
|
+
if(!pickedTools.length)missing.push(['tools-heading','an AI assistant in step 2']);
|
|
854
1042
|
if(!missing.length){
|
|
855
|
-
if(pickedTools.some(client=>A.modeFor(state,client)===null))missing.push(['mode-heading','a work mode for each selected
|
|
1043
|
+
if(pickedTools.some(client=>A.modeFor(state,client)===null))missing.push(['mode-heading','a work mode for each selected AI assistant in step 3']);
|
|
856
1044
|
else{
|
|
857
1045
|
const {config,errors}=A.buildConfig(state,RELEASE.preferences,RELEASE.catalog);
|
|
858
|
-
if(errors.length){summary='Check your
|
|
859
|
-
else try{next=A.buildCommand(config,RELEASE);summary=`${helpers.length} subagent role${helpers.length===1?'':'s'} · ${pickedTools.length}
|
|
1046
|
+
if(errors.length){summary='Check your settings.';detail=errors[0];}
|
|
1047
|
+
else try{next=A.buildCommand(config,RELEASE);summary=`${helpers.length} subagent role${helpers.length===1?'':'s'} · ${pickedTools.length} AI assistant${pickedTools.length===1?'':'s'}`;}
|
|
860
1048
|
catch{summary='Command unavailable.';detail='Check the configuration release.';}
|
|
861
1049
|
}
|
|
862
1050
|
}
|
|
@@ -872,7 +1060,7 @@ function decodeFormState(fragment,release){
|
|
|
872
1060
|
updateProgress();publishAddress();
|
|
873
1061
|
}
|
|
874
1062
|
function renderNow(){syncTargets();renderPickers();renderModes();renderResult();}
|
|
875
|
-
function render({fromAddress=false}={}){if(mounted&&!fromAddress)linkError='';if(!mounted){renderNow();mounted=true;}else animateUpdate(renderNow);}
|
|
1063
|
+
function render({fromAddress=false}={}){if(archiveNavigation)return;if(mounted&&!fromAddress)linkError='';if(!mounted){renderNow();mounted=true;}else animateUpdate(renderNow);}
|
|
876
1064
|
function addressChanged(){
|
|
877
1065
|
if(location.hash===lastAddress||(location.hash&&!location.hash.startsWith('#setup=')))return;
|
|
878
1066
|
lastAddress=location.hash;loadAddress();render({fromAddress:true});
|
|
@@ -880,6 +1068,10 @@ function decodeFormState(fragment,release){
|
|
|
880
1068
|
window.addEventListener('hashchange',addressChanged);window.addEventListener('popstate',addressChanged);
|
|
881
1069
|
$('reset-form').addEventListener('click',()=>{freshForm();linkError='';render();});
|
|
882
1070
|
|
|
1071
|
+
function refreshConcurrency(){linkError='';toolModeLabel(state.active);renderModes();renderResult();}
|
|
1072
|
+
$('max-concurrent').addEventListener('input',event=>{const client=event.target.dataset.client;if(client!==state.active||!clients.includes(client))return;A.updateConcurrency(state,client,event.target.value);refreshConcurrency();});
|
|
1073
|
+
for(const [id,step]of [['decrease-concurrency',-1],['increase-concurrency',1]])$(id).addEventListener('click',()=>{const client=state.active;if(!clients.includes(client))return;A.stepConcurrency(state,client,step);$('max-concurrent').value=A.concurrencyFor(state,client);refreshConcurrency();});
|
|
1074
|
+
$('top-models-toggle').addEventListener('click',event=>{A.setTopModels(state,topTargets(),event.currentTarget.getAttribute('aria-checked')!=='true');render();});
|
|
883
1075
|
$('setup-command').addEventListener('focus',()=>$('setup-command').select());
|
|
884
1076
|
$('copy').addEventListener('click',async()=>{
|
|
885
1077
|
if(!currentCommand)return;const commandToCopy=currentCommand,revision=commandRevision;
|