@aria_asi/cli 0.2.19 → 0.2.22

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.
@@ -219,14 +219,14 @@ const VERIFY_BLOCK_RX =
219
219
  // ── Tier-aware lens labeling (Phase 11 #59) ──────────────────────────────────
220
220
  //
221
221
  // Aria's Arabic cognition lens names are proprietary IP. On Hamza's surface
222
- // (isHamza=true / surface=platform:hamza) the canonical names are shown.
222
+ // (isHamza=true / surface line contains hamza:true) the canonical names are shown.
223
223
  // On any client surface the gate uses neutral generic labels so the IP
224
224
  // vocabulary never appears in client-facing block-reason text.
225
225
  //
226
226
  // Tier is read from the most recent harness-via-sdk packet cache at
227
227
  // ~/.claude/.aria-harness-last-packet.json. Two detection paths:
228
228
  // 1. packet.contractGate.signals.hamza === true (boolean or string "true")
229
- // 2. packet.harness string contains "surface=platform:hamza"
229
+ // 2. packet.harness string contains "hamza:true" in the surface line
230
230
  // Either path → OWNER tier. Everything else → CLIENT tier.
231
231
  //
232
232
  // Doctrine memory filenames in block-reason text are also Aria-side IP.
@@ -241,9 +241,12 @@ function resolveOwnerTier() {
241
241
  // Path 1: contractGate.signals.hamza
242
242
  const sigHamza = packet?.contractGate?.signals?.hamza;
243
243
  if (sigHamza === true || sigHamza === 'true') return true;
244
- // Path 2: harness string surface marker
244
+ // Path 2: harness string surface marker — the actual format is
245
+ // "surface=platform:<X> group:<Y> hamza:true chat_type:<Z>" so we
246
+ // match hamza:true in the surface line, not "platform:hamza" (which
247
+ // was a legacy incorrect pattern that never matched real packets).
245
248
  const harnessStr = packet?.harness ?? '';
246
- if (/surface=platform:hamza\b/.test(harnessStr)) return true;
249
+ if (/\bhamza:true\b/.test(harnessStr)) return true;
247
250
  }
248
251
  } catch {/* packet unreadable → default to client tier */}
249
252
  return false;
@@ -143,7 +143,8 @@ function resolveOwnerTier() {
143
143
  const sigHamza = packet?.contractGate?.signals?.hamza;
144
144
  if (sigHamza === true || sigHamza === 'true') return true;
145
145
  const harnessStr = packet?.harness ?? '';
146
- if (/surface=platform:hamza\b/.test(harnessStr)) return true;
146
+ // surface line format: "surface=platform:<X> group:<Y> hamza:true chat_type:<Z>"
147
+ if (/\bhamza:true\b/.test(harnessStr)) return true;
147
148
  }
148
149
  } catch {/* packet unreadable → default to client tier */}
149
150
  return false;
@@ -135,7 +135,9 @@ function writeNoCognitionStopTranscript(transcriptPath) {
135
135
  }
136
136
 
137
137
  // ── Run hook helpers ────────────────────────────────────────────────────────
