sideby 0.13.0 → 0.14.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.
Files changed (78) hide show
  1. package/README.md +1 -1
  2. package/dist/build.json +1 -1
  3. package/dist/src/cli/commands.d.ts +3 -2
  4. package/dist/src/cli/commands.js +69 -8
  5. package/dist/src/cli/format.js +7 -3
  6. package/dist/src/cli/json-schemas.js +62 -2
  7. package/dist/src/cli/main.js +42 -4
  8. package/dist/src/core/config.d.ts +27 -0
  9. package/dist/src/core/config.js +48 -1
  10. package/dist/src/core/handoff-enable.js +10 -5
  11. package/dist/src/core/launch.d.ts +5 -0
  12. package/dist/src/core/launch.js +14 -3
  13. package/dist/src/core/quota-fetch.d.ts +22 -0
  14. package/dist/src/core/quota-fetch.js +98 -0
  15. package/dist/src/core/quota-levels.d.ts +3 -2
  16. package/dist/src/core/quota-levels.js +8 -4
  17. package/dist/src/core/quota-store.d.ts +19 -0
  18. package/dist/src/core/quota-store.js +62 -0
  19. package/dist/src/core/skill-check.d.ts +15 -0
  20. package/dist/src/core/skill-check.js +49 -3
  21. package/dist/src/core/update.d.ts +45 -0
  22. package/dist/src/core/update.js +72 -1
  23. package/dist/src/families/grok/handoff-hook.d.ts +6 -0
  24. package/dist/src/families/grok/handoff-hook.js +45 -2
  25. package/dist/src/families/grok/handoff.d.ts +6 -1
  26. package/dist/src/families/grok/handoff.js +30 -13
  27. package/dist/src/families/grok/index.js +5 -0
  28. package/dist/src/families/grok/quota-log.d.ts +30 -0
  29. package/dist/src/families/grok/quota-log.js +140 -0
  30. package/dist/src/families/grok/quota.d.ts +5 -0
  31. package/dist/src/families/grok/quota.js +112 -0
  32. package/dist/src/panel/handler.d.ts +9 -3
  33. package/dist/src/panel/handler.js +65 -3
  34. package/dist/src/panel/i18n.d.ts +25 -5
  35. package/dist/src/panel/i18n.js +52 -12
  36. package/dist/src/panel/page-logic.d.ts +18 -2
  37. package/dist/src/panel/page-logic.js +53 -6
  38. package/dist/src/panel/page-script.js +286 -92
  39. package/dist/src/panel/page-styles.js +30 -10
  40. package/dist/src/runtime.d.ts +30 -2
  41. package/dist/src/runtime.js +64 -21
  42. package/dist/src/types.d.ts +49 -1
  43. package/package.json +2 -2
  44. package/schemas/alias.json +62 -0
  45. package/schemas/app-install.json +62 -0
  46. package/schemas/app-uninstall.json +62 -0
  47. package/schemas/browser-open.json +62 -0
  48. package/schemas/browser-switch.json +62 -0
  49. package/schemas/browser.json +62 -0
  50. package/schemas/config.json +46 -0
  51. package/schemas/desktop-remove.json +62 -0
  52. package/schemas/desktop.json +62 -0
  53. package/schemas/doctor.json +62 -0
  54. package/schemas/error.json +62 -0
  55. package/schemas/families.json +62 -0
  56. package/schemas/handoff-disable.json +62 -0
  57. package/schemas/handoff-enable.json +62 -0
  58. package/schemas/handoff-ready.json +62 -0
  59. package/schemas/handoff-setup.json +62 -0
  60. package/schemas/handoff-status.json +62 -0
  61. package/schemas/handoff-teardown.json +62 -0
  62. package/schemas/list.json +62 -0
  63. package/schemas/model.json +62 -0
  64. package/schemas/new.json +62 -0
  65. package/schemas/next.json +62 -0
  66. package/schemas/plugins.json +62 -0
  67. package/schemas/quota-setup.json +62 -0
  68. package/schemas/quota-teardown.json +62 -0
  69. package/schemas/quota.json +76 -1
  70. package/schemas/remote-control.json +62 -0
  71. package/schemas/tune-change.json +62 -0
  72. package/schemas/tune.json +62 -0
  73. package/schemas/update.json +107 -1
  74. package/skills/sideby/SKILL.md +4 -2
  75. package/skills/sideby/references/diagnose.md +3 -2
  76. package/skills/sideby/references/handoff.md +1 -1
  77. package/skills/sideby/references/quota.md +5 -1
  78. package/skills/sideby/references/update.md +16 -0
