@ghl-ai/aw 0.1.62-beta.0 → 0.1.62-beta.2

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.
@@ -318,13 +318,15 @@ function isDir(p) {
318
318
  * Supports nested domain dirs (e.g. platform/review/commands/).
319
319
  */
320
320
  function findCommandDirs(nsDir, segments = []) {
321
+ if (segments.includes('evals')) return [];
322
+
321
323
  const results = [];
322
324
  const commandsDir = join(nsDir, 'commands');
323
325
  if (existsSync(commandsDir) && isDir(commandsDir)) {
324
326
  results.push({ dir: commandsDir, segments });
325
327
  }
326
328
  for (const entry of safeReaddir(nsDir)) {
327
- if (entry === 'commands' || entry.startsWith('.')) continue;
329
+ if (entry === 'commands' || entry === 'evals' || entry.startsWith('.')) continue;
328
330
  const sub = join(nsDir, entry);
329
331
  if (isDir(sub)) {
330
332
  results.push(...findCommandDirs(sub, [...segments, entry]));
@@ -111,6 +111,18 @@ AW_PACKAGE="${AW_PACKAGE:-@ghl-ai/aw@latest}"
111
111
  echo "[aw-c4-bootstrap] installing ${AW_PACKAGE}"
112
112
  npm install -g "${AW_PACKAGE}"
113
113
 
114
+ # --dry-run and --diagnose are read-only modes; skip post-c4 verification
115
+ # so we don't mutate $HOME or contact the registry unexpectedly.
116
+ is_readonly_mode=false
117
+ for arg in "$@"; do
118
+ case "$arg" in --dry-run|--diagnose) is_readonly_mode=true ;; esac
119
+ done
120
+
121
+ if "$is_readonly_mode"; then
122
+ echo "[aw-c4-bootstrap] running: aw c4 $*"
123
+ exec aw c4 "$@"
124
+ fi
125
+
114
126
  echo "[aw-c4-bootstrap] running: aw c4 $*"
115
127
  aw c4 "$@"
116
128
  aw_c4_exit=$?
@@ -130,12 +142,12 @@ verify_registry_commands() {
130
142
  fi
131
143
 
132
144
  local cmd_count
133
- cmd_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' 2>/dev/null | wc -l | tr -d ' ')
145
+ cmd_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' ! -path '*/evals/*' 2>/dev/null | wc -l | tr -d ' ')
134
146
  if [ "${cmd_count:-0}" -lt 20 ]; then
135
147
  echo "[aw-c4-bootstrap] only ${cmd_count} registry commands found — running aw pull"
136
148
  aw pull 2>&1 | tail -5 || true
137
149
  local new_count
138
- new_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' 2>/dev/null | wc -l | tr -d ' ')
150
+ new_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' ! -path '*/evals/*' 2>/dev/null | wc -l | tr -d ' ')
139
151
  echo "[aw-c4-bootstrap] registry commands: ${cmd_count} → ${new_count}"
140
152
  else
141
153
  echo "[aw-c4-bootstrap] registry: ${cmd_count} commands OK"
package/commands/c4.mjs CHANGED
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  import { spawnSync as nodeSpawnSync } from 'node:child_process';
27
- import { existsSync as fsExistsSync, readdirSync } from 'node:fs';
27
+ import { existsSync as fsExistsSync, readdirSync, statSync } from 'node:fs';
28
28
  import { join } from 'node:path';
29
29
  import * as c4Default from '../c4/index.mjs';
30
30
  import { isMcpEnabled } from '../mcp.mjs';
@@ -101,6 +101,15 @@ function safeReaddirSync(dir) {
101
101
  try { return readdirSync(dir); } catch { return []; }
102
102
  }
103
103
 
104
+ function safeListNamespaceDirs(dir) {
105
+ try {
106
+ return readdirSync(dir).filter((entry) => {
107
+ if (entry.startsWith('.')) return false;
108
+ try { return statSync(join(dir, entry)).isDirectory(); } catch { return false; }
109
+ });
110
+ } catch { return []; }
111
+ }
112
+
104
113
  async function safeAsync(label, fn, writer) {
105
114
  try {
106
115
  return { ok: true, value: await fn() };
@@ -396,20 +405,19 @@ export async function c4Command(rawArgs, overrides = {}) {
396
405
  return exit(1);
397
406
  }
398
407
 
399
- // Step 9a — verify registry has content. `aw init --silent` can succeed
400
- // (exit 0) but fail to fetch from remote (fetchAndMerge swallows the error
401
- // in silent mode). When the registry dir exists but contains no namespace
402
- // directories, the fetch likely failed. Retry with `aw pull` which runs
403
- // a targeted git pull on the existing clone.
408
+ // Step 9a — verify registry has namespace directories. `aw init --silent`
409
+ // can exit 0 but fail to fetch (fetchAndMerge swallows the error in silent
410
+ // mode). Metadata-only artifacts (AW-PROTOCOL.md) pass a simple non-empty
411
+ // check, so we specifically look for directories (namespaces like
412
+ // "platform") to confirm the registry content was actually pulled.
404
413
  {
405
- const registryEntries = safeReaddirSync(awRegistry).filter(
406
- (e) => !e.startsWith('.'),
407
- );
408
- if (registryEntries.length === 0) {
409
- writer.stderr('[aw-c4] registry empty after init — retrying with aw pull\n');
414
+ const registryNamespaces = safeListNamespaceDirs(awRegistry);
415
+ if (registryNamespaces.length === 0) {
416
+ writer.stderr('[aw-c4] registry has no namespace directories after init — retrying with aw pull\n');
410
417
  const pullRes = spawnSync('aw', ['pull'], { stdio: 'pipe' });
411
- if (pullRes && pullRes.status !== 0) {
412
- writer.stderr('[aw-c4] aw pull also failed; commands may be incomplete\n');
418
+ if (pullRes?.status !== 0 || safeListNamespaceDirs(awRegistry).length === 0) {
419
+ writer.stderr('[aw-c4] FATAL: registry commands were not fetched\n');
420
+ return exit(1);
413
421
  }
414
422
  }
415
423
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.62-beta.0",
3
+ "version": "0.1.62-beta.2",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
6
  "bin": {