@aria_asi/cli 0.2.36 → 0.2.38
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 +290 -32
- 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 +86 -8
- package/dist/assets/hooks/aria-pre-tool-use.mjs +75 -0
- 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 +377 -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 +86 -8
- package/dist/runtime/hooks/aria-pre-tool-use.mjs +75 -0
- 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 +86 -8
- package/hooks/aria-pre-tool-use.mjs +75 -0
- 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 +377 -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 +288 -32
- 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,20 +525,19 @@ try {
|
|
|
426
525
|
function buildCodexPreToolHook(): string {
|
|
427
526
|
return `#!/usr/bin/env node
|
|
428
527
|
import {
|
|
429
|
-
getHarnessClient,
|
|
430
528
|
inferSessionId,
|
|
431
529
|
classifyAction,
|
|
432
530
|
summarizeTarget,
|
|
433
531
|
readEventFromStdin,
|
|
434
532
|
loadTurnState,
|
|
435
533
|
makeEvidenceRef,
|
|
534
|
+
recordCoachPhase,
|
|
436
535
|
saveTurnState,
|
|
437
|
-
|
|
536
|
+
formatCodexRecoveryBlock,
|
|
438
537
|
emitJson,
|
|
439
538
|
} from './lib/runtime-client.mjs';
|
|
440
539
|
|
|
441
540
|
const event = readEventFromStdin();
|
|
442
|
-
const client = getHarnessClient();
|
|
443
541
|
const sessionId = inferSessionId(event);
|
|
444
542
|
const action = classifyAction(event);
|
|
445
543
|
const target = summarizeTarget(event);
|
|
@@ -449,28 +547,34 @@ try {
|
|
|
449
547
|
if (!state?.preReceiptId && !state?.userText) {
|
|
450
548
|
emitJson({
|
|
451
549
|
decision: 'block',
|
|
452
|
-
reason:
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
emitJson({
|
|
458
|
-
decision: 'block',
|
|
459
|
-
reason: actionCheck?.reason || \`Aria denied \${action}\`,
|
|
550
|
+
reason: formatCodexRecoveryBlock({
|
|
551
|
+
surface: 'codex-pre-tool',
|
|
552
|
+
reason: 'this turn has no pre-turn Mizan receipt',
|
|
553
|
+
next: '6. Re-submit the prompt so cognition is established before tool use, then request the tool again.',
|
|
554
|
+
}),
|
|
460
555
|
});
|
|
461
556
|
}
|
|
462
557
|
const toolName = String(event?.tool_name || event?.toolName || '').trim() || null;
|
|
463
|
-
|
|
558
|
+
const requestRef = makeEvidenceRef('codex_tool_request', { action, toolName, target }, { sessionId });
|
|
559
|
+
const coach = await recordCoachPhase('pre_tool', {
|
|
560
|
+
requestId: state?.traceId || sessionId,
|
|
464
561
|
sessionId,
|
|
465
|
-
|
|
466
|
-
surface: 'codex-pre-tool-use',
|
|
467
|
-
text: JSON.stringify(event).slice(0, 8000),
|
|
562
|
+
text: target,
|
|
468
563
|
action,
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
evidence: makeEvidenceRef('codex_tool_request', { action, toolName, target }, { sessionId }),
|
|
564
|
+
target,
|
|
565
|
+
evidenceRefs: [requestRef],
|
|
566
|
+
metadata: { source: 'codex-pre-tool-hook', toolName, requireVerify: action === 'deploy' || action === 'delete' },
|
|
473
567
|
});
|
|
568
|
+
if (coach?.permitted === false) {
|
|
569
|
+
emitJson({
|
|
570
|
+
decision: 'block',
|
|
571
|
+
reason: formatCodexRecoveryBlock({
|
|
572
|
+
surface: 'codex-pre-tool-coach',
|
|
573
|
+
reason: coach.clientMessage || 'Coach Kernel denied ' + action,
|
|
574
|
+
next: '6. Add the required evidence/cognition contract, then request the tool again.',
|
|
575
|
+
}),
|
|
576
|
+
});
|
|
577
|
+
}
|
|
474
578
|
const tools = Array.isArray(state?.tools) ? state.tools.slice(-24) : [];
|
|
475
579
|
tools.push({
|
|
476
580
|
at: new Date().toISOString(),
|
|
@@ -487,7 +591,10 @@ try {
|
|
|
487
591
|
} catch (error) {
|
|
488
592
|
emitJson({
|
|
489
593
|
decision: 'block',
|
|
490
|
-
reason:
|
|
594
|
+
reason: formatCodexRecoveryBlock({
|
|
595
|
+
surface: 'codex-pre-tool-hook',
|
|
596
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
597
|
+
}),
|
|
491
598
|
});
|
|
492
599
|
}
|
|
493
600
|
`;
|
|
@@ -500,7 +607,9 @@ import {
|
|
|
500
607
|
readEventFromStdin,
|
|
501
608
|
loadTurnState,
|
|
502
609
|
makeEvidenceRef,
|
|
610
|
+
recordCoachPhase,
|
|
503
611
|
saveTurnState,
|
|
612
|
+
updateTaskProjectLedger,
|
|
504
613
|
} from './lib/runtime-client.mjs';
|
|
505
614
|
|
|
506
615
|
const event = readEventFromStdin();
|
|
@@ -514,6 +623,20 @@ try {
|
|
|
514
623
|
toolName: event?.tool_name || event?.toolName || null,
|
|
515
624
|
});
|
|
516
625
|
const toolOutputs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.slice(-24) : [];
|
|
626
|
+
const verificationText = JSON.stringify(event).slice(0, 8000);
|
|
627
|
+
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);
|
|
628
|
+
await recordCoachPhase('post_tool', {
|
|
629
|
+
requestId: state?.traceId || sessionId,
|
|
630
|
+
sessionId,
|
|
631
|
+
text: verificationText,
|
|
632
|
+
evidenceRefs: [evidenceRef],
|
|
633
|
+
metadata: {
|
|
634
|
+
source: 'codex-post-tool-hook',
|
|
635
|
+
toolName: event?.tool_name || event?.toolName || null,
|
|
636
|
+
verification,
|
|
637
|
+
error: event?.error || null,
|
|
638
|
+
},
|
|
639
|
+
});
|
|
517
640
|
toolOutputs.push({
|
|
518
641
|
at: new Date().toISOString(),
|
|
519
642
|
toolName: event?.tool_name || event?.toolName || null,
|
|
@@ -524,6 +647,17 @@ try {
|
|
|
524
647
|
toolOutputs,
|
|
525
648
|
lastEvent: 'PostToolUse',
|
|
526
649
|
});
|
|
650
|
+
updateTaskProjectLedger({
|
|
651
|
+
platform: 'codex',
|
|
652
|
+
phase: 'post_tool',
|
|
653
|
+
source: 'codex-post-tool-hook',
|
|
654
|
+
event: { ...event, sessionId, cwd: process.cwd() },
|
|
655
|
+
evidence: {
|
|
656
|
+
outcome_ref: evidenceRef,
|
|
657
|
+
verification,
|
|
658
|
+
commandResult: verification ? 'success' : '',
|
|
659
|
+
},
|
|
660
|
+
});
|
|
527
661
|
process.exit(0);
|
|
528
662
|
} catch {
|
|
529
663
|
process.exit(0);
|
|
@@ -538,11 +672,16 @@ import {
|
|
|
538
672
|
extractAssistantText,
|
|
539
673
|
readEventFromStdin,
|
|
540
674
|
runtimePost,
|
|
675
|
+
recordCoachPhase,
|
|
541
676
|
loadTurnState,
|
|
542
677
|
makeEvidenceRef,
|
|
543
678
|
clearTurnState,
|
|
544
679
|
formatValidationFailure,
|
|
545
|
-
|
|
680
|
+
formatCodexRecoveryBlock,
|
|
681
|
+
isAriaControlBlock,
|
|
682
|
+
updateTaskProjectLedger,
|
|
683
|
+
evaluateTaskProjectClaim,
|
|
684
|
+
recordBlockedTaskProjectClaim,
|
|
546
685
|
emitJson,
|
|
547
686
|
} from './lib/runtime-client.mjs';
|
|
548
687
|
|
|
@@ -552,19 +691,58 @@ const state = loadTurnState(sessionId);
|
|
|
552
691
|
const text = extractAssistantText(event);
|
|
553
692
|
const outputRef = makeEvidenceRef('assistant_output', text, { sessionId, traceId: state?.traceId || null });
|
|
554
693
|
const toolRefs = Array.isArray(state?.toolOutputs) ? state.toolOutputs.map((entry) => entry.evidenceRef).filter(Boolean) : [];
|
|
694
|
+
const ledgerResult = updateTaskProjectLedger({
|
|
695
|
+
platform: 'codex',
|
|
696
|
+
phase: 'stop',
|
|
697
|
+
source: 'codex-stop-hook',
|
|
698
|
+
event: { ...event, text, sessionId, cwd: process.cwd() },
|
|
699
|
+
});
|
|
555
700
|
|
|
556
701
|
try {
|
|
557
702
|
if (!text) {
|
|
558
703
|
emitJson({ continue: true });
|
|
559
704
|
}
|
|
560
|
-
|
|
705
|
+
if (isAriaControlBlock(text)) {
|
|
706
|
+
clearTurnState(sessionId);
|
|
707
|
+
emitJson({ continue: true });
|
|
708
|
+
}
|
|
709
|
+
const postGenerationCoach = await recordCoachPhase('post_generation', {
|
|
710
|
+
requestId: state?.traceId || sessionId,
|
|
561
711
|
sessionId,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
isOutputCloseout: true,
|
|
566
|
-
evidence: outputRef,
|
|
712
|
+
text,
|
|
713
|
+
evidenceRefs: [outputRef],
|
|
714
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
567
715
|
});
|
|
716
|
+
if (postGenerationCoach?.permitted === false) {
|
|
717
|
+
emitJson({
|
|
718
|
+
decision: 'block',
|
|
719
|
+
reason: formatCodexRecoveryBlock({
|
|
720
|
+
surface: 'codex-stop-coach-post-generation',
|
|
721
|
+
reason: postGenerationCoach.clientMessage || 'Coach Kernel held Codex output before validation.',
|
|
722
|
+
}),
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
const ledgerClaim = evaluateTaskProjectClaim({ text, ledger: ledgerResult.ledger });
|
|
726
|
+
if (!ledgerClaim.ok) {
|
|
727
|
+
recordBlockedTaskProjectClaim({
|
|
728
|
+
ledger: ledgerResult.ledger,
|
|
729
|
+
paths: ledgerResult.paths,
|
|
730
|
+
text,
|
|
731
|
+
evaluation: ledgerClaim,
|
|
732
|
+
});
|
|
733
|
+
emitJson({
|
|
734
|
+
decision: 'block',
|
|
735
|
+
reason: formatCodexRecoveryBlock({
|
|
736
|
+
surface: 'codex-stop-ledger',
|
|
737
|
+
reason: 'task/project ledger rejected an output claim',
|
|
738
|
+
issues: [
|
|
739
|
+
\`missing readiness gates: \${ledgerClaim.missingReadinessGates.join(', ') || 'none'}\`,
|
|
740
|
+
\`open blockers: \${ledgerClaim.openBlockers.length}\`,
|
|
741
|
+
],
|
|
742
|
+
next: '6. Record real verification evidence or emit bounded status without completion/readiness language, then re-submit.',
|
|
743
|
+
}),
|
|
744
|
+
});
|
|
745
|
+
}
|
|
568
746
|
const validation = await runtimePost('/validate-output', {
|
|
569
747
|
text,
|
|
570
748
|
sessionId,
|
|
@@ -579,10 +757,31 @@ try {
|
|
|
579
757
|
requireCognitionBlock: false,
|
|
580
758
|
runLayer3: true,
|
|
581
759
|
});
|
|
760
|
+
const preOutputCoach = await recordCoachPhase('pre_output', {
|
|
761
|
+
requestId: state?.traceId || sessionId,
|
|
762
|
+
sessionId,
|
|
763
|
+
text,
|
|
764
|
+
validation: validation?.validation || null,
|
|
765
|
+
layer3: validation?.layer3 || null,
|
|
766
|
+
evidenceRefs: [outputRef, makeEvidenceRef('runtime_validation', validation, { sessionId, traceId: state?.traceId || null })],
|
|
767
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
768
|
+
});
|
|
769
|
+
if (preOutputCoach?.permitted === false) {
|
|
770
|
+
emitJson({
|
|
771
|
+
decision: 'block',
|
|
772
|
+
reason: formatCodexRecoveryBlock({
|
|
773
|
+
surface: 'codex-stop-coach-pre-output',
|
|
774
|
+
reason: preOutputCoach.clientMessage || 'Coach Kernel held Codex output before release.',
|
|
775
|
+
}),
|
|
776
|
+
});
|
|
777
|
+
}
|
|
582
778
|
if (validation?.pass === false || validation?.validation?.passed === false || validation?.layer3?.pass === false) {
|
|
583
779
|
emitJson({
|
|
584
780
|
decision: 'block',
|
|
585
|
-
reason:
|
|
781
|
+
reason: formatCodexRecoveryBlock({
|
|
782
|
+
surface: 'codex-stop-output',
|
|
783
|
+
reason: formatValidationFailure(validation),
|
|
784
|
+
}),
|
|
586
785
|
});
|
|
587
786
|
}
|
|
588
787
|
const post = await runtimePost('/mizan/post', {
|
|
@@ -607,6 +806,18 @@ try {
|
|
|
607
806
|
},
|
|
608
807
|
parentReceiptId: state?.preReceiptId || null,
|
|
609
808
|
});
|
|
809
|
+
await recordCoachPhase('post_output', {
|
|
810
|
+
requestId: state?.traceId || sessionId,
|
|
811
|
+
sessionId,
|
|
812
|
+
text,
|
|
813
|
+
validation: validation?.validation || null,
|
|
814
|
+
layer3: validation?.layer3 || null,
|
|
815
|
+
evidenceRefs: [
|
|
816
|
+
outputRef,
|
|
817
|
+
makeEvidenceRef('mizan_post_receipt', post?.receipt || null, { sessionId, traceId: state?.traceId || null }),
|
|
818
|
+
],
|
|
819
|
+
metadata: { source: 'codex-stop-hook', requireCognitionBlock: false, requireAppliedCognition: false },
|
|
820
|
+
});
|
|
610
821
|
await runtimePost('/decision/log', {
|
|
611
822
|
session_id: sessionId,
|
|
612
823
|
decision_type: 'operational',
|
|
@@ -643,12 +854,51 @@ try {
|
|
|
643
854
|
},
|
|
644
855
|
});
|
|
645
856
|
}
|
|
857
|
+
updateTaskProjectLedger({
|
|
858
|
+
platform: 'codex',
|
|
859
|
+
phase: 'post_turn',
|
|
860
|
+
source: 'codex-stop-hook',
|
|
861
|
+
event: { ...event, text, sessionId, cwd: process.cwd() },
|
|
862
|
+
evidence: {
|
|
863
|
+
post_turn: true,
|
|
864
|
+
output_ref: outputRef,
|
|
865
|
+
verification: false,
|
|
866
|
+
},
|
|
867
|
+
});
|
|
868
|
+
const releaseCoach = await recordCoachPhase('claim_or_release', {
|
|
869
|
+
requestId: state?.traceId || sessionId,
|
|
870
|
+
sessionId,
|
|
871
|
+
text,
|
|
872
|
+
validation: validation?.validation || null,
|
|
873
|
+
layer3: validation?.layer3 || null,
|
|
874
|
+
evidenceRefs: [outputRef, ...toolRefs],
|
|
875
|
+
metadata: {
|
|
876
|
+
source: 'codex-stop-hook',
|
|
877
|
+
validated_output: true,
|
|
878
|
+
requireCognitionBlock: false,
|
|
879
|
+
requireAppliedCognition: false,
|
|
880
|
+
post_receipt_id: post?.receipt?.receiptId || null,
|
|
881
|
+
},
|
|
882
|
+
});
|
|
883
|
+
if (releaseCoach?.permitted === false) {
|
|
884
|
+
emitJson({
|
|
885
|
+
decision: 'block',
|
|
886
|
+
reason: formatCodexRecoveryBlock({
|
|
887
|
+
surface: 'codex-stop-coach-release',
|
|
888
|
+
reason: releaseCoach.clientMessage || 'Coach Kernel held the release claim.',
|
|
889
|
+
}),
|
|
890
|
+
});
|
|
891
|
+
}
|
|
646
892
|
clearTurnState(sessionId);
|
|
647
893
|
emitJson({ continue: true });
|
|
648
894
|
} catch (error) {
|
|
649
895
|
emitJson({
|
|
650
896
|
decision: 'block',
|
|
651
|
-
reason:
|
|
897
|
+
reason: formatCodexRecoveryBlock({
|
|
898
|
+
surface: 'codex-stop-hook',
|
|
899
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
900
|
+
next: '6. Re-open the turn substrate, repair the hook/runtime blocker, and re-submit with this recovery contract if it repeats.',
|
|
901
|
+
}),
|
|
652
902
|
});
|
|
653
903
|
}
|
|
654
904
|
`;
|
|
@@ -696,6 +946,10 @@ function installCodexHooksConfig(codexDir: string, logs: string[]): void {
|
|
|
696
946
|
function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
697
947
|
const hooksDir = path.join(codexDir, 'hooks');
|
|
698
948
|
mkdirSync(path.join(hooksDir, 'lib'), { recursive: true, mode: 0o755 });
|
|
949
|
+
const ledgerHelperSrc = packageTaskProjectLedgerHelperPath();
|
|
950
|
+
if (!existsSync(ledgerHelperSrc)) {
|
|
951
|
+
throw new Error(`Task/project ledger helper missing: ${ledgerHelperSrc}`);
|
|
952
|
+
}
|
|
699
953
|
|
|
700
954
|
const files: Array<[string, string]> = [
|
|
701
955
|
[path.join(hooksDir, 'lib', 'runtime-client.mjs'), buildCodexHookRuntimeClient()],
|
|
@@ -709,6 +963,8 @@ function installCodexHooks(codexDir: string, logs: string[]): void {
|
|
|
709
963
|
writeFileSync(filePath, content, { mode: 0o755 });
|
|
710
964
|
try { chmodSync(filePath, 0o755); } catch {}
|
|
711
965
|
}
|
|
966
|
+
copyFileSync(ledgerHelperSrc, path.join(hooksDir, 'lib', 'task-project-ledger.mjs'));
|
|
967
|
+
try { chmodSync(path.join(hooksDir, 'lib', 'task-project-ledger.mjs'), 0o755); } catch {}
|
|
712
968
|
|
|
713
969
|
logs.push(`Installed Codex native hooks → ${hooksDir}`);
|
|
714
970
|
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
|
|