@lumpcode/core 0.0.11 → 0.0.13
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/helpers/executeStepsForContextList/main.d.ts +1 -1
- package/dist/helpers/getCodeBasePaths/main.d.ts +2 -2
- package/dist/helpers/getCodeBasePaths/main.d.ts.map +1 -1
- package/dist/helpers/getToDoContextList/main.d.ts +2 -2
- package/dist/helpers/getToDoContextList/main.d.ts.map +1 -1
- package/dist/index.cjs +151 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +151 -9
- package/dist/index.js.map +1 -1
- package/dist/utils/historyFile/main.d.ts.map +1 -1
- package/dist/utils/resolveSpawnExecutable/index.d.ts +1 -0
- package/dist/utils/resolveSpawnExecutable/index.d.ts.map +1 -1
- package/dist/utils/resolveSpawnExecutable/main.d.ts +4 -0
- package/dist/utils/resolveSpawnExecutable/main.d.ts.map +1 -1
- package/dist/utils/resolveSpawnExecutable/npmCmdShimFixture.d.ts +6 -0
- package/dist/utils/resolveSpawnExecutable/npmCmdShimFixture.d.ts.map +1 -0
- package/dist/utils/resolveSpawnExecutable/windowsNpmCmdShimBody.d.ts +6 -0
- package/dist/utils/resolveSpawnExecutable/windowsNpmCmdShimBody.d.ts.map +1 -0
- package/dist/utils/resolveSpawnExecutable/windowsNpmCmdShimFixture.d.ts +6 -0
- package/dist/utils/resolveSpawnExecutable/windowsNpmCmdShimFixture.d.ts.map +1 -0
- package/package.json +2 -1
|
@@ -6,7 +6,7 @@ export type ExecuteStepsForContextListParams = Required<Pick<RunLumpInput, 'base
|
|
|
6
6
|
};
|
|
7
7
|
export declare function executeStepsForContextList({ baseBranch, branchFn, lumpVariables, contextList, gitAddCommandFn, gitCommitCommandFn, gitPushCommandFn, gitCommitMessageFn, projectRoot, steps, setupFn, setupWorkspaceFn, teardownFn, teardownWorkspaceFn, getKeepHistoryFilePathFn, logger: loggerInput, }: ExecuteStepsForContextListParams): Promise<Failure<{
|
|
8
8
|
message: string;
|
|
9
|
-
}> | import("
|
|
9
|
+
}> | import("../..").Success<{
|
|
10
10
|
branchName: string;
|
|
11
11
|
contextNames: string[];
|
|
12
12
|
contextRunStateList: ContextRunState[];
|
|
@@ -2,7 +2,7 @@ import { CodeBasePath, Logger } from '../../types';
|
|
|
2
2
|
export declare function getCodeBasePaths({ cwd, logger: loggerInput, }: {
|
|
3
3
|
cwd: string;
|
|
4
4
|
logger?: Logger;
|
|
5
|
-
}): Promise<import("
|
|
5
|
+
}): Promise<import("../..").Failure<{
|
|
6
6
|
message: string;
|
|
7
|
-
}> | import("
|
|
7
|
+
}> | import("../..").Success<CodeBasePath[]>>;
|
|
8
8
|
//# sourceMappingURL=main.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getCodeBasePaths/main.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,EACnC,GAAG,EACH,MAAM,EAAE,WAAW,GACtB,EAAE;IACC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getCodeBasePaths/main.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,wBAAsB,gBAAgB,CAAC,EACnC,GAAG,EACH,MAAM,EAAE,WAAW,GACtB,EAAE;IACC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;8CAoBA"}
|
|
@@ -7,7 +7,7 @@ export declare function getToDoContextList(params: {
|
|
|
7
7
|
projectRoot: string;
|
|
8
8
|
baseBranch: string;
|
|
9
9
|
logger?: Logger;
|
|
10
|
-
}): Promise<import("
|
|
10
|
+
}): Promise<import("../..").Failure<{
|
|
11
11
|
message: string;
|
|
12
|
-
}> | import("
|
|
12
|
+
}> | import("../..").Success<import("../..").Context<Record<string, string | number | boolean>>[]>>;
|
|
13
13
|
//# sourceMappingURL=main.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getToDoContextList/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../../src/helpers/getToDoContextList/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;;oGA8DA"}
|
package/dist/index.cjs
CHANGED
|
@@ -86,6 +86,10 @@ const DEFAULT_WINDOWS_PATHEXT = [
|
|
|
86
86
|
'.WSH',
|
|
87
87
|
'.MSC',
|
|
88
88
|
];
|
|
89
|
+
/** Matches a quoted script path using %dp0% / %~dp0 relative to a Windows .cmd shim. */
|
|
90
|
+
const WINDOWS_DP0_SCRIPT_RE = /"(?:%dp0%|%~dp0)\\?((?:[^"\r\n])+?\.(?:js|mjs|cjs))"/i;
|
|
91
|
+
/** Absolute Windows path to a Node script in quotes. */
|
|
92
|
+
const WINDOWS_ABS_SCRIPT_RE = /"([A-Za-z]:\\[^"\r\n]+\.(?:js|mjs|cjs))"/i;
|
|
89
93
|
function windowsPathext() {
|
|
90
94
|
const fromEnv = process.env.PATHEXT?.split(';').map((entry) => entry.trim()).filter(Boolean);
|
|
91
95
|
return fromEnv?.length ? fromEnv : DEFAULT_WINDOWS_PATHEXT;
|
|
@@ -151,9 +155,83 @@ function wrapWindowsCmdShim(resolvedPath, args) {
|
|
|
151
155
|
args: ['/d', '/s', '/c', resolvedPath, ...args],
|
|
152
156
|
};
|
|
153
157
|
}
|
|
158
|
+
function resolveWindowsJsPathFromShim(shimDir, relativeOrAbsolute) {
|
|
159
|
+
if (/^[A-Za-z]:[\\/]/.test(relativeOrAbsolute)) {
|
|
160
|
+
return path__namespace.resolve(relativeOrAbsolute);
|
|
161
|
+
}
|
|
162
|
+
// Normalize Windows separators so stubbed-win32 tests on POSIX still resolve.
|
|
163
|
+
const parts = relativeOrAbsolute.replace(/^[\\/]+/, '').split(/[/\\]+/).filter(Boolean);
|
|
164
|
+
return path__namespace.resolve(shimDir, ...parts);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Prefer a real Node binary — never a .cmd/.bat shim (those reintroduce cmd.exe),
|
|
168
|
+
* and never the host SEA/`lumpcode` binary via process.execPath.
|
|
169
|
+
* Returns bare `"node"` as last resort so spawn fails with ENOENT instead of
|
|
170
|
+
* silently falling back to cmd.exe after a Node entry was identified.
|
|
171
|
+
*/
|
|
172
|
+
function resolveNodeExecutable(preferredDir) {
|
|
173
|
+
if (preferredDir != null) {
|
|
174
|
+
const bundledNode = path__namespace.join(preferredDir, 'node.exe');
|
|
175
|
+
if (fileExists(bundledNode)) {
|
|
176
|
+
return bundledNode;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
for (const name of ['node.exe', 'node']) {
|
|
180
|
+
const found = resolveOnPath(name);
|
|
181
|
+
if (!found)
|
|
182
|
+
continue;
|
|
183
|
+
const ext = path__namespace.extname(found).toLowerCase();
|
|
184
|
+
if (ext === '.cmd' || ext === '.bat')
|
|
185
|
+
continue;
|
|
186
|
+
return found;
|
|
187
|
+
}
|
|
188
|
+
const base = path__namespace.basename(process.execPath).toLowerCase();
|
|
189
|
+
if (base === 'node' || base === 'node.exe') {
|
|
190
|
+
return process.execPath;
|
|
191
|
+
}
|
|
192
|
+
return 'node';
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Parse an npm/yarn-style Windows `.cmd` shim to `node <script.js>`.
|
|
196
|
+
* Returns null only when the file is not a recognizable Node cmd-shim
|
|
197
|
+
* (caller may wrap with cmd.exe). Once a script path is found, never falls
|
|
198
|
+
* back to cmd.exe — missing Node uses bare `"node"` for a clear spawn failure.
|
|
199
|
+
*/
|
|
200
|
+
function tryUnwrapWindowsNpmCmdShim(cmdPath) {
|
|
201
|
+
let body;
|
|
202
|
+
try {
|
|
203
|
+
body = fs__namespace.readFileSync(cmdPath, 'utf8');
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
const shimDir = path__namespace.dirname(cmdPath);
|
|
209
|
+
const lines = body.split(/\r?\n/);
|
|
210
|
+
// Windows npm-cmd-shim ends with `%*` pass-through; prefer that line for the script path.
|
|
211
|
+
const passThroughLine = [...lines].reverse().find((line) => /%\*\s*$/.test(line));
|
|
212
|
+
const searchOrder = passThroughLine != null ? [passThroughLine, body] : [body];
|
|
213
|
+
for (const searchIn of searchOrder) {
|
|
214
|
+
const dp0Match = searchIn.match(WINDOWS_DP0_SCRIPT_RE);
|
|
215
|
+
if (dp0Match?.[1]) {
|
|
216
|
+
const candidate = resolveWindowsJsPathFromShim(shimDir, dp0Match[1]);
|
|
217
|
+
if (fileExists(candidate)) {
|
|
218
|
+
return { scriptPath: candidate };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const absMatch = searchIn.match(WINDOWS_ABS_SCRIPT_RE);
|
|
222
|
+
if (absMatch?.[1] && fileExists(absMatch[1])) {
|
|
223
|
+
return { scriptPath: absMatch[1] };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
154
228
|
/**
|
|
155
229
|
* Resolves bare executable names on Windows so npm-style `.cmd` shims and
|
|
156
230
|
* extensionless Node entrypoints work with `child_process.spawn` (no shell).
|
|
231
|
+
*
|
|
232
|
+
* For Node agent CLIs installed via npm (copilot.cmd, cursor-agent.cmd, …),
|
|
233
|
+
* unwraps the shim to `node <entry.js> …args` so prompt argv is not mangled by
|
|
234
|
+
* cmd.exe / `%*`. Unrecognized `.cmd`/`.bat` files still wrap through cmd.exe.
|
|
157
235
|
*/
|
|
158
236
|
function resolveSpawnExecutable(executable, args) {
|
|
159
237
|
if (process.platform !== 'win32') {
|
|
@@ -174,17 +252,52 @@ function resolveSpawnExecutable(executable, args) {
|
|
|
174
252
|
}
|
|
175
253
|
const ext = path__namespace.extname(resolved).toLowerCase();
|
|
176
254
|
if (ext === '.cmd' || ext === '.bat') {
|
|
255
|
+
const unwrapped = tryUnwrapWindowsNpmCmdShim(resolved);
|
|
256
|
+
if (unwrapped != null) {
|
|
257
|
+
return {
|
|
258
|
+
executable: resolveNodeExecutable(path__namespace.dirname(resolved)),
|
|
259
|
+
args: [unwrapped.scriptPath, ...args],
|
|
260
|
+
};
|
|
261
|
+
}
|
|
177
262
|
return wrapWindowsCmdShim(resolved, args);
|
|
178
263
|
}
|
|
179
264
|
if (isNodeScript(resolved)) {
|
|
180
265
|
return {
|
|
181
|
-
executable:
|
|
266
|
+
executable: resolveNodeExecutable(path__namespace.dirname(resolved)),
|
|
182
267
|
args: [resolved, ...args],
|
|
183
268
|
};
|
|
184
269
|
}
|
|
185
270
|
return { executable: resolved, args };
|
|
186
271
|
}
|
|
187
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Minimal Windows npm-cmd-shim `.cmd` body (modern `"%_prog%"` + `"%dp0%\\…\\.js" %*` form).
|
|
275
|
+
* Shared by core spawn tests and CLI e2e path-agent install — do not duplicate.
|
|
276
|
+
*/
|
|
277
|
+
function windowsNpmCmdShimBody(relativeJsFromShimDir) {
|
|
278
|
+
const target = relativeJsFromShimDir.replace(/\//g, '\\');
|
|
279
|
+
return [
|
|
280
|
+
'@ECHO off',
|
|
281
|
+
'GOTO start',
|
|
282
|
+
':find_dp0',
|
|
283
|
+
'SET dp0=%~dp0',
|
|
284
|
+
'EXIT /b',
|
|
285
|
+
':start',
|
|
286
|
+
'SETLOCAL',
|
|
287
|
+
'CALL :find_dp0',
|
|
288
|
+
'',
|
|
289
|
+
'IF EXIST "%dp0%\\node.exe" (',
|
|
290
|
+
' SET "_prog=%dp0%\\node.exe"',
|
|
291
|
+
') ELSE (',
|
|
292
|
+
' SET "_prog=node"',
|
|
293
|
+
' SET PATHEXT=%PATHEXT:;.JS;=;%',
|
|
294
|
+
')',
|
|
295
|
+
'',
|
|
296
|
+
`endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & set PATHEXT=%PATHEXT:;.JS;=;% & "%_prog%" "%dp0%\\${target}" %*`,
|
|
297
|
+
'',
|
|
298
|
+
].join('\r\n');
|
|
299
|
+
}
|
|
300
|
+
|
|
188
301
|
function formatMessage(prefix, message) {
|
|
189
302
|
if (!prefix)
|
|
190
303
|
return message;
|
|
@@ -3165,6 +3278,38 @@ async function pathExists(filePath) {
|
|
|
3165
3278
|
}
|
|
3166
3279
|
}
|
|
3167
3280
|
|
|
3281
|
+
/** Strip terminal ANSI escapes and other C0 controls js-yaml rejects in literal blocks. */
|
|
3282
|
+
function sanitizeHistoryText(value) {
|
|
3283
|
+
return value
|
|
3284
|
+
.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '')
|
|
3285
|
+
.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, '');
|
|
3286
|
+
}
|
|
3287
|
+
function parseHistoryYamlContent(content) {
|
|
3288
|
+
const parsed = load(content, { schema: YAML11_SCHEMA });
|
|
3289
|
+
if (!Array.isArray(parsed)) {
|
|
3290
|
+
throw new Error('History file must contain a YAML sequence');
|
|
3291
|
+
}
|
|
3292
|
+
return parsed;
|
|
3293
|
+
}
|
|
3294
|
+
function tryParseHistoryContent(content) {
|
|
3295
|
+
try {
|
|
3296
|
+
return parseHistoryYamlContent(content);
|
|
3297
|
+
}
|
|
3298
|
+
catch (firstError) {
|
|
3299
|
+
const sanitized = sanitizeHistoryText(content);
|
|
3300
|
+
if (sanitized === content) {
|
|
3301
|
+
throw firstError;
|
|
3302
|
+
}
|
|
3303
|
+
return parseHistoryYamlContent(sanitized);
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
function sanitizeHistoryEntry(entry) {
|
|
3307
|
+
return {
|
|
3308
|
+
...entry,
|
|
3309
|
+
prompt: sanitizeHistoryText(entry.prompt),
|
|
3310
|
+
commandResult: sanitizeHistoryText(entry.commandResult),
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3168
3313
|
function historyFormatFromPath(filePath) {
|
|
3169
3314
|
const ext = path.extname(filePath).toLowerCase();
|
|
3170
3315
|
if (ext === '.yaml' || ext === '.yml') {
|
|
@@ -3202,7 +3347,8 @@ function dumpHistoryEntries(entries) {
|
|
|
3202
3347
|
if (entries.length === 0) {
|
|
3203
3348
|
return '[]\n';
|
|
3204
3349
|
}
|
|
3205
|
-
|
|
3350
|
+
const sanitizedEntries = entries.map(sanitizeHistoryEntry);
|
|
3351
|
+
return dump(sanitizedEntries, {
|
|
3206
3352
|
schema: YAML11_SCHEMA,
|
|
3207
3353
|
lineWidth: 0,
|
|
3208
3354
|
noRefs: true,
|
|
@@ -3220,11 +3366,7 @@ async function readHistoryFile({ filePath, }) {
|
|
|
3220
3366
|
}
|
|
3221
3367
|
try {
|
|
3222
3368
|
const content = await fs$1.readFile(filePath, 'utf-8');
|
|
3223
|
-
|
|
3224
|
-
if (!Array.isArray(parsed)) {
|
|
3225
|
-
return failure(`History file ${filePath} must contain a YAML sequence`);
|
|
3226
|
-
}
|
|
3227
|
-
return success(parsed);
|
|
3369
|
+
return success(tryParseHistoryContent(content));
|
|
3228
3370
|
}
|
|
3229
3371
|
catch (error) {
|
|
3230
3372
|
const detail = error instanceof Error ? error.message : String(error);
|
|
@@ -3264,7 +3406,7 @@ async function appendHistoryEntry({ filePath, entry, }) {
|
|
|
3264
3406
|
await fs$1.mkdir(path.dirname(filePath), { recursive: true });
|
|
3265
3407
|
entries = [];
|
|
3266
3408
|
}
|
|
3267
|
-
entries.push(entry);
|
|
3409
|
+
entries.push(sanitizeHistoryEntry(entry));
|
|
3268
3410
|
return writeHistoryFile({ filePath, entries });
|
|
3269
3411
|
}
|
|
3270
3412
|
|
|
@@ -3977,5 +4119,6 @@ exports.set = set;
|
|
|
3977
4119
|
exports.shellSingleQuote = shellSingleQuote;
|
|
3978
4120
|
exports.success = success;
|
|
3979
4121
|
exports.validateContextListNames = validateContextListNames;
|
|
4122
|
+
exports.windowsNpmCmdShimBody = windowsNpmCmdShimBody;
|
|
3980
4123
|
exports.writeHistoryFile = writeHistoryFile;
|
|
3981
4124
|
//# sourceMappingURL=index.cjs.map
|