@aria_asi/cli 0.2.36 → 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 +310 -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 +308 -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
|
`;
|
|
@@ -433,8 +532,11 @@ import {
|
|
|
433
532
|
readEventFromStdin,
|
|
434
533
|
loadTurnState,
|
|
435
534
|
makeEvidenceRef,
|
|
535
|
+
recordCoachPhase,
|
|
436
536
|
saveTurnState,
|
|
437
537
|
runGovernanceGate,
|
|
538
|
+
updateTaskProjectLedger,
|
|
539
|
+
formatCodexRecoveryBlock,
|
|
438
540
|
emitJson,
|
|
439
541
|
} from './lib/runtime-client.mjs';
|
|
440
542
|
|
|
@@ -449,17 +551,52 @@ try {
|
|
|
449
551
|
if (!state?.preReceiptId && !state?.userText) {
|
|
450
552
|
emitJson({
|
|
451
553
|
decision: 'block',
|
|
452
|
-
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
|
+
}),
|
|
453
580
|
});
|
|
454
581
|
}
|
|
455
582
|
const actionCheck = await client.checkAction(action, target);
|
|
456
583
|
if (actionCheck?.allowed === false) {
|
|
457
584
|
emitJson({
|
|
458
585
|
decision: 'block',
|
|
459
|
-
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
|
+
}),
|
|
460
591
|
});
|
|
461
592
|
}
|
|
462
|
-
|
|
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
|
+
});
|
|
463
600
|
runGovernanceGate({
|
|
464
601
|
sessionId,
|
|
465
602
|
sourceRuntime: 'codex',
|
|
@@ -469,7 +606,7 @@ try {
|
|
|
469
606
|
toolName,
|
|
470
607
|
isDeploy: action === 'deploy',
|
|
471
608
|
isMutation: action === 'write' || action === 'delete',
|
|
472
|
-
evidence:
|
|
609
|
+
evidence: requestRef,
|
|
473
610
|
});
|
|
474
611
|
const tools = Array.isArray(state?.tools) ? state.tools.slice(-24) : [];
|
|
475
612
|
tools.push({
|
|
@@ -487,7 +624,10 @@ try {
|
|
|
487
624
|
} catch (error) {
|
|
488
625
|
emitJson({
|
|
489
626
|
decision: 'block',
|
|
490
|
-
reason:
|
|
627
|
+
reason: formatCodexRecoveryBlock({
|
|
628
|
+
surface: 'codex-pre-tool-hook',
|
|
629
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
630
|
+
}),
|
|
491
631
|
});
|
|
492
632
|
}
|
|
493
633
|
`;
|
|
@@ -500,7 +640,9 @@ import {
|
|
|
500
640
|
readEventFromStdin,
|
|
501
641
|
loadTurnState,
|
|
502
642
|
makeEvidenceRef,
|
|
643
|
+
recordCoachPhase,
|
|
503
644
|
saveTurnState,
|
|
645
|
+
updateTaskProjectLedger,
|
|
504
646
|
} from './lib/runtime-client.mjs';
|
|
505
647
|
|
|
506
648
|
const event = readEventFromStdin();
|
|
@@ -514,6 +656,20 @@ try {
|
|
|
514
656
|
toolName: event?.tool_name || event?.toolName || null,
|
|
515
657
|
});
|
|
516
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
|
+
});
|
|
517
673
|
toolOutputs.push({
|
|
518
674
|
at: new Date().toISOString(),
|
|
519
675
|
toolName: event?.tool_name || event?.toolName || null,
|
|
@@ -524,6 +680,17 @@ try {
|
|
|
524
680
|
toolOutputs,
|
|
525
681
|
lastEvent: 'PostToolUse',
|
|
526
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
|
+
});
|
|
527
694
|
process.exit(0);
|
|
528
695
|
} catch {
|
|
529
696
|
process.exit(0);
|
|
@@ -538,11 +705,17 @@ import {
|
|
|
538
705
|
extractAssistantText,
|
|
539
706
|
readEventFromStdin,
|
|
540
707
|
runtimePost,
|
|
708
|
+
recordCoachPhase,
|
|
541
709
|
loadTurnState,
|
|
542
710
|
makeEvidenceRef,
|
|
543
711
|
clearTurnState,
|
|
544
712
|
formatValidationFailure,
|
|
713
|
+
formatCodexRecoveryBlock,
|
|
714
|
+
isAriaControlBlock,
|
|
545
715
|
runGovernanceGate,
|
|
716
|
+
updateTaskProjectLedger,
|
|
717
|
+
evaluateTaskProjectClaim,
|
|
718
|
+
recordBlockedTaskProjectClaim,
|
|
546
719
|
emitJson,
|
|
547
720
|
} from './lib/runtime-client.mjs';
|
|
548
721
|
|
|
@@ -552,11 +725,58 @@ const state = loadTurnState(sessionId);
|
|
|
552
725
|
const text = extractAssistantText(event);
|
|
553
726
|
const outputRef = makeEvidenceRef('assistant_output', text, { sessionId, traceId: state?.traceId || null });
|
|
554
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
|
+
});
|
|
555
734
|
|
|
556
735
|
try {
|
|
557
736
|
if (!text) {
|
|
558
737
|
emitJson({ continue: true });
|
|
559
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
|
+
}
|
|
560
780
|
runGovernanceGate({
|
|
561
781
|
sessionId,
|
|
562
782
|
sourceRuntime: 'codex',
|
|
@@ -579,10 +799,31 @@ try {
|
|
|
579
799
|
requireCognitionBlock: false,
|
|
580
800
|
runLayer3: true,
|
|
581
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
|
+
}
|
|
582
820
|
if (validation?.pass === false || validation?.validation?.passed === false || validation?.layer3?.pass === false) {
|
|
583
821
|
emitJson({
|
|
584
822
|
decision: 'block',
|
|
585
|
-
reason:
|
|
823
|
+
reason: formatCodexRecoveryBlock({
|
|
824
|
+
surface: 'codex-stop-output',
|
|
825
|
+
reason: formatValidationFailure(validation),
|
|
826
|
+
}),
|
|
586
827
|
});
|
|
587
828
|
}
|
|
588
829
|
const post = await runtimePost('/mizan/post', {
|
|
@@ -607,6 +848,18 @@ try {
|
|
|
607
848
|
},
|
|
608
849
|
parentReceiptId: state?.preReceiptId || null,
|
|
609
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
|
+
});
|
|
610
863
|
await runtimePost('/decision/log', {
|
|
611
864
|
session_id: sessionId,
|
|
612
865
|
decision_type: 'operational',
|
|
@@ -643,12 +896,51 @@ try {
|
|
|
643
896
|
},
|
|
644
897
|
});
|
|
645
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
|
+
}
|
|
646
934
|
clearTurnState(sessionId);
|
|
647
935
|
emitJson({ continue: true });
|
|
648
936
|
} catch (error) {
|
|
649
937
|
emitJson({
|
|
650
938
|
decision: 'block',
|
|
651
|
-
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
|
+
}),
|
|
652
944
|
});
|
|
653
945
|
}
|
|
654
946
|
`;
|
|
@@ -696,6 +988,10 @@ function installCodexHooksConfig(codexDir: string, logs: string[]): void {
|
|
|
696
988
|
function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
697
989
|
const hooksDir = path.join(codexDir, 'hooks');
|
|
698
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
|
+
}
|
|
699
995
|
|
|
700
996
|
const files: Array<[string, string]> = [
|
|
701
997
|
[path.join(hooksDir, 'lib', 'runtime-client.mjs'), buildCodexHookRuntimeClient()],
|
|
@@ -709,6 +1005,8 @@ function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
|
709
1005
|
writeFileSync(filePath, content, { mode: 0o755 });
|
|
710
1006
|
try { chmodSync(filePath, 0o755); } catch {}
|
|
711
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 {}
|
|
712
1010
|
|
|
713
1011
|
logs.push(`Installed Codex native hooks → ${hooksDir}`);
|
|
714
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
|
|