very-happy-cli 0.2.119 → 0.2.121
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-DpsLyp2y.mjs → AcpBackend-BxvQ6O4k.mjs} +1 -1
- package/dist/{AcpBackend-BpwOAcgu.cjs → AcpBackend-Cdj56ZfU.cjs} +1 -1
- package/dist/{AcpSessionManager-Ck6heffK.cjs → AcpSessionManager-DahCU78z.cjs} +51 -11
- package/dist/{AcpSessionManager-CM0PcgwO.mjs → AcpSessionManager-DlWlQVhw.mjs} +51 -11
- package/dist/{config-CtQJKe8h.cjs → config-DxOhdFEx.cjs} +2 -2
- package/dist/{config-DpE-aSHW.mjs → config-osO37dR1.mjs} +2 -2
- package/dist/{index-BITXLEZo.mjs → index-BcwAnM9k.mjs} +25 -11
- package/dist/{index-CK-yge8m.cjs → index-Bv53Zygv.cjs} +24 -10
- package/dist/{index-CRhOD3CQ.cjs → index-DObePs_K.cjs} +176 -54
- package/dist/{index-CGpkGfDj.mjs → index-DtZFY8aS.mjs} +2 -2
- package/dist/{index-DNXCQz_A.mjs → index-Iz-M3qbz.mjs} +172 -51
- package/dist/{index-DY7g3UWq.cjs → index-Vjo1jIJH.cjs} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-Dmr3JUJR.mjs → installTerminalHooks-Bq11vOqF.mjs} +2 -2
- package/dist/{installTerminalHooks-BOOg7NNs.cjs → installTerminalHooks-DehsXLmV.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +25 -1
- package/dist/lib.d.mts +25 -1
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-D4N7yn98.mjs → mcp-Bx1B3uny.mjs} +2 -2
- package/dist/{mcp-CxIk4Mes.cjs → mcp-Cpx9Qlch.cjs} +2 -2
- package/dist/{runGemini-Bexbg8pA.mjs → runGemini-CMgudbJs.mjs} +9 -5
- package/dist/{runGemini-TbGYRy0V.cjs → runGemini-DI8DipUx.cjs} +9 -5
- package/dist/{runOpenClaw-B-TV4EkO.cjs → runOpenClaw-CetdjTl-.cjs} +3 -3
- package/dist/{runOpenClaw-BpoIQWbe.mjs → runOpenClaw-DR3fLtVf.mjs} +3 -3
- package/dist/{send-U9UJvqNA.cjs → send-Cq0NZCn8.cjs} +2 -2
- package/dist/{send-z5SeDtKA.mjs → send-M4b_hD7t.mjs} +2 -2
- package/dist/{sessions-DNALvNe8.mjs → sessions-CelkWhqX.mjs} +11 -4
- package/dist/{sessions-BAZGALtl.cjs → sessions-DW4lrLOp.cjs} +11 -4
- package/dist/{spawn-CsV0SKkw.mjs → spawn-C4fF0q3Z.mjs} +2 -2
- package/dist/{spawn-dBxu-RAv.cjs → spawn-D3cwBlWI.cjs} +2 -2
- package/dist/{types-Bw_6p8NP.cjs → types-COOYpI8_.cjs} +176 -33
- package/dist/{types-DdyNuB7D.mjs → types-P2cJWD0E.mjs} +174 -33
- package/package.json +7 -7
|
@@ -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.121";
|
|
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.121",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.121",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.121",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.121",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.121",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.121"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -720,6 +720,11 @@ const sessionProgressEventSchema = z.object({
|
|
|
720
720
|
durationMs: z.number().optional(),
|
|
721
721
|
summary: z.string().optional()
|
|
722
722
|
});
|
|
723
|
+
const sessionQueueCancelEventSchema = z.object({
|
|
724
|
+
t: z.literal("queue-cancel"),
|
|
725
|
+
targetLocalKeys: z.array(z.string().min(1)).min(1),
|
|
726
|
+
reason: z.string().min(1).optional()
|
|
727
|
+
});
|
|
723
728
|
const sessionEventSchema = z.discriminatedUnion("t", [
|
|
724
729
|
sessionTextEventSchema,
|
|
725
730
|
sessionServiceMessageEventSchema,
|
|
@@ -730,7 +735,8 @@ const sessionEventSchema = z.discriminatedUnion("t", [
|
|
|
730
735
|
sessionStartEventSchema,
|
|
731
736
|
sessionTurnEndEventSchema,
|
|
732
737
|
sessionStopEventSchema,
|
|
733
|
-
sessionProgressEventSchema
|
|
738
|
+
sessionProgressEventSchema,
|
|
739
|
+
sessionQueueCancelEventSchema
|
|
734
740
|
]);
|
|
735
741
|
const sessionEnvelopeSchema = z.object({
|
|
736
742
|
id: z.string(),
|
|
@@ -3113,6 +3119,48 @@ class InvalidateSync {
|
|
|
3113
3119
|
};
|
|
3114
3120
|
}
|
|
3115
3121
|
|
|
3122
|
+
function sessionEnvelopeOf(body) {
|
|
3123
|
+
if (!body || typeof body !== "object") return null;
|
|
3124
|
+
const record = body;
|
|
3125
|
+
if (record.role !== "session" || !record.content || typeof record.content !== "object") return null;
|
|
3126
|
+
const content = record.content;
|
|
3127
|
+
if (content.type === "session" && content.data && typeof content.data === "object") {
|
|
3128
|
+
return content.data;
|
|
3129
|
+
}
|
|
3130
|
+
if (content.ev !== void 0) return content;
|
|
3131
|
+
return null;
|
|
3132
|
+
}
|
|
3133
|
+
function isQueuedUserText(body) {
|
|
3134
|
+
if (!body || typeof body !== "object") return false;
|
|
3135
|
+
const record = body;
|
|
3136
|
+
return record.role === "user" && record.content?.type === "text" && typeof record.meta?.queuedAt === "number";
|
|
3137
|
+
}
|
|
3138
|
+
function scanUndeliveredQueuedInputs(records, prior) {
|
|
3139
|
+
const canceled = prior?.canceled ?? /* @__PURE__ */ new Set();
|
|
3140
|
+
const undelivered = [];
|
|
3141
|
+
let reachedBoundary = false;
|
|
3142
|
+
for (const record of records) {
|
|
3143
|
+
const envelope = sessionEnvelopeOf(record.body);
|
|
3144
|
+
if (envelope) {
|
|
3145
|
+
const t = envelope.ev?.t;
|
|
3146
|
+
if (t === "turn-end") {
|
|
3147
|
+
reachedBoundary = true;
|
|
3148
|
+
break;
|
|
3149
|
+
}
|
|
3150
|
+
if (t === "queue-cancel" && Array.isArray(envelope.ev?.targetLocalKeys)) {
|
|
3151
|
+
for (const key of envelope.ev.targetLocalKeys) {
|
|
3152
|
+
if (typeof key === "string") canceled.add(key);
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
continue;
|
|
3156
|
+
}
|
|
3157
|
+
if (isQueuedUserText(record.body) && record.localId && !canceled.has(record.localId)) {
|
|
3158
|
+
undelivered.push(record.localId);
|
|
3159
|
+
}
|
|
3160
|
+
}
|
|
3161
|
+
return { undeliveredLocalKeys: undelivered, reachedBoundary, canceled };
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3116
3164
|
function record(value) {
|
|
3117
3165
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
3118
3166
|
}
|
|
@@ -3756,8 +3804,75 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3756
3804
|
this.sendSync.invalidate();
|
|
3757
3805
|
}
|
|
3758
3806
|
}
|
|
3807
|
+
/** B-332: emit a queue-cancel tombstone, mirroring the web's own signal. */
|
|
3808
|
+
sendQueueCancelReason(localKeys, reason) {
|
|
3809
|
+
if (localKeys.length === 0) return;
|
|
3810
|
+
const envelope = createEnvelope("user", { t: "queue-cancel", targetLocalKeys: localKeys, reason });
|
|
3811
|
+
this.sendSessionProtocolMessage(envelope);
|
|
3812
|
+
}
|
|
3759
3813
|
/**
|
|
3760
|
-
*
|
|
3814
|
+
* B-332 site ③: find queued user input this wrapper destroyed (it was still
|
|
3815
|
+
* in the previous wrapper's in-memory queue when it died) and tell the web.
|
|
3816
|
+
*
|
|
3817
|
+
* Walks NEWEST → OLDEST via `before_seq`, decrypting each page, and stops at
|
|
3818
|
+
* the first turn-end. The runner calls this on EVERY reconnect (runClaude /
|
|
3819
|
+
* runCodex), seeded or not: a cursor seeded at the server's latest seq skips
|
|
3820
|
+
* the undelivered tail just as thoroughly as skipExistingMessages does —
|
|
3821
|
+
* and the daemon's resume/restart always seeds, so gating on the skip path
|
|
3822
|
+
* would miss the common case. Best-effort: a failed scan must not take a
|
|
3823
|
+
* session down. Needs no socket; POSTs through the same session-message
|
|
3824
|
+
* channel so the web receives it identically to a cancel-button tombstone.
|
|
3825
|
+
*/
|
|
3826
|
+
async cancelUndeliveredQueuedInputs() {
|
|
3827
|
+
const MAX_SCAN_PAGES = 10;
|
|
3828
|
+
const canceled = /* @__PURE__ */ new Set();
|
|
3829
|
+
const undelivered = [];
|
|
3830
|
+
let beforeSeq = 2147483647;
|
|
3831
|
+
let reachedBoundary = false;
|
|
3832
|
+
let pages = 0;
|
|
3833
|
+
try {
|
|
3834
|
+
while (!reachedBoundary && pages < MAX_SCAN_PAGES) {
|
|
3835
|
+
pages += 1;
|
|
3836
|
+
const response = await axios.get(
|
|
3837
|
+
`${configuration.serverUrl}/v3/sessions/${encodeURIComponent(this.sessionId)}/messages`,
|
|
3838
|
+
{
|
|
3839
|
+
params: { before_seq: beforeSeq, limit: 100 },
|
|
3840
|
+
headers: this.authHeaders(),
|
|
3841
|
+
timeout: 6e4
|
|
3842
|
+
}
|
|
3843
|
+
);
|
|
3844
|
+
const messages = Array.isArray(response.data.messages) ? response.data.messages : [];
|
|
3845
|
+
if (messages.length === 0) break;
|
|
3846
|
+
const records = messages.map((message) => {
|
|
3847
|
+
let body = null;
|
|
3848
|
+
try {
|
|
3849
|
+
body = message.content?.t === "encrypted" ? decrypt(this.encryptionKey, this.encryptionVariant, decodeBase64(message.content.c)) : null;
|
|
3850
|
+
} catch (error) {
|
|
3851
|
+
logger.debug("[API] Failed to decrypt during undelivered scan:", error);
|
|
3852
|
+
}
|
|
3853
|
+
return { seq: message.seq, localId: message.localId, body };
|
|
3854
|
+
});
|
|
3855
|
+
const scan = scanUndeliveredQueuedInputs(records, { canceled });
|
|
3856
|
+
for (const key of scan.canceled) canceled.add(key);
|
|
3857
|
+
undelivered.push(...scan.undeliveredLocalKeys);
|
|
3858
|
+
reachedBoundary = scan.reachedBoundary;
|
|
3859
|
+
const oldest = records.at(-1)?.seq;
|
|
3860
|
+
if (oldest === void 0 || messages.length < 100) break;
|
|
3861
|
+
beforeSeq = oldest;
|
|
3862
|
+
}
|
|
3863
|
+
} catch (error) {
|
|
3864
|
+
logger.debug("[API] cancelUndeliveredQueuedInputs scan failed:", error);
|
|
3865
|
+
return;
|
|
3866
|
+
}
|
|
3867
|
+
if (!reachedBoundary) {
|
|
3868
|
+
logger.debug("[API] cancelUndeliveredQueuedInputs found no turn boundary; leaving messages as-is");
|
|
3869
|
+
return;
|
|
3870
|
+
}
|
|
3871
|
+
undelivered.reverse();
|
|
3872
|
+
this.sendQueueCancelReason(undelivered, "restarted");
|
|
3873
|
+
}
|
|
3874
|
+
/**
|
|
3875
|
+
* Send a message to session
|
|
3761
3876
|
* @param body - Message body (can be MessageContent or raw content for agent messages)
|
|
3762
3877
|
*/
|
|
3763
3878
|
sendClaudeSessionMessage(body, opts) {
|
|
@@ -4450,34 +4565,44 @@ function migrateSettings(raw, fromVersion) {
|
|
|
4450
4565
|
let migrated = { ...raw };
|
|
4451
4566
|
return migrated;
|
|
4452
4567
|
}
|
|
4453
|
-
async function
|
|
4568
|
+
async function readSettingsOutcome() {
|
|
4454
4569
|
if (!existsSync(configuration.settingsFile)) {
|
|
4455
|
-
return {
|
|
4570
|
+
return { kind: "absent" };
|
|
4456
4571
|
}
|
|
4457
4572
|
try {
|
|
4458
|
-
|
|
4459
|
-
const raw = JSON.parse(content);
|
|
4460
|
-
const schemaVersion = raw.schemaVersion ?? 1;
|
|
4461
|
-
if (schemaVersion > SUPPORTED_SCHEMA_VERSION) {
|
|
4462
|
-
logger.warn(
|
|
4463
|
-
`\u26A0\uFE0F Settings schema v${schemaVersion} > supported v${SUPPORTED_SCHEMA_VERSION}. Update happy-cli for full functionality.`
|
|
4464
|
-
);
|
|
4465
|
-
}
|
|
4466
|
-
const migrated = migrateSettings(raw, schemaVersion);
|
|
4467
|
-
if (migrated.sandboxConfig !== void 0) {
|
|
4468
|
-
try {
|
|
4469
|
-
migrated.sandboxConfig = SandboxConfigSchema.parse(migrated.sandboxConfig);
|
|
4470
|
-
} catch (error) {
|
|
4471
|
-
logger.warn(`\u26A0\uFE0F Invalid sandbox config - skipping. Error: ${error.message}`);
|
|
4472
|
-
migrated.sandboxConfig = void 0;
|
|
4473
|
-
}
|
|
4474
|
-
}
|
|
4475
|
-
return { ...defaultSettings, ...migrated };
|
|
4573
|
+
return { kind: "ok", settings: await parseSettingsFile() };
|
|
4476
4574
|
} catch (error) {
|
|
4477
|
-
|
|
4478
|
-
return { ...defaultSettings };
|
|
4575
|
+
return { kind: "unreadable", error: error?.message ?? String(error) };
|
|
4479
4576
|
}
|
|
4480
4577
|
}
|
|
4578
|
+
async function readSettings() {
|
|
4579
|
+
const outcome = await readSettingsOutcome();
|
|
4580
|
+
if (outcome.kind === "ok") return outcome.settings;
|
|
4581
|
+
if (outcome.kind === "unreadable") {
|
|
4582
|
+
logger.warn(`Failed to read settings: ${outcome.error}`);
|
|
4583
|
+
}
|
|
4584
|
+
return { ...defaultSettings };
|
|
4585
|
+
}
|
|
4586
|
+
async function parseSettingsFile() {
|
|
4587
|
+
const content = await readFile$1(configuration.settingsFile, "utf8");
|
|
4588
|
+
const raw = JSON.parse(content);
|
|
4589
|
+
const schemaVersion = raw.schemaVersion ?? 1;
|
|
4590
|
+
if (schemaVersion > SUPPORTED_SCHEMA_VERSION) {
|
|
4591
|
+
logger.warn(
|
|
4592
|
+
`\u26A0\uFE0F Settings schema v${schemaVersion} > supported v${SUPPORTED_SCHEMA_VERSION}. Update happy-cli for full functionality.`
|
|
4593
|
+
);
|
|
4594
|
+
}
|
|
4595
|
+
const migrated = migrateSettings(raw);
|
|
4596
|
+
if (migrated.sandboxConfig !== void 0) {
|
|
4597
|
+
try {
|
|
4598
|
+
migrated.sandboxConfig = SandboxConfigSchema.parse(migrated.sandboxConfig);
|
|
4599
|
+
} catch (error) {
|
|
4600
|
+
logger.warn(`\u26A0\uFE0F Invalid sandbox config - skipping. Error: ${error.message}`);
|
|
4601
|
+
migrated.sandboxConfig = void 0;
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
return { ...defaultSettings, ...migrated };
|
|
4605
|
+
}
|
|
4481
4606
|
async function writeSettings(settings) {
|
|
4482
4607
|
await ensurePrivateDirectory(configuration.happyHomeDir);
|
|
4483
4608
|
const settingsWithVersion = {
|
|
@@ -4519,7 +4644,13 @@ async function updateSettings(updater) {
|
|
|
4519
4644
|
throw new Error(`Failed to acquire settings lock after ${MAX_LOCK_ATTEMPTS * LOCK_RETRY_INTERVAL_MS / 1e3} seconds`);
|
|
4520
4645
|
}
|
|
4521
4646
|
try {
|
|
4522
|
-
const
|
|
4647
|
+
const outcome = await readSettingsOutcome();
|
|
4648
|
+
if (outcome.kind === "unreadable") {
|
|
4649
|
+
throw new Error(
|
|
4650
|
+
`Settings file ${configuration.settingsFile} exists but could not be read (${outcome.error}). Refusing to overwrite it \u2014 fix or remove the file (a removed file is recreated with defaults).`
|
|
4651
|
+
);
|
|
4652
|
+
}
|
|
4653
|
+
const current = outcome.kind === "ok" ? outcome.settings : { ...defaultSettings };
|
|
4523
4654
|
const updated = await updater(current);
|
|
4524
4655
|
await ensurePrivateDirectory(configuration.happyHomeDir);
|
|
4525
4656
|
await writePrivateFile(tmpFile, JSON.stringify(updated, null, 2));
|
|
@@ -4766,6 +4897,7 @@ var persistence = /*#__PURE__*/Object.freeze({
|
|
|
4766
4897
|
readDaemonState: readDaemonState,
|
|
4767
4898
|
readPersistedSessions: readPersistedSessions,
|
|
4768
4899
|
readSettings: readSettings,
|
|
4900
|
+
readSettingsOutcome: readSettingsOutcome,
|
|
4769
4901
|
readTrackedClaudeSessionIds: readTrackedClaudeSessionIds,
|
|
4770
4902
|
releaseDaemonLock: releaseDaemonLock,
|
|
4771
4903
|
updateSettings: updateSettings,
|
|
@@ -14513,6 +14645,7 @@ async function withCodexAppServerClient(handler) {
|
|
|
14513
14645
|
await client.disconnect();
|
|
14514
14646
|
}
|
|
14515
14647
|
}
|
|
14648
|
+
const CLI_AVAILABILITY_RECHECK_MS = 5 * 60 * 1e3;
|
|
14516
14649
|
class ApiMachineClient {
|
|
14517
14650
|
constructor(token, machine) {
|
|
14518
14651
|
this.token = token;
|
|
@@ -14536,6 +14669,10 @@ class ApiMachineClient {
|
|
|
14536
14669
|
keepAliveInterval = null;
|
|
14537
14670
|
lastKnownCLIAvailability = null;
|
|
14538
14671
|
lastKnownResumeSupport = null;
|
|
14672
|
+
/** Wall-clock of the last CLI availability probe. Initialised as "already
|
|
14673
|
+
* stale" so the FIRST keep-alive tick always probes and populates the
|
|
14674
|
+
* machine metadata that a connecting/reconnecting web client reads. */
|
|
14675
|
+
lastCliProbeAt = Date.now() - CLI_AVAILABILITY_RECHECK_MS;
|
|
14539
14676
|
cliUpdateState = null;
|
|
14540
14677
|
cliUpdatePushChain = Promise.resolve();
|
|
14541
14678
|
claudeAuthState = null;
|
|
@@ -15403,6 +15540,10 @@ class ApiMachineClient {
|
|
|
15403
15540
|
}
|
|
15404
15541
|
this.socket.emit("machine-alive", payload);
|
|
15405
15542
|
void this.refreshRelayConnection();
|
|
15543
|
+
if (Date.now() - this.lastCliProbeAt < CLI_AVAILABILITY_RECHECK_MS) {
|
|
15544
|
+
return;
|
|
15545
|
+
}
|
|
15546
|
+
this.lastCliProbeAt = Date.now();
|
|
15406
15547
|
const newAvailability = detectCLIAvailability();
|
|
15407
15548
|
const prev = this.lastKnownCLIAvailability;
|
|
15408
15549
|
const newResumeSupport = detectResumeSupport();
|
|
@@ -16630,4 +16771,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
16630
16771
|
}).passthrough()
|
|
16631
16772
|
]);
|
|
16632
16773
|
|
|
16633
|
-
export {
|
|
16774
|
+
export { scrubTmuxClientEnv as $, ApiClient as A, commandOnPath as B, readCredentials as C, credentialRelayProblem as D, deriveLocalCliUpdateSummary as E, readSettingsOutcome as F, updateSettings as G, encodeBase64Url as H, InvalidateSync as I, decodeBase64 as J, writeCredentialsLegacy as K, writeCredentialsDataKey as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, readCredentialsForConfiguredRelay as N, encrypt as O, isClaudeSessionId as P, getLocalHappyAgentCredentialPath as Q, RawJSONLinesSchema as R, STREAM_DELTA_MAX_CHARS as S, readLocalHappyAgentCredentials as T, decryptWithDataKey as U, decryptLegacy as V, compareExactVersions as W, extractCompleteLines as X, decideBackfill as Y, parseTerminalHookPayload as Z, tmuxArgs as _, ApiSessionClient as a, decideMirrorBinding as a0, MIRROR_BACKFILL_LINES_DEFAULT as a1, persistSession as a2, mirrorLineKey as a3, mirrorLocalId as a4, detectCLIAvailability as a5, detectResumeSupport as a6, acquireDaemonLock as a7, summarizeSpawnSessionForLog as a8, deletePersistedSessions as a9, shellescape as aa, decrypt as ab, writeDaemonState as ac, writeSettings as ad, fetchCliUpdateState as ae, resolveCliUpdateCheckInterval as af, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as ag, releaseDaemonLock as ah, listVhTerminals as ai, isValidTerminalId as aj, readVhTerminal as ak, sendToVhTerminal as al, TITLE_PROMPT_PREFIX as am, BOARD_ANALYZER_PROMPT_PREFIX as an, startOfflineReconnection as ao, clearCredentials as ap, clearMachineId as aq, SandboxConfigSchema as ar, CodexAppServerClient as as, getLatestDaemonLog as at, persistence as au, api as av, createEnvelope as b, configuration as c, connectionState as d, readSettings as e, encodeBase64 as f, contentLogMetadata as g, errorLogMetadata as h, isValidSessionId as i, packageJson as j, delay as k, logger as l, ensurePrivateDirectorySync as m, hardenPrivateFileSync as n, readDaemonState as o, projectPath as p, clearDaemonState as q, readPersistedSessions as r, streamKeyOf as s, getProjectPath as t, initializeSandbox as u, wrapCommand as v, writePrivateFileSync as w, AsyncLock as x, ensurePrivateDirectory as y, hardenPrivateFile 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.121",
|
|
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.121",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.121",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.121",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.121",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.121",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.121"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|