@polka-codes/cli 0.9.90 → 0.9.92

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 CHANGED
@@ -16534,12 +16534,12 @@ var init_memory = __esm(() => {
16534
16534
  memoryConfigSchema = exports_external.object({
16535
16535
  enabled: exports_external.boolean().optional().default(true),
16536
16536
  type: exports_external.enum(["sqlite", "memory"]).optional().default("sqlite"),
16537
- path: exports_external.string().optional().default("~/.config/polka-codes/memory.sqlite")
16537
+ path: exports_external.string().optional().default("~/.config/polkacodes/memory/memory.sqlite")
16538
16538
  }).strict().optional();
16539
16539
  DEFAULT_MEMORY_CONFIG = {
16540
16540
  enabled: true,
16541
16541
  type: "sqlite",
16542
- path: "~/.config/polka-codes/memory.sqlite"
16542
+ path: "~/.config/polkacodes/memory/memory.sqlite"
16543
16543
  };
16544
16544
  });
16545
16545
 
@@ -25517,6 +25517,7 @@ var init_tools2 = __esm(() => {
25517
25517
  // ../core/src/UsageMeter.ts
25518
25518
  class UsageMeter {
25519
25519
  #totals = { input: 0, output: 0, cachedRead: 0, cost: 0, messageCount: 0 };
25520
+ #providerMetadataEntries = [];
25520
25521
  #modelInfos;
25521
25522
  #maxMessages;
25522
25523
  #maxCost;
@@ -25598,8 +25599,17 @@ class UsageMeter {
25598
25599
  this.#totals.cachedRead += result.cachedRead || 0;
25599
25600
  this.#totals.cost += result.cost || 0;
25600
25601
  this.#totals.messageCount += 1;
25602
+ if (resp.providerMetadata && Object.keys(resp.providerMetadata).length > 0) {
25603
+ const providerKey = Object.keys(resp.providerMetadata)[0];
25604
+ this.#providerMetadataEntries.push({
25605
+ provider: providerKey || llm.provider,
25606
+ model: llm.modelId,
25607
+ metadata: resp.providerMetadata[providerKey] || resp.providerMetadata,
25608
+ timestamp: Date.now()
25609
+ });
25610
+ }
25601
25611
  }
25602
- setUsage(newUsage) {
25612
+ setUsage(newUsage, options = {}) {
25603
25613
  if (newUsage.input != null)
25604
25614
  this.#totals.input = newUsage.input;
25605
25615
  if (newUsage.output != null)
@@ -25610,12 +25620,16 @@ class UsageMeter {
25610
25620
  this.#totals.cost = newUsage.cost;
25611
25621
  if (newUsage.messageCount != null)
25612
25622
  this.#totals.messageCount = newUsage.messageCount;
25623
+ if (options.clearMetadata) {
25624
+ this.#providerMetadataEntries = [];
25625
+ }
25613
25626
  }
25614
25627
  incrementMessageCount(n = 1) {
25615
25628
  this.#totals.messageCount += n;
25616
25629
  }
25617
25630
  resetUsage() {
25618
25631
  this.#totals = { input: 0, output: 0, cachedRead: 0, cost: 0, messageCount: 0 };
25632
+ this.#providerMetadataEntries = [];
25619
25633
  }
25620
25634
  isLimitExceeded() {
25621
25635
  const messageCount = this.#maxMessages > 0 && this.#totals.messageCount >= this.#maxMessages;
@@ -25637,6 +25651,34 @@ class UsageMeter {
25637
25651
  get usage() {
25638
25652
  return { ...this.#totals };
25639
25653
  }
25654
+ get providerMetadata() {
25655
+ return [...this.#providerMetadataEntries];
25656
+ }
25657
+ get cacheStats() {
25658
+ const entries = this.#providerMetadataEntries;
25659
+ const totalRequests = entries.length;
25660
+ let totalCachedTokens = 0;
25661
+ let requestsWithCache = 0;
25662
+ for (const entry of entries) {
25663
+ const metadata = entry.metadata;
25664
+ const cachedTokens = metadata.cachedPromptTokens ?? metadata.cacheReadTokens ?? metadata.prompt_cache_hit_tokens ?? 0;
25665
+ if (cachedTokens > 0) {
25666
+ totalCachedTokens += cachedTokens;
25667
+ requestsWithCache++;
25668
+ }
25669
+ }
25670
+ const cacheHitRate = totalRequests > 0 ? requestsWithCache / totalRequests : 0;
25671
+ return {
25672
+ totalCachedTokens,
25673
+ totalRequests,
25674
+ requestsWithCache,
25675
+ cacheHitRate,
25676
+ entries: [...this.#providerMetadataEntries]
25677
+ };
25678
+ }
25679
+ clearProviderMetadata() {
25680
+ this.#providerMetadataEntries = [];
25681
+ }
25640
25682
  merge(other) {
25641
25683
  const otherUsage = other.usage;
25642
25684
  this.#totals.input += otherUsage.input;
@@ -25644,6 +25686,7 @@ class UsageMeter {
25644
25686
  this.#totals.cachedRead += otherUsage.cachedRead;
25645
25687
  this.#totals.cost += otherUsage.cost;
25646
25688
  this.#totals.messageCount += otherUsage.messageCount;
25689
+ this.#providerMetadataEntries.push(...other.providerMetadata);
25647
25690
  }
25648
25691
  getUsageText() {
25649
25692
  const u = this.usage;
@@ -73481,7 +73524,7 @@ var init_provider = __esm(() => {
73481
73524
 
73482
73525
  // ../../node_modules/sql.js/dist/sql-wasm.js
73483
73526
  var require_sql_wasm = __commonJS((exports, module) => {
73484
- var __dirname = "/Users/xiliangchen/projects/polka-codes/node_modules/sql.js/dist";
73527
+ var __dirname = "/home/ubuntu/polka-codes/node_modules/sql.js/dist";
73485
73528
  var initSqlJsPromise = undefined;
73486
73529
  var initSqlJs = function(moduleConfig) {
73487
73530
  if (initSqlJsPromise) {
@@ -75769,6 +75812,7 @@ import { randomUUID } from "node:crypto";
75769
75812
  import { existsSync as existsSync4 } from "node:fs";
75770
75813
  import { mkdir as mkdir2, readFile as readFile4, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
75771
75814
  import { dirname as dirname3, resolve as resolve5 } from "node:path";
75815
+ import { fileURLToPath } from "node:url";
75772
75816
 
75773
75817
  class FileLock {
75774
75818
  lockfilePath;
@@ -75875,7 +75919,24 @@ async function getSqlJs() {
75875
75919
  if (SqlJsInitPromise) {
75876
75920
  return SqlJsInitPromise;
75877
75921
  }
75878
- SqlJsInitPromise = import_sql.default({});
75922
+ const moduleDir = dirname3(fileURLToPath(import.meta.url));
75923
+ const candidates = [
75924
+ resolve5(moduleDir, "sql-wasm.wasm"),
75925
+ resolve5(moduleDir, "..", "dist", "sql-wasm.wasm"),
75926
+ resolve5(moduleDir, "..", "node_modules", "sql.js", "dist", "sql-wasm.wasm"),
75927
+ resolve5(moduleDir, "..", "..", "..", "node_modules", "sql.js", "dist", "sql-wasm.wasm"),
75928
+ resolve5(process.cwd(), "node_modules", "sql.js", "dist", "sql-wasm.wasm")
75929
+ ];
75930
+ SqlJsInitPromise = import_sql.default({
75931
+ locateFile: (file2) => {
75932
+ for (const candidate of candidates) {
75933
+ if (existsSync4(candidate)) {
75934
+ return candidate;
75935
+ }
75936
+ }
75937
+ return file2;
75938
+ }
75939
+ });
75879
75940
  SqlJs = await SqlJsInitPromise;
75880
75941
  return SqlJs;
75881
75942
  }
@@ -77730,15 +77791,15 @@ ${value}
77730
77791
  }
77731
77792
  function getReviewInstructions(params) {
77732
77793
  if (params.targetCommit) {
77733
- return `Review the changes in commit '${params.targetCommit}'. The gitDiff tool is NOT available for past commits. Use readFile to inspect the file contents and identify issues in the modified files listed in <file_status>.`;
77794
+ return `Review the changes in commit '${params.targetCommit}'. Use the gitDiff tool with the file parameter to inspect what changed in each file. Focus your review on the actual changes shown in the diff.`;
77734
77795
  }
77735
77796
  if (params.commitRange) {
77736
- return `Review the pull request. Use the gitDiff tool with commit range '${params.commitRange}' to inspect the actual code changes.`;
77797
+ return `Review the pull request or commit range '${params.commitRange}'. Use the gitDiff tool with the file parameter to inspect the actual code changes.`;
77737
77798
  }
77738
77799
  if (params.staged) {
77739
- return "Review the staged changes. Use the gitDiff tool with staged: true to inspect the actual code changes.";
77800
+ return "Review the staged changes. Use the gitDiff tool with the file parameter and staged: true to inspect the actual code changes.";
77740
77801
  }
77741
- return "Review the unstaged changes. Use the gitDiff tool to inspect the actual code changes.";
77802
+ return "Review the unstaged changes. Use the gitDiff tool with the file parameter to inspect the actual code changes.";
77742
77803
  }
77743
77804
  function formatReviewToolInput(params) {
77744
77805
  const fileList = params.changedFiles && params.changedFiles.length > 0 ? params.changedFiles.map((file2) => {
@@ -77777,18 +77838,20 @@ ${TOOL_USAGE_INSTRUCTION}
77777
77838
  - **Include**: Source code, config files, and template files.
77778
77839
  - **Exclude**: Lockfiles, build artifacts, test snapshots, binary/media files, data and fixtures and other generated files.
77779
77840
  3. **Inspect Changes**:
77780
- - When the \`gitDiff\` tool is available: Use it on one file at a time to see the exact changes. When reviewing pull requests, use the \`commitRange\` parameter provided in the review instructions.
77781
- - When the \`gitDiff\` tool is NOT available (reviewing past commits): Use \`readFile\` to inspect the file contents. You will not have access to the exact diff, so focus on reviewing the code for issues in the modified files listed in \`<file_status>\`.
77841
+ - The \`gitDiff\` tool is ALWAYS available for reviewing changes.
77842
+ - When reviewing pull requests or commit ranges: Use \`gitDiff\` with the file parameter to see exact changes.
77843
+ - When reviewing local changes: Use \`gitDiff\` with staged: true for staged changes, or without parameters for unstaged changes.
77844
+ - When reviewing a specific commit: Use \`gitDiff\` with the file parameter to see what changed in that commit.
77782
77845
  4. **Analyze and Review**: Analyze the code for issues. When using \`gitDiff\`, focus only on the modified lines (additions/deletions). Provide specific, actionable feedback with accurate line numbers.
77783
77846
 
77784
77847
  ## Critical Rules
77785
77848
 
77786
- - **Focus on Changes**: When using \`gitDiff\`, ONLY review the actual changes shown in the diff. Do not comment on existing, unmodified code. When \`gitDiff\` is not available, focus on the modified files listed in \`<file_status>\`.
77849
+ - **Focus on Changes**: When using \`gitDiff\`, ONLY review the actual changes shown in the diff. Do not comment on existing, unmodified code.
77787
77850
  - **Focus Scope**: Do not comment on overall project structure or architecture unless directly impacted by the changes in the diff.
77788
77851
  - **No Feature Requests**: Do not comment on missing features or functionality that are not part of this diff.
77789
- - **One File at a Time**: Review files individually using \`gitDiff\` (when available) with the specific file path, or \`readFile\` when reviewing past commits.
77790
- - **No Empty Diffs**: MUST NOT call \`gitDiff\` with an empty or omitted file parameter when the tool is available.
77791
- - **Accurate Line Numbers**: When using \`gitDiff\`, use the line numbers from the diff annotations (\`[Line N]\` for additions, \`[Line N removed]\` for deletions). When \`gitDiff\` is not available, use line numbers from \`readFile\` output.
77852
+ - **One File at a Time**: Review files individually using \`gitDiff\` with the specific file path.
77853
+ - **No Empty Diffs**: MUST NOT call \`gitDiff\` with an empty or omitted file parameter. Always specify a file path.
77854
+ - **Accurate Line Numbers**: When using \`gitDiff\`, use the line numbers from the diff annotations (\`[Line N]\` for additions, \`[Line N removed]\` for deletions).
77792
77855
  - **No Praise**: Provide only reviews for actual issues found. Do not include praise or positive feedback.
77793
77856
  - **Clear Reasoning**: For each issue, provide clear reasoning explaining why it's a problem and what the impact could be.
77794
77857
  - **Specific Advice**: Avoid generic advice. Provide concrete, actionable suggestions specific to the code being reviewed.
@@ -94005,9 +94068,9 @@ function createGitReadBinaryFile(commit2) {
94005
94068
  }
94006
94069
  };
94007
94070
  }
94008
- const result = await provider3.executeCommand(`git show ${quotedCommit}:${quotedUrl} | base64`, false);
94071
+ const result = await provider3.executeCommand(`git show ${quotedCommit}:${quotedUrl}`, false);
94009
94072
  if (result.exitCode === 0) {
94010
- const base64Data = result.stdout.replace(/\n/g, "");
94073
+ const base64Data = Buffer.from(result.stdout, "binary").toString("base64");
94011
94074
  return {
94012
94075
  success: true,
94013
94076
  message: {
@@ -94044,6 +94107,91 @@ function createGitAwareTools(commit2) {
94044
94107
  readBinaryFile: createGitReadBinaryFile(commit2)
94045
94108
  };
94046
94109
  }
94110
+ function createGitAwareDiff(commit2) {
94111
+ const toolInfo20 = {
94112
+ name: "git_diff",
94113
+ description: `Get the git diff for commit ${commit2}. Shows the exact changes introduced by this specific commit. Use this to inspect what changed in each file. Always specify a file path.`,
94114
+ parameters: exports_external.object({
94115
+ file: exports_external.string().describe("Get the diff for a specific file within the commit. This parameter is required.").meta({ usageValue: "File path here (required)" }),
94116
+ contextLines: exports_external.coerce.number().int().min(0).optional().default(5).describe("Number of context lines to include around changes.").meta({ usageValue: "Context lines count (optional)" }),
94117
+ includeLineNumbers: exports_external.preprocess((val) => {
94118
+ if (typeof val === "string") {
94119
+ const lower2 = val.toLowerCase();
94120
+ if (lower2 === "false")
94121
+ return false;
94122
+ if (lower2 === "true")
94123
+ return true;
94124
+ }
94125
+ return val;
94126
+ }, exports_external.boolean().optional().default(true)).describe("Annotate the diff with line numbers for additions and deletions.").meta({ usageValue: "true or false (optional)" })
94127
+ })
94128
+ };
94129
+ const handler20 = async (provider3, args) => {
94130
+ if (!provider3.executeCommand) {
94131
+ return {
94132
+ success: false,
94133
+ message: {
94134
+ type: "error-text",
94135
+ value: "Not possible to execute command."
94136
+ }
94137
+ };
94138
+ }
94139
+ const { file: file2, contextLines, includeLineNumbers } = toolInfo20.parameters.parse(args);
94140
+ const quotedCommit = quoteForShell(commit2);
94141
+ let command = `git show --no-color --format= -U${contextLines} ${quotedCommit}`;
94142
+ if (file2) {
94143
+ const quotedFile = quoteForShell(file2);
94144
+ command = `git show --no-color --format= -U${contextLines} ${quotedCommit} -- ${quotedFile}`;
94145
+ }
94146
+ try {
94147
+ const result = await provider3.executeCommand(command, false);
94148
+ if (result.exitCode === 0) {
94149
+ if (!result.stdout.trim()) {
94150
+ return {
94151
+ success: true,
94152
+ message: {
94153
+ type: "text",
94154
+ value: "No diff found."
94155
+ }
94156
+ };
94157
+ }
94158
+ let diffOutput = result.stdout;
94159
+ if (includeLineNumbers) {
94160
+ diffOutput = annotateDiffWithLineNumbers(diffOutput);
94161
+ }
94162
+ return {
94163
+ success: true,
94164
+ message: {
94165
+ type: "text",
94166
+ value: `<diff file="${file2 ?? "all"}">
94167
+ ${diffOutput}
94168
+ </diff>`
94169
+ }
94170
+ };
94171
+ }
94172
+ return {
94173
+ success: false,
94174
+ message: {
94175
+ type: "error-text",
94176
+ value: `\`${command}\` exited with code ${result.exitCode}:
94177
+ ${result.stderr}`
94178
+ }
94179
+ };
94180
+ } catch (error48) {
94181
+ return {
94182
+ success: false,
94183
+ message: {
94184
+ type: "error-text",
94185
+ value: error48 instanceof Error ? error48.message : String(error48)
94186
+ }
94187
+ };
94188
+ }
94189
+ };
94190
+ return {
94191
+ ...toolInfo20,
94192
+ handler: handler20
94193
+ };
94194
+ }
94047
94195
  var init_git_file_tools = __esm(() => {
94048
94196
  init_zod();
94049
94197
  });
@@ -94336,10 +94484,10 @@ var reviewWorkflow = async (input, context) => {
94336
94484
  return { overview: "No changes to review.", specificReviews: [] };
94337
94485
  }
94338
94486
  const targetCommit = extractTargetCommit(range, pr2);
94339
- const isReviewingCommit = targetCommit !== null;
94340
- const finalChangeInfo = targetCommit ? { ...changeInfo, targetCommit } : changeInfo;
94341
- const fileTools = isReviewingCommit && targetCommit ? createGitAwareTools(targetCommit) : { readFile: readFile_default, listFiles: listFiles_default, readBinaryFile: readBinaryFile_default };
94342
- const reviewTools = isReviewingCommit ? [fileTools.readFile, fileTools.readBinaryFile, fileTools.listFiles] : [readFile_default, readBinaryFile_default, searchFiles_default, listFiles_default, gitDiff_default];
94487
+ const isRange = range?.includes("..");
94488
+ const finalChangeInfo = targetCommit && !isRange ? { ...changeInfo, targetCommit } : changeInfo;
94489
+ const fileTools = targetCommit && !isRange ? createGitAwareTools(targetCommit) : { readFile: readFile_default, listFiles: listFiles_default, readBinaryFile: readBinaryFile_default };
94490
+ const reviewTools = targetCommit && !isRange ? [fileTools.readFile, fileTools.readBinaryFile, fileTools.listFiles, createGitAwareDiff(targetCommit)] : [readFile_default, readBinaryFile_default, searchFiles_default, listFiles_default, gitDiff_default];
94343
94491
  const result = await step("review", async () => {
94344
94492
  const defaultContext = await getDefaultContext("review");
94345
94493
  const memoryContext = await tools3.getMemoryContext();
@@ -112131,7 +112279,7 @@ var {
112131
112279
  Help
112132
112280
  } = import__.default;
112133
112281
  // package.json
112134
- var version = "0.9.90";
112282
+ var version = "0.9.92";
112135
112283
 
112136
112284
  // src/commands/agent.ts
112137
112285
  init_src();
@@ -115346,7 +115494,7 @@ class TaskHistory {
115346
115494
  return r2.actualTime === 0 ? 0 : 100;
115347
115495
  }
115348
115496
  return Math.abs((r2.estimatedTime - r2.actualTime) / r2.estimatedTime) * 100;
115349
- }).filter((e2) => !isNaN(e2));
115497
+ }).filter((e2) => !Number.isNaN(e2));
115350
115498
  const avgErrorPercentage = errorPercentages.reduce((sum, e2) => sum + e2, 0) / errorPercentages.length;
115351
115499
  return {
115352
115500
  averageError: avgError,
@@ -120828,8 +120976,8 @@ async function memoryStatus() {
120828
120976
  const stats = await store.getStats();
120829
120977
  const globalConfigPath = getGlobalConfigPath();
120830
120978
  const config4 = await loadConfigAtPath(globalConfigPath);
120831
- const memoryConfig = config4?.memory || { path: "~/.config/polka-codes/memory.sqlite" };
120832
- const dbPath = resolveHomePath(memoryConfig.path || "~/.config/polka-codes/memory.sqlite");
120979
+ const memoryConfig = config4?.memory || { path: "~/.config/polkacodes/memory/memory.sqlite" };
120980
+ const dbPath = resolveHomePath(memoryConfig.path || "~/.config/polkacodes/memory/memory.sqlite");
120833
120981
  console.log(`
120834
120982
  Memory Store Status:`);
120835
120983
  console.log("─".repeat(80));
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@polka-codes/cli",
3
- "version": "0.9.90",
3
+ "version": "0.9.92",
4
4
  "license": "AGPL-3.0",
5
5
  "author": "github@polka.codes",
6
6
  "type": "module",
@@ -14,7 +14,8 @@
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 && bun run build:copy-wasm",
18
+ "build:copy-wasm": "mkdir -p dist && cp ../../node_modules/sql.js/dist/sql-wasm.wasm dist/"
18
19
  },
19
20
  "dependencies": {
20
21
  "@ai-sdk/anthropic": "^2.0.57",
@@ -28,8 +29,8 @@
28
29
  "@inquirer/prompts": "^8.1.0",
29
30
  "@modelcontextprotocol/sdk": "^1.25.1",
30
31
  "@openrouter/ai-sdk-provider": "^1.5.4",
31
- "@polka-codes/cli-shared": "0.9.89",
32
- "@polka-codes/core": "0.9.89",
32
+ "@polka-codes/cli-shared": "0.9.91",
33
+ "@polka-codes/core": "0.9.91",
33
34
  "ai": "^5.0.117",
34
35
  "chalk": "^5.6.2",
35
36
  "commander": "^14.0.2",