@ghl-ai/aw 0.1.72 → 0.1.73-beta.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.
- package/c4/templates/scripts/aw-c4-bootstrap.sh +14 -13
- package/commands/c4.mjs +9 -13
- package/constants.mjs +1 -1
- package/ecc.mjs +1 -1
- package/git.mjs +2 -1
- package/hooks/aw-usage/hooks/aw-usage-commit-created.js +1 -0
- package/hooks/aw-usage/hooks/aw-usage-telemetry-send.js +1 -1
- package/hooks/aw-usage/lib/aw-usage-telemetry.js +5 -0
- package/hooks.mjs +2 -2
- package/package.json +1 -1
- package/startup.mjs +26 -5
|
@@ -129,29 +129,30 @@ aw_c4_exit=$?
|
|
|
129
129
|
|
|
130
130
|
# Defense-in-depth: `aw c4` delegates registry sync to `aw init --silent`,
|
|
131
131
|
# which can fail to fetch in silent mode without surfacing an error. When
|
|
132
|
-
# that happens, the registry (~/.aw/.aw_registry) may be empty or incomplete
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
132
|
+
# that happens, the registry (~/.aw/.aw_registry) may be empty or incomplete
|
|
133
|
+
# and only the 10 hardcoded stage commands get linked. Re-run `aw pull`
|
|
134
|
+
# post-c4 if the command count looks low.
|
|
135
|
+
verify_registry_commands() {
|
|
136
|
+
local aw_cmd_dir="$HOME/.aw/.aw_registry"
|
|
137
|
+
if [ ! -d "$aw_cmd_dir" ]; then
|
|
137
138
|
echo "[aw-c4-bootstrap] registry dir missing — running aw init + pull"
|
|
138
139
|
aw init --no-integrations --silent 2>&1 | tail -3 || true
|
|
139
140
|
aw pull 2>&1 | tail -5 || true
|
|
140
141
|
return
|
|
141
142
|
fi
|
|
142
143
|
|
|
143
|
-
local
|
|
144
|
-
|
|
145
|
-
if [ "${
|
|
146
|
-
echo "[aw-c4-bootstrap] only ${
|
|
144
|
+
local cmd_count
|
|
145
|
+
cmd_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' ! -path '*/evals/*' 2>/dev/null | wc -l | tr -d ' ')
|
|
146
|
+
if [ "${cmd_count:-0}" -lt 20 ]; then
|
|
147
|
+
echo "[aw-c4-bootstrap] only ${cmd_count} registry commands found — running aw pull"
|
|
147
148
|
aw pull 2>&1 | tail -5 || true
|
|
148
149
|
local new_count
|
|
149
|
-
new_count=$(find "$
|
|
150
|
-
echo "[aw-c4-bootstrap] registry
|
|
150
|
+
new_count=$(find "$aw_cmd_dir" -name '*.md' -path '*/commands/*' ! -path '*/evals/*' 2>/dev/null | wc -l | tr -d ' ')
|
|
151
|
+
echo "[aw-c4-bootstrap] registry commands: ${cmd_count} → ${new_count}"
|
|
151
152
|
else
|
|
152
|
-
echo "[aw-c4-bootstrap] registry: ${
|
|
153
|
+
echo "[aw-c4-bootstrap] registry: ${cmd_count} commands OK"
|
|
153
154
|
fi
|
|
154
155
|
}
|
|
155
|
-
|
|
156
|
+
verify_registry_commands || true
|
|
156
157
|
|
|
157
158
|
exit "$aw_c4_exit"
|
package/commands/c4.mjs
CHANGED
|
@@ -110,11 +110,6 @@ function safeListNamespaceDirs(dir) {
|
|
|
110
110
|
} catch { return []; }
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
function hasRegistrySkillSurface(registryDir, existsSync = fsExistsSync) {
|
|
114
|
-
if (existsSync(join(registryDir, 'platform', 'core', 'skills'))) return true;
|
|
115
|
-
return safeListNamespaceDirs(registryDir).length > 0;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
113
|
async function safeAsync(label, fn, writer) {
|
|
119
114
|
try {
|
|
120
115
|
return { ok: true, value: await fn() };
|
|
@@ -410,17 +405,18 @@ export async function c4Command(rawArgs, overrides = {}) {
|
|
|
410
405
|
return exit(1);
|
|
411
406
|
}
|
|
412
407
|
|
|
413
|
-
// Step 9a — verify registry has
|
|
408
|
+
// Step 9a — verify registry has namespace directories. `aw init --silent`
|
|
414
409
|
// can exit 0 but fail to fetch (fetchAndMerge swallows the error in silent
|
|
415
410
|
// mode). Metadata-only artifacts (AW-PROTOCOL.md) pass a simple non-empty
|
|
416
|
-
// check, so we specifically look for
|
|
417
|
-
// the registry content was actually pulled.
|
|
411
|
+
// check, so we specifically look for directories (namespaces like
|
|
412
|
+
// "platform") to confirm the registry content was actually pulled.
|
|
418
413
|
{
|
|
419
|
-
|
|
420
|
-
|
|
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');
|
|
421
417
|
const pullRes = spawnSync('aw', ['pull'], { stdio: 'pipe' });
|
|
422
|
-
if (pullRes?.status !== 0 ||
|
|
423
|
-
writer.stderr('[aw-c4] FATAL: registry
|
|
418
|
+
if (pullRes?.status !== 0 || safeListNamespaceDirs(awRegistry).length === 0) {
|
|
419
|
+
writer.stderr('[aw-c4] FATAL: registry commands were not fetched\n');
|
|
424
420
|
return exit(1);
|
|
425
421
|
}
|
|
426
422
|
}
|
|
@@ -443,7 +439,7 @@ export async function c4Command(rawArgs, overrides = {}) {
|
|
|
443
439
|
writer.stdout('[aw-c4] MCP disabled; skipping registerGhlAiMcp\n');
|
|
444
440
|
}
|
|
445
441
|
|
|
446
|
-
// Step 12 —
|
|
442
|
+
// Step 12 — slash command surface (10 stage commands from ECC).
|
|
447
443
|
safe('ensureCommandSurface', () => c4.ensureCommandSurface({ harness, home, eccHome }), writer);
|
|
448
444
|
|
|
449
445
|
// Step 12a — full registry command surface.
|
package/constants.mjs
CHANGED
|
@@ -105,7 +105,7 @@ export const RULES_SOURCE_DIR = '.aw_rules';
|
|
|
105
105
|
/** Runtime location exposed to harnesses and generated instructions */
|
|
106
106
|
export const RULES_RUNTIME_DIR = '.aw/.aw_rules';
|
|
107
107
|
/** Telemetry endpoint — override with AW_TELEMETRY_URL env var */
|
|
108
|
-
export const TELEMETRY_URL = process.env.AW_TELEMETRY_URL || 'https://services.leadconnectorhq.com/agentic-workspace/api/telemetry/events';
|
|
108
|
+
export const TELEMETRY_URL = process.env.AW_TELEMETRY_URL || 'https://staging.services.leadconnectorhq.com/agentic-workspace/api/telemetry/events';
|
|
109
109
|
|
|
110
110
|
/** AW bot identity for Co-Authored-By trailers */
|
|
111
111
|
export const AW_BOT_NAME = 'AW';
|
package/ecc.mjs
CHANGED
|
@@ -12,7 +12,7 @@ import { applyStoredStartupPreferences } from "./startup.mjs";
|
|
|
12
12
|
|
|
13
13
|
const AW_ECC_REPO_SSH = "git@github.com:shreyansh-ghl/aw-ecc.git";
|
|
14
14
|
const AW_ECC_REPO_HTTPS = "https://github.com/shreyansh-ghl/aw-ecc.git";
|
|
15
|
-
export const AW_ECC_TAG = "v1.4.67
|
|
15
|
+
export const AW_ECC_TAG = "v1.4.67";
|
|
16
16
|
const REQUIRED_ECC_FILES = [
|
|
17
17
|
"package.json",
|
|
18
18
|
"scripts/install-apply.js",
|
package/git.mjs
CHANGED
|
@@ -390,7 +390,8 @@ export async function fetchAndMerge(awHome, { silent = true } = {}) {
|
|
|
390
390
|
// drops bare-name patterns (e.g. "content", "CODEOWNERS") when HEAD advances.
|
|
391
391
|
//
|
|
392
392
|
// --autostash: AW writes into the registry working tree from external
|
|
393
|
-
// sources (
|
|
393
|
+
// sources (ensureAwRuntimeHook copies ~/.aw-ecc/.../session-start.sh into a
|
|
394
|
+
// tracked path; transformCursorAwRefs rewrites /aw: → /aw- through Cursor
|
|
394
395
|
// skill directory symlinks that resolve into .aw_registry/). When those
|
|
395
396
|
// versions drift, the working tree is dirty at rebase time and rebase
|
|
396
397
|
// refuses to run, silently aborting the entire pull. Autostash stashes the
|
|
@@ -18,6 +18,7 @@ function buildCommitCreatedEvent({ commitHash = 'unknown', branch = 'unknown', c
|
|
|
18
18
|
// project_hash so the dashboard can correlate commits back to /aw:* sessions.
|
|
19
19
|
const event = buildEvent({ cwd }, 'commit_created', {
|
|
20
20
|
commit_hash: commitHash,
|
|
21
|
+
commit_sha: commitHash,
|
|
21
22
|
branch,
|
|
22
23
|
});
|
|
23
24
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const https = require('https');
|
|
13
13
|
const http = require('http');
|
|
14
14
|
|
|
15
|
-
const DEFAULT_URL = 'https://services.leadconnectorhq.com/agentic-workspace/api/telemetry/usage-events';
|
|
15
|
+
const DEFAULT_URL = 'https://staging.services.leadconnectorhq.com/agentic-workspace/api/telemetry/usage-events';
|
|
16
16
|
const TIMEOUT_MS = 10_000;
|
|
17
17
|
|
|
18
18
|
function post(url, body) {
|
|
@@ -119,6 +119,11 @@ function getAwCliVersionDetails() {
|
|
|
119
119
|
const candidates = [
|
|
120
120
|
path.join(AW_HOME, 'node_modules', '@ghl-ai', 'aw', 'package.json'),
|
|
121
121
|
];
|
|
122
|
+
// Derive global npm prefix from the running node binary (no shell needed)
|
|
123
|
+
try {
|
|
124
|
+
const nodeDir = path.dirname(process.execPath);
|
|
125
|
+
candidates.push(path.join(nodeDir, '..', 'lib', 'node_modules', '@ghl-ai', 'aw', 'package.json'));
|
|
126
|
+
} catch { /* ignore */ }
|
|
122
127
|
try {
|
|
123
128
|
const globalPrefix = execSync('npm prefix -g', { encoding: 'utf8', timeout: 3000 }).trim();
|
|
124
129
|
candidates.push(path.join(globalPrefix, 'lib', 'node_modules', '@ghl-ai', 'aw', 'package.json'));
|
package/hooks.mjs
CHANGED
|
@@ -102,7 +102,7 @@ if git log -1 --format='%b' HEAD 2>/dev/null | grep -qF "Co-Authored-By: AW"; th
|
|
|
102
102
|
TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-commit-created.js"
|
|
103
103
|
fi
|
|
104
104
|
if command -v node >/dev/null 2>&1 && [ -f "$TELEMETRY_HOOK" ]; then
|
|
105
|
-
COMMIT_HASH="$(git rev-parse
|
|
105
|
+
COMMIT_HASH="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
|
106
106
|
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
|
|
107
107
|
node "$TELEMETRY_HOOK" "$COMMIT_HASH" "$BRANCH" "$(pwd)" >/dev/null 2>&1
|
|
108
108
|
fi
|
|
@@ -286,7 +286,7 @@ if git log -1 --format='%b' HEAD 2>/dev/null | grep -qF "Co-Authored-By: AW"; th
|
|
|
286
286
|
TELEMETRY_HOOK="$HOME/.aw-ecc/scripts/hooks/aw-usage-commit-created.js"
|
|
287
287
|
fi
|
|
288
288
|
if command -v node >/dev/null 2>&1 && [ -f "$TELEMETRY_HOOK" ]; then
|
|
289
|
-
COMMIT_HASH="$(git rev-parse
|
|
289
|
+
COMMIT_HASH="$(git rev-parse HEAD 2>/dev/null || echo unknown)"
|
|
290
290
|
BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
|
|
291
291
|
node "$TELEMETRY_HOOK" "$COMMIT_HASH" "$BRANCH" "$(pwd)" >/dev/null 2>&1
|
|
292
292
|
fi
|
package/package.json
CHANGED
package/startup.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { randomBytes } from 'node:crypto';
|
|
@@ -83,6 +83,10 @@ function resolveRegistryRoot(homeDir = homedir()) {
|
|
|
83
83
|
].find(existsSync) || null;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
function awRuntimeHookSourcePath(homeDir = homedir()) {
|
|
87
|
+
return join(homeDir, '.aw-ecc', 'skills', 'using-aw-skills', 'hooks', 'session-start.sh');
|
|
88
|
+
}
|
|
89
|
+
|
|
86
90
|
function readJson(filePath, fallback = {}) {
|
|
87
91
|
if (!existsSync(filePath)) return fallback;
|
|
88
92
|
try {
|
|
@@ -389,10 +393,27 @@ function hasCodexSessionStartScript(homeDir = homedir()) {
|
|
|
389
393
|
}
|
|
390
394
|
|
|
391
395
|
export function ensureAwRuntimeHook(homeDir = homedir()) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
+
const sourcePath = awRuntimeHookSourcePath(homeDir);
|
|
397
|
+
const registryRoot = resolveRegistryRoot(homeDir);
|
|
398
|
+
if (!existsSync(sourcePath) || !registryRoot) return [];
|
|
399
|
+
|
|
400
|
+
const destinationPath = join(
|
|
401
|
+
registryRoot,
|
|
402
|
+
'platform',
|
|
403
|
+
'core',
|
|
404
|
+
'skills',
|
|
405
|
+
'using-aw-skills',
|
|
406
|
+
'hooks',
|
|
407
|
+
'session-start.sh',
|
|
408
|
+
);
|
|
409
|
+
const sourceContent = readFileSync(sourcePath, 'utf8');
|
|
410
|
+
const existingContent = existsSync(destinationPath) ? readFileSync(destinationPath, 'utf8') : null;
|
|
411
|
+
if (existingContent === sourceContent) return [];
|
|
412
|
+
|
|
413
|
+
mkdirSync(dirname(destinationPath), { recursive: true });
|
|
414
|
+
writeFileSync(destinationPath, sourceContent);
|
|
415
|
+
try { chmodSync(destinationPath, 0o755); } catch { /* best effort */ }
|
|
416
|
+
return [destinationPath];
|
|
396
417
|
}
|
|
397
418
|
|
|
398
419
|
function hasCodexHooksEnabled(homeDir = homedir()) {
|