pi-python-helper 0.4.2 → 0.4.3
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 +10 -0
- package/docs/tools.md +1 -0
- package/extensions/tools/testing.ts +4 -4
- package/extensions/tools/validation.ts +13 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ does not guarantee a stable public tool schema.
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.3] - 2026-09-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- A project named through `path` now runs `uv` and `pytest` in the resolved project root instead of `ctx.cwd`. `py_sync`, `py_test`, `py_test_select`, `py_validation_bundle`, and `py_tdd_checkpoint` previously generated and executed their commands in the session directory, so a project reached through `path` failed with "No `pyproject.toml` found in current directory" or ran the wrong tests.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `py_tdd_checkpoint` accepts an optional `path` for git discovery.
|
|
19
|
+
|
|
10
20
|
## [0.4.2] - 2026-09-21
|
|
11
21
|
|
|
12
22
|
### Removed
|
package/docs/tools.md
CHANGED
|
@@ -415,6 +415,7 @@ Check whether production Python changes have related test changes before impleme
|
|
|
415
415
|
| 파라미터 | 타입 | 필수 | 설명 |
|
|
416
416
|
|---|---|---|---|
|
|
417
417
|
| `changedPaths` | `array<string>` | 아니오 | maxItems 500 |
|
|
418
|
+
| `path` | `string` | 아니오 | — |
|
|
418
419
|
| `testChangedPaths` | `array<string>` | 아니오 | maxItems 500 |
|
|
419
420
|
|
|
420
421
|
**프롬프트 가이드라인**
|
|
@@ -89,7 +89,7 @@ export function registerTestingTools(pi: Pi): void {
|
|
|
89
89
|
let changed = params.changedPaths ?? [];
|
|
90
90
|
let changedSource = 'argument';
|
|
91
91
|
if (!changed.length) {
|
|
92
|
-
const discovered = await changedPaths(
|
|
92
|
+
const discovered = await changedPaths(root, signal);
|
|
93
93
|
changed = discovered.paths;
|
|
94
94
|
changedSource = discovered.source === 'git' ? 'git' : (discovered.error ?? 'none');
|
|
95
95
|
}
|
|
@@ -109,7 +109,7 @@ export function registerTestingTools(pi: Pi): void {
|
|
|
109
109
|
(entry) => isRunnableTestFile(entry.path) || basename(entry.path) === 'conftest.py',
|
|
110
110
|
)
|
|
111
111
|
.map((entry) => entry.path);
|
|
112
|
-
const command = pytestCommand(
|
|
112
|
+
const command = pytestCommand(root, {
|
|
113
113
|
targets: selection.fellBackToAll ? [] : targets,
|
|
114
114
|
});
|
|
115
115
|
|
|
@@ -232,7 +232,7 @@ export function registerTestingTools(pi: Pi): void {
|
|
|
232
232
|
const started = Date.now();
|
|
233
233
|
try {
|
|
234
234
|
const root = (await resolveProjectRoot(ctx.cwd, params.path)) ?? ctx.cwd;
|
|
235
|
-
const command = pytestCommand(
|
|
235
|
+
const command = pytestCommand(root, {
|
|
236
236
|
targets: params.targets,
|
|
237
237
|
lastFailed: params.lastFailed,
|
|
238
238
|
keyword: params.keyword,
|
|
@@ -261,7 +261,7 @@ export function registerTestingTools(pi: Pi): void {
|
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
const run = await runCommand(command.executable, command.args, {
|
|
264
|
-
cwd:
|
|
264
|
+
cwd: root,
|
|
265
265
|
signal,
|
|
266
266
|
timeoutMs: (params.timeoutSeconds ?? 900) * 1000,
|
|
267
267
|
maxBytes: 512 * 1024,
|
|
@@ -73,7 +73,7 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
73
73
|
const root = (await resolveProjectRoot(ctx.cwd, params.path)) ?? ctx.cwd;
|
|
74
74
|
const mode = params.mode ?? 'check';
|
|
75
75
|
const extras = params.extras ?? 'all';
|
|
76
|
-
const command = mode === 'check' ? uvLockCheck(
|
|
76
|
+
const command = mode === 'check' ? uvLockCheck(root) : uvSyncFrozen(root, { extras });
|
|
77
77
|
const lockPresent = await isFile(join(root, 'uv.lock'));
|
|
78
78
|
|
|
79
79
|
if (!params.execute) {
|
|
@@ -109,7 +109,7 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
const run = await runCommand(command.executable, command.args, {
|
|
112
|
-
cwd:
|
|
112
|
+
cwd: root,
|
|
113
113
|
signal,
|
|
114
114
|
timeoutMs: (params.timeoutSeconds ?? 600) * 1000,
|
|
115
115
|
maxBytes: 256 * 1024,
|
|
@@ -296,9 +296,9 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
296
296
|
try {
|
|
297
297
|
const root = (await resolveProjectRoot(ctx.cwd, params.path)) ?? ctx.cwd;
|
|
298
298
|
const lockPresent = await isFile(join(root, 'uv.lock'));
|
|
299
|
-
const lock = uvLockCheck(
|
|
300
|
-
const sync = uvSyncFrozen(
|
|
301
|
-
const test = pytestCommand(
|
|
299
|
+
const lock = uvLockCheck(root);
|
|
300
|
+
const sync = uvSyncFrozen(root);
|
|
301
|
+
const test = pytestCommand(root, { targets: params.targets });
|
|
302
302
|
const timeoutMs = (params.timeoutSeconds ?? 1800) * 1000;
|
|
303
303
|
const runQuality = params.quality ?? true;
|
|
304
304
|
|
|
@@ -317,7 +317,7 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
317
317
|
toolConfiguration: manifestScan.payload?.manifest?.toolConfiguration,
|
|
318
318
|
})
|
|
319
319
|
: [];
|
|
320
|
-
const quality = qualityCommands(
|
|
320
|
+
const quality = qualityCommands(root, runners);
|
|
321
321
|
const commands = [lock, sync, test, ...quality];
|
|
322
322
|
|
|
323
323
|
if (!params.execute) {
|
|
@@ -369,14 +369,14 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
369
369
|
|
|
370
370
|
const lockRun = lockPresent
|
|
371
371
|
? await runCommand(lock.executable, lock.args, {
|
|
372
|
-
cwd:
|
|
372
|
+
cwd: root,
|
|
373
373
|
signal,
|
|
374
374
|
timeoutMs,
|
|
375
375
|
maxBytes: 256 * 1024,
|
|
376
376
|
})
|
|
377
377
|
: undefined;
|
|
378
378
|
const syncRun = await runCommand(sync.executable, sync.args, {
|
|
379
|
-
cwd:
|
|
379
|
+
cwd: root,
|
|
380
380
|
signal,
|
|
381
381
|
timeoutMs,
|
|
382
382
|
maxBytes: 256 * 1024,
|
|
@@ -400,7 +400,7 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
400
400
|
|
|
401
401
|
const testRun = syncOk
|
|
402
402
|
? await runCommand(test.executable, test.args, {
|
|
403
|
-
cwd:
|
|
403
|
+
cwd: root,
|
|
404
404
|
signal,
|
|
405
405
|
timeoutMs,
|
|
406
406
|
maxBytes: 512 * 1024,
|
|
@@ -466,7 +466,7 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
466
466
|
}
|
|
467
467
|
const preview = quality[index];
|
|
468
468
|
const run = await runCommand(preview.executable, preview.args, {
|
|
469
|
-
cwd:
|
|
469
|
+
cwd: root,
|
|
470
470
|
signal,
|
|
471
471
|
timeoutMs,
|
|
472
472
|
maxBytes: 256 * 1024,
|
|
@@ -615,14 +615,16 @@ export function registerValidationTools(pi: Pi): void {
|
|
|
615
615
|
parameters: Type.Object({
|
|
616
616
|
changedPaths: Type.Optional(Type.Array(Type.String(), { maxItems: 500 })),
|
|
617
617
|
testChangedPaths: Type.Optional(Type.Array(Type.String(), { maxItems: 500 })),
|
|
618
|
+
path: Type.Optional(Type.String()),
|
|
618
619
|
}),
|
|
619
620
|
async execute(_id, params, signal, _update, ctx) {
|
|
620
621
|
const started = Date.now();
|
|
622
|
+
const root = (await resolveProjectRoot(ctx.cwd, params.path)) ?? ctx.cwd;
|
|
621
623
|
let changedPaths = params.changedPaths ?? [];
|
|
622
624
|
let source = 'argument';
|
|
623
625
|
if (!changedPaths.length) {
|
|
624
626
|
const diff = await runCommand('git', ['diff', '--name-only', 'HEAD'], {
|
|
625
|
-
cwd:
|
|
627
|
+
cwd: root,
|
|
626
628
|
signal,
|
|
627
629
|
timeoutMs: 10000,
|
|
628
630
|
maxBytes: 100_000,
|