@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.
- package/README.md +34 -2
- package/cli.js +52 -34
- 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
|
-
##
|
|
314
|
+
## Voice Integration
|
|
315
315
|
|
|
316
|
-
proto
|
|
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.
|
|
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
|
-
|
|
273764
|
-
|
|
273765
|
-
|
|
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
|
-
|
|
273770
|
-
|
|
273771
|
-
|
|
273772
|
-
}
|
|
273784
|
+
allPaths.add(homeContextPath);
|
|
273785
|
+
logger4.debug(`Found readable home ${geminiMdFilename}: ${homeContextPath}`);
|
|
273786
|
+
break;
|
|
273773
273787
|
} catch {
|
|
273774
273788
|
}
|
|
273775
|
-
}
|
|
273776
|
-
|
|
273777
|
-
|
|
273778
|
-
|
|
273779
|
-
|
|
273780
|
-
|
|
273781
|
-
|
|
273782
|
-
|
|
273783
|
-
|
|
273784
|
-
|
|
273785
|
-
|
|
273786
|
-
|
|
273787
|
-
|
|
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
|
-
|
|
273791
|
-
|
|
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
|
|
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.
|
|
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 = "
|
|
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.
|
|
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.
|
|
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/
|
|
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.
|
|
24
|
+
"sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.16.0"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {},
|
|
27
27
|
"optionalDependencies": {
|