@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/cli.js
CHANGED
|
@@ -1636,13 +1636,13 @@ class Session {
|
|
|
1636
1636
|
type: "StatusChanged",
|
|
1637
1637
|
status: "waiting_approval"
|
|
1638
1638
|
});
|
|
1639
|
-
return new Promise((
|
|
1639
|
+
return new Promise((resolve) => {
|
|
1640
1640
|
this.pendingApprovals.set(params.approvalId, (approved) => {
|
|
1641
1641
|
this.emitEvent({
|
|
1642
1642
|
type: "StatusChanged",
|
|
1643
1643
|
status: "running"
|
|
1644
1644
|
});
|
|
1645
|
-
|
|
1645
|
+
resolve(approved);
|
|
1646
1646
|
});
|
|
1647
1647
|
});
|
|
1648
1648
|
}
|
|
@@ -1665,13 +1665,13 @@ class Session {
|
|
|
1665
1665
|
type: "StatusChanged",
|
|
1666
1666
|
status: "waiting_user_input"
|
|
1667
1667
|
});
|
|
1668
|
-
return new Promise((
|
|
1668
|
+
return new Promise((resolve) => {
|
|
1669
1669
|
this.pendingUserQuestions.set(params.questionId, (answer) => {
|
|
1670
1670
|
this.emitEvent({
|
|
1671
1671
|
type: "StatusChanged",
|
|
1672
1672
|
status: "running"
|
|
1673
1673
|
});
|
|
1674
|
-
|
|
1674
|
+
resolve(answer);
|
|
1675
1675
|
});
|
|
1676
1676
|
});
|
|
1677
1677
|
}
|
|
@@ -1701,7 +1701,7 @@ class Session {
|
|
|
1701
1701
|
return handleTurnInput(this, { text, images });
|
|
1702
1702
|
}
|
|
1703
1703
|
async promptAndWait(text, images, timeoutMs = 30000) {
|
|
1704
|
-
return new Promise((
|
|
1704
|
+
return new Promise((resolve, reject) => {
|
|
1705
1705
|
const timer = setTimeout(() => {
|
|
1706
1706
|
unsub();
|
|
1707
1707
|
reject(new Error(`Turn timed out after ${timeoutMs}ms`));
|
|
@@ -1710,7 +1710,7 @@ class Session {
|
|
|
1710
1710
|
if (event.msg.type === "TurnCompleted") {
|
|
1711
1711
|
clearTimeout(timer);
|
|
1712
1712
|
unsub();
|
|
1713
|
-
|
|
1713
|
+
resolve();
|
|
1714
1714
|
} else if (event.msg.type === "Error") {
|
|
1715
1715
|
clearTimeout(timer);
|
|
1716
1716
|
unsub();
|
|
@@ -1729,8 +1729,8 @@ class Session {
|
|
|
1729
1729
|
if (this.submissionQueue.length > 0) {
|
|
1730
1730
|
yield this.submissionQueue.shift();
|
|
1731
1731
|
} else {
|
|
1732
|
-
const nextSub = await new Promise((
|
|
1733
|
-
this.submissionResolvers.push(
|
|
1732
|
+
const nextSub = await new Promise((resolve) => {
|
|
1733
|
+
this.submissionResolvers.push(resolve);
|
|
1734
1734
|
});
|
|
1735
1735
|
yield nextSub;
|
|
1736
1736
|
}
|
|
@@ -1910,6 +1910,12 @@ class WindowsSandbox {
|
|
|
1910
1910
|
return null;
|
|
1911
1911
|
}
|
|
1912
1912
|
try {
|
|
1913
|
+
if (this.jobObjectHandle) {
|
|
1914
|
+
try {
|
|
1915
|
+
this.kernel32.symbols.CloseHandle(this.jobObjectHandle);
|
|
1916
|
+
} catch {}
|
|
1917
|
+
this.jobObjectHandle = null;
|
|
1918
|
+
}
|
|
1913
1919
|
const jobHandle = this.kernel32.symbols.CreateJobObjectW(null, null);
|
|
1914
1920
|
if (!jobHandle || jobHandle === 0) {
|
|
1915
1921
|
return null;
|
|
@@ -2338,7 +2344,7 @@ function createShellTool(policy = new ExecPolicy) {
|
|
|
2338
2344
|
} catch {}
|
|
2339
2345
|
});
|
|
2340
2346
|
}
|
|
2341
|
-
const timeoutPromise = new Promise((
|
|
2347
|
+
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve({ isTimeout: true }), timeoutMs));
|
|
2342
2348
|
const result = await Promise.race([
|
|
2343
2349
|
proc.exited.then(async (code) => {
|
|
2344
2350
|
const stdout = await new Response(proc.stdout).text();
|
|
@@ -3756,8 +3762,8 @@ Your nickname is ${nickname}. Your assigned task is: '${params.taskName}'. Focus
|
|
|
3756
3762
|
});
|
|
3757
3763
|
let resolvePromise;
|
|
3758
3764
|
let rejectPromise;
|
|
3759
|
-
const taskPromise = new Promise((
|
|
3760
|
-
resolvePromise =
|
|
3765
|
+
const taskPromise = new Promise((resolve, reject) => {
|
|
3766
|
+
resolvePromise = resolve;
|
|
3761
3767
|
rejectPromise = reject;
|
|
3762
3768
|
});
|
|
3763
3769
|
const handle = {
|
|
@@ -4050,9 +4056,9 @@ function createMultiAgentTools(spawner) {
|
|
|
4050
4056
|
};
|
|
4051
4057
|
return [spawnAgentTool, waitAgentTool, sendInputTool, closeAgentTool, listAgentsTool];
|
|
4052
4058
|
}
|
|
4053
|
-
function registerMultiAgentTools(
|
|
4059
|
+
function registerMultiAgentTools(router, spawner) {
|
|
4054
4060
|
for (const tool of createMultiAgentTools(spawner)) {
|
|
4055
|
-
|
|
4061
|
+
router.register(tool);
|
|
4056
4062
|
}
|
|
4057
4063
|
}
|
|
4058
4064
|
|
|
@@ -4452,13 +4458,13 @@ class StdioTransport {
|
|
|
4452
4458
|
if (this.isClosed || !this.proc || !this.proc.stdin) {
|
|
4453
4459
|
throw new GroupyError("MCP Stdio transport is closed");
|
|
4454
4460
|
}
|
|
4455
|
-
return new Promise((
|
|
4461
|
+
return new Promise((resolve, reject) => {
|
|
4456
4462
|
const timeoutMs = 30000;
|
|
4457
4463
|
const timer = setTimeout(() => {
|
|
4458
4464
|
this.pendingRequests.delete(request.id);
|
|
4459
4465
|
reject(new GroupyError(`MCP request timed out after ${timeoutMs}ms (method: ${request.method})`));
|
|
4460
4466
|
}, timeoutMs);
|
|
4461
|
-
this.pendingRequests.set(request.id, { resolve
|
|
4467
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
4462
4468
|
try {
|
|
4463
4469
|
const payload = JSON.stringify(request) + `
|
|
4464
4470
|
`;
|
|
@@ -4591,12 +4597,12 @@ class SseTransport {
|
|
|
4591
4597
|
if (!this.messageUrl) {
|
|
4592
4598
|
this.messageUrl = this.endpointUrl;
|
|
4593
4599
|
}
|
|
4594
|
-
return new Promise((
|
|
4600
|
+
return new Promise((resolve, reject) => {
|
|
4595
4601
|
const timer = setTimeout(() => {
|
|
4596
4602
|
this.pendingRequests.delete(request.id);
|
|
4597
4603
|
reject(new GroupyError(`MCP SSE request timed out (method: ${request.method})`));
|
|
4598
4604
|
}, 30000);
|
|
4599
|
-
this.pendingRequests.set(request.id, { resolve
|
|
4605
|
+
this.pendingRequests.set(request.id, { resolve, reject, timer });
|
|
4600
4606
|
fetch(this.messageUrl, {
|
|
4601
4607
|
method: "POST",
|
|
4602
4608
|
headers: {
|
|
@@ -4725,7 +4731,7 @@ class McpManager {
|
|
|
4725
4731
|
}
|
|
4726
4732
|
return client.ping();
|
|
4727
4733
|
}
|
|
4728
|
-
async removeServer(name,
|
|
4734
|
+
async removeServer(name, router) {
|
|
4729
4735
|
const client = this.clients.get(name);
|
|
4730
4736
|
if (!client)
|
|
4731
4737
|
return false;
|
|
@@ -4734,12 +4740,12 @@ class McpManager {
|
|
|
4734
4740
|
} catch {}
|
|
4735
4741
|
this.clients.delete(name);
|
|
4736
4742
|
this.serverConfigs.delete(name);
|
|
4737
|
-
if (
|
|
4738
|
-
|
|
4743
|
+
if (router) {
|
|
4744
|
+
router.unregisterPrefix(`mcp__${name}__`);
|
|
4739
4745
|
}
|
|
4740
4746
|
return true;
|
|
4741
4747
|
}
|
|
4742
|
-
registerToolsIntoRouter(
|
|
4748
|
+
registerToolsIntoRouter(router) {
|
|
4743
4749
|
if (this.clients.size === 0)
|
|
4744
4750
|
return;
|
|
4745
4751
|
let hasAnyLazyServer = false;
|
|
@@ -4763,7 +4769,7 @@ class McpManager {
|
|
|
4763
4769
|
return client.callTool(mcpTool.name, args);
|
|
4764
4770
|
}
|
|
4765
4771
|
};
|
|
4766
|
-
|
|
4772
|
+
router.register(tool);
|
|
4767
4773
|
}
|
|
4768
4774
|
}
|
|
4769
4775
|
if (client.getResources().length > 0) {
|
|
@@ -4813,7 +4819,7 @@ class McpManager {
|
|
|
4813
4819
|
}
|
|
4814
4820
|
}
|
|
4815
4821
|
};
|
|
4816
|
-
|
|
4822
|
+
router.register(callMcpTool);
|
|
4817
4823
|
const getToolSchemaTool = {
|
|
4818
4824
|
name: "get_mcp_tool_schema",
|
|
4819
4825
|
description: "Retrieve parameter specification and JSONSchema for a lazy-loaded MCP tool.",
|
|
@@ -4842,7 +4848,7 @@ class McpManager {
|
|
|
4842
4848
|
return { output: JSON.stringify(tool, null, 2) };
|
|
4843
4849
|
}
|
|
4844
4850
|
};
|
|
4845
|
-
|
|
4851
|
+
router.register(getToolSchemaTool);
|
|
4846
4852
|
const listResourcesTool = {
|
|
4847
4853
|
name: "list_mcp_resources",
|
|
4848
4854
|
description: "List available data resources exposed by a connected MCP server.",
|
|
@@ -4862,7 +4868,7 @@ class McpManager {
|
|
|
4862
4868
|
return { output: JSON.stringify(client.getResources(), null, 2) };
|
|
4863
4869
|
}
|
|
4864
4870
|
};
|
|
4865
|
-
|
|
4871
|
+
router.register(listResourcesTool);
|
|
4866
4872
|
const readResourceTool = {
|
|
4867
4873
|
name: "read_mcp_resource",
|
|
4868
4874
|
description: "Read the contents of an MCP resource by URI across connected MCP servers.",
|
|
@@ -4892,7 +4898,7 @@ class McpManager {
|
|
|
4892
4898
|
}
|
|
4893
4899
|
}
|
|
4894
4900
|
};
|
|
4895
|
-
|
|
4901
|
+
router.register(readResourceTool);
|
|
4896
4902
|
}
|
|
4897
4903
|
formatMcpPrompt() {
|
|
4898
4904
|
if (this.clients.size === 0)
|
|
@@ -4961,20 +4967,20 @@ class McpManager {
|
|
|
4961
4967
|
} catch {}
|
|
4962
4968
|
return false;
|
|
4963
4969
|
}
|
|
4964
|
-
async reload(
|
|
4970
|
+
async reload(router) {
|
|
4965
4971
|
await this.closeAll();
|
|
4966
|
-
if (
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
+
if (router) {
|
|
4973
|
+
router.unregisterPrefix("mcp__");
|
|
4974
|
+
router.unregister("call_mcp_tool");
|
|
4975
|
+
router.unregister("get_mcp_tool_schema");
|
|
4976
|
+
router.unregister("list_mcp_resources");
|
|
4977
|
+
router.unregister("read_mcp_resource");
|
|
4972
4978
|
}
|
|
4973
4979
|
for (const filePath of this.loadedConfigFiles) {
|
|
4974
4980
|
await this.loadConfigFile(filePath);
|
|
4975
4981
|
}
|
|
4976
|
-
if (
|
|
4977
|
-
this.registerToolsIntoRouter(
|
|
4982
|
+
if (router) {
|
|
4983
|
+
this.registerToolsIntoRouter(router);
|
|
4978
4984
|
}
|
|
4979
4985
|
}
|
|
4980
4986
|
getDefaultConfigFile(cwd = process.cwd()) {
|
|
@@ -5391,9 +5397,9 @@ class SkillsLoader {
|
|
|
5391
5397
|
}
|
|
5392
5398
|
const all = this.listSkills(cwd, { includeDisabled: false });
|
|
5393
5399
|
const target = skillName.trim().toLowerCase();
|
|
5394
|
-
const
|
|
5395
|
-
const targetNorm =
|
|
5396
|
-
const meta = all.find((s) => s.name.toLowerCase() === target) || all.find((s) =>
|
|
5400
|
+
const normalize = (str) => str.toLowerCase().replace(/[-_\s]/g, "");
|
|
5401
|
+
const targetNorm = normalize(skillName);
|
|
5402
|
+
const meta = all.find((s) => s.name.toLowerCase() === target) || all.find((s) => normalize(s.name) === targetNorm);
|
|
5397
5403
|
if (!meta)
|
|
5398
5404
|
return null;
|
|
5399
5405
|
try {
|
|
@@ -5590,13 +5596,13 @@ class MemoryStore {
|
|
|
5590
5596
|
}
|
|
5591
5597
|
getProjectMemoryDir(cwd) {
|
|
5592
5598
|
if (this.customWorkspacePath) {
|
|
5593
|
-
const
|
|
5594
|
-
if (!existsSync18(
|
|
5599
|
+
const dir = resolve15(this.customWorkspacePath);
|
|
5600
|
+
if (!existsSync18(dir)) {
|
|
5595
5601
|
try {
|
|
5596
|
-
mkdirSync11(
|
|
5602
|
+
mkdirSync11(dir, { recursive: true });
|
|
5597
5603
|
} catch {}
|
|
5598
5604
|
}
|
|
5599
|
-
return
|
|
5605
|
+
return dir;
|
|
5600
5606
|
}
|
|
5601
5607
|
const slug = this.getProjectSlug(cwd);
|
|
5602
5608
|
const dir = join10(getProjectsDir(), slug, "memory");
|
|
@@ -6126,8 +6132,8 @@ class AuthClient {
|
|
|
6126
6132
|
if (!res.ok) {
|
|
6127
6133
|
let errDetail = `HTTP ${res.status}`;
|
|
6128
6134
|
try {
|
|
6129
|
-
const
|
|
6130
|
-
errDetail =
|
|
6135
|
+
const data = await res.json();
|
|
6136
|
+
errDetail = data.detail || JSON.stringify(data);
|
|
6131
6137
|
} catch {}
|
|
6132
6138
|
throw new Error(`Login failed: ${errDetail}`);
|
|
6133
6139
|
}
|
|
@@ -6153,8 +6159,8 @@ class AuthClient {
|
|
|
6153
6159
|
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`;
|
|
6154
6160
|
let serverResolve;
|
|
6155
6161
|
let serverReject;
|
|
6156
|
-
const codePromise = new Promise((
|
|
6157
|
-
serverResolve =
|
|
6162
|
+
const codePromise = new Promise((resolve, reject) => {
|
|
6163
|
+
serverResolve = resolve;
|
|
6158
6164
|
serverReject = reject;
|
|
6159
6165
|
});
|
|
6160
6166
|
if (options.openBrowser !== false) {
|
|
@@ -6539,9 +6545,9 @@ function lcsTokenDiff(oldTokens, newTokens) {
|
|
|
6539
6545
|
const m = oldTokens.length;
|
|
6540
6546
|
const n = newTokens.length;
|
|
6541
6547
|
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
6542
|
-
for (let
|
|
6543
|
-
for (let
|
|
6544
|
-
dp[
|
|
6548
|
+
for (let i = 1;i <= m; i++) {
|
|
6549
|
+
for (let j = 1;j <= n; j++) {
|
|
6550
|
+
dp[i][j] = oldTokens[i - 1] === newTokens[j - 1] ? dp[i - 1][j - 1] + 1 : Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
6545
6551
|
}
|
|
6546
6552
|
}
|
|
6547
6553
|
const ops = [];
|
|
@@ -6723,7 +6729,7 @@ function parsePatch(oldSrc, newSrc, contextLines = 3) {
|
|
|
6723
6729
|
// package.json
|
|
6724
6730
|
var package_default = {
|
|
6725
6731
|
name: "@pikaa-ai/pikaa",
|
|
6726
|
-
version: "0.3.
|
|
6732
|
+
version: "0.3.26",
|
|
6727
6733
|
description: "PIKAA CLI - AI coding agent that runs locally in your terminal.",
|
|
6728
6734
|
main: "./dist/index.js",
|
|
6729
6735
|
module: "./dist/index.js",
|
|
@@ -6749,10 +6755,21 @@ var package_default = {
|
|
|
6749
6755
|
"build:js": "bun build ./src/index.ts --outdir ./dist --target=bun && bun build ./src/cli/index.ts --outfile ./dist/cli.js --target=bun",
|
|
6750
6756
|
"build:exe": "bun build ./src/cli/index.ts --compile --outfile pikaa.exe",
|
|
6751
6757
|
"build:binaries": "bun run scripts/build-binaries.ts",
|
|
6758
|
+
"publish:packages": "bun run scripts/publish-packages.ts",
|
|
6752
6759
|
"release:prepare": "bun run scripts/prepare-release.ts",
|
|
6753
6760
|
build: "bun run build:js && bun run build:exe",
|
|
6754
6761
|
prepublishOnly: "bun run build:js"
|
|
6755
6762
|
},
|
|
6763
|
+
optionalDependencies: {
|
|
6764
|
+
"@pikaa-ai/pikaa-linux-x64": "0.3.26",
|
|
6765
|
+
"@pikaa-ai/pikaa-linux-x64-musl": "0.3.26",
|
|
6766
|
+
"@pikaa-ai/pikaa-linux-arm64": "0.3.26",
|
|
6767
|
+
"@pikaa-ai/pikaa-linux-arm64-musl": "0.3.26",
|
|
6768
|
+
"@pikaa-ai/pikaa-darwin-x64": "0.3.26",
|
|
6769
|
+
"@pikaa-ai/pikaa-darwin-arm64": "0.3.26",
|
|
6770
|
+
"@pikaa-ai/pikaa-windows-x64": "0.3.26",
|
|
6771
|
+
"@pikaa-ai/pikaa-windows-arm64": "0.3.26"
|
|
6772
|
+
},
|
|
6756
6773
|
keywords: [
|
|
6757
6774
|
"ai",
|
|
6758
6775
|
"coding-agent",
|
|
@@ -6947,8 +6964,8 @@ class BannerAnimator {
|
|
|
6947
6964
|
async function renderAnimatedGroupyBanner(info, options) {
|
|
6948
6965
|
await BannerAnimator.play(info, options);
|
|
6949
6966
|
}
|
|
6950
|
-
function formatTaskProgressPlan(
|
|
6951
|
-
CliFormatter.formatTaskProgressPlan(
|
|
6967
|
+
function formatTaskProgressPlan(plan, explanation) {
|
|
6968
|
+
CliFormatter.formatTaskProgressPlan(plan, explanation);
|
|
6952
6969
|
}
|
|
6953
6970
|
function formatTurnSummary(metrics) {
|
|
6954
6971
|
CliFormatter.formatTurnSummary(metrics);
|
|
@@ -7000,9 +7017,9 @@ class CliFormatter {
|
|
|
7000
7017
|
const lat = update.latestVersion.startsWith("v") ? update.latestVersion : `v${update.latestVersion}`;
|
|
7001
7018
|
const innerWidth = 54;
|
|
7002
7019
|
const padLine = (content) => {
|
|
7003
|
-
const
|
|
7004
|
-
const
|
|
7005
|
-
return ` ${style.yellow("\u2502")} ${content}${" ".repeat(
|
|
7020
|
+
const visibleLen = style.stripAnsi(content).length;
|
|
7021
|
+
const padRight = Math.max(0, innerWidth - visibleLen);
|
|
7022
|
+
return ` ${style.yellow("\u2502")} ${content}${" ".repeat(padRight)}${style.yellow("\u2502")}`;
|
|
7006
7023
|
};
|
|
7007
7024
|
const topBorder = ` ${style.yellow("\u256D")}${style.yellow("\u2500".repeat(innerWidth + 2))}${style.yellow("\u256E")}`;
|
|
7008
7025
|
const bottomBorder = ` ${style.yellow("\u2570")}${style.yellow("\u2500".repeat(innerWidth + 2))}${style.yellow("\u256F")}`;
|
|
@@ -7149,7 +7166,7 @@ ${preview}${more}`);
|
|
|
7149
7166
|
formatted = formatted.replace(/^(#{1,3})\s+(.*)$/gm, `${c.bold}${c.brand}$1 $2${c.reset}`);
|
|
7150
7167
|
return formatted;
|
|
7151
7168
|
}
|
|
7152
|
-
static formatTaskProgressPlan(
|
|
7169
|
+
static formatTaskProgressPlan(plan, explanation) {
|
|
7153
7170
|
console.log();
|
|
7154
7171
|
if (explanation) {
|
|
7155
7172
|
console.log(` ${style.bold(explanation)}`);
|
|
@@ -7158,18 +7175,18 @@ ${preview}${more}`);
|
|
|
7158
7175
|
const ACTIVE = "\x1B[38;5;174m\u25FC\x1B[0m";
|
|
7159
7176
|
const PENDING = "\x1B[38;5;246m\u25FB\x1B[0m";
|
|
7160
7177
|
const DIM = "\x1B[38;5;246m";
|
|
7161
|
-
const
|
|
7162
|
-
for (let i = 0;i <
|
|
7163
|
-
const item =
|
|
7178
|
+
const RESET = "\x1B[0m";
|
|
7179
|
+
for (let i = 0;i < plan.length; i++) {
|
|
7180
|
+
const item = plan[i];
|
|
7164
7181
|
if (!item)
|
|
7165
7182
|
continue;
|
|
7166
7183
|
const prefix = i === 0 ? " \u23BF " : " ";
|
|
7167
7184
|
if (item.status === "completed") {
|
|
7168
|
-
console.log(` ${DIM}${prefix}${
|
|
7185
|
+
console.log(` ${DIM}${prefix}${RESET}${DONE} \x1B[9m\x1B[38;5;246m${item.step}\x1B[0m`);
|
|
7169
7186
|
} else if (item.status === "in_progress") {
|
|
7170
|
-
console.log(` ${DIM}${prefix}${
|
|
7187
|
+
console.log(` ${DIM}${prefix}${RESET}${ACTIVE} \x1B[1m\x1B[38;5;174m${item.step}\x1B[0m`);
|
|
7171
7188
|
} else {
|
|
7172
|
-
console.log(` ${DIM}${prefix}${
|
|
7189
|
+
console.log(` ${DIM}${prefix}${RESET}${PENDING} \x1B[38;5;246m${item.step}\x1B[0m`);
|
|
7173
7190
|
}
|
|
7174
7191
|
}
|
|
7175
7192
|
console.log();
|
|
@@ -7242,7 +7259,7 @@ ${preview}${more}`);
|
|
|
7242
7259
|
const BG = "\x1B[48;2;43;43;45m";
|
|
7243
7260
|
const CHEVRON = "\x1B[38;2;128;128;133m";
|
|
7244
7261
|
const TEXT = "\x1B[38;2;240;240;242m";
|
|
7245
|
-
const
|
|
7262
|
+
const RESET = "\x1B[0m";
|
|
7246
7263
|
const rawLines = text.split(`
|
|
7247
7264
|
`);
|
|
7248
7265
|
const wrappedLines = [];
|
|
@@ -7267,7 +7284,7 @@ ${preview}${more}`);
|
|
|
7267
7284
|
const formatted = wrappedLines.map((line, idx) => {
|
|
7268
7285
|
const prefix = idx === 0 ? `${CHEVRON} \u276F ` : `${CHEVRON} `;
|
|
7269
7286
|
const padLen = Math.max(0, contentWidth - line.length);
|
|
7270
|
-
return ` ${BG}${prefix}${TEXT}${line}${" ".repeat(padLen)}${
|
|
7287
|
+
return ` ${BG}${prefix}${TEXT}${line}${" ".repeat(padLen)}${RESET}`;
|
|
7271
7288
|
});
|
|
7272
7289
|
return formatted.join(`
|
|
7273
7290
|
`);
|
|
@@ -7290,8 +7307,25 @@ import readline2 from "readline";
|
|
|
7290
7307
|
import readline from "readline";
|
|
7291
7308
|
var keypressEventsInitialized = false;
|
|
7292
7309
|
var listeners = new Set;
|
|
7310
|
+
var rawModeState = null;
|
|
7311
|
+
function ensureRawMode(active) {
|
|
7312
|
+
if (!process.stdin.isTTY)
|
|
7313
|
+
return;
|
|
7314
|
+
if (rawModeState === active)
|
|
7315
|
+
return;
|
|
7316
|
+
try {
|
|
7317
|
+
process.stdin.setRawMode(active);
|
|
7318
|
+
rawModeState = active;
|
|
7319
|
+
if (active) {
|
|
7320
|
+
process.stdin.resume();
|
|
7321
|
+
}
|
|
7322
|
+
} catch {}
|
|
7323
|
+
}
|
|
7293
7324
|
function initGlobalKeypress() {
|
|
7294
7325
|
if (!keypressEventsInitialized && process.stdin.isTTY) {
|
|
7326
|
+
try {
|
|
7327
|
+
process.stdin.on("error", () => {});
|
|
7328
|
+
} catch {}
|
|
7295
7329
|
readline.emitKeypressEvents(process.stdin);
|
|
7296
7330
|
keypressEventsInitialized = true;
|
|
7297
7331
|
process.stdin.on("keypress", (str, key) => {
|
|
@@ -7368,15 +7402,15 @@ class InteractiveLineEditor {
|
|
|
7368
7402
|
}
|
|
7369
7403
|
async readLine() {
|
|
7370
7404
|
if (!process.stdin.isTTY) {
|
|
7371
|
-
return new Promise((
|
|
7405
|
+
return new Promise((resolve) => {
|
|
7372
7406
|
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
7373
7407
|
rl.question(this.promptSymbol, (answer) => {
|
|
7374
7408
|
rl.close();
|
|
7375
|
-
|
|
7409
|
+
resolve(answer);
|
|
7376
7410
|
});
|
|
7377
7411
|
});
|
|
7378
7412
|
}
|
|
7379
|
-
return new Promise((
|
|
7413
|
+
return new Promise((resolve) => {
|
|
7380
7414
|
let buffer = "";
|
|
7381
7415
|
let cursor = 0;
|
|
7382
7416
|
let selectedIndex = 0;
|
|
@@ -7384,12 +7418,7 @@ class InteractiveLineEditor {
|
|
|
7384
7418
|
let popupDismissed = false;
|
|
7385
7419
|
let lastCursorRowFromTop = 0;
|
|
7386
7420
|
let unsubscribeKeypress = null;
|
|
7387
|
-
|
|
7388
|
-
try {
|
|
7389
|
-
process.stdin.setRawMode(true);
|
|
7390
|
-
} catch {}
|
|
7391
|
-
}
|
|
7392
|
-
process.stdin.resume();
|
|
7421
|
+
ensureRawMode(true);
|
|
7393
7422
|
const getMatchingCommands = () => {
|
|
7394
7423
|
if (!buffer.startsWith("/") || popupDismissed)
|
|
7395
7424
|
return [];
|
|
@@ -7423,7 +7452,7 @@ class InteractiveLineEditor {
|
|
|
7423
7452
|
};
|
|
7424
7453
|
const getRule = () => {
|
|
7425
7454
|
const cols = getTerminalCols();
|
|
7426
|
-
const ruleLen = Math.max(10, cols -
|
|
7455
|
+
const ruleLen = Math.max(10, cols - 6);
|
|
7427
7456
|
return "\u2500".repeat(ruleLen);
|
|
7428
7457
|
};
|
|
7429
7458
|
const ensureVisible = (totalItems, visibleRows) => {
|
|
@@ -7449,11 +7478,12 @@ class InteractiveLineEditor {
|
|
|
7449
7478
|
const redraw = () => {
|
|
7450
7479
|
const termCols = getTerminalCols();
|
|
7451
7480
|
const visiblePromptWidth = this.promptSymbol.replace(/\x1b\[[0-9;]*m/g, "").length;
|
|
7481
|
+
let frame = "";
|
|
7452
7482
|
if (lastCursorRowFromTop > 0) {
|
|
7453
|
-
|
|
7483
|
+
frame += `\x1B[${lastCursorRowFromTop}A`;
|
|
7454
7484
|
}
|
|
7455
|
-
|
|
7456
|
-
|
|
7485
|
+
frame += "\r\x1B[J";
|
|
7486
|
+
frame += `${this.promptSymbol}${buffer}`;
|
|
7457
7487
|
const totalPromptChars = visiblePromptWidth + buffer.length;
|
|
7458
7488
|
const promptRows = Math.max(1, Math.floor(totalPromptChars / termCols) + 1);
|
|
7459
7489
|
const slashMatches = getMatchingCommands();
|
|
@@ -7461,39 +7491,39 @@ class InteractiveLineEditor {
|
|
|
7461
7491
|
const fileMatches = activeFile ? getMatchingFiles(activeFile.query) : [];
|
|
7462
7492
|
let menuRows = 0;
|
|
7463
7493
|
if (buffer.startsWith("/") && !popupDismissed && slashMatches.length > 0) {
|
|
7464
|
-
const BOX_WIDTH = Math.max(20, Math.min(termCols -
|
|
7494
|
+
const BOX_WIDTH = Math.max(20, Math.min(termCols - 6, 120));
|
|
7465
7495
|
const maxVisible = Math.min(slashMatches.length, 7);
|
|
7466
7496
|
ensureVisible(slashMatches.length, maxVisible);
|
|
7467
7497
|
const visibleMatches = slashMatches.slice(scrollTop, scrollTop + maxVisible);
|
|
7468
7498
|
const menuLines = [];
|
|
7469
7499
|
const rule = "\u2500".repeat(BOX_WIDTH);
|
|
7470
|
-
const
|
|
7500
|
+
const RULE_COLOR = "\x1B[38;2;80;80;88m";
|
|
7471
7501
|
const ACTIVE_COLOR = "\x1B[38;2;225;225;225m";
|
|
7472
7502
|
const INACTIVE_COLOR = "\x1B[38;2;139;139;144m";
|
|
7473
|
-
const
|
|
7474
|
-
menuLines.push(` ${
|
|
7503
|
+
const RESET = "\x1B[0m";
|
|
7504
|
+
menuLines.push(` ${RULE_COLOR}${rule}${RESET}`);
|
|
7475
7505
|
const maxDescLen = Math.max(10, BOX_WIDTH - 22);
|
|
7476
7506
|
for (let i = 0;i < visibleMatches.length; i++) {
|
|
7477
7507
|
const cmd = visibleMatches[i];
|
|
7478
7508
|
const actualIdx = scrollTop + i;
|
|
7479
7509
|
const isSelected = actualIdx === selectedIndex;
|
|
7480
|
-
const marker = isSelected ? `${ACTIVE_COLOR}\u276F${
|
|
7510
|
+
const marker = isSelected ? `${ACTIVE_COLOR}\u276F${RESET}` : " ";
|
|
7481
7511
|
const rawName = cmd.name.padEnd(16).slice(0, 16);
|
|
7482
7512
|
const rawDesc = cmd.description.length > maxDescLen ? cmd.description.slice(0, maxDescLen - 3) + "..." : cmd.description;
|
|
7483
7513
|
if (isSelected) {
|
|
7484
|
-
menuLines.push(` ${marker} \x1B[1m${ACTIVE_COLOR}${rawName}${
|
|
7514
|
+
menuLines.push(` ${marker} \x1B[1m${ACTIVE_COLOR}${rawName}${RESET} \x1B[1m${ACTIVE_COLOR}${rawDesc}${RESET}`);
|
|
7485
7515
|
} else {
|
|
7486
|
-
menuLines.push(` ${marker} ${INACTIVE_COLOR}${rawName}${
|
|
7516
|
+
menuLines.push(` ${marker} ${INACTIVE_COLOR}${rawName}${RESET} ${INACTIVE_COLOR}${rawDesc}${RESET}`);
|
|
7487
7517
|
}
|
|
7488
7518
|
}
|
|
7489
|
-
menuLines.push(` ${
|
|
7519
|
+
menuLines.push(` ${RULE_COLOR}${rule}${RESET}`);
|
|
7490
7520
|
for (const line of menuLines) {
|
|
7491
|
-
|
|
7492
|
-
\x1B[2K${line}
|
|
7521
|
+
frame += `
|
|
7522
|
+
\x1B[2K${line}`;
|
|
7493
7523
|
}
|
|
7494
7524
|
menuRows = menuLines.length;
|
|
7495
7525
|
} else if (activeFile && !popupDismissed && fileMatches.length > 0) {
|
|
7496
|
-
const BOX_WIDTH = Math.max(20, Math.min(termCols -
|
|
7526
|
+
const BOX_WIDTH = Math.max(20, Math.min(termCols - 6, 120));
|
|
7497
7527
|
const maxVisible = Math.min(fileMatches.length, 7);
|
|
7498
7528
|
ensureVisible(fileMatches.length, maxVisible);
|
|
7499
7529
|
const visibleMatches = fileMatches.slice(scrollTop, scrollTop + maxVisible);
|
|
@@ -7525,31 +7555,34 @@ class InteractiveLineEditor {
|
|
|
7525
7555
|
menuLines.push(` ${style.dim("\u2502")}${style.dim(footerPadded)}${style.dim("\u2502")}`);
|
|
7526
7556
|
menuLines.push(` ${style.dim("\u2514" + "\u2500".repeat(BOX_WIDTH) + "\u2518")}`);
|
|
7527
7557
|
for (const line of menuLines) {
|
|
7528
|
-
|
|
7529
|
-
\x1B[2K${line}
|
|
7558
|
+
frame += `
|
|
7559
|
+
\x1B[2K${line}`;
|
|
7530
7560
|
}
|
|
7531
7561
|
menuRows = menuLines.length;
|
|
7532
7562
|
} else {
|
|
7533
|
-
const
|
|
7534
|
-
const bottomRule = ` ${
|
|
7563
|
+
const RULE_COLOR = "\x1B[38;2;60;60;68m";
|
|
7564
|
+
const bottomRule = ` ${RULE_COLOR}${getRule()}\x1B[0m`;
|
|
7535
7565
|
const modeLine = this.getModeLine();
|
|
7536
|
-
|
|
7566
|
+
frame += `
|
|
7537
7567
|
\x1B[2K${bottomRule}
|
|
7538
|
-
\x1B[2K${modeLine}
|
|
7568
|
+
\x1B[2K${modeLine}`;
|
|
7539
7569
|
menuRows = 2;
|
|
7540
7570
|
}
|
|
7541
7571
|
const cursorCharsFromTop = visiblePromptWidth + cursor;
|
|
7542
7572
|
const cursorRow = Math.floor(cursorCharsFromTop / termCols);
|
|
7543
7573
|
const cursorCol = cursorCharsFromTop % termCols;
|
|
7544
|
-
const moveUpRows = promptRows - 1 - cursorRow + menuRows;
|
|
7574
|
+
const moveUpRows = Math.max(0, promptRows - 1 - cursorRow + menuRows);
|
|
7545
7575
|
if (moveUpRows > 0) {
|
|
7546
|
-
|
|
7576
|
+
frame += `\x1B[${moveUpRows}A`;
|
|
7547
7577
|
}
|
|
7548
|
-
|
|
7578
|
+
frame += "\r";
|
|
7549
7579
|
if (cursorCol > 0) {
|
|
7550
|
-
|
|
7580
|
+
frame += `\x1B[${cursorCol}C`;
|
|
7551
7581
|
}
|
|
7552
7582
|
lastCursorRowFromTop = cursorRow;
|
|
7583
|
+
try {
|
|
7584
|
+
process.stdout.write(frame);
|
|
7585
|
+
} catch {}
|
|
7553
7586
|
};
|
|
7554
7587
|
const onResize = () => {
|
|
7555
7588
|
redraw();
|
|
@@ -7565,24 +7598,24 @@ class InteractiveLineEditor {
|
|
|
7565
7598
|
unsubscribeKeypress();
|
|
7566
7599
|
unsubscribeKeypress = null;
|
|
7567
7600
|
}
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
process.stdin.setRawMode(false);
|
|
7571
|
-
} catch {}
|
|
7572
|
-
}
|
|
7601
|
+
ensureRawMode(false);
|
|
7602
|
+
let cleanupFrame = "";
|
|
7573
7603
|
if (lastCursorRowFromTop > 0) {
|
|
7574
|
-
|
|
7604
|
+
cleanupFrame += `\x1B[${lastCursorRowFromTop}A`;
|
|
7575
7605
|
}
|
|
7576
|
-
|
|
7606
|
+
cleanupFrame += "\r\x1B[J";
|
|
7577
7607
|
if (result.trim().length > 0 && !result.startsWith("/")) {
|
|
7578
|
-
|
|
7608
|
+
cleanupFrame += `${CliFormatter.formatClaudeUserPrompt(result)}
|
|
7579
7609
|
|
|
7580
|
-
|
|
7610
|
+
`;
|
|
7581
7611
|
} else {
|
|
7582
|
-
|
|
7583
|
-
|
|
7612
|
+
cleanupFrame += `
|
|
7613
|
+
`;
|
|
7584
7614
|
}
|
|
7585
|
-
|
|
7615
|
+
try {
|
|
7616
|
+
process.stdout.write(cleanupFrame);
|
|
7617
|
+
} catch {}
|
|
7618
|
+
resolve(result);
|
|
7586
7619
|
};
|
|
7587
7620
|
const onKeypress = (_str, key) => {
|
|
7588
7621
|
if (!key)
|
|
@@ -7770,31 +7803,28 @@ async function promptChoice(config) {
|
|
|
7770
7803
|
const def = choices[defaultIndex] || choices[0];
|
|
7771
7804
|
return def ? def.value : "";
|
|
7772
7805
|
}
|
|
7773
|
-
return new Promise((
|
|
7806
|
+
return new Promise((resolve) => {
|
|
7774
7807
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7775
|
-
const promptText = ` ${message} (${choices.map((
|
|
7808
|
+
const promptText = ` ${message} (${choices.map((c2) => `[${c2.key}] ${c2.label}`).join(", ")}): `;
|
|
7776
7809
|
rl.question(promptText, (answer) => {
|
|
7777
7810
|
rl.close();
|
|
7778
7811
|
const trimmed = answer.trim().toLowerCase();
|
|
7779
|
-
const match = choices.find((
|
|
7812
|
+
const match = choices.find((c2) => c2.key.toLowerCase() === trimmed);
|
|
7780
7813
|
if (match) {
|
|
7781
|
-
|
|
7814
|
+
resolve(match.value);
|
|
7782
7815
|
} else {
|
|
7783
7816
|
const def = choices[defaultIndex] || choices[0];
|
|
7784
|
-
|
|
7817
|
+
resolve(def ? def.value : "");
|
|
7785
7818
|
}
|
|
7786
7819
|
});
|
|
7787
7820
|
});
|
|
7788
7821
|
}
|
|
7789
|
-
return new Promise((
|
|
7822
|
+
return new Promise((resolve) => {
|
|
7790
7823
|
let selectedIndex = defaultIndex;
|
|
7791
7824
|
if (selectedIndex < 0 || selectedIndex >= choices.length)
|
|
7792
7825
|
selectedIndex = 0;
|
|
7793
|
-
const wasRaw = process.stdin.isRaw;
|
|
7794
|
-
|
|
7795
|
-
process.stdin.setRawMode(true);
|
|
7796
|
-
} catch {}
|
|
7797
|
-
process.stdin.resume();
|
|
7826
|
+
const wasRaw = process.stdin.isRaw ?? false;
|
|
7827
|
+
ensureRawMode(true);
|
|
7798
7828
|
const render = () => {
|
|
7799
7829
|
const parts = choices.map((choice, idx) => {
|
|
7800
7830
|
const isSelected = idx === selectedIndex;
|
|
@@ -7813,12 +7843,10 @@ async function promptChoice(config) {
|
|
|
7813
7843
|
unsubscribe();
|
|
7814
7844
|
unsubscribe = null;
|
|
7815
7845
|
}
|
|
7816
|
-
|
|
7817
|
-
process.stdin.setRawMode(wasRaw ?? false);
|
|
7818
|
-
} catch {}
|
|
7846
|
+
ensureRawMode(wasRaw);
|
|
7819
7847
|
process.stdout.write(`\r\x1B[1A\r\x1B[2K ${style.bold(message)} ${style.cyan(`[${confirmedChoice.key}] ${confirmedChoice.label}`)}
|
|
7820
7848
|
\r\x1B[2K`);
|
|
7821
|
-
|
|
7849
|
+
resolve(confirmedChoice.value);
|
|
7822
7850
|
};
|
|
7823
7851
|
const onKeypress = (_str, key) => {
|
|
7824
7852
|
if (!key)
|
|
@@ -7840,7 +7868,7 @@ async function promptChoice(config) {
|
|
|
7840
7868
|
}
|
|
7841
7869
|
const char = _str ? _str.toLowerCase() : key.name ? key.name.toLowerCase() : "";
|
|
7842
7870
|
if (char) {
|
|
7843
|
-
const directMatch = choices.find((
|
|
7871
|
+
const directMatch = choices.find((c2) => c2.key.toLowerCase() === char);
|
|
7844
7872
|
if (directMatch) {
|
|
7845
7873
|
cleanup(directMatch);
|
|
7846
7874
|
return;
|
|
@@ -7863,34 +7891,31 @@ async function promptToolApproval(params) {
|
|
|
7863
7891
|
const FG = "\x1B[38;2;225;225;225m";
|
|
7864
7892
|
const MUTED = "\x1B[38;2;139;139;144m";
|
|
7865
7893
|
const DIM = "\x1B[38;2;108;108;108m";
|
|
7866
|
-
const
|
|
7894
|
+
const RESET = "\x1B[0m";
|
|
7867
7895
|
console.log();
|
|
7868
|
-
console.log(` ${BORDER} ${FG}${title}${
|
|
7869
|
-
console.log(` ${BORDER} ${MUTED}${command}${
|
|
7896
|
+
console.log(` ${BORDER} ${FG}${title}${RESET}`);
|
|
7897
|
+
console.log(` ${BORDER} ${MUTED}${command}${RESET}`);
|
|
7870
7898
|
console.log(` ${BORDER}`);
|
|
7871
7899
|
const renderCard = (selected) => {
|
|
7872
7900
|
for (let i = 0;i < options.length; i++) {
|
|
7873
7901
|
const opt = options[i];
|
|
7874
7902
|
const active = i === selected;
|
|
7875
|
-
const radio = active ? `${FG}(\u25CF)${
|
|
7876
|
-
const num = `${FG}${i + 1}${
|
|
7877
|
-
const label = active ? `\x1B[1m${FG}${opt.label}${
|
|
7903
|
+
const radio = active ? `${FG}(\u25CF)${RESET}` : `${DIM}(\u25CB)${RESET}`;
|
|
7904
|
+
const num = `${FG}${i + 1}${RESET}`;
|
|
7905
|
+
const label = active ? `\x1B[1m${FG}${opt.label}${RESET}` : `${MUTED}${opt.label}${RESET}`;
|
|
7878
7906
|
console.log(` ${BORDER} ${num} ${radio} ${label}`);
|
|
7879
7907
|
}
|
|
7880
7908
|
console.log(` ${BORDER}`);
|
|
7881
|
-
console.log(` ${FG}${selected + 1}/${options.length}${
|
|
7909
|
+
console.log(` ${FG}${selected + 1}/${options.length}${RESET}${DIM}:select \u2502 ${FG}Ctrl+o${RESET}${DIM}:yolo \u2502 ${FG}Ctrl+c${RESET}${DIM}:cancel${RESET}`);
|
|
7882
7910
|
};
|
|
7883
7911
|
if (!process.stdin.isTTY || false || !process.stdin.readable) {
|
|
7884
7912
|
renderCard(1);
|
|
7885
7913
|
return "yes";
|
|
7886
7914
|
}
|
|
7887
|
-
return new Promise((
|
|
7915
|
+
return new Promise((resolve) => {
|
|
7888
7916
|
let selectedIndex = 1;
|
|
7889
|
-
const wasRaw = process.stdin.isRaw;
|
|
7890
|
-
|
|
7891
|
-
process.stdin.setRawMode(true);
|
|
7892
|
-
} catch {}
|
|
7893
|
-
process.stdin.resume();
|
|
7917
|
+
const wasRaw = process.stdin.isRaw ?? false;
|
|
7918
|
+
ensureRawMode(true);
|
|
7894
7919
|
const render = () => {
|
|
7895
7920
|
renderCard(selectedIndex);
|
|
7896
7921
|
};
|
|
@@ -7900,11 +7925,9 @@ async function promptToolApproval(params) {
|
|
|
7900
7925
|
unsubscribe();
|
|
7901
7926
|
unsubscribe = null;
|
|
7902
7927
|
}
|
|
7903
|
-
|
|
7904
|
-
process.stdin.setRawMode(wasRaw ?? false);
|
|
7905
|
-
} catch {}
|
|
7928
|
+
ensureRawMode(wasRaw);
|
|
7906
7929
|
console.log();
|
|
7907
|
-
|
|
7930
|
+
resolve(val);
|
|
7908
7931
|
};
|
|
7909
7932
|
const onKeypress = (_str, key) => {
|
|
7910
7933
|
if (!key)
|
|
@@ -7987,7 +8010,7 @@ async function promptUserQuestion(params) {
|
|
|
7987
8010
|
if (!process.stdin.isTTY || false || !process.stdin.readable) {
|
|
7988
8011
|
return options[0] || "yes";
|
|
7989
8012
|
}
|
|
7990
|
-
return new Promise((
|
|
8013
|
+
return new Promise((resolve) => {
|
|
7991
8014
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7992
8015
|
const promptLabel = options.length > 0 ? `Select [1-${options.length}] or type custom response: ` : `Your response: `;
|
|
7993
8016
|
rl.question(` ${style.bold(promptLabel)}`, (answer) => {
|
|
@@ -7997,7 +8020,7 @@ async function promptUserQuestion(params) {
|
|
|
7997
8020
|
const fallback = options[0] || "";
|
|
7998
8021
|
console.log(style.dim(` \u21B3 Default: ${fallback || "(empty)"}
|
|
7999
8022
|
`));
|
|
8000
|
-
|
|
8023
|
+
resolve(fallback);
|
|
8001
8024
|
return;
|
|
8002
8025
|
}
|
|
8003
8026
|
const num = parseInt(trimmed, 10);
|
|
@@ -8005,26 +8028,26 @@ async function promptUserQuestion(params) {
|
|
|
8005
8028
|
const picked = options[num - 1];
|
|
8006
8029
|
console.log(style.green(` \u2714 Selected: ${picked}
|
|
8007
8030
|
`));
|
|
8008
|
-
|
|
8031
|
+
resolve(picked);
|
|
8009
8032
|
return;
|
|
8010
8033
|
}
|
|
8011
8034
|
if (options.length === 2) {
|
|
8012
8035
|
if (/^(y|yes)$/i.test(trimmed)) {
|
|
8013
8036
|
console.log(style.green(` \u2714 Selected: ${options[0]}
|
|
8014
8037
|
`));
|
|
8015
|
-
|
|
8038
|
+
resolve(options[0]);
|
|
8016
8039
|
return;
|
|
8017
8040
|
}
|
|
8018
8041
|
if (/^(n|no)$/i.test(trimmed)) {
|
|
8019
8042
|
console.log(style.green(` \u2714 Selected: ${options[1]}
|
|
8020
8043
|
`));
|
|
8021
|
-
|
|
8044
|
+
resolve(options[1]);
|
|
8022
8045
|
return;
|
|
8023
8046
|
}
|
|
8024
8047
|
}
|
|
8025
8048
|
console.log(style.green(` \u2714 Answer: ${trimmed}
|
|
8026
8049
|
`));
|
|
8027
|
-
|
|
8050
|
+
resolve(trimmed);
|
|
8028
8051
|
});
|
|
8029
8052
|
});
|
|
8030
8053
|
}
|
|
@@ -8053,15 +8076,12 @@ async function promptInteractiveList(config) {
|
|
|
8053
8076
|
`);
|
|
8054
8077
|
return { selectedIndex: -1, action: "close" };
|
|
8055
8078
|
}
|
|
8056
|
-
return new Promise((
|
|
8079
|
+
return new Promise((resolve) => {
|
|
8057
8080
|
let selectedIndex = Math.max(0, Math.min(defaultIndex, items.length - 1));
|
|
8058
8081
|
let scrollTop = 0;
|
|
8059
8082
|
let renderedLines = 0;
|
|
8060
|
-
const wasRaw = process.stdin.isRaw;
|
|
8061
|
-
|
|
8062
|
-
process.stdin.setRawMode(true);
|
|
8063
|
-
} catch {}
|
|
8064
|
-
process.stdin.resume();
|
|
8083
|
+
const wasRaw = process.stdin.isRaw ?? false;
|
|
8084
|
+
ensureRawMode(true);
|
|
8065
8085
|
process.stdout.write("\x1B[?25l");
|
|
8066
8086
|
const BOX_WIDTH = Math.min(process.stdout.columns ?? 80, 76);
|
|
8067
8087
|
const ensureVisible = () => {
|
|
@@ -8145,10 +8165,8 @@ async function promptInteractiveList(config) {
|
|
|
8145
8165
|
unsubscribe();
|
|
8146
8166
|
unsubscribe = null;
|
|
8147
8167
|
}
|
|
8148
|
-
|
|
8149
|
-
|
|
8150
|
-
} catch {}
|
|
8151
|
-
resolve18(res);
|
|
8168
|
+
ensureRawMode(wasRaw);
|
|
8169
|
+
resolve(res);
|
|
8152
8170
|
};
|
|
8153
8171
|
const onKeypress = async (_str, key) => {
|
|
8154
8172
|
if (!key)
|
|
@@ -8859,52 +8877,52 @@ function runProjectInit(options = {}) {
|
|
|
8859
8877
|
};
|
|
8860
8878
|
}
|
|
8861
8879
|
function printInitSummary(result) {
|
|
8862
|
-
const
|
|
8880
|
+
const BOLD = "\x1B[1m";
|
|
8863
8881
|
const GREEN = "\x1B[38;2;120;220;140m";
|
|
8864
8882
|
const BRAND = "\x1B[38;2;217;119;87m";
|
|
8865
8883
|
const CYAN = "\x1B[38;2;125;207;255m";
|
|
8866
|
-
const
|
|
8867
|
-
const
|
|
8868
|
-
const
|
|
8884
|
+
const GRAY = "\x1B[38;2;148;148;148m";
|
|
8885
|
+
const WHITE = "\x1B[38;2;240;240;245m";
|
|
8886
|
+
const RESET = "\x1B[0m";
|
|
8869
8887
|
const { analysis, filePath, overwritten } = result;
|
|
8870
8888
|
console.log("");
|
|
8871
|
-
console.log(` ${GREEN}\u2713${
|
|
8872
|
-
console.log(` ${
|
|
8889
|
+
console.log(` ${GREEN}\u2713${RESET} ${BOLD}${WHITE}${overwritten ? "Updated" : "Created"} Project Instructions Document${RESET}`);
|
|
8890
|
+
console.log(` ${GRAY}Path: ${CYAN}${filePath}${RESET}`);
|
|
8873
8891
|
console.log("");
|
|
8874
|
-
console.log(` ${BRAND}\u250C\u2500 ${
|
|
8875
|
-
console.log(` ${BRAND}\u2502${
|
|
8892
|
+
console.log(` ${BRAND}\u250C\u2500 ${BOLD}Project Overview${RESET} ${BRAND}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510${RESET}`);
|
|
8893
|
+
console.log(` ${BRAND}\u2502${RESET} ${BOLD}Project:${RESET} ${WHITE}${analysis.projectName}${RESET}`);
|
|
8876
8894
|
if (analysis.languages.length > 0) {
|
|
8877
|
-
console.log(` ${BRAND}\u2502${
|
|
8895
|
+
console.log(` ${BRAND}\u2502${RESET} ${BOLD}Languages:${RESET} ${analysis.languages.join(", ")}`);
|
|
8878
8896
|
}
|
|
8879
8897
|
if (analysis.packageManager) {
|
|
8880
|
-
console.log(` ${BRAND}\u2502${
|
|
8898
|
+
console.log(` ${BRAND}\u2502${RESET} ${BOLD}Package Manager:${RESET} ${analysis.packageManager}`);
|
|
8881
8899
|
}
|
|
8882
8900
|
if (analysis.frameworks.length > 0) {
|
|
8883
|
-
console.log(` ${BRAND}\u2502${
|
|
8901
|
+
console.log(` ${BRAND}\u2502${RESET} ${BOLD}Frameworks:${RESET} ${analysis.frameworks.join(", ")}`);
|
|
8884
8902
|
}
|
|
8885
|
-
console.log(` ${BRAND}\u2502${
|
|
8886
|
-
console.log(` ${BRAND}\u2502${
|
|
8903
|
+
console.log(` ${BRAND}\u2502${RESET}`);
|
|
8904
|
+
console.log(` ${BRAND}\u2502${RESET} ${BOLD}Detected Commands:${RESET}`);
|
|
8887
8905
|
if (analysis.commands.build) {
|
|
8888
|
-
console.log(` ${BRAND}\u2502${
|
|
8906
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 Build: ${CYAN}${analysis.commands.build}${RESET}`);
|
|
8889
8907
|
}
|
|
8890
8908
|
if (analysis.commands.test) {
|
|
8891
|
-
console.log(` ${BRAND}\u2502${
|
|
8909
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 Test: ${GREEN}${analysis.commands.test}${RESET}`);
|
|
8892
8910
|
}
|
|
8893
8911
|
if (analysis.commands.typecheck) {
|
|
8894
|
-
console.log(` ${BRAND}\u2502${
|
|
8912
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 Typecheck: ${CYAN}${analysis.commands.typecheck}${RESET}`);
|
|
8895
8913
|
}
|
|
8896
8914
|
if (analysis.commands.lint) {
|
|
8897
|
-
console.log(` ${BRAND}\u2502${
|
|
8915
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 Lint: ${CYAN}${analysis.commands.lint}${RESET}`);
|
|
8898
8916
|
}
|
|
8899
8917
|
if (analysis.commands.dev) {
|
|
8900
|
-
console.log(` ${BRAND}\u2502${
|
|
8918
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 Dev: ${CYAN}${analysis.commands.dev}${RESET}`);
|
|
8901
8919
|
}
|
|
8902
8920
|
if (Object.keys(analysis.commands).length === 0) {
|
|
8903
|
-
console.log(` ${BRAND}\u2502${
|
|
8921
|
+
console.log(` ${BRAND}\u2502${RESET} \u2022 ${GRAY}(No standard commands detected)${RESET}`);
|
|
8904
8922
|
}
|
|
8905
|
-
console.log(` ${BRAND}\u2502${
|
|
8906
|
-
console.log(` ${BRAND}\u2502${
|
|
8907
|
-
console.log(` ${BRAND}\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${
|
|
8923
|
+
console.log(` ${BRAND}\u2502${RESET}`);
|
|
8924
|
+
console.log(` ${BRAND}\u2502${RESET} ${GRAY}AI agents will now automatically load AGENTS.md on every session.${RESET}`);
|
|
8925
|
+
console.log(` ${BRAND}\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518${RESET}`);
|
|
8908
8926
|
console.log("");
|
|
8909
8927
|
}
|
|
8910
8928
|
// src/cli/commands.ts
|
|
@@ -9090,10 +9108,10 @@ async function printHelp(ctx) {
|
|
|
9090
9108
|
console.log();
|
|
9091
9109
|
return;
|
|
9092
9110
|
}
|
|
9093
|
-
const items = AVAILABLE_SLASH_COMMANDS.map((
|
|
9094
|
-
id:
|
|
9095
|
-
label:
|
|
9096
|
-
description:
|
|
9111
|
+
const items = AVAILABLE_SLASH_COMMANDS.map((c) => ({
|
|
9112
|
+
id: c.name,
|
|
9113
|
+
label: c.name,
|
|
9114
|
+
description: c.description
|
|
9097
9115
|
}));
|
|
9098
9116
|
const res = await promptInteractiveList({
|
|
9099
9117
|
title: "\u26A1 Slash Commands Palette",
|
|
@@ -9125,9 +9143,9 @@ async function handleReasoningCommand(ctx, arg) {
|
|
|
9125
9143
|
} else {
|
|
9126
9144
|
ctx.repl.showReasoning = !ctx.repl.showReasoning;
|
|
9127
9145
|
}
|
|
9128
|
-
const
|
|
9146
|
+
const stateStr = ctx.repl.showReasoning ? style.green("Visible") : style.yellow("Hidden (default)");
|
|
9129
9147
|
console.log(`
|
|
9130
|
-
Reasoning display: [${
|
|
9148
|
+
Reasoning display: [${stateStr}]
|
|
9131
9149
|
`);
|
|
9132
9150
|
return;
|
|
9133
9151
|
}
|
|
@@ -9166,14 +9184,14 @@ async function handleModelSelection(ctx, modelArg) {
|
|
|
9166
9184
|
const headers = {};
|
|
9167
9185
|
if (apiKey)
|
|
9168
9186
|
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
9169
|
-
const
|
|
9170
|
-
const timeout = setTimeout(() =>
|
|
9171
|
-
const
|
|
9187
|
+
const controller = new AbortController;
|
|
9188
|
+
const timeout = setTimeout(() => controller.abort(), 1500);
|
|
9189
|
+
const res = await fetch(`${baseUrl}/models`, {
|
|
9172
9190
|
headers,
|
|
9173
|
-
signal:
|
|
9191
|
+
signal: controller.signal
|
|
9174
9192
|
}).finally(() => clearTimeout(timeout));
|
|
9175
|
-
if (
|
|
9176
|
-
const data = await
|
|
9193
|
+
if (res.ok) {
|
|
9194
|
+
const data = await res.json();
|
|
9177
9195
|
if (Array.isArray(data.data) && data.data.length > 0) {
|
|
9178
9196
|
models = data.data;
|
|
9179
9197
|
}
|
|
@@ -9262,8 +9280,8 @@ Direct login failed: ${directErr instanceof Error ? directErr.message : String(d
|
|
|
9262
9280
|
}
|
|
9263
9281
|
}
|
|
9264
9282
|
function printWhoami() {
|
|
9265
|
-
const
|
|
9266
|
-
const creds =
|
|
9283
|
+
const store = new CredentialsStore;
|
|
9284
|
+
const creds = store.load();
|
|
9267
9285
|
console.log();
|
|
9268
9286
|
if (!creds || !creds.accessToken) {
|
|
9269
9287
|
console.log(style.yellow(" Not logged in."));
|
|
@@ -9336,11 +9354,11 @@ async function handleRolesCommand(ctx, roleArg) {
|
|
|
9336
9354
|
return;
|
|
9337
9355
|
}
|
|
9338
9356
|
const items = roles.map((r) => {
|
|
9339
|
-
const
|
|
9357
|
+
const tools = r.allowedToolNames ? r.allowedToolNames.join(", ") : "all tools";
|
|
9340
9358
|
return {
|
|
9341
9359
|
id: r.name,
|
|
9342
9360
|
label: r.name,
|
|
9343
|
-
description: `${r.description} \xB7 [${
|
|
9361
|
+
description: `${r.description} \xB7 [${tools}]`,
|
|
9344
9362
|
badge: r.name === "default" ? "primary" : undefined
|
|
9345
9363
|
};
|
|
9346
9364
|
});
|
|
@@ -9360,12 +9378,12 @@ async function handleRolesCommand(ctx, roleArg) {
|
|
|
9360
9378
|
function displayRoleDetails(role) {
|
|
9361
9379
|
const boxWidth = Math.min(process.stdout.columns ?? 80, 75);
|
|
9362
9380
|
const border = "\u2500".repeat(Math.max(10, boxWidth - role.name.length - 16));
|
|
9363
|
-
const
|
|
9381
|
+
const tools = role.allowedToolNames ? role.allowedToolNames.join(", ") : "all tools";
|
|
9364
9382
|
const nicks = role.nicknameCandidates ? role.nicknameCandidates.join(", ") : "none";
|
|
9365
9383
|
console.log();
|
|
9366
9384
|
console.log(` ${style.cyan("\u250C\u2500\u2500")} ${style.bold(`Role: ${role.name}`)} ${style.cyan(border)}`);
|
|
9367
9385
|
console.log(` ${style.cyan("\u2502")} ${style.bold("Description:")} ${role.description}`);
|
|
9368
|
-
console.log(` ${style.cyan("\u2502")} ${style.bold("Allowed Tools:")} ${style.dim(`[${
|
|
9386
|
+
console.log(` ${style.cyan("\u2502")} ${style.bold("Allowed Tools:")} ${style.dim(`[${tools}]`)}`);
|
|
9369
9387
|
console.log(` ${style.cyan("\u2502")} ${style.bold("Nicknames:")} ${style.dim(`[${nicks}]`)}`);
|
|
9370
9388
|
console.log(` ${style.cyan("\u2502")}`);
|
|
9371
9389
|
console.log(` ${style.cyan("\u2502")} ${style.bold("System Prompt:")}`);
|
|
@@ -9383,9 +9401,9 @@ function printRoles(ctx) {
|
|
|
9383
9401
|
console.log();
|
|
9384
9402
|
console.log(style.bold(" Configured Agent Roles:"));
|
|
9385
9403
|
for (const r of roles) {
|
|
9386
|
-
const
|
|
9404
|
+
const tools = r.allowedToolNames ? r.allowedToolNames.join(", ") : "all tools";
|
|
9387
9405
|
console.log(` \u2022 ${style.cyan(r.name)}: ${r.description}`);
|
|
9388
|
-
console.log(` ${style.dim(`Tools: [${
|
|
9406
|
+
console.log(` ${style.dim(`Tools: [${tools}]`)}`);
|
|
9389
9407
|
if (r.nicknameCandidates) {
|
|
9390
9408
|
console.log(` ${style.dim(`Nicknames: [${r.nicknameCandidates.join(", ")}]`)}`);
|
|
9391
9409
|
}
|
|
@@ -9560,19 +9578,19 @@ async function handleSkillsCommand(ctx, args) {
|
|
|
9560
9578
|
`);
|
|
9561
9579
|
}
|
|
9562
9580
|
function printMemories(ctx) {
|
|
9563
|
-
const
|
|
9564
|
-
if (!
|
|
9581
|
+
const store = ctx.memoryStore;
|
|
9582
|
+
if (!store) {
|
|
9565
9583
|
console.log(style.yellow(`
|
|
9566
9584
|
Memory store not active.
|
|
9567
9585
|
`));
|
|
9568
9586
|
return;
|
|
9569
9587
|
}
|
|
9570
9588
|
const cwd = ctx.session.cwd;
|
|
9571
|
-
const memoryDir =
|
|
9572
|
-
const topics =
|
|
9573
|
-
const indexContent =
|
|
9574
|
-
const
|
|
9575
|
-
const
|
|
9589
|
+
const memoryDir = store.getProjectMemoryDir(cwd);
|
|
9590
|
+
const topics = store.listProjectMemories(cwd);
|
|
9591
|
+
const indexContent = store.loadMemoryIndex(cwd);
|
|
9592
|
+
const BOLD = "\x1B[1m";
|
|
9593
|
+
const RESET = "\x1B[0m";
|
|
9576
9594
|
const DIM = "\x1B[2m";
|
|
9577
9595
|
const CYAN = "\x1B[38;2;120;190;255m";
|
|
9578
9596
|
const GREEN = "\x1B[38;2;140;220;140m";
|
|
@@ -9594,19 +9612,19 @@ function printMemories(ctx) {
|
|
|
9594
9612
|
}
|
|
9595
9613
|
};
|
|
9596
9614
|
console.log();
|
|
9597
|
-
console.log(` ${
|
|
9598
|
-
console.log(` ${DIM}Directory: ${memoryDir}${
|
|
9599
|
-
console.log(` ${DIM}Status: ${GREEN}Active (Loaded into turn context \u2264200 lines)${
|
|
9615
|
+
console.log(` ${BOLD}\uD83E\uDDE0 Project Auto-Memory Bank${RESET}`);
|
|
9616
|
+
console.log(` ${DIM}Directory: ${memoryDir}${RESET}`);
|
|
9617
|
+
console.log(` ${DIM}Status: ${GREEN}Active (Loaded into turn context \u2264200 lines)${RESET}`);
|
|
9600
9618
|
console.log();
|
|
9601
9619
|
if (topics.length === 0) {
|
|
9602
|
-
console.log(` ${DIM}No persistent topic memories saved for this project yet.${
|
|
9603
|
-
console.log(` ${DIM}As you work, Pikaa automatically records user preferences, feedback, and project context.${
|
|
9620
|
+
console.log(` ${DIM}No persistent topic memories saved for this project yet.${RESET}`);
|
|
9621
|
+
console.log(` ${DIM}As you work, Pikaa automatically records user preferences, feedback, and project context.${RESET}`);
|
|
9604
9622
|
} else {
|
|
9605
|
-
console.log(` ${
|
|
9623
|
+
console.log(` ${BOLD}Learned Memory Topics (${topics.length}):${RESET}`);
|
|
9606
9624
|
for (const t of topics) {
|
|
9607
9625
|
const color = getCategoryColor(t.type);
|
|
9608
|
-
console.log(` \u2022 ${color}[${t.type}]${
|
|
9609
|
-
`)[0]}${
|
|
9626
|
+
console.log(` \u2022 ${color}[${t.type}]${RESET} ${BOLD}${t.name}${RESET}: ${DIM}${t.description || t.content.split(`
|
|
9627
|
+
`)[0]}${RESET}`);
|
|
9610
9628
|
}
|
|
9611
9629
|
}
|
|
9612
9630
|
console.log();
|
|
@@ -10038,51 +10056,51 @@ async function handleMcpCommand(ctx, args) {
|
|
|
10038
10056
|
}
|
|
10039
10057
|
function printReleaseNotes() {
|
|
10040
10058
|
const version = getCliVersion({ prefix: true });
|
|
10041
|
-
const
|
|
10042
|
-
const
|
|
10043
|
-
const
|
|
10044
|
-
const
|
|
10045
|
-
const
|
|
10046
|
-
function
|
|
10059
|
+
const ROSE = "\x1B[38;2;205;105;74m";
|
|
10060
|
+
const WHITE = "\x1B[38;2;255;255;255m";
|
|
10061
|
+
const GRAY = "\x1B[38;2;148;148;148m";
|
|
10062
|
+
const BOLD = "\x1B[1m";
|
|
10063
|
+
const RESET = "\x1B[0m";
|
|
10064
|
+
function stripAnsi(str) {
|
|
10047
10065
|
return str.replace(/\x1b\[[0-9;]*m/g, "");
|
|
10048
10066
|
}
|
|
10049
10067
|
function padLine(str, width) {
|
|
10050
|
-
const vis =
|
|
10068
|
+
const vis = stripAnsi(str);
|
|
10051
10069
|
return str + " ".repeat(Math.max(0, width - vis.length));
|
|
10052
10070
|
}
|
|
10053
10071
|
const totalInnerWidth = 74;
|
|
10054
10072
|
const contentLines = [
|
|
10055
10073
|
"",
|
|
10056
|
-
" " +
|
|
10057
|
-
" " +
|
|
10074
|
+
" " + BOLD + WHITE + "\uD83D\uDE80 What's New in " + version + " (Latest)" + RESET,
|
|
10075
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Persistent Default AI Model" + RESET + ": Switch via " + ROSE + "/model" + RESET + " and save",
|
|
10058
10076
|
" preference across sessions in ~/.pikaa/credentials.json.",
|
|
10059
|
-
" " +
|
|
10077
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Real-time Git Branch Detection" + RESET + ": Header displays active branch",
|
|
10060
10078
|
" (\uE0A0 main) alongside user subscription tier (Groupy Pro / Max).",
|
|
10061
|
-
" " +
|
|
10079
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Claude Code Terminal UI Parity" + RESET + ": Authentic pixel emblem, fieldset",
|
|
10062
10080
|
" header box, user prompt badge pills, and streaming responses.",
|
|
10063
|
-
" " +
|
|
10081
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Autonomous Sub-Agents & Roles" + RESET + ": Multi-agent spawner with roles",
|
|
10064
10082
|
" (Pikaa, Heca, Bankli, Moli) and cryptographic action provenance.",
|
|
10065
|
-
" " +
|
|
10083
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Model Context Protocol (MCP)" + RESET + ": Connect stdio & SSE servers with",
|
|
10066
10084
|
" multi-config auto-discovery, tool hot-reloads, and ping tests.",
|
|
10067
|
-
" " +
|
|
10085
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Isolated Git Worktrees" + RESET + ": Run risky tasks in isolated worktree",
|
|
10068
10086
|
" branches without dirtying your main workspace (/worktrees).",
|
|
10069
|
-
" " +
|
|
10087
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + BOLD + "Strix-Inspired Security Auditor" + RESET + ": Automated scanner for exposed",
|
|
10070
10088
|
" secrets, eval(), and SQL injection vulnerabilities (/security).",
|
|
10071
10089
|
"",
|
|
10072
|
-
" " +
|
|
10073
|
-
" " +
|
|
10074
|
-
" " +
|
|
10075
|
-
" " +
|
|
10090
|
+
" " + BOLD + WHITE + "\uD83D\uDCE6 Previous Highlights (v0.3.0 - v0.3.1)" + RESET,
|
|
10091
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + "Unified CI/CD Pipeline" + RESET + ": Single automated release packager on merge.",
|
|
10092
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + "Interactive Question Flow" + RESET + ": Selectable multiple-choice dialogs.",
|
|
10093
|
+
" " + ROSE + "\u2022" + RESET + " " + WHITE + "Persistent Memory Store" + RESET + ": Learned user preferences in markdown.",
|
|
10076
10094
|
"",
|
|
10077
|
-
" " +
|
|
10095
|
+
" " + GRAY + "Tip: Type " + ROSE + "/help" + GRAY + " to view all available commands." + RESET
|
|
10078
10096
|
];
|
|
10079
10097
|
const topDashes = Math.max(2, totalInnerWidth - (15 + version.length + 14));
|
|
10080
10098
|
console.log("");
|
|
10081
|
-
console.log(" " +
|
|
10099
|
+
console.log(" " + ROSE + "\u250C\u2500 " + ROSE + BOLD + "Groupy Code Release Notes" + RESET + " " + GRAY + version + RESET + " " + ROSE + "\u2500".repeat(topDashes) + "\u2510" + RESET);
|
|
10082
10100
|
for (const line of contentLines) {
|
|
10083
|
-
console.log(" " +
|
|
10101
|
+
console.log(" " + ROSE + "\u2502" + RESET + padLine(line, totalInnerWidth) + ROSE + "\u2502" + RESET);
|
|
10084
10102
|
}
|
|
10085
|
-
console.log(" " +
|
|
10103
|
+
console.log(" " + ROSE + "\u2514" + "\u2500".repeat(totalInnerWidth) + "\u2518" + RESET);
|
|
10086
10104
|
console.log("");
|
|
10087
10105
|
}
|
|
10088
10106
|
async function handleModeCommand(ctx, arg) {
|
|
@@ -10463,10 +10481,10 @@ function getUpdateCachePath() {
|
|
|
10463
10481
|
async function fetchLatestNpmVersion(packageName, timeoutMs = 1500) {
|
|
10464
10482
|
const url = `https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`;
|
|
10465
10483
|
try {
|
|
10466
|
-
const
|
|
10467
|
-
const timeout = setTimeout(() =>
|
|
10484
|
+
const controller = new AbortController;
|
|
10485
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
10468
10486
|
const response = await fetch(url, {
|
|
10469
|
-
signal:
|
|
10487
|
+
signal: controller.signal,
|
|
10470
10488
|
headers: {
|
|
10471
10489
|
Accept: "application/json",
|
|
10472
10490
|
"User-Agent": "pikaa-update-checker"
|
|
@@ -10696,9 +10714,9 @@ class CliRepl {
|
|
|
10696
10714
|
filesModified: Array.from(this.turnFilesModified)
|
|
10697
10715
|
});
|
|
10698
10716
|
if (this.turnDoneResolver) {
|
|
10699
|
-
const
|
|
10717
|
+
const resolve = this.turnDoneResolver;
|
|
10700
10718
|
this.turnDoneResolver = undefined;
|
|
10701
|
-
|
|
10719
|
+
resolve();
|
|
10702
10720
|
}
|
|
10703
10721
|
break;
|
|
10704
10722
|
case "Error":
|
|
@@ -10714,9 +10732,9 @@ class CliRepl {
|
|
|
10714
10732
|
console.error(style.red(`Error: ${msg.message}
|
|
10715
10733
|
`));
|
|
10716
10734
|
if (this.turnDoneResolver) {
|
|
10717
|
-
const
|
|
10735
|
+
const resolve = this.turnDoneResolver;
|
|
10718
10736
|
this.turnDoneResolver = undefined;
|
|
10719
|
-
|
|
10737
|
+
resolve();
|
|
10720
10738
|
}
|
|
10721
10739
|
break;
|
|
10722
10740
|
}
|
|
@@ -10786,15 +10804,21 @@ class CliRepl {
|
|
|
10786
10804
|
`));
|
|
10787
10805
|
this.isProcessing = false;
|
|
10788
10806
|
if (this.turnDoneResolver) {
|
|
10789
|
-
const
|
|
10807
|
+
const resolve = this.turnDoneResolver;
|
|
10790
10808
|
this.turnDoneResolver = undefined;
|
|
10791
|
-
|
|
10809
|
+
resolve();
|
|
10792
10810
|
}
|
|
10793
10811
|
}
|
|
10794
10812
|
}
|
|
10795
10813
|
}
|
|
10796
10814
|
});
|
|
10797
10815
|
while (!this.isClosed) {
|
|
10816
|
+
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
10817
|
+
if (typeof Bun !== "undefined" && typeof Bun.gc === "function") {
|
|
10818
|
+
try {
|
|
10819
|
+
Bun.gc(false);
|
|
10820
|
+
} catch {}
|
|
10821
|
+
}
|
|
10798
10822
|
let rawLine;
|
|
10799
10823
|
try {
|
|
10800
10824
|
rawLine = await editor.readLine();
|
|
@@ -10825,8 +10849,8 @@ class CliRepl {
|
|
|
10825
10849
|
}
|
|
10826
10850
|
async submitTurn(text) {
|
|
10827
10851
|
try {
|
|
10828
|
-
const turnPromise = new Promise((
|
|
10829
|
-
this.turnDoneResolver =
|
|
10852
|
+
const turnPromise = new Promise((resolve) => {
|
|
10853
|
+
this.turnDoneResolver = resolve;
|
|
10830
10854
|
});
|
|
10831
10855
|
await this.session.submit({
|
|
10832
10856
|
type: "TurnInput",
|
|
@@ -10951,7 +10975,7 @@ async function main() {
|
|
|
10951
10975
|
apiKey: explicitApiKey,
|
|
10952
10976
|
defaultModel: model
|
|
10953
10977
|
});
|
|
10954
|
-
const
|
|
10978
|
+
const tools = createDefaultTools({ skillsLoader, memoryStore, worktreeManager });
|
|
10955
10979
|
const mcpManager = new McpManager;
|
|
10956
10980
|
const candidateConfigs = [
|
|
10957
10981
|
mcpConfigFile,
|
|
@@ -10962,7 +10986,7 @@ async function main() {
|
|
|
10962
10986
|
if (existsSync24(cfg)) {
|
|
10963
10987
|
try {
|
|
10964
10988
|
await mcpManager.loadConfigFile(cfg);
|
|
10965
|
-
mcpManager.registerToolsIntoRouter(
|
|
10989
|
+
mcpManager.registerToolsIntoRouter(tools);
|
|
10966
10990
|
break;
|
|
10967
10991
|
} catch {}
|
|
10968
10992
|
}
|
|
@@ -10973,7 +10997,7 @@ async function main() {
|
|
|
10973
10997
|
session = storageManager.resumeSession(resumeThreadId, {
|
|
10974
10998
|
model,
|
|
10975
10999
|
cwd,
|
|
10976
|
-
tools
|
|
11000
|
+
tools,
|
|
10977
11001
|
skillsLoader,
|
|
10978
11002
|
memoryStore,
|
|
10979
11003
|
mcpManager,
|
|
@@ -10988,7 +11012,7 @@ async function main() {
|
|
|
10988
11012
|
session = new Session({
|
|
10989
11013
|
model,
|
|
10990
11014
|
cwd,
|
|
10991
|
-
tools
|
|
11015
|
+
tools,
|
|
10992
11016
|
skillsLoader,
|
|
10993
11017
|
memoryStore,
|
|
10994
11018
|
mcpManager,
|
|
@@ -10997,7 +11021,7 @@ async function main() {
|
|
|
10997
11021
|
storageManager.bindSession(session, role);
|
|
10998
11022
|
}
|
|
10999
11023
|
const spawner = new AgentSpawner(session);
|
|
11000
|
-
registerMultiAgentTools(
|
|
11024
|
+
registerMultiAgentTools(tools, spawner);
|
|
11001
11025
|
if (singlePrompt) {
|
|
11002
11026
|
if (singlePrompt.startsWith("/") || singlePrompt.startsWith("security") || singlePrompt.startsWith("scan") || singlePrompt.startsWith("audit") || singlePrompt.startsWith("skills") || singlePrompt.startsWith("whoami") || singlePrompt.startsWith("roles") || singlePrompt.startsWith("mcp")) {
|
|
11003
11027
|
const slashInput = singlePrompt.startsWith("/") ? singlePrompt : `/${singlePrompt}`;
|
|
@@ -11102,8 +11126,8 @@ Direct login failed: ${directErr instanceof Error ? directErr.message : String(d
|
|
|
11102
11126
|
}
|
|
11103
11127
|
}
|
|
11104
11128
|
}
|
|
11105
|
-
function printWhoami2(
|
|
11106
|
-
const creds =
|
|
11129
|
+
function printWhoami2(store) {
|
|
11130
|
+
const creds = store.load();
|
|
11107
11131
|
console.log();
|
|
11108
11132
|
if (!creds || !creds.accessToken) {
|
|
11109
11133
|
console.log(style.yellow("Not logged in."));
|
|
@@ -11231,8 +11255,8 @@ function printSkillsList(loader, cwd) {
|
|
|
11231
11255
|
}
|
|
11232
11256
|
console.log();
|
|
11233
11257
|
}
|
|
11234
|
-
function printMemoriesList(
|
|
11235
|
-
const memories =
|
|
11258
|
+
function printMemoriesList(store, cwd) {
|
|
11259
|
+
const memories = store.getAllMemories(cwd);
|
|
11236
11260
|
console.log();
|
|
11237
11261
|
if (memories.length === 0) {
|
|
11238
11262
|
console.log(style.dim("No memories recorded yet."));
|