@ghl-ai/aw 0.1.37-beta.63 → 0.1.37-beta.65

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.
@@ -16,6 +16,8 @@ const STATUS_LABEL = {
16
16
  };
17
17
 
18
18
  const GENERATED_RULE_HEADER = '<!-- Generated by aw — do not edit manually -->';
19
+ const AW_ROUTER_BRIDGE_START_MARKER = '<!-- aw-managed:start router-bridge -->';
20
+ const AW_ROUTER_BRIDGE_END_MARKER = '<!-- aw-managed:end router-bridge -->';
19
21
  const PRIMARY_AW_ROUTES = ['plan', 'build', 'test', 'review', 'deploy', 'ship'];
20
22
  const CONDITIONAL_AW_ROUTES = ['investigate'];
21
23
  const COMPAT_AW_ROUTES = ['execute', 'verify'];
@@ -344,6 +346,16 @@ function textHasRulesReference(text) {
344
346
  return text.includes('Platform Rules') && text.includes('.aw_registry/.aw_rules/platform/');
345
347
  }
346
348
 
349
+ function textHasManagedRouterBridge(text) {
350
+ return text.includes(AW_ROUTER_BRIDGE_START_MARKER)
351
+ && text.includes(AW_ROUTER_BRIDGE_END_MARKER)
352
+ && text.includes('## AW Router Bridge')
353
+ && text.includes('### 1. Route First (MANDATORY)')
354
+ && text.includes('### 5. Verify With Proof')
355
+ && text.includes('using-aw-skills')
356
+ && text.includes('incremental-implementation');
357
+ }
358
+
347
359
  function extractRegistryReferencePaths(text) {
348
360
  const matches = [];
349
361
  const pattern = /(?:\]\(|`)([^)\n`]*\.aw_registry\/[^)\n`]+\.md)(?:\)|`)/g;
@@ -443,22 +455,27 @@ function buildDoctorChecks(homeDir, cwd) {
443
455
  );
444
456
  }
445
457
 
