very-happy-cli 0.2.110 → 0.2.112

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/dist/{AcpBackend-D0_wbTs6.cjs → AcpBackend-B3x-gQWP.cjs} +1 -1
  2. package/dist/{AcpBackend-DzZR7TEv.mjs → AcpBackend-DDEdYVW2.mjs} +1 -1
  3. package/dist/{AcpSessionManager-tWuFWeIF.mjs → AcpSessionManager-BORAhQ1r.mjs} +1 -1
  4. package/dist/{AcpSessionManager-Dcj_iHw8.cjs → AcpSessionManager-DGPLD-go.cjs} +1 -1
  5. package/dist/{config-CTyyVXHj.mjs → config-B_L5vXXu.mjs} +2 -2
  6. package/dist/{config-CTCGilz_.cjs → config-KX6e7GEu.cjs} +2 -2
  7. package/dist/{index-D-adqB7g.cjs → index-B7-t5Kwz.cjs} +4 -4
  8. package/dist/{index-CvnMiYgh.cjs → index-BnRQP3PL.cjs} +250 -20
  9. package/dist/{index-DW78HyvK.cjs → index-CTd0skWH.cjs} +2 -2
  10. package/dist/{index-Brhvj7p0.mjs → index-Cu5FdgTq.mjs} +5 -5
  11. package/dist/{index-BW9kDx5m.mjs → index-inkhalP5.mjs} +245 -17
  12. package/dist/{index-jYltd-ZW.mjs → index-lQzCAx9I.mjs} +2 -2
  13. package/dist/index.cjs +2 -2
  14. package/dist/index.mjs +2 -2
  15. package/dist/{installTerminalHooks-DhQ6k7YD.cjs → installTerminalHooks-BVk-r0yD.cjs} +2 -2
  16. package/dist/{installTerminalHooks-CJyoR9jp.mjs → installTerminalHooks-CQiW7Jn9.mjs} +2 -2
  17. package/dist/lib.cjs +1 -1
  18. package/dist/lib.d.cts +44 -0
  19. package/dist/lib.d.mts +44 -0
  20. package/dist/lib.mjs +1 -1
  21. package/dist/{mcp-Dr1PegOw.cjs → mcp-D0DIU8Q2.cjs} +2 -2
  22. package/dist/{mcp-BO9-sxMr.mjs → mcp-DD-0VkiA.mjs} +2 -2
  23. package/dist/{runGemini-CuzqF6Ys.mjs → runGemini-DHyBDo5P.mjs} +4 -4
  24. package/dist/{runGemini-D6Wwfk_0.cjs → runGemini-Dq1d8Ccb.cjs} +4 -4
  25. package/dist/{runOpenClaw-BYmlS-4Q.cjs → runOpenClaw-BHXnUF_m.cjs} +3 -3
  26. package/dist/{runOpenClaw-B5pkmSTb.mjs → runOpenClaw-DX-tgQ2V.mjs} +3 -3
  27. package/dist/{send-Btz1IZ9U.mjs → send-0TYDXiGx.mjs} +2 -2
  28. package/dist/{send-CuajooZC.cjs → send-By6zEUWo.cjs} +2 -2
  29. package/dist/{sessions-CVUBS3LG.cjs → sessions-DTBRcBRk.cjs} +2 -2
  30. package/dist/{sessions-DDwCphTQ.mjs → sessions-TM8VaCMY.mjs} +2 -2
  31. package/dist/{spawn-CwS8CPbr.cjs → spawn-CweTEYze.cjs} +57 -4
  32. package/dist/{spawn-DcA80_VN.mjs → spawn-D0oTo5BT.mjs} +56 -5
  33. package/dist/{types-BdO0jg7G.mjs → types-C5ewhu1Q.mjs} +96 -11
  34. package/dist/{types--t4zLibT.cjs → types-R11tMGyX.cjs} +97 -11
  35. package/package.json +7 -7
@@ -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.110";
54
+ var version = "0.2.112";
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.110",
168
- "very-happy-tools-x64-darwin": "0.2.110",
169
- "very-happy-tools-arm64-linux": "0.2.110",
170
- "very-happy-tools-x64-linux": "0.2.110",
171
- "very-happy-tools-arm64-win32": "0.2.110",
172
- "very-happy-tools-x64-win32": "0.2.110"
167
+ "very-happy-tools-arm64-darwin": "0.2.112",
168
+ "very-happy-tools-x64-darwin": "0.2.112",
169
+ "very-happy-tools-arm64-linux": "0.2.112",
170
+ "very-happy-tools-x64-linux": "0.2.112",
171
+ "very-happy-tools-arm64-win32": "0.2.112",
172
+ "very-happy-tools-x64-win32": "0.2.112"
173
173
  };
