@aria_asi/cli 0.2.29 → 0.2.31

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.
Files changed (98) hide show
  1. package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
  2. package/dist/aria-connector/src/connectors/claude-code.js +88 -20
  3. package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
  4. package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
  5. package/dist/aria-connector/src/connectors/codex.js +526 -2
  6. package/dist/aria-connector/src/connectors/codex.js.map +1 -1
  7. package/dist/aria-connector/src/connectors/doctrine-trigger-map.d.ts +7 -0
  8. package/dist/aria-connector/src/connectors/doctrine-trigger-map.d.ts.map +1 -0
  9. package/dist/aria-connector/src/connectors/doctrine-trigger-map.js +87 -0
  10. package/dist/aria-connector/src/connectors/doctrine-trigger-map.js.map +1 -0
  11. package/dist/aria-connector/src/connectors/must-read.d.ts +4 -0
  12. package/dist/aria-connector/src/connectors/must-read.d.ts.map +1 -0
  13. package/dist/aria-connector/src/connectors/must-read.js +111 -0
  14. package/dist/aria-connector/src/connectors/must-read.js.map +1 -0
  15. package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
  16. package/dist/aria-connector/src/connectors/opencode.js +2 -0
  17. package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
  18. package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -1
  19. package/dist/aria-connector/src/connectors/runtime.js +231 -19
  20. package/dist/aria-connector/src/connectors/runtime.js.map +1 -1
  21. package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
  22. package/dist/aria-connector/src/connectors/shell.js +76 -3
  23. package/dist/aria-connector/src/connectors/shell.js.map +1 -1
  24. package/dist/aria-connector/src/self-update.d.ts +2 -1
  25. package/dist/aria-connector/src/self-update.d.ts.map +1 -1
  26. package/dist/aria-connector/src/self-update.js +84 -8
  27. package/dist/aria-connector/src/self-update.js.map +1 -1
  28. package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +53 -34
  29. package/dist/assets/hooks/aria-harness-via-sdk.mjs +126 -12
  30. package/dist/assets/hooks/aria-pre-tool-gate.mjs +185 -76
  31. package/dist/assets/hooks/aria-preturn-memory-gate.mjs +63 -14
  32. package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +2 -0
  33. package/dist/assets/hooks/aria-stop-gate.mjs +225 -52
  34. package/dist/assets/hooks/lib/canonical-lenses.mjs +6 -5
  35. package/dist/assets/hooks/lib/gate-loop-state.mjs +50 -0
  36. package/dist/assets/hooks/lib/hook-message-window.mjs +121 -0
  37. package/dist/assets/hooks/test-tier-lens-labeling.mjs +26 -58
  38. package/dist/assets/opencode-plugins/harness-gate/index.js +24 -2
  39. package/dist/assets/opencode-plugins/harness-stop/index.js +94 -5
  40. package/dist/runtime/auth-middleware.mjs +251 -0
  41. package/dist/runtime/codex-bridge.mjs +644 -0
  42. package/dist/runtime/discipline/CLAUDE.md +12 -0
  43. package/dist/runtime/discipline/doctrine_trigger_map.json +479 -0
  44. package/dist/runtime/doctrine_trigger_map.json +479 -0
  45. package/dist/runtime/fleet-engine.mjs +231 -0
  46. package/dist/runtime/harness-daemon.mjs +433 -0
  47. package/dist/runtime/local-phase.mjs +18 -0
  48. package/dist/runtime/manifest.json +1 -1
  49. package/dist/runtime/metering.mjs +100 -0
  50. package/dist/runtime/onboarding-engine.mjs +89 -0
  51. package/dist/runtime/plugin-engine.mjs +196 -0
  52. package/dist/runtime/sdk/BUNDLED.json +1 -1
  53. package/dist/runtime/sdk/index.d.ts +7 -0
  54. package/dist/runtime/sdk/index.js +120 -14
  55. package/dist/runtime/sdk/index.js.map +1 -1
  56. package/dist/runtime/service.mjs +1464 -67
  57. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +1 -1
  58. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -1
  59. package/dist/runtime/vendor/aria-gate-runtime/index.js +16 -1
  60. package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -1
  61. package/dist/runtime/workflow-engine.mjs +322 -0
  62. package/dist/sdk/BUNDLED.json +1 -1
  63. package/dist/sdk/index.d.ts +7 -0
  64. package/dist/sdk/index.js +120 -14
  65. package/dist/sdk/index.js.map +1 -1
  66. package/hooks/aria-cognition-substrate-binding.mjs +53 -34
  67. package/hooks/aria-harness-via-sdk.mjs +126 -12
  68. package/hooks/aria-pre-tool-gate.mjs +185 -76
  69. package/hooks/aria-preturn-memory-gate.mjs +63 -14
  70. package/hooks/aria-repo-doctrine-gate.mjs +2 -0
  71. package/hooks/aria-stop-gate.mjs +225 -52
  72. package/hooks/lib/canonical-lenses.mjs +6 -5
  73. package/hooks/lib/gate-loop-state.mjs +50 -0
  74. package/hooks/lib/hook-message-window.mjs +121 -0
  75. package/hooks/test-tier-lens-labeling.mjs +26 -58
  76. package/opencode-plugins/harness-gate/index.js +24 -2
  77. package/opencode-plugins/harness-stop/index.js +94 -5
  78. package/package.json +2 -2
  79. package/runtime-src/auth-middleware.mjs +251 -0
  80. package/runtime-src/codex-bridge.mjs +644 -0
  81. package/runtime-src/fleet-engine.mjs +231 -0
  82. package/runtime-src/harness-daemon.mjs +433 -0
  83. package/runtime-src/local-phase.mjs +18 -0
  84. package/runtime-src/metering.mjs +100 -0
  85. package/runtime-src/onboarding-engine.mjs +89 -0
  86. package/runtime-src/plugin-engine.mjs +196 -0
  87. package/runtime-src/service.mjs +1464 -67
  88. package/runtime-src/workflow-engine.mjs +322 -0
  89. package/scripts/bundle-sdk.mjs +5 -0
  90. package/src/connectors/claude-code.ts +98 -20
  91. package/src/connectors/codex.ts +534 -1
  92. package/src/connectors/doctrine-trigger-map.ts +112 -0
  93. package/src/connectors/must-read.ts +113 -0
  94. package/src/connectors/opencode.ts +3 -0
  95. package/src/connectors/runtime.ts +241 -21
  96. package/src/connectors/shell.ts +78 -3
  97. package/src/self-update.ts +89 -8
  98. package/dist/cli-0.2.0.tgz +0 -0
