@pikaa-ai/pikaa 0.3.24 → 0.3.26
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/bin/pikaa.js +125 -29
- package/dist/cli.js +283 -259
- package/dist/index.js +126 -120
- package/package.json +12 -1
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
18
18
|
return cached;
|
|
19
19
|
}
|
|
20
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
22
|
if (mod && typeof mod === "object" || typeof mod === "function") {
|
|
23
23
|
for (let key of __getOwnPropNames(mod))
|
|
24
24
|
if (!__hasOwnProp.call(to, key))
|
|
@@ -383,21 +383,21 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
383
383
|
}
|
|
384
384
|
return enqueueTaskImpl(task);
|
|
385
385
|
}
|
|
386
|
-
function aggregateErrors(
|
|
387
|
-
return 1 <
|
|
386
|
+
function aggregateErrors(errors) {
|
|
387
|
+
return 1 < errors.length && typeof AggregateError === "function" ? new AggregateError(errors) : errors[0];
|
|
388
388
|
}
|
|
389
389
|
function popActScope(prevActQueue, prevActScopeDepth) {
|
|
390
390
|
prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
|
|
391
391
|
actScopeDepth = prevActScopeDepth;
|
|
392
392
|
}
|
|
393
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
393
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {
|
|
394
394
|
var queue = ReactSharedInternals.actQueue;
|
|
395
395
|
if (queue !== null)
|
|
396
396
|
if (queue.length !== 0)
|
|
397
397
|
try {
|
|
398
398
|
flushActQueue(queue);
|
|
399
399
|
enqueueTask(function() {
|
|
400
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
400
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
|
|
401
401
|
});
|
|
402
402
|
return;
|
|
403
403
|
} catch (error) {
|
|
@@ -405,7 +405,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
405
405
|
}
|
|
406
406
|
else
|
|
407
407
|
ReactSharedInternals.actQueue = null;
|
|
408
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
408
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve(returnValue);
|
|
409
409
|
}
|
|
410
410
|
function flushActQueue(queue) {
|
|
411
411
|
if (!isFlushing) {
|
|
@@ -581,14 +581,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
581
581
|
didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
|
|
582
582
|
});
|
|
583
583
|
return {
|
|
584
|
-
then: function(
|
|
584
|
+
then: function(resolve, reject) {
|
|
585
585
|
didAwaitActCall = true;
|
|
586
586
|
thenable.then(function(returnValue) {
|
|
587
587
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
588
588
|
if (prevActScopeDepth === 0) {
|
|
589
589
|
try {
|
|
590
590
|
flushActQueue(queue), enqueueTask(function() {
|
|
591
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
591
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve, reject);
|
|
592
592
|
});
|
|
593
593
|
} catch (error$0) {
|
|
594
594
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -599,7 +599,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
599
599
|
reject(_thrownError);
|
|
600
600
|
}
|
|
601
601
|
} else
|
|
602
|
-
|
|
602
|
+
resolve(returnValue);
|
|
603
603
|
}, function(error) {
|
|
604
604
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
605
605
|
0 < ReactSharedInternals.thrownErrors.length ? (error = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error)) : reject(error);
|
|
@@ -615,11 +615,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
615
615
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
616
616
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
617
617
|
return {
|
|
618
|
-
then: function(
|
|
618
|
+
then: function(resolve, reject) {
|
|
619
619
|
didAwaitActCall = true;
|
|
620
620
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
621
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
622
|
-
})) :
|
|
621
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve, reject);
|
|
622
|
+
})) : resolve(returnValue$jscomp$0);
|
|
623
623
|
}
|
|
624
624
|
};
|
|
625
625
|
};
|
|
@@ -638,7 +638,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
638
638
|
exports.cloneElement = function(element, config, children) {
|
|
639
639
|
if (element === null || element === undefined)
|
|
640
640
|
throw Error("The argument must be a React element, but you passed " + element + ".");
|
|
641
|
-
var props = assign({}, element.props),
|
|
641
|
+
var props = assign({}, element.props), { key, _owner: owner } = element;
|
|
642
642
|
if (config != null) {
|
|
643
643
|
var JSCompiler_inline_result;
|
|
644
644
|
a: {
|
|
@@ -2007,6 +2007,12 @@ class WindowsSandbox {
|
|
|
2007
2007
|
return null;
|
|
2008
2008
|
}
|
|
2009
2009
|
try {
|
|
2010
|
+
if (this.jobObjectHandle) {
|
|
2011
|
+
try {
|
|
2012
|
+
this.kernel32.symbols.CloseHandle(this.jobObjectHandle);
|
|
2013
|
+
} catch {}
|
|
2014
|
+
this.jobObjectHandle = null;
|
|
2015
|
+
}
|
|
2010
2016
|
const jobHandle = this.kernel32.symbols.CreateJobObjectW(null, null);
|
|
2011
2017
|
if (!jobHandle || jobHandle === 0) {
|
|
2012
2018
|
return null;
|
|
@@ -2505,7 +2511,7 @@ function createShellTool(policy = new ExecPolicy) {
|
|
|
2505
2511
|
} catch {}
|
|
2506
2512
|
});
|
|
2507
2513
|
}
|
|
2508
|
-
const timeoutPromise = new Promise((
|
|
2514
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve({ isTimeout: true }), timeoutMs));
|
|
2509
2515
|
const result = await Promise.race([
|
|
2510
2516
|
proc.exited.then(async (code) => {
|
|
2511
2517
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -4411,12 +4417,12 @@ async function runTurn(session, turnContext, input) {
|
|
|
4411
4417
|
execPolicy: session.execPolicy,
|
|
4412
4418
|
mode: session.collaborationMode,
|
|
4413
4419
|
permissionMode: session.permissionMode,
|
|
4414
|
-
onPlanUpdate: (
|
|
4420
|
+
onPlanUpdate: (plan, explanation) => {
|
|
4415
4421
|
session.emitEvent({
|
|
4416
4422
|
type: "PlanUpdated",
|
|
4417
4423
|
turnId,
|
|
4418
4424
|
explanation,
|
|
4419
|
-
plan
|
|
4425
|
+
plan
|
|
4420
4426
|
});
|
|
4421
4427
|
},
|
|
4422
4428
|
requestApproval: async (description, command, prefixRule) => {
|
|
@@ -4657,8 +4663,8 @@ class Session {
|
|
|
4657
4663
|
getHistory() {
|
|
4658
4664
|
return [...this.history];
|
|
4659
4665
|
}
|
|
4660
|
-
setHistory(
|
|
4661
|
-
this.history = [...
|
|
4666
|
+
setHistory(items) {
|
|
4667
|
+
this.history = [...items];
|
|
4662
4668
|
}
|
|
4663
4669
|
addHistoryItem(item) {
|
|
4664
4670
|
this.history.push(item);
|
|
@@ -4705,13 +4711,13 @@ class Session {
|
|
|
4705
4711
|
type: "StatusChanged",
|
|
4706
4712
|
status: "waiting_approval"
|
|
4707
4713
|
});
|
|
4708
|
-
return new Promise((
|
|
4714
|
+
return new Promise((resolve) => {
|
|
4709
4715
|
this.pendingApprovals.set(params.approvalId, (approved) => {
|
|
4710
4716
|
this.emitEvent({
|
|
4711
4717
|
type: "StatusChanged",
|
|
4712
4718
|
status: "running"
|
|
4713
4719
|
});
|
|
4714
|
-
|
|
4720
|
+
resolve(approved);
|
|
4715
4721
|
});
|
|
4716
4722
|
});
|
|
4717
4723
|
}
|
|
@@ -4734,13 +4740,13 @@ class Session {
|
|
|
4734
4740
|
type: "StatusChanged",
|
|
4735
4741
|
status: "waiting_user_input"
|
|
4736
4742
|
});
|
|
4737
|
-
return new Promise((
|
|
4743
|
+
return new Promise((resolve) => {
|
|
4738
4744
|
this.pendingUserQuestions.set(params.questionId, (answer) => {
|
|
4739
4745
|
this.emitEvent({
|
|
4740
4746
|
type: "StatusChanged",
|
|
4741
4747
|
status: "running"
|
|
4742
4748
|
});
|
|
4743
|
-
|
|
4749
|
+
resolve(answer);
|
|
4744
4750
|
});
|
|
4745
4751
|
});
|
|
4746
4752
|
}
|
|
@@ -4770,7 +4776,7 @@ class Session {
|
|
|
4770
4776
|
return handleTurnInput(this, { text, images });
|
|
4771
4777
|
}
|
|
4772
4778
|
async promptAndWait(text, images, timeoutMs = 30000) {
|
|
4773
|
-
return new Promise((
|
|
4779
|
+
return new Promise((resolve, reject) => {
|
|
4774
4780
|
const timer = setTimeout(() => {
|
|
4775
4781
|
unsub();
|
|
4776
4782
|
reject(new Error(`Turn timed out after ${timeoutMs}ms`));
|
|
@@ -4779,7 +4785,7 @@ class Session {
|
|
|
4779
4785
|
if (event.msg.type === "TurnCompleted") {
|
|
4780
4786
|
clearTimeout(timer);
|
|
4781
4787
|
unsub();
|
|
4782
|
-
|
|
4788
|
+
resolve();
|
|
4783
4789
|
} else if (event.msg.type === "Error") {
|
|
4784
4790
|
clearTimeout(timer);
|
|
4785
4791
|
unsub();
|
|
@@ -4798,8 +4804,8 @@ class Session {
|
|
|
4798
4804
|
if (this.submissionQueue.length > 0) {
|
|
4799
4805
|
yield this.submissionQueue.shift();
|
|
4800
4806
|
} else {
|
|
4801
|
-
const nextSub = await new Promise((
|
|
4802
|
-
this.submissionResolvers.push(
|
|
4807
|
+
const nextSub = await new Promise((resolve) => {
|
|
4808
|
+
this.submissionResolvers.push(resolve);
|
|
4803
4809
|
});
|
|
4804
4810
|
yield nextSub;
|
|
4805
4811
|
}
|
|
@@ -5063,13 +5069,13 @@ class StdioTransport {
|
|
|
5063
5069
|
if (this.isClosed || !this.proc || !this.proc.stdin) {
|
|
5064
5070
|
throw new GroupyError("MCP Stdio transport is closed");
|
|
5065
5071
|
}
|
|
5066
|
-
return new Promise((
|
|
5072
|
+
return new Promise((resolve, reject) => {
|
|
5067
5073
|
const timeoutMs = 30000;
|
|
5068
5074
|
const timer = setTimeout(() => {
|
|
5069
5075
|
this.pendingRequests.delete(request.id);
|
|
5070
5076
|
reject(new GroupyError(`MCP request timed out after ${timeoutMs}ms (method: ${request.method})`));
|
|
5071
5077
|
}, timeoutMs);
|
|
5072
|
-
this.pendingRequests.set(request.id, { resolve
|
|
5078
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
5073
5079
|
try {
|
|
5074
5080
|
const payload = JSON.stringify(request) + `
|
|
5075
5081
|
`;
|
|
@@ -5159,11 +5165,11 @@ class SseTransport {
|
|
|
5159
5165
|
if (done)
|
|
5160
5166
|
break;
|
|
5161
5167
|
buffer += decoder.decode(value, { stream: true });
|
|
5162
|
-
const
|
|
5168
|
+
const events = buffer.split(`
|
|
5163
5169
|
|
|
5164
5170
|
`);
|
|
5165
|
-
buffer =
|
|
5166
|
-
for (const eventBlock of
|
|
5171
|
+
buffer = events.pop() || "";
|
|
5172
|
+
for (const eventBlock of events) {
|
|
5167
5173
|
const lines = eventBlock.split(`
|
|
5168
5174
|
`);
|
|
5169
5175
|
let eventType = "message";
|
|
@@ -5202,12 +5208,12 @@ class SseTransport {
|
|
|
5202
5208
|
if (!this.messageUrl) {
|
|
5203
5209
|
this.messageUrl = this.endpointUrl;
|
|
5204
5210
|
}
|
|
5205
|
-
return new Promise((
|
|
5211
|
+
return new Promise((resolve, reject) => {
|
|
5206
5212
|
const timer = setTimeout(() => {
|
|
5207
5213
|
this.pendingRequests.delete(request.id);
|
|
5208
5214
|
reject(new GroupyError(`MCP SSE request timed out (method: ${request.method})`));
|
|
5209
5215
|
}, 30000);
|
|
5210
|
-
this.pendingRequests.set(request.id, { resolve
|
|
5216
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
5211
5217
|
fetch(this.messageUrl, {
|
|
5212
5218
|
method: "POST",
|
|
5213
5219
|
headers: {
|
|
@@ -5531,7 +5537,7 @@ class McpManager {
|
|
|
5531
5537
|
}
|
|
5532
5538
|
return client.ping();
|
|
5533
5539
|
}
|
|
5534
|
-
async removeServer(name,
|
|
5540
|
+
async removeServer(name, router) {
|
|
5535
5541
|
const client = this.clients.get(name);
|
|
5536
5542
|
if (!client)
|
|
5537
5543
|
return false;
|
|
@@ -5540,12 +5546,12 @@ class McpManager {
|
|
|
5540
5546
|
} catch {}
|
|
5541
5547
|
this.clients.delete(name);
|
|
5542
5548
|
this.serverConfigs.delete(name);
|
|
5543
|
-
if (
|
|
5544
|
-
|
|
5549
|
+
if (router) {
|
|
5550
|
+
router.unregisterPrefix(`mcp__${name}__`);
|
|
5545
5551
|
}
|
|
5546
5552
|
return true;
|
|
5547
5553
|
}
|
|
5548
|
-
registerToolsIntoRouter(
|
|
5554
|
+
registerToolsIntoRouter(router) {
|
|
5549
5555
|
if (this.clients.size === 0)
|
|
5550
5556
|
return;
|
|
5551
5557
|
let hasAnyLazyServer = false;
|
|
@@ -5569,7 +5575,7 @@ class McpManager {
|
|
|
5569
5575
|
return client.callTool(mcpTool.name, args);
|
|
5570
5576
|
}
|
|
5571
5577
|
};
|
|
5572
|
-
|
|
5578
|
+
router.register(tool);
|
|
5573
5579
|
}
|
|
5574
5580
|
}
|
|
5575
5581
|
if (client.getResources().length > 0) {
|
|
@@ -5619,7 +5625,7 @@ class McpManager {
|
|
|
5619
5625
|
}
|
|
5620
5626
|
}
|
|
5621
5627
|
};
|
|
5622
|
-
|
|
5628
|
+
router.register(callMcpTool);
|
|
5623
5629
|
const getToolSchemaTool = {
|
|
5624
5630
|
name: "get_mcp_tool_schema",
|
|
5625
5631
|
description: "Retrieve parameter specification and JSONSchema for a lazy-loaded MCP tool.",
|
|
@@ -5648,7 +5654,7 @@ class McpManager {
|
|
|
5648
5654
|
return { output: JSON.stringify(tool, null, 2) };
|
|
5649
5655
|
}
|
|
5650
5656
|
};
|
|
5651
|
-
|
|
5657
|
+
router.register(getToolSchemaTool);
|
|
5652
5658
|
const listResourcesTool = {
|
|
5653
5659
|
name: "list_mcp_resources",
|
|
5654
5660
|
description: "List available data resources exposed by a connected MCP server.",
|
|
@@ -5668,7 +5674,7 @@ class McpManager {
|
|
|
5668
5674
|
return { output: JSON.stringify(client.getResources(), null, 2) };
|
|
5669
5675
|
}
|
|
5670
5676
|
};
|
|
5671
|
-
|
|
5677
|
+
router.register(listResourcesTool);
|
|
5672
5678
|
const readResourceTool = {
|
|
5673
5679
|
name: "read_mcp_resource",
|
|
5674
5680
|
description: "Read the contents of an MCP resource by URI across connected MCP servers.",
|
|
@@ -5698,7 +5704,7 @@ class McpManager {
|
|
|
5698
5704
|
}
|
|
5699
5705
|
}
|
|
5700
5706
|
};
|
|
5701
|
-
|
|
5707
|
+
router.register(readResourceTool);
|
|
5702
5708
|
}
|
|
5703
5709
|
formatMcpPrompt() {
|
|
5704
5710
|
if (this.clients.size === 0)
|
|
@@ -5767,20 +5773,20 @@ class McpManager {
|
|
|
5767
5773
|
} catch {}
|
|
5768
5774
|
return false;
|
|
5769
5775
|
}
|
|
5770
|
-
async reload(
|
|
5776
|
+
async reload(router) {
|
|
5771
5777
|
await this.closeAll();
|
|
5772
|
-
if (
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
+
if (router) {
|
|
5779
|
+
router.unregisterPrefix("mcp__");
|
|
5780
|
+
router.unregister("call_mcp_tool");
|
|
5781
|
+
router.unregister("get_mcp_tool_schema");
|
|
5782
|
+
router.unregister("list_mcp_resources");
|
|
5783
|
+
router.unregister("read_mcp_resource");
|
|
5778
5784
|
}
|
|
5779
5785
|
for (const filePath of this.loadedConfigFiles) {
|
|
5780
5786
|
await this.loadConfigFile(filePath);
|
|
5781
5787
|
}
|
|
5782
|
-
if (
|
|
5783
|
-
this.registerToolsIntoRouter(
|
|
5788
|
+
if (router) {
|
|
5789
|
+
this.registerToolsIntoRouter(router);
|
|
5784
5790
|
}
|
|
5785
5791
|
}
|
|
5786
5792
|
getDefaultConfigFile(cwd = process.cwd()) {
|
|
@@ -5969,7 +5975,7 @@ class CdpSession {
|
|
|
5969
5975
|
this.wsUrl = wsUrl;
|
|
5970
5976
|
}
|
|
5971
5977
|
async connect() {
|
|
5972
|
-
return new Promise((
|
|
5978
|
+
return new Promise((resolve, reject) => {
|
|
5973
5979
|
try {
|
|
5974
5980
|
this.ws = new WebSocket(this.wsUrl);
|
|
5975
5981
|
const onOpen = async () => {
|
|
@@ -5985,7 +5991,7 @@ class CdpSession {
|
|
|
5985
5991
|
await this.send("Network.enable").catch(() => {});
|
|
5986
5992
|
await this.send("Page.setLifecycleEventsEnabled", { enabled: true }).catch(() => {});
|
|
5987
5993
|
this.setupEventHandlers();
|
|
5988
|
-
|
|
5994
|
+
resolve();
|
|
5989
5995
|
} catch (err) {
|
|
5990
5996
|
reject(err);
|
|
5991
5997
|
}
|
|
@@ -6107,13 +6113,13 @@ class CdpSession {
|
|
|
6107
6113
|
throw new Error("CDP WebSocket is not connected");
|
|
6108
6114
|
}
|
|
6109
6115
|
const id = this.nextId++;
|
|
6110
|
-
return new Promise((
|
|
6116
|
+
return new Promise((resolve, reject) => {
|
|
6111
6117
|
const timeoutMs = 30000;
|
|
6112
6118
|
const timer = setTimeout(() => {
|
|
6113
6119
|
this.pending.delete(id);
|
|
6114
6120
|
reject(new Error(`CDP command '${method}' timed out after ${timeoutMs}ms`));
|
|
6115
6121
|
}, timeoutMs);
|
|
6116
|
-
this.pending.set(id, { resolve
|
|
6122
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
6117
6123
|
try {
|
|
6118
6124
|
this.ws?.send(JSON.stringify({ id, method, params }));
|
|
6119
6125
|
} catch (err) {
|
|
@@ -6142,7 +6148,7 @@ class CdpSession {
|
|
|
6142
6148
|
}
|
|
6143
6149
|
// src/mcp/servers/chrome-devtools/dom-snapshot.ts
|
|
6144
6150
|
class DomSnapshotEngine {
|
|
6145
|
-
static async captureSnapshot(
|
|
6151
|
+
static async captureSnapshot(session, verbose = false) {
|
|
6146
6152
|
const crawlerScript = `
|
|
6147
6153
|
(() => {
|
|
6148
6154
|
let currentUid = 1;
|
|
@@ -6267,7 +6273,7 @@ class DomSnapshotEngine {
|
|
|
6267
6273
|
};
|
|
6268
6274
|
})()
|
|
6269
6275
|
`;
|
|
6270
|
-
const res = await
|
|
6276
|
+
const res = await session.send("Runtime.evaluate", {
|
|
6271
6277
|
expression: crawlerScript,
|
|
6272
6278
|
returnByValue: true,
|
|
6273
6279
|
awaitPromise: true
|
|
@@ -6281,7 +6287,7 @@ class DomSnapshotEngine {
|
|
|
6281
6287
|
elementsCount: val.count
|
|
6282
6288
|
};
|
|
6283
6289
|
}
|
|
6284
|
-
static async getElementCenter(
|
|
6290
|
+
static async getElementCenter(session, uid) {
|
|
6285
6291
|
const script = `
|
|
6286
6292
|
(() => {
|
|
6287
6293
|
const el = document.querySelector(\`[data-groupy-mcp-uid="\${${JSON.stringify(uid)}}"]\`);
|
|
@@ -6296,7 +6302,7 @@ class DomSnapshotEngine {
|
|
|
6296
6302
|
};
|
|
6297
6303
|
})()
|
|
6298
6304
|
`;
|
|
6299
|
-
const res = await
|
|
6305
|
+
const res = await session.send("Runtime.evaluate", {
|
|
6300
6306
|
expression: script,
|
|
6301
6307
|
returnByValue: true,
|
|
6302
6308
|
awaitPromise: true
|
|
@@ -6437,12 +6443,12 @@ class ChromeDevToolsController {
|
|
|
6437
6443
|
} else if (navType === "reload") {
|
|
6438
6444
|
await cdp.send("Page.reload", { ignoreCache: params.ignoreCache });
|
|
6439
6445
|
}
|
|
6440
|
-
await new Promise((
|
|
6441
|
-
const timer = setTimeout(
|
|
6446
|
+
await new Promise((resolve) => {
|
|
6447
|
+
const timer = setTimeout(resolve, params.timeout || 3000);
|
|
6442
6448
|
const unsub = cdp.on("Page.loadEventFired", () => {
|
|
6443
6449
|
clearTimeout(timer);
|
|
6444
6450
|
unsub();
|
|
6445
|
-
|
|
6451
|
+
resolve();
|
|
6446
6452
|
});
|
|
6447
6453
|
});
|
|
6448
6454
|
const evalRes = await cdp.send("Runtime.evaluate", {
|
|
@@ -7391,11 +7397,11 @@ class WebSearchEngine {
|
|
|
7391
7397
|
class LiveDocFetcher {
|
|
7392
7398
|
static async fetchPageContent(url, options = {}) {
|
|
7393
7399
|
const timeoutMs = options.timeoutMs || 15000;
|
|
7394
|
-
const
|
|
7395
|
-
const timer = setTimeout(() =>
|
|
7400
|
+
const controller = new AbortController;
|
|
7401
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7396
7402
|
try {
|
|
7397
7403
|
const res = await fetch(url, {
|
|
7398
|
-
signal:
|
|
7404
|
+
signal: controller.signal,
|
|
7399
7405
|
headers: {
|
|
7400
7406
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
7401
7407
|
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,text/plain,*/*;q=0.8"
|
|
@@ -8576,8 +8582,8 @@ Your nickname is ${nickname}. Your assigned task is: '${params.taskName}'. Focus
|
|
|
8576
8582
|
});
|
|
8577
8583
|
let resolvePromise;
|
|
8578
8584
|
let rejectPromise;
|
|
8579
|
-
const taskPromise = new Promise((
|
|
8580
|
-
resolvePromise =
|
|
8585
|
+
const taskPromise = new Promise((resolve, reject) => {
|
|
8586
|
+
resolvePromise = resolve;
|
|
8581
8587
|
rejectPromise = reject;
|
|
8582
8588
|
});
|
|
8583
8589
|
const handle = {
|
|
@@ -8869,9 +8875,9 @@ function createMultiAgentTools(spawner) {
|
|
|
8869
8875
|
};
|
|
8870
8876
|
return [spawnAgentTool, waitAgentTool, sendInputTool, closeAgentTool, listAgentsTool];
|
|
8871
8877
|
}
|
|
8872
|
-
function registerMultiAgentTools(
|
|
8878
|
+
function registerMultiAgentTools(router, spawner) {
|
|
8873
8879
|
for (const tool of createMultiAgentTools(spawner)) {
|
|
8874
|
-
|
|
8880
|
+
router.register(tool);
|
|
8875
8881
|
}
|
|
8876
8882
|
}
|
|
8877
8883
|
// src/storage/sqlite-store.ts
|
|
@@ -8925,20 +8931,20 @@ class SqliteThreadStore {
|
|
|
8925
8931
|
CREATE INDEX IF NOT EXISTS idx_items_thread_seq ON items(thread_id, seq ASC);
|
|
8926
8932
|
`);
|
|
8927
8933
|
}
|
|
8928
|
-
saveThread(
|
|
8934
|
+
saveThread(thread) {
|
|
8929
8935
|
const query = this.db.prepare(`
|
|
8930
8936
|
INSERT OR REPLACE INTO threads (id, title, model, cwd, role, status, created_at, updated_at)
|
|
8931
8937
|
VALUES ($id, $title, $model, $cwd, $role, $status, $createdAt, $updatedAt)
|
|
8932
8938
|
`);
|
|
8933
8939
|
query.run({
|
|
8934
|
-
$id:
|
|
8935
|
-
$title:
|
|
8936
|
-
$model:
|
|
8937
|
-
$cwd:
|
|
8938
|
-
$role:
|
|
8939
|
-
$status:
|
|
8940
|
-
$createdAt:
|
|
8941
|
-
$updatedAt:
|
|
8940
|
+
$id: thread.id,
|
|
8941
|
+
$title: thread.title,
|
|
8942
|
+
$model: thread.model,
|
|
8943
|
+
$cwd: thread.cwd,
|
|
8944
|
+
$role: thread.role,
|
|
8945
|
+
$status: thread.status,
|
|
8946
|
+
$createdAt: thread.createdAt,
|
|
8947
|
+
$updatedAt: thread.updatedAt
|
|
8942
8948
|
});
|
|
8943
8949
|
}
|
|
8944
8950
|
updateThreadTitle(id, title) {
|
|
@@ -9015,12 +9021,12 @@ class SqliteThreadStore {
|
|
|
9015
9021
|
return rows.map((r) => JSON.parse(r.payload));
|
|
9016
9022
|
}
|
|
9017
9023
|
restoreSession(threadId) {
|
|
9018
|
-
const
|
|
9019
|
-
if (!
|
|
9024
|
+
const thread = this.getThread(threadId);
|
|
9025
|
+
if (!thread) {
|
|
9020
9026
|
throw new GroupyError(`Thread with id '${threadId}' not found in thread store.`);
|
|
9021
9027
|
}
|
|
9022
|
-
const
|
|
9023
|
-
return { thread
|
|
9028
|
+
const items = this.getItems(threadId);
|
|
9029
|
+
return { thread, items };
|
|
9024
9030
|
}
|
|
9025
9031
|
deleteThread(id) {
|
|
9026
9032
|
const query = this.db.prepare(`DELETE FROM threads WHERE id = $id`);
|
|
@@ -9042,15 +9048,15 @@ class SessionPersistenceManager {
|
|
|
9042
9048
|
this.store = new SqliteThreadStore(storeOrPath);
|
|
9043
9049
|
}
|
|
9044
9050
|
}
|
|
9045
|
-
bindSession(
|
|
9046
|
-
const threadId =
|
|
9051
|
+
bindSession(session, role = "default") {
|
|
9052
|
+
const threadId = session.threadId;
|
|
9047
9053
|
const existing = this.store.getThread(threadId);
|
|
9048
9054
|
if (!existing) {
|
|
9049
9055
|
this.store.saveThread({
|
|
9050
9056
|
id: threadId,
|
|
9051
9057
|
title: "New Session",
|
|
9052
|
-
model:
|
|
9053
|
-
cwd:
|
|
9058
|
+
model: session.model,
|
|
9059
|
+
cwd: session.cwd,
|
|
9054
9060
|
role,
|
|
9055
9061
|
status: "active",
|
|
9056
9062
|
createdAt: Date.now(),
|
|
@@ -9059,7 +9065,7 @@ class SessionPersistenceManager {
|
|
|
9059
9065
|
}
|
|
9060
9066
|
const existingItems = this.store.getItems(threadId);
|
|
9061
9067
|
let seq = existingItems.length;
|
|
9062
|
-
const unsub =
|
|
9068
|
+
const unsub = session.onEvent((event) => {
|
|
9063
9069
|
const msg = event.msg;
|
|
9064
9070
|
if (msg.type === "ItemCompleted") {
|
|
9065
9071
|
const item = msg.item;
|
|
@@ -9078,7 +9084,7 @@ class SessionPersistenceManager {
|
|
|
9078
9084
|
}
|
|
9079
9085
|
resumeSession(threadId, overrides = {}) {
|
|
9080
9086
|
const restored = this.store.restoreSession(threadId);
|
|
9081
|
-
const
|
|
9087
|
+
const session = new Session({
|
|
9082
9088
|
threadId: restored.thread.id,
|
|
9083
9089
|
model: overrides.model || restored.thread.model,
|
|
9084
9090
|
cwd: overrides.cwd || restored.thread.cwd,
|
|
@@ -9090,8 +9096,8 @@ class SessionPersistenceManager {
|
|
|
9090
9096
|
systemPrompt: overrides.systemPrompt,
|
|
9091
9097
|
initialHistory: restored.items
|
|
9092
9098
|
});
|
|
9093
|
-
this.bindSession(
|
|
9094
|
-
return
|
|
9099
|
+
this.bindSession(session, restored.thread.role);
|
|
9100
|
+
return session;
|
|
9095
9101
|
}
|
|
9096
9102
|
loadSession(threadId) {
|
|
9097
9103
|
try {
|
|
@@ -9108,17 +9114,17 @@ class SessionPersistenceManager {
|
|
|
9108
9114
|
}
|
|
9109
9115
|
this.unsubscribers = [];
|
|
9110
9116
|
}
|
|
9111
|
-
resumeIntoSession(
|
|
9117
|
+
resumeIntoSession(session, threadId) {
|
|
9112
9118
|
const restored = this.loadSession(threadId);
|
|
9113
9119
|
if (!restored)
|
|
9114
9120
|
return null;
|
|
9115
9121
|
this.unbindSession();
|
|
9116
|
-
|
|
9117
|
-
|
|
9122
|
+
session.threadId = restored.thread.id;
|
|
9123
|
+
session.setHistory(restored.items);
|
|
9118
9124
|
if (restored.thread.model) {
|
|
9119
|
-
|
|
9125
|
+
session.model = restored.thread.model;
|
|
9120
9126
|
}
|
|
9121
|
-
this.bindSession(
|
|
9127
|
+
this.bindSession(session, restored.thread.role);
|
|
9122
9128
|
return restored;
|
|
9123
9129
|
}
|
|
9124
9130
|
listSessions(options) {
|
|
@@ -9262,9 +9268,9 @@ class SkillsLoader {
|
|
|
9262
9268
|
}
|
|
9263
9269
|
const all = this.listSkills(cwd, { includeDisabled: false });
|
|
9264
9270
|
const target = skillName.trim().toLowerCase();
|
|
9265
|
-
const
|
|
9266
|
-
const targetNorm =
|
|
9267
|
-
const meta = all.find((s) => s.name.toLowerCase() === target) || all.find((s) =>
|
|
9271
|
+
const normalize = (str) => str.toLowerCase().replace(/[-_\s]/g, "");
|
|
9272
|
+
const targetNorm = normalize(skillName);
|
|
9273
|
+
const meta = all.find((s) => s.name.toLowerCase() === target) || all.find((s) => normalize(s.name) === targetNorm);
|
|
9268
9274
|
if (!meta)
|
|
9269
9275
|
return null;
|
|
9270
9276
|
try {
|
|
@@ -9392,13 +9398,13 @@ class MemoryStore {
|
|
|
9392
9398
|
}
|
|
9393
9399
|
getProjectMemoryDir(cwd) {
|
|
9394
9400
|
if (this.customWorkspacePath) {
|
|
9395
|
-
const
|
|
9396
|
-
if (!existsSync20(
|
|
9401
|
+
const dir = resolve21(this.customWorkspacePath);
|
|
9402
|
+
if (!existsSync20(dir)) {
|
|
9397
9403
|
try {
|
|
9398
|
-
mkdirSync12(
|
|
9404
|
+
mkdirSync12(dir, { recursive: true });
|
|
9399
9405
|
} catch {}
|
|
9400
9406
|
}
|
|
9401
|
-
return
|
|
9407
|
+
return dir;
|
|
9402
9408
|
}
|
|
9403
9409
|
const slug = this.getProjectSlug(cwd);
|
|
9404
9410
|
const dir = join11(getProjectsDir(), slug, "memory");
|
|
@@ -9537,12 +9543,12 @@ class MemoryStore {
|
|
|
9537
9543
|
const memoryDir = this.getProjectMemoryDir(cwd);
|
|
9538
9544
|
const indexPath = join11(memoryDir, "MEMORY.md");
|
|
9539
9545
|
const files = existsSync20(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md") : [];
|
|
9540
|
-
const
|
|
9546
|
+
const items = [];
|
|
9541
9547
|
for (const f of files) {
|
|
9542
9548
|
try {
|
|
9543
9549
|
const full = join11(memoryDir, f);
|
|
9544
9550
|
const parsed = this.parseTopicFile(readFileSync11(full, "utf8"), full);
|
|
9545
|
-
|
|
9551
|
+
items.push({
|
|
9546
9552
|
type: parsed.type,
|
|
9547
9553
|
name: parsed.name,
|
|
9548
9554
|
desc: parsed.description || parsed.content.split(`
|
|
@@ -9557,7 +9563,7 @@ class MemoryStore {
|
|
|
9557
9563
|
"This index is loaded at session startup. Detailed topics can be retrieved via read_memory tool.",
|
|
9558
9564
|
""
|
|
9559
9565
|
];
|
|
9560
|
-
for (const item of
|
|
9566
|
+
for (const item of items) {
|
|
9561
9567
|
indexLines.push(`- [${item.type}] **${item.name}**: ${item.desc} (topic: ${item.file})`);
|
|
9562
9568
|
}
|
|
9563
9569
|
const boundedLines = indexLines.slice(0, 200);
|
|
@@ -9928,8 +9934,8 @@ class AuthClient {
|
|
|
9928
9934
|
if (!res.ok) {
|
|
9929
9935
|
let errDetail = `HTTP ${res.status}`;
|
|
9930
9936
|
try {
|
|
9931
|
-
const
|
|
9932
|
-
errDetail =
|
|
9937
|
+
const data = await res.json();
|
|
9938
|
+
errDetail = data.detail || JSON.stringify(data);
|
|
9933
9939
|
} catch {}
|
|
9934
9940
|
throw new Error(`Login failed: ${errDetail}`);
|
|
9935
9941
|
}
|
|
@@ -9955,8 +9961,8 @@ class AuthClient {
|
|
|
9955
9961
|
const authUrl = `${backendUrl}/api/auth/authorize?response_type=code&client_id=groupy-cli&redirect_uri=${encodeURIComponent(redirectUri)}&code_challenge=${encodeURIComponent(codeChallenge)}&code_challenge_method=S256&state=${state}&direct=1`;
|
|
9956
9962
|
let serverResolve;
|
|
9957
9963
|
let serverReject;
|
|
9958
|
-
const codePromise = new Promise((
|
|
9959
|
-
serverResolve =
|
|
9964
|
+
const codePromise = new Promise((resolve, reject) => {
|
|
9965
|
+
serverResolve = resolve;
|
|
9960
9966
|
serverReject = reject;
|
|
9961
9967
|
});
|
|
9962
9968
|
if (options.openBrowser !== false) {
|
|
@@ -9965,9 +9971,9 @@ class AuthClient {
|
|
|
9965
9971
|
exec(startCmd);
|
|
9966
9972
|
} catch {}
|
|
9967
9973
|
}
|
|
9968
|
-
let
|
|
9974
|
+
let server;
|
|
9969
9975
|
try {
|
|
9970
|
-
|
|
9976
|
+
server = Bun.serve({
|
|
9971
9977
|
port,
|
|
9972
9978
|
fetch: async (req) => {
|
|
9973
9979
|
const url = new URL(req.url);
|
|
@@ -10047,8 +10053,8 @@ class AuthClient {
|
|
|
10047
10053
|
this.store.save(credentials);
|
|
10048
10054
|
return credentials;
|
|
10049
10055
|
} finally {
|
|
10050
|
-
if (
|
|
10051
|
-
|
|
10056
|
+
if (server) {
|
|
10057
|
+
server.stop();
|
|
10052
10058
|
}
|
|
10053
10059
|
}
|
|
10054
10060
|
};
|
|
@@ -10114,7 +10120,7 @@ function ClaudeHeader({
|
|
|
10114
10120
|
version = "v0.3.2",
|
|
10115
10121
|
user = "Developer",
|
|
10116
10122
|
model = "Claude 3.7 Sonnet (Thinking)",
|
|
10117
|
-
plan
|
|
10123
|
+
plan = "Pro",
|
|
10118
10124
|
branch = "main",
|
|
10119
10125
|
cwd = "~/workspace",
|
|
10120
10126
|
tips = ["Ask Groupy to create a new app, test code, or run tasks"],
|
|
@@ -10124,7 +10130,7 @@ function ClaudeHeader({
|
|
|
10124
10130
|
],
|
|
10125
10131
|
className
|
|
10126
10132
|
}) {
|
|
10127
|
-
const modelLine = `${model} \xB7 Groupy ${
|
|
10133
|
+
const modelLine = `${model} \xB7 Groupy ${plan}`;
|
|
10128
10134
|
const branchLine = `\uE0A0 ${branch}`;
|
|
10129
10135
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("fieldset", {
|
|
10130
10136
|
className: `min-w-0 rounded-[6px] border px-3 pb-3.5 pt-1 font-mono text-[13px] leading-[1.5] text-[#c0caf5] sm:px-4 ${className || ""}`,
|
|
@@ -10366,7 +10372,7 @@ var STATUS_COLOR = {
|
|
|
10366
10372
|
pending: "#e0af68"
|
|
10367
10373
|
};
|
|
10368
10374
|
function ClaudeToolCall({
|
|
10369
|
-
tool
|
|
10375
|
+
tool,
|
|
10370
10376
|
arg,
|
|
10371
10377
|
result,
|
|
10372
10378
|
status = "success",
|
|
@@ -10396,7 +10402,7 @@ function ClaudeToolCall({
|
|
|
10396
10402
|
children: [
|
|
10397
10403
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV("span", {
|
|
10398
10404
|
className: "text-[#c0caf5] font-semibold",
|
|
10399
|
-
children:
|
|
10405
|
+
children: tool
|
|
10400
10406
|
}, undefined, false, undefined, this),
|
|
10401
10407
|
arg !== undefined ? /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(jsx_dev_runtime4.Fragment, {
|
|
10402
10408
|
children: [
|
|
@@ -11048,13 +11054,13 @@ function GrokStatus({
|
|
|
11048
11054
|
directory = process.cwd ? process.cwd() : "~/workspace",
|
|
11049
11055
|
contextUsed = "16K",
|
|
11050
11056
|
contextLimit = "500K",
|
|
11051
|
-
turn
|
|
11057
|
+
turn,
|
|
11052
11058
|
turnTotal,
|
|
11053
11059
|
mcp,
|
|
11054
11060
|
mcpTotal,
|
|
11055
11061
|
className = ""
|
|
11056
11062
|
}) {
|
|
11057
|
-
const showTurn = typeof
|
|
11063
|
+
const showTurn = typeof turn === "number" && typeof turnTotal === "number" && turnTotal > 0;
|
|
11058
11064
|
const showMcp = typeof mcp === "number" && typeof mcpTotal === "number" && mcpTotal > 0;
|
|
11059
11065
|
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
11060
11066
|
className: `flex min-w-0 flex-wrap items-baseline justify-between gap-x-4 gap-y-1 font-mono text-[12px] ${className}`,
|
|
@@ -11123,7 +11129,7 @@ function GrokStatus({
|
|
|
11123
11129
|
}, undefined, false, undefined, this),
|
|
11124
11130
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
|
|
11125
11131
|
children: [
|
|
11126
|
-
|
|
11132
|
+
turn,
|
|
11127
11133
|
"/",
|
|
11128
11134
|
turnTotal
|
|
11129
11135
|
]
|