@pikaa-ai/pikaa 0.3.16 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +70 -47
- package/dist/index.js +3 -1
- package/package.json +1 -1
- package/templates/base/groupy_prompt.md +5 -1
package/dist/cli.js
CHANGED
|
@@ -742,9 +742,11 @@ async function captureWorldState(cwd) {
|
|
|
742
742
|
};
|
|
743
743
|
}
|
|
744
744
|
function formatWorldStatePrompt(state) {
|
|
745
|
+
const isWindows = process.platform === "win32";
|
|
746
|
+
const platformNote = isWindows ? `Platform: Windows (${state.os}). Shell is cmd.exe / PowerShell. POSIX commands (grep, find, cat, sed, awk) are NOT supported in shell. ALWAYS use native grep_search, find_files, and read_file tools.` : `Platform: ${state.os}`;
|
|
745
747
|
const parts = [
|
|
746
748
|
`Current Working Directory: ${state.cwd}`,
|
|
747
|
-
|
|
749
|
+
platformNote
|
|
748
750
|
];
|
|
749
751
|
if (state.gitBranch) {
|
|
750
752
|
parts.push(`Git Branch: ${state.gitBranch}`);
|
|
@@ -6429,7 +6431,7 @@ function parsePatch(oldSrc, newSrc, contextLines = 3) {
|
|
|
6429
6431
|
// package.json
|
|
6430
6432
|
var package_default = {
|
|
6431
6433
|
name: "@pikaa-ai/pikaa",
|
|
6432
|
-
version: "0.3.
|
|
6434
|
+
version: "0.3.19",
|
|
6433
6435
|
description: "PIKAA CLI - AI coding agent that runs locally in your terminal.",
|
|
6434
6436
|
main: "./dist/index.js",
|
|
6435
6437
|
module: "./dist/index.js",
|
|
@@ -6986,12 +6988,23 @@ ${preview}${more}`);
|
|
|
6986
6988
|
}
|
|
6987
6989
|
|
|
6988
6990
|
// src/cli/ui/line-editor.ts
|
|
6991
|
+
import readline2 from "readline";
|
|
6992
|
+
|
|
6993
|
+
// src/cli/ui/keypress.ts
|
|
6989
6994
|
import readline from "readline";
|
|
6990
6995
|
var keypressEventsInitialized = false;
|
|
6991
|
-
|
|
6996
|
+
var listeners = new Set;
|
|
6997
|
+
function initGlobalKeypress() {
|
|
6992
6998
|
if (!keypressEventsInitialized && process.stdin.isTTY) {
|
|
6993
6999
|
readline.emitKeypressEvents(process.stdin);
|
|
6994
7000
|
keypressEventsInitialized = true;
|
|
7001
|
+
process.stdin.on("keypress", (str, key) => {
|
|
7002
|
+
for (const listener of Array.from(listeners)) {
|
|
7003
|
+
try {
|
|
7004
|
+
listener(str, key);
|
|
7005
|
+
} catch {}
|
|
7006
|
+
}
|
|
7007
|
+
});
|
|
6995
7008
|
process.on("exit", () => {
|
|
6996
7009
|
if (process.stdin.isTTY) {
|
|
6997
7010
|
try {
|
|
@@ -7001,7 +7014,15 @@ function ensureKeypressInitialized() {
|
|
|
7001
7014
|
});
|
|
7002
7015
|
}
|
|
7003
7016
|
}
|
|
7017
|
+
function addGlobalKeypressListener(listener) {
|
|
7018
|
+
initGlobalKeypress();
|
|
7019
|
+
listeners.add(listener);
|
|
7020
|
+
return () => {
|
|
7021
|
+
listeners.delete(listener);
|
|
7022
|
+
};
|
|
7023
|
+
}
|
|
7004
7024
|
|
|
7025
|
+
// src/cli/ui/line-editor.ts
|
|
7005
7026
|
class InteractiveLineEditor {
|
|
7006
7027
|
promptSymbol;
|
|
7007
7028
|
cwd;
|
|
@@ -7052,14 +7073,13 @@ class InteractiveLineEditor {
|
|
|
7052
7073
|
async readLine() {
|
|
7053
7074
|
if (!process.stdin.isTTY) {
|
|
7054
7075
|
return new Promise((resolve17) => {
|
|
7055
|
-
const rl =
|
|
7076
|
+
const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
|
|
7056
7077
|
rl.question(this.promptSymbol, (answer) => {
|
|
7057
7078
|
rl.close();
|
|
7058
7079
|
resolve17(answer);
|
|
7059
7080
|
});
|
|
7060
7081
|
});
|
|
7061
7082
|
}
|
|
7062
|
-
ensureKeypressInitialized();
|
|
7063
7083
|
return new Promise((resolve17) => {
|
|
7064
7084
|
let buffer = "";
|
|
7065
7085
|
let cursor = 0;
|
|
@@ -7067,6 +7087,7 @@ class InteractiveLineEditor {
|
|
|
7067
7087
|
let scrollTop = 0;
|
|
7068
7088
|
let popupDismissed = false;
|
|
7069
7089
|
let lastCursorRowFromTop = 0;
|
|
7090
|
+
let unsubscribeKeypress = null;
|
|
7070
7091
|
if (process.stdin.isTTY) {
|
|
7071
7092
|
try {
|
|
7072
7093
|
process.stdin.setRawMode(true);
|
|
@@ -7244,7 +7265,10 @@ class InteractiveLineEditor {
|
|
|
7244
7265
|
if (process.stdout && typeof process.stdout.removeListener === "function") {
|
|
7245
7266
|
process.stdout.removeListener("resize", onResize);
|
|
7246
7267
|
}
|
|
7247
|
-
|
|
7268
|
+
if (unsubscribeKeypress) {
|
|
7269
|
+
unsubscribeKeypress();
|
|
7270
|
+
unsubscribeKeypress = null;
|
|
7271
|
+
}
|
|
7248
7272
|
if (process.stdin.isTTY) {
|
|
7249
7273
|
try {
|
|
7250
7274
|
process.stdin.setRawMode(false);
|
|
@@ -7284,12 +7308,15 @@ class InteractiveLineEditor {
|
|
|
7284
7308
|
process.stdout.write(`\x1B[${lastCursorRowFromTop}A`);
|
|
7285
7309
|
}
|
|
7286
7310
|
process.stdout.write("\r\x1B[J");
|
|
7311
|
+
if (unsubscribeKeypress) {
|
|
7312
|
+
unsubscribeKeypress();
|
|
7313
|
+
unsubscribeKeypress = null;
|
|
7314
|
+
}
|
|
7287
7315
|
if (process.stdin.isTTY) {
|
|
7288
7316
|
try {
|
|
7289
7317
|
process.stdin.setRawMode(false);
|
|
7290
7318
|
} catch {}
|
|
7291
7319
|
}
|
|
7292
|
-
process.stdin.removeListener("keypress", onKeypress);
|
|
7293
7320
|
if (this.onInterrupt) {
|
|
7294
7321
|
this.onInterrupt();
|
|
7295
7322
|
}
|
|
@@ -7428,7 +7455,7 @@ class InteractiveLineEditor {
|
|
|
7428
7455
|
redraw();
|
|
7429
7456
|
}
|
|
7430
7457
|
};
|
|
7431
|
-
|
|
7458
|
+
unsubscribeKeypress = addGlobalKeypressListener(onKeypress);
|
|
7432
7459
|
const RULE_COLOR = "\x1B[38;2;60;60;68m";
|
|
7433
7460
|
process.stdout.write(`
|
|
7434
7461
|
${RULE_COLOR}${getRule()}\x1B[0m
|
|
@@ -7439,31 +7466,27 @@ class InteractiveLineEditor {
|
|
|
7439
7466
|
}
|
|
7440
7467
|
|
|
7441
7468
|
// src/cli/ui/prompt.ts
|
|
7442
|
-
import
|
|
7469
|
+
import readline3 from "readline";
|
|
7443
7470
|
async function promptChoice(config) {
|
|
7444
7471
|
const { message, choices, defaultIndex = 0 } = config;
|
|
7445
7472
|
if (!process.stdin.isTTY) {
|
|
7446
7473
|
if (!process.stdin.readable) {
|
|
7447
|
-
|
|
7474
|
+
const def = choices[defaultIndex] || choices[0];
|
|
7475
|
+
return def ? def.value : "";
|
|
7448
7476
|
}
|
|
7449
7477
|
return new Promise((resolve17) => {
|
|
7450
|
-
const rl =
|
|
7451
|
-
const
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
if (!resolved) {
|
|
7455
|
-
resolved = true;
|
|
7456
|
-
rl.close();
|
|
7457
|
-
resolve17(val);
|
|
7458
|
-
}
|
|
7459
|
-
};
|
|
7460
|
-
rl.question(`${message} ${hint}: `, (answer) => {
|
|
7478
|
+
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7479
|
+
const promptText = ` ${message} (${choices.map((c3) => `[${c3.key}] ${c3.label}`).join(", ")}): `;
|
|
7480
|
+
rl.question(promptText, (answer) => {
|
|
7481
|
+
rl.close();
|
|
7461
7482
|
const trimmed = answer.trim().toLowerCase();
|
|
7462
|
-
const
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7483
|
+
const match = choices.find((c3) => c3.key.toLowerCase() === trimmed);
|
|
7484
|
+
if (match) {
|
|
7485
|
+
resolve17(match.value);
|
|
7486
|
+
} else {
|
|
7487
|
+
const def = choices[defaultIndex] || choices[0];
|
|
7488
|
+
resolve17(def ? def.value : "");
|
|
7489
|
+
}
|
|
7467
7490
|
});
|
|
7468
7491
|
});
|
|
7469
7492
|
}
|
|
@@ -7471,7 +7494,6 @@ async function promptChoice(config) {
|
|
|
7471
7494
|
let selectedIndex = defaultIndex;
|
|
7472
7495
|
if (selectedIndex < 0 || selectedIndex >= choices.length)
|
|
7473
7496
|
selectedIndex = 0;
|
|
7474
|
-
readline2.emitKeypressEvents(process.stdin);
|
|
7475
7497
|
const wasRaw = process.stdin.isRaw;
|
|
7476
7498
|
try {
|
|
7477
7499
|
process.stdin.setRawMode(true);
|
|
@@ -7489,8 +7511,12 @@ async function promptChoice(config) {
|
|
|
7489
7511
|
process.stdout.write(`\r\x1B[2K ${style.bold(message)}
|
|
7490
7512
|
\r\x1B[2K${parts.join(" ")}`);
|
|
7491
7513
|
};
|
|
7514
|
+
let unsubscribe = null;
|
|
7492
7515
|
const cleanup = (confirmedChoice) => {
|
|
7493
|
-
|
|
7516
|
+
if (unsubscribe) {
|
|
7517
|
+
unsubscribe();
|
|
7518
|
+
unsubscribe = null;
|
|
7519
|
+
}
|
|
7494
7520
|
try {
|
|
7495
7521
|
process.stdin.setRawMode(wasRaw ?? false);
|
|
7496
7522
|
} catch {}
|
|
@@ -7502,21 +7528,12 @@ async function promptChoice(config) {
|
|
|
7502
7528
|
if (!key)
|
|
7503
7529
|
return;
|
|
7504
7530
|
if (key.ctrl && key.name === "c") {
|
|
7505
|
-
|
|
7531
|
+
const def = choices[defaultIndex] || choices[0];
|
|
7532
|
+
cleanup(def);
|
|
7506
7533
|
return;
|
|
7507
7534
|
}
|
|
7508
|
-
if (key.name === "
|
|
7509
|
-
cleanup(choices.find((c3) => c3.key.toLowerCase() === "n") || choices[defaultIndex]);
|
|
7510
|
-
return;
|
|
7511
|
-
}
|
|
7512
|
-
if (key.name === "return" || key.name === "enter") {
|
|
7513
|
-
cleanup(choices[selectedIndex]);
|
|
7514
|
-
return;
|
|
7515
|
-
}
|
|
7516
|
-
if (key.name === "left") {
|
|
7535
|
+
if (key.name === "left" || key.name === "up" || key.name === "h" || key.name === "k") {
|
|
7517
7536
|
selectedIndex = (selectedIndex - 1 + choices.length) % choices.length;
|
|
7518
|
-
process.stdout.write("\x1B[1A");
|
|
7519
|
-
render();
|
|
7520
7537
|
return;
|
|
7521
7538
|
}
|
|
7522
7539
|
if (key.name === "right" || key.name === "tab") {
|
|
@@ -7573,7 +7590,6 @@ async function promptToolApproval(params) {
|
|
|
7573
7590
|
}
|
|
7574
7591
|
return new Promise((resolve17) => {
|
|
7575
7592
|
let selectedIndex = 1;
|
|
7576
|
-
readline2.emitKeypressEvents(process.stdin);
|
|
7577
7593
|
const wasRaw = process.stdin.isRaw;
|
|
7578
7594
|
try {
|
|
7579
7595
|
process.stdin.setRawMode(true);
|
|
@@ -7582,8 +7598,12 @@ async function promptToolApproval(params) {
|
|
|
7582
7598
|
const render = () => {
|
|
7583
7599
|
renderCard(selectedIndex);
|
|
7584
7600
|
};
|
|
7601
|
+
let unsubscribe = null;
|
|
7585
7602
|
const cleanup = (val) => {
|
|
7586
|
-
|
|
7603
|
+
if (unsubscribe) {
|
|
7604
|
+
unsubscribe();
|
|
7605
|
+
unsubscribe = null;
|
|
7606
|
+
}
|
|
7587
7607
|
try {
|
|
7588
7608
|
process.stdin.setRawMode(wasRaw ?? false);
|
|
7589
7609
|
} catch {}
|
|
@@ -7642,7 +7662,7 @@ async function promptToolApproval(params) {
|
|
|
7642
7662
|
return;
|
|
7643
7663
|
}
|
|
7644
7664
|
};
|
|
7645
|
-
|
|
7665
|
+
unsubscribe = addGlobalKeypressListener(onKeypress);
|
|
7646
7666
|
render();
|
|
7647
7667
|
});
|
|
7648
7668
|
}
|
|
@@ -7672,7 +7692,7 @@ async function promptUserQuestion(params) {
|
|
|
7672
7692
|
return options[0] || "yes";
|
|
7673
7693
|
}
|
|
7674
7694
|
return new Promise((resolve17) => {
|
|
7675
|
-
const rl =
|
|
7695
|
+
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
7676
7696
|
const promptLabel = options.length > 0 ? `Select [1-${options.length}] or type custom response: ` : `Your response: `;
|
|
7677
7697
|
rl.question(` ${style.bold(promptLabel)}`, (answer) => {
|
|
7678
7698
|
rl.close();
|
|
@@ -7741,7 +7761,6 @@ async function promptInteractiveList(config) {
|
|
|
7741
7761
|
let selectedIndex = Math.max(0, Math.min(defaultIndex, items.length - 1));
|
|
7742
7762
|
let scrollTop = 0;
|
|
7743
7763
|
let renderedLines = 0;
|
|
7744
|
-
readline2.emitKeypressEvents(process.stdin);
|
|
7745
7764
|
const wasRaw = process.stdin.isRaw;
|
|
7746
7765
|
try {
|
|
7747
7766
|
process.stdin.setRawMode(true);
|
|
@@ -7818,6 +7837,7 @@ async function promptInteractiveList(config) {
|
|
|
7818
7837
|
process.stdout.write(buffer);
|
|
7819
7838
|
renderedLines = lines.length;
|
|
7820
7839
|
};
|
|
7840
|
+
let unsubscribe = null;
|
|
7821
7841
|
const cleanup = (res) => {
|
|
7822
7842
|
if (renderedLines > 0) {
|
|
7823
7843
|
process.stdout.write(`\x1B[${renderedLines}A\r\x1B[J\x1B[?25h`);
|
|
@@ -7825,7 +7845,10 @@ async function promptInteractiveList(config) {
|
|
|
7825
7845
|
} else {
|
|
7826
7846
|
process.stdout.write("\x1B[?25h");
|
|
7827
7847
|
}
|
|
7828
|
-
|
|
7848
|
+
if (unsubscribe) {
|
|
7849
|
+
unsubscribe();
|
|
7850
|
+
unsubscribe = null;
|
|
7851
|
+
}
|
|
7829
7852
|
try {
|
|
7830
7853
|
process.stdin.setRawMode(wasRaw ?? false);
|
|
7831
7854
|
} catch {}
|
|
@@ -7894,7 +7917,7 @@ async function promptInteractiveList(config) {
|
|
|
7894
7917
|
render();
|
|
7895
7918
|
}
|
|
7896
7919
|
};
|
|
7897
|
-
|
|
7920
|
+
unsubscribe = addGlobalKeypressListener(onKeypress);
|
|
7898
7921
|
render();
|
|
7899
7922
|
});
|
|
7900
7923
|
}
|
package/dist/index.js
CHANGED
|
@@ -3793,9 +3793,11 @@ async function captureWorldState(cwd) {
|
|
|
3793
3793
|
};
|
|
3794
3794
|
}
|
|
3795
3795
|
function formatWorldStatePrompt(state) {
|
|
3796
|
+
const isWindows = process.platform === "win32";
|
|
3797
|
+
const platformNote = isWindows ? `Platform: Windows (${state.os}). Shell is cmd.exe / PowerShell. POSIX commands (grep, find, cat, sed, awk) are NOT supported in shell. ALWAYS use native grep_search, find_files, and read_file tools.` : `Platform: ${state.os}`;
|
|
3796
3798
|
const parts = [
|
|
3797
3799
|
`Current Working Directory: ${state.cwd}`,
|
|
3798
|
-
|
|
3800
|
+
platformNote
|
|
3799
3801
|
];
|
|
3800
3802
|
if (state.gitBranch) {
|
|
3801
3803
|
parts.push(`Git Branch: ${state.gitBranch}`);
|
package/package.json
CHANGED
|
@@ -2,7 +2,11 @@ You are Groupy, an expert autonomous AI coding assistant. You are running as a c
|
|
|
2
2
|
|
|
3
3
|
## General
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- **CRITICAL: For searching, inspecting, reading, and editing code: ALWAYS use native tools (`grep_search`, `find_files`, `read_file`, `list_dir`, `apply_patch`, `write_file`).**
|
|
6
|
+
- **NEVER use the `shell` tool to run inspection/searching commands (e.g. `grep`, `find`, `cat`, `head`, `tail`, `sed`, `awk`, `ls`).**
|
|
7
|
+
* On Windows, shell commands like `grep` fail or exit with code 1.
|
|
8
|
+
* Native tools (`grep_search`, `find_files`, `read_file`) are structured, fast, and 100% cross-platform.
|
|
9
|
+
- The `shell` tool is reserved strictly for running build/test scripts (e.g. `bun test`, `pytest`, `cargo test`, `npm run build`), git operations, and package manager commands.
|
|
6
10
|
- **NEVER generate an empty response.** Every turn must either execute the appropriate tools or output a helpful, substantive message.
|
|
7
11
|
- When the user confirms or gives approval (e.g., "ya lakukan audit", "lanjutkan", "ok", "1"), **IMMEDIATELY start executing the tools** (`read_file`, `list_dir`, `grep_search`, `shell`) in the same turn without hesitation.
|
|
8
12
|
|