dexto 1.1.4 → 1.1.6

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 (130) hide show
  1. package/README.md +480 -0
  2. package/dist/analytics/constants.d.ts +19 -0
  3. package/dist/analytics/constants.d.ts.map +1 -0
  4. package/dist/analytics/constants.js +24 -0
  5. package/dist/analytics/events.d.ts +112 -0
  6. package/dist/analytics/events.d.ts.map +1 -0
  7. package/dist/analytics/events.js +6 -0
  8. package/dist/analytics/index.d.ts +37 -0
  9. package/dist/analytics/index.d.ts.map +1 -0
  10. package/dist/analytics/index.js +145 -0
  11. package/dist/analytics/state.d.ts +23 -0
  12. package/dist/analytics/state.d.ts.map +1 -0
  13. package/dist/analytics/state.js +74 -0
  14. package/dist/analytics/wrapper.d.ts +11 -0
  15. package/dist/analytics/wrapper.d.ts.map +1 -0
  16. package/dist/analytics/wrapper.js +125 -0
  17. package/dist/cli/cli.d.ts +5 -0
  18. package/dist/cli/cli.d.ts.map +1 -1
  19. package/dist/cli/cli.js +10 -4
  20. package/dist/cli/commands/{interactive-commands/session/helpers → helpers}/formatters.d.ts +1 -1
  21. package/dist/cli/commands/helpers/formatters.d.ts.map +1 -0
  22. package/dist/cli/commands/{interactive-commands/session/helpers → helpers}/formatters.js +1 -1
  23. package/dist/cli/commands/install.d.ts.map +1 -1
  24. package/dist/cli/commands/install.js +56 -2
  25. package/dist/cli/commands/interactive-commands/session/index.d.ts +1 -1
  26. package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
  27. package/dist/cli/commands/interactive-commands/session/index.js +1 -1
  28. package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
  29. package/dist/cli/commands/interactive-commands/session/session-commands.js +10 -76
  30. package/dist/cli/commands/list-agents.d.ts +2 -2
  31. package/dist/cli/commands/session-commands.d.ts +28 -0
  32. package/dist/cli/commands/session-commands.d.ts.map +1 -0
  33. package/dist/cli/commands/session-commands.js +184 -0
  34. package/dist/cli/commands/setup.d.ts +2 -2
  35. package/dist/cli/commands/setup.d.ts.map +1 -1
  36. package/dist/cli/commands/setup.js +9 -0
  37. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  38. package/dist/cli/commands/uninstall.js +42 -1
  39. package/dist/cli/utils/api-key-setup.js +1 -1
  40. package/dist/index.js +271 -75
  41. package/dist/webui/.next/standalone/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
  42. package/dist/webui/.next/standalone/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
  43. package/dist/webui/.next/standalone/.next/static/chunks/app/{page-24123c97236d46cb.js → page-cf95b233c1df6dcd.js} +1 -1
  44. package/dist/webui/.next/standalone/.next/static/css/9cdfb06589a2f6ce.css +3 -0
  45. package/dist/webui/.next/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  46. package/dist/webui/.next/standalone/package.json +2 -1
  47. package/dist/webui/.next/standalone/packages/webui/.next/BUILD_ID +1 -1
  48. package/dist/webui/.next/standalone/packages/webui/.next/app-build-manifest.json +5 -7
  49. package/dist/webui/.next/standalone/packages/webui/.next/build-manifest.json +2 -2
  50. package/dist/webui/.next/standalone/packages/webui/.next/prerender-manifest.json +3 -3
  51. package/dist/webui/.next/standalone/packages/webui/.next/required-server-files.json +1 -1
  52. package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js +2 -2
  53. package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page.js.nft.json +1 -1
  54. package/dist/webui/.next/standalone/packages/webui/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  55. package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js +3 -3
  56. package/dist/webui/.next/standalone/packages/webui/.next/server/app/page.js.nft.json +1 -1
  57. package/dist/webui/.next/standalone/packages/webui/.next/server/app/page_client-reference-manifest.js +1 -1
  58. package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js +3 -3
  59. package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page.js.nft.json +1 -1
  60. package/dist/webui/.next/standalone/packages/webui/.next/server/app/playground/page_client-reference-manifest.js +1 -1
  61. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/43.js +1 -4
  62. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/619.js +30 -0
  63. package/dist/webui/.next/standalone/packages/webui/.next/server/next-font-manifest.js +1 -1
  64. package/dist/webui/.next/standalone/packages/webui/.next/server/next-font-manifest.json +1 -1
  65. package/dist/webui/.next/standalone/packages/webui/.next/server/pages/500.html +1 -1
  66. package/dist/webui/.next/standalone/packages/webui/.next/server/pages/_error.js +2 -2
  67. package/dist/webui/.next/standalone/packages/webui/.next/server/server-reference-manifest.json +1 -1
  68. package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
  69. package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
  70. package/dist/webui/.next/{static/chunks/app/page-24123c97236d46cb.js → standalone/packages/webui/.next/static/chunks/app/page-cf95b233c1df6dcd.js} +1 -1
  71. package/dist/webui/.next/standalone/packages/webui/.next/static/css/9cdfb06589a2f6ce.css +3 -0
  72. package/dist/webui/.next/standalone/packages/webui/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  73. package/dist/webui/.next/standalone/packages/webui/package.json +1 -1
  74. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto/dexto_logo.svg +31 -0
  75. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto/dexto_logo_icon.svg +14 -0
  76. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto/dexto_logo_icon_light.svg +17 -0
  77. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto/dexto_logo_light.svg +31 -0
  78. package/dist/webui/.next/standalone/packages/webui/server.js +1 -1
  79. package/dist/webui/.next/standalone/public/logos/dexto/dexto_logo.svg +31 -0
  80. package/dist/webui/.next/standalone/public/logos/dexto/dexto_logo_icon.svg +14 -0
  81. package/dist/webui/.next/standalone/public/logos/dexto/dexto_logo_icon_light.svg +17 -0
  82. package/dist/webui/.next/standalone/public/logos/dexto/dexto_logo_light.svg +31 -0
  83. package/dist/webui/.next/static/chunks/854-2a6d5a5297a15d52.js +1 -0
  84. package/dist/webui/.next/static/chunks/app/{layout-615a56c6184a488f.js → layout-dde711766eda096b.js} +1 -1
  85. package/dist/webui/.next/{standalone/packages/webui/.next/static/chunks/app/page-24123c97236d46cb.js → static/chunks/app/page-cf95b233c1df6dcd.js} +1 -1
  86. package/dist/webui/.next/static/css/9cdfb06589a2f6ce.css +3 -0
  87. package/dist/webui/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  88. package/dist/webui/package.json +1 -1
  89. package/dist/webui/public/logos/dexto/dexto_logo.svg +31 -0
  90. package/dist/webui/public/logos/dexto/dexto_logo_icon.svg +14 -0
  91. package/dist/webui/public/logos/dexto/dexto_logo_icon_light.svg +17 -0
  92. package/dist/webui/public/logos/dexto/dexto_logo_light.svg +31 -0
  93. package/package.json +7 -4
  94. package/dist/cli/commands/interactive-commands/session/helpers/formatters.d.ts.map +0 -1
  95. package/dist/webui/.next/standalone/.next/static/chunks/221-608218ab04068cb2.js +0 -1
  96. package/dist/webui/.next/standalone/.next/static/chunks/854-47418382efcea1d4.js +0 -1
  97. package/dist/webui/.next/standalone/.next/static/css/75b11629ebbc461a.css +0 -3
  98. package/dist/webui/.next/standalone/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
  99. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/387.js +0 -14
  100. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/392.js +0 -1
  101. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/450.js +0 -139
  102. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/514.js +0 -2
  103. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/531.js +0 -1
  104. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/723.js +0 -1
  105. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/737.js +0 -1
  106. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/767.js +0 -20
  107. package/dist/webui/.next/standalone/packages/webui/.next/server/chunks/89.js +0 -95
  108. package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/221-608218ab04068cb2.js +0 -1
  109. package/dist/webui/.next/standalone/packages/webui/.next/static/chunks/854-47418382efcea1d4.js +0 -1
  110. package/dist/webui/.next/standalone/packages/webui/.next/static/css/75b11629ebbc461a.css +0 -3
  111. package/dist/webui/.next/standalone/packages/webui/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
  112. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto_logo.svg +0 -1
  113. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto_logo_light.svg +0 -18
  114. package/dist/webui/.next/standalone/packages/webui/public/logos/dexto_logo_no_text.png +0 -0
  115. package/dist/webui/.next/standalone/public/logos/dexto_logo.svg +0 -1
  116. package/dist/webui/.next/standalone/public/logos/dexto_logo_light.svg +0 -18
  117. package/dist/webui/.next/standalone/public/logos/dexto_logo_no_text.png +0 -0
  118. package/dist/webui/.next/static/chunks/221-608218ab04068cb2.js +0 -1
  119. package/dist/webui/.next/static/chunks/854-47418382efcea1d4.js +0 -1
  120. package/dist/webui/.next/static/css/75b11629ebbc461a.css +0 -3
  121. package/dist/webui/.next/static/media/569ce4b8f30dc480-s.p.woff2 +0 -0
  122. package/dist/webui/public/logos/dexto_logo.svg +0 -1
  123. package/dist/webui/public/logos/dexto_logo_light.svg +0 -18
  124. package/dist/webui/public/logos/dexto_logo_no_text.png +0 -0
  125. /package/dist/webui/.next/standalone/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_buildManifest.js +0 -0
  126. /package/dist/webui/.next/standalone/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_ssgManifest.js +0 -0
  127. /package/dist/webui/.next/standalone/packages/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_buildManifest.js +0 -0
  128. /package/dist/webui/.next/standalone/packages/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_ssgManifest.js +0 -0
  129. /package/dist/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_buildManifest.js +0 -0
  130. /package/dist/webui/.next/static/{abgua6ybDH7yT2b5rvLlU → OsQGbLQi9bS4RzNw_6wgr}/_ssgManifest.js +0 -0
