@aria_asi/cli 0.2.26 → 0.2.30
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 +282 -0
- package/bin/aria.js +1140 -14
- package/dist/aria-connector/src/auth-commands.d.ts +1 -0
- package/dist/aria-connector/src/auth-commands.d.ts.map +1 -1
- package/dist/aria-connector/src/auth-commands.js +89 -41
- package/dist/aria-connector/src/auth-commands.js.map +1 -1
- package/dist/aria-connector/src/chat.d.ts +3 -0
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +146 -8
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.d.ts +2 -2
- package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.js +1 -1
- package/dist/aria-connector/src/codebase-scanner.js.map +1 -1
- package/dist/aria-connector/src/config.d.ts +12 -0
- package/dist/aria-connector/src/config.d.ts.map +1 -1
- package/dist/aria-connector/src/config.js +2 -0
- 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 +80 -24
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +37 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js +335 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -0
- package/dist/aria-connector/src/connectors/codex.d.ts +3 -0
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/codex.js +248 -0
- package/dist/aria-connector/src/connectors/codex.js.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts +2 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js +47 -0
- package/dist/aria-connector/src/connectors/cognitive-skills.js.map +1 -0
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +90 -4
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts +3 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js +87 -0
- package/dist/aria-connector/src/connectors/repo-git-hooks.js.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts +19 -0
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/repo-guard.js +509 -0
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts +2 -0
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/runtime.js +330 -0
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -0
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +78 -13
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/connectors/syncd.d.ts +27 -0
- package/dist/aria-connector/src/connectors/syncd.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/syncd.js +405 -0
- package/dist/aria-connector/src/connectors/syncd.js.map +1 -0
- package/dist/aria-connector/src/decisions.d.ts +207 -0
- package/dist/aria-connector/src/decisions.d.ts.map +1 -0
- package/dist/aria-connector/src/decisions.js +291 -0
- package/dist/aria-connector/src/decisions.js.map +1 -0
- package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
- package/dist/aria-connector/src/garden-control-plane.js +74 -17
- package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
- package/dist/aria-connector/src/github-connect.d.ts +18 -0
- package/dist/aria-connector/src/github-connect.d.ts.map +1 -0
- package/dist/aria-connector/src/github-connect.js +117 -0
- package/dist/aria-connector/src/github-connect.js.map +1 -0
- package/dist/aria-connector/src/harness-client.d.ts +15 -0
- package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
- package/dist/aria-connector/src/harness-client.js +106 -3
- package/dist/aria-connector/src/harness-client.js.map +1 -1
- package/dist/aria-connector/src/hive-client.d.ts +30 -0
- package/dist/aria-connector/src/hive-client.d.ts.map +1 -1
- package/dist/aria-connector/src/hive-client.js +124 -5
- package/dist/aria-connector/src/hive-client.js.map +1 -1
- package/dist/aria-connector/src/index.d.ts +13 -2
- package/dist/aria-connector/src/index.d.ts.map +1 -1
- package/dist/aria-connector/src/index.js +10 -1
- package/dist/aria-connector/src/index.js.map +1 -1
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts +102 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts.map +1 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js +231 -0
- package/dist/aria-connector/src/lib/aristotle-noor-wire.js.map +1 -0
- package/dist/aria-connector/src/providers/types.d.ts +5 -0
- package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
- package/dist/aria-connector/src/runtime-proof.d.ts +45 -0
- package/dist/aria-connector/src/runtime-proof.d.ts.map +1 -0
- package/dist/aria-connector/src/runtime-proof.js +340 -0
- package/dist/aria-connector/src/runtime-proof.js.map +1 -0
- package/dist/aria-connector/src/self-update.d.ts +2 -1
- package/dist/aria-connector/src/self-update.d.ts.map +1 -1
- package/dist/aria-connector/src/self-update.js +84 -8
- package/dist/aria-connector/src/self-update.js.map +1 -1
- package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
- package/dist/aria-connector/src/setup-wizard.js +34 -2
- package/dist/aria-connector/src/setup-wizard.js.map +1 -1
- package/dist/assets/hooks/aria-agent-handoff.mjs +224 -0
- package/dist/assets/hooks/aria-agent-ledger-merge.mjs +164 -0
- package/dist/assets/hooks/aria-architect-fallback.mjs +267 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/dist/assets/hooks/aria-discovery-record.mjs +101 -0
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +412 -0
- package/dist/assets/hooks/aria-import-resolution-gate.mjs +330 -0
- package/dist/assets/hooks/aria-outcome-record.mjs +84 -0
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/dist/assets/hooks/aria-pre-text-gate.mjs +112 -0
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +2133 -0
- package/dist/assets/hooks/aria-preprompt-consult.mjs +438 -0
- package/dist/assets/hooks/aria-preturn-memory-gate.mjs +570 -0
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/dist/assets/hooks/aria-stop-gate.mjs +1551 -0
- package/dist/assets/hooks/aria-trigger-autolearn.mjs +229 -0
- package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +192 -0
- package/dist/assets/hooks/doctrine_trigger_map.json +479 -0
- package/dist/assets/hooks/lib/canonical-lenses.mjs +64 -0
- package/dist/assets/hooks/lib/gate-audit.mjs +43 -0
- package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +245 -0
- package/dist/assets/hooks/test-tier-lens-labeling.mjs +399 -0
- package/dist/assets/opencode-plugins/harness-context/index.js +60 -0
- package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +179 -0
- package/dist/assets/opencode-plugins/harness-context/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-gate/index.js +248 -0
- package/dist/assets/opencode-plugins/harness-outcome/index.js +129 -0
- package/dist/assets/opencode-plugins/harness-role/index.js +77 -0
- package/dist/assets/opencode-plugins/harness-role/package.json +9 -0
- package/dist/assets/opencode-plugins/harness-stop/index.js +241 -0
- package/dist/runtime/discipline/CLAUDE.md +339 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +81 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +98 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +99 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +127 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +117 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +112 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +102 -0
- package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +121 -0
- package/dist/runtime/doctor.mjs +23 -0
- package/dist/runtime/local-phase.mjs +650 -0
- package/dist/runtime/manifest.json +15 -0
- package/dist/runtime/mizan-scheduler.mjs +331 -0
- package/dist/runtime/package.json +6 -0
- package/dist/runtime/provider-proxy.mjs +594 -0
- package/dist/runtime/sdk/BUNDLED.json +5 -0
- package/dist/runtime/sdk/index.d.ts +477 -0
- package/dist/runtime/sdk/index.js +1469 -0
- package/dist/runtime/sdk/index.js.map +1 -0
- package/dist/runtime/sdk/package.json +8 -0
- package/dist/runtime/sdk/runWithCognition.d.ts +77 -0
- package/dist/runtime/sdk/runWithCognition.js +157 -0
- package/dist/runtime/sdk/runWithCognition.js.map +1 -0
- package/dist/runtime/service.mjs +3058 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +53 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js +292 -0
- package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -0
- package/dist/runtime/vendor/aria-gate-runtime/package.json +6 -0
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/index.d.ts +283 -0
- package/dist/sdk/index.js +622 -85
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runWithCognition.d.ts +77 -0
- package/dist/sdk/runWithCognition.js +157 -0
- package/dist/sdk/runWithCognition.js.map +1 -0
- package/hooks/aria-agent-handoff.mjs +11 -1
- package/hooks/aria-architect-fallback.mjs +109 -40
- package/hooks/aria-cognition-substrate-binding.mjs +668 -0
- package/hooks/aria-harness-via-sdk.mjs +34 -21
- package/hooks/aria-import-resolution-gate.mjs +330 -0
- package/hooks/aria-outcome-record.mjs +5 -1
- package/hooks/aria-pre-emit-dryrun.mjs +294 -0
- package/hooks/aria-pre-tool-gate.mjs +828 -41
- package/hooks/aria-preprompt-consult.mjs +113 -13
- package/hooks/aria-preturn-memory-gate.mjs +298 -6
- package/hooks/aria-repo-doctrine-gate.mjs +397 -0
- package/hooks/aria-stop-gate.mjs +739 -76
- package/hooks/aria-userprompt-abandon-detect.mjs +5 -1
- package/hooks/doctrine_trigger_map.json +209 -15
- package/hooks/lib/canonical-lenses.mjs +64 -0
- package/hooks/lib/gate-audit.mjs +43 -0
- package/opencode-plugins/harness-context/index.js +1 -1
- package/opencode-plugins/harness-context/inject-context.mjs +82 -23
- package/opencode-plugins/harness-gate/index.js +248 -0
- package/opencode-plugins/harness-outcome/index.js +129 -0
- package/opencode-plugins/harness-stop/index.js +241 -0
- package/package.json +9 -3
- package/runtime-src/doctor.mjs +23 -0
- package/runtime-src/local-phase.mjs +650 -0
- package/runtime-src/mizan-scheduler.mjs +331 -0
- package/runtime-src/provider-proxy.mjs +594 -0
- package/runtime-src/service.mjs +3058 -0
- package/scripts/bundle-sdk.mjs +317 -0
- package/scripts/install-client.sh +176 -0
- package/scripts/publish-all.sh +344 -0
- package/scripts/publish-docker.sh +27 -0
- package/scripts/validate-hook-contracts.mjs +54 -0
- package/scripts/validate-skill-prompts.mjs +95 -0
- package/skills/aria-cognition/aria-essence/SKILL.md +63 -0
- package/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
- package/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
- package/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
- package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
- package/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
- package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
- package/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
- package/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
- package/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
- package/skills/aria-cognition/mizan/SKILL.md +72 -0
- package/skills/aria-cognition/nadia/SKILL.md +38 -0
- package/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
- package/skills/aria-cognition/predictor/SKILL.md +25 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
- package/skills/aria-cognition/soul-domains/SKILL.md +25 -0
- package/src/auth-commands.ts +111 -45
- package/src/chat.ts +174 -13
- package/src/codebase-scanner.ts +4 -0
- package/src/config.ts +15 -0
- package/src/connectors/claude-code.ts +79 -25
- package/src/connectors/codebase-awareness.ts +408 -0
- package/src/connectors/codex.ts +274 -0
- package/src/connectors/cognitive-skills.ts +51 -0
- package/src/connectors/opencode.ts +93 -4
- package/src/connectors/repo-git-hooks.ts +86 -0
- package/src/connectors/repo-guard.ts +589 -0
- package/src/connectors/runtime.ts +374 -0
- package/src/connectors/shell.ts +83 -14
- package/src/connectors/syncd.ts +488 -0
- package/src/decisions.ts +469 -0
- package/src/garden-control-plane.ts +101 -26
- package/src/github-connect.ts +143 -0
- package/src/harness-client.ts +128 -3
- package/src/hive-client.ts +165 -5
- package/src/index.ts +41 -2
- package/src/lib/aristotle-noor-wire.ts +310 -0
- package/src/providers/types.ts +6 -0
- package/src/runtime-proof.ts +392 -0
- package/src/self-update.ts +89 -8
- package/src/setup-wizard.ts +37 -2
|
@@ -40,6 +40,19 @@ const HOOK_FILES = [
|
|
|
40
40
|
// outcome-record fires on every state-mutating tool PostToolUse.
|
|
41
41
|
'aria-discovery-record.mjs',
|
|
42
42
|
'aria-outcome-record.mjs',
|
|
43
|
+
// Substrate-binding gate — validates cognition lenses cite real loaded
|
|
44
|
+
// substrate (axioms, frames, memories) not forged/generic anchors.
|
|
45
|
+
// Writes ~/.claude/.aria-loaded-substrate.json manifest (#142).
|
|
46
|
+
'aria-cognition-substrate-binding.mjs',
|
|
47
|
+
// Repo-side doctrine gate — scans edited/staged source files for
|
|
48
|
+
// mock/stub/pending semantics in doctrine-bound packages.
|
|
49
|
+
'aria-repo-doctrine-gate.mjs',
|
|
50
|
+
// Pre-emit dry-run validator (#140) — model self-checks draft against
|
|
51
|
+
// substrate-binding + drift-triggers before emit. CLI tool, not auto-hook.
|
|
52
|
+
'aria-pre-emit-dryrun.mjs',
|
|
53
|
+
];
|
|
54
|
+
const HOOK_DIRS = [
|
|
55
|
+
'lib',
|
|
43
56
|
];
|
|
44
57
|
// Compiled location: <pkg>/dist/aria-connector/src/connectors/claude-code.js
|
|
45
58
|
// (tsc preserves the src/ rooted layout under outDir). From this file:
|
|
@@ -57,7 +70,12 @@ const HOOK_FILES = [
|
|
|
57
70
|
// the fix lands in the same turn as the discovery.
|
|
58
71
|
function packageHooksDir(): string {
|
|
59
72
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
60
|
-
|
|
73
|
+
const candidates = [
|
|
74
|
+
path.resolve(here, '..', '..', '..', '..', 'hooks'),
|
|
75
|
+
path.resolve(here, '..', '..', '..', 'assets', 'hooks'),
|
|
76
|
+
];
|
|
77
|
+
const found = candidates.find((candidate) => existsSync(candidate));
|
|
78
|
+
return found || candidates[0];
|
|
61
79
|
}
|
|
62
80
|
|
|
63
81
|
function packageSdkDir(): string {
|
|
@@ -177,15 +195,22 @@ const HOOKS_BLOCK = {
|
|
|
177
195
|
}],
|
|
178
196
|
},
|
|
179
197
|
{
|
|
180
|
-
// Outcome-record: fires on every state-mutating tool to accumulate the
|
|
181
|
-
// outcome ledger (Sonnet H's #76 endpoint). Fire-and-forget — HTTP
|
|
182
|
-
// failures in the hook do not block the tool pipeline.
|
|
183
198
|
matcher: 'Bash|Edit|Write|NotebookEdit',
|
|
184
|
-
hooks: [
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
199
|
+
hooks: [
|
|
200
|
+
{
|
|
201
|
+
type: 'command',
|
|
202
|
+
command: 'node $HOME/.claude/hooks/aria-repo-doctrine-gate.mjs',
|
|
203
|
+
timeout: 5,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
// Outcome-record: fires on every state-mutating tool to accumulate the
|
|
207
|
+
// outcome ledger (Sonnet H's #76 endpoint). Fire-and-forget — HTTP
|
|
208
|
+
// failures in the hook do not block the tool pipeline.
|
|
209
|
+
type: 'command',
|
|
210
|
+
command: 'node $HOME/.claude/hooks/aria-outcome-record.mjs',
|
|
211
|
+
timeout: 3,
|
|
212
|
+
},
|
|
213
|
+
],
|
|
189
214
|
},
|
|
190
215
|
],
|
|
191
216
|
Stop: [{
|
|
@@ -197,6 +222,11 @@ const HOOKS_BLOCK = {
|
|
|
197
222
|
// against probe evidence in this turn's tool results. Closes the
|
|
198
223
|
// "WHEN TO LOOK before speaking" gap left open by both existing gates.
|
|
199
224
|
hooks: [
|
|
225
|
+
{
|
|
226
|
+
type: 'command',
|
|
227
|
+
command: 'node $HOME/.claude/hooks/aria-cognition-substrate-binding.mjs',
|
|
228
|
+
timeout: 3,
|
|
229
|
+
},
|
|
200
230
|
{
|
|
201
231
|
type: 'command',
|
|
202
232
|
command: 'node $HOME/.claude/hooks/aria-stop-gate.mjs',
|
|
@@ -217,6 +247,25 @@ function installHooks(claudeDir: string, logs: string[], opts: { force?: boolean
|
|
|
217
247
|
mkdirSync(hooksTargetDir, { recursive: true, mode: 0o700 });
|
|
218
248
|
}
|
|
219
249
|
const sourceDir = packageHooksDir();
|
|
250
|
+
for (const dirName of HOOK_DIRS) {
|
|
251
|
+
const srcDir = path.join(sourceDir, dirName);
|
|
252
|
+
if (!existsSync(srcDir)) continue;
|
|
253
|
+
const dstDir = path.join(hooksTargetDir, dirName);
|
|
254
|
+
if (!existsSync(dstDir)) {
|
|
255
|
+
mkdirSync(dstDir, { recursive: true, mode: 0o700 });
|
|
256
|
+
}
|
|
257
|
+
for (const child of readdirSync(srcDir)) {
|
|
258
|
+
const src = path.join(srcDir, child);
|
|
259
|
+
const stat = statSync(src);
|
|
260
|
+
if (!stat.isFile()) continue;
|
|
261
|
+
const dst = path.join(dstDir, child);
|
|
262
|
+
copyFileSync(src, dst);
|
|
263
|
+
if (child.endsWith('.mjs') || child.endsWith('.js')) {
|
|
264
|
+
try { chmodSync(dst, 0o755); } catch {}
|
|
265
|
+
}
|
|
266
|
+
logs.push(`Installed hook helper: ${dirName}/${child}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
220
269
|
for (const name of HOOK_FILES) {
|
|
221
270
|
const src = path.join(sourceDir, name);
|
|
222
271
|
if (!existsSync(src)) {
|
|
@@ -294,29 +343,34 @@ function wireHooksBlock(settings: Record<string, unknown>, logs: string[]): void
|
|
|
294
343
|
}
|
|
295
344
|
const hooks = settings.hooks as Record<string, unknown[]>;
|
|
296
345
|
let mergedEvents = 0;
|
|
346
|
+
|
|
347
|
+
const isManagedAriaCommand = (command: string): boolean =>
|
|
348
|
+
command.includes('$HOME/.claude/hooks/aria-');
|
|
349
|
+
|
|
350
|
+
const isSameManagedEntry = (entry: unknown, matcher: string, commands: string[]): boolean => {
|
|
351
|
+
if (typeof entry !== 'object' || entry === null) return false;
|
|
352
|
+
const eMatcher = (entry as { matcher?: string }).matcher ?? '';
|
|
353
|
+
if (eMatcher !== matcher) return false;
|
|
354
|
+
const eCommands = ((entry as { hooks?: Array<{ command?: string }> }).hooks ?? [])
|
|
355
|
+
.map((h) => h.command)
|
|
356
|
+
.filter((c): c is string => typeof c === 'string');
|
|
357
|
+
if (eCommands.length === 0) return false;
|
|
358
|
+
return eCommands.every(isManagedAriaCommand) || commands.every((c) => eCommands.includes(c));
|
|
359
|
+
};
|
|
360
|
+
|
|
297
361
|
for (const [event, ourEntries] of Object.entries(HOOKS_BLOCK)) {
|
|
298
362
|
const existingEntries = Array.isArray(hooks[event]) ? hooks[event] : [];
|
|
363
|
+
const normalizedEntries = [...existingEntries];
|
|
299
364
|
for (const ourEntry of ourEntries) {
|
|
300
365
|
const ourMatcher = (ourEntry as { matcher?: string }).matcher ?? '';
|
|
301
366
|
const ourCommands = ((ourEntry as { hooks?: Array<{ command?: string }> }).hooks ?? [])
|
|
302
367
|
.map((h) => h.command)
|
|
303
368
|
.filter((c): c is string => typeof c === 'string');
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
if (typeof e !== 'object' || e === null) return false;
|
|
308
|
-
const eMatcher = (e as { matcher?: string }).matcher ?? '';
|
|
309
|
-
if (eMatcher !== ourMatcher) return false;
|
|
310
|
-
const eCommands = ((e as { hooks?: Array<{ command?: string }> }).hooks ?? [])
|
|
311
|
-
.map((h) => h.command)
|
|
312
|
-
.filter((c): c is string => typeof c === 'string');
|
|
313
|
-
return ourCommands.every((c) => eCommands.includes(c));
|
|
314
|
-
});
|
|
315
|
-
if (!alreadyPresent) {
|
|
316
|
-
existingEntries.push(ourEntry);
|
|
317
|
-
}
|
|
369
|
+
const filteredEntries = normalizedEntries.filter((e) => !isSameManagedEntry(e, ourMatcher, ourCommands));
|
|
370
|
+
normalizedEntries.length = 0;
|
|
371
|
+
normalizedEntries.push(...filteredEntries, ourEntry);
|
|
318
372
|
}
|
|
319
|
-
hooks[event] =
|
|
373
|
+
hooks[event] = normalizedEntries;
|
|
320
374
|
mergedEvents++;
|
|
321
375
|
}
|
|
322
376
|
settings.hooks = hooks;
|
|
@@ -324,7 +378,7 @@ function wireHooksBlock(settings: Record<string, unknown>, logs: string[]): void
|
|
|
324
378
|
if (!settings.$schema) {
|
|
325
379
|
settings.$schema = 'https://json.schemastore.org/claude-code-settings.json';
|
|
326
380
|
}
|
|
327
|
-
logs.push(`Wired hooks into settings.json (${mergedEvents} events: SessionStart, UserPromptSubmit, PreToolUse [cognition+memory-gate+Agent-handoff], PostToolUse [Agent-ledger-merge + outcome-record], Stop) — merge-safe, preserves third-party entries`);
|
|
381
|
+
logs.push(`Wired hooks into settings.json (${mergedEvents} events: SessionStart, UserPromptSubmit, PreToolUse [cognition+memory-gate+Agent-handoff], PostToolUse [repo-doctrine-gate + Agent-ledger-merge + outcome-record], Stop) — merge-safe, preserves third-party entries`);
|
|
328
382
|
}
|
|
329
383
|
|
|
330
384
|
// Layer 2 (#84): hard prefix injected into every Agent dispatch so sub-agents
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { execFileSync } from 'child_process';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import type { AriaConfig, LinkedRepo } from '../config.js';
|
|
8
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
9
|
+
import { scanCodebase, schemaImageToText, watchCodebase } from '../codebase-scanner.js';
|
|
10
|
+
|
|
11
|
+
const ARIA_DIR = path.join(homedir(), '.aria');
|
|
12
|
+
const BIN_DIR = path.join(ARIA_DIR, 'bin');
|
|
13
|
+
const ENV_PATH = path.join(ARIA_DIR, 'codebase-awareness.env');
|
|
14
|
+
const STATE_PATH = path.join(ARIA_DIR, 'codebase-awareness-state.json');
|
|
15
|
+
const INDEX_PATH = path.join(ARIA_DIR, 'codebase-awareness-index.json');
|
|
16
|
+
|
|
17
|
+
type AwarenessStatus = 'idle' | 'watching' | 'scanning' | 'error';
|
|
18
|
+
|
|
19
|
+
interface RepoSnapshot {
|
|
20
|
+
path: string;
|
|
21
|
+
name: string;
|
|
22
|
+
scanHash: string;
|
|
23
|
+
lastScan: string;
|
|
24
|
+
fileCount: number;
|
|
25
|
+
language: string;
|
|
26
|
+
framework: string | null;
|
|
27
|
+
packageManager: string | null;
|
|
28
|
+
database: string | null;
|
|
29
|
+
orm: string | null;
|
|
30
|
+
architecture: string | null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface AwarenessState {
|
|
34
|
+
status: AwarenessStatus;
|
|
35
|
+
watchedRepos: string[];
|
|
36
|
+
repoSnapshots: RepoSnapshot[];
|
|
37
|
+
lastError: string | null;
|
|
38
|
+
updatedAt: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function connectorPackageRoot(): string {
|
|
42
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
43
|
+
const candidates = [
|
|
44
|
+
path.resolve(here, '..', '..'),
|
|
45
|
+
path.resolve(here, '..', '..', '..', '..'),
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
for (const candidate of candidates) {
|
|
49
|
+
if (existsSync(path.join(candidate, 'bin', 'aria.js')) && existsSync(path.join(candidate, 'package.json'))) {
|
|
50
|
+
return candidate;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return candidates[candidates.length - 1];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function writeWrapper(binPath: string, args: string[]): void {
|
|
58
|
+
const ariaBin = path.join(connectorPackageRoot(), 'bin', 'aria.js');
|
|
59
|
+
writeFileSync(
|
|
60
|
+
binPath,
|
|
61
|
+
`#!/usr/bin/env bash\nexec node "${ariaBin}" ${args.join(' ')} "$@"\n`,
|
|
62
|
+
{ mode: 0o755 },
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function defaultState(): AwarenessState {
|
|
67
|
+
return {
|
|
68
|
+
status: 'idle',
|
|
69
|
+
watchedRepos: [],
|
|
70
|
+
repoSnapshots: [],
|
|
71
|
+
lastError: null,
|
|
72
|
+
updatedAt: new Date(0).toISOString(),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function readState(): AwarenessState {
|
|
77
|
+
try {
|
|
78
|
+
const parsed = JSON.parse(readFileSync(STATE_PATH, 'utf8')) as Partial<AwarenessState>;
|
|
79
|
+
return {
|
|
80
|
+
status: parsed.status || 'idle',
|
|
81
|
+
watchedRepos: Array.isArray(parsed.watchedRepos) ? parsed.watchedRepos : [],
|
|
82
|
+
repoSnapshots: Array.isArray(parsed.repoSnapshots) ? parsed.repoSnapshots as RepoSnapshot[] : [],
|
|
83
|
+
lastError: parsed.lastError || null,
|
|
84
|
+
updatedAt: parsed.updatedAt || new Date(0).toISOString(),
|
|
85
|
+
};
|
|
86
|
+
} catch {
|
|
87
|
+
return defaultState();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function writeState(update: Partial<AwarenessState>): AwarenessState {
|
|
92
|
+
const current = readState();
|
|
93
|
+
const next: AwarenessState = {
|
|
94
|
+
...current,
|
|
95
|
+
...update,
|
|
96
|
+
updatedAt: new Date().toISOString(),
|
|
97
|
+
};
|
|
98
|
+
mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
99
|
+
writeFileSync(STATE_PATH, JSON.stringify(next, null, 2) + '\n', { mode: 0o600 });
|
|
100
|
+
return next;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function writeIndex(payload: Record<string, unknown>): void {
|
|
104
|
+
mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
105
|
+
writeFileSync(INDEX_PATH, JSON.stringify(payload, null, 2) + '\n', { mode: 0o600 });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function looksLikeRepoRoot(candidate: string): boolean {
|
|
109
|
+
return existsSync(path.join(candidate, '.git'));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function findRepoRoot(startDir: string): string | null {
|
|
113
|
+
let current = path.resolve(startDir);
|
|
114
|
+
while (true) {
|
|
115
|
+
if (looksLikeRepoRoot(current)) return current;
|
|
116
|
+
const parent = path.dirname(current);
|
|
117
|
+
if (parent === current) return null;
|
|
118
|
+
current = parent;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function resolveRepos(config?: AriaConfig, explicit?: string[], fallbackRepoPath?: string): string[] {
|
|
123
|
+
if (explicit?.length) return explicit.map((repo) => path.resolve(repo)).filter(looksLikeRepoRoot);
|
|
124
|
+
|
|
125
|
+
const envRepos = process.env.ARIA_CODEBASE_AWARENESS_REPOS?.split(path.delimiter)
|
|
126
|
+
.map((repo) => repo.trim())
|
|
127
|
+
.filter(Boolean) || [];
|
|
128
|
+
if (envRepos.length) return envRepos.map((repo) => path.resolve(repo)).filter(looksLikeRepoRoot);
|
|
129
|
+
|
|
130
|
+
const loaded = config || loadConfig();
|
|
131
|
+
const configured = (loaded.repositories || [])
|
|
132
|
+
.map((repo) => path.resolve(repo.path))
|
|
133
|
+
.filter(looksLikeRepoRoot);
|
|
134
|
+
if (configured.length) return configured;
|
|
135
|
+
|
|
136
|
+
if (fallbackRepoPath) {
|
|
137
|
+
const resolvedFallback = findRepoRoot(fallbackRepoPath);
|
|
138
|
+
if (resolvedFallback) return [resolvedFallback];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const cwd = findRepoRoot(process.cwd());
|
|
142
|
+
return cwd ? [cwd] : [];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function hashSchema(text: string): string {
|
|
146
|
+
return createHash('sha256').update(text).digest('hex').slice(0, 16);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function architectureSummary(image: {
|
|
150
|
+
architecture?: unknown;
|
|
151
|
+
}): string | null {
|
|
152
|
+
if (Array.isArray(image.architecture) && image.architecture.length > 0) {
|
|
153
|
+
const first = image.architecture[0];
|
|
154
|
+
if (typeof first === 'string' && first.trim()) return first.trim();
|
|
155
|
+
if (first && typeof first === 'object' && typeof first.pattern === 'string' && first.pattern.trim()) {
|
|
156
|
+
return first.pattern.trim();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (typeof image.architecture === 'string' && image.architecture.trim()) return image.architecture.trim();
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async function applyRepoScan(repoRoot: string): Promise<RepoSnapshot> {
|
|
164
|
+
const image = await scanCodebase(repoRoot);
|
|
165
|
+
const schemaText = schemaImageToText(image);
|
|
166
|
+
const scanHash = hashSchema(schemaText);
|
|
167
|
+
const lastScan = new Date().toISOString();
|
|
168
|
+
|
|
169
|
+
const config = loadConfig();
|
|
170
|
+
const nextRepo: LinkedRepo = {
|
|
171
|
+
path: repoRoot,
|
|
172
|
+
name: image.projectName,
|
|
173
|
+
scanHash,
|
|
174
|
+
lastScan,
|
|
175
|
+
};
|
|
176
|
+
const repositories = [
|
|
177
|
+
...(config.repositories || []).filter((repo) => path.resolve(repo.path) !== repoRoot),
|
|
178
|
+
nextRepo,
|
|
179
|
+
];
|
|
180
|
+
|
|
181
|
+
saveConfig({
|
|
182
|
+
...config,
|
|
183
|
+
repositories,
|
|
184
|
+
schemaImages: {
|
|
185
|
+
...(config.schemaImages || {}),
|
|
186
|
+
[image.projectName]: schemaText,
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const snapshot: RepoSnapshot = {
|
|
191
|
+
path: repoRoot,
|
|
192
|
+
name: image.projectName,
|
|
193
|
+
scanHash,
|
|
194
|
+
lastScan,
|
|
195
|
+
fileCount: image.fileCount,
|
|
196
|
+
language: image.language,
|
|
197
|
+
framework: image.framework || null,
|
|
198
|
+
packageManager: image.packageManager || null,
|
|
199
|
+
database: image.database || null,
|
|
200
|
+
orm: image.orm || null,
|
|
201
|
+
architecture: architectureSummary(image),
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const current = readState();
|
|
205
|
+
const nextSnapshots = [
|
|
206
|
+
snapshot,
|
|
207
|
+
...current.repoSnapshots.filter((entry) => path.resolve(entry.path) !== repoRoot),
|
|
208
|
+
];
|
|
209
|
+
writeState({
|
|
210
|
+
status: 'watching',
|
|
211
|
+
watchedRepos: Array.from(new Set([repoRoot, ...current.watchedRepos])),
|
|
212
|
+
repoSnapshots: nextSnapshots,
|
|
213
|
+
lastError: null,
|
|
214
|
+
});
|
|
215
|
+
writeIndex({
|
|
216
|
+
generatedAt: new Date().toISOString(),
|
|
217
|
+
watchedRepos: Array.from(new Set([repoRoot, ...current.watchedRepos])),
|
|
218
|
+
repoSnapshots: nextSnapshots,
|
|
219
|
+
schemaImages: loadConfig().schemaImages || {},
|
|
220
|
+
});
|
|
221
|
+
return snapshot;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function readCodebaseAwarenessState(): AwarenessState {
|
|
225
|
+
return readState();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export async function runCodebaseAwarenessScan(options: {
|
|
229
|
+
repos?: string[];
|
|
230
|
+
fallbackRepoPath?: string;
|
|
231
|
+
} = {}): Promise<{ ok: true; repos: RepoSnapshot[] }> {
|
|
232
|
+
const repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
|
|
233
|
+
if (!repos.length) {
|
|
234
|
+
writeState({ status: 'error', watchedRepos: [], lastError: 'No git repositories configured for codebase awareness.' });
|
|
235
|
+
throw new Error('No git repositories configured for codebase awareness.');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
writeState({ status: 'scanning', watchedRepos: repos, lastError: null });
|
|
239
|
+
const snapshots: RepoSnapshot[] = [];
|
|
240
|
+
for (const repo of repos) {
|
|
241
|
+
snapshots.push(await applyRepoScan(repo));
|
|
242
|
+
}
|
|
243
|
+
writeState({ status: 'watching', watchedRepos: repos, repoSnapshots: snapshots, lastError: null });
|
|
244
|
+
writeIndex({
|
|
245
|
+
generatedAt: new Date().toISOString(),
|
|
246
|
+
watchedRepos: repos,
|
|
247
|
+
repoSnapshots: snapshots,
|
|
248
|
+
schemaImages: loadConfig().schemaImages || {},
|
|
249
|
+
});
|
|
250
|
+
return { ok: true, repos: snapshots };
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export async function startCodebaseAwarenessDaemon(options: {
|
|
254
|
+
repos?: string[];
|
|
255
|
+
fallbackRepoPath?: string;
|
|
256
|
+
} = {}): Promise<void> {
|
|
257
|
+
const repos = resolveRepos(undefined, options.repos, options.fallbackRepoPath);
|
|
258
|
+
if (!repos.length) {
|
|
259
|
+
writeState({ status: 'error', watchedRepos: [], lastError: 'No git repositories configured for codebase awareness.' });
|
|
260
|
+
throw new Error('No git repositories configured for codebase awareness.');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
await runCodebaseAwarenessScan({ repos });
|
|
264
|
+
writeState({ status: 'watching', watchedRepos: repos, lastError: null });
|
|
265
|
+
|
|
266
|
+
for (const repo of repos) {
|
|
267
|
+
watchCodebase(
|
|
268
|
+
repo,
|
|
269
|
+
(image) => {
|
|
270
|
+
const schemaText = schemaImageToText(image);
|
|
271
|
+
const scanHash = hashSchema(schemaText);
|
|
272
|
+
const lastScan = new Date().toISOString();
|
|
273
|
+
const config = loadConfig();
|
|
274
|
+
const repositories = [
|
|
275
|
+
...(config.repositories || []).filter((entry) => path.resolve(entry.path) !== repo),
|
|
276
|
+
{
|
|
277
|
+
path: repo,
|
|
278
|
+
name: image.projectName,
|
|
279
|
+
scanHash,
|
|
280
|
+
lastScan,
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
const nextConfig = {
|
|
284
|
+
...config,
|
|
285
|
+
repositories,
|
|
286
|
+
schemaImages: {
|
|
287
|
+
...(config.schemaImages || {}),
|
|
288
|
+
[image.projectName]: schemaText,
|
|
289
|
+
},
|
|
290
|
+
};
|
|
291
|
+
saveConfig(nextConfig);
|
|
292
|
+
|
|
293
|
+
const current = readState();
|
|
294
|
+
const snapshot: RepoSnapshot = {
|
|
295
|
+
path: repo,
|
|
296
|
+
name: image.projectName,
|
|
297
|
+
scanHash,
|
|
298
|
+
lastScan,
|
|
299
|
+
fileCount: image.fileCount,
|
|
300
|
+
language: image.language,
|
|
301
|
+
framework: image.framework || null,
|
|
302
|
+
packageManager: image.packageManager || null,
|
|
303
|
+
database: image.database || null,
|
|
304
|
+
orm: image.orm || null,
|
|
305
|
+
architecture: architectureSummary(image),
|
|
306
|
+
};
|
|
307
|
+
const repoSnapshots = [
|
|
308
|
+
snapshot,
|
|
309
|
+
...current.repoSnapshots.filter((entry) => path.resolve(entry.path) !== repo),
|
|
310
|
+
];
|
|
311
|
+
writeState({
|
|
312
|
+
status: 'watching',
|
|
313
|
+
watchedRepos: repos,
|
|
314
|
+
repoSnapshots,
|
|
315
|
+
lastError: null,
|
|
316
|
+
});
|
|
317
|
+
writeIndex({
|
|
318
|
+
generatedAt: new Date().toISOString(),
|
|
319
|
+
watchedRepos: repos,
|
|
320
|
+
repoSnapshots,
|
|
321
|
+
schemaImages: nextConfig.schemaImages || {},
|
|
322
|
+
});
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
debounceMs: 800,
|
|
326
|
+
pollIntervalMs: 4000,
|
|
327
|
+
onError: ({ error }) => {
|
|
328
|
+
writeState({
|
|
329
|
+
status: 'error',
|
|
330
|
+
watchedRepos: repos,
|
|
331
|
+
lastError: error.message,
|
|
332
|
+
});
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
await new Promise(() => {});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function writeEnv(repos: string[]): string {
|
|
342
|
+
mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
|
|
343
|
+
writeFileSync(
|
|
344
|
+
ENV_PATH,
|
|
345
|
+
[
|
|
346
|
+
`ARIA_CODEBASE_AWARENESS_REPOS=${repos.join(path.delimiter)}`,
|
|
347
|
+
'',
|
|
348
|
+
].join('\n'),
|
|
349
|
+
{ mode: 0o600 },
|
|
350
|
+
);
|
|
351
|
+
return ENV_PATH;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function installSystemdUserService(logs: string[]): void {
|
|
355
|
+
const systemctlPath = '/bin/systemctl';
|
|
356
|
+
if (process.platform !== 'linux' || !existsSync(systemctlPath)) return;
|
|
357
|
+
|
|
358
|
+
const serviceDir = path.join(homedir(), '.config', 'systemd', 'user');
|
|
359
|
+
const servicePath = path.join(serviceDir, 'aria-codebase-awareness.service');
|
|
360
|
+
mkdirSync(serviceDir, { recursive: true, mode: 0o755 });
|
|
361
|
+
|
|
362
|
+
const unit = [
|
|
363
|
+
'[Unit]',
|
|
364
|
+
'Description=Aria Codebase Awareness',
|
|
365
|
+
'After=network.target',
|
|
366
|
+
'',
|
|
367
|
+
'[Service]',
|
|
368
|
+
'Type=simple',
|
|
369
|
+
`EnvironmentFile=-${ENV_PATH}`,
|
|
370
|
+
`ExecStart=${path.join(BIN_DIR, 'aria-codebase-awareness')} start`,
|
|
371
|
+
'Restart=always',
|
|
372
|
+
'RestartSec=2',
|
|
373
|
+
'',
|
|
374
|
+
'[Install]',
|
|
375
|
+
'WantedBy=default.target',
|
|
376
|
+
'',
|
|
377
|
+
].join('\n');
|
|
378
|
+
|
|
379
|
+
writeFileSync(servicePath, unit, { mode: 0o644 });
|
|
380
|
+
logs.push(`Installed systemd user unit → ${servicePath}`);
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
execFileSync(systemctlPath, ['--user', 'daemon-reload'], { stdio: 'ignore' });
|
|
384
|
+
execFileSync(systemctlPath, ['--user', 'enable', '--now', 'aria-codebase-awareness.service'], { stdio: 'ignore' });
|
|
385
|
+
logs.push('Enabled and started systemd user service: aria-codebase-awareness.service');
|
|
386
|
+
} catch (error) {
|
|
387
|
+
logs.push(`⚠ codebase awareness service installed but not activated: ${error instanceof Error ? error.message : String(error)}`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
export async function installCodebaseAwarenessDaemon(config?: AriaConfig, fallbackRepoPath?: string): Promise<string[]> {
|
|
392
|
+
const repos = resolveRepos(config, undefined, fallbackRepoPath);
|
|
393
|
+
const logs: string[] = [];
|
|
394
|
+
if (!repos.length) {
|
|
395
|
+
logs.push('Skipped codebase awareness install: no git repositories configured.');
|
|
396
|
+
return logs;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
mkdirSync(BIN_DIR, { recursive: true, mode: 0o755 });
|
|
400
|
+
const envPath = writeEnv(repos);
|
|
401
|
+
writeWrapper(path.join(BIN_DIR, 'aria-codebase-awareness'), ['codebase-awareness']);
|
|
402
|
+
installSystemdUserService(logs);
|
|
403
|
+
|
|
404
|
+
logs.push(`Installed codebase awareness wrapper → ${path.join(BIN_DIR, 'aria-codebase-awareness')}`);
|
|
405
|
+
logs.push(`Installed codebase awareness env → ${envPath}`);
|
|
406
|
+
logs.push(`Codebase awareness watching ${repos.length} repos`);
|
|
407
|
+
return logs;
|
|
408
|
+
}
|