happy-imou-cloud 2.0.20 → 2.0.22

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 (35) hide show
  1. package/bin/happy-cloud.mjs +1 -1
  2. package/dist/{BaseReasoningProcessor-B9z785Pi.cjs → BaseReasoningProcessor-CJVv1aNR.cjs} +3 -3
  3. package/dist/{BaseReasoningProcessor-iTk5q5Vy.mjs → BaseReasoningProcessor-mIqqngd3.mjs} +3 -3
  4. package/dist/ProviderSelectionHandler-BjLyIfSR.mjs +673 -0
  5. package/dist/ProviderSelectionHandler-e4zL4Y5_.cjs +680 -0
  6. package/dist/{api-BKnzORe4.cjs → api-DP-RQUao.cjs} +88 -3
  7. package/dist/{api-_Y2kzqZL.mjs → api-DrijKeDb.mjs} +86 -4
  8. package/dist/{command-BDkgHdQU.mjs → command--vV6BSsL.mjs} +3 -3
  9. package/dist/{command-BBNzMWEG.cjs → command-BZphfJrt.cjs} +3 -3
  10. package/dist/{index-Bg4KLXYY.mjs → index-BIki80pQ.mjs} +8 -8
  11. package/dist/{index-0TIyXMQu.cjs → index-CqCEZDFi.cjs} +11 -11
  12. package/dist/index.cjs +3 -3
  13. package/dist/index.mjs +3 -3
  14. package/dist/lib.cjs +1 -1
  15. package/dist/lib.d.cts +393 -36
  16. package/dist/lib.d.mts +393 -36
  17. package/dist/lib.mjs +1 -1
  18. package/dist/{persistence-BCkHc68b.mjs → persistence-C3NBdZdz.mjs} +1 -1
  19. package/dist/{persistence-D5uolhHo.cjs → persistence-yVTbf_Ng.cjs} +1 -1
  20. package/dist/{registerKillSessionHandler-DJMH-gar.mjs → registerKillSessionHandler-CHEj7UjN.mjs} +3 -3
  21. package/dist/{registerKillSessionHandler-BMUE5Oaj.cjs → registerKillSessionHandler-QmBN446A.cjs} +3 -3
  22. package/dist/{runClaude-BUhD2jR2.cjs → runClaude-BuI6OOEv.cjs} +72 -9
  23. package/dist/{runClaude-BMv-eao6.mjs → runClaude-D0DD_Ya5.mjs} +72 -9
  24. package/dist/{runCodex-DyNSDN6X.cjs → runCodex-1jTTmCvq.cjs} +84 -14
  25. package/dist/{runCodex-DwnLnXWK.mjs → runCodex-BzZ0jODI.mjs} +84 -14
  26. package/dist/{runGemini-UKpRbyNY.cjs → runGemini-1gJRE8oT.cjs} +5 -5
  27. package/dist/{runGemini-uVHDcJ09.mjs → runGemini-Bx2SYAyG.mjs} +5 -5
  28. package/package.json +1 -1
  29. package/scripts/build.mjs +66 -66
  30. package/scripts/devtools/README.md +9 -9
  31. package/scripts/e2e/fake-codex-acp-agent.mjs +139 -139
  32. package/scripts/e2e/local-server-session-roundtrip.mjs +1063 -1063
  33. package/scripts/release-smoke.mjs +3 -3
  34. package/dist/ProviderSelectionHandler-DUBEXkmo.cjs +0 -265
  35. package/dist/ProviderSelectionHandler-s79sTquD.mjs +0 -261
