@polka-codes/cli-shared 0.8.20 → 0.8.21

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.
Files changed (2) hide show
  1. package/dist/index.js +146 -256
  2. package/package.json +1 -2
package/dist/index.js CHANGED
@@ -36783,39 +36783,6 @@ __export(exports_allTools, {
36783
36783
  askFollowupQuestion: () => askFollowupQuestion_default
36784
36784
  });
36785
36785
 
36786
- // ../core/src/tools/utils/editFile.ts
36787
- var START_OF_FILE = "<<<START_OF_FILE>>>";
36788
- var END_OF_FILE = "<<<END_OF_FILE>>>";
36789
- var editFile = async (fileContent, operations) => {
36790
- if (!operations || operations.length === 0) {
36791
- throw new Error("At least one edit operation is required");
36792
- }
36793
- let updatedContent = fileContent;
36794
- for (const operation of operations) {
36795
- updatedContent = await applyEditOperation(updatedContent, operation);
36796
- }
36797
- return updatedContent;
36798
- };
36799
- async function applyEditOperation(fileContent, operation) {
36800
- const { search, replace } = operation;
36801
- if (search === START_OF_FILE && replace === END_OF_FILE) {
36802
- throw new Error("Cannot search for START_OF_FILE and replace with END_OF_FILE");
36803
- }
36804
- if (search === END_OF_FILE && replace === START_OF_FILE) {
36805
- throw new Error("Cannot search for END_OF_FILE and replace with START_OF_FILE");
36806
- }
36807
- if (search === START_OF_FILE) {
36808
- return replace + fileContent;
36809
- }
36810
- if (search === END_OF_FILE) {
36811
- return fileContent + replace;
36812
- }
36813
- const index = fileContent.indexOf(search);
36814
- if (index === -1) {
36815
- throw new Error(`Could not find text: ${search}`);
36816
- }
36817
- return fileContent.slice(0, index) + replace + fileContent.slice(index + search.length);
36818
- }
36819
36786
  // ../core/src/tools/utils/getArg.ts