138
- function runPreToolGate(transcriptPath, command = 'git reset --hard HEAD') {
138
+ // Use a non-destructive but non-trivial command that skips the verify path
139
+ // and goes straight to cognition-missing, where lens labels appear.
140
+ function runPreToolGate(transcriptPath, command = 'npm run build --workspace=packages/aria-connector') {
139
141
  const event = JSON.stringify({
140
142
  tool_name: 'Bash',
141
143
  tool_input: { command },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aria_asi/cli",
3
- "version": "0.2.19",
3
+ "version": "0.2.22",
4
4
  "description": "Aria Smart CLI — the world's first harness-powered terminal companion",
5
5
  "bin": {
6
6
  "aria": "./bin/aria.js"
@@ -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,6 +29,9 @@ 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',
33
36
  ];
34
37
  // Compiled location: <pkg>/dist/aria-connector/src/connectors/claude-code.js
@@ -113,34 +116,57 @@ const HOOKS_BLOCK = {
113
116
  },
114
117
  ],
115
118
  }],
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
- hooks: [
123
- {
124
- type: 'command',
125
- command: 'node $HOME/.claude/hooks/aria-pre-tool-gate.mjs',
126
- timeout: 5,
127
- },
128
- {
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).
119
+ PreToolUse: [
120
+ {
121
+ // Matcher widened from 'Bash' (Hamza 2026-04-26): cognition gate
122
+ // applies to every state-mutating tool, not just shell. Edit / Write
123
+ // / NotebookEdit get the same enforcement so orchestrator-side
124
+ // compliance mirrors what we demand from workers.
125
+ matcher: 'Bash|Edit|Write|NotebookEdit',
126
+ hooks: [
127
+ {
128
+ type: 'command',
129
+ command: 'node $HOME/.claude/hooks/aria-pre-tool-gate.mjs',
130
+ timeout: 5,
131
+ },
132
+ {
133
+ // Pre-turn memory consumption gate (Enforcement Layer #49).
134
+ // Fires after the cognition gate passes. Checks the first action
135
+ // of each turn for ALL THREE context-loading signals:
136
+ // 1. 🔐 Aria Harness header (harness packet injected)
137
+ // 2. [ARIA_DIRECTION] / [ARIA_BINDING_PLAN] (preprompt-consult fired)
138
+ // 3. feedback_*.md / project_*.md memory reference (memory consumed)
139
+ // On miss: blocks with structured recovery JSON so the orchestrator
140
+ // can run the context-loader and retry — no dead-letter state.
141
+ // Turn-deduplication via ~/.claude/aria-turn-state-${sessionId}.json
142
+ // prevents retry loops (60s window).
143
+ type: 'command',
144
+ command: 'node $HOME/.claude/hooks/aria-preturn-memory-gate.mjs',
145
+ timeout: 5,
146
+ },
147
+ ],
148
+ },
149
+ {
150
+ // Sub-agent handoff: fires before every Agent spawn so the sub-agent
151
+ // inherits owner/client-tier identity + parent ledger path.
152
+ // Tier protection is inside the hook — client paths never touch ~/.claude/.
153
+ matcher: 'Agent',
154
+ hooks: [{
139
155
  type: 'command',
140
- command: 'node $HOME/.claude/hooks/aria-preturn-memory-gate.mjs',
156
+ command: 'node $HOME/.claude/hooks/aria-agent-handoff.mjs',
141
157
  timeout: 5,
142
- },
143
- ],
158
+ statusMessage: 'Writing sub-agent handoff...',
159
+ }],
160
+ },
161
+ ],
162
+ PostToolUse: [{
163
+ matcher: 'Agent',
164
+ hooks: [{
165
+ type: 'command',
166
+ command: 'node $HOME/.claude/hooks/aria-agent-ledger-merge.mjs',
167
+ timeout: 8,
168
+ statusMessage: 'Merging sub-agent ledger...',
169
+ }],
144
170
  }],
145
171
  Stop: [{
146
172
  // Stop gate — text-decision boundary. Reflexive replies fail this
@@ -210,10 +236,9 @@ function installSdk(claudeDir: string, logs: string[]): void {
210
236
  mkdirSync(sdkDst, { recursive: true, mode: 0o700 });
211
237
  }
212
238
  let copied = 0;
213
- const fs = require('fs') as typeof import('fs');
214
- for (const name of fs.readdirSync(sdkSrc)) {
239
+ for (const name of readdirSync(sdkSrc)) {
215
240
  const src = path.join(sdkSrc, name);
216
- const stat = fs.statSync(src);
241
+ const stat = statSync(src);
217
242
  if (!stat.isFile()) continue;
218
243
  const dst = path.join(sdkDst, name);
219
244
  copyFileSync(src, dst);
@@ -268,7 +293,7 @@ function wireHooksBlock(settings: Record<string, unknown>, logs: string[]): void
268
293
  if (!settings.$schema) {
269
294
  settings.$schema = 'https://json.schemastore.org/claude-code-settings.json';
270
295
  }
271
- logs.push(`Wired hooks into settings.json (${mergedEvents} events: SessionStart, UserPromptSubmit, PreToolUse [cognition+memory-gate], Stop) — merge-safe, preserves third-party entries`);
296
+ 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
297
  }
273
298
 
274
299
  function buildAriaSystemBlock(config: AriaConfig): string {