lua-cli 3.12.1 → 3.13.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.
Files changed (235) hide show
  1. package/dist/api/logs.api.service.d.ts +6 -3
  2. package/dist/api/logs.api.service.d.ts.map +1 -1
  3. package/dist/api/logs.api.service.js +5 -4
  4. package/dist/api/logs.api.service.js.map +1 -1
  5. package/dist/cli/command-definitions.d.ts.map +1 -1
  6. package/dist/cli/command-definitions.js +24 -2
  7. package/dist/cli/command-definitions.js.map +1 -1
  8. package/dist/commands/channels.d.ts.map +1 -1
  9. package/dist/commands/channels.js +2 -11
  10. package/dist/commands/channels.js.map +1 -1
  11. package/dist/commands/chat-log-probe.d.ts +59 -0
  12. package/dist/commands/chat-log-probe.d.ts.map +1 -0
  13. package/dist/commands/chat-log-probe.js +91 -0
  14. package/dist/commands/chat-log-probe.js.map +1 -0
  15. package/dist/commands/chat.d.ts.map +1 -1
  16. package/dist/commands/chat.js +134 -28
  17. package/dist/commands/chat.js.map +1 -1
  18. package/dist/commands/compile.d.ts +7 -0
  19. package/dist/commands/compile.d.ts.map +1 -1
  20. package/dist/commands/compile.js +32 -2
  21. package/dist/commands/compile.js.map +1 -1
  22. package/dist/commands/completion.d.ts.map +1 -1
  23. package/dist/commands/completion.js +7 -8
  24. package/dist/commands/completion.js.map +1 -1
  25. package/dist/commands/deploy.d.ts.map +1 -1
  26. package/dist/commands/deploy.js +108 -23
  27. package/dist/commands/deploy.js.map +1 -1
  28. package/dist/commands/devices.d.ts.map +1 -1
  29. package/dist/commands/devices.js +3 -2
  30. package/dist/commands/devices.js.map +1 -1
  31. package/dist/commands/env.d.ts.map +1 -1
  32. package/dist/commands/env.js +43 -20
  33. package/dist/commands/env.js.map +1 -1
  34. package/dist/commands/features.d.ts.map +1 -1
  35. package/dist/commands/features.js +2 -12
  36. package/dist/commands/features.js.map +1 -1
  37. package/dist/commands/governance.d.ts.map +1 -1
  38. package/dist/commands/governance.js +4 -8
  39. package/dist/commands/governance.js.map +1 -1
  40. package/dist/commands/index.d.ts +1 -0
  41. package/dist/commands/index.d.ts.map +1 -1
  42. package/dist/commands/index.js +1 -0
  43. package/dist/commands/index.js.map +1 -1
  44. package/dist/commands/init.d.ts.map +1 -1
  45. package/dist/commands/init.js +12 -2
  46. package/dist/commands/init.js.map +1 -1
  47. package/dist/commands/integrations.d.ts.map +1 -1
  48. package/dist/commands/integrations.js +4 -2
  49. package/dist/commands/integrations.js.map +1 -1
  50. package/dist/commands/jobs.d.ts.map +1 -1
  51. package/dist/commands/jobs.js +61 -23
  52. package/dist/commands/jobs.js.map +1 -1
  53. package/dist/commands/log-tip.d.ts +79 -0
  54. package/dist/commands/log-tip.d.ts.map +1 -0
  55. package/dist/commands/log-tip.js +91 -0
  56. package/dist/commands/log-tip.js.map +1 -0
  57. package/dist/commands/logs.d.ts.map +1 -1
  58. package/dist/commands/logs.js +97 -136
  59. package/dist/commands/logs.js.map +1 -1
  60. package/dist/commands/marketplace.d.ts.map +1 -1
  61. package/dist/commands/marketplace.js +14 -25
  62. package/dist/commands/marketplace.js.map +1 -1
  63. package/dist/commands/mcp.d.ts.map +1 -1
  64. package/dist/commands/mcp.js +17 -19
  65. package/dist/commands/mcp.js.map +1 -1
  66. package/dist/commands/models.d.ts.map +1 -1
  67. package/dist/commands/models.js +2 -1
  68. package/dist/commands/models.js.map +1 -1
  69. package/dist/commands/persona.d.ts.map +1 -1
  70. package/dist/commands/persona.js +4 -30
  71. package/dist/commands/persona.js.map +1 -1
  72. package/dist/commands/postprocessors.d.ts.map +1 -1
  73. package/dist/commands/postprocessors.js +43 -17
  74. package/dist/commands/postprocessors.js.map +1 -1
  75. package/dist/commands/preprocessors.d.ts.map +1 -1
  76. package/dist/commands/preprocessors.js +43 -17
  77. package/dist/commands/preprocessors.js.map +1 -1
  78. package/dist/commands/production.d.ts.map +1 -1
  79. package/dist/commands/production.js +2 -12
  80. package/dist/commands/production.js.map +1 -1
  81. package/dist/commands/push-helpers.d.ts +42 -0
  82. package/dist/commands/push-helpers.d.ts.map +1 -0
  83. package/dist/commands/push-helpers.js +48 -0
  84. package/dist/commands/push-helpers.js.map +1 -0
  85. package/dist/commands/push.d.ts +2 -0
  86. package/dist/commands/push.d.ts.map +1 -1
  87. package/dist/commands/push.js +269 -54
  88. package/dist/commands/push.js.map +1 -1
  89. package/dist/commands/pushBackup.d.ts.map +1 -1
  90. package/dist/commands/pushBackup.js +7 -1
  91. package/dist/commands/pushBackup.js.map +1 -1
  92. package/dist/commands/resources.d.ts.map +1 -1
  93. package/dist/commands/resources.js +2 -12
  94. package/dist/commands/resources.js.map +1 -1
  95. package/dist/commands/skills.d.ts.map +1 -1
  96. package/dist/commands/skills.js +51 -36
  97. package/dist/commands/skills.js.map +1 -1
  98. package/dist/commands/status.d.ts +14 -0
  99. package/dist/commands/status.d.ts.map +1 -0
  100. package/dist/commands/status.js +734 -0
  101. package/dist/commands/status.js.map +1 -0
  102. package/dist/commands/sync.d.ts.map +1 -1
  103. package/dist/commands/sync.js +37 -2
  104. package/dist/commands/sync.js.map +1 -1
  105. package/dist/commands/telemetry.d.ts.map +1 -1
  106. package/dist/commands/telemetry.js +4 -0
  107. package/dist/commands/telemetry.js.map +1 -1
  108. package/dist/commands/test-output.helpers.d.ts +24 -0
  109. package/dist/commands/test-output.helpers.d.ts.map +1 -0
  110. package/dist/commands/test-output.helpers.js +62 -0
  111. package/dist/commands/test-output.helpers.js.map +1 -0
  112. package/dist/commands/test.d.ts.map +1 -1
  113. package/dist/commands/test.js +236 -76
  114. package/dist/commands/test.js.map +1 -1
  115. package/dist/commands/webhooks.d.ts.map +1 -1
  116. package/dist/commands/webhooks.js +34 -21
  117. package/dist/commands/webhooks.js.map +1 -1
  118. package/dist/compiler/agent-traverser.d.ts +50 -14
  119. package/dist/compiler/agent-traverser.d.ts.map +1 -1
  120. package/dist/compiler/agent-traverser.js +191 -86
  121. package/dist/compiler/agent-traverser.js.map +1 -1
  122. package/dist/compiler/compiler.d.ts +32 -0
  123. package/dist/compiler/compiler.d.ts.map +1 -1
  124. package/dist/compiler/compiler.js +143 -18
  125. package/dist/compiler/compiler.js.map +1 -1
  126. package/dist/compiler/index.d.ts +1 -1
  127. package/dist/compiler/index.d.ts.map +1 -1
  128. package/dist/compiler/index.js +1 -1
  129. package/dist/compiler/index.js.map +1 -1
  130. package/dist/compiler/plugins/base.d.ts +21 -0
  131. package/dist/compiler/plugins/base.d.ts.map +1 -1
  132. package/dist/compiler/plugins/base.js +10 -0
  133. package/dist/compiler/plugins/base.js.map +1 -1
  134. package/dist/compiler/plugins/skill.plugin.d.ts +35 -9
  135. package/dist/compiler/plugins/skill.plugin.d.ts.map +1 -1
  136. package/dist/compiler/plugins/skill.plugin.js +131 -84
  137. package/dist/compiler/plugins/skill.plugin.js.map +1 -1
  138. package/dist/compiler/types.d.ts +33 -0
  139. package/dist/compiler/types.d.ts.map +1 -1
  140. package/dist/compiler/types.js.map +1 -1
  141. package/dist/compiler/utils/ast-helpers.d.ts +1 -16
  142. package/dist/compiler/utils/ast-helpers.d.ts.map +1 -1
  143. package/dist/compiler/utils/ast-helpers.js +2 -31
  144. package/dist/compiler/utils/ast-helpers.js.map +1 -1
  145. package/dist/compiler/utils/common.d.ts +14 -0
  146. package/dist/compiler/utils/common.d.ts.map +1 -1
  147. package/dist/compiler/utils/common.js +38 -0
  148. package/dist/compiler/utils/common.js.map +1 -1
  149. package/dist/compiler/utils/path-resolver.d.ts +67 -10
  150. package/dist/compiler/utils/path-resolver.d.ts.map +1 -1
  151. package/dist/compiler/utils/path-resolver.js +120 -24
  152. package/dist/compiler/utils/path-resolver.js.map +1 -1
  153. package/dist/compiler/utils/reference-resolver.d.ts +196 -0
  154. package/dist/compiler/utils/reference-resolver.d.ts.map +1 -0
  155. package/dist/compiler/utils/reference-resolver.js +1030 -0
  156. package/dist/compiler/utils/reference-resolver.js.map +1 -0
  157. package/dist/compiler/utils/schema-converter.d.ts +25 -0
  158. package/dist/compiler/utils/schema-converter.d.ts.map +1 -1
  159. package/dist/compiler/utils/schema-converter.js +83 -4
  160. package/dist/compiler/utils/schema-converter.js.map +1 -1
  161. package/dist/compiler/utils/workspace.d.ts +35 -0
  162. package/dist/compiler/utils/workspace.d.ts.map +1 -0
  163. package/dist/compiler/utils/workspace.js +121 -0
  164. package/dist/compiler/utils/workspace.js.map +1 -0
  165. package/dist/compiler/utils/zod-runtime.mjs +5334 -0
  166. package/dist/index.js +1 -0
  167. package/dist/index.js.map +1 -1
  168. package/dist/interfaces/backup.d.ts +19 -1
  169. package/dist/interfaces/backup.d.ts.map +1 -1
  170. package/dist/interfaces/chat.d.ts +2 -2
  171. package/dist/interfaces/chat.d.ts.map +1 -1
  172. package/dist/interfaces/logs.d.ts +7 -4
  173. package/dist/interfaces/logs.d.ts.map +1 -1
  174. package/dist/primitives/base.handler.d.ts +10 -0
  175. package/dist/primitives/base.handler.d.ts.map +1 -1
  176. package/dist/primitives/base.handler.js +73 -44
  177. package/dist/primitives/base.handler.js.map +1 -1
  178. package/dist/primitives/job.handler.d.ts +5 -0
  179. package/dist/primitives/job.handler.d.ts.map +1 -1
  180. package/dist/primitives/job.handler.js +9 -0
  181. package/dist/primitives/job.handler.js.map +1 -1
  182. package/dist/primitives/webhook.handler.d.ts +2 -1
  183. package/dist/primitives/webhook.handler.d.ts.map +1 -1
  184. package/dist/primitives/webhook.handler.js +7 -1
  185. package/dist/primitives/webhook.handler.js.map +1 -1
  186. package/dist/services/auth.d.ts +8 -0
  187. package/dist/services/auth.d.ts.map +1 -1
  188. package/dist/services/auth.js +19 -0
  189. package/dist/services/auth.js.map +1 -1
  190. package/dist/services/sandbox.service.d.ts.map +1 -1
  191. package/dist/services/sandbox.service.js +6 -2
  192. package/dist/services/sandbox.service.js.map +1 -1
  193. package/dist/utils/aliases.d.ts +7 -0
  194. package/dist/utils/aliases.d.ts.map +1 -0
  195. package/dist/utils/aliases.js +457 -0
  196. package/dist/utils/aliases.js.map +1 -0
  197. package/dist/utils/backup-helpers.d.ts +24 -0
  198. package/dist/utils/backup-helpers.d.ts.map +1 -1
  199. package/dist/utils/backup-helpers.js +94 -8
  200. package/dist/utils/backup-helpers.js.map +1 -1
  201. package/dist/utils/chat-attachments.d.ts +15 -0
  202. package/dist/utils/chat-attachments.d.ts.map +1 -0
  203. package/dist/utils/chat-attachments.js +116 -0
  204. package/dist/utils/chat-attachments.js.map +1 -0
  205. package/dist/utils/cli.d.ts +24 -6
  206. package/dist/utils/cli.d.ts.map +1 -1
  207. package/dist/utils/cli.js +23 -9
  208. package/dist/utils/cli.js.map +1 -1
  209. package/dist/utils/hints.d.ts +81 -0
  210. package/dist/utils/hints.d.ts.map +1 -0
  211. package/dist/utils/hints.js +83 -0
  212. package/dist/utils/hints.js.map +1 -0
  213. package/dist/utils/suggest.d.ts +3 -0
  214. package/dist/utils/suggest.d.ts.map +1 -0
  215. package/dist/utils/suggest.js +34 -0
  216. package/dist/utils/suggest.js.map +1 -0
  217. package/dist/utils/write-info.d.ts +9 -0
  218. package/dist/utils/write-info.d.ts.map +1 -0
  219. package/dist/utils/write-info.js +11 -0
  220. package/dist/utils/write-info.js.map +1 -0
  221. package/docs/README.md +1 -1
  222. package/node_modules/@lua/shared-types/dist/index.d.mts +64 -2
  223. package/node_modules/@lua/shared-types/dist/index.d.ts +64 -2
  224. package/node_modules/@lua/shared-types/dist/index.js +27 -0
  225. package/node_modules/@lua/shared-types/dist/index.mjs +24 -0
  226. package/node_modules/@lua/shared-types/src/channel.type.ts +1 -0
  227. package/node_modules/@lua/shared-types/src/client-tools.types.ts +47 -0
  228. package/node_modules/@lua/shared-types/src/index.ts +2 -0
  229. package/node_modules/@lua/shared-types/src/vm-execution-log.types.ts +41 -0
  230. package/package.json +10 -6
  231. package/scripts/build-vendor.mjs +53 -0
  232. package/scripts/vendor-entry.mjs +11 -0
  233. package/template/examples/skills/tools/CustomDataTool.ts +1 -5
  234. package/template/examples/skills/tools/PremiumFeatureTool.ts +18 -18
  235. package/template/package.json +1 -1
