@ghl-ai/aw 0.1.37-beta.6 → 0.1.37-beta.60
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 +18 -3
- package/commands/init.mjs +32 -7
- package/commands/link-project.mjs +3 -0
- package/commands/memory.mjs +1328 -0
- package/commands/nuke.mjs +19 -14
- package/commands/pull.mjs +74 -32
- package/commands/push-rules.mjs +212 -0
- package/commands/push.mjs +27 -3
- package/config.mjs +1 -1
- package/constants.mjs +14 -1
- package/ecc.mjs +80 -4
- package/file-tree.mjs +76 -0
- package/fmt.mjs +14 -0
- package/git.mjs +2 -1
- package/hooks.mjs +101 -0
- package/integrate.mjs +49 -11
- package/memory-bridge.mjs +264 -0
- package/memory-queue.mjs +131 -0
- package/memory-sync.mjs +127 -0
- package/package.json +11 -4
- package/render-rules.mjs +483 -0
- package/telemetry.mjs +9 -5
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
|
|
|
@@ -15,6 +15,7 @@ const COMMANDS = {
|
|
|
15
15
|
init: () => import('./commands/init.mjs').then(m => m.initCommand),
|
|
16
16
|
pull: () => import('./commands/pull.mjs').then(m => m.pullCommand),
|
|
17
17
|
push: () => import('./commands/push.mjs').then(m => m.pushCommand),
|
|
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
21
|
search: () => import('./commands/search.mjs').then(m => m.searchCommand),
|
|
@@ -22,6 +23,7 @@ const COMMANDS = {
|
|
|
22
23
|
nuke: () => import('./commands/nuke.mjs').then(m => m.nukeCommand),
|
|
23
24
|
daemon: () => import('./commands/daemon.mjs').then(m => m.daemonCommand),
|
|
24
25
|
telemetry: () => import('./commands/telemetry.mjs').then(m => m.telemetryCommand),
|
|
26
|
+
memory: () => import('./commands/memory.mjs').then(m => m.memoryCommand),
|
|
25
27
|
};
|
|
26
28
|
|
|
27
29
|
function parseArgs(argv) {
|
|
@@ -88,6 +90,7 @@ function printHelp() {
|
|
|
88
90
|
sec('Upload'),
|
|
89
91
|
cmd('aw push', 'Push all modified files (creates one PR)'),
|
|
90
92
|
cmd('aw push <path>', 'Push file, folder, or namespace to registry'),
|
|
93
|
+
cmd('aw push-rules [path]', 'Push platform rules to platform-docs'),
|
|
91
94
|
cmd('aw push --dry-run [path]', 'Preview what would be pushed'),
|
|
92
95
|
|
|
93
96
|
sec('Discover'),
|
|
@@ -103,6 +106,12 @@ function printHelp() {
|
|
|
103
106
|
cmd('aw daemon uninstall', 'Stop the background daemon'),
|
|
104
107
|
cmd('aw daemon status', 'Check if daemon is running'),
|
|
105
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
|
+
|
|
106
115
|
sec('Settings'),
|
|
107
116
|
cmd('aw telemetry status', 'Show telemetry status'),
|
|
108
117
|
cmd('aw telemetry disable', 'Opt out of anonymous analytics'),
|
|
@@ -122,6 +131,8 @@ function printHelp() {
|
|
|
122
131
|
cmd('aw push .aw_registry/<team>/', 'Push entire namespace (one PR)'),
|
|
123
132
|
cmd('aw push .aw_registry/agents/<name>.md', 'Push a single agent'),
|
|
124
133
|
cmd('aw push .aw_registry/skills/<name>/', 'Push a single skill folder'),
|
|
134
|
+
cmd('aw push .aw_rules', 'Auto-redirects to aw push-rules'),
|
|
135
|
+
cmd('aw push-rules', 'Pushes .aw_rules or .aw_registry/.aw_rules'),
|
|
125
136
|
'',
|
|
126
137
|
` ${chalk.dim('# Remove content from workspace')}`,
|
|
127
138
|
cmd('aw drop <team>', 'Stop syncing a namespace (removes all files)'),
|
|
@@ -154,7 +165,7 @@ export async function run(argv) {
|
|
|
154
165
|
}
|
|
155
166
|
|
|
156
167
|
if (command && COMMANDS[command]) {
|
|
157
|
-
const span = startSpan(command, args);
|
|
168
|
+
const span = await startSpan(command, args);
|
|
158
169
|
span.notice();
|
|
159
170
|
args._updateCheck = updateCheck;
|
|
160
171
|
try {
|
|
@@ -162,6 +173,10 @@ export async function run(argv) {
|
|
|
162
173
|
await handler(args);
|
|
163
174
|
await span.end({ status: 'completed' });
|
|
164
175
|
} catch (err) {
|
|
176
|
+
if (err instanceof CancelError) {
|
|
177
|
+
await span.end({ status: 'cancelled', error_type: 'CancelError' });
|
|
178
|
+
process.exit(err.exitCode ?? 1);
|
|
179
|
+
}
|
|
165
180
|
await span.end({ status: 'failed', error_type: err.constructor.name });
|
|
166
181
|
throw err;
|
|
167
182
|
}
|
|
@@ -174,5 +189,5 @@ export async function run(argv) {
|
|
|
174
189
|
process.exit(0);
|
|
175
190
|
}
|
|
176
191
|
|
|
177
|
-
fmt.
|
|
192
|
+
fmt.cancelAndExit(`Unknown command: ${command}`);
|
|
178
193
|
}
|
package/commands/init.mjs
CHANGED
|
@@ -4,7 +4,18 @@
|
|
|
4
4
|
// Uses core.hooksPath (git-lfs pattern) for system-wide hook interception.
|
|
5
5
|
// Uses IDE tasks for auto-pull on workspace open.
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
existsSync,
|
|
9
|
+
mkdirSync,
|
|
10
|
+
writeFileSync,
|
|
11
|
+
symlinkSync,
|
|
12
|
+
lstatSync,
|
|
13
|
+
readdirSync,
|
|
14
|
+
readFileSync,
|
|
15
|
+
rmSync,
|
|
16
|
+
realpathSync,
|
|
17
|
+
appendFileSync,
|
|
18
|
+
} from 'node:fs';
|
|
8
19
|
import { execSync } from 'node:child_process';
|
|
9
20
|
import { join, dirname, sep } from 'node:path';
|
|
10
21
|
import { homedir } from 'node:os';
|
|
@@ -15,6 +26,7 @@ import { chalk } from '../fmt.mjs';
|
|
|
15
26
|
import { linkWorkspace } from '../link.mjs';
|
|
16
27
|
import { generateCommands, copyInstructions, initAwDocs } from '../integrate.mjs';
|
|
17
28
|
import { setupMcp } from '../mcp.mjs';
|
|
29
|
+
import { installLocalCommitHook } from '../hooks.mjs';
|
|
18
30
|
import { autoUpdate, promptUpdate } from '../update.mjs';
|
|
19
31
|
import { installGlobalHooks } from '../hooks.mjs';
|
|
20
32
|
import { installAwEcc } from '../ecc.mjs';
|
|
@@ -31,7 +43,8 @@ import {
|
|
|
31
43
|
syncWorktreeSparseCheckout,
|
|
32
44
|
findNearestWorktree,
|
|
33
45
|
} from '../git.mjs';
|
|
34
|
-
import { REGISTRY_DIR, REGISTRY_REPO, REGISTRY_URL } from '../constants.mjs';
|
|
46
|
+
import { REGISTRY_DIR, REGISTRY_REPO, REGISTRY_URL, RULES_SOURCE_DIR } from '../constants.mjs';
|
|
47
|
+
import { syncFileTree } from '../file-tree.mjs';
|
|
35
48
|
|
|
36
49
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
37
50
|
const VERSION = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8')).version;
|
|
@@ -195,7 +208,7 @@ export async function initCommand(args) {
|
|
|
195
208
|
}
|
|
196
209
|
|
|
197
210
|
if (choice === 'platform-only') {
|
|
198
|
-
namespace =
|
|
211
|
+
namespace = 'platform'; team = 'platform'; subTeam = null; folderName = null;
|
|
199
212
|
}
|
|
200
213
|
}
|
|
201
214
|
|
|
@@ -210,7 +223,7 @@ export async function initCommand(args) {
|
|
|
210
223
|
const isNewSubTeam = folderName && cfg && !cfg.include.includes(folderName);
|
|
211
224
|
if (isNewSubTeam) {
|
|
212
225
|
if (!silent) fmt.logStep(`Adding sub-team ${chalk.cyan(folderName)}...`);
|
|
213
|
-
const newSparsePaths = [`.aw_registry/${folderName}`,
|
|
226
|
+
const newSparsePaths = [`.aw_registry/${folderName}`, 'content', RULES_SOURCE_DIR];
|
|
214
227
|
addToSparseCheckout(AW_HOME, newSparsePaths);
|
|
215
228
|
config.addPattern(GLOBAL_AW_DIR, folderName);
|
|
216
229
|
} else {
|
|
@@ -234,7 +247,11 @@ export async function initCommand(args) {
|
|
|
234
247
|
}
|
|
235
248
|
|
|
236
249
|
ensureAwGitignore(AW_HOME);
|
|
250
|
+
mkdirSync(join(GLOBAL_AW_DIR, 'memory'), { recursive: true });
|
|
237
251
|
const freshCfg = config.load(GLOBAL_AW_DIR);
|
|
252
|
+
if (existsSync(GLOBAL_AW_DIR)) {
|
|
253
|
+
syncFileTree(join(AW_HOME, RULES_SOURCE_DIR), join(GLOBAL_AW_DIR, RULES_SOURCE_DIR));
|
|
254
|
+
}
|
|
238
255
|
|
|
239
256
|
// Ensure project worktree sparse checkout matches the global clone.
|
|
240
257
|
// Covers the case where a namespace was added from HOME (or another project)
|
|
@@ -279,6 +296,7 @@ export async function initCommand(args) {
|
|
|
279
296
|
const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
|
|
280
297
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
281
298
|
const commands = generateCommands(HOME, { silent: true });
|
|
299
|
+
if (cwd !== HOME) installLocalCommitHook(cwd);
|
|
282
300
|
|
|
283
301
|
if (silent) {
|
|
284
302
|
autoUpdate(await args._updateCheck);
|
|
@@ -317,7 +335,7 @@ export async function initCommand(args) {
|
|
|
317
335
|
}
|
|
318
336
|
|
|
319
337
|
// Determine sparse paths
|
|
320
|
-
const sparsePaths = [`.aw_registry/platform`, `content`, `.aw_registry/AW-PROTOCOL.md`, `CODEOWNERS`];
|
|
338
|
+
const sparsePaths = [`.aw_registry/platform`, `content`, RULES_SOURCE_DIR, `.aw_registry/AW-PROTOCOL.md`, `CODEOWNERS`];
|
|
321
339
|
if (folderName) {
|
|
322
340
|
sparsePaths.push(`.aw_registry/${folderName}`);
|
|
323
341
|
}
|
|
@@ -363,11 +381,17 @@ export async function initCommand(args) {
|
|
|
363
381
|
}
|
|
364
382
|
}
|
|
365
383
|
|
|
366
|
-
// Create
|
|
367
|
-
|
|
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 });
|
|
368
389
|
if (folderName) {
|
|
369
390
|
config.addPattern(GLOBAL_AW_DIR, folderName);
|
|
370
391
|
}
|
|
392
|
+
if (existsSync(GLOBAL_AW_DIR)) {
|
|
393
|
+
syncFileTree(join(AW_HOME, RULES_SOURCE_DIR), join(GLOBAL_AW_DIR, RULES_SOURCE_DIR));
|
|
394
|
+
}
|
|
371
395
|
|
|
372
396
|
// Step 3: Setup tasks, MCP, hooks
|
|
373
397
|
await installAwEcc(cwd, { silent });
|
|
@@ -406,6 +430,7 @@ export async function initCommand(args) {
|
|
|
406
430
|
const projectRegistryDir = cwd !== HOME ? join(cwd, '.aw', REGISTRY_DIR) : null;
|
|
407
431
|
const awDirForLinks = (projectRegistryDir && existsSync(projectRegistryDir)) ? projectRegistryDir : null;
|
|
408
432
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
433
|
+
if (cwd !== HOME) installLocalCommitHook(cwd);
|
|
409
434
|
ideSpinner.message('Generating commands...');
|
|
410
435
|
const commands = generateCommands(HOME, { silent: true });
|
|
411
436
|
ideSpinner.stop(`IDE wired — ${chalk.bold(symlinks)} symlinks · ${chalk.bold(commands)} commands`);
|
|
@@ -9,6 +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 { installLocalCommitHook } from '../hooks.mjs';
|
|
12
13
|
|
|
13
14
|
const HOME = homedir();
|
|
14
15
|
const AW_HOME = join(HOME, '.aw');
|
|
@@ -40,6 +41,7 @@ export function linkProjectCommand(args) {
|
|
|
40
41
|
const awDirForLinks = existsSync(projectRegistryDir) ? projectRegistryDir : null;
|
|
41
42
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
42
43
|
const commands = generateCommands(HOME, { silent: true });
|
|
44
|
+
installLocalCommitHook(cwd);
|
|
43
45
|
fmt.logSuccess(`Already linked — refreshed ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`);
|
|
44
46
|
return;
|
|
45
47
|
}
|
|
@@ -50,6 +52,7 @@ export function linkProjectCommand(args) {
|
|
|
50
52
|
const awDirForLinks = existsSync(projectRegistryDir) ? projectRegistryDir : null;
|
|
51
53
|
const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
|
|
52
54
|
const commands = generateCommands(HOME, { silent: true });
|
|
55
|
+
installLocalCommitHook(cwd);
|
|
53
56
|
fmt.logSuccess([
|
|
54
57
|
`Project linked — ${chalk.bold(symlinks)} IDE symlinks · ${chalk.bold(commands)} commands`,
|
|
55
58
|
'',
|