@solarains/va-cli 0.1.3 → 0.1.5

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.
@@ -0,0 +1,185 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.inspectManagedPack = inspectManagedPack;
4
+ exports.collectManagedPackStatuses = collectManagedPackStatuses;
5
+ exports.syncManagedPacks = syncManagedPacks;
6
+ exports.removeManagedPacks = removeManagedPacks;
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = require("node:path");
10
+ const version_1 = require("../update/version");
11
+ const package_metadata_1 = require("../runtime/package-metadata");
12
+ const manifest_1 = require("./manifest");
13
+ const installer_1 = require("./installer");
14
+ const target_registry_1 = require("./target-registry");
15
+ const templates_1 = require("./templates");
16
+ async function readText(path) {
17
+ try {
18
+ return await (0, promises_1.readFile)(path, 'utf8');
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT') {
22
+ return null;
23
+ }
24
+ throw error;
25
+ }
26
+ }
27
+ async function pruneEmptyDirectories(startDir, stopDir) {
28
+ let current = startDir;
29
+ while (current.startsWith(stopDir) && current !== stopDir) {
30
+ try {
31
+ await (0, promises_1.rmdir)(current);
32
+ }
33
+ catch (error) {
34
+ const code = error.code;
35
+ if (code === 'ENOTEMPTY' || code === 'ENOENT') {
36
+ return;
37
+ }
38
+ throw error;
39
+ }
40
+ current = (0, node_path_1.dirname)(current);
41
+ }
42
+ }
43
+ function resolveRoot(input) {
44
+ const target = (0, target_registry_1.getAgentTarget)(input.targetId);
45
+ const cwd = input.cwd ?? process.cwd();
46
+ const homeDir = input.homeDir ?? (0, node_os_1.homedir)();
47
+ const rootDir = target.resolveRoot({
48
+ cwd,
49
+ homeDir,
50
+ scope: input.scope,
51
+ });
52
+ return {
53
+ target,
54
+ rootDir,
55
+ manifestPath: (0, node_path_1.join)(rootDir, manifest_1.MANIFEST_FILE_NAME),
56
+ };
57
+ }
58
+ async function inspectManagedPack(input) {
59
+ const runtimePackage = input.currentVersion === undefined
60
+ ? await (0, package_metadata_1.resolveRuntimePackageInfo)()
61
+ : null;
62
+ const currentVersion = input.currentVersion ?? runtimePackage?.version ?? '';
63
+ const { target, rootDir, manifestPath } = resolveRoot(input);
64
+ const manifest = await (0, manifest_1.readManagedManifest)(manifestPath);
65
+ const managedSkillPath = (0, node_path_1.join)(rootDir, templates_1.SKILL_NAME, 'SKILL.md');
66
+ const existingSkill = await readText(managedSkillPath);
67
+ const hasManagedSkillFile = existingSkill?.includes(templates_1.MANAGED_MARKER) ?? false;
68
+ if (!manifest) {
69
+ return {
70
+ target,
71
+ scope: input.scope,
72
+ rootDir,
73
+ manifestPath,
74
+ kind: hasManagedSkillFile ? 'untracked' : 'missing',
75
+ currentVersion,
76
+ };
77
+ }
78
+ const installedVersion = manifest.packVersion;
79
+ if (!installedVersion) {
80
+ return {
81
+ target,
82
+ scope: input.scope,
83
+ rootDir,
84
+ manifestPath,
85
+ kind: 'legacy',
86
+ currentVersion,
87
+ };
88
+ }
89
+ const comparison = (0, version_1.compareVersions)(installedVersion, currentVersion);
90
+ return {
91
+ target,
92
+ scope: input.scope,
93
+ rootDir,
94
+ manifestPath,
95
+ kind: comparison === 0 ? 'current' : comparison < 0 ? 'stale' : 'ahead',
96
+ currentVersion,
97
+ installedVersion,
98
+ };
99
+ }
100
+ async function collectManagedPackStatuses(input) {
101
+ const runtimePackage = input?.currentVersion === undefined
102
+ ? await (0, package_metadata_1.resolveRuntimePackageInfo)()
103
+ : null;
104
+ const currentVersion = input?.currentVersion ?? runtimePackage?.version ?? '';
105
+ const agentIds = input?.agentIds ?? (0, target_registry_1.getAgentTargetRegistry)().map((target) => target.id);
106
+ const scopes = input?.scopes ?? ['project', 'user'];
107
+ const statuses = [];
108
+ for (const scope of scopes) {
109
+ for (const agentId of agentIds) {
110
+ statuses.push(await inspectManagedPack({
111
+ targetId: agentId,
112
+ scope,
113
+ cwd: input?.cwd,
114
+ homeDir: input?.homeDir,
115
+ currentVersion,
116
+ }));
117
+ }
118
+ }
119
+ return statuses;
120
+ }
121
+ async function syncManagedPacks(input) {
122
+ const runtimePackage = input?.currentVersion === undefined
123
+ ? await (0, package_metadata_1.resolveRuntimePackageInfo)()
124
+ : null;
125
+ const currentVersion = input?.currentVersion ?? runtimePackage?.version ?? '';
126
+ const statuses = await collectManagedPackStatuses({
127
+ ...input,
128
+ currentVersion,
129
+ });
130
+ const refreshed = [];
131
+ for (const status of statuses) {
132
+ if (status.kind !== 'legacy' && status.kind !== 'stale') {
133
+ continue;
134
+ }
135
+ const prepared = await (0, installer_1.prepareInstallations)({
136
+ agentIds: [status.target.id],
137
+ scope: status.scope,
138
+ cwd: input?.cwd ?? process.cwd(),
139
+ homeDir: input?.homeDir ?? (0, node_os_1.homedir)(),
140
+ });
141
+ await (0, installer_1.applyInstallations)(prepared, {
142
+ allowUnmanagedOverwrite: false,
143
+ });
144
+ refreshed.push({
145
+ target: status.target,
146
+ scope: status.scope,
147
+ rootDir: status.rootDir,
148
+ previousStatus: status.kind,
149
+ });
150
+ }
151
+ return refreshed;
152
+ }
153
+ async function removeManagedPacks(input) {
154
+ const agentIds = input?.agentIds ?? (0, target_registry_1.getAgentTargetRegistry)().map((target) => target.id);
155
+ const scopes = input?.scopes ?? ['project', 'user'];
156
+ const removed = [];
157
+ for (const scope of scopes) {
158
+ for (const agentId of agentIds) {
159
+ const { target, rootDir, manifestPath } = resolveRoot({
160
+ targetId: agentId,
161
+ scope,
162
+ cwd: input?.cwd,
163
+ homeDir: input?.homeDir,
164
+ });
165
+ const manifest = await (0, manifest_1.readManagedManifest)(manifestPath);
166
+ if (!manifest) {
167
+ continue;
168
+ }
169
+ const removedFiles = [];
170
+ for (const relativePath of manifest.files) {
171
+ await (0, promises_1.rm)((0, node_path_1.join)(rootDir, relativePath), { force: true });
172
+ removedFiles.push(relativePath);
173
+ }
174
+ await (0, promises_1.rm)(manifestPath, { force: true });
175
+ await pruneEmptyDirectories((0, node_path_1.join)(rootDir, templates_1.SKILL_NAME), rootDir);
176
+ removed.push({
177
+ target,
178
+ scope,
179
+ rootDir,
180
+ removedFiles,
181
+ });
182
+ }
183
+ }
184
+ return removed;
185
+ }
@@ -29,7 +29,9 @@ const TARGET_REGISTRY = [
29
29
  displayName: 'OpenClaw',
30
30
  supportedScopes: ['project', 'user'],
31
31
  resolveRoot({ cwd, homeDir, scope }) {
32
- return scope === 'project' ? (0, node_path_1.join)(cwd, 'skills') : (0, node_path_1.join)(homeDir, '.openclaw', 'skills');
32
+ return scope === 'project'
33
+ ? (0, node_path_1.join)(cwd, 'skills')
34
+ : (0, node_path_1.join)(homeDir, '.openclaw', 'skills');
33
35
  },
34
36
  },