@@ -0,0 +1,734 @@
1
+ /**
2
+ * Status Command
3
+ *
4
+ * Unified state dump of the lua-cli + project + server.
5
+ * Print (or emit as JSON) the full state across all "doctor" sections:
6
+ * environment, install method, updates, auth, project, per-primitive sync,
7
+ * persona, backup, telemetry, and derived next-step hints.
8
+ *
9
+ * Aliases: lua describe.
10
+ */
11
+ import { readFileSync, existsSync } from 'fs';
12
+ import { fileURLToPath } from 'url';
13
+ import { dirname, join } from 'path';
14
+ import { performance } from 'perf_hooks';
15
+ import * as os from 'os';
16
+ import { withErrorHandling } from '../utils/cli.js';
17
+ import { hintsDisabled } from '../utils/hints.js';
18
+ import { trackEvent } from '../services/analytics.js';
19
+ import { loadApiKey } from '../services/auth.js';
20
+ import AuthApi from '../api/auth.api.service.js';
21
+ import { readYamlConfig } from '../utils/files.js';
22
+ import { loadManifest, getAgentName } from '../utils/artifact-loader.js';
23
+ import { syncableHandlers, isVersionedHandler } from '../primitives/index.js';
24
+ import { compareVersions, parseVersion } from '../utils/semver.js';
25
+ import { isUpdateAvailable, getCachedVersionCheck } from '../utils/version-check.js';
26
+ import { checkPersonaDrift } from '../utils/sync-fetch.js';
27
+ import { getCurrentProjectHash, isBackupOutOfSync } from '../utils/backup-helpers.js';
28
+ import { BASE_URLS, CLI_CONFIG_DIR, TELEMETRY_FILE } from '../config/constants.js';
29
+ import { COMPILE_FILES } from '../config/compile.constants.js';
30
+ import { PrimitiveKind } from '../compiler/types.js';
31
+ // =============================================================================
32
+ // HELPERS
33
+ // =============================================================================
34
+ function getCliVersion() {
35
+ try {
36
+ const __filename = fileURLToPath(import.meta.url);
37
+ const __dirname = dirname(__filename);
38
+ const pkg = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf8'));
39
+ return pkg.version;
40
+ }
41
+ catch {
42
+ return '0.0.0';
43
+ }
44
+ }
45
+ function detectInstallMethod(execPath) {
46
+ if (execPath.includes('/.volta/'))
47
+ return 'volta';
48
+ if (execPath.includes('/.nvm/versions/')) {
49
+ const nodeMajor = process.version.split('.')[0].replace('v', '');
50
+ return `nvm-${nodeMajor}`;
51
+ }
52
+ if (execPath.includes('/.fnm/'))
53
+ return 'fnm';
54
+ if (execPath.includes('/pnpm/global/'))
55
+ return 'pnpm-global';
56
+ if (execPath.includes('/.bun/install/'))
57
+ return 'bun-install';
58
+ if (execPath.startsWith('/usr/local/') || execPath.startsWith('/opt/homebrew/')) {
59
+ return 'homebrew-or-npm-global';
60
+ }
61
+ if (execPath.includes('/node_modules/.bin'))
62
+ return 'project-local';
63
+ return 'unknown';
64
+ }
65
+ function detectChannel(currentVersion) {
66
+ const { preRelease } = parseVersion(currentVersion);
67
+ if (!preRelease)
68
+ return 'latest';
69
+ const tag = preRelease.split('.')[0].replace(/[0-9]/g, '');
70
+ return tag || 'latest';
71
+ }
72
+ function formatRelativeTime(checkedAtMs) {
73
+ if (!checkedAtMs)
74
+ return null;
75
+ return new Date(checkedAtMs).toISOString();
76
+ }
77
+ // =============================================================================
78
+ // SECTION GATHERERS
79
+ // =============================================================================
80
+ function gatherEnvironment(currentVersion) {
81
+ return {
82
+ cliVersion: currentVersion,
83
+ channel: detectChannel(currentVersion),
84
+ nodeVersion: process.version,
85
+ platform: os.platform(),
86
+ arch: os.arch(),
87
+ osRelease: os.release(),
88
+ installMethod: detectInstallMethod(process.execPath),
89
+ execPath: process.execPath,
90
+ configDir: CLI_CONFIG_DIR,
91
+ apiBase: BASE_URLS.API,
92
+ authBase: BASE_URLS.AUTH,
93
+ envOverrides: {
94
+ LUA_API_URL: process.env.LUA_API_URL ?? null,
95
+ LUA_AUTH_URL: process.env.LUA_AUTH_URL ?? null,
96
+ LUA_API_KEY: process.env.LUA_API_KEY ? 'set' : 'not set',
97
+ LUA_TELEMETRY: process.env.LUA_TELEMETRY ?? null,
98
+ LUA_NO_HINTS: process.env.LUA_NO_HINTS ?? null,
99
+ },
100
+ };
101
+ }
102
+ async function gatherUpdates(currentVersion) {
103
+ const preFetchCache = getCachedVersionCheck();
104
+ try {
105
+ const result = await isUpdateAvailable(currentVersion);
106
+ const postFetchCache = getCachedVersionCheck();
107
+ return {
108
+ current: currentVersion,
109
+ latest: result.latest,
110
+ available: result.available,
111
+ lastCheckedAt: postFetchCache ? formatRelativeTime(postFetchCache.checkedAt) : null,
112
+ fromCache: !!preFetchCache,
113
+ };
114
+ }
115
+ catch {
116
+ const postFetchCache = getCachedVersionCheck();
117
+ return {
118
+ current: currentVersion,
119
+ latest: postFetchCache?.latestVersion ?? null,
120
+ available: false,
121
+ lastCheckedAt: postFetchCache ? formatRelativeTime(postFetchCache.checkedAt) : null,
122
+ fromCache: !!preFetchCache,
123
+ };
124
+ }
125
+ }
126
+ async function gatherAuth() {
127
+ let apiKey = null;
128
+ try {
129
+ apiKey = loadApiKey();
130
+ }
131
+ catch {
132
+ apiKey = null;
133
+ }
134
+ if (!apiKey) {
135
+ let serverReachable = null;
136
+ let reachabilityMs = null;
137
+ try {
138
+ const start = performance.now();
139
+ const response = await fetch(BASE_URLS.API, {
140
+ method: 'HEAD',
141
+ signal: AbortSignal.timeout(3000),
142
+ });
143
+ reachabilityMs = Math.round(performance.now() - start);
144
+ serverReachable = response.ok || (response.status >= 200 && response.status < 500);
145
+ }
146
+ catch {
147
+ serverReachable = false;
148
+ reachabilityMs = null;
149
+ }
150
+ return {
151
+ authenticated: false,
152
+ source: null,
153
+ email: null,
154
+ userId: null,
155
+ organizations: [],
156
+ serverReachable,
157
+ reachabilityMs,
158
+ };
159
+ }
160
+ const source = process.env.LUA_API_KEY ? 'env' : 'credentials file';
161
+ let email = null;
162
+ let userId = null;
163
+ let organizations = [];
164
+ let serverReachable = null;
165
+ let reachabilityMs = null;
166
+ let keyAccepted = false;
167
+ try {
168
+ const authApi = new AuthApi(BASE_URLS.API);
169
+ const start = performance.now();
170
+ const result = await authApi.checkApiKey(apiKey);
171
+ reachabilityMs = Math.round(performance.now() - start);
172
+ serverReachable = true; // got a network response (key may still be rejected)
173
+ if (result.success && result.data) {
174
+ keyAccepted = true;
175
+ email = result.data.email ?? null;
176
+ userId = result.data.uid ?? null;
177
+ const orgs = result.data.admin?.orgs ?? [];
178
+ organizations = orgs.map((o) => ({
179
+ id: o.id ?? o.orgId ?? '',
180
+ name: o.registeredName ?? o.name ?? '',
181
+ }));
182
+ }
183
+ }
184
+ catch {
185
+ serverReachable = false; // network error — couldn't reach the server
186
+ }
187
+ return {
188
+ authenticated: keyAccepted,
189
+ source,
190
+ email,
191
+ userId,
192
+ organizations,
193
+ serverReachable,
194
+ reachabilityMs,
195
+ };
196
+ }
197
+ function gatherProject(config) {
198
+ if (!config) {
199
+ return {
200
+ inProject: false,
201
+ rootDir: null,
202
+ configPath: null,
203
+ agentId: null,
204
+ agentName: null,
205
+ manifest: { found: false, primitiveCount: 0 },
206
+ };
207
+ }
208
+ const rootDir = process.cwd();
209
+ const configPath = join(rootDir, COMPILE_FILES.LUA_SKILL_YAML);
210
+ const agentId = config.agent?.agentId != null ? String(config.agent.agentId) : null;
211
+ let agentName = null;
212
+ let manifestFound = false;
213
+ let primitiveCount = 0;
214
+ try {
215
+ agentName = getAgentName() ?? null;
216
+ }
217
+ catch {
218
+ agentName = null;
219
+ }
220
+ try {
221
+ const manifest = loadManifest();
222
+ manifestFound = true;
223
+ primitiveCount = manifest.primitives.filter(p => p.kind !== PrimitiveKind.AGENT).length;
224
+ }
225
+ catch {
226
+ manifestFound = false;
227
+ }
228
+ return {
229
+ inProject: true,
230
+ rootDir,
231
+ configPath,
232
+ agentId,
233
+ agentName,
234
+ manifest: { found: manifestFound, primitiveCount },
235
+ };
236
+ }
237
+ async function gatherPrimitives(input, warnings) {
238
+ const { apiKey, agentId, config } = input;
239
+ if (!config)
240
+ return [];
241
+ const sections = [];
242
+ // Local items per handler (sync — read from yaml)
243
+ const localPerHandler = new Map();
244
+ for (const handler of syncableHandlers) {
245
+ const yamlItems = handler.getFromYaml(config);
246
+ const items = yamlItems.map((item) => ({
247
+ name: item.name,
248
+ version: item.version || '',
249
+ entityId: item[handler.yamlConfig.idField] ?? '',
250
+ }));
251
+ localPerHandler.set(handler, items);
252
+ }
253
+ // Fetch server state per handler in parallel — Promise.allSettled to isolate failures.
254
+ const serverPerHandler = new Map();
255
+ if (apiKey && agentId) {
256
+ const fetchResults = await Promise.allSettled(syncableHandlers.map(handler => handler.fetchServerState(apiKey, agentId)));
257
+ syncableHandlers.forEach((handler, i) => {
258
+ const result = fetchResults[i];
259
+ if (result.status === 'fulfilled') {
260
+ if (result.value.fetchError) {
261
+ warnings.push(`Failed to fetch server state for ${handler.displayNamePlural}: ${result.value.fetchError}`);
262
+ serverPerHandler.set(handler, null);
263
+ }
264
+ else {
265
+ serverPerHandler.set(handler, result.value.serverItems ?? []);
266
+ }
267
+ }
268
+ else {
269
+ warnings.push(`Failed to fetch server state for ${handler.displayNamePlural}: ${result.reason?.message ?? 'unknown error'}`);
270
+ serverPerHandler.set(handler, null);
271
+ }
272
+ });
273
+ }
274
+ for (const handler of syncableHandlers) {
275
+ const local = localPerHandler.get(handler) ?? [];
276
+ const serverItems = serverPerHandler.get(handler) ?? null;
277
+ const versioned = isVersionedHandler(handler);
278
+ const server = (serverItems ?? []).map((s) => ({
279
+ name: s.name,
280
+ activeVersion: versioned ? handler.getActiveVersion(s) : null,
281
+ active: handler.isActive?.(s) ?? true,
282
+ }));
283
+ const serverByName = new Map();
284
+ for (const s of serverItems ?? []) {
285
+ serverByName.set(s.name, s);
286
+ }
287
+ const diffs = [];
288
+ if (serverItems !== null) {
289
+ for (const item of local) {
290
+ const serverItem = serverByName.get(item.name);
291
+ const activeVersion = versioned && serverItem ? handler.getActiveVersion(serverItem) : null;
292
+ let status;
293
+ if (!versioned) {
294
+ // Non-versioned (MCP servers): present on server = synced, absent = not deployed
295
+ status = serverItem ? 'synced' : 'not deployed';
296
+ }
297
+ else if (!item.version || activeVersion === null) {
298
+ status = 'not deployed';
299
+ }
300
+ else {
301
+ const cmp = compareVersions(item.version, activeVersion);
302
+ if (cmp > 0)
303
+ status = 'ahead';
304
+ else if (cmp < 0)
305
+ status = 'behind';
306
+ else
307
+ status = 'synced';
308
+ }
309
+ diffs.push({
310
+ name: item.name,
311
+ localVersion: item.version,
312
+ serverVersion: activeVersion,
313
+ status,
314
+ });
315
+ }
316
+ }
317
+ const orphans = [];
318
+ if (serverItems !== null) {
319
+ const localNames = new Set(local.map(i => i.name));
320
+ const isProcessor = handler.kind === PrimitiveKind.PREPROCESSOR ||
321
+ handler.kind === PrimitiveKind.POSTPROCESSOR;
322
+ for (const s of serverItems) {
323
+ if (localNames.has(s.name))
324
+ continue;
325
+ if (!(handler.isActive?.(s) ?? true))
326
+ continue;
327
+ if (!handler.shouldConsiderForOrphan(s))
328
+ continue;
329
+ const flagName = `--${handler.displayName.toLowerCase().replace(/\s+/g, '-')}-name`;
330
+ // Some primitive types have no CLI delete command yet
331
+ const cleanupCommand = handler.kind !== PrimitiveKind.DEVICE_TRIGGER
332
+ ? `${handler.deleteCommand} ${flagName} "${s.name}"`
333
+ : '';
334
+ orphans.push({
335
+ name: s.name,
336
+ cleanupCommand,
337
+ critical: isProcessor,
338
+ });
339
+ }
340
+ }
341
+ sections.push({
342
+ kind: handler.kind,
343
+ displayName: handler.displayNamePlural,
344
+ local,
345
+ server,
346
+ diffs,
347
+ orphans,
348
+ });
349
+ }
350
+ return sections;
351
+ }
352
+ async function gatherPersona(apiKey, agentId) {
353
+ if (!apiKey || !agentId)
354
+ return { status: 'unknown' };
355
+ try {
356
+ const drift = await checkPersonaDrift(apiKey, agentId);
357
+ return { status: drift ? 'drift' : 'synced' };
358
+ }
359
+ catch {
360
+ return { status: 'unknown' };
361
+ }
362
+ }
363
+ function gatherBackup(config) {
364
+ if (!config)
365
+ return { status: 'unknown' };
366
+ let currentHash = null;
367
+ try {
368
+ currentHash = getCurrentProjectHash();
369
+ }
370
+ catch {
371
+ currentHash = null;
372
+ }
373
+ if (!currentHash)
374
+ return { status: 'never-compiled' };
375
+ try {
376
+ const out = isBackupOutOfSync(currentHash, config.backup);
377
+ return { status: out ? 'out-of-sync' : 'synced' };
378
+ }
379
+ catch {
380
+ return { status: 'unknown' };
381
+ }
382
+ }
383
+ function gatherTelemetry() {
384
+ const envVal = process.env.LUA_TELEMETRY;
385
+ const envOverride = envVal !== undefined;
386
+ let enabled = true;
387
+ if (envOverride) {
388
+ enabled = !['false', '0', 'off', 'no'].includes(envVal.toLowerCase());
389
+ }
390
+ else {
391
+ try {
392
+ if (existsSync(TELEMETRY_FILE)) {
393
+ const raw = readFileSync(TELEMETRY_FILE, 'utf8');
394
+ const cfg = JSON.parse(raw);
395
+ if (typeof cfg.enabled === 'boolean')
396
+ enabled = cfg.enabled;
397
+ }
398
+ }
399
+ catch {
400
+ // default enabled = true
401
+ }
402
+ }
403
+ return { enabled, envOverride };
404
+ }
405
+ // =============================================================================
406
+ // HINTS
407
+ // =============================================================================
408
+ function deriveHints(report) {
409
+ const hints = [];
410
+ if (report.updates.available && report.updates.latest) {
411
+ hints.push({
412
+ command: 'lua update',
413
+ reason: `Upgrade lua-cli (${report.updates.current} → ${report.updates.latest})`,
414
+ });
415
+ }
416
+ if (!report.auth.authenticated) {
417
+ hints.push({
418
+ command: 'lua auth configure',
419
+ reason: 'Authenticate for full server comparison',
420
+ });
421
+ }
422
+ for (const section of report.primitives) {
423
+ for (const orphan of section.orphans) {
424
+ if (!orphan.cleanupCommand)
425
+ continue;
426
+ hints.push({
427
+ command: orphan.cleanupCommand,
428
+ reason: orphan.critical
429
+ ? `Remove orphan ${section.displayName} "${orphan.name}" (causes errors)`
430
+ : `Remove orphan ${section.displayName} "${orphan.name}"`,
431
+ });
432
+ }
433
+ }
434
+ if (report.backup.status === 'out-of-sync') {
435
+ hints.push({
436
+ command: 'lua push backup',
437
+ reason: 'Sync source backup',
438
+ });
439
+ }
440
+ if (report.persona.status === 'drift') {
441
+ hints.push({
442
+ command: 'lua sync',
443
+ reason: 'Resolve persona drift',
444
+ });
445
+ }
446
+ return hints;
447
+ }
448
+ // =============================================================================
449
+ // RENDERERS
450
+ // =============================================================================
451
+ function pad(s, n) {
452
+ return s.length >= n ? s : s + ' '.repeat(n - s.length);
453
+ }
454
+ function printJson(report) {
455
+ console.log(JSON.stringify(report));
456
+ }
457
+ function printHuman(report) {
458
+ const lines = [];
459
+ lines.push('');
460
+ lines.push('== lua status ==');
461
+ lines.push('');
462
+ // Environment
463
+ const env = report.environment;
464
+ lines.push('Environment');
465
+ lines.push(` CLI version ${env.cliVersion} (channel: ${env.channel})`);
466
+ lines.push(` Node ${env.nodeVersion}`);
467
+ lines.push(` OS ${env.platform} ${env.osRelease} (${env.arch})`);
468
+ lines.push(` Install method ${env.installMethod}`);
469
+ lines.push(` Exec path ${env.execPath}`);
470
+ lines.push(` Config dir ${env.configDir}`);
471
+ lines.push(` API base ${env.apiBase}`);
472
+ lines.push(` Auth base ${env.authBase}`);
473
+ const overrides = env.envOverrides;
474
+ const overridesStr = [
475
+ `LUA_API_URL: ${overrides.LUA_API_URL ?? 'not set'}`,
476
+ `LUA_AUTH_URL: ${overrides.LUA_AUTH_URL ?? 'not set'}`,
477
+ `LUA_API_KEY: ${overrides.LUA_API_KEY}`,
478
+ `LUA_TELEMETRY: ${overrides.LUA_TELEMETRY ?? 'not set'}`,
479
+ `LUA_NO_HINTS: ${overrides.LUA_NO_HINTS ?? 'not set'}`,
480
+ ].join(', ');
481
+ lines.push(` Env overrides ${overridesStr}`);
482
+ lines.push('');
483
+ // Updates
484
+ const u = report.updates;
485
+ lines.push('Updates');
486
+ lines.push(` Current ${u.current}`);
487
+ lines.push(` Latest published ${u.latest ?? 'unknown'}`);
488
+ lines.push(` Status ${u.available ? 'update available — run `lua update`' : 'up to date'}`);
489
+ if (u.lastCheckedAt) {
490
+ lines.push(` Last checked ${u.lastCheckedAt}${u.fromCache ? ' (cache)' : ''}`);
491
+ }
492
+ lines.push('');
493
+ // Auth
494
+ const a = report.auth;
495
+ lines.push('Auth');
496
+ if (a.source) {
497
+ lines.push(` Key source ${a.source}`);
498
+ if (a.authenticated) {
499
+ lines.push(` Email ${a.email ?? 'unknown'}`);
500
+ lines.push(` User ID ${a.userId ?? 'unknown'}`);
501
+ if (a.organizations.length > 0) {
502
+ const orgNames = a.organizations.map(o => o.name || o.id).filter(Boolean).join(', ');
503
+ lines.push(` Organizations ${a.organizations.length} (${orgNames})`);
504
+ }
505
+ else {
506
+ lines.push(` Organizations 0`);
507
+ }
508
+ lines.push(` Status authenticated${a.reachabilityMs !== null ? ` (${a.reachabilityMs}ms)` : ''}`);
509
+ }
510
+ else if (a.serverReachable) {
511
+ lines.push(` Status key rejected by server${a.reachabilityMs !== null ? ` (${a.reachabilityMs}ms)` : ''}`);
512
+ }
513
+ else {
514
+ lines.push(` Status key found, server unreachable`);
515
+ }
516
+ }
517
+ else {
518
+ lines.push(` Status no API key configured — run \`lua auth configure\``);
519
+ if (a.serverReachable !== null) {
520
+ lines.push(` Server ${a.serverReachable ? 'reachable' : 'unreachable'}${a.reachabilityMs !== null ? ` (${a.reachabilityMs}ms)` : ''}`);
521
+ }
522
+ }
523
+ lines.push('');
524
+ // Project
525
+ const p = report.project;
526
+ lines.push('Project');
527
+ if (p.inProject) {
528
+ lines.push(` Path ${p.rootDir}`);
529
+ lines.push(` Config ${p.configPath} (found)`);
530
+ lines.push(` Agent ${p.agentName ?? 'unnamed'}${p.agentId ? ` (${p.agentId.substring(0, 8)})` : ''}`);
531
+ if (p.manifest.found) {
532
+ lines.push(` Manifest dist-v2/manifest.json (compiled, ${p.manifest.primitiveCount} primitives)`);
533
+ }
534
+ else {
535
+ lines.push(` Manifest (never compiled)`);
536
+ }
537
+ }
538
+ else {
539
+ lines.push(` (not in a lua project)`);
540
+ }
541
+ lines.push('');
542
+ // Per-primitive sections
543
+ for (const section of report.primitives) {
544
+ const label = section.displayName.charAt(0).toUpperCase() + section.displayName.slice(1);
545
+ const localCount = section.local.length;
546
+ const serverCount = section.server.length;
547
+ lines.push(`${pad(label, 22)}${localCount} local ${serverCount} server`);
548
+ if (localCount === 0 && section.orphans.length === 0) {
549
+ lines.push(' (none)');
550
+ lines.push('');
551
+ continue;
552
+ }
553
+ lines.push(` ${pad('name', 22)}${pad('local', 10)}${pad('server', 10)}status`);
554
+ lines.push('');
555
+ for (const diff of section.diffs) {
556
+ const sv = diff.serverVersion ?? '--';
557
+ lines.push(` ${pad(diff.name, 22)}${pad(diff.localVersion, 10)}${pad(sv, 10)}${diff.status}`);
558
+ }
559
+ for (const orphan of section.orphans) {
560
+ const serverEntry = section.server.find(s => s.name === orphan.name);
561
+ const sv = serverEntry?.activeVersion ?? '--';
562
+ lines.push(` ${pad(orphan.name, 22)}${pad('--', 10)}${pad(sv, 10)}server only${orphan.critical ? ' ⚠ causes errors' : ''}`);
563
+ }
564
+ lines.push('');
565
+ }
566
+ // Persona
567
+ const personaLabel = report.persona.status === 'synced'
568
+ ? '[synced]'
569
+ : report.persona.status === 'drift'
570
+ ? '[drift detected] Local differs from server'
571
+ : '[unknown]';
572
+ lines.push(`Persona ${personaLabel}`);
573
+ // Backup
574
+ const backupLabel = report.backup.status === 'synced'
575
+ ? '[synced]'
576
+ : report.backup.status === 'out-of-sync'
577
+ ? '[out of sync] Source files changed since last push'
578
+ : report.backup.status === 'never-compiled'
579
+ ? '[never-compiled] Run `lua compile` first'
580
+ : '[unknown]';
581
+ lines.push(`Backup ${backupLabel}`);
582
+ // Telemetry
583
+ lines.push(`Telemetry ${report.telemetry.enabled ? 'enabled' : 'disabled'}${report.telemetry.envOverride ? ' (LUA_TELEMETRY override)' : ''}`);
584
+ lines.push('');
585
+ // Warnings
586
+ if (report.warnings.length > 0) {
587
+ lines.push('Warnings');
588
+ for (const w of report.warnings) {
589
+ lines.push(` - ${w}`);
590
+ }
591
+ lines.push('');
592
+ }
593
+ // Next steps
594
+ if (report.hints.length > 0) {
595
+ lines.push('Next steps');
596
+ for (const h of report.hints) {
597
+ lines.push(` - ${h.reason}: \`${h.command}\``);
598
+ }
599
+ lines.push('');
600
+ }
601
+ console.log(lines.join('\n'));
602
+ }
603
+ // =============================================================================
604
+ // ENTRY POINT
605
+ // =============================================================================
606
+ export async function statusCommand(options) {
607
+ return withErrorHandling(async () => {
608
+ const warnings = [];
609
+ const currentVersion = getCliVersion();
610
+ const environment = gatherEnvironment(currentVersion);
611
+ // Gather concurrent sections via allSettled — each failure becomes a warning, never aborts.
612
+ const [updatesResult, authResult] = await Promise.allSettled([
613
+ gatherUpdates(currentVersion),
614
+ gatherAuth(),
615
+ ]);
616
+ const updates = updatesResult.status === 'fulfilled'
617
+ ? updatesResult.value
618
+ : (() => {
619
+ warnings.push(`updates: ${updatesResult.reason?.message ?? 'unknown'}`);
620
+ return {
621
+ current: currentVersion,
622
+ latest: null,
623
+ available: false,
624
+ lastCheckedAt: null,
625
+ fromCache: false,
626
+ };
627
+ })();
628
+ const auth = authResult.status === 'fulfilled'
629
+ ? authResult.value
630
+ : (() => {
631
+ warnings.push(`auth: ${authResult.reason?.message ?? 'unknown'}`);
632
+ return {
633
+ authenticated: false,
634
+ source: null,
635
+ email: null,
636
+ userId: null,
637
+ organizations: [],
638
+ serverReachable: null,
639
+ reachabilityMs: null,
640
+ };
641
+ })();
642
+ let config = null;
643
+ try {
644
+ config = readYamlConfig();
645
+ }
646
+ catch (err) {
647
+ warnings.push(`config: ${err?.message ?? 'unknown'}`);
648
+ }
649
+ let project;
650
+ try {
651
+ project = gatherProject(config);
652
+ }
653
+ catch (err) {
654
+ warnings.push(`project: ${err?.message ?? 'unknown'}`);
655
+ project = {
656
+ inProject: false,
657
+ rootDir: null,
658
+ configPath: null,
659
+ agentId: null,
660
+ agentName: null,
661
+ manifest: { found: false, primitiveCount: 0 },
662
+ };
663
+ }
664
+ const apiKey = (() => {
665
+ try {
666
+ return loadApiKey();
667
+ }
668
+ catch {
669
+ return null;
670
+ }
671
+ })();
672
+ const [primitivesResult, personaResult] = await Promise.allSettled([
673
+ gatherPrimitives({ apiKey, agentId: project.agentId, config }, warnings),
674
+ gatherPersona(apiKey, project.agentId),
675
+ ]);
676
+ const primitives = primitivesResult.status === 'fulfilled'
677
+ ? primitivesResult.value
678
+ : (() => {
679
+ warnings.push(`primitives: ${primitivesResult.reason?.message ?? 'unknown'}`);
680
+ return [];
681
+ })();
682
+ const persona = personaResult.status === 'fulfilled'
683
+ ? personaResult.value
684
+ : (() => {
685
+ warnings.push(`persona: ${personaResult.reason?.message ?? 'unknown'}`);
686
+ return { status: 'unknown' };
687
+ })();
688
+ let backup;
689
+ try {
690
+ backup = gatherBackup(config);
691
+ }
692
+ catch (err) {
693
+ warnings.push(`backup: ${err?.message ?? 'unknown'}`);
694
+ backup = { status: 'unknown' };
695
+ }
696
+ let telemetry;
697
+ try {
698
+ telemetry = gatherTelemetry();
699
+ }
700
+ catch (err) {
701
+ warnings.push(`telemetry: ${err?.message ?? 'unknown'}`);
702
+ telemetry = { enabled: true, envOverride: false };
703
+ }
704
+ const reportNoHints = {
705
+ schemaVersion: 1,
706
+ command: 'status',
707
+ generatedAt: new Date().toISOString(),
708
+ environment,
709
+ updates,
710
+ auth,
711
+ project,
712
+ primitives,
713
+ persona,
714
+ backup,
715
+ telemetry,
716
+ warnings,
717
+ };
718
+ const hints = hintsDisabled() ? [] : deriveHints(reportNoHints);
719
+ const report = { ...reportNoHints, hints };
720
+ if (options.json) {
721
+ printJson(report);
722
+ }
723
+ else {
724
+ printHuman(report);
725
+ }
726
+ trackEvent('cli_status_completed', {
727
+ has_server: !!apiKey,
728
+ in_project: project.inProject,
729
+ json_mode: !!options.json,
730
+ sections_failed: warnings.length,
731
+ });
732
+ }, 'status');
733
+ }
734
+ //# sourceMappingURL=status.js.map