very-happy-cli 0.2.109 → 0.2.111
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-Cc4Ilypg.cjs → AcpBackend-B_olk79F.cjs} +1 -1
- package/dist/{AcpBackend-DOzPxcth.mjs → AcpBackend-CeXVb_s_.mjs} +1 -1
- package/dist/{AcpSessionManager-CLfzatC_.cjs → AcpSessionManager-uXwWO2Tn.cjs} +1 -1
- package/dist/{AcpSessionManager-DDN-Yir4.mjs → AcpSessionManager-vqdqfD1l.mjs} +1 -1
- package/dist/{config-DiVKfYr0.cjs → config-BR3tkFL_.cjs} +2 -2
- package/dist/{config-DnvzvFHR.mjs → config-vGkcq9nM.mjs} +2 -2
- package/dist/{index-dd2R8uSE.cjs → index-BOoGJGQc.cjs} +90 -21
- package/dist/{index-DO-9Ep72.mjs → index-Bn-xsguz.mjs} +85 -18
- package/dist/{index-CGKxZKlo.mjs → index-C-RLk8-e.mjs} +2 -2
- package/dist/{index-D2qU5HP4.cjs → index-CtBP0Qvc.cjs} +4 -4
- package/dist/{index-DaQIcHvY.mjs → index-JAhGeW4_.mjs} +5 -5
- package/dist/{index-B2U15moC.cjs → index-SjthsMid.cjs} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +2 -2
- package/dist/{installTerminalHooks-BDagPTQW.mjs → installTerminalHooks-ADNcNdnB.mjs} +2 -2
- package/dist/{installTerminalHooks-BoUmuYdq.cjs → installTerminalHooks-FbKaK149.cjs} +2 -2
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{mcp-Ck_y0mCB.mjs → mcp-DHPm_gvL.mjs} +2 -2
- package/dist/{mcp-Du1QEnIf.cjs → mcp-DPp-bYNE.cjs} +2 -2
- package/dist/{runGemini-D20S6Lc3.mjs → runGemini-CWWyjQMz.mjs} +4 -4
- package/dist/{runGemini-DV2M0A_k.cjs → runGemini-D5ySpYIZ.cjs} +4 -4
- package/dist/{runOpenClaw-CuuXkfDE.mjs → runOpenClaw-Bv4rUTyJ.mjs} +3 -3
- package/dist/{runOpenClaw-C1Q2zl--.cjs → runOpenClaw-Bwrb1LXP.cjs} +3 -3
- package/dist/{send-yUiBqHHL.mjs → send-BlkxFZu4.mjs} +2 -2
- package/dist/{send-CtgnnJic.cjs → send-DBfSNILO.cjs} +2 -2
- package/dist/{sessions-BsaCq0Do.mjs → sessions-1fW8soBM.mjs} +2 -2
- package/dist/{sessions-CbbZhOTy.cjs → sessions-CVuEsdRl.cjs} +2 -2
- package/dist/{spawn-BKBY9P3J.mjs → spawn-BorKN3W2.mjs} +56 -5
- package/dist/{spawn-CTO_hR8v.cjs → spawn-D_ZexrY9.cjs} +57 -4
- package/dist/{types-Cg8zzX_f.cjs → types-BG_5QKX5.cjs} +18 -10
- package/dist/{types-BKCvo4Cv.mjs → types-k_ipDb0c.mjs} +17 -9
- package/package.json +7 -7
|
@@ -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, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-CeXVb_s_.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-CeXVb_s_.mjs';
|
|
3
|
+
import { h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-k_ipDb0c.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-vqdqfD1l.mjs';
|
|
5
5
|
import { randomUUID } from 'node:crypto';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, u as startHappyServer, v as registerKillSessionHandler, B as BasePermissionHandler } from './index-Bn-xsguz.mjs';
|
|
8
8
|
import 'node:child_process';
|
|
9
9
|
import '@agentclientprotocol/sdk';
|
|
10
10
|
import 'axios';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-BOoGJGQc.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-BG_5QKX5.cjs');
|
|
9
9
|
require('axios');
|
|
10
10
|
require('node:util');
|
|
11
11
|
require('node:fs');
|
package/dist/index.cjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { join, resolve } from 'node:path';
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { spawnSync } from 'node:child_process';
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
-
import { p as projectPath } from './types-
|
|
7
|
-
import { t as tmuxSupportsSessionEnv } from './index-
|
|
6
|
+
import { p as projectPath } from './types-k_ipDb0c.mjs';
|
|
7
|
+
import { t as tmuxSupportsSessionEnv } from './index-Bn-xsguz.mjs';
|
|
8
8
|
import 'axios';
|
|
9
9
|
import 'node:util';
|
|
10
10
|
import 'node:fs/promises';
|
|
@@ -5,8 +5,8 @@ var path = require('node:path');
|
|
|
5
5
|
var os = require('node:os');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var chalk = require('chalk');
|
|
8
|
-
var persistence = require('./types-
|
|
9
|
-
var index = require('./index-
|
|
8
|
+
var persistence = require('./types-BG_5QKX5.cjs');
|
|
9
|
+
var index = require('./index-BOoGJGQc.cjs');
|
|
10
10
|
require('axios');
|
|
11
11
|
require('node:util');
|
|
12
12
|
require('node:fs/promises');
|
package/dist/lib.cjs
CHANGED
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-k_ipDb0c.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'node:util';
|
|
@@ -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-Bn-xsguz.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-k_ipDb0c.mjs';
|
|
7
7
|
import 'chalk';
|
|
8
8
|
import 'node:os';
|
|
9
9
|
import 'node:crypto';
|
|
@@ -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-BOoGJGQc.cjs');
|
|
7
7
|
var limits = require('./limits-KdWKmwtH.cjs');
|
|
8
|
-
var persistence = require('./types-
|
|
8
|
+
var persistence = require('./types-BG_5QKX5.cjs');
|
|
9
9
|
require('chalk');
|
|
10
10
|
require('node:os');
|
|
11
11
|
require('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, j as readSettings, e as errorLogMetadata, k as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-
|
|
6
|
-
import {
|
|
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, j as readSettings, e as errorLogMetadata, k as encodeBase64, p as projectPath, d as contentLogMetadata } from './types-k_ipDb0c.mjs';
|
|
6
|
+
import { x as GEMINI_API_KEY_ENV, y as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, B as BasePermissionHandler, z as BaseReasoningProcessor, h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, o as hashObject, C as MessageBuffer, E as CHANGE_TITLE_INSTRUCTION, v as registerKillSessionHandler, u as startHappyServer } from './index-Bn-xsguz.mjs';
|
|
7
|
+
import { A as AcpBackend } from './AcpBackend-CeXVb_s_.mjs';
|
|
8
|
+
import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-vGkcq9nM.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-BG_5QKX5.cjs');
|
|
8
|
+
var index = require('./index-BOoGJGQc.cjs');
|
|
9
|
+
var AcpBackend = require('./AcpBackend-B_olk79F.cjs');
|
|
10
|
+
var config = require('./config-BR3tkFL_.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 { m as ensurePrivateDirectorySync, n as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, c as configuration } from './types-
|
|
7
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
8
|
-
import {
|
|
6
|
+
import { m as ensurePrivateDirectorySync, n as hardenPrivateFileSync, w as writePrivateFileSync, e as errorLogMetadata, d as contentLogMetadata, h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, c as configuration } from './types-k_ipDb0c.mjs';
|
|
7
|
+
import { A as AcpSessionManager } from './AcpSessionManager-vqdqfD1l.mjs';
|
|
8
|
+
import { h as initialMachineMetadata, j as createSessionMetadata, k as setupOfflineReconnection, n as notifyDaemonSessionStarted, m as MessageQueue2, v as registerKillSessionHandler } from './index-Bn-xsguz.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-BG_5QKX5.cjs');
|
|
9
|
+
var AcpSessionManager = require('./AcpSessionManager-uXwWO2Tn.cjs');
|
|
10
|
+
var index = require('./index-BOoGJGQc.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 {
|
|
4
|
+
import { r as readPersistedSessions, c as configuration } from './types-k_ipDb0c.mjs';
|
|
5
|
+
import { d as sendUserMessage, a as sessionWebUrl } from './index-Bn-xsguz.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-BG_5QKX5.cjs');
|
|
7
|
+
var index = require('./index-BOoGJGQc.cjs');
|
|
8
8
|
require('axios');
|
|
9
9
|
require('node:util');
|
|
10
10
|
require('node:os');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listSessions, r as readSessionTranscript,
|
|
3
|
-
import { i as isValidSessionId } from './types-
|
|
2
|
+
import { D as DEFAULT_RECENT_LIMIT, M as MAX_READ_LIMIT, l as listSessions, r as readSessionTranscript, e as stopSession, f as archiveSession } from './index-Bn-xsguz.mjs';
|
|
3
|
+
import { i as isValidSessionId } from './types-k_ipDb0c.mjs';
|
|
4
4
|
import 'node:os';
|
|
5
5
|
import 'node:crypto';
|
|
6
6
|
import 'cross-spawn';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var index = require('./index-
|
|
5
|
-
var persistence = require('./types-
|
|
4
|
+
var index = require('./index-BOoGJGQc.cjs');
|
|
5
|
+
var persistence = require('./types-BG_5QKX5.cjs');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
8
|
require('cross-spawn');
|
|
@@ -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, i as isValidSpawnOrigin, w as waitForSessionKey,
|
|
5
|
-
import { l as logger } from './types-
|
|
4
|
+
import { c as checkIfDaemonRunningAndCleanupStaleState, s as spawnDaemonSession, a as sessionWebUrl, i as isValidSpawnOrigin, b as sanitizeSpawnPermissionMode, A as ALLOWED_SPAWN_PERMISSION_MODES, w as waitForSessionKey, d as sendUserMessage } from './index-Bn-xsguz.mjs';
|
|
5
|
+
import { l as logger } from './types-k_ipDb0c.mjs';
|
|
6
6
|
import 'node:os';
|
|
7
7
|
import 'node:crypto';
|
|
8
8
|
import 'cross-spawn';
|
|
@@ -46,6 +46,14 @@ import 'node:util';
|
|
|
46
46
|
import 'url';
|
|
47
47
|
import 'node-pty';
|
|
48
48
|
|
|
49
|
+
const SPAWN_AGENTS = ["claude", "codex", "gemini", "openclaw"];
|
|
50
|
+
function parseEnvAssignment(raw) {
|
|
51
|
+
const eq = raw.indexOf("=");
|
|
52
|
+
if (eq <= 0) throw new Error(`--env expects KEY=VALUE, got: ${raw}`);
|
|
53
|
+
const key = raw.slice(0, eq);
|
|
54
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`--env key is not a valid variable name: ${key}`);
|
|
55
|
+
return [key, raw.slice(eq + 1)];
|
|
56
|
+
}
|
|
49
57
|
function parseSpawnArgs(args) {
|
|
50
58
|
const options = { json: false, help: false };
|
|
51
59
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -69,6 +77,25 @@ function parseSpawnArgs(args) {
|
|
|
69
77
|
throw new Error("--spawned-by must be 1-24 chars of [a-z0-9] plus - or _, starting with a letter or digit");
|
|
70
78
|
}
|
|
71
79
|
options.spawnedBy = value;
|
|
80
|
+
} else if (arg === "--permission-mode") {
|
|
81
|
+
const value = args[++i];
|
|
82
|
+
if (value === void 0) throw new Error("--permission-mode requires a value");
|
|
83
|
+
if (sanitizeSpawnPermissionMode(value) === null) {
|
|
84
|
+
throw new Error(`--permission-mode must be one of: ${ALLOWED_SPAWN_PERMISSION_MODES.join(", ")}`);
|
|
85
|
+
}
|
|
86
|
+
options.permissionMode = value;
|
|
87
|
+
} else if (arg === "--agent") {
|
|
88
|
+
const value = args[++i];
|
|
89
|
+
if (value === void 0) throw new Error("--agent requires a value");
|
|
90
|
+
if (!SPAWN_AGENTS.includes(value)) {
|
|
91
|
+
throw new Error(`--agent must be one of: ${SPAWN_AGENTS.join(", ")}`);
|
|
92
|
+
}
|
|
93
|
+
options.agent = value;
|
|
94
|
+
} else if (arg === "--env") {
|
|
95
|
+
const value = args[++i];
|
|
96
|
+
if (value === void 0) throw new Error("--env requires a value");
|
|
97
|
+
const [key, val] = parseEnvAssignment(value);
|
|
98
|
+
options.env = { ...options.env ?? {}, [key]: val };
|
|
72
99
|
} else if (arg === "--json") {
|
|
73
100
|
options.json = true;
|
|
74
101
|
} else if (arg === "--help" || arg === "-h") {
|
|
@@ -87,7 +114,9 @@ function printHelp() {
|
|
|
87
114
|
${chalk.bold("very-happy spawn")} - Spawn a remote session via the local daemon (for automation)
|
|
88
115
|
|
|
89
116
|
${chalk.bold("Usage:")}
|
|
90
|
-
very-happy spawn --dir <path> [--prompt <text> | --prompt-file <file>]
|
|
117
|
+
very-happy spawn --dir <path> [--prompt <text> | --prompt-file <file>]
|
|
118
|
+
[--spawned-by <name>] [--permission-mode <mode>]
|
|
119
|
+
[--agent <name>] [--env KEY=VALUE]... [--json]
|
|
91
120
|
|
|
92
121
|
${chalk.bold("Options:")}
|
|
93
122
|
--dir, -d <path> Working directory for the new session (required)
|
|
@@ -96,6 +125,17 @@ ${chalk.bold("Options:")}
|
|
|
96
125
|
--spawned-by <name> Tag the new session with its origin (e.g. tanka).
|
|
97
126
|
1-24 chars: [a-z0-9] plus - or _. Shows as a chip in
|
|
98
127
|
the web list and is searchable as #<name>.
|
|
128
|
+
--permission-mode <m> Permission mode for the new session: default,
|
|
129
|
+
acceptEdits, plan, yolo, bypassPermissions.
|
|
130
|
+
WITHOUT this the session runs in 'default' and stops
|
|
131
|
+
at the first un-allowlisted tool waiting for someone
|
|
132
|
+
to approve \u2014 if nothing is watching, it just hangs.
|
|
133
|
+
Unattended dispatchers want bypassPermissions.
|
|
134
|
+
--agent <name> Backend to run: claude (default), codex, gemini,
|
|
135
|
+
openclaw.
|
|
136
|
+
--env KEY=VALUE Extra environment for the session process. Repeatable.
|
|
137
|
+
\${VAR} is expanded against the daemon's environment;
|
|
138
|
+
an unresolved reference fails the spawn.
|
|
99
139
|
--json Machine-readable output: {"sessionId", "url"}
|
|
100
140
|
-h, --help Show this help
|
|
101
141
|
|
|
@@ -161,7 +201,12 @@ async function handleSpawnCommand(args) {
|
|
|
161
201
|
process.exit(1);
|
|
162
202
|
}
|
|
163
203
|
logger.debug(`[SPAWN CMD] Spawning session in ${directory}`);
|
|
164
|
-
const result = await spawnDaemonSession(directory, void 0, {
|
|
204
|
+
const result = await spawnDaemonSession(directory, void 0, {
|
|
205
|
+
spawnedBy: options.spawnedBy,
|
|
206
|
+
permissionMode: options.permissionMode,
|
|
207
|
+
agent: options.agent,
|
|
208
|
+
environmentVariables: options.env
|
|
209
|
+
});
|
|
165
210
|
if (result?.error || !result?.success || !result?.sessionId) {
|
|
166
211
|
const message = result?.error || "Daemon returned no session ID";
|
|
167
212
|
console.error(chalk.red("Error:"), `Failed to spawn session: ${message}`);
|
|
@@ -182,6 +227,12 @@ async function handleSpawnCommand(args) {
|
|
|
182
227
|
if (options.spawnedBy !== void 0) {
|
|
183
228
|
payload.spawnedBy = options.spawnedBy;
|
|
184
229
|
}
|
|
230
|
+
if (options.permissionMode !== void 0) {
|
|
231
|
+
payload.permissionMode = options.permissionMode;
|
|
232
|
+
}
|
|
233
|
+
if (options.agent !== void 0) {
|
|
234
|
+
payload.agent = options.agent;
|
|
235
|
+
}
|
|
185
236
|
if (prompt !== void 0) {
|
|
186
237
|
payload.promptDelivered = promptError === null;
|
|
187
238
|
}
|
|
@@ -204,4 +255,4 @@ async function handleSpawnCommand(args) {
|
|
|
204
255
|
process.exit(0);
|
|
205
256
|
}
|
|
206
257
|
|
|
207
|
-
export { handleSpawnCommand, parseSpawnArgs, sessionWebUrl };
|
|
258
|
+
export { SPAWN_AGENTS, handleSpawnCommand, parseEnvAssignment, parseSpawnArgs, sessionWebUrl };
|
|
@@ -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-BOoGJGQc.cjs');
|
|
7
|
+
var persistence = require('./types-BG_5QKX5.cjs');
|
|
8
8
|
require('node:os');
|
|
9
9
|
require('node:crypto');
|
|
10
10
|
require('cross-spawn');
|
|
@@ -48,6 +48,14 @@ require('node:util');
|
|
|
48
48
|
require('url');
|
|
49
49
|
require('node-pty');
|
|
50
50
|
|
|
51
|
+
const SPAWN_AGENTS = ["claude", "codex", "gemini", "openclaw"];
|
|
52
|
+
function parseEnvAssignment(raw) {
|
|
53
|
+
const eq = raw.indexOf("=");
|
|
54
|
+
if (eq <= 0) throw new Error(`--env expects KEY=VALUE, got: ${raw}`);
|
|
55
|
+
const key = raw.slice(0, eq);
|
|
56
|
+
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) throw new Error(`--env key is not a valid variable name: ${key}`);
|
|
57
|
+
return [key, raw.slice(eq + 1)];
|
|
58
|
+
}
|
|
51
59
|
function parseSpawnArgs(args) {
|
|
52
60
|
const options = { json: false, help: false };
|
|
53
61
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -71,6 +79,25 @@ function parseSpawnArgs(args) {
|
|
|
71
79
|
throw new Error("--spawned-by must be 1-24 chars of [a-z0-9] plus - or _, starting with a letter or digit");
|
|
72
80
|
}
|
|
73
81
|
options.spawnedBy = value;
|
|
82
|
+
} else if (arg === "--permission-mode") {
|
|
83
|
+
const value = args[++i];
|
|
84
|
+
if (value === void 0) throw new Error("--permission-mode requires a value");
|
|
85
|
+
if (index.sanitizeSpawnPermissionMode(value) === null) {
|
|
86
|
+
throw new Error(`--permission-mode must be one of: ${index.ALLOWED_SPAWN_PERMISSION_MODES.join(", ")}`);
|
|
87
|
+
}
|
|
88
|
+
options.permissionMode = value;
|
|
89
|
+
} else if (arg === "--agent") {
|
|
90
|
+
const value = args[++i];
|
|
91
|
+
if (value === void 0) throw new Error("--agent requires a value");
|
|
92
|
+
if (!SPAWN_AGENTS.includes(value)) {
|
|
93
|
+
throw new Error(`--agent must be one of: ${SPAWN_AGENTS.join(", ")}`);
|
|
94
|
+
}
|
|
95
|
+
options.agent = value;
|
|
96
|
+
} else if (arg === "--env") {
|
|
97
|
+
const value = args[++i];
|
|
98
|
+
if (value === void 0) throw new Error("--env requires a value");
|
|
99
|
+
const [key, val] = parseEnvAssignment(value);
|
|
100
|
+
options.env = { ...options.env ?? {}, [key]: val };
|
|
74
101
|
} else if (arg === "--json") {
|
|
75
102
|
options.json = true;
|
|
76
103
|
} else if (arg === "--help" || arg === "-h") {
|
|
@@ -89,7 +116,9 @@ function printHelp() {
|
|
|
89
116
|
${chalk.bold("very-happy spawn")} - Spawn a remote session via the local daemon (for automation)
|
|
90
117
|
|
|
91
118
|
${chalk.bold("Usage:")}
|
|
92
|
-
very-happy spawn --dir <path> [--prompt <text> | --prompt-file <file>]
|
|
119
|
+
very-happy spawn --dir <path> [--prompt <text> | --prompt-file <file>]
|
|
120
|
+
[--spawned-by <name>] [--permission-mode <mode>]
|
|
121
|
+
[--agent <name>] [--env KEY=VALUE]... [--json]
|
|
93
122
|
|
|
94
123
|
${chalk.bold("Options:")}
|
|
95
124
|
--dir, -d <path> Working directory for the new session (required)
|
|
@@ -98,6 +127,17 @@ ${chalk.bold("Options:")}
|
|
|
98
127
|
--spawned-by <name> Tag the new session with its origin (e.g. tanka).
|
|
99
128
|
1-24 chars: [a-z0-9] plus - or _. Shows as a chip in
|
|
100
129
|
the web list and is searchable as #<name>.
|
|
130
|
+
--permission-mode <m> Permission mode for the new session: default,
|
|
131
|
+
acceptEdits, plan, yolo, bypassPermissions.
|
|
132
|
+
WITHOUT this the session runs in 'default' and stops
|
|
133
|
+
at the first un-allowlisted tool waiting for someone
|
|
134
|
+
to approve \u2014 if nothing is watching, it just hangs.
|
|
135
|
+
Unattended dispatchers want bypassPermissions.
|
|
136
|
+
--agent <name> Backend to run: claude (default), codex, gemini,
|
|
137
|
+
openclaw.
|
|
138
|
+
--env KEY=VALUE Extra environment for the session process. Repeatable.
|
|
139
|
+
\${VAR} is expanded against the daemon's environment;
|
|
140
|
+
an unresolved reference fails the spawn.
|
|
101
141
|
--json Machine-readable output: {"sessionId", "url"}
|
|
102
142
|
-h, --help Show this help
|
|
103
143
|
|
|
@@ -163,7 +203,12 @@ async function handleSpawnCommand(args) {
|
|
|
163
203
|
process.exit(1);
|
|
164
204
|
}
|
|
165
205
|
persistence.logger.debug(`[SPAWN CMD] Spawning session in ${directory}`);
|
|
166
|
-
const result = await index.spawnDaemonSession(directory, void 0, {
|
|
206
|
+
const result = await index.spawnDaemonSession(directory, void 0, {
|
|
207
|
+
spawnedBy: options.spawnedBy,
|
|
208
|
+
permissionMode: options.permissionMode,
|
|
209
|
+
agent: options.agent,
|
|
210
|
+
environmentVariables: options.env
|
|
211
|
+
});
|
|
167
212
|
if (result?.error || !result?.success || !result?.sessionId) {
|
|
168
213
|
const message = result?.error || "Daemon returned no session ID";
|
|
169
214
|
console.error(chalk.red("Error:"), `Failed to spawn session: ${message}`);
|
|
@@ -184,6 +229,12 @@ async function handleSpawnCommand(args) {
|
|
|
184
229
|
if (options.spawnedBy !== void 0) {
|
|
185
230
|
payload.spawnedBy = options.spawnedBy;
|
|
186
231
|
}
|
|
232
|
+
if (options.permissionMode !== void 0) {
|
|
233
|
+
payload.permissionMode = options.permissionMode;
|
|
234
|
+
}
|
|
235
|
+
if (options.agent !== void 0) {
|
|
236
|
+
payload.agent = options.agent;
|
|
237
|
+
}
|
|
187
238
|
if (prompt !== void 0) {
|
|
188
239
|
payload.promptDelivered = promptError === null;
|
|
189
240
|
}
|
|
@@ -207,5 +258,7 @@ async function handleSpawnCommand(args) {
|
|
|
207
258
|
}
|
|
208
259
|
|
|
209
260
|
exports.sessionWebUrl = index.sessionWebUrl;
|
|
261
|
+
exports.SPAWN_AGENTS = SPAWN_AGENTS;
|
|
210
262
|
exports.handleSpawnCommand = handleSpawnCommand;
|
|
263
|
+
exports.parseEnvAssignment = parseEnvAssignment;
|
|
211
264
|
exports.parseSpawnArgs = parseSpawnArgs;
|
|
@@ -51,7 +51,7 @@ var z__namespace = /*#__PURE__*/_interopNamespaceDefault(z);
|
|
|
51
51
|
var pty__namespace = /*#__PURE__*/_interopNamespaceDefault(pty);
|
|
52
52
|
|
|
53
53
|
var name = "very-happy-cli";
|
|
54
|
-
var version = "0.2.
|
|
54
|
+
var version = "0.2.111";
|
|
55
55
|
var description = "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.";
|
|
56
56
|
var author = "Kirill Dubovitskiy";
|
|
57
57
|
var contributors = [
|
|
@@ -164,12 +164,12 @@ var dependencies = {
|
|
|
164
164
|
zod: "^4.0.0"
|
|
165
165
|
};
|
|
166
166
|
var optionalDependencies = {
|
|
167
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
168
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
169
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
170
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
171
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
172
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
167
|
+
"very-happy-tools-arm64-darwin": "0.2.111",
|
|
168
|
+
"very-happy-tools-x64-darwin": "0.2.111",
|
|
169
|
+
"very-happy-tools-arm64-linux": "0.2.111",
|
|
170
|
+
"very-happy-tools-x64-linux": "0.2.111",
|
|
171
|
+
"very-happy-tools-arm64-win32": "0.2.111",
|
|
172
|
+
"very-happy-tools-x64-win32": "0.2.111"
|
|
173
173
|
};
|
|
174
174
|
var devDependencies = {
|
|
175
175
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -1603,7 +1603,7 @@ class RpcHandlerManager {
|
|
|
1603
1603
|
}
|
|
1604
1604
|
}
|
|
1605
1605
|
|
|
1606
|
-
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-
|
|
1606
|
+
const __dirname$1 = path$1.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('types-BG_5QKX5.cjs', document.baseURI).href))));
|
|
1607
1607
|
function projectPath() {
|
|
1608
1608
|
const path = path$1.resolve(__dirname$1, "..");
|
|
1609
1609
|
return path;
|
|
@@ -15778,6 +15778,13 @@ class NotificationProducer {
|
|
|
15778
15778
|
}
|
|
15779
15779
|
const DEDUP_WINDOW_MS = 3e3;
|
|
15780
15780
|
|
|
15781
|
+
function describeSessionCreateError(error) {
|
|
15782
|
+
const base = error instanceof Error ? error.message : "Unknown error";
|
|
15783
|
+
if (!axios.isAxiosError(error) || !error.response) return base;
|
|
15784
|
+
const data = error.response.data;
|
|
15785
|
+
const code = data && typeof data === "object" && typeof data.error === "string" ? data.error : null;
|
|
15786
|
+
return code ? `${base} (${code})` : base;
|
|
15787
|
+
}
|
|
15781
15788
|
class ApiClient {
|
|
15782
15789
|
static async create(credential) {
|
|
15783
15790
|
return new ApiClient(credential);
|
|
@@ -15873,7 +15880,7 @@ class ApiClient {
|
|
|
15873
15880
|
return null;
|
|
15874
15881
|
}
|
|
15875
15882
|
}
|
|
15876
|
-
throw new Error(`Failed to get or create session: ${error
|
|
15883
|
+
throw new Error(`Failed to get or create session: ${describeSessionCreateError(error)}`);
|
|
15877
15884
|
}
|
|
15878
15885
|
}
|
|
15879
15886
|
/**
|
|
@@ -16252,7 +16259,8 @@ class ApiClient {
|
|
|
16252
16259
|
|
|
16253
16260
|
var api = /*#__PURE__*/Object.freeze({
|
|
16254
16261
|
__proto__: null,
|
|
16255
|
-
ApiClient: ApiClient
|
|
16262
|
+
ApiClient: ApiClient,
|
|
16263
|
+
describeSessionCreateError: describeSessionCreateError
|
|
16256
16264
|
});
|
|
16257
16265
|
|
|
16258
16266
|
const UsageSchema = z.z.object({
|
|
@@ -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.111";
|
|
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.111",
|
|
146
|
+
"very-happy-tools-x64-darwin": "0.2.111",
|
|
147
|
+
"very-happy-tools-arm64-linux": "0.2.111",
|
|
148
|
+
"very-happy-tools-x64-linux": "0.2.111",
|
|
149
|
+
"very-happy-tools-arm64-win32": "0.2.111",
|
|
150
|
+
"very-happy-tools-x64-win32": "0.2.111"
|
|
151
151
|
};
|
|
152
152
|
var devDependencies = {
|
|
153
153
|
"@slopus/happy-wire": "workspace:*",
|
|
@@ -15756,6 +15756,13 @@ class NotificationProducer {
|
|
|
15756
15756
|
}
|
|
15757
15757
|
const DEDUP_WINDOW_MS = 3e3;
|
|
15758
15758
|
|
|
15759
|
+
function describeSessionCreateError(error) {
|
|
15760
|
+
const base = error instanceof Error ? error.message : "Unknown error";
|
|
15761
|
+
if (!axios.isAxiosError(error) || !error.response) return base;
|
|
15762
|
+
const data = error.response.data;
|
|
15763
|
+
const code = data && typeof data === "object" && typeof data.error === "string" ? data.error : null;
|
|
15764
|
+
return code ? `${base} (${code})` : base;
|
|
15765
|
+
}
|
|
15759
15766
|
class ApiClient {
|
|
15760
15767
|
static async create(credential) {
|
|
15761
15768
|
return new ApiClient(credential);
|
|
@@ -15851,7 +15858,7 @@ class ApiClient {
|
|
|
15851
15858
|
return null;
|
|
15852
15859
|
}
|
|
15853
15860
|
}
|
|
15854
|
-
throw new Error(`Failed to get or create session: ${error
|
|
15861
|
+
throw new Error(`Failed to get or create session: ${describeSessionCreateError(error)}`);
|
|
15855
15862
|
}
|
|
15856
15863
|
}
|
|
15857
15864
|
/**
|
|
@@ -16230,7 +16237,8 @@ class ApiClient {
|
|
|
16230
16237
|
|
|
16231
16238
|
var api = /*#__PURE__*/Object.freeze({
|
|
16232
16239
|
__proto__: null,
|
|
16233
|
-
ApiClient: ApiClient
|
|
16240
|
+
ApiClient: ApiClient,
|
|
16241
|
+
describeSessionCreateError: describeSessionCreateError
|
|
16234
16242
|
});
|
|
16235
16243
|
|
|
16236
16244
|
const UsageSchema = z$1.object({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "very-happy-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.111",
|
|
4
4
|
"description": "Remote multi-agent workspace CLI with deep Claude integration, native terminal streaming, and self-hosting.",
|
|
5
5
|
"author": "Kirill Dubovitskiy",
|
|
6
6
|
"contributors": [
|
|
@@ -113,12 +113,12 @@
|
|
|
113
113
|
"zod": "^4.0.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"very-happy-tools-arm64-darwin": "0.2.
|
|
117
|
-
"very-happy-tools-x64-darwin": "0.2.
|
|
118
|
-
"very-happy-tools-arm64-linux": "0.2.
|
|
119
|
-
"very-happy-tools-x64-linux": "0.2.
|
|
120
|
-
"very-happy-tools-arm64-win32": "0.2.
|
|
121
|
-
"very-happy-tools-x64-win32": "0.2.
|
|
116
|
+
"very-happy-tools-arm64-darwin": "0.2.111",
|
|
117
|
+
"very-happy-tools-x64-darwin": "0.2.111",
|
|
118
|
+
"very-happy-tools-arm64-linux": "0.2.111",
|
|
119
|
+
"very-happy-tools-x64-linux": "0.2.111",
|
|
120
|
+
"very-happy-tools-arm64-win32": "0.2.111",
|
|
121
|
+
"very-happy-tools-x64-win32": "0.2.111"
|
|
122
122
|
},
|
|
123
123
|
"devDependencies": {
|
|
124
124
|
"@slopus/happy-wire": "workspace:*",
|