very-happy-cli 0.2.108 → 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-D4vV6SVl.cjs → AcpBackend-Cc4Ilypg.cjs} +1 -1
- package/dist/{AcpBackend-DwR8rrkS.mjs → AcpBackend-DOzPxcth.mjs} +1 -1
- package/dist/{AcpSessionManager-CPHDZ-nz.cjs → AcpSessionManager-CLfzatC_.cjs} +1 -1
- package/dist/{AcpSessionManager-C057dkLF.mjs → AcpSessionManager-DDN-Yir4.mjs} +1 -1
- package/dist/{config-BvVwprR0.cjs → config-DiVKfYr0.cjs} +2 -2
- package/dist/{config-DKMwLc1k.mjs → config-DnvzvFHR.mjs} +2 -2
- package/dist/{index-C7N-ONU_.cjs → index-B2U15moC.cjs} +2 -2
- package/dist/{index-DYY1DUOD.mjs → index-CGKxZKlo.mjs} +2 -2
- package/dist/{index-Db5m34eh.cjs → index-D2qU5HP4.cjs} +4 -4
- package/dist/{index-CzSv4d_S.mjs → index-DO-9Ep72.mjs} +175 -89
- package/dist/{index-BXnHT-Wu.mjs → index-DaQIcHvY.mjs} +5 -5
- package/dist/{index-DM0Ku1Rv.cjs → index-dd2R8uSE.cjs} +185 -92
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-Cs49gg_E.mjs → installTerminalHooks-BDagPTQW.mjs} +2 -2
- package/dist/{installTerminalHooks-BpvWmkZ9.cjs → installTerminalHooks-BoUmuYdq.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-DY17lhMH.mjs → mcp-Ck_y0mCB.mjs} +2 -2
- package/dist/{mcp-rTSmj-tn.cjs → mcp-Du1QEnIf.cjs} +2 -2
- package/dist/{runGemini-Bqs52hw_.mjs → runGemini-D20S6Lc3.mjs} +4 -4
- package/dist/{runGemini-B3Mme1zr.cjs → runGemini-DV2M0A_k.cjs} +4 -4
- package/dist/{runOpenClaw-B2V9j9Le.cjs → runOpenClaw-C1Q2zl--.cjs} +3 -3
- package/dist/{runOpenClaw-CpbsQ7NZ.mjs → runOpenClaw-CuuXkfDE.mjs} +3 -3
- package/dist/{send-CLdMBQ8e.cjs → send-CtgnnJic.cjs} +2 -2
- package/dist/{send-uHgpvIqm.mjs → send-yUiBqHHL.mjs} +2 -2
- package/dist/sessions-BsaCq0Do.mjs +200 -0
- package/dist/sessions-CbbZhOTy.cjs +204 -0
- package/dist/{spawn-Dt4ujmHH.mjs → spawn-BKBY9P3J.mjs} +16 -3
- package/dist/{spawn-BXbVzbMs.cjs → spawn-CTO_hR8v.cjs} +16 -3
- package/dist/{types-D0-nhvuW.mjs → types-BKCvo4Cv.mjs} +8 -8
- package/dist/{types-D4bwyM-D.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
|
}
|
|
@@ -9297,6 +9304,109 @@ function formatTranscript(bodies) {
|
|
|
9297
9304
|
return lines.join("\n");
|
|
9298
9305
|
}
|
|
9299
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
|
+
|
|
9300
9410
|
const PERSONAL_MEMORY_SOFT_LIMIT_CHARS = 2e3;
|
|
9301
9411
|
function headingTitle(line) {
|
|
9302
9412
|
const m = /^##(?!#)\s*(.*?)\s*$/.exec(line);
|
|
@@ -9393,19 +9503,24 @@ function fail(text) {
|
|
|
9393
9503
|
function describeSession(id, persisted, extra) {
|
|
9394
9504
|
const meta = persisted?.metadata;
|
|
9395
9505
|
const parts = [id];
|
|
9396
|
-
if (extra?.live !== void 0) parts.push(extra.live ? "[running]" : "[not running]");
|
|
9397
9506
|
if (meta?.summary?.text) parts.push(`title="${meta.summary.text}"`);
|
|
9398
9507
|
if (meta?.path) parts.push(`cwd=${meta.path}`);
|
|
9399
9508
|
if (meta?.flavor) parts.push(`agent=${meta.flavor}`);
|
|
9509
|
+
if (meta?.tags?.length) parts.push(`tags=${meta.tags.join(",")}`);
|
|
9400
9510
|
if (meta?.variant === "assistant") parts.push("(assistant)");
|
|
9401
|
-
if (extra?.pid) parts.push(`pid=${extra.pid}`);
|
|
9402
9511
|
parts.push(sessionWebUrl(id));
|
|
9403
9512
|
return parts.join(" ");
|
|
9404
9513
|
}
|
|
9405
|
-
|
|
9406
|
-
const
|
|
9407
|
-
if (
|
|
9408
|
-
|
|
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(" ");
|
|
9409
9524
|
}
|
|
9410
9525
|
function registerAssistantTools(mcp) {
|
|
9411
9526
|
mcp.registerTool("sessions_list", {
|
|
@@ -9414,22 +9529,10 @@ function registerAssistantTools(mcp) {
|
|
|
9414
9529
|
inputSchema: {}
|
|
9415
9530
|
}, async () => {
|
|
9416
9531
|
try {
|
|
9417
|
-
const
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
for (const child of live) {
|
|
9422
|
-
const id = child.happySessionId;
|
|
9423
|
-
seen.add(id);
|
|
9424
|
-
lines.push(describeSession(id, persisted[id], { pid: child.pid, live: true }));
|
|
9425
|
-
}
|
|
9426
|
-
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);
|
|
9427
|
-
for (const [id, entry] of rest) {
|
|
9428
|
-
lines.push(describeSession(id, entry, { live: false }));
|
|
9429
|
-
}
|
|
9430
|
-
if (lines.length === 0) return ok("No sessions found on this machine.");
|
|
9431
|
-
return ok(`${lines.length} session(s):
|
|
9432
|
-
${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")}`);
|
|
9433
9536
|
} catch (error) {
|
|
9434
9537
|
return fail(`Failed to list sessions: ${error instanceof Error ? error.message : String(error)}`);
|
|
9435
9538
|
}
|
|
@@ -9443,37 +9546,12 @@ ${lines.join("\n")}`);
|
|
|
9443
9546
|
}
|
|
9444
9547
|
}, async (args) => {
|
|
9445
9548
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9446
|
-
const limit = Math.max(1, Math.min(100, Math.floor(args.limit ?? 20)));
|
|
9447
9549
|
try {
|
|
9448
|
-
const
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
const response = await axios.get(
|
|
9454
|
-
`${configuration.serverUrl}/v3/sessions/${encodeURIComponent(args.sessionId)}/messages`,
|
|
9455
|
-
{
|
|
9456
|
-
params: { before_seq: 2147483647, limit },
|
|
9457
|
-
headers: { "Authorization": `Bearer ${token}`, "X-Happy-Client": `${MCP_CLIENT_TAG}/${configuration.currentCliVersion}` },
|
|
9458
|
-
timeout: 15e3
|
|
9459
|
-
}
|
|
9460
|
-
);
|
|
9461
|
-
const messages = Array.isArray(response.data?.messages) ? response.data.messages : [];
|
|
9462
|
-
messages.reverse();
|
|
9463
|
-
const key = decodeBase64(persisted.encryptionKey);
|
|
9464
|
-
const bodies = messages.map((m) => {
|
|
9465
|
-
if (m.content?.t !== "encrypted") return null;
|
|
9466
|
-
try {
|
|
9467
|
-
return decrypt(key, persisted.encryptionVariant, decodeBase64(m.content.c));
|
|
9468
|
-
} catch {
|
|
9469
|
-
return null;
|
|
9470
|
-
}
|
|
9471
|
-
});
|
|
9472
|
-
const transcript = formatTranscript(bodies);
|
|
9473
|
-
const header = describeSession(args.sessionId, persisted);
|
|
9474
|
-
return ok(`${header}
|
|
9475
|
-
--- last ${messages.length} message(s) ---
|
|
9476
|
-
${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}`);
|
|
9477
9555
|
} catch (error) {
|
|
9478
9556
|
return fail(`Failed to read session: ${error instanceof Error ? error.message : String(error)}`);
|
|
9479
9557
|
}
|
|
@@ -9538,7 +9616,7 @@ ${transcript.length > 0 ? transcript : "(no readable conversation content in thi
|
|
|
9538
9616
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9539
9617
|
try {
|
|
9540
9618
|
const persisted = readPersistedSessions()[args.sessionId];
|
|
9541
|
-
const success = await
|
|
9619
|
+
const success = await stopSession(args.sessionId);
|
|
9542
9620
|
if (!success) return fail(`Session ${args.sessionId} was not found among the daemon's running sessions.`);
|
|
9543
9621
|
return ok(`Stopped ${describeSession(args.sessionId, persisted)}`);
|
|
9544
9622
|
} catch (error) {
|
|
@@ -9554,15 +9632,7 @@ ${transcript.length > 0 ? transcript : "(no readable conversation content in thi
|
|
|
9554
9632
|
}, async (args) => {
|
|
9555
9633
|
if (!isValidSessionId(args.sessionId)) return fail("Invalid sessionId");
|
|
9556
9634
|
try {
|
|
9557
|
-
|
|
9558
|
-
await axios.post(
|
|
9559
|
-
`${configuration.serverUrl}/v1/sessions/${encodeURIComponent(args.sessionId)}/archive`,
|
|
9560
|
-
{},
|
|
9561
|
-
{
|
|
9562
|
-
headers: { "Authorization": `Bearer ${token}`, "X-Happy-Client": `${MCP_CLIENT_TAG}/${configuration.currentCliVersion}` },
|
|
9563
|
-
timeout: 1e4
|
|
9564
|
-
}
|
|
9565
|
-
);
|
|
9635
|
+
await archiveSession(args.sessionId);
|
|
9566
9636
|
const persisted = readPersistedSessions()[args.sessionId];
|
|
9567
9637
|
return ok(`Archived ${describeSession(args.sessionId, persisted)}`);
|
|
9568
9638
|
} catch (error) {
|
|
@@ -10238,7 +10308,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
10238
10308
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
10239
10309
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
10240
10310
|
const run = deps.run ?? (async (input) => {
|
|
10241
|
-
const { query } = await import('./index-
|
|
10311
|
+
const { query } = await import('./index-CGKxZKlo.mjs');
|
|
10242
10312
|
return runSideQuestion(query, input);
|
|
10243
10313
|
});
|
|
10244
10314
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -10778,6 +10848,7 @@ async function runClaude(credentials, options = {}) {
|
|
|
10778
10848
|
const forkedFromMessageId = process.env.HAPPY_FORKED_FROM_MESSAGE_ID;
|
|
10779
10849
|
const importedFromClaudeSessionId = process.env.HAPPY_IMPORTED_FROM_CLAUDE_SESSION_ID;
|
|
10780
10850
|
const importTitle = process.env.HAPPY_IMPORT_TITLE;
|
|
10851
|
+
const originTags = spawnOriginTags();
|
|
10781
10852
|
let metadata = {
|
|
10782
10853
|
path: workingDirectory,
|
|
10783
10854
|
host: os.hostname(),
|
|
@@ -10810,12 +10881,13 @@ async function runClaude(credentials, options = {}) {
|
|
|
10810
10881
|
...importedFromClaudeSessionId ? { importedFromClaudeSessionId } : {},
|
|
10811
10882
|
...importTitle ? { summary: { text: importTitle, updatedAt: Date.now() } } : {},
|
|
10812
10883
|
...isAssistantVariant ? { variant: "assistant" } : {},
|
|
10813
|
-
// B-091: sessions
|
|
10814
|
-
// HAPPY_SPAWNED_BY, B-069) are born with
|
|
10815
|
-
// list shows
|
|
10816
|
-
// the variant above and never joins the lists at
|
|
10817
|
-
// the other flavors get the same tag via
|
|
10818
|
-
|
|
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 } : {}
|
|
10819
10891
|
};
|
|
10820
10892
|
const reconnectSessionId = process.env.HAPPY_RECONNECT_SESSION_ID;
|
|
10821
10893
|
const reconnectKeyBase64 = process.env.HAPPY_RECONNECT_ENCRYPTION_KEY;
|
|
@@ -15166,7 +15238,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15166
15238
|
process.exit(0);
|
|
15167
15239
|
} else if (subcommand === "install-terminal-hooks") {
|
|
15168
15240
|
try {
|
|
15169
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-
|
|
15241
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await import('./installTerminalHooks-BDagPTQW.mjs');
|
|
15170
15242
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
15171
15243
|
if (command.action === "help") {
|
|
15172
15244
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -15183,7 +15255,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15183
15255
|
}
|
|
15184
15256
|
} else if (subcommand === "spawn") {
|
|
15185
15257
|
try {
|
|
15186
|
-
const { handleSpawnCommand } = await import('./spawn-
|
|
15258
|
+
const { handleSpawnCommand } = await import('./spawn-BKBY9P3J.mjs');
|
|
15187
15259
|
await handleSpawnCommand(args.slice(1));
|
|
15188
15260
|
} catch (error) {
|
|
15189
15261
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -15193,9 +15265,21 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15193
15265
|
process.exit(1);
|
|
15194
15266
|
}
|
|
15195
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;
|
|
15196
15280
|
} else if (subcommand === "send") {
|
|
15197
15281
|
try {
|
|
15198
|
-
const { handleSendCommand } = await import('./send-
|
|
15282
|
+
const { handleSendCommand } = await import('./send-yUiBqHHL.mjs');
|
|
15199
15283
|
await handleSendCommand(args.slice(1));
|
|
15200
15284
|
} catch (error) {
|
|
15201
15285
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -15301,9 +15385,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15301
15385
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
15302
15386
|
const projectId = args[3];
|
|
15303
15387
|
try {
|
|
15304
|
-
const { saveGoogleCloudProjectToConfig } = await import('./config-
|
|
15305
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await import('./types-
|
|
15306
|
-
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; });
|
|
15307
15391
|
let userEmail = void 0;
|
|
15308
15392
|
try {
|
|
15309
15393
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -15334,7 +15418,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15334
15418
|
}
|
|
15335
15419
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
15336
15420
|
try {
|
|
15337
|
-
const { readGeminiLocalConfig } = await import('./config-
|
|
15421
|
+
const { readGeminiLocalConfig } = await import('./config-DnvzvFHR.mjs');
|
|
15338
15422
|
const config = readGeminiLocalConfig();
|
|
15339
15423
|
if (config.googleCloudProject) {
|
|
15340
15424
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -15374,7 +15458,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15374
15458
|
process.exit(0);
|
|
15375
15459
|
}
|
|
15376
15460
|
try {
|
|
15377
|
-
const { runGemini } = await import('./runGemini-
|
|
15461
|
+
const { runGemini } = await import('./runGemini-D20S6Lc3.mjs');
|
|
15378
15462
|
let startedBy = void 0;
|
|
15379
15463
|
for (let i = 1; i < args.length; i++) {
|
|
15380
15464
|
if (args[i] === "--started-by") {
|
|
@@ -15396,7 +15480,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15396
15480
|
return;
|
|
15397
15481
|
} else if (subcommand === "acp") {
|
|
15398
15482
|
try {
|
|
15399
|
-
const { runAcp, resolveAcpAgentConfig } = await import('./index-
|
|
15483
|
+
const { runAcp, resolveAcpAgentConfig } = await import('./index-DaQIcHvY.mjs');
|
|
15400
15484
|
let startedBy = void 0;
|
|
15401
15485
|
let verbose = false;
|
|
15402
15486
|
const acpArgs = [];
|
|
@@ -15436,7 +15520,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15436
15520
|
return;
|
|
15437
15521
|
} else if (subcommand === "openclaw") {
|
|
15438
15522
|
try {
|
|
15439
|
-
const { runOpenClaw } = await import('./runOpenClaw-
|
|
15523
|
+
const { runOpenClaw } = await import('./runOpenClaw-CuuXkfDE.mjs');
|
|
15440
15524
|
let startedBy = void 0;
|
|
15441
15525
|
let verbose = false;
|
|
15442
15526
|
let gatewayUrl;
|
|
@@ -15487,7 +15571,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
15487
15571
|
return;
|
|
15488
15572
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
15489
15573
|
try {
|
|
15490
|
-
const { handleMcpCommand } = await import('./mcp-
|
|
15574
|
+
const { handleMcpCommand } = await import('./mcp-Ck_y0mCB.mjs');
|
|
15491
15575
|
await handleMcpCommand();
|
|
15492
15576
|
} catch (error) {
|
|
15493
15577
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -15702,6 +15786,8 @@ ${chalk.bold("Usage:")}
|
|
|
15702
15786
|
print its web URL (for automation; see spawn --help)
|
|
15703
15787
|
very-happy send Send a message into an existing session
|
|
15704
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)
|
|
15705
15791
|
very-happy codex Start Codex mode
|
|
15706
15792
|
very-happy gemini Start Gemini mode (ACP)
|
|
15707
15793
|
very-happy acp Start a generic ACP-compatible agent
|
|
@@ -15843,4 +15929,4 @@ ${chalk.bold("Examples:")}
|
|
|
15843
15929
|
}
|
|
15844
15930
|
}
|
|
15845
15931
|
|
|
15846
|
-
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';
|