@liquiditytech/rapidx-cli 1.0.32 → 1.0.33

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.
@@ -13,6 +13,9 @@ export async function runUpdateCommand(action, input) {
13
13
  if (typeof input.maxCacheAgeSeconds === "number") {
14
14
  updateInput.maxCacheAgeSeconds = input.maxCacheAgeSeconds;
15
15
  }
16
+ if (typeof input.installedSkillsVersion === "string") {
17
+ updateInput.installedSkillsVersion = input.installedSkillsVersion;
18
+ }
16
19
  const result = await checkForUpdate(updateInput);
17
20
  return ok(result, "rapidx update check --json", envelopeStatusForUpdate(result.status));
18
21
  }
@@ -1,7 +1,7 @@
1
1
  import { SCHEMA_VERSION } from "./types.js";
2
2
  import { RAPIDX_VERSION } from "../version.js";
3
3
  export const RAPIDX_SKILLS_DISTRIBUTION = "github";
4
- export const RAPIDX_SKILLS_VERSION = "1.0.6";
4
+ export const RAPIDX_SKILLS_VERSION = "1.0.8";
5
5
  export const RAPIDX_SKILLS_SCHEMA_VERSION = "1.0.0";
6
6
  export function buildCompatibilityReport(input = {}) {
7
7
  const checks = [
@@ -305,7 +305,7 @@ export function inputSchemaForName(name) {
305
305
  case "InvocationCheckInput":
306
306
  return objectSchema({ commandLine: stringSchema, preflightError: stringSchema });
307
307
  case "UpdateCheckInput":
308
- return objectSchema({ force: booleanSchema, manifestUrl: stringSchema, maxCacheAgeSeconds: numberSchema });
308
+ return objectSchema({ force: booleanSchema, manifestUrl: stringSchema, maxCacheAgeSeconds: numberSchema, installedSkillsVersion: stringSchema });
309
309
  case "SchemaQuery":
310
310
  return objectSchema({ consumer: stringSchema, consumerVersion: stringSchema, includeExamples: booleanSchema });
311
311
  case "SelfCheckInput":
@@ -13,11 +13,14 @@ export async function checkForUpdate(input = {}, env = process.env, cwd = proces
13
13
  const cacheFile = resolveUpdateCacheFile(env, cwd);
14
14
  const cached = loadCachedUpdateState(cacheFile);
15
15
  if (!input.force && cached && !isCacheExpired(cached, cacheTtlSeconds)) {
16
- return {
17
- ...cached.result,
16
+ const manifest = cached.manifest ?? manifestFromCachedResult(cached.result);
17
+ return buildUpdateCheckResult(manifest, {
18
+ checkedAt: cached.checkedAt,
19
+ cacheTtlSeconds,
20
+ manifestUrl,
18
21
  manifestSource: "cache",
19
- cacheTtlSeconds
20
- };
22
+ installedSkillsVersion: input.installedSkillsVersion
23
+ });
21
24
  }
22
25
  try {
23
26
  const manifest = await fetchReleaseManifest(manifestUrl);
@@ -25,29 +28,35 @@ export async function checkForUpdate(input = {}, env = process.env, cwd = proces
25
28
  checkedAt: new Date().toISOString(),
26
29
  cacheTtlSeconds,
27
30
  manifestUrl,
28
- manifestSource: "remote"
31
+ manifestSource: "remote",
32
+ installedSkillsVersion: input.installedSkillsVersion
29
33
  });
30
34
  saveCachedUpdateState(cacheFile, {
31
35
  checkedAt: result.checkedAt,
32
36
  cacheTtlSeconds,
37
+ manifest,
33
38
  result
34
39
  });
35
40
  return result;
36
41
  }
37
42
  catch (error) {
38
43
  if (cached) {
39
- return {
40
- ...cached.result,
41
- manifestSource: "cache",
44
+ const manifest = cached.manifest ?? manifestFromCachedResult(cached.result);
45
+ return buildUpdateCheckResult(manifest, {
46
+ checkedAt: cached.checkedAt,
42
47
  cacheTtlSeconds,
48
+ manifestUrl,
49
+ manifestSource: "cache",
50
+ installedSkillsVersion: input.installedSkillsVersion,
43
51
  error: error instanceof Error ? error.message : String(error)
44
- };
52
+ });
45
53
  }
46
54
  return buildUnknownUpdateCheckResult({
47
55
  checkedAt: new Date().toISOString(),
48
56
  cacheTtlSeconds,
49
57
  manifestUrl,
50
58
  manifestSource: "fallback",
59
+ installedSkillsVersion: input.installedSkillsVersion,
51
60
  error: error instanceof Error ? error.message : String(error)
52
61
  });
53
62
  }
@@ -62,6 +71,11 @@ export function buildUpdateCheckResult(manifest, metadata) {
62
71
  minimumWriteVersion
63
72
  });
64
73
  const writeAllowed = status !== "WRITE_BLOCKED";
74
+ const installedSkillsVersion = normalizeInstalledSkillsVersion(metadata.installedSkillsVersion);
75
+ const skillsInstallStatus = computeSkillsInstallStatus(installedSkillsVersion, manifest.skillsVersion);
76
+ const skillsUpdateRecommended = manifest.skillsUpdateRecommended
77
+ || skillsInstallStatus === "UPDATE_AVAILABLE"
78
+ || (skillsInstallStatus === "NOT_VERIFIED" && compareVersions(RAPIDX_SKILLS_VERSION, manifest.skillsVersion) < 0);
65
79
  return {
66
80
  currentVersion: RAPIDX_VERSION,
67
81
  latestVersion: manifest.latestCliVersion,
@@ -71,6 +85,10 @@ export function buildUpdateCheckResult(manifest, metadata) {
71
85
  currentMcpSchemaVersion: SCHEMA_VERSION,
72
86
  skillsVersion: manifest.skillsVersion,
73
87
  currentSkillsVersion: RAPIDX_SKILLS_VERSION,
88
+ latestSkillsVersion: manifest.skillsVersion,
89
+ bundledExpectedSkillsVersion: RAPIDX_SKILLS_VERSION,
90
+ installedSkillsVersion,
91
+ skillsInstallStatus,
74
92
  skillsSchemaVersion: manifest.skillsSchemaVersion,
75
93
  currentSkillsSchemaVersion: RAPIDX_SKILLS_SCHEMA_VERSION,
76
94
  updateAvailable: compareVersions(RAPIDX_VERSION, manifest.latestCliVersion) < 0,
@@ -82,9 +100,12 @@ export function buildUpdateCheckResult(manifest, metadata) {
82
100
  cacheTtlSeconds: metadata.cacheTtlSeconds,
83
101
  manifestUrl: metadata.manifestUrl,
84
102
  manifestSource: metadata.manifestSource,
103
+ updateFreshness: freshnessForSource(metadata.manifestSource),
104
+ refreshCommand: "rapidx update check --input '{\"force\":true}' --json",
85
105
  releaseNotesUrl: manifest.releaseNotesUrl,
86
- skillsUpdateRecommended: manifest.skillsUpdateRecommended || compareVersions(RAPIDX_SKILLS_VERSION, manifest.skillsVersion) < 0,
106
+ skillsUpdateRecommended,
87
107
  upgrade: manifest.upgrade,
108
+ ...(metadata.manifestSource === "cache" ? { cacheWarning: "Result came from local cache. Use force=true to refresh the remote release manifest." } : {}),
88
109
  ...(metadata.error ? { error: metadata.error } : {})
89
110
  };
90
111
  }
@@ -160,6 +181,8 @@ function fallbackManifest() {
160
181
  }
161
182
  function buildUnknownUpdateCheckResult(metadata) {
162
183
  const manifest = fallbackManifest();
184
+ const installedSkillsVersion = normalizeInstalledSkillsVersion(metadata.installedSkillsVersion);
185
+ const skillsInstallStatus = computeSkillsInstallStatus(installedSkillsVersion, manifest.skillsVersion);
163
186
  return {
164
187
  currentVersion: RAPIDX_VERSION,
165
188
  latestVersion: RAPIDX_VERSION,
@@ -169,6 +192,10 @@ function buildUnknownUpdateCheckResult(metadata) {
169
192
  currentMcpSchemaVersion: SCHEMA_VERSION,
170
193
  skillsVersion: manifest.skillsVersion,
171
194
  currentSkillsVersion: RAPIDX_SKILLS_VERSION,
195
+ latestSkillsVersion: manifest.skillsVersion,
196
+ bundledExpectedSkillsVersion: RAPIDX_SKILLS_VERSION,
197
+ installedSkillsVersion,
198
+ skillsInstallStatus,
172
199
  skillsSchemaVersion: manifest.skillsSchemaVersion,
173
200
  currentSkillsSchemaVersion: RAPIDX_SKILLS_SCHEMA_VERSION,
174
201
  updateAvailable: false,
@@ -180,6 +207,8 @@ function buildUnknownUpdateCheckResult(metadata) {
180
207
  cacheTtlSeconds: metadata.cacheTtlSeconds,
181
208
  manifestUrl: metadata.manifestUrl,
182
209
  manifestSource: metadata.manifestSource,
210
+ updateFreshness: freshnessForSource(metadata.manifestSource),
211
+ refreshCommand: "rapidx update check --input '{\"force\":true}' --json",
183
212
  releaseNotesUrl: "",
184
213
  skillsUpdateRecommended: false,
185
214
  upgrade: {},
@@ -198,6 +227,41 @@ function computeUpdateStatus(input) {
198
227
  }
199
228
  return "CURRENT";
200
229
  }
230
+ function computeSkillsInstallStatus(installedSkillsVersion, latestSkillsVersion) {
231
+ if (installedSkillsVersion === "NOT_VERIFIED") {
232
+ return "NOT_VERIFIED";
233
+ }
234
+ return compareVersions(installedSkillsVersion, latestSkillsVersion) < 0 ? "UPDATE_AVAILABLE" : "CURRENT";
235
+ }
236
+ function normalizeInstalledSkillsVersion(value) {
237
+ return typeof value === "string" && isSemver(value) ? value : "NOT_VERIFIED";
238
+ }
239
+ function freshnessForSource(source) {
240
+ if (source === "remote") {
241
+ return "REMOTE";
242
+ }
243
+ if (source === "cache") {
244
+ return "CACHE";
245
+ }
246
+ return "FALLBACK";
247
+ }
248
+ function manifestFromCachedResult(result) {
249
+ return {
250
+ product: "rapidx",
251
+ channel: "stable",
252
+ latestCliVersion: result.latestVersion,
253
+ minimumSupportedVersion: result.minimumSupportedVersion,
254
+ minimumWriteVersion: result.minimumWriteVersion,
255
+ latestMcpSchemaVersion: result.latestMcpSchemaVersion,
256
+ skillsVersion: result.skillsVersion,
257
+ skillsSchemaVersion: result.skillsSchemaVersion,
258
+ skillsUpdateRecommended: result.skillsUpdateRecommended,
259
+ severity: result.severity,
260
+ breaking: result.breaking,
261
+ releaseNotesUrl: result.releaseNotesUrl,
262
+ upgrade: result.upgrade
263
+ };
264
+ }
201
265
  function compareVersions(left, right) {
202
266
  const a = parseVersion(left);
203
267
  const b = parseVersion(right);
@@ -220,6 +284,9 @@ function parseVersion(version) {
220
284
  }
221
285
  return [Number(match[1]), Number(match[2]), Number(match[3])];
222
286
  }
287
+ function isSemver(version) {
288
+ return /^(\d+)\.(\d+)\.(\d+)(?:[-+].*)?$/.test(version);
289
+ }
223
290
  function assertSemver(version, field) {
224
291
  try {
225
292
  parseVersion(version);
@@ -1 +1 @@
1
- export const RAPIDX_VERSION = "1.0.32";
1
+ export const RAPIDX_VERSION = "1.0.33";
@@ -40,6 +40,9 @@ export async function runMcpTool(toolName, input = {}) {
40
40
  if (typeof input.maxCacheAgeSeconds === "number") {
41
41
  updateInput.maxCacheAgeSeconds = input.maxCacheAgeSeconds;
42
42
  }
43
+ if (typeof input.installedSkillsVersion === "string") {
44
+ updateInput.installedSkillsVersion = input.installedSkillsVersion;
45
+ }
43
46
  const update = await checkForUpdate(updateInput);
44
47
  const status = envelopeStatusForUpdate(update.status);
45
48
  const auditId = writeMcpAudit("update-check", status, { toolName, updateStatus: update.status });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liquiditytech/rapidx-cli",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "RapidX CLI, MCP server mode, registry, and release assets.",
5
5
  "type": "module",
6
6
  "private": false,
@@ -44,6 +44,31 @@ rapidx portfolio set-position-mode --input @/absolute/path/set-position-mode.jso
44
44
 
45
45
  `rapidx update check --json` reads the RapidX release manifest and caches the result locally. Use it during setup, review, or session startup. Trade submit paths should not perform a fresh network update check.
46
46
 
47
+ When checking an existing installation, read the installed RapidX skill `version` from the loaded `SKILL.md` frontmatter and pass it to update check:
48
+
49
+ ```bash
50
+ rapidx update check --input '{"installedSkillsVersion":"1.0.8"}' --json
51
+ ```
52
+
53
+ For upgrade reviews, force a remote manifest refresh:
54
+
55
+ ```bash
56
+ rapidx update check --input '{"installedSkillsVersion":"1.0.8","force":true}' --json
57
+ ```
58
+
59
+ Update output fields:
60
+
61
+ - `latestVersion`: latest CLI version from the release manifest.
62
+ - `currentVersion`: running CLI version.
63
+ - `latestSkillsVersion` / `skillsVersion`: latest RapidX skills version from the release manifest.
64
+ - `bundledExpectedSkillsVersion` / `currentSkillsVersion`: skills version expected by this CLI build, not proof of locally installed skills.
65
+ - `installedSkillsVersion`: local skill version supplied by the caller, or `NOT_VERIFIED`.
66
+ - `skillsInstallStatus`: `CURRENT`, `UPDATE_AVAILABLE`, or `NOT_VERIFIED`.
67
+ - `manifestSource`: `remote`, `cache`, or `fallback`.
68
+ - `updateFreshness`: `REMOTE`, `CACHE`, or `FALLBACK`.
69
+ - `cacheWarning`: present when the result came from local cache.
70
+ - `refreshCommand`: command for forcing a remote manifest refresh.
71
+
47
72
  `rapidx schema --json` returns `capabilities` plus `inputSchemas`. Agents should read the concrete input schema before constructing write inputs.
48
73
 
49
74
  `rapidx portfolio assets` reads `/api/v1/trading/portfolio/assets`. It is the canonical CLI command for portfolio asset balances.
@@ -137,4 +137,4 @@ The config skill guides the agent to install `@liquiditytech/rapidx-cli`, config
137
137
 
138
138
  The trading skill guides read flow, preview-first write flow, state confirmation, and small real-trade verification.
139
139
 
140
- For existing installations, run `rapidx update check --json` or call `rapidx/update/check` through MCP before an integration review. Reinstall the GitHub-distributed skills when the update result sets `skillsUpdateRecommended=true`.
140
+ For existing installations, read the installed skill `version` from each loaded `SKILL.md` frontmatter, then run `rapidx update check --input '{"installedSkillsVersion":"<local-skill-version>","force":true}' --json` or call `rapidx/update/check` through MCP with the same input before an integration review. Reinstall the GitHub-distributed skills when `skillsInstallStatus=UPDATE_AVAILABLE`, `installedSkillsVersion=NOT_VERIFIED`, or `skillsUpdateRecommended=true`.
@@ -1,11 +1,11 @@
1
1
  {
2
- "version": "1.0.32",
2
+ "version": "1.0.33",
3
3
  "artifacts": [
4
4
  {
5
5
  "name": "rapidx-mcp-registry",
6
6
  "path": "packages/distribution/registry/rapidx.mcp.json",
7
7
  "channel": "offline",
8
- "checksum": "sha256:b75ee5a765902c45f13614cdaf906633590456480fe91174ecee2422048aaf93",
8
+ "checksum": "sha256:a78b9c1ad3aa0df1f1e968e68c5ae30dbfcf39d4902e31973cbbfd0e306827ac",
9
9
  "status": "ready"
10
10
  },
11
11
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rapidx",
3
3
  "packageName": "@liquiditytech/rapidx-cli",
4
- "version": "1.0.32",
4
+ "version": "1.0.33",
5
5
  "command": "rapidx",
6
6
  "args": ["mcp", "serve"],
7
7
  "launchCommand": "rapidx",