very-happy-cli 0.2.123 → 0.2.125

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 (49) hide show
  1. package/dist/{AcpBackend-hM-qHLN3.mjs → AcpBackend-DOQGItcS.mjs} +2 -1
  2. package/dist/{AcpBackend-DzIvpTxZ.cjs → AcpBackend-ssQpTLks.cjs} +30 -29
  3. package/dist/{AcpSessionManager-CRPZPHPa.mjs → AcpSessionManager-D4WkNsRs.mjs} +1 -1
  4. package/dist/{AcpSessionManager-DyU3Ikgj.cjs → AcpSessionManager-DHLc-D50.cjs} +9 -9
  5. package/dist/agentGuidance-Cg9ZG1pP.cjs +236 -0
  6. package/dist/agentGuidance-QpYwykb9.mjs +224 -0
  7. package/dist/codex/happyMcpStdioBridge.cjs +29 -6
  8. package/dist/codex/happyMcpStdioBridge.mjs +25 -2
  9. package/dist/{config-4RaHrVSV.cjs → config-BxHOGtEK.cjs} +11 -11
  10. package/dist/{config-alG86PDN.mjs → config-CZNIz3W0.mjs} +11 -11
  11. package/dist/{index-Beh0UZf8.cjs → index-CBj99SO6.cjs} +53 -19
  12. package/dist/{index-36AkXNF2.mjs → index-CrSifgJM.mjs} +2046 -1719
  13. package/dist/{index-vyYHKKk6.mjs → index-D-BgvQi5.mjs} +8 -8
  14. package/dist/{index-DWBKJ5zy.cjs → index-D_Rm9dw9.cjs} +8 -8
  15. package/dist/{index-5b9YhV-1.cjs → index-Do-kjc30.cjs} +2191 -1864
  16. package/dist/{index-Cg3Vfc00.mjs → index-Jrk6ud3g.mjs} +49 -15
  17. package/dist/index.cjs +5 -5
  18. package/dist/index.mjs +5 -5
  19. package/dist/{installTerminalHooks-DWCa5j7u.cjs → installTerminalHooks-CPsdeOM4.cjs} +9 -9
  20. package/dist/{installTerminalHooks-DqUPkh0l.mjs → installTerminalHooks-Z1Jb6yjb.mjs} +8 -8
  21. package/dist/lib.cjs +12 -12
  22. package/dist/lib.d.cts +3 -0
  23. package/dist/lib.d.mts +3 -0
  24. package/dist/lib.mjs +9 -9
  25. package/dist/limits-DViGHwSj.cjs +1198 -0
  26. package/dist/limits-FjbPJPsF.mjs +1129 -0
  27. package/dist/{mcp-BBya5dsZ.cjs → mcp-BbQ5FWcQ.cjs} +11 -10
  28. package/dist/{mcp-DZIdcsJp.mjs → mcp-zqPJ94Bk.mjs} +7 -6
  29. package/dist/resources-CVl7NdOB.cjs +83 -0
  30. package/dist/resources-D-mn7ptO.mjs +80 -0
  31. package/dist/{runGemini-DmWxHIwS.cjs → runGemini-BnHGYX-H.cjs} +30 -30
  32. package/dist/{runGemini-BQa2eF3i.mjs → runGemini-Bu49s_bN.mjs} +13 -13
  33. package/dist/{runOpenClaw-boyJtPBq.cjs → runOpenClaw-3Ld1eoWV.cjs} +24 -24
  34. package/dist/{runOpenClaw-362eg04u.mjs → runOpenClaw-CznAYPCh.mjs} +9 -9
  35. package/dist/{send-CT22-8Tp.mjs → send-BevgS1mf.mjs} +10 -10
  36. package/dist/{send-BINA__Ke.cjs → send-DCzyBxLl.cjs} +10 -10
  37. package/dist/{sessions-DemgtCkr.mjs → sessions-Ba2oRTmw.mjs} +10 -10
  38. package/dist/{sessions-DXYxV6Np.cjs → sessions-DSoaBHwA.cjs} +11 -11
  39. package/dist/{spawn-BtV9dU1i.cjs → spawn-CqMLY6dE.cjs} +21 -21
  40. package/dist/{spawn-D2egvPgO.mjs → spawn-j9KBfj4e.mjs} +21 -21
  41. package/dist/teams-C0ggJTJ-.mjs +164 -0
  42. package/dist/teams-CmU3K9vB.cjs +166 -0
  43. package/dist/{types-Cd_tUN3U.cjs → types-BGHnQXl5.cjs} +585 -1577
  44. package/dist/{types-BqW7nEN_.mjs → types-DLDkfrTC.mjs} +198 -1153
  45. package/package.json +7 -7
  46. package/dist/agentGuidance-BifkGXdE.cjs +0 -46
  47. package/dist/agentGuidance-C2_pkgRI.mjs +0 -37
  48. package/dist/limits-CwFb5S2b.mjs +0 -22
  49. package/dist/limits-KdWKmwtH.cjs +0 -28
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var agentGuidance = require('./agentGuidance-Cg9ZG1pP.cjs');
3
4
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
4
5
  var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
