@aria_asi/cli 0.2.20 → 0.2.23

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.
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, writeFileSync, copyFileSync, chmodSync, mkdirSync } from 'fs';
1
+ import { existsSync, readFileSync, writeFileSync, copyFileSync, chmodSync, mkdirSync, readdirSync, statSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import * as path from 'path';
4
4
  import { fileURLToPath } from 'node:url';
@@ -29,7 +29,13 @@ const HOOK_FILES = [
29
29
  'aria-preprompt-consult.mjs',
30
30
  'aria-trigger-autolearn.mjs',
31
31
  'aria-userprompt-abandon-detect.mjs',
32
+ // Sub-agent handoff + ledger merge — installed 0.2.21
33
+ 'aria-agent-handoff.mjs',
34
+ 'aria-agent-ledger-merge.mjs',
32
35
  'doctrine_trigger_map.json',
36
+ // Pre-text gate — validates state-dependent claims in prose against
37
+ // probe evidence before emission. Closes "WHEN TO LOOK before speaking" gap.
38
+ 'aria-pre-text-gate.mjs',
33
39
  ];
34
40
  // Compiled location: <pkg>/dist/aria-connector/src/connectors/claude-code.js
35
41
  // (tsc preserves the src/ rooted layout under outDir). From this file:
@@ -113,45 +119,79 @@ const HOOKS_BLOCK = {
113
119
  },
114
120
  ],
115
121
  }],
