very-happy-cli 0.2.125 → 0.2.127
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AcpBackend-DOQGItcS.mjs → AcpBackend-B9_vB_mY.mjs} +2 -2
- package/dist/{AcpBackend-ssQpTLks.cjs → AcpBackend-Cbykm5Pg.cjs} +2 -2
- package/dist/{AcpSessionManager-DHLc-D50.cjs → AcpSessionManager-DGCsNKRd.cjs} +1 -1
- package/dist/{AcpSessionManager-D4WkNsRs.mjs → AcpSessionManager-HsxKXreC.mjs} +1 -1
- package/dist/{agentGuidance-Cg9ZG1pP.cjs → agentGuidance-B-CazXmT.cjs} +64 -33
- package/dist/{agentGuidance-QpYwykb9.mjs → agentGuidance-CTyzeLCQ.mjs} +62 -35
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-CZNIz3W0.mjs → config-DotNknpP.mjs} +4 -4
- package/dist/{config-BxHOGtEK.cjs → config-Dwt-15hE.cjs} +4 -4
- package/dist/{index-CrSifgJM.mjs → index-B1qzJIMw.mjs} +249 -28
- package/dist/{index-Jrk6ud3g.mjs → index-C2kblG8-.mjs} +13 -9
- package/dist/{index-D-BgvQi5.mjs → index-CWPgxeLD.mjs} +4 -4
- package/dist/{index-Do-kjc30.cjs → index-DgjzHewW.cjs} +254 -31
- package/dist/{index-D_Rm9dw9.cjs → index-DhCEmP3d.cjs} +4 -4
- package/dist/{index-CBj99SO6.cjs → index-DyvVjr8Y.cjs} +13 -9
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-CPsdeOM4.cjs → installTerminalHooks-DfBvxRdw.cjs} +4 -4
- package/dist/{installTerminalHooks-Z1Jb6yjb.mjs → installTerminalHooks-cpuDExTT.mjs} +4 -4
- package/dist/lib.cjs +2 -2
- package/dist/lib.d.cts +1 -0
- package/dist/lib.d.mts +1 -0
- package/dist/lib.mjs +2 -2
- package/dist/{limits-DViGHwSj.cjs → limits-BDG3QjIB.cjs} +7 -7
- package/dist/{limits-FjbPJPsF.mjs → limits-D2XM3dvN.mjs} +9 -9
- package/dist/{mcp-BbQ5FWcQ.cjs → mcp-BZ3iYnBc.cjs} +4 -4
- package/dist/{mcp-zqPJ94Bk.mjs → mcp-CpUrsnoC.mjs} +4 -4
- package/dist/{runGemini-BnHGYX-H.cjs → runGemini-BE_nghsj.cjs} +6 -6
- package/dist/{runGemini-Bu49s_bN.mjs → runGemini-BY7uA-Uk.mjs} +6 -6
- package/dist/{runOpenClaw-CznAYPCh.mjs → runOpenClaw-Be_U4DHZ.mjs} +5 -5
- package/dist/{runOpenClaw-3Ld1eoWV.cjs → runOpenClaw-Cqun9jar.cjs} +5 -5
- package/dist/{send-BevgS1mf.mjs → send-D2xX42zg.mjs} +4 -4
- package/dist/{send-DCzyBxLl.cjs → send-DbqRxLQW.cjs} +4 -4
- package/dist/{sessions-DSoaBHwA.cjs → sessions-CtrMbMBJ.cjs} +4 -4
- package/dist/{sessions-Ba2oRTmw.mjs → sessions-D06cLJ7f.mjs} +4 -4
- package/dist/{spawn-CqMLY6dE.cjs → spawn-Cu_kM761.cjs} +4 -4
- package/dist/{spawn-j9KBfj4e.mjs → spawn-DMx1JKXo.mjs} +4 -4
- package/dist/{teams-CmU3K9vB.cjs → teams-C2MfKWFe.cjs} +67 -7
- package/dist/{teams-C0ggJTJ-.mjs → teams-D7ubdfTY.mjs} +64 -4
- package/dist/todo-hKSIY23F.mjs +128 -0
- package/dist/todo-yvodzg_y.cjs +132 -0
- package/dist/{types-BGHnQXl5.cjs → types-BuxqyzYf.cjs} +329 -12
- package/dist/{types-DLDkfrTC.mjs → types-Df_vXvzD.mjs} +320 -6
- package/package.json +7 -7
- package/dist/resources-CVl7NdOB.cjs +0 -83
- package/dist/resources-D-mn7ptO.mjs +0 -80
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
4
|
var os = require('node:os');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
|
-
var api = require('./types-
|
|
7
|
-
var persistence = require('./limits-
|
|
6
|
+
var api = require('./types-BuxqyzYf.cjs');
|
|
7
|
+
var persistence = require('./limits-BDG3QjIB.cjs');
|
|
8
8
|
var spawn = require('cross-spawn');
|
|
9
9
|
var path = require('node:path');
|
|
10
10
|
var node_readline = require('node:readline');
|
|
11
11
|
var node_fs = require('node:fs');
|
|
12
|
-
var agentGuidance = require('./agentGuidance-
|
|
12
|
+
var agentGuidance = require('./agentGuidance-B-CazXmT.cjs');
|
|
13
13
|
var promises = require('node:fs/promises');
|
|
14
14
|
var fs = require('fs/promises');
|
|
15
15
|
var ink = require('ink');
|
|
@@ -669,7 +669,7 @@ function shouldIncludeCoAuthoredBy() {
|
|
|
669
669
|
|
|
670
670
|
const BASE_SYSTEM_PROMPT = (() => agentGuidance.trimIdent(`
|
|
671
671
|
ALWAYS when you start a new chat - you must call a tool "mcp__happy__change_title" to set a chat title. When you think chat title is not relevant anymore - call the tool again to change it. When chat name is too generic and you have a change to make it more specific - call the tool again to change it. This title is needed to easily find the chat in the future. Help human.
|
|
672
|
-
`))() + "\n\n" + agentGuidance.AGENT_GUIDANCE;
|
|
672
|
+
`))() + "\n\n" + agentGuidance.AGENT_GUIDANCE + "\n\n" + api.BUILTIN_TODO_DISCOVERY;
|
|
673
673
|
const CO_AUTHORED_CREDITS = (() => agentGuidance.trimIdent(`
|
|
674
674
|
When making commit messages, instead of just giving co-credit to Claude, also give credit to Happy like so:
|
|
675
675
|
|
|
@@ -5853,7 +5853,8 @@ async function sendUserMessage(sessionId, persisted, text, client, options = {})
|
|
|
5853
5853
|
text
|
|
5854
5854
|
},
|
|
5855
5855
|
meta: {
|
|
5856
|
-
sentFrom: options.sentFrom ?? "cli"
|
|
5856
|
+
sentFrom: options.sentFrom ?? "cli",
|
|
5857
|
+
...options.model ? { model: options.model } : {}
|
|
5857
5858
|
}
|
|
5858
5859
|
};
|
|
5859
5860
|
const encrypted = persistence.encodeBase64(persistence.encrypt(
|
|
@@ -7675,7 +7676,7 @@ function parseJsonObject(text) {
|
|
|
7675
7676
|
return null;
|
|
7676
7677
|
}
|
|
7677
7678
|
}
|
|
7678
|
-
function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
7679
|
+
function resolveSdkClaudeBinary(platform = process.platform, arch = process.arch, resolver = (s) => node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DgjzHewW.cjs', document.baseURI).href))).resolve(s)) {
|
|
7679
7680
|
const platformArch = `${platform}-${arch}`;
|
|
7680
7681
|
const candidates = [
|
|
7681
7682
|
`@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
|
|
@@ -8822,6 +8823,100 @@ async function claimSessionOrExit(happySessionId, options) {
|
|
|
8822
8823
|
process.on("exit", () => releaseSessionLock(happySessionId));
|
|
8823
8824
|
}
|
|
8824
8825
|
|
|
8826
|
+
const TEAM_SKILL = `---
|
|
8827
|
+
name: very-happy-teams
|
|
8828
|
+
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.
|
|
8829
|
+
---
|
|
8830
|
+
|
|
8831
|
+
# Very Happy Agent Teams
|
|
8832
|
+
|
|
8833
|
+
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.
|
|
8834
|
+
|
|
8835
|
+
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.
|
|
8836
|
+
|
|
8837
|
+
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. After delegating child work, wait for those results instead of continuing parallel edits yourself. Waiting parents yield their execution slot to their children; the team limit counts progressing leaf assignments, not OS processes.
|
|
8838
|
+
|
|
8839
|
+
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.
|
|
8840
|
+
|
|
8841
|
+
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.
|
|
8842
|
+
|
|
8843
|
+
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.
|
|
8844
|
+
|
|
8845
|
+
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.
|
|
8846
|
+
|
|
8847
|
+
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.
|
|
8848
|
+
|
|
8849
|
+
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.
|
|
8850
|
+
`;
|
|
8851
|
+
const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
|
|
8852
|
+
export default async function(pi) {
|
|
8853
|
+
const endpoint = process.env.HAPPY_MCP_URL;
|
|
8854
|
+
if (!endpoint) return;
|
|
8855
|
+
const url = new URL(endpoint);
|
|
8856
|
+
if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
|
|
8857
|
+
const {readFile} = await import('node:fs/promises');
|
|
8858
|
+
const {join} = await import('node:path');
|
|
8859
|
+
const {homedir} = await import('node:os');
|
|
8860
|
+
pi.on('tool_call', async (event, ctx) => {
|
|
8861
|
+
let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
|
|
8862
|
+
const sid = process.env.HAPPY_SESSION_ID;
|
|
8863
|
+
if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
|
|
8864
|
+
try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
|
|
8865
|
+
catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
|
|
8866
|
+
}
|
|
8867
|
+
if (mode === 'yolo') mode = 'bypassPermissions';
|
|
8868
|
+
if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
|
|
8869
|
+
if (mode === 'bypassPermissions') return;
|
|
8870
|
+
if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
|
|
8871
|
+
if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
|
|
8872
|
+
if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
|
|
8873
|
+
try {
|
|
8874
|
+
const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
|
|
8875
|
+
if (allowed === true) return;
|
|
8876
|
+
} catch {}
|
|
8877
|
+
return {block:true,reason:'Tool requires explicit approval'};
|
|
8878
|
+
});
|
|
8879
|
+
let nextId = 0;
|
|
8880
|
+
async function rpc(method, params) {
|
|
8881
|
+
const requestId = ++nextId;
|
|
8882
|
+
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) });
|
|
8883
|
+
if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
|
|
8884
|
+
const body = await response.text();
|
|
8885
|
+
let data;
|
|
8886
|
+
if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
|
|
8887
|
+
for (const event of body.split(/\\r?\\n\\r?\\n/)) {
|
|
8888
|
+
const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
|
|
8889
|
+
if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
|
|
8890
|
+
}
|
|
8891
|
+
} else data = JSON.parse(body);
|
|
8892
|
+
if (!data || data.error) throw new Error('Very Happy tool request failed');
|
|
8893
|
+
return data.result;
|
|
8894
|
+
}
|
|
8895
|
+
await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
|
|
8896
|
+
const available = await rpc('tools/list', {});
|
|
8897
|
+
for (const tool of available.tools || []) {
|
|
8898
|
+
pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
|
|
8899
|
+
async execute(_id, args) { const result = await rpc('tools/call', {name:tool.name,arguments:args}); return {content:result.content,details:{isError:!!result.isError}}; }
|
|
8900
|
+
});
|
|
8901
|
+
}
|
|
8902
|
+
}
|
|
8903
|
+
`;
|
|
8904
|
+
|
|
8905
|
+
function teamInitialPrompt(goal, root, directory) {
|
|
8906
|
+
const role = root ? "You are the team lead. Inspect your assigned goal, arrange independent work when useful, review member results, integrate changes, and submit the final result for the user to accept. Delegate under your assigned goal using parentTaskId. You must not accept your own root goal." : "You are a team member. Inspect your assigned task and work in your assigned worktree. Delegate within your task when useful, then submit evidence for the lead to review.";
|
|
8907
|
+
return `${TEAM_SKILL}
|
|
8908
|
+
|
|
8909
|
+
## Your role
|
|
8910
|
+
${role}
|
|
8911
|
+
|
|
8912
|
+
## Working directory
|
|
8913
|
+
${directory ? JSON.stringify(directory) : "Use your current managed session working directory."}
|
|
8914
|
+
Delegate from this working directory unless a different repository was explicitly requested.
|
|
8915
|
+
|
|
8916
|
+
## Assigned goal
|
|
8917
|
+
${goal}`;
|
|
8918
|
+
}
|
|
8919
|
+
|
|
8825
8920
|
const MAX_LINE_CHARS = 500;
|
|
8826
8921
|
const MAX_ARGS_CHARS = 160;
|
|
8827
8922
|
function truncateText(text, max = MAX_LINE_CHARS) {
|
|
@@ -9403,7 +9498,7 @@ function createTeamWorker(deps) {
|
|
|
9403
9498
|
let knownSessionIds = /* @__PURE__ */ new Set();
|
|
9404
9499
|
const action = async (teamId, requestId, value) => (await http.post(`/v1/teams/${encodeURIComponent(teamId)}/actions`, { requestId, action: value })).data;
|
|
9405
9500
|
async function complete(op, receipt) {
|
|
9406
|
-
await action(op.teamId, `complete-${op.id}`, { type: "complete-operation", operationId: op.id, machineId: deps.machineId, claimId: receipt.claimId, ...receipt.sessionId ? { sessionId: receipt.sessionId } : {} });
|
|
9501
|
+
await action(op.teamId, `complete-${op.id}`, { type: "complete-operation", operationId: op.id, machineId: deps.machineId, claimId: receipt.claimId, ...receipt.sessionId ? { sessionId: receipt.sessionId } : {}, ...op.type === "spawn" && receipt.directory ? { workingDirectory: receipt.directory } : {} });
|
|
9407
9502
|
writeReceipt(home, { ...receipt, phase: "completed" });
|
|
9408
9503
|
}
|
|
9409
9504
|
async function execute(op) {
|
|
@@ -9416,7 +9511,7 @@ function createTeamWorker(deps) {
|
|
|
9416
9511
|
}
|
|
9417
9512
|
return;
|
|
9418
9513
|
}
|
|
9419
|
-
const claimed = await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId });
|
|
9514
|
+
const claimed = await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId, ...op.teamLaunchVersion === 1 ? { teamLaunchVersion: 1 } : {} });
|
|
9420
9515
|
if (!claimed.operation?.claimId) throw new Error("Operation claim did not return a receipt");
|
|
9421
9516
|
op = claimed.operation;
|
|
9422
9517
|
credential = claimed.credential;
|
|
@@ -9427,7 +9522,7 @@ function createTeamWorker(deps) {
|
|
|
9427
9522
|
try {
|
|
9428
9523
|
if (op.type === "spawn") {
|
|
9429
9524
|
if (receipt.phase === "prepared") {
|
|
9430
|
-
if (!credential) credential = (await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId })).credential;
|
|
9525
|
+
if (!credential) credential = (await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId, ...op.teamLaunchVersion === 1 ? { teamLaunchVersion: 1 } : {} })).credential;
|
|
9431
9526
|
if (!credential) throw new Error("No scoped credential for worker");
|
|
9432
9527
|
const current = (await http.get(`/v1/teams/${encodeURIComponent(op.teamId)}`)).data.team;
|
|
9433
9528
|
const task = current.tasks.find((t) => t.id === op.taskId);
|
|
@@ -9445,7 +9540,7 @@ function createTeamWorker(deps) {
|
|
|
9445
9540
|
persistence.writePrivateFileSync(scopeFile, JSON.stringify({ serverUrl: server, scopeToken: credential.token, teamId: op.teamId, botId: op.botId, taskId: op.taskId, attemptId: op.attemptId }));
|
|
9446
9541
|
receipt = { ...receipt, ...resource, scopeFile, phase: "spawning" };
|
|
9447
9542
|
writeReceipt(home, receipt);
|
|
9448
|
-
const spawned = await deps.spawn({ directory: resource.directory, agent: op.assistant === "pi-acp" ? "pi" : op.assistant, permissionMode: "default", spawnedBy: "teams", environmentVariables: { VH_TEAM_SCOPE_FILE: scopeFile, VH_TEAM_OPERATION_ID: op.id } });
|
|
9543
|
+
const spawned = await deps.spawn({ directory: resource.directory, agent: op.assistant === "pi-acp" ? "pi" : op.assistant, permissionMode: op.permissionMode === "bypassPermissions" ? "bypassPermissions" : "default", spawnedBy: "teams", environmentVariables: { VH_TEAM_SCOPE_FILE: scopeFile, VH_TEAM_OPERATION_ID: op.id } });
|
|
9449
9544
|
if (spawned.type !== "success") throw new Error(spawned.type === "error" ? spawned.errorMessage : "Directory approval required");
|
|
9450
9545
|
receipt = { ...receipt, sessionId: spawned.sessionId, phase: "spawned" };
|
|
9451
9546
|
writeReceipt(home, receipt);
|
|
@@ -9467,7 +9562,7 @@ function createTeamWorker(deps) {
|
|
|
9467
9562
|
return;
|
|
9468
9563
|
}
|
|
9469
9564
|
const key = await waitForSessionKey(receipt.sessionId, 1e4);
|
|
9470
|
-
await sendUserMessage(receipt.sessionId, key, op.prompt, "teams", { localId: `teams-initial-${op.id}`, sentFrom: "team" });
|
|
9565
|
+
await sendUserMessage(receipt.sessionId, key, teamInitialPrompt(op.prompt, bot?.root === true, receipt.directory), "teams", { localId: `teams-initial-${op.id}`, sentFrom: "team", ...op.model ? { model: op.model } : {} });
|
|
9471
9566
|
receipt = { ...receipt, phase: "delivered" };
|
|
9472
9567
|
writeReceipt(home, receipt);
|
|
9473
9568
|
}
|
|
@@ -9569,7 +9664,7 @@ Use the teams tools to inspect current task state before acting. This message is
|
|
|
9569
9664
|
const status = axios.isAxiosError(error) ? error.response?.status : void 0;
|
|
9570
9665
|
if (status !== 404) deps.log("Teams schedule advancement unavailable; regular reconciliation continues");
|
|
9571
9666
|
}
|
|
9572
|
-
const { data } = await http.get("/v1/teams/operations", { params: { machineId: deps.machineId, schedulesVersion: 1 } });
|
|
9667
|
+
const { data } = await http.get("/v1/teams/operations", { params: { machineId: deps.machineId, schedulesVersion: 1, teamLaunchVersion: 1 } });
|
|
9573
9668
|
knownSessionIds = new Set((data.teams ?? []).flatMap((team) => team.bots.flatMap((bot) => bot.sessionId ? [bot.sessionId] : [])));
|
|
9574
9669
|
for (const op of data.operations) {
|
|
9575
9670
|
if (closed) break;
|
|
@@ -9613,6 +9708,7 @@ const hostSuffix = process.env.HAPPY_VARIANT === "dev" ? "-dev" : "";
|
|
|
9613
9708
|
const startupCliAvailability = api.detectCLIAvailability();
|
|
9614
9709
|
const initialMachineMetadata = {
|
|
9615
9710
|
teamsVersion: 1,
|
|
9711
|
+
teamLaunchVersion: 1,
|
|
9616
9712
|
host: os$1.hostname() + hostSuffix,
|
|
9617
9713
|
platform: os$1.platform(),
|
|
9618
9714
|
happyCliVersion: persistence.packageJson.version,
|
|
@@ -10883,7 +10979,8 @@ async function startDaemon() {
|
|
|
10883
10979
|
});
|
|
10884
10980
|
void apiMachine.updateMachineMetadata((current) => ({
|
|
10885
10981
|
...current ?? initialMachineMetadata,
|
|
10886
|
-
teamsVersion: 1
|
|
10982
|
+
teamsVersion: 1,
|
|
10983
|
+
teamLaunchVersion: 1
|
|
10887
10984
|
})).catch(() => persistence.logger.debug("[DAEMON RUN] Teams capability publication will retry on reconnect"));
|
|
10888
10985
|
const cleanupAndShutdown = async (source, errorMessage) => {
|
|
10889
10986
|
persistence.logger.debug(`[DAEMON RUN] Starting proper cleanup (source: ${source}, errorMessage: ${errorMessage})...`);
|
|
@@ -10922,6 +11019,113 @@ async function startDaemon() {
|
|
|
10922
11019
|
}
|
|
10923
11020
|
}
|
|
10924
11021
|
|
|
11022
|
+
const TEAMS_ADOPT_CAPABILITY = "teams-adopt-v1";
|
|
11023
|
+
const TeamAdoptSchema = z.z.object({
|
|
11024
|
+
requestId: z.z.string().min(1).max(128),
|
|
11025
|
+
name: z.z.string().trim().min(1).max(128),
|
|
11026
|
+
teamId: z.z.string().min(1).max(128).optional()
|
|
11027
|
+
}).strict();
|
|
11028
|
+
async function retainIntent(path$1, input) {
|
|
11029
|
+
await promises.mkdir(path.dirname(path$1), { recursive: true, mode: 448 });
|
|
11030
|
+
let file;
|
|
11031
|
+
try {
|
|
11032
|
+
file = await promises.open(path$1, node_fs.constants.O_WRONLY | node_fs.constants.O_CREAT | node_fs.constants.O_EXCL, 384);
|
|
11033
|
+
} catch (error) {
|
|
11034
|
+
if (error.code !== "EEXIST") throw new Error("Cannot retain team connection request");
|
|
11035
|
+
}
|
|
11036
|
+
if (file) {
|
|
11037
|
+
try {
|
|
11038
|
+
await file.writeFile(JSON.stringify(input));
|
|
11039
|
+
await file.sync();
|
|
11040
|
+
} finally {
|
|
11041
|
+
await file.close();
|
|
11042
|
+
}
|
|
11043
|
+
return { fresh: true };
|
|
11044
|
+
}
|
|
11045
|
+
const existing = await promises.open(path$1, node_fs.constants.O_RDONLY | (node_fs.constants.O_NOFOLLOW ?? 0));
|
|
11046
|
+
try {
|
|
11047
|
+
const stat = await existing.stat();
|
|
11048
|
+
if (!stat.isFile() || process.platform !== "win32" && (stat.mode & 63) !== 0 || typeof process.getuid === "function" && stat.uid !== process.getuid()) throw new Error("Unsafe team connection receipt");
|
|
11049
|
+
const stored = JSON.parse(await existing.readFile("utf8"));
|
|
11050
|
+
const { resolvedTeamId, guidanceDelivered, ...request } = stored;
|
|
11051
|
+
const previous = TeamAdoptSchema.parse(request);
|
|
11052
|
+
if (JSON.stringify(previous) !== JSON.stringify(input)) throw new Error("Another team connection request already exists; retry the original request");
|
|
11053
|
+
if (resolvedTeamId !== void 0 && (typeof resolvedTeamId !== "string" || !resolvedTeamId)) throw new Error("Invalid connection receipt");
|
|
11054
|
+
if (guidanceDelivered !== void 0 && typeof guidanceDelivered !== "boolean") throw new Error("Invalid guidance receipt");
|
|
11055
|
+
return { resolvedTeamId, guidanceDelivered };
|
|
11056
|
+
} finally {
|
|
11057
|
+
await existing.close();
|
|
11058
|
+
}
|
|
11059
|
+
}
|
|
11060
|
+
async function retainTeam(path, input, resolvedTeamId, guidanceDelivered = false) {
|
|
11061
|
+
const temporary = `${path}.${node_crypto.randomUUID()}.new`;
|
|
11062
|
+
const file = await promises.open(temporary, "wx", 384);
|
|
11063
|
+
try {
|
|
11064
|
+
await file.writeFile(JSON.stringify({ ...input, resolvedTeamId, guidanceDelivered }));
|
|
11065
|
+
await file.sync();
|
|
11066
|
+
} finally {
|
|
11067
|
+
await file.close();
|
|
11068
|
+
}
|
|
11069
|
+
try {
|
|
11070
|
+
await promises.rename(temporary, path);
|
|
11071
|
+
} finally {
|
|
11072
|
+
await promises.unlink(temporary).catch(() => {
|
|
11073
|
+
});
|
|
11074
|
+
}
|
|
11075
|
+
}
|
|
11076
|
+
function createTeamAdoption(sessionId) {
|
|
11077
|
+
const client = agentGuidance.createTeamsClient(sessionId);
|
|
11078
|
+
let current;
|
|
11079
|
+
return (raw) => {
|
|
11080
|
+
const parsed = TeamAdoptSchema.safeParse(raw);
|
|
11081
|
+
if (!parsed.success) return { error: "Invalid team connection request" };
|
|
11082
|
+
if (process.env.VH_TEAM_SCOPE_FILE) return { error: "Assigned team members cannot create or join another team" };
|
|
11083
|
+
let path;
|
|
11084
|
+
try {
|
|
11085
|
+
path = `${agentGuidance.teamScopePath(sessionId)}.adopt.json`;
|
|
11086
|
+
} catch {
|
|
11087
|
+
return { error: "A managed session identity is required" };
|
|
11088
|
+
}
|
|
11089
|
+
const input = parsed.data;
|
|
11090
|
+
const signature = JSON.stringify(input);
|
|
11091
|
+
if (current) {
|
|
11092
|
+
if (current.signature !== signature && current.safeToChange) current = void 0;
|
|
11093
|
+
else if (current.signature !== signature) return { error: "Another team connection request already exists; retry the original request" };
|
|
11094
|
+
}
|
|
11095
|
+
if (current) {
|
|
11096
|
+
const result = current.result;
|
|
11097
|
+
if (result && "error" in result) current = void 0;
|
|
11098
|
+
return result ?? { status: "pending", requestId: input.requestId };
|
|
11099
|
+
}
|
|
11100
|
+
const operation = { signature };
|
|
11101
|
+
current = operation;
|
|
11102
|
+
void (async () => {
|
|
11103
|
+
let intent;
|
|
11104
|
+
try {
|
|
11105
|
+
intent = await retainIntent(path, input);
|
|
11106
|
+
const connected = await client.initialize(input, { resumeAdoption: true, expectedTeamId: intent.resolvedTeamId, onTeamResolved: (teamId) => retainTeam(path, input, teamId, intent?.guidanceDelivered) });
|
|
11107
|
+
const instructions = `${TEAM_SKILL}
|
|
11108
|
+
|
|
11109
|
+
This session is now connected as the team lead. Call team_inspect to read the authoritative state before continuing the user's goal. Do not call team_create or team_join again.`;
|
|
11110
|
+
if (!intent.guidanceDelivered) {
|
|
11111
|
+
const key = await waitForSessionKey(sessionId, 1e4);
|
|
11112
|
+
await sendUserMessage(sessionId, key, instructions, "teams", { localId: `teams-adopt-${input.requestId}`, sentFrom: "team" });
|
|
11113
|
+
await retainTeam(path, input, connected.team.id, true);
|
|
11114
|
+
}
|
|
11115
|
+
operation.result = { status: "connected", teamId: connected.team.id, botId: connected.botId, instructions };
|
|
11116
|
+
} catch (error) {
|
|
11117
|
+
if (error instanceof agentGuidance.TeamConnectionPreflightError && intent?.fresh && !intent.resolvedTeamId) {
|
|
11118
|
+
await promises.unlink(path).catch(() => {
|
|
11119
|
+
});
|
|
11120
|
+
operation.safeToChange = true;
|
|
11121
|
+
}
|
|
11122
|
+
operation.result = { error: error instanceof Error ? error.message : "Team connection failed; retry the same request", ...operation.safeToChange ? { safeToChange: true } : {} };
|
|
11123
|
+
}
|
|
11124
|
+
})();
|
|
11125
|
+
return { status: "pending", requestId: input.requestId };
|
|
11126
|
+
};
|
|
11127
|
+
}
|
|
11128
|
+
|
|
10925
11129
|
const PERSONAL_MEMORY_SOFT_LIMIT_CHARS = 2e3;
|
|
10926
11130
|
function headingTitle(line) {
|
|
10927
11131
|
const m = /^##(?!#)\s*(.*?)\s*$/.exec(line);
|
|
@@ -11565,6 +11769,11 @@ async function startHappyServer(client, options) {
|
|
|
11565
11769
|
resolve(new URL(`http://127.0.0.1:${addr.port}`));
|
|
11566
11770
|
});
|
|
11567
11771
|
});
|
|
11772
|
+
const adoptionEnabled = !process.env.VH_TEAM_SCOPE_FILE;
|
|
11773
|
+
if (adoptionEnabled) {
|
|
11774
|
+
client.rpcHandlerManager.registerHandler("teams-adopt", createTeamAdoption(client.sessionId));
|
|
11775
|
+
client.updateMetadata((metadata) => ({ ...metadata, capabilities: [.../* @__PURE__ */ new Set([...metadata.capabilities ?? [], TEAMS_ADOPT_CAPABILITY])] }));
|
|
11776
|
+
}
|
|
11568
11777
|
persistence.logger.debug(`[happyMCP] server:ready sessionId=${client.sessionId} url=${baseUrl.toString()}`);
|
|
11569
11778
|
return {
|
|
11570
11779
|
url: baseUrl.toString(),
|
|
@@ -11578,6 +11787,7 @@ async function startHappyServer(client, options) {
|
|
|
11578
11787
|
],
|
|
11579
11788
|
stop: () => {
|
|
11580
11789
|
persistence.logger.debug(`[happyMCP] server:stop sessionId=${client.sessionId}`);
|
|
11790
|
+
if (adoptionEnabled) client.rpcHandlerManager.unregisterHandler("teams-adopt");
|
|
11581
11791
|
server.close();
|
|
11582
11792
|
}
|
|
11583
11793
|
};
|
|
@@ -11834,7 +12044,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
11834
12044
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
11835
12045
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
11836
12046
|
const run = deps.run ?? (async (input) => {
|
|
11837
|
-
const { query } = await Promise.resolve().then(function () { return require('./index-
|
|
12047
|
+
const { query } = await Promise.resolve().then(function () { return require('./index-DhCEmP3d.cjs'); });
|
|
11838
12048
|
return runSideQuestion(query, input);
|
|
11839
12049
|
});
|
|
11840
12050
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -11936,7 +12146,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
11936
12146
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
11937
12147
|
function resolveClaudeBinary() {
|
|
11938
12148
|
try {
|
|
11939
|
-
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
12149
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DgjzHewW.cjs', document.baseURI).href)));
|
|
11940
12150
|
const utilsPath = path.resolve(path.join(api.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
11941
12151
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
11942
12152
|
const path$1 = getClaudeCliPath();
|
|
@@ -14154,9 +14364,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
14154
14364
|
};
|
|
14155
14365
|
}
|
|
14156
14366
|
|
|
14157
|
-
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
14367
|
+
const __filename$1 = node_url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DgjzHewW.cjs', document.baseURI).href)));
|
|
14158
14368
|
const __dirname$1 = path.dirname(__filename$1);
|
|
14159
|
-
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-
|
|
14369
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-DgjzHewW.cjs', document.baseURI).href)));
|
|
14160
14370
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
14161
14371
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
14162
14372
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -15895,6 +16105,7 @@ function buildCodexTurnPrompt(opts) {
|
|
|
15895
16105
|
parts.push(opts.message);
|
|
15896
16106
|
if (opts.includeTitleInstruction) {
|
|
15897
16107
|
parts.push(CHANGE_TITLE_INSTRUCTION);
|
|
16108
|
+
parts.push(api.BUILTIN_TODO_DISCOVERY);
|
|
15898
16109
|
}
|
|
15899
16110
|
return parts.join("\n\n");
|
|
15900
16111
|
}
|
|
@@ -16787,7 +16998,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16787
16998
|
process.exit(0);
|
|
16788
16999
|
} else if (subcommand === "install-terminal-hooks") {
|
|
16789
17000
|
try {
|
|
16790
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
17001
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-DfBvxRdw.cjs'); });
|
|
16791
17002
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
16792
17003
|
if (command.action === "help") {
|
|
16793
17004
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -16804,7 +17015,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16804
17015
|
}
|
|
16805
17016
|
} else if (subcommand === "spawn") {
|
|
16806
17017
|
try {
|
|
16807
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
17018
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-Cu_kM761.cjs'); });
|
|
16808
17019
|
await handleSpawnCommand(args.slice(1));
|
|
16809
17020
|
} catch (error) {
|
|
16810
17021
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16816,7 +17027,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16816
17027
|
return;
|
|
16817
17028
|
} else if (subcommand === "sessions") {
|
|
16818
17029
|
try {
|
|
16819
|
-
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-
|
|
17030
|
+
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-CtrMbMBJ.cjs'); });
|
|
16820
17031
|
await handleSessionsCommand(args.slice(1));
|
|
16821
17032
|
} catch (error) {
|
|
16822
17033
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16828,7 +17039,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16828
17039
|
return;
|
|
16829
17040
|
} else if (subcommand === "send") {
|
|
16830
17041
|
try {
|
|
16831
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
17042
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-DbqRxLQW.cjs'); });
|
|
16832
17043
|
await handleSendCommand(args.slice(1));
|
|
16833
17044
|
} catch (error) {
|
|
16834
17045
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16934,9 +17145,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16934
17145
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
16935
17146
|
const projectId = args[3];
|
|
16936
17147
|
try {
|
|
16937
|
-
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
16938
|
-
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-
|
|
16939
|
-
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-
|
|
17148
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-Dwt-15hE.cjs'); });
|
|
17149
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-BDG3QjIB.cjs'); }).then(function (n) { return n.persistence; });
|
|
17150
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-BuxqyzYf.cjs'); }).then(function (n) { return n.api; });
|
|
16940
17151
|
let userEmail = void 0;
|
|
16941
17152
|
try {
|
|
16942
17153
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -16967,7 +17178,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16967
17178
|
}
|
|
16968
17179
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
16969
17180
|
try {
|
|
16970
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
17181
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-Dwt-15hE.cjs'); });
|
|
16971
17182
|
const config = readGeminiLocalConfig();
|
|
16972
17183
|
if (config.googleCloudProject) {
|
|
16973
17184
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17007,7 +17218,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17007
17218
|
process.exit(0);
|
|
17008
17219
|
}
|
|
17009
17220
|
try {
|
|
17010
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
17221
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-BE_nghsj.cjs'); });
|
|
17011
17222
|
let startedBy = void 0;
|
|
17012
17223
|
for (let i = 1; i < args.length; i++) {
|
|
17013
17224
|
if (args[i] === "--started-by") {
|
|
@@ -17037,7 +17248,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17037
17248
|
}
|
|
17038
17249
|
};
|
|
17039
17250
|
try {
|
|
17040
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17251
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-DyvVjr8Y.cjs'); });
|
|
17041
17252
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17042
17253
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17043
17254
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17064,7 +17275,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17064
17275
|
return;
|
|
17065
17276
|
} else if (subcommand === "acp") {
|
|
17066
17277
|
try {
|
|
17067
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17278
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-DyvVjr8Y.cjs'); });
|
|
17068
17279
|
let startedBy = void 0;
|
|
17069
17280
|
let verbose = false;
|
|
17070
17281
|
const acpArgs = [];
|
|
@@ -17104,7 +17315,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17104
17315
|
return;
|
|
17105
17316
|
} else if (subcommand === "openclaw") {
|
|
17106
17317
|
try {
|
|
17107
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
17318
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-Cqun9jar.cjs'); });
|
|
17108
17319
|
let startedBy = void 0;
|
|
17109
17320
|
let verbose = false;
|
|
17110
17321
|
let gatewayUrl;
|
|
@@ -17153,9 +17364,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17153
17364
|
process.exit(1);
|
|
17154
17365
|
}
|
|
17155
17366
|
return;
|
|
17367
|
+
} else if (subcommand === "todo") {
|
|
17368
|
+
try {
|
|
17369
|
+
const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-yvodzg_y.cjs'); });
|
|
17370
|
+
await handleTodoCommand(args.slice(1));
|
|
17371
|
+
} catch (error) {
|
|
17372
|
+
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
17373
|
+
process.exitCode = 1;
|
|
17374
|
+
}
|
|
17375
|
+
return;
|
|
17156
17376
|
} else if (subcommand === "teams") {
|
|
17157
17377
|
try {
|
|
17158
|
-
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-
|
|
17378
|
+
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-C2MfKWFe.cjs'); });
|
|
17159
17379
|
await handleTeamsCommand(args.slice(1));
|
|
17160
17380
|
} catch (error) {
|
|
17161
17381
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -17164,7 +17384,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17164
17384
|
return;
|
|
17165
17385
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17166
17386
|
try {
|
|
17167
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
17387
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-BZ3iYnBc.cjs'); });
|
|
17168
17388
|
await handleMcpCommand();
|
|
17169
17389
|
} catch (error) {
|
|
17170
17390
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -17391,6 +17611,7 @@ ${chalk.bold("Usage:")}
|
|
|
17391
17611
|
Install optional Claude terminal mirror hooks
|
|
17392
17612
|
(add --remove to uninstall them)
|
|
17393
17613
|
very-happy connect Connect AI vendor API keys
|
|
17614
|
+
very-happy todo Built-in Todos and official agent skill (todo --help)
|
|
17394
17615
|
very-happy sandbox Configure and manage OS-level sandboxing
|
|
17395
17616
|
very-happy notify Send push notification
|
|
17396
17617
|
very-happy mcp Stdio MCP server exposing copy_to_clipboard for a
|
|
@@ -17537,8 +17758,10 @@ exports.GOOGLE_API_KEY_ENV = GOOGLE_API_KEY_ENV;
|
|
|
17537
17758
|
exports.MAX_READ_LIMIT = MAX_READ_LIMIT;
|
|
17538
17759
|
exports.MessageBuffer = MessageBuffer;
|
|
17539
17760
|
exports.MessageQueue2 = MessageQueue2;
|
|
17761
|
+
exports.PI_TEAMS_EXTENSION = PI_TEAMS_EXTENSION;
|
|
17540
17762
|
exports.SPAWN_AGENTS = SPAWN_AGENTS;
|
|
17541
17763
|
exports.StreamRelay = StreamRelay;
|
|
17764
|
+
exports.TEAM_SKILL = TEAM_SKILL;
|
|
17542
17765
|
exports.TitleGenerator = TitleGenerator;
|
|
17543
17766
|
exports.archiveSession = archiveSession;
|
|
17544
17767
|
exports.checkIfDaemonRunningAndCleanupStaleState = checkIfDaemonRunningAndCleanupStaleState;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-DgjzHewW.cjs');
|
|
4
4
|
var claudeAgentSdk = require('@anthropic-ai/claude-agent-sdk');
|
|
5
5
|
require('chalk');
|
|
6
6
|
require('node:os');
|
|
7
7
|
require('node:crypto');
|
|
8
|
-
require('./types-
|
|
8
|
+
require('./types-BuxqyzYf.cjs');
|
|
9
9
|
require('axios');
|
|
10
|
-
require('./limits-
|
|
10
|
+
require('./limits-BDG3QjIB.cjs');
|
|
11
11
|
require('node:fs/promises');
|
|
12
12
|
require('node:fs');
|
|
13
13
|
require('node:path');
|
|
@@ -31,7 +31,7 @@ require('fs');
|
|
|
31
31
|
require('node:readline');
|
|
32
32
|
require('@anthropic-ai/sandbox-runtime');
|
|
33
33
|
require('expo-server-sdk');
|
|
34
|
-
require('./agentGuidance-
|
|
34
|
+
require('./agentGuidance-B-CazXmT.cjs');
|
|
35
35
|
require('ink');
|
|
36
36
|
require('react');
|
|
37
37
|
require('ps-list');
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var AcpBackend = require('./AcpBackend-
|
|
4
|
-
var persistence = require('./limits-
|
|
5
|
-
var AcpSessionManager = require('./AcpSessionManager-
|
|
3
|
+
var AcpBackend = require('./AcpBackend-Cbykm5Pg.cjs');
|
|
4
|
+
var persistence = require('./limits-BDG3QjIB.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-DGCsNKRd.cjs');
|
|
6
|
+
var api = require('./types-BuxqyzYf.cjs');
|
|
6
7
|
var promises = require('node:fs/promises');
|
|
7
8
|
var node_crypto = require('node:crypto');
|
|
8
9
|
var path = require('node:path');
|
|
9
|
-
var
|
|
10
|
-
var api = require('./types-BGHnQXl5.cjs');
|
|
11
|
-
var index = require('./index-Do-kjc30.cjs');
|
|
10
|
+
var index = require('./index-DgjzHewW.cjs');
|
|
12
11
|
require('node:child_process');
|
|
13
12
|
require('@agentclientprotocol/sdk');
|
|
14
13
|
require('node:fs');
|
|
@@ -34,7 +33,7 @@ require('fs');
|
|
|
34
33
|
require('node:readline');
|
|
35
34
|
require('@anthropic-ai/sandbox-runtime');
|
|
36
35
|
require('expo-server-sdk');
|
|
37
|
-
require('./agentGuidance-
|
|
36
|
+
require('./agentGuidance-B-CazXmT.cjs');
|
|
38
37
|
require('ink');
|
|
39
38
|
require('react');
|
|
40
39
|
require('@anthropic-ai/claude-agent-sdk');
|
|
@@ -75,7 +74,7 @@ async function preparePiTeamsRuntime() {
|
|
|
75
74
|
const directory = path.join(persistence.configuration.happyHomeDir, "teams", "pi-runtime");
|
|
76
75
|
await promises.mkdir(directory, { recursive: true, mode: 448 });
|
|
77
76
|
const extension = path.join(directory, "very-happy-teams.mjs");
|
|
78
|
-
await publish(extension,
|
|
77
|
+
await publish(extension, index.PI_TEAMS_EXTENSION, 384);
|
|
79
78
|
const launcher = path.join(directory, "pi-teams.mjs");
|
|
80
79
|
const script = `#!${process.execPath}
|
|
81
80
|
import { spawn } from 'node:child_process';
|
|
@@ -1075,6 +1074,7 @@ async function runAcp(opts) {
|
|
|
1075
1074
|
logAcp("muted", `Outgoing models from ${opts.agentName}: not reported yet`);
|
|
1076
1075
|
}
|
|
1077
1076
|
}
|
|
1077
|
+
let todoDiscoverySent = false;
|
|
1078
1078
|
while (!shouldExit) {
|
|
1079
1079
|
const waitSignal = abortController.signal;
|
|
1080
1080
|
const batch = await messageQueue.waitForMessagesAndGetAsString(waitSignal);
|
|
@@ -1101,7 +1101,11 @@ async function runAcp(opts) {
|
|
|
1101
1101
|
if (typeof batch.mode.model === "string" && batch.mode.model.length > 0) {
|
|
1102
1102
|
await switchModelIfRequested(batch.mode.model);
|
|
1103
1103
|
}
|
|
1104
|
-
|
|
1104
|
+
const prompt = todoDiscoverySent ? batch.message : `${batch.message}
|
|
1105
|
+
|
|
1106
|
+
${api.BUILTIN_TODO_DISCOVERY}`;
|
|
1107
|
+
await backend.sendPrompt(acpSessionId, prompt);
|
|
1108
|
+
todoDiscoverySent = true;
|
|
1105
1109
|
await turnEnded;
|
|
1106
1110
|
sendEnvelopes(sessionManager.endTurn("completed"));
|
|
1107
1111
|
streamRelay.endTurn();
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
require('chalk');
|
|
4
|
-
require('./index-
|
|
5
|
-
require('./limits-
|
|
4
|
+
require('./index-DgjzHewW.cjs');
|
|
5
|
+
require('./limits-BDG3QjIB.cjs');
|
|
6
6
|
require('zod');
|
|
7
|
-
require('./types-
|
|
7
|
+
require('./types-BuxqyzYf.cjs');
|
|
8
8
|
require('node:child_process');
|
|
9
9
|
require('node:os');
|
|
10
10
|
require('node:crypto');
|
|
@@ -12,7 +12,7 @@ require('cross-spawn');
|
|
|
12
12
|
require('node:path');
|
|
13
13
|
require('node:readline');
|
|
14
14
|
require('node:fs');
|
|
15
|
-
require('./agentGuidance-
|
|
15
|
+
require('./agentGuidance-B-CazXmT.cjs');
|
|
16
16
|
require('node:fs/promises');
|
|
17
17
|
require('fs/promises');
|
|
18
18
|
require('ink');
|