@@ -54,6 +54,68 @@
54
54
  "type": "string"
55
55
  }
56
56
  }
57
+ },
58
+ "_notice": {
59
+ "type": "object",
60
+ "properties": {
61
+ "update": {
62
+ "type": "object",
63
+ "required": [
64
+ "current",
65
+ "latest",
66
+ "command",
67
+ "message"
68
+ ],
69
+ "properties": {
70
+ "current": {
71
+ "type": "string"
72
+ },
73
+ "latest": {
74
+ "type": "string"
75
+ },
76
+ "command": {
77
+ "type": "string",
78
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
79
+ },
80
+ "message": {
81
+ "type": "string"
82
+ }
83
+ }
84
+ },
85
+ "skill": {
86
+ "type": "object",
87
+ "required": [
88
+ "installed",
89
+ "current",
90
+ "command",
91
+ "message"
92
+ ],
93
+ "properties": {
94
+ "installed": {
95
+ "anyOf": [
96
+ {
97
+ "type": "string"
98
+ },
99
+ {
100
+ "type": "null"
101
+ }
102
+ ],
103
+ "description": "The skill's version; null when it has none."
104
+ },
105
+ "current": {
106
+ "type": "string"
107
+ },
108
+ "command": {
109
+ "type": "string",
110
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
111
+ },
112
+ "message": {
113
+ "type": "string"
114
+ }
115
+ }
116
+ }
117
+ },
118
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
57
119
  }
58
120
  },
59
121
  "title": "sideby quota setup --json"
@@ -24,6 +24,68 @@
24
24
  },
25
25
  "diff": {
26
26
  "type": "string"
27
+ },
28
+ "_notice": {
29
+ "type": "object",
30
+ "properties": {
31
+ "update": {
32
+ "type": "object",
33
+ "required": [
34
+ "current",
35
+ "latest",
36
+ "command",
37
+ "message"
38
+ ],
39
+ "properties": {
40
+ "current": {
41
+ "type": "string"
42
+ },
43
+ "latest": {
44
+ "type": "string"
45
+ },
46
+ "command": {
47
+ "type": "string",
48
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
49
+ },
50
+ "message": {
51
+ "type": "string"
52
+ }
53
+ }
54
+ },
55
+ "skill": {
56
+ "type": "object",
57
+ "required": [
58
+ "installed",
59
+ "current",
60
+ "command",
61
+ "message"
62
+ ],
63
+ "properties": {
64
+ "installed": {
65
+ "anyOf": [
66
+ {
67
+ "type": "string"
68
+ },
69
+ {
70
+ "type": "null"
71
+ }
72
+ ],
73
+ "description": "The skill's version; null when it has none."
74
+ },
75
+ "current": {
76
+ "type": "string"
77
+ },
78
+ "command": {
79
+ "type": "string",
80
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
81
+ },
82
+ "message": {
83
+ "type": "string"
84
+ }
85
+ }
86
+ }
87
+ },
88
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
27
89
  }
28
90
  },
29
91
  "title": "sideby quota teardown --json"
@@ -66,6 +66,10 @@
66
66
  "label": {
67
67
  "type": "string"
68
68
  },
69
+ "name": {
70
+ "type": "string",
71
+ "description": "The group of models this limit covers, when it covers only some (spec §3.26); it does not count toward Quota Pressure."
72
+ },
69
73
  "windowMinutes": {
70
74
  "type": "number"
71
75
  },
@@ -90,6 +94,14 @@
90
94
  "from": {
91
95
  "type": "string",
92
96
  "description": "The account this reading was taken from, when it is another account of the same login (spec §3.21); observedAt is its time."
97
+ },
98
+ "fetched": {
99
+ "type": "boolean",
100
+ "description": "This reading is the kept answer of a quota check that costs a request (spec §3.26)."
101
+ },
102
+ "fetchError": {
103
+ "type": "string",
104
+ "description": "Why the latest quota check failed, while this older reading is shown."
93
105
  }
