very-happy-cli 0.2.116 → 0.2.118

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.
Files changed (37) hide show
  1. package/dist/{AcpBackend-CfKPvoTU.mjs → AcpBackend-Bk9b823B.mjs} +116 -12
  2. package/dist/{AcpBackend-CauAQpC1.cjs → AcpBackend-p_KNJkHc.cjs} +116 -12
  3. package/dist/{AcpSessionManager-CA6xeET_.cjs → AcpSessionManager-B9FTbpGQ.cjs} +15 -2
  4. package/dist/{AcpSessionManager-BQ6pBRW4.mjs → AcpSessionManager-CDvqVHKf.mjs} +15 -2
  5. package/dist/{config-BpR_CwZu.mjs → config-CIpgmGLR.mjs} +2 -2
  6. package/dist/{config-BoteFn-v.cjs → config-CkUn1dI4.cjs} +2 -2
  7. package/dist/{index-C45xN8s0.mjs → index-B6cpyG_G.mjs} +78 -8
  8. package/dist/{index-D7azxfcs.mjs → index-BUVQf9PI.mjs} +2 -2
  9. package/dist/{index-4jiUeiUz.cjs → index-BXOXRblP.cjs} +513 -47
  10. package/dist/{index-DWmhmji9.cjs → index-BzgtwTxC.cjs} +77 -7
  11. package/dist/{index-lX1UliOs.cjs → index-CxjX8DGz.cjs} +2 -2
  12. package/dist/{index-Dq-eFp89.mjs → index-DIXjhnV1.mjs} +502 -45
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-k3TrBHD0.mjs → installTerminalHooks-BAa6LaQQ.mjs} +2 -2
  16. package/dist/{installTerminalHooks-DnaFkrTF.cjs → installTerminalHooks-lXQa6bQU.cjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +43 -1
  19. package/dist/lib.d.mts +43 -1
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-DSpEpM_2.cjs → mcp-DMD7FxBI.cjs} +62 -16
  22. package/dist/{mcp-DRePTOap.mjs → mcp-Dwc299mU.mjs} +62 -17
  23. package/dist/{runGemini-_9-a7duU.mjs → runGemini-BaxGXE9w.mjs} +4 -4
  24. package/dist/{runGemini-IWHyBq0A.cjs → runGemini-Bj4Egq7j.cjs} +4 -4
  25. package/dist/{runOpenClaw-0myYIz1U.cjs → runOpenClaw-BJhSvXYy.cjs} +3 -3
  26. package/dist/{runOpenClaw-Boq6LQ9a.mjs → runOpenClaw-BwJhbIKU.mjs} +3 -3
  27. package/dist/{send-CwWvFfay.cjs → send-BWGUkWhi.cjs} +2 -2
  28. package/dist/{send-Cyo6mgMl.mjs → send-DX13svrS.mjs} +2 -2
  29. package/dist/sessions-CGhpBNqn.cjs +322 -0
  30. package/dist/sessions-L7O3ypda.mjs +317 -0
  31. package/dist/{spawn-DQ6FTUK9.cjs → spawn-CbY233Eg.cjs} +6 -7
  32. package/dist/{spawn-CU0DMauA.mjs → spawn-DPDWZdoW.mjs} +3 -4
  33. package/dist/{types-Ds0SiQ1D.mjs → types-BtuOM9lw.mjs} +52 -19
  34. package/dist/{types-C5kEpkcZ.cjs → types-ClvvHves.cjs} +54 -19
  35. package/package.json +7 -7
  36. package/dist/sessions-CbzqYiAy.cjs +0 -204
  37. package/dist/sessions-lvfTH_ql.mjs +0 -200
@@ -1,10 +1,10 @@
1
- import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-CfKPvoTU.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-CfKPvoTU.mjs';
3
- import { h as connectionState, A as ApiClient, j as readSettings, k as encodeBase64, l as logger, p as projectPath } from './types-Ds0SiQ1D.mjs';
4
- import { A as AcpSessionManager } from './AcpSessionManager-BQ6pBRW4.mjs';
1
+ import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-Bk9b823B.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-Bk9b823B.mjs';
3
+ import { d as connectionState, A as ApiClient, e as readSettings, f as encodeBase64, l as logger, p as projectPath } from './types-BtuOM9lw.mjs';
4
+ import { A as AcpSessionManager } from './AcpSessionManager-CDvqVHKf.mjs';
5
5
  import { randomUUID } from 'node:crypto';
6
6
  import { join } from 'node:path';
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-Dq-eFp89.mjs';
7
+ import { n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, x as MessageQueue2, y as hashObject, z as startHappyServer, T as TitleGenerator, B as registerKillSessionHandler, C as BasePermissionHandler, E as writeSessionModeFile, F as normalizeAcpPermissionMode, H as removeSessionModeFile } from './index-DIXjhnV1.mjs';
8
8
  import 'node:child_process';
9
9
  import '@agentclientprotocol/sdk';
10
10
  import 'axios';
@@ -483,12 +483,16 @@ function extractConfigSelector(configOptions, category) {
483
483
  if (option.category === category) {
484
484
  return true;
485
485
  }
486
+ if (option.category) {
487
+ return false;
488
+ }
486
489
  const id = normalizeComparable(option.id);
487
490
  const name = normalizeComparable(option.name);
488
491
  if (category === "model") {
489
492
  return id.includes("model") || name.includes("model");
490
493
  }
491
- return id.includes("mode") || id.includes("permission") || name.includes("mode") || name.includes("permission");
494
+ const mentionsMode = (value) => value.includes("permission") || value.includes("mode") && !value.includes("model");
495
+ return mentionsMode(id) || mentionsMode(name);
492
496
  };
493
497
  for (const option of configOptions) {
494
498
  if (option.type !== "select" || !optionMatchesCategory(option)) {
@@ -643,7 +647,27 @@ async function runAcp(opts) {
643
647
  let sawSlashCommands = false;
644
648
  let sawModes = false;
645
649
  let sawModels = false;
646
- const happyServer = await startHappyServer(session);
650
+ const initialPermissionMode = opts.permissionMode ?? "default";
651
+ let fileBackedModeActive = false;
652
+ const permissionModeIsFileBacked = () => opts.agentName === "pi" || !modeSelector && !legacyModes;
653
+ let fileBackedPermissionMode = null;
654
+ const publishFileBackedPermissionMode = (mode) => {
655
+ if (fileBackedPermissionMode === mode) {
656
+ return true;
657
+ }
658
+ try {
659
+ writeSessionModeFile(session.sessionId, mode);
660
+ } catch (error) {
661
+ logger.debug(`[${opts.agentName}] Failed to write session mode file:`, error);
662
+ return false;
663
+ }
664
+ fileBackedPermissionMode = mode;
665
+ session.updateMetadata((currentMetadata) => ({ ...currentMetadata, permissionMode: mode }));
666
+ logger.debug(`[${opts.agentName}] Published file-backed permission mode: ${mode}`);
667
+ return true;
668
+ };
669
+ const isAssistantVariant = process.env.HAPPY_SESSION_VARIANT === "assistant";
670
+ const happyServer = await startHappyServer(session, { assistant: isAssistantVariant });
647
671
  const mcpServers = {
648
672
  happy: {
649
673
  command: join(projectPath(), "bin", "happy-mcp.mjs"),
@@ -655,6 +679,11 @@ async function runAcp(opts) {
655
679
  cwd: process.cwd(),
656
680
  command: opts.command,
657
681
  args: opts.args,
682
+ env: {
683
+ HAPPY_MCP_URL: happyServer.url,
684
+ HAPPY_SESSION_ID: session.sessionId,
685
+ HAPPY_PERMISSION_MODE: initialPermissionMode
686
+ },
658
687
  mcpServers,
659
688
  permissionHandler,
660
689
  transportHandler: new DefaultTransport(opts.agentName),
@@ -708,6 +737,15 @@ async function runAcp(opts) {
708
737
  if (!requestedMode) {
709
738
  return;
710
739
  }
740
+ if (permissionModeIsFileBacked()) {
741
+ const mode = normalizeAcpPermissionMode(requestedMode);
742
+ if (!mode) {
743
+ logger.debug(`[${opts.agentName}] Ignoring unknown file-backed permission mode request: ${requestedMode}`);
744
+ return;
745
+ }
746
+ publishFileBackedPermissionMode(mode);
747
+ return;
748
+ }
711
749
  if (modeSelector) {
712
750
  const resolved = resolveRequestedCode(modeSelector.options, requestedMode);
713
751
  if (!resolved) {
@@ -905,6 +943,7 @@ async function runAcp(opts) {
905
943
  clearPendingTurn();
906
944
  }
907
945
  if (msg.status === "error" || msg.status === "stopped") {
946
+ if (msg.status === "error") opts.onBackendError?.(msg.detail);
908
947
  stopRunnerFromBackendStatus(msg.status, msg.detail);
909
948
  }
910
949
  }
@@ -918,10 +957,12 @@ async function runAcp(opts) {
918
957
  sendEnvelopes(sessionManager.mapMessage(msg));
919
958
  };
920
959
  backend.onMessage(onBackendMessage);
960
+ const titleGenerator = new TitleGenerator(session);
921
961
  session.onUserMessage((message) => {
922
962
  if (!message.content.text) {
923
963
  return;
924
964
  }
965
+ titleGenerator.maybeGenerate(message.content.text);
925
966
  if (typeof message.meta?.permissionMode === "string") {
926
967
  currentPermissionMode = message.meta.permissionMode;
927
968
  logger.debug(`[${opts.agentName}] Requested ACP permission mode: ${currentPermissionMode}`);
@@ -953,6 +994,22 @@ async function runAcp(opts) {
953
994
  }
954
995
  }
955
996
  session.rpcHandlerManager.registerHandler("abort", handleAbort);
997
+ session.rpcHandlerManager.registerHandler(
998
+ "set-permission-mode",
999
+ async (request) => {
1000
+ if (!fileBackedModeActive) {
1001
+ throw new Error(`${opts.agentName} does not support live permission mode changes`);
1002
+ }
1003
+ const mode = typeof request?.mode === "string" ? normalizeAcpPermissionMode(request.mode) : null;
1004
+ if (!mode) {
1005
+ throw new Error("Invalid permission mode");
1006
+ }
1007
+ if (!publishFileBackedPermissionMode(mode)) {
1008
+ throw new Error("Failed to write session mode file");
1009
+ }
1010
+ return { mode };
1011
+ }
1012
+ );
956
1013
  registerKillSessionHandler(session.rpcHandlerManager, async () => {
957
1014
  shouldExit = true;
958
1015
  messageQueue.close();
@@ -962,6 +1019,10 @@ async function runAcp(opts) {
962
1019
  try {
963
1020
  const started = await backend.startSession();
964
1021
  acpSessionId = started.sessionId;
1022
+ if (permissionModeIsFileBacked()) {
1023
+ fileBackedModeActive = true;
1024
+ publishFileBackedPermissionMode(initialPermissionMode);
1025
+ }
965
1026
  if (verbose) {
966
1027
  if (!sawSlashCommands) {
967
1028
  logAcp("muted", `Outgoing slash commands from ${opts.agentName}: not reported yet`);
@@ -1024,6 +1085,13 @@ async function runAcp(opts) {
1024
1085
  }
1025
1086
  backend.offMessage?.(onBackendMessage);
1026
1087
  await backend.dispose();
1088
+ if (fileBackedPermissionMode) {
1089
+ try {
1090
+ removeSessionModeFile(session.sessionId);
1091
+ } catch (error) {
1092
+ logger.debug(`[${opts.agentName}] Failed to remove session mode file:`, error);
1093
+ }
1094
+ }
1027
1095
  try {
1028
1096
  happyServer.stop();
1029
1097
  } catch (error) {
@@ -1046,9 +1114,11 @@ async function runAcp(opts) {
1046
1114
  }
1047
1115
  }
1048
1116
 
1117
+ const PI_ACP_COMMAND = "pi-acp";
1049
1118
  const KNOWN_ACP_AGENTS = {
1050
1119
  gemini: { command: "gemini", args: ["--experimental-acp"] },
1051
- opencode: { command: "opencode", args: ["acp"] }
1120
+ opencode: { command: "opencode", args: ["acp"] },
1121
+ pi: { command: PI_ACP_COMMAND, args: [] }
1052
1122
  };
1053
1123
  function resolveAcpAgentConfig(cliArgs) {
1054
1124
  if (cliArgs.length === 0) {
@@ -1,9 +1,9 @@
1
- import { q as query } from './index-Dq-eFp89.mjs';
1
+ import { q as query } from './index-DIXjhnV1.mjs';
2
2
  export { AbortError } from '@anthropic-ai/claude-agent-sdk';
3
3
  import 'chalk';
4
4
  import 'node:os';
5
5
  import 'node:crypto';
6
- import './types-Ds0SiQ1D.mjs';
6
+ import './types-BtuOM9lw.mjs';
7
7
  import 'axios';
8
8
  import 'node:util';
9
9
  import 'node:fs';