@vzn/vx 0.0.634 → 0.0.635
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 +51 -52
- package/docs/caching.md +7 -1
- package/docs/cli.md +102 -35
- package/docs/features.md +2 -1
- package/docs/patterns.md +8 -5
- package/docs/schema.md +34 -2
- package/docs/security.md +6 -0
- package/launcher.cjs +0 -0
- package/launcher.sh +50 -0
- package/package.json +17 -8
- package/schemas/last.json +5 -1
- package/schemas/show.json +2 -1
- package/schemas/why.json +4 -1
- package/src/cache/layered-cache.ts +3 -1
- package/src/cli/last.ts +9 -1
- package/src/cli/plugin-templates.ts +1 -1
- package/src/cli/run.ts +9 -6
- package/src/cli/select.ts +17 -11
- package/src/cli/show.ts +2 -2
- package/src/config.ts +14 -2
- package/src/graph/scheduler.ts +14 -3
- package/src/graph/task-graph.ts +22 -5
- package/src/index.ts +6 -1
- package/src/orchestrator/execute-task.ts +30 -1
- package/src/orchestrator/framed-output.ts +27 -1
- package/src/orchestrator/history.ts +75 -1
- package/src/orchestrator/index.ts +1 -0
- package/src/orchestrator/path-links.ts +5 -3
- package/src/orchestrator/plugin.ts +3 -1
- package/src/orchestrator/prepare.ts +15 -12
- package/src/orchestrator/run-failures.ts +20 -3
- package/src/orchestrator/run.ts +11 -1
- package/src/orchestrator/sandbox-fix.ts +123 -0
- package/src/orchestrator/task-hash.ts +7 -1
- package/src/workspace/affected.ts +16 -4
- package/src/workspace/config-schema.ts +14 -2
- package/src/workspace/migration.ts +51 -4
- package/src/workspace/project-loader.ts +3 -1
|
@@ -377,6 +377,18 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
377
377
|
// One reason, its tasks: on a Turbo template the same two-line cache TODO
|
|
378
378
|
// printed five times and the persistent one eight (the first-five-minutes
|
|
379
379
|
// walk, 2026-09-28), and the list read as noise.
|
|
380
|
+
// A file .gitignore drops is lost at the first commit, unnoticed: vueuse
|
|
381
|
+
// ignores `packages/**/*.mjs`, so `--mjs` wrote configs git never saw.
|
|
382
|
+
const ignored = gitIgnored(
|
|
383
|
+
root,
|
|
384
|
+
files.map((f) => f.relPath),
|
|
385
|
+
)
|
|
386
|
+
const ignoredNote =
|
|
387
|
+
ignored.length === 0
|
|
388
|
+
? []
|
|
389
|
+
: [
|
|
390
|
+
`.gitignore drops ${ignored.length} file${ignored.length === 1 ? '' : 's'} this ${dry ? 'would write' : 'wrote'} (${ignored.slice(0, TODO_IDS_SHOWN).join(', ')}${ignored.length > TODO_IDS_SHOWN ? ', …' : ''}): add ${[...new Set(ignored.map((f) => `!${path.posix.basename(f)}`))].join(' and ')} to .gitignore, or commit them with git add -f`,
|
|
391
|
+
]
|
|
380
392
|
const todos = new Map<string, string[]>()
|
|
381
393
|
let todoCount = 0
|
|
382
394
|
let clean = 0
|
|
@@ -423,7 +435,7 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
423
435
|
args.unmapped === true
|
|
424
436
|
? `${verb}: no package.json scripts became tasks.`
|
|
425
437
|
: `${verb}: no package.json scripts to turn into tasks.`,
|
|
426
|
-
...[...noMembers, ...(args.notes ?? [])].map((n) => `note: ${n}`),
|
|
438
|
+
...[...noMembers, ...(args.notes ?? []), ...ignoredNote].map((n) => `note: ${n}`),
|
|
427
439
|
hasWorkspaceFile
|
|
428
440
|
? `${workspaceName} already exists.`
|
|
429
441
|
: dry
|
|
@@ -438,7 +450,7 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
438
450
|
)
|
|
439
451
|
} else {
|
|
440
452
|
report.push(`${verb}: ${source} → ${configName}`)
|
|
441
|
-
for (const n of args.notes ?? []) report.push(`note: ${n}`)
|
|
453
|
+
for (const n of [...(args.notes ?? []), ...ignoredNote]) report.push(`note: ${n}`)
|
|
442
454
|
for (const n of plan.headerNotes) report.push(`note: ${n}`)
|
|
443
455
|
report.push(
|
|
444
456
|
'',
|
|
@@ -470,7 +482,10 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
470
482
|
// A run of tasks none of which caches is never a hit, and a first try
|
|
471
483
|
// that runs twice to see the cache work saw it run twice.
|
|
472
484
|
if (!cached && [...todos.keys()].some(isCacheTodo)) {
|
|
473
|
-
report.push(
|
|
485
|
+
report.push(
|
|
486
|
+
'',
|
|
487
|
+
'no task caches yet: uncomment the cache line in each TODO task with its real globs, and a second run hits',
|
|
488
|
+
)
|
|
474
489
|
}
|
|
475
490
|
const installed = existsSync(path.join(root, 'node_modules', '@vzn', 'vx', 'package.json'))
|
|
476
491
|
// The line is the next thing to type, so it names what that run would
|
|
@@ -495,6 +510,7 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
495
510
|
...(empty && unreached.length > 0 ? [unreachedHint(unreached, root)] : []),
|
|
496
511
|
...(empty ? noMembers : []),
|
|
497
512
|
...(args.notes ?? []),
|
|
513
|
+
...ignoredNote,
|
|
498
514
|
...plan.headerNotes,
|
|
499
515
|
...plan.notes,
|
|
500
516
|
],
|
|
@@ -508,6 +524,28 @@ export async function applyMigration(args: ApplyMigrationArgs): Promise<number>
|
|
|
508
524
|
return 0
|
|
509
525
|
}
|
|
510
526
|
|
|
527
|
+
/** The paths (root-relative) git's ignore rules drop; none outside a work tree. */
|
|
528
|
+
function gitIgnored(root: string, relPaths: readonly string[]): string[] {
|
|
529
|
+
if (relPaths.length === 0) return []
|
|
530
|
+
try {
|
|
531
|
+
const r = Bun.spawnSync({
|
|
532
|
+
cmd: [executablePath('git'), 'check-ignore', '--stdin', '-z'],
|
|
533
|
+
cwd: root,
|
|
534
|
+
stdin: Buffer.from(relPaths.map((p) => `${p}\0`).join('')),
|
|
535
|
+
stdout: 'pipe',
|
|
536
|
+
stderr: 'ignore',
|
|
537
|
+
})
|
|
538
|
+
// 0: some ignored; 1: none; anything else (no work tree): nothing to say.
|
|
539
|
+
if (r.exitCode !== 0) return []
|
|
540
|
+
return r.stdout
|
|
541
|
+
.toString()
|
|
542
|
+
.split('\0')
|
|
543
|
+
.filter((p) => p !== '')
|
|
544
|
+
} catch {
|
|
545
|
+
return []
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
511
549
|
function inGitWorkTree(root: string): boolean {
|
|
512
550
|
try {
|
|
513
551
|
return (
|
|
@@ -660,7 +698,16 @@ function renderConfigFile(p: GeneratedProject, format: MigrationFormat): string
|
|
|
660
698
|
: IDENT.test(t.name)
|
|
661
699
|
? t.name
|
|
662
700
|
: quoteTsLiteral(t.name)
|
|
663
|
-
|
|
701
|
+
const rendered = renderValue(t.task, ' ')
|
|
702
|
+
// The suggested block sits in the task, commented: deleting `// `
|
|
703
|
+
// after setting the real globs caches it, no copying from the TODO.
|
|
704
|
+
const block =
|
|
705
|
+
t.task['cache'] === undefined
|
|
706
|
+
? t.todos.find(isCacheTodo)?.match(/^cache: add `(.+?)`/)?.[1]
|
|
707
|
+
: undefined
|
|
708
|
+
lines.push(
|
|
709
|
+
` ${key}: ${block === undefined ? rendered : rendered.replace('{\n', `{\n // ${block},\n`)},`,
|
|
710
|
+
)
|
|
664
711
|
}
|
|
665
712
|
lines.push(' },', format === 'ts' ? '} satisfies ProjectConfig' : '}', '')
|
|
666
713
|
return lines.join('\n')
|
|
@@ -2,7 +2,7 @@ import { existsSync, realpathSync, statSync } from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import type { ProjectConfig, WorkspaceConfig } from '../config.js'
|
|
4
4
|
import { UserError, xxh3hex } from '../util/index.js'
|
|
5
|
-
import { validateProjectConfig, validateWorkspace } from './config-schema.js'
|
|
5
|
+
import { isSkippedPlugin, validateProjectConfig, validateWorkspace } from './config-schema.js'
|
|
6
6
|
import {
|
|
7
7
|
beginEvalRound,
|
|
8
8
|
builtinsChangedBy,
|
|
@@ -1163,6 +1163,8 @@ export async function loadWorkspaceConfig(root: string): Promise<WorkspaceConfig
|
|
|
1163
1163
|
// config at all (D-6).
|
|
1164
1164
|
assertDefaultObject(mod, 'Workspace', configPath)
|
|
1165
1165
|
validateWorkspace(mod, configPath)
|
|
1166
|
+
if (mod.plugins?.some(isSkippedPlugin) === true)
|
|
1167
|
+
mod = { ...mod, plugins: mod.plugins.filter((p) => !isSkippedPlugin(p)) }
|
|
1166
1168
|
// Set by a load that succeeded: a failed one may have left nothing in
|
|
1167
1169
|
// the registry, and its fix must not be refused.
|
|
1168
1170
|
if (since === undefined) workspaceLoadedAt.set(configPath, startedAt)
|