very-happy-cli 0.2.107 → 0.2.109
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-B3WfHjyi.cjs → AcpBackend-Cc4Ilypg.cjs} +1 -1
- package/dist/{AcpBackend-leZGKCNL.mjs → AcpBackend-DOzPxcth.mjs} +1 -1
- package/dist/{AcpSessionManager-Cza1nTaQ.cjs → AcpSessionManager-CLfzatC_.cjs} +1 -1
- package/dist/{AcpSessionManager-CI_-4TvB.mjs → AcpSessionManager-DDN-Yir4.mjs} +1 -1
- package/dist/{config-CpVncJmR.cjs → config-DiVKfYr0.cjs} +2 -2
- package/dist/{config-TEae6YCF.mjs → config-DnvzvFHR.mjs} +2 -2
- package/dist/{index-RyvQwH4I.cjs → index-B2U15moC.cjs} +2 -2
- package/dist/{index-Dg78JF0h.mjs → index-CGKxZKlo.mjs} +2 -2
- package/dist/{index-b_E_olpx.cjs → index-D2qU5HP4.cjs} +4 -4
- package/dist/{index-CIfhQ_X6.mjs → index-DO-9Ep72.mjs} +181 -89
- package/dist/{index-D9H-dsUT.mjs → index-DaQIcHvY.mjs} +5 -5
- package/dist/{index-CF9-9B70.cjs → index-dd2R8uSE.cjs} +191 -92
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-tPNg8EgD.mjs → installTerminalHooks-BDagPTQW.mjs} +2 -2
- package/dist/{installTerminalHooks-DMSUDPG3.cjs → installTerminalHooks-BoUmuYdq.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-DUXABUpc.mjs → mcp-Ck_y0mCB.mjs} +2 -2
- package/dist/{mcp-B13ZiAxa.cjs → mcp-Du1QEnIf.cjs} +2 -2
- package/dist/{runGemini-aCMjZ4lm.mjs → runGemini-D20S6Lc3.mjs} +4 -4
- package/dist/{runGemini-Dvf_ajZd.cjs → runGemini-DV2M0A_k.cjs} +4 -4
- package/dist/{runOpenClaw-D9v6E9th.cjs → runOpenClaw-C1Q2zl--.cjs} +3 -3
- package/dist/{runOpenClaw-BLdlHdZa.mjs → runOpenClaw-CuuXkfDE.mjs} +3 -3
- package/dist/{send-DUoz9am9.cjs → send-CtgnnJic.cjs} +2 -2
- package/dist/{send-DAnYf1wR.mjs → send-yUiBqHHL.mjs} +2 -2
- package/dist/sessions-BsaCq0Do.mjs +200 -0
- package/dist/sessions-CbbZhOTy.cjs +204 -0
- package/dist/{spawn-Gr4_bY2m.mjs → spawn-BKBY9P3J.mjs} +16 -3
- package/dist/{spawn-4FlGcOQK.cjs → spawn-CTO_hR8v.cjs} +16 -3
- package/dist/{types-DOJq8cyH.mjs → types-BKCvo4Cv.mjs} +8 -8
- package/dist/{types-4iIbK7lA.cjs → types-Cg8zzX_f.cjs} +8 -8
- package/package.json +7 -7
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var node_child_process = require('node:child_process');
|
|
4
4
|
var sdk = require('@agentclientprotocol/sdk');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var persistence = require('./types-
|
|
6
|
+
var persistence = require('./types-Cg8zzX_f.cjs');
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TIMEOUTS = {
|
|
9
9
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { ndJsonStream, ClientSideConnection } from '@agentclientprotocol/sdk';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
|
-
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-
|
|
4
|
+
import { l as logger, d as contentLogMetadata, e as errorLogMetadata, f as packageJson, g as delay } from './types-BKCvo4Cv.mjs';
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIMEOUTS = {
|
|
7
7
|
/** Default initialization timeout: 60 seconds */
|
|
@@ -4,8 +4,8 @@ var fs = require('fs');
|
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var os = require('os');
|
|
6
6
|
var child_process = require('child_process');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
7
|
+
var persistence = require('./types-Cg8zzX_f.cjs');
|
|
8
|
+
var index = require('./index-dd2R8uSE.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('chalk');
|
|
11
11
|
require('node:util');
|
|
@@ -2,8 +2,8 @@ import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { execSync } from 'child_process';
|
|
5
|
-
import { l as logger } from './types-
|
|
6
|
-
import {
|
|
5
|
+
import { l as logger } from './types-BKCvo4Cv.mjs';
|
|
6
|
+
import { f as DEFAULT_GEMINI_MODEL, G as GEMINI_MODEL_ENV } from './index-DO-9Ep72.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'chalk';
|
|
9
9
|
import 'node:util';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-dd2R8uSE.cjs');
|
|
4
4
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
5
5
|
require('chalk');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./types-
|
|
8
|
+
require('./types-Cg8zzX_f.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('node:util');
|
|
11
11
|
require('node:fs');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { q as query } from './index-
|
|
1
|
+
import { q as query } from './index-DO-9Ep72.mjs';
|
|
2
2
|
export { AbortError } from '@anthropic-ai/claude-agent-sdk';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './types-
|
|
6
|
+
import './types-BKCvo4Cv.mjs';
|
|
7
7
|
import 'axios';
|
|
8
8
|
import 'node:util';
|
|
9
9
|
import 'node:fs';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./types-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-Cc4Ilypg.cjs');
|
|
4
|
+
var persistence = require('./types-Cg8zzX_f.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-CLfzatC_.cjs');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var index = require('./index-
|
|
8
|
+
var index = require('./index-dd2R8uSE.cjs');
|
|
9
9
|
require('node:child_process');
|
|
10
10
|
require('@agentclientprotocol/sdk');
|
|
11
11
|
require('axios');
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import chalk from 'chalk';
|
|
2
2
|
import os, { homedir, userInfo } from 'node:os';
|
|
3
3
|
import { randomUUID, randomBytes, createHash as createHash$1, timingSafeEqual } from 'node:crypto';
|
|
4
|
-
import {
|
|
4
|
+
import { o as readDaemonState, l as logger, c as configuration, q as clearDaemonState, s as getProjectPath, p as projectPath, t as initializeSandbox, u as wrapCommand, d as contentLogMetadata, I as InvalidateSync, R as RawJSONLinesSchema, g as delay, v as AsyncLock, x as ensurePrivateDirectory, M as MAX_CHAT_ATTACHMENT_SOURCE_BYTES, y as hardenPrivateFile, f as packageJson, j as readSettings, z as readCredentials, B as credentialRelayProblem, C as deriveLocalCliUpdateSummary, k as encodeBase64, D as updateSettings, E as encodeBase64Url, F as decodeBase64, G as writeCredentialsLegacy, H as writeCredentialsDataKey, J as readCredentialsForConfiguredRelay, K as encrypt, r as readPersistedSessions, L as isClaudeSessionId, N as getLocalHappyAgentCredentialPath, O as readLocalHappyAgentCredentials, P as decryptWithDataKey, Q as decryptLegacy, S as extractCompleteLines, T as decideBackfill, U as parseTerminalHookPayload, V as tmuxArgs, W as scrubTmuxClientEnv, X as decideMirrorBinding, Y as MIRROR_BACKFILL_LINES_DEFAULT, Z as persistSession, _ as mirrorLineKey, $ as mirrorLocalId, w as writePrivateFileSync, a0 as detectResumeSupport, a1 as detectCLIAvailability, a2 as acquireDaemonLock, a3 as summarizeSpawnSessionForLog, a4 as deletePersistedSessions, a5 as shellescape, a6 as decrypt, a7 as writeDaemonState, A as ApiClient, a8 as writeSettings, a9 as fetchCliUpdateState, aa as resolveCliUpdateCheckInterval, ab as DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS, ac as releaseDaemonLock, i as isValidSessionId, ad as listVhTerminals, ae as isValidTerminalId, af as readVhTerminal, ag as sendToVhTerminal, ah as TITLE_PROMPT_PREFIX, ai as BOARD_ANALYZER_PROMPT_PREFIX, h as connectionState, aj as startOfflineReconnection, ak as clearCredentials, al as clearMachineId, m as ensurePrivateDirectorySync, am as SandboxConfigSchema, b as createEnvelope, an as CodexAppServerClient, ao as getLatestDaemonLog } from './types-BKCvo4Cv.mjs';
|
|
5
5
|
import spawn$1, { spawn } from 'cross-spawn';
|
|
6
6
|
import path, { join, resolve, basename, delimiter, isAbsolute, normalize, sep, dirname } from 'node:path';
|
|
7
7
|
import { createInterface } from 'node:readline';
|
|
@@ -4422,16 +4422,23 @@ function claudeModeHash(mode) {
|
|
|
4422
4422
|
});
|
|
4423
4423
|
}
|
|
4424
4424
|
|
|
4425
|
-
|
|
4426
|
-
|
|
4425
|
+
const SPAWN_ORIGIN_TAG_MAX = 24;
|
|
4426
|
+
function spawnOriginTags(env = process.env) {
|
|
4427
4427
|
if (env.HAPPY_SESSION_VARIANT === "assistant") return void 0;
|
|
4428
|
-
|
|
4428
|
+
const origin = (env.HAPPY_SPAWNED_BY ?? "").trim();
|
|
4429
|
+
if (!origin) return void 0;
|
|
4430
|
+
if (origin.length > SPAWN_ORIGIN_TAG_MAX) return void 0;
|
|
4431
|
+
if (!/^[a-z0-9][a-z0-9_-]*$/.test(origin)) return void 0;
|
|
4432
|
+
return [origin];
|
|
4433
|
+
}
|
|
4434
|
+
function isValidSpawnOrigin(value) {
|
|
4435
|
+
return spawnOriginTags({ HAPPY_SPAWNED_BY: value }) !== void 0;
|
|
4429
4436
|
}
|
|
4430
4437
|
function createSessionMetadata(opts) {
|
|
4431
4438
|
const state = {
|
|
4432
4439
|
controlledByUser: false
|
|
4433
4440
|
};
|
|
4434
|
-
const
|
|
4441
|
+
const originTags = spawnOriginTags();
|
|
4435
4442
|
const metadata = {
|
|
4436
4443
|
path: process.cwd(),
|
|
4437
4444
|
host: os.hostname(),
|
|
@@ -4452,10 +4459,10 @@ function createSessionMetadata(opts) {
|
|
|
4452
4459
|
dangerouslySkipPermissions: opts.dangerouslySkipPermissions ?? null,
|
|
4453
4460
|
...opts.parentSessionId ? { parentSessionId: opts.parentSessionId } : {},
|
|
4454
4461
|
...opts.forkedFromMessageId ? { forkedFromMessageId: opts.forkedFromMessageId } : {},
|
|
4455
|
-
// B-091:
|
|
4456
|
-
// birth (see
|
|
4462
|
+
// B-091/B-303: dispatched sessions carry their spawn origin as a tag
|
|
4463
|
+
// from birth (see spawnOriginTags) — applies to every flavor the daemon
|
|
4457
4464
|
// can spawn, since HAPPY_SPAWNED_BY is exported flavor-independently.
|
|
4458
|
-
...
|
|
4465
|
+
...originTags ? { tags: originTags } : {}
|
|
4459
4466
|
};
|
|
4460
4467
|
return { state, metadata };
|
|
4461
4468
|
}
|
|
@@ -9077,6 +9084,12 @@ async function startDaemon() {
|
|
|
9077
9084
|
});
|
|
9078
9085
|
claudeAuthService.start();
|
|
9079
9086
|
apiMachine.connect();
|
|
9087
|
+
if (identityConflict?.confidence === "weak") {
|
|
9088
|
+
void apiMachine.updateMachineMetadata((current) => ({
|
|
9089
|
+
...current ?? initialMachineMetadata,
|
|
9090
|
+
host: initialMachineMetadata.host
|
|
9091
|
+
})).then(() => logger.debug(`[DAEMON RUN] claimed the machine record for host ${initialMachineMetadata.host}`)).catch((error) => logger.debug("[DAEMON RUN] could not refresh the recorded host:", error));
|
|
9092
|
+
}
|
|
9080
9093
|
let cliUpdateCheckRunning = false;
|
|
9081
9094
|
const refreshCliUpdate = async () => {
|
|
9082
9095
|
if (cliUpdateCheckRunning) return;
|
|
@@ -9291,6 +9304,109 @@ function formatTranscript(bodies) {
|
|
|
9291
9304
|
return lines.join("\n");
|
|
9292
9305
|
}
|
|
9293
9306
|
|
|
9307
|
+
const SESSION_OPS_CLIENT = "session-ops";
|
|
9308
|
+
const DEFAULT_RECENT_LIMIT = 15;
|
|
9309
|
+
const MAX_READ_LIMIT = 100;
|
|
9310
|
+
function mergeSessionSummaries(live, persisted, options = {}) {
|
|
9311
|
+
const recentLimit = Math.max(0, options.recentLimit ?? DEFAULT_RECENT_LIMIT);
|
|
9312
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9313
|
+
const summaries = [];
|
|
9314
|
+
for (const child of live) {
|
|
9315
|
+
const id = typeof child.happySessionId === "string" ? child.happySessionId : void 0;
|
|
9316
|
+
if (!id || seen.has(id)) continue;
|
|
9317
|
+
seen.add(id);
|
|
9318
|
+
summaries.push(toSummary(id, persisted[id], {
|
|
9319
|
+
live: true,
|
|
9320
|
+
pid: typeof child.pid === "number" ? child.pid : void 0
|
|
9321
|
+
}));
|
|
9322
|
+
}
|
|
9323
|
+
const rest = Object.entries(persisted).filter(([id]) => !seen.has(id)).filter(([, entry]) => entry.metadata?.flavor !== "terminal-mirror").sort((a, b) => b[1].savedAt - a[1].savedAt).slice(0, recentLimit);
|
|
9324
|
+
for (const [id, entry] of rest) {
|
|
9325
|
+
summaries.push(toSummary(id, entry, { live: false }));
|
|
9326
|
+
}
|
|
9327
|
+
if (!options.tag) return summaries;
|
|
9328
|
+
const wanted = options.tag;
|
|
9329
|
+
return summaries.filter((summary) => summary.tags?.includes(wanted) === true);
|
|
9330
|
+
}
|
|
9331
|
+
function toSummary(id, persisted, extra) {
|
|
9332
|
+
const meta = persisted?.metadata;
|
|
9333
|
+
return {
|
|
9334
|
+
id,
|
|
9335
|
+
live: extra.live,
|
|
9336
|
+
...extra.pid !== void 0 ? { pid: extra.pid } : {},
|
|
9337
|
+
...meta?.summary?.text ? { title: meta.summary.text } : {},
|
|
9338
|
+
...meta?.path ? { cwd: meta.path } : {},
|
|
9339
|
+
...meta?.flavor ? { flavor: meta.flavor } : {},
|
|
9340
|
+
...meta?.tags?.length ? { tags: [...meta.tags] } : {},
|
|
9341
|
+
...meta?.variant ? { variant: meta.variant } : {},
|
|
9342
|
+
url: sessionWebUrl(id),
|
|
9343
|
+
...persisted?.savedAt !== void 0 ? { savedAt: persisted.savedAt } : {}
|
|
9344
|
+
};
|
|
9345
|
+
}
|
|
9346
|
+
async function listSessions(options = {}) {
|
|
9347
|
+
const live = await listDaemonSessions();
|
|
9348
|
+
return mergeSessionSummaries(live, readPersistedSessions(), options);
|
|
9349
|
+
}
|
|
9350
|
+
async function bearerToken() {
|
|
9351
|
+
const credentials = await readCredentialsForConfiguredRelay();
|
|
9352
|
+
if (!credentials) throw new Error("CLI is not authenticated (no ~/.happy/access.key)");
|
|
9353
|
+
return credentials.token;
|
|
9354
|
+
}
|
|
9355
|
+
async function readSessionTranscript(sessionId, limit) {
|
|
9356
|
+
const persisted = readPersistedSessions()[sessionId];
|
|
9357
|
+
if (!persisted) {
|
|
9358
|
+
throw new Error(
|
|
9359
|
+
`No local key for session ${sessionId} \u2014 it was not spawned by this machine's daemon (or is older than 14 days).`
|
|
9360
|
+
);
|
|
9361
|
+
}
|
|
9362
|
+
const bounded = Math.max(1, Math.min(MAX_READ_LIMIT, Math.floor(limit)));
|
|
9363
|
+
const token = await bearerToken();
|
|
9364
|
+
const response = await axios.get(
|
|
9365
|
+
`${configuration.serverUrl}/v3/sessions/${encodeURIComponent(sessionId)}/messages`,
|
|
9366
|
+
{
|
|
9367
|
+
params: { before_seq: 2147483647, limit: bounded },
|
|
9368
|
+
headers: {
|
|
9369
|
+
"Authorization": `Bearer ${token}`,
|
|
9370
|
+
"X-Happy-Client": `${SESSION_OPS_CLIENT}/${configuration.currentCliVersion}`
|
|
9371
|
+
},
|
|
9372
|
+
timeout: 15e3
|
|
9373
|
+
}
|
|
9374
|
+
);
|
|
9375
|
+
const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
|
|
9376
|
+
messages.reverse();
|
|
9377
|
+
const key = decodeBase64(persisted.encryptionKey);
|
|
9378
|
+
const bodies = messages.map((message) => {
|
|
9379
|
+
if (message.content?.t !== "encrypted") return null;
|
|
9380
|
+
try {
|
|
9381
|
+
return decrypt(key, persisted.encryptionVariant, decodeBase64(message.content.c));
|
|
9382
|
+
} catch {
|
|
9383
|
+
return null;
|
|
9384
|
+
}
|
|
9385
|
+
});
|
|
9386
|
+
return {
|
|
9387
|
+
summary: toSummary(sessionId, persisted, { live: false }),
|
|
9388
|
+
messageCount: messages.length,
|
|
9389
|
+
transcript: formatTranscript(bodies)
|
|
9390
|
+
};
|
|
9391
|
+
}
|
|
9392
|
+
async function stopSession(sessionId) {
|
|
9393
|
+
return await stopDaemonSession(sessionId);
|
|
9394
|
+
}
|
|
9395
|
+
async function archiveSession(sessionId) {
|
|
9396
|
+
const token = await bearerToken();
|
|
9397
|
+
await axios.post(
|
|
9398
|
+
`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(sessionId)}/archive`,
|
|
9399
|
+
{},
|
|
9400
|
+
{
|
|
9401
|
+
headers: {
|
|
9402
|
+
"Authorization": `Bearer ${token}`,
|
|
9403
|
+
"X-Happy-Client": `${SESSION_OPS_CLIENT}/${configuration.currentCliVersion}`
|
|
9404
|
+
},
|
|
9405
|
+
timeout: 1e4
|
|
9406
|
+
}
|
|
9407
|
+
);
|
|
9408
|
+
}
|
|
9409
|
+
|
|
9294
9410
|
const PERSONAL_MEMORY_SOFT_LIMIT_CHARS = 2e3;
|
|
9295
9411
|
function headingTitle(line) {
|
|
9296
9412
|
const m = /^##(?!#)\s*(.*?)\s*$/.exec(line);
|
|
@@ -9387,19 +9503,24 @@ function fail(text) {
|
|
|
9387
9503
|
function describeSession(id, persisted, extra) {
|
|
9388
9504
|
const meta = persisted?.metadata;
|
|
9389
9505
|
const parts = [id];
|
|
9390
|
-
if (extra?.live !== void 0) parts.push(extra.live ? "[running]" : "[not running]");
|
|
9391
9506
|
if (meta?.summary?.text) parts.push(`title="${meta.summary.text}"`);
|
|
9392
9507
|
if (meta?.path) parts.push(`cwd=${meta.path}`);
|
|
9393
9508
|
if (meta?.flavor) parts.push(`agent=${meta.flavor}`);
|
|
9509
|
+
if (meta?.tags?.length) parts.push(`tags=${meta.tags.join(",")}`);
|
|
9394
9510
|
if (meta?.variant === "assistant") parts.push("(assistant)");
|
|
9395
|
-
if (extra?.pid) parts.push(`pid=${extra.pid}`);
|
|
9396
9511
|
parts.push(sessionWebUrl(id));
|
|
9397
9512
|
return parts.join(" ");
|
|
9398
9513
|
}
|
|
9399
|
-
|
|
9400
|
-
const
|
|
9401
|
-
if (
|
|
9402
|
-
|
|
9514
|
+
function describeSummary(summary) {
|
|
9515
|
+
const parts = [summary.id, summary.live ? "[running]" : "[not running]"];
|
|
9516
|
+
if (summary.title) parts.push(`title="${summary.title}"`);
|
|
9517
|
+
if (summary.cwd) parts.push(`cwd=${summary.cwd}`);
|
|
9518
|
+
if (summary.flavor) parts.push(`agent=${summary.flavor}`);
|
|
9519
|
+
if (summary.tags?.length) parts.push(`tags=${summary.tags.join(",")}`);
|
|
9520
|
+
if (summary.variant === "assistant") parts.push("(assistant)");
|
|
9521
|
+
if (summary.pid !== void 0) parts.push(`pid=${summary.pid}`);
|
|
9522
|
+
parts.push(summary.url);
|
|
9523
|
+
return parts.join(" ");
|
|
9403
9524
|
}
|
|
9404
9525
|
function registerAssistantTools(mcp) {
|
|
9405
9526
|
mcp.registerTool("sessions_list", {
|
|
@@ -9408,22 +9529,10 @@ function registerAssistantTools(mcp) {
|
|
|
9408
9529
|
inputSchema: {}
|
|
9409
9530
|
}, async () => {
|
|
9410
9531
|
try {
|
|
9411
|
-
const
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
for (const child of live) {
|
|
9416
|
-
const id = child.happySessionId;
|
|
9417
|
-
seen.add(id);
|
|
9418
|
-
lines.push(describeSession(id, persisted[id], { pid: child.pid, live: true }));
|
|
9419
|
-
}
|
|
9420
|
-
const rest = Object.entries(persisted).filter(([id]) => !seen.has(id)).filter(([, entry]) => entry.metadata?.flavor !== "terminal-mirror").sort((a, b) => b[1].savedAt - a[1].savedAt).slice(0, 15);
|
|
9421
|
-
for (const [id, entry] of rest) {
|
|
9422
|
-
lines.push(describeSession(id, entry, { live: false }));
|
|
9423
|
-
}
|
|
9424
|
-
if (lines.length === 0) return ok("No sessions found on this machine.");
|
|
9425
|
-
return ok(`${lines.length} session(s):
|
|
9426
|
-
${lines.join("\n")}`);
|
|
9532
|
+
const sessions = await listSessions();
|
|
9533
|
+
if (sessions.length === 0) return ok("No sessions found on this machine.");
|
|
9534
|
+
return ok(`${sessions.length} session(s):
|
|
9535
|
+
${sessions.map(describeSummary).join("\n")}`);
|
|
9427
9536
|
} catch (error) {
|
|
9428
9537
|
return fail(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`);
|
|
9429
9538
|
}
|
|
@@ -9437,37 +9546,12 @@ ${lines.join("\n")}`);
|
|
|
9437
9546
|
}
|
|
9438
9547
|
}, async (args) => {
|
|
9439
9548
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9440
|
-
const limit = Math.max(1, Math.min(100, Math.floor(args.limit ?? 20)));
|
|
9441
9549
|
try {
|
|
9442
|
-
const
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
const response = await axios.get(
|
|
9448
|
-
`${configuration.serverUrl}/v3/sessions/${encodeURIComponent(args.sessionId)}/messages`,
|
|
9449
|
-
{
|
|
9450
|
-
params: { before_seq: 2147483647, limit },
|
|
9451
|
-
headers: { "Authorization": `Bearer ${token}`, "X-Happy-Client": `${MCP_CLIENT_TAG}/${configuration.currentCliVersion}` },
|
|
9452
|
-
timeout: 15e3
|
|
9453
|
-
}
|
|
9454
|
-
);
|
|
9455
|
-
const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
|
|
9456
|
-
messages.reverse();
|
|
9457
|
-
const key = decodeBase64(persisted.encryptionKey);
|
|
9458
|
-
const bodies = messages.map((m) => {
|
|
9459
|
-
if (m.content?.t !== "encrypted") return null;
|
|
9460
|
-
try {
|
|
9461
|
-
return decrypt(key, persisted.encryptionVariant, decodeBase64(m.content.c));
|
|
9462
|
-
} catch {
|
|
9463
|
-
return null;
|
|
9464
|
-
}
|
|
9465
|
-
});
|
|
9466
|
-
const transcript = formatTranscript(bodies);
|
|
9467
|
-
const header = describeSession(args.sessionId, persisted);
|
|
9468
|
-
return ok(`${header}
|
|
9469
|
-
--- last ${messages.length} message(s) ---
|
|
9470
|
-
${transcript.length > 0 ? transcript : "(no readable conversation content in this range)"}`);
|
|
9550
|
+
const result = await readSessionTranscript(args.sessionId, args.limit ?? 20);
|
|
9551
|
+
const body = result.transcript.length > 0 ? result.transcript : "(no readable conversation content in this range)";
|
|
9552
|
+
return ok(`${describeSummary(result.summary)}
|
|
9553
|
+
--- last ${result.messageCount} message(s) ---
|
|
9554
|
+
${body}`);
|
|
9471
9555
|
} catch (error) {
|
|
9472
9556
|
return fail(`Failed to read session: ${error instanceof Error ? error.message : String(error)}`);
|
|
9473
9557
|
}
|
|
@@ -9532,7 +9616,7 @@ ${transcript.length > 0 ? transcript : "(no readable conversation content in thi
|
|
|
9532
9616
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9533
9617
|
try {
|
|
9534
9618
|
const persisted = readPersistedSessions()[args.sessionId];
|
|
9535
|
-
const success = await
|
|
9619
|
+
const success = await stopSession(args.sessionId);
|
|
9536
9620
|
if (!success) return fail(`Session ${args.sessionId} was not found among the daemon's running sessions.`);
|
|
9537
9621
|
return ok(`Stopped ${describeSession(args.sessionId, persisted)}`);
|
|
9538
9622
|
} catch (error) {
|
|
@@ -9548,15 +9632,7 @@ ${transcript.length > 0 ? transcript : "(no readable conversation content in thi
|
|
|
9548
9632
|
}, async (args) => {
|
|
9549
9633
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9550
9634
|
try {
|
|
9551
|
-
|
|
9552
|
-
await axios.post(
|
|
9553
|
-
`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(args.sessionId)}/archive`,
|
|
9554
|
-
{},
|
|
9555
|
-
{
|
|
9556
|
-
headers: { "Authorization": `Bearer ${token}`, "X-Happy-Client": `${MCP_CLIENT_TAG}/${configuration.currentCliVersion}` },
|
|
9557
|
-
timeout: 1e4
|
|
9558
|
-
}
|
|
9559
|
-
);
|
|
9635
|
+
await archiveSession(args.sessionId);
|
|
9560
9636
|
const persisted = readPersistedSessions()[args.sessionId];
|
|
9561
9637
|
return ok(`Archived ${describeSession(args.sessionId, persisted)}`);
|
|
9562
9638
|
} catch (error) {
|
|
@@ -10232,7 +10308,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
10232
10308
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
10233
10309
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
10234
10310
|
const run = deps.run ?? (async (input) => {
|
|
10235
|
-
const { query } = await import('./index-
|
|
10311
|
+
const { query } = await import('./index-CGKxZKlo.mjs');
|
|
10236
10312
|
return runSideQuestion(query, input);
|
|
10237
10313
|
});
|
|
10238
10314
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -10772,6 +10848,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
10772
10848
|
const forkedFromMessageId = process.env.HAPPY_FORKED_FROM_MESSAGE_ID;
|
|
10773
10849
|
const importedFromClaudeSessionId = process.env.HAPPY_IMPORTED_FROM_CLAUDE_SESSION_ID;
|
|
10774
10850
|
const importTitle = process.env.HAPPY_IMPORT_TITLE;
|
|
10851
|
+
const originTags = spawnOriginTags();
|
|
10775
10852
|
let metadata = {
|
|
10776
10853
|
path: workingDirectory,
|
|
10777
10854
|
host: os.hostname(),
|
|
@@ -10804,12 +10881,13 @@ async function runClaude(credentials, options = {}) {
|
|
|
10804
10881
|
...importedFromClaudeSessionId ? { importedFromClaudeSessionId } : {},
|
|
10805
10882
|
...importTitle ? { summary: { text: importTitle, updatedAt: Date.now() } } : {},
|
|
10806
10883
|
...isAssistantVariant ? { variant: "assistant" } : {},
|
|
10807
|
-
// B-091: sessions
|
|
10808
|
-
// HAPPY_SPAWNED_BY, B-069) are born with
|
|
10809
|
-
// list shows
|
|
10810
|
-
// the variant above and never joins the lists at
|
|
10811
|
-
// the other flavors get the same tag via
|
|
10812
|
-
|
|
10884
|
+
// B-091/B-303: dispatched sessions (daemon spawn RPC exports
|
|
10885
|
+
// HAPPY_SPAWNED_BY, B-069) are born tagged with their spawn origin so
|
|
10886
|
+
// every list shows where the work came from. NOT on the meta-agent
|
|
10887
|
+
// itself — that one is the variant above and never joins the lists at
|
|
10888
|
+
// all. (Shared helper: the other flavors get the same tag via
|
|
10889
|
+
// createSessionMetadata.)
|
|
10890
|
+
...originTags ? { tags: originTags } : {}
|
|
10813
10891
|
};
|
|
10814
10892
|
const reconnectSessionId = process.env.HAPPY_RECONNECT_SESSION_ID;
|
|
10815
10893
|
const reconnectKeyBase64 = process.env.HAPPY_RECONNECT_ENCRYPTION_KEY;
|
|
@@ -15160,7 +15238,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15160
15238
|
process.exit(0);
|
|
15161
15239
|
} else if (subcommand === "install-terminal-hooks") {
|
|
15162
15240
|
try {
|
|
15163
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
15241
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BDagPTQW.mjs');
|
|
15164
15242
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
15165
15243
|
if (command.action === "help") {
|
|
15166
15244
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -15177,7 +15255,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15177
15255
|
}
|
|
15178
15256
|
} else if (subcommand === "spawn") {
|
|
15179
15257
|
try {
|
|
15180
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
15258
|
+
const { handleSpawnCommand } = await import('./spawn-BKBY9P3J.mjs');
|
|
15181
15259
|
await handleSpawnCommand(args.slice(1));
|
|
15182
15260
|
} catch (error) {
|
|
15183
15261
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -15187,9 +15265,21 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15187
15265
|
process.exit(1);
|
|
15188
15266
|
}
|
|
15189
15267
|
return;
|
|
15268
|
+
} else if (subcommand === "sessions") {
|
|
15269
|
+
try {
|
|
15270
|
+
const { handleSessionsCommand } = await import('./sessions-BsaCq0Do.mjs');
|
|
15271
|
+
await handleSessionsCommand(args.slice(1));
|
|
15272
|
+
} catch (error) {
|
|
15273
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
15274
|
+
if (process.env.DEBUG) {
|
|
15275
|
+
console.error(error);
|
|
15276
|
+
}
|
|
15277
|
+
process.exit(1);
|
|
15278
|
+
}
|
|
15279
|
+
return;
|
|
15190
15280
|
} else if (subcommand === "send") {
|
|
15191
15281
|
try {
|
|
15192
|
-
const { handleSendCommand } = await import('./send-
|
|
15282
|
+
const { handleSendCommand } = await import('./send-yUiBqHHL.mjs');
|
|
15193
15283
|
await handleSendCommand(args.slice(1));
|
|
15194
15284
|
} catch (error) {
|
|
15195
15285
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -15295,9 +15385,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15295
15385
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
15296
15386
|
const projectId = args[3];
|
|
15297
15387
|
try {
|
|
15298
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
15299
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
15300
|
-
const { ApiClient: ApiClient2 } = await import('./types-
|
|
15388
|
+
const { saveGoogleCloudProjectToConfig } = await import('./config-DnvzvFHR.mjs');
|
|
15389
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-BKCvo4Cv.mjs').then(function (n) { return n.ap; });
|
|
15390
|
+
const { ApiClient: ApiClient2 } = await import('./types-BKCvo4Cv.mjs').then(function (n) { return n.aq; });
|
|
15301
15391
|
let userEmail = void 0;
|
|
15302
15392
|
try {
|
|
15303
15393
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -15328,7 +15418,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15328
15418
|
}
|
|
15329
15419
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
15330
15420
|
try {
|
|
15331
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
15421
|
+
const { readGeminiLocalConfig } = await import('./config-DnvzvFHR.mjs');
|
|
15332
15422
|
const config = readGeminiLocalConfig();
|
|
15333
15423
|
if (config.googleCloudProject) {
|
|
15334
15424
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -15368,7 +15458,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15368
15458
|
process.exit(0);
|
|
15369
15459
|
}
|
|
15370
15460
|
try {
|
|
15371
|
-
const { runGemini } = await import('./runGemini-
|
|
15461
|
+
const { runGemini } = await import('./runGemini-D20S6Lc3.mjs');
|
|
15372
15462
|
let startedBy = void 0;
|
|
15373
15463
|
for (let i = 1; i < args.length; i++) {
|
|
15374
15464
|
if (args[i] === "--started-by") {
|
|
@@ -15390,7 +15480,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15390
15480
|
return;
|
|
15391
15481
|
} else if (subcommand === "acp") {
|
|
15392
15482
|
try {
|
|
15393
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
15483
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-DaQIcHvY.mjs');
|
|
15394
15484
|
let startedBy = void 0;
|
|
15395
15485
|
let verbose = false;
|
|
15396
15486
|
const acpArgs = [];
|
|
@@ -15430,7 +15520,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15430
15520
|
return;
|
|
15431
15521
|
} else if (subcommand === "openclaw") {
|
|
15432
15522
|
try {
|
|
15433
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
15523
|
+
const { runOpenClaw } = await import('./runOpenClaw-CuuXkfDE.mjs');
|
|
15434
15524
|
let startedBy = void 0;
|
|
15435
15525
|
let verbose = false;
|
|
15436
15526
|
let gatewayUrl;
|
|
@@ -15481,7 +15571,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15481
15571
|
return;
|
|
15482
15572
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
15483
15573
|
try {
|
|
15484
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
15574
|
+
const { handleMcpCommand } = await import('./mcp-Ck_y0mCB.mjs');
|
|
15485
15575
|
await handleMcpCommand();
|
|
15486
15576
|
} catch (error) {
|
|
15487
15577
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -15696,6 +15786,8 @@ ${chalk.bold("Usage:")}
|
|
|
15696
15786
|
print its web URL (for automation; see spawn --help)
|
|
15697
15787
|
very-happy send Send a message into an existing session
|
|
15698
15788
|
(for automation; see send --help)
|
|
15789
|
+
very-happy sessions List, read, stop or archive sessions on this
|
|
15790
|
+
machine (for automation; see sessions --help)
|
|
15699
15791
|
very-happy codex Start Codex mode
|
|
15700
15792
|
very-happy gemini Start Gemini mode (ACP)
|
|
15701
15793
|
very-happy acp Start a generic ACP-compatible agent
|
|
@@ -15837,4 +15929,4 @@ ${chalk.bold("Examples:")}
|
|
|
15837
15929
|
}
|
|
15838
15930
|
}
|
|
15839
15931
|
|
|
15840
|
-
export { BasePermissionHandler as B, CHANGE_TITLE_INSTRUCTION as C,
|
|
15932
|
+
export { BasePermissionHandler as B, CHANGE_TITLE_INSTRUCTION as C, DEFAULT_RECENT_LIMIT as D, GEMINI_MODEL_ENV as G, MAX_READ_LIMIT as M, sessionWebUrl as a, sendUserMessage as b, checkIfDaemonRunningAndCleanupStaleState as c, stopSession as d, archiveSession as e, DEFAULT_GEMINI_MODEL as f, initialMachineMetadata as g, createSessionMetadata as h, isValidSpawnOrigin as i, setupOfflineReconnection as j, MessageQueue2 as k, listSessions as l, hashObject as m, notifyDaemonSessionStarted as n, startHappyServer as o, pushClipboardViaDaemon as p, query as q, readSessionTranscript as r, spawnDaemonSession as s, tmuxSupportsSessionEnv as t, registerKillSessionHandler as u, GEMINI_API_KEY_ENV as v, waitForSessionKey as w, GOOGLE_API_KEY_ENV as x, BaseReasoningProcessor as y, MessageBuffer as z };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-
|
|
2
|
-
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-
|
|
3
|
-
import { h as connectionState, A as ApiClient,
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-DOzPxcth.mjs';
|
|
2
|
+
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-DOzPxcth.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-BKCvo4Cv.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-DDN-Yir4.mjs';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { g as initialMachineMetadata, h as createSessionMetadata, j as setupOfflineReconnection, n as notifyDaemonSessionStarted, k as MessageQueue2, m as hashObject, o as startHappyServer, u as registerKillSessionHandler, B as BasePermissionHandler } from './index-DO-9Ep72.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|