94
106
  }
95
107
  },
@@ -105,7 +117,8 @@
105
117
  "const": "unavailable"
106
118
  },
107
119
  "reason": {
108
- "type": "string"
120
+ "type": "string",
121
+ "description": "not-enabled, no-session, unrecognized, no-source, api-account or fetch-failed."
109
122
  },
110
123
  "detail": {
111
124
  "type": "string"
@@ -207,6 +220,68 @@
207
220
  }
208
221
  }
209
222
  }
223
+ },
224
+ "_notice": {
225
+ "type": "object",
226
+ "properties": {
227
+ "update": {
228
+ "type": "object",
229
+ "required": [
230
+ "current",
231
+ "latest",
232
+ "command",
233
+ "message"
234
+ ],
235
+ "properties": {
236
+ "current": {
237
+ "type": "string"
238
+ },
239
+ "latest": {
240
+ "type": "string"
241
+ },
242
+ "command": {
243
+ "type": "string",
244
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
245
+ },
246
+ "message": {
247
+ "type": "string"
248
+ }
249
+ }
250
+ },
251
+ "skill": {
252
+ "type": "object",
253
+ "required": [
254
+ "installed",
255
+ "current",
256
+ "command",
257
+ "message"
258
+ ],
259
+ "properties": {
260
+ "installed": {
261
+ "anyOf": [
262
+ {
263
+ "type": "string"
264
+ },
265
+ {
266
+ "type": "null"
267
+ }
268
+ ],
269
+ "description": "The skill's version; null when it has none."
270
+ },
271
+ "current": {
272
+ "type": "string"
273
+ },
274
+ "command": {
275
+ "type": "string",
276
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
277
+ },
278
+ "message": {
279
+ "type": "string"
280
+ }
281
+ }
282
+ }
283
+ },
284
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
210
285
  }
211
286
  },
212
287
  "title": "sideby quota --json"
@@ -123,6 +123,68 @@
123
123
  },
124
124
  "message": {
125
125
  "type": "string"
126
+ },
127
+ "_notice": {
128
+ "type": "object",
129
+ "properties": {
130
+ "update": {
131
+ "type": "object",
132
+ "required": [
133
+ "current",
134
+ "latest",
135
+ "command",
136
+ "message"
137
+ ],
138
+ "properties": {
139
+ "current": {
140
+ "type": "string"
141
+ },
142
+ "latest": {
143
+ "type": "string"
144
+ },
145
+ "command": {
146
+ "type": "string",
147
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
148
+ },
149
+ "message": {
150
+ "type": "string"
151
+ }
152
+ }
153
+ },
154
+ "skill": {
155
+ "type": "object",
156
+ "required": [
157
+ "installed",
158
+ "current",
159
+ "command",
160
+ "message"
161
+ ],
162
+ "properties": {
163
+ "installed": {
164
+ "anyOf": [
165
+ {
166
+ "type": "string"
167
+ },
168
+ {
169
+ "type": "null"
170
+ }
171
+ ],
172
+ "description": "The skill's version; null when it has none."
173
+ },
174
+ "current": {
175
+ "type": "string"
176
+ },
177
+ "command": {
178
+ "type": "string",
179
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
180
+ },
181
+ "message": {
182
+ "type": "string"
183
+ }
184
+ }
185
+ }
186
+ },
187
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
126
188
  }
127
189
  },
128
190
  "title": "sideby remote-control [off|undo] --json"
@@ -120,6 +120,68 @@
120
120
  },
