very-happy-cli 0.2.133 → 0.2.135
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-DgG8o4jd.cjs → AcpBackend-C0Bwx6bc.cjs} +3 -3
- package/dist/{AcpBackend-BQm7dNza.mjs → AcpBackend-CkDpu1n_.mjs} +3 -3
- package/dist/{AcpSessionManager-C7unPEZO.mjs → AcpSessionManager-DB_mfFaH.mjs} +1 -1
- package/dist/{AcpSessionManager-DDFEmhQp.cjs → AcpSessionManager-DqvUp-UU.cjs} +1 -1
- package/dist/{agentGuidance-BaplwDcV.mjs → agentGuidance-7MByWxKj.mjs} +1 -1
- package/dist/{agentGuidance-BItqIZTf.cjs → agentGuidance-DlZM_YPV.cjs} +1 -1
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-uLywzv5t.cjs → config-BO0ZHyoB.cjs} +4 -4
- package/dist/{config-BZ8xEnOv.mjs → config-DzvbcL_x.mjs} +4 -4
- package/dist/{index-Daga0ztv.cjs → index-BEpZjXs4.cjs} +15 -9
- package/dist/{index-ClCeQ1FW.mjs → index-C33JB4xB.mjs} +16 -10
- package/dist/{index-D8i2EViA.mjs → index-CpEdOGpe.mjs} +4 -4
- package/dist/{index-CdH3ecC5.cjs → index-DHI6Y1xW.cjs} +4 -4
- package/dist/{index-6Xm0CgN_.cjs → index-DNbKbe23.cjs} +1536 -1202
- package/dist/{index-EsR8ayIg.mjs → index-gefLe1Bk.mjs} +1534 -1200
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-NH4kiB2E.mjs → installTerminalHooks-BWoHGCew.mjs} +4 -4
- package/dist/{installTerminalHooks-CKG0MYVK.cjs → installTerminalHooks-gmWKACNb.cjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +20 -60
- package/dist/lib.d.mts +20 -60
- package/dist/lib.mjs +2 -2
- package/dist/{limits-Du7S6jqA.mjs → limits-CPTgiQ9A.mjs} +8 -8
- package/dist/{limits-XRNzIlVm.cjs → limits-K17AgMHD.cjs} +8 -8
- package/dist/{mcp-CAMCuudA.cjs → mcp-CK1NCZm0.cjs} +4 -4
- package/dist/{mcp-D8zhjyZa.mjs → mcp-DhuxpwTB.mjs} +4 -4
- package/dist/{runGemini-Db4rX54F.mjs → runGemini-BVJE7LZl.mjs} +6 -6
- package/dist/{runGemini-BIVHp0ST.cjs → runGemini-n0wD2Z9R.cjs} +6 -6
- package/dist/{runOpenClaw-D2MceXPO.mjs → runOpenClaw-CJaIYpB7.mjs} +5 -5
- package/dist/{runOpenClaw-a0f2pZZp.cjs → runOpenClaw-fYx1XweW.cjs} +5 -5
- package/dist/{send-DKbumEcg.cjs → send-WlJ4r3U2.cjs} +4 -4
- package/dist/{send-1Wjb0lIh.mjs → send-fWHOFJV9.mjs} +4 -4
- package/dist/{sessions-DXCCRDb5.mjs → sessions-5fJxQ2xj.mjs} +4 -4
- package/dist/{sessions-SIFOOlGp.cjs → sessions-Cx_3cvN6.cjs} +4 -4
- package/dist/{spawn-Bj3W6HR4.mjs → spawn-CF1ZV-YH.mjs} +4 -4
- package/dist/{spawn-C-XpSPLX.cjs → spawn-DVJtNwWN.cjs} +4 -4
- package/dist/{teams-ChFzXAqr.cjs → teams-BbYi0fWG.cjs} +4 -4
- package/dist/{teams-CqhFQLVC.mjs → teams-gzvKrMfn.mjs} +4 -4
- package/dist/{todo-B0gbQHH8.mjs → todo-BAK2DVLV.mjs} +3 -3
- package/dist/{todo-o0clp-_I.cjs → todo-DHY20tpD.cjs} +3 -3
- package/dist/{types-6DrEgHVx.mjs → types-BEXGahmj.mjs} +128 -35
- package/dist/{types-CcjVmS2i.cjs → types-DjAHWb4J.cjs} +129 -35
- package/package.json +8 -8
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, e as listSessions, r as readSessionTranscript, f as stopSession, g as resolvePermissionRequest, h as archiveSession } from './index-
|
|
3
|
-
import { i as isValidSessionId } from './types-
|
|
2
|
+
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listAccountSessions, e as listSessions, r as readSessionTranscript, f as stopSession, g as resolvePermissionRequest, h as archiveSession } from './index-gefLe1Bk.mjs';
|
|
3
|
+
import { i as isValidSessionId } from './types-BEXGahmj.mjs';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
|
-
import './limits-
|
|
6
|
+
import './limits-CPTgiQ9A.mjs';
|
|
7
7
|
import 'node:fs/promises';
|
|
8
8
|
import 'node:fs';
|
|
9
9
|
import 'node:path';
|
|
@@ -12,7 +12,7 @@ import 'tweetnacl';
|
|
|
12
12
|
import 'node:util';
|
|
13
13
|
import 'cross-spawn';
|
|
14
14
|
import 'node:readline';
|
|
15
|
-
import './agentGuidance-
|
|
15
|
+
import './agentGuidance-7MByWxKj.mjs';
|
|
16
16
|
import 'fs/promises';
|
|
17
17
|
import 'ink';
|
|
18
18
|
import 'react';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var index = require('./index-
|
|
5
|
-
var api = require('./types-
|
|
4
|
+
var index = require('./index-DNbKbe23.cjs');
|
|
5
|
+
var api = require('./types-DjAHWb4J.cjs');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./limits-
|
|
8
|
+
require('./limits-K17AgMHD.cjs');
|
|
9
9
|
require('node:fs/promises');
|
|
10
10
|
require('node:fs');
|
|
11
11
|
require('node:path');
|
|
@@ -14,7 +14,7 @@ require('tweetnacl');
|
|
|
14
14
|
require('node:util');
|
|
15
15
|
require('cross-spawn');
|
|
16
16
|
require('node:readline');
|
|
17
|
-
require('./agentGuidance-
|
|
17
|
+
require('./agentGuidance-DlZM_YPV.cjs');
|
|
18
18
|
require('fs/promises');
|
|
19
19
|
require('ink');
|
|
20
20
|
require('react');
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync, statSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS, w as waitForSessionKey, d as sendUserMessage } from './index-
|
|
5
|
-
import { l as logger } from './limits-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, S as SPAWN_AGENTS, w as waitForSessionKey, d as sendUserMessage } from './index-gefLe1Bk.mjs';
|
|
5
|
+
import { l as logger } from './limits-CPTgiQ9A.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
|
-
import './types-
|
|
8
|
+
import './types-BEXGahmj.mjs';
|
|
9
9
|
import 'axios';
|
|
10
10
|
import 'node:events';
|
|
11
11
|
import 'socket.io-client';
|
|
@@ -27,7 +27,7 @@ import 'tweetnacl';
|
|
|
27
27
|
import 'node:readline';
|
|
28
28
|
import '@anthropic-ai/sandbox-runtime';
|
|
29
29
|
import 'expo-server-sdk';
|
|
30
|
-
import './agentGuidance-
|
|
30
|
+
import './agentGuidance-7MByWxKj.mjs';
|
|
31
31
|
import 'ink';
|
|
32
32
|
import 'react';
|
|
33
33
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var index = require('./index-
|
|
7
|
-
var persistence = require('./limits-
|
|
6
|
+
var index = require('./index-DNbKbe23.cjs');
|
|
7
|
+
var persistence = require('./limits-K17AgMHD.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
|
-
require('./types-
|
|
10
|
+
require('./types-DjAHWb4J.cjs');
|
|
11
11
|
require('axios');
|
|
12
12
|
require('node:events');
|
|
13
13
|
require('socket.io-client');
|
|
@@ -29,7 +29,7 @@ require('tweetnacl');
|
|
|
29
29
|
require('node:readline');
|
|
30
30
|
require('@anthropic-ai/sandbox-runtime');
|
|
31
31
|
require('expo-server-sdk');
|
|
32
|
-
require('./agentGuidance-
|
|
32
|
+
require('./agentGuidance-DlZM_YPV.cjs');
|
|
33
33
|
require('ink');
|
|
34
34
|
require('react');
|
|
35
35
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -4,15 +4,15 @@ var os = require('node:os');
|
|
|
4
4
|
var promises = require('node:fs/promises');
|
|
5
5
|
var z = require('zod');
|
|
6
6
|
var node_crypto = require('node:crypto');
|
|
7
|
-
var agentGuidance = require('./agentGuidance-
|
|
8
|
-
var persistence = require('./limits-
|
|
7
|
+
var agentGuidance = require('./agentGuidance-DlZM_YPV.cjs');
|
|
8
|
+
var persistence = require('./limits-K17AgMHD.cjs');
|
|
9
9
|
var path = require('node:path');
|
|
10
|
-
var index = require('./index-
|
|
10
|
+
var index = require('./index-DNbKbe23.cjs');
|
|
11
11
|
require('node:fs');
|
|
12
12
|
require('tweetnacl');
|
|
13
13
|
require('chalk');
|
|
14
14
|
require('node:util');
|
|
15
|
-
require('./types-
|
|
15
|
+
require('./types-DjAHWb4J.cjs');
|
|
16
16
|
require('axios');
|
|
17
17
|
require('node:events');
|
|
18
18
|
require('socket.io-client');
|
|
@@ -2,15 +2,15 @@ import { homedir } from 'node:os';
|
|
|
2
2
|
import { unlink, rmdir, mkdir, lstat, readFile, writeFile, rename } from 'node:fs/promises';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { createHash, randomUUID } from 'node:crypto';
|
|
5
|
-
import { d as teamRequest, e as createTeamsClient } from './agentGuidance-
|
|
6
|
-
import { d as readCredentialsForConfiguredRelay } from './limits-
|
|
5
|
+
import { d as teamRequest, e as createTeamsClient } from './agentGuidance-7MByWxKj.mjs';
|
|
6
|
+
import { d as readCredentialsForConfiguredRelay } from './limits-CPTgiQ9A.mjs';
|
|
7
7
|
import { join, resolve, dirname } from 'node:path';
|
|
8
|
-
import { T as TEAM_SKILL } from './index-
|
|
8
|
+
import { T as TEAM_SKILL } from './index-gefLe1Bk.mjs';
|
|
9
9
|
import 'node:fs';
|
|
10
10
|
import 'tweetnacl';
|
|
11
11
|
import 'chalk';
|
|
12
12
|
import 'node:util';
|
|
13
|
-
import './types-
|
|
13
|
+
import './types-BEXGahmj.mjs';
|
|
14
14
|
import 'axios';
|
|
15
15
|
import 'node:events';
|
|
16
16
|
import 'socket.io-client';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as readCredentialsForConfiguredRelay, c as configuration } from './limits-
|
|
2
|
-
import { b as createBuiltinTodoClient, B as BUILTIN_TODO_SKILL } from './types-
|
|
3
|
-
import { c as readTeamScope, t as teamScopePath } from './agentGuidance-
|
|
1
|
+
import { d as readCredentialsForConfiguredRelay, c as configuration } from './limits-CPTgiQ9A.mjs';
|
|
2
|
+
import { b as createBuiltinTodoClient, B as BUILTIN_TODO_SKILL } from './types-BEXGahmj.mjs';
|
|
3
|
+
import { c as readTeamScope, t as teamScopePath } from './agentGuidance-7MByWxKj.mjs';
|
|
4
4
|
import 'node:fs/promises';
|
|
5
5
|
import 'node:fs';
|
|
6
6
|
import 'node:os';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var persistence = require('./limits-
|
|
4
|
-
var api = require('./types-
|
|
5
|
-
var agentGuidance = require('./agentGuidance-
|
|
3
|
+
var persistence = require('./limits-K17AgMHD.cjs');
|
|
4
|
+
var api = require('./types-DjAHWb4J.cjs');
|
|
5
|
+
var agentGuidance = require('./agentGuidance-DlZM_YPV.cjs');
|
|
6
6
|
require('node:fs/promises');
|
|
7
7
|
require('node:fs');
|
|
8
8
|
require('node:os');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import { l as logger, i as encodeBase64, j as encrypt, k as decrypt, m as decodeBase64, c as configuration, o as decryptBlob, q as prepareClipboardText, g as readSettings, r as readPersistedSessions, s as credentialRelayProblem, p as packageJson, t as readTrackedClaudeSessionIds, u as libsodiumEncryptForPublicKey, v as libsodiumPublicKeyFromSecretKey, x as getRandomBytes, y as redactLogValue } from './limits-
|
|
2
|
+
import { l as logger, i as encodeBase64, j as encrypt, k as decrypt, m as decodeBase64, c as configuration, o as decryptBlob, q as prepareClipboardText, g as readSettings, r as readPersistedSessions, s as credentialRelayProblem, p as packageJson, t as readTrackedClaudeSessionIds, u as libsodiumEncryptForPublicKey, v as libsodiumPublicKeyFromSecretKey, x as getRandomBytes, y as redactLogValue } from './limits-CPTgiQ9A.mjs';
|
|
3
3
|
import { EventEmitter } from 'node:events';
|
|
4
4
|
import { io } from 'socket.io-client';
|
|
5
5
|
import * as z from 'zod';
|
|
@@ -31,7 +31,8 @@ const sessionRoleSchema = z.enum(["user", "agent"]);
|
|
|
31
31
|
const sessionTextEventSchema = z.object({
|
|
32
32
|
t: z.literal("text"),
|
|
33
33
|
text: z.string(),
|
|
34
|
-
thinking: z.boolean().optional()
|
|
34
|
+
thinking: z.boolean().optional(),
|
|
35
|
+
actualModel: z.string().optional()
|
|
35
36
|
});
|
|
36
37
|
const sessionServiceMessageEventSchema = z.object({
|
|
37
38
|
t: z.literal("service"),
|
|
@@ -778,6 +779,25 @@ const ContextUsageSchema = z$1.object({
|
|
|
778
779
|
contextWindow: z$1.number().finite().positive(),
|
|
779
780
|
updatedAt: z$1.number().finite().nonnegative()
|
|
780
781
|
});
|
|
782
|
+
const AgentVersionsSchema = z$1.object({
|
|
783
|
+
checkedAt: z$1.number(),
|
|
784
|
+
daemonPid: z$1.number(),
|
|
785
|
+
agents: z$1.array(z$1.object({
|
|
786
|
+
id: z$1.string(),
|
|
787
|
+
installed: z$1.string().nullable(),
|
|
788
|
+
latest: z$1.string().nullable(),
|
|
789
|
+
status: z$1.string()
|
|
790
|
+
}))
|
|
791
|
+
});
|
|
792
|
+
const AGENT_VERSION_SOURCES = [
|
|
793
|
+
{ id: "claude", label: "Claude Code", command: "claude", package: "@anthropic-ai/claude-code", docs: "https://code.claude.com/docs/en/setup" },
|
|
794
|
+
{ id: "codex", label: "Codex", command: "codex", package: "@openai/codex", docs: "https://github.com/openai/codex#installation-and-usage" },
|
|
795
|
+
{ id: "pi", label: "Pi", command: "pi", package: "@mariozechner/pi-coding-agent", docs: "https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent" },
|
|
796
|
+
{ id: "gemini", label: "Gemini CLI", command: "gemini", package: "@google/gemini-cli", docs: "https://github.com/google-gemini/gemini-cli#installation" },
|
|
797
|
+
{ id: "opencode", label: "OpenCode", command: "opencode", package: "opencode-ai", docs: "https://opencode.ai/docs/" },
|
|
798
|
+
{ id: "openclaw", label: "OpenClaw", command: "openclaw", package: "openclaw", docs: "https://docs.openclaw.ai/install/updating" },
|
|
799
|
+
{ id: "claude-sdk", label: "Claude Agent SDK", command: null, package: "@anthropic-ai/claude-agent-sdk", docs: "https://github.com/anthropics/claude-agent-sdk-typescript" }
|
|
800
|
+
];
|
|
781
801
|
|
|
782
802
|
z$1.object({
|
|
783
803
|
teamsVersion: z$1.number().int().positive().optional(),
|
|
@@ -857,6 +877,8 @@ const WebTerminalListItemSchema = z$1.object({
|
|
|
857
877
|
createdAt: z$1.number().optional(),
|
|
858
878
|
activityAt: z$1.number().optional(),
|
|
859
879
|
agentState: z$1.enum(["working", "needs_input", "idle", "shell"]).optional(),
|
|
880
|
+
agentKind: z$1.string().optional(),
|
|
881
|
+
agentObservedAt: z$1.number().optional(),
|
|
860
882
|
/** B-105: mirror session of the claude running inside the terminal. */
|
|
861
883
|
mirrorSessionId: z$1.string().optional(),
|
|
862
884
|
/** B-150: auto-restored after a restart (ms epoch) — the directory and the
|
|
@@ -887,6 +909,8 @@ const ClosedTerminalRecordSchema = z$1.object({
|
|
|
887
909
|
closedAt: z$1.number()
|
|
888
910
|
});
|
|
889
911
|
z$1.object({
|
|
912
|
+
agentVersions: AgentVersionsSchema.optional(),
|
|
913
|
+
agentVersionEpoch: z$1.number().optional(),
|
|
890
914
|
status: z$1.union([
|
|
891
915
|
z$1.enum(["running", "shutting-down"]),
|
|
892
916
|
z$1.string()
|
|
@@ -2424,7 +2448,12 @@ function mapTaskLifecycleSystemMessage(message, state, envelopes) {
|
|
|
2424
2448
|
if (!subtype.startsWith("task_")) return;
|
|
2425
2449
|
if (raw.skip_transcript === true) return;
|
|
2426
2450
|
const toolUseId = typeof raw.tool_use_id === "string" && raw.tool_use_id.length > 0 ? raw.tool_use_id : null;
|
|
2427
|
-
if (!toolUseId
|
|
2451
|
+
if (!toolUseId) return;
|
|
2452
|
+
if (subtype === "task_started" && raw.task_type === "local_bash" && state.bashToolCalls?.has(toolUseId)) {
|
|
2453
|
+
(state.backgroundBashCalls ??= /* @__PURE__ */ new Set()).add(toolUseId);
|
|
2454
|
+
}
|
|
2455
|
+
const backgroundBash = state.backgroundBashCalls?.has(toolUseId) === true;
|
|
2456
|
+
if (!getAgentToolCalls(state).has(toolUseId) && !backgroundBash) return;
|
|
2428
2457
|
const subagent = ensureSessionSubagentIdForProviderSubagent(state, toolUseId);
|
|
2429
2458
|
const usage = raw.usage && typeof raw.usage === "object" ? {
|
|
2430
2459
|
...typeof raw.usage.tool_uses === "number" ? { toolUses: raw.usage.tool_uses } : {},
|
|
@@ -2432,7 +2461,7 @@ function mapTaskLifecycleSystemMessage(message, state, envelopes) {
|
|
|
2432
2461
|
...typeof raw.usage.duration_ms === "number" ? { durationMs: raw.usage.duration_ms } : {}
|
|
2433
2462
|
} : void 0;
|
|
2434
2463
|
if (subtype === "task_started") {
|
|
2435
|
-
rememberSubagentMeta(state, subagent, { description: raw.description, subagentType: raw.subagent_type });
|
|
2464
|
+
rememberSubagentMeta(state, subagent, { description: raw.description, subagentType: backgroundBash ? "background-command" : raw.subagent_type });
|
|
2436
2465
|
const turn = ensureTurn(state, envelopes);
|
|
2437
2466
|
getStartedSubagents(state).delete(subagent);
|
|
2438
2467
|
maybeEmitSubagentStart(state, turn, subagent, envelopes);
|
|
@@ -2521,14 +2550,15 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2521
2550
|
blockCursor = state.streamBlockCursor ?? 0;
|
|
2522
2551
|
state.streamBlockCursor = blockCursor + blocks.length;
|
|
2523
2552
|
}
|
|
2553
|
+
const actualModel = subagent && typeof message.message?.model === "string" && message.message.model.trim() ? { actualModel: message.message.model.trim() } : {};
|
|
2524
2554
|
const draftKey = (index) => apiMessageId ? streamKeyOf(apiMessageId, blockCursor + index) : void 0;
|
|
2525
2555
|
for (const [blockIndex, block] of blocks.entries()) {
|
|
2526
2556
|
if (block.type === "text" && typeof block.text === "string" && block.text.trim().length > 0) {
|
|
2527
|
-
envelopes.push(createEnvelope("agent", { t: "text", text: block.text }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
|
|
2557
|
+
envelopes.push(createEnvelope("agent", { t: "text", text: block.text, ...actualModel }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
|
|
2528
2558
|
continue;
|
|
2529
2559
|
}
|
|
2530
2560
|
if (block.type === "thinking" && typeof block.thinking === "string" && block.thinking.trim().length > 0) {
|
|
2531
|
-
envelopes.push(createEnvelope("agent", { t: "text", text: block.thinking, thinking: true }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
|
|
2561
|
+
envelopes.push(createEnvelope("agent", { t: "text", text: block.thinking, thinking: true, ...actualModel }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
|
|
2532
2562
|
continue;
|
|
2533
2563
|
}
|
|
2534
2564
|
if (block.type === "tool_use") {
|
|
@@ -2556,7 +2586,8 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2556
2586
|
}
|
|
2557
2587
|
continue;
|
|
2558
2588
|
}
|
|
2559
|
-
|
|
2589
|
+
if (name === "Bash") (state.bashToolCalls ??= /* @__PURE__ */ new Set()).add(call);
|
|
2590
|
+
const args = isSubagentTool(name) || name === "Bash" ? { ...baseArgs, sessionSubagent: sessionSubagentForCall } : baseArgs;
|
|
2560
2591
|
envelopes.push(createEnvelope("agent", {
|
|
2561
2592
|
t: "tool-call-start",
|
|
2562
2593
|
call,
|
|
@@ -2657,7 +2688,7 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2657
2688
|
continue;
|
|
2658
2689
|
}
|
|
2659
2690
|
}
|
|
2660
|
-
if (sessionSubagentForToolResult) {
|
|
2691
|
+
if (sessionSubagentForToolResult && !state.backgroundBashCalls?.has(block.tool_use_id)) {
|
|
2661
2692
|
maybeEmitSubagentStop(state, turnId, sessionSubagentForToolResult, envelopes);
|
|
2662
2693
|
}
|
|
2663
2694
|
}
|
|
@@ -4337,6 +4368,58 @@ function registerTodoHandlers(manager) {
|
|
|
4337
4368
|
});
|
|
4338
4369
|
}
|
|
4339
4370
|
|
|
4371
|
+
function codingAgentFromProcessTree(panePid, snapshot) {
|
|
4372
|
+
const rows = snapshot.split("\n").flatMap((line) => {
|
|
4373
|
+
const m = line.trim().match(/^(\d+)\s+(\d+)\s+(.+)$/);
|
|
4374
|
+
return m ? [{ pid: Number(m[1]), parent: Number(m[2]), command: m[3] }] : [];
|
|
4375
|
+
});
|
|
4376
|
+
const visit = (pid, seen = /* @__PURE__ */ new Set()) => {
|
|
4377
|
+
if (seen.has(pid)) return void 0;
|
|
4378
|
+
seen.add(pid);
|
|
4379
|
+
const row = rows.find((r) => r.pid === pid);
|
|
4380
|
+
if (!row) return void 0;
|
|
4381
|
+
for (const child of rows.filter((r) => r.parent === pid)) {
|
|
4382
|
+
const kind = visit(child.pid, seen);
|
|
4383
|
+
if (kind) return kind;
|
|
4384
|
+
}
|
|
4385
|
+
const words = row.command.split(/\s+/);
|
|
4386
|
+
const executable = words[0].split("/").pop();
|
|
4387
|
+
const candidate = executable === "node" ? words[1]?.split("/").pop() : executable;
|
|
4388
|
+
if (candidate === "pi" || candidate === "pi-coding-agent") return "pi";
|
|
4389
|
+
if (candidate === "codex") return "codex";
|
|
4390
|
+
if (candidate === "claude" || /^\d+\.\d+\.\d+$/.test(candidate ?? "")) return "claude";
|
|
4391
|
+
return void 0;
|
|
4392
|
+
};
|
|
4393
|
+
return visit(panePid);
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4396
|
+
const shells = /* @__PURE__ */ new Set(["zsh", "bash", "fish", "sh", "dash", "ksh", "tcsh", "csh"]);
|
|
4397
|
+
function classifyAgentPane(command, tail) {
|
|
4398
|
+
const cmd = command.trim().replace(/^-/, "").split(/[\\/]/).pop().toLowerCase();
|
|
4399
|
+
const lines = tail.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "").replace(/\r/g, "").trimEnd().split("\n");
|
|
4400
|
+
const screen = lines.join("\n");
|
|
4401
|
+
const footer = lines.slice(-20).join("\n");
|
|
4402
|
+
if (shells.has(cmd)) return { agentState: "shell" };
|
|
4403
|
+
if (!["node", "claude", "codex", "pi"].includes(cmd) && !/^\d+\.\d+\.\d+$/.test(cmd)) return {};
|
|
4404
|
+
const agentKind = cmd === "pi" ? "pi" : cmd === "codex" ? "codex" : cmd === "claude" || /^\d+\.\d+\.\d+$/.test(cmd) ? "claude" : /OpenAI Codex/.test(screen) ? "codex" : /(?:^|\n)\s*pi v\d|Pi can explain its own features/.test(screen) ? "pi" : /Claude Code|tell Claude what to do|bypass permissions on|⏵⏵|[·✻✽✶✳] [^\n]+… \(esc to interrupt\)/.test(footer) ? "claude" : void 0;
|
|
4405
|
+
if (!agentKind) return {};
|
|
4406
|
+
const result = (agentState) => ({ agentKind, agentState });
|
|
4407
|
+
if (agentKind === "pi") {
|
|
4408
|
+
if (/^\s*→ \S/m.test(screen) && /(?:↑↓ navigate.*(?:enter|return) select.*esc cancel|Enter to select.*Esc to cancel)/i.test(footer)) return result("needs_input");
|
|
4409
|
+
if (/^\s*[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏◐◓◑◒]\s+(?:Working|Thinking|Retrying|Compacting context|Auto-compacting|Summarizing branch).*$/m.test(footer)) return result("working");
|
|
4410
|
+
if (/^\s*[⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏◐◓◑◒]\s/m.test(footer)) return result();
|
|
4411
|
+
const editorRules = footer.match(/^\s*─{8,}\s*$/gm) ?? [];
|
|
4412
|
+
if (editorRules.length >= 2 && /(?:\d+(?:\.\d+)?|\?)%\/\d+(?:\.\d+)?[km]?.* • (?:thinking off|minimal|low|medium|high|xhigh)/i.test(footer)) return result("idle");
|
|
4413
|
+
return result();
|
|
4414
|
+
}
|
|
4415
|
+
const choice = /^[\s│]*[❯›>]\s*\d+\.\s/m.test(footer);
|
|
4416
|
+
if (choice && /Do you want|Would you like|approve|Yes,|Yes\b|Enter to select.*navigate.*Esc to cancel/i.test(footer)) return result("needs_input");
|
|
4417
|
+
if (/esc to interrupt/i.test(footer)) return result("working");
|
|
4418
|
+
if (agentKind === "codex" && /^\s*gpt-[\w.-]+ (?:minimal|low|medium|high|xhigh|fast)[^\n]* · (?:~|\/|[A-Z]:[\\/])/m.test(footer) && /^› /m.test(footer)) return result("idle");
|
|
4419
|
+
if (/\? for shortcuts|bypass permissions on|⏵⏵|\d+% context left/.test(footer)) return result("idle");
|
|
4420
|
+
return result();
|
|
4421
|
+
}
|
|
4422
|
+
|
|
4340
4423
|
function sanitizeGeometry(cols, rows) {
|
|
4341
4424
|
const ok = (v) => typeof v === "number" && Number.isInteger(v) && v >= 2 && v <= 1e4;
|
|
4342
4425
|
return ok(cols) && ok(rows) ? { cols, rows } : void 0;
|
|
@@ -9546,10 +9629,12 @@ class TerminalNotifyTracker {
|
|
|
9546
9629
|
* Feed one observation for a terminal. Returns the notification event this
|
|
9547
9630
|
* observation triggers, or null. Call once per terminal per tick.
|
|
9548
9631
|
*/
|
|
9549
|
-
observe(terminalId, state, now) {
|
|
9632
|
+
observe(terminalId, state, now, agentKind) {
|
|
9550
9633
|
let t = this.tracks.get(terminalId);
|
|
9551
|
-
if (!t) {
|
|
9634
|
+
if (!t || t.agentKind !== agentKind || now - t.lastObservedAt > 45e3) {
|
|
9552
9635
|
t = {
|
|
9636
|
+
agentKind,
|
|
9637
|
+
lastObservedAt: now,
|
|
9553
9638
|
armed: state === "working",
|
|
9554
9639
|
confirmed: state,
|
|
9555
9640
|
candidate: state,
|
|
@@ -9560,6 +9645,7 @@ class TerminalNotifyTracker {
|
|
|
9560
9645
|
this.tracks.set(terminalId, t);
|
|
9561
9646
|
return null;
|
|
9562
9647
|
}
|
|
9648
|
+
t.lastObservedAt = now;
|
|
9563
9649
|
if (state === "working") t.armed = true;
|
|
9564
9650
|
if (state === t.confirmed) {
|
|
9565
9651
|
t.candidate = state;
|
|
@@ -9892,6 +9978,8 @@ function terminalListSignature(items) {
|
|
|
9892
9978
|
t.createdAt ?? 0,
|
|
9893
9979
|
Math.floor((t.activityAt ?? 0) / ACTIVITY_SIGNATURE_BUCKET_MS),
|
|
9894
9980
|
t.agentState ?? "",
|
|
9981
|
+
t.agentKind ?? "",
|
|
9982
|
+
Math.floor((t.agentObservedAt ?? 0) / 1e4),
|
|
9895
9983
|
// B-105: a mirror binding appearing/disappearing MUST push the
|
|
9896
9984
|
// list, or the web never learns the toggle became available.
|
|
9897
9985
|
t.mirrorSessionId ?? "",
|
|
@@ -9940,7 +10028,7 @@ const LIST_SESSIONS_FORMAT = [
|
|
|
9940
10028
|
// command only separates shell/idle). MUST stay before pane_title: that
|
|
9941
10029
|
// field is deliberately last so a pathological 0x1f inside a title can only
|
|
9942
10030
|
// garble the title, never shift the fields.
|
|
9943
|
-
"#{pane_current_command}",
|
|
10031
|
+
"#{pane_current_command} #{pane_pid}",
|
|
9944
10032
|
"#{pane_title}"
|
|
9945
10033
|
].join(LIST_FIELD_SEP);
|
|
9946
10034
|
function parseSessionListLine(line) {
|
|
@@ -9958,7 +10046,8 @@ function parseSessionListLine(line) {
|
|
|
9958
10046
|
vhTitle: vhTitle.trim() || void 0,
|
|
9959
10047
|
manual: manual.trim().length > 0,
|
|
9960
10048
|
tags: parseTerminalTags(vhTags),
|
|
9961
|
-
paneCurrentCommand: paneCommand.trim() || void 0,
|
|
10049
|
+
paneCurrentCommand: paneCommand.trim().replace(/ \d+$/, "") || void 0,
|
|
10050
|
+
.../ (\d+)$/.test(paneCommand) ? { panePid: Number(paneCommand.match(/ (\d+)$/)[1]) } : {},
|
|
9962
10051
|
// Verbatim (no trim): tmux allows edge spaces in a session name and the
|
|
9963
10052
|
// restore lookup / attach echo compare it exactly.
|
|
9964
10053
|
attachTmux: isSafeTmuxSessionName(vhAttach) ? vhAttach : void 0,
|
|
@@ -10000,22 +10089,6 @@ function parseTerminalTags(raw) {
|
|
|
10000
10089
|
return [];
|
|
10001
10090
|
}
|
|
10002
10091
|
}
|
|
10003
|
-
function classifyPane(currentCommand, tail) {
|
|
10004
|
-
const cmd = (currentCommand || "").trim().replace(/^-/, "").toLowerCase();
|
|
10005
|
-
const isShell = SHELL_COMMANDS.has(cmd);
|
|
10006
|
-
const lines = tail.replace(/\r/g, "").split("\n").map((l) => l.trimEnd());
|
|
10007
|
-
while (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
|
|
10008
|
-
const text = lines.join("\n");
|
|
10009
|
-
const last15 = lines.slice(-15).join("\n");
|
|
10010
|
-
const hasDialog = last15.includes("Do you want") || last15.includes("Would you like to proceed") || /^[\s│]*[❯>]\s*1\.\s/m.test(last15) || /\(y\/n\)/i.test(last15);
|
|
10011
|
-
if (hasDialog) return "needs_input";
|
|
10012
|
-
if (text.includes("esc to interrupt")) return "working";
|
|
10013
|
-
const looksLikeClaude = looksLikeClaudeCommand(cmd);
|
|
10014
|
-
const hasIdleFooter = text.includes("? for shortcuts") || text.includes("bypass permissions on") || text.includes("\u23F5\u23F5");
|
|
10015
|
-
if (looksLikeClaude || hasIdleFooter) return "idle";
|
|
10016
|
-
if (isShell) return "shell";
|
|
10017
|
-
return void 0;
|
|
10018
|
-
}
|
|
10019
10092
|
function looksLikeClaudeCommand(currentCommand) {
|
|
10020
10093
|
const cmd = (currentCommand || "").trim().replace(/^-/, "").toLowerCase();
|
|
10021
10094
|
return cmd === "claude" || cmd === "node" || /^\d+\.\d+(\.\d+)?$/.test(cmd);
|
|
@@ -11026,7 +11099,7 @@ class WebTerminalManager {
|
|
|
11026
11099
|
const now = Date.now();
|
|
11027
11100
|
this.notifyTracker.prune(list.map((t) => t.id));
|
|
11028
11101
|
for (const item of list) {
|
|
11029
|
-
const event = this.notifyTracker.observe(item.id, item.agentState, now);
|
|
11102
|
+
const event = this.notifyTracker.observe(item.id, item.agentState, now, item.agentKind);
|
|
11030
11103
|
if (!event) continue;
|
|
11031
11104
|
try {
|
|
11032
11105
|
this.onNotify({ terminalId: item.id, title: item.title || "Terminal", event });
|
|
@@ -11758,6 +11831,7 @@ class WebTerminalManager {
|
|
|
11758
11831
|
if (r.status !== 0 || !r.stdout) return [];
|
|
11759
11832
|
const hostname = os$1.hostname();
|
|
11760
11833
|
const out = [];
|
|
11834
|
+
let processSnapshot;
|
|
11761
11835
|
for (const line of r.stdout.split("\n")) {
|
|
11762
11836
|
const s = parseSessionListLine(line);
|
|
11763
11837
|
if (!s || !s.name.startsWith("vh-")) continue;
|
|
@@ -11775,7 +11849,15 @@ class WebTerminalManager {
|
|
|
11775
11849
|
} catch {
|
|
11776
11850
|
}
|
|
11777
11851
|
}
|
|
11778
|
-
|
|
11852
|
+
let identity = s.paneCurrentCommand;
|
|
11853
|
+
if (identity === "node" && s.panePid) {
|
|
11854
|
+
if (processSnapshot === void 0) {
|
|
11855
|
+
const ps = spawnSync("ps", ["-axo", "pid=,ppid=,args="], { encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS });
|
|
11856
|
+
processSnapshot = ps.status === 0 ? ps.stdout : "";
|
|
11857
|
+
}
|
|
11858
|
+
identity = codingAgentFromProcessTree(s.panePid, processSnapshot) ?? identity;
|
|
11859
|
+
}
|
|
11860
|
+
const probe = this.probeAgentState(s.name, identity);
|
|
11779
11861
|
out.push({
|
|
11780
11862
|
id,
|
|
11781
11863
|
title,
|
|
@@ -11787,6 +11869,8 @@ class WebTerminalManager {
|
|
|
11787
11869
|
// simply omit it and web clients fall back to createdAt.
|
|
11788
11870
|
activityAt: s.activity,
|
|
11789
11871
|
agentState: probe.agentState,
|
|
11872
|
+
agentKind: probe.agentKind,
|
|
11873
|
+
agentObservedAt: probe.agentObservedAt,
|
|
11790
11874
|
// Daemon-internal (not pushed to web / not in the signature):
|
|
11791
11875
|
// the mirror reconciler's stricter "claude is really here" gate.
|
|
11792
11876
|
claudeConfident: probe.claudeConfident,
|
|
@@ -11813,16 +11897,17 @@ class WebTerminalManager {
|
|
|
11813
11897
|
if (live) {
|
|
11814
11898
|
try {
|
|
11815
11899
|
const { command, tail } = live.agentProbeInput();
|
|
11816
|
-
|
|
11900
|
+
const observation = classifyAgentPane(command === "node" ? polledCommand || command : command || polledCommand || "", tail);
|
|
11901
|
+
return { ...observation, agentObservedAt: Date.now(), claudeConfident: observation.agentKind === "claude" && isClaudeConfident(tail) };
|
|
11817
11902
|
} catch {
|
|
11818
11903
|
}
|
|
11819
11904
|
}
|
|
11820
|
-
return this.probeAgentStateViaTmux(sessionName);
|
|
11905
|
+
return this.probeAgentStateViaTmux(sessionName, polledCommand);
|
|
11821
11906
|
}
|
|
11822
11907
|
/** Fallback probe for sessions with no live headless: 2 short tmux calls
|
|
11823
11908
|
* (foreground command + pane tail) fed into classifyPane. Any failure or
|
|
11824
11909
|
* timeout → undefined (the field is omitted), never an error. */
|
|
11825
|
-
probeAgentStateViaTmux(sessionName) {
|
|
11910
|
+
probeAgentStateViaTmux(sessionName, polledCommand) {
|
|
11826
11911
|
try {
|
|
11827
11912
|
const cmd = spawnSync(
|
|
11828
11913
|
"tmux",
|
|
@@ -11836,7 +11921,8 @@ class WebTerminalManager {
|
|
|
11836
11921
|
{ encoding: "utf8", timeout: TMUX_PROBE_TIMEOUT_MS, env: ptyEnv() }
|
|
11837
11922
|
);
|
|
11838
11923
|
if (cap.status !== 0 || typeof cap.stdout !== "string") return { agentState: void 0, claudeConfident: false };
|
|
11839
|
-
|
|
11924
|
+
const observation = classifyAgentPane(cmd.stdout.trim() === "node" ? polledCommand || "node" : cmd.stdout.trim(), cap.stdout);
|
|
11925
|
+
return { ...observation, agentObservedAt: Date.now(), claudeConfident: observation.agentKind === "claude" && isClaudeConfident(cap.stdout) };
|
|
11840
11926
|
} catch {
|
|
11841
11927
|
return { agentState: void 0, claudeConfident: false };
|
|
11842
11928
|
}
|
|
@@ -12972,6 +13058,10 @@ class CodexAppServerClient {
|
|
|
12972
13058
|
if (!item || typeof item !== "object") {
|
|
12973
13059
|
return method.startsWith("item/");
|
|
12974
13060
|
}
|
|
13061
|
+
if ((method === "item/started" || method === "item/completed") && (item.type === "collabAgentToolCall" || item.type === "subAgentActivity")) {
|
|
13062
|
+
this.eventHandler?.({ type: "collab_agent_item", item });
|
|
13063
|
+
return true;
|
|
13064
|
+
}
|
|
12975
13065
|
if (method === "item/started" && item.type === "commandExecution") {
|
|
12976
13066
|
const callId = typeof item.id === "string" ? item.id : "";
|
|
12977
13067
|
this.eventHandler?.({
|
|
@@ -14082,6 +14172,8 @@ class ApiMachineClient {
|
|
|
14082
14172
|
* stale" so the FIRST keep-alive tick always probes and populates the
|
|
14083
14173
|
* machine metadata that a connecting/reconnecting web client reads. */
|
|
14084
14174
|
lastCliProbeAt = Date.now() - CLI_AVAILABILITY_RECHECK_MS;
|
|
14175
|
+
/** Stable across socket reconnects; a new client/run invalidates old version checks. */
|
|
14176
|
+
agentVersionEpoch = Date.now();
|
|
14085
14177
|
cliUpdateState = null;
|
|
14086
14178
|
cliUpdatePushChain = Promise.resolve();
|
|
14087
14179
|
claudeAuthState = null;
|
|
@@ -14842,6 +14934,7 @@ class ApiMachineClient {
|
|
|
14842
14934
|
pid: process.pid,
|
|
14843
14935
|
httpPort: this.machine.daemonState?.httpPort,
|
|
14844
14936
|
startedAt: now,
|
|
14937
|
+
agentVersionEpoch: this.agentVersionEpoch,
|
|
14845
14938
|
webTerminals: { updatedAt: now, terminals: initialTerminals },
|
|
14846
14939
|
// B-265 capability flag; restamped every connect so the
|
|
14847
14940
|
// web's `detectedAt >= startedAt` trust rule holds.
|
|
@@ -16206,4 +16299,4 @@ const RawJSONLinesSchema = z$1.discriminatedUnion("type", [
|
|
|
16206
16299
|
}).passthrough()
|
|
16207
16300
|
]);
|
|
16208
16301
|
|
|
16209
|
-
export {
|
|
16302
|
+
export { CodexAppServerClient as $, ApiClient as A, BUILTIN_TODO_SKILL as B, tmuxArgs as C, scrubTmuxClientEnv as D, decideMirrorBinding as E, MIRROR_BACKFILL_LINES_DEFAULT as F, mirrorLineKey as G, mirrorLocalId as H, InvalidateSync as I, detectCLIAvailability as J, detectResumeSupport as K, summarizeSpawnSessionForLog as L, MAX_CHAT_ATTACHMENT_SOURCE_BYTES as M, shellescape as N, fetchCliUpdateState as O, resolveCliUpdateCheckInterval as P, DEFAULT_CLI_UPDATE_CHECK_INTERVAL_MS as Q, RawJSONLinesSchema as R, STREAM_DELTA_MAX_CHARS as S, listVhTerminals as T, isValidTerminalId as U, readVhTerminal as V, sendToVhTerminal as W, ContextUsageSchema as X, TITLE_PROMPT_PREFIX as Y, BOARD_ANALYZER_PROMPT_PREFIX as Z, startOfflineReconnection as _, ApiSessionClient as a, api as a0, createBuiltinTodoClient as b, createEnvelope as c, contentLogMetadata as d, errorLogMetadata as e, connectionState as f, BUILTIN_TODO_DISCOVERY as g, delay as h, isValidSessionId as i, getProjectPath as j, initializeSandbox as k, AsyncLock as l, commandOnPath as m, deriveLocalCliUpdateSummary as n, AGENT_VERSION_SOURCES as o, projectPath as p, isClaudeSessionId as q, getLocalHappyAgentCredentialPath as r, streamKeyOf as s, readLocalHappyAgentCredentials as t, parseExactVersion as u, compareExactVersions as v, wrapCommand as w, extractCompleteLines as x, decideBackfill as y, parseTerminalHookPayload as z };
|