@@ -0,0 +1,37 @@
1
+ import { AnalyticsEventName, AnalyticsEventPayload, CliCommandEndEvent, CliCommandStartEvent } from './events.js';
2
+ interface InitOptions {
3
+ appVersion: string;
4
+ }
5
+ /**
6
+ * Initialize the analytics client for the CLI.
7
+ *
8
+ * - Respects DEXTO_ANALYTICS_DISABLED.
9
+ * - Creates/loads the anonymous distinctId and a per-process session_id.
10
+ * - Emits a dexto_session_start event for each process run.
11
+ */
12
+ export declare function initAnalytics(opts: InitOptions): Promise<void>;
13
+ /**
14
+ * Capture a single analytics event with optional properties.
15
+ * Automatically enriches events with base context (app/os/node/session).
16
+ */
17
+ export declare function capture<Name extends AnalyticsEventName>(event: Name, properties?: AnalyticsEventPayload<Name>): void;
18
+ /**
19
+ * Attempt a graceful shutdown of the analytics client, flushing queued events.
20
+ */
21
+ export declare function shutdownAnalytics(): Promise<void>;
22
+ /**
23
+ * Mark the start of a command for timing and emit a lightweight start event.
24
+ * Adds local counters as a coarse diagnostic aid.
25
+ */
26
+ export declare function onCommandStart(name: string, extra?: Partial<Omit<CliCommandStartEvent, 'name' | 'phase'>>): Promise<void>;
27
+ /**
28
+ * Mark the end of a command and emit a completion event with success/failure
29
+ * and measured duration. Accepts optional extra properties.
30
+ */
31
+ export declare function onCommandEnd(name: string, success: boolean, extra?: Partial<Omit<CliCommandEndEvent, 'name' | 'phase' | 'success' | 'durationMs'>>): Promise<void>;
32
+ /**
33
+ * Whether analytics are currently enabled for this process.
34
+ */
35
+ export declare function getEnabled(): boolean;
36
+ export {};
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACH,kBAAkB,EAClB,qBAAqB,EAErB,kBAAkB,EAClB,oBAAoB,EACvB,MAAM,aAAa,CAAC;AAErB,UAAU,WAAW;IACjB,UAAU,EAAE,MAAM,CAAC;CACtB;AAqBD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCpE;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,SAAS,kBAAkB,EACnD,KAAK,EAAE,IAAI,EACX,UAAU,GAAE,qBAAqB,CAAC,IAAI,CAAqC,GAC5E,IAAI,CAWN;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAQvD;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,OAAO,CAAC,CAAM,GAClE,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,KAAK,GAAE,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC,CAAM,GAC3F,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC"}
@@ -0,0 +1,145 @@
1
+ // packages/cli/src/analytics/index.ts
2
+ import { PostHog } from 'posthog-node';
3
+ import os from 'os';
4
+ import { isAnalyticsDisabled, DEFAULT_POSTHOG_HOST, DEFAULT_POSTHOG_KEY } from './constants.js';
5
+ import { loadState, saveState } from './state.js';
6
+ import { getExecutionContext } from '@dexto/core';
7
+ import { randomUUID } from 'crypto';
8
+ let client = null;
9
+ let enabled = false;
10
+ let state = null;
11
+ let sessionId = null;
12
+ let appVersion = null;
13
+ function baseProps() {
14
+ return {
15
+ app: 'dexto',
16
+ app_version: appVersion || 'unknown',
17
+ node_version: process.version,
18
+ os_platform: os.platform(),
19
+ os_release: os.release(),
20
+ os_arch: os.arch(),
21
+ execution_context: getExecutionContext(),
22
+ session_id: sessionId,
23
+ };
24
+ }
25
+ /**
26
+ * Initialize the analytics client for the CLI.
27
+ *
28
+ * - Respects DEXTO_ANALYTICS_DISABLED.
29
+ * - Creates/loads the anonymous distinctId and a per-process session_id.
30
+ * - Emits a dexto_session_start event for each process run.
31
+ */
32
+ export async function initAnalytics(opts) {
33
+ if (enabled || client)
34
+ return; // idempotent
35
+ if (isAnalyticsDisabled()) {
36
+ enabled = false;
37
+ return;
38
+ }
39
+ // Load or create state
40
+ state = await loadState();
41
+ sessionId = randomUUID();
42
+ appVersion = opts.appVersion;
43
+ const key = process.env.DEXTO_POSTHOG_KEY ?? DEFAULT_POSTHOG_KEY;
44
+ const host = process.env.DEXTO_POSTHOG_HOST ?? DEFAULT_POSTHOG_HOST;
45
+ if (typeof key !== 'string' || !/^phc_[A-Za-z0-9]+/.test(key) || !host) {
46
+ enabled = false;
47
+ return;
48
+ }
49
+ client = new PostHog(key, {
50
+ host,
51
+ flushAt: 1,
52
+ flushInterval: 0,
53
+ disableGeoip: false,
54
+ });
55
+ enabled = true;
56
+ process.on('exit', () => {
57
+ try {
58
+ client?.flush?.();
59
+ }
60
+ catch {
61
+ // Ignore flush errors: analytics should never block process exit.
62
+ }
63
+ });
64
+ capture('dexto_session_start', {});
65
+ }
66
+ /**
67
+ * Capture a single analytics event with optional properties.
68
+ * Automatically enriches events with base context (app/os/node/session).
69
+ */
70
+ export function capture(event, properties = {}) {
71
+ if (!enabled || !client || !state)
72
+ return;
73
+ try {
74
+ client.capture({
75
+ distinctId: state.distinctId,
76
+ event,
77
+ properties: { ...baseProps(), ...properties },
78
+ });
79
+ }
80
+ catch {
81
+ // swallow
82
+ }
83
+ }
84
+ /**
85
+ * Attempt a graceful shutdown of the analytics client, flushing queued events.
86
+ */
87
+ export async function shutdownAnalytics() {
88
+ if (client) {
89
+ try {
90
+ await client.shutdown();
91
+ }
92
+ catch {
93
+ // ignore
94
+ }
95
+ }
96
+ }
97
+ const timers = new Map();
98
+ /**
99
+ * Mark the start of a command for timing and emit a lightweight start event.
100
+ * Adds local counters as a coarse diagnostic aid.
101
+ */
102
+ export async function onCommandStart(name, extra = {}) {
103
+ if (!enabled)
104
+ return;
105
+ timers.set(name, Date.now());
106
+ if (state) {
107
+ await saveState(state);
108
+ }
109
+ const payload = {
110
+ name,
111
+ phase: 'start',
112
+ ...extra,
113
+ };
114
+ capture('dexto_cli_command', payload);
115
+ }
116
+ /**
117
+ * Mark the end of a command and emit a completion event with success/failure
118
+ * and measured duration. Accepts optional extra properties.
119
+ */
120
+ export async function onCommandEnd(name, success, extra = {}) {
121
+ if (!enabled)
122
+ return;
123
+ const start = timers.get(name) ?? Date.now();
124
+ const durationMs = Date.now() - start;
125
+ timers.delete(name);
126
+ const payload = {
127
+ name,
128
+ phase: 'end',
129
+ success,
130
+ durationMs,
131
+ ...extra,
132
+ };
133
+ capture('dexto_cli_command', payload);
134
+ if (state) {
135
+ state.commandRunCounts = state.commandRunCounts || {};
136
+ state.commandRunCounts[name] = (state.commandRunCounts[name] || 0) + 1;
137
+ await saveState(state);
138
+ }
139
+ }
140
+ /**
141
+ * Whether analytics are currently enabled for this process.
142
+ */
143
+ export function getEnabled() {
144
+ return enabled;
145
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shape of the persisted analytics state written to
3
+ * ~/.dexto/telemetry/state.json.
4
+ *
5
+ * - distinctId: Anonymous ID (UUID) for grouping events by machine.
6
+ * - createdAt: ISO timestamp when the state was first created.
7
+ * - commandRunCounts: Local counters per command for coarse diagnostics.
8
+ */
9
+ export interface AnalyticsState {
10
+ distinctId: string;
11
+ createdAt: string;
12
+ commandRunCounts?: Record<string, number>;
13
+ }
14
+ /**
15
+ * Load the persisted analytics state, creating a new file if missing.
16
+ * Returns a valid state object with defaults populated.
17
+ */
18
+ export declare function loadState(): Promise<AnalyticsState>;
19
+ /**
20
+ * Persist the analytics state to ~/.dexto/telemetry/state.json.
21
+ */
22
+ export declare function saveState(state: AnalyticsState): Promise<void>;
23
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/analytics/state.ts"],"names":[],"mappings":"AAcA;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAKD;;;GAGG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC,CAqBzD;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAGpE"}
@@ -0,0 +1,74 @@
1
+ // packages/cli/src/analytics/state.ts
2
+ import { promises as fs } from 'fs';
3
+ import * as path from 'path';
4
+ import os from 'os';
5
+ import { randomUUID, createHash } from 'crypto';
6
+ import { createRequire } from 'module';
7
+ const requireCJS = createRequire(import.meta.url);
8
+ // node-machine-id is CommonJS; import via createRequire to avoid ESM interop issues
9
+ const { machineIdSync } = requireCJS('node-machine-id');
10
+ import { getDextoGlobalPath } from '@dexto/core';
11
+ const STATE_DIR = getDextoGlobalPath('telemetry');
12
+ const STATE_FILE = path.join(STATE_DIR, 'state.json');
13
+ /**
14
+ * Load the persisted analytics state, creating a new file if missing.
15
+ * Returns a valid state object with defaults populated.
16
+ */
17
+ export async function loadState() {
18
+ try {
19
+ const content = await fs.readFile(STATE_FILE, 'utf8');
20
+ const parsed = JSON.parse(content);
21
+ // Validate minimal shape
22
+ if (!parsed.distinctId)
23
+ throw new Error('invalid state');
24
+ return {
25
+ distinctId: parsed.distinctId,
26
+ createdAt: parsed.createdAt || new Date().toISOString(),
27
+ commandRunCounts: parsed.commandRunCounts ?? {},
28
+ };
29
+ }
30
+ catch {
31
+ await fs.mkdir(STATE_DIR, { recursive: true });
32
+ const state = {
33
+ distinctId: computeDistinctId(),
34
+ createdAt: new Date().toISOString(),
35
+ commandRunCounts: {},
36
+ };
37
+ await saveState(state);
38
+ return state;
39
+ }
40
+ }
41
+ /**
42
+ * Persist the analytics state to ~/.dexto/telemetry/state.json.
43
+ */
44
+ export async function saveState(state) {
45
+ await fs.mkdir(STATE_DIR, { recursive: true });
46
+ await fs.writeFile(STATE_FILE, JSON.stringify(state, null, 2), 'utf8');
47
+ }
48
+ /**
49
+ * Compute a stable, privacy‑safe machine identifier so identity
50
+ * survives ~/.dexto deletion by default.
51
+ *
52
+ * Strategy:
53
+ * - Prefer node-machine-id (hashed), which abstracts platform differences.
54
+ * - Fallback to a salted/hashed hostname.
55
+ * - As a last resort, generate a random UUID.
56
+ */
57
+ function computeDistinctId() {
58
+ try {
59
+ // machineIdSync(true) returns a hashed, stable identifier
60
+ const id = machineIdSync(true);
61
+ if (typeof id === 'string' && id.length > 0)
62
+ return `DEXTO-${id}`;
63
+ }
64
+ catch {
65
+ // fall through to hostname hash
66
+ }
67
+ // Fallback: hash hostname to avoid exposing raw value
68
+ const hostname = os.hostname() || 'unknown-host';
69
+ const digest = createHash('sha256').update(hostname).digest('hex');
70
+ if (digest)
71
+ return `DEXTO-${digest.slice(0, 32)}`;
72
+ // Last resort
73
+ return `DEXTO-${randomUUID()}`;
74
+ }
@@ -0,0 +1,11 @@
1
+ export declare function withAnalytics<A extends unknown[], R = unknown>(commandName: string, handler: (...args: A) => Promise<R> | R, opts?: {
2
+ timeoutMs?: number;
3
+ }): (...args: A) => Promise<R>;
4
+ export declare class ExitSignal extends Error {
5
+ code: number;
6
+ reason?: string | undefined;
7
+ commandName?: string | undefined;
8
+ constructor(code?: number, reason?: string, commandName?: string);
9
+ }
10
+ export declare function safeExit(commandName: string, code?: number, reason?: string): never;
11
+ //# sourceMappingURL=wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrapper.d.ts","sourceRoot":"","sources":["../../src/analytics/wrapper.ts"],"names":[],"mappings":"AAkDA,wBAAgB,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,GAAG,OAAO,EAC1D,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EACvC,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9B,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CA+D5B;AAED,qBAAa,UAAW,SAAQ,KAAK;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;gBACrB,IAAI,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;CAOtE;AAED,wBAAgB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE,MAAU,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,CAEtF"}
@@ -0,0 +1,125 @@
1
+ // packages/cli/src/analytics/wrapper.ts
2
+ import { onCommandStart, onCommandEnd, capture } from './index.js';
3
+ import { COMMAND_TIMEOUT_MS } from './constants.js';
4
+ function sanitizeOptions(obj) {
5
+ const redactedKeys = /key|token|secret|password|api[_-]?key|authorization|auth/i;
6
+ const truncate = (s, max = 256) => (s.length > max ? s.slice(0, max) + '…' : s);
7
+ const out = {};
8
+ for (const [k, v] of Object.entries(obj)) {
9
+ if (typeof v === 'string') {
10
+ out[k] = redactedKeys.test(k) ? '[REDACTED]' : truncate(v);
11
+ }
12
+ else if (Array.isArray(v)) {
13
+ out[k] = { type: 'array', length: v.length };
14
+ }
15
+ else if (typeof v === 'number' || typeof v === 'boolean' || v === null) {
16
+ out[k] = v;
17
+ }
18
+ else if (typeof v === 'object' && v) {
19
+ out[k] = { type: 'object' };
20
+ }
21
+ else {
22
+ out[k] = String(v ?? 'unknown');
23
+ }
24
+ }
25
+ return out;
26
+ }
27
+ function buildArgsPayload(args) {
28
+ const meta = {
29
+ argTypes: args.map((a) => (Array.isArray(a) ? 'array' : typeof a)),
30
+ };
31
+ if (args.length > 0 && Array.isArray(args[0])) {
32
+ const list = args[0].map((x) => String(x));
33
+ const trimmed = list.map((s) => (s.length > 512 ? s.slice(0, 512) + '…' : s)).slice(0, 10);
34
+ meta.positionalRaw = trimmed;
35
+ meta.positionalCount = list.length;
36
+ }
37
+ const last = args[args.length - 1];
38
+ if (last && typeof last === 'object' && !Array.isArray(last)) {
39
+ meta.optionKeys = Object.keys(last);
40
+ meta.options = sanitizeOptions(last);
41
+ }
42
+ return meta;
43
+ }
44
+ export function withAnalytics(commandName, handler, opts) {
45
+ const timeoutMs = opts?.timeoutMs ?? COMMAND_TIMEOUT_MS;
46
+ return async (...args) => {
47
+ const argsMeta = buildArgsPayload(args);
48
+ await onCommandStart(commandName, { args: argsMeta });
49
+ const timeout = timeoutMs > 0
50
+ ? (() => {
51
+ const t = setTimeout(() => {
52
+ try {
53
+ const payload = {
54
+ name: commandName,
55
+ phase: 'timeout',
56
+ timeoutMs,
57
+ args: argsMeta,
58
+ };
59
+ capture('dexto_cli_command', payload);
60
+ }
61
+ catch {
62
+ // Timeout instrumentation is best-effort.
63
+ }
64
+ }, timeoutMs);
65
+ // Prevent timeout from keeping process alive
66
+ t.unref();
67
+ return t;
68
+ })()
69
+ : null;
70
+ try {
71
+ const result = await handler(...args);
72
+ const success = (typeof process.exitCode === 'number' ? process.exitCode : 0) === 0;
73
+ await onCommandEnd(commandName, success, { args: argsMeta });
74
+ return result;
75
+ }
76
+ catch (err) {
77
+ if (err instanceof ExitSignal) {
78
+ process.exitCode = err.code ?? 0;
79
+ try {
80
+ const endMeta = { args: argsMeta };
81
+ if (typeof err.reason === 'string') {
82
+ endMeta.reason = err.reason;
83
+ }
84
+ if (err.commandName) {
85
+ endMeta.command = err.commandName;
86
+ }
87
+ await onCommandEnd(commandName, err.code === 0, endMeta);
88
+ }
89
+ catch {
90
+ // Ignore analytics errors when propagating ExitSignal.
91
+ }
92
+ return undefined;
93
+ }
94
+ try {
95
+ await onCommandEnd(commandName, false, {
96
+ error: err instanceof Error ? err.message : String(err),
97
+ args: argsMeta,
98
+ });
99
+ }
100
+ catch {
101
+ // Ignore analytics errors when recording failures.
102
+ }
103
+ throw err;
104
+ }
105
+ finally {
106
+ if (timeout)
107
+ clearTimeout(timeout);
108
+ }
109
+ };
110
+ }
111
+ export class ExitSignal extends Error {
112
+ code;
113
+ reason;
114
+ commandName;
115
+ constructor(code = 0, reason, commandName) {
116
+ super('ExitSignal');
117
+ this.name = 'ExitSignal';
118
+ this.code = code;
119
+ this.reason = reason;
120
+ this.commandName = commandName;
121
+ }
122
+ }
123
+ export function safeExit(commandName, code = 0, reason) {
124
+ throw new ExitSignal(code, reason, commandName);
125
+ }
package/dist/cli/cli.d.ts CHANGED
@@ -1,4 +1,9 @@
1
1
  import { DextoAgent } from '@dexto/core';
2
+ /**
3
+ * Find and load the most recent session based on lastActivity.
4
+ * This provides better UX than always loading the "default" session.
5
+ */
6
+ export declare function loadMostRecentSession(agent: DextoAgent): Promise<void>;
2
7
  /**
3
8
  * Run the AI CLI with the given LLM service
4
9
  * @param agent Dexto agent instance
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA6HzC;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,UAAU,iBAkHjD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCvF"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AASzC;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAkC5E;AAgFD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,UAAU,iBAoHjD;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CvF"}
package/dist/cli/cli.js CHANGED
@@ -7,11 +7,13 @@ import { executeCommand } from './commands/interactive-commands/commands.js';
7
7
  import { getDextoPath } from '@dexto/core';
8
8
  import { registerGracefulShutdown } from '../utils/graceful-shutdown.js';
9
9
  import { DextoRuntimeError, DextoValidationError, ErrorScope, LLMErrorCode } from '@dexto/core';
10
+ import { capture } from '../analytics/index.js';
11
+ import { safeExit } from '../analytics/wrapper.js';
10
12
  /**
11
13
  * Find and load the most recent session based on lastActivity.
12
14
  * This provides better UX than always loading the "default" session.
13
15
  */
14
- async function loadMostRecentSession(agent) {
16
+ export async function loadMostRecentSession(agent) {
15
17
  try {
16
18
  const sessionIds = await agent.listSessions();
17
19
  if (sessionIds.length === 0) {
@@ -46,7 +48,7 @@ async function loadMostRecentSession(agent) {
46
48
  * @param agent The DextoAgent instance providing access to all required services
47
49
  */
48
50
  async function _initCli(agent) {
49
- await loadMostRecentSession(agent);
51
+ // Note: Session loading is now handled by the main CLI logic, not here
50
52
  registerGracefulShutdown(agent);
51
53
  // Gather startup information
52
54
  const llmConfig = agent.getCurrentLLMConfig();
@@ -147,6 +149,8 @@ export async function startAiCli(agent) {
147
149
  }
148
150
  else {
149
151
  // Handle regular prompt - pass to AI
152
+ const llm = agent.getCurrentLLMConfig();
153
+ capture('dexto_prompt', { mode: 'cli', provider: llm.provider, model: llm.model });
150
154
  return false;
151
155
  }
152
156
  }
@@ -211,7 +215,7 @@ export async function startAiCli(agent) {
211
215
  catch (error) {
212
216
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
213
217
  logger.error(`Error during CLI initialization: ${errorMessage}`);
214
- process.exit(1); // Exit with error code if CLI setup fails
218
+ safeExit('main', 1); // Exit with error code if CLI setup fails
215
219
  }
216
220
  }
217
221
  /**
@@ -237,6 +241,8 @@ export async function startHeadlessCli(agent, prompt) {
237
241
  // Execute the task as a regular AI prompt
238
242
  // uncomment if we need to reset conversation for headless mode
239
243
  // await agent.resetConversation();
244
+ const llm = agent.getCurrentLLMConfig();
245
+ capture('dexto_prompt', { mode: 'headless', provider: llm.provider, model: llm.model });
240
246
  await agent.run(prompt);
241
247
  }
242
248
  }
@@ -256,6 +262,6 @@ export async function startHeadlessCli(agent, prompt) {
256
262
  else {
257
263
  logger.error(`Error in processing input: ${error instanceof Error ? error.message : String(error)}`);
258
264
  }
259
- process.exit(1); // Exit with error code if headless execution fails
265
+ safeExit('main', 1); // Exit with error code if headless execution fails
260
266
  }
261
267
  }
@@ -2,7 +2,7 @@
2
2
  * Session Formatting Utilities
3
3
  *
4
4
  * This module contains formatting functions for session-related CLI output.
5
- * Extracted from commands.ts as part of CLI refactoring to improve code organization.
5
+ * Shared between interactive and non-interactive session commands.
6
6
  */
7
7
  import type { SessionMetadata, InternalMessage } from '@dexto/core';
8
8
  /**
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/helpers/formatters.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEpE;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,eAAe,EAC1B,SAAS,GAAE,OAAe,GAC3B,MAAM,CAqBR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CA8DpF"}
@@ -2,7 +2,7 @@
2
2
  * Session Formatting Utilities
3
3
  *
4
4
  * This module contains formatting functions for session-related CLI output.
5
- * Extracted from commands.ts as part of CLI refactoring to improve code organization.
5
+ * Shared between interactive and non-interactive session commands.
6
6
  */
7
7
  import chalk from 'chalk';
8
8
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;EAOb,CAAC;AAEd,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAuC1E,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACxC,OAAO,CAAC,IAAI,CAAC,CAoEf"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/install.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;EAOb,CAAC;AAEd,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAwC1E,wBAAsB,oBAAoB,CACtC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACxC,OAAO,CAAC,IAAI,CAAC,CAsHf"}
@@ -3,6 +3,7 @@ import { existsSync } from 'fs';
3
3
  import path from 'path';
4
4
  import { z } from 'zod';
5
5
  import { getAgentRegistry, getDextoGlobalPath } from '@dexto/core';
6
+ import { capture } from '../../analytics/index.js';
6
7
  // Zod schema for install command validation
7
8
  const InstallCommandSchema = z
8
9
  .object({
@@ -37,6 +38,7 @@ function validateInstallCommand(agents, options) {
37
38
  }
38
39
  return validated;
39
40
  }
41
+ // TODO: move registry code into CLI and move dexto_install_agent metric into registry
40
42
  export async function handleInstallCommand(agents, options) {
41
43
  // Validate command with Zod
42
44
  const validated = validateInstallCommand(agents, options);
@@ -54,6 +56,9 @@ export async function handleInstallCommand(agents, options) {
54
56
  let successCount = 0;
55
57
  let errorCount = 0;
56
58
  const errors = [];
59
+ const installed = [];
60
+ const skipped = [];
61
+ const failed = [];
57
62
  // Install each agent
58
63
  for (const agentName of agentsToInstall) {
59
64
  try {
@@ -63,21 +68,70 @@ export async function handleInstallCommand(agents, options) {
63
68
  const installedPath = path.join(globalAgentsDir, agentName);
64
69
  if (existsSync(installedPath) && !validated.force) {
65
70
  console.log(`⏭️ ${agentName} already installed (use --force to reinstall)`);
66
- successCount++;
71
+ skipped.push(agentName);
72
+ // Per-agent analytics for skipped install
73
+ capture('dexto_install_agent', {
74
+ agent: agentName,
75
+ status: 'skipped',
76
+ reason: 'already_installed',
77
+ force: validated.force,
78
+ injectPreferences: validated.injectPreferences,
79
+ });
67
80
  continue;
68
81
  }
69
82
  await registry.installAgent(agentName, validated.injectPreferences);
70
83
  successCount++;
71
84
  console.log(`✅ ${agentName} installed successfully`);
85
+ installed.push(agentName);
86
+ // Per-agent analytics for successful install
87
+ try {
88
+ capture('dexto_install_agent', {
89
+ agent: agentName,
90
+ status: 'installed',
91
+ force: validated.force,
92
+ injectPreferences: validated.injectPreferences,
93
+ });
94
+ }
95
+ catch {
96
+ // Analytics failures should not block CLI execution.
97
+ }
72
98
  }
73
99
  catch (error) {
74
100
  errorCount++;
75
101
  const errorMsg = `Failed to install ${agentName}: ${error instanceof Error ? error.message : String(error)}`;
76
102
  errors.push(errorMsg);
103
+ failed.push(agentName);
77
104
  console.error(`❌ ${errorMsg}`);
105
+ // Per-agent analytics for failed install
106
+ try {
107
+ capture('dexto_install_agent', {
108
+ agent: agentName,
109
+ status: 'failed',
110
+ error_message: error instanceof Error ? error.message : String(error),
111
+ force: validated.force,
112
+ injectPreferences: validated.injectPreferences,
113
+ });
114
+ }
115
+ catch {
116
+ // Analytics failures should not block CLI execution.
117
+ }
78
118
  }
79
119
  }
80
- // For single agent operations, throw error if it failed
120
+ // Emit analytics for both single- and multi-agent cases
121
+ try {
122
+ capture('dexto_install', {
123
+ requested: agentsToInstall,
124
+ installed,
125
+ skipped,
126
+ failed,
127
+ successCount,
128
+ errorCount,
129
+ });
130
+ }
131
+ catch {
132
+ // Analytics failures should not block CLI execution.
133
+ }
134
+ // For single agent operations, throw error if it failed (after emitting analytics)
81
135
  if (agentsToInstall.length === 1) {
82
136
  if (errorCount > 0) {
83
137
  throw new Error(errors[0]);
@@ -12,6 +12,6 @@
12
12
  * - Formatter utilities from helpers (re-exported for convenience)
13
13
  */
14
14
  export { sessionCommand, historyCommand, searchCommand } from './session-commands.js';
15
- export { formatSessionInfo, formatHistoryMessage } from './helpers/formatters.js';
15
+ export { formatSessionInfo, formatHistoryMessage } from '../../helpers/formatters.js';
16
16
  export declare const sessionCommands: import("../command-parser.js").CommandDefinition[];
17
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAIlF,eAAO,MAAM,eAAe,oDAAkD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/session/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAItF,eAAO,MAAM,eAAe,oDAAkD,CAAC"}
@@ -12,7 +12,7 @@
12
12
  * - Formatter utilities from helpers (re-exported for convenience)
13
13
  */
14
14
  export { sessionCommand, historyCommand, searchCommand } from './session-commands.js';
15
- export { formatSessionInfo, formatHistoryMessage } from './helpers/formatters.js';
15
+ export { formatSessionInfo, formatHistoryMessage } from '../../helpers/formatters.js';
16
16
  // Export all session commands as a convenient array
17
17
  import { sessionCommand, historyCommand, searchCommand } from './session-commands.js';
18
18
  export const sessionCommands = [sessionCommand, historyCommand, searchCommand];
@@ -1 +1 @@
1
- {"version":3,"file":"session-commands.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/session/session-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAsCzD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBAgQ5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBAwB5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,iBA+H3B,CAAC"}
1
+ {"version":3,"file":"session-commands.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/interactive-commands/session/session-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAwCzD;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBA0L5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,iBAwB5B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,iBA+H3B,CAAC"}