121
121
  "message": {
122
122
  "type": "string"
123
+ },
124
+ "_notice": {
125
+ "type": "object",
126
+ "properties": {
127
+ "update": {
128
+ "type": "object",
129
+ "required": [
130
+ "current",
131
+ "latest",
132
+ "command",
133
+ "message"
134
+ ],
135
+ "properties": {
136
+ "current": {
137
+ "type": "string"
138
+ },
139
+ "latest": {
140
+ "type": "string"
141
+ },
142
+ "command": {
143
+ "type": "string",
144
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
145
+ },
146
+ "message": {
147
+ "type": "string"
148
+ }
149
+ }
150
+ },
151
+ "skill": {
152
+ "type": "object",
153
+ "required": [
154
+ "installed",
155
+ "current",
156
+ "command",
157
+ "message"
158
+ ],
159
+ "properties": {
160
+ "installed": {
161
+ "anyOf": [
162
+ {
163
+ "type": "string"
164
+ },
165
+ {
166
+ "type": "null"
167
+ }
168
+ ],
169
+ "description": "The skill's version; null when it has none."
170
+ },
171
+ "current": {
172
+ "type": "string"
173
+ },
174
+ "command": {
175
+ "type": "string",
176
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
177
+ },
178
+ "message": {
179
+ "type": "string"
180
+ }
181
+ }
182
+ }
183
+ },
184
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
123
185
  }
124
186
  },
125
187
  "title": "sideby tune apply|undo --json"
package/schemas/tune.json CHANGED
@@ -242,6 +242,68 @@
242
242
  }
243
243
  }
244
244
  }
245
+ },
246
+ "_notice": {
247
+ "type": "object",
248
+ "properties": {
249
+ "update": {
250
+ "type": "object",
251
+ "required": [
252
+ "current",
253
+ "latest",
254
+ "command",
255
+ "message"
256
+ ],
257
+ "properties": {
258
+ "current": {
259
+ "type": "string"
260
+ },
261
+ "latest": {
262
+ "type": "string"
263
+ },
264
+ "command": {
265
+ "type": "string",
266
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
267
+ },
268
+ "message": {
269
+ "type": "string"
270
+ }
271
+ }
272
+ },
273
+ "skill": {
274
+ "type": "object",
275
+ "required": [
276
+ "installed",
277
+ "current",
278
+ "command",
279
+ "message"
280
+ ],
281
+ "properties": {
282
+ "installed": {
283
+ "anyOf": [
284
+ {
285
+ "type": "string"
286
+ },
287
+ {
288
+ "type": "null"
289
+ }
290
+ ],
291
+ "description": "The skill's version; null when it has none."
292
+ },
293
+ "current": {
294
+ "type": "string"
295
+ },
296
+ "command": {
297
+ "type": "string",
298
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
299
+ },
300
+ "message": {
301
+ "type": "string"
302
+ }
303
+ }
304
+ }
305
+ },
306
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
245
307
  }
246
308
  },
247
309
  "title": "sideby tune --json"
@@ -108,11 +108,117 @@
108
108
  },
109
109
  "skill": {
110
110
  "type": "string",
111
- "description": "The command that updates the sideby skill; sideby never runs it."
111
+ "description": "The command that installs the sideby skill by hand."
112
+ },
113
+ "skillUpdate": {
114
+ "type": "object",
115
+ "required": [
116
+ "installed",
117
+ "outdated",
118
+ "command",
119
+ "canRun"
120
+ ],
121
+ "properties": {
122
+ "installed": {
123
+ "type": "array",
124
+ "items": {
125
+ "anyOf": [
126
+ {
127
+ "type": "string"
128
+ },
129
+ {
130
+ "type": "null"
131
+ }
132
+ ]
133
+ },
134
+ "description": "Versions of the installed sideby skills; null for one without a version."
135
+ },
136
+ "outdated": {
137
+ "type": "boolean",
138
+ "description": "Some installed skill is for another version than sideby will run."
139
+ },
140
+ "command": {
141
+ "type": "string"
142
+ },
143
+ "canRun": {
144
+ "type": "boolean",
145
+ "description": "False when sideby leaves the skill alone (see reason): give the user command."
146
+ },
147
+ "reason": {
148
+ "type": "string"
149
+ }
150
+ },
151
+ "description": "The installed sideby skill, which the Update brings along; absent when none is installed."
152
+ },
153
+ "skillUpdated": {
154
+ "type": "boolean",
155
+ "description": "The skill was updated too (true) or that failed (false); absent when not tried."
112
156
  },
