@aria_asi/cli 0.2.35 → 0.2.37
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/CLIENT-ONBOARDING.md +4 -2
- package/bin/aria.js +11 -7
- package/dist/aria-connector/src/auth.d.ts +14 -0
- package/dist/aria-connector/src/auth.d.ts.map +1 -1
- package/dist/aria-connector/src/auth.js +103 -1
- package/dist/aria-connector/src/auth.js.map +1 -1
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +13 -8
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/config.d.ts +6 -1
- package/dist/aria-connector/src/config.d.ts.map +1 -1
- package/dist/aria-connector/src/config.js.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +50 -6
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codex.js +312 -10
- package/dist/aria-connector/src/connectors/codex.js.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +35 -11
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.d.ts +10 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.js +110 -164
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.js +17 -7
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -1
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +12 -8
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/harness-client.d.ts +3 -1
- package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
- package/dist/aria-connector/src/harness-client.js +7 -20
- package/dist/aria-connector/src/harness-client.js.map +1 -1
- package/dist/aria-connector/src/model-context.d.ts.map +1 -1
- package/dist/aria-connector/src/model-context.js +5 -0
- package/dist/aria-connector/src/model-context.js.map +1 -1
- package/dist/aria-connector/src/providers/types.d.ts +1 -1
- package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
- package/dist/aria-connector/src/providers/xai.d.ts +3 -0
- package/dist/aria-connector/src/providers/xai.d.ts.map +1 -0
- package/dist/aria-connector/src/providers/xai.js +40 -0
- package/dist/aria-connector/src/providers/xai.js.map +1 -0
- package/dist/aria-connector/src/setup-wizard.js +1 -0
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/aria-connector/src/types.d.ts +2 -0
- package/dist/aria-connector/src/types.d.ts.map +1 -1
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/dist/assets/hooks/aria-first-class-coach.mjs +129 -0
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +33 -6
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +33 -8
- package/dist/assets/hooks/aria-preprompt-consult.mjs +5 -6
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/dist/assets/hooks/aria-stop-gate.mjs +125 -17
- package/dist/assets/hooks/doctrine_trigger_map.json +11 -0
- package/dist/assets/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/dist/assets/hooks/lib/emergency-gateoff.mjs +6 -0
- package/dist/assets/hooks/lib/first-class-coach.mjs +755 -0
- package/dist/assets/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/dist/assets/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/dist/assets/opencode-plugins/harness-context/auth-token.mjs +126 -0
- package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +62 -22
- package/dist/assets/opencode-plugins/harness-context/task-project-ledger.mjs +290 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +87 -27
- package/dist/assets/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -14
- package/dist/assets/opencode-plugins/harness-outcome/index.js +29 -24
- package/dist/assets/opencode-plugins/harness-stop/index.js +229 -68
- package/dist/assets/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -14
- package/dist/runtime/auth-token.mjs +121 -0
- package/dist/runtime/coach-kernel.mjs +371 -0
- package/dist/runtime/codex-bridge.mjs +440 -69
- package/dist/runtime/discipline/doctrine_trigger_map.json +11 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +18 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +18 -0
- package/dist/runtime/doctrine_trigger_map.json +11 -0
- package/dist/runtime/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/dist/runtime/hooks/aria-first-class-coach.mjs +129 -0
- package/dist/runtime/hooks/aria-harness-via-sdk.mjs +33 -6
- package/dist/runtime/hooks/aria-pre-tool-gate.mjs +33 -8
- package/dist/runtime/hooks/aria-preprompt-consult.mjs +5 -6
- package/dist/runtime/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/dist/runtime/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/dist/runtime/hooks/aria-stop-gate.mjs +125 -17
- package/dist/runtime/hooks/doctrine_trigger_map.json +11 -0
- package/dist/runtime/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/dist/runtime/hooks/lib/emergency-gateoff.mjs +6 -0
- package/dist/runtime/hooks/lib/first-class-coach.mjs +755 -0
- package/dist/runtime/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/dist/runtime/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/dist/runtime/local-phase.mjs +8 -0
- package/dist/runtime/manifest.json +2 -2
- package/dist/runtime/provider-proxy.mjs +136 -33
- package/dist/runtime/sdk/BUNDLED.json +2 -2
- package/dist/runtime/sdk/auth.d.ts +17 -0
- package/dist/runtime/sdk/auth.js +158 -0
- package/dist/runtime/sdk/auth.js.map +1 -0
- package/dist/runtime/sdk/index.d.ts +8 -1
- package/dist/runtime/sdk/index.js +15 -1
- package/dist/runtime/sdk/index.js.map +1 -1
- package/dist/runtime/service.mjs +1711 -74
- package/dist/runtime/task-project-ledger.mjs +290 -0
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/auth.d.ts +17 -0
- package/dist/sdk/auth.js +158 -0
- package/dist/sdk/auth.js.map +1 -0
- package/dist/sdk/index.d.ts +8 -1
- package/dist/sdk/index.js +15 -1
- package/dist/sdk/index.js.map +1 -1
- package/hooks/aria-cognition-substrate-binding.mjs +51 -9
- package/hooks/aria-first-class-coach.mjs +129 -0
- package/hooks/aria-harness-via-sdk.mjs +33 -6
- package/hooks/aria-pre-tool-gate.mjs +33 -8
- package/hooks/aria-preprompt-consult.mjs +5 -6
- package/hooks/aria-preturn-memory-gate.mjs +5 -0
- package/hooks/aria-repo-doctrine-gate.mjs +15 -0
- package/hooks/aria-stop-gate.mjs +125 -17
- package/hooks/doctrine_trigger_map.json +11 -0
- package/hooks/lib/emergency-gateoff-impl.mjs +39 -0
- package/hooks/lib/emergency-gateoff.mjs +6 -0
- package/hooks/lib/first-class-coach.mjs +755 -0
- package/hooks/lib/skill-autoload-gate-impl.mjs +103 -0
- package/hooks/lib/skill-autoload-gate.mjs +1 -14
- package/opencode-plugins/harness-context/auth-token.mjs +126 -0
- package/opencode-plugins/harness-context/inject-context.mjs +62 -22
- package/opencode-plugins/harness-context/task-project-ledger.mjs +290 -0
- package/opencode-plugins/harness-gate/index.js +87 -27
- package/opencode-plugins/harness-gate/lib/skill-autoload-gate.js +1 -14
- package/opencode-plugins/harness-outcome/index.js +29 -24
- package/opencode-plugins/harness-stop/index.js +229 -68
- package/opencode-plugins/harness-stop/lib/skill-autoload-gate.js +1 -14
- package/package.json +8 -2
- package/runtime-src/auth-token.mjs +121 -0
- package/runtime-src/coach-kernel.mjs +371 -0
- package/runtime-src/codex-bridge.mjs +440 -69
- package/runtime-src/local-phase.mjs +8 -0
- package/runtime-src/provider-proxy.mjs +136 -33
- package/runtime-src/service.mjs +1711 -74
- package/scripts/bundle-sdk.mjs +8 -0
- package/scripts/check-client-compatibility.mjs +422 -0
- package/scripts/check-coach-kernel.mjs +204 -0
- package/scripts/check-managed-runtime-ledger.mjs +107 -0
- package/scripts/check-opencode-config-contract.mjs +78 -0
- package/scripts/check-quality-ledger.mjs +121 -0
- package/scripts/self-test-harness-gates.mjs +179 -11
- package/scripts/self-test-repo-guard.mjs +38 -0
- package/scripts/validate-skill-prompts.mjs +14 -1
- package/skills/aria-cognition/aria-essence/SKILL.md +18 -0
- package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +18 -0
- package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +18 -0
- package/skills/aria-cognition/forge-quality-rules/SKILL.md +18 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +18 -0
- package/skills/aria-cognition/istiqra-induction/SKILL.md +18 -0
- package/skills/aria-cognition/ladunni-22/SKILL.md +18 -0
- package/skills/aria-cognition/mizan/SKILL.md +18 -0
- package/skills/aria-cognition/nadia/SKILL.md +18 -0
- package/skills/aria-cognition/nadia-psi/SKILL.md +18 -0
- package/skills/aria-cognition/predictor/SKILL.md +18 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +18 -0
- package/skills/aria-cognition/soul-domains/SKILL.md +18 -0
- package/src/auth.ts +136 -1
- package/src/chat.ts +13 -8
- package/src/config.ts +6 -1
- package/src/connectors/claude-code.ts +62 -18
- package/src/connectors/codex.ts +310 -10
- package/src/connectors/opencode.ts +35 -12
- package/src/connectors/repo-guard.ts +117 -172
- package/src/connectors/runtime.ts +19 -7
- package/src/connectors/shell.ts +12 -8
- package/src/harness-client.ts +8 -22
- package/src/model-context.ts +6 -0
- package/src/providers/types.ts +1 -1
- package/src/providers/xai.ts +55 -0
- package/src/setup-wizard.ts +1 -0
- package/src/types.ts +2 -0
package/src/connectors/codex.ts
CHANGED
|
@@ -24,6 +24,15 @@ function packageSdkDir(): string {
|
|
|
24
24
|
return path.resolve(here, '..', '..', '..', 'sdk');
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
function packageTaskProjectLedgerHelperPath(): string {
|
|
28
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
const candidates = [
|
|
30
|
+
path.resolve(here, '..', '..', '..', '..', 'opencode-plugins', 'harness-context', 'task-project-ledger.mjs'),
|
|
31
|
+
path.resolve(here, '..', '..', '..', 'assets', 'opencode-plugins', 'harness-context', 'task-project-ledger.mjs'),
|
|
32
|
+
];
|
|
33
|
+
return candidates.find((candidate) => existsSync(candidate)) || candidates[0];
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
function installSdk(codexDir: string, logs: string[]): void {
|
|
28
37
|
const sdkSrc = packageSdkDir();
|
|
29
38
|
if (!existsSync(sdkSrc)) {
|
|
@@ -95,6 +104,9 @@ import { createHash, randomUUID } from 'node:crypto';
|
|
|
95
104
|
import { homedir } from 'node:os';
|
|
96
105
|
import path from 'node:path';
|
|
97
106
|
import { HTTPHarnessClient } from '@aria_asi/harness-http-client';
|
|
107
|
+
import { updateTaskProjectLedger, evaluateTaskProjectClaim, recordBlockedTaskProjectClaim } from './task-project-ledger.mjs';
|
|
108
|
+
|
|
109
|
+
export { updateTaskProjectLedger, evaluateTaskProjectClaim, recordBlockedTaskProjectClaim };
|
|
98
110
|
|
|
99
111
|
const HOME = homedir();
|
|
100
112
|
const DEFAULT_RUNTIME_URL = (process.env.ARIA_RUNTIME_URL || 'http://127.0.0.1:4319').replace(/\\/+$/, '');
|
|
@@ -102,7 +114,7 @@ const TURN_STATE_DIR = path.join(HOME, '.codex', 'tmp', 'aria-hook-turn-state');
|
|
|
102
114
|
const GOVERNANCE_GATE_PATH = path.join(HOME, '.aria', 'bin', 'aria-governance-gate');
|
|
103
115
|
|
|
104
116
|
function readToken() {
|
|
105
|
-
const envToken = process.env.
|
|
117
|
+
const envToken = process.env.ARIA_HARNESS_TOKEN || process.env.ARIA_API_KEY || process.env.ARIA_MASTER_TOKEN;
|
|
106
118
|
if (envToken) return envToken;
|
|
107
119
|
const ownerPath = path.join(HOME, '.aria', 'owner-token');
|
|
108
120
|
if (existsSync(ownerPath)) return readFileSync(ownerPath, 'utf8').trim();
|
|
@@ -264,6 +276,24 @@ export async function runtimePost(route, body = {}) {
|
|
|
264
276
|
return response.json();
|
|
265
277
|
}
|
|
266
278
|
|
|
279
|
+
export async function recordCoachPhase(phase, body = {}) {
|
|
280
|
+
try {
|
|
281
|
+
return await runtimePost('/coach/phase', {
|
|
282
|
+
phase,
|
|
283
|
+
surface: 'codex-hooks',
|
|
284
|
+
lane: 'codex_native_hooks',
|
|
285
|
+
...body,
|
|
286
|
+
});
|
|
287
|
+
} catch (error) {
|
|
288
|
+
return {
|
|
289
|
+
ok: false,
|
|
290
|
+
permitted: true,
|
|
291
|
+
decision: 'warn_operator_only',
|
|
292
|
+
error: error instanceof Error ? error.message : String(error),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
267
297
|
export function classifyAction(event) {
|
|
268
298
|
const toolName = String(event?.tool_name || event?.toolName || '').trim();
|
|
269
299
|
const toolCommand = String(
|
|
@@ -307,6 +337,23 @@ export function extractAssistantText(event) {
|
|
|
307
337
|
);
|
|
308
338
|
}
|
|
309
339
|
|
|
340
|
+
function normalizeValidationIssue(issue) {
|
|
341
|
+
const raw = String(issue || '').replace(/\\s+/g, ' ').trim();
|
|
342
|
+
if (!raw) return '';
|
|
343
|
+
if (/No <cognition>/i.test(raw)) return 'missing readable cognition block';
|
|
344
|
+
if (/missing\\s+<applied_cognition>/i.test(raw)) return 'missing applied cognition contract';
|
|
345
|
+
if (/qualitative_drift/i.test(raw)) return 'qualitative drift language needs a measurable predicate';
|
|
346
|
+
if (/premature_task_closeout|feedback_no_premature_task_closeout|done\\|complete\\|completed\\|ready\\|verified\\|fixed/i.test(raw)) {
|
|
347
|
+
return 'completion/readiness claim conflicts with unresolved blocker state';
|
|
348
|
+
}
|
|
349
|
+
if (/\\(\\?:/.test(raw)) return 'doctrine matcher triggered; re-author with the named doctrine and concrete evidence';
|
|
350
|
+
return raw.slice(0, 600);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function uniqueStrings(values) {
|
|
354
|
+
return Array.from(new Set(values.map(normalizeValidationIssue).filter(Boolean)));
|
|
355
|
+
}
|
|
356
|
+
|
|
310
357
|
export function formatValidationFailure(result) {
|
|
311
358
|
const parts = [];
|
|
312
359
|
if (Array.isArray(result?.validation?.violations) && result.validation.violations.length) {
|
|
@@ -318,7 +365,31 @@ export function formatValidationFailure(result) {
|
|
|
318
365
|
if (!parts.length && typeof result?.summary === 'string' && result.summary.trim()) {
|
|
319
366
|
parts.push(result.summary.trim());
|
|
320
367
|
}
|
|
321
|
-
return parts.join(' | ') || 'Aria validation failed.';
|
|
368
|
+
return uniqueStrings(parts).join(' | ') || 'Aria validation failed.';
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export function isAriaControlBlock(text) {
|
|
372
|
+
return /^(?:ARIA CODEX RECOVERY CONTRACT|Aria runtime blocked final output for this Codex turn\\.|Aria stop gate blocked output:|Aria task\\/project ledger blocked output claim\\.|Aria stop hook failed closed:)/i.test(String(text || '').trim());
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function formatCodexRecoveryBlock({ surface = 'codex', reason = '', issues = [], next = '' } = {}) {
|
|
376
|
+
const blockers = uniqueStrings([reason, ...issues]);
|
|
377
|
+
return [
|
|
378
|
+
'ARIA CODEX RECOVERY CONTRACT',
|
|
379
|
+
'surface: ' + surface,
|
|
380
|
+
'status: output held for re-authoring',
|
|
381
|
+
'',
|
|
382
|
+
'Observed blockers:',
|
|
383
|
+
...(blockers.length ? blockers.map((item) => '- ' + item) : ['- Aria validation failed.']),
|
|
384
|
+
'',
|
|
385
|
+
'Recovery contract:',
|
|
386
|
+
'1. Do not retry the same blocked text.',
|
|
387
|
+
'2. Re-author the answer from the user request, not from this block report.',
|
|
388
|
+
'3. Include <cognition> and <applied_cognition> when the answer is non-trivial.',
|
|
389
|
+
'4. Use bounded status language when evidence is missing; do not use completion/readiness claims without proof.',
|
|
390
|
+
'5. Name a measurable verification predicate, or explicitly state that verification has not run.',
|
|
391
|
+
next || '6. Re-submit the corrected answer; if the same blocker repeats twice, escalate with this full recovery contract.',
|
|
392
|
+
].join('\\n');
|
|
322
393
|
}
|
|
323
394
|
|
|
324
395
|
export function emitJson(payload, code = 0) {
|
|
@@ -355,9 +426,12 @@ import {
|
|
|
355
426
|
makeEvidenceRef,
|
|
356
427
|
readEventFromStdin,
|
|
357
428
|
runtimePost,
|
|
429
|
+
recordCoachPhase,
|
|
358
430
|
loadTurnState,
|
|
359
431
|
saveTurnState,
|
|
360
432
|
runGovernanceGate,
|
|
433
|
+
updateTaskProjectLedger,
|
|
434
|
+
formatCodexRecoveryBlock,
|
|
361
435
|
emitJson,
|
|
362
436
|
} from './lib/runtime-client.mjs';
|
|
363
437
|
|
|
@@ -368,8 +442,21 @@ const sessionId = inferSessionId(event);
|
|
|
368
442
|
const userId = inferUserId(event);
|
|
369
443
|
const priorState = loadTurnState(sessionId);
|
|
370
444
|
const traceId = ensureTraceId(priorState);
|
|
445
|
+
const ledgerResult = updateTaskProjectLedger({
|
|
446
|
+
platform: 'codex',
|
|
447
|
+
phase: 'pre_prompt_injection',
|
|
448
|
+
source: 'codex-userprompt-hook',
|
|
449
|
+
event: { ...event, prompt: userText, sessionId, cwd: process.cwd() },
|
|
450
|
+
});
|
|
371
451
|
|
|
372
452
|
try {
|
|
453
|
+
await recordCoachPhase('pre_turn', {
|
|
454
|
+
requestId: traceId,
|
|
455
|
+
sessionId,
|
|
456
|
+
text: userText,
|
|
457
|
+
evidenceRefs: [makeEvidenceRef('user_input', userText, { sessionId, traceId, platform: 'codex' })],
|
|
458
|
+
metadata: { source: 'codex-userprompt-hook', userId },
|
|
459
|
+
});
|
|
373
460
|
const packet = await client.getHarnessPacket({
|
|
374
461
|
sessionId,
|
|
375
462
|
platform: 'codex',
|
|
@@ -404,11 +491,19 @@ try {
|
|
|
404
491
|
evidenceRefs: [packetRef],
|
|
405
492
|
},
|
|
406
493
|
});
|
|
494
|
+
await recordCoachPhase('post_cognition', {
|
|
495
|
+
requestId: traceId,
|
|
496
|
+
sessionId,
|
|
497
|
+
text: userText,
|
|
498
|
+
evidenceRefs: [packetRef, makeEvidenceRef('mizan_pre_receipt', result?.receipt || null, { sessionId, traceId })],
|
|
499
|
+
metadata: { source: 'codex-userprompt-hook', pre_receipt_id: result?.receipt?.receiptId || null },
|
|
500
|
+
});
|
|
407
501
|
saveTurnState(sessionId, {
|
|
408
502
|
traceId,
|
|
409
503
|
userId,
|
|
410
504
|
userText,
|
|
411
505
|
preReceiptId: result?.receipt?.receiptId || null,
|
|
506
|
+
taskProjectLedgerId: ledgerResult.ledger.ledgerId,
|
|
412
507
|
packetTimestamp: packet?.timestamp || null,
|
|
413
508
|
packetRef,
|
|
414
509
|
lastEvent: 'UserPromptSubmit',
|
|
@@ -417,7 +512,11 @@ try {
|
|
|
417
512
|
} catch (error) {
|
|
418
513
|
emitJson({
|
|
419
514
|
decision: 'block',
|
|
420
|
-
reason:
|
|
515
|
+
reason: formatCodexRecoveryBlock({
|
|
516
|
+
surface: 'codex-userprompt',
|
|
517
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
518
|
+
next: '6. Re-open the prompt substrate, repair the cognition gate blocker, then submit the prompt again.',
|
|
519
|
+
}),
|
|
421
520
|
});
|
|
422
521
|
}
|
|
423
522
|
`;
|
|
@@ -426,18 +525,23 @@ try {
|
|
|
426
525
|
function buildCodexPreToolHook(): string {
|
|
427
526
|
return `#!/usr/bin/env node
|
|
428
527
|
import {
|
|
528
|
+
getHarnessClient,
|
|
429
529
|
inferSessionId,
|
|
430
530
|
classifyAction,
|
|
431
531
|
summarizeTarget,
|
|
432
532
|
readEventFromStdin,
|
|
433
533
|
loadTurnState,
|
|
434
534
|
makeEvidenceRef,
|
|
535
|
+
recordCoachPhase,
|
|
435
536
|
saveTurnState,
|
|
436
537
|
runGovernanceGate,
|
|
538
|
+
updateTaskProjectLedger,
|
|
539
|
+
formatCodexRecoveryBlock,
|
|
437
540
|
emitJson,
|
|
438
541
|
} from './lib/runtime-client.mjs';
|
|
439
542
|
|
|
440
543
|
const event = readEventFromStdin();
|
|
544
|
+
const client = getHarnessClient();
|
|
441
545
|
const sessionId = inferSessionId(event);
|
|
442
546
|
const action = classifyAction(event);
|
|
443
547
|
const target = summarizeTarget(event);
|
|
@@ -447,17 +551,52 @@ try {
|
|
|
447
551
|
if (!state?.preReceiptId && !state?.userText) {
|
|
448
552
|
emitJson({
|
|
449
553
|
decision: 'block',
|
|
450
|
-
reason:
|
|
554
|
+
reason: formatCodexRecoveryBlock({
|
|
555
|
+
surface: 'codex-pre-tool',
|
|
556
|
+
reason: 'this turn has no pre-turn Mizan receipt',
|
|
557
|
+
next: '6. Re-submit the prompt so cognition is established before tool use, then request the tool again.',
|
|
558
|
+
}),
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
const toolName = String(event?.tool_name || event?.toolName || '').trim() || null;
|
|
562
|
+
const requestRef = makeEvidenceRef('codex_tool_request', { action, toolName, target }, { sessionId });
|
|
563
|
+
const coach = await recordCoachPhase('pre_tool', {
|
|
564
|
+
requestId: state?.traceId || sessionId,
|
|
565
|
+
sessionId,
|
|
566
|
+
text: target,
|
|
567
|
+
action,
|
|
568
|
+
target,
|
|
569
|
+
evidenceRefs: [requestRef],
|
|
570
|
+
metadata: { source: 'codex-pre-tool-hook', toolName, requireVerify: action === 'deploy' || action === 'delete' },
|
|
571
|
+
});
|
|
572
|
+
if (coach?.permitted === false) {
|
|
573
|
+
emitJson({
|
|
574
|
+
decision: 'block',
|
|
575
|
+
reason: formatCodexRecoveryBlock({
|
|
576
|
+
surface: 'codex-pre-tool-coach',
|
|
577
|
+
reason: coach.clientMessage || 'Coach Kernel denied ' + action,
|
|
578
|
+
next: '6. Add the required evidence/cognition contract, then request the tool again.',
|
|
579
|
+
}),
|
|
451
580
|
});
|
|
452
581
|
}
|
|
453
582
|
const actionCheck = await client.checkAction(action, target);
|
|
454
583
|
if (actionCheck?.allowed === false) {
|
|
455
584
|
emitJson({
|
|
456
585
|
decision: 'block',
|
|
457
|
-
reason:
|
|
586
|
+
reason: formatCodexRecoveryBlock({
|
|
587
|
+
surface: 'codex-pre-tool-action',
|
|
588
|
+
reason: actionCheck?.reason || \`Aria denied \${action}\`,
|
|
589
|
+
next: '6. Add the required verification/cognition contract for the action, then request the tool again.',
|
|
590
|
+
}),
|
|
458
591
|
});
|
|
459
592
|
}
|
|
460
|
-
|
|
593
|
+
updateTaskProjectLedger({
|
|
594
|
+
platform: 'codex',
|
|
595
|
+
phase: 'pre_tool',
|
|
596
|
+
source: 'codex-pre-tool-hook',
|
|
597
|
+
event: { ...event, sessionId, cwd: process.cwd() },
|
|
598
|
+
evidence: { action_ref: requestRef },
|
|
599
|
+
});
|
|
461
600
|
runGovernanceGate({
|
|
462
601
|
sessionId,
|
|
463
602
|
sourceRuntime: 'codex',
|
|
@@ -467,7 +606,7 @@ try {
|
|
|
467
606
|
toolName,
|
|
468
607
|
isDeploy: action === 'deploy',
|
|
469
608
|
isMutation: action === 'write' || action === 'delete',
|
|
470
|
-
evidence:
|
|
609
|
+
evidence: requestRef,
|
|
471
610
|
});
|
|
472
611
|
const tools = Array.isArray(state?.tools) ? state.tools.slice(-24) : [];
|
|
473
612
|
tools.push({
|
|
@@ -485,7 +624,10 @@ try {
|
|
|
485
624
|
} catch (error) {
|
|
486
625
|
emitJson({
|
|
487
626
|
decision: 'block',
|
|
488
|
-
reason:
|
|
627
|
+
reason: formatCodexRecoveryBlock({
|
|
628
|
+
surface: 'codex-pre-tool-hook',
|
|
629
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
630
|
+
}),
|
|
489
631
|
});
|
|
490
632
|
}
|
|
491
633
|
`;
|
|
@@ -498,7 +640,9 @@ import {
|
|
|
498
640
|
readEventFromStdin,
|
|
499
641
|
loadTurnState,
|
|
500
642
|
makeEvidenceRef,
|
|
643
|
+
recordCoachPhase,
|
|
501
644
|
saveTurnState,
|
|
645
|
+
updateTaskProjectLedger,
|
|
502
646
|
} from './lib/runtime-client.mjs';
|
|
503
647
|
|
|
504
648
|
const event = readEventFromStdin();
|
|
@@ -512,6 +656,20 @@ try {
|
|
|
512
656
|
toolName: event?.tool_name || event?.toolName || null,
|
|
513
657
|
});
|
|
514
658
|
const toolOutputs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.slice(-24) : [];
|
|
659
|
+
const verificationText = JSON.stringify(event).slice(0, 8000);
|
|
660
|
+
const verification = !event?.error && /\\b(?:npm\\s+run\\s+(?:check|test|build|lint|typecheck)|(?:npx\\s+)?(?:jest|vitest|tsc|eslint)|check:|test:|build:|passed|exit\\s*0|0\\s*failures?)\\b/i.test(verificationText);
|
|
661
|
+
await recordCoachPhase('post_tool', {
|
|
662
|
+
requestId: state?.traceId || sessionId,
|
|
663
|
+
sessionId,
|
|
664
|
+
text: verificationText,
|
|
665
|
+
evidenceRefs: [evidenceRef],
|
|
666
|
+
metadata: {
|
|
667
|
+
source: 'codex-post-tool-hook',
|
|
668
|
+
toolName: event?.tool_name || event?.toolName || null,
|
|
669
|
+
verification,
|
|
670
|
+
error: event?.error || null,
|
|
671
|
+
},
|
|
672
|
+
});
|
|
515
673
|
toolOutputs.push({
|
|
516
674
|
at: new Date().toISOString(),
|
|
517
675
|
toolName: event?.tool_name || event?.toolName || null,
|
|
@@ -522,6 +680,17 @@ try {
|
|
|
522
680
|
toolOutputs,
|
|
523
681
|
lastEvent: 'PostToolUse',
|
|
524
682
|
});
|
|
683
|
+
updateTaskProjectLedger({
|
|
684
|
+
platform: 'codex',
|
|
685
|
+
phase: 'post_tool',
|
|
686
|
+
source: 'codex-post-tool-hook',
|
|
687
|
+
event: { ...event, sessionId, cwd: process.cwd() },
|
|
688
|
+
evidence: {
|
|
689
|
+
outcome_ref: evidenceRef,
|
|
690
|
+
verification,
|
|
691
|
+
commandResult: verification ? 'success' : '',
|
|
692
|
+
},
|
|
693
|
+
});
|
|
525
694
|
process.exit(0);
|
|
526
695
|
} catch {
|
|
527
696
|
process.exit(0);
|
|
@@ -536,11 +705,17 @@ import {
|
|
|
536
705
|
extractAssistantText,
|
|
537
706
|
readEventFromStdin,
|
|
538
707
|
runtimePost,
|
|
708
|
+
recordCoachPhase,
|
|
539
709
|
loadTurnState,
|
|
540
710
|
makeEvidenceRef,
|
|
541
711
|
clearTurnState,
|
|
542
712
|
formatValidationFailure,
|
|
713
|
+
formatCodexRecoveryBlock,
|
|
714
|
+
isAriaControlBlock,
|
|
543
715
|
runGovernanceGate,
|
|
716
|
+
updateTaskProjectLedger,
|
|
717
|
+
evaluateTaskProjectClaim,
|
|
718
|
+
recordBlockedTaskProjectClaim,
|
|
544
719
|
emitJson,
|
|
545
720
|
} from './lib/runtime-client.mjs';
|
|
546
721
|
|
|
@@ -550,11 +725,58 @@ const state = loadTurnState(sessionId);
|
|
|
550
725
|
const text = extractAssistantText(event);
|
|
551
726
|
const outputRef = makeEvidenceRef('assistant_output', text, { sessionId, traceId: state?.traceId || null });
|
|
552
727
|
const toolRefs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.map((entry) => entry.evidenceRef).filter(Boolean) : [];
|
|
728
|
+
const ledgerResult = updateTaskProjectLedger({
|
|
729
|
+
platform: 'codex',
|
|
730
|
+
phase: 'stop',
|
|
731
|
+
source: 'codex-stop-hook',
|
|
732
|
+
event: { ...event, text, sessionId, cwd: process.cwd() },
|
|
733
|
+
});
|
|
553
734
|
|
|
554
735
|
try {
|
|
555
736
|
if (!text) {
|
|
556
737
|
emitJson({ continue: true });
|
|
557
738
|
}
|
|
739
|
+
if (isAriaControlBlock(text)) {
|
|
740
|
+
clearTurnState(sessionId);
|
|
741
|
+
emitJson({ continue: true });
|
|
742
|
+
}
|
|
743
|
+
const postGenerationCoach = await recordCoachPhase('post_generation', {
|
|
744
|
+
requestId: state?.traceId || sessionId,
|
|
745
|
+
sessionId,
|
|
746
|
+
text,
|
|
747
|
+
evidenceRefs: [outputRef],
|
|
748
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
749
|
+
});
|
|
750
|
+
if (postGenerationCoach?.permitted === false) {
|
|
751
|
+
emitJson({
|
|
752
|
+
decision: 'block',
|
|
753
|
+
reason: formatCodexRecoveryBlock({
|
|
754
|
+
surface: 'codex-stop-coach-post-generation',
|
|
755
|
+
reason: postGenerationCoach.clientMessage || 'Coach Kernel held Codex output before validation.',
|
|
756
|
+
}),
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
const ledgerClaim = evaluateTaskProjectClaim({ text, ledger: ledgerResult.ledger });
|
|
760
|
+
if (!ledgerClaim.ok) {
|
|
761
|
+
recordBlockedTaskProjectClaim({
|
|
762
|
+
ledger: ledgerResult.ledger,
|
|
763
|
+
paths: ledgerResult.paths,
|
|
764
|
+
text,
|
|
765
|
+
evaluation: ledgerClaim,
|
|
766
|
+
});
|
|
767
|
+
emitJson({
|
|
768
|
+
decision: 'block',
|
|
769
|
+
reason: formatCodexRecoveryBlock({
|
|
770
|
+
surface: 'codex-stop-ledger',
|
|
771
|
+
reason: 'task/project ledger rejected an output claim',
|
|
772
|
+
issues: [
|
|
773
|
+
\`missing readiness gates: \${ledgerClaim.missingReadinessGates.join(', ') || 'none'}\`,
|
|
774
|
+
\`open blockers: \${ledgerClaim.openBlockers.length}\`,
|
|
775
|
+
],
|
|
776
|
+
next: '6. Record real verification evidence or emit bounded status without completion/readiness language, then re-submit.',
|
|
777
|
+
}),
|
|
778
|
+
});
|
|
779
|
+
}
|
|
558
780
|
runGovernanceGate({
|
|
559
781
|
sessionId,
|
|
560
782
|
sourceRuntime: 'codex',
|
|
@@ -577,10 +799,31 @@ try {
|
|
|
577
799
|
requireCognitionBlock: false,
|
|
578
800
|
runLayer3: true,
|
|
579
801
|
});
|
|
802
|
+
const preOutputCoach = await recordCoachPhase('pre_output', {
|
|
803
|
+
requestId: state?.traceId || sessionId,
|
|
804
|
+
sessionId,
|
|
805
|
+
text,
|
|
806
|
+
validation: validation?.validation || null,
|
|
807
|
+
layer3: validation?.layer3 || null,
|
|
808
|
+
evidenceRefs: [outputRef, makeEvidenceRef('runtime_validation', validation, { sessionId, traceId: state?.traceId || null })],
|
|
809
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
810
|
+
});
|
|
811
|
+
if (preOutputCoach?.permitted === false) {
|
|
812
|
+
emitJson({
|
|
813
|
+
decision: 'block',
|
|
814
|
+
reason: formatCodexRecoveryBlock({
|
|
815
|
+
surface: 'codex-stop-coach-pre-output',
|
|
816
|
+
reason: preOutputCoach.clientMessage || 'Coach Kernel held Codex output before release.',
|
|
817
|
+
}),
|
|
818
|
+
});
|
|
819
|
+
}
|
|
580
820
|
if (validation?.pass === false || validation?.validation?.passed === false || validation?.layer3?.pass === false) {
|
|
581
821
|
emitJson({
|
|
582
822
|
decision: 'block',
|
|
583
|
-
reason:
|
|
823
|
+
reason: formatCodexRecoveryBlock({
|
|
824
|
+
surface: 'codex-stop-output',
|
|
825
|
+
reason: formatValidationFailure(validation),
|
|
826
|
+
}),
|
|
584
827
|
});
|
|
585
828
|
}
|
|
586
829
|
const post = await runtimePost('/mizan/post', {
|
|
@@ -605,6 +848,18 @@ try {
|
|
|
605
848
|
},
|
|
606
849
|
parentReceiptId: state?.preReceiptId || null,
|
|
607
850
|
});
|
|
851
|
+
await recordCoachPhase('post_output', {
|
|
852
|
+
requestId: state?.traceId || sessionId,
|
|
853
|
+
sessionId,
|
|
854
|
+
text,
|
|
855
|
+
validation: validation?.validation || null,
|
|
856
|
+
layer3: validation?.layer3 || null,
|
|
857
|
+
evidenceRefs: [
|
|
858
|
+
outputRef,
|
|
859
|
+
makeEvidenceRef('mizan_post_receipt', post?.receipt || null, { sessionId, traceId: state?.traceId || null }),
|
|
860
|
+
],
|
|
861
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
862
|
+
});
|
|
608
863
|
await runtimePost('/decision/log', {
|
|
609
864
|
session_id: sessionId,
|
|
610
865
|
decision_type: 'operational',
|
|
@@ -641,12 +896,51 @@ try {
|
|
|
641
896
|
},
|
|
642
897
|
});
|
|
643
898
|
}
|
|
899
|
+
updateTaskProjectLedger({
|
|
900
|
+
platform: 'codex',
|
|
901
|
+
phase: 'post_turn',
|
|
902
|
+
source: 'codex-stop-hook',
|
|
903
|
+
event: { ...event, text, sessionId, cwd: process.cwd() },
|
|
904
|
+
evidence: {
|
|
905
|
+
post_turn: true,
|
|
906
|
+
output_ref: outputRef,
|
|
907
|
+
verification: false,
|
|
908
|
+
},
|
|
909
|
+
});
|
|
910
|
+
const releaseCoach = await recordCoachPhase('claim_or_release', {
|
|
911
|
+
requestId: state?.traceId || sessionId,
|
|
912
|
+
sessionId,
|
|
913
|
+
text,
|
|
914
|
+
validation: validation?.validation || null,
|
|
915
|
+
layer3: validation?.layer3 || null,
|
|
916
|
+
evidenceRefs: [outputRef, ...toolRefs],
|
|
917
|
+
metadata: {
|
|
918
|
+
source: 'codex-stop-hook',
|
|
919
|
+
validated_output: true,
|
|
920
|
+
requireCognitionBlock: false,
|
|
921
|
+
requireAppliedCognition: false,
|
|
922
|
+
post_receipt_id: post?.receipt?.receiptId || null,
|
|
923
|
+
},
|
|
924
|
+
});
|
|
925
|
+
if (releaseCoach?.permitted === false) {
|
|
926
|
+
emitJson({
|
|
927
|
+
decision: 'block',
|
|
928
|
+
reason: formatCodexRecoveryBlock({
|
|
929
|
+
surface: 'codex-stop-coach-release',
|
|
930
|
+
reason: releaseCoach.clientMessage || 'Coach Kernel held the release claim.',
|
|
931
|
+
}),
|
|
932
|
+
});
|
|
933
|
+
}
|
|
644
934
|
clearTurnState(sessionId);
|
|
645
935
|
emitJson({ continue: true });
|
|
646
936
|
} catch (error) {
|
|
647
937
|
emitJson({
|
|
648
938
|
decision: 'block',
|
|
649
|
-
reason:
|
|
939
|
+
reason: formatCodexRecoveryBlock({
|
|
940
|
+
surface: 'codex-stop-hook',
|
|
941
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
942
|
+
next: '6. Re-open the turn substrate, repair the hook/runtime blocker, and re-submit with this recovery contract if it repeats.',
|
|
943
|
+
}),
|
|
650
944
|
});
|
|
651
945
|
}
|
|
652
946
|
`;
|
|
@@ -694,6 +988,10 @@ function installCodexHooksConfig(codexDir: string, logs: string[]): void {
|
|
|
694
988
|
function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
695
989
|
const hooksDir = path.join(codexDir, 'hooks');
|
|
696
990
|
mkdirSync(path.join(hooksDir, 'lib'), { recursive: true, mode: 0o755 });
|
|
991
|
+
const ledgerHelperSrc = packageTaskProjectLedgerHelperPath();
|
|
992
|
+
if (!existsSync(ledgerHelperSrc)) {
|
|
993
|
+
throw new Error(`Task/project ledger helper missing: ${ledgerHelperSrc}`);
|
|
994
|
+
}
|
|
697
995
|
|
|
698
996
|
const files: Array<[string, string]> = [
|
|
699
997
|
[path.join(hooksDir, 'lib', 'runtime-client.mjs'), buildCodexHookRuntimeClient()],
|
|
@@ -707,6 +1005,8 @@ function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
|
707
1005
|
writeFileSync(filePath, content, { mode: 0o755 });
|
|
708
1006
|
try { chmodSync(filePath, 0o755); } catch {}
|
|
709
1007
|
}
|
|
1008
|
+
copyFileSync(ledgerHelperSrc, path.join(hooksDir, 'lib', 'task-project-ledger.mjs'));
|
|
1009
|
+
try { chmodSync(path.join(hooksDir, 'lib', 'task-project-ledger.mjs'), 0o755); } catch {}
|
|
710
1010
|
|
|
711
1011
|
logs.push(`Installed Codex native hooks → ${hooksDir}`);
|
|
712
1012
|
installCodexHooksConfig(codexDir, logs);
|
|
@@ -18,6 +18,7 @@ import type { AriaConfig } from '../config.js';
|
|
|
18
18
|
import { connectShell } from './shell.js';
|
|
19
19
|
import { syncDoctrineTriggerMap } from './doctrine-trigger-map.js';
|
|
20
20
|
import { buildMustReadGuide, mustReadIntro } from './must-read.js';
|
|
21
|
+
import { resolveHarnessToken } from '../auth.js';
|
|
21
22
|
|
|
22
23
|
// ── Bundled OpenCode plugins ────────────────────────────────────────────────
|
|
23
24
|
//
|
|
@@ -33,6 +34,8 @@ import { buildMustReadGuide, mustReadIntro } from './must-read.js';
|
|
|
33
34
|
// Both live at <pkg>/opencode-plugins/<name>/. connectOpenCode copies them
|
|
34
35
|
// into ~/.opencode/plugins/<name>/ and wires the absolute paths into
|
|
35
36
|
// ~/.opencode/config.json's `plugin` (singular, OpenCode v2 schema) array.
|
|
37
|
+
// Shared hook helpers are also copied into ~/.opencode/hooks/ because the
|
|
38
|
+
// installed plugins resolve their gate helpers from that OpenCode-owned root.
|
|
36
39
|
//
|
|
37
40
|
// Compiled location of THIS file (claude-code path applies the same way):
|
|
38
41
|
// <pkg>/dist/aria-connector/src/connectors/opencode.js
|
|
@@ -51,6 +54,16 @@ function packageOpenCodePluginsDir(): string {
|
|
|
51
54
|
return found || candidates[0];
|
|
52
55
|
}
|
|
53
56
|
|
|
57
|
+
function packageOpenCodeHooksDir(): string {
|
|
58
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
59
|
+
const candidates = [
|
|
60
|
+
path.resolve(here, '..', '..', '..', '..', 'hooks'),
|
|
61
|
+
path.resolve(here, '..', '..', '..', 'assets', 'hooks'),
|
|
62
|
+
];
|
|
63
|
+
const found = candidates.find((candidate) => existsSync(candidate));
|
|
64
|
+
return found || candidates[0];
|
|
65
|
+
}
|
|
66
|
+
|
|
54
67
|
function copyPluginDir(srcDir: string, dstDir: string, logs: string[]): void {
|
|
55
68
|
if (!existsSync(dstDir)) {
|
|
56
69
|
mkdirSync(dstDir, { recursive: true, mode: 0o755 });
|
|
@@ -58,8 +71,12 @@ function copyPluginDir(srcDir: string, dstDir: string, logs: string[]): void {
|
|
|
58
71
|
for (const name of readdirSync(srcDir)) {
|
|
59
72
|
const src = path.join(srcDir, name);
|
|
60
73
|
const stat = statSync(src);
|
|
61
|
-
if (!stat.isFile()) continue;
|
|
62
74
|
const dst = path.join(dstDir, name);
|
|
75
|
+
if (stat.isDirectory()) {
|
|
76
|
+
copyPluginDir(src, dst, logs);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (!stat.isFile()) continue;
|
|
63
80
|
copyFileSync(src, dst);
|
|
64
81
|
if (name.endsWith('.mjs') || name.endsWith('.js')) {
|
|
65
82
|
try {
|
|
@@ -141,11 +158,22 @@ export async function connectOpenCode(config: AriaConfig): Promise<string[]> {
|
|
|
141
158
|
copyPluginDir(srcDir, dstDir, logs);
|
|
142
159
|
installedPaths.push(dstDir);
|
|
143
160
|
}
|
|
161
|
+
|
|
162
|
+
const bundledHooksDir = packageOpenCodeHooksDir();
|
|
163
|
+
if (existsSync(bundledHooksDir)) {
|
|
164
|
+
copyPluginDir(bundledHooksDir, path.join(opencodeDir, 'hooks'), logs);
|
|
165
|
+
} else {
|
|
166
|
+
logs.push(`⚠ Bundled OpenCode hook helpers missing: ${bundledHooksDir} — gate plugins may fail to load`);
|
|
167
|
+
}
|
|
144
168
|
syncDoctrineTriggerMap(logs);
|
|
145
169
|
|
|
146
|
-
// ── Wire
|
|
147
|
-
const
|
|
148
|
-
|
|
170
|
+
// ── Wire OpenCode config files ────────────────────────────────────────────
|
|
171
|
+
const configPaths = [
|
|
172
|
+
path.join(opencodeDir, 'config.json'),
|
|
173
|
+
path.join(homedir(), '.config', 'opencode', 'config.json'),
|
|
174
|
+
];
|
|
175
|
+
for (const configPath of configPaths) {
|
|
176
|
+
if (!existsSync(configPath)) continue;
|
|
149
177
|
try {
|
|
150
178
|
const opencodeConfig: Record<string, unknown> = JSON.parse(
|
|
151
179
|
readFileSync(configPath, 'utf-8'),
|
|
@@ -191,19 +219,14 @@ export async function connectOpenCode(config: AriaConfig): Promise<string[]> {
|
|
|
191
219
|
logs.push(`Wired ${installedPaths.length} Aria plugin(s) into OpenCode config.plugin`);
|
|
192
220
|
}
|
|
193
221
|
|
|
194
|
-
if (!opencodeConfig.agentsMdPath) {
|
|
195
|
-
opencodeConfig.agentsMdPath = path.join(homedir(), '.aria', 'AGENTS.md');
|
|
196
|
-
modified = true;
|
|
197
|
-
logs.push('Set OpenCode AGENTS.md path to ~/.aria/AGENTS.md');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
222
|
const providerMap = opencodeConfig.provider && typeof opencodeConfig.provider === 'object'
|
|
201
223
|
? opencodeConfig.provider as Record<string, unknown>
|
|
202
224
|
: {};
|
|
203
225
|
const currentAriaProvider = providerMap.aria && typeof providerMap.aria === 'object'
|
|
204
226
|
? providerMap.aria as Record<string, unknown>
|
|
205
227
|
: {};
|
|
206
|
-
const
|
|
228
|
+
const resolvedLocalToken = await resolveHarnessToken({ baseUrl: LOCAL_RUNTIME_V1_URL });
|
|
229
|
+
const localToken = resolvedLocalToken.token || resolveLocalRuntimeToken();
|
|
207
230
|
const nextAriaProvider = {
|
|
208
231
|
npm: '@ai-sdk/openai-compatible',
|
|
209
232
|
name: 'Aria Runtime',
|
|
@@ -252,7 +275,7 @@ export async function connectOpenCode(config: AriaConfig): Promise<string[]> {
|
|
|
252
275
|
logs.push('OpenCode already configured for Aria');
|
|
253
276
|
}
|
|
254
277
|
} catch {
|
|
255
|
-
logs.push(
|
|
278
|
+
logs.push(`Failed to parse OpenCode config.json at ${configPath}`);
|
|
256
279
|
}
|
|
257
280
|
}
|
|
258
281
|
|