5
6
  var z = require('zod');
6
- var index = require('./index-5b9YhV-1.cjs');
7
- var limits = require('./limits-KdWKmwtH.cjs');
8
- var persistence = require('./types-Cd_tUN3U.cjs');
7
+ var index = require('./index-Do-kjc30.cjs');
8
+ var persistence = require('./limits-DViGHwSj.cjs');
9
9
  require('node:fs/promises');
10
10
  require('node:os');
11
11
  require('node:crypto');
@@ -13,12 +13,12 @@ require('axios');
13
13
  require('tweetnacl');
14
14
  require('socket.io-client');
15
15
  require('node:child_process');
16
+ require('./types-BGHnQXl5.cjs');
16
17
  require('node:fs');
17
18
  require('node:path');
18
19
  require('chalk');
19
20
  require('cross-spawn');
20
21
  require('node:readline');
21
- require('./agentGuidance-BifkGXdE.cjs');
22
22
  require('fs/promises');
23
23
  require('ink');
24
24
  require('react');
@@ -38,6 +38,7 @@ require('open');
38
38
  require('fastify');
39
39
  require('fastify-type-provider-zod');
40
40
  require('node:module');
41
+ require('node:util');
41
42
  require('node:http');
42
43
  require('@modelcontextprotocol/sdk/server/streamableHttp.js');
43
44
  require('http');
@@ -45,7 +46,6 @@ require('util');
45
46
  require('inquirer');
46
47
  require('node:url');
47
48
  require('node:readline/promises');
48
- require('node:util');
49
49
  require('url');
50
50
  require('node-pty');
51
51
 
@@ -62,9 +62,9 @@ function resolveMcpToolSurface(env) {
62
62
  }
63
63
 
