very-happy-cli 0.2.77 → 0.2.79
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-CsLnh1So.cjs → AcpBackend-BuxJntPo.cjs} +1 -1
- package/dist/{AcpBackend-BFFC77vV.mjs → AcpBackend-DPcRh_3n.mjs} +1 -1
- package/dist/{AcpSessionManager--CixPN-p.cjs → AcpSessionManager-BOZPQZUQ.cjs} +1 -1
- package/dist/{AcpSessionManager-CU5vsxgF.mjs → AcpSessionManager-DVGWPtBC.mjs} +1 -1
- package/dist/{config-pv17N6Kg.cjs → config-DB0v5eoc.cjs} +2 -2
- package/dist/{config-CRFTYuTN.mjs → config-T7eM_8eT.mjs} +2 -2
- package/dist/{index-Dcv1RKe8.cjs → index-BGvGqzc1.cjs} +252 -73
- package/dist/{index-BkvUwyIU.mjs → index-CuLe9SB7.mjs} +5 -5
- package/dist/{index-C1OnwMx0.cjs → index-D_ZjCYNI.cjs} +4 -4
- package/dist/{index-DOb57EGb.mjs → index-HYOkniru.mjs} +249 -70
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-YyT3fv6w.cjs → installTerminalHooks-CAViJyYh.cjs} +2 -2
- package/dist/{installTerminalHooks-IXvZMGJq.mjs → installTerminalHooks-CPKThY28.mjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.d.cts +11 -2
- package/dist/lib.d.mts +11 -2
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-CsKnmeE5.cjs → mcp-DhQcmKO7.cjs} +2 -2
- package/dist/{mcp-B-GdhlKD.mjs → mcp-DhUA22wj.mjs} +2 -2
- package/dist/{runGemini-D0lddF43.mjs → runGemini-BVxviS8T.mjs} +4 -4
- package/dist/{runGemini-DuUdmlVZ.cjs → runGemini-CfWCL9K7.cjs} +4 -4
- package/dist/{runOpenClaw-BiwwYnYf.mjs → runOpenClaw-DVTaZJtj.mjs} +3 -3
- package/dist/{runOpenClaw-DEMCYSoD.cjs → runOpenClaw-kSy7Os3C.cjs} +3 -3
- package/dist/{send-DM8oqJFp.mjs → send-DjjJQXJt.mjs} +2 -2
- package/dist/{send-DijSXAMp.cjs → send-jzwPToBN.cjs} +2 -2
- package/dist/{spawn-nISXbZD5.mjs → spawn-DBpgsEkS.mjs} +2 -2
- package/dist/{spawn-De3b5Hsu.cjs → spawn-DFnYIiKP.cjs} +2 -2
- package/dist/{types-D2qSKjsO.mjs → types-BRDN6zN2.mjs} +92 -14
- package/dist/{types-NwtcBgfS.cjs → types-Dy7P_1bh.cjs} +93 -15
- package/package.json +7 -7
package/dist/lib.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
|
|
1
2
|
import * as z from 'zod';
|
|
2
3
|
import { z as z$1 } from 'zod';
|
|
3
4
|
import { EventEmitter } from 'node:events';
|
|
@@ -67,6 +68,7 @@ declare const sessionEnvelopeSchema: z.ZodObject<{
|
|
|
67
68
|
failed: "failed";
|
|
68
69
|
cancelled: "cancelled";
|
|
69
70
|
}>;
|
|
71
|
+
error: z.ZodOptional<z.ZodString>;
|
|
70
72
|
costUsd: z.ZodOptional<z.ZodNumber>;
|
|
71
73
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
72
74
|
numTurns: z.ZodOptional<z.ZodNumber>;
|
|
@@ -273,6 +275,7 @@ declare const DaemonStateSchema: z$1.ZodObject<{
|
|
|
273
275
|
terminals: z$1.ZodArray<z$1.ZodObject<{
|
|
274
276
|
id: z$1.ZodString;
|
|
275
277
|
title: z$1.ZodOptional<z$1.ZodString>;
|
|
278
|
+
tags: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
|
|
276
279
|
cwd: z$1.ZodOptional<z$1.ZodString>;
|
|
277
280
|
createdAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
278
281
|
activityAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
@@ -475,6 +478,8 @@ type AgentState$1 = {
|
|
|
475
478
|
tool: string;
|
|
476
479
|
arguments: any;
|
|
477
480
|
createdAt: number;
|
|
481
|
+
kind?: 'tool' | 'elicitation' | 'user_dialog';
|
|
482
|
+
permissionSuggestions?: _anthropic_ai_claude_agent_sdk.PermissionUpdate[];
|
|
478
483
|
};
|
|
479
484
|
};
|
|
480
485
|
completedRequests?: {
|
|
@@ -487,7 +492,7 @@ type AgentState$1 = {
|
|
|
487
492
|
reason?: string;
|
|
488
493
|
mode?: PermissionMode;
|
|
489
494
|
decision?: 'approved' | 'approved_for_session' | 'denied' | 'abort';
|
|
490
|
-
|
|
495
|
+
allowedTools?: string[];
|
|
491
496
|
};
|
|
492
497
|
};
|
|
493
498
|
};
|
|
@@ -733,7 +738,9 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
733
738
|
* unique constraint swallow every envelope after the first. */
|
|
734
739
|
localIdFor?: (envelopeIndex: number) => string;
|
|
735
740
|
}): void;
|
|
736
|
-
closeClaudeSessionTurn(status?: SessionTurnEndStatus
|
|
741
|
+
closeClaudeSessionTurn(status?: SessionTurnEndStatus, meta?: {
|
|
742
|
+
error?: string;
|
|
743
|
+
}): void;
|
|
737
744
|
sendCodexMessage(body: any): void;
|
|
738
745
|
private enqueueSessionProtocolEnvelope;
|
|
739
746
|
sendSessionProtocolMessage(envelope: SessionEnvelope, localId?: string): void;
|
|
@@ -974,6 +981,8 @@ type AgentState = 'working' | 'needs_input' | 'idle' | 'shell';
|
|
|
974
981
|
interface TerminalListItem {
|
|
975
982
|
id: string;
|
|
976
983
|
title?: string;
|
|
984
|
+
/** Always present in new daemon output; optional for old persisted state. */
|
|
985
|
+
tags?: string[];
|
|
977
986
|
cwd?: string;
|
|
978
987
|
createdAt?: number;
|
|
979
988
|
activityAt?: number;
|
package/dist/lib.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as _anthropic_ai_claude_agent_sdk from '@anthropic-ai/claude-agent-sdk';
|
|
1
2
|
import * as z from 'zod';
|
|
2
3
|
import { z as z$1 } from 'zod';
|
|
3
4
|
import { EventEmitter } from 'node:events';
|
|
@@ -67,6 +68,7 @@ declare const sessionEnvelopeSchema: z.ZodObject<{
|
|
|
67
68
|
failed: "failed";
|
|
68
69
|
cancelled: "cancelled";
|
|
69
70
|
}>;
|
|
71
|
+
error: z.ZodOptional<z.ZodString>;
|
|
70
72
|
costUsd: z.ZodOptional<z.ZodNumber>;
|
|
71
73
|
durationMs: z.ZodOptional<z.ZodNumber>;
|
|
72
74
|
numTurns: z.ZodOptional<z.ZodNumber>;
|
|
@@ -273,6 +275,7 @@ declare const DaemonStateSchema: z$1.ZodObject<{
|
|
|
273
275
|
terminals: z$1.ZodArray<z$1.ZodObject<{
|
|
274
276
|
id: z$1.ZodString;
|
|
275
277
|
title: z$1.ZodOptional<z$1.ZodString>;
|
|
278
|
+
tags: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
|
|
276
279
|
cwd: z$1.ZodOptional<z$1.ZodString>;
|
|
277
280
|
createdAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
278
281
|
activityAt: z$1.ZodOptional<z$1.ZodNumber>;
|
|
@@ -475,6 +478,8 @@ type AgentState$1 = {
|
|
|
475
478
|
tool: string;
|
|
476
479
|
arguments: any;
|
|
477
480
|
createdAt: number;
|
|
481
|
+
kind?: 'tool' | 'elicitation' | 'user_dialog';
|
|
482
|
+
permissionSuggestions?: _anthropic_ai_claude_agent_sdk.PermissionUpdate[];
|
|
478
483
|
};
|
|
479
484
|
};
|
|
480
485
|
completedRequests?: {
|
|
@@ -487,7 +492,7 @@ type AgentState$1 = {
|
|
|
487
492
|
reason?: string;
|
|
488
493
|
mode?: PermissionMode;
|
|
489
494
|
decision?: 'approved' | 'approved_for_session' | 'denied' | 'abort';
|
|
490
|
-
|
|
495
|
+
allowedTools?: string[];
|
|
491
496
|
};
|
|
492
497
|
};
|
|
493
498
|
};
|
|
@@ -733,7 +738,9 @@ declare class ApiSessionClient extends EventEmitter {
|
|
|
733
738
|
* unique constraint swallow every envelope after the first. */
|
|
734
739
|
localIdFor?: (envelopeIndex: number) => string;
|
|
735
740
|
}): void;
|
|
736
|
-
closeClaudeSessionTurn(status?: SessionTurnEndStatus
|
|
741
|
+
closeClaudeSessionTurn(status?: SessionTurnEndStatus, meta?: {
|
|
742
|
+
error?: string;
|
|
743
|
+
}): void;
|
|
737
744
|
sendCodexMessage(body: any): void;
|
|
738
745
|
private enqueueSessionProtocolEnvelope;
|
|
739
746
|
sendSessionProtocolMessage(envelope: SessionEnvelope, localId?: string): void;
|
|
@@ -974,6 +981,8 @@ type AgentState = 'working' | 'needs_input' | 'idle' | 'shell';
|
|
|
974
981
|
interface TerminalListItem {
|
|
975
982
|
id: string;
|
|
976
983
|
title?: string;
|
|
984
|
+
/** Always present in new daemon output; optional for old persisted state. */
|
|
985
|
+
tags?: string[];
|
|
977
986
|
cwd?: string;
|
|
978
987
|
createdAt?: number;
|
|
979
988
|
activityAt?: number;
|
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, l as logger } from './types-BRDN6zN2.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:util';
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
|
|
4
4
|
var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
5
5
|
var z = require('zod');
|
|
6
|
-
var index = require('./index-
|
|
6
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
7
7
|
var limits = require('./limits-KdWKmwtH.cjs');
|
|
8
|
-
var persistence = require('./types-
|
|
8
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
9
9
|
require('chalk');
|
|
10
10
|
require('node:os');
|
|
11
11
|
require('node:crypto');
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
-
import { p as pushClipboardViaDaemon } from './index-
|
|
4
|
+
import { p as pushClipboardViaDaemon } from './index-HYOkniru.mjs';
|
|
5
5
|
import { C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, c as CLIPBOARD_MAX_BYTES } from './limits-CwFb5S2b.mjs';
|
|
6
|
-
import { l as logger } from './types-
|
|
6
|
+
import { l as logger } from './types-BRDN6zN2.mjs';
|
|
7
7
|
import 'chalk';
|
|
8
8
|
import 'node:os';
|
|
9
9
|
import 'node:crypto';
|
|
@@ -2,10 +2,10 @@ import { useStdout, useInput, Box, Text, render } from 'ink';
|
|
|
2
2
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
3
3
|
import { randomUUID } from 'node:crypto';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-
|
|
6
|
-
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-
|
|
7
|
-
import { A as AcpBackend } from './AcpBackend-
|
|
8
|
-
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-
|
|
5
|
+
import { l as logger, h as connectionState, A as ApiClient, i as readSettings, e as errorLogMetadata, j as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-BRDN6zN2.mjs';
|
|
6
|
+
import { g as GEMINI_API_KEY_ENV, j as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, k as BaseReasoningProcessor, i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, h as hashObject, l as MessageBuffer, C as CHANGE_TITLE_INSTRUCTION, r as registerKillSessionHandler, f as startHappyServer } from './index-HYOkniru.mjs';
|
|
7
|
+
import { A as AcpBackend } from './AcpBackend-DPcRh_3n.mjs';
|
|
8
|
+
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-T7eM_8eT.mjs';
|
|
9
9
|
import 'axios';
|
|
10
10
|
import 'chalk';
|
|
11
11
|
import 'node:util';
|
|
@@ -4,10 +4,10 @@ var ink = require('ink');
|
|
|
4
4
|
var React = require('react');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
6
|
var path = require('node:path');
|
|
7
|
-
var persistence = require('./types-
|
|
8
|
-
var index = require('./index-
|
|
9
|
-
var AcpBackend = require('./AcpBackend-
|
|
10
|
-
var config = require('./config-
|
|
7
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
8
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
9
|
+
var AcpBackend = require('./AcpBackend-BuxJntPo.cjs');
|
|
10
|
+
var config = require('./config-DB0v5eoc.cjs');
|
|
11
11
|
require('axios');
|
|
12
12
|
require('chalk');
|
|
13
13
|
require('node:util');
|
|
@@ -3,9 +3,9 @@ import { execFileSync } from 'node:child_process';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import { existsSync, readFileSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
|
-
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-
|
|
7
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
8
|
-
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-
|
|
6
|
+
import { k as ensurePrivateDirectorySync, m as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, i as readSettings, j as encodeBase64, l as logger, c as configuration } from './types-BRDN6zN2.mjs';
|
|
7
|
+
import { A as AcpSessionManager } from './AcpSessionManager-DVGWPtBC.mjs';
|
|
8
|
+
import { i as initialMachineMetadata, d as createSessionMetadata, e as setupOfflineReconnection, n as notifyDaemonSessionStarted, M as MessageQueue2, r as registerKillSessionHandler } from './index-HYOkniru.mjs';
|
|
9
9
|
import WebSocket from 'ws';
|
|
10
10
|
import * as ed from '@noble/ed25519';
|
|
11
11
|
import { sha512 } from '@noble/hashes/sha2.js';
|
|
@@ -5,9 +5,9 @@ var node_child_process = require('node:child_process');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_fs = require('node:fs');
|
|
7
7
|
var path = require('node:path');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var AcpSessionManager = require('./AcpSessionManager
|
|
10
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
9
|
+
var AcpSessionManager = require('./AcpSessionManager-BOZPQZUQ.cjs');
|
|
10
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
11
11
|
var WebSocket = require('ws');
|
|
12
12
|
var ed = require('@noble/ed25519');
|
|
13
13
|
var sha2_js = require('@noble/hashes/sha2.js');
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { readFileSync } from 'node:fs';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
|
-
import { r as readPersistedSessions, c as configuration } from './types-
|
|
5
|
-
import { b as sendUserMessage, a as sessionWebUrl } from './index-
|
|
4
|
+
import { r as readPersistedSessions, c as configuration } from './types-BRDN6zN2.mjs';
|
|
5
|
+
import { b as sendUserMessage, a as sessionWebUrl } from './index-HYOkniru.mjs';
|
|
6
6
|
import 'axios';
|
|
7
7
|
import 'node:util';
|
|
8
8
|
import 'node:os';
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var node_fs = require('node:fs');
|
|
5
5
|
var path = require('node:path');
|
|
6
|
-
var persistence = require('./types-
|
|
7
|
-
var index = require('./index-
|
|
6
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
7
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
8
8
|
require('axios');
|
|
9
9
|
require('node:util');
|
|
10
10
|
require('node:os');
|
|
@@ -1,8 +1,8 @@
|
|
|
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, w as waitForSessionKey, b as sendUserMessage } from './index-
|
|
5
|
-
import { l as logger } from './types-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, w as waitForSessionKey, b as sendUserMessage } from './index-HYOkniru.mjs';
|
|
5
|
+
import { l as logger } from './types-BRDN6zN2.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
8
|
import 'cross-spawn';
|
|
@@ -3,8 +3,8 @@
|
|
|
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('./types-
|
|
6
|
+
var index = require('./index-BGvGqzc1.cjs');
|
|
7
|
+
var persistence = require('./types-Dy7P_1bh.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
10
|
require('cross-spawn');
|
|
@@ -29,7 +29,7 @@ import { SandboxManager } from '@anthropic-ai/sandbox-runtime';
|
|
|
29
29
|
import { Expo } from 'expo-server-sdk';
|
|
30
30
|
|
|
31
31
|
var name = "very-happy-cli";
|
|
32
|
-
var version = "0.2.
|
|
32
|
+
var version = "0.2.79";
|
|
33
33
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
34
34
|
var author = "Kirill Dubovitskiy";
|
|
35
35
|
var contributors = [
|
|
@@ -142,12 +142,12 @@ var dependencies = {
|
|
|
142
142
|
zod: "^4.0.0"
|
|
143
143
|
};
|
|
144
144
|
var optionalDependencies = {
|
|
145
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
146
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
147
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
148
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
149
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
150
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
145
|
+
"very-happy-tools-arm64-darwin": "0.2.79",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.79",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.79",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.79",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.79",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.79"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -672,6 +672,9 @@ const sessionTurnUsageSchema = z.object({
|
|
|
672
672
|
const sessionTurnEndEventSchema = z.object({
|
|
673
673
|
t: z.literal("turn-end"),
|
|
674
674
|
status: sessionTurnEndStatusSchema,
|
|
675
|
+
// Human-readable SDK failure detail. Optional for backward compatibility;
|
|
676
|
+
// successful and cancelled turns normally omit it.
|
|
677
|
+
error: z.string().optional(),
|
|
675
678
|
// Optional per-turn metadata sourced from the SDK result message. Present
|
|
676
679
|
// only on turns ended by a result event; absent on lazily-closed turns.
|
|
677
680
|
costUsd: z.number().optional(),
|
|
@@ -938,6 +941,9 @@ const CliUpdateStateSchema = z$1.object({
|
|
|
938
941
|
const WebTerminalListItemSchema = z$1.object({
|
|
939
942
|
id: z$1.string(),
|
|
940
943
|
title: z$1.string().optional(),
|
|
944
|
+
/** New daemons always send an array (including []); absence identifies an
|
|
945
|
+
* old daemon that cannot persist terminal tags. */
|
|
946
|
+
tags: z$1.array(z$1.string()).optional(),
|
|
941
947
|
cwd: z$1.string().optional(),
|
|
942
948
|
createdAt: z$1.number().optional(),
|
|
943
949
|
activityAt: z$1.number().optional(),
|
|
@@ -2444,12 +2450,14 @@ function closeTurn(state, status, envelopes, meta) {
|
|
|
2444
2450
|
envelopes.push(createEnvelope("agent", {
|
|
2445
2451
|
t: "turn-end",
|
|
2446
2452
|
status,
|
|
2453
|
+
...meta?.error ? { error: meta.error } : {},
|
|
2447
2454
|
...typeof meta?.costUsd === "number" ? { costUsd: meta.costUsd } : {},
|
|
2448
2455
|
...typeof meta?.durationMs === "number" ? { durationMs: meta.durationMs } : {},
|
|
2449
2456
|
...typeof meta?.numTurns === "number" ? { numTurns: meta.numTurns } : {},
|
|
2450
2457
|
...meta?.usage ? { usage: meta.usage } : {}
|
|
2451
2458
|
}, { turn: state.currentTurnId }));
|
|
2452
2459
|
state.currentTurnId = null;
|
|
2460
|
+
state.pendingAssistantError = void 0;
|
|
2453
2461
|
clearSubagentTracking(state);
|
|
2454
2462
|
}
|
|
2455
2463
|
function toolTitle(name, input) {
|
|
@@ -2470,9 +2478,9 @@ function toToolArgs(input) {
|
|
|
2470
2478
|
}
|
|
2471
2479
|
return { input };
|
|
2472
2480
|
}
|
|
2473
|
-
function closeClaudeTurnWithStatus(state, status) {
|
|
2481
|
+
function closeClaudeTurnWithStatus(state, status, meta) {
|
|
2474
2482
|
const envelopes = [];
|
|
2475
|
-
closeTurn(state, status, envelopes);
|
|
2483
|
+
closeTurn(state, status, envelopes, meta);
|
|
2476
2484
|
return {
|
|
2477
2485
|
currentTurnId: state.currentTurnId,
|
|
2478
2486
|
envelopes
|
|
@@ -2513,6 +2521,10 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2513
2521
|
};
|
|
2514
2522
|
}
|
|
2515
2523
|
if (message.type === "assistant") {
|
|
2524
|
+
const assistantError = message.error;
|
|
2525
|
+
if (!message.isSidechain && typeof assistantError === "string" && assistantError.trim()) {
|
|
2526
|
+
state.pendingAssistantError = assistantError.trim();
|
|
2527
|
+
}
|
|
2516
2528
|
const turnId = ensureTurn(state, envelopes);
|
|
2517
2529
|
maybeEmitSubagentStart(state, turnId, subagent, envelopes);
|
|
2518
2530
|
const usage = pickAssistantUsage(message);
|
|
@@ -2634,6 +2646,10 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2634
2646
|
if (message.type === "result") {
|
|
2635
2647
|
const raw = message;
|
|
2636
2648
|
const status = raw.is_error === true ? "failed" : "completed";
|
|
2649
|
+
const error = status === "failed" ? raw.errors?.filter((item) => typeof item === "string" && item.trim()).join("\n") || state.pendingAssistantError || raw.subtype || "Claude turn failed" : void 0;
|
|
2650
|
+
if (status === "failed" && !state.currentTurnId) {
|
|
2651
|
+
ensureTurn(state, envelopes);
|
|
2652
|
+
}
|
|
2637
2653
|
const usage = raw.usage && typeof raw.usage.input_tokens === "number" && typeof raw.usage.output_tokens === "number" ? {
|
|
2638
2654
|
input_tokens: raw.usage.input_tokens,
|
|
2639
2655
|
output_tokens: raw.usage.output_tokens,
|
|
@@ -2641,6 +2657,7 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
|
|
|
2641
2657
|
...typeof raw.usage.cache_read_input_tokens === "number" ? { cache_read_input_tokens: raw.usage.cache_read_input_tokens } : {}
|
|
2642
2658
|
} : void 0;
|
|
2643
2659
|
closeTurn(state, status, envelopes, {
|
|
2660
|
+
error,
|
|
2644
2661
|
costUsd: typeof raw.total_cost_usd === "number" ? raw.total_cost_usd : void 0,
|
|
2645
2662
|
durationMs: typeof raw.duration_ms === "number" ? raw.duration_ms : void 0,
|
|
2646
2663
|
numTurns: typeof raw.num_turns === "number" ? raw.num_turns : void 0,
|
|
@@ -3376,9 +3393,9 @@ class ApiSessionClient extends EventEmitter {
|
|
|
3376
3393
|
}));
|
|
3377
3394
|
}
|
|
3378
3395
|
}
|
|
3379
|
-
closeClaudeSessionTurn(status = "completed") {
|
|
3396
|
+
closeClaudeSessionTurn(status = "completed", meta) {
|
|
3380
3397
|
this.emit("turn-ended", status);
|
|
3381
|
-
const mapped = closeClaudeTurnWithStatus(this.claudeSessionProtocolState, status);
|
|
3398
|
+
const mapped = closeClaudeTurnWithStatus(this.claudeSessionProtocolState, status, meta);
|
|
3382
3399
|
this.claudeSessionProtocolState.currentTurnId = mapped.currentTurnId;
|
|
3383
3400
|
for (const envelope of mapped.envelopes) {
|
|
3384
3401
|
this.sendSessionProtocolMessage(envelope);
|
|
@@ -9786,6 +9803,7 @@ function terminalListSignature(items) {
|
|
|
9786
9803
|
const canon = [...items].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0).map((t) => [
|
|
9787
9804
|
t.id,
|
|
9788
9805
|
t.title ?? "",
|
|
9806
|
+
t.tags ?? [],
|
|
9789
9807
|
t.cwd ?? "",
|
|
9790
9808
|
t.createdAt ?? 0,
|
|
9791
9809
|
Math.floor((t.activityAt ?? 0) / ACTIVITY_SIGNATURE_BUCKET_MS),
|
|
@@ -9819,6 +9837,7 @@ const LIST_SESSIONS_FORMAT = [
|
|
|
9819
9837
|
"#{pane_current_path}",
|
|
9820
9838
|
"#{@vh_title}",
|
|
9821
9839
|
"#{@vh_title_manual}",
|
|
9840
|
+
"#{@vh_tags}",
|
|
9822
9841
|
// B-121: the control-mode client has no `pty.process`, so the agent-state
|
|
9823
9842
|
// fast path lost its live `#{pane_current_command}` equivalent. Carry it in
|
|
9824
9843
|
// the ONE list-sessions call the tracker already makes — the value goes
|
|
@@ -9833,8 +9852,8 @@ const LIST_SESSIONS_FORMAT = [
|
|
|
9833
9852
|
function parseSessionListLine(line) {
|
|
9834
9853
|
if (!line) return void 0;
|
|
9835
9854
|
const parts = line.split(LIST_FIELD_SEP);
|
|
9836
|
-
if (parts.length <
|
|
9837
|
-
const [name, created, activity, cwd, vhTitle, manual, paneCommand] = parts;
|
|
9855
|
+
if (parts.length < 9) return void 0;
|
|
9856
|
+
const [name, created, activity, cwd, vhTitle, manual, vhTags, paneCommand] = parts;
|
|
9838
9857
|
if (!name) return void 0;
|
|
9839
9858
|
return {
|
|
9840
9859
|
name,
|
|
@@ -9843,12 +9862,40 @@ function parseSessionListLine(line) {
|
|
|
9843
9862
|
cwd: cwd || void 0,
|
|
9844
9863
|
vhTitle: vhTitle.trim() || void 0,
|
|
9845
9864
|
manual: manual.trim().length > 0,
|
|
9865
|
+
tags: parseTerminalTags(vhTags),
|
|
9846
9866
|
paneCurrentCommand: paneCommand.trim() || void 0,
|
|
9847
9867
|
// pane_title is last, so anything after field 8 is title content that
|
|
9848
9868
|
// contained the separator — rejoin it rather than dropping it.
|
|
9849
|
-
paneTitle: parts.slice(
|
|
9869
|
+
paneTitle: parts.slice(8).join(LIST_FIELD_SEP) || void 0
|
|
9850
9870
|
};
|
|
9851
9871
|
}
|
|
9872
|
+
const TERMINAL_TAG_MAX_COUNT = 64;
|
|
9873
|
+
const TERMINAL_TAG_MAX_LENGTH = 24;
|
|
9874
|
+
const TERMINAL_TAGS_MAX_BYTES = 4096;
|
|
9875
|
+
function validateTerminalTags(value) {
|
|
9876
|
+
if (!Array.isArray(value) || value.length > TERMINAL_TAG_MAX_COUNT) return void 0;
|
|
9877
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9878
|
+
const out = [];
|
|
9879
|
+
for (const valueTag of value) {
|
|
9880
|
+
if (typeof valueTag !== "string") return void 0;
|
|
9881
|
+
const tag = valueTag.trim().replace(/^#+/, "").trim().replace(/\s+/g, "-").slice(0, TERMINAL_TAG_MAX_LENGTH);
|
|
9882
|
+
if (!tag || tag !== valueTag) return void 0;
|
|
9883
|
+
const key = tag.toLowerCase();
|
|
9884
|
+
if (seen.has(key)) return void 0;
|
|
9885
|
+
seen.add(key);
|
|
9886
|
+
out.push(tag);
|
|
9887
|
+
}
|
|
9888
|
+
if (Buffer.byteLength(JSON.stringify(out), "utf8") > TERMINAL_TAGS_MAX_BYTES) return void 0;
|
|
9889
|
+
return out;
|
|
9890
|
+
}
|
|
9891
|
+
function parseTerminalTags(raw) {
|
|
9892
|
+
if (typeof raw !== "string" || !raw.trim()) return [];
|
|
9893
|
+
try {
|
|
9894
|
+
return validateTerminalTags(JSON.parse(raw)) ?? [];
|
|
9895
|
+
} catch {
|
|
9896
|
+
return [];
|
|
9897
|
+
}
|
|
9898
|
+
}
|
|
9852
9899
|
function classifyPane(currentCommand, tail) {
|
|
9853
9900
|
const cmd = (currentCommand || "").trim().replace(/^-/, "").toLowerCase();
|
|
9854
9901
|
const isShell = SHELL_COMMANDS.has(cmd);
|
|
@@ -11281,6 +11328,8 @@ class WebTerminalManager {
|
|
|
11281
11328
|
out.push({
|
|
11282
11329
|
id,
|
|
11283
11330
|
title,
|
|
11331
|
+
// Always include [] so Web can feature-detect tag support.
|
|
11332
|
+
tags: s.tags,
|
|
11284
11333
|
cwd: s.cwd,
|
|
11285
11334
|
createdAt: s.created,
|
|
11286
11335
|
// tmux last-activity (epoch s) → ms; optional so old daemons
|
|
@@ -11458,6 +11507,25 @@ class WebTerminalManager {
|
|
|
11458
11507
|
return false;
|
|
11459
11508
|
}
|
|
11460
11509
|
}
|
|
11510
|
+
/** Persist terminal tags in tmux, parallel to @vh_title. */
|
|
11511
|
+
setTags(terminalId, tags) {
|
|
11512
|
+
if (!isTmuxAvailable()) return false;
|
|
11513
|
+
if (!/^[a-zA-Z0-9_-]{1,64}$/.test(terminalId)) return false;
|
|
11514
|
+
const valid = validateTerminalTags(tags);
|
|
11515
|
+
if (!valid) return false;
|
|
11516
|
+
const name = `vh-${terminalId}`;
|
|
11517
|
+
try {
|
|
11518
|
+
const r = spawnSync("tmux", ["set-option", "-t", name, "@vh_tags", JSON.stringify(valid)], {
|
|
11519
|
+
stdio: "ignore",
|
|
11520
|
+
env: ptyEnv()
|
|
11521
|
+
});
|
|
11522
|
+
if (r.status !== 0) return false;
|
|
11523
|
+
this.kickListRefresh();
|
|
11524
|
+
return true;
|
|
11525
|
+
} catch {
|
|
11526
|
+
return false;
|
|
11527
|
+
}
|
|
11528
|
+
}
|
|
11461
11529
|
}
|
|
11462
11530
|
|
|
11463
11531
|
const TMUX_TIMEOUT_MS = 3e3;
|
|
@@ -13406,6 +13474,16 @@ class ApiMachineClient {
|
|
|
13406
13474
|
}
|
|
13407
13475
|
return { type: "success" };
|
|
13408
13476
|
});
|
|
13477
|
+
this.rpcHandlerManager.registerHandler("set-terminal-tags", async (params) => {
|
|
13478
|
+
const { terminalId, tags } = params || {};
|
|
13479
|
+
if (!terminalId || !Array.isArray(tags)) {
|
|
13480
|
+
throw new Error("terminalId and tags are required");
|
|
13481
|
+
}
|
|
13482
|
+
if (!this.webTerminal.setTags(terminalId, tags)) {
|
|
13483
|
+
throw new Error("Failed to set terminal tags (invalid tags, tmux unavailable, or session gone)");
|
|
13484
|
+
}
|
|
13485
|
+
return { type: "success" };
|
|
13486
|
+
});
|
|
13409
13487
|
this.rpcHandlerManager.registerHandler("stop-session", (params) => {
|
|
13410
13488
|
const { sessionId } = params || {};
|
|
13411
13489
|
if (!sessionId) {
|