@solarains/va-cli 0.1.1

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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +132 -0
  3. package/dist/cli/command-types.js +2 -0
  4. package/dist/cli/help-copy.js +97 -0
  5. package/dist/cli/help.js +29 -0
  6. package/dist/cli/root-command.js +24 -0
  7. package/dist/cli/run-cli.js +107 -0
  8. package/dist/commands/assets/assets-command.js +10 -0
  9. package/dist/commands/assets/list-command.js +52 -0
  10. package/dist/commands/auth/auth-command.js +11 -0
  11. package/dist/commands/auth/login-command.js +127 -0
  12. package/dist/commands/auth/logout-command.js +57 -0
  13. package/dist/commands/doctor/doctor-command.js +33 -0
  14. package/dist/commands/init/init-command.js +19 -0
  15. package/dist/commands/intelligence/intelligence-command.js +10 -0
  16. package/dist/commands/intelligence/query-command.js +109 -0
  17. package/dist/commands/reports/get-command.js +69 -0
  18. package/dist/commands/reports/list-command.js +33 -0
  19. package/dist/commands/reports/reports-command.js +11 -0
  20. package/dist/commands/usage/usage-command.js +27 -0
  21. package/dist/config/locale.js +30 -0
  22. package/dist/config/runtime-config.js +64 -0
  23. package/dist/features/assets/assets-api-client.js +18 -0
  24. package/dist/features/assets/assets-output.js +28 -0
  25. package/dist/features/auth/auth-api-client.js +60 -0
  26. package/dist/features/auth/authenticated-api-client.js +142 -0
  27. package/dist/features/auth/browser-login.js +191 -0
  28. package/dist/features/auth/installation-state.js +65 -0
  29. package/dist/features/auth/loopback-callback-page.js +231 -0
  30. package/dist/features/daily-reports/daily-reports-api-client.js +22 -0
  31. package/dist/features/daily-reports/daily-reports-output.js +54 -0
  32. package/dist/features/init/detect-targets.js +57 -0
  33. package/dist/features/init/init-copy.js +348 -0
  34. package/dist/features/init/init-flow.js +661 -0
  35. package/dist/features/init/installer.js +122 -0
  36. package/dist/features/init/manifest.js +29 -0
  37. package/dist/features/init/presentation.js +147 -0
  38. package/dist/features/init/prompt.js +135 -0
  39. package/dist/features/init/target-registry.js +45 -0
  40. package/dist/features/init/templates.js +84 -0
  41. package/dist/features/init/types.js +2 -0
  42. package/dist/features/intelligence/intelligence-api-client.js +18 -0
  43. package/dist/features/intelligence/intelligence-output.js +36 -0
  44. package/dist/features/intelligence/intelligence-query-state.js +20 -0
  45. package/dist/features/usage/usage-api-client.js +7 -0
  46. package/dist/features/usage/usage-output.js +52 -0
  47. package/dist/main.js +7 -0
  48. package/dist/shared/argv.js +65 -0
  49. package/dist/shared/logger.js +32 -0
  50. package/dist/shared/output.js +22 -0
  51. package/dist/state/paths.js +32 -0
  52. package/dist/state/stores/file-json-store.js +29 -0
  53. package/dist/state/stores/installation-store.js +20 -0
  54. package/dist/state/stores/token-store.js +20 -0
  55. package/package.json +19 -0
  56. package/skills/visionalpha-operator/SKILL.md +38 -0
  57. package/skills/visionalpha-operator/agents/openai.yaml +4 -0
  58. package/skills/visionalpha-operator/references/asset-intelligence.md +35 -0
  59. package/skills/visionalpha-operator/references/assets.md +29 -0
  60. package/skills/visionalpha-operator/references/auth-recovery.md +26 -0
  61. package/skills/visionalpha-operator/references/daily-reports.md +30 -0
  62. package/skills/visionalpha-operator/references/usage-summary.md +24 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prepareInstallations = prepareInstallations;