64
64
  function registerMcpTools(server, surface, terminalId = null) {
65
- server.registerTool(limits.CLIPBOARD_TOOL_NAME, {
66
- description: limits.CLIPBOARD_TOOL_DESCRIPTION,
67
- title: limits.CLIPBOARD_TOOL_TITLE,
65
+ server.registerTool(persistence.CLIPBOARD_TOOL_NAME, {
66
+ description: persistence.CLIPBOARD_TOOL_DESCRIPTION,
67
+ title: persistence.CLIPBOARD_TOOL_TITLE,
68
68
  inputSchema: {
69
69
  text: z.z.string().describe("The text to copy to the user's clipboard")
70
70
  }
@@ -72,7 +72,7 @@ function registerMcpTools(server, surface, terminalId = null) {
72
72
  persistence.logger.debug(`[MCP] copy_to_clipboard called (${args.text.length} chars)`);
73
73
  const result = await index.pushClipboardViaDaemon(args.text);
74
74
  if (result.delivered) {
75
- const note = result.truncated ? ` (truncated to ${limits.CLIPBOARD_MAX_BYTES / 1024}KB \u2014 original was ${result.totalBytes} bytes)` : "";
75
+ const note = result.truncated ? ` (truncated to ${persistence.CLIPBOARD_MAX_BYTES / 1024}KB \u2014 original was ${result.totalBytes} bytes)` : "";
76
76
  return {
77
77
  content: [{
78
78
  type: "text",
@@ -114,7 +114,7 @@ function registerMcpTools(server, surface, terminalId = null) {
114
114
  };
115
115
  });
116
116
  }
117
- if (surface === "assistant") {
117
+ if (surface === "assistant" && !process.env.VH_TEAM_SCOPE_FILE) {
118
118
  index.registerAssistantSessionTools(server);
119
119
  }
120
120
  }
@@ -126,6 +126,7 @@ async function handleMcpCommand() {
126
126
  const surface = resolveMcpToolSurface(process.env);
127
127
  const terminalId = resolveMcpTerminalId(process.env);
128
128
  registerMcpTools(server, surface, terminalId);
129
+ if (process.env.HAPPY_MANAGED !== "1" && !process.env.HAPPY_MCP_URL) agentGuidance.registerTeamsTools(server, process.env.HAPPY_SESSION_ID);
129
130
  const transport = new stdio_js.StdioServerTransport();
130
131
  await server.connect(transport);
131
132
  persistence.logger.debug(`[MCP] very-happy stdio MCP server started (surface=${surface}, terminal=${terminalId ?? "none"})`);
@@ -1,9 +1,9 @@
1
+ import { r as registerTeamsTools } from './agentGuidance-QpYwykb9.mjs';
1
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
3
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
4
  import { z } from 'zod';
4
- import { p as pushClipboardViaDaemon, k as setTerminalTitleViaDaemon, m as registerAssistantSessionTools } from './index-36AkXNF2.mjs';
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-BqW7nEN_.mjs';
5
+ import { p as pushClipboardViaDaemon, k as setTerminalTitleViaDaemon, m as registerAssistantSessionTools } from './index-CrSifgJM.mjs';
6
+ import { l as logger, C as CLIPBOARD_TOOL_NAME, a as CLIPBOARD_TOOL_TITLE, b as CLIPBOARD_TOOL_DESCRIPTION, d as CLIPBOARD_MAX_BYTES } from './limits-FjbPJPsF.mjs';
7
7
  import 'node:fs/promises';
8
8
  import 'node:os';
9
9
  import 'node:crypto';
@@ -11,12 +11,12 @@ import 'axios';
11
11
  import 'tweetnacl';
12
12
  import 'socket.io-client';
13
13
  import 'node:child_process';
14
+ import './types-DLDkfrTC.mjs';
14
15
  import 'node:fs';
15
16
  import 'node:path';
16
17
  import 'chalk';
17
18
  import 'cross-spawn';
18
19
  import 'node:readline';
19
- import './agentGuidance-C2_pkgRI.mjs';
20
20
  import 'fs/promises';
21
21
  import 'ink';
22
22
  import 'react';
@@ -36,6 +36,7 @@ import 'open';
36
36
  import 'fastify';
37
37
  import 'fastify-type-provider-zod';
38
38
  import 'node:module';
39
+ import 'node:util';
39
40
  import 'node:http';
40
41
  import '@modelcontextprotocol/sdk/server/streamableHttp.js';
41
42
  import 'http';
@@ -43,7 +44,6 @@ import 'util';
43
44
  import 'inquirer';
44
45
  import 'node:url';
45
46
  import 'node:readline/promises';
46
- import 'node:util';
47
47
  import 'url';
48
48
  import 'node-pty';
49
49
 
@@ -112,7 +112,7 @@ function registerMcpTools(server, surface, terminalId = null) {
112
112
  };
113
113
  });
114
114
  }
115
- if (surface === "assistant") {
115
+ if (surface === "assistant" && !process.env.VH_TEAM_SCOPE_FILE) {
116
116
  registerAssistantSessionTools(server);
117
117
  }
118
118
  }
@@ -124,6 +124,7 @@ async function handleMcpCommand() {
124
124
  const surface = resolveMcpToolSurface(process.env);
125
125
  const terminalId = resolveMcpTerminalId(process.env);
126
126
  registerMcpTools(server, surface, terminalId);
127
+ if (process.env.HAPPY_MANAGED !== "1" && !process.env.HAPPY_MCP_URL) registerTeamsTools(server, process.env.HAPPY_SESSION_ID);
127
128
  const transport = new StdioServerTransport();
128
129
  await server.connect(transport);
129
130
  logger.debug(`[MCP] very-happy stdio MCP server started (surface=${surface}, terminal=${terminalId ?? "none"})`);
@@ -0,0 +1,83 @@
1
+ 'use strict';
2
+
3
+ const TEAM_SKILL = `---
4
+ name: very-happy-teams
5
+ description: Coordinate coding agents through Very Happy teams: delegate tasks, exchange messages, review results, and recover interrupted work. Use when asked to organize or participate in an agent team.
6
+ ---
7
+
8
+ # Very Happy Agent Teams
9
+
10
+ Use the team_* tools in a managed Very Happy session. If absent, explain that this host needs Very Happy Teams setup; reading this skill alone does not establish a connection.
11
+
12
+ Start with team_inspect if already assigned. Otherwise team_create or team_join connects the current session. A scoped worker cannot create another root identity or use account-wide tools to bypass its scope.
13
+
14
+ Work yourself when delegation would add needless overhead. Delegate independent work with a clear goal and acceptance criteria. When delegating within your assignment, pass its parentTaskId. Members may delegate further within their existing authority.
15
+
16
+ Name exactly one integrator for each team. Workers edit only their assigned worktrees; they must not merge main, publish releases, change global daemon or npm installations, or allocate shared backlog IDs. The integrator serializes these operations. Across teams, the owner coordinates shared resources: a worktree is not a global lock.
17
+
18
+ Use a unique requestId for each action and reuse it with identical arguments when the outcome is unknown. Inspect state before retrying; a timeout does not prove no action occurred. A delivered message is not proof its recipient processed it.
19
+
20
+ Inspect the current attemptId and goalVersion before team_submit. Include artifact locations and verification evidence. The owner reviews and accepts or returns the result. All children completing does not automatically satisfy the parent goal.
21
+
22
+ Acceptance and cleanup are separate. Never delete dirty worktrees, stop user-owned sessions, or bypass permissions to finish cleanup. Use team_cancel or team_handoff and inspect the resulting status. Keep summaries concise; do not repeatedly forward full descendant transcripts.
23
+
24
+ A root member may create a persistent schedule for itself with the schedule tools; team_inspect shows schedules. Timely delivery requires an online daemon. A scheduled delivery does not prove the model completed the work. Pause or cancel schedules explicitly when they are no longer needed.
25
+
26
+ On restart inspect authoritative state and messages before taking new actions. Do not invent completed work from a previous context. Scope credentials are runtime-owned; never read, print, or copy them into prompts.
27
+ `;
28
+ const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
29
+ export default async function(pi) {
30
+ const endpoint = process.env.HAPPY_MCP_URL;
31
+ if (!endpoint) return;
32
+ const url = new URL(endpoint);
33
+ if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
34
+ const {readFile} = await import('node:fs/promises');
35
+ const {join} = await import('node:path');
36
+ const {homedir} = await import('node:os');
37
+ pi.on('tool_call', async (event, ctx) => {
38
+ let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
39
+ const sid = process.env.HAPPY_SESSION_ID;
40
+ if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
41
+ try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
42
+ catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
43
+ }
44
+ if (mode === 'yolo') mode = 'bypassPermissions';
45
+ if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
46
+ if (mode === 'bypassPermissions') return;
47
+ if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
48
+ if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
49
+ if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
50
+ try {
51
+ const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
52
+ if (allowed === true) return;
53
+ } catch {}
54
+ return {block:true,reason:'Tool requires explicit approval'};
55
+ });
56
+ let nextId = 0;
57
+ async function rpc(method, params) {
58
+ const requestId = ++nextId;
59
+ const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: {'content-type':'application/json', accept:'application/json, text/event-stream'}, body: JSON.stringify({jsonrpc:'2.0',id:requestId,method,params}), signal: AbortSignal.timeout(30000) });
60
+ if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
61
+ const body = await response.text();
62
+ let data;
63
+ if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
64
+ for (const event of body.split(/\\r?\\n\\r?\\n/)) {
65
+ const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
66
+ if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
67
+ }
68
+ } else data = JSON.parse(body);
69
+ if (!data || data.error) throw new Error('Very Happy tool request failed');
70
+ return data.result;
71
+ }
72
+ await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
73
+ const available = await rpc('tools/list', {});
74
+ for (const tool of available.tools || []) {
75
+ pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
76
+ async execute(_id, args) { const result = await rpc('tools/call', {name:tool.name,arguments:args}); return {content:result.content,details:{isError:!!result.isError}}; }
77
+ });
78
+ }
79
+ }
80
+ `;
81
+
82
+ exports.PI_TEAMS_EXTENSION = PI_TEAMS_EXTENSION;
83
+ exports.TEAM_SKILL = TEAM_SKILL;
@@ -0,0 +1,80 @@
1
+ const TEAM_SKILL = `---
2
+ name: very-happy-teams
3
+ description: Coordinate coding agents through Very Happy teams: delegate tasks, exchange messages, review results, and recover interrupted work. Use when asked to organize or participate in an agent team.
4
+ ---
5
+
6
+ # Very Happy Agent Teams
7
+
8
+ Use the team_* tools in a managed Very Happy session. If absent, explain that this host needs Very Happy Teams setup; reading this skill alone does not establish a connection.
9
+
10
+ Start with team_inspect if already assigned. Otherwise team_create or team_join connects the current session. A scoped worker cannot create another root identity or use account-wide tools to bypass its scope.
11
+
12
+ Work yourself when delegation would add needless overhead. Delegate independent work with a clear goal and acceptance criteria. When delegating within your assignment, pass its parentTaskId. Members may delegate further within their existing authority.
13
+
14
+ Name exactly one integrator for each team. Workers edit only their assigned worktrees; they must not merge main, publish releases, change global daemon or npm installations, or allocate shared backlog IDs. The integrator serializes these operations. Across teams, the owner coordinates shared resources: a worktree is not a global lock.
15
+
16
+ Use a unique requestId for each action and reuse it with identical arguments when the outcome is unknown. Inspect state before retrying; a timeout does not prove no action occurred. A delivered message is not proof its recipient processed it.
17
+
18
+ Inspect the current attemptId and goalVersion before team_submit. Include artifact locations and verification evidence. The owner reviews and accepts or returns the result. All children completing does not automatically satisfy the parent goal.
19
+
20
+ Acceptance and cleanup are separate. Never delete dirty worktrees, stop user-owned sessions, or bypass permissions to finish cleanup. Use team_cancel or team_handoff and inspect the resulting status. Keep summaries concise; do not repeatedly forward full descendant transcripts.
21
+
22
+ A root member may create a persistent schedule for itself with the schedule tools; team_inspect shows schedules. Timely delivery requires an online daemon. A scheduled delivery does not prove the model completed the work. Pause or cancel schedules explicitly when they are no longer needed.
23
+
24
+ On restart inspect authoritative state and messages before taking new actions. Do not invent completed work from a previous context. Scope credentials are runtime-owned; never read, print, or copy them into prompts.
25
+ `;
26
+ const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
27
+ export default async function(pi) {
28
+ const endpoint = process.env.HAPPY_MCP_URL;
29
+ if (!endpoint) return;
30
+ const url = new URL(endpoint);
31
+ if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
32
+ const {readFile} = await import('node:fs/promises');
33
+ const {join} = await import('node:path');
34
+ const {homedir} = await import('node:os');
35
+ pi.on('tool_call', async (event, ctx) => {
36
+ let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
37
+ const sid = process.env.HAPPY_SESSION_ID;
38
+ if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
39
+ try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
40
+ catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
41
+ }
42
+ if (mode === 'yolo') mode = 'bypassPermissions';
43
+ if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
44
+ if (mode === 'bypassPermissions') return;
45
+ if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
46
+ if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
47
+ if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
48
+ try {
49
+ const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
50
+ if (allowed === true) return;
51
+ } catch {}
52
+ return {block:true,reason:'Tool requires explicit approval'};
53
+ });
54
+ let nextId = 0;
55
+ async function rpc(method, params) {
56
+ const requestId = ++nextId;
57
+ const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: {'content-type':'application/json', accept:'application/json, text/event-stream'}, body: JSON.stringify({jsonrpc:'2.0',id:requestId,method,params}), signal: AbortSignal.timeout(30000) });
58
+ if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
59
+ const body = await response.text();
60
+ let data;
61
+ if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
62
+ for (const event of body.split(/\\r?\\n\\r?\\n/)) {
63
+ const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
64
+ if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
65
+ }
66
+ } else data = JSON.parse(body);
67
+ if (!data || data.error) throw new Error('Very Happy tool request failed');
68
+ return data.result;
69
+ }
70
+ await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
71
+ const available = await rpc('tools/list', {});
72
+ for (const tool of available.tools || []) {
73
+ pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
74
+ async execute(_id, args) { const result = await rpc('tools/call', {name:tool.name,arguments:args}); return {content:result.content,details:{isError:!!result.isError}}; }
75
+ });
76
+ }
77
+ }
78
+ `;
79
+
80
+ export { PI_TEAMS_EXTENSION as P, TEAM_SKILL as T };
@@ -4,22 +4,16 @@ 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-Cd_tUN3U.cjs');
8
- var index = require('./index-5b9YhV-1.cjs');
9
- var AcpBackend = require('./AcpBackend-DzIvpTxZ.cjs');
10
- var config = require('./config-4RaHrVSV.cjs');
7
+ var api = require('./types-BGHnQXl5.cjs');
8
+ var persistence = require('./limits-DViGHwSj.cjs');
9
+ var index = require('./index-Do-kjc30.cjs');
10
+ var AcpBackend = require('./AcpBackend-ssQpTLks.cjs');
11
+ var config = require('./config-BxHOGtEK.cjs');
11
12
  require('axios');
