@deftai/directive-core 0.61.2 → 0.63.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/dist/check-updates/index.d.ts +49 -0
- package/dist/check-updates/index.js +323 -0
- package/dist/install-upgrade/index.js +3 -3
- package/dist/migrate-preflight/index.d.ts +1 -2
- package/dist/migrate-preflight/index.js +16 -36
- package/dist/release/build-dist-runner.d.ts +2 -0
- package/dist/release/build-dist-runner.js +21 -0
- package/dist/release/build-dist.d.ts +14 -0
- package/dist/release/build-dist.js +171 -0
- package/dist/release/constants.d.ts +1 -1
- package/dist/release/constants.js +1 -6
- package/dist/release/index.d.ts +2 -3
- package/dist/release/index.js +2 -3
- package/dist/release/native-steps.d.ts +5 -0
- package/dist/release/native-steps.js +72 -0
- package/dist/release/pipeline.js +8 -27
- package/dist/release-e2e/rollback-bridge.d.ts +1 -1
- package/dist/release-e2e/rollback-bridge.js +3 -17
- package/dist/render/framework-commands.d.ts +2 -2
- package/dist/render/framework-commands.js +102 -84
- package/dist/umbrella-current-shape/index.d.ts +87 -0
- package/dist/umbrella-current-shape/index.js +329 -0
- package/dist/vbrief-validate/precutover.d.ts +3 -0
- package/dist/vbrief-validate/precutover.js +8 -1
- package/dist/verify-env/verify-hooks-installed.d.ts +2 -0
- package/dist/verify-env/verify-hooks-installed.js +20 -4
- package/package.json +15 -3
- package/dist/release/pyproject-sync.d.ts +0 -6
- package/dist/release/pyproject-sync.js +0 -52
- package/dist/release/pyproject.d.ts +0 -3
- package/dist/release/pyproject.js +0 -33
- package/dist/release/python-steps.d.ts +0 -6
- package/dist/release/python-steps.js +0 -143
|
@@ -98,13 +98,20 @@ export function detectPreCutover(projectRoot) {
|
|
|
98
98
|
}
|
|
99
99
|
return { preCutover: reasons.length > 0, reasons };
|
|
100
100
|
}
|
|
101
|
+
/** Last release that ships `scripts/migrate_vbrief.py` on the consumer deposit path (#2068). */
|
|
102
|
+
export const FROZEN_PRECUTOVER_MIGRATION_TAG = "v0.59.0";
|
|
103
|
+
export function frozenPreCutoverMigrationGuidance() {
|
|
104
|
+
return (`Current npm releases no longer ship in-product \`task migrate:vbrief\`. Pin framework ${FROZEN_PRECUTOVER_MIGRATION_TAG} ` +
|
|
105
|
+
`(frozen Go installer or git tag), install Python 3.11+ and uv, run \`task migrate:vbrief\` once from that payload, ` +
|
|
106
|
+
`then upgrade to current npm. See UPGRADING.md § Frozen pre-v0.20 document-model migration (#2068).`);
|
|
107
|
+
}
|
|
101
108
|
export function renderPrecutoverLine(projectRoot) {
|
|
102
109
|
const { preCutover, reasons } = detectPreCutover(projectRoot);
|
|
103
110
|
if (!preCutover) {
|
|
104
111
|
return "Pre-cutover: none -- project is on the current vBRIEF document model.";
|
|
105
112
|
}
|
|
106
113
|
const summary = reasons.join("; ").replace(/\r?\n/g, " ");
|
|
107
|
-
return `Pre-cutover: migration needed -- ${summary}.
|
|
114
|
+
return `Pre-cutover: migration needed -- ${summary}. ${frozenPreCutoverMigrationGuidance()}`;
|
|
108
115
|
}
|
|
109
116
|
// Re-export for classify callers (#2013).
|
|
110
117
|
export { isFullSpecState, isGreenfieldSpecExport };
|
|
@@ -16,6 +16,8 @@ export interface EvaluateOptions {
|
|
|
16
16
|
readonly gitConfigReader?: GitConfigReader;
|
|
17
17
|
readonly platform?: NodeJS.Platform;
|
|
18
18
|
}
|
|
19
|
+
/** Drop shell ``#`` comment lines before pattern scans (#2049 shipped-hook false positives). */
|
|
20
|
+
export declare function stripShellCommentLines(content: string): string;
|
|
19
21
|
/** Pure evaluator mirroring scripts/verify_hooks_installed.py::evaluate. */
|
|
20
22
|
export declare function evaluate(projectRoot: string, options?: EvaluateOptions): EvaluateResult;
|
|
21
23
|
//# sourceMappingURL=verify-hooks-installed.d.ts.map
|
|
@@ -69,15 +69,31 @@ function readHookContent(hookPath) {
|
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
+
/** Drop shell ``#`` comment lines before pattern scans (#2049 shipped-hook false positives). */
|
|
73
|
+
export function stripShellCommentLines(content) {
|
|
74
|
+
return content
|
|
75
|
+
.split(/\r?\n/)
|
|
76
|
+
.filter((line) => !/^\s*#/.test(line))
|
|
77
|
+
.join("\n");
|
|
78
|
+
}
|
|
79
|
+
function executableHookBody(content) {
|
|
80
|
+
return stripShellCommentLines(content);
|
|
81
|
+
}
|
|
72
82
|
function usesLegacyPythonDispatch(content) {
|
|
73
|
-
|
|
83
|
+
const body = executableHookBody(content);
|
|
84
|
+
return LEGACY_HOOK_PATTERNS.some((pattern) => pattern.test(body));
|
|
74
85
|
}
|
|
75
86
|
function hookInvokesDeftCli(content, requiredCommands) {
|
|
76
|
-
|
|
87
|
+
const body = executableHookBody(content);
|
|
88
|
+
if (!/\bdeft\b/.test(body))
|
|
77
89
|
return false;
|
|
78
90
|
if (usesLegacyPythonDispatch(content))
|
|
79
91
|
return false;
|
|
80
|
-
return requiredCommands.every((cmd) =>
|
|
92
|
+
return requiredCommands.every((cmd) => body.includes(cmd));
|
|
93
|
+
}
|
|
94
|
+
function prePushInvokesVerifyBranch(content) {
|
|
95
|
+
const body = executableHookBody(content);
|
|
96
|
+
return /\bdeft\s+verify:branch\b/.test(body);
|
|
81
97
|
}
|
|
82
98
|
function validateHookContent(hookName, content, requiredCommands) {
|
|
83
99
|
if (content === null) {
|
|
@@ -176,7 +192,7 @@ export function evaluate(projectRoot, options = {}) {
|
|
|
176
192
|
stream: "stderr",
|
|
177
193
|
};
|
|
178
194
|
}
|
|
179
|
-
if (prePushContent
|
|
195
|
+
if (prePushContent && prePushInvokesVerifyBranch(prePushContent)) {
|
|
180
196
|
return {
|
|
181
197
|
code: 1,
|
|
182
198
|
message: "❌ deft hooks wired but NON-FUNCTIONAL: pre-push must not invoke verify:branch (#1814).\n" +
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.63.0",
|
|
4
4
|
"description": "TypeScript engine core for the Directive framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -194,6 +194,14 @@
|
|
|
194
194
|
"types": "./dist/migrate-preflight/index.d.ts",
|
|
195
195
|
"default": "./dist/migrate-preflight/index.js"
|
|
196
196
|
},
|
|
197
|
+
"./check-updates": {
|
|
198
|
+
"types": "./dist/check-updates/index.d.ts",
|
|
199
|
+
"default": "./dist/check-updates/index.js"
|
|
200
|
+
},
|
|
201
|
+
"./umbrella-current-shape": {
|
|
202
|
+
"types": "./dist/umbrella-current-shape/index.d.ts",
|
|
203
|
+
"default": "./dist/umbrella-current-shape/index.js"
|
|
204
|
+
},
|
|
197
205
|
"./install-upgrade": {
|
|
198
206
|
"types": "./dist/install-upgrade/index.d.ts",
|
|
199
207
|
"default": "./dist/install-upgrade/index.js"
|
|
@@ -221,11 +229,15 @@
|
|
|
221
229
|
"provenance": true
|
|
222
230
|
},
|
|
223
231
|
"dependencies": {
|
|
224
|
-
"@deftai/directive-content": "^0.
|
|
225
|
-
"@deftai/directive-types": "^0.
|
|
232
|
+
"@deftai/directive-content": "^0.63.0",
|
|
233
|
+
"@deftai/directive-types": "^0.63.0",
|
|
234
|
+
"archiver": "^8.0.0"
|
|
226
235
|
},
|
|
227
236
|
"scripts": {
|
|
228
237
|
"build": "tsc -b",
|
|
229
238
|
"test": "pnpm -w exec vitest run --coverage packages/core/src"
|
|
239
|
+
},
|
|
240
|
+
"devDependencies": {
|
|
241
|
+
"@types/archiver": "^8.0.0"
|
|
230
242
|
}
|
|
231
243
|
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ReleaseSeams } from "./types.js";
|
|
2
|
-
export declare function syncPyprojectForRelease(pyprojectPath: string, version: string, options: {
|
|
3
|
-
dryRun: boolean;
|
|
4
|
-
}, seams?: ReleaseSeams): [string, string | null];
|
|
5
|
-
export declare function pyprojectPathFor(projectRoot: string): string;
|
|
6
|
-
//# sourceMappingURL=pyproject-sync.d.ts.map
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { updatePyprojectVersion } from "./pyproject.js";
|
|
4
|
-
import { NonPublishableVersionError, toPep440 } from "./version.js";
|
|
5
|
-
export function syncPyprojectForRelease(pyprojectPath, version, options, seams = {}) {
|
|
6
|
-
const exists = seams.fileExists ??
|
|
7
|
-
((p) => {
|
|
8
|
-
try {
|
|
9
|
-
return existsSync(p) && statSync(p).isFile();
|
|
10
|
-
}
|
|
11
|
-
catch {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
const read = seams.readFile ?? ((p) => readFileSync(p, "utf8"));
|
|
16
|
-
if (!exists(pyprojectPath)) {
|
|
17
|
-
return ["no pyproject.toml; skipping sync", null];
|
|
18
|
-
}
|
|
19
|
-
let pepVersion;
|
|
20
|
-
try {
|
|
21
|
-
pepVersion = toPep440(version);
|
|
22
|
-
}
|
|
23
|
-
catch (err) {
|
|
24
|
-
if (err instanceof NonPublishableVersionError) {
|
|
25
|
-
return [`non-publishable tag (${err.message}); skipping pyproject sync`, null];
|
|
26
|
-
}
|
|
27
|
-
if (err instanceof Error) {
|
|
28
|
-
return [`FAIL (cannot normalize version to PEP 440: ${err.message})`, null];
|
|
29
|
-
}
|
|
30
|
-
return [`FAIL (cannot normalize version to PEP 440: ${String(err)})`, null];
|
|
31
|
-
}
|
|
32
|
-
const original = read(pyprojectPath);
|
|
33
|
-
let newText;
|
|
34
|
-
try {
|
|
35
|
-
newText = updatePyprojectVersion(original, pepVersion);
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
39
|
-
return [`FAIL (pyproject.toml: ${msg})`, null];
|
|
40
|
-
}
|
|
41
|
-
if (newText === original) {
|
|
42
|
-
return [`pyproject already at ${pepVersion}`, null];
|
|
43
|
-
}
|
|
44
|
-
if (options.dryRun) {
|
|
45
|
-
return [`pyproject [project].version -> ${pepVersion}`, null];
|
|
46
|
-
}
|
|
47
|
-
return [`pyproject [project].version -> ${pepVersion}`, newText];
|
|
48
|
-
}
|
|
49
|
-
export function pyprojectPathFor(projectRoot) {
|
|
50
|
-
return join(projectRoot, "pyproject.toml");
|
|
51
|
-
}
|
|
52
|
-
//# sourceMappingURL=pyproject-sync.js.map
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { PYPROJECT_VERSION_LINE_RE } from "./constants.js";
|
|
2
|
-
/** Rewrite [project].version in pyproject.toml content (#771). */
|
|
3
|
-
export function updatePyprojectVersion(text, version) {
|
|
4
|
-
if (typeof text !== "string") {
|
|
5
|
-
throw new Error(`text must be a string, got ${typeof text}`);
|
|
6
|
-
}
|
|
7
|
-
if (typeof version !== "string" || !version.trim()) {
|
|
8
|
-
throw new Error("version must be a non-empty string");
|
|
9
|
-
}
|
|
10
|
-
const lines = text.split(/(?<=\n)/);
|
|
11
|
-
let inProjectSection = false;
|
|
12
|
-
for (let idx = 0; idx < lines.length; idx += 1) {
|
|
13
|
-
const line = lines[idx] ?? "";
|
|
14
|
-
const stripped = line.trim();
|
|
15
|
-
if (!stripped || stripped.startsWith("#")) {
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
if (stripped.startsWith("[") && stripped.endsWith("]")) {
|
|
19
|
-
inProjectSection = stripped === "[project]";
|
|
20
|
-
continue;
|
|
21
|
-
}
|
|
22
|
-
if (inProjectSection && PYPROJECT_VERSION_LINE_RE.test(stripped)) {
|
|
23
|
-
const newLine = line.replace(PYPROJECT_VERSION_LINE_RE, `version = "${version}"`);
|
|
24
|
-
if (newLine === line) {
|
|
25
|
-
return text;
|
|
26
|
-
}
|
|
27
|
-
lines[idx] = newLine;
|
|
28
|
-
return lines.join("");
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
throw new Error("pyproject.toml has no [project] section with a version key");
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=pyproject.js.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { ReleaseSeams } from "./types.js";
|
|
2
|
-
export declare function refreshRoadmap(projectRoot: string, scriptsDir: string, seams?: ReleaseSeams): [boolean, string];
|
|
3
|
-
export declare function checkVbriefLifecycleSync(projectRoot: string, repo: string, scriptsDir: string, seams?: ReleaseSeams): [boolean, number, string];
|
|
4
|
-
export declare function runBuild(projectRoot: string, scriptsDir: string, version: string | null, seams?: ReleaseSeams): [boolean, string];
|
|
5
|
-
export declare function runUvLock(projectRoot: string, seams?: ReleaseSeams): [boolean, string];
|
|
6
|
-
//# sourceMappingURL=python-steps.d.ts.map
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* python-steps.ts -- Residual Python-backed release pipeline steps.
|
|
3
|
-
*
|
|
4
|
-
* #2022 Phase 1 removed the `ci_local.py` Step-5 pre-flight bridge (now native
|
|
5
|
-
* TypeScript via release/preflight.ts), retiring the former `python-bridge.ts`
|
|
6
|
-
* module. These remaining steps still shell into bundled Python and stay here
|
|
7
|
-
* until their own purge phases land:
|
|
8
|
-
* - refreshRoadmap (Step 7) -> scripts/roadmap_render.py
|
|
9
|
-
* - checkVbriefLifecycleSync (Step 3) -> scripts/reconcile_issues.py
|
|
10
|
-
* - runBuild (Step 8) -> scripts/build_dist.py (Bucket B, deleted by #1860)
|
|
11
|
-
* - runUvLock (Step 6) -> `uv lock`
|
|
12
|
-
*/
|
|
13
|
-
import { existsSync, statSync } from "node:fs";
|
|
14
|
-
import { join } from "node:path";
|
|
15
|
-
import { defaultWhich, spawnText } from "./spawn.js";
|
|
16
|
-
function runUvPython(_scriptsDir, code, cwd, env = process.env, seams = {}) {
|
|
17
|
-
const spawn = seams.spawnText ?? spawnText;
|
|
18
|
-
return spawn("uv", ["run", "python", "-c", code], {
|
|
19
|
-
cwd,
|
|
20
|
-
env: { ...env, PYTHONUTF8: "1" },
|
|
21
|
-
timeoutMs: 300_000,
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
export function refreshRoadmap(projectRoot, scriptsDir, seams = {}) {
|
|
25
|
-
const pending = join(projectRoot, "vbrief", "pending");
|
|
26
|
-
const roadmap = join(projectRoot, "ROADMAP.md");
|
|
27
|
-
const completed = join(projectRoot, "vbrief", "completed");
|
|
28
|
-
const code = [
|
|
29
|
-
"import sys",
|
|
30
|
-
`sys.path.insert(0, ${JSON.stringify(scriptsDir)})`,
|
|
31
|
-
"import roadmap_render",
|
|
32
|
-
`ok, msg = roadmap_render.render_roadmap(${JSON.stringify(pending)}, ${JSON.stringify(roadmap)}, completed_dir=${JSON.stringify(completed)})`,
|
|
33
|
-
"if ok:",
|
|
34
|
-
" sys.exit(0)",
|
|
35
|
-
"print(msg, file=sys.stderr)",
|
|
36
|
-
"sys.exit(1)",
|
|
37
|
-
].join("\n");
|
|
38
|
-
const result = runUvPython(scriptsDir, code, projectRoot, process.env, seams);
|
|
39
|
-
if (result.status !== 0) {
|
|
40
|
-
const msg = result.stderr.trim() || result.stdout.trim();
|
|
41
|
-
return [false, `roadmap:render failed: ${msg}`];
|
|
42
|
-
}
|
|
43
|
-
return [true, "ROADMAP.md re-rendered"];
|
|
44
|
-
}
|
|
45
|
-
export function checkVbriefLifecycleSync(projectRoot, repo, scriptsDir, seams = {}) {
|
|
46
|
-
const code = [
|
|
47
|
-
"import json, sys",
|
|
48
|
-
"from pathlib import Path",
|
|
49
|
-
`scripts_dir = Path(${JSON.stringify(scriptsDir)})`,
|
|
50
|
-
"sys.path.insert(0, str(scripts_dir))",
|
|
51
|
-
"try:",
|
|
52
|
-
" import reconcile_issues",
|
|
53
|
-
"except ImportError as exc:",
|
|
54
|
-
" print(json.dumps({'ok': False, 'mismatch_count': -1, 'reason': f'reconcile_issues import failed: {exc}'}))",
|
|
55
|
-
" sys.exit(0)",
|
|
56
|
-
`project_root = Path(${JSON.stringify(projectRoot)})`,
|
|
57
|
-
`repo = ${JSON.stringify(repo)}`,
|
|
58
|
-
"vbrief_dir = project_root / 'vbrief'",
|
|
59
|
-
"if not vbrief_dir.is_dir():",
|
|
60
|
-
" print(json.dumps({'ok': False, 'mismatch_count': -1, 'reason': f'vbrief directory not found at {vbrief_dir}'}))",
|
|
61
|
-
" sys.exit(0)",
|
|
62
|
-
"issue_to_vbriefs = reconcile_issues.scan_vbrief_dir(vbrief_dir)",
|
|
63
|
-
"issue_state_map = reconcile_issues.fetch_issue_states(repo, set(issue_to_vbriefs.keys()), cwd=project_root)",
|
|
64
|
-
"if issue_state_map is None:",
|
|
65
|
-
" print(json.dumps({'ok': False, 'mismatch_count': -1, 'reason': 'failed to fetch issue states from gh'}))",
|
|
66
|
-
" sys.exit(0)",
|
|
67
|
-
"report = reconcile_issues.reconcile(issue_to_vbriefs, issue_state_map)",
|
|
68
|
-
"mismatches = [rel for entry in report.get('no_open_issue', []) for rel in entry.get('vbrief_files', []) if not reconcile_issues.is_terminal_lifecycle_path(rel)]",
|
|
69
|
-
"count = len(mismatches)",
|
|
70
|
-
"if count == 0:",
|
|
71
|
-
" print(json.dumps({'ok': True, 'mismatch_count': 0, 'reason': 'no mismatches'}))",
|
|
72
|
-
"else:",
|
|
73
|
-
" suffix = ' ...' if count > 5 else ''",
|
|
74
|
-
" preview = ', '.join(mismatches[:5])",
|
|
75
|
-
" reason = f'{count} closed-issue vBRIEF(s) not in completed/ or cancelled/: {preview}{suffix}'",
|
|
76
|
-
" print(json.dumps({'ok': False, 'mismatch_count': count, 'reason': reason}))",
|
|
77
|
-
].join("\n");
|
|
78
|
-
const result = runUvPython(scriptsDir, code, projectRoot, process.env, seams);
|
|
79
|
-
try {
|
|
80
|
-
const payload = JSON.parse(result.stdout.trim());
|
|
81
|
-
return [payload.ok, payload.mismatch_count, payload.reason];
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
return [
|
|
85
|
-
false,
|
|
86
|
-
-1,
|
|
87
|
-
`reconcile_issues bridge failed: ${result.stderr.trim() || result.stdout.trim()}`,
|
|
88
|
-
];
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
export function runBuild(projectRoot, scriptsDir, version, seams = {}) {
|
|
92
|
-
const env = { ...process.env };
|
|
93
|
-
if (version) {
|
|
94
|
-
env.DEFT_RELEASE_VERSION = version;
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
delete env.DEFT_RELEASE_VERSION;
|
|
98
|
-
}
|
|
99
|
-
const code = [
|
|
100
|
-
"import sys",
|
|
101
|
-
"from pathlib import Path",
|
|
102
|
-
`sys.path.insert(0, ${JSON.stringify(scriptsDir)})`,
|
|
103
|
-
"from framework_commands import run_framework_command",
|
|
104
|
-
`root = Path(${JSON.stringify(projectRoot)})`,
|
|
105
|
-
"result = run_framework_command('build', project_root=root, framework_root=root)",
|
|
106
|
-
"sys.exit(result.code)",
|
|
107
|
-
].join("\n");
|
|
108
|
-
const result = runUvPython(scriptsDir, code, projectRoot, env, seams);
|
|
109
|
-
if (result.status !== 0) {
|
|
110
|
-
return [false, `build failed (exit ${result.status})`];
|
|
111
|
-
}
|
|
112
|
-
const suffix = version ? ` (DEFT_RELEASE_VERSION=${version})` : "";
|
|
113
|
-
return [true, `build ran clean${suffix}`];
|
|
114
|
-
}
|
|
115
|
-
export function runUvLock(projectRoot, seams = {}) {
|
|
116
|
-
const exists = seams.fileExists ??
|
|
117
|
-
((p) => {
|
|
118
|
-
try {
|
|
119
|
-
return existsSync(p) && statSync(p).isFile();
|
|
120
|
-
}
|
|
121
|
-
catch {
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
if (!exists(join(projectRoot, "pyproject.toml"))) {
|
|
126
|
-
return [true, "no pyproject.toml; skipping uv lock"];
|
|
127
|
-
}
|
|
128
|
-
const whichUv = seams.whichUv ?? defaultWhich;
|
|
129
|
-
const uvPath = whichUv("uv");
|
|
130
|
-
if (uvPath === null) {
|
|
131
|
-
process.stderr.write("WARNING: uv binary not on PATH; skipping uv.lock regeneration " +
|
|
132
|
-
"(see #774). Run `uv lock` manually before pushing the release tag.\n");
|
|
133
|
-
return [true, "uv binary not on PATH; skipping uv lock"];
|
|
134
|
-
}
|
|
135
|
-
const spawn = seams.spawnText ?? spawnText;
|
|
136
|
-
const result = spawn(uvPath, ["lock"], { cwd: projectRoot, timeoutMs: 300_000 });
|
|
137
|
-
if (result.status !== 0) {
|
|
138
|
-
const stderr = result.stderr.trim();
|
|
139
|
-
return [false, `uv lock failed (exit ${result.status}): ${stderr}`];
|
|
140
|
-
}
|
|
141
|
-
return [true, "uv.lock regenerated"];
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=python-steps.js.map
|