@vzn/vx 0.0.48 → 0.0.50

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.48",
3
+ "version": "0.0.50",
4
4
  "description": "An open, extensible monorepo task runner.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,10 +17,10 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@vzn/vx-linux-x64": "0.0.48",
21
- "@vzn/vx-linux-arm64": "0.0.48",
22
- "@vzn/vx-darwin-x64": "0.0.48",
23
- "@vzn/vx-darwin-arm64": "0.0.48"
20
+ "@vzn/vx-linux-x64": "0.0.50",
21
+ "@vzn/vx-linux-arm64": "0.0.50",
22
+ "@vzn/vx-darwin-x64": "0.0.50",
23
+ "@vzn/vx-darwin-arm64": "0.0.50"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
package/src/cli/lock.ts CHANGED
@@ -124,9 +124,13 @@ async function checkLock(root: string, metas: ConfiguredMeta[], bare: number): P
124
124
  JSON.stringify(await loadProjectConfig(m.configPath, { fresh: true })),
125
125
  ) as ProjectConfig
126
126
  if (!Bun.deepEquals(fresh, entry.config, true)) {
127
+ // Bytes unchanged, so the drift is in what the evaluation read: a
128
+ // file the config imports, or the environment. Blaming only the
129
+ // environment sent an edited preset's author looking for env reads
130
+ // the config does not have (item 1044).
127
131
  return (
128
132
  `lock differs from fresh evaluation in this environment (${m.name}) — ` +
129
- `env-dependent config? run 'vx lock' here or remove env reads from config`
133
+ `a file the config imports changed, or the config reads the environment; run 'vx lock' here`
130
134
  )
131
135
  }
132
136
  return null
@@ -90,13 +90,20 @@ function scriptsOf(meta: ProjectMeta): Record<string, unknown> {
90
90
  return raw as Record<string, unknown>
91
91
  }
92
92
 
93
+ /** The cache block the task that builds should declare, as a TODO on it. */
94
+ const CACHE_TODO =
95
+ "cache: add `cache: { inputs: { files: ['src/**'] }, outputs: { files: ['dist/**'] } }` with this package's real inputs and outputs — without it the task always runs and every file here, what it writes included, folds into the key its dependents fold; a block with EMPTY outputs would be a cached no-op, not an uncached task"
96
+
93
97
  /**
94
98
  * A `build` that only delegates (`build: pnpm run compile`) is a group over
95
99
  * its target, and the `^build` edge every `build` carries belongs on the
96
100
  * task that does the work: the group ran `compile` with no edge at all, so
97
101
  * a package compiled before the ones it imports had built (item 907). On
98
102
  * the group itself it would not hold — the group waits on both, `compile`
99
- * on neither. Followed through a chain of groups to the first command.
103
+ * on neither. Followed through a chain of groups to the first command,
104
+ * which takes the cache TODO too: a group has no command to cache, and the
105
+ * TODO a delegating `build` never got was the one the header promised
106
+ * (item 1045).
100
107
  */
101
108
  function upstreamBuildOnWorker(tasks: GeneratedTask[]): void {
102
109
  const byName = new Map(tasks.map((t) => [t.name, t]))
@@ -111,6 +118,7 @@ function upstreamBuildOnWorker(tasks: GeneratedTask[]): void {
111
118
  if (at === undefined || at.name === 'build' || at.task === null || at.task === undefined) return
112
119
  const deps = Array.isArray(at.task['dependsOn']) ? (at.task['dependsOn'] as string[]) : []
113
120
  if (!deps.includes('^build')) at.task['dependsOn'] = ['^build', ...deps]
121
+ if (!at.todos.includes(CACHE_TODO)) at.todos.push(CACHE_TODO)
114
122
  }
115
123
 
116
124
  export function migrateScripts(metas: readonly ProjectMeta[]): MigrationPlan {
@@ -175,9 +183,7 @@ export function migrateScripts(metas: readonly ProjectMeta[]): MigrationPlan {
175
183
  }
176
184
  if (name === 'build') {
177
185
  task['dependsOn'] = ['^build']
178
- todos.push(
179
- "cache: add `cache: { inputs: { files: ['src/**'] }, outputs: { files: ['dist/**'] } }` with this package's real inputs and outputs — without it the task always runs and every file here, what it writes included, folds into the key its dependents fold; a block with EMPTY outputs would be a cached no-op, not an uncached task",
180
- )
186
+ todos.push(CACHE_TODO)
181
187
  } else if (AFTER_BUILD.has(name) && hasBuild) {
182
188
  task['dependsOn'] = ['build']
183
189
  }
@@ -197,7 +203,7 @@ export function migrateScripts(metas: readonly ProjectMeta[]): MigrationPlan {
197
203
  }
198
204
  return {
199
205
  headerNotes: [
200
- 'each script became a task with its command verbatim; caching needs declared inputs and outputs, so no task got a cache block — `build` carries a TODO showing the one to add',
206
+ 'each script became a task with its command verbatim; caching needs declared inputs and outputs, so no task got a cache block — `build`, or the script it delegates to, carries a TODO showing the one to add',
201
207
  ],
202
208
  projects,
203
209
  extraFiles: [],