12
- require('chalk');
13
- require('node:util');
14
- require('node:fs');
15
- require('node:os');
16
- require('node:fs/promises');
17
13
  require('node:events');
18
14
  require('socket.io-client');
19
15
  require('zod');
20
16
  require('@paralleldrive/cuid2');
21
- require('tweetnacl');
22
- require('./limits-KdWKmwtH.cjs');
23
17
  require('child_process');
24
18
  require('util');
25
19
  require('fs/promises');
@@ -28,13 +22,19 @@ require('path');
28
22
  require('cross-spawn');
29
23
  require('url');
30
24
  require('os');
25
+ require('node:fs/promises');
26
+ require('node:os');
31
27
  require('node:child_process');
32
28
  require('node-pty');
29
+ require('node:fs');
33
30
  require('fs');
31
+ require('tweetnacl');
34
32
  require('node:readline');
35
33
  require('@anthropic-ai/sandbox-runtime');
36
34
  require('expo-server-sdk');
37
- require('./agentGuidance-BifkGXdE.cjs');
35
+ require('chalk');
36
+ require('node:util');
37
+ require('./agentGuidance-Cg9ZG1pP.cjs');
38
38
  require('@anthropic-ai/claude-agent-sdk');
39
39
  require('ps-list');
40
40
  require('tmp');