113
157
  "output": {
114
158
  "type": "string",
115
159
  "description": "What the failed install command printed."
160
+ },
161
+ "_notice": {
162
+ "type": "object",
163
+ "properties": {
164
+ "update": {
165
+ "type": "object",
166
+ "required": [
167
+ "current",
168
+ "latest",
169
+ "command",
170
+ "message"
171
+ ],
172
+ "properties": {
173
+ "current": {
174
+ "type": "string"
175
+ },
176
+ "latest": {
177
+ "type": "string"
178
+ },
179
+ "command": {
180
+ "type": "string",
181
+ "description": "Run it after the user agrees: it shows the plan and exits 10; then --yes."
182
+ },
183
+ "message": {
184
+ "type": "string"
185
+ }
186
+ }
187
+ },
188
+ "skill": {
189
+ "type": "object",
190
+ "required": [
191
+ "installed",
192
+ "current",
193
+ "command",
194
+ "message"
195
+ ],
196
+ "properties": {
197
+ "installed": {
198
+ "anyOf": [
199
+ {
200
+ "type": "string"
201
+ },
202
+ {
203
+ "type": "null"
204
+ }
205
+ ],
206
+ "description": "The skill's version; null when it has none."
207
+ },
208
+ "current": {
209
+ "type": "string"
210
+ },
211
+ "command": {
212
+ "type": "string",
213
+ "description": "Updates the installed sideby skill (run it after the user agrees)."
214
+ },
215
+ "message": {
216
+ "type": "string"
217
+ }
218
+ }
219
+ }
220
+ },
221
+ "description": "Not the answer to the task: mention it briefly afterwards and offer to update."
116
222
  }
117
223
  },
118
224
  "title": "sideby update --json"
@@ -2,7 +2,7 @@
2
2
  name: sideby
3
3
  description: Use when the user runs, or wants to run, several AI coding accounts (Claude Code, Codex, Grok Build, pi) side by side. Covers installing sideby and setting up a new account ("install sideby", "set up another Claude account", "add cc008", "配置一个 cc00x", "再加一个 Codex 账号"), explaining what accounts share and what stays separate ("what do my accounts share?", "这些账号共享了什么"), showing which account a session is ("show [cc001] in the status line", "加上账号标识"), seeing accounts, quota and usage, moving on when one hits its 5-hour or weekly limit, moving the current task to another account ("用 cc008 继续", "交回 cc008"), adding a short command (alias), and repairing drifted account directories (skills, hooks, rules or settings not shared, wrong symlinks, credential file permissions). Drives the `sideby` CLI with `--json`; the agent does every step except browser sign-in, filling in secrets and starting interactive sessions, which it hands to the user as one command (inside an Auto Handoff session, `sideby handoff ready --to` moves the task itself).
4
4
  metadata:
5
- version: "0.13.0"
5
+ version: "0.14.0"
6
6
  requires:
7
7
  bins: [sideby, node]
8
8
  cliHelp: sideby --help
@@ -29,6 +29,7 @@ Do every step you can yourself. Only browser sign-in, secrets and interactive se
29
29
  - Every `--json` output has `schemaVersion: 1`. On an error it is `{ "schemaVersion": 1, "error": "<what to do next>", "code": "<reason>" }`; `code` is `usage` for a malformed command line.
30
30
  - Exit codes: `0` done, `1` failed or found a `fail` problem, `2` malformed command line, `10` **needs the user's confirmation**. `run`, `next` and `login` return the Host's own exit code once it starts.
31
31
  - On `10`: show the user the change the command printed, ask, and only after a clear yes run the same command again with `--yes` added. Never add `--yes` on your own.
32
+ - `_notice` on any `--json` output: a newer sideby (`_notice.update`) or an installed sideby skill for another version (`_notice.skill`). It is not the answer to the task: finish the task first, then mention it in one line and offer to update, following `references/update.md`.
32
33
 
33
34
  ## What do you want to do
34
35
 
@@ -48,6 +49,7 @@ Account refs are `<family>:<name>`; a bare `<name>` works only when it is unique
48
49
  | See or set the model and effort an account starts with ("用哪个模型", "set effort to high for cc002") | `sideby model <acct> --json`; `sideby model <acct> <model\|default> --effort <level\|default>` (exit 10 first, then `--yes` after the user agrees) | — |