35
37
  ];
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MANAGED_MARKER = void 0;
3
+ exports.SKILL_NAME = exports.MANAGED_MARKER = void 0;
4
4
  exports.resolveSkillSourceRoot = resolveSkillSourceRoot;
5
5
  exports.createAgentPackFiles = createAgentPackFiles;
6
6
  const promises_1 = require("node:fs/promises");
7
7
  const node_path_1 = require("node:path");
8
+ const package_metadata_1 = require("../runtime/package-metadata");
8
9
  exports.MANAGED_MARKER = 'VAONE-MANAGED FILE';
9
- const SKILL_NAME = 'visionalpha-operator';
10
+ exports.SKILL_NAME = 'visionalpha-operator';
10
11
  async function pathExists(path) {
11
12
  try {
12
13
  await (0, promises_1.access)((0, node_path_1.join)(path, 'SKILL.md'));
@@ -23,12 +24,12 @@ async function resolveSkillSourceRoot(input) {
23
24
  const env = input?.env ?? process.env;
24
25
  const candidates = [
25
26
  env.VAONE_SKILL_SOURCE_DIR,
26
- (0, node_path_1.join)(moduleDir, '..', '..', '..', 'skills', SKILL_NAME),
27
- (0, node_path_1.join)(cwd, 'skills', SKILL_NAME),
28
- (0, node_path_1.join)(cwd, 'va-cli', 'skills', SKILL_NAME),
29
- (0, node_path_1.join)((0, node_path_1.dirname)(execPath), 'skills', SKILL_NAME),
30
- (0, node_path_1.join)((0, node_path_1.dirname)(execPath), '..', 'skills', SKILL_NAME),
31
- (0, node_path_1.join)((0, node_path_1.dirname)(execPath), '..', 'va-cli', 'skills', SKILL_NAME),
27
+ (0, node_path_1.join)(moduleDir, '..', '..', '..', 'skills', exports.SKILL_NAME),
28
+ (0, node_path_1.join)(cwd, 'skills', exports.SKILL_NAME),
29
+ (0, node_path_1.join)(cwd, 'va-cli', 'skills', exports.SKILL_NAME),
30
+ (0, node_path_1.join)((0, node_path_1.dirname)(execPath), 'skills', exports.SKILL_NAME),
31
+ (0, node_path_1.join)((0, node_path_1.dirname)(execPath), '..', 'skills', exports.SKILL_NAME),
32
+ (0, node_path_1.join)((0, node_path_1.dirname)(execPath), '..', 'va-cli', 'skills', exports.SKILL_NAME),
32
33
  ]
33
34
  .filter((candidate) => Boolean(candidate))
34
35
  .map((candidate) => (0, node_path_1.resolve)(candidate));
@@ -38,7 +39,7 @@ async function resolveSkillSourceRoot(input) {
38
39
  return candidate;
39
40
  }
40
41
  }
41
- throw new Error(`Unable to locate the managed skill source for "${SKILL_NAME}". Checked: ${deduped.join(', ')}. Set VAONE_SKILL_SOURCE_DIR to override the lookup path.`);
42
+ throw new Error(`Unable to locate the managed skill source for "${exports.SKILL_NAME}". Checked: ${deduped.join(', ')}. Set VAONE_SKILL_SOURCE_DIR to override the lookup path.`);
42
43
  }
43
44
  function buildManagedHeader(target, relativePath) {
44
45
  if (relativePath.endsWith('.yaml') || relativePath.endsWith('.yml')) {
@@ -58,6 +59,27 @@ function injectManagedHeader(target, relativePath, contents) {
58
59
  const insertAt = closingIndex + '\n---\n'.length;
59
60
  return `${contents.slice(0, insertAt)}${header}\n\n${contents.slice(insertAt)}`;
60
61
  }
62
+ function upsertFrontMatterValue(contents, key, value) {
63
+ if (!contents.startsWith('---\n')) {
64
+ return contents;
65
+ }
66
+ const closingIndex = contents.indexOf('\n---\n', 4);
67
+ if (closingIndex === -1) {
68
+ return contents;
69
+ }
70
+ const frontMatter = contents.slice(4, closingIndex);
71
+ const body = contents.slice(closingIndex);
72
+ const lines = frontMatter.split('\n');
73
+ const nextLine = `${key}: "${value}"`;
74
+ const existingIndex = lines.findIndex((line) => line.startsWith(`${key}:`));
75
+ if (existingIndex >= 0) {
76
+ lines[existingIndex] = nextLine;
77
+ }
78
+ else {
79
+ lines.push(nextLine);
80
+ }
81
+ return `---\n${lines.join('\n')}${body}`;
82
+ }
61
83
  async function listRelativeFiles(rootDir, currentDir = rootDir) {
62
84
  const entries = await (0, promises_1.readdir)(currentDir, { withFileTypes: true });
63
85
  const files = await Promise.all(entries.map(async (entry) => {
@@ -71,14 +93,18 @@ async function listRelativeFiles(rootDir, currentDir = rootDir) {
71
93
  }
72
94
  async function createAgentPackFiles(target, scope) {
73
95
  void scope;
96
+ const runtimePackage = await (0, package_metadata_1.resolveRuntimePackageInfo)();
74
97
  const skillSourceRoot = await resolveSkillSourceRoot();
75
98
  const relativeFiles = await listRelativeFiles(skillSourceRoot);
76
99
  return Promise.all(relativeFiles.map(async (relativePath) => {
77
- const contents = await (0, promises_1.readFile)((0, node_path_1.join)(skillSourceRoot, relativePath), 'utf8');
100
+ const rawContents = await (0, promises_1.readFile)((0, node_path_1.join)(skillSourceRoot, relativePath), 'utf8');
101
+ const contents = relativePath.endsWith('SKILL.md')
102
+ ? upsertFrontMatterValue(rawContents, 'version', runtimePackage.version)
103
+ : rawContents;
78
104
  return {
79
- relativePath: (0, node_path_1.join)(SKILL_NAME, relativePath),
105
+ relativePath: (0, node_path_1.join)(exports.SKILL_NAME, relativePath),
80
106
  description: `${target.displayName} VisionAlpha operator skill asset`,
81
- contents: injectManagedHeader(target, (0, node_path_1.join)(SKILL_NAME, relativePath), contents),
107
+ contents: injectManagedHeader(target, (0, node_path_1.join)(exports.SKILL_NAME, relativePath), contents),
82
108
  };
83
109
  }));
84
110
  }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveRuntimePackageInfo = resolveRuntimePackageInfo;
4
+ const promises_1 = require("node:fs/promises");
5
+ const node_path_1 = require("node:path");
6
+ async function pathExists(path) {
7
+ try {
8
+ await (0, promises_1.access)(path);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ async function findNearestPackageJson(startDir) {
16
+ let current = (0, node_path_1.resolve)(startDir);
17
+ for (;;) {
18
+ const packageJsonPath = (0, node_path_1.resolve)(current, 'package.json');
19
+ if (await pathExists(packageJsonPath)) {
20
+ return packageJsonPath;
21
+ }
22
+ const parent = (0, node_path_1.dirname)(current);
23
+ if (parent === current) {
24
+ return null;
25
+ }
26
+ current = parent;
27
+ }
28
+ }
29
+ async function resolveRuntimePackageInfo(input) {
30
+ const entryPath = input?.entryPath ?? process.argv[1];
31
+ const moduleDir = input?.moduleDir ?? __dirname;
32
+ const candidateDirs = [
33
+ entryPath ? (0, node_path_1.dirname)((0, node_path_1.resolve)(entryPath)) : null,
34
+ (0, node_path_1.resolve)(moduleDir),
35
+ ].filter((value) => Boolean(value));
36
+ const seen = new Set();
37
+ for (const candidateDir of candidateDirs) {
38
+ const packageJsonPath = await findNearestPackageJson(candidateDir);
39
+ if (!packageJsonPath || seen.has(packageJsonPath)) {
40
+ continue;
41
+ }
42
+ seen.add(packageJsonPath);
43
+ const raw = await (0, promises_1.readFile)(packageJsonPath, 'utf8');
44
+ const parsed = JSON.parse(raw);
45
+ if (!parsed.name || !parsed.version) {
46
+ continue;
47
+ }
48
+ return {
49
+ rootDir: (0, node_path_1.dirname)(packageJsonPath),
50
+ packageJsonPath,
51
+ name: parsed.name,
52
+ version: parsed.version,
53
+ private: parsed.private === true,
54
+ isPackagedInstall: parsed.private !== true,
55
+ };
56
+ }
57
+ throw new Error('Unable to resolve runtime package metadata for `vaone`.');
58
+ }