oneworks 0.1.0-alpha.1 → 0.1.0-beta.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.
@@ -1,5 +1,7 @@
1
1
  import { describe, expect, it, vi } from 'vitest'
2
2
 
3
+ import bootstrapPackageJson from '../package.json'
4
+ import { getBootstrapVersion } from '../src/package-config'
3
5
  import { createBootstrapCli, routeBootstrapCommand } from '../src/program'
4
6
 
5
7
  describe('bootstrap cli', () => {
@@ -67,6 +69,23 @@ describe('bootstrap cli', () => {
67
69
  })
68
70
  })
69
71
 
72
+ it('routes runtime package cache versions from flags', () => {
73
+ expect(routeBootstrapCommand('runtime', [
74
+ 'install',
75
+ 'server',
76
+ '--version=2.3.4',
77
+ '--cache-version',
78
+ 'dev-local'
79
+ ])).toEqual({
80
+ action: 'install',
81
+ cacheVersion: 'dev-local',
82
+ json: false,
83
+ kind: 'runtime-package',
84
+ target: 'server',
85
+ version: '2.3.4'
86
+ })
87
+ })
88
+
70
89
  it('routes unknown commands through the CLI package', () => {
71
90
  expect(routeBootstrapCommand('hello', [])).toEqual({
72
91
  commandName: 'oneworks',
@@ -76,6 +95,10 @@ describe('bootstrap cli', () => {
76
95
  })
77
96
  })
78
97
 
98
+ it('reads the current bootstrap package version', () => {
99
+ expect(getBootstrapVersion()).toBe(bootstrapPackageJson.version)
100
+ })
101
+
79
102
  it('dispatches the desktop launcher for app', async () => {
80
103
  const launchDesktopApp = vi.fn(async () => {})
81
104
  const launchInstalledPackage = vi.fn(async () => 0)
@@ -191,6 +214,46 @@ describe('bootstrap cli', () => {
191
214
  expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('"requestedVersion":"1.2.3"'))
192
215
  })
193
216
 
217
+ it('dispatches runtime package installation with a cache version', async () => {
218
+ const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true)
219
+ const installRuntimePackage = vi.fn(async () => ({
220
+ cacheVersion: 'dev-local',
221
+ installed: true,
222
+ installedVersion: '1.2.3',
223
+ latestInstalled: true,
224
+ latestVersion: '1.2.3',
225
+ packageName: '@oneworks/server',
226
+ requestedVersion: '1.2.3',
227
+ target: 'server' as const,
228
+ updateAvailable: false
229
+ }))
230
+ const cli = createBootstrapCli({
231
+ checkRuntimePackage: vi.fn(async () => {
232
+ throw new Error('unexpected check')
233
+ }),
234
+ installRuntimePackage,
235
+ launchDesktopApp: vi.fn(async () => {}),
236
+ launchInstalledPackage: vi.fn(async () => 0)
237
+ })
238
+
239
+ await cli.parseAsync([
240
+ 'node',
241
+ 'oneworks',
242
+ 'runtime',
243
+ 'install',
244
+ 'server',
245
+ '--version=1.2.3',
246
+ '--cache-version=dev-local',
247
+ '--json'
248
+ ])
249
+
250
+ expect(installRuntimePackage).toHaveBeenCalledWith('server', {
251
+ cacheVersion: 'dev-local',
252
+ version: '1.2.3'
253
+ })
254
+ expect(writeSpy).toHaveBeenCalledWith(expect.stringContaining('"cacheVersion":"dev-local"'))
255
+ })
256
+
194
257
  it('forwards --help after a routed command', async () => {
195
258
  const launchDesktopApp = vi.fn(async () => {})
196
259
  const launchInstalledPackage = vi.fn(async () => 0)
@@ -26,13 +26,13 @@ describe('bootstrap runtime package commands', () => {
26
26
  await rm(tempDir, { force: true, recursive: true })
27
27
  })
28
28
 
29
- const writeCachedPackage = async (packageName: string, version: string) => {
29
+ const writeCachedPackage = async (packageName: string, version: string, cacheVersion = version) => {
30
30
  const sanitizedName = packageName.replace(/^@/, '').replace(/[\\/]/g, '__')
31
31
  const packageDir = path.join(
32
32
  tempDir,
33
33
  '.oneworks/bootstrap/npm',
34
34
  sanitizedName,
35
- version,
35
+ cacheVersion,
36
36
  'node_modules',
37
37
  ...packageName.split('/')
38
38
  )
@@ -190,6 +190,49 @@ process.exit(1)
190
190
  ).resolves.toBeUndefined()
191
191
  })
192
192
 
193
+ it('installs a runtime package under an explicit cache version', async () => {
194
+ vi.stubEnv('ONEWORKS_TEST_NPM_VERSION', '9.9.9')
195
+
196
+ await expect(installRuntimePackage('server', {
197
+ cacheVersion: 'dev-local',
198
+ version: '2.2.0'
199
+ })).resolves.toMatchObject({
200
+ cacheVersion: 'dev-local',
201
+ installedVersion: '2.2.0',
202
+ latestInstalled: true,
203
+ latestVersion: '2.2.0',
204
+ packageName: '@oneworks/server',
205
+ requestedVersion: '2.2.0',
206
+ target: 'server',
207
+ updateAvailable: false
208
+ })
209
+ await expect(
210
+ writeFile(
211
+ path.join(
212
+ tempDir,
213
+ '.oneworks/bootstrap/npm/oneworks__server/dev-local/node_modules/@oneworks/server/probe'
214
+ ),
215
+ 'ok'
216
+ )
217
+ ).resolves.toBeUndefined()
218
+ })
219
+
220
+ it('uses the runtime package cache version env for check and install', async () => {
221
+ await writeCachedPackage('@oneworks/server', '2.2.0', 'dev-env')
222
+ vi.stubEnv('ONEWORKS_RUNTIME_PACKAGE_CACHE_VERSION', 'dev-env')
223
+ vi.stubEnv('ONEWORKS_TEST_NPM_VERSION', '2.2.0')
224
+
225
+ await expect(checkRuntimePackage('server')).resolves.toMatchObject({
226
+ cacheVersion: 'dev-env',
227
+ installedVersion: '2.2.0',
228
+ latestInstalled: true,
229
+ latestVersion: '2.2.0',
230
+ packageName: '@oneworks/server',
231
+ target: 'server',
232
+ updateAvailable: false
233
+ })
234
+ })
235
+
193
236
  it('installs the latest client runtime package target', async () => {
194
237
  vi.stubEnv('ONEWORKS_TEST_NPM_VERSION', '2.2.0')
195
238
 
@@ -208,4 +251,10 @@ process.exit(1)
208
251
  'Runtime package version must be an exact semver version'
209
252
  )
210
253
  })
254
+
255
+ it('rejects unsafe runtime package cache versions', async () => {
256
+ await expect(checkRuntimePackage('cli', { cacheVersion: '../dev', version: '1.0.0' })).rejects.toThrow(
257
+ 'Runtime package cache version contains unsupported characters'
258
+ )
259
+ })
211
260
  })
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "oneworks",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "One Works bootstrap launcher",
4
5
  "repository": {
5
6
  "type": "git",
6
7
  "url": "https://github.com/oneworks-ai/app.git",
7
8
  "directory": "apps/bootstrap"
8
9
  },