49
50
  | Stop Claude sessions from connecting to claude.ai / the Claude app by themselves ("关闭 remote control", "别让别人远程看到对话") for every account | `sideby remote-control --json`, then `sideby remote-control off` (exits 10 with the change; rerun with `--yes` after they agree); `sideby remote-control undo` puts it back; `sideby remote-control on` turns it back on the same way (only when they ask for it) | — |
50
51
  | See Claude quota (it shows `not-enabled`) | `sideby quota setup claude` (exits 10) | `references/quota.md` |
52
+ | Update sideby or its skill ("is there a new version", "更新 sideby"), or an output has `_notice` | `sideby update --json` (exits 10 first) | `references/update.md` |
51
53
  | See everything at once | `sideby ui` (local panel on `127.0.0.1:17420`; `--no-open` prints the address) | — |
52
54
  | Start an account | give them `sideby run <ref> [-- host args]` | — |
53
55
 
@@ -73,4 +75,4 @@ To update sideby, run `sideby update --json` yourself: it shows `current`, `late
73
75
 
74
76
  ## Keeping this skill current
75
77
 
76
- If `sideby doctor --json` reports `skill.outdated`, this skill was written for another sideby version. Tell the user to update it with `npx skills add Adonis0123/sideby -g`.
78
+ If `sideby doctor --json` reports `skill.outdated`, this skill was written for another sideby version. Offer `sideby update --json` (exit 10, then `--yes` after they agree): it updates the skill, together with sideby when a newer one is out (`references/update.md`).
@@ -23,13 +23,14 @@ Shared Items the Main Account does not have are skipped: no Finding, not counted
23
23
  | `fail` `link.dangling` | The link points at nothing | Show the hint (`ls -l <path>`); the user decides how to repair it |
24
24
  | `fail` `symlink-forbidden` without `fixable` | The Host needs a real file here, but the link points somewhere other than the Main Account | Show the hint; sideby will not replace a link it did not create |
25
25
  | credential item, mode not 600 | `proxy.env`, `auth.json`, `.claude.json` readable by others | `--fix` resets the mode to 600 |
26
- | `warn` `skill.outdated` (in `general`) | The installed sideby skill is for another sideby version | Tell the user to run `npx skills add Adonis0123/sideby -g` |
26
+ | `warn` `skill.outdated` (in `general`) | The installed sideby skill is for another sideby version | Offer `sideby update` (it updates the skill; see `update.md`) |
27
27
  | name looks like a backup (`bak`, `backup`, `old`, `tmp`) | A stray directory was picked up as an account | Suggest adding its ref to `ignore` in `${XDG_CONFIG_HOME:-~/.config}/sideby/config.json` |
28
28
  | `login: "not-needed"` (`key` in `sideby list`) | API account; it authenticates with `proxy.env` | Nothing to do |
29
29
  | `problems` on an account in `list --json` | A plugin failed while reading it (for example a settings file that is not valid JSON) | Show the message; the account itself still works |
30
30
  | quota `unavailable` / `not-enabled` | Claude quota source is off | Offer `sideby quota setup claude` |
31
31
  | quota `unavailable` / `no-session` | No session since the source was enabled | Ask the user to start one session with that account |
32
- | quota `unavailable` / `no-source` | Grok, pi: the Host has no public source | Nothing to fix |
32
+ | quota `unavailable` / `no-source` | pi: the Host has no public source | Nothing to fix |
33
+ | quota `unavailable` / `fetch-failed` | Grok: its CLI could not get the quota | Follow `detail` (update Grok, `sideby login grok:<name>`), then `sideby quota grok --refresh` |
33
34
  | quota `unavailable` / `api-account` | API accounts have no quota | Nothing to fix |
34
35
  | quota `unavailable` / `unrecognized` | Host changed its file format | Report it; suggest filing an issue with the Host version |
35
36
  | host not installed | Accounts exist but the CLI is missing | Point to the Host's install docs; do not install it unasked |
@@ -29,7 +29,7 @@ Use this when the user says an account hit its 5-hour or weekly limit ("usage li
29
29
 
30
30
  ## Other answers
31
31
 
32
- - Error `code: "no-quota-source"` (Grok, pi): the Host publishes no quota. The message lists the family's accounts; let the user choose one for `sideby run <ref>`.
32
+ - Error `code: "no-quota-source"` (pi, or a plugin family without quota): the Host publishes no quota. The message lists the family's accounts; let the user choose one for `sideby run <ref>`.
33
33
  - Error `code: "no-accounts"`: the family has no account yet; see creating accounts.
34
34
  - Many `unknown` Claude accounts: Claude quota may be off. `sideby quota --json` shows `not-enabled`; the one-time setup turns it on.
35
35
  - Host arguments the user wants (another model, say) go after `--`: `sideby next claude -- --model opus`.
@@ -13,4 +13,8 @@ After setup, each account shows quota once it has had one session with a reply.
13
13
 
14
14
  Two Claude accounts signed in as the same login (same email and organization; `sameLogin` in `sideby list --json`) share one quota: both show the freshest reading, and `quota.from` names the account it was read from. Explain that to the user rather than calling the numbers wrong; usage stays per account, and sideby never merges or deletes either directory.
15
15
 
16
- Usage (7-day tokens) is read by sideby itself from Claude Code and Codex local records; no ccusage is needed. Grok and pi have no quota or usage source.
16
+ Grok quota needs no setup: sideby asks the `grok` CLI of each signed-in account (`grok agent --no-leader stdio`, the Host makes the request with its own login; sideby never reads `auth.json`) at most every 15 minutes, and also reads the quota Grok logs after each turn. `sideby quota grok --refresh` asks again now. `quota.status: "unavailable"` with `reason: "fetch-failed"` carries the cause and next step in `detail` (update Grok, `sideby login grok:<name>`); `"not-enabled"` means the user turned it off (config `quota.check.grok: false`, or the Panel's Settings) or it runs in CI. A reading with `fetchError` is the last good one; say it may be old.
17
+
18
+ A window with a `name` (a plugin's Cursor "Other models") covers only some models: show it, but it does not make the account full.
19
+
20
+ Usage (7-day tokens) is read by sideby itself from Claude Code and Codex local records; no ccusage is needed. Grok and pi have no usage source; pi has no quota either.
@@ -0,0 +1,16 @@
1
+ # Updates and `_notice`
2
+
3
+ Every `--json` output can carry `_notice` (it comes from sideby's daily Update Check and the installed skill, and reads no network itself):
4
+
5
+ - `_notice.update`: `{ current, latest, command: "sideby update", message }`, a newer sideby is out.
6
+ - `_notice.skill`: `{ installed, current, command, message }`, the sideby skill agents read here is for another version (`installed: null` when it has no version), so it may describe commands this CLI does not have.
7
+
8
+ What to do:
9
+
10
+ 1. Finish what the user asked first. Do not answer with the notice, and do not stop a task to update.
11
+ 2. If the notice is still relevant at the end, say it in one line in the user's language, for example "sideby 0.14.0 is out (you have 0.13.0); want me to update it?", and offer to do it. Say it once per conversation, not after every command.
12
+ 3. When they agree:
13
+ - Run `sideby update --json`. It shows the version, the install method and the command it would run, and exits `10`. Show that to the user; after their yes, run `sideby update --yes --json`.
14
+ - If it exits `1` with `canRun: false` (npx, Volta, a project dependency, a source checkout, a Local Build), sideby cannot update itself: give the user the `command` it printed as one line to run.
15
+ - The same command updates the installed sideby skill (`skillUpdate` in the plan, `skillUpdated` in the result), so do not run a skill command yourself. With sideby already current and only the skill old (`_notice.skill`), `sideby update` updates the skill alone, after the same preview. When `skillUpdate.canRun` is false (the skill lives in a git repository), tell the user `reason` and give them `command`. Tell them that sessions already running keep the old version until they start again.
16
+ 4. The user can turn notices off with `SIDEBY_NO_UPDATE_NOTIFIER=1` (or config `update.check: false`); set it for one command when a script needs JSON without `_notice`. A Local Build (`pnpm local`) never has one.