very-happy-cli 0.2.95 → 0.2.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AcpBackend-Cuiff4Nu.mjs → AcpBackend-CTUM4dvG.mjs} +1 -1
- package/dist/{AcpBackend-BXsbwTbl.cjs → AcpBackend-DrwdVSeJ.cjs} +1 -1
- package/dist/{AcpSessionManager-BXGmMoe8.cjs → AcpSessionManager-BieE187D.cjs} +1 -1
- package/dist/{AcpSessionManager-BU69q_vR.mjs → AcpSessionManager-BoBuHee3.mjs} +1 -1
- package/dist/{config-BVOE0pni.cjs → config-COq6X7U7.cjs} +3 -3
- package/dist/{config-2GD21yg_.mjs → config-DCH33LOM.mjs} +3 -3
- package/dist/{index-BzbaMrIa.cjs → index-BD2fHJ8o.cjs} +526 -20
- package/dist/{index-DVEdpWq0.mjs → index-Bcgquogx.mjs} +527 -21
- package/dist/{index-DZ0uw6ef.mjs → index-DkhMvofH.mjs} +6 -6
- package/dist/{index-CbPc1iVx.cjs → index-Dn0iOBFd.cjs} +5 -5
- package/dist/index.cjs +3 -3
- package/dist/index.mjs +3 -3
- package/dist/{installTerminalHooks-FiujjEvb.mjs → installTerminalHooks-DqNtW6a2.mjs} +3 -3
- package/dist/{installTerminalHooks-BrrsyTMd.cjs → installTerminalHooks-H3kpFEZS.cjs} +3 -3
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +67 -0
- package/dist/lib.d.mts +67 -0
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-0mZcHPtz.mjs → mcp-BKAuzaLX.mjs} +3 -3
- package/dist/{mcp-ziyMk3eS.cjs → mcp-BwNc5eRs.cjs} +3 -3
- package/dist/{runGemini-D_InkOhk.mjs → runGemini-Brp0UmLx.mjs} +5 -5
- package/dist/{runGemini-C91O1oxi.cjs → runGemini-w35qiFBB.cjs} +5 -5
- package/dist/{runOpenClaw-BjebGmV6.mjs → runOpenClaw-BvPRFx-L.mjs} +4 -4
- package/dist/{runOpenClaw-B1RRfA1V.cjs → runOpenClaw-CkHtTCpI.cjs} +4 -4
- package/dist/{send-CxLL0z9J.mjs → send-c-wEmh5U.mjs} +3 -3
- package/dist/{send-DgK6MtgT.cjs → send-tyKG13xt.cjs} +3 -3
- package/dist/{spawn-Dian7x_g.cjs → spawn-xdCsG2RT.cjs} +3 -3
- package/dist/{spawn-uTPD3qOt.mjs → spawn-yS6yY8Xi.mjs} +3 -3
- package/dist/{types-HRuZ13LS.cjs → types-DoGaKVfK.cjs} +88 -11
- package/dist/{types-BLE8Hfmh.mjs → types-xZOYW0_G.mjs} +87 -11
- package/package.json +7 -7
- package/scripts/shims/keychain-off/security +51 -0
|
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
|
51
51
|
var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
|
|
52
52
|
|
|
53
53
|
var name = "very-happy-cli";
|
|
54
|
-
var version = "0.2.
|
|
54
|
+
var version = "0.2.97";
|
|
55
55
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
56
56
|
var author = "Kirill Dubovitskiy";
|
|
57
57
|
var contributors = [
|
|
@@ -164,12 +164,12 @@ var dependencies = {
|
|
|
164
164
|
zod: "^4.0.0"
|
|
165
165
|
};
|
|
166
166
|
var optionalDependencies = {
|
|
167
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
168
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
169
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
170
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
171
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
172
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
167
|
+
"very-happy-tools-arm64-darwin": "0.2.97",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.97",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.97",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.97",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.97",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.97"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -1002,6 +1002,22 @@ z.z.object({
|
|
|
1002
1002
|
detectedAt: z.z.number()
|
|
1003
1003
|
}).optional()
|
|
1004
1004
|
});
|
|
1005
|
+
const ClaudeAuthStateSchema = z.z.object({
|
|
1006
|
+
probeVersion: z.z.number(),
|
|
1007
|
+
daemonPid: z.z.number(),
|
|
1008
|
+
status: z.z.union([z.z.enum(["ok", "not-logged-in", "unknown", "error", "claude-missing"]), z.z.string()]),
|
|
1009
|
+
authMethod: z.z.string().optional(),
|
|
1010
|
+
subscriptionType: z.z.string().optional(),
|
|
1011
|
+
diagnosis: z.z.string().optional(),
|
|
1012
|
+
detail: z.z.string().optional(),
|
|
1013
|
+
repairable: z.z.string().optional(),
|
|
1014
|
+
context: z.z.object({
|
|
1015
|
+
platform: z.z.string(),
|
|
1016
|
+
lineage: z.z.string(),
|
|
1017
|
+
credentialStore: z.z.string()
|
|
1018
|
+
}),
|
|
1019
|
+
checkedAt: z.z.number()
|
|
1020
|
+
});
|
|
1005
1021
|
const CliUpdateStateSchema = z.z.object({
|
|
1006
1022
|
currentVersion: z.z.string(),
|
|
1007
1023
|
recommendedVersion: z.z.string().nullable(),
|
|
@@ -1096,7 +1112,15 @@ z.z.object({
|
|
|
1096
1112
|
detectedAt: z.z.number()
|
|
1097
1113
|
}).optional(),
|
|
1098
1114
|
/** Relay-owned CLI compatibility/update policy last checked by this daemon. */
|
|
1099
|
-
cliUpdate: CliUpdateStateSchema.optional()
|
|
1115
|
+
cliUpdate: CliUpdateStateSchema.optional(),
|
|
1116
|
+
/**
|
|
1117
|
+
* B-276: result of the daemon-context Claude auth preflight (spec
|
|
1118
|
+
* 2026-09-claude-auth-preflight). Trust rule for consumers:
|
|
1119
|
+
* `claudeAuth.daemonPid === daemonState.pid` — daemonState survives daemon
|
|
1120
|
+
* restarts (the server returns the existing row and connect spreads it
|
|
1121
|
+
* forward), so a downgraded daemon carries this field along unchanged.
|
|
1122
|
+
*/
|
|
1123
|
+
claudeAuth: ClaudeAuthStateSchema.optional()
|
|
1100
1124
|
});
|
|
1101
1125
|
const MessageMetaSchema = z.z.object({
|
|
1102
1126
|
sentFrom: z.z.string().optional(),
|
|
@@ -1545,7 +1569,7 @@ class RpcHandlerManager {
|
|
|
1545
1569
|
}
|
|
1546
1570
|
}
|
|
1547
1571
|
|
|
1548
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1572
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-DoGaKVfK.cjs', document.baseURI).href))));
|
|
1549
1573
|
function projectPath() {
|
|
1550
1574
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1551
1575
|
return path;
|
|
@@ -10368,8 +10392,18 @@ function resolveDefaultShell(platform, env, isExecutable = (path) => {
|
|
|
10368
10392
|
function defaultShell() {
|
|
10369
10393
|
return resolveDefaultShell(process.platform, process.env);
|
|
10370
10394
|
}
|
|
10395
|
+
const VH_SESSION_OPTION_OVERRIDES = [
|
|
10396
|
+
["session", "destroy-unattached", "off"],
|
|
10397
|
+
["window", "remain-on-exit", "off"],
|
|
10398
|
+
["window", "window-size", "latest"],
|
|
10399
|
+
["window", "pane-border-status", "off"]
|
|
10400
|
+
];
|
|
10371
10401
|
function tmuxNewSessionArgs(session, cols, rows, cwd, envFlags, shell) {
|
|
10372
|
-
|
|
10402
|
+
const args = ["new-session", "-d", ...envFlags, "-s", session, "-x", String(cols), "-y", String(rows), "-c", cwd, shell];
|
|
10403
|
+
for (const [scope, option, value] of VH_SESSION_OPTION_OVERRIDES) {
|
|
10404
|
+
args.push(";", "set-option", ...scope === "window" ? ["-w"] : [], "-q", "-t", `=${session}:`, option, value);
|
|
10405
|
+
}
|
|
10406
|
+
return args;
|
|
10373
10407
|
}
|
|
10374
10408
|
function shouldUseDirectPtyFallback(attachOnly, createdNew, sessionAlive) {
|
|
10375
10409
|
return !attachOnly && !createdNew && !sessionAlive;
|
|
@@ -13771,6 +13805,7 @@ class ApiMachineClient {
|
|
|
13771
13805
|
lastKnownResumeSupport = null;
|
|
13772
13806
|
cliUpdateState = null;
|
|
13773
13807
|
cliUpdatePushChain = Promise.resolve();
|
|
13808
|
+
claudeAuthState = null;
|
|
13774
13809
|
rpcHandlerManager;
|
|
13775
13810
|
resumeSessionHandler = null;
|
|
13776
13811
|
restartSessionHandler = null;
|
|
@@ -13837,6 +13872,44 @@ class ApiMachineClient {
|
|
|
13837
13872
|
if (!this.socket?.connected) return;
|
|
13838
13873
|
this.cliUpdatePushChain = this.cliUpdatePushChain.then(() => this.updateDaemonState((current) => withCurrentCliUpdateState(current, this.cliUpdateState))).catch((error) => logger.debug("[API MACHINE] Failed to publish CLI update policy:", error));
|
|
13839
13874
|
}
|
|
13875
|
+
/**
|
|
13876
|
+
* B-276: publish the daemon-context Claude auth preflight into daemonState
|
|
13877
|
+
* (same serialized push chain as the CLI update policy). Resolves true when
|
|
13878
|
+
* the server acknowledged the write with our value in it, false otherwise
|
|
13879
|
+
* (rate-limit `result:'error'` is swallowed by updateDaemonState, so the
|
|
13880
|
+
* caller checks the echoed state and re-sends on the next probe).
|
|
13881
|
+
*/
|
|
13882
|
+
setClaudeAuthState(state) {
|
|
13883
|
+
this.claudeAuthState = state;
|
|
13884
|
+
if (!this.socket?.connected) return Promise.resolve(false);
|
|
13885
|
+
const attempt = this.cliUpdatePushChain.then(() => this.updateDaemonState((current) => ({
|
|
13886
|
+
...current ?? {},
|
|
13887
|
+
status: current?.status ?? "running",
|
|
13888
|
+
claudeAuth: state
|
|
13889
|
+
}))).then(() => this.machine.daemonState?.claudeAuth?.checkedAt === state.checkedAt && this.machine.daemonState?.claudeAuth?.daemonPid === state.daemonPid).catch((error) => {
|
|
13890
|
+
logger.debug("[API MACHINE] Failed to publish Claude auth state:", error);
|
|
13891
|
+
return false;
|
|
13892
|
+
});
|
|
13893
|
+
this.cliUpdatePushChain = attempt.then(() => void 0);
|
|
13894
|
+
return attempt;
|
|
13895
|
+
}
|
|
13896
|
+
/** B-276 machine RPCs. Responses always carry `claudeAuth` so the web can refresh in place. */
|
|
13897
|
+
setClaudeAuthHandlers(handlers) {
|
|
13898
|
+
this.rpcHandlerManager.registerHandler("claude-auth-probe", async () => {
|
|
13899
|
+
const claudeAuth = await handlers.probe();
|
|
13900
|
+
return { claudeAuth };
|
|
13901
|
+
});
|
|
13902
|
+
this.rpcHandlerManager.registerHandler("claude-auth-repair", async (params) => {
|
|
13903
|
+
const action = typeof params?.action === "string" ? params.action : "";
|
|
13904
|
+
return handlers.repair(action);
|
|
13905
|
+
});
|
|
13906
|
+
this.rpcHandlerManager.registerHandler("claude-auth-set-store", async (params) => {
|
|
13907
|
+
const store = params?.store === "file" ? "file" : params?.store === "auto" ? "auto" : null;
|
|
13908
|
+
if (!store) return { error: "invalid-store", claudeAuth: this.claudeAuthState };
|
|
13909
|
+
const claudeAuth = await handlers.setStore(store);
|
|
13910
|
+
return { claudeAuth };
|
|
13911
|
+
});
|
|
13912
|
+
}
|
|
13840
13913
|
setRPCHandlers({
|
|
13841
13914
|
spawnSession,
|
|
13842
13915
|
resumeSession,
|
|
@@ -14351,7 +14424,10 @@ class ApiMachineClient {
|
|
|
14351
14424
|
// B-084: closed records survive daemon restarts (persisted
|
|
14352
14425
|
// in closed-terminals.json), so the connect snapshot ships
|
|
14353
14426
|
// them too — not just the incremental pushes.
|
|
14354
|
-
closedTerminals: this.webTerminal.getClosedTerminals()
|
|
14427
|
+
closedTerminals: this.webTerminal.getClosedTerminals(),
|
|
14428
|
+
// B-276: re-ship the last preflight so a reconnect never
|
|
14429
|
+
// leaves a stale-pid value visible longer than needed.
|
|
14430
|
+
...this.claudeAuthState ? { claudeAuth: this.claudeAuthState } : {}
|
|
14355
14431
|
};
|
|
14356
14432
|
});
|
|
14357
14433
|
this.webTerminal.startListTracking((terminals) => this.pushTerminalList(terminals));
|
|
@@ -15763,3 +15839,4 @@ exports.writeCredentialsDataKey = writeCredentialsDataKey;
|
|
|
15763
15839
|
exports.writeCredentialsLegacy = writeCredentialsLegacy;
|
|
15764
15840
|
exports.writeDaemonState = writeDaemonState;
|
|
15765
15841
|
exports.writePrivateFileSync = writePrivateFileSync;
|
|
15842
|
+
exports.writeSettings = writeSettings;
|
|
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
|
|
|
29
29
|
import { Expo } from 'expo-server-sdk';
|
|
30
30
|
|
|
31
31
|
var name = "very-happy-cli";
|
|
32
|
-
var version = "0.2.
|
|
32
|
+
var version = "0.2.97";
|
|
33
33
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
34
34
|
var author = "Kirill Dubovitskiy";
|
|
35
35
|
var contributors = [
|
|
@@ -142,12 +142,12 @@ var dependencies = {
|
|
|
142
142
|
zod: "^4.0.0"
|
|
143
143
|
};
|
|
144
144
|
var optionalDependencies = {
|
|
145
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
146
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
147
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
148
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
149
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
150
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
145
|
+
"very-happy-tools-arm64-darwin": "0.2.97",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.97",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.97",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.97",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.97",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.97"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -980,6 +980,22 @@ z$1.object({
|
|
|
980
980
|
detectedAt: z$1.number()
|
|
981
981
|
}).optional()
|
|
982
982
|
});
|
|
983
|
+
const ClaudeAuthStateSchema = z$1.object({
|
|
984
|
+
probeVersion: z$1.number(),
|
|
985
|
+
daemonPid: z$1.number(),
|
|
986
|
+
status: z$1.union([z$1.enum(["ok", "not-logged-in", "unknown", "error", "claude-missing"]), z$1.string()]),
|
|
987
|
+
authMethod: z$1.string().optional(),
|
|
988
|
+
subscriptionType: z$1.string().optional(),
|
|
989
|
+
diagnosis: z$1.string().optional(),
|
|
990
|
+
detail: z$1.string().optional(),
|
|
991
|
+
repairable: z$1.string().optional(),
|
|
992
|
+
context: z$1.object({
|
|
993
|
+
platform: z$1.string(),
|
|
994
|
+
lineage: z$1.string(),
|
|
995
|
+
credentialStore: z$1.string()
|
|
996
|
+
}),
|
|
997
|
+
checkedAt: z$1.number()
|
|
998
|
+
});
|
|
983
999
|
const CliUpdateStateSchema = z$1.object({
|
|
984
1000
|
currentVersion: z$1.string(),
|
|
985
1001
|
recommendedVersion: z$1.string().nullable(),
|
|
@@ -1074,7 +1090,15 @@ z$1.object({
|
|
|
1074
1090
|
detectedAt: z$1.number()
|
|
1075
1091
|
}).optional(),
|
|
1076
1092
|
/** Relay-owned CLI compatibility/update policy last checked by this daemon. */
|
|
1077
|
-
cliUpdate: CliUpdateStateSchema.optional()
|
|
1093
|
+
cliUpdate: CliUpdateStateSchema.optional(),
|
|
1094
|
+
/**
|
|
1095
|
+
* B-276: result of the daemon-context Claude auth preflight (spec
|
|
1096
|
+
* 2026-09-claude-auth-preflight). Trust rule for consumers:
|
|
1097
|
+
* `claudeAuth.daemonPid === daemonState.pid` — daemonState survives daemon
|
|
1098
|
+
* restarts (the server returns the existing row and connect spreads it
|
|
1099
|
+
* forward), so a downgraded daemon carries this field along unchanged.
|
|
1100
|
+
*/
|
|
1101
|
+
claudeAuth: ClaudeAuthStateSchema.optional()
|
|
1078
1102
|
});
|
|
1079
1103
|
const MessageMetaSchema = z$1.object({
|
|
1080
1104
|
sentFrom: z$1.string().optional(),
|
|
@@ -10346,8 +10370,18 @@ function resolveDefaultShell(platform, env, isExecutable = (path) => {
|
|
|
10346
10370
|
function defaultShell() {
|
|
10347
10371
|
return resolveDefaultShell(process.platform, process.env);
|
|
10348
10372
|
}
|
|
10373
|
+
const VH_SESSION_OPTION_OVERRIDES = [
|
|
10374
|
+
["session", "destroy-unattached", "off"],
|
|
10375
|
+
["window", "remain-on-exit", "off"],
|
|
10376
|
+
["window", "window-size", "latest"],
|
|
10377
|
+
["window", "pane-border-status", "off"]
|
|
10378
|
+
];
|
|
10349
10379
|
function tmuxNewSessionArgs(session, cols, rows, cwd, envFlags, shell) {
|
|
10350
|
-
|
|
10380
|
+
const args = ["new-session", "-d", ...envFlags, "-s", session, "-x", String(cols), "-y", String(rows), "-c", cwd, shell];
|
|
10381
|
+
for (const [scope, option, value] of VH_SESSION_OPTION_OVERRIDES) {
|
|
10382
|
+
args.push(";", "set-option", ...scope === "window" ? ["-w"] : [], "-q", "-t", `=${session}:`, option, value);
|
|
10383
|
+
}
|
|
10384
|
+
return args;
|
|
10351
10385
|
}
|
|
10352
10386
|
function shouldUseDirectPtyFallback(attachOnly, createdNew, sessionAlive) {
|
|
10353
10387
|
return !attachOnly && !createdNew && !sessionAlive;
|
|
@@ -13749,6 +13783,7 @@ class ApiMachineClient {
|
|
|
13749
13783
|
lastKnownResumeSupport = null;
|
|
13750
13784
|
cliUpdateState = null;
|
|
13751
13785
|
cliUpdatePushChain = Promise.resolve();
|
|
13786
|
+
claudeAuthState = null;
|
|
13752
13787
|
rpcHandlerManager;
|
|
13753
13788
|
resumeSessionHandler = null;
|
|
13754
13789
|
restartSessionHandler = null;
|
|
@@ -13815,6 +13850,44 @@ class ApiMachineClient {
|
|
|
13815
13850
|
if (!this.socket?.connected) return;
|
|
13816
13851
|
this.cliUpdatePushChain = this.cliUpdatePushChain.then(() => this.updateDaemonState((current) => withCurrentCliUpdateState(current, this.cliUpdateState))).catch((error) => logger.debug("[API MACHINE] Failed to publish CLI update policy:", error));
|
|
13817
13852
|
}
|
|
13853
|
+
/**
|
|
13854
|
+
* B-276: publish the daemon-context Claude auth preflight into daemonState
|
|
13855
|
+
* (same serialized push chain as the CLI update policy). Resolves true when
|
|
13856
|
+
* the server acknowledged the write with our value in it, false otherwise
|
|
13857
|
+
* (rate-limit `result:'error'` is swallowed by updateDaemonState, so the
|
|
13858
|
+
* caller checks the echoed state and re-sends on the next probe).
|
|
13859
|
+
*/
|
|
13860
|
+
setClaudeAuthState(state) {
|
|
13861
|
+
this.claudeAuthState = state;
|
|
13862
|
+
if (!this.socket?.connected) return Promise.resolve(false);
|
|
13863
|
+
const attempt = this.cliUpdatePushChain.then(() => this.updateDaemonState((current) => ({
|
|
13864
|
+
...current ?? {},
|
|
13865
|
+
status: current?.status ?? "running",
|
|
13866
|
+
claudeAuth: state
|
|
13867
|
+
}))).then(() => this.machine.daemonState?.claudeAuth?.checkedAt === state.checkedAt && this.machine.daemonState?.claudeAuth?.daemonPid === state.daemonPid).catch((error) => {
|
|
13868
|
+
logger.debug("[API MACHINE] Failed to publish Claude auth state:", error);
|
|
13869
|
+
return false;
|
|
13870
|
+
});
|
|
13871
|
+
this.cliUpdatePushChain = attempt.then(() => void 0);
|
|
13872
|
+
return attempt;
|
|
13873
|
+
}
|
|
13874
|
+
/** B-276 machine RPCs. Responses always carry `claudeAuth` so the web can refresh in place. */
|
|
13875
|
+
setClaudeAuthHandlers(handlers) {
|
|
13876
|
+
this.rpcHandlerManager.registerHandler("claude-auth-probe", async () => {
|
|
13877
|
+
const claudeAuth = await handlers.probe();
|
|
13878
|
+
return { claudeAuth };
|
|
13879
|
+
});
|
|
13880
|
+
this.rpcHandlerManager.registerHandler("claude-auth-repair", async (params) => {
|
|
13881
|
+
const action = typeof params?.action === "string" ? params.action : "";
|
|
13882
|
+
return handlers.repair(action);
|
|
13883
|
+
});
|
|
13884
|
+
this.rpcHandlerManager.registerHandler("claude-auth-set-store", async (params) => {
|
|
13885
|
+
const store = params?.store === "file" ? "file" : params?.store === "auto" ? "auto" : null;
|
|
13886
|
+
if (!store) return { error: "invalid-store", claudeAuth: this.claudeAuthState };
|
|
13887
|
+
const claudeAuth = await handlers.setStore(store);
|
|
13888
|
+
return { claudeAuth };
|
|
13889
|
+
});
|
|
13890
|
+
}
|
|
13818
13891
|
setRPCHandlers({
|
|
13819
13892
|
spawnSession,
|
|
13820
13893
|
resumeSession,
|
|
@@ -14329,7 +14402,10 @@ class ApiMachineClient {
|
|
|
14329
14402
|
// B-084: closed records survive daemon restarts (persisted
|
|
14330
14403
|
// in closed-terminals.json), so the connect snapshot ships
|
|
14331
14404
|
// them too — not just the incremental pushes.
|
|
14332
|
-
closedTerminals: this.webTerminal.getClosedTerminals()
|
|
14405
|
+
closedTerminals: this.webTerminal.getClosedTerminals(),
|
|
14406
|
+
// B-276: re-ship the last preflight so a reconnect never
|
|
14407
|
+
// leaves a stale-pid value visible longer than needed.
|
|
14408
|
+
...this.claudeAuthState ? { claudeAuth: this.claudeAuthState } : {}
|
|
14333
14409
|
};
|
|
14334
14410
|
});
|
|
14335
14411
|
this.webTerminal.startListTracking((terminals) => this.pushTerminalList(terminals));
|
|
@@ -15664,4 +15740,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
15664
15740
|
}).passthrough()
|
|
15665
15741
|
]);
|
|
15666
15742
|
|
|
15667
|
-
export { detectResumeSupport as $, ApiClient as A, deriveLocalCliUpdateSummary as B, updateSettings as C, encodeBase64Url as D, decodeBase64 as E, writeCredentialsLegacy as F, writeCredentialsDataKey as G, readCredentialsForConfiguredRelay as H, InvalidateSync as I, encrypt as J, isClaudeSessionId as K, getLocalHappyAgentCredentialPath as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readLocalHappyAgentCredentials as N, decryptWithDataKey as O, decryptLegacy as P, extractCompleteLines as Q, RawJSONLinesSchema as R, decideBackfill as S, parseTerminalHookPayload as T, tmuxArgs as U, scrubTmuxClientEnv as V, decideMirrorBinding as W, MIRROR_BACKFILL_LINES_DEFAULT as X, persistSession as Y, mirrorLineKey as Z, mirrorLocalId as _, ApiSessionClient as a, detectCLIAvailability as a0, acquireDaemonLock as a1, summarizeSpawnSessionForLog as a2, deletePersistedSessions as a3, decrypt as a4, writeDaemonState as a5,
|
|
15743
|
+
export { detectResumeSupport as $, ApiClient as A, deriveLocalCliUpdateSummary as B, updateSettings as C, encodeBase64Url as D, decodeBase64 as E, writeCredentialsLegacy as F, writeCredentialsDataKey as G, readCredentialsForConfiguredRelay as H, InvalidateSync as I, encrypt as J, isClaudeSessionId as K, getLocalHappyAgentCredentialPath as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readLocalHappyAgentCredentials as N, decryptWithDataKey as O, decryptLegacy as P, extractCompleteLines as Q, RawJSONLinesSchema as R, decideBackfill as S, parseTerminalHookPayload as T, tmuxArgs as U, scrubTmuxClientEnv as V, decideMirrorBinding as W, MIRROR_BACKFILL_LINES_DEFAULT as X, persistSession as Y, mirrorLineKey as Z, mirrorLocalId as _, ApiSessionClient as a, detectCLIAvailability as a0, acquireDaemonLock as a1, summarizeSpawnSessionForLog as a2, deletePersistedSessions as a3, decrypt as a4, writeDaemonState as a5, writeSettings as a6, fetchCliUpdateState as a7, resolveCliUpdateCheckInterval as a8, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as a9, releaseDaemonLock as aa, isValidSessionId as ab, listVhTerminals as ac, isValidTerminalId as ad, readVhTerminal as ae, sendToVhTerminal as af, startOfflineReconnection as ag, clearCredentials as ah, clearMachineId as ai, SandboxConfigSchema as aj, CodexAppServerClient as ak, getLatestDaemonLog as al, persistence as am, api as an, createEnvelope as b, configuration as c, contentLogMetadata as d, errorLogMetadata as e, packageJson as f, delay as g, connectionState as h, readSettings as i, encodeBase64 as j, ensurePrivateDirectorySync as k, logger as l, hardenPrivateFileSync as m, readDaemonState as n, clearDaemonState as o, projectPath as p, getProjectPath as q, readPersistedSessions as r, initializeSandbox as s, wrapCommand as t, AsyncLock as u, ensurePrivateDirectory as v, writePrivateFileSync as w, hardenPrivateFile as x, readCredentials as y, credentialRelayProblem as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.97",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.97",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.97",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.97",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.97",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.97",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.97"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# very-happy keychain-off shim for Claude Code (B-276, spec 2026-09-claude-auth-preflight D8).
|
|
3
|
+
#
|
|
4
|
+
# Placed FIRST on PATH only for the Claude Code processes very-happy spawns when
|
|
5
|
+
# the machine-local setting `claudeCredentialStore` is `file`. Claude Code reads
|
|
6
|
+
# and writes its OAuth credentials through the bare `security` CLI; an exit code
|
|
7
|
+
# of 36 (errSecInteractionNotAllowed) on its own keychain item makes it fall
|
|
8
|
+
# back to ~/.claude/.credentials.json for reads AND writes without deleting the
|
|
9
|
+
# file — exactly what an ssh/tmux shell sees. Everything that is not Claude
|
|
10
|
+
# Code's own item is passed through to the real binary untouched.
|
|
11
|
+
#
|
|
12
|
+
# Exit code MUST be 36 or 44: anything else is treated by Claude Code as a
|
|
13
|
+
# transient READ_FAILED (cached credentials), not as "use the file".
|
|
14
|
+
REAL="${HAPPY_SECURITY_BIN:-/usr/bin/security}"
|
|
15
|
+
|
|
16
|
+
is_claude_item() {
|
|
17
|
+
# $@ = tokens of one security command line; true when -s <value> starts with "Claude Code"
|
|
18
|
+
local prev="" tok
|
|
19
|
+
for tok in "$@"; do
|
|
20
|
+
if [ "$prev" = "-s" ]; then
|
|
21
|
+
tok="${tok%\"}"; tok="${tok#\"}"; tok="${tok%\'}"; tok="${tok#\'}"
|
|
22
|
+
case "$tok" in "Claude Code"*) return 0 ;; esac
|
|
23
|
+
return 1
|
|
24
|
+
fi
|
|
25
|
+
prev="$tok"
|
|
26
|
+
done
|
|
27
|
+
return 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
case "${1:-}" in
|
|
31
|
+
show-keychain-info)
|
|
32
|
+
exit 36 ;;
|
|
33
|
+
find-generic-password|add-generic-password|delete-generic-password)
|
|
34
|
+
if is_claude_item "$@"; then exit 36; fi
|
|
35
|
+
exec "$REAL" "$@" ;;
|
|
36
|
+
-i)
|
|
37
|
+
# Interactive form: Claude Code's normal write path feeds
|
|
38
|
+
# `add-generic-password -U -a <user> -s "<service>" -X <hex>` on stdin.
|
|
39
|
+
input="$(cat)"
|
|
40
|
+
first_line="$(printf '%s\n' "$input" | sed -n '1p')"
|
|
41
|
+
case "$first_line" in
|
|
42
|
+
find-generic-password*|add-generic-password*|delete-generic-password*)
|
|
43
|
+
if [[ "$first_line" =~ (^|[[:space:]])-s[[:space:]]+(\"([^\"]*)\"|\'([^\']*)\'|([^[:space:]]+)) ]]; then
|
|
44
|
+
svc="${BASH_REMATCH[3]}${BASH_REMATCH[4]}${BASH_REMATCH[5]}"
|
|
45
|
+
case "$svc" in "Claude Code"*) exit 36 ;; esac
|
|
46
|
+
fi ;;
|
|
47
|
+
esac
|
|
48
|
+
printf '%s\n' "$input" | exec "$REAL" -i ;;
|
|
49
|
+
*)
|
|
50
|
+
exec "$REAL" "$@" ;;
|
|
51
|
+
esac
|