@pikaa-ai/pikaa 0.3.25 → 0.3.27
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 +214 -203
- package/dist/index.js +120 -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: {
|
|
@@ -2511,7 +2511,7 @@ function createShellTool(policy = new ExecPolicy) {
|
|
|
2511
2511
|
} catch {}
|
|
2512
2512
|
});
|
|
2513
2513
|
}
|
|
2514
|
-
const timeoutPromise = new Promise((
|
|
2514
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve({ isTimeout: true }), timeoutMs));
|
|
2515
2515
|
const result = await Promise.race([
|
|
2516
2516
|
proc.exited.then(async (code) => {
|
|
2517
2517
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -4417,12 +4417,12 @@ async function runTurn(session, turnContext, input) {
|
|
|
4417
4417
|
execPolicy: session.execPolicy,
|
|
4418
4418
|
mode: session.collaborationMode,
|
|
4419
4419
|
permissionMode: session.permissionMode,
|
|
4420
|
-
onPlanUpdate: (
|
|
4420
|
+
onPlanUpdate: (plan, explanation) => {
|
|
4421
4421
|
session.emitEvent({
|
|
4422
4422
|
type: "PlanUpdated",
|
|
4423
4423
|
turnId,
|
|
4424
4424
|
explanation,
|
|
4425
|
-
plan
|
|
4425
|
+
plan
|
|
4426
4426
|
});
|
|
4427
4427
|
},
|
|
4428
4428
|
requestApproval: async (description, command, prefixRule) => {
|
|
@@ -4663,8 +4663,8 @@ class Session {
|
|
|
4663
4663
|
getHistory() {
|
|
4664
4664
|
return [...this.history];
|
|
4665
4665
|
}
|
|
4666
|
-
setHistory(
|
|
4667
|
-
this.history = [...
|
|
4666
|
+
setHistory(items) {
|
|
4667
|
+
this.history = [...items];
|
|
4668
4668
|
}
|
|
4669
4669
|
addHistoryItem(item) {
|
|
4670
4670
|
this.history.push(item);
|
|
@@ -4711,13 +4711,13 @@ class Session {
|
|
|
4711
4711
|
type: "StatusChanged",
|
|
4712
4712
|
status: "waiting_approval"
|
|
4713
4713
|
});
|
|
4714
|
-
return new Promise((
|
|
4714
|
+
return new Promise((resolve) => {
|
|
4715
4715
|
this.pendingApprovals.set(params.approvalId, (approved) => {
|
|
4716
4716
|
this.emitEvent({
|
|
4717
4717
|
type: "StatusChanged",
|
|
4718
4718
|
status: "running"
|
|
4719
4719
|
});
|
|
4720
|
-
|
|
4720
|
+
resolve(approved);
|
|
4721
4721
|
});
|
|
4722
4722
|
});
|
|
4723
4723
|
}
|
|
@@ -4740,13 +4740,13 @@ class Session {
|
|
|
4740
4740
|
type: "StatusChanged",
|
|
4741
4741
|
status: "waiting_user_input"
|
|
4742
4742
|
});
|
|
4743
|
-
return new Promise((
|
|
4743
|
+
return new Promise((resolve) => {
|
|
4744
4744
|
this.pendingUserQuestions.set(params.questionId, (answer) => {
|
|
4745
4745
|
this.emitEvent({
|
|
4746
4746
|
type: "StatusChanged",
|
|
4747
4747
|
status: "running"
|
|
4748
4748
|
});
|
|
4749
|
-
|
|
4749
|
+
resolve(answer);
|
|
4750
4750
|
});
|
|
4751
4751
|
});
|
|
4752
4752
|
}
|
|
@@ -4776,7 +4776,7 @@ class Session {
|
|
|
4776
4776
|
return handleTurnInput(this, { text, images });
|
|
4777
4777
|
}
|
|
4778
4778
|
async promptAndWait(text, images, timeoutMs = 30000) {
|
|
4779
|
-
return new Promise((
|
|
4779
|
+
return new Promise((resolve, reject) => {
|
|
4780
4780
|
const timer = setTimeout(() => {
|
|
4781
4781
|
unsub();
|
|
4782
4782
|
reject(new Error(`Turn timed out after ${timeoutMs}ms`));
|
|
@@ -4785,7 +4785,7 @@ class Session {
|
|
|
4785
4785
|
if (event.msg.type === "TurnCompleted") {
|
|
4786
4786
|
clearTimeout(timer);
|
|
4787
4787
|
unsub();
|
|
4788
|
-
|
|
4788
|
+
resolve();
|
|
4789
4789
|
} else if (event.msg.type === "Error") {
|
|
4790
4790
|
clearTimeout(timer);
|
|
4791
4791
|
unsub();
|
|
@@ -4804,8 +4804,8 @@ class Session {
|
|
|
4804
4804
|
if (this.submissionQueue.length > 0) {
|
|
4805
4805
|
yield this.submissionQueue.shift();
|
|
4806
4806
|
} else {
|
|
4807
|
-
const nextSub = await new Promise((
|
|
4808
|
-
this.submissionResolvers.push(
|
|
4807
|
+
const nextSub = await new Promise((resolve) => {
|
|
4808
|
+
this.submissionResolvers.push(resolve);
|
|
4809
4809
|
});
|
|
4810
4810
|
yield nextSub;
|
|
4811
4811
|
}
|
|
@@ -5069,13 +5069,13 @@ class StdioTransport {
|
|
|
5069
5069
|
if (this.isClosed || !this.proc || !this.proc.stdin) {
|
|
5070
5070
|
throw new GroupyError("MCP Stdio transport is closed");
|
|
5071
5071
|
}
|
|
5072
|
-
return new Promise((
|
|
5072
|
+
return new Promise((resolve, reject) => {
|
|
5073
5073
|
const timeoutMs = 30000;
|
|
5074
5074
|
const timer = setTimeout(() => {
|
|
5075
5075
|
this.pendingRequests.delete(request.id);
|
|
5076
5076
|
reject(new GroupyError(`MCP request timed out after ${timeoutMs}ms (method: ${request.method})`));
|
|
5077
5077
|
}, timeoutMs);
|
|
5078
|
-
this.pendingRequests.set(request.id, { resolve
|
|
5078
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
5079
5079
|
try {
|
|
5080
5080
|
const payload = JSON.stringify(request) + `
|
|
5081
5081
|
`;
|
|
@@ -5165,11 +5165,11 @@ class SseTransport {
|
|
|
5165
5165
|
if (done)
|
|
5166
5166
|
break;
|
|
5167
5167
|
buffer += decoder.decode(value, { stream: true });
|
|
5168
|
-
const
|
|
5168
|
+
const events = buffer.split(`
|
|
5169
5169
|
|
|
5170
5170
|
`);
|
|
5171
|
-
buffer =
|
|
5172
|
-
for (const eventBlock of
|
|
5171
|
+
buffer = events.pop() || "";
|
|
5172
|
+
for (const eventBlock of events) {
|
|
5173
5173
|
const lines = eventBlock.split(`
|
|
5174
5174
|
`);
|
|
5175
5175
|
let eventType = "message";
|
|
@@ -5208,12 +5208,12 @@ class SseTransport {
|
|
|
5208
5208
|
if (!this.messageUrl) {
|
|
5209
5209
|
this.messageUrl = this.endpointUrl;
|
|
5210
5210
|
}
|
|
5211
|
-
return new Promise((
|
|
5211
|
+
return new Promise((resolve, reject) => {
|
|
5212
5212
|
const timer = setTimeout(() => {
|
|
5213
5213
|
this.pendingRequests.delete(request.id);
|
|
5214
5214
|
reject(new GroupyError(`MCP SSE request timed out (method: ${request.method})`));
|
|
5215
5215
|
}, 30000);
|
|
5216
|
-
this.pendingRequests.set(request.id, { resolve
|
|
5216
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
5217
5217
|
fetch(this.messageUrl, {
|
|
5218
5218
|
method: "POST",
|
|
5219
5219
|
headers: {
|
|
@@ -5537,7 +5537,7 @@ class McpManager {
|
|
|
5537
5537
|
}
|
|
5538
5538
|
return client.ping();
|
|
5539
5539
|
}
|
|
5540
|
-
async removeServer(name,
|
|
5540
|
+
async removeServer(name, router) {
|
|
5541
5541
|
const client = this.clients.get(name);
|
|
5542
5542
|
if (!client)
|
|
5543
5543
|
return false;
|
|
@@ -5546,12 +5546,12 @@ class McpManager {
|
|
|
5546
5546
|
} catch {}
|
|
5547
5547
|
this.clients.delete(name);
|
|
5548
5548
|
this.serverConfigs.delete(name);
|
|
5549
|
-
if (
|
|
5550
|
-
|
|
5549
|
+
if (router) {
|
|
5550
|
+
router.unregisterPrefix(`mcp__${name}__`);
|
|
5551
5551
|
}
|
|
5552
5552
|
return true;
|
|
5553
5553
|
}
|
|
5554
|
-
registerToolsIntoRouter(
|
|
5554
|
+
registerToolsIntoRouter(router) {
|
|
5555
5555
|
if (this.clients.size === 0)
|
|
5556
5556
|
return;
|
|
5557
5557
|
let hasAnyLazyServer = false;
|
|
@@ -5575,7 +5575,7 @@ class McpManager {
|
|
|
5575
5575
|
return client.callTool(mcpTool.name, args);
|
|
5576
5576
|
}
|
|
5577
5577
|
};
|
|
5578
|
-
|
|
5578
|
+
router.register(tool);
|
|
5579
5579
|
}
|
|
5580
5580
|
}
|
|
5581
5581
|
if (client.getResources().length > 0) {
|
|
@@ -5625,7 +5625,7 @@ class McpManager {
|
|
|
5625
5625
|
}
|
|
5626
5626
|
}
|
|
5627
5627
|
};
|
|
5628
|
-
|
|
5628
|
+
router.register(callMcpTool);
|
|
5629
5629
|
const getToolSchemaTool = {
|
|
5630
5630
|
name: "get_mcp_tool_schema",
|
|
5631
5631
|
description: "Retrieve parameter specification and JSONSchema for a lazy-loaded MCP tool.",
|
|
@@ -5654,7 +5654,7 @@ class McpManager {
|
|
|
5654
5654
|
return { output: JSON.stringify(tool, null, 2) };
|
|
5655
5655
|
}
|
|
5656
5656
|
};
|
|
5657
|
-
|
|
5657
|
+
router.register(getToolSchemaTool);
|
|
5658
5658
|
const listResourcesTool = {
|
|
5659
5659
|
name: "list_mcp_resources",
|
|
5660
5660
|
description: "List available data resources exposed by a connected MCP server.",
|
|
@@ -5674,7 +5674,7 @@ class McpManager {
|
|
|
5674
5674
|
return { output: JSON.stringify(client.getResources(), null, 2) };
|
|
5675
5675
|
}
|
|
5676
5676
|
};
|
|
5677
|
-
|
|
5677
|
+
router.register(listResourcesTool);
|
|
5678
5678
|
const readResourceTool = {
|
|
5679
5679
|
name: "read_mcp_resource",
|
|
5680
5680
|
description: "Read the contents of an MCP resource by URI across connected MCP servers.",
|
|
@@ -5704,7 +5704,7 @@ class McpManager {
|
|
|
5704
5704
|
}
|
|
5705
5705
|
}
|
|
5706
5706
|
};
|
|
5707
|
-
|
|
5707
|
+
router.register(readResourceTool);
|
|
5708
5708
|
}
|
|
5709
5709
|
formatMcpPrompt() {
|
|
5710
5710
|
if (this.clients.size === 0)
|
|
@@ -5773,20 +5773,20 @@ class McpManager {
|
|
|
5773
5773
|
} catch {}
|
|
5774
5774
|
return false;
|
|
5775
5775
|
}
|
|
5776
|
-
async reload(
|
|
5776
|
+
async reload(router) {
|
|
5777
5777
|
await this.closeAll();
|
|
5778
|
-
if (
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
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");
|
|
5784
5784
|
}
|
|
5785
5785
|
for (const filePath of this.loadedConfigFiles) {
|
|
5786
5786
|
await this.loadConfigFile(filePath);
|
|
5787
5787
|
}
|
|
5788
|
-
if (
|
|
5789
|
-
this.registerToolsIntoRouter(
|
|
5788
|
+
if (router) {
|
|
5789
|
+
this.registerToolsIntoRouter(router);
|
|
5790
5790
|
}
|
|
5791
5791
|
}
|
|
5792
5792
|
getDefaultConfigFile(cwd = process.cwd()) {
|
|
@@ -5975,7 +5975,7 @@ class CdpSession {
|
|
|
5975
5975
|
this.wsUrl = wsUrl;
|
|
5976
5976
|
}
|
|
5977
5977
|
async connect() {
|
|
5978
|
-
return new Promise((
|
|
5978
|
+
return new Promise((resolve, reject) => {
|
|
5979
5979
|
try {
|
|
5980
5980
|
this.ws = new WebSocket(this.wsUrl);
|
|
5981
5981
|
const onOpen = async () => {
|
|
@@ -5991,7 +5991,7 @@ class CdpSession {
|
|
|
5991
5991
|
await this.send("Network.enable").catch(() => {});
|
|
5992
5992
|
await this.send("Page.setLifecycleEventsEnabled", { enabled: true }).catch(() => {});
|
|
5993
5993
|
this.setupEventHandlers();
|
|
5994
|
-
|
|
5994
|
+
resolve();
|
|
5995
5995
|
} catch (err) {
|
|
5996
5996
|
reject(err);
|
|
5997
5997
|
}
|
|
@@ -6113,13 +6113,13 @@ class CdpSession {
|
|
|
6113
6113
|
throw new Error("CDP WebSocket is not connected");
|
|
6114
6114
|
}
|
|
6115
6115
|
const id = this.nextId++;
|
|
6116
|
-
return new Promise((
|
|
6116
|
+
return new Promise((resolve, reject) => {
|
|
6117
6117
|
const timeoutMs = 30000;
|
|
6118
6118
|
const timer = setTimeout(() => {
|
|
6119
6119
|
this.pending.delete(id);
|
|
6120
6120
|
reject(new Error(`CDP command '${method}' timed out after ${timeoutMs}ms`));
|
|
6121
6121
|
}, timeoutMs);
|
|
6122
|
-
this.pending.set(id, { resolve
|
|
6122
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
6123
6123
|
try {
|
|
6124
6124
|
this.ws?.send(JSON.stringify({ id, method, params }));
|
|
6125
6125
|
} catch (err) {
|
|
@@ -6148,7 +6148,7 @@ class CdpSession {
|
|
|
6148
6148
|
}
|
|
6149
6149
|
// src/mcp/servers/chrome-devtools/dom-snapshot.ts
|
|
6150
6150
|
class DomSnapshotEngine {
|
|
6151
|
-
static async captureSnapshot(
|
|
6151
|
+
static async captureSnapshot(session, verbose = false) {
|
|
6152
6152
|
const crawlerScript = `
|
|
6153
6153
|
(() => {
|
|
6154
6154
|
let currentUid = 1;
|
|
@@ -6273,7 +6273,7 @@ class DomSnapshotEngine {
|
|
|
6273
6273
|
};
|
|
6274
6274
|
})()
|
|
6275
6275
|
`;
|
|
6276
|
-
const res = await
|
|
6276
|
+
const res = await session.send("Runtime.evaluate", {
|
|
6277
6277
|
expression: crawlerScript,
|
|
6278
6278
|
returnByValue: true,
|
|
6279
6279
|
awaitPromise: true
|
|
@@ -6287,7 +6287,7 @@ class DomSnapshotEngine {
|
|
|
6287
6287
|
elementsCount: val.count
|
|
6288
6288
|
};
|
|
6289
6289
|
}
|
|
6290
|
-
static async getElementCenter(
|
|
6290
|
+
static async getElementCenter(session, uid) {
|
|
6291
6291
|
const script = `
|
|
6292
6292
|
(() => {
|
|
6293
6293
|
const el = document.querySelector(\`[data-groupy-mcp-uid="\${${JSON.stringify(uid)}}"]\`);
|
|
@@ -6302,7 +6302,7 @@ class DomSnapshotEngine {
|
|
|
6302
6302
|
};
|
|
6303
6303
|
})()
|
|
6304
6304
|
`;
|
|
6305
|
-
const res = await
|
|
6305
|
+
const res = await session.send("Runtime.evaluate", {
|
|
6306
6306
|
expression: script,
|
|
6307
6307
|
returnByValue: true,
|
|
6308
6308
|
awaitPromise: true
|
|
@@ -6443,12 +6443,12 @@ class ChromeDevToolsController {
|
|
|
6443
6443
|
} else if (navType === "reload") {
|
|
6444
6444
|
await cdp.send("Page.reload", { ignoreCache: params.ignoreCache });
|
|
6445
6445
|
}
|
|
6446
|
-
await new Promise((
|
|
6447
|
-
const timer = setTimeout(
|
|
6446
|
+
await new Promise((resolve) => {
|
|
6447
|
+
const timer = setTimeout(resolve, params.timeout || 3000);
|
|
6448
6448
|
const unsub = cdp.on("Page.loadEventFired", () => {
|
|
6449
6449
|
clearTimeout(timer);
|
|
6450
6450
|
unsub();
|
|
6451
|
-
|
|
6451
|
+
resolve();
|
|
6452
6452
|
});
|
|
6453
6453
|
});
|
|
6454
6454
|
const evalRes = await cdp.send("Runtime.evaluate", {
|
|
@@ -7397,11 +7397,11 @@ class WebSearchEngine {
|
|
|
7397
7397
|
class LiveDocFetcher {
|
|
7398
7398
|
static async fetchPageContent(url, options = {}) {
|
|
7399
7399
|
const timeoutMs = options.timeoutMs || 15000;
|
|
7400
|
-
const
|
|
7401
|
-
const timer = setTimeout(() =>
|
|
7400
|
+
const controller = new AbortController;
|
|
7401
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
7402
7402
|
try {
|
|
7403
7403
|
const res = await fetch(url, {
|
|
7404
|
-
signal:
|
|
7404
|
+
signal: controller.signal,
|
|
7405
7405
|
headers: {
|
|
7406
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",
|
|
7407
7407
|
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,text/plain,*/*;q=0.8"
|
|
@@ -8582,8 +8582,8 @@ Your nickname is ${nickname}. Your assigned task is: '${params.taskName}'. Focus
|
|
|
8582
8582
|
});
|
|
8583
8583
|
let resolvePromise;
|
|
8584
8584
|
let rejectPromise;
|
|
8585
|
-
const taskPromise = new Promise((
|
|
8586
|
-
resolvePromise =
|
|
8585
|
+
const taskPromise = new Promise((resolve, reject) => {
|
|
8586
|
+
resolvePromise = resolve;
|
|
8587
8587
|
rejectPromise = reject;
|
|
8588
8588
|
});
|
|
8589
8589
|
const handle = {
|
|
@@ -8875,9 +8875,9 @@ function createMultiAgentTools(spawner) {
|
|
|
8875
8875
|
};
|
|
8876
8876
|
return [spawnAgentTool, waitAgentTool, sendInputTool, closeAgentTool, listAgentsTool];
|
|
8877
8877
|
}
|
|
8878
|
-
function registerMultiAgentTools(
|
|
8878
|
+
function registerMultiAgentTools(router, spawner) {
|
|
8879
8879
|
for (const tool of createMultiAgentTools(spawner)) {
|
|
8880
|
-
|
|
8880
|
+
router.register(tool);
|
|
8881
8881
|
}
|
|
8882
8882
|
}
|
|
8883
8883
|
// src/storage/sqlite-store.ts
|
|
@@ -8931,20 +8931,20 @@ class SqliteThreadStore {
|
|
|
8931
8931
|
CREATE INDEX IF NOT EXISTS idx_items_thread_seq ON items(thread_id, seq ASC);
|
|
8932
8932
|
`);
|
|
8933
8933
|
}
|
|
8934
|
-
saveThread(
|
|
8934
|
+
saveThread(thread) {
|
|
8935
8935
|
const query = this.db.prepare(`
|
|
8936
8936
|
INSERT OR REPLACE INTO threads (id, title, model, cwd, role, status, created_at, updated_at)
|
|
8937
8937
|
VALUES ($id, $title, $model, $cwd, $role, $status, $createdAt, $updatedAt)
|
|
8938
8938
|
`);
|
|
8939
8939
|
query.run({
|
|
8940
|
-
$id:
|
|
8941
|
-
$title:
|
|
8942
|
-
$model:
|
|
8943
|
-
$cwd:
|
|
8944
|
-
$role:
|
|
8945
|
-
$status:
|
|
8946
|
-
$createdAt:
|
|
8947
|
-
$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
|
|
8948
8948
|
});
|
|
8949
8949
|
}
|
|
8950
8950
|
updateThreadTitle(id, title) {
|
|
@@ -9021,12 +9021,12 @@ class SqliteThreadStore {
|
|
|
9021
9021
|
return rows.map((r) => JSON.parse(r.payload));
|
|
9022
9022
|
}
|
|
9023
9023
|
restoreSession(threadId) {
|
|
9024
|
-
const
|
|
9025
|
-
if (!
|
|
9024
|
+
const thread = this.getThread(threadId);
|
|
9025
|
+
if (!thread) {
|
|
9026
9026
|
throw new GroupyError(`Thread with id '${threadId}' not found in thread store.`);
|
|
9027
9027
|
}
|
|
9028
|
-
const
|
|
9029
|
-
return { thread
|
|
9028
|
+
const items = this.getItems(threadId);
|
|
9029
|
+
return { thread, items };
|
|
9030
9030
|
}
|
|
9031
9031
|
deleteThread(id) {
|
|
9032
9032
|
const query = this.db.prepare(`DELETE FROM threads WHERE id = $id`);
|
|
@@ -9048,15 +9048,15 @@ class SessionPersistenceManager {
|
|
|
9048
9048
|
this.store = new SqliteThreadStore(storeOrPath);
|
|
9049
9049
|
}
|
|
9050
9050
|
}
|
|
9051
|
-
bindSession(
|
|
9052
|
-
const threadId =
|
|
9051
|
+
bindSession(session, role = "default") {
|
|
9052
|
+
const threadId = session.threadId;
|
|
9053
9053
|
const existing = this.store.getThread(threadId);
|
|
9054
9054
|
if (!existing) {
|
|
9055
9055
|
this.store.saveThread({
|
|
9056
9056
|
id: threadId,
|
|
9057
9057
|
title: "New Session",
|
|
9058
|
-
model:
|
|
9059
|
-
cwd:
|
|
9058
|
+
model: session.model,
|
|
9059
|
+
cwd: session.cwd,
|
|
9060
9060
|
role,
|
|
9061
9061
|
status: "active",
|
|
9062
9062
|
createdAt: Date.now(),
|
|
@@ -9065,7 +9065,7 @@ class SessionPersistenceManager {
|
|
|
9065
9065
|
}
|
|
9066
9066
|
const existingItems = this.store.getItems(threadId);
|
|
9067
9067
|
let seq = existingItems.length;
|
|
9068
|
-
const unsub =
|
|
9068
|
+
const unsub = session.onEvent((event) => {
|
|
9069
9069
|
const msg = event.msg;
|
|
9070
9070
|
if (msg.type === "ItemCompleted") {
|
|
9071
9071
|
const item = msg.item;
|
|
@@ -9084,7 +9084,7 @@ class SessionPersistenceManager {
|
|
|
9084
9084
|
}
|
|
9085
9085
|
resumeSession(threadId, overrides = {}) {
|
|
9086
9086
|
const restored = this.store.restoreSession(threadId);
|
|
9087
|
-
const
|
|
9087
|
+
const session = new Session({
|
|
9088
9088
|
threadId: restored.thread.id,
|
|
9089
9089
|
model: overrides.model || restored.thread.model,
|
|
9090
9090
|
cwd: overrides.cwd || restored.thread.cwd,
|
|
@@ -9096,8 +9096,8 @@ class SessionPersistenceManager {
|
|
|
9096
9096
|
systemPrompt: overrides.systemPrompt,
|
|
9097
9097
|
initialHistory: restored.items
|
|
9098
9098
|
});
|
|
9099
|
-
this.bindSession(
|
|
9100
|
-
return
|
|
9099
|
+
this.bindSession(session, restored.thread.role);
|
|
9100
|
+
return session;
|
|
9101
9101
|
}
|
|
9102
9102
|
loadSession(threadId) {
|
|
9103
9103
|
try {
|
|
@@ -9114,17 +9114,17 @@ class SessionPersistenceManager {
|
|
|
9114
9114
|
}
|
|
9115
9115
|
this.unsubscribers = [];
|
|
9116
9116
|
}
|
|
9117
|
-
resumeIntoSession(
|
|
9117
|
+
resumeIntoSession(session, threadId) {
|
|
9118
9118
|
const restored = this.loadSession(threadId);
|
|
9119
9119
|
if (!restored)
|
|
9120
9120
|
return null;
|
|
9121
9121
|
this.unbindSession();
|
|
9122
|
-
|
|
9123
|
-
|
|
9122
|
+
session.threadId = restored.thread.id;
|
|
9123
|
+
session.setHistory(restored.items);
|
|
9124
9124
|
if (restored.thread.model) {
|
|
9125
|
-
|
|
9125
|
+
session.model = restored.thread.model;
|
|
9126
9126
|
}
|
|
9127
|
-
this.bindSession(
|
|
9127
|
+
this.bindSession(session, restored.thread.role);
|
|
9128
9128
|
return restored;
|
|
9129
9129
|
}
|
|
9130
9130
|
listSessions(options) {
|
|
@@ -9268,9 +9268,9 @@ class SkillsLoader {
|
|
|
9268
9268
|
}
|
|
9269
9269
|
const all = this.listSkills(cwd, { includeDisabled: false });
|
|
9270
9270
|
const target = skillName.trim().toLowerCase();
|
|
9271
|
-
const
|
|
9272
|
-
const targetNorm =
|
|
9273
|
-
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);
|
|
9274
9274
|
if (!meta)
|
|
9275
9275
|
return null;
|
|
9276
9276
|
try {
|
|
@@ -9398,13 +9398,13 @@ class MemoryStore {
|
|
|
9398
9398
|
}
|
|
9399
9399
|
getProjectMemoryDir(cwd) {
|
|
9400
9400
|
if (this.customWorkspacePath) {
|
|
9401
|
-
const
|
|
9402
|
-
if (!existsSync20(
|
|
9401
|
+
const dir = resolve21(this.customWorkspacePath);
|
|
9402
|
+
if (!existsSync20(dir)) {
|
|
9403
9403
|
try {
|
|
9404
|
-
mkdirSync12(
|
|
9404
|
+
mkdirSync12(dir, { recursive: true });
|
|
9405
9405
|
} catch {}
|
|
9406
9406
|
}
|
|
9407
|
-
return
|
|
9407
|
+
return dir;
|
|
9408
9408
|
}
|
|
9409
9409
|
const slug = this.getProjectSlug(cwd);
|
|
9410
9410
|
const dir = join11(getProjectsDir(), slug, "memory");
|
|
@@ -9543,12 +9543,12 @@ class MemoryStore {
|
|
|
9543
9543
|
const memoryDir = this.getProjectMemoryDir(cwd);
|
|
9544
9544
|
const indexPath = join11(memoryDir, "MEMORY.md");
|
|
9545
9545
|
const files = existsSync20(memoryDir) ? readdirSync9(memoryDir).filter((f) => f.endsWith(".md") && f !== "MEMORY.md") : [];
|
|
9546
|
-
const
|
|
9546
|
+
const items = [];
|
|
9547
9547
|
for (const f of files) {
|
|
9548
9548
|
try {
|
|
9549
9549
|
const full = join11(memoryDir, f);
|
|
9550
9550
|
const parsed = this.parseTopicFile(readFileSync11(full, "utf8"), full);
|
|
9551
|
-
|
|
9551
|
+
items.push({
|
|
9552
9552
|
type: parsed.type,
|
|
9553
9553
|
name: parsed.name,
|
|
9554
9554
|
desc: parsed.description || parsed.content.split(`
|
|
@@ -9563,7 +9563,7 @@ class MemoryStore {
|
|
|
9563
9563
|
"This index is loaded at session startup. Detailed topics can be retrieved via read_memory tool.",
|
|
9564
9564
|
""
|
|
9565
9565
|
];
|
|
9566
|
-
for (const item of
|
|
9566
|
+
for (const item of items) {
|
|
9567
9567
|
indexLines.push(`- [${item.type}] **${item.name}**: ${item.desc} (topic: ${item.file})`);
|
|
9568
9568
|
}
|
|
9569
9569
|
const boundedLines = indexLines.slice(0, 200);
|
|
@@ -9934,8 +9934,8 @@ class AuthClient {
|
|
|
9934
9934
|
if (!res.ok) {
|
|
9935
9935
|
let errDetail = `HTTP ${res.status}`;
|
|
9936
9936
|
try {
|
|
9937
|
-
const
|
|
9938
|
-
errDetail =
|
|
9937
|
+
const data = await res.json();
|
|
9938
|
+
errDetail = data.detail || JSON.stringify(data);
|
|
9939
9939
|
} catch {}
|
|
9940
9940
|
throw new Error(`Login failed: ${errDetail}`);
|
|
9941
9941
|
}
|
|
@@ -9961,8 +9961,8 @@ class AuthClient {
|
|
|
9961
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`;
|
|
9962
9962
|
let serverResolve;
|
|
9963
9963
|
let serverReject;
|
|
9964
|
-
const codePromise = new Promise((
|
|
9965
|
-
serverResolve =
|
|
9964
|
+
const codePromise = new Promise((resolve, reject) => {
|
|
9965
|
+
serverResolve = resolve;
|
|
9966
9966
|
serverReject = reject;
|
|
9967
9967
|
});
|
|
9968
9968
|
if (options.openBrowser !== false) {
|
|
@@ -9971,9 +9971,9 @@ class AuthClient {
|
|
|
9971
9971
|
exec(startCmd);
|
|
9972
9972
|
} catch {}
|
|
9973
9973
|
}
|
|
9974
|
-
let
|
|
9974
|
+
let server;
|
|
9975
9975
|
try {
|
|
9976
|
-
|
|
9976
|
+
server = Bun.serve({
|
|
9977
9977
|
port,
|
|
9978
9978
|
fetch: async (req) => {
|
|
9979
9979
|
const url = new URL(req.url);
|
|
@@ -10053,8 +10053,8 @@ class AuthClient {
|
|
|
10053
10053
|
this.store.save(credentials);
|
|
10054
10054
|
return credentials;
|
|
10055
10055
|
} finally {
|
|
10056
|
-
if (
|
|
10057
|
-
|
|
10056
|
+
if (server) {
|
|
10057
|
+
server.stop();
|
|
10058
10058
|
}
|
|
10059
10059
|
}
|
|
10060
10060
|
};
|
|
@@ -10120,7 +10120,7 @@ function ClaudeHeader({
|
|
|
10120
10120
|
version = "v0.3.2",
|
|
10121
10121
|
user = "Developer",
|
|
10122
10122
|
model = "Claude 3.7 Sonnet (Thinking)",
|
|
10123
|
-
plan
|
|
10123
|
+
plan = "Pro",
|
|
10124
10124
|
branch = "main",
|
|
10125
10125
|
cwd = "~/workspace",
|
|
10126
10126
|
tips = ["Ask Groupy to create a new app, test code, or run tasks"],
|
|
@@ -10130,7 +10130,7 @@ function ClaudeHeader({
|
|
|
10130
10130
|
],
|
|
10131
10131
|
className
|
|
10132
10132
|
}) {
|
|
10133
|
-
const modelLine = `${model} \xB7 Groupy ${
|
|
10133
|
+
const modelLine = `${model} \xB7 Groupy ${plan}`;
|
|
10134
10134
|
const branchLine = `\uE0A0 ${branch}`;
|
|
10135
10135
|
return /* @__PURE__ */ jsx_dev_runtime.jsxDEV("fieldset", {
|
|
10136
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 || ""}`,
|
|
@@ -10372,7 +10372,7 @@ var STATUS_COLOR = {
|
|
|
10372
10372
|
pending: "#e0af68"
|
|
10373
10373
|
};
|
|
10374
10374
|
function ClaudeToolCall({
|
|
10375
|
-
tool
|
|
10375
|
+
tool,
|
|
10376
10376
|
arg,
|
|
10377
10377
|
result,
|
|
10378
10378
|
status = "success",
|
|
@@ -10402,7 +10402,7 @@ function ClaudeToolCall({
|
|
|
10402
10402
|
children: [
|
|
10403
10403
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV("span", {
|
|
10404
10404
|
className: "text-[#c0caf5] font-semibold",
|
|
10405
|
-
children:
|
|
10405
|
+
children: tool
|
|
10406
10406
|
}, undefined, false, undefined, this),
|
|
10407
10407
|
arg !== undefined ? /* @__PURE__ */ jsx_dev_runtime4.jsxDEV(jsx_dev_runtime4.Fragment, {
|
|
10408
10408
|
children: [
|
|
@@ -11054,13 +11054,13 @@ function GrokStatus({
|
|
|
11054
11054
|
directory = process.cwd ? process.cwd() : "~/workspace",
|
|
11055
11055
|
contextUsed = "16K",
|
|
11056
11056
|
contextLimit = "500K",
|
|
11057
|
-
turn
|
|
11057
|
+
turn,
|
|
11058
11058
|
turnTotal,
|
|
11059
11059
|
mcp,
|
|
11060
11060
|
mcpTotal,
|
|
11061
11061
|
className = ""
|
|
11062
11062
|
}) {
|
|
11063
|
-
const showTurn = typeof
|
|
11063
|
+
const showTurn = typeof turn === "number" && typeof turnTotal === "number" && turnTotal > 0;
|
|
11064
11064
|
const showMcp = typeof mcp === "number" && typeof mcpTotal === "number" && mcpTotal > 0;
|
|
11065
11065
|
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV("div", {
|
|
11066
11066
|
className: `flex min-w-0 flex-wrap items-baseline justify-between gap-x-4 gap-y-1 font-mono text-[12px] ${className}`,
|
|
@@ -11129,7 +11129,7 @@ function GrokStatus({
|
|
|
11129
11129
|
}, undefined, false, undefined, this),
|
|
11130
11130
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV("span", {
|
|
11131
11131
|
children: [
|
|
11132
|
-
|
|
11132
|
+
turn,
|
|
11133
11133
|
"/",
|
|
11134
11134
|
turnTotal
|
|
11135
11135
|
]
|