116
- PreToolUse: [{
117
- // Matcher widened from 'Bash' (Hamza 2026-04-26): cognition gate
118
- // applies to every state-mutating tool, not just shell. Edit / Write
119
- // / NotebookEdit get the same enforcement so orchestrator-side
120
- // compliance mirrors what we demand from workers.
121
- matcher: 'Bash|Edit|Write|NotebookEdit',
122
+ PreToolUse: [
123
+ {
124
+ // Matcher widened from 'Bash' (Hamza 2026-04-26): cognition gate
125
+ // applies to every state-mutating tool, not just shell. Edit / Write
126
+ // / NotebookEdit get the same enforcement so orchestrator-side
127
+ // compliance mirrors what we demand from workers.
128
+ matcher: 'Bash|Edit|Write|NotebookEdit',
129
+ hooks: [
130
+ {
131
+ type: 'command',
132
+ command: 'node $HOME/.claude/hooks/aria-pre-tool-gate.mjs',
133
+ timeout: 5,
134
+ },
135
+ {
136
+ // Pre-turn memory consumption gate (Enforcement Layer #49).
137
+ // Fires after the cognition gate passes. Checks the first action
138
+ // of each turn for ALL THREE context-loading signals:
139
+ // 1. 🔐 Aria Harness header (harness packet injected)
140
+ // 2. [ARIA_DIRECTION] / [ARIA_BINDING_PLAN] (preprompt-consult fired)
141
+ // 3. feedback_*.md / project_*.md memory reference (memory consumed)
142
+ // On miss: blocks with structured recovery JSON so the orchestrator
143
+ // can run the context-loader and retry — no dead-letter state.
144
+ // Turn-deduplication via ~/.claude/aria-turn-state-${sessionId}.json
145
+ // prevents retry loops (60s window).
146
+ type: 'command',
147
+ command: 'node $HOME/.claude/hooks/aria-preturn-memory-gate.mjs',
148
+ timeout: 5,
149
+ },
150
+ ],
151
+ },
152
+ {
153
+ // Sub-agent handoff: fires before every Agent spawn so the sub-agent
154
+ // inherits owner/client-tier identity + parent ledger path.
155
+ // Tier protection is inside the hook — client paths never touch ~/.claude/.
156
+ matcher: 'Agent',
157
+ hooks: [{
158
+ type: 'command',
159
+ command: 'node $HOME/.claude/hooks/aria-agent-handoff.mjs',
160
+ timeout: 5,
161
+ statusMessage: 'Writing sub-agent handoff...',
162
+ }],
163
+ },
164
+ ],
165
+ PostToolUse: [{
166
+ matcher: 'Agent',
167
+ hooks: [{
168
+ type: 'command',
169
+ command: 'node $HOME/.claude/hooks/aria-agent-ledger-merge.mjs',
170
+ timeout: 8,
171
+ statusMessage: 'Merging sub-agent ledger...',
172
+ }],
173
+ }],
174
+ Stop: [{
175
+ // Stop gate — text-decision boundary. Reflexive replies fail this
176
+ // gate the same way reflexive Bash does. Mirrors PreToolUse
177
+ // enforcement at the text-emission surface.
178
+ // Pre-text gate fires alongside: validates state-dependent claims
179
+ // in prose (env vars, file states, pod states, deploy outcomes, etc.)
180
+ // against probe evidence in this turn's tool results. Closes the
181
+ // "WHEN TO LOOK before speaking" gap left open by both existing gates.
122
182
  hooks: [
123
183
  {
124
184
  type: 'command',
125
- command: 'node $HOME/.claude/hooks/aria-pre-tool-gate.mjs',
185
+ command: 'node $HOME/.claude/hooks/aria-stop-gate.mjs',
126
186
  timeout: 5,
127
187
  },
128
188
  {
129
- // Pre-turn memory consumption gate (Enforcement Layer #49).
130
- // Fires after the cognition gate passes. Checks the first action
131
- // of each turn for ALL THREE context-loading signals:
132
- // 1. 🔐 Aria Harness header (harness packet injected)
133
- // 2. [ARIA_DIRECTION] / [ARIA_BINDING_PLAN] (preprompt-consult fired)
134
- // 3. feedback_*.md / project_*.md memory reference (memory consumed)
135
- // On miss: blocks with structured recovery JSON so the orchestrator
136
- // can run the context-loader and retry — no dead-letter state.
137
- // Turn-deduplication via ~/.claude/aria-turn-state-${sessionId}.json
138
- // prevents retry loops (60s window).
139
189
  type: 'command',
140
- command: 'node $HOME/.claude/hooks/aria-preturn-memory-gate.mjs',
190
+ command: 'node $HOME/.claude/hooks/aria-pre-text-gate.mjs',
141
191
  timeout: 5,
142
192
  },
143
193
  ],
144
194
  }],
145
- Stop: [{
146
- // Stop gate — text-decision boundary. Reflexive replies fail this
147
- // gate the same way reflexive Bash does. Mirrors PreToolUse
148
- // enforcement at the text-emission surface.
149
- hooks: [{
150
- type: 'command',
151
- command: 'node $HOME/.claude/hooks/aria-stop-gate.mjs',
152
- timeout: 5,
153
- }],
154
- }],
155
195
  };
156
196
 
157
197
  function installHooks(claudeDir: string, logs: string[], opts: { force?: boolean } = {}): void {
@@ -210,10 +250,9 @@ function installSdk(claudeDir: string, logs: string[]): void {
210
250
  mkdirSync(sdkDst, { recursive: true, mode: 0o700 });
211
251
  }
212
252
  let copied = 0;
213
- const fs = require('fs') as typeof import('fs');
214
- for (const name of fs.readdirSync(sdkSrc)) {
253
+ for (const name of readdirSync(sdkSrc)) {
215
254
  const src = path.join(sdkSrc, name);
216
- const stat = fs.statSync(src);
255
+ const stat = statSync(src);
217
256
  if (!stat.isFile()) continue;
218
257
  const dst = path.join(sdkDst, name);
219
258
  copyFileSync(src, dst);
@@ -268,7 +307,7 @@ function wireHooksBlock(settings: Record<string, unknown>, logs: string[]): void
268
307
  if (!settings.$schema) {
269
308
  settings.$schema = 'https://json.schemastore.org/claude-code-settings.json';
270
309
  }
271
- logs.push(`Wired hooks into settings.json (${mergedEvents} events: SessionStart, UserPromptSubmit, PreToolUse [cognition+memory-gate], Stop) — merge-safe, preserves third-party entries`);
310
+ logs.push(`Wired hooks into settings.json (${mergedEvents} events: SessionStart, UserPromptSubmit, PreToolUse [cognition+memory-gate+Agent-handoff], PostToolUse [Agent-ledger-merge], Stop) — merge-safe, preserves third-party entries`);
272
311
  }
273
312
 
274
313
  function buildAriaSystemBlock(config: AriaConfig): string {
@@ -18,11 +18,20 @@ export async function connectOpenCode(config: AriaConfig): Promise<string[]> {
18
18
  const opencodeConfig = JSON.parse(readFileSync(configPath, 'utf-8'));
19
19
  let modified = false;
20
20
 
21
+ // Remove any prior reference to '@aria/connector' from plugins.
22
+ // That package name was written into older client configs but no
23
+ // such npm package exists — the harness integration with OpenCode
24
+ // is via agentsMdPath below, not via a plugin module. Loading a
25
+ // non-existent plugin name crashes OpenCode on open. Idempotent
26
+ // cleanup so re-running connect heals broken installs.
21
27
  if (Array.isArray(opencodeConfig.plugins)) {
22
- if (!opencodeConfig.plugins.includes('@aria/connector')) {
23
- opencodeConfig.plugins.push('@aria/connector');
28
+ const before = opencodeConfig.plugins.length;
29
+ opencodeConfig.plugins = opencodeConfig.plugins.filter(
30
+ (p: unknown) => p !== '@aria/connector',
31
+ );
32
+ if (opencodeConfig.plugins.length !== before) {
24
33
  modified = true;
25
- logs.push('Added @aria/connector to OpenCode plugins');
34
+ logs.push('Removed legacy @aria/connector reference from OpenCode plugins (was crashing on open)');
26
35
  }
27
36
  }
28
37