4
+ exports.applyInstallations = applyInstallations;
5
+ const promises_1 = require("node:fs/promises");
6
+ const node_path_1 = require("node:path");
7
+ const manifest_1 = require("./manifest");
8
+ const target_registry_1 = require("./target-registry");
9
+ const templates_1 = require("./templates");
10
+ async function readText(path) {
11
+ try {
12
+ return await (0, promises_1.readFile)(path, 'utf8');
13
+ }
14
+ catch (error) {
15
+ if (error.code === 'ENOENT') {
16
+ return null;
17
+ }
18
+ throw error;
19
+ }
20
+ }
21
+ function isManagedFile(relativePath, contents, manifest) {
22
+ if (contents.includes(templates_1.MANAGED_MARKER)) {
23
+ return true;
24
+ }
25
+ return manifest?.files.includes(relativePath) ?? false;
26
+ }
27
+ function createAnalysis() {
28
+ return {
29
+ toCreate: [],
30
+ toRefresh: [],
31
+ toRemove: [],
32
+ conflicts: [],
33
+ };
34
+ }
35
+ async function prepareInstallations(input) {
36
+ const prepared = [];
37
+ for (const agentId of input.agentIds) {
38
+ const target = (0, target_registry_1.getAgentTarget)(agentId);
39
+ if (!target.supportedScopes.includes(input.scope)) {
40
+ throw new Error(`Target "${target.displayName}" does not support "${input.scope}" scope.`);
41
+ }
42
+ const rootDir = target.resolveRoot({
43
+ cwd: input.cwd,
44
+ homeDir: input.homeDir,
45
+ scope: input.scope,
46
+ });
47
+ const manifestPath = (0, node_path_1.join)(rootDir, manifest_1.MANIFEST_FILE_NAME);
48
+ const manifest = await (0, manifest_1.readManagedManifest)(manifestPath);
49
+ const files = await (0, templates_1.createAgentPackFiles)(target, input.scope);
50
+ const analysis = createAnalysis();
51
+ const nextRelativePaths = new Set(files.map((file) => file.relativePath));
52
+ for (const file of files) {
53
+ const absolutePath = (0, node_path_1.join)(rootDir, file.relativePath);
54
+ const existing = await readText(absolutePath);
55
+ if (existing === null) {
56
+ analysis.toCreate.push(file.relativePath);
57
+ continue;
58
+ }
59
+ if (isManagedFile(file.relativePath, existing, manifest)) {
60
+ analysis.toRefresh.push(file.relativePath);
61
+ continue;
62
+ }
63
+ analysis.conflicts.push(file.relativePath);
64
+ }
65
+ for (const relativePath of manifest?.files ?? []) {
66
+ if (!nextRelativePaths.has(relativePath)) {
67
+ analysis.toRemove.push(relativePath);
68
+ }
69
+ }
70
+ const existingManifest = await readText(manifestPath);
71
+ if (existingManifest !== null && manifest === null) {
72
+ analysis.conflicts.push(manifest_1.MANIFEST_FILE_NAME);
73
+ }
74
+ prepared.push({
75
+ target,
76
+ scope: input.scope,
77
+ rootDir,
78
+ manifestPath,
79
+ files,
80
+ analysis,
81
+ });
82
+ }
83
+ return prepared;
84
+ }
85
+ async function applyInstallations(prepared, options) {
86
+ const applied = [];
87
+ const timestamp = options.now ?? (() => new Date().toISOString());
88
+ for (const entry of prepared) {
89
+ if (entry.analysis.conflicts.length > 0 && !options.allowUnmanagedOverwrite) {
90
+ throw new Error(`Unmanaged files block ${entry.target.displayName} installation: ${entry.analysis.conflicts.join(', ')}. Re-run with --force or confirm overwrite interactively.`);
91
+ }
92
+ const overwritten = [...entry.analysis.conflicts];
93
+ for (const relativePath of entry.analysis.toRemove) {
94
+ const absolutePath = (0, node_path_1.join)(entry.rootDir, relativePath);
95
+ await (0, promises_1.rm)(absolutePath, { force: true });
96
+ }
97
+ for (const file of entry.files) {
98
+ const absolutePath = (0, node_path_1.join)(entry.rootDir, file.relativePath);
99
+ await (0, promises_1.mkdir)((0, node_path_1.dirname)(absolutePath), { recursive: true });
100
+ await (0, promises_1.writeFile)(absolutePath, file.contents, 'utf8');
101
+ }
102
+ await (0, promises_1.mkdir)(entry.rootDir, { recursive: true });
103
+ await (0, manifest_1.writeManagedManifest)(entry.manifestPath, {
104
+ managedBy: 'vaone',
105
+ manifestVersion: 1,
106
+ packId: 'vaone-agent-pack',
107
+ targetId: entry.target.id,
108
+ scope: entry.scope,
109
+ updatedAt: timestamp(),
110
+ files: entry.files.map((file) => file.relativePath),
111
+ });
112
+ applied.push({
113
+ target: entry.target,
114
+ scope: entry.scope,
115
+ rootDir: entry.rootDir,
116
+ created: [...entry.analysis.toCreate],
117
+ refreshed: [...entry.analysis.toRefresh],
118
+ overwritten,
119
+ });
120
+ }
121
+ return applied;
122
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANIFEST_FILE_NAME = void 0;
4
+ exports.readManagedManifest = readManagedManifest;
5
+ exports.writeManagedManifest = writeManagedManifest;
6
+ const promises_1 = require("node:fs/promises");
7
+ exports.MANIFEST_FILE_NAME = '.vaone-managed.json';
8
+ async function readManagedManifest(manifestPath) {
9
+ try {
10
+ const raw = await (0, promises_1.readFile)(manifestPath, 'utf8');
11
+ const parsed = JSON.parse(raw);
12
+ if (parsed.managedBy !== 'vaone' ||
13
+ parsed.packId !== 'vaone-agent-pack' ||
14
+ parsed.manifestVersion !== 1 ||
15
+ !Array.isArray(parsed.files)) {
16
+ return null;
17
+ }
18
+ return parsed;
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT') {
22
+ return null;
23
+ }
24
+ throw error;
25
+ }
26
+ }
27
+ async function writeManagedManifest(manifestPath, manifest) {
28
+ await (0, promises_1.writeFile)(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`, 'utf8');
29
+ }
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.waitForTerminalEnter = waitForTerminalEnter;
7
+ exports.showVisionAlphaWelcome = showVisionAlphaWelcome;
8
+ exports.createInitPresenter = createInitPresenter;
9
+ const core_1 = require("@inquirer/core");
10
+ const chalk_1 = __importDefault(require("chalk"));
11
+ const PALETTE = {
12
+ blue: chalk_1.default.hex('#4DA3FF'),
13
+ cyan: chalk_1.default.hex('#7DD3FC'),
14
+ dimBlue: chalk_1.default.hex('#6D84B3'),
15
+ darkBlue: chalk_1.default.hex('#214C8E'),
16
+ white: chalk_1.default.hex('#EAF4FF'),
17
+ };
18
+ const ART_COLUMN_WIDTH = 28;
19
+ const WELCOME_ART = [
20
+ ' ╭──────────────╮',
21
+ ' ╭───┤ VA SIGNAL ├───╮',
22
+ ' │ ╰──────────────╯ │',
23
+ ' │ ▓▓██▓▓▒▒░░▒▒▓▓ │',
24
+ ' ╰────── market sync ───╯',
25
+ ];
26
+ function supportsColor() {
27
+ return Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
28
+ }
29
+ function buildFrameLines(textLines, artLines) {
30
+ const maxLines = Math.max(textLines.length, artLines.length);
31
+ const lines = [];
32
+ for (let index = 0; index < maxLines; index += 1) {
33
+ const art = (artLines[index] ?? '').padEnd(ART_COLUMN_WIDTH);
34
+ const text = textLines[index] ?? '';
35
+ lines.push(`${colorize(art, 'blue')}${text}`);
36
+ }
37
+ return lines;
38
+ }
39
+ function colorize(value, tone) {
40
+ return supportsColor() ? PALETTE[tone](value) : value;
41
+ }
42
+ function renderFrame(textLines, artLines) {
43
+ return buildFrameLines(textLines, artLines).join('\n');
44
+ }
45
+ function splitDisplayLines(message) {
46
+ return message.split('\n');
47
+ }
48
+ const enterScreenPrompt = (0, core_1.createPrompt)((config, done) => {
49
+ (0, core_1.useKeypress)((key) => {
50
+ if ((0, core_1.isEnterKey)(key)) {
51
+ done();
52
+ }
53
+ if (key.name === 'c' && key.ctrl) {
54
+ process.stdout.write('\n');
55
+ process.exit(0);
56
+ }
57
+ });
58
+ return config.content;
59
+ });
60
+ function getWelcomeText() {
61
+ return [
62
+ colorize('VisionAlpha CLI', 'white'),
63
+ colorize('Operator bootstrap', 'cyan'),
64
+ '',
65
+ colorize('Preparing a branded setup flow for your agent apps.', 'dimBlue'),
66
+ colorize('Press Enter to begin / 按 Enter 开始', supportsColor() ? 'cyan' : 'white'),
67
+ ];
68
+ }
69
+ function waitForTerminalEnter() {
70
+ return new Promise((resolve) => {
71
+ const { stdin } = process;
72
+ if (!stdin.isTTY) {
73
+ resolve();
74
+ return;
75
+ }
76
+ const wasRaw = stdin.isRaw;
77
+ stdin.setRawMode(true);
78
+ stdin.resume();
79
+ const onData = (data) => {
80
+ const value = data.toString();
81
+ if (value === '\r' || value === '\n' || value === '\u0003') {
82
+ stdin.removeListener('data', onData);
83
+ stdin.setRawMode(Boolean(wasRaw));
84
+ stdin.pause();
85
+ if (value === '\u0003') {
86
+ process.stdout.write('\n');
87
+ process.exit(0);
88
+ }
89
+ resolve();
90
+ }
91
+ };
92
+ stdin.on('data', onData);
93
+ });
94
+ }
95
+ async function showVisionAlphaWelcome() {
96
+ const textLines = getWelcomeText();
97
+ const content = `\n${renderFrame(textLines, WELCOME_ART)}\n\n`;
98
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
99
+ process.stdout.write(content);
100
+ await waitForTerminalEnter();
101
+ return;
102
+ }
103
+ await enterScreenPrompt({ content });
104
+ }
105
+ function createInitPresenter(logger) {
106
+ function bullet() {
107
+ return supportsColor() ? colorize('•', 'cyan') : '-';
108
+ }
109
+ function vertical() {
110
+ return colorize('│', 'darkBlue');
111
+ }
112
+ return {
113
+ section(title) {
114
+ logger.plain('');
115
+ logger.plain(colorize(title, 'white'));
116
+ logger.plain(colorize('─'.repeat(title.length), 'darkBlue'));
117
+ },
118
+ list(items) {
119
+ for (const item of items) {
120
+ logger.plain(`${bullet()} ${item}`);
121
+ }
122
+ },
123
+ step(status, statusLabel, label) {
124
+ const renderedStatus = colorize(statusLabel, status === 'failed' ? 'cyan' : 'white');
125
+ logger.plain(`${bullet()} [${renderedStatus}] ${label}`);
126
+ },
127
+ openBox(title) {
128
+ logger.plain(colorize(`╭─ ${title}`, 'darkBlue'));
129
+ return {
130
+ write(message) {
131
+ for (const line of splitDisplayLines(message)) {
132
+ logger.plain(`${vertical()} ${line}`);
133
+ }
134
+ },
135
+ close() {
136
+ logger.plain(colorize('╰─', 'darkBlue'));
137
+ },
138
+ };
139
+ },
140
+ emptyLine() {
141
+ logger.plain('');
142
+ },
143
+ emphasize(value) {
144
+ return colorize(value, 'cyan');
145
+ },
146
+ };
147
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatPromptKeysHelpTip = formatPromptKeysHelpTip;
4
+ exports.createTerminalPrompt = createTerminalPrompt;
5
+ const prompts_1 = require("@inquirer/prompts");
6
+ const ZH_PROMPT_ACTIONS = {
7
+ navigate: '导航',
8
+ select: '选择',
9
+ all: '全选',
10
+ invert: '反选',
11
+ submit: '提交',
12
+ };
13
+ const ZH_PROMPT_KEYS = {
14
+ space: '空格',
15
+ };
16
+ function formatPromptKeysHelpTip(locale, keys) {
17
+ if (locale !== 'zh-CN') {
18
+ return undefined;
19
+ }
20
+ return keys
21
+ .map(([key, action]) => {
22
+ const localizedKey = ZH_PROMPT_KEYS[key] ?? key;
23
+ return `${localizedKey} ${ZH_PROMPT_ACTIONS[action] ?? action}`;
24
+ })
25
+ .join(' • ');
26
+ }
27
+ function createTerminalPrompt() {
28
+ let activePrompt = null;
29
+ let activeController = null;
30
+ function createPromptController() {
31
+ const controller = new AbortController();
32
+ activeController = controller;
33
+ return controller;
34
+ }
35
+ function trackPrompt(prompt) {
36
+ activePrompt = prompt;
37
+ return prompt.finally(() => {
38
+ if (activePrompt === prompt) {
39
+ activePrompt = null;
40
+ }
41
+ });
42
+ }
43
+ return {
44
+ async select({ message, choices, defaultValue, locale }) {
45
+ const controller = createPromptController();
46
+ const prompt = (0, prompts_1.select)({
47
+ message,
48
+ choices: choices.map((choice) => ({
49
+ value: choice.value,
50
+ name: choice.label,
51
+ description: choice.description,
52
+ })),
53
+ default: defaultValue,
54
+ theme: locale === 'zh-CN'
55
+ ? {
56
+ style: {
57
+ keysHelpTip(keys) {
58
+ return formatPromptKeysHelpTip(locale, keys);
59
+ },
60
+ },
61
+ }
62
+ : undefined,
63
+ }, {
64
+ signal: controller.signal,
65
+ });
66
+ try {
67
+ return await trackPrompt(prompt);
68
+ }
69
+ finally {
70
+ if (activeController === controller) {
71
+ activeController = null;
72
+ }
73
+ }
74
+ },
75
+ async multiselect({ message, choices, locale }) {
76
+ const controller = createPromptController();
77
+ const prompt = (0, prompts_1.checkbox)({
78
+ message,
79
+ choices: choices.map((choice) => ({
80
+ value: choice.value,
81
+ name: choice.label,
82
+ description: choice.description,
83
+ checked: choice.checked,
84
+ })),
85
+ pageSize: 8,
86
+ theme: locale === 'zh-CN'
87
+ ? {
88
+ style: {
89
+ keysHelpTip(keys) {
90
+ return formatPromptKeysHelpTip(locale, keys);
91
+ },
92
+ },
93
+ }
94
+ : undefined,
95
+ }, {
96
+ signal: controller.signal,
97
+ });
98
+ try {
99
+ return await trackPrompt(prompt);
100
+ }
101
+ finally {
102
+ if (activeController === controller) {
103
+ activeController = null;
104
+ }
105
+ }
106
+ },
107
+ async confirm(message, defaultValue = false) {
108
+ const controller = createPromptController();
109
+ const prompt = (0, prompts_1.confirm)({
110
+ message,
111
+ default: defaultValue,
112
+ }, {
113
+ signal: controller.signal,
114
+ });
115
+ try {
116
+ return await trackPrompt(prompt);
117
+ }
118
+ finally {
119
+ if (activeController === controller) {
120
+ activeController = null;
121
+ }
122
+ }
123
+ },
124
+ async close() {
125
+ activeController?.abort();
126
+ activeController = null;
127
+ activePrompt?.cancel();
128
+ activePrompt = null;
129
+ if (process.stdin.isTTY && process.stdin.isRaw) {
130
+ process.stdin.setRawMode(false);
131
+ }
132
+ process.stdin.pause();
133
+ },
134
+ };
135
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAgentTargetRegistry = getAgentTargetRegistry;
4
+ exports.getAgentTarget = getAgentTarget;
5
+ const node_path_1 = require("node:path");
6
+ const TARGET_REGISTRY = [
7
+ {
8
+ id: 'codex',
9
+ displayName: 'Codex',
10
+ supportedScopes: ['project', 'user'],
11
+ resolveRoot({ cwd, homeDir, scope }) {
12
+ return scope === 'project'
13
+ ? (0, node_path_1.join)(cwd, '.codex', 'skills')
14
+ : (0, node_path_1.join)(homeDir, '.codex', 'skills');
15
+ },
16
+ },
17
+ {
18
+ id: 'claude',
19
+ displayName: 'Claude Code',
20
+ supportedScopes: ['project', 'user'],
21
+ resolveRoot({ cwd, homeDir, scope }) {
22
+ return scope === 'project'
23
+ ? (0, node_path_1.join)(cwd, '.claude', 'skills')
24
+ : (0, node_path_1.join)(homeDir, '.claude', 'skills');
25
+ },
26
+ },
27
+ {
28
+ id: 'openclaw',
29
+ displayName: 'OpenClaw',
30
+ supportedScopes: ['project', 'user'],
31
+ resolveRoot({ cwd, homeDir, scope }) {
32
+ return scope === 'project' ? (0, node_path_1.join)(cwd, 'skills') : (0, node_path_1.join)(homeDir, '.openclaw', 'skills');
33
+ },
34
+ },
35
+ ];
36
+ function getAgentTargetRegistry() {
37
+ return TARGET_REGISTRY;
38
+ }
39
+ function getAgentTarget(targetId) {
40
+ const target = TARGET_REGISTRY.find((entry) => entry.id === targetId);
41
+ if (!target) {
42
+ throw new Error(`Unsupported agent target "${targetId}".`);
43
+ }
44
+ return target;
45
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MANAGED_MARKER = void 0;
4
+ exports.resolveSkillSourceRoot = resolveSkillSourceRoot;
5
+ exports.createAgentPackFiles = createAgentPackFiles;
6
+ const promises_1 = require("node:fs/promises");
7
+ const node_path_1 = require("node:path");
8
+ exports.MANAGED_MARKER = 'VAONE-MANAGED FILE';
9
+ const SKILL_NAME = 'visionalpha-operator';
10
+ async function pathExists(path) {
11
+ try {
12
+ await (0, promises_1.access)((0, node_path_1.join)(path, 'SKILL.md'));
13
+ return true;
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ }
19
+ async function resolveSkillSourceRoot(input) {
20
+ const cwd = input?.cwd ?? process.cwd();
21
+ const execPath = input?.execPath ?? process.execPath;
22
+ const moduleDir = input?.moduleDir ?? __dirname;
23
+ const env = input?.env ?? process.env;
24
+ const candidates = [
25
+ 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),
32
+ ]
33
+ .filter((candidate) => Boolean(candidate))
34
+ .map((candidate) => (0, node_path_1.resolve)(candidate));
35
+ const deduped = [...new Set(candidates)];
36
+ for (const candidate of deduped) {
37
+ if (await pathExists(candidate)) {
38
+ return candidate;
39
+ }
40
+ }
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
+ }
43
+ function buildManagedHeader(target, relativePath) {
44
+ if (relativePath.endsWith('.yaml') || relativePath.endsWith('.yml')) {
45
+ return `# ${exports.MANAGED_MARKER}; target=${target.id}; path=${relativePath}`;
46
+ }
47
+ return `<!-- ${exports.MANAGED_MARKER}; target=${target.id}; path=${relativePath} -->`;
48
+ }
49
+ function injectManagedHeader(target, relativePath, contents) {
50
+ const header = buildManagedHeader(target, relativePath);
51
+ if (!relativePath.endsWith('SKILL.md') || !contents.startsWith('---\n')) {
52
+ return `${header}\n${contents}`;
53
+ }
54
+ const closingIndex = contents.indexOf('\n---\n', 4);
55
+ if (closingIndex === -1) {
56
+ return `${header}\n${contents}`;
57
+ }
58
+ const insertAt = closingIndex + '\n---\n'.length;
59
+ return `${contents.slice(0, insertAt)}${header}\n\n${contents.slice(insertAt)}`;
60
+ }
61
+ async function listRelativeFiles(rootDir, currentDir = rootDir) {
62
+ const entries = await (0, promises_1.readdir)(currentDir, { withFileTypes: true });
63
+ const files = await Promise.all(entries.map(async (entry) => {
64
+ const absolutePath = (0, node_path_1.join)(currentDir, entry.name);
65
+ if (entry.isDirectory()) {
66
+ return listRelativeFiles(rootDir, absolutePath);
67
+ }
68
+ return [absolutePath.slice(rootDir.length + 1)];
69
+ }));
70
+ return files.flat().sort();
71
+ }
72
+ async function createAgentPackFiles(target, scope) {
73
+ void scope;
74
+ const skillSourceRoot = await resolveSkillSourceRoot();
75
+ const relativeFiles = await listRelativeFiles(skillSourceRoot);
76
+ return Promise.all(relativeFiles.map(async (relativePath) => {
77
+ const contents = await (0, promises_1.readFile)((0, node_path_1.join)(skillSourceRoot, relativePath), 'utf8');
78
+ return {
79
+ relativePath: (0, node_path_1.join)(SKILL_NAME, relativePath),
80
+ description: `${target.displayName} VisionAlpha operator skill asset`,
81
+ contents: injectManagedHeader(target, (0, node_path_1.join)(SKILL_NAME, relativePath), contents),
82
+ };
83
+ }));
84
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryAssetIntelligence = queryAssetIntelligence;
4
+ const authenticated_api_client_1 = require("../auth/authenticated-api-client");
5
+ function createQueryString(query) {
6
+ const searchParams = new URLSearchParams();
7
+ for (const [key, value] of Object.entries(query)) {
8
+ if (value === undefined) {
9
+ continue;
10
+ }
11
+ searchParams.set(key, String(value));
12
+ }
13
+ const encoded = searchParams.toString();
14
+ return encoded ? `?${encoded}` : '';
15
+ }
16
+ async function queryAssetIntelligence(context, query) {
17
+ return (0, authenticated_api_client_1.requestAuthenticatedJson)(context, `/v1/asset-intelligence/query${createQueryString(query)}`);
18
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderIntelligencePage = renderIntelligencePage;
4
+ const output_1 = require("../../shared/output");
5
+ function formatAssetName(input) {
6
+ return input.assetNameZh || input.assetNameEn || input.assetId;
7
+ }
8
+ function renderIntelligencePage(logger, page) {
9
+ (0, output_1.printSection)(logger, 'Query summary');
10
+ (0, output_1.printKeyValue)(logger, 'Returned rows', String(page.returnedRows));
11
+ (0, output_1.printKeyValue)(logger, 'Effective limit', String(page.limit));
12
+ (0, output_1.printKeyValue)(logger, 'Continuation', page.nextCursor
13
+ ? 'Another page is available. Run `vaone intelligence query --next`.'
14
+ : 'No additional page is available.');
15
+ (0, output_1.printSection)(logger, 'Results');
16
+ if (!page.items.length) {
17
+ logger.info('No intelligence rows matched the current query.');
18
+ return;
19
+ }
20
+ page.items.forEach((item, index) => {
21
+ if (index > 0) {
22
+ logger.plain('');
23
+ }
24
+ (0, output_1.printKeyValue)(logger, 'Asset', `${formatAssetName(item)} (${item.assetId})`);
25
+ (0, output_1.printKeyValue)(logger, 'Publish date', item.publishDate);
26
+ (0, output_1.printKeyValue)(logger, 'Issuer', item.issuer ?? 'unknown');
27
+ (0, output_1.printKeyValue)(logger, 'Source', item.fileName ?? item.fileId);
28
+ if (item.relevanceScore !== undefined) {
29
+ (0, output_1.printKeyValue)(logger, 'Relevance', String(item.relevanceScore));
30
+ }
31
+ (0, output_1.printList)(logger, [item.narrative.text || 'No narrative text available.']);
32
+ if (item.narrative.keyThemes.length) {
33
+ (0, output_1.printKeyValue)(logger, 'Key themes', item.narrative.keyThemes.join(', '));
34
+ }
35
+ });
36
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IntelligenceQueryStateStore = void 0;
4
+ const file_json_store_1 = require("../../state/stores/file-json-store");
5
+ class IntelligenceQueryStateStore {
6
+ store;
7
+ constructor(filePath) {
8
+ this.store = new file_json_store_1.FileJsonStore(filePath);
9
+ }
10
+ async read() {
11
+ return this.store.read();
12
+ }
13
+ async save(state) {
14
+ await this.store.write(state);
15
+ }
16
+ async clear() {
17
+ await this.store.clear();
18
+ }
19
+ }
20
+ exports.IntelligenceQueryStateStore = IntelligenceQueryStateStore;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUsageSummary = getUsageSummary;
4
+ const authenticated_api_client_1 = require("../auth/authenticated-api-client");
5
+ async function getUsageSummary(context) {
6
+ return (0, authenticated_api_client_1.requestAuthenticatedJson)(context, '/v1/usage/summary');
7
+ }