@ghl-ai/aw 0.1.37-beta.7 → 0.1.37-beta.9

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.
package/cli.mjs CHANGED
@@ -4,7 +4,7 @@ import { readFileSync } from 'node:fs';
4
4
  import { join, dirname } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import * as fmt from './fmt.mjs';
7
- import { chalk } from './fmt.mjs';
7
+ import { chalk, CancelError } from './fmt.mjs';
8
8
  import { checkForUpdate, notifyUpdate } from './update.mjs';
9
9
  import { startSpan } from './telemetry.mjs';
10
10
 
@@ -154,7 +154,7 @@ export async function run(argv) {
154
154
  }
155
155
 
156
156
  if (command && COMMANDS[command]) {
157
- const span = startSpan(command, args);
157
+ const span = await startSpan(command, args);
158
158
  span.notice();
159
159
  args._updateCheck = updateCheck;
160
160
  try {
@@ -162,6 +162,10 @@ export async function run(argv) {
162
162
  await handler(args);
163
163
  await span.end({ status: 'completed' });
164
164
  } catch (err) {
165
+ if (err instanceof CancelError) {
166
+ await span.end({ status: 'cancelled', error_type: 'CancelError' });
167
+ process.exit(err.exitCode ?? 1);
168
+ }
165
169
  await span.end({ status: 'failed', error_type: err.constructor.name });
166
170
  throw err;
167
171
  }
@@ -174,5 +178,5 @@ export async function run(argv) {
174
178
  process.exit(0);
175
179
  }
176
180
 
177
- fmt.cancel(`Unknown command: ${command}`);
181
+ fmt.cancelAndExit(`Unknown command: ${command}`);
178
182
  }
package/commands/nuke.mjs CHANGED
@@ -204,8 +204,8 @@ function removeIdeTasks() {
204
204
 
205
205
  export async function nukeCommand(args) {
206
206
  // Catch unhandled errors and surface them instead of letting clack show generic "Something went wrong"
207
- process.on('uncaughtException', (e) => { fmt.cancel(`Unexpected error: ${e.message}`); });
208
- process.on('unhandledRejection', (e) => { fmt.cancel(`Unexpected error: ${e?.message ?? e}`); });
207
+ process.on('uncaughtException', (e) => { fmt.cancelAndExit(`Unexpected error: ${e.message}`); });
208
+ process.on('unhandledRejection', (e) => { fmt.cancelAndExit(`Unexpected error: ${e?.message ?? e}`); });
209
209
 
210
210
  fmt.intro('aw nuke');
211
211
 
package/commands/pull.mjs CHANGED
@@ -25,7 +25,7 @@ export async function pullCommand(args) {
25
25
  const silent = args['--silent'] === true || args._silent === true;
26
26
 
27
27
  const log = {
28
- cancel: silent ? () => { process.exit(0); } : fmt.cancel,
28
+ cancel: silent ? (msg) => { throw new fmt.CancelError(msg || 'silent cancel', { exitCode: 0 }); } : fmt.cancel,
29
29
  logInfo: silent ? () => {} : fmt.logInfo,
30
30
  logSuccess: silent ? () => {} : fmt.logSuccess,
31
31
  logStep: silent ? () => {} : fmt.logStep,
package/fmt.mjs CHANGED
@@ -72,7 +72,21 @@ export const isCancel = p.isCancel;
72
72
 
73
73
  export const spinner = () => p.spinner();
74
74
 
75
+ export class CancelError extends Error {
76
+ constructor(message, { exitCode = 1 } = {}) {
77
+ super(message);
78
+ this.name = 'CancelError';
79
+ this.exitCode = exitCode;
80
+ }
81
+ }
82
+
75
83
  export function cancel(msg) {
84
+ p.cancel(msg);
85
+ throw new CancelError(msg);
86
+ }
87
+
88
+ /** Hard exit — for use in process exception handlers where throwing is unsafe */
89
+ export function cancelAndExit(msg) {
76
90
  p.cancel(msg);
77
91
  process.exit(1);
78
92
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.37-beta.7",
3
+ "version": "0.1.37-beta.9",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": "bin.js",
package/telemetry.mjs CHANGED
@@ -142,7 +142,7 @@ export async function send(payload) {
142
142
 
143
143
  // ── Span API ────────────────────────────────────────────────────────
144
144
 
145
- export function startSpan(command, args) {
145
+ export async function startSpan(command, args) {
146
146
  const config = loadConfig();
147
147
  const disabled = isDisabled(config);
148
148
  const runId = randomUUID();
@@ -164,9 +164,9 @@ export function startSpan(command, args) {
164
164
 
165
165
  const env = disabled ? null : collectEnv(config);
166
166
 
167
- // Fire command_started (non-blocking)
167
+ // Await command_started so it always lands before the command runs
168
168
  if (!disabled) {
169
- send({
169
+ await send({
170
170
  event: 'command_started',
171
171
  run_id: runId,
172
172
  timestamp: new Date().toISOString(),