174
174
  var devDependencies = {
175
175
  "@slopus/happy-wire": "workspace:*",
@@ -769,6 +769,14 @@ const sessionEnvelopeSchema = z__namespace.object({
769
769
  // Codex app-server item id for this envelope. Used as the precise
770
770
  // rollback point for Codex thread duplicate/fork-from-message.
771
771
  codexItemId: z__namespace.string().min(1).optional(),
772
+ // B-309: identity of the live draft this envelope supersedes,
773
+ // `"<api message id>:<content block index>"`. Set on text/thinking
774
+ // envelopes mapped from a Claude assistant message so the web can replace
775
+ // the streamed draft with the persisted message in a single frame instead
776
+ // of letting it flicker out and back in. Absent from every other producer
777
+ // (and from CLIs older than the streaming relay) — consumers must treat a
778
+ // missing key as "no draft to claim", never as an error.
779
+ streamKey: z__namespace.string().min(1).optional(),
772
780
  // Per-API-call token usage of the assistant message this envelope was
773
781
  // mapped from (B-108). Envelope-level (not inside `ev`) so every envelope
774
782
  // type carries it uniformly — the web feeds it into its context meter.
@@ -807,6 +815,7 @@ function createEnvelope(role, ev, opts = {}) {
807
815
  ...opts.subagent ? { subagent: opts.subagent } : {},
808
816
  ...opts.claudeUuid ? { claudeUuid: opts.claudeUuid } : {},
809
817
  ...opts.codexItemId ? { codexItemId: opts.codexItemId } : {},
818
+ ...opts.streamKey ? { streamKey: opts.streamKey } : {},
810
819
  ...opts.usage ? { usage: opts.usage } : {},
811
820
  ev
812
821
  });
@@ -909,6 +918,44 @@ z__namespace.object({
909
918
  body: CoreUpdateBodySchema,
910
919
  createdAt: z__namespace.number()
911
920
  });
921
+ const STREAM_DELTA_MAX_CHARS = 16 * 1024;
922
+ const sessionStreamBlockKindSchema = z__namespace.enum(["text", "thinking"]);
923
+ const sessionStreamBlockStartSchema = z__namespace.object({
924
+ t: z__namespace.literal("block-start"),
925
+ mid: z__namespace.string().min(1),
926
+ idx: z__namespace.number().int().min(0),
927
+ kind: sessionStreamBlockKindSchema
928
+ });
929
+ const sessionStreamBlockDeltaSchema = z__namespace.object({
930
+ t: z__namespace.literal("block-delta"),
931
+ mid: z__namespace.string().min(1),
932
+ idx: z__namespace.number().int().min(0),
933
+ text: z__namespace.string().max(STREAM_DELTA_MAX_CHARS)
934
+ });
935
+ const sessionStreamBlockEndSchema = z__namespace.object({
936
+ t: z__namespace.literal("block-end"),
937
+ mid: z__namespace.string().min(1),
938
+ idx: z__namespace.number().int().min(0)
939
+ });
940
+ const sessionStreamProgressSchema = z__namespace.object({
941
+ t: z__namespace.literal("progress"),
942
+ thinkingTokens: z__namespace.number().int().min(0).optional(),
943
+ outputTokens: z__namespace.number().int().min(0).optional(),
944
+ status: z__namespace.enum(["requesting", "compacting"]).optional()
945
+ });
946
+ const sessionStreamTurnEndSchema = z__namespace.object({
947
+ t: z__namespace.literal("turn-end")
948
+ });
949
+ z__namespace.discriminatedUnion("t", [
950
+ sessionStreamBlockStartSchema,
951
+ sessionStreamBlockDeltaSchema,
952
+ sessionStreamBlockEndSchema,
953
+ sessionStreamProgressSchema,
954
+ sessionStreamTurnEndSchema
955
+ ]);
956
+ function streamKeyOf(messageId, blockIndex) {
957
+ return `${messageId}:${blockIndex}`;
958
+ }
912
959
  const VoiceConversationGrantedSchema = z__namespace.object({
913
960
  allowed: z__namespace.literal(true),
914
961
  conversationToken: z__namespace.string(),
@@ -1603,7 +1650,7 @@ class RpcHandlerManager {
1603
1650
  }
1604
1651
  }
1605
1652
 
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--t4zLibT.cjs', document.baseURI).href))));
1653
+ 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-R11tMGyX.cjs', document.baseURI).href))));
1607
1654
  function projectPath() {
1608
1655
  const path = path$1.resolve(__dirname$1, "..");
1609
1656
  return path;
@@ -2791,13 +2838,24 @@ function mapClaudeLogMessageToSessionEnvelopesInternal(message, state) {
2791
2838
  maybeEmitSubagentStart(state, turnId, subagent, envelopes);
2792
2839
  const usage = pickAssistantUsage(message);
2793
2840
  const blocks = Array.isArray(message.message?.content) ? message.message.content : [];
2794
- for (const block of blocks) {
2841
+ const apiMessageId = !isSidechainMessage(message) && typeof message.message?.id === "string" && message.message.id.length > 0 ? message.message.id : void 0;
2842
+ let blockCursor = 0;
2843
+ if (apiMessageId) {
2844
+ if (state.streamBlockMessageId !== apiMessageId) {
2845
+ state.streamBlockMessageId = apiMessageId;
2846
+ state.streamBlockCursor = 0;
2847
+ }
2848
+ blockCursor = state.streamBlockCursor ?? 0;
2849
+ state.streamBlockCursor = blockCursor + blocks.length;
2850
+ }
2851
+ const draftKey = (index) => apiMessageId ? streamKeyOf(apiMessageId, blockCursor + index) : void 0;
2852
+ for (const [blockIndex, block] of blocks.entries()) {
2795
2853
  if (block.type === "text" && typeof block.text === "string" && block.text.trim().length > 0) {
2796
- envelopes.push(createEnvelope("agent", { t: "text", text: block.text }, { turn: turnId, subagent, claudeUuid, usage }));
2854
+ envelopes.push(createEnvelope("agent", { t: "text", text: block.text }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
2797
2855
  continue;
2798
2856
  }
2799
2857
  if (block.type === "thinking" && typeof block.thinking === "string" && block.thinking.trim().length > 0) {
2800
- envelopes.push(createEnvelope("agent", { t: "text", text: block.thinking, thinking: true }, { turn: turnId, subagent, claudeUuid, usage }));
2858
+ envelopes.push(createEnvelope("agent", { t: "text", text: block.thinking, thinking: true }, { turn: turnId, subagent, claudeUuid, usage, streamKey: draftKey(blockIndex) }));
2801
2859
  continue;
2802
2860
  }
2803
2861
  if (block.type === "tool_use") {
@@ -3796,6 +3854,33 @@ class ApiSessionClient extends node_events.EventEmitter {
3796
3854
  mode
3797
3855
  });
3798
3856
  }
3857
+ /**
3858
+ * B-309: push one live stream frame (thinking/text delta or progress) to
3859
+ * this account's web clients.
3860
+ *
3861
+ * Encrypted with the SESSION key and relayed without being stored —
3862
+ * clipboard-push's shape, for clipboard-push's reasons: the relay must not
3863
+ * be able to read thinking text, and the session id is stamped by the
3864
+ * server from the authenticated connection rather than trusted from here.
3865
+ *
3866
+ * `volatile` on purpose. A draft that misses the wire while disconnected
3867
+ * is worth nothing — the persisted message is still coming, and replaying
3868
+ * stale deltas after a reconnect would paint text that has already landed.
3869
+ */
3870
+ sendStreamFrame(frame) {
3871
+ if (!this.socket.connected) return;
3872
+ try {
3873
+ this.socket.volatile.emit("session-stream", {
3874
+ // The frame object, NOT a JSON string: `encrypt` serializes
3875
+ // internally, so pre-stringifying would double-encode and
3876
+ // escape every quote in the streamed text.
3877
+ payload: encodeBase64(encrypt(this.encryptionKey, this.encryptionVariant, frame)),
3878
+ enc: true
3879
+ });
3880
+ } catch (error) {
3881
+ logger.debug(`[API] Failed to relay stream frame: ${error}`);
3882
+ }
3883
+ }
3799
3884
  /**
3800
3885
  * Send session death message
3801
3886
  */
@@ -16334,6 +16419,7 @@ exports.InvalidateSync = InvalidateSync;
16334
16419
  exports.MAX_CHAT_ATTACHMENT_SOURCE_BYTES = MAX_CHAT_ATTACHMENT_SOURCE_BYTES;
16335
16420
  exports.MIRROR_BACKFILL_LINES_DEFAULT = MIRROR_BACKFILL_LINES_DEFAULT;
16336
16421
  exports.RawJSONLinesSchema = RawJSONLinesSchema;
16422
+ exports.STREAM_DELTA_MAX_CHARS = STREAM_DELTA_MAX_CHARS;
16337
16423
  exports.SandboxConfigSchema = SandboxConfigSchema;
16338
16424
  exports.TITLE_PROMPT_PREFIX = TITLE_PROMPT_PREFIX;
16339
16425
  exports.acquireDaemonLock = acquireDaemonLock;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "very-happy-cli",
3
- "version": "0.2.110",
3
+ "version": "0.2.112",
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.110",
117
- "very-happy-tools-x64-darwin": "0.2.110",
118
- "very-happy-tools-arm64-linux": "0.2.110",
119
- "very-happy-tools-x64-linux": "0.2.110",
120
- "very-happy-tools-arm64-win32": "0.2.110",
121
- "very-happy-tools-x64-win32": "0.2.110"
116
+ "very-happy-tools-arm64-darwin": "0.2.112",
117
+ "very-happy-tools-x64-darwin": "0.2.112",
118
+ "very-happy-tools-arm64-linux": "0.2.112",
119
+ "very-happy-tools-x64-linux": "0.2.112",
120
+ "very-happy-tools-arm64-win32": "0.2.112",
121
+ "very-happy-tools-x64-win32": "0.2.112"
122
122
  },
123
123
  "devDependencies": {
124
124
  "@slopus/happy-wire": "workspace:*",