sideby 0.3.0 → 0.4.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/README.md +27 -10
- package/dist/build.json +1 -1
- package/dist/src/cli/commands.d.ts +8 -1
- package/dist/src/cli/commands.js +330 -9
- package/dist/src/cli/format.d.ts +3 -1
- package/dist/src/cli/format.js +25 -0
- package/dist/src/cli/json-schemas.js +113 -0
- package/dist/src/cli/main.d.ts +5 -0
- package/dist/src/cli/main.js +40 -8
- package/dist/src/core/config.d.ts +40 -0
- package/dist/src/core/config.js +83 -11
- package/dist/src/core/file-memo.d.ts +23 -0
- package/dist/src/core/file-memo.js +37 -0
- package/dist/src/core/handoff-brief.d.ts +17 -0
- package/dist/src/core/handoff-brief.js +75 -0
- package/dist/src/core/handoff-chain.d.ts +74 -0
- package/dist/src/core/handoff-chain.js +74 -0
- package/dist/src/core/handoff-doctor.d.ts +13 -0
- package/dist/src/core/handoff-doctor.js +35 -0
- package/dist/src/core/handoff-run.d.ts +31 -0
- package/dist/src/core/handoff-run.js +346 -0
- package/dist/src/core/handoff-select.d.ts +42 -0
- package/dist/src/core/handoff-select.js +88 -0
- package/dist/src/core/handoff-status.d.ts +66 -0
- package/dist/src/core/handoff-status.js +198 -0
- package/dist/src/core/launch.d.ts +15 -0
- package/dist/src/core/launch.js +25 -2
- package/dist/src/core/memo-store.d.ts +20 -0
- package/dist/src/core/memo-store.js +92 -0
- package/dist/src/core/resume.d.ts +7 -2
- package/dist/src/core/resume.js +22 -9
- package/dist/src/core/tuning-apply.d.ts +51 -0
- package/dist/src/core/tuning-apply.js +237 -0
- package/dist/src/core/tuning.d.ts +98 -0
- package/dist/src/core/tuning.js +176 -0
- package/dist/src/families/claude/brief.d.ts +5 -0
- package/dist/src/families/claude/brief.js +63 -0
- package/dist/src/families/claude/handoff-hook.d.ts +2 -0
- package/dist/src/families/claude/handoff-hook.js +31 -0
- package/dist/src/families/claude/handoff.d.ts +5 -0
- package/dist/src/families/claude/handoff.js +115 -0
- package/dist/src/families/claude/index.js +8 -1
- package/dist/src/families/claude/tuning.d.ts +22 -0
- package/dist/src/families/claude/tuning.js +187 -0
- package/dist/src/families/claude/usage.d.ts +1 -0
- package/dist/src/families/claude/usage.js +2 -2
- package/dist/src/families/codex/brief.d.ts +5 -0
- package/dist/src/families/codex/brief.js +49 -0
- package/dist/src/families/codex/handoff-hook.d.ts +2 -0
- package/dist/src/families/codex/handoff-hook.js +16 -0
- package/dist/src/families/codex/handoff.d.ts +5 -0
- package/dist/src/families/codex/handoff.js +121 -0
- package/dist/src/families/codex/index.js +4 -0
- package/dist/src/families/codex/rate-limits.d.ts +16 -0
- package/dist/src/families/codex/rate-limits.js +92 -0
- package/dist/src/families/codex/rollout.d.ts +1 -2
- package/dist/src/families/codex/rollout.js +4 -48
- package/dist/src/families/codex/tuning.d.ts +16 -0
- package/dist/src/families/codex/tuning.js +145 -0
- package/dist/src/families/grok/brief.d.ts +5 -0
- package/dist/src/families/grok/brief.js +74 -0
- package/dist/src/families/grok/handoff-hook.d.ts +4 -0
- package/dist/src/families/grok/handoff-hook.js +26 -0
- package/dist/src/families/grok/handoff.d.ts +47 -0
- package/dist/src/families/grok/handoff.js +219 -0
- package/dist/src/families/grok/index.js +2 -0
- package/dist/src/families/pi/handoff.d.ts +2 -0
- package/dist/src/families/pi/handoff.js +13 -0
- package/dist/src/families/pi/index.js +2 -0
- package/dist/src/families/shared/brief.d.ts +24 -0
- package/dist/src/families/shared/brief.js +42 -0
- package/dist/src/families/shared/handoff-args.d.ts +18 -0
- package/dist/src/families/shared/handoff-args.js +57 -0
- package/dist/src/families/shared/sessions.d.ts +4 -0
- package/dist/src/families/shared/sessions.js +19 -0
- package/dist/src/families/shared/toml.d.ts +5 -0
- package/dist/src/families/shared/toml.js +30 -0
- package/dist/src/handoff/hook.d.ts +16 -0
- package/dist/src/handoff/hook.js +166 -0
- package/dist/src/handoff/messages.d.ts +7 -0
- package/dist/src/handoff/messages.js +27 -0
- package/dist/src/handoff/reader.d.ts +11 -0
- package/dist/src/handoff/reader.js +9 -0
- package/dist/src/panel/handler.d.ts +6 -0
- package/dist/src/panel/handler.js +110 -0
- package/dist/src/panel/i18n.d.ts +96 -0
- package/dist/src/panel/i18n.js +192 -0
- package/dist/src/panel/page-logic.d.ts +49 -0
- package/dist/src/panel/page-logic.js +67 -0
- package/dist/src/panel/page-script.js +454 -4
- package/dist/src/panel/page-styles.js +28 -2
- package/dist/src/panel/page.js +4 -1
- package/dist/src/quota/claude-statusline.js +4 -7
- package/dist/src/runtime.d.ts +40 -3
- package/dist/src/runtime.js +210 -41
- package/dist/src/types.d.ts +93 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.js +1 -0
- package/package.json +16 -4
- package/schemas/config.json +73 -0
- package/schemas/families.json +5 -1
- package/schemas/handoff-disable.json +106 -0
- package/schemas/handoff-enable.json +106 -0
- package/schemas/handoff-ready.json +23 -0
- package/schemas/handoff-setup.json +60 -0
- package/schemas/handoff-status.json +137 -0
- package/schemas/handoff-teardown.json +30 -0
- package/schemas/list.json +5 -1
- package/schemas/tune-change.json +108 -0
- package/schemas/tune.json +243 -0
- package/skills/sideby/SKILL.md +5 -3
- package/skills/sideby/references/badge.md +1 -1
- package/skills/sideby/references/diagnose.md +4 -0
- package/skills/sideby/references/handoff.md +24 -2
- package/README.zh-CN.md +0 -112
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "sideby/tune-change.json",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"schemaVersion",
|
|
7
|
+
"account",
|
|
8
|
+
"action",
|
|
9
|
+
"applied"
|
|
10
|
+
],
|
|
11
|
+
"properties": {
|
|
12
|
+
"schemaVersion": {
|
|
13
|
+
"type": "number",
|
|
14
|
+
"const": 1
|
|
15
|
+
},
|
|
16
|
+
"account": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
},
|
|
19
|
+
"action": {
|
|
20
|
+
"anyOf": [
|
|
21
|
+
{
|
|
22
|
+
"type": "string",
|
|
23
|
+
"const": "apply"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "string",
|
|
27
|
+
"const": "undo"
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"applied": {
|
|
32
|
+
"type": "boolean",
|
|
33
|
+
"description": "True once the change was written (or undone)."
|
|
34
|
+
},
|
|
35
|
+
"plan": {
|
|
36
|
+
"type": "object",
|
|
37
|
+
"required": [
|
|
38
|
+
"status",
|
|
39
|
+
"file",
|
|
40
|
+
"link",
|
|
41
|
+
"affected",
|
|
42
|
+
"current",
|
|
43
|
+
"next",
|
|
44
|
+
"creates"
|
|
45
|
+
],
|
|
46
|
+
"properties": {
|
|
47
|
+
"status": {
|
|
48
|
+
"anyOf": [
|
|
49
|
+
{
|
|
50
|
+
"type": "string",
|
|
51
|
+
"const": "ready"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "string",
|
|
55
|
+
"const": "unchanged"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"type": "string",
|
|
59
|
+
"const": "blocked"
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
"file": {
|
|
64
|
+
"type": "string"
|
|
65
|
+
},
|
|
66
|
+
"link": {
|
|
67
|
+
"type": "boolean"
|
|
68
|
+
},
|
|
69
|
+
"affected": {
|
|
70
|
+
"type": "array",
|
|
71
|
+
"items": {
|
|
72
|
+
"type": "string"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"current": {
|
|
76
|
+
"anyOf": [
|
|
77
|
+
{
|
|
78
|
+
"type": "number"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "null"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
},
|
|
85
|
+
"next": {
|
|
86
|
+
"anyOf": [
|
|
87
|
+
{
|
|
88
|
+
"type": "number"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"type": "null"
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
"creates": {
|
|
96
|
+
"type": "boolean"
|
|
97
|
+
},
|
|
98
|
+
"reason": {
|
|
99
|
+
"type": "string"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"message": {
|
|
104
|
+
"type": "string"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"title": "sideby tune apply|undo --json"
|
|
108
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "sideby/tune.json",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"schemaVersion",
|
|
7
|
+
"accounts"
|
|
8
|
+
],
|
|
9
|
+
"properties": {
|
|
10
|
+
"schemaVersion": {
|
|
11
|
+
"type": "number",
|
|
12
|
+
"const": 1
|
|
13
|
+
},
|
|
14
|
+
"accounts": {
|
|
15
|
+
"type": "array",
|
|
16
|
+
"items": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"required": [
|
|
19
|
+
"ref",
|
|
20
|
+
"family",
|
|
21
|
+
"tuning"
|
|
22
|
+
],
|
|
23
|
+
"properties": {
|
|
24
|
+
"ref": {
|
|
25
|
+
"type": "string"
|
|
26
|
+
},
|
|
27
|
+
"family": {
|
|
28
|
+
"type": "string"
|
|
29
|
+
},
|
|
30
|
+
"tuning": {
|
|
31
|
+
"anyOf": [
|
|
32
|
+
{
|
|
33
|
+
"type": "object",
|
|
34
|
+
"required": [
|
|
35
|
+
"status",
|
|
36
|
+
"days",
|
|
37
|
+
"estimate",
|
|
38
|
+
"models"
|
|
39
|
+
],
|
|
40
|
+
"properties": {
|
|
41
|
+
"status": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"const": "ok"
|
|
44
|
+
},
|
|
45
|
+
"days": {
|
|
46
|
+
"type": "number"
|
|
47
|
+
},
|
|
48
|
+
"estimate": {
|
|
49
|
+
"type": "boolean",
|
|
50
|
+
"const": true
|
|
51
|
+
},
|
|
52
|
+
"models": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "object",
|
|
56
|
+
"required": [
|
|
57
|
+
"model",
|
|
58
|
+
"calls",
|
|
59
|
+
"contextWindow",
|
|
60
|
+
"configured",
|
|
61
|
+
"effective",
|
|
62
|
+
"compactions",
|
|
63
|
+
"suggestion",
|
|
64
|
+
"reason"
|
|
65
|
+
],
|
|
66
|
+
"properties": {
|
|
67
|
+
"model": {
|
|
68
|
+
"type": "string"
|
|
69
|
+
},
|
|
70
|
+
"calls": {
|
|
71
|
+
"type": "number"
|
|
72
|
+
},
|
|
73
|
+
"contextWindow": {
|
|
74
|
+
"type": "number"
|
|
75
|
+
},
|
|
76
|
+
"configured": {
|
|
77
|
+
"anyOf": [
|
|
78
|
+
{
|
|
79
|
+
"type": "number"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "null"
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
|
+
"description": "Configured threshold in tokens; null is the Host default."
|
|
86
|
+
},
|
|
87
|
+
"effective": {
|
|
88
|
+
"anyOf": [
|
|
89
|
+
{
|
|
90
|
+
"type": "number"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"type": "null"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"compactions": {
|
|
98
|
+
"type": "object",
|
|
99
|
+
"required": [
|
|
100
|
+
"total",
|
|
101
|
+
"auto",
|
|
102
|
+
"manual",
|
|
103
|
+
"preTokensP50",
|
|
104
|
+
"preTokensMax"
|
|
105
|
+
],
|
|
106
|
+
"properties": {
|
|
107
|
+
"total": {
|
|
108
|
+
"type": "number",
|
|
109
|
+
"description": "All compactions, including those whose trigger the Host does not record."
|
|
110
|
+
},
|
|
111
|
+
"auto": {
|
|
112
|
+
"type": "number"
|
|
113
|
+
},
|
|
114
|
+
"manual": {
|
|
115
|
+
"type": "number"
|
|
116
|
+
},
|
|
117
|
+
"preTokensP50": {
|
|
118
|
+
"anyOf": [
|
|
119
|
+
{
|
|
120
|
+
"type": "number"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "null"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"preTokensMax": {
|
|
128
|
+
"anyOf": [
|
|
129
|
+
{
|
|
130
|
+
"type": "number"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"type": "null"
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"suggestion": {
|
|
140
|
+
"anyOf": [
|
|
141
|
+
{
|
|
142
|
+
"type": "object",
|
|
143
|
+
"required": [
|
|
144
|
+
"threshold",
|
|
145
|
+
"savedPercent",
|
|
146
|
+
"savedWeighted"
|
|
147
|
+
],
|
|
148
|
+
"properties": {
|
|
149
|
+
"threshold": {
|
|
150
|
+
"type": "number"
|
|
151
|
+
},
|
|
152
|
+
"savedPercent": {
|
|
153
|
+
"anyOf": [
|
|
154
|
+
{
|
|
155
|
+
"type": "number"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"type": "null"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
"savedWeighted": {
|
|
163
|
+
"anyOf": [
|
|
164
|
+
{
|
|
165
|
+
"type": "number"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"type": "null"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"type": "null"
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"description": "The estimated cheapest threshold; null when `reason` says why there is none."
|
|
179
|
+
},
|
|
180
|
+
"reason": {
|
|
181
|
+
"anyOf": [
|
|
182
|
+
{
|
|
183
|
+
"type": "string",
|
|
184
|
+
"const": "suggested"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"type": "string",
|
|
188
|
+
"const": "already-best"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"type": "string",
|
|
192
|
+
"const": "insufficient-calls"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"type": "string",
|
|
196
|
+
"const": "no-compactions"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"type": "string",
|
|
200
|
+
"const": "no-optimum"
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"type": "string",
|
|
204
|
+
"const": "unknown-model"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"type": "string",
|
|
208
|
+
"const": "observe-only"
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"type": "object",
|
|
219
|
+
"required": [
|
|
220
|
+
"status",
|
|
221
|
+
"reason"
|
|
222
|
+
],
|
|
223
|
+
"properties": {
|
|
224
|
+
"status": {
|
|
225
|
+
"type": "string",
|
|
226
|
+
"const": "unavailable"
|
|
227
|
+
},
|
|
228
|
+
"reason": {
|
|
229
|
+
"type": "string"
|
|
230
|
+
},
|
|
231
|
+
"detail": {
|
|
232
|
+
"type": "string"
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
"title": "sideby tune --json"
|
|
243
|
+
}
|
package/skills/sideby/SKILL.md
CHANGED
|
@@ -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, 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.
|
|
4
4
|
metadata:
|
|
5
|
-
version: "0.
|
|
5
|
+
version: "0.4.0"
|
|
6
6
|
requires:
|
|
7
7
|
bins: [sideby, node]
|
|
8
8
|
cliHelp: sideby --help
|
|
@@ -20,7 +20,7 @@ Do every step you can yourself. Only browser sign-in, secrets and interactive se
|
|
|
20
20
|
- **Never sign in for the user.** Give them `sideby login <ref>` as one line to run in their own terminal (Claude Code: `! sideby login <ref>`). OAuth needs their browser and their decision.
|
|
21
21
|
- **Never put a secret on the command line or in chat.** For API accounts, the user edits `proxy.env` themselves.
|
|
22
22
|
- **Never start a Host session from your shell.** `sideby run`, `sideby next` (without `--dry-run`) and `sideby login` open an interactive session; give the user the command instead.
|
|
23
|
-
- **Never switch, rotate or proxy accounts.**
|
|
23
|
+
- **Never switch, rotate or proxy accounts yourself.** Do not work around sideby by editing config, copying session files or moving credentials. `sideby next` only recommends. Moving a running task on its own is Auto Handoff, which the user turns on: use `sideby handoff enable` (exit 10, then their yes), never hand-edit `config.json`. Inside such a session you may run `sideby handoff ready` when the user asks to hand over.
|
|
24
24
|
- **Say what you change.** Read-only commands first. What the user asked for (the account they asked to create, its short command, the shell line that makes it work) you do, saying what you do. Changes they did not ask for (`doctor --fix` on other accounts, `quota setup`, `app install`) wait until they have seen the change and agreed.
|
|
25
25
|
- Do not edit Host config files (`settings.json`, `config.toml`, symlinks in account directories) by hand when a `sideby` command does the job.
|
|
26
26
|
|
|
@@ -42,7 +42,9 @@ Account refs are `<family>:<name>`; a bare `<name>` works only when it is unique
|
|
|
42
42
|
| See accounts, health, quota and usage | `sideby list --json`, `sideby doctor --json`, `sideby quota --json` | `references/diagnose.md` |
|
|
43
43
|
| Repair drift or permissions | `sideby doctor [ref] --json`, then `--fix` after they agree | `references/diagnose.md` |
|
|
44
44
|
| Keep working because an account hit its limit | `sideby next <family> --json` | `references/handoff.md` |
|
|
45
|
+
| Turn on Auto Handoff ("自动交接", "hand over when quota runs low"), see what it still needs, hand this session over now, or pick an account with room for a subtask | `sideby handoff status --json`, `sideby handoff enable --json` (exit 10 first), `sideby handoff ready`, `sideby next <family> --json` | `references/handoff.md` |
|
|
45
46
|
| Create an account with a given name, an API account, or a short command | `sideby new`, `sideby alias add` | `references/accounts.md` |
|
|
47
|
+
| Tune the auto-compact threshold ("which compaction setting costs the fewest tokens"), use the suggestion or undo it | `sideby tune --json`, `sideby tune apply` (exit 10 first), `sideby tune undo` | `references/diagnose.md` |
|
|
46
48
|
| See Claude quota (it shows `not-enabled`) | `sideby quota setup claude` (exits 10) | `references/quota.md` |
|
|
47
49
|
| See everything at once | `sideby ui` (local panel on `127.0.0.1:17420`; `--no-open` prints the address) | — |
|
|
48
50
|
| Start an account | give them `sideby run <ref> [-- host args]` | — |
|
|
@@ -53,7 +55,7 @@ Read only the reference the task needs.
|
|
|
53
55
|
|
|
54
56
|
`eval "$(sideby shell-init zsh)"` defines one function per account (`sideby-claude-work`) plus the config `aliases`. Users who source a file instead set config `shellInitFile` (for example `{ "zsh": "~/.config/sideby/shell-init.zsh" }`); `new` and `alias add|rm` keep it current, and `sideby shell-init zsh --write` rewrites it. New functions work in a new shell.
|
|
55
57
|
|
|
56
|
-
When a terminal manager such as Orca reopens a pane with a bare `claude --resume <id>` (or `codex resume <id>`, `grok --resume <id>`) and the Host says `No conversation found`, the session lives in another account. Suggest config `"resumeRouting": true` followed by `sideby shell-init --write` (or a new shell with `eval`): `shell-init` then defines Host-named functions that call `sideby resume <family>`, which starts the account holding that session. For a one-off, find it with `ls -d ~/.claude*/projects/*/<id>.jsonl` and run `sideby run <ref> -- --resume <id>`.
|
|
58
|
+
When a terminal manager such as Orca reopens a pane with a bare `claude --resume <id>` (or `codex resume <id>`, `grok --resume <id>`) and the Host says `No conversation found`, the session lives in another account. Suggest config `"resumeRouting": true` followed by `sideby shell-init --write` (or a new shell with `eval`): `shell-init` then defines Host-named functions that call `sideby resume <family>`, which starts the account holding that session. For a one-off, find it with `ls -d ~/.claude*/projects/*/<id>.jsonl` and run `sideby run <ref> -- --resume <id>`. When no account has that file, the session was opened but never got a message, so there is nothing to resume: `ls -d ~/.claude*/session-env/<id>` names the account that started it, and with routing on `sideby resume` starts a new session there by itself.
|
|
57
59
|
|
|
58
60
|
For someone who would rather double-click than use a terminal, `sideby app install` adds a desktop app (macOS `~/Applications/sideby.app`, Linux app menu) that runs `sideby ui --background`; `sideby ui --stop` stops it and `sideby app uninstall` removes the app. Ask before `app install`: it writes outside sideby's own directories.
|
|
59
61
|
|
|
@@ -22,7 +22,7 @@ For "show the account in the status line", "加上 [cc001] 这个标识". sideby
|
|
|
22
22
|
|
|
23
23
|
Never add a second `[ui]` table; if `[ui.status_line]` exists, change it.
|
|
24
24
|
3. `sideby doctor grok --fix` copies `config.toml` to subscription accounts (it must be a real copy there). API accounts (`kind: "api"`) keep their own `config.toml`: add the same table to each.
|
|
25
|
-
4. `GROK_HOME=<dir> grok inspect` must not report the new keys as unrecognized. It takes effect in a new Grok session.
|
|
25
|
+
4. `GROK_HOME=<dir> grok inspect` must not report the new keys as unrecognized. It takes effect in a new Grok session, and Grok hides the row on its welcome screen: tell the user it appears after the first message.
|
|
26
26
|
|
|
27
27
|
## Codex: terminal tab title
|
|
28
28
|
|
|
@@ -45,3 +45,7 @@ Quota is only as fresh as each account's last session; `observedAt` says when it
|
|
|
45
45
|
`--fix` never replaces a real file with a link, never re-points an existing symlink (wrong or dangling links are only reported), never writes through a link into the Main Account, and never changes credential contents. Findings it skips need a human decision; explain the hint, do not work around it with `rm` or `ln`.
|
|
46
46
|
|
|
47
47
|
`doctor` exits 1 only when a `fail` finding is left; warnings alone exit 0.
|
|
48
|
+
|
|
49
|
+
## Context tuning
|
|
50
|
+
|
|
51
|
+
`sideby tune [ref|family] --json` estimates, per model, the auto-compact threshold that spends the fewest tokens, from the account's last 7 days of local sessions. It is read-only and an estimate: each model has `reason` (`suggested` carries `suggestion.threshold`; the others say why there is none: `insufficient-calls`, `no-compactions`, `no-optimum` (the cheapest point is at the bottom of the range tried, so there is no clear best), `unknown-model`, `already-best`, `observe-only`). Only Claude gets suggestions; Codex is observation only; Grok and pi return `no-source`. The analysis changes nothing. To use a suggestion run `sideby tune apply <ref> [tokens]`: it prints the file, the change and every account sharing that file (a linked `settings.json` is one shared file) and exits 10. Show that to the user in plain words, and only after a yes rerun with `--yes`. `sideby tune undo <ref> --yes` puts the old value back. Do not hand-edit `settings.json` for the user.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Handoff: keep working on another account
|
|
2
2
|
|
|
3
|
-
Use this when the user says an account hit its 5-hour or weekly limit ("usage limit reached", "rate limited", "resets at …") and wants to keep working, or asks which account has room. sideby recommends the account of the same family with the lowest Quota Pressure (the fullest window that has not reset yet).
|
|
3
|
+
Use this when the user says an account hit its 5-hour or weekly limit ("usage limit reached", "rate limited", "resets at …") and wants to keep working, or asks which account has room. sideby recommends the account of the same family with the lowest Quota Pressure (the fullest window that has not reset yet), and the user starts it. Only Auto Handoff, which the user turns on in the config, moves a running task by itself (see below).
|
|
4
4
|
|
|
5
5
|
## Steps
|
|
6
6
|
|
|
@@ -35,7 +35,29 @@ Use this when the user says an account hit its 5-hour or weekly limit ("usage li
|
|
|
35
35
|
- Host arguments the user wants (another model, say) go after `--`: `sideby next claude -- --model opus`.
|
|
36
36
|
- Quota is only as fresh as each account's last session. Do not promise an account has room; say what the data shows and when it was recorded.
|
|
37
37
|
|
|
38
|
+
## Auto Handoff (the user turns it on)
|
|
39
|
+
|
|
40
|
+
With config `"handoff": { "auto": true }`, a session sideby started hands its task to the next account when quota runs low; see the guide's Auto Handoff section for the settings. If you are in such a session (the environment has `SIDEBY_HANDOFF_RUN`):
|
|
41
|
+
|
|
42
|
+
- When sideby tells you the quota is at 80%, write the handoff brief at the path it names and keep it current: the goal, what is done, the remaining steps, key decisions and why, the files that matter. Reference specs, ADRs, commits and diffs by path; list the skills the next agent should use; never include keys, passwords or personal data.
|
|
43
|
+
- When it says the quota is at 95%, finish the current step, update the brief, and end your turn. sideby starts the next account from it.
|
|
44
|
+
- When the user asks to hand over now, update the brief, run `sideby handoff ready` (add `--brief <file>` when the user's own handoff tool wrote one), and end your turn.
|
|
45
|
+
|
|
46
|
+
### Turning it on for the user
|
|
47
|
+
|
|
48
|
+
1. Run `sideby handoff status --json`. Read `auto`, `sideby` (is the `sideby` on PATH able to run the hook), each family's `starts`, `ready`, `problems` and `notes`, and `nextSteps`.
|
|
49
|
+
2. Tell the user what Auto Handoff does, that it is off by default, and the risk: hand-over between two subscriptions of one vendor (`--same-family`, cc001 → cc002) is the kind vendors may act on. Add `--same-family` only when the user asks for it. Ask which accounts each family should hand over to if they care about the order (`--order claude=codex001,cc002`; accounts or short commands, any family).
|
|
50
|
+
3. Run `sideby handoff enable [flags] --json`. Exit 10 means the config change was shown: show the user `diff`, ask, and only after a clear yes run the same command with `--yes`. It writes only the `handoff` key of the config and returns `nextSteps`.
|
|
51
|
+
4. Work through `nextSteps` in order. `sideby quota setup claude` and `sideby handoff setup grok` also exit 10 first: ask before adding `--yes`. `npm i -g sideby` installs or upgrades sideby on PATH; ask first. Codex needs the user to trust sideby's hooks once per account (`/hooks` in Codex); you cannot do that for them.
|
|
52
|
+
5. Run `sideby handoff status --json` again and report which families are `ready`.
|
|
53
|
+
|
|
54
|
+
To turn it off: `sideby handoff disable --json`, then `--yes` after the user agrees; the other settings stay. The panel has the same settings under **Auto Handoff** in its top bar.
|
|
55
|
+
|
|
56
|
+
## Picking an account for a subtask
|
|
57
|
+
|
|
58
|
+
Before you delegate work to another account (for example a review in a headless run), run `sideby next <family> --json` and use its `pick`, so the subtask lands on the account with the most room. Prefer an account of the same family for speed; running two subscriptions of one vendor at once carries the same vendor risk as `sameFamily`, so say so. A headless run such as `sideby run <pick> -- -p "<task>"` is yours to start only when the user asked for the delegation.
|
|
59
|
+
|
|
38
60
|
## Never
|
|
39
61
|
|
|
40
62
|
- Switch accounts by editing config or environment, copy session files between account directories, or read any credential.
|
|
41
|
-
- Start
|
|
63
|
+
- Start an interactive session for the user.
|
package/README.zh-CN.md
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img alt="sideby:一份共享配置,每个账号一个终端" src="https://raw.githubusercontent.com/Adonis0123/sideby/main/docs/assets/banner.jpg" width="880">
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<p align="center">
|
|
6
|
-
<b>Run every AI coding account side by side.</b><br>
|
|
7
|
-
把 Claude Code、Codex、Grok Build、pi 的多个账号并排跑起来:每个账号一个目录,skills、hooks、规则共用一份,额度在一个面板里看完。
|
|
8
|
-
</p>
|
|
9
|
-
|
|
10
|
-
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package/sideby"><img alt="npm" src="https://img.shields.io/npm/v/sideby"></a>
|
|
12
|
-
<a href="https://github.com/Adonis0123/sideby/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/Adonis0123/sideby/actions/workflows/ci.yml/badge.svg"></a>
|
|
13
|
-
<img alt="Node 22.18+" src="https://img.shields.io/badge/node-%E2%89%A522.18-339933">
|
|
14
|
-
<a href="LICENSE"><img alt="MIT" src="https://img.shields.io/badge/license-MIT-blue"></a>
|
|
15
|
-
</p>
|
|
16
|
-
|
|
17
|
-
<p align="center"><a href="README.md">English</a> | 中文</p>
|
|
18
|
-
|
|
19
|
-
## 为什么用 sideby
|
|
20
|
-
|
|
21
|
-
你有一个工作订阅、一个个人订阅,可能还有一个 API key。切换类工具会改宿主的全局配置,同一时间只有一个账号生效;各账号的 skills 和 hooks 也会慢慢变得不一致。
|
|
22
|
-
|
|
23
|
-
- **并排,不切换。** 每个账号一个独立目录,sideby 启动官方 CLI 时选中这个目录。三个账号可以同时开在三个终端里,你的 shell 环境不受影响。
|
|
24
|
-
- **skills、hooks、规则只维护一份。** 主账号(例如 `~/.claude`)是唯一来源,其他账号链接或复制它的共享项(Shared Item,[共享了哪些](docs/guide/usage.zh-CN.md#每个账号共享什么))。`sideby doctor --fix` 修复漂移,不碰真实文件,也不碰凭据。
|
|
25
|
-
- **额度一屏看完。** 每个账号的 5 小时、7 天额度、重置时间和近 7 天 token 用量。额度用完了,`sideby next` 帮你启动剩余最多的账号。数据都来自本地文件:不联网,不读 token。
|
|
26
|
-
|
|
27
|
-
## 快速上手
|
|
28
|
-
|
|
29
|
-
需要 Node 22.18 或更高版本,并且至少装好一个宿主 CLI(Claude Code、Codex、Grok Build 或 pi)。AI agent 请改按 [`llms.txt`](llms.txt) 里 "Set up sideby for a user" 的步骤做。
|
|
30
|
-
|
|
31
|
-
```sh
|
|
32
|
-
npm i -g sideby
|
|
33
|
-
sideby new claude work # 新建 ~/.claude-work,共用 ~/.claude 的 skills 和 hooks
|
|
34
|
-
sideby login claude:work # 登录一次
|
|
35
|
-
sideby run work # 用 work 账号启动 Claude Code
|
|
36
|
-
sideby ui # 在 http://127.0.0.1:17420 查看所有账号的额度
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
`sideby run claude:main` 可以同时在另一个终端里继续用 `~/.claude`。`--` 之后的参数原样交给宿主:`sideby run work -- --resume`。不想安装,可以先跑 `npx sideby` 试试。
|
|
40
|
-
|
|
41
|
-
## 让 AI 帮你装
|
|
42
|
-
|
|
43
|
-
把下面这段粘贴给 Claude Code、Codex 或其他 coding agent:
|
|
44
|
-
|
|
45
|
-
```text
|
|
46
|
-
帮我安装 sideby(npm 包 `sideby`)和它的 agent skill,再给我加一个 Claude Code 账号。
|
|
47
|
-
按 https://raw.githubusercontent.com/Adonis0123/sideby/main/llms.txt 里 "Set up sideby for a user" 的步骤来。
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
agent 会检查 Node 和宿主 CLI,装好 sideby 和 skill,建账号,告诉你它和主账号共享什么,并让短命令生效。你只需要在浏览器里登录一次,agent 会把那一行命令给你。装好 skill 之后,简短的说法也行:「再加一个 Claude 账号,叫 cc008」「我的 Codex 账号共享了什么」「哪个账号还有额度」。
|
|
51
|
-
|
|
52
|
-
## 长什么样
|
|
53
|
-
|
|
54
|
-
<img alt="终端里的 sideby:列出账号、查看额度、推荐下一个账号、发现并修复漂移" src="https://raw.githubusercontent.com/Adonis0123/sideby/main/docs/assets/demo.gif" width="1320">
|
|
55
|
-
|
|
56
|
-
<picture>
|
|
57
|
-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/Adonis0123/sideby/main/docs/assets/panel-dark.zh-CN.png">
|
|
58
|
-
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/Adonis0123/sideby/main/docs/assets/panel.zh-CN.png">
|
|
59
|
-
<img alt="sideby 面板:每个账号的 5h、7d 额度,近 7 天 token 用量和健康状态" src="https://raw.githubusercontent.com/Adonis0123/sideby/main/docs/assets/panel.zh-CN.png" width="1280">
|
|
60
|
-
</picture>
|
|
61
|
-
|
|
62
|
-
## 还能做什么
|
|
63
|
-
|
|
64
|
-
| 你想 | 命令 | 说明 |
|
|
65
|
-
|---|---|---|
|
|
66
|
-
| 加一个 API key 账号(DeepSeek、网关等) | `sideby new claude deepseek --api` | [API 账号](docs/guide/usage.zh-CN.md#api-账号) |
|
|
67
|
-
| 找出并修复账号之间的配置漂移 | `sideby doctor --fix` | [体检](docs/guide/usage.zh-CN.md#体检doctor) |
|
|
68
|
-
| 看 Claude 额度(Codex 不用设置) | `sideby quota setup claude --yes` | [Claude 额度](docs/guide/usage.zh-CN.md#claude-额度) |
|
|
69
|
-
| 账号撞上限额时换一个接着用 | `sideby next claude` | [接力](docs/guide/usage.zh-CN.md#账号撞上限额时) |
|
|
70
|
-
| 用 `ccw` 这样的短命令 | `sideby alias add ccw claude:work` | [Shell 函数](docs/guide/configuration.zh-CN.md#shell-函数) |
|
|
71
|
-
| 在 Orca 这类工具里重开会话时,自动进到存有它的账号 | config 里写 `"resumeRouting": true` | [从其他工具恢复会话](docs/guide/configuration.zh-CN.md#从其他工具恢复会话) |
|
|
72
|
-
| 从 Dock 或应用菜单打开面板 | `sideby app install` | [桌面应用](docs/guide/panel.zh-CN.md#桌面应用) |
|
|
73
|
-
| 把面板嵌进自己的本地页面 | `createPanelHandler()` | [嵌入面板](docs/guide/panel.zh-CN.md#嵌入面板) |
|
|
74
|
-
| 新增一个宿主,或加启动前检查 | 本地插件 | [插件](docs/guide/plugins.zh-CN.md) |
|
|
75
|
-
|
|
76
|
-
## 支持的宿主
|
|
77
|
-
|
|
78
|
-
| 宿主 | 账号目录 | 登录 | 额度 | 用量(7 天) |
|
|
79
|
-
|---|---|---|---|---|
|
|
80
|
-
| Claude Code | `~/.claude`、`~/.claude-<name>` | `claude auth login` | ✓ 需先 `quota setup claude` | ✓ |
|
|
81
|
-
| Codex CLI | `~/.codex`、`~/.codex-<name>` | `codex login` | ✓ | ✓ |
|
|
82
|
-
| Grok Build | `~/.grok`、`~/.grok-<name>` | `grok login` | 无公开来源 | 无公开来源 |
|
|
83
|
-
| pi | `~/.pi/agent`、`~/.pi-<name>/agent` | 在 pi 里输入 `/login` | 无公开来源 | 无公开来源 |
|
|
84
|
-
|
|
85
|
-
sideby 启动 `PATH` 上的官方程序,从不修改它。测试过的版本和各宿主的注意事项见[使用指南](docs/guide/usage.zh-CN.md#宿主说明)。
|
|
86
|
-
|
|
87
|
-
## 安全边界
|
|
88
|
-
|
|
89
|
-
- 不改宿主的全局配置来切换账号,也不会自己轮换账号。
|
|
90
|
-
- 不读取、不打印、不发送任何凭据的值。数据不出本机:sideby 不调用任何远程服务。
|
|
91
|
-
- `doctor --fix` 不替换真实文件,也不改链接的指向。
|
|
92
|
-
|
|
93
|
-
细节和服务条款的问题见[常见问题](docs/guide/faq.zh-CN.md)。
|
|
94
|
-
|
|
95
|
-
## 文档
|
|
96
|
-
|
|
97
|
-
- [使用指南](docs/guide/usage.zh-CN.md):账号、API 账号、体检、额度、接力、宿主说明
|
|
98
|
-
- [命令](docs/guide/commands.zh-CN.md):所有命令、退出码和 `--json`
|
|
99
|
-
- [配置](docs/guide/configuration.zh-CN.md):`config.json`、短命令、Shell 函数
|
|
100
|
-
- [面板](docs/guide/panel.zh-CN.md):面板、桌面应用、嵌入
|
|
101
|
-
- [插件](docs/guide/plugins.zh-CN.md):自己写家族或启动 hook
|
|
102
|
-
- [常见问题](docs/guide/faq.zh-CN.md):服务条款、数据位置、同类工具对比、卸载
|
|
103
|
-
|
|
104
|
-
## 给 AI agent
|
|
105
|
-
|
|
106
|
-
- [`llms.txt`](llms.txt):安装步骤、命令、JSON 契约和插件 API 的索引。`sideby families --json` 给出每个宿主的账号共享什么。
|
|
107
|
-
- [`skills/sideby/SKILL.md`](skills/sideby/SKILL.md):一个 Agent Skill,用来查看、修复、新建账号,以及在额度用完时换账号。用 `npx skills add Adonis0123/sideby -g` 安装;装的版本和 sideby 不一致时,`sideby doctor` 会提醒。
|
|
108
|
-
- [`AGENTS.md`](AGENTS.md):给维护本仓库的 agent 的规则。
|
|
109
|
-
|
|
110
|
-
## 许可证
|
|
111
|
-
|
|
112
|
-
[MIT](LICENSE)
|