9
- "description": "One Works bootstrap launcher",
10
10
  "oneworks": {
11
11
  "runtimeTranspile": true,
12
12
  "publishAliases": [
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@clack/prompts": "^0.11.0",
28
28
  "commander": "^12.1.0",
29
- "@oneworks/cli-helper": "0.1.0-alpha.0"
29
+ "@oneworks/cli-helper": "0.1.0-beta.0"
30
30
  },
31
31
  "scripts": {
32
32
  "test": "pnpm -C ../.. exec vitest run --workspace vitest.workspace.ts --project node apps/bootstrap/__tests__"
@@ -1,3 +1,4 @@
1
+ /* eslint-disable max-lines -- package cache resolution keeps shared cache lookup and version fallback policy together. */
1
2
  import { createHash } from 'node:crypto'
2
3
  import { existsSync } from 'node:fs'
3
4
  import { access, mkdir, readFile, rename, writeFile } from 'node:fs/promises'
@@ -9,6 +10,12 @@ import { resolveBootstrapPackageCacheDir, resolveRealHomeDir } from './paths'
9
10
  const DEFAULT_PACKAGE_TAG = 'latest'
10
11
  const DEFAULT_PACKAGE_LOOKUP_TIMEOUT_MS = 1_000
11
12
  const DEFAULT_CACHE_FIRST = true
13
+ const PACKAGE_CACHE_VERSION_PATTERN = /^[\w.+-]+$/u
14
+
15
+ export const RUNTIME_PACKAGE_CACHE_VERSION_ENV = '__ONEWORKS_RUNTIME_PACKAGE_CACHE_VERSION__'
16
+ export const PUBLIC_RUNTIME_PACKAGE_CACHE_VERSION_ENV = 'ONEWORKS_RUNTIME_PACKAGE_CACHE_VERSION'
17
+ export const DESKTOP_DEV_RUNTIME_VERSION_ENV = '__ONEWORKS_DESKTOP_DEV_RUNTIME_VERSION__'
18
+ export const PUBLIC_DESKTOP_DEV_RUNTIME_VERSION_ENV = 'ONEWORKS_DESKTOP_DEV_RUNTIME_VERSION'
12
19
 
13
20
  interface PublishedPackageVersionMetadata {
14
21
  lookupKey: string
@@ -58,8 +65,33 @@ export const shouldUseCachedPackageVersionFirst = () => {
58
65
  return !['0', 'false', 'no', 'off'].includes(rawValue)
59
66
  }
60
67
 
61
- export const resolvePackageCacheDir = (packageName: string, version: string) => (
62
- path.join(resolveBootstrapPackageCacheDir(), 'npm', sanitizePackageName(packageName), version)
68
+ export const normalizePackageCacheVersion = (value: string | undefined) => {
69
+ const normalized = value?.trim()
70
+ if (normalized == null || normalized === '') return undefined
71
+ if (!PACKAGE_CACHE_VERSION_PATTERN.test(normalized) || normalized === '.' || normalized === '..') {
72
+ throw new Error(`Runtime package cache version contains unsupported characters: ${normalized}.`)
73
+ }
74
+ return normalized
75
+ }
76
+
77
+ export const resolveRuntimePackageCacheVersion = () => (
78
+ normalizePackageCacheVersion(process.env[RUNTIME_PACKAGE_CACHE_VERSION_ENV]) ??
79
+ normalizePackageCacheVersion(process.env[PUBLIC_RUNTIME_PACKAGE_CACHE_VERSION_ENV]) ??
80
+ normalizePackageCacheVersion(process.env[DESKTOP_DEV_RUNTIME_VERSION_ENV]) ??
81
+ normalizePackageCacheVersion(process.env[PUBLIC_DESKTOP_DEV_RUNTIME_VERSION_ENV])
82
+ )
83
+
84
+ export const resolvePackageCacheDir = (
85
+ packageName: string,
86
+ version: string,
87
+ options: { cacheVersion?: string } = {}
88
+ ) => (
89
+ path.join(
90
+ resolveBootstrapPackageCacheDir(),
91
+ 'npm',
92
+ sanitizePackageName(packageName),
93
+ normalizePackageCacheVersion(options.cacheVersion) ?? version
94
+ )
63
95
  )
64
96
 
65
97
  export const resolvePackageCacheRootDir = (packageName: string) => (
@@ -6,10 +6,12 @@ import {
6
6
  compareVersionLike,
7
7
  ensureDirectory,
8
8
  isExistingPath,
9
+ normalizePackageCacheVersion,
9
10
  resolvePackageCacheDir,
10
11
  resolvePackageCacheRootDir,
11
12
  resolvePackageInstallDir,
12
- resolvePackageManagerEnv
13
+ resolvePackageManagerEnv,
14
+ resolveRuntimePackageCacheVersion
13
15
  } from './npm-package-cache'
14
16
  import { runBufferedCommand } from './process-utils'
15
17
  import { createBootstrapProgress } from './progress'
@@ -17,6 +19,7 @@ import { createBootstrapProgress } from './progress'
17
19
  const NPM_BIN = process.platform === 'win32' ? 'npm.cmd' : 'npm'
18
20
 
19
21
  interface InstalledPackageInfo {
22
+ cacheVersion: string
20
23
  packageDir: string
21
24
  version: string
22
25
  }
@@ -63,12 +66,19 @@ const formatInstallError = (message: string, stderr: string) => {
63
66
  return detail ? `${message}\n${detail}` : message
64
67
  }
65
68
 
66
- export const installPublishedPackage = async (packageName: string, version: string): Promise<InstalledPackageInfo> => {
67
- const cacheDir = resolvePackageCacheDir(packageName, version)
69
+ export const installPublishedPackage = async (
70
+ packageName: string,
71
+ version: string,
72
+ options: { cacheVersion?: string } = {}
73
+ ): Promise<InstalledPackageInfo> => {
74
+ const cacheVersion = normalizePackageCacheVersion(options.cacheVersion) ??
75
+ resolveRuntimePackageCacheVersion() ??
76
+ version
77
+ const cacheDir = resolvePackageCacheDir(packageName, version, { cacheVersion })
68
78
  const packageDir = resolvePackageInstallDir(cacheDir, packageName)
69
79
  const installedVersion = await readInstalledPackageVersion(packageDir)
70
80
  if (installedVersion === version) {
71
- return { packageDir, version }
81
+ return { cacheVersion, packageDir, version }
72
82
  }
73
83
 
74
84
  const stagingDir = `${cacheDir}.tmp-${process.pid}-${Date.now()}`
@@ -76,7 +86,9 @@ export const installPublishedPackage = async (packageName: string, version: stri
76
86
  await ensureDirectory(stagingDir)
77
87
 
78
88
  const progress = createBootstrapProgress({
79
- label: `installing ${packageName}@${version} into bootstrap cache`
89
+ label: cacheVersion === version
90
+ ? `installing ${packageName}@${version} into bootstrap cache`
91
+ : `installing ${packageName}@${version} into bootstrap cache ${cacheVersion}`
80
92
  })
81
93
  try {
82
94
  const result = await runBufferedCommand({
@@ -100,7 +112,11 @@ export const installPublishedPackage = async (packageName: string, version: stri
100
112
  await ensureDirectory(path.dirname(cacheDir))
101
113
  await rm(cacheDir, { recursive: true, force: true })
102
114
  await rename(stagingDir, cacheDir)
103
- progress.finish(`cached ${packageName}@${version}`)
115
+ progress.finish(
116
+ cacheVersion === version
117
+ ? `cached ${packageName}@${version}`
118
+ : `cached ${packageName}@${version} as ${cacheVersion}`
119
+ )
104
120
  } catch (error) {
105
121
  progress.fail(`failed to cache ${packageName}@${version}`)
106
122
  await rm(stagingDir, { recursive: true, force: true }).catch(() => {})
@@ -108,6 +124,7 @@ export const installPublishedPackage = async (packageName: string, version: stri
108
124
  }
109
125
 
110
126
  return {
127
+ cacheVersion,
111
128
  packageDir: resolvePackageInstallDir(cacheDir, packageName),
112
129
  version
113
130
  }
@@ -4,7 +4,7 @@ const getPackageJson = () => {
4
4
  if (!packageJson) {
5
5
  try {
6
6
  // eslint-disable-next-line ts/no-require-imports
7
- packageJson = require('oneworks/package.json') as Record<string, unknown>
7
+ packageJson = require('../package.json') as Record<string, unknown>
8
8
  } catch {
9
9
  packageJson = {}
10
10
  }
package/src/program.ts CHANGED
@@ -35,6 +35,7 @@ type BootstrapTarget =
35
35
  }
36
36
  | {
37
37
  action: RuntimePackageAction
38
+ cacheVersion?: string
38
39
  json: boolean
39
40
  kind: 'runtime-package'
40
41
  target?: string
@@ -88,6 +89,7 @@ const parseRuntimePackageTarget = (args: string[]): BootstrapTarget => {
88
89
  }
89
90
 
90
91
  let version: string | undefined
92
+ let cacheVersion: string | undefined
91
93
  for (let index = 0; index < forwardedArgs.length; index += 1) {
92
94
  const arg = forwardedArgs[index]
93
95
  if (arg === '--version') {
@@ -109,6 +111,28 @@ const parseRuntimePackageTarget = (args: string[]): BootstrapTarget => {
109
111
  version = value
110
112
  forwardedArgs.splice(index, 1)
111
113
  index -= 1
114
+ continue
115
+ }
116
+
117
+ if (arg === '--cache-version') {
118
+ const value = forwardedArgs[index + 1]
119
+ if (value == null || value.trim() === '') {
120
+ throw new Error('Runtime package --cache-version requires a value.')
121
+ }
122
+ cacheVersion = value
123
+ forwardedArgs.splice(index, 2)
124
+ index -= 1
125
+ continue
126
+ }
127
+
128
+ if (arg?.startsWith('--cache-version=')) {
129
+ const value = arg.slice('--cache-version='.length)
130
+ if (value.trim() === '') {
131
+ throw new Error('Runtime package --cache-version requires a value.')
132
+ }
133
+ cacheVersion = value
134
+ forwardedArgs.splice(index, 1)
135
+ index -= 1
112
136
  }
113
137
  }
114
138
 
@@ -130,6 +154,7 @@ const parseRuntimePackageTarget = (args: string[]): BootstrapTarget => {
130
154
 
131
155
  return {
132
156
  action,
157
+ ...(cacheVersion != null ? { cacheVersion } : {}),
133
158
  json,
134
159
  kind: 'runtime-package',
135
160
  target: selectorTarget,
@@ -216,6 +241,7 @@ Examples:
216
241
  npx oneworks runtime check cli@0.1.0-alpha.0
217
242
  npx oneworks runtime install server
218
243
  npx oneworks runtime install server --version 0.1.0-alpha.0
244
+ npx oneworks runtime install server --version 0.1.0-alpha.0 --cache-version dev-local
219
245
  npx oneworks app
220
246
  npx oneworks app cache
221
247
  npx oneworks app --no-cache
@@ -240,15 +266,20 @@ Examples:
240
266
  }
241
267
 
242
268
  if (target.kind === 'runtime-package') {
269
+ const runtimeOptions: RuntimePackageOptions = {
270
+ ...(target.version == null ? {} : { version: target.version }),
271
+ ...(target.cacheVersion == null ? {} : { cacheVersion: target.cacheVersion })
272
+ }
273
+ const hasRuntimeOptions = Object.keys(runtimeOptions).length > 0
243
274
  let status: RuntimePackageStatus
244
275
  if (target.action === 'install') {
245
- status = target.version == null
276
+ status = !hasRuntimeOptions
246
277
  ? await deps.installRuntimePackage(target.target)
247
- : await deps.installRuntimePackage(target.target, { version: target.version })
278
+ : await deps.installRuntimePackage(target.target, runtimeOptions)
248
279
  } else {
249
- status = target.version == null
280
+ status = !hasRuntimeOptions
250
281
  ? await deps.checkRuntimePackage(target.target)
251
- : await deps.checkRuntimePackage(target.target, { version: target.version })
282
+ : await deps.checkRuntimePackage(target.target, runtimeOptions)
252
283
  }
253
284
  const output = target.json ? JSON.stringify(status) : formatRuntimePackageStatus(status)
254
285
  process.stdout.write(`${output}\n`)
@@ -1,5 +1,10 @@
1
1
  import { resolvePublishedPackageVersion } from './npm-package'
2
- import { resolvePackageCacheDir, resolvePackageInstallDir } from './npm-package-cache'
2
+ import {
3
+ normalizePackageCacheVersion,
4
+ resolvePackageCacheDir,
5
+ resolvePackageInstallDir,
6
+ resolveRuntimePackageCacheVersion
7
+ } from './npm-package-cache'
3
8
  import {
4
9
  findInstalledPublishedPackageVersion,
5
10
  installPublishedPackage,
@@ -10,10 +15,12 @@ export type RuntimePackageAction = 'check' | 'install'
10
15
  export type RuntimePackageTarget = 'cli' | 'client' | 'server' | 'web'
11
16
 
12
17
  export interface RuntimePackageOptions {
18
+ cacheVersion?: string
13
19
  version?: string
14
20
  }
15
21
 
16
22
  export interface RuntimePackageStatus {
23
+ cacheVersion?: string
17
24
  installed: boolean
18
25
  installedVersion?: string
19
26
  latestInstalled: boolean
@@ -56,8 +63,11 @@ export const resolveRuntimePackageTarget = (value: string | undefined): RuntimeP
56
63
  )
57
64
  }
58
65
 
59
- const readVersionInstalledAt = async (packageName: string, version: string) => {
60
- const packageDir = resolvePackageInstallDir(resolvePackageCacheDir(packageName, version), packageName)
66
+ const readVersionInstalledAt = async (packageName: string, version: string, cacheVersion = version) => {
67
+ const packageDir = resolvePackageInstallDir(
68
+ resolvePackageCacheDir(packageName, version, { cacheVersion }),
69
+ packageName
70
+ )
61
71
  return await readInstalledPackageVersion(packageDir)
62
72
  }
63
73
 
@@ -70,12 +80,19 @@ const createRuntimePackageStatus = async (
70
80
  target: RuntimePackageTarget,
71
81
  packageName: string,
72
82
  targetVersion: string,
73
- requestedVersion: string | undefined
83
+ requestedVersion: string | undefined,
84
+ requestedCacheVersion: string | undefined
74
85
  ): Promise<RuntimePackageStatus> => {
75
- const installedVersion = await findInstalledPublishedPackageVersion(packageName)
76
- const targetInstalled = await readVersionInstalledAt(packageName, targetVersion) === targetVersion
86
+ const cacheVersion = normalizePackageCacheVersion(requestedCacheVersion)
87
+ const resolvedCacheVersion = cacheVersion ?? targetVersion
88
+ const installedVersion = cacheVersion == null
89
+ ? await findInstalledPublishedPackageVersion(packageName)
90
+ : await readVersionInstalledAt(packageName, targetVersion, resolvedCacheVersion)
91
+ const targetInstalled =
92
+ await readVersionInstalledAt(packageName, targetVersion, resolvedCacheVersion) === targetVersion
77
93
 
78
94
  return {
95
+ ...(cacheVersion != null ? { cacheVersion } : {}),
79
96
  installed: installedVersion != null,
80
97
  ...(installedVersion != null ? { installedVersion } : {}),
81
98
  latestInstalled: targetInstalled,
@@ -83,7 +100,9 @@ const createRuntimePackageStatus = async (
83
100
  packageName,
84
101
  ...(requestedVersion != null ? { requestedVersion } : {}),
85
102
  target,
86
- updateAvailable: requestedVersion != null ? !targetInstalled : installedVersion !== targetVersion
103
+ updateAvailable: requestedVersion != null || cacheVersion != null
104
+ ? !targetInstalled
105
+ : installedVersion !== targetVersion
87
106
  }
88
107
  }
89
108
 
@@ -94,8 +113,9 @@ export const checkRuntimePackage = async (
94
113
  const target = resolveRuntimePackageTarget(targetValue)
95
114
  const packageName = RUNTIME_PACKAGE_NAMES[target]
96
115
  const requestedVersion = normalizeRequestedVersion(options.version)
116
+ const cacheVersion = normalizePackageCacheVersion(options.cacheVersion) ?? resolveRuntimePackageCacheVersion()
97
117
  const targetVersion = requestedVersion ?? await resolveRuntimePackageVersion(packageName, options)
98
- return await createRuntimePackageStatus(target, packageName, targetVersion, requestedVersion)
118
+ return await createRuntimePackageStatus(target, packageName, targetVersion, requestedVersion, cacheVersion)
99
119
  }
100
120
 
101
121
  export const installRuntimePackage = async (
@@ -105,19 +125,31 @@ export const installRuntimePackage = async (
105
125
  const target = resolveRuntimePackageTarget(targetValue)
106
126
  const packageName = RUNTIME_PACKAGE_NAMES[target]
107
127
  const requestedVersion = normalizeRequestedVersion(options.version)
128
+ const cacheVersion = normalizePackageCacheVersion(options.cacheVersion) ?? resolveRuntimePackageCacheVersion()
108
129
  const targetVersion = requestedVersion ?? await resolveRuntimePackageVersion(packageName, options)
109
- await installPublishedPackage(packageName, targetVersion)
110
- return await createRuntimePackageStatus(target, packageName, targetVersion, requestedVersion)
130
+ await installPublishedPackage(packageName, targetVersion, cacheVersion == null ? {} : { cacheVersion })
131
+ return await createRuntimePackageStatus(target, packageName, targetVersion, requestedVersion, cacheVersion)
111
132
  }
112
133
 
113
134
  export const formatRuntimePackageStatus = (status: RuntimePackageStatus) => {
114
135
  const current = status.installedVersion ?? 'not installed'
115
136
  if (status.requestedVersion != null) {
137
+ if (status.cacheVersion != null) {
138
+ return status.latestInstalled
139
+ ? `${status.packageName}@${status.requestedVersion} cached as ${status.cacheVersion}`
140
+ : `${status.packageName}@${status.requestedVersion} not cached as ${status.cacheVersion} (${current})`
141
+ }
116
142
  return status.latestInstalled
117
143
  ? `${status.packageName}@${status.requestedVersion} cached`
118
144
  : `${status.packageName}@${status.requestedVersion} not cached (${current})`
119
145
  }
120
146
 
147
+ if (status.cacheVersion != null) {
148
+ return status.latestInstalled
149
+ ? `${status.packageName}@${status.latestVersion} cached as ${status.cacheVersion}`
150
+ : `${status.packageName}@${status.latestVersion} not cached as ${status.cacheVersion} (${current})`
151
+ }
152
+
121
153
  const suffix = status.updateAvailable
122
154
  ? `update available: ${current} -> ${status.latestVersion}`
123
155
  : `up to date: ${status.latestVersion}`