pi-rtk-optimizer 0.5.0 → 0.5.2
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/CHANGELOG.md +24 -0
- package/package.json +60 -60
- package/src/additional-coverage-test.ts +23 -0
- package/src/index.ts +3 -3
- package/src/rewrite-pipeline-safety.ts +7 -4
- package/src/rtk-command-environment.ts +3 -3
- package/src/shell-env-prefix.ts +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.2] - 2026-04-01
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Updated `@mariozechner/pi-coding-agent` and `@mariozechner/pi-tui` peer dependencies to ^0.64.0
|
|
14
|
+
- Improved RTK note message to guide users through '/rtk' toggle in Pi TUI
|
|
15
|
+
|
|
16
|
+
## [0.5.1] - 2026-03-24
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- RTK_DB_PATH environment variable now correctly scoped to rewritten producer commands only — Windows commands now use subshell scoping `{ RTK_DB_PATH=...; ... }` instead of leaking the prefix into the rewritten command
|
|
20
|
+
- Command rewrite pipeline now applies environment scoping BEFORE shell safety fixups to prevent env prefix stripping
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- `shell-env-prefix.ts` module for splitting leading environment variable assignments from commands
|
|
24
|
+
- `splitLeadingEnvAssignments()` function to properly extract `ENV=value` prefixes before command analysis
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- Refactored `rtk-command-environment.ts` to use the new `splitLeadingEnvAssignments` utility
|
|
28
|
+
- Refactored `rewrite-pipeline-safety.ts` to preserve env prefixes when analyzing and rewriting rtk commands
|
|
29
|
+
|
|
30
|
+
### Tests
|
|
31
|
+
- Added test coverage for RTK_DB_PATH scoping on Windows vs Unix platforms
|
|
32
|
+
- Verified env prefix is preserved through the rewrite pipeline
|
|
33
|
+
|
|
10
34
|
## [0.5.0] - 2026-03-23
|
|
11
35
|
|
|
12
36
|
### Added
|
package/package.json
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pi-rtk-optimizer",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "Pi extension that optimizes RTK command rewriting and tool output compaction for the coding agent.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./index.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": "./index.ts"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"index.ts",
|
|
12
|
-
"src",
|
|
13
|
-
"config/config.example.json",
|
|
14
|
-
"README.md",
|
|
15
|
-
"CHANGELOG.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
],
|
|
18
|
-
"scripts": {
|
|
19
|
-
"build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
|
|
20
|
-
"lint": "npm run build",
|
|
21
|
-
"typecheck": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json",
|
|
22
|
-
"test": "bun ./src/output-compactor-test.ts && bun ./src/command-rewriter-test.ts && bun ./src/runtime-guard-test.ts && bun ./src/additional-coverage-test.ts && bun ./src/config-modal-test.ts && bun ./src/index-test.ts",
|
|
23
|
-
"check": "npm run lint && npm run typecheck && npm run test",
|
|
24
|
-
"build:check": "bunx esbuild ./index.ts --bundle --platform=node --format=esm --outfile=./.pi-rtk-optimizer-check.mjs --external:@mariozechner/pi-coding-agent --external:@mariozechner/pi-tui && bun -e \"import { unlinkSync } from 'node:fs'; unlinkSync('./.pi-rtk-optimizer-check.mjs');\""
|
|
25
|
-
},
|
|
26
|
-
"keywords": [
|
|
27
|
-
"pi-package",
|
|
28
|
-
"pi",
|
|
29
|
-
"pi-extension",
|
|
30
|
-
"rtk",
|
|
31
|
-
"token-optimization",
|
|
32
|
-
"tool-compaction",
|
|
33
|
-
"coding-agent"
|
|
34
|
-
],
|
|
35
|
-
"author": "MasuRii",
|
|
36
|
-
"license": "MIT",
|
|
37
|
-
"repository": {
|
|
38
|
-
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/MasuRii/pi-rtk-optimizer.git"
|
|
40
|
-
},
|
|
41
|
-
"bugs": {
|
|
42
|
-
"url": "https://github.com/MasuRii/pi-rtk-optimizer/issues"
|
|
43
|
-
},
|
|
44
|
-
"homepage": "https://github.com/MasuRii/pi-rtk-optimizer#readme",
|
|
45
|
-
"engines": {
|
|
46
|
-
"node": ">=20"
|
|
47
|
-
},
|
|
48
|
-
"publishConfig": {
|
|
49
|
-
"access": "public"
|
|
50
|
-
},
|
|
51
|
-
"pi": {
|
|
52
|
-
"extensions": [
|
|
53
|
-
"./index.ts"
|
|
54
|
-
]
|
|
55
|
-
},
|
|
56
|
-
"peerDependencies": {
|
|
57
|
-
"@mariozechner/pi-coding-agent": "^0.
|
|
58
|
-
"@mariozechner/pi-tui": "^0.
|
|
59
|
-
}
|
|
60
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "pi-rtk-optimizer",
|
|
3
|
+
"version": "0.5.2",
|
|
4
|
+
"description": "Pi extension that optimizes RTK command rewriting and tool output compaction for the coding agent.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.ts",
|
|
12
|
+
"src",
|
|
13
|
+
"config/config.example.json",
|
|
14
|
+
"README.md",
|
|
15
|
+
"CHANGELOG.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json --noCheck",
|
|
20
|
+
"lint": "npm run build",
|
|
21
|
+
"typecheck": "npx --yes -p typescript@5.7.3 tsc -p tsconfig.json",
|
|
22
|
+
"test": "bun ./src/output-compactor-test.ts && bun ./src/command-rewriter-test.ts && bun ./src/runtime-guard-test.ts && bun ./src/additional-coverage-test.ts && bun ./src/config-modal-test.ts && bun ./src/index-test.ts",
|
|
23
|
+
"check": "npm run lint && npm run typecheck && npm run test",
|
|
24
|
+
"build:check": "bunx esbuild ./index.ts --bundle --platform=node --format=esm --outfile=./.pi-rtk-optimizer-check.mjs --external:@mariozechner/pi-coding-agent --external:@mariozechner/pi-tui && bun -e \"import { unlinkSync } from 'node:fs'; unlinkSync('./.pi-rtk-optimizer-check.mjs');\""
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"pi-package",
|
|
28
|
+
"pi",
|
|
29
|
+
"pi-extension",
|
|
30
|
+
"rtk",
|
|
31
|
+
"token-optimization",
|
|
32
|
+
"tool-compaction",
|
|
33
|
+
"coding-agent"
|
|
34
|
+
],
|
|
35
|
+
"author": "MasuRii",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/MasuRii/pi-rtk-optimizer.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/MasuRii/pi-rtk-optimizer/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/MasuRii/pi-rtk-optimizer#readme",
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"pi": {
|
|
52
|
+
"extensions": [
|
|
53
|
+
"./index.ts"
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@mariozechner/pi-coding-agent": "^0.64.0",
|
|
58
|
+
"@mariozechner/pi-tui": "^0.64.0"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -14,6 +14,7 @@ import { matchesCommandPatterns, normalizeCommandForDetection } from "./techniqu
|
|
|
14
14
|
import { compactPath } from "./techniques/path-utils.ts";
|
|
15
15
|
import { applyWindowsBashCompatibilityFixes } from "./windows-command-helpers.ts";
|
|
16
16
|
import { applyRewrittenCommandShellSafetyFixups } from "./rewrite-pipeline-safety.ts";
|
|
17
|
+
import { applyRtkCommandEnvironment } from "./rtk-command-environment.ts";
|
|
17
18
|
import { sanitizeStreamingBashExecutionResult } from "./tool-execution-sanitizer.ts";
|
|
18
19
|
import { sanitizeRtkEmojiOutput } from "./techniques/emoji.ts";
|
|
19
20
|
import { stripRtkHookWarnings } from "./techniques/rtk.ts";
|
|
@@ -197,6 +198,28 @@ runTest("rewrite pipeline safety buffers rewritten Windows producer commands", (
|
|
|
197
198
|
assert.equal(applyRewrittenCommandShellSafetyFixups("git diff | grep TODO"), "git diff | grep TODO");
|
|
198
199
|
});
|
|
199
200
|
|
|
201
|
+
runTest("rewrite pipeline safety keeps RTK_DB_PATH scoped to rewritten producer commands", () => {
|
|
202
|
+
const rewritten = applyRewrittenCommandShellSafetyFixups(
|
|
203
|
+
applyRtkCommandEnvironment("rtk git diff agent/extensions/pi-multi-auth/account-manager.ts | head -200"),
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
if (process.platform === "win32") {
|
|
207
|
+
assert.ok(rewritten.startsWith("{"));
|
|
208
|
+
assert.equal(rewritten.startsWith("RTK_DB_PATH="), false);
|
|
209
|
+
assert.ok(rewritten.includes("RTK_DB_PATH="));
|
|
210
|
+
assert.ok(
|
|
211
|
+
rewritten.includes('rtk git diff agent/extensions/pi-multi-auth/account-manager.ts > "$__pi_rtk_pipe_tmp"'),
|
|
212
|
+
);
|
|
213
|
+
assert.ok(rewritten.includes('(head -200) < "$__pi_rtk_pipe_tmp"'));
|
|
214
|
+
} else {
|
|
215
|
+
assert.ok(rewritten.startsWith("RTK_DB_PATH="));
|
|
216
|
+
assert.equal(
|
|
217
|
+
rewritten,
|
|
218
|
+
applyRtkCommandEnvironment("rtk git diff agent/extensions/pi-multi-auth/account-manager.ts | head -200"),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
200
223
|
runTest("stripRtkHookWarnings handles bare, prefixed, and already-sanitized hook notices", () => {
|
|
201
224
|
assert.equal(
|
|
202
225
|
stripRtkHookWarnings("No hook installed — run `rtk init -g` for automatic token savings\n\nready\n", null),
|
package/src/index.ts
CHANGED
|
@@ -28,7 +28,7 @@ function trimMessage(raw: string, maxLength = 220): string {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const SOURCE_FILTER_TROUBLESHOOTING_NOTE =
|
|
31
|
-
"RTK note: If file edits repeatedly fail because old text does not match, run '/rtk',
|
|
31
|
+
"RTK note: If file edits repeatedly fail because old text does not match, ask the user to manually run '/rtk' in the Pi TUI, disable 'Read source filtering enabled', re-read the file, apply the edit, then ask the user to manually re-enable it in the Pi TUI.";
|
|
32
32
|
|
|
33
33
|
function mergeCompactionDetails(
|
|
34
34
|
existingDetails: unknown,
|
|
@@ -363,8 +363,8 @@ export default function rtkIntegrationExtension(pi: ExtensionAPI): void {
|
|
|
363
363
|
if (config.showRewriteNotifications && ctx.hasUI) {
|
|
364
364
|
ctx.ui.notify(formatRewriteNotice(decision.originalCommand, decision.rewrittenCommand), "info");
|
|
365
365
|
}
|
|
366
|
-
const
|
|
367
|
-
event.input.command =
|
|
366
|
+
const envScopedRewrittenCommand = applyRtkCommandEnvironment(decision.rewrittenCommand);
|
|
367
|
+
event.input.command = applyRewrittenCommandShellSafetyFixups(envScopedRewrittenCommand);
|
|
368
368
|
return {};
|
|
369
369
|
}
|
|
370
370
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { splitLeadingEnvAssignments } from "./shell-env-prefix.js";
|
|
2
|
+
|
|
1
3
|
interface ParsedPipeline {
|
|
2
4
|
segments: string[];
|
|
3
5
|
separators: string[];
|
|
@@ -88,18 +90,19 @@ function parseSimpleTopLevelPipeline(command: string): ParsedPipeline | null {
|
|
|
88
90
|
|
|
89
91
|
function extractProducerRewritePlan(segment: string, firstSeparator: string): ProducerRewritePlan | null {
|
|
90
92
|
const trimmed = segment.trim();
|
|
91
|
-
|
|
93
|
+
const { envPrefix, command: commandWithOptionalRedirect } = splitLeadingEnvAssignments(trimmed);
|
|
94
|
+
if (!/^rtk\s+/i.test(commandWithOptionalRedirect)) {
|
|
92
95
|
return null;
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
const stderrMergeMatch =
|
|
98
|
+
const stderrMergeMatch = commandWithOptionalRedirect.match(/^(.*?)(?:\s+)?2>\s*&1\s*$/u);
|
|
96
99
|
if (stderrMergeMatch) {
|
|
97
100
|
const command = stderrMergeMatch[1]?.trimEnd() ?? "";
|
|
98
|
-
return command ? { command, captureStderr: true } : null;
|
|
101
|
+
return command ? { command: `${envPrefix}${command}`.trim(), captureStderr: true } : null;
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
return {
|
|
102
|
-
command:
|
|
105
|
+
command: `${envPrefix}${commandWithOptionalRedirect}`.trim(),
|
|
103
106
|
captureStderr: firstSeparator === "|&",
|
|
104
107
|
};
|
|
105
108
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { join } from "node:path";
|
|
2
2
|
|
|
3
|
+
import { splitLeadingEnvAssignments } from "./shell-env-prefix.js";
|
|
4
|
+
|
|
3
5
|
const RTK_DB_PATH_ENV_NAME = "RTK_DB_PATH";
|
|
4
|
-
const LEADING_ENV_ASSIGNMENT_PATTERN = /^((?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+)\s+)*)/;
|
|
5
6
|
const RTK_DB_PATH_ASSIGNMENT_PATTERN = /(?:^|\s)RTK_DB_PATH=(?:"[^"]*"|'[^']*'|[^\s]+)(?=\s|$)/;
|
|
6
7
|
|
|
7
8
|
function resolveTemporaryDirectory(): string {
|
|
@@ -47,8 +48,7 @@ function quoteForShellEnv(value: string): string {
|
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
function hasLeadingRtkDbPathAssignment(command: string): boolean {
|
|
50
|
-
|
|
51
|
-
return RTK_DB_PATH_ASSIGNMENT_PATTERN.test(leadingAssignments);
|
|
51
|
+
return RTK_DB_PATH_ASSIGNMENT_PATTERN.test(splitLeadingEnvAssignments(command).envPrefix);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
export function applyRtkCommandEnvironment(command: string): string {
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const LEADING_ENV_ASSIGNMENT_PATTERN = /^((?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s]+)\s+)*)/;
|
|
2
|
+
|
|
3
|
+
export interface LeadingEnvAssignmentSplit {
|
|
4
|
+
envPrefix: string;
|
|
5
|
+
command: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function splitLeadingEnvAssignments(input: string): LeadingEnvAssignmentSplit {
|
|
9
|
+
const envPrefix = input.match(LEADING_ENV_ASSIGNMENT_PATTERN)?.[1] ?? "";
|
|
10
|
+
return {
|
|
11
|
+
envPrefix,
|
|
12
|
+
command: input.slice(envPrefix.length),
|
|
13
|
+
};
|
|
14
|
+
}
|