@protolabsai/proto 0.15.0 → 0.16.0

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 (3) hide show
  1. package/README.md +34 -2
  2. package/cli.js +52 -34
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -311,9 +311,41 @@ Use `/skills` to list available skills in a session.
311
311
  | `Ctrl+D` | Exit (on empty line) |
312
312
  | `Up/Down` | Navigate command history |
313
313
 
314
- ## IDE Integration
314
+ ## Voice Integration
315
315
 
316
- proto works with VS Code, Zed, and JetBrains IDEs. See the upstream [Qwen Code docs](https://qwenlm.github.io/qwen-code-docs/en/users/overview) for setup instructions.
316
+ proto supports push-to-talk voice input. Press the mic button in the footer or use `/voice` to toggle.
317
+
318
+ ### Requirements
319
+
320
+ Voice capture requires a system audio backend:
321
+
322
+ | OS | Backend | Install |
323
+ | ----- | ------- | ------------------------------------- |
324
+ | macOS | sox | `brew install sox` |
325
+ | Linux | sox | `apt install sox` / `dnf install sox` |
326
+ | Linux | arecord | `apt install alsa-utils` (fallback) |
327
+
328
+ Verify detection: `/voice status`
329
+
330
+ ### STT backend
331
+
332
+ Voice input transcribes audio via a Whisper-compatible `/v1/audio/transcriptions` endpoint. Self-host one (e.g. [faster-whisper-server](https://github.com/fedirz/faster-whisper-server)):
333
+
334
+ ```bash
335
+ docker run --gpus all -p 8000:8000 fedirz/faster-whisper-server:latest-cuda
336
+ ```
337
+
338
+ ```json
339
+ // ~/.proto/settings.json
340
+ {
341
+ "voice": {
342
+ "enabled": true,
343
+ "sttEndpoint": "http://localhost:8000/v1/audio/transcriptions"
344
+ }
345
+ }
346
+ ```
347
+
348
+ The default endpoint is `http://localhost:8000/v1/audio/transcriptions` if none is configured.
317
349
 
318
350
  ## Architecture
319
351
 
package/cli.js CHANGED
@@ -172344,7 +172344,7 @@ __export(geminiContentGenerator_exports, {
172344
172344
  createGeminiContentGenerator: () => createGeminiContentGenerator
172345
172345
  });
172346
172346
  function createGeminiContentGenerator(config2, gcConfig) {
172347
- const version2 = "0.15.0";
172347
+ const version2 = "0.16.0";
172348
172348
  const userAgent2 = config2.userAgent || `QwenCode/${version2} (${process.platform}; ${process.arch})`;
172349
172349
  const baseHeaders = {
172350
172350
  "User-Agent": userAgent2
@@ -174458,6 +174458,7 @@ When requested to perform tasks like fixing bugs, adding features, refactoring,
174458
174458
  - **Implement:** Begin implementing the plan while gathering additional context as needed. Use '${ToolNames.GREP}', '${ToolNames.GLOB}', and '${ToolNames.READ_FILE}' tools strategically when you encounter specific unknowns during implementation. Use the available tools (e.g., '${ToolNames.EDIT}', '${ToolNames.WRITE_FILE}' '${ToolNames.SHELL}' ...) to act on the plan, strictly adhering to the project's established conventions (detailed under 'Core Mandates').
174459
174459
  - **Adapt:** As you discover new information or encounter obstacles, update your plan and tasks accordingly. Use ${ToolNames.TASK_UPDATE} to mark tasks as in_progress when starting and completed when finishing. Use ${ToolNames.TASK_CREATE} to add new tasks if the scope expands. Refine your approach based on what you learn.
174460
174460
  - **Verify (Tests):** If applicable and feasible, verify the changes using the project's testing procedures. Identify the correct test commands and frameworks by examining 'README' files, build/package configuration (e.g., 'package.json'), or existing test execution patterns. NEVER assume standard test commands.
174461
+ - **Verify (Match the verifier):** When a task specifies a test file, task.yaml, or verification script, read it before verifying your own output. Your implementation must satisfy the *exact* tool or function the verifier uses \u2014 not just produce plausible-looking output using a different library or algorithm. A self-check that passes with the wrong tool is not a passing check.
174461
174462
  - **Verify (Standards):** VERY IMPORTANT: After making code changes, execute the project-specific build, linting and type-checking commands (e.g., 'tsc', 'npm run lint', 'ruff check .') that you have identified for this project (or obtained from the user). This ensures code quality and adherence to standards. If unsure about these commands, you can ask the user if they'd like you to run them and if so how to.
174462
174463
 
174463
174464
  **Key Principle:** Start with a reasonable plan based on available information, then adapt as you learn. Users prefer seeing progress quickly rather than waiting for perfect understanding.
@@ -174509,6 +174510,17 @@ When an action fails, follow this exact sequence:
174509
174510
  5. Do NOT discard a fundamentally sound strategy because of a single failure.
174510
174511
  6. Only escalate to the user when you have exhausted actionable diagnostic steps.
174511
174512
 
174513
+ ## Data Recovery and Reconstruction
174514
+ When recovering, reconstructing, or parsing data from a binary or encoded source:
174515
+ - **Always decode the actual bytes.** Do not infer values from patterns visible in surrounding data (e.g., if you see 100, 200, 300, do not assume the next value follows that pattern). Patterns have exceptions \u2014 the whole point of recovery tasks is often to surface those exceptions.
174516
+ - **Read before you conclude.** Fully decode each record, frame, or entry from the source before writing any output. A single unread entry that deviates from the pattern will silently corrupt the result.
174517
+
174518
+ ## Binary Format / Reverse-Engineering Tasks
174519
+ When a task requires producing output compatible with a binary format defined in C source (or similar low-level code):
174520
+ - **Read the full source first.** Understand the complete format before writing a single byte of output.
174521
+ - **Write an encoder in one pass.** Map the format to a Python (or equivalent) encoder script, then generate the output from that script. Do not iterate by trial and error against the binary \u2014 each failed attempt (e.g., segfault) costs time and rarely gives useful signal.
174522
+ - **Run the decompressor/validator on your first attempt.** If it segfaults or errors, read the error output, patch the encoder logic, and re-run \u2014 do not start over from scratch.
174523
+
174512
174524
  ## Acting with Caution
174513
174525
  Before executing any action, evaluate two dimensions: how easily it can be undone, and how widely its effects propagate.
174514
174526
 
@@ -273750,61 +273762,67 @@ async function getGeminiMdFilePathsInternalForEachDir(dir, userHomePath, fileSer
273750
273762
  const GLOBAL_DIR_FOR_FILENAME = {
273751
273763
  "CLAUDE.md": CLAUDE_DIR
273752
273764
  };
273765
+ const resolvedHome = path78.resolve(userHomePath);
273753
273766
  for (const geminiMdFilename of geminiMdFilenames) {
273754
- const resolvedHome = path78.resolve(userHomePath);
273755
273767
  const globalDir = GLOBAL_DIR_FOR_FILENAME[geminiMdFilename] ?? QWEN_DIR;
273756
273768
  const globalMemoryPath = path78.join(resolvedHome, globalDir, geminiMdFilename);
273757
273769
  try {
273758
273770
  await fs76.access(globalMemoryPath, fsSync3.constants.R_OK);
273759
273771
  allPaths.add(globalMemoryPath);
273760
273772
  logger4.debug(`Found readable global ${geminiMdFilename}: ${globalMemoryPath}`);
273773
+ break;
273761
273774
  } catch {
273762
273775
  }
273763
- const resolvedDir = dir ? path78.resolve(dir) : resolvedHome;
273764
- const isHomeDirectory = resolvedDir === resolvedHome;
273765
- if (isHomeDirectory) {
273776
+ }
273777
+ const resolvedDir = dir ? path78.resolve(dir) : resolvedHome;
273778
+ const isHomeDirectory = resolvedDir === resolvedHome;
273779
+ if (isHomeDirectory) {
273780
+ for (const geminiMdFilename of geminiMdFilenames) {
273766
273781
  const homeContextPath = path78.join(resolvedHome, geminiMdFilename);
273767
273782
  try {
273768
273783
  await fs76.access(homeContextPath, fsSync3.constants.R_OK);
273769
- if (homeContextPath !== globalMemoryPath) {
273770
- allPaths.add(homeContextPath);
273771
- logger4.debug(`Found readable home ${geminiMdFilename}: ${homeContextPath}`);
273772
- }
273784
+ allPaths.add(homeContextPath);
273785
+ logger4.debug(`Found readable home ${geminiMdFilename}: ${homeContextPath}`);
273786
+ break;
273773
273787
  } catch {
273774
273788
  }
273775
- } else if (dir && folderTrust) {
273776
- const resolvedCwd = path78.resolve(dir);
273777
- logger4.debug(`Searching for ${geminiMdFilename} starting from CWD: ${resolvedCwd}`);
273778
- const projectRoot = await findProjectRoot2(resolvedCwd);
273779
- logger4.debug(`Determined project root: ${projectRoot ?? "None"}`);
273780
- const upwardPaths = [];
273781
- let currentDir = resolvedCwd;
273782
- const ultimateStopDir = projectRoot ? path78.dirname(projectRoot) : path78.dirname(resolvedHome);
273783
- while (currentDir && currentDir !== path78.dirname(currentDir)) {
273784
- if (currentDir === path78.join(resolvedHome, QWEN_DIR)) {
273785
- break;
273786
- }
273787
- const potentialPath = path78.join(currentDir, geminiMdFilename);
273789
+ }
273790
+ } else if (dir && folderTrust) {
273791
+ const resolvedCwd = path78.resolve(dir);
273792
+ logger4.debug(`Searching for context files starting from CWD: ${resolvedCwd}`);
273793
+ const projectRoot = await findProjectRoot2(resolvedCwd);
273794
+ logger4.debug(`Determined project root: ${projectRoot ?? "None"}`);
273795
+ const walkDirs = [];
273796
+ let currentDir = resolvedCwd;
273797
+ const ultimateStopDir = projectRoot ? path78.dirname(projectRoot) : path78.dirname(resolvedHome);
273798
+ while (currentDir && currentDir !== path78.dirname(currentDir)) {
273799
+ if (currentDir === path78.join(resolvedHome, QWEN_DIR)) {
273800
+ break;
273801
+ }
273802
+ walkDirs.unshift(currentDir);
273803
+ if (currentDir === ultimateStopDir) {
273804
+ break;
273805
+ }
273806
+ currentDir = path78.dirname(currentDir);
273807
+ }
273808
+ for (const walkDir of walkDirs) {
273809
+ for (const geminiMdFilename of geminiMdFilenames) {
273810
+ const potentialPath = path78.join(walkDir, geminiMdFilename);
273788
273811
  try {
273789
273812
  await fs76.access(potentialPath, fsSync3.constants.R_OK);
273790
- if (potentialPath !== globalMemoryPath) {
273791
- upwardPaths.unshift(potentialPath);
273792
- }
273793
- } catch {
273794
- }
273795
- if (currentDir === ultimateStopDir) {
273813
+ allPaths.add(potentialPath);
273814
+ logger4.debug(`Found ${geminiMdFilename} in ${walkDir}: ${potentialPath}`);
273796
273815
  break;
273816
+ } catch {
273797
273817
  }
273798
- currentDir = path78.dirname(currentDir);
273799
273818
  }
273800
- upwardPaths.forEach((p2) => allPaths.add(p2));
273801
273819
  }
273802
273820
  }
273803
273821
  for (const extensionPath of extensionContextFilePaths) {
273804
273822
  allPaths.add(extensionPath);
273805
273823
  }
273806
273824
  const finalPaths = Array.from(allPaths);
273807
- logger4.debug(`Final ordered ${getAllGeminiMdFilenames()} paths to read: ${JSON.stringify(finalPaths)}`);
273825
+ logger4.debug(`Final ordered context file paths to read: ${JSON.stringify(finalPaths)}`);
273808
273826
  return finalPaths;
273809
273827
  }
273810
273828
  async function readGeminiMdFiles(filePaths, importFormat = "tree") {
@@ -413673,7 +413691,7 @@ __name(getPackageJson, "getPackageJson");
413673
413691
  // packages/cli/src/utils/version.ts
413674
413692
  async function getCliVersion() {
413675
413693
  const pkgJson = await getPackageJson();
413676
- return "0.15.0";
413694
+ return "0.16.0";
413677
413695
  }
413678
413696
  __name(getCliVersion, "getCliVersion");
413679
413697
 
@@ -421453,7 +421471,7 @@ var formatDuration = /* @__PURE__ */ __name((milliseconds) => {
421453
421471
 
421454
421472
  // packages/cli/src/generated/git-commit.ts
421455
421473
  init_esbuild_shims();
421456
- var GIT_COMMIT_INFO = "f2df988ea";
421474
+ var GIT_COMMIT_INFO = "bc957ade0";
421457
421475
 
421458
421476
  // packages/cli/src/utils/systemInfo.ts
421459
421477
  async function getNpmVersion() {
@@ -487523,7 +487541,7 @@ var QwenAgent = class {
487523
487541
  async initialize(args2) {
487524
487542
  this.clientCapabilities = args2.clientCapabilities;
487525
487543
  const authMethods = buildAuthMethods();
487526
- const version2 = "0.15.0";
487544
+ const version2 = "0.16.0";
487527
487545
  return {
487528
487546
  protocolVersion: PROTOCOL_VERSION,
487529
487547
  agentInfo: {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@protolabsai/proto",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "proto - AI-powered coding agent",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/QwenLM/qwen-code.git"
7
+ "url": "git+https://github.com/protoLabsAI/protoCLI.git"
8
8
  },
9
9
  "type": "module",
10
10
  "main": "cli.js",
@@ -21,7 +21,7 @@
21
21
  "bundled"
22
22
  ],
23
23
  "config": {
24
- "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.15.0"
24
+ "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.16.0"
25
25
  },
26
26
  "dependencies": {},
27
27
  "optionalDependencies": {