@@ -26,7 +26,10 @@ const LOG_FILE = `${HOME}/.claude/aria-harness-history.log`;
26
26
  const LAST_URL_CACHE = `${HOME}/.claude/.aria-harness-last-url`;
27
27
  const PACKET_CACHE = `${HOME}/.claude/.aria-harness-last-packet.json`;
28
28
  const SHARED_PACKET_CACHE = `${HOME}/.aria/.aria-harness-last-packet.json`;
29
+ const MIZAN_RECEIPT_DIR = `${HOME}/.claude/.aria-mizan-receipts`;
29
30
  const HEADER_PREFIX = '🔐 Aria Harness';
31
+ const DEFAULT_RUNTIME_URL = process.env.ARIA_RUNTIME_URL || 'http://127.0.0.1:4319';
32
+ const RUNTIME_PACKET_SUFFIX = '/packet';
30
33
 
31
34
  const args = process.argv.slice(2);
32
35
  const MODE = args.includes('--mode') ? args[args.indexOf('--mode') + 1] : 'session';
@@ -133,6 +136,8 @@ function buildUrlList() {
133
136
  const list = [];
134
137
  const cached = loadCachedUrl();
135
138
  if (cached) list.push(cached);
139
+ if (process.env.ARIA_RUNTIME_URL) list.push(process.env.ARIA_RUNTIME_URL.replace(/\/+$/, ''));
140
+ list.push(DEFAULT_RUNTIME_URL.replace(/\/+$/, ''));
136
141
  if (process.env.ARIA_HIVE_RUNTIME_URL) list.push(process.env.ARIA_HIVE_RUNTIME_URL.replace(/\/+$/, ''));
137
142
  if (process.env.ARIA_HARNESS_BASE_URL) list.push(process.env.ARIA_HARNESS_BASE_URL.replace(/\/+$/, ''));
138
143
  if (process.env.ARIA_HARNESS_URL) list.push(process.env.ARIA_HARNESS_URL.replace(/\/+$/, ''));
@@ -155,6 +160,21 @@ function buildUrlList() {
155
160
  return list.filter((u) => (seen.has(u) ? false : (seen.add(u), true)));
156
161
  }
157
162
 
163
+ function isMountedRuntimeUrl(baseUrl) {
164
+ return /:\/\/(?:127\.0\.0\.1|localhost):4319$/i.test(String(baseUrl || '').replace(/\/+$/, ''));
165
+ }
166
+
167
+ function normalizeHarnessPacketPayload(payload) {
168
+ let current = payload;
169
+ for (let depth = 0; depth < 3; depth++) {
170
+ if (!current || typeof current !== 'object' || Array.isArray(current)) break;
171
+ if (!('packet' in current) || !current.packet || typeof current.packet !== 'object') break;
172
+ if (!('timestamp' in current) && !('version' in current)) break;
173
+ current = current.packet;
174
+ }
175
+ return current;
176
+ }
177
+
158
178
  // SDK loader — dynamic-import the bundled HTTPHarnessClient from the shared
159
179
  // ~/.aria/sdk bundle first, then client-local bundles. Module-cached after
160
180
  // first load so we don't repeatedly read disk.
@@ -204,6 +224,7 @@ async function loadSdkClass() {
204
224
  // before forwarding to avoid blowing the POST body size limit; the most recent
205
225
  // messages are the most relevant for history-count purposes.
206
226
  let HOOK_EVENT_MESSAGES = undefined;
227
+ let HOOK_EVENT = null;
207
228
  try {
208
229
  // Claude Code hooks receive the event JSON on stdin. We read it synchronously
209
230
  // only if data is already available (i.e. piped); we don't block waiting for
@@ -211,6 +232,7 @@ try {
211
232
  // a terminal (e.g. manual invocation for testing).
212
233
  const stdinBuf = readFileSync('/dev/stdin', { flag: 'r' });
213
234
  const hookEvent = JSON.parse(stdinBuf.toString('utf8'));
235
+ HOOK_EVENT = hookEvent;
214
236
  if (Array.isArray(hookEvent?.messages) && hookEvent.messages.length > 0) {
215
237
  // Cap to last 50 messages. The server-side handler slices further if needed.
216
238
  HOOK_EVENT_MESSAGES = hookEvent.messages.slice(-50);
@@ -219,6 +241,81 @@ try {
219
241
  // stdin not available / not JSON / no messages field — HOOK_EVENT_MESSAGES stays undefined.
220
242
  }
221
243
 
244
+ function sanitizeSessionId(sessionId) {
245
+ return String(sessionId || 'claude-code').replace(/[^a-zA-Z0-9_-]/g, '_');
246
+ }
247
+
248
+ function lastUserMessageFromEvent() {
249
+ const messages = Array.isArray(HOOK_EVENT?.messages) ? HOOK_EVENT.messages : [];
250
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
251
+ const message = messages[index];
252
+ const role = message?.role || message?.message?.role || message?.type;
253
+ if (role !== 'user') continue;
254
+ const content = message?.content ?? message?.message?.content;
255
+ if (typeof content === 'string' && content.trim()) return content.trim();
256
+ if (Array.isArray(content)) {
257
+ const text = content
258
+ .filter((entry) => entry?.type === 'text' && typeof entry?.text === 'string')
259
+ .map((entry) => entry.text.trim())
260
+ .filter(Boolean)
261
+ .join('\n');
262
+ if (text) return text;
263
+ }
264
+ }
265
+ return isTurn ? 'Claude turn refresh via harness hook' : 'Claude session start via harness hook';
266
+ }
267
+
268
+ function receiptPathForSession(sessionId) {
269
+ return `${MIZAN_RECEIPT_DIR}/${sanitizeSessionId(sessionId)}.json`;
270
+ }
271
+
272
+ function persistMizanReceipt(sessionId, payload) {
273
+ try {
274
+ mkdirSync(MIZAN_RECEIPT_DIR, { recursive: true });
275
+ writeFileSync(receiptPathForSession(sessionId), JSON.stringify(payload, null, 2) + '\n');
276
+ } catch {}
277
+ }
278
+
279
+ async function runMizanPre(apiKey, packet, sourceLabel) {
280
+ if (!isTurn) return null;
281
+ const sessionId = HOOK_EVENT?.session_id || HOOK_EVENT?.sessionId || 'claude-code';
282
+ const response = await fetch(`${DEFAULT_RUNTIME_URL.replace(/\/+$/, '')}/mizan/pre`, {
283
+ method: 'POST',
284
+ headers: {
285
+ Authorization: `Bearer ${apiKey}`,
286
+ 'Content-Type': 'application/json',
287
+ },
288
+ body: JSON.stringify({
289
+ sessionId,
290
+ packet,
291
+ context: {
292
+ sessionId,
293
+ message: lastUserMessageFromEvent().slice(0, 4000),
294
+ intendedAction: 'Establish canonical pre-turn cognition receipt for this Claude turn before any tool or output work.',
295
+ rationale: `Claude turn-start harness sync via ${sourceLabel} must mint a canonical Mizan pre receipt for downstream tool and output enforcement.`,
296
+ platform: 'claude-code',
297
+ stage: 'hook-turn-pre',
298
+ },
299
+ }),
300
+ });
301
+ const payload = await response.json().catch(() => ({}));
302
+ if (!response.ok) {
303
+ throw new Error(payload?.error || `mizan/pre failed (${response.status})`);
304
+ }
305
+ if (payload?.receipt) {
306
+ persistMizanReceipt(sessionId, {
307
+ updatedAt: new Date().toISOString(),
308
+ source: sourceLabel,
309
+ sessionId,
310
+ receipt: payload.receipt,
311
+ result: payload.result || null,
312
+ contract: payload.contract || null,
313
+ summary: payload.summary || null,
314
+ });
315
+ }
316
+ return payload;
317
+ }
318
+
222
319
  async function tryViaSdk(baseUrl, apiKey) {
223
320
  // Canonical path: HTTPHarnessClient.getHarnessPacket(). The SDK POSTs to
224
321
  // /api/harness/codex with the right shape and returns { packet, timestamp,
@@ -228,16 +325,19 @@ async function tryViaSdk(baseUrl, apiKey) {
228
325
  // SDK's `body.packet ?? body` passes the body through unchanged).
229
326
  const Cls = await loadSdkClass();
230
327
  if (Cls) {
328
+ const packetUrl = isMountedRuntimeUrl(baseUrl)
329
+ ? `${baseUrl}${RUNTIME_PACKET_SUFFIX}`
330
+ : `${baseUrl}/api/harness/codex`;
231
331
  const client = new Cls({
232
332
  baseUrl,
233
333
  apiKey,
234
- harnessPacketUrl: `${baseUrl}/api/harness/codex`,
334
+ harnessPacketUrl: packetUrl,
235
335
  });
236
336
  // Pass a bodyOverride that does NOT include isHamza:false. The server
237
337
  // identifies owner tier from the Bearer token (isMasterTokenRequest).
238
338
  // Hardcoding isHamza:false in the body would override that server-side
239
339
  // signal and produce hamza:false in the packet even for master-token callers.
240
- const bodyOverride = {
340
+ const bodyOverride = {
241
341
  message: isTurn ? 'Claude turn refresh — harness via SDK' : 'Claude session start — harness via SDK',
242
342
  stage: isTurn ? 'checkpoint' : 'preflight',
243
343
  actor: 'claude-code',
@@ -246,15 +346,19 @@ async function tryViaSdk(baseUrl, apiKey) {
246
346
  // Bonus #74: forward conversation history so codex handler can report
247
347
  // a non-zero conversation_history_count in the packet.
248
348
  ...(HOOK_EVENT_MESSAGES ? { messages: HOOK_EVENT_MESSAGES } : {}),
249
- };
250
- const wrapped = await client.getHarnessPacket(bodyOverride);
251
- const json = wrapped.packet;
252
- if (json && json.ok === false) throw new Error(`ok=false: ${json.error || 'unknown'}`);
253
- return { json, raw: JSON.stringify(json) };
254
- }
349
+ };
350
+ const wrapped = await client.getHarnessPacket(bodyOverride);
351
+ const json = normalizeHarnessPacketPayload(wrapped.packet);
352
+ if (json && json.ok === false) throw new Error(`ok=false: ${json.error || 'unknown'}`);
353
+ await runMizanPre(apiKey, wrapped.packet, `${baseUrl}${RUNTIME_PACKET_SUFFIX}`);
354
+ return { json, raw: JSON.stringify(json) };
355
+ }
255
356
 
357
+ const packetUrl = isMountedRuntimeUrl(baseUrl)
358
+ ? `${baseUrl}${RUNTIME_PACKET_SUFFIX}`
359
+ : `${baseUrl}/api/harness/codex`;
256
360
  // SDK absent (dev environment) — direct fetch with identical wire shape.
257
- const resp = await fetch(`${baseUrl}/api/harness/codex`, {
361
+ const resp = await fetch(packetUrl, {
258
362
  method: 'POST',
259
363
  headers: {
260
364
  Authorization: `Bearer ${apiKey}`,
@@ -272,8 +376,10 @@ async function tryViaSdk(baseUrl, apiKey) {
272
376
  }),
273
377
  });
274
378
  if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
275
- const json = await resp.json();
379
+ const responseBody = await resp.json();
380
+ const json = normalizeHarnessPacketPayload(responseBody.packet ?? responseBody);
276
381
  if (json && json.ok === false) throw new Error(`ok=false: ${json.error || 'unknown'}`);
382
+ await runMizanPre(apiKey, responseBody.packet ?? responseBody, packetUrl);
277
383
  return { json, raw: JSON.stringify(json) };
278
384
  }
279
385
 
@@ -284,6 +390,9 @@ function renderPacket(json, source, ageNote = '') {
284
390
  const con = json.contractGate || {};
285
391
  const mc = json.missingCritical || [];
286
392
  const loaded = json.loadedByClass || {};
393
+ const offlineBundle = json.runtimeOfflineBundle && typeof json.runtimeOfflineBundle === 'object'
394
+ ? json.runtimeOfflineBundle
395
+ : null;
287
396
 
288
397
  let header = `${HEADER_PREFIX} (${MODE}${ageNote}, sdk=harness-http-client) hash=${phash.slice(0, 16)} via=${source}\n`;
289
398
  header += ` preStateGate: passed=${pre.passed} score=${(pre.score || 0).toFixed(2)}`;
@@ -292,6 +401,9 @@ function renderPacket(json, source, ageNote = '') {
292
401
  if (mc.length) header += `\n missingCritical: ${JSON.stringify(mc.slice(0, 5))}`;
293
402
  const loadedSummary = Object.entries(loaded).sort().map(([k, v]) => `${k}=${v}`).join(' ');
294
403
  if (loadedSummary) header += `\n loadedByClass: ${loadedSummary}`;
404
+ if (offlineBundle) {
405
+ header += `\n offlineBundle: phase=${offlineBundle.phase || 'unknown'} age=${offlineBundle.ageSeconds ?? 'unknown'}s source=${offlineBundle.source || 'runtime-cache'}`;
406
+ }
295
407
 
296
408
  let ctx = header;
297
409
  if (harness) {
@@ -344,8 +456,9 @@ async function main() {
344
456
  const stat = fs.statSync(PACKET_CACHE);
345
457
  const ageSec = (Date.now() - stat.mtimeMs) / 1000;
346
458
  if (ageSec < PACKET_CACHE_TTL_SEC) {
347
- const cached = JSON.parse(fs.readFileSync(PACKET_CACHE, 'utf8'));
348
- return renderPacket(cached, '(cache)', ` cached ${Math.round(ageSec)}s`);
459
+ const cached = JSON.parse(fs.readFileSync(PACKET_CACHE, 'utf8'));
460
+ await runMizanPre(apiKey, cached, '(cache)');
461
+ return renderPacket(cached, '(cache)', ` cached ${Math.round(ageSec)}s`);
349
462
  }
350
463
  } catch {}
351
464
  }
@@ -396,6 +509,7 @@ async function main() {
396
509
  const ageSec = (Date.now() - stat.mtimeMs) / 1000;
397
510
  if (ageSec >= 0) {
398
511
  const cached = JSON.parse(fs.readFileSync(PACKET_CACHE, 'utf8'));
512
+ await runMizanPre(apiKey, cached, '(stale-cache)');
399
513
  try {
400
514
  appendFileSync(LOG_FILE, `${new Date().toISOString()} stale mode=${MODE} cache_age=${Math.round(ageSec)}s last_err="${lastErr.replace(/"/g, "'")}" sdk=harness-http-client\n`);
401
515
  } catch {}