very-happy-cli 0.2.126 → 0.2.128
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-C9eu6CDu.cjs → AcpBackend-BYU6J2n0.cjs} +2 -2
- package/dist/{AcpBackend-BzGpBAZ0.mjs → AcpBackend-D7987ody.mjs} +2 -2
- package/dist/{AcpSessionManager-B223yT78.mjs → AcpSessionManager-BwrjVZyn.mjs} +1 -1
- package/dist/{AcpSessionManager-DQ1e_0gc.cjs → AcpSessionManager-artXJgqb.cjs} +1 -1
- package/dist/{agentGuidance-Tm8Z5HYp.cjs → agentGuidance-B1xYgHx6.cjs} +63 -33
- package/dist/{agentGuidance-BR0OFumQ.mjs → agentGuidance-BPGPaNlo.mjs} +62 -35
- package/dist/codex/happyMcpStdioBridge.cjs +2 -2
- package/dist/codex/happyMcpStdioBridge.mjs +2 -2
- package/dist/{config-Bjd1nG0P.mjs → config-DSBE0Az0.mjs} +4 -4
- package/dist/{config-C0mofvCH.cjs → config-Dmkzs3o4.cjs} +4 -4
- package/dist/{index-BP56asuS.mjs → index-35FahgEU.mjs} +4 -4
- package/dist/{index-HW-KdG6W.cjs → index-CJmXLSQc.cjs} +4 -4
- package/dist/{index-D4eCRu9x.mjs → index-CfM6ewd8.mjs} +249 -27
- package/dist/{index-Cw9Zj1Zr.cjs → index-D_YVlpsW.cjs} +254 -30
- package/dist/{index-CV6sAa4a.mjs → index-m0Dnccc_.mjs} +13 -9
- package/dist/{index-CMbKpntk.cjs → index-vyTJsT_R.cjs} +13 -9
- package/dist/index.cjs +4 -4
- package/dist/index.mjs +4 -4
- package/dist/{installTerminalHooks-CNp1LExn.cjs → installTerminalHooks-C1zwiJJ2.cjs} +4 -4
- package/dist/{installTerminalHooks-D-CNSalI.mjs → installTerminalHooks-ClrFe2fA.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-DlbYYtOw.mjs → limits-BNTLh2lw.mjs} +9 -9
- package/dist/{limits-DG1OQnCb.cjs → limits-CrwtFbi8.cjs} +7 -7
- package/dist/{mcp-BtZoIIIM.cjs → mcp-Bc_mmJt8.cjs} +4 -4
- package/dist/{mcp-D3oV_dH-.mjs → mcp-BsohER5A.mjs} +4 -4
- package/dist/{runGemini-BfCSOPL1.cjs → runGemini-B2GesRWm.cjs} +6 -6
- package/dist/{runGemini-BJ8bU1pP.mjs → runGemini-B9S85Vms.mjs} +6 -6
- package/dist/{runOpenClaw-DTgOpJnO.mjs → runOpenClaw-Byhq-B1y.mjs} +5 -5
- package/dist/{runOpenClaw-CBlHXEAT.cjs → runOpenClaw-DCK-R8qe.cjs} +5 -5
- package/dist/{send-CDK1bZFj.cjs → send-CPdT1nOg.cjs} +4 -4
- package/dist/{send-9duZlpGX.mjs → send-DQS1zNWp.mjs} +4 -4
- package/dist/{sessions-CNkLCorF.cjs → sessions-DC0IKaD9.cjs} +4 -4
- package/dist/{sessions-jAFOkKvW.mjs → sessions-DIOdWnPe.mjs} +4 -4
- package/dist/{spawn-BG5oHi_f.mjs → spawn-DV4pIAHZ.mjs} +4 -4
- package/dist/{spawn-J-A5WGZ7.cjs → spawn-DrnCW2QK.cjs} +4 -4
- package/dist/{teams-MgWeyutG.cjs → teams-CwXEJs9I.cjs} +41 -6
- package/dist/{teams-Cuqsk7Ty.mjs → teams-DlTHOiCk.mjs} +38 -3
- package/dist/todo-BwXURAbQ.mjs +128 -0
- package/dist/todo-DrME15xq.cjs +132 -0
- package/dist/{types-n_VWu9qe.mjs → types-CFs8FmiY.mjs} +318 -6
- package/dist/{types-P5deH8Ls.cjs → types-DfatCoQL.cjs} +327 -12
- 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-DfatCoQL.cjs');
|
|
7
|
+
var persistence = require('./limits-CrwtFbi8.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-B1xYgHx6.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
|
|
|
@@ -4764,6 +4764,7 @@ function createSessionMetadata(opts) {
|
|
|
4764
4764
|
version: persistence.packageJson.version,
|
|
4765
4765
|
os: os.platform(),
|
|
4766
4766
|
machineId: opts.machineId,
|
|
4767
|
+
...opts.teamOperationId ? { teamOperationId: opts.teamOperationId } : {},
|
|
4767
4768
|
homeDir: os.homedir(),
|
|
4768
4769
|
happyHomeDir: persistence.configuration.happyHomeDir,
|
|
4769
4770
|
happyLibDir: api.projectPath(),
|
|
@@ -5853,7 +5854,8 @@ async function sendUserMessage(sessionId, persisted, text, client, options = {})
|
|
|
5853
5854
|
text
|
|
5854
5855
|
},
|
|
5855
5856
|
meta: {
|
|
5856
|
-
sentFrom: options.sentFrom ?? "cli"
|
|
5857
|
+
sentFrom: options.sentFrom ?? "cli",
|
|
5858
|
+
...options.model ? { model: options.model } : {}
|
|
5857
5859
|
}
|
|
5858
5860
|
};
|
|
5859
5861
|
const encrypted = persistence.encodeBase64(persistence.encrypt(
|
|
@@ -7675,7 +7677,7 @@ function parseJsonObject(text) {
|
|
|
7675
7677
|
return null;
|
|
7676
7678
|
}
|
|
7677
7679
|
}
|
|
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-
|
|
7680
|
+
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-D_YVlpsW.cjs', document.baseURI).href))).resolve(s)) {
|
|
7679
7681
|
const platformArch = `${platform}-${arch}`;
|
|
7680
7682
|
const candidates = [
|
|
7681
7683
|
`@anthropic-ai/claude-agent-sdk-${platformArch}/claude`,
|
|
@@ -8822,6 +8824,100 @@ async function claimSessionOrExit(happySessionId, options) {
|
|
|
8822
8824
|
process.on("exit", () => releaseSessionLock(happySessionId));
|
|
8823
8825
|
}
|
|
8824
8826
|
|
|
8827
|
+
const TEAM_SKILL = `---
|
|
8828
|
+
name: very-happy-teams
|
|
8829
|
+
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.
|
|
8830
|
+
---
|
|
8831
|
+
|
|
8832
|
+
# Very Happy Agent Teams
|
|
8833
|
+
|
|
8834
|
+
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.
|
|
8835
|
+
|
|
8836
|
+
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.
|
|
8837
|
+
|
|
8838
|
+
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.
|
|
8839
|
+
|
|
8840
|
+
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.
|
|
8841
|
+
|
|
8842
|
+
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.
|
|
8843
|
+
|
|
8844
|
+
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.
|
|
8845
|
+
|
|
8846
|
+
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.
|
|
8847
|
+
|
|
8848
|
+
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.
|
|
8849
|
+
|
|
8850
|
+
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.
|
|
8851
|
+
`;
|
|
8852
|
+
const PI_TEAMS_EXTENSION = `// Managed by Very Happy Agent Teams.
|
|
8853
|
+
export default async function(pi) {
|
|
8854
|
+
const endpoint = process.env.HAPPY_MCP_URL;
|
|
8855
|
+
if (!endpoint) return;
|
|
8856
|
+
const url = new URL(endpoint);
|
|
8857
|
+
if (!['127.0.0.1', 'localhost', '[::1]'].includes(url.hostname) || url.protocol !== 'http:') throw new Error('Very Happy MCP must be local');
|
|
8858
|
+
const {readFile} = await import('node:fs/promises');
|
|
8859
|
+
const {join} = await import('node:path');
|
|
8860
|
+
const {homedir} = await import('node:os');
|
|
8861
|
+
pi.on('tool_call', async (event, ctx) => {
|
|
8862
|
+
let mode = process.env.HAPPY_PERMISSION_MODE || 'default';
|
|
8863
|
+
const sid = process.env.HAPPY_SESSION_ID;
|
|
8864
|
+
if (sid && /^[a-zA-Z0-9_-]+$/.test(sid)) {
|
|
8865
|
+
try { mode = JSON.parse(await readFile(join(process.env.HAPPY_HOME_DIR || join(homedir(), '.happy'), 'session-modes', sid + '.json'), 'utf8')).permissionMode; }
|
|
8866
|
+
catch (error) { if (error.code !== 'ENOENT') mode = 'default'; }
|
|
8867
|
+
}
|
|
8868
|
+
if (mode === 'yolo') mode = 'bypassPermissions';
|
|
8869
|
+
if (!['default','plan','acceptEdits','bypassPermissions'].includes(mode)) mode = 'default';
|
|
8870
|
+
if (mode === 'bypassPermissions') return;
|
|
8871
|
+
if (['read','ls','find','grep','team_inspect','change_title','report_progress'].includes(event.toolName)) return;
|
|
8872
|
+
if (mode === 'plan') return {block:true,reason:'Plan mode allows read-only tools'};
|
|
8873
|
+
if (mode === 'acceptEdits' && ['write','edit'].includes(event.toolName)) return;
|
|
8874
|
+
try {
|
|
8875
|
+
const allowed = await ctx.ui.confirm('Allow ' + event.toolName + '?', JSON.stringify(event.input || {}).slice(0,4000));
|
|
8876
|
+
if (allowed === true) return;
|
|
8877
|
+
} catch {}
|
|
8878
|
+
return {block:true,reason:'Tool requires explicit approval'};
|
|
8879
|
+
});
|
|
8880
|
+
let nextId = 0;
|
|
8881
|
+
async function rpc(method, params) {
|
|
8882
|
+
const requestId = ++nextId;
|
|
8883
|
+
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) });
|
|
8884
|
+
if (!response.ok) throw new Error('Very Happy tools unavailable (HTTP ' + response.status + ')');
|
|
8885
|
+
const body = await response.text();
|
|
8886
|
+
let data;
|
|
8887
|
+
if ((response.headers.get('content-type') || '').includes('text/event-stream')) {
|
|
8888
|
+
for (const event of body.split(/\\r?\\n\\r?\\n/)) {
|
|
8889
|
+
const payload = event.split(/\\r?\\n/).filter(line => line.startsWith('data:')).map(line => line.slice(5).trimStart()).join('\\n');
|
|
8890
|
+
if (payload) { const candidate = JSON.parse(payload); if (candidate.id === requestId) data = candidate; }
|
|
8891
|
+
}
|
|
8892
|
+
} else data = JSON.parse(body);
|
|
8893
|
+
if (!data || data.error) throw new Error('Very Happy tool request failed');
|
|
8894
|
+
return data.result;
|
|
8895
|
+
}
|
|
8896
|
+
await rpc('initialize', {protocolVersion:'2024-11-05',capabilities:{},clientInfo:{name:'very-happy-pi-teams',version:'1'}});
|
|
8897
|
+
const available = await rpc('tools/list', {});
|
|
8898
|
+
for (const tool of available.tools || []) {
|
|
8899
|
+
pi.registerTool({name:tool.name,label:tool.name,description:tool.description || tool.name,parameters:tool.inputSchema,
|
|
8900
|
+
async execute(_id, args) { const result = await rpc('tools/call', {name:tool.name,arguments:args}); return {content:result.content,details:{isError:!!result.isError}}; }
|
|
8901
|
+
});
|
|
8902
|
+
}
|
|
8903
|
+
}
|
|
8904
|
+
`;
|
|
8905
|
+
|
|
8906
|
+
function teamInitialPrompt(goal, root, directory) {
|
|
8907
|
+
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.";
|
|
8908
|
+
return `${TEAM_SKILL}
|
|
8909
|
+
|
|
8910
|
+
## Your role
|
|
8911
|
+
${role}
|
|
8912
|
+
|
|
8913
|
+
## Working directory
|
|
8914
|
+
${directory ? JSON.stringify(directory) : "Use your current managed session working directory."}
|
|
8915
|
+
Delegate from this working directory unless a different repository was explicitly requested.
|
|
8916
|
+
|
|
8917
|
+
## Assigned goal
|
|
8918
|
+
${goal}`;
|
|
8919
|
+
}
|
|
8920
|
+
|
|
8825
8921
|
const MAX_LINE_CHARS = 500;
|
|
8826
8922
|
const MAX_ARGS_CHARS = 160;
|
|
8827
8923
|
function truncateText(text, max = MAX_LINE_CHARS) {
|
|
@@ -9403,7 +9499,7 @@ function createTeamWorker(deps) {
|
|
|
9403
9499
|
let knownSessionIds = /* @__PURE__ */ new Set();
|
|
9404
9500
|
const action = async (teamId, requestId, value) => (await http.post(`/v1/teams/${encodeURIComponent(teamId)}/actions`, { requestId, action: value })).data;
|
|
9405
9501
|
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 } : {} });
|
|
9502
|
+
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
9503
|
writeReceipt(home, { ...receipt, phase: "completed" });
|
|
9408
9504
|
}
|
|
9409
9505
|
async function execute(op) {
|
|
@@ -9416,7 +9512,7 @@ function createTeamWorker(deps) {
|
|
|
9416
9512
|
}
|
|
9417
9513
|
return;
|
|
9418
9514
|
}
|
|
9419
|
-
const claimed = await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId });
|
|
9515
|
+
const claimed = await action(op.teamId, `claim-${op.id}`, { type: "claim-operation", operationId: op.id, machineId: deps.machineId, ...op.teamLaunchVersion === 1 ? { teamLaunchVersion: 1 } : {} });
|
|
9420
9516
|
if (!claimed.operation?.claimId) throw new Error("Operation claim did not return a receipt");
|
|
9421
9517
|
op = claimed.operation;
|
|
9422
9518
|
credential = claimed.credential;
|
|
@@ -9427,7 +9523,7 @@ function createTeamWorker(deps) {
|
|
|
9427
9523
|
try {
|
|
9428
9524
|
if (op.type === "spawn") {
|
|
9429
9525
|
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;
|
|
9526
|
+
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
9527
|
if (!credential) throw new Error("No scoped credential for worker");
|
|
9432
9528
|
const current = (await http.get(`/v1/teams/${encodeURIComponent(op.teamId)}`)).data.team;
|
|
9433
9529
|
const task = current.tasks.find((t) => t.id === op.taskId);
|
|
@@ -9467,7 +9563,7 @@ function createTeamWorker(deps) {
|
|
|
9467
9563
|
return;
|
|
9468
9564
|
}
|
|
9469
9565
|
const key = await waitForSessionKey(receipt.sessionId, 1e4);
|
|
9470
|
-
await sendUserMessage(receipt.sessionId, key, op.prompt, "teams", { localId: `teams-initial-${op.id}`, sentFrom: "team" });
|
|
9566
|
+
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
9567
|
receipt = { ...receipt, phase: "delivered" };
|
|
9472
9568
|
writeReceipt(home, receipt);
|
|
9473
9569
|
}
|
|
@@ -9569,7 +9665,7 @@ Use the teams tools to inspect current task state before acting. This message is
|
|
|
9569
9665
|
const status = axios.isAxiosError(error) ? error.response?.status : void 0;
|
|
9570
9666
|
if (status !== 404) deps.log("Teams schedule advancement unavailable; regular reconciliation continues");
|
|
9571
9667
|
}
|
|
9572
|
-
const { data } = await http.get("/v1/teams/operations", { params: { machineId: deps.machineId, schedulesVersion: 1 } });
|
|
9668
|
+
const { data } = await http.get("/v1/teams/operations", { params: { machineId: deps.machineId, schedulesVersion: 1, teamLaunchVersion: 1 } });
|
|
9573
9669
|
knownSessionIds = new Set((data.teams ?? []).flatMap((team) => team.bots.flatMap((bot) => bot.sessionId ? [bot.sessionId] : [])));
|
|
9574
9670
|
for (const op of data.operations) {
|
|
9575
9671
|
if (closed) break;
|
|
@@ -9613,6 +9709,7 @@ const hostSuffix = process.env.HAPPY_VARIANT === "dev" ? "-dev" : "";
|
|
|
9613
9709
|
const startupCliAvailability = api.detectCLIAvailability();
|
|
9614
9710
|
const initialMachineMetadata = {
|
|
9615
9711
|
teamsVersion: 1,
|
|
9712
|
+
teamLaunchVersion: 1,
|
|
9616
9713
|
host: os$1.hostname() + hostSuffix,
|
|
9617
9714
|
platform: os$1.platform(),
|
|
9618
9715
|
happyCliVersion: persistence.packageJson.version,
|
|
@@ -10883,7 +10980,8 @@ async function startDaemon() {
|
|
|
10883
10980
|
});
|
|
10884
10981
|
void apiMachine.updateMachineMetadata((current) => ({
|
|
10885
10982
|
...current ?? initialMachineMetadata,
|
|
10886
|
-
teamsVersion: 1
|
|
10983
|
+
teamsVersion: 1,
|
|
10984
|
+
teamLaunchVersion: 1
|
|
10887
10985
|
})).catch(() => persistence.logger.debug("[DAEMON RUN] Teams capability publication will retry on reconnect"));
|
|
10888
10986
|
const cleanupAndShutdown = async (source, errorMessage) => {
|
|
10889
10987
|
persistence.logger.debug(`[DAEMON RUN] Starting proper cleanup (source: ${source}, errorMessage: ${errorMessage})...`);
|
|
@@ -10922,6 +11020,113 @@ async function startDaemon() {
|
|
|
10922
11020
|
}
|
|
10923
11021
|
}
|
|
10924
11022
|
|
|
11023
|
+
const TEAMS_ADOPT_CAPABILITY = "teams-adopt-v1";
|
|
11024
|
+
const TeamAdoptSchema = z.z.object({
|
|
11025
|
+
requestId: z.z.string().min(1).max(128),
|
|
11026
|
+
name: z.z.string().trim().min(1).max(128),
|
|
11027
|
+
teamId: z.z.string().min(1).max(128).optional()
|
|
11028
|
+
}).strict();
|
|
11029
|
+
async function retainIntent(path$1, input) {
|
|
11030
|
+
await promises.mkdir(path.dirname(path$1), { recursive: true, mode: 448 });
|
|
11031
|
+
let file;
|
|
11032
|
+
try {
|
|
11033
|
+
file = await promises.open(path$1, node_fs.constants.O_WRONLY | node_fs.constants.O_CREAT | node_fs.constants.O_EXCL, 384);
|
|
11034
|
+
} catch (error) {
|
|
11035
|
+
if (error.code !== "EEXIST") throw new Error("Cannot retain team connection request");
|
|
11036
|
+
}
|
|
11037
|
+
if (file) {
|
|
11038
|
+
try {
|
|
11039
|
+
await file.writeFile(JSON.stringify(input));
|
|
11040
|
+
await file.sync();
|
|
11041
|
+
} finally {
|
|
11042
|
+
await file.close();
|
|
11043
|
+
}
|
|
11044
|
+
return { fresh: true };
|
|
11045
|
+
}
|
|
11046
|
+
const existing = await promises.open(path$1, node_fs.constants.O_RDONLY | (node_fs.constants.O_NOFOLLOW ?? 0));
|
|
11047
|
+
try {
|
|
11048
|
+
const stat = await existing.stat();
|
|
11049
|
+
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");
|
|
11050
|
+
const stored = JSON.parse(await existing.readFile("utf8"));
|
|
11051
|
+
const { resolvedTeamId, guidanceDelivered, ...request } = stored;
|
|
11052
|
+
const previous = TeamAdoptSchema.parse(request);
|
|
11053
|
+
if (JSON.stringify(previous) !== JSON.stringify(input)) throw new Error("Another team connection request already exists; retry the original request");
|
|
11054
|
+
if (resolvedTeamId !== void 0 && (typeof resolvedTeamId !== "string" || !resolvedTeamId)) throw new Error("Invalid connection receipt");
|
|
11055
|
+
if (guidanceDelivered !== void 0 && typeof guidanceDelivered !== "boolean") throw new Error("Invalid guidance receipt");
|
|
11056
|
+
return { resolvedTeamId, guidanceDelivered };
|
|
11057
|
+
} finally {
|
|
11058
|
+
await existing.close();
|
|
11059
|
+
}
|
|
11060
|
+
}
|
|
11061
|
+
async function retainTeam(path, input, resolvedTeamId, guidanceDelivered = false) {
|
|
11062
|
+
const temporary = `${path}.${node_crypto.randomUUID()}.new`;
|
|
11063
|
+
const file = await promises.open(temporary, "wx", 384);
|
|
11064
|
+
try {
|
|
11065
|
+
await file.writeFile(JSON.stringify({ ...input, resolvedTeamId, guidanceDelivered }));
|
|
11066
|
+
await file.sync();
|
|
11067
|
+
} finally {
|
|
11068
|
+
await file.close();
|
|
11069
|
+
}
|
|
11070
|
+
try {
|
|
11071
|
+
await promises.rename(temporary, path);
|
|
11072
|
+
} finally {
|
|
11073
|
+
await promises.unlink(temporary).catch(() => {
|
|
11074
|
+
});
|
|
11075
|
+
}
|
|
11076
|
+
}
|
|
11077
|
+
function createTeamAdoption(sessionId) {
|
|
11078
|
+
const client = agentGuidance.createTeamsClient(sessionId);
|
|
11079
|
+
let current;
|
|
11080
|
+
return (raw) => {
|
|
11081
|
+
const parsed = TeamAdoptSchema.safeParse(raw);
|
|
11082
|
+
if (!parsed.success) return { error: "Invalid team connection request" };
|
|
11083
|
+
if (process.env.VH_TEAM_SCOPE_FILE) return { error: "Assigned team members cannot create or join another team" };
|
|
11084
|
+
let path;
|
|
11085
|
+
try {
|
|
11086
|
+
path = `${agentGuidance.teamScopePath(sessionId)}.adopt.json`;
|
|
11087
|
+
} catch {
|
|
11088
|
+
return { error: "A managed session identity is required" };
|
|
11089
|
+
}
|
|
11090
|
+
const input = parsed.data;
|
|
11091
|
+
const signature = JSON.stringify(input);
|
|
11092
|
+
if (current) {
|
|
11093
|
+
if (current.signature !== signature && current.safeToChange) current = void 0;
|
|
11094
|
+
else if (current.signature !== signature) return { error: "Another team connection request already exists; retry the original request" };
|
|
11095
|
+
}
|
|
11096
|
+
if (current) {
|
|
11097
|
+
const result = current.result;
|
|
11098
|
+
if (result && "error" in result) current = void 0;
|
|
11099
|
+
return result ?? { status: "pending", requestId: input.requestId };
|
|
11100
|
+
}
|
|
11101
|
+
const operation = { signature };
|
|
11102
|
+
current = operation;
|
|
11103
|
+
void (async () => {
|
|
11104
|
+
let intent;
|
|
11105
|
+
try {
|
|
11106
|
+
intent = await retainIntent(path, input);
|
|
11107
|
+
const connected = await client.initialize(input, { resumeAdoption: true, expectedTeamId: intent.resolvedTeamId, onTeamResolved: (teamId) => retainTeam(path, input, teamId, intent?.guidanceDelivered) });
|
|
11108
|
+
const instructions = `${TEAM_SKILL}
|
|
11109
|
+
|
|
11110
|
+
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.`;
|
|
11111
|
+
if (!intent.guidanceDelivered) {
|
|
11112
|
+
const key = await waitForSessionKey(sessionId, 1e4);
|
|
11113
|
+
await sendUserMessage(sessionId, key, instructions, "teams", { localId: `teams-adopt-${input.requestId}`, sentFrom: "team" });
|
|
11114
|
+
await retainTeam(path, input, connected.team.id, true);
|
|
11115
|
+
}
|
|
11116
|
+
operation.result = { status: "connected", teamId: connected.team.id, botId: connected.botId, instructions };
|
|
11117
|
+
} catch (error) {
|
|
11118
|
+
if (error instanceof agentGuidance.TeamConnectionPreflightError && intent?.fresh && !intent.resolvedTeamId) {
|
|
11119
|
+
await promises.unlink(path).catch(() => {
|
|
11120
|
+
});
|
|
11121
|
+
operation.safeToChange = true;
|
|
11122
|
+
}
|
|
11123
|
+
operation.result = { error: error instanceof Error ? error.message : "Team connection failed; retry the same request", ...operation.safeToChange ? { safeToChange: true } : {} };
|
|
11124
|
+
}
|
|
11125
|
+
})();
|
|
11126
|
+
return { status: "pending", requestId: input.requestId };
|
|
11127
|
+
};
|
|
11128
|
+
}
|
|
11129
|
+
|
|
10925
11130
|
const PERSONAL_MEMORY_SOFT_LIMIT_CHARS = 2e3;
|
|
10926
11131
|
function headingTitle(line) {
|
|
10927
11132
|
const m = /^##(?!#)\s*(.*?)\s*$/.exec(line);
|
|
@@ -11565,6 +11770,11 @@ async function startHappyServer(client, options) {
|
|
|
11565
11770
|
resolve(new URL(`http://127.0.0.1:${addr.port}`));
|
|
11566
11771
|
});
|
|
11567
11772
|
});
|
|
11773
|
+
const adoptionEnabled = !process.env.VH_TEAM_SCOPE_FILE;
|
|
11774
|
+
if (adoptionEnabled) {
|
|
11775
|
+
client.rpcHandlerManager.registerHandler("teams-adopt", createTeamAdoption(client.sessionId));
|
|
11776
|
+
client.updateMetadata((metadata) => ({ ...metadata, capabilities: [.../* @__PURE__ */ new Set([...metadata.capabilities ?? [], TEAMS_ADOPT_CAPABILITY])] }));
|
|
11777
|
+
}
|
|
11568
11778
|
persistence.logger.debug(`[happyMCP] server:ready sessionId=${client.sessionId} url=${baseUrl.toString()}`);
|
|
11569
11779
|
return {
|
|
11570
11780
|
url: baseUrl.toString(),
|
|
@@ -11578,6 +11788,7 @@ async function startHappyServer(client, options) {
|
|
|
11578
11788
|
],
|
|
11579
11789
|
stop: () => {
|
|
11580
11790
|
persistence.logger.debug(`[happyMCP] server:stop sessionId=${client.sessionId}`);
|
|
11791
|
+
if (adoptionEnabled) client.rpcHandlerManager.unregisterHandler("teams-adopt");
|
|
11581
11792
|
server.close();
|
|
11582
11793
|
}
|
|
11583
11794
|
};
|
|
@@ -11834,7 +12045,7 @@ function registerSideQuestionHandler(rpc, deps) {
|
|
|
11834
12045
|
const retainMs = deps.retainMs ?? SIDE_QUESTION_RETAIN_MS;
|
|
11835
12046
|
const maxRunMs = deps.maxRunMs ?? SIDE_QUESTION_MAX_RUN_MS;
|
|
11836
12047
|
const run = deps.run ?? (async (input) => {
|
|
11837
|
-
const { query } = await Promise.resolve().then(function () { return require('./index-
|
|
12048
|
+
const { query } = await Promise.resolve().then(function () { return require('./index-CJmXLSQc.cjs'); });
|
|
11838
12049
|
return runSideQuestion(query, input);
|
|
11839
12050
|
});
|
|
11840
12051
|
const slots = /* @__PURE__ */ new Map();
|
|
@@ -11936,7 +12147,7 @@ const MAX_TITLE_CHARS = 60;
|
|
|
11936
12147
|
const GENERATION_TIMEOUT_MS = 3e4;
|
|
11937
12148
|
function resolveClaudeBinary() {
|
|
11938
12149
|
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-
|
|
12150
|
+
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-D_YVlpsW.cjs', document.baseURI).href)));
|
|
11940
12151
|
const utilsPath = path.resolve(path.join(api.projectPath(), "scripts", "claude_version_utils.cjs"));
|
|
11941
12152
|
const { getClaudeCliPath } = require$1(utilsPath);
|
|
11942
12153
|
const path$1 = getClaudeCliPath();
|
|
@@ -14154,9 +14365,9 @@ function resolveLocalSignupBootstrap(configuredMode, configuredInviteCodes, gene
|
|
|
14154
14365
|
};
|
|
14155
14366
|
}
|
|
14156
14367
|
|
|
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-
|
|
14368
|
+
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-D_YVlpsW.cjs', document.baseURI).href)));
|
|
14158
14369
|
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-
|
|
14370
|
+
const require_ = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index-D_YVlpsW.cjs', document.baseURI).href)));
|
|
14160
14371
|
const PRISMA_QUERY_ENGINE_FILES = {
|
|
14161
14372
|
"arm64-darwin": "libquery_engine-darwin-arm64.dylib.node",
|
|
14162
14373
|
"x64-darwin": "libquery_engine-darwin.dylib.node",
|
|
@@ -15895,6 +16106,7 @@ function buildCodexTurnPrompt(opts) {
|
|
|
15895
16106
|
parts.push(opts.message);
|
|
15896
16107
|
if (opts.includeTitleInstruction) {
|
|
15897
16108
|
parts.push(CHANGE_TITLE_INSTRUCTION);
|
|
16109
|
+
parts.push(api.BUILTIN_TODO_DISCOVERY);
|
|
15898
16110
|
}
|
|
15899
16111
|
return parts.join("\n\n");
|
|
15900
16112
|
}
|
|
@@ -16787,7 +16999,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16787
16999
|
process.exit(0);
|
|
16788
17000
|
} else if (subcommand === "install-terminal-hooks") {
|
|
16789
17001
|
try {
|
|
16790
|
-
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-
|
|
17002
|
+
const { installTerminalHooks, parseTerminalHooksArgs, TERMINAL_HOOKS_HELP } = await Promise.resolve().then(function () { return require('./installTerminalHooks-C1zwiJJ2.cjs'); });
|
|
16791
17003
|
const command = parseTerminalHooksArgs(args.slice(1));
|
|
16792
17004
|
if (command.action === "help") {
|
|
16793
17005
|
console.log(TERMINAL_HOOKS_HELP);
|
|
@@ -16804,7 +17016,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16804
17016
|
}
|
|
16805
17017
|
} else if (subcommand === "spawn") {
|
|
16806
17018
|
try {
|
|
16807
|
-
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-
|
|
17019
|
+
const { handleSpawnCommand } = await Promise.resolve().then(function () { return require('./spawn-DrnCW2QK.cjs'); });
|
|
16808
17020
|
await handleSpawnCommand(args.slice(1));
|
|
16809
17021
|
} catch (error) {
|
|
16810
17022
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16816,7 +17028,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16816
17028
|
return;
|
|
16817
17029
|
} else if (subcommand === "sessions") {
|
|
16818
17030
|
try {
|
|
16819
|
-
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-
|
|
17031
|
+
const { handleSessionsCommand } = await Promise.resolve().then(function () { return require('./sessions-DC0IKaD9.cjs'); });
|
|
16820
17032
|
await handleSessionsCommand(args.slice(1));
|
|
16821
17033
|
} catch (error) {
|
|
16822
17034
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16828,7 +17040,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16828
17040
|
return;
|
|
16829
17041
|
} else if (subcommand === "send") {
|
|
16830
17042
|
try {
|
|
16831
|
-
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-
|
|
17043
|
+
const { handleSendCommand } = await Promise.resolve().then(function () { return require('./send-CPdT1nOg.cjs'); });
|
|
16832
17044
|
await handleSendCommand(args.slice(1));
|
|
16833
17045
|
} catch (error) {
|
|
16834
17046
|
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16934,9 +17146,9 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16934
17146
|
if (geminiSubcommand === "project" && args[2] === "set" && args[3]) {
|
|
16935
17147
|
const projectId = args[3];
|
|
16936
17148
|
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-
|
|
17149
|
+
const { saveGoogleCloudProjectToConfig } = await Promise.resolve().then(function () { return require('./config-Dmkzs3o4.cjs'); });
|
|
17150
|
+
const { readCredentialsForConfiguredRelay: readCredentialsForConfiguredRelay2 } = await Promise.resolve().then(function () { return require('./limits-CrwtFbi8.cjs'); }).then(function (n) { return n.persistence; });
|
|
17151
|
+
const { ApiClient: ApiClient2 } = await Promise.resolve().then(function () { return require('./types-DfatCoQL.cjs'); }).then(function (n) { return n.api; });
|
|
16940
17152
|
let userEmail = void 0;
|
|
16941
17153
|
try {
|
|
16942
17154
|
const credentials = await readCredentialsForConfiguredRelay2();
|
|
@@ -16967,7 +17179,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
16967
17179
|
}
|
|
16968
17180
|
if (geminiSubcommand === "project" && args[2] === "get") {
|
|
16969
17181
|
try {
|
|
16970
|
-
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-
|
|
17182
|
+
const { readGeminiLocalConfig } = await Promise.resolve().then(function () { return require('./config-Dmkzs3o4.cjs'); });
|
|
16971
17183
|
const config = readGeminiLocalConfig();
|
|
16972
17184
|
if (config.googleCloudProject) {
|
|
16973
17185
|
console.log(`Current Google Cloud Project: ${config.googleCloudProject}`);
|
|
@@ -17007,7 +17219,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17007
17219
|
process.exit(0);
|
|
17008
17220
|
}
|
|
17009
17221
|
try {
|
|
17010
|
-
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-
|
|
17222
|
+
const { runGemini } = await Promise.resolve().then(function () { return require('./runGemini-B2GesRWm.cjs'); });
|
|
17011
17223
|
let startedBy = void 0;
|
|
17012
17224
|
for (let i = 1; i < args.length; i++) {
|
|
17013
17225
|
if (args[i] === "--started-by") {
|
|
@@ -17037,7 +17249,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17037
17249
|
}
|
|
17038
17250
|
};
|
|
17039
17251
|
try {
|
|
17040
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17252
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-vyTJsT_R.cjs'); });
|
|
17041
17253
|
const parsed = parsePiRunnerArgs(args.slice(1));
|
|
17042
17254
|
const resolved = resolveAcpAgentConfig(["pi", ...parsed.passthrough]);
|
|
17043
17255
|
const { credentials } = await authAndSetupMachineIfNeeded();
|
|
@@ -17064,7 +17276,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17064
17276
|
return;
|
|
17065
17277
|
} else if (subcommand === "acp") {
|
|
17066
17278
|
try {
|
|
17067
|
-
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-
|
|
17279
|
+
const { runAcp, resolveAcpAgentConfig } = await Promise.resolve().then(function () { return require('./index-vyTJsT_R.cjs'); });
|
|
17068
17280
|
let startedBy = void 0;
|
|
17069
17281
|
let verbose = false;
|
|
17070
17282
|
const acpArgs = [];
|
|
@@ -17104,7 +17316,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17104
17316
|
return;
|
|
17105
17317
|
} else if (subcommand === "openclaw") {
|
|
17106
17318
|
try {
|
|
17107
|
-
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-
|
|
17319
|
+
const { runOpenClaw } = await Promise.resolve().then(function () { return require('./runOpenClaw-DCK-R8qe.cjs'); });
|
|
17108
17320
|
let startedBy = void 0;
|
|
17109
17321
|
let verbose = false;
|
|
17110
17322
|
let gatewayUrl;
|
|
@@ -17153,9 +17365,18 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17153
17365
|
process.exit(1);
|
|
17154
17366
|
}
|
|
17155
17367
|
return;
|
|
17368
|
+
} else if (subcommand === "todo") {
|
|
17369
|
+
try {
|
|
17370
|
+
const { handleTodoCommand } = await Promise.resolve().then(function () { return require('./todo-DrME15xq.cjs'); });
|
|
17371
|
+
await handleTodoCommand(args.slice(1));
|
|
17372
|
+
} catch (error) {
|
|
17373
|
+
console.error(JSON.stringify({ error: error instanceof Error ? error.message : "Todo command failed" }));
|
|
17374
|
+
process.exitCode = 1;
|
|
17375
|
+
}
|
|
17376
|
+
return;
|
|
17156
17377
|
} else if (subcommand === "teams") {
|
|
17157
17378
|
try {
|
|
17158
|
-
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-
|
|
17379
|
+
const { handleTeamsCommand } = await Promise.resolve().then(function () { return require('./teams-CwXEJs9I.cjs'); });
|
|
17159
17380
|
await handleTeamsCommand(args.slice(1));
|
|
17160
17381
|
} catch (error) {
|
|
17161
17382
|
console.error(error instanceof Error ? error.message : "Teams command failed");
|
|
@@ -17164,7 +17385,7 @@ Conversation history is preserved on the server, but in-flight tool calls are in
|
|
|
17164
17385
|
return;
|
|
17165
17386
|
} else if (subcommand === "mcp" && args.length === 1) {
|
|
17166
17387
|
try {
|
|
17167
|
-
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-
|
|
17388
|
+
const { handleMcpCommand } = await Promise.resolve().then(function () { return require('./mcp-Bc_mmJt8.cjs'); });
|
|
17168
17389
|
await handleMcpCommand();
|
|
17169
17390
|
} catch (error) {
|
|
17170
17391
|
process.stderr.write(`[very-happy mcp] Fatal: ${error instanceof Error ? error.message : String(error)}
|
|
@@ -17391,6 +17612,7 @@ ${chalk.bold("Usage:")}
|
|
|
17391
17612
|
Install optional Claude terminal mirror hooks
|
|
17392
17613
|
(add --remove to uninstall them)
|
|
17393
17614
|
very-happy connect Connect AI vendor API keys
|
|
17615
|
+
very-happy todo Built-in Todos and official agent skill (todo --help)
|
|
17394
17616
|
very-happy sandbox Configure and manage OS-level sandboxing
|
|
17395
17617
|
very-happy notify Send push notification
|
|
17396
17618
|
very-happy mcp Stdio MCP server exposing copy_to_clipboard for a
|
|
@@ -17537,8 +17759,10 @@ exports.GOOGLE_API_KEY_ENV = GOOGLE_API_KEY_ENV;
|
|
|
17537
17759
|
exports.MAX_READ_LIMIT = MAX_READ_LIMIT;
|
|
17538
17760
|
exports.MessageBuffer = MessageBuffer;
|
|
17539
17761
|
exports.MessageQueue2 = MessageQueue2;
|
|
17762
|
+
exports.PI_TEAMS_EXTENSION = PI_TEAMS_EXTENSION;
|
|
17540
17763
|
exports.SPAWN_AGENTS = SPAWN_AGENTS;
|
|
17541
17764
|
exports.StreamRelay = StreamRelay;
|
|
17765
|
+
exports.TEAM_SKILL = TEAM_SKILL;
|
|
17542
17766
|
exports.TitleGenerator = TitleGenerator;
|
|
17543
17767
|
exports.archiveSession = archiveSession;
|
|
17544
17768
|
exports.checkIfDaemonRunningAndCleanupStaleState = checkIfDaemonRunningAndCleanupStaleState;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-
|
|
2
|
-
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-
|
|
3
|
-
import { c as configuration,
|
|
4
|
-
import { A as AcpSessionManager } from './AcpSessionManager-
|
|
1
|
+
import { D as DefaultTransport, A as AcpBackend } from './AcpBackend-D7987ody.mjs';
|
|
2
|
+
export { a as DEFAULT_IDLE_TIMEOUT_MS, b as DEFAULT_TOOL_CALL_TIMEOUT_MS, e as extractErrorDetail, f as formatDuration, c as formatDurationMinutes, h as handleAgentMessageChunk, d as handleAgentThoughtChunk, g as handleLegacyMessageChunk, i as handlePlanUpdate, j as handleThinkingUpdate, k as handleToolCall, l as handleToolCallUpdate, p as parseArgsFromContent } from './AcpBackend-D7987ody.mjs';
|
|
3
|
+
import { c as configuration, g as readSettings, i as encodeBase64, l as logger } from './limits-BNTLh2lw.mjs';
|
|
4
|
+
import { A as AcpSessionManager } from './AcpSessionManager-BwrjVZyn.mjs';
|
|
5
|
+
import { g as connectionState, A as ApiClient, p as projectPath, h as BUILTIN_TODO_DISCOVERY } from './types-CFs8FmiY.mjs';
|
|
5
6
|
import { mkdir, chmod, writeFile, rename } from 'node:fs/promises';
|
|
6
7
|
import { randomUUID } from 'node:crypto';
|
|
7
8
|
import { join } from 'node:path';
|
|
8
|
-
import { P as PI_TEAMS_EXTENSION } from './
|
|
9
|
-
import { f as connectionState, A as ApiClient, p as projectPath } from './types-n_VWu9qe.mjs';
|
|
10
|
-
import { n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, z as StreamRelay, x as MessageQueue2, B as hashObject, C as startHappyServer, T as TitleGenerator, y as registerKillSessionHandler, E as BasePermissionHandler, F as writeSessionModeFile, H as normalizeAcpPermissionMode, I as removeSessionModeFile } from './index-D4eCRu9x.mjs';
|
|
9
|
+
import { P as PI_TEAMS_EXTENSION, n as initialMachineMetadata, o as createSessionMetadata, u as setupOfflineReconnection, v as notifyDaemonSessionStarted, z as StreamRelay, x as MessageQueue2, B as hashObject, C as startHappyServer, E as TitleGenerator, y as registerKillSessionHandler, F as BasePermissionHandler, H as writeSessionModeFile, I as normalizeAcpPermissionMode, J as removeSessionModeFile } from './index-CfM6ewd8.mjs';
|
|
11
10
|
import 'node:child_process';
|
|
12
11
|
import '@agentclientprotocol/sdk';
|
|
13
12
|
import 'node:fs';
|
|
@@ -33,7 +32,7 @@ import 'fs';
|
|
|
33
32
|
import 'node:readline';
|
|
34
33
|
import '@anthropic-ai/sandbox-runtime';
|
|
35
34
|
import 'expo-server-sdk';
|
|
36
|
-
import './agentGuidance-
|
|
35
|
+
import './agentGuidance-BPGPaNlo.mjs';
|
|
37
36
|
import 'ink';
|
|
38
37
|
import 'react';
|
|
39
38
|
import '@anthropic-ai/claude-agent-sdk';
|
|
@@ -1074,6 +1073,7 @@ async function runAcp(opts) {
|
|
|
1074
1073
|
logAcp("muted", `Outgoing models from ${opts.agentName}: not reported yet`);
|
|
1075
1074
|
}
|
|
1076
1075
|
}
|
|
1076
|
+
let todoDiscoverySent = false;
|
|
1077
1077
|
while (!shouldExit) {
|
|
1078
1078
|
const waitSignal = abortController.signal;
|
|
1079
1079
|
const batch = await messageQueue.waitForMessagesAndGetAsString(waitSignal);
|
|
@@ -1100,7 +1100,11 @@ async function runAcp(opts) {
|
|
|
1100
1100
|
if (typeof batch.mode.model === "string" && batch.mode.model.length > 0) {
|
|
1101
1101
|
await switchModelIfRequested(batch.mode.model);
|
|
1102
1102
|
}
|
|
1103
|
-
|
|
1103
|
+
const prompt = todoDiscoverySent ? batch.message : `${batch.message}
|
|
1104
|
+
|
|
1105
|
+
${BUILTIN_TODO_DISCOVERY}`;
|
|
1106
|
+
await backend.sendPrompt(acpSessionId, prompt);
|
|
1107
|
+
todoDiscoverySent = true;
|
|
1104
1108
|
await turnEnded;
|
|
1105
1109
|
sendEnvelopes(sessionManager.endTurn("completed"));
|
|
1106
1110
|
streamRelay.endTurn();
|
|
@@ -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-BYU6J2n0.cjs');
|
|
4
|
+
var persistence = require('./limits-CrwtFbi8.cjs');
|
|
5
|
+
var AcpSessionManager = require('./AcpSessionManager-artXJgqb.cjs');
|
|
6
|
+
var api = require('./types-DfatCoQL.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-P5deH8Ls.cjs');
|
|
11
|
-
var index = require('./index-Cw9Zj1Zr.cjs');
|
|
10
|
+
var index = require('./index-D_YVlpsW.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-B1xYgHx6.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();
|