@polka-codes/cli 0.8.20 → 0.8.22
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/index.js +216 -266
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -38447,7 +38447,7 @@ var {
|
|
|
38447
38447
|
Help
|
|
38448
38448
|
} = import__.default;
|
|
38449
38449
|
// package.json
|
|
38450
|
-
var version = "0.8.
|
|
38450
|
+
var version = "0.8.22";
|
|
38451
38451
|
|
|
38452
38452
|
// ../core/src/AiService/AiServiceBase.ts
|
|
38453
38453
|
class AiServiceBase {
|
|
@@ -47758,39 +47758,6 @@ __export(exports_allTools, {
|
|
|
47758
47758
|
askFollowupQuestion: () => askFollowupQuestion_default
|
|
47759
47759
|
});
|
|
47760
47760
|
|
|
47761
|
-
// ../core/src/tools/utils/editFile.ts
|
|
47762
|
-
var START_OF_FILE = "<<<START_OF_FILE>>>";
|
|
47763
|
-
var END_OF_FILE = "<<<END_OF_FILE>>>";
|
|
47764
|
-
var editFile = async (fileContent, operations) => {
|
|
47765
|
-
if (!operations || operations.length === 0) {
|
|
47766
|
-
throw new Error("At least one edit operation is required");
|
|
47767
|
-
}
|
|
47768
|
-
let updatedContent = fileContent;
|
|
47769
|
-
for (const operation of operations) {
|
|
47770
|
-
updatedContent = await applyEditOperation(updatedContent, operation);
|
|
47771
|
-
}
|
|
47772
|
-
return updatedContent;
|
|
47773
|
-
};
|
|
47774
|
-
async function applyEditOperation(fileContent, operation) {
|
|
47775
|
-
const { search, replace } = operation;
|
|
47776
|
-
if (search === START_OF_FILE && replace === END_OF_FILE) {
|
|
47777
|
-
throw new Error("Cannot search for START_OF_FILE and replace with END_OF_FILE");
|
|
47778
|
-
}
|
|
47779
|
-
if (search === END_OF_FILE && replace === START_OF_FILE) {
|
|
47780
|
-
throw new Error("Cannot search for END_OF_FILE and replace with START_OF_FILE");
|
|
47781
|
-
}
|
|
47782
|
-
if (search === START_OF_FILE) {
|
|
47783
|
-
return replace + fileContent;
|
|
47784
|
-
}
|
|
47785
|
-
if (search === END_OF_FILE) {
|
|
47786
|
-
return fileContent + replace;
|
|
47787
|
-
}
|
|
47788
|
-
const index = fileContent.indexOf(search);
|
|
47789
|
-
if (index === -1) {
|
|
47790
|
-
throw new Error(`Could not find text: ${search}`);
|
|
47791
|
-
}
|
|
47792
|
-
return fileContent.slice(0, index) + replace + fileContent.slice(index + search.length);
|
|
47793
|
-
}
|
|
47794
47761
|
// ../core/src/tools/utils/getArg.ts
|
|
47795
47762
|
var getString = (args, name, defaultValue) => {
|
|
47796
47763
|
if (typeof args !== "object" || Array.isArray(args)) {
|
|
@@ -48397,29 +48364,29 @@ var toolInfo7 = {
|
|
|
48397
48364
|
{
|
|
48398
48365
|
name: "diff",
|
|
48399
48366
|
description: `One or more SEARCH/REPLACE blocks following this exact format:
|
|
48400
|
-
|
|
48401
|
-
|
|
48402
|
-
|
|
48403
|
-
|
|
48404
|
-
|
|
48405
|
-
|
|
48406
|
-
|
|
48407
|
-
|
|
48408
|
-
|
|
48409
|
-
|
|
48410
|
-
|
|
48411
|
-
|
|
48412
|
-
|
|
48413
|
-
|
|
48414
|
-
|
|
48415
|
-
|
|
48416
|
-
|
|
48417
|
-
|
|
48418
|
-
|
|
48419
|
-
|
|
48420
|
-
|
|
48421
|
-
|
|
48422
|
-
|
|
48367
|
+
\`\`\`
|
|
48368
|
+
<<<<<<< SEARCH
|
|
48369
|
+
[exact content to find]
|
|
48370
|
+
=======
|
|
48371
|
+
[new content to replace with]
|
|
48372
|
+
>>>>>>> REPLACE
|
|
48373
|
+
\`\`\`
|
|
48374
|
+
Critical rules:
|
|
48375
|
+
1. SEARCH content must match the associated file section to find EXACTLY:
|
|
48376
|
+
* Match character-for-character including whitespace, indentation, line endings
|
|
48377
|
+
* Include all comments, docstrings, etc.
|
|
48378
|
+
2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
|
|
48379
|
+
* Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
|
|
48380
|
+
* Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
|
|
48381
|
+
* When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
|
|
48382
|
+
3. Keep SEARCH/REPLACE blocks concise:
|
|
48383
|
+
* Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
|
|
48384
|
+
* Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
48385
|
+
* Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
|
|
48386
|
+
* Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
|
|
48387
|
+
4. Special operations:
|
|
48388
|
+
* To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
|
|
48389
|
+
* To delete code: Use empty REPLACE section`,
|
|
48423
48390
|
required: true,
|
|
48424
48391
|
usageValue: "Search and replace blocks here"
|
|
48425
48392
|
}
|
|
@@ -48462,6 +48429,73 @@ function handleSubmit() {
|
|
|
48462
48429
|
return (
|
|
48463
48430
|
<div>
|
|
48464
48431
|
>>>>>>> REPLACE
|
|
48432
|
+
`
|
|
48433
|
+
}
|
|
48434
|
+
]
|
|
48435
|
+
},
|
|
48436
|
+
{
|
|
48437
|
+
description: "Request to perform a simple, single-line replacement",
|
|
48438
|
+
parameters: [
|
|
48439
|
+
{
|
|
48440
|
+
name: "path",
|
|
48441
|
+
value: "src/config.js"
|
|
48442
|
+
},
|
|
48443
|
+
{
|
|
48444
|
+
name: "diff",
|
|
48445
|
+
value: `
|
|
48446
|
+
<<<<<<< SEARCH
|
|
48447
|
+
const API_URL = 'https://api.example.com';
|
|
48448
|
+
=======
|
|
48449
|
+
const API_URL = 'https://api.staging.example.com';
|
|
48450
|
+
>>>>>>> REPLACE
|
|
48451
|
+
`
|
|
48452
|
+
}
|
|
48453
|
+
]
|
|
48454
|
+
},
|
|
48455
|
+
{
|
|
48456
|
+
description: "Request to add a new function to a file",
|
|
48457
|
+
parameters: [
|
|
48458
|
+
{
|
|
48459
|
+
name: "path",
|
|
48460
|
+
value: "src/utils.js"
|
|
48461
|
+
},
|
|
48462
|
+
{
|
|
48463
|
+
name: "diff",
|
|
48464
|
+
value: `
|
|
48465
|
+
<<<<<<< SEARCH
|
|
48466
|
+
function helperA() {
|
|
48467
|
+
// ...
|
|
48468
|
+
}
|
|
48469
|
+
=======
|
|
48470
|
+
function helperA() {
|
|
48471
|
+
// ...
|
|
48472
|
+
}
|
|
48473
|
+
|
|
48474
|
+
function newHelper() {
|
|
48475
|
+
// implementation
|
|
48476
|
+
}
|
|
48477
|
+
>>>>>>> REPLACE
|
|
48478
|
+
`
|
|
48479
|
+
}
|
|
48480
|
+
]
|
|
48481
|
+
},
|
|
48482
|
+
{
|
|
48483
|
+
description: "Request to delete a block of code from a file",
|
|
48484
|
+
parameters: [
|
|
48485
|
+
{
|
|
48486
|
+
name: "path",
|
|
48487
|
+
value: "src/app.js"
|
|
48488
|
+
},
|
|
48489
|
+
{
|
|
48490
|
+
name: "diff",
|
|
48491
|
+
value: `
|
|
48492
|
+
<<<<<<< SEARCH
|
|
48493
|
+
function oldFeature() {
|
|
48494
|
+
// This is no longer needed
|
|
48495
|
+
}
|
|
48496
|
+
|
|
48497
|
+
=======
|
|
48498
|
+
>>>>>>> REPLACE
|
|
48465
48499
|
`
|
|
48466
48500
|
}
|
|
48467
48501
|
]
|
|
@@ -48578,7 +48612,64 @@ var searchFiles_default = {
|
|
|
48578
48612
|
};
|
|
48579
48613
|
// ../core/src/tools/updateKnowledge.ts
|
|
48580
48614
|
var import_yaml = __toESM(require_dist(), 1);
|
|
48581
|
-
|
|
48615
|
+
|
|
48616
|
+
// ../core/src/path.ts
|
|
48617
|
+
function dirname(path) {
|
|
48618
|
+
if (path.length === 0)
|
|
48619
|
+
return ".";
|
|
48620
|
+
const isRooted = path[0] === "/";
|
|
48621
|
+
let end = path.length - 1;
|
|
48622
|
+
while (end > 0 && path[end] === "/")
|
|
48623
|
+
end--;
|
|
48624
|
+
const idx = path.lastIndexOf("/", end);
|
|
48625
|
+
if (idx < 0) {
|
|
48626
|
+
return isRooted ? "/" : ".";
|
|
48627
|
+
}
|
|
48628
|
+
if (isRooted && idx === 0) {
|
|
48629
|
+
return "/";
|
|
48630
|
+
}
|
|
48631
|
+
return path.slice(0, idx);
|
|
48632
|
+
}
|
|
48633
|
+
function normalize(path) {
|
|
48634
|
+
const isAbsolute = path.startsWith("/");
|
|
48635
|
+
const segments = path.split("/").filter(Boolean);
|
|
48636
|
+
const stack = [];
|
|
48637
|
+
for (const seg of segments) {
|
|
48638
|
+
if (seg === ".")
|
|
48639
|
+
continue;
|
|
48640
|
+
if (seg === "..") {
|
|
48641
|
+
if (stack.length && stack[stack.length - 1] !== "..") {
|
|
48642
|
+
stack.pop();
|
|
48643
|
+
} else if (!isAbsolute) {
|
|
48644
|
+
stack.push("..");
|
|
48645
|
+
}
|
|
48646
|
+
} else {
|
|
48647
|
+
stack.push(seg);
|
|
48648
|
+
}
|
|
48649
|
+
}
|
|
48650
|
+
let result = stack.join("/");
|
|
48651
|
+
if (!result && !isAbsolute)
|
|
48652
|
+
return ".";
|
|
48653
|
+
if (result && path.endsWith("/"))
|
|
48654
|
+
result += "/";
|
|
48655
|
+
return (isAbsolute ? "/" : "") + result;
|
|
48656
|
+
}
|
|
48657
|
+
function join(...parts) {
|
|
48658
|
+
if (parts.length === 0)
|
|
48659
|
+
return ".";
|
|
48660
|
+
let combined = "";
|
|
48661
|
+
for (const p2 of parts) {
|
|
48662
|
+
if (typeof p2 !== "string") {
|
|
48663
|
+
throw new TypeError("Arguments to join must be strings");
|
|
48664
|
+
}
|
|
48665
|
+
if (p2) {
|
|
48666
|
+
combined = combined ? `${combined}/${p2}` : p2;
|
|
48667
|
+
}
|
|
48668
|
+
}
|
|
48669
|
+
return normalize(combined);
|
|
48670
|
+
}
|
|
48671
|
+
|
|
48672
|
+
// ../core/src/tools/updateKnowledge.ts
|
|
48582
48673
|
var toolInfo9 = {
|
|
48583
48674
|
name: "update_knowledge",
|
|
48584
48675
|
description: "Update knowledge in a knowledge.ai.yml file with smart merging capabilities. This tool lets you add, update, or remove information using path-based updates and special directives.",
|
|
@@ -49086,167 +49177,6 @@ var renameFile_default = {
|
|
|
49086
49177
|
handler: handler13,
|
|
49087
49178
|
isAvailable: isAvailable13
|
|
49088
49179
|
};
|
|
49089
|
-
// ../core/src/tools/editFile.ts
|
|
49090
|
-
var toolInfo14 = {
|
|
49091
|
-
name: "edit_file",
|
|
49092
|
-
description: "Request to edit file contents using search/replace operations. Supports multiple edit operations in a single call.",
|
|
49093
|
-
parameters: [
|
|
49094
|
-
{
|
|
49095
|
-
name: "path",
|
|
49096
|
-
description: "The path of the file to edit",
|
|
49097
|
-
required: true,
|
|
49098
|
-
usageValue: "File path here"
|
|
49099
|
-
},
|
|
49100
|
-
{
|
|
49101
|
-
name: "operations",
|
|
49102
|
-
description: "Edit operation with search and replace parameters",
|
|
49103
|
-
required: true,
|
|
49104
|
-
allowMultiple: true,
|
|
49105
|
-
children: [
|
|
49106
|
-
{
|
|
49107
|
-
name: "search",
|
|
49108
|
-
description: `Text to search for and replace (use ${START_OF_FILE} to insert at file start, ${END_OF_FILE} to insert at file end)`,
|
|
49109
|
-
required: true,
|
|
49110
|
-
usageValue: "Text to find and replace"
|
|
49111
|
-
},
|
|
49112
|
-
{
|
|
49113
|
-
name: "replace",
|
|
49114
|
-
description: "Text to replace the search text with",
|
|
49115
|
-
required: true,
|
|
49116
|
-
usageValue: "Replacement text"
|
|
49117
|
-
}
|
|
49118
|
-
],
|
|
49119
|
-
usageValue: "operations here"
|
|
49120
|
-
}
|
|
49121
|
-
],
|
|
49122
|
-
examples: [
|
|
49123
|
-
{
|
|
49124
|
-
description: "Replace specific text",
|
|
49125
|
-
parameters: [
|
|
49126
|
-
{
|
|
49127
|
-
name: "path",
|
|
49128
|
-
value: "src/main.ts"
|
|
49129
|
-
},
|
|
49130
|
-
{
|
|
49131
|
-
name: "operations",
|
|
49132
|
-
value: {
|
|
49133
|
-
search: `function oldFunction() {
|
|
49134
|
-
return 42;
|
|
49135
|
-
}`,
|
|
49136
|
-
replace: `function newFunction() {
|
|
49137
|
-
return "new implementation";
|
|
49138
|
-
}`
|
|
49139
|
-
}
|
|
49140
|
-
}
|
|
49141
|
-
]
|
|
49142
|
-
},
|
|
49143
|
-
{
|
|
49144
|
-
description: "Insert at start of file",
|
|
49145
|
-
parameters: [
|
|
49146
|
-
{
|
|
49147
|
-
name: "path",
|
|
49148
|
-
value: "src/header.ts"
|
|
49149
|
-
},
|
|
49150
|
-
{
|
|
49151
|
-
name: "operations",
|
|
49152
|
-
value: {
|
|
49153
|
-
search: START_OF_FILE,
|
|
49154
|
-
replace: `// File header comment
|
|
49155
|
-
`
|
|
49156
|
-
}
|
|
49157
|
-
}
|
|
49158
|
-
]
|
|
49159
|
-
},
|
|
49160
|
-
{
|
|
49161
|
-
description: "Multiple operations in one call",
|
|
49162
|
-
parameters: [
|
|
49163
|
-
{
|
|
49164
|
-
name: "path",
|
|
49165
|
-
value: "src/utils.ts"
|
|
49166
|
-
},
|
|
49167
|
-
{
|
|
49168
|
-
name: "operations",
|
|
49169
|
-
value: [
|
|
49170
|
-
{
|
|
49171
|
-
search: 'import React from "react"',
|
|
49172
|
-
replace: 'import React, { useState } from "react"'
|
|
49173
|
-
},
|
|
49174
|
-
{
|
|
49175
|
-
search: `function Component() {
|
|
49176
|
-
return (`,
|
|
49177
|
-
replace: `function Component() {
|
|
49178
|
-
const [state, setState] = useState(false);
|
|
49179
|
-
return (`
|
|
49180
|
-
}
|
|
49181
|
-
]
|
|
49182
|
-
}
|
|
49183
|
-
]
|
|
49184
|
-
},
|
|
49185
|
-
{
|
|
49186
|
-
description: "Append content at end of file",
|
|
49187
|
-
parameters: [
|
|
49188
|
-
{
|
|
49189
|
-
name: "path",
|
|
49190
|
-
value: "src/footer.ts"
|
|
49191
|
-
},
|
|
49192
|
-
{
|
|
49193
|
-
name: "operations",
|
|
49194
|
-
value: {
|
|
49195
|
-
search: END_OF_FILE,
|
|
49196
|
-
replace: `
|
|
49197
|
-
// End of file appended comment
|
|
49198
|
-
`
|
|
49199
|
-
}
|
|
49200
|
-
}
|
|
49201
|
-
]
|
|
49202
|
-
}
|
|
49203
|
-
],
|
|
49204
|
-
permissionLevel: 2 /* Write */
|
|
49205
|
-
};
|
|
49206
|
-
var handler14 = async (provider, args) => {
|
|
49207
|
-
if (!provider.readFile || !provider.writeFile) {
|
|
49208
|
-
return {
|
|
49209
|
-
type: "Error" /* Error */,
|
|
49210
|
-
message: "Not possible to edit file. Abort."
|
|
49211
|
-
};
|
|
49212
|
-
}
|
|
49213
|
-
const path = getString(args, "path");
|
|
49214
|
-
const operations = getArray(args, "operations");
|
|
49215
|
-
if (!operations || operations.length === 0) {
|
|
49216
|
-
return {
|
|
49217
|
-
type: "Error" /* Error */,
|
|
49218
|
-
message: `<error><edit_file_path>${path}</edit_file_path><error_message>At least one edit operation is required</error_message></error>`
|
|
49219
|
-
};
|
|
49220
|
-
}
|
|
49221
|
-
const fileContent = await provider.readFile(path);
|
|
49222
|
-
if (fileContent == null) {
|
|
49223
|
-
return {
|
|
49224
|
-
type: "Error" /* Error */,
|
|
49225
|
-
message: `<error><edit_file_path>${path}</edit_file_path><error_message>File not found</error_message></error>`
|
|
49226
|
-
};
|
|
49227
|
-
}
|
|
49228
|
-
try {
|
|
49229
|
-
const result = await editFile(fileContent, operations);
|
|
49230
|
-
await provider.writeFile(path, result);
|
|
49231
|
-
return {
|
|
49232
|
-
type: "Reply" /* Reply */,
|
|
49233
|
-
message: `<edit_file_path>${path}</edit_file_path>`
|
|
49234
|
-
};
|
|
49235
|
-
} catch (error) {
|
|
49236
|
-
return {
|
|
49237
|
-
type: "Error" /* Error */,
|
|
49238
|
-
message: `<error><edit_file_path>${path}</edit_file_path><error_message>${error instanceof Error ? error.message : String(error)}</error_message></error>`
|
|
49239
|
-
};
|
|
49240
|
-
}
|
|
49241
|
-
};
|
|
49242
|
-
var isAvailable14 = (provider) => {
|
|
49243
|
-
return !!provider.readFile && !!provider.writeFile;
|
|
49244
|
-
};
|
|
49245
|
-
var editFile_default = {
|
|
49246
|
-
...toolInfo14,
|
|
49247
|
-
handler: handler14,
|
|
49248
|
-
isAvailable: isAvailable14
|
|
49249
|
-
};
|
|
49250
49180
|
// ../core/src/getAvailableTools.ts
|
|
49251
49181
|
var getAvailableTools = ({
|
|
49252
49182
|
provider: provider2,
|
|
@@ -49471,6 +49401,8 @@ Tool use is formatted using XML-style tags. The tool name is enclosed in opening
|
|
|
49471
49401
|
...
|
|
49472
49402
|
</${toolNamePrefix}tool_name>
|
|
49473
49403
|
|
|
49404
|
+
**It is crucial that all tags are correctly nested and closed.**
|
|
49405
|
+
|
|
49474
49406
|
## Array Parameters
|
|
49475
49407
|
|
|
49476
49408
|
To create an array of values for a parameter, repeat the parameter tag multiple times:
|
|
@@ -49505,7 +49437,7 @@ You can also combine array parameters with nested objects:
|
|
|
49505
49437
|
</${parameterPrefix}key>
|
|
49506
49438
|
</${toolNamePrefix}example_tool>
|
|
49507
49439
|
|
|
49508
|
-
Always adhere to this format
|
|
49440
|
+
Always adhere to this format, ensuring every opening tag has a matching closing tag, to ensure proper parsing and execution.
|
|
49509
49441
|
|
|
49510
49442
|
NEVER surround tool use with triple backticks (\`\`\`).
|
|
49511
49443
|
|
|
@@ -49844,8 +49776,8 @@ ${instance.prompt}`;
|
|
|
49844
49776
|
}
|
|
49845
49777
|
async#invokeTool(name, args) {
|
|
49846
49778
|
try {
|
|
49847
|
-
const
|
|
49848
|
-
if (!
|
|
49779
|
+
const handler14 = this.handlers[name]?.handler;
|
|
49780
|
+
if (!handler14) {
|
|
49849
49781
|
return {
|
|
49850
49782
|
type: "Error" /* Error */,
|
|
49851
49783
|
message: responsePrompts.errorInvokeTool(name, "Tool not found"),
|
|
@@ -49864,7 +49796,7 @@ ${instance.prompt}`;
|
|
|
49864
49796
|
if (resp) {
|
|
49865
49797
|
return resp;
|
|
49866
49798
|
}
|
|
49867
|
-
return await
|
|
49799
|
+
return await handler14(this.config.provider, args);
|
|
49868
49800
|
} catch (error) {
|
|
49869
49801
|
return {
|
|
49870
49802
|
type: "Error" /* Error */,
|
|
@@ -50203,7 +50135,7 @@ var editingFilesPrompt = (toolNamePrefix) => `
|
|
|
50203
50135
|
|
|
50204
50136
|
EDITING FILES
|
|
50205
50137
|
|
|
50206
|
-
You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full overwrite) and **${toolNamePrefix}
|
|
50138
|
+
You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full overwrite) and **${toolNamePrefix}replace_in_file** (targeted anchor-based edits). Choose the smallest safe operation for every change.
|
|
50207
50139
|
|
|
50208
50140
|
# ${toolNamePrefix}write_to_file
|
|
50209
50141
|
|
|
@@ -50215,16 +50147,16 @@ You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full o
|
|
|
50215
50147
|
|
|
50216
50148
|
- Initial file creation, such as when scaffolding a new project.
|
|
50217
50149
|
- Overwriting large boilerplate files where you want to replace the entire content at once.
|
|
50218
|
-
- When the complexity or number of changes would make ${toolNamePrefix}
|
|
50150
|
+
- When the complexity or number of changes would make ${toolNamePrefix}replace_in_file unwieldy or error-prone.
|
|
50219
50151
|
- When you need to completely restructure a file's content or change its fundamental organization.
|
|
50220
50152
|
|
|
50221
50153
|
## Important Considerations
|
|
50222
50154
|
|
|
50223
50155
|
- Using ${toolNamePrefix}write_to_file requires providing the file's complete final content.
|
|
50224
|
-
- If you only need to make small changes to an existing file, consider using ${toolNamePrefix}
|
|
50156
|
+
- If you only need to make small changes to an existing file, consider using ${toolNamePrefix}replace_in_file instead to avoid unnecessarily rewriting the entire file.
|
|
50225
50157
|
- While ${toolNamePrefix}write_to_file should not be your default choice, don't hesitate to use it when the situation truly calls for it.
|
|
50226
50158
|
|
|
50227
|
-
# ${toolNamePrefix}
|
|
50159
|
+
# ${toolNamePrefix}replace_in_file
|
|
50228
50160
|
|
|
50229
50161
|
## Purpose
|
|
50230
50162
|
|
|
@@ -50243,10 +50175,10 @@ You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full o
|
|
|
50243
50175
|
|
|
50244
50176
|
# Choosing the Appropriate Tool
|
|
50245
50177
|
|
|
50246
|
-
- **Default to ${toolNamePrefix}
|
|
50178
|
+
- **Default to ${toolNamePrefix}replace_in_file** for most changes. It keeps diffs small and reduces risk.
|
|
50247
50179
|
- **Use ${toolNamePrefix}write_to_file** when:
|
|
50248
50180
|
- Creating new files
|
|
50249
|
-
- The changes are so extensive that using ${toolNamePrefix}
|
|
50181
|
+
- The changes are so extensive that using ${toolNamePrefix}replace_in_file would be more complex or risky
|
|
50250
50182
|
- You need to completely reorganize or restructure a file
|
|
50251
50183
|
- The file is relatively small and the changes affect most of its content
|
|
50252
50184
|
- You're generating boilerplate or template files
|
|
@@ -50254,9 +50186,9 @@ You have two file-manipulation tools: **${toolNamePrefix}write_to_file** (full o
|
|
|
50254
50186
|
# Workflow Tips
|
|
50255
50187
|
|
|
50256
50188
|
1. Before editing, assess the scope of your changes and decide which tool to use.
|
|
50257
|
-
2. For targeted edits, apply ${toolNamePrefix}
|
|
50189
|
+
2. For targeted edits, apply ${toolNamePrefix}replace_in_file with carefully crafted before/after text anchors. If you need multiple changes, you can stack multiple operations within a single ${toolNamePrefix}replace_in_file call.
|
|
50258
50190
|
3. For major overhauls or initial file creation, rely on ${toolNamePrefix}write_to_file.
|
|
50259
|
-
4. Once the file has been edited with either ${toolNamePrefix}write_to_file or ${toolNamePrefix}
|
|
50191
|
+
4. Once the file has been edited with either ${toolNamePrefix}write_to_file or ${toolNamePrefix}replace_in_file, the system will provide you with the final state of the modified file. Use this updated content as the reference point for any subsequent operations, since it reflects any auto-formatting or user-applied changes.
|
|
50260
50192
|
|
|
50261
50193
|
Picking the right tool keeps edits minimal, safe, and easy to review.
|
|
50262
50194
|
`;
|
|
@@ -50270,10 +50202,10 @@ RULES
|
|
|
50270
50202
|
For text files (e.g. README.md), append a footer with the same notice.
|
|
50271
50203
|
- Never describe what changed inside code comments; comments must focus on purpose or usage only.
|
|
50272
50204
|
- Before using ${toolNamePrefix}execute_command, consider SYSTEM INFORMATION to ensure commands suit the user's OS. If a command must run in a subdirectory, prepend a single \`cd childDir &&\` segment.
|
|
50273
|
-
- Use ${toolNamePrefix}search_files for broad analysis, then ${toolNamePrefix}read_file to inspect context, and finally ${toolNamePrefix}
|
|
50274
|
-
- Prefer ${toolNamePrefix}
|
|
50205
|
+
- Use ${toolNamePrefix}search_files for broad analysis, then ${toolNamePrefix}read_file to inspect context, and finally ${toolNamePrefix}replace_in_file or ${toolNamePrefix}write_to_file to modify.
|
|
50206
|
+
- Prefer ${toolNamePrefix}replace_in_file for focused edits; choose ${toolNamePrefix}write_to_file for new files or complete rewrites.
|
|
50275
50207
|
- When creating a new file, look for existing files with similar content or patterns; if found, read them and use their structure or conventions as a reference.
|
|
50276
|
-
- Use before/after text anchors in ${toolNamePrefix}
|
|
50208
|
+
- Use before/after text anchors in ${toolNamePrefix}replace_in_file to target changes. If multiple operations are needed, list them in file order.
|
|
50277
50209
|
- Do not guess unseen content. Read existing files first unless creating new ones.
|
|
50278
50210
|
- Follow existing style, lint, and naming conventions. Ensure all changes compile and pass tests where applicable.
|
|
50279
50211
|
- ALWAYS wait for the user's confirmation after each tool call before starting the next step.
|
|
@@ -50458,9 +50390,6 @@ class MultiAgent {
|
|
|
50458
50390
|
return this.#agents.length > 0;
|
|
50459
50391
|
}
|
|
50460
50392
|
}
|
|
50461
|
-
// ../core/src/Agent/policies/KnowledgeManagement.ts
|
|
50462
|
-
import { dirname, join as join2 } from "node:path";
|
|
50463
|
-
|
|
50464
50393
|
// ../core/node_modules/zod/lib/index.mjs
|
|
50465
50394
|
var util;
|
|
50466
50395
|
(function(util2) {
|
|
@@ -54607,7 +54536,7 @@ var KnowledgeManagementPolicy = (tools) => {
|
|
|
54607
54536
|
if (path === ".") {
|
|
54608
54537
|
continue;
|
|
54609
54538
|
}
|
|
54610
|
-
const fullpath =
|
|
54539
|
+
const fullpath = join(path, "knowledge.ai.yml");
|
|
54611
54540
|
if (!readFiles.has(fullpath)) {
|
|
54612
54541
|
allFullPaths.push(fullpath);
|
|
54613
54542
|
readFiles.add(fullpath);
|
|
@@ -55226,12 +55155,12 @@ Available commands:
|
|
|
55226
55155
|
import { existsSync as existsSync2 } from "node:fs";
|
|
55227
55156
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
55228
55157
|
import os2 from "node:os";
|
|
55229
|
-
import { join as
|
|
55158
|
+
import { join as join4 } from "node:path";
|
|
55230
55159
|
|
|
55231
55160
|
// ../cli-shared/src/config.ts
|
|
55232
55161
|
import { existsSync, readFileSync } from "node:fs";
|
|
55233
55162
|
import { homedir } from "node:os";
|
|
55234
|
-
import { join as
|
|
55163
|
+
import { join as join2 } from "node:path";
|
|
55235
55164
|
var import_lodash2 = __toESM(require_lodash(), 1);
|
|
55236
55165
|
|
|
55237
55166
|
// ../cli-shared/node_modules/yaml/dist/index.js
|
|
@@ -59116,7 +59045,7 @@ var pipelineType2 = ZodPipeline2.create;
|
|
|
59116
59045
|
|
|
59117
59046
|
// ../cli-shared/src/config.ts
|
|
59118
59047
|
function getGlobalConfigPath(home = homedir()) {
|
|
59119
|
-
return
|
|
59048
|
+
return join2(home, ".config", "polkacodes", "config.yml");
|
|
59120
59049
|
}
|
|
59121
59050
|
function loadConfigAtPath(path) {
|
|
59122
59051
|
try {
|
|
@@ -59183,7 +59112,7 @@ ${error}`);
|
|
|
59183
59112
|
}
|
|
59184
59113
|
}
|
|
59185
59114
|
} else {
|
|
59186
|
-
const configPath =
|
|
59115
|
+
const configPath = join2(cwd, localConfigFileName);
|
|
59187
59116
|
try {
|
|
59188
59117
|
const projectConfig = readConfig(configPath);
|
|
59189
59118
|
configs.push(projectConfig);
|
|
@@ -59768,15 +59697,15 @@ function useKeypress(userHandler) {
|
|
|
59768
59697
|
signal.current = userHandler;
|
|
59769
59698
|
useEffect((rl) => {
|
|
59770
59699
|
let ignore = false;
|
|
59771
|
-
const
|
|
59700
|
+
const handler14 = withUpdates((_input, event) => {
|
|
59772
59701
|
if (ignore)
|
|
59773
59702
|
return;
|
|
59774
59703
|
signal.current(event, rl);
|
|
59775
59704
|
});
|
|
59776
|
-
rl.input.on("keypress",
|
|
59705
|
+
rl.input.on("keypress", handler14);
|
|
59777
59706
|
return () => {
|
|
59778
59707
|
ignore = true;
|
|
59779
|
-
rl.input.removeListener("keypress",
|
|
59708
|
+
rl.input.removeListener("keypress", handler14);
|
|
59780
59709
|
};
|
|
59781
59710
|
}, []);
|
|
59782
59711
|
}
|
|
@@ -59958,16 +59887,16 @@ class Emitter {
|
|
|
59958
59887
|
|
|
59959
59888
|
class SignalExitBase {
|
|
59960
59889
|
}
|
|
59961
|
-
var signalExitWrap = (
|
|
59890
|
+
var signalExitWrap = (handler14) => {
|
|
59962
59891
|
return {
|
|
59963
59892
|
onExit(cb, opts) {
|
|
59964
|
-
return
|
|
59893
|
+
return handler14.onExit(cb, opts);
|
|
59965
59894
|
},
|
|
59966
59895
|
load() {
|
|
59967
|
-
return
|
|
59896
|
+
return handler14.load();
|
|
59968
59897
|
},
|
|
59969
59898
|
unload() {
|
|
59970
|
-
return
|
|
59899
|
+
return handler14.unload();
|
|
59971
59900
|
}
|
|
59972
59901
|
};
|
|
59973
59902
|
};
|
|
@@ -60575,10 +60504,28 @@ ${theme.style.description(selectedChoice.description)}` : ``;
|
|
|
60575
60504
|
return `${[prefix, message, helpTipTop].filter(Boolean).join(" ")}
|
|
60576
60505
|
${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes3.default.cursorHide}`;
|
|
60577
60506
|
});
|
|
60507
|
+
// ../cli-shared/src/utils/checkRipgrep.ts
|
|
60508
|
+
import { spawnSync } from "node:child_process";
|
|
60509
|
+
var rgAvailability = {
|
|
60510
|
+
isAvailable: null
|
|
60511
|
+
};
|
|
60512
|
+
function checkRipgrep() {
|
|
60513
|
+
if (rgAvailability.isAvailable !== null) {
|
|
60514
|
+
return rgAvailability.isAvailable;
|
|
60515
|
+
}
|
|
60516
|
+
const rg = spawnSync("rg", ["--version"]);
|
|
60517
|
+
if (rg.error || rg.status !== 0) {
|
|
60518
|
+
rgAvailability.isAvailable = false;
|
|
60519
|
+
return false;
|
|
60520
|
+
}
|
|
60521
|
+
rgAvailability.isAvailable = true;
|
|
60522
|
+
return true;
|
|
60523
|
+
}
|
|
60524
|
+
|
|
60578
60525
|
// ../cli-shared/src/utils/listFiles.ts
|
|
60579
60526
|
var import_ignore = __toESM(require_ignore(), 1);
|
|
60580
60527
|
import { promises as fs2 } from "node:fs";
|
|
60581
|
-
import { join as
|
|
60528
|
+
import { join as join3, relative, resolve } from "node:path";
|
|
60582
60529
|
var DEFAULT_IGNORES = [
|
|
60583
60530
|
"__pycache__",
|
|
60584
60531
|
".DS_Store",
|
|
@@ -60596,7 +60543,7 @@ var DEFAULT_IGNORES = [
|
|
|
60596
60543
|
];
|
|
60597
60544
|
async function extendPatterns(basePatterns, dirPath) {
|
|
60598
60545
|
try {
|
|
60599
|
-
const gitignorePath =
|
|
60546
|
+
const gitignorePath = join3(dirPath, ".gitignore");
|
|
60600
60547
|
const content = await fs2.readFile(gitignorePath, "utf8");
|
|
60601
60548
|
const lines2 = content.split(/\r?\n/).filter(Boolean);
|
|
60602
60549
|
return [...basePatterns, ...lines2];
|
|
@@ -60610,7 +60557,7 @@ function createIgnore(patterns) {
|
|
|
60610
60557
|
async function listFiles(dirPath, recursive, maxCount, cwd, excludeFiles) {
|
|
60611
60558
|
let rootPatterns = [...DEFAULT_IGNORES, ...excludeFiles || []];
|
|
60612
60559
|
try {
|
|
60613
|
-
const rootGitignore = await fs2.readFile(
|
|
60560
|
+
const rootGitignore = await fs2.readFile(join3(cwd, ".gitignore"), "utf8");
|
|
60614
60561
|
const lines2 = rootGitignore.split(/\r?\n/).filter(Boolean);
|
|
60615
60562
|
rootPatterns = [...rootPatterns, ...lines2];
|
|
60616
60563
|
} catch {}
|
|
@@ -60631,7 +60578,7 @@ async function listFiles(dirPath, recursive, maxCount, cwd, excludeFiles) {
|
|
|
60631
60578
|
const entries = await fs2.readdir(currentPath, { withFileTypes: true });
|
|
60632
60579
|
entries.sort((a2, b2) => a2.name.localeCompare(b2.name));
|
|
60633
60580
|
for (const entry of entries) {
|
|
60634
|
-
const fullPath =
|
|
60581
|
+
const fullPath = join3(currentPath, entry.name);
|
|
60635
60582
|
const relPath = relative(cwd, fullPath).replace(/\\/g, "/");
|
|
60636
60583
|
if (folderIg.ignores(relPath)) {
|
|
60637
60584
|
continue;
|
|
@@ -60648,7 +60595,7 @@ async function listFiles(dirPath, recursive, maxCount, cwd, excludeFiles) {
|
|
|
60648
60595
|
results.push(relPath);
|
|
60649
60596
|
if (results.length >= maxCount) {
|
|
60650
60597
|
const remainingEntries = entries.slice(entries.indexOf(entry) + 1);
|
|
60651
|
-
const hasRemainingFiles = remainingEntries.some((e2) => !e2.isDirectory() && !folderIg.ignores(relative(cwd,
|
|
60598
|
+
const hasRemainingFiles = remainingEntries.some((e2) => !e2.isDirectory() && !folderIg.ignores(relative(cwd, join3(currentPath, e2.name)).replace(/\\/g, "/")));
|
|
60652
60599
|
if (hasRemainingFiles) {
|
|
60653
60600
|
const marker = `${currentRelPath}/(files omitted)`;
|
|
60654
60601
|
results.push(marker);
|
|
@@ -60672,7 +60619,6 @@ async function listFiles(dirPath, recursive, maxCount, cwd, excludeFiles) {
|
|
|
60672
60619
|
|
|
60673
60620
|
// ../cli-shared/src/utils/searchFiles.ts
|
|
60674
60621
|
import { spawn } from "node:child_process";
|
|
60675
|
-
import { rgPath } from "@vscode/ripgrep";
|
|
60676
60622
|
async function searchFiles(path, regex, filePattern, cwd, excludeFiles) {
|
|
60677
60623
|
const args = [
|
|
60678
60624
|
"--line-number",
|
|
@@ -60697,7 +60643,7 @@ async function searchFiles(path, regex, filePattern, cwd, excludeFiles) {
|
|
|
60697
60643
|
args.push(regex, path);
|
|
60698
60644
|
return new Promise((resolve2, reject) => {
|
|
60699
60645
|
const results = [];
|
|
60700
|
-
const rg = spawn(
|
|
60646
|
+
const rg = spawn("rg", args, {
|
|
60701
60647
|
cwd,
|
|
60702
60648
|
stdio: ["ignore", "pipe", "pipe"]
|
|
60703
60649
|
});
|
|
@@ -60755,9 +60701,6 @@ var getProvider = (agentName, config2, options = {}) => {
|
|
|
60755
60701
|
listFiles: async (path, recursive, maxCount) => {
|
|
60756
60702
|
return await listFiles(path, recursive, maxCount, process.cwd(), options.excludeFiles);
|
|
60757
60703
|
},
|
|
60758
|
-
searchFiles: async (path, regex, filePattern) => {
|
|
60759
|
-
return await searchFiles(path, regex, filePattern, process.cwd(), options.excludeFiles);
|
|
60760
|
-
},
|
|
60761
60704
|
executeCommand: (command, needApprove) => {
|
|
60762
60705
|
return new Promise((resolve2, reject) => {
|
|
60763
60706
|
options.command?.onStarted(command);
|
|
@@ -60813,6 +60756,13 @@ var getProvider = (agentName, config2, options = {}) => {
|
|
|
60813
60756
|
return;
|
|
60814
60757
|
}
|
|
60815
60758
|
};
|
|
60759
|
+
if (checkRipgrep()) {
|
|
60760
|
+
provider2.searchFiles = async (path, regex, filePattern) => {
|
|
60761
|
+
return await searchFiles(path, regex, filePattern, process.cwd(), options.excludeFiles);
|
|
60762
|
+
};
|
|
60763
|
+
} else {
|
|
60764
|
+
console.error("Error: ripgrep (rg) is not installed. Search file tool is disabled. Please install it from https://github.com/BurntSushi/ripgrep#installation");
|
|
60765
|
+
}
|
|
60816
60766
|
return provider2;
|
|
60817
60767
|
};
|
|
60818
60768
|
// ../../node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
@@ -61582,7 +61532,7 @@ ${fileList.join(`
|
|
|
61582
61532
|
</files>`;
|
|
61583
61533
|
let knowledgeContent = "";
|
|
61584
61534
|
if (this.#hasKnowledgeManagementPolicy) {
|
|
61585
|
-
const knowledgeFilePath =
|
|
61535
|
+
const knowledgeFilePath = join4(cwd, "knowledge.ai.yml");
|
|
61586
61536
|
if (existsSync2(knowledgeFilePath)) {
|
|
61587
61537
|
try {
|
|
61588
61538
|
const content = await readFile2(knowledgeFilePath, "utf8");
|
|
@@ -61854,7 +61804,7 @@ var runChat = async (opts, command) => {
|
|
|
61854
61804
|
};
|
|
61855
61805
|
|
|
61856
61806
|
// src/commands/commit.ts
|
|
61857
|
-
import { execSync, spawnSync } from "node:child_process";
|
|
61807
|
+
import { execSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
61858
61808
|
|
|
61859
61809
|
// ../../node_modules/ora/index.js
|
|
61860
61810
|
import process10 from "node:process";
|
|
@@ -62511,7 +62461,7 @@ var commitCommand = new Command("commit").description("Create a commit with AI-g
|
|
|
62511
62461
|
Commit message:
|
|
62512
62462
|
${result.response}`);
|
|
62513
62463
|
try {
|
|
62514
|
-
|
|
62464
|
+
spawnSync2("git", ["commit", "-m", result.response], { stdio: "inherit" });
|
|
62515
62465
|
} catch {
|
|
62516
62466
|
console.error("Error: Commit failed");
|
|
62517
62467
|
process.exit(1);
|
|
@@ -62525,9 +62475,9 @@ ${result.response}`);
|
|
|
62525
62475
|
// src/commands/create.ts
|
|
62526
62476
|
import { existsSync as existsSync3 } from "node:fs";
|
|
62527
62477
|
import { mkdir as mkdir2, stat } from "node:fs/promises";
|
|
62528
|
-
import { join as
|
|
62478
|
+
import { join as join5 } from "node:path";
|
|
62529
62479
|
var askForPath = async (projectName) => {
|
|
62530
|
-
let targetPath =
|
|
62480
|
+
let targetPath = join5(process.cwd(), projectName);
|
|
62531
62481
|
while (true) {
|
|
62532
62482
|
const confirmPath = await esm_default2({
|
|
62533
62483
|
message: `Do you want to create project at ${targetPath}?`,
|
|
@@ -66627,7 +66577,7 @@ ${newConfig.provider.toUpperCase()}_API_KEY=${newConfig.apiKey}`;
|
|
|
66627
66577
|
});
|
|
66628
66578
|
|
|
66629
66579
|
// src/commands/pr.ts
|
|
66630
|
-
import { execSync as execSync2, spawnSync as
|
|
66580
|
+
import { execSync as execSync2, spawnSync as spawnSync3 } from "node:child_process";
|
|
66631
66581
|
var prCommand = new Command("pr").description("Create a GitHub pull request").argument("[message]", "Optional context for the commit message generation").action(async (message, _options, command) => {
|
|
66632
66582
|
const options = command.parent?.opts() ?? {};
|
|
66633
66583
|
const { providerConfig, config: config3 } = parseOptions(options);
|
|
@@ -66687,7 +66637,7 @@ var prCommand = new Command("pr").description("Create a GitHub pull request").ar
|
|
|
66687
66637
|
console.log("Title:", prDetails.response.title);
|
|
66688
66638
|
console.log(prDetails.response.description);
|
|
66689
66639
|
await new Promise((resolve2) => setTimeout(resolve2, 10));
|
|
66690
|
-
|
|
66640
|
+
spawnSync3("gh", ["pr", "create", "--title", prDetails.response.title.trim(), "--body", prDetails.response.description.trim()], {
|
|
66691
66641
|
stdio: "inherit"
|
|
66692
66642
|
});
|
|
66693
66643
|
usage.printUsage();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@polka-codes/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.22",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"author": "github@polka.codes",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
17
|
-
"build": "bun build src/index.ts --outdir dist --target node
|
|
17
|
+
"build": "bun build src/index.ts --outdir dist --target node"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@inquirer/prompts": "^7.2.3",
|