36820
36787
  var getString = (args, name, defaultValue) => {
36821
36788
  if (typeof args !== "object" || Array.isArray(args)) {
@@ -37422,29 +37389,29 @@ var toolInfo7 = {
37422
37389
  {
37423
37390
  name: "diff",
37424
37391
  description: `One or more SEARCH/REPLACE blocks following this exact format:
37425
- \`\`\`
37426
- <<<<<<< SEARCH
37427
- [exact content to find]
37428
- =======
37429
- [new content to replace with]
37430
- >>>>>>> REPLACE
37431
- \`\`\`
37432
- Critical rules:
37433
- 1. SEARCH content must match the associated file section to find EXACTLY:
37434
- * Match character-for-character including whitespace, indentation, line endings
37435
- * Include all comments, docstrings, etc.
37436
- 2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
37437
- * Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
37438
- * Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
37439
- * When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
37440
- 3. Keep SEARCH/REPLACE blocks concise:
37441
- * Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
37442
- * Include just the changing lines, and a few surrounding lines if needed for uniqueness.
37443
- * Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
37444
- * Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
37445
- 4. Special operations:
37446
- * To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
37447
- * To delete code: Use empty REPLACE section`,
37392
+ \`\`\`
37393
+ <<<<<<< SEARCH
37394
+ [exact content to find]
37395
+ =======
37396
+ [new content to replace with]
37397
+ >>>>>>> REPLACE
37398
+ \`\`\`
37399
+ Critical rules:
37400
+ 1. SEARCH content must match the associated file section to find EXACTLY:
37401
+ * Match character-for-character including whitespace, indentation, line endings
37402
+ * Include all comments, docstrings, etc.
37403
+ 2. SEARCH/REPLACE blocks will ONLY replace the first match occurrence.
37404
+ * Including multiple unique SEARCH/REPLACE blocks if you need to make multiple changes.
37405
+ * Include *just* enough lines in each SEARCH section to uniquely match each set of lines that need to change.
37406
+ * When using multiple SEARCH/REPLACE blocks, list them in the order they appear in the file.
37407
+ 3. Keep SEARCH/REPLACE blocks concise:
37408
+ * Break large SEARCH/REPLACE blocks into a series of smaller blocks that each change a small portion of the file.
37409
+ * Include just the changing lines, and a few surrounding lines if needed for uniqueness.
37410
+ * Do not include long runs of unchanging lines in SEARCH/REPLACE blocks.
37411
+ * Each line must be complete. Never truncate lines mid-way through as this can cause matching failures.
37412
+ 4. Special operations:
37413
+ * To move code: Use two SEARCH/REPLACE blocks (one to delete from original + one to insert at new location)
37414
+ * To delete code: Use empty REPLACE section`,
37448
37415
  required: true,
37449
37416
  usageValue: "Search and replace blocks here"
37450
37417
  }
@@ -37487,6 +37454,73 @@ function handleSubmit() {
37487
37454
  return (
37488
37455
  <div>
37489
37456
  >>>>>>> REPLACE
37457
+ `
37458
+ }
37459
+ ]
37460
+ },
37461
+ {
37462
+ description: "Request to perform a simple, single-line replacement",
37463
+ parameters: [
37464
+ {
37465
+ name: "path",
37466
+ value: "src/config.js"
37467
+ },
37468
+ {
37469
+ name: "diff",
37470
+ value: `
37471
+ <<<<<<< SEARCH
37472
+ const API_URL = 'https://api.example.com';
37473
+ =======
37474
+ const API_URL = 'https://api.staging.example.com';
37475
+ >>>>>>> REPLACE
37476
+ `
37477
+ }
37478
+ ]
37479
+ },
37480
+ {
37481
+ description: "Request to add a new function to a file",
37482
+ parameters: [
37483
+ {
37484
+ name: "path",
37485
+ value: "src/utils.js"
37486
+ },
37487
+ {
37488
+ name: "diff",
37489
+ value: `
37490
+ <<<<<<< SEARCH
37491
+ function helperA() {
37492
+ // ...
37493
+ }
37494
+ =======
37495
+ function helperA() {
37496
+ // ...
37497
+ }
37498
+
37499
+ function newHelper() {
37500
+ // implementation
37501
+ }
37502
+ >>>>>>> REPLACE
37503
+ `
37504
+ }
37505
+ ]
37506
+ },
37507
+ {
37508
+ description: "Request to delete a block of code from a file",
37509
+ parameters: [
37510
+ {
37511
+ name: "path",
37512
+ value: "src/app.js"
37513
+ },
37514
+ {
37515
+ name: "diff",
37516
+ value: `
37517
+ <<<<<<< SEARCH
37518
+ function oldFeature() {
37519
+ // This is no longer needed
37520
+ }
37521
+
37522
+ =======
37523
+ >>>>>>> REPLACE
37490
37524
  `
37491
37525
  }
37492
37526
  ]
@@ -38111,167 +38145,6 @@ var renameFile_default = {
38111
38145
  handler: handler13,
38112
38146
  isAvailable: isAvailable13
38113
38147
  };
38114
- // ../core/src/tools/editFile.ts
38115
- var toolInfo14 = {
38116
- name: "edit_file",
38117
- description: "Request to edit file contents using search/replace operations. Supports multiple edit operations in a single call.",
38118
- parameters: [
38119
- {
38120
- name: "path",
38121
- description: "The path of the file to edit",
38122
- required: true,
38123
- usageValue: "File path here"
38124
- },
38125
- {
38126
- name: "operations",
38127
- description: "Edit operation with search and replace parameters",
38128
- required: true,
38129
- allowMultiple: true,
38130
- children: [
38131
- {
38132
- name: "search",
38133
- description: `Text to search for and replace (use ${START_OF_FILE} to insert at file start, ${END_OF_FILE} to insert at file end)`,
38134
- required: true,
38135
- usageValue: "Text to find and replace"
38136
- },
38137
- {
38138
- name: "replace",
38139
- description: "Text to replace the search text with",
38140
- required: true,
38141
- usageValue: "Replacement text"
38142
- }
38143
- ],
38144
- usageValue: "operations here"
38145
- }
38146
- ],
38147
- examples: [
38148
- {
38149
- description: "Replace specific text",
38150
- parameters: [
38151
- {
38152
- name: "path",
38153
- value: "src/main.ts"
38154
- },
38155
- {
38156
- name: "operations",
38157
- value: {
38158
- search: `function oldFunction() {
38159
- return 42;
38160
- }`,
38161
- replace: `function newFunction() {
38162
- return "new implementation";
38163
- }`
38164
- }
38165
- }
38166
- ]
38167
- },
38168
- {
38169
- description: "Insert at start of file",
38170
- parameters: [
38171
- {
38172
- name: "path",
38173
- value: "src/header.ts"
38174
- },
38175
- {
38176
- name: "operations",
38177
- value: {
38178
- search: START_OF_FILE,
38179
- replace: `// File header comment
38180
- `
38181
- }
38182
- }
38183
- ]
38184
- },
38185
- {
38186
- description: "Multiple operations in one call",
38187
- parameters: [
38188
- {
38189
- name: "path",
38190
- value: "src/utils.ts"
38191
- },
38192
- {
38193
- name: "operations",
38194
- value: [
38195
- {
38196
- search: 'import React from "react"',
38197
- replace: 'import React, { useState } from "react"'
38198
- },
38199
- {
38200
- search: `function Component() {
38201
- return (`,
38202
- replace: `function Component() {
38203
- const [state, setState] = useState(false);
38204
- return (`
38205
- }
38206
- ]
38207
- }
38208
- ]
38209
- },
38210
- {
38211
- description: "Append content at end of file",
38212
- parameters: [
38213
- {
38214
- name: "path",
38215
- value: "src/footer.ts"
38216
- },
38217
- {
38218
- name: "operations",
38219
- value: {
38220
- search: END_OF_FILE,
38221
- replace: `
38222
- // End of file appended comment
38223
- `
38224
- }
38225
- }
38226
- ]
38227
- }
38228
- ],
38229
- permissionLevel: 2 /* Write */
38230
- };
38231
- var handler14 = async (provider, args) => {
38232
- if (!provider.readFile || !provider.writeFile) {
38233
- return {
38234
- type: "Error" /* Error */,
38235
- message: "Not possible to edit file. Abort."
38236
- };
38237
- }
38238
- const path = getString(args, "path");
38239
- const operations = getArray(args, "operations");
38240
- if (!operations || operations.length === 0) {
38241
- return {
38242
- type: "Error" /* Error */,
38243
- message: `<error><edit_file_path>${path}</edit_file_path><error_message>At least one edit operation is required</error_message></error>`
38244
- };
38245
- }
38246
- const fileContent = await provider.readFile(path);
38247
- if (fileContent == null) {
38248
- return {
38249
- type: "Error" /* Error */,
38250
- message: `<error><edit_file_path>${path}</edit_file_path><error_message>File not found</error_message></error>`
38251
- };
38252
- }
38253
- try {
38254
- const result = await editFile(fileContent, operations);
38255
- await provider.writeFile(path, result);
38256
- return {
38257
- type: "Reply" /* Reply */,
38258
- message: `<edit_file_path>${path}</edit_file_path>`
38259
- };
38260
- } catch (error) {
38261
- return {
38262
- type: "Error" /* Error */,
38263
- message: `<error><edit_file_path>${path}</edit_file_path><error_message>${error instanceof Error ? error.message : String(error)}</error_message></error>`
38264
- };
38265
- }
38266
- };
38267
- var isAvailable14 = (provider) => {
38268
- return !!provider.readFile && !!provider.writeFile;
38269
- };
38270
- var editFile_default = {
38271
- ...toolInfo14,
38272
- handler: handler14,
38273
- isAvailable: isAvailable14
38274
- };
38275
38148
  // ../core/src/getAvailableTools.ts
38276
38149
  var getAvailableTools = ({
38277
38150
  provider: provider2,
@@ -38496,6 +38369,8 @@ Tool use is formatted using XML-style tags. The tool name is enclosed in opening
38496
38369
  ...
38497
38370
  </${toolNamePrefix}tool_name>
38498
38371
 
38372
+ **It is crucial that all tags are correctly nested and closed.**
38373
+
38499
38374
  ## Array Parameters
38500
38375
 
38501
38376
  To create an array of values for a parameter, repeat the parameter tag multiple times:
@@ -38530,7 +38405,7 @@ You can also combine array parameters with nested objects:
38530
38405
  </${parameterPrefix}key>
38531
38406
  </${toolNamePrefix}example_tool>
38532
38407
 
38533
- Always adhere to this format for the tool use to ensure proper parsing and execution.
38408
+ Always adhere to this format, ensuring every opening tag has a matching closing tag, to ensure proper parsing and execution.
38534
38409
 
38535
38410
  NEVER surround tool use with triple backticks (\`\`\`).
38536
38411
 
@@ -38869,8 +38744,8 @@ ${instance.prompt}`;
38869
38744
  }
38870
38745
  async#invokeTool(name, args) {
38871
38746
  try {
38872
- const handler15 = this.handlers[name]?.handler;
38873
- if (!handler15) {
38747
+ const handler14 = this.handlers[name]?.handler;
38748
+ if (!handler14) {
38874
38749
  return {
38875
38750
  type: "Error" /* Error */,
38876
38751
  message: responsePrompts.errorInvokeTool(name, "Tool not found"),
@@ -38889,7 +38764,7 @@ ${instance.prompt}`;
38889
38764
  if (resp) {
38890
38765
  return resp;
38891
38766
  }
38892
- return await handler15(this.config.provider, args);
38767
+ return await handler14(this.config.provider, args);
38893
38768
  } catch (error) {
38894
38769
  return {
38895
38770
  type: "Error" /* Error */,
@@ -48098,15 +47973,15 @@ function useKeypress(userHandler) {
48098
47973
  signal.current = userHandler;
48099
47974
  useEffect((rl) => {
48100
47975
  let ignore = false;
48101
- const handler15 = withUpdates((_input, event) => {
47976
+ const handler14 = withUpdates((_input, event) => {
48102
47977
  if (ignore)
48103
47978
  return;
48104
47979
  signal.current(event, rl);
48105
47980
  });
48106
- rl.input.on("keypress", handler15);
47981
+ rl.input.on("keypress", handler14);
48107
47982
  return () => {
48108
47983
  ignore = true;
48109
- rl.input.removeListener("keypress", handler15);
47984
+ rl.input.removeListener("keypress", handler14);
48110
47985
  };
48111
47986
  }, []);
48112
47987
  }
@@ -48288,16 +48163,16 @@ class Emitter {
48288
48163
 
48289
48164
  class SignalExitBase {
48290
48165
  }
48291
- var signalExitWrap = (handler15) => {
48166
+ var signalExitWrap = (handler14) => {
48292
48167
  return {
48293
48168
  onExit(cb, opts) {
48294
- return handler15.onExit(cb, opts);
48169
+ return handler14.onExit(cb, opts);
48295
48170
  },
48296
48171
  load() {
48297
- return handler15.load();
48172
+ return handler14.load();
48298
48173
  },
48299
48174
  unload() {
48300
- return handler15.unload();
48175
+ return handler14.unload();
48301
48176
  }
48302
48177
  };
48303
48178
  };
@@ -48813,6 +48688,24 @@ ${theme.style.description(selectedChoice.description)}` : ``;
48813
48688
  return `${[prefix, message, helpTipTop].filter(Boolean).join(" ")}
48814
48689
  ${page}${helpTipBottom}${choiceDescription}${import_ansi_escapes2.default.cursorHide}`;
48815
48690
  });
48691
+ // src/utils/checkRipgrep.ts
48692
+ import { spawnSync } from "node:child_process";
48693
+ var rgAvailability = {
48694
+ isAvailable: null
48695
+ };
48696
+ function checkRipgrep() {
48697
+ if (rgAvailability.isAvailable !== null) {
48698
+ return rgAvailability.isAvailable;
48699
+ }
48700
+ const rg = spawnSync("rg", ["--version"]);
48701
+ if (rg.error || rg.status !== 0) {
48702
+ rgAvailability.isAvailable = false;
48703
+ return false;
48704
+ }
48705
+ rgAvailability.isAvailable = true;
48706
+ return true;
48707
+ }
48708
+
48816
48709
  // src/utils/listFiles.ts
48817
48710
  var import_ignore = __toESM(require_ignore(), 1);
48818
48711
  import { promises as fs2 } from "node:fs";
@@ -48910,14 +48803,7 @@ async function listFiles(dirPath, recursive, maxCount, cwd, excludeFiles) {
48910
48803
 
48911
48804
  // src/utils/searchFiles.ts
48912
48805
  import { spawn } from "node:child_process";
48913
-
48914
- // ../../node_modules/@vscode/ripgrep/lib/index.js
48915
- var __dirname = "/Users/xiliangchen/projects/polka-codes/node_modules/@vscode/ripgrep/lib";
48916
- var path = __require("path");
48917
- var $rgPath = path.join(__dirname, `../bin/rg${process.platform === "win32" ? ".exe" : ""}`);
48918
-
48919
- // src/utils/searchFiles.ts
48920
- async function searchFiles(path2, regex, filePattern, cwd, excludeFiles) {
48806
+ async function searchFiles(path, regex, filePattern, cwd, excludeFiles) {
48921
48807
  const args = [
48922
48808
  "--line-number",
48923
48809
  "--context=5",
@@ -48938,10 +48824,10 @@ async function searchFiles(path2, regex, filePattern, cwd, excludeFiles) {
48938
48824
  args.push("--glob", `!${pattern}`);
48939
48825
  }
48940
48826
  }
48941
- args.push(regex, path2);
48827
+ args.push(regex, path);
48942
48828
  return new Promise((resolve2, reject) => {
48943
48829
  const results = [];
48944
- const rg = spawn($rgPath, args, {
48830
+ const rg = spawn("rg", args, {
48945
48831
  cwd,
48946
48832
  stdio: ["ignore", "pipe", "pipe"]
48947
48833
  });
@@ -48967,28 +48853,28 @@ async function searchFiles(path2, regex, filePattern, cwd, excludeFiles) {
48967
48853
  var getProvider = (agentName, config2, options = {}) => {
48968
48854
  const ig = import_ignore2.default().add(options.excludeFiles ?? []);
48969
48855
  const provider2 = {
48970
- readFile: async (path2) => {
48971
- if (ig.ignores(path2)) {
48972
- throw new Error(`Not allow to access file ${path2}`);
48856
+ readFile: async (path) => {
48857
+ if (ig.ignores(path)) {
48858
+ throw new Error(`Not allow to access file ${path}`);
48973
48859
  }
48974
48860
  try {
48975
- return await readFile(path2, "utf8");
48861
+ return await readFile(path, "utf8");
48976
48862
  } catch (_e2) {
48977
48863
  return;
48978
48864
  }
48979
48865
  },
48980
- writeFile: async (path2, content) => {
48981
- if (ig.ignores(path2)) {
48982
- throw new Error(`Not allow to access file ${path2}`);
48866
+ writeFile: async (path, content) => {
48867
+ if (ig.ignores(path)) {
48868
+ throw new Error(`Not allow to access file ${path}`);
48983
48869
  }
48984
- await mkdir(dirname(path2), { recursive: true });
48985
- return await writeFile(path2, content, "utf8");
48870
+ await mkdir(dirname(path), { recursive: true });
48871
+ return await writeFile(path, content, "utf8");
48986
48872
  },
48987
- removeFile: async (path2) => {
48988
- if (ig.ignores(path2)) {
48989
- throw new Error(`Not allow to access file ${path2}`);
48873
+ removeFile: async (path) => {
48874
+ if (ig.ignores(path)) {
48875
+ throw new Error(`Not allow to access file ${path}`);
48990
48876
  }
48991
- return await unlink(path2);
48877
+ return await unlink(path);
48992
48878
  },
48993
48879
  renameFile: async (sourcePath, targetPath) => {
48994
48880
  if (ig.ignores(sourcePath) || ig.ignores(targetPath)) {
@@ -48996,11 +48882,8 @@ var getProvider = (agentName, config2, options = {}) => {
48996
48882
  }
48997
48883
  return await rename(sourcePath, targetPath);
48998
48884
  },
48999
- listFiles: async (path2, recursive, maxCount) => {
49000
- return await listFiles(path2, recursive, maxCount, process.cwd(), options.excludeFiles);
49001
- },
49002
- searchFiles: async (path2, regex, filePattern) => {
49003
- return await searchFiles(path2, regex, filePattern, process.cwd(), options.excludeFiles);
48885
+ listFiles: async (path, recursive, maxCount) => {
48886
+ return await listFiles(path, recursive, maxCount, process.cwd(), options.excludeFiles);
49004
48887
  },
49005
48888
  executeCommand: (command, needApprove) => {
49006
48889
  return new Promise((resolve2, reject) => {
@@ -49057,6 +48940,13 @@ var getProvider = (agentName, config2, options = {}) => {
49057
48940
  return;
49058
48941
  }
49059
48942
  };
48943
+ if (checkRipgrep()) {
48944
+ provider2.searchFiles = async (path, regex, filePattern) => {
48945
+ return await searchFiles(path, regex, filePattern, process.cwd(), options.excludeFiles);
48946
+ };
48947
+ } else {
48948
+ console.error("Error: ripgrep (rg) is not installed. Search file tool is disabled. Please install it from https://github.com/BurntSushi/ripgrep#installation");
48949
+ }
49060
48950
  return provider2;
49061
48951
  };
49062
48952
  // ../../node_modules/chalk/source/vendor/ansi-styles/index.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polka-codes/cli-shared",
3
- "version": "0.8.20",
3
+ "version": "0.8.21",
4
4
  "license": "AGPL-3.0",
5
5
  "author": "github@polka.codes",
6
6
  "type": "module",
@@ -16,7 +16,6 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "@polka-codes/core": "0.8.10",
19
- "@vscode/ripgrep": "^1.15.10",
20
19
  "ignore": "^7.0.3",
21
20
  "lodash": "^4.17.21",
22
21
  "yaml": "^2.7.0",