@@ -860,8 +860,8 @@ ${formattedMessages}
860
860
 
861
861
  async function runGemini(opts) {
862
862
  const sessionTag = node_crypto.randomUUID();
863
- persistence.connectionState.setBackend("Gemini");
864
- const api = await persistence.ApiClient.create(opts.credentials);
863
+ api.connectionState.setBackend("Gemini");
864
+ const api$1 = await api.ApiClient.create(opts.credentials);
865
865
  const settings = await persistence.readSettings();
866
866
  const machineId = settings?.machineId;
867
867
  const sandboxConfig = settings?.sandboxConfig;
@@ -870,14 +870,14 @@ async function runGemini(opts) {
870
870
  process.exit(1);
871
871
  }
872
872
  persistence.logger.debug(`Using machineId: ${machineId}`);
873
- await api.getOrCreateMachine({
873
+ await api$1.getOrCreateMachine({
874
874
  machineId,
875
875
  metadata: index.initialMachineMetadata
876
876
  });
877
877
  let cloudToken = void 0;
878
878
  let currentUserEmail = void 0;
879
879
  try {
880
- const vendorToken = await api.getVendorToken("gemini");
880
+ const vendorToken = await api$1.getVendorToken("gemini");
881
881
  if (vendorToken?.oauth?.access_token) {
882
882
  cloudToken = vendorToken.oauth.access_token;
883
883
  persistence.logger.debug("[Gemini] Using OAuth token from Happy cloud");
@@ -897,7 +897,7 @@ async function runGemini(opts) {
897
897
  }
898
898
  }
899
899
  } catch (error) {
900
- persistence.logger.debug("[Gemini] Failed to fetch cloud token:", persistence.errorLogMetadata(error));
900
+ persistence.logger.debug("[Gemini] Failed to fetch cloud token:", api.errorLogMetadata(error));
901
901
  }
902
902
  const { state, metadata } = index.createSessionMetadata({
903
903
  flavor: "gemini",
@@ -905,7 +905,7 @@ async function runGemini(opts) {
905
905
  startedBy: opts.startedBy,
906
906
  sandbox: sandboxConfig
907
907
  });
908
- const response = await api.getOrCreateSession({ tag: sessionTag, metadata, state });
908
+ const response = await api$1.getOrCreateSession({ tag: sessionTag, metadata, state });
909
909
  let session;
910
910
  let permissionHandler;
911
911
  let isProcessingMessage = false;
@@ -921,7 +921,7 @@ async function runGemini(opts) {
921
921
  }
922
922
  };
923
923
  const { session: initialSession, reconnectionHandle } = index.setupOfflineReconnection({
924
- api,
924
+ api: api$1,
925
925
  sessionTag,
926
926
  metadata,
927
927
  state,
@@ -1028,7 +1028,7 @@ async function runGemini(opts) {
1028
1028
  const sendReady = () => {
1029
1029
  session.sendSessionEvent({ type: "ready" });
1030
1030
  try {
1031
- api.push().sendSessionNotification({
1031
+ api$1.push().sendSessionNotification({
1032
1032
  kind: "done",
1033
1033
  metadata: session.getMetadata(),
1034
1034
  data: {
@@ -1168,7 +1168,7 @@ async function runGemini(opts) {
1168
1168
  process.stdin.setEncoding("utf8");
1169
1169
  }
1170
1170
  const happyServer = await index.startHappyServer(session);
1171
- const bridgeCommand = path.join(persistence.projectPath(), "bin", "happy-mcp.mjs");
1171
+ const bridgeCommand = path.join(api.projectPath(), "bin", "very-happy-mcp.mjs");
1172
1172
  const mcpServers = {
1173
1173
  happy: {
1174
1174
  command: bridgeCommand,
@@ -1211,10 +1211,10 @@ async function runGemini(opts) {
1211
1211
  case "status":
1212
1212
  const statusDetail = msg.detail ? typeof msg.detail === "object" ? JSON.stringify(msg.detail) : String(msg.detail) : "";
1213
1213
  persistence.logger.debug(`[gemini] Status changed: ${msg.status}`, {
1214
- detail: persistence.contentLogMetadata(statusDetail)
1214
+ detail: api.contentLogMetadata(statusDetail)
1215
1215
  });
1216
1216
  if (msg.status === "error") {
1217
- persistence.logger.debug("[gemini] Error status received:", persistence.contentLogMetadata(statusDetail));
1217
+ persistence.logger.debug("[gemini] Error status received:", api.contentLogMetadata(statusDetail));
1218
1218
  session.sendAgentMessage("gemini", {
1219
1219
  type: "turn_aborted",
1220
1220
  id: node_crypto.randomUUID()
@@ -1266,7 +1266,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1266
1266
  const isInvestigationTool = msg.toolName === "codebase_investigator" || typeof msg.toolName === "string" && msg.toolName.includes("investigator");
1267
1267
  persistence.logger.debug(`[gemini] \u{1F527} Tool call received: ${msg.toolName} (${msg.callId})${isInvestigationTool ? " [INVESTIGATION]" : ""}`);
1268
1268
  if (isInvestigationTool && msg.args && typeof msg.args === "object" && "objective" in msg.args) {
1269
- persistence.logger.debug("[gemini] Investigation objective received:", persistence.contentLogMetadata(msg.args.objective));
1269
+ persistence.logger.debug("[gemini] Investigation objective received:", api.contentLogMetadata(msg.args.objective));
1270
1270
  }
1271
1271
  messageBuffer.addMessage(`Executing: ${msg.toolName}${toolArgs ? ` ${toolArgs}${toolArgs.length >= 100 ? "..." : ""}` : ""}`, "tool");
1272
1272
  session.sendAgentMessage("gemini", {
@@ -1292,7 +1292,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1292
1292
  }
1293
1293
  if (isError) {
1294
1294
  const errorMsg = msg.result.error || "Tool call failed";
1295
- persistence.logger.debug("[gemini] Tool call error received:", persistence.contentLogMetadata(errorMsg));
1295
+ persistence.logger.debug("[gemini] Tool call error received:", api.contentLogMetadata(errorMsg));
1296
1296
  messageBuffer.addMessage(`Error: ${errorMsg}`, "status");
1297
1297
  } else {
1298
1298
  if (resultSize > 1e3) {
@@ -1410,7 +1410,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1410
1410
  const thinkingText = thinkingPayload && typeof thinkingPayload === "object" && "text" in thinkingPayload ? String(thinkingPayload.text || "") : "";
1411
1411
  if (thinkingText) {
1412
1412
  reasoningProcessor.processChunk(thinkingText);
1413
- persistence.logger.debug("[gemini] Thinking chunk received:", persistence.contentLogMetadata(thinkingText));
1413
+ persistence.logger.debug("[gemini] Thinking chunk received:", api.contentLogMetadata(thinkingText));
1414
1414
  if (!thinkingText.startsWith("**")) {
1415
1415
  const thinkingPreview = thinkingText.substring(0, 100);
1416
1416
  messageBuffer.updateLastMessage(`[Thinking] ${thinkingPreview}...`, "system");
@@ -1549,7 +1549,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1549
1549
  promptToSend = historyContext + promptToSend;
1550
1550
  persistence.logger.debug(`[gemini] Injected conversation history context (${historyContext.length} chars)`);
1551
1551
  }
1552
- persistence.logger.debug("[gemini] Sending prompt to Gemini:", persistence.contentLogMetadata(promptToSend));
1552
+ persistence.logger.debug("[gemini] Sending prompt to Gemini:", api.contentLogMetadata(promptToSend));
1553
1553
  const MAX_RETRIES = 3;
1554
1554
  const RETRY_DELAY_MS = 2e3;
1555
1555
  let lastError = null;
@@ -1584,7 +1584,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1584
1584
  const isInternalError = errorCode === -32603;
1585
1585
  const isRetryable = isEmptyResponseError || isInternalError;
1586
1586
  if (isRetryable && attempt < MAX_RETRIES) {
1587
- persistence.logger.debug(`[gemini] Retryable error on attempt ${attempt}/${MAX_RETRIES}:`, persistence.contentLogMetadata(errorDetails));
1587
+ persistence.logger.debug(`[gemini] Retryable error on attempt ${attempt}/${MAX_RETRIES}:`, api.contentLogMetadata(errorDetails));
1588
1588
  messageBuffer.addMessage(`Gemini returned empty response, retrying (${attempt}/${MAX_RETRIES})...`, "status");
1589
1589
  await new Promise((resolve2) => setTimeout(resolve2, RETRY_DELAY_MS * attempt));
1590
1590
  continue;
@@ -1599,7 +1599,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1599
1599
  first = false;
1600
1600
  }
1601
1601
  } catch (error) {
1602
- persistence.logger.debug("[gemini] Error in gemini session:", persistence.errorLogMetadata(error));
1602
+ persistence.logger.debug("[gemini] Error in gemini session:", api.errorLogMetadata(error));
1603
1603
  const isAbortError = error instanceof Error && error.name === "AbortError";
1604
1604
  if (isAbortError) {
1605
1605
  messageBuffer.addMessage("Aborted by user", "status");
@@ -1667,7 +1667,7 @@ Guide: https://goo.gle/gemini-cli-auth-docs#workspace-gca`;
1667
1667
  id: node_crypto.randomUUID(),
1668
1668
  ...options.length > 0 && { options }
1669
1669
  };
1670
- persistence.logger.debug("[gemini] Sending complete message to mobile:", persistence.contentLogMetadata(finalMessageText));
1670
+ persistence.logger.debug("[gemini] Sending complete message to mobile:", api.contentLogMetadata(finalMessageText));
1671
1671
  session.sendAgentMessage("gemini", messagePayload);
1672
1672
  accumulatedResponse = "";
1673
1673
  isResponseInProgress = false;
@@ -2,22 +2,16 @@ 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, d as connectionState, A as ApiClient, e as readSettings, h as errorLogMetadata, f as encodeBase64, p as projectPath, g as contentLogMetadata } from './types-BqW7nEN_.mjs';
6
- import { J as GEMINI_API_KEY_ENV, K as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, E as BasePermissionHandler, L as BaseReasoningProcessor, n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, y as MessageQueue2, z as hashObject, N as MessageBuffer, O as CHANGE_TITLE_INSTRUCTION, C as registerKillSessionHandler, B as startHappyServer } from './index-36AkXNF2.mjs';
7
- import { A as AcpBackend } from './AcpBackend-hM-qHLN3.mjs';
8
- import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-alG86PDN.mjs';
5
+ import { f as connectionState, A as ApiClient, e as errorLogMetadata, p as projectPath, b as contentLogMetadata } from './types-DLDkfrTC.mjs';
6
+ import { l as logger, f as readSettings, g as encodeBase64 } from './limits-FjbPJPsF.mjs';
7
+ import { J as GEMINI_API_KEY_ENV, K as GOOGLE_API_KEY_ENV, G as GEMINI_MODEL_ENV, E as BasePermissionHandler, L as BaseReasoningProcessor, n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, x as MessageQueue2, B as hashObject, N as MessageBuffer, O as CHANGE_TITLE_INSTRUCTION, y as registerKillSessionHandler, C as startHappyServer } from './index-CrSifgJM.mjs';
8
+ import { A as AcpBackend } from './AcpBackend-DOQGItcS.mjs';
9
+ import { readGeminiLocalConfig, determineGeminiModel, getGeminiModelSource, getInitialGeminiModel, saveGeminiModelToConfig } from './config-CZNIz3W0.mjs';
9
10
  import 'axios';
10
- import 'chalk';
11
- import 'node:util';
12
- import 'node:fs';
13
- import 'node:os';
14
- import 'node:fs/promises';
15
11
  import 'node:events';
16
12
  import 'socket.io-client';
17
13
  import 'zod';
18
14
  import '@paralleldrive/cuid2';
19
- import 'tweetnacl';
20
- import './limits-CwFb5S2b.mjs';
21
15
  import 'child_process';
22
16
  import 'util';
23
17
  import 'fs/promises';
@@ -26,13 +20,19 @@ import 'path';
26
20
  import 'cross-spawn';
27
21
  import 'url';
28
22
  import 'os';
23
+ import 'node:fs/promises';
24
+ import 'node:os';
29
25
  import 'node:child_process';
30
26
  import 'node-pty';
27
+ import 'node:fs';
31
28
  import 'fs';
29
+ import 'tweetnacl';
32
30
  import 'node:readline';
33
31
  import '@anthropic-ai/sandbox-runtime';
34
32
  import 'expo-server-sdk';
35
- import './agentGuidance-C2_pkgRI.mjs';
33
+ import 'chalk';
34
+ import 'node:util';
35
+ import './agentGuidance-QpYwykb9.mjs';
36
36
  import '@anthropic-ai/claude-agent-sdk';
37
37
  import 'ps-list';
38
38
  import 'tmp';
@@ -1166,7 +1166,7 @@ async function runGemini(opts) {
1166
1166
  process.stdin.setEncoding("utf8");
1167
1167
  }
1168
1168
  const happyServer = await startHappyServer(session);
1169
- const bridgeCommand = join(projectPath(), "bin", "happy-mcp.mjs");
1169
+ const bridgeCommand = join(projectPath(), "bin", "very-happy-mcp.mjs");
1170
1170
  const mcpServers = {
1171
1171
  happy: {
1172
1172
  command: bridgeCommand,