package/dist/lib.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-_Y2kzqZL.mjs';
1
+ export { A as ApiClient, a as ApiSessionClient, c as configuration, l as logger } from './api-DrijKeDb.mjs';
2
2
  export { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
3
3
  import 'axios';
4
4
  import 'chalk';
@@ -1,7 +1,7 @@
1
1
  import { unlink, readFile, mkdir, open, stat, writeFile, rename } from 'node:fs/promises';
2
2
  import { existsSync, unlinkSync, readdirSync, constants, writeFileSync, readFileSync } from 'node:fs';
3
3
  import { join, dirname } from 'node:path';
4
- import { c as configuration, l as logger, e as encodeBase64 } from './api-_Y2kzqZL.mjs';
4
+ import { c as configuration, l as logger, e as encodeBase64 } from './api-DrijKeDb.mjs';
5
5
  import * as z from 'zod';
6
6
  import 'axios';
7
7
  import 'chalk';
@@ -3,7 +3,7 @@
3
3
  var promises = require('node:fs/promises');
4
4
  var fs = require('node:fs');
5
5
  var path = require('node:path');
6
- var api = require('./api-BKnzORe4.cjs');
6
+ var api = require('./api-DP-RQUao.cjs');
7
7
  var z = require('zod');
8
8
  require('axios');
9
9
  require('chalk');
@@ -1,8 +1,8 @@
1
- import { i as initialMachineMetadata, e as projectPath, R as RuntimeShell, h as resolveCanonicalToolNameV2, f as formatDisplayMessage } from './index-Bg4KLXYY.mjs';
2
- import { readSettings } from './persistence-BCkHc68b.mjs';
1
+ import { i as initialMachineMetadata, e as projectPath, R as RuntimeShell, h as resolveCanonicalToolNameV2, f as formatDisplayMessage } from './index-BIki80pQ.mjs';
2
+ import { readSettings } from './persistence-C3NBdZdz.mjs';
3
3
  import os from 'node:os';
4
4
  import { resolve } from 'node:path';
5
- import { c as configuration, p as packageJson, l as logger } from './api-_Y2kzqZL.mjs';
5
+ import { c as configuration, p as packageJson, l as logger } from './api-DrijKeDb.mjs';
6
6
  import { randomUUID } from 'node:crypto';
7
7
  import { createHash } from 'crypto';
8
8
  import 'axios';
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-0TIyXMQu.cjs');
4
- var persistence = require('./persistence-D5uolhHo.cjs');
3
+ var index = require('./index-CqCEZDFi.cjs');
4
+ var persistence = require('./persistence-yVTbf_Ng.cjs');
5
5
  var os = require('node:os');
6
6
  var path = require('node:path');
7
- var api = require('./api-BKnzORe4.cjs');
7
+ var api = require('./api-DP-RQUao.cjs');
8
8
  var node_crypto = require('node:crypto');
9
9
  var crypto = require('crypto');
10
10
  require('axios');
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
- var api = require('./api-BKnzORe4.cjs');
4
+ var api = require('./api-DP-RQUao.cjs');
5
5
  require('cross-spawn');
6
6
  require('@agentclientprotocol/sdk');
7
- var index = require('./index-0TIyXMQu.cjs');
7
+ var index = require('./index-CqCEZDFi.cjs');
8
8
  require('ps-list');
9
9
  require('fs');
10
10
  require('path');
@@ -15,7 +15,7 @@ var path = require('node:path');
15
15
  var os = require('node:os');
16
16
  var node_child_process = require('node:child_process');
17
17
  require('node:readline');
18
- require('./persistence-D5uolhHo.cjs');
18
+ require('./persistence-yVTbf_Ng.cjs');
19
19
  var promises = require('node:fs/promises');
20
20
  var fs = require('fs/promises');
21
21
  require('crypto');
@@ -26,9 +26,9 @@ require('tweetnacl');
26
26
  require('open');
27
27
  var React = require('react');
28
28
  var ink = require('ink');
29
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-DUBEXkmo.cjs');
29
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-e4zL4Y5_.cjs');
30
30
  var types = require('./types-DVk3crez.cjs');
31
- var registerKillSessionHandler = require('./registerKillSessionHandler-BMUE5Oaj.cjs');
31
+ var registerKillSessionHandler = require('./registerKillSessionHandler-QmBN446A.cjs');
32
32
  require('socket.io-client');
33
33
  require('expo-server-sdk');
34
34
  var node_util = require('node:util');
@@ -1040,6 +1040,13 @@ async function claudeAcpRemoteLauncher(session) {
1040
1040
  message
1041
1041
  });
1042
1042
  };
1043
+ const emitTurnReport = (report) => {
1044
+ session.client.sendAgentMessage("claude", {
1045
+ type: "turn-report",
1046
+ id: node_crypto.randomUUID(),
1047
+ report
1048
+ });
1049
+ };
1043
1050
  const resetTurnState = () => {
1044
1051
  accumulatedResponse = "";
1045
1052
  isResponseInProgress = false;
@@ -1048,13 +1055,16 @@ async function claudeAcpRemoteLauncher(session) {
1048
1055
  currentThinkingMessageId = null;
1049
1056
  session.onThinkingChange(false);
1050
1057
  };
1051
- const emitFinalAssistantMessage = () => {
1052
- const finalMessage = accumulatedResponse.trim();
1058
+ const emitFinalAssistantMessage = (finalMessageText) => {
1059
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
1053
1060
  if (!finalMessage) {
1054
1061
  accumulatedResponse = "";
1055
1062
  isResponseInProgress = false;
1056
1063
  return;
1057
1064
  }
1065
+ if (currentAssistantMessageId) {
1066
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
1067
+ }
1058
1068
  conversationHistory.addAssistantMessage(finalMessage);
1059
1069
  session.client.sendAgentMessage("claude", {
1060
1070
  type: "message",
@@ -1366,6 +1376,7 @@ ${systemPrompt}` : systemPrompt,
1366
1376
  permissionHandler.setPermissionMode(message.mode.permissionMode);
1367
1377
  messageBuffer.addMessage(message.message, "user");
1368
1378
  let shouldClearHistoryAfterTurn = false;
1379
+ let turnStatus = "task_complete";
1369
1380
  try {
1370
1381
  const activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
1371
1382
  let promptToSend = message.message;
@@ -1376,6 +1387,9 @@ ${systemPrompt}` : systemPrompt,
1376
1387
  promptToSend = historyContext + promptToSend;
1377
1388
  api.logger.debug(`[ClaudeACP] Injected conversation history context (${historyContext.length} chars)`);
1378
1389
  }
1390
+ if (message.mode.happyOrg) {
1391
+ promptToSend = ProviderSelectionHandler.buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1392
+ }
1379
1393
  if (specialCommand.type === "compact") {
1380
1394
  emitStatusMessage("Compaction started");
1381
1395
  }
@@ -1389,6 +1403,7 @@ ${systemPrompt}` : systemPrompt,
1389
1403
  const isAbortError = error instanceof Error && error.name === "AbortError";
1390
1404
  const isExpectedInterruption = isAbortError || abortController.signal.aborted || shouldExit;
1391
1405
  if (isExpectedInterruption) {
1406
+ turnStatus = "turn_aborted";
1392
1407
  session.client.sendAgentMessage("claude", {
1393
1408
  type: "turn_aborted",
1394
1409
  id: node_crypto.randomUUID()
@@ -1405,7 +1420,23 @@ ${systemPrompt}` : systemPrompt,
1405
1420
  currentModeHash = null;
1406
1421
  }
1407
1422
  } finally {
1408
- emitFinalAssistantMessage();
1423
+ const finalizedTurn = ProviderSelectionHandler.finalizeHappyOrgTurn({
1424
+ metadata: session.client.getMetadataSnapshot?.() ?? null,
1425
+ queuedTurn: message.mode.happyOrg,
1426
+ responseText: accumulatedResponse,
1427
+ turnStatus
1428
+ });
1429
+ if (finalizedTurn.nextMetadata && typeof session.client.updateMetadata === "function") {
1430
+ session.client.updateMetadata(() => finalizedTurn.nextMetadata);
1431
+ }
1432
+ if (finalizedTurn.report) {
1433
+ emitTurnReport(finalizedTurn.report);
1434
+ }
1435
+ if (finalizedTurn.terminateMessage) {
1436
+ emitStatusMessage(finalizedTurn.terminateMessage);
1437
+ }
1438
+ accumulatedResponse = finalizedTurn.cleanedText;
1439
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1409
1440
  if (shouldClearHistoryAfterTurn) {
1410
1441
  conversationHistory.clear();
1411
1442
  emitStatusMessage("Compaction completed");
@@ -3130,8 +3161,28 @@ function resolveClaudeQueuedMessage(message, currentState) {
3130
3161
  function bindClaudeUserMessageQueue(opts) {
3131
3162
  let currentState = { ...opts.initialState };
3132
3163
  opts.session.onUserMessage((message) => {
3164
+ const happyOrgResult = opts.happyOrg ? ProviderSelectionHandler.resolveHappyOrgQueuedTurn({
3165
+ metadata: opts.happyOrg.getMetadata(),
3166
+ message
3167
+ }) : {
3168
+ nextMetadata: null,
3169
+ queuedTurn: null,
3170
+ blocked: false,
3171
+ statusMessage: void 0
3172
+ };
3173
+ if (opts.happyOrg && happyOrgResult.nextMetadata) {
3174
+ opts.happyOrg.updateMetadata(() => happyOrgResult.nextMetadata);
3175
+ }
3176
+ if (happyOrgResult.blocked) {
3177
+ if (happyOrgResult.statusMessage) {
3178
+ opts.happyOrg?.emitStatusMessage(happyOrgResult.statusMessage);
3179
+ }
3180
+ api.logger.debugLargeJson("[claude] User message blocked by Happy Org runtime:", message);
3181
+ return;
3182
+ }
3133
3183
  const { nextState, queuedMessage } = resolveClaudeQueuedMessage(message, currentState);
3134
3184
  currentState = nextState;
3185
+ queuedMessage.mode.happyOrg = happyOrgResult.queuedTurn;
3135
3186
  if (queuedMessage.isolate) {
3136
3187
  api.logger.debug(`[claude] Queuing isolated special command: ${queuedMessage.specialCommand}`);
3137
3188
  opts.messageQueue.pushIsolateAndClear(queuedMessage.text, queuedMessage.mode);
@@ -3236,7 +3287,14 @@ async function runClaude(credentials, options = {}) {
3236
3287
  customSystemPrompt: mode.customSystemPrompt,
3237
3288
  appendSystemPrompt: mode.appendSystemPrompt,
3238
3289
  allowedTools: mode.allowedTools,
3239
- disallowedTools: mode.disallowedTools
3290
+ disallowedTools: mode.disallowedTools,
3291
+ happyOrg: mode.happyOrg ? {
3292
+ taskId: mode.happyOrg.context.taskId,
3293
+ organizationId: mode.happyOrg.context.organizationId,
3294
+ memberAgentId: mode.happyOrg.context.memberAgentId,
3295
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
3296
+ reopenContext: mode.happyOrg.reopenContext ?? null
3297
+ } : null
3240
3298
  }));
3241
3299
  bindClaudeUserMessageQueue({
3242
3300
  session,
@@ -3244,6 +3302,11 @@ async function runClaude(credentials, options = {}) {
3244
3302
  initialState: {
3245
3303
  permissionMode: options.permissionMode,
3246
3304
  model: options.model
3305
+ },
3306
+ happyOrg: {
3307
+ getMetadata: () => session.getMetadataSnapshot(),
3308
+ updateMetadata: (handler) => session.updateMetadata(handler),
3309
+ emitStatusMessage: (message) => session.sendSessionEvent({ type: "message", message })
3247
3310
  }
3248
3311
  });
3249
3312
  const cleanup = async () => {
@@ -1,8 +1,8 @@
1
1
  import { randomUUID } from 'node:crypto';
2
- import { l as logger, d as backoff, f as delay, g as AsyncLock, c as configuration, s as startOfflineReconnection, b as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-_Y2kzqZL.mjs';
2
+ import { l as logger, g as backoff, h as delay, j as AsyncLock, c as configuration, s as startOfflineReconnection, f as connectionState, A as ApiClient, i as isAuthenticationRequiredError } from './api-DrijKeDb.mjs';
3
3
  import 'cross-spawn';
4
4
  import '@agentclientprotocol/sdk';
5
- import { j as getProjectPath, F as Future, k as claudeLocal, E as ExitCodeError, l as trimIdent, m as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, n as claudeCheckSession, e as projectPath, o as mapToClaudeMode, P as PushableAsyncIterable, q as query, A as AbortError, b as stopCaffeinate, p as publishSessionRegistration, u as getEnvironmentInfo, w as startCaffeinate } from './index-Bg4KLXYY.mjs';
5
+ import { j as getProjectPath, F as Future, k as claudeLocal, E as ExitCodeError, l as trimIdent, m as createClaudeBackend, f as formatDisplayMessage, t as truncateDisplayMessage, n as claudeCheckSession, e as projectPath, o as mapToClaudeMode, P as PushableAsyncIterable, q as query, A as AbortError, b as stopCaffeinate, p as publishSessionRegistration, u as getEnvironmentInfo, w as startCaffeinate } from './index-BIki80pQ.mjs';
6
6
  import 'ps-list';
7
7
  import 'fs';
8
8
  import 'path';
@@ -13,7 +13,7 @@ import { dirname, basename, join, resolve } from 'node:path';
13
13
  import { homedir } from 'node:os';
14
14
  import { execSync } from 'node:child_process';
15
15
  import 'node:readline';
16
- import './persistence-BCkHc68b.mjs';
16
+ import './persistence-C3NBdZdz.mjs';
17
17
  import { readFile } from 'node:fs/promises';
18
18
  import { stat, watch, access } from 'fs/promises';
19
19
  import 'crypto';
@@ -24,9 +24,9 @@ import 'tweetnacl';
24
24
  import 'open';
25
25
  import React, { useState, useRef, useEffect, useCallback } from 'react';
26
26
  import { useStdout, useInput, Box, Text, render } from 'ink';
27
- import { c as createKeepAliveController, P as ProviderSelectionHandler, r as runModeLoop } from './ProviderSelectionHandler-s79sTquD.mjs';
27
+ import { c as createKeepAliveController, P as ProviderSelectionHandler, b as buildHappyOrgTurnPrompt, f as finalizeHappyOrgTurn, r as runModeLoop, a as resolveHappyOrgQueuedTurn } from './ProviderSelectionHandler-BjLyIfSR.mjs';
28
28
  import { R as RawJSONLinesSchema } from './types-CiliQpqS.mjs';
29
- import { B as BasePermissionHandler, d as MessageBuffer, C as ConversationHistory$1, w as waitForResponseCompleteWithAbort, l as launchRuntimeHandleWithFactoryResult, j as forwardAgentMessageToProviderSession, s as syncControlledByUserState, e as ensureManagedProviderMachine, M as MissingMachineIdError, c as createSessionMetadata, b as MessageQueue2, h as hashObject, r as registerKillSessionHandler, f as closeProviderSession } from './registerKillSessionHandler-DJMH-gar.mjs';
29
+ import { B as BasePermissionHandler, d as MessageBuffer, C as ConversationHistory$1, w as waitForResponseCompleteWithAbort, l as launchRuntimeHandleWithFactoryResult, j as forwardAgentMessageToProviderSession, s as syncControlledByUserState, e as ensureManagedProviderMachine, M as MissingMachineIdError, c as createSessionMetadata, b as MessageQueue2, h as hashObject, r as registerKillSessionHandler, f as closeProviderSession } from './registerKillSessionHandler-CHEj7UjN.mjs';
30
30
  import 'socket.io-client';
31
31
  import 'expo-server-sdk';
32
32
  import { isDeepStrictEqual } from 'node:util';
@@ -1038,6 +1038,13 @@ async function claudeAcpRemoteLauncher(session) {
1038
1038
  message
1039
1039
  });
1040
1040
  };
1041
+ const emitTurnReport = (report) => {
1042
+ session.client.sendAgentMessage("claude", {
1043
+ type: "turn-report",
1044
+ id: randomUUID(),
1045
+ report
1046
+ });
1047
+ };
1041
1048
  const resetTurnState = () => {
1042
1049
  accumulatedResponse = "";
1043
1050
  isResponseInProgress = false;
@@ -1046,13 +1053,16 @@ async function claudeAcpRemoteLauncher(session) {
1046
1053
  currentThinkingMessageId = null;
1047
1054
  session.onThinkingChange(false);
1048
1055
  };
1049
- const emitFinalAssistantMessage = () => {
1050
- const finalMessage = accumulatedResponse.trim();
1056
+ const emitFinalAssistantMessage = (finalMessageText) => {
1057
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
1051
1058
  if (!finalMessage) {
1052
1059
  accumulatedResponse = "";
1053
1060
  isResponseInProgress = false;
1054
1061
  return;
1055
1062
  }
1063
+ if (currentAssistantMessageId) {
1064
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
1065
+ }
1056
1066
  conversationHistory.addAssistantMessage(finalMessage);
1057
1067
  session.client.sendAgentMessage("claude", {
1058
1068
  type: "message",
@@ -1364,6 +1374,7 @@ ${systemPrompt}` : systemPrompt,
1364
1374
  permissionHandler.setPermissionMode(message.mode.permissionMode);
1365
1375
  messageBuffer.addMessage(message.message, "user");
1366
1376
  let shouldClearHistoryAfterTurn = false;
1377
+ let turnStatus = "task_complete";
1367
1378
  try {
1368
1379
  const activeRuntimeHandle = runtimeHandle ?? await createRuntimeHandle(message.mode);
1369
1380
  let promptToSend = message.message;
@@ -1374,6 +1385,9 @@ ${systemPrompt}` : systemPrompt,
1374
1385
  promptToSend = historyContext + promptToSend;
1375
1386
  logger.debug(`[ClaudeACP] Injected conversation history context (${historyContext.length} chars)`);
1376
1387
  }
1388
+ if (message.mode.happyOrg) {
1389
+ promptToSend = buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1390
+ }
1377
1391
  if (specialCommand.type === "compact") {
1378
1392
  emitStatusMessage("Compaction started");
1379
1393
  }
@@ -1387,6 +1401,7 @@ ${systemPrompt}` : systemPrompt,
1387
1401
  const isAbortError = error instanceof Error && error.name === "AbortError";
1388
1402
  const isExpectedInterruption = isAbortError || abortController.signal.aborted || shouldExit;
1389
1403
  if (isExpectedInterruption) {
1404
+ turnStatus = "turn_aborted";
1390
1405
  session.client.sendAgentMessage("claude", {
1391
1406
  type: "turn_aborted",
1392
1407
  id: randomUUID()
@@ -1403,7 +1418,23 @@ ${systemPrompt}` : systemPrompt,
1403
1418
  currentModeHash = null;
1404
1419
  }
1405
1420
  } finally {
1406
- emitFinalAssistantMessage();
1421
+ const finalizedTurn = finalizeHappyOrgTurn({
1422
+ metadata: session.client.getMetadataSnapshot?.() ?? null,
1423
+ queuedTurn: message.mode.happyOrg,
1424
+ responseText: accumulatedResponse,
1425
+ turnStatus
1426
+ });
1427
+ if (finalizedTurn.nextMetadata && typeof session.client.updateMetadata === "function") {
1428
+ session.client.updateMetadata(() => finalizedTurn.nextMetadata);
1429
+ }
1430
+ if (finalizedTurn.report) {
1431
+ emitTurnReport(finalizedTurn.report);
1432
+ }
1433
+ if (finalizedTurn.terminateMessage) {
1434
+ emitStatusMessage(finalizedTurn.terminateMessage);
1435
+ }
1436
+ accumulatedResponse = finalizedTurn.cleanedText;
1437
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1407
1438
  if (shouldClearHistoryAfterTurn) {
1408
1439
  conversationHistory.clear();
1409
1440
  emitStatusMessage("Compaction completed");
@@ -3128,8 +3159,28 @@ function resolveClaudeQueuedMessage(message, currentState) {
3128
3159
  function bindClaudeUserMessageQueue(opts) {
3129
3160
  let currentState = { ...opts.initialState };
3130
3161
  opts.session.onUserMessage((message) => {
3162
+ const happyOrgResult = opts.happyOrg ? resolveHappyOrgQueuedTurn({
3163
+ metadata: opts.happyOrg.getMetadata(),
3164
+ message
3165
+ }) : {
3166
+ nextMetadata: null,
3167
+ queuedTurn: null,
3168
+ blocked: false,
3169
+ statusMessage: void 0
3170
+ };
3171
+ if (opts.happyOrg && happyOrgResult.nextMetadata) {
3172
+ opts.happyOrg.updateMetadata(() => happyOrgResult.nextMetadata);
3173
+ }
3174
+ if (happyOrgResult.blocked) {
3175
+ if (happyOrgResult.statusMessage) {
3176
+ opts.happyOrg?.emitStatusMessage(happyOrgResult.statusMessage);
3177
+ }
3178
+ logger.debugLargeJson("[claude] User message blocked by Happy Org runtime:", message);
3179
+ return;
3180
+ }
3131
3181
  const { nextState, queuedMessage } = resolveClaudeQueuedMessage(message, currentState);
3132
3182
  currentState = nextState;
3183
+ queuedMessage.mode.happyOrg = happyOrgResult.queuedTurn;
3133
3184
  if (queuedMessage.isolate) {
3134
3185
  logger.debug(`[claude] Queuing isolated special command: ${queuedMessage.specialCommand}`);
3135
3186
  opts.messageQueue.pushIsolateAndClear(queuedMessage.text, queuedMessage.mode);
@@ -3234,7 +3285,14 @@ async function runClaude(credentials, options = {}) {
3234
3285
  customSystemPrompt: mode.customSystemPrompt,
3235
3286
  appendSystemPrompt: mode.appendSystemPrompt,
3236
3287
  allowedTools: mode.allowedTools,
3237
- disallowedTools: mode.disallowedTools
3288
+ disallowedTools: mode.disallowedTools,
3289
+ happyOrg: mode.happyOrg ? {
3290
+ taskId: mode.happyOrg.context.taskId,
3291
+ organizationId: mode.happyOrg.context.organizationId,
3292
+ memberAgentId: mode.happyOrg.context.memberAgentId,
3293
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
3294
+ reopenContext: mode.happyOrg.reopenContext ?? null
3295
+ } : null
3238
3296
  }));
3239
3297
  bindClaudeUserMessageQueue({
3240
3298
  session,
@@ -3242,6 +3300,11 @@ async function runClaude(credentials, options = {}) {
3242
3300
  initialState: {
3243
3301
  permissionMode: options.permissionMode,
3244
3302
  model: options.model
3303
+ },
3304
+ happyOrg: {
3305
+ getMetadata: () => session.getMetadataSnapshot(),
3306
+ updateMetadata: (handler) => session.updateMetadata(handler),
3307
+ emitStatusMessage: (message) => session.sendSessionEvent({ type: "message", message })
3245
3308
  }
3246
3309
  });
3247
3310
  const cleanup = async () => {
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
3
  var node_crypto = require('node:crypto');
4
- var api = require('./api-BKnzORe4.cjs');
5
- var registerKillSessionHandler = require('./registerKillSessionHandler-BMUE5Oaj.cjs');
6
- var index = require('./index-0TIyXMQu.cjs');
4
+ var api = require('./api-DP-RQUao.cjs');
5
+ var registerKillSessionHandler = require('./registerKillSessionHandler-QmBN446A.cjs');
6
+ var index = require('./index-CqCEZDFi.cjs');
7
7
  require('cross-spawn');
8
8
  require('@agentclientprotocol/sdk');
9
9
  require('ps-list');
@@ -16,7 +16,7 @@ require('node:path');
16
16
  require('node:os');
17
17
  require('node:child_process');
18
18
  require('node:readline');
19
- require('./persistence-D5uolhHo.cjs');
19
+ require('./persistence-yVTbf_Ng.cjs');
20
20
  require('node:fs/promises');
21
21
  require('fs/promises');
22
22
  require('crypto');
@@ -27,8 +27,8 @@ require('tweetnacl');
27
27
  require('open');
28
28
  var React = require('react');
29
29
  var ink = require('ink');
30
- var ProviderSelectionHandler = require('./ProviderSelectionHandler-DUBEXkmo.cjs');
31
- var BaseReasoningProcessor = require('./BaseReasoningProcessor-B9z785Pi.cjs');
30
+ var ProviderSelectionHandler = require('./ProviderSelectionHandler-e4zL4Y5_.cjs');
31
+ var BaseReasoningProcessor = require('./BaseReasoningProcessor-CJVv1aNR.cjs');
32
32
  require('zod');
33
33
  require('socket.io-client');
34
34
  require('expo-server-sdk');
@@ -488,7 +488,16 @@ function resolveCodexAcpExecutionMode(mode) {
488
488
  };
489
489
  }
490
490
  function getCodexExecutionFingerprint(mode) {
491
- return registerKillSessionHandler.hashObject(resolveCodexAcpExecutionMode(mode));
491
+ return registerKillSessionHandler.hashObject({
492
+ ...resolveCodexAcpExecutionMode(mode),
493
+ happyOrg: mode.happyOrg ? {
494
+ taskId: mode.happyOrg.context.taskId,
495
+ organizationId: mode.happyOrg.context.organizationId,
496
+ memberAgentId: mode.happyOrg.context.memberAgentId,
497
+ supervisorAgentId: mode.happyOrg.context.supervisorAgentId,
498
+ reopenContext: mode.happyOrg.reopenContext ?? null
499
+ } : null
500
+ });
492
501
  }
493
502
 
494
503
  function normalizeCodexBackendError(error) {
@@ -567,6 +576,7 @@ async function codexRemoteLauncher(session) {
567
576
  let currentAssistantMessageId = null;
568
577
  let currentThinkingMessageId = null;
569
578
  let fatalRuntimeStopError = null;
579
+ let currentHappyOrgTurn = null;
570
580
  const permissionHandler = new CodexPermissionHandler(session.client);
571
581
  const selectionHandler = new CodexSelectionHandler(session.client);
572
582
  const conversationHistory = new registerKillSessionHandler.ConversationHistory({ maxMessages: 20, maxCharacters: 5e4 });
@@ -599,6 +609,7 @@ async function codexRemoteLauncher(session) {
599
609
  shouldCommitAccumulatedResponse = false;
600
610
  currentAssistantMessageId = null;
601
611
  currentThinkingMessageId = null;
612
+ currentHappyOrgTurn = null;
602
613
  session.onThinkingChange(false);
603
614
  };
604
615
  const abortActiveTurn = () => {
@@ -638,6 +649,13 @@ async function codexRemoteLauncher(session) {
638
649
  id: node_crypto.randomUUID()
639
650
  });
640
651
  };
652
+ const emitTurnReport = (report) => {
653
+ session.runtimeSession.sendCodexMessage({
654
+ type: "turn-report",
655
+ id: node_crypto.randomUUID(),
656
+ report
657
+ });
658
+ };
641
659
  const handleUnexpectedRuntimeStop = (detail) => {
642
660
  if (shouldExit || fatalRuntimeStopError) {
643
661
  return;
@@ -660,17 +678,33 @@ async function codexRemoteLauncher(session) {
660
678
  }
661
679
  emitStatusMessage(reason);
662
680
  };
663
- const emitFinalAssistantMessage = () => {
664
- if (!accumulatedResponse.trim()) {
681
+ const emitFinalAssistantMessage = (finalMessageText) => {
682
+ const finalMessage = (finalMessageText ?? accumulatedResponse).trim();
683
+ if (!finalMessage) {
665
684
  return;
666
685
  }
667
- conversationHistory.addAssistantMessage(accumulatedResponse);
668
- emitPendingAssistantMessageDelta();
686
+ if (currentAssistantMessageId) {
687
+ messageBuffer.updateMessage(currentAssistantMessageId, finalMessage, { mode: "replace" });
688
+ }
689
+ conversationHistory.addAssistantMessage(finalMessage);
690
+ if (currentHappyOrgTurn) {
691
+ session.runtimeSession.sendCodexMessage({
692
+ type: "message",
693
+ message: finalMessage,
694
+ id: node_crypto.randomUUID()
695
+ });
696
+ } else {
697
+ accumulatedResponse = finalMessage;
698
+ emitPendingAssistantMessageDelta({ force: true });
699
+ }
669
700
  accumulatedResponse = "";
670
701
  emittedResponseLength = 0;
671
702
  isResponseInProgress = false;
672
703
  };
673
- const emitPendingAssistantMessageDelta = () => {
704
+ const emitPendingAssistantMessageDelta = (opts) => {
705
+ if (currentHappyOrgTurn && !opts?.force) {
706
+ return false;
707
+ }
674
708
  const nextMessage = accumulatedResponse.slice(emittedResponseLength);
675
709
  if (!nextMessage.trim()) {
676
710
  return false;
@@ -970,6 +1004,8 @@ async function codexRemoteLauncher(session) {
970
1004
  readyAlreadySent = false;
971
1005
  messageBuffer.addMessage(message.message, "user");
972
1006
  const turnSignal = abortController.signal;
1007
+ let turnStatus = "task_complete";
1008
+ currentHappyOrgTurn = message.mode.happyOrg ?? null;
973
1009
  try {
974
1010
  turnInFlight = true;
975
1011
  shouldCommitAccumulatedResponse = false;
@@ -984,6 +1020,9 @@ async function codexRemoteLauncher(session) {
984
1020
  promptToSend = historyContext + promptToSend;
985
1021
  api.logger.debug(`[Codex] Injected conversation history context (${historyContext.length} chars)`);
986
1022
  }
1023
+ if (message.mode.happyOrg) {
1024
+ promptToSend = ProviderSelectionHandler.buildHappyOrgTurnPrompt(promptToSend, message.mode.happyOrg);
1025
+ }
987
1026
  conversationHistory.addUserMessage(message.message);
988
1027
  await activeRuntimeHandle.sendPrompt(promptToSend);
989
1028
  await registerKillSessionHandler.waitForResponseCompleteWithAbort(activeRuntimeHandle.backend, turnSignal);
@@ -995,6 +1034,7 @@ async function codexRemoteLauncher(session) {
995
1034
  const isAbortError = error instanceof Error && error.name === "AbortError";
996
1035
  const isExpectedInterruption = isAbortError || turnSignal.aborted || shouldExit;
997
1036
  if (isExpectedInterruption) {
1037
+ turnStatus = "turn_aborted";
998
1038
  session.runtimeSession.sendCodexMessage({
999
1039
  type: "turn_aborted",
1000
1040
  id: node_crypto.randomUUID()
@@ -1011,8 +1051,24 @@ async function codexRemoteLauncher(session) {
1011
1051
  }
1012
1052
  } finally {
1013
1053
  turnInFlight = false;
1054
+ const finalizedTurn = ProviderSelectionHandler.finalizeHappyOrgTurn({
1055
+ metadata: session.runtimeSession.getMetadataSnapshot?.() ?? null,
1056
+ queuedTurn: message.mode.happyOrg,
1057
+ responseText: accumulatedResponse,
1058
+ turnStatus
1059
+ });
1060
+ if (finalizedTurn.nextMetadata && typeof session.runtimeSession.updateMetadata === "function") {
1061
+ session.runtimeSession.updateMetadata(() => finalizedTurn.nextMetadata);
1062
+ }
1063
+ if (finalizedTurn.report) {
1064
+ emitTurnReport(finalizedTurn.report);
1065
+ }
1066
+ if (finalizedTurn.terminateMessage) {
1067
+ emitStatusMessage(finalizedTurn.terminateMessage);
1068
+ }
1069
+ accumulatedResponse = finalizedTurn.cleanedText;
1014
1070
  if (shouldCommitAccumulatedResponse) {
1015
- emitFinalAssistantMessage();
1071
+ emitFinalAssistantMessage(finalizedTurn.cleanedText);
1016
1072
  }
1017
1073
  if (!shouldExit) {
1018
1074
  session.runtimeSession.sendCodexMessage({
@@ -1177,6 +1233,19 @@ async function runCodex(opts) {
1177
1233
  let currentPermissionMode = initialPermissionMode;
1178
1234
  let currentModel;
1179
1235
  sessionClient.onUserMessage((message) => {
1236
+ const happyOrgResult = ProviderSelectionHandler.resolveHappyOrgQueuedTurn({
1237
+ metadata: sessionClient.getMetadataSnapshot?.() ?? metadata,
1238
+ message
1239
+ });
1240
+ if (happyOrgResult.nextMetadata) {
1241
+ sessionClient.updateMetadata(() => happyOrgResult.nextMetadata);
1242
+ }
1243
+ if (happyOrgResult.blocked) {
1244
+ if (happyOrgResult.statusMessage) {
1245
+ sessionClient.sendSessionEvent({ type: "message", message: happyOrgResult.statusMessage });
1246
+ }
1247
+ return;
1248
+ }
1180
1249
  const previousPermissionMode = currentPermissionMode;
1181
1250
  let messagePermissionMode = previousPermissionMode;
1182
1251
  if (message.meta?.permissionMode) {
@@ -1195,7 +1264,8 @@ async function runCodex(opts) {
1195
1264
  }
1196
1265
  messageQueue.push(message.content.text, {
1197
1266
  permissionMode: permissionResolution.resolvedPermissionMode,
1198
- model: messageModel
1267
+ model: messageModel,
1268
+ happyOrg: happyOrgResult.queuedTurn
1199
1269
  });
1200
1270
  });
1201
1271
  codexSession = new CodexSession({