446
- const homeAgentsPath = join(homeDir, 'AGENTS.md');
447
- checks.push(
448
- existsSync(homeAgentsPath) && textHasRulesReference(readText(homeAgentsPath))
449
- ? makeCheck('home-agents-md', 'Global AGENTS.md', 'pass', 'Global AGENTS.md includes the AW rules reference table')
450
- : makeCheck(
451
- 'home-agents-md',
452
- 'Global AGENTS.md',
453
- rulesDir ? 'fail' : 'warn',
454
- existsSync(homeAgentsPath)
455
- ? 'Global AGENTS.md is present but missing the AW rules reference table'
456
- : 'Global AGENTS.md is missing',
457
- 'Run `aw init` or `aw pull` to regenerate the managed AGENTS.md instructions.',
458
- ),
459
- );
460
-
461
458
  if (cwd !== homeDir) {
459
+ const projectAgentsPath = join(cwd, 'AGENTS.md');
460
+ const projectClaudePath = join(cwd, 'CLAUDE.md');
461
+ const projectAgentsHasBridge = existsSync(projectAgentsPath) && textHasManagedRouterBridge(readText(projectAgentsPath));
462
+ const projectClaudeExists = existsSync(projectClaudePath);
463
+ const projectClaudeHasBridge = projectClaudeExists && textHasManagedRouterBridge(readText(projectClaudePath));
464
+
465
+ checks.push(
466
+ !projectAgentsHasBridge && !projectClaudeHasBridge
467
+ ? makeCheck('project-router-bridge', 'Current repo router bridge', 'pass', 'Current repo does not carry a stale managed AW Router Bridge block')
468
+ : makeCheck(
469
+ 'project-router-bridge',
470
+ 'Current repo router bridge',
471
+ 'warn',
472
+ projectAgentsHasBridge
473
+ ? 'Current repo AGENTS.md still carries a stale managed AW Router Bridge block'
474
+ : 'Current repo CLAUDE.md still carries a stale managed AW Router Bridge block',
475
+ 'Run `aw init` to move the managed AW Router Bridge into the user-home harness files and remove stale repo-local copies.',
476
+ ),
477
+ );
478
+
462
479
  const projectClaudeSessionStartStatus = getProjectClaudeSessionStartStatus(cwd);
463
480
  if (!projectClaudeSessionStartStatus.ok) {
464
481
  checks.push(makeCheck(
@@ -592,6 +609,21 @@ function buildDoctorChecks(homeDir, cwd) {
592
609
  );
593
610
 
594
611
  const claudeRulesDir = join(homeDir, '.claude', 'rules', 'platform');
612
+ const claudeHomeInstructionsPath = join(homeDir, '.claude', 'CLAUDE.md');
613
+ checks.push(
614
+ existsSync(claudeHomeInstructionsPath) && textHasManagedRouterBridge(readText(claudeHomeInstructionsPath))
615
+ ? makeCheck('claude-home-instructions', 'Claude home instructions', 'pass', 'Claude home CLAUDE.md includes the managed AW Router Bridge block')
616
+ : makeCheck(
617
+ 'claude-home-instructions',
618
+ 'Claude home instructions',
619
+ 'fail',
620
+ existsSync(claudeHomeInstructionsPath)
621
+ ? 'Claude home CLAUDE.md is present but missing the managed AW Router Bridge block'
622
+ : 'Claude home CLAUDE.md is missing',
623
+ 'Run `aw init` to regenerate ~/.claude/CLAUDE.md with the managed AW Router Bridge block.',
624
+ ),
625
+ );
626
+
595
627
  checks.push(
596
628
  rulesDir && directoryContainsGeneratedRuleFiles(claudeRulesDir, '.md')
597
629
  ? makeCheck('claude-rules', 'Claude AW rules', 'pass', 'Claude has generated platform rules under ~/.claude/rules/platform/')
@@ -695,16 +727,16 @@ function buildDoctorChecks(homeDir, cwd) {
695
727
 
696
728
  const codexAgentsPath = join(homeDir, '.codex', 'AGENTS.md');
697
729
  checks.push(
698
- existsSync(codexAgentsPath) && textHasRulesReference(readText(codexAgentsPath))
699
- ? makeCheck('codex-agents-md', 'Codex AGENTS.md', 'pass', 'Codex AGENTS.md includes the AW rules reference table')
730
+ existsSync(codexAgentsPath) && textHasManagedRouterBridge(readText(codexAgentsPath)) && textHasRulesReference(readText(codexAgentsPath))
731
+ ? makeCheck('codex-agents-md', 'Codex AGENTS.md', 'pass', 'Codex AGENTS.md includes the managed AW Router Bridge block and AW rules reference table')
700
732
  : makeCheck(
701
733
  'codex-agents-md',
702
734
  'Codex AGENTS.md',
703
735
  rulesDir ? 'fail' : 'warn',
704
736
  existsSync(codexAgentsPath)
705
- ? 'Codex AGENTS.md is present but missing the AW rules reference table'
737
+ ? 'Codex AGENTS.md is present but missing the managed AW Router Bridge block or AW rules reference table'
706
738
  : 'Codex AGENTS.md is missing',
707
- 'Re-run `aw init` so Codex instructions are regenerated with the AW rules reference table.',
739
+ 'Re-run `aw init` so Codex instructions are regenerated with the managed AW Router Bridge block and AW rules reference table.',
708
740
  ),
709
741
  );
710
742
 
@@ -779,6 +811,20 @@ function buildDoctorChecks(homeDir, cwd) {
779
811
  );
780
812
 
781
813
  const cursorRefPath = join(homeDir, '.cursor', 'references', 'route-selection-patterns.md');
814
+ const cursorAgentsPath = join(homeDir, '.cursor', 'AGENTS.md');
815
+ checks.push(
816
+ existsSync(cursorAgentsPath) && textHasManagedRouterBridge(readText(cursorAgentsPath))
817
+ ? makeCheck('cursor-home-instructions', 'Cursor home instructions', 'pass', 'Cursor home AGENTS.md includes the managed AW Router Bridge block')
818
+ : makeCheck(
819
+ 'cursor-home-instructions',
820
+ 'Cursor home instructions',
821
+ 'fail',
822
+ existsSync(cursorAgentsPath)
823
+ ? 'Cursor home AGENTS.md is present but missing the managed AW Router Bridge block'
824
+ : 'Cursor home AGENTS.md is missing',
825
+ 'Run `aw init` to regenerate ~/.cursor/AGENTS.md with the managed AW Router Bridge block.',
826
+ ),
827
+ );
782
828
  checks.push(
783
829
  existsSync(cursorRefPath)
784
830
  ? makeCheck('cursor-references', 'Cursor shared references', 'pass', 'Cursor shared references are materialized')
package/commands/init.mjs CHANGED
@@ -23,7 +23,7 @@ import * as config from '../config.mjs';
23
23
  import * as fmt from '../fmt.mjs';
24
24
  import { chalk } from '../fmt.mjs';
25
25
  import { linkWorkspace } from '../link.mjs';
26
- import { generateCommands, copyInstructions, initAwDocs, syncCodexHomeAgents } from '../integrate.mjs';
26
+ import { generateCommands, copyInstructions, initAwDocs, syncHomeHarnessInstructions } from '../integrate.mjs';
27
27
  import { setupMcp } from '../mcp.mjs';
28
28
  import { applyStoredStartupPreferences, ensureAwRuntimeHook } from '../startup.mjs';
29
29
  import { autoUpdate, promptUpdate } from '../update.mjs';
@@ -64,8 +64,8 @@ function syncInstructionsAndAwDocs(targetDir, namespace) {
64
64
  }
65
65
 
66
66
  function syncHomeAndProjectInstructions(cwd, namespace) {
67
- syncInstructionsAndAwDocs(HOME, namespace);
68
- syncCodexHomeAgents(HOME);
67
+ syncHomeHarnessInstructions(HOME);
68
+ initAwDocs(HOME);
69
69
  if (cwd !== HOME) {
70
70
  syncInstructionsAndAwDocs(cwd, namespace);
71
71
  }
package/commands/pull.mjs CHANGED
@@ -30,7 +30,7 @@ import {
30
30
  } from '../constants.mjs';
31
31
  import { collectAllPaths, syncFileTree } from '../file-tree.mjs';
32
32
  import { linkWorkspace } from '../link.mjs';
33
- import { generateCommands, copyInstructions, syncCodexHomeAgents } from '../integrate.mjs';
33
+ import { generateCommands, copyInstructions, syncHomeHarnessInstructions } from '../integrate.mjs';
34
34
  import { removeWorkspaceHookDefaults } from '../codex.mjs';
35
35
  import { applyStoredStartupPreferences, ensureAwRuntimeHook } from '../startup.mjs';
36
36
 
@@ -255,8 +255,7 @@ export async function pullCommand(args) {
255
255
  const symlinks = linkWorkspace(HOME, awDirForLinks, { silent: true });
256
256
  ideSpinner.message('Generating commands...');
257
257
  const commands = generateCommands(HOME, { silent: true });
258
- copyInstructions(HOME, null, cfg.namespace);
259
- syncCodexHomeAgents(HOME);
258
+ syncHomeHarnessInstructions(HOME);
260
259
  ensureAwRuntimeHook(HOME);
261
260
  applyStoredStartupPreferences(HOME);
262
261
  if (startupCleanupDir) removeWorkspaceHookDefaults(startupCleanupDir);
@@ -264,8 +263,7 @@ export async function pullCommand(args) {
264
263
  } else {
265
264
  linkWorkspace(HOME, awDirForLinks, { silent: true });
266
265
  generateCommands(HOME, { silent: true });
267
- copyInstructions(HOME, null, cfg.namespace);
268
- syncCodexHomeAgents(HOME);
266
+ syncHomeHarnessInstructions(HOME);
269
267
  ensureAwRuntimeHook(HOME);
270
268
  applyStoredStartupPreferences(HOME);
271
269
  if (startupCleanupDir) removeWorkspaceHookDefaults(startupCleanupDir);
package/integrate.mjs CHANGED
@@ -1,13 +1,14 @@
1
1
  // integrate.mjs — Generate commands for all IDEs, instructions (CLAUDE.md, AGENTS.md)
2
2
 
3
3
  import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, rmSync } from 'node:fs';
4
- import { join } from 'node:path';
4
+ import { dirname, join } from 'node:path';
5
5
  import { homedir } from 'node:os';
6
6
  import * as fmt from './fmt.mjs';
7
7
  import * as config from './config.mjs';
8
8
  import { getLocalRegistryDir } from './git.mjs';
9
9
  import {
10
10
  generateAgentsMdRulesSection,
11
+ generateClaudeMdRulesSection,
11
12
  renderRules,
12
13
  resolveRulesSourceDir,
13
14
  } from './render-rules.mjs';
@@ -22,22 +23,39 @@ function generateAwRouterBridgeSection() {
22
23
  return `${AW_ROUTER_BRIDGE_START_MARKER}
23
24
  ## ${AW_ROUTER_BRIDGE_HEADER}
24
25
 
25
- Before any substantive response on every new user turn, you MUST first resolve and apply \`$HOME/.codex/skills/using-aw-skills/SKILL.md\`, then use it to select the smallest correct AW route and stage skill for the current request.
26
- You MUST resolve and read the applicable AW rules from \`$HOME/.aw/.aw_registry/.aw_rules/platform/<domain>/AGENTS.md\`, and you MUST also read \`$HOME/.aw/.aw_registry/.aw_rules/platform/universal/AGENTS.md\` plus \`$HOME/.aw/.aw_registry/.aw_rules/platform/security/AGENTS.md\` whenever those cross-cutting rules apply.
27
- You MUST NOT assume any previously used skill remains active; re-evaluate and re-select the required AW skill stack on each turn.
28
- When repo-local instructions conflict with these user-home AW skill or AW rules sources of truth, you MUST follow the user-home sources of truth.
29
-
30
- ## Engineering Principles
31
-
32
- Use \`using-aw-skills\` first to choose the smallest correct AW route before exploration, planning, implementation, testing, or review.
33
- Before proposing or writing code, first inspect the existing code paths, adjacent patterns, configs, generated artifacts, and tests that already implement similar behavior in this repo.
34
- For non-trivial work, explore the relevant platform docs, app surfaces, harness behavior, and integration points before choosing an approach; prefer extending existing patterns over inventing new ones.
35
- If requirements, product intent, or behavioral consequences are ambiguous and cannot be resolved from code, docs, or tests, ask a short clarifying question before making a risky change.
36
- For bug fixes and behavior changes, prefer a Red -> Green -> Refactor loop, using \`aw-debug\`, \`aw-build\`, \`aw-test\`, and \`aw-review\` as needed.
37
- For multi-step implementation work, use \`incremental-implementation\` to break the work into thin, reversible slices with clear validation at each step before moving on.
38
- When the request still needs a tighter execution contract, use \`aw-plan\`.
39
- When changing interfaces or config contracts, follow \`interface-stability\`.
40
- Verify the exact changed surface with focused tests, static checks, or runtime probes before claiming success.
26
+ ### 1. Route First (MANDATORY)
27
+ - Before any substantive response, resolve and apply \`using-aw-skills\`
28
+ - Select the smallest correct AW route and stage skill for this task
29
+ - Do not assume the previous skill stack is still active
30
+
31
+ ### 2. Read Rules Before Acting (MANDATORY)
32
+ - Read applicable AW rules from \`$HOME/.aw/.aw_registry/.aw_rules/platform/<domain>/AGENTS.md\`
33
+ - Also read \`universal\` and \`security\` rules whenever they apply
34
+ - If repo-local instructions conflict with org-level sources of truth, follow org-level sources
35
+
36
+ ### 3. Explore Before Building
37
+ - Read existing code, adjacent patterns, configs, generated artifacts, and tests before writing anything
38
+ - For non-trivial work, inspect platform docs, runtime behavior, app surfaces, and integration boundaries first
39
+ - Ask one short clarifying question only when ambiguity remains after exploration
40
+
41
+ ### 4. Build in Small Steps
42
+ - For multi-step work, resolve and apply \`incremental-implementation\`
43
+ - Break work into thin, reversible slices with validation at each step
44
+ - Prefer extending existing patterns over inventing new ones
45
+ - Never batch unrelated changes in one pass
46
+
47
+ ### 5. Verify With Proof
48
+ - For bug fixes and behavior changes, use Red -> Green -> Refactor
49
+ - For config, docs, scaffolding, and integration wiring, use focused verification appropriate to the changed surface
50
+ - Use \`aw-debug\`, \`aw-build\`, \`aw-test\`, and \`aw-review\` as needed
51
+ - Never mark work complete without focused proof
52
+
53
+ ### 6. Core Principles
54
+ - Correctness over cleverness
55
+ - Clarity over complexity
56
+ - Small diffs over broad rewrites
57
+ - Evidence over assumption
58
+ - When corrected, update the working pattern and do not repeat the same mistake
41
59
  ${AW_ROUTER_BRIDGE_END_MARKER}`;
42
60
  }
43
61
 
@@ -73,16 +91,17 @@ function stripManagedSection(content, header, stopHeaders = []) {
73
91
  return `${content.slice(0, idx).trimEnd()}${content.slice(end)}`;
74
92
  }
75
93
 
76
- function applyManagedInstructionSections(content, file, rulesSections = {}) {
94
+ function applyManagedInstructionSections(content, file, rulesSections = {}, options = {}) {
77
95
  const rulesHeader = file === 'CLAUDE.md' ? CLAUDE_RULES_HEADER : AGENTS_RULES_HEADER;
78
96
  const rulesSection = file === 'CLAUDE.md' ? rulesSections.claudeSection : rulesSections.agentsSection;
97
+ const includeBridge = options.includeBridge !== false;
79
98
 
80
99
  let next = stripManagedBlock(content, AW_ROUTER_BRIDGE_START_MARKER, AW_ROUTER_BRIDGE_END_MARKER);
81
100
  next = stripManagedSection(next, AW_ROUTER_BRIDGE_HEADER, [rulesHeader]);
82
101
  next = stripManagedSection(next, rulesHeader);
83
102
  next = next.trimEnd();
84
103
 
85
- const sections = [generateAwRouterBridgeSection(), rulesSection].filter(Boolean);
104
+ const sections = [includeBridge ? generateAwRouterBridgeSection() : null, rulesSection].filter(Boolean);
86
105
  if (sections.length === 0) {
87
106
  return next ? `${next}\n` : '';
88
107
  }
@@ -157,7 +176,7 @@ export function copyInstructions(cwd, tempDir, namespace) {
157
176
  const dest = join(cwd, file);
158
177
  if (existsSync(dest)) {
159
178
  const existing = readFileSync(dest, 'utf8');
160
- const updated = applyManagedInstructionSections(existing, file, rulesSections);
179
+ const updated = applyManagedInstructionSections(existing, file, rulesSections, { includeBridge: false });
161
180
 
162
181
  if (updated !== existing) {
163
182
  writeFileSync(dest, updated);
@@ -175,7 +194,7 @@ export function copyInstructions(cwd, tempDir, namespace) {
175
194
  if (namespace) {
176
195
  content = content.replace(/\{\{TEAM\}\}/g, namespace);
177
196
  }
178
- content = applyManagedInstructionSections(content, file, rulesSections);
197
+ content = applyManagedInstructionSections(content, file, rulesSections, { includeBridge: false });
179
198
  writeFileSync(dest, content);
180
199
  fmt.logSuccess(`Created ${file}`);
181
200
  createdFiles.push(dest);
@@ -185,7 +204,7 @@ export function copyInstructions(cwd, tempDir, namespace) {
185
204
 
186
205
  const content = generateAgentsMd(cwd, namespace, rulesSections);
187
206
  if (content) {
188
- writeFileSync(dest, content);
207
+ writeFileSync(dest, applyManagedInstructionSections(content, file, rulesSections, { includeBridge: false }));
189
208
  fmt.logSuccess(`Created ${file}`);
190
209
  createdFiles.push(dest);
191
210
  }
@@ -193,25 +212,48 @@ export function copyInstructions(cwd, tempDir, namespace) {
193
212
  return createdFiles;
194
213
  }
195
214
 
196
- export function syncCodexHomeAgents(homeDir = homedir()) {
197
- const codexAgentsPath = join(homeDir, '.codex', 'AGENTS.md');
198
- const rulesDir = resolveRulesSourceDir(homeDir, { homeDir });
199
- if (!rulesDir) return null;
215
+ function syncHomeInstructionFile(destPath, file, rulesSection) {
216
+ const existing = existsSync(destPath)
217
+ ? readFileSync(destPath, 'utf8')
218
+ : (file === 'CLAUDE.md' ? '# CLAUDE.md\n' : '# AGENTS.md\n');
219
+ const updated = applyManagedInstructionSections(
220
+ existing,
221
+ file,
222
+ file === 'CLAUDE.md' ? { claudeSection: rulesSection } : { agentsSection: rulesSection },
223
+ );
200
224
 
201
- const rulesSection = generateAgentsMdRulesSection(rulesDir, {
202
- outputDir: join(homeDir, '.codex'),
203
- });
204
- if (!rulesSection) return null;
205
- const normalizedRulesSection = rulesSection.replaceAll('../.aw/.aw_registry/', '../.aw_registry/');
206
-
207
- const existing = existsSync(codexAgentsPath) ? readFileSync(codexAgentsPath, 'utf8') : '# AGENTS\n';
208
- const withoutRules = stripManagedSection(existing, AGENTS_RULES_HEADER).trimEnd();
209
- const updated = withoutRules ? `${withoutRules}\n\n${normalizedRulesSection}\n` : `${normalizedRulesSection}\n`;
210
225
  if (updated === existing) return null;
211
226
 
212
- mkdirSync(join(homeDir, '.codex'), { recursive: true });
213
- writeFileSync(codexAgentsPath, updated);
214
- return codexAgentsPath;
227
+ mkdirSync(dirname(destPath), { recursive: true });
228
+ writeFileSync(destPath, updated);
229
+ return destPath;
230
+ }
231
+
232
+ export function syncHomeHarnessInstructions(homeDir = homedir()) {
233
+ const rulesDir = resolveRulesSourceDir(homeDir, { homeDir });
234
+ const codexRulesSection = rulesDir
235
+ ? generateAgentsMdRulesSection(rulesDir, {
236
+ outputDir: join(homeDir, '.codex'),
237
+ }).replaceAll('../.aw/.aw_registry/', '../.aw_registry/')
238
+ : '';
239
+ const cursorRulesSection = rulesDir
240
+ ? generateAgentsMdRulesSection(rulesDir, {
241
+ outputDir: join(homeDir, '.cursor'),
242
+ }).replaceAll('../.aw/.aw_registry/', '../.aw_registry/')
243
+ : '';
244
+ const claudeRulesSection = rulesDir ? generateClaudeMdRulesSection(rulesDir) : '';
245
+
246
+ return [
247
+ syncHomeInstructionFile(join(homeDir, '.codex', 'AGENTS.md'), 'AGENTS.md', codexRulesSection),
248
+ syncHomeInstructionFile(join(homeDir, '.claude', 'CLAUDE.md'), 'CLAUDE.md', claudeRulesSection),
249
+ syncHomeInstructionFile(join(homeDir, '.cursor', 'AGENTS.md'), 'AGENTS.md', cursorRulesSection),
250
+ ].filter(Boolean);
251
+ }
252
+
253
+ export function syncCodexHomeAgents(homeDir = homedir()) {
254
+ const codexAgentsPath = join(homeDir, '.codex', 'AGENTS.md');
255
+ syncHomeHarnessInstructions(homeDir);
256
+ return existsSync(codexAgentsPath) ? codexAgentsPath : null;
215
257
  }
216
258
 
217
259
  function generateClaudeMd(cwd, namespace, rulesSections = {}) {
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@ghl-ai/aw",
3
- "version": "0.1.37-beta.63",
3
+ "version": "0.1.37-beta.65",
4
4
  "description": "Agentic Workspace CLI — pull, push & manage agents, skills and commands from the registry",
5
5
  "type": "module",
6
- "bin": "bin.js",
6
+ "bin": {
7
+ "aw": "bin.js"
8
+ },
7
9
  "files": [
8
10
  "bin.js",
9
11
  "cli.mjs",