@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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// ARIA_ALLOW_STUB: this gate helper must match doctrine trigger words as data.
|
|
2
|
+
const POST = /\b(?:post[_ -]?compact[_ -]?continuation|handoff[_ -]?resume|continuation[_ -]?handoff|post-compact|compact(?:ion)? handoff|post\s+commission)\b/i;
|
|
3
|
+
const OFF = /\bGATEOFF\b/i;
|
|
4
|
+
const SKILL_CONTENT_RX = /<skill_content\s+name=["']([^"']+)["']/gi;
|
|
5
|
+
const DEPLOY_VERIFY_RX = /<verify>[\s\S]*?target\s*:[\s\S]*?role\s*:[\s\S]*?verified\s*:[\s\S]*?rollback\s*:[\s\S]*?axiom\s*:[\s\S]*?<\/verify>/i;
|
|
6
|
+
const COGNITION_BLOCK_RX = /<cognition>[\s\S]*?nur\s*:[\s\S]*?mizan\s*:[\s\S]*?hikma\s*:[\s\S]*?tafakkur\s*:[\s\S]*?tadabbur\s*:[\s\S]*?ilham\s*:[\s\S]*?wahi\s*:[\s\S]*?firasah\s*:[\s\S]*?<\/cognition>/i;
|
|
7
|
+
const EXPECTED_BLOCK_RX = /<expected>[\s\S]*?predicate\s*:[\s\S]*?measurable_type\s*:[\s\S]*?<\/expected>/i;
|
|
8
|
+
const APPLIED_COGNITION_RX = /<applied_cognition>[\s\S]*?decision_delta\s*:[\s\S]*?dominant_domain\s*:[\s\S]*?binds_to\s*:[\s\S]*?expected_predicate\s*:[\s\S]*?artifact_change\s*:[\s\S]*?<\/applied_cognition>/i;
|
|
9
|
+
const NO_STRIPPING_BLOCK_RX = /<no_stripping>[\s\S]*?preserved_contract\s*:[\s\S]*?root_mechanism\s*:[\s\S]*?removed_surface\s*:\s*none[\s\S]*?verification\s*:[\s\S]*?<\/no_stripping>/i;
|
|
10
|
+
|
|
11
|
+
function bypass(text) {
|
|
12
|
+
return /^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_GATES_OFF || process.env.ARIA_HARNESS_GATES_OFF || '')) || POST.test(String(text || '')) || OFF.test(String(text || ''));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function addSkill(set, skill) {
|
|
16
|
+
const normalized = String(skill || '').trim();
|
|
17
|
+
if (normalized) set.add(normalized);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function collectLoadedSkills(options = {}, body = '') {
|
|
21
|
+
const loaded = new Set();
|
|
22
|
+
for (const m of String(body || '').matchAll(SKILL_CONTENT_RX)) addSkill(loaded, m[1]);
|
|
23
|
+
for (const skill of Array.isArray(options.loadedSkills) ? options.loadedSkills : []) addSkill(loaded, skill);
|
|
24
|
+
return loaded;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function collectContractEvidence(options = {}, body = '') {
|
|
28
|
+
const evidence = new Set();
|
|
29
|
+
if (DEPLOY_VERIFY_RX.test(body) && COGNITION_BLOCK_RX.test(body) && EXPECTED_BLOCK_RX.test(body)) {
|
|
30
|
+
evidence.add('aria-harness-deploy');
|
|
31
|
+
evidence.add('aria-forge-guardrails');
|
|
32
|
+
evidence.add('aria-harness-output-discipline');
|
|
33
|
+
}
|
|
34
|
+
if (APPLIED_COGNITION_RX.test(body)) evidence.add('aria-forge-guardrails');
|
|
35
|
+
if (NO_STRIPPING_BLOCK_RX.test(body)) evidence.add('aria-harness-no-stripping');
|
|
36
|
+
if (options.repoDoctrineVerified === true) evidence.add('aria-repo-doctrine');
|
|
37
|
+
if (options.noStrippingVerified === true) evidence.add('aria-harness-no-stripping');
|
|
38
|
+
if (options.outputDisciplineVerified === true) evidence.add('aria-harness-output-discipline');
|
|
39
|
+
return evidence;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function recordSkillLoaded({ skill } = {}) {
|
|
43
|
+
return { skill, recordedAt: new Date().toISOString() };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function classifyRequiredSkills({ text = '', action = '', toolName = '', filePath = '', isDeploy = false, isMutation = false, isOutputCloseout = false } = {}) {
|
|
47
|
+
const c = [text, action, toolName, filePath].filter(Boolean).join('\n');
|
|
48
|
+
const required = new Set();
|
|
49
|
+
const reasons = [];
|
|
50
|
+
const recoveryMissing = [];
|
|
51
|
+
let redirectOnly = false;
|
|
52
|
+
if (bypass(c)) return { requiredSkills: [], recoveryMissing: [], reasons: ['post-compaction or emergency gate-off bypasses skill autoload classification'] };
|
|
53
|
+
if (isDeploy || /deploy-service\.sh|kubectl\s+(?:apply|set|rollout|delete|scale)|helm\s+upgrade|terraform\s+apply|docker\s+push/i.test(c)) {
|
|
54
|
+
required.add('aria-harness-deploy');
|
|
55
|
+
required.add('aria-forge-guardrails');
|
|
56
|
+
reasons.push('deploy/shared-infrastructure action requires fail-closed deploy and forge guardrails');
|
|
57
|
+
}
|
|
58
|
+
if (isMutation || /^(?:edit|write|notebookedit|patch|apply_patch)$/i.test(toolName)) {
|
|
59
|
+
required.add('aria-repo-doctrine');
|
|
60
|
+
reasons.push('repository/runtime mutation requires repo doctrine');
|
|
61
|
+
}
|
|
62
|
+
if (/remove|delete|strip|drop|omit|disable|bypass|skip|stub|mock|fake|placeholder|temporary|quick scaffold|band-aid/i.test(c)) {
|
|
63
|
+
required.add('aria-harness-no-stripping');
|
|
64
|
+
required.add('aria-forge-guardrails');
|
|
65
|
+
reasons.push('contract-reduction language requires no-stripping and forge guardrails');
|
|
66
|
+
}
|
|
67
|
+
if (isOutputCloseout && /done|complete|completed|ready|verified|fixed|shipped|implemented|production-ready/i.test(c)) {
|
|
68
|
+
required.add('aria-harness-output-discipline');
|
|
69
|
+
reasons.push('owner-facing completion/readiness claim requires output discipline');
|
|
70
|
+
if (!/(verified|passed|success|successful|green|ok|exit\s*0)/i.test(c)) recoveryMissing.push('successful proof from a concrete command/probe');
|
|
71
|
+
}
|
|
72
|
+
if (/production-ready|ready for production|first[- ]class|works in general|general readiness|client packages?|npm packages?|SDKs?|runtimes?|harnesses?|release-ready|ship-ready/i.test(c)) {
|
|
73
|
+
redirectOnly = true;
|
|
74
|
+
reasons.push('broad readiness language requires recovery guidance instead of a permanent skill block');
|
|
75
|
+
}
|
|
76
|
+
if (/done|complete|completed|ready|verified|fixed|shipped|implemented|production-ready/i.test(c) && /but|except|caveat|remaining|not yet|still|separate|later|blocked|skipped|unresolved|follow-up|failed|failing|error|\bred\b|not run|could not verify|untested|no proof|missing proof|without proof/i.test(c)) {
|
|
77
|
+
required.add('aria-harness-output-discipline');
|
|
78
|
+
required.add('aria-forge-guardrails');
|
|
79
|
+
redirectOnly = true;
|
|
80
|
+
reasons.push('completion claim with explicit unresolved state requires recovery guidance');
|
|
81
|
+
}
|
|
82
|
+
if (/non-blocking|warning only|warn only|advisory|fall through|falls through|fail open|soft fail|logged and continue|quality gate warning/i.test(c)) {
|
|
83
|
+
required.add('aria-forge-guardrails');
|
|
84
|
+
reasons.push('advisory/fail-open gate language requires fail-closed hardening discipline');
|
|
85
|
+
}
|
|
86
|
+
return { requiredSkills: [...required].sort(), recoveryMissing: [...new Set(recoveryMissing)], reasons, redirectOnly };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function evaluateSkillGate(options = {}) {
|
|
90
|
+
const c = classifyRequiredSkills(options);
|
|
91
|
+
const body = [options.text, options.action].filter(Boolean).join('\n');
|
|
92
|
+
const loaded = collectLoadedSkills(options, body);
|
|
93
|
+
const contractEvidence = collectContractEvidence(options, body);
|
|
94
|
+
const satisfied = new Set([...loaded, ...contractEvidence]);
|
|
95
|
+
const missingSkills = c.requiredSkills.filter((skill) => !satisfied.has(skill));
|
|
96
|
+
const recoveryMissing = contractEvidence.has('aria-harness-deploy') && contractEvidence.has('aria-forge-guardrails') ? [] : c.recoveryMissing;
|
|
97
|
+
return { ok: c.redirectOnly === true || (missingSkills.length === 0 && recoveryMissing.length === 0), redirectOnly: c.redirectOnly === true, surface: options.surface || 'unknown', sessionId: options.sessionId || 'unknown', requiredSkills: c.requiredSkills, loadedSkills: [...loaded].sort(), contractEvidence: [...contractEvidence].sort(), missingSkills, recoveryMissing, reasons: c.reasons, autoLoadAvailable: options.autoLoadAvailable === true };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function formatSkillGateBlock(result = {}) {
|
|
101
|
+
const m = result.missingSkills || [], r = result.recoveryMissing || [], reasons = result.reasons || [];
|
|
102
|
+
return ['=== ARIA SKILL AUTOLOAD GATE BLOCK ===', `surface: ${result.surface || 'unknown'}`, `missing_skills: ${m.length ? m.join(', ') : '(none)'}`, `missing_recovery_cycle: ${r.length ? r.join(', ') : '(none)'}`, `required_skills: ${(result.requiredSkills || []).join(', ') || '(none)'}`, reasons.length ? `reasons: ${reasons.join(' | ')}` : 'reasons: no classifier reason recorded', 'Recovery contract:', '1. Do not retry the same blocked text.', `2. Load missing skills first: ${m.length ? m.join(', ') : '(none)'}`, `3. Repair missing recovery cycle items: ${r.length ? r.join(', ') : '(none)'}`, '4. Re-write with concrete proof and an applied_cognition block:', '<applied_cognition>', 'decision_delta: <what changed after the block>', 'dominant_domain: <deploy|code|security|testing|ops|product|writing>', 'binds_to: <specific file, command, endpoint, or user instruction>', 'expected_predicate: <measurable condition such as exit=0, status=healthy, count=N>', 'artifact_change: <exact artifact changed or none>', '</applied_cognition>', '5. Re-test using the concrete command/probe named in the block.', '6. Re-submit only after the proof exists; if blocked twice, escalate through ARIA console/MCP with this full block.'].join('\n');
|
|
103
|
+
}
|
|
@@ -1,14 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
const RECEIPT_ROOT = process.env.ARIA_SKILL_RECEIPT_DIR || join(tmpdir(), 'aria-skill-receipts');
|
|
5
|
-
const ALIASES = new Map([['deploy', 'aria-harness-deploy'], ['output', 'aria-harness-output-discipline'], ['repo', 'aria-repo-doctrine'], ['forge', 'aria-forge-guardrails']]);
|
|
6
|
-
const RX = { deploy: /deploy-service\.sh|kubectl\s+(?:apply|set|rollout|delete|scale)|helm\s+upgrade|terraform\s+apply|docker\s+push/i, mutationTool: /^(?:edit|write|notebookedit|patch|apply_patch)$/i, mutation: /apply_patch|write file|edit file|modify|delete file|migration|handler|route|runtime|hook|plugin|\btest\b|smoke script/i, strip: /remove|delete|strip|drop|omit|disable|bypass|skip|stub|mock|fake|placeholder|temporary|quick scaffold|band-aid/i, readiness: /production-ready|ready for production|works in general|general readiness|client packages?|npm packages?|SDKs?|runtimes?|harnesses?|release-ready|ship-ready/i, narrow: /single flow|one flow|narrow e2e|covered flow|specific path|widget flow/i, completion: /done|complete|completed|ready|verified|fixed|shipped|implemented|production-ready/i, badProof: /but|except|caveat|remaining|not yet|still|separate|later|blocked|skipped|unresolved|follow-up|failed|failing|error|red|not run|could not verify|untested|no proof|missing proof|without proof/i, advisory: /non-blocking|warning only|warn only|advisory|fall through|falls through|fail open|soft fail|logged and continue|quality gate warning/i, success: /(?:verified|passed|success|successful|green|ok)\s*[:=\-].{0,120}(?:npm|node|playwright|jest|vitest|build|test|lint|typecheck|curl|kubectl|self-test|e2e|probe|smoke)|(?:npm|node|playwright|jest|vitest|build|test|lint|typecheck|curl|kubectl).{0,120}(?:passed|success|successful|green|exit\s*0)/i, resubmit: /re-?submission|resubmit/i, rewrite: /re-?write|rewrite|fix/i, retest: /re-?test|retest|rerun/i, aria: /ARIA console|Aria console|\/chat|aria-pipeline-mcp|aria_chat|escalat(?:e|ion).{0,80}ARIA/i };
|
|
7
|
-
function normalizeSkillName(skill) { return ALIASES.get(String(skill || '').trim()) || String(skill || '').trim(); }
|
|
8
|
-
function sessionDir(sessionId) { return join(RECEIPT_ROOT, encodeURIComponent(String(sessionId || 'unknown'))); }
|
|
9
|
-
function readReceiptSkills(sessionId) { const dir = sessionDir(sessionId); if (!existsSync(dir)) return new Set(); const skills = new Set(); for (const name of readdirSync(dir)) { if (!name.endsWith('.json')) continue; try { const receipt = JSON.parse(readFileSync(join(dir, name), 'utf8')); if (receipt?.skill) skills.add(normalizeSkillName(receipt.skill)); } catch {} } return skills; }
|
|
10
|
-
function readInlineSkills(text) { const skills = new Set(); const value = String(text || ''); for (const match of value.matchAll(/<skill_content\s+name=["']([^"']+)["']/gi)) skills.add(normalizeSkillName(match[1])); return skills; }
|
|
11
|
-
export function recordSkillLoaded({ sessionId, skill, surface = 'unknown', metadata = {} } = {}) { const normalized = normalizeSkillName(skill); if (!normalized) throw new Error('recordSkillLoaded requires a skill name'); const dir = sessionDir(sessionId); mkdirSync(dir, { recursive: true }); const receipt = { skill: normalized, surface, metadata, recordedAt: new Date().toISOString() }; writeFileSync(join(dir, `${encodeURIComponent(normalized)}.json`), `${JSON.stringify(receipt, null, 2)}\n`); return receipt; }
|
|
12
|
-
export function classifyRequiredSkills({ text = '', action = '', toolName = '', filePath = '', isDeploy = false, isMutation = false, isOutputCloseout = false } = {}) { const combined = [text, action, toolName, filePath].filter(Boolean).join('\n'); const required = new Set(); const reasons = []; const recoveryMissing = []; if (isDeploy || RX.deploy.test(combined)) { required.add('aria-harness-deploy'); required.add('aria-forge-guardrails'); reasons.push('deploy/shared-infrastructure action requires fail-closed deploy and forge guardrails'); } if (isMutation || RX.mutationTool.test(toolName)) { required.add('aria-repo-doctrine'); reasons.push('repository/runtime mutation requires repo doctrine'); } if (RX.strip.test(combined)) { required.add('aria-harness-no-stripping'); reasons.push('strip/remove/bypass language requires no-stripping gate'); } if (isOutputCloseout && RX.completion.test(combined)) { required.add('aria-harness-output-discipline'); reasons.push('owner-facing completion/readiness claim requires output discipline'); if (!RX.success.test(combined)) recoveryMissing.push('successful proof from a concrete command/probe'); } if (RX.readiness.test(combined)) { required.add('architecture-decision'); required.add('testing-strategy'); required.add('aria-forge-guardrails'); required.add('aria-harness-output-discipline'); reasons.push('broad production/package/SDK/runtime readiness claim requires architecture, testing, and forge guardrails'); } if (RX.readiness.test(combined) && RX.narrow.test(combined)) { required.add('testing-strategy'); required.add('aria-forge-guardrails'); reasons.push('narrow e2e proof cannot support broad readiness claim without readiness-matrix discipline'); } if (RX.completion.test(combined) && RX.badProof.test(combined)) { required.add('aria-harness-output-discipline'); required.add('aria-forge-guardrails'); reasons.push('completion claim with unresolved or failed proof requires recovery cycle'); if (!RX.resubmit.test(combined)) recoveryMissing.push('re-submission'); if (!RX.rewrite.test(combined)) recoveryMissing.push('re-write'); if (!RX.retest.test(combined)) recoveryMissing.push('re-test'); if (!RX.aria.test(combined)) recoveryMissing.push('ARIA console escalation'); } if (RX.advisory.test(combined)) { required.add('aria-forge-guardrails'); required.add('aria-harness-output-discipline'); reasons.push('advisory/fail-open gate language requires fail-closed hardening discipline'); } return { requiredSkills: [...required].sort(), reasons, recoveryMissing }; }
|
|
13
|
-
export function evaluateSkillGate(options = {}) { const classified = classifyRequiredSkills(options); const text = [options.text, options.action].filter(Boolean).join('\n'); const loaded = new Set([...readReceiptSkills(options.sessionId), ...readInlineSkills(text)]); const missingSkills = classified.requiredSkills.filter((skill) => !loaded.has(skill)); const recoveryMissing = classified.recoveryMissing || []; return { ok: missingSkills.length === 0 && recoveryMissing.length === 0, surface: options.surface || 'unknown', sessionId: options.sessionId || 'unknown', requiredSkills: classified.requiredSkills, loadedSkills: [...loaded].sort(), missingSkills, recoveryMissing, reasons: classified.reasons, autoLoadAvailable: options.autoLoadAvailable === true }; }
|
|
14
|
-
export function formatSkillGateBlock(result = {}) { const missing = Array.isArray(result.missingSkills) ? result.missingSkills : []; const recovery = Array.isArray(result.recoveryMissing) ? result.recoveryMissing : []; const reasons = Array.isArray(result.reasons) ? result.reasons : []; return ['=== ARIA SKILL AUTOLOAD GATE BLOCK ===', `surface: ${result.surface || 'unknown'}`, `missing_skills: ${missing.length ? missing.join(', ') : '(none)'}`, `missing_recovery_cycle: ${recovery.length ? recovery.join(', ') : '(none)'}`, `required_skills: ${(result.requiredSkills || []).join(', ') || '(none)'}`, reasons.length ? `reasons: ${reasons.join(' | ')}` : 'reasons: no classifier reason recorded', 'counter_action: re-submit, re-write, re-test, and escalate through ARIA console until successful proof exists. Do not downgrade this to an advisory warning.'].join('\n'); }
|
|
1
|
+
export * from './skill-autoload-gate-impl.mjs';
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const HOME = homedir();
|
|
7
|
+
const ARIA_DIR = join(HOME, '.aria');
|
|
8
|
+
const OWNER_TOKEN_PATH = join(ARIA_DIR, 'owner-token');
|
|
9
|
+
const LICENSE_PATH = join(ARIA_DIR, 'license.json');
|
|
10
|
+
const CLIENT_TOKEN_DIR = join(ARIA_DIR, 'harness-tokens');
|
|
11
|
+
|
|
12
|
+
function nonEmpty(value) {
|
|
13
|
+
return typeof value === 'string' && value.trim() ? value.trim() : '';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function readJson(path) {
|
|
17
|
+
try {
|
|
18
|
+
if (!existsSync(path)) return null;
|
|
19
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
20
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function readText(path) {
|
|
27
|
+
try {
|
|
28
|
+
if (!existsSync(path)) return '';
|
|
29
|
+
return readFileSync(path, 'utf8').trim();
|
|
30
|
+
} catch {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function sanitizeScope(value) {
|
|
36
|
+
const clean = String(value || '').trim().replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 96);
|
|
37
|
+
return clean || 'default';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function scopeFromBaseUrl(baseUrl) {
|
|
41
|
+
try {
|
|
42
|
+
const parsed = new URL(String(baseUrl || ''));
|
|
43
|
+
return `base-${createHash('sha256').update(`${parsed.protocol}//${parsed.host}`).digest('hex').slice(0, 16)}`;
|
|
44
|
+
} catch {
|
|
45
|
+
return 'default';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function hasExplicitClientScope(options) {
|
|
50
|
+
return Boolean(nonEmpty(options.clientId) || nonEmpty(options.tokenScope));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function inferScope(options, license) {
|
|
54
|
+
const explicit = nonEmpty(options.tokenScope) || nonEmpty(options.clientId);
|
|
55
|
+
if (explicit) return sanitizeScope(explicit);
|
|
56
|
+
const envScope = nonEmpty(process.env.ARIA_HARNESS_CLIENT_ID) || nonEmpty(process.env.ARIA_CLIENT_ID) || nonEmpty(process.env.ARIA_TENANT_ID);
|
|
57
|
+
if (envScope) return sanitizeScope(envScope);
|
|
58
|
+
const licenseScope = nonEmpty(license?.jti) || nonEmpty(license?.sub);
|
|
59
|
+
if (licenseScope) return sanitizeScope(licenseScope);
|
|
60
|
+
return sanitizeScope(scopeFromBaseUrl(nonEmpty(options.baseUrl)));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function persistedPath(scope) {
|
|
64
|
+
return join(CLIENT_TOKEN_DIR, `${sanitizeScope(scope)}.json`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function readPersistedToken(scope) {
|
|
68
|
+
const parsed = readJson(persistedPath(scope));
|
|
69
|
+
return nonEmpty(parsed?.token);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function persistToken(scope, token, source) {
|
|
73
|
+
if (!token) return false;
|
|
74
|
+
try {
|
|
75
|
+
mkdirSync(CLIENT_TOKEN_DIR, { recursive: true, mode: 0o700 });
|
|
76
|
+
writeFileSync(
|
|
77
|
+
persistedPath(scope),
|
|
78
|
+
`${JSON.stringify({ scope, token, source, updatedAt: new Date().toISOString() }, null, 2)}\n`,
|
|
79
|
+
{ encoding: 'utf8', mode: 0o600 },
|
|
80
|
+
);
|
|
81
|
+
return true;
|
|
82
|
+
} catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function resolveAriaAuthToken(options = {}) {
|
|
88
|
+
const license = readJson(LICENSE_PATH);
|
|
89
|
+
const scope = inferScope(options, license);
|
|
90
|
+
const persist = options.persistToken !== false;
|
|
91
|
+
|
|
92
|
+
const explicit = nonEmpty(options.explicitToken);
|
|
93
|
+
if (explicit) {
|
|
94
|
+
return { token: explicit, source: 'explicit', scope, persisted: persist ? persistToken(scope, explicit, 'explicit') : false };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const envSources = [
|
|
98
|
+
['env:ARIA_HARNESS_TOKEN', process.env.ARIA_HARNESS_TOKEN],
|
|
99
|
+
['env:ARIA_API_KEY', process.env.ARIA_API_KEY],
|
|
100
|
+
['env:ARIA_MASTER_TOKEN', process.env.ARIA_MASTER_TOKEN],
|
|
101
|
+
];
|
|
102
|
+
for (const [source, value] of envSources) {
|
|
103
|
+
const token = nonEmpty(value);
|
|
104
|
+
if (!token) continue;
|
|
105
|
+
return { token, source, scope, persisted: persist ? persistToken(scope, token, source) : false };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const stored = readPersistedToken(scope);
|
|
109
|
+
if (stored) return { token: stored, source: 'persisted-client-token', scope, persisted: true };
|
|
110
|
+
|
|
111
|
+
if (!hasExplicitClientScope(options) || process.env.ARIA_ALLOW_OWNER_TOKEN_FOR_CLIENT_SCOPE === 'true') {
|
|
112
|
+
const ownerToken = readText(OWNER_TOKEN_PATH);
|
|
113
|
+
if (ownerToken) return { token: ownerToken, source: 'owner-token-file', scope, persisted: false };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const harnessToken = nonEmpty(license?.harnessToken);
|
|
117
|
+
if (harnessToken) return { token: harnessToken, source: 'license:harnessToken', scope, persisted: false };
|
|
118
|
+
const token = nonEmpty(license?.token);
|
|
119
|
+
if (token) return { token, source: 'license:token', scope, persisted: false };
|
|
120
|
+
return { token: '', source: 'missing', scope, persisted: false };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export function resolveAriaAuthHeader(options = {}) {
|
|
124
|
+
const resolved = resolveAriaAuthToken(options);
|
|
125
|
+
return resolved.token ? { Authorization: `Bearer ${resolved.token}` } : {};
|
|
126
|
+
}
|
|
@@ -16,16 +16,20 @@
|
|
|
16
16
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
17
17
|
import { homedir } from 'node:os';
|
|
18
18
|
import { join } from 'node:path';
|
|
19
|
+
import {
|
|
20
|
+
formatTaskProjectLedgerContext,
|
|
21
|
+
updateTaskProjectLedger,
|
|
22
|
+
} from './task-project-ledger.mjs';
|
|
23
|
+
import { resolveAriaAuthToken } from './auth-token.mjs';
|
|
19
24
|
|
|
20
25
|
const HOME = homedir();
|
|
21
|
-
const LICENSE_PATH = join(HOME, '.aria', 'license.json');
|
|
22
|
-
const OWNER_TOKEN_PATH = join(HOME, '.aria', 'owner-token');
|
|
23
26
|
const SDK_CANDIDATES = [
|
|
24
27
|
join(HOME, '.aria', 'sdk', 'index.js'),
|
|
25
28
|
join(HOME, '.codex', 'aria-sdk', 'index.js'),
|
|
26
29
|
join(HOME, '.claude', 'aria-sdk', 'index.js'),
|
|
27
30
|
];
|
|
28
31
|
const RUNTIME_URL = (process.env.ARIA_RUNTIME_URL || 'http://127.0.0.1:4319').replace(/\/+$/, '');
|
|
32
|
+
const CURRENT_RECOVERY_PATH = join(HOME, '.aria', 'governance-recovery-current.json');
|
|
29
33
|
const PACKET_CACHE_PATHS = [
|
|
30
34
|
join(HOME, '.aria', '.aria-harness-last-packet.json'),
|
|
31
35
|
join(HOME, '.claude', '.aria-harness-last-packet.json'),
|
|
@@ -39,22 +43,7 @@ function fail(reason) {
|
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
function resolveApiKey() {
|
|
42
|
-
|
|
43
|
-
if (process.env.ARIA_HARNESS_TOKEN) return process.env.ARIA_HARNESS_TOKEN;
|
|
44
|
-
if (process.env.ARIA_MASTER_TOKEN) return process.env.ARIA_MASTER_TOKEN;
|
|
45
|
-
if (existsSync(OWNER_TOKEN_PATH)) {
|
|
46
|
-
try {
|
|
47
|
-
const v = readFileSync(OWNER_TOKEN_PATH, 'utf8').trim();
|
|
48
|
-
if (v) return v;
|
|
49
|
-
} catch {}
|
|
50
|
-
}
|
|
51
|
-
if (existsSync(LICENSE_PATH)) {
|
|
52
|
-
try {
|
|
53
|
-
const j = JSON.parse(readFileSync(LICENSE_PATH, 'utf8'));
|
|
54
|
-
if (j.token) return j.token;
|
|
55
|
-
} catch {}
|
|
56
|
-
}
|
|
57
|
-
return '';
|
|
46
|
+
return resolveAriaAuthToken({ baseUrl: resolveBaseUrl() }).token;
|
|
58
47
|
}
|
|
59
48
|
|
|
60
49
|
function resolveBaseUrl() {
|
|
@@ -98,6 +87,57 @@ function formatPacketAsContext(packet) {
|
|
|
98
87
|
return '';
|
|
99
88
|
}
|
|
100
89
|
|
|
90
|
+
function currentGovernanceRecoveryContext() {
|
|
91
|
+
try {
|
|
92
|
+
if (!existsSync(CURRENT_RECOVERY_PATH)) return '';
|
|
93
|
+
const recovery = JSON.parse(readFileSync(CURRENT_RECOVERY_PATH, 'utf8'));
|
|
94
|
+
const mode = String(recovery.governanceMode || '').trim();
|
|
95
|
+
if (!mode || mode === 'allow') return '';
|
|
96
|
+
const loop = recovery.recoveryLoop && typeof recovery.recoveryLoop === 'object' ? recovery.recoveryLoop : {};
|
|
97
|
+
const contract = recovery.recoveryContract && typeof recovery.recoveryContract === 'object' ? recovery.recoveryContract : {};
|
|
98
|
+
return [
|
|
99
|
+
'--- CURRENT GOVERNANCE RECOVERY CONTEXT ---',
|
|
100
|
+
`Mode: ${mode}`,
|
|
101
|
+
`Decision: ${recovery.decision || 'warn'}`,
|
|
102
|
+
`Fingerprint: ${loop.fingerprint || 'unknown'}`,
|
|
103
|
+
`Allowed recovery attempts: ${loop.allowedRecoveryAttempts ?? 1}`,
|
|
104
|
+
`Prior recovery attempts: ${loop.priorRecoveryAttempts ?? 0}`,
|
|
105
|
+
`Remaining recovery attempts: ${loop.remainingRecoveryAttempts ?? 0}`,
|
|
106
|
+
`Next step: ${loop.nextStep || 'execute recovery contract before claiming completion'}`,
|
|
107
|
+
`Architect fallback: ${loop.architectFallback || contract.fallbackWhenAriaUnavailable || 'if Aria consult is unavailable, use the strongest available client LLM under the architect harness'}`,
|
|
108
|
+
`Load skills first: ${(contract.loadSkillsFirst || []).join(', ') || '(none)'}`,
|
|
109
|
+
`Repair recovery cycle: ${(contract.repairRecoveryCycle || []).join(', ') || '(none)'}`,
|
|
110
|
+
`Retest: ${contract.retest || 'run the concrete verification probe'}`,
|
|
111
|
+
'Mandatory behavior: this is system-prompt recovery state; execute it before final output.',
|
|
112
|
+
].join('\n');
|
|
113
|
+
} catch (error) {
|
|
114
|
+
process.stderr.write(`[inject-context] governance recovery context ignored (${error.message})\n`);
|
|
115
|
+
return '';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function appendAllLocalGuidance(contextText) {
|
|
120
|
+
const ledgerResult = updateTaskProjectLedger({
|
|
121
|
+
platform: 'opencode',
|
|
122
|
+
phase: 'session_start',
|
|
123
|
+
source: 'opencode-harness-context',
|
|
124
|
+
event: {
|
|
125
|
+
sessionId: process.env.OPENCODE_SESSION_ID || process.env.ARIA_SESSION_ID || 'opencode',
|
|
126
|
+
cwd: process.cwd(),
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
return [
|
|
130
|
+
currentGovernanceRecoveryContext(),
|
|
131
|
+
formatTaskProjectLedgerContext({
|
|
132
|
+
ledger: ledgerResult.ledger,
|
|
133
|
+
paths: ledgerResult.paths,
|
|
134
|
+
platform: 'opencode',
|
|
135
|
+
phase: 'session_start',
|
|
136
|
+
}),
|
|
137
|
+
contextText,
|
|
138
|
+
].filter(Boolean).join('\n');
|
|
139
|
+
}
|
|
140
|
+
|
|
101
141
|
async function fetchViaSdk(baseUrl, apiKey) {
|
|
102
142
|
const sdkPath = resolveSdkPath();
|
|
103
143
|
if (!sdkPath) {
|
|
@@ -146,7 +186,7 @@ async function main() {
|
|
|
146
186
|
const stale = loadCachedPacket({ ignoreTtl: true });
|
|
147
187
|
if (stale) {
|
|
148
188
|
process.stderr.write('[inject-context] using stale cached packet (no API key)\n');
|
|
149
|
-
process.stdout.write(formatPacketAsContext(stale));
|
|
189
|
+
process.stdout.write(appendAllLocalGuidance(formatPacketAsContext(stale)));
|
|
150
190
|
return;
|
|
151
191
|
}
|
|
152
192
|
fail('no API key — set ARIA_API_KEY or run `aria login`');
|
|
@@ -155,19 +195,19 @@ async function main() {
|
|
|
155
195
|
|
|
156
196
|
try {
|
|
157
197
|
const packet = await fetchViaRuntime(apiKey).catch(() => fetchViaSdk(baseUrl, apiKey));
|
|
158
|
-
process.stdout.write(formatPacketAsContext(packet));
|
|
198
|
+
process.stdout.write(appendAllLocalGuidance(formatPacketAsContext(packet)));
|
|
159
199
|
return;
|
|
160
200
|
} catch (err) {
|
|
161
201
|
const fresh = loadCachedPacket();
|
|
162
202
|
if (fresh) {
|
|
163
203
|
process.stderr.write(`[inject-context] SDK fetch failed (${err.message}), using fresh cached packet\n`);
|
|
164
|
-
process.stdout.write(formatPacketAsContext(fresh));
|
|
204
|
+
process.stdout.write(appendAllLocalGuidance(formatPacketAsContext(fresh)));
|
|
165
205
|
return;
|
|
166
206
|
}
|
|
167
207
|
const stale = loadCachedPacket({ ignoreTtl: true });
|
|
168
208
|
if (stale) {
|
|
169
209
|
process.stderr.write(`[inject-context] network failed (${err.message}), using stale cached packet\n`);
|
|
170
|
-
process.stdout.write(formatPacketAsContext(stale));
|
|
210
|
+
process.stdout.write(appendAllLocalGuidance(formatPacketAsContext(stale)));
|
|
171
211
|
return;
|
|
172
212
|
}
|
|
173
213
|
fail(`SDK fetch failed: ${err && err.message ? err.message : String(err)}`);
|