@ghl-ai/aw 0.1.37-beta.53 → 0.1.37-beta.55
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 +30 -9
- package/commands/init.mjs +16 -30
- package/commands/link-project.mjs +4 -11
- package/commands/memory.mjs +1328 -0
- package/commands/nuke.mjs +23 -28
- package/commands/pull.mjs +2 -79
- package/commands/push-rules.mjs +2 -2
- package/commands/push.mjs +15 -8
- package/commands/search.mjs +1 -1
- package/commands/telemetry.mjs +31 -0
- package/config.mjs +1 -1
- package/constants.mjs +13 -0
- package/ecc.mjs +84 -70
- package/fmt.mjs +14 -0
- package/hooks.mjs +106 -5
- package/link.mjs +1 -36
- package/memory-bridge.mjs +264 -0
- package/memory-queue.mjs +131 -0
- package/memory-sync.mjs +127 -0
- package/package.json +8 -6
- package/paths.mjs +1 -1
- package/registry.mjs +1 -1
- package/telemetry.mjs +233 -0
- package/codex.mjs +0 -723
- package/commands/startup.mjs +0 -78
- package/startup.mjs +0 -470
package/cli.mjs
CHANGED
|
@@ -4,8 +4,9 @@ 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
|
+
import { startSpan } from './telemetry.mjs';
|
|
9
10
|
|
|
10
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
12
|
const VERSION = JSON.parse(readFileSync(join(__dirname, 'package.json'), 'utf8')).version;
|
|
@@ -17,12 +18,12 @@ const COMMANDS = {
|
|
|
17
18
|
'push-rules': () => import('./commands/push-rules.mjs').then(m => m.pushRulesCommand),
|
|
18
19
|
drop: () => import('./commands/drop.mjs').then(m => m.dropCommand),
|
|
19
20
|
status: () => import('./commands/status.mjs').then(m => m.statusCommand),
|
|
20
|
-
routing: () => import('./commands/startup.mjs').then(m => m.routingCommand),
|
|
21
|
-
startup: () => import('./commands/startup.mjs').then(m => m.startupCommand),
|
|
22
21
|
search: () => import('./commands/search.mjs').then(m => m.searchCommand),
|
|
23
22
|
link: () => import('./commands/link-project.mjs').then(m => m.linkProjectCommand),
|
|
24
23
|
nuke: () => import('./commands/nuke.mjs').then(m => m.nukeCommand),
|
|
25
24
|
daemon: () => import('./commands/daemon.mjs').then(m => m.daemonCommand),
|
|
25
|
+
telemetry: () => import('./commands/telemetry.mjs').then(m => m.telemetryCommand),
|
|
26
|
+
memory: () => import('./commands/memory.mjs').then(m => m.memoryCommand),
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
function parseArgs(argv) {
|
|
@@ -98,9 +99,6 @@ function printHelp() {
|
|
|
98
99
|
sec('Manage'),
|
|
99
100
|
cmd('aw status', 'Show synced paths, modified files & conflicts'),
|
|
100
101
|
cmd('aw link', 'Link current project as a git worktree (wires IDE symlinks)'),
|
|
101
|
-
cmd('aw routing status', 'Show global AW session-routing mode for Claude/Cursor/Codex'),
|
|
102
|
-
cmd('aw routing disable', 'Disable automatic AW session routing globally'),
|
|
103
|
-
cmd('aw routing enable', 'Re-enable automatic AW session routing globally'),
|
|
104
102
|
cmd('aw drop <path>', 'Stop syncing or delete local content'),
|
|
105
103
|
cmd('aw nuke', 'Remove entire .aw_registry/ & start fresh'),
|
|
106
104
|
cmd('aw daemon install', 'Auto-pull on a schedule (macOS launchd / Linux cron)'),
|
|
@@ -108,6 +106,17 @@ function printHelp() {
|
|
|
108
106
|
cmd('aw daemon uninstall', 'Stop the background daemon'),
|
|
109
107
|
cmd('aw daemon status', 'Check if daemon is running'),
|
|
110
108
|
|
|
109
|
+
sec('Memory'),
|
|
110
|
+
cmd('aw memory store <content>', 'Store a memory (curated)'),
|
|
111
|
+
cmd('aw memory search <query>', 'Search memories'),
|
|
112
|
+
cmd('aw memory pack <query>', 'Get a memory pack (token-budgeted)'),
|
|
113
|
+
cmd('aw memory stats', 'Show memory statistics'),
|
|
114
|
+
|
|
115
|
+
sec('Settings'),
|
|
116
|
+
cmd('aw telemetry status', 'Show telemetry status'),
|
|
117
|
+
cmd('aw telemetry disable', 'Opt out of anonymous analytics'),
|
|
118
|
+
cmd('aw telemetry enable', 'Re-enable analytics'),
|
|
119
|
+
|
|
111
120
|
sec('Examples'),
|
|
112
121
|
'',
|
|
113
122
|
` ${chalk.dim('# Pull content from registry using path')}`,
|
|
@@ -156,9 +165,21 @@ export async function run(argv) {
|
|
|
156
165
|
}
|
|
157
166
|
|
|
158
167
|
if (command && COMMANDS[command]) {
|
|
168
|
+
const span = await startSpan(command, args);
|
|
169
|
+
span.notice();
|
|
159
170
|
args._updateCheck = updateCheck;
|
|
160
|
-
|
|
161
|
-
|
|
171
|
+
try {
|
|
172
|
+
const handler = await COMMANDS[command]();
|
|
173
|
+
await handler(args);
|
|
174
|
+
await span.end({ status: 'completed' });
|
|
175
|
+
} catch (err) {
|
|
176
|
+
if (err instanceof CancelError) {
|
|
177
|
+
await span.end({ status: 'cancelled', error_type: 'CancelError' });
|
|
178
|
+
process.exit(err.exitCode ?? 1);
|
|
179
|
+
}
|
|
180
|
+
await span.end({ status: 'failed', error_type: err.constructor.name });
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
162
183
|
notifyUpdate(await updateCheck);
|
|
163
184
|
return;
|
|
164
185
|
}
|
|
@@ -168,5 +189,5 @@ export async function run(argv) {
|
|
|
168
189
|
process.exit(0);
|
|
169
190
|
}
|
|
170
191
|
|
|
171
|
-
fmt.
|
|
192
|
+
fmt.cancelAndExit(`Unknown command: ${command}`);
|
|
172
193
|
}
|
package/commands/init.mjs
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
existsSync,
|
|
9
|
+
mkdirSync,
|
|
9
10
|
writeFileSync,
|
|
10
11
|
symlinkSync,
|
|
11
12
|
lstatSync,
|
|
@@ -25,11 +26,10 @@ import { chalk } from '../fmt.mjs';
|
|
|
25
26
|
import { linkWorkspace } from '../link.mjs';
|
|
26
27
|
import { generateCommands, copyInstructions, initAwDocs } from '../integrate.mjs';
|
|
27
28
|
import { setupMcp } from '../mcp.mjs';
|
|
28
|
-
import {
|
|
29
|
+
import { installLocalCommitHook } from '../hooks.mjs';
|
|
29
30
|
import { autoUpdate, promptUpdate } from '../update.mjs';
|
|
30
31
|
import { installGlobalHooks } from '../hooks.mjs';
|
|
31
32
|
import { installAwEcc } from '../ecc.mjs';
|
|
32
|
-
import { removeWorkspaceHookDefaults } from '../codex.mjs';
|
|
33
33
|
import {
|
|
34
34
|
initPersistentClone,
|
|
35
35
|
isValidClone,
|
|
@@ -58,18 +58,6 @@ const HOME = (() => { try { return realpathSync(_rawHome); } catch { return _raw
|
|
|
58
58
|
const GLOBAL_AW_DIR = join(HOME, '.aw_registry');
|
|
59
59
|
const AW_HOME = join(HOME, '.aw');
|
|
60
60
|
|
|
61
|
-
function syncInstructionsAndAwDocs(targetDir, namespace) {
|
|
62
|
-
copyInstructions(targetDir, null, namespace);
|
|
63
|
-
initAwDocs(targetDir);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function syncHomeAndProjectInstructions(cwd, namespace) {
|
|
67
|
-
syncInstructionsAndAwDocs(HOME, namespace);
|
|
68
|
-
if (cwd !== HOME) {
|
|
69
|
-
syncInstructionsAndAwDocs(cwd, namespace);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
61
|
// ── Ensure ~/.aw/.gitignore has personal/local entries ───────────────────
|
|
74
62
|
|
|
75
63
|
const AW_GITIGNORE_ENTRIES = [
|
|
@@ -99,7 +87,7 @@ function installIdeTasks() {
|
|
|
99
87
|
{
|
|
100
88
|
label: 'aw: sync registry',
|
|
101
89
|
type: 'shell',
|
|
102
|
-
command: 'aw init --silent',
|
|
90
|
+
command: 'AW_TRIGGER=ide:task aw init --silent',
|
|
103
91
|
presentation: { reveal: 'silent', panel: 'shared', close: true },
|
|
104
92
|
runOptions: { runOn: 'folderOpen' },
|
|
105
93
|
problemMatcher: [],
|
|
@@ -220,7 +208,7 @@ export async function initCommand(args) {
|
|
|
220
208
|
}
|
|
221
209
|
|
|
222
210
|
if (choice === 'platform-only') {
|
|
223
|
-
namespace =
|
|
211
|
+
namespace = 'platform'; team = 'platform'; subTeam = null; folderName = null;
|
|
224
212
|
}
|
|
225
213
|
}
|
|
226
214
|
|
|
@@ -259,6 +247,7 @@ export async function initCommand(args) {
|
|
|
259
247
|
}
|
|
260
248
|
|
|
261
249
|
ensureAwGitignore(AW_HOME);
|
|
250
|
+
mkdirSync(join(GLOBAL_AW_DIR, 'memory'), { recursive: true });
|
|
262
251
|
const freshCfg = config.load(GLOBAL_AW_DIR);
|
|
263
252
|
if (existsSync(GLOBAL_AW_DIR)) {
|
|
264
253
|
syncFileTree(join(AW_HOME, RULES_SOURCE_DIR), join(GLOBAL_AW_DIR, RULES_SOURCE_DIR));
|
|
@@ -273,9 +262,9 @@ export async function initCommand(args) {
|
|
|
273
262
|
}
|
|
274
263
|
|
|
275
264
|
await installAwEcc(cwd, { silent });
|
|
276
|
-
|
|
265
|
+
copyInstructions(HOME, null, freshCfg?.namespace || team) || [];
|
|
266
|
+
initAwDocs(HOME);
|
|
277
267
|
await setupMcp(HOME, freshCfg?.namespace || team, { silent });
|
|
278
|
-
const removedLegacyStartupFiles = cwd !== HOME ? removeWorkspaceHookDefaults(cwd) : [];
|
|
279
268
|
installGlobalHooks();
|
|
280
269
|
|
|
281
270
|
// Remove old local .git/hooks/post-checkout that pre-dates core.hooksPath (creates stale .aw_registry symlink)
|
|
@@ -307,6 +296,7 @@ export async function initCommand(args) {
|
|
|
307
296
|
const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
|
|
308
297
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
309
298
|
const commands = generateCommands(HOME, { silent: true });
|
|
299
|
+
if (cwd !== HOME) installLocalCommitHook(cwd);
|
|
310
300
|
|
|
311
301
|
if (silent) {
|
|
312
302
|
autoUpdate(await args._updateCheck);
|
|
@@ -316,9 +306,6 @@ export async function initCommand(args) {
|
|
|
316
306
|
'',
|
|
317
307
|
` ${chalk.green('✓')} Registry synced`,
|
|
318
308
|
` ${chalk.green('✓')} IDE refreshed — ${chalk.bold(symlinks)} symlinks · ${chalk.bold(commands)} commands`,
|
|
319
|
-
removedLegacyStartupFiles.length > 0
|
|
320
|
-
? ` ${chalk.green('✓')} Removed ${removedLegacyStartupFiles.length} legacy repo startup file${removedLegacyStartupFiles.length > 1 ? 's' : ''}`
|
|
321
|
-
: null,
|
|
322
309
|
cwd !== HOME && isWorktree(join(cwd, '.aw')) ? ` ${chalk.green('✓')} Project linked` : null,
|
|
323
310
|
].filter(Boolean).join('\n'));
|
|
324
311
|
}
|
|
@@ -394,8 +381,11 @@ export async function initCommand(args) {
|
|
|
394
381
|
}
|
|
395
382
|
}
|
|
396
383
|
|
|
397
|
-
// Create
|
|
398
|
-
|
|
384
|
+
// Create memory dir after symlink so GLOBAL_AW_DIR resolves correctly
|
|
385
|
+
mkdirSync(join(GLOBAL_AW_DIR, 'memory'), { recursive: true });
|
|
386
|
+
|
|
387
|
+
// Create sync config — default to 'platform' when no namespace specified
|
|
388
|
+
const cfg = config.create(GLOBAL_AW_DIR, { namespace: team || 'platform', user });
|
|
399
389
|
if (folderName) {
|
|
400
390
|
config.addPattern(GLOBAL_AW_DIR, folderName);
|
|
401
391
|
}
|
|
@@ -405,10 +395,9 @@ export async function initCommand(args) {
|
|
|
405
395
|
|
|
406
396
|
// Step 3: Setup tasks, MCP, hooks
|
|
407
397
|
await installAwEcc(cwd, { silent });
|
|
408
|
-
|
|
398
|
+
const instructionFiles = copyInstructions(HOME, null, team) || [];
|
|
399
|
+
initAwDocs(HOME);
|
|
409
400
|
const mcpFiles = await setupMcp(HOME, team, { silent }) || [];
|
|
410
|
-
applyStoredStartupPreferences(HOME);
|
|
411
|
-
const removedLegacyStartupFiles = cwd !== HOME ? removeWorkspaceHookDefaults(cwd) : [];
|
|
412
401
|
const hooksInstalled = installGlobalHooks();
|
|
413
402
|
installIdeTasks();
|
|
414
403
|
|
|
@@ -441,6 +430,7 @@ export async function initCommand(args) {
|
|
|
441
430
|
const projectRegistryDir = cwd !== HOME ? join(cwd, '.aw', REGISTRY_DIR) : null;
|
|
442
431
|
const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
|
|
443
432
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
433
|
+
if (cwd !== HOME) installLocalCommitHook(cwd);
|
|
444
434
|
ideSpinner.message('Generating commands...');
|
|
445
435
|
const commands = generateCommands(HOME, { silent: true });
|
|
446
436
|
ideSpinner.stop(`IDE wired — ${chalk.bold(symlinks)} symlinks · ${chalk.bold(commands)} commands`);
|
|
@@ -454,10 +444,6 @@ export async function initCommand(args) {
|
|
|
454
444
|
` ${chalk.green('✓')} Source of truth: ~/.aw/ (git clone)`,
|
|
455
445
|
` ${chalk.green('✓')} Symlink: ~/.aw_registry/ → ~/.aw/.aw_registry/`,
|
|
456
446
|
` ${chalk.green('✓')} IDE integration: ~/.claude/, ~/.cursor/, ~/.codex/`,
|
|
457
|
-
cwd !== HOME ? ` ${chalk.green('✓')} Global startup managed from ~/.claude/, ~/.cursor/, ~/.codex/` : null,
|
|
458
|
-
removedLegacyStartupFiles.length > 0
|
|
459
|
-
? ` ${chalk.green('✓')} Removed ${removedLegacyStartupFiles.length} legacy repo startup file${removedLegacyStartupFiles.length > 1 ? 's' : ''}`
|
|
460
|
-
: null,
|
|
461
447
|
hooksInstalled ? ` ${chalk.green('✓')} Git hooks: auto-sync on pull/clone (core.hooksPath)` : null,
|
|
462
448
|
` ${chalk.green('✓')} IDE task: auto-sync on workspace open`,
|
|
463
449
|
cwd !== HOME && isWorktree(join(cwd, '.aw')) ? ` ${chalk.green('✓')} Linked in current project` : null,
|
|
@@ -9,8 +9,7 @@ import { addProjectWorktree, isWorktree, isValidClone } from '../git.mjs';
|
|
|
9
9
|
import { REGISTRY_DIR, REGISTRY_URL } from '../constants.mjs';
|
|
10
10
|
import { linkWorkspace } from '../link.mjs';
|
|
11
11
|
import { generateCommands } from '../integrate.mjs';
|
|
12
|
-
import {
|
|
13
|
-
import { applyStoredStartupPreferences } from '../startup.mjs';
|
|
12
|
+
import { installLocalCommitHook } from '../hooks.mjs';
|
|
14
13
|
|
|
15
14
|
const HOME = homedir();
|
|
16
15
|
const AW_HOME = join(HOME, '.aw');
|
|
@@ -42,9 +41,8 @@ export function linkProjectCommand(args) {
|
|
|
42
41
|
const awDirForLinks = existsSync(projectRegistryDir) ? projectRegistryDir : null;
|
|
43
42
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
44
43
|
const commands = generateCommands(HOME, { silent: true });
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
fmt.logSuccess(`Already linked — refreshed ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands${removedLegacyStartupFiles.length > 0 ? ` · removed ${removedLegacyStartupFiles.length} legacy repo startup file${removedLegacyStartupFiles.length > 1 ? 's' : ''}` : ''}`);
|
|
44
|
+
installLocalCommitHook(cwd);
|
|
45
|
+
fmt.logSuccess(`Already linked — refreshed ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`);
|
|
48
46
|
return;
|
|
49
47
|
}
|
|
50
48
|
|
|
@@ -54,18 +52,13 @@ export function linkProjectCommand(args) {
|
|
|
54
52
|
const awDirForLinks = existsSync(projectRegistryDir) ? projectRegistryDir : null;
|
|
55
53
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
56
54
|
const commands = generateCommands(HOME, { silent: true });
|
|
57
|
-
|
|
58
|
-
const removedLegacyStartupFiles = removeWorkspaceHookDefaults(cwd);
|
|
55
|
+
installLocalCommitHook(cwd);
|
|
59
56
|
fmt.logSuccess([
|
|
60
57
|
`Project linked — ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`,
|
|
61
58
|
'',
|
|
62
59
|
` ${chalk.green('✓')} ${chalk.dim('.aw/')} git worktree (IDE git panel enabled)`,
|
|
63
60
|
` ${chalk.green('✓')} ${chalk.dim(`.aw/${REGISTRY_DIR}/`)} registry content`,
|
|
64
61
|
` ${chalk.green('✓')} ${chalk.dim('.claude/.cursor/.codex/')} IDE symlinks wired`,
|
|
65
|
-
` ${chalk.green('✓')} ${chalk.dim('startup mode')} global-first via ~/.claude/, ~/.cursor/, ~/.codex/`,
|
|
66
|
-
removedLegacyStartupFiles.length > 0
|
|
67
|
-
? ` ${chalk.green('✓')} ${chalk.dim('legacy repo hooks')} removed ${removedLegacyStartupFiles.length} AW-managed file${removedLegacyStartupFiles.length > 1 ? 's' : ''}`
|
|
68
|
-
: null,
|
|
69
62
|
].join('\n'));
|
|
70
63
|
} catch (e) {
|
|
71
64
|
fmt.cancel(`Failed to link project: ${e.message}`);
|