@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.
Files changed (253) hide show
  1. package/CLIENT-ONBOARDING.md +282 -0
  2. package/bin/aria.js +1140 -14
  3. package/dist/aria-connector/src/auth-commands.d.ts +1 -0
  4. package/dist/aria-connector/src/auth-commands.d.ts.map +1 -1
  5. package/dist/aria-connector/src/auth-commands.js +89 -41
  6. package/dist/aria-connector/src/auth-commands.js.map +1 -1
  7. package/dist/aria-connector/src/chat.d.ts +3 -0
  8. package/dist/aria-connector/src/chat.d.ts.map +1 -1
  9. package/dist/aria-connector/src/chat.js +146 -8
  10. package/dist/aria-connector/src/chat.js.map +1 -1
  11. package/dist/aria-connector/src/codebase-scanner.d.ts +2 -2
  12. package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
  13. package/dist/aria-connector/src/codebase-scanner.js +1 -1
  14. package/dist/aria-connector/src/codebase-scanner.js.map +1 -1
  15. package/dist/aria-connector/src/config.d.ts +12 -0
  16. package/dist/aria-connector/src/config.d.ts.map +1 -1
  17. package/dist/aria-connector/src/config.js +2 -0
  18. package/dist/aria-connector/src/config.js.map +1 -1
  19. package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
  20. package/dist/aria-connector/src/connectors/claude-code.js +80 -24
  21. package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
  22. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +37 -0
  23. package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -0
  24. package/dist/aria-connector/src/connectors/codebase-awareness.js +335 -0
  25. package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -0
  26. package/dist/aria-connector/src/connectors/codex.d.ts +3 -0
  27. package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -0
  28. package/dist/aria-connector/src/connectors/codex.js +248 -0
  29. package/dist/aria-connector/src/connectors/codex.js.map +1 -0
  30. package/dist/aria-connector/src/connectors/cognitive-skills.d.ts +2 -0
  31. package/dist/aria-connector/src/connectors/cognitive-skills.d.ts.map +1 -0
  32. package/dist/aria-connector/src/connectors/cognitive-skills.js +47 -0
  33. package/dist/aria-connector/src/connectors/cognitive-skills.js.map +1 -0
  34. package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
  35. package/dist/aria-connector/src/connectors/opencode.js +90 -4
  36. package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
  37. package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts +3 -0
  38. package/dist/aria-connector/src/connectors/repo-git-hooks.d.ts.map +1 -0
  39. package/dist/aria-connector/src/connectors/repo-git-hooks.js +87 -0
  40. package/dist/aria-connector/src/connectors/repo-git-hooks.js.map +1 -0
  41. package/dist/aria-connector/src/connectors/repo-guard.d.ts +19 -0
  42. package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -0
  43. package/dist/aria-connector/src/connectors/repo-guard.js +509 -0
  44. package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -0
  45. package/dist/aria-connector/src/connectors/runtime.d.ts +2 -0
  46. package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -0
  47. package/dist/aria-connector/src/connectors/runtime.js +330 -0
  48. package/dist/aria-connector/src/connectors/runtime.js.map +1 -0
  49. package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
  50. package/dist/aria-connector/src/connectors/shell.js +78 -13
  51. package/dist/aria-connector/src/connectors/shell.js.map +1 -1
  52. package/dist/aria-connector/src/connectors/syncd.d.ts +27 -0
  53. package/dist/aria-connector/src/connectors/syncd.d.ts.map +1 -0
  54. package/dist/aria-connector/src/connectors/syncd.js +405 -0
  55. package/dist/aria-connector/src/connectors/syncd.js.map +1 -0
  56. package/dist/aria-connector/src/decisions.d.ts +207 -0
  57. package/dist/aria-connector/src/decisions.d.ts.map +1 -0
  58. package/dist/aria-connector/src/decisions.js +291 -0
  59. package/dist/aria-connector/src/decisions.js.map +1 -0
  60. package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
  61. package/dist/aria-connector/src/garden-control-plane.js +74 -17
  62. package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
  63. package/dist/aria-connector/src/github-connect.d.ts +18 -0
  64. package/dist/aria-connector/src/github-connect.d.ts.map +1 -0
  65. package/dist/aria-connector/src/github-connect.js +117 -0
  66. package/dist/aria-connector/src/github-connect.js.map +1 -0
  67. package/dist/aria-connector/src/harness-client.d.ts +15 -0
  68. package/dist/aria-connector/src/harness-client.d.ts.map +1 -1
  69. package/dist/aria-connector/src/harness-client.js +106 -3
  70. package/dist/aria-connector/src/harness-client.js.map +1 -1
  71. package/dist/aria-connector/src/hive-client.d.ts +30 -0
  72. package/dist/aria-connector/src/hive-client.d.ts.map +1 -1
  73. package/dist/aria-connector/src/hive-client.js +124 -5
  74. package/dist/aria-connector/src/hive-client.js.map +1 -1
  75. package/dist/aria-connector/src/index.d.ts +13 -2
  76. package/dist/aria-connector/src/index.d.ts.map +1 -1
  77. package/dist/aria-connector/src/index.js +10 -1
  78. package/dist/aria-connector/src/index.js.map +1 -1
  79. package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts +102 -0
  80. package/dist/aria-connector/src/lib/aristotle-noor-wire.d.ts.map +1 -0
  81. package/dist/aria-connector/src/lib/aristotle-noor-wire.js +231 -0
  82. package/dist/aria-connector/src/lib/aristotle-noor-wire.js.map +1 -0
  83. package/dist/aria-connector/src/providers/types.d.ts +5 -0
  84. package/dist/aria-connector/src/providers/types.d.ts.map +1 -1
  85. package/dist/aria-connector/src/runtime-proof.d.ts +45 -0
  86. package/dist/aria-connector/src/runtime-proof.d.ts.map +1 -0
  87. package/dist/aria-connector/src/runtime-proof.js +340 -0
  88. package/dist/aria-connector/src/runtime-proof.js.map +1 -0
  89. package/dist/aria-connector/src/self-update.d.ts +2 -1
  90. package/dist/aria-connector/src/self-update.d.ts.map +1 -1
  91. package/dist/aria-connector/src/self-update.js +84 -8
  92. package/dist/aria-connector/src/self-update.js.map +1 -1
  93. package/dist/aria-connector/src/setup-wizard.d.ts.map +1 -1
  94. package/dist/aria-connector/src/setup-wizard.js +34 -2
  95. package/dist/aria-connector/src/setup-wizard.js.map +1 -1
  96. package/dist/assets/hooks/aria-agent-handoff.mjs +224 -0
  97. package/dist/assets/hooks/aria-agent-ledger-merge.mjs +164 -0
  98. package/dist/assets/hooks/aria-architect-fallback.mjs +267 -0
  99. package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +668 -0
  100. package/dist/assets/hooks/aria-discovery-record.mjs +101 -0
  101. package/dist/assets/hooks/aria-harness-via-sdk.mjs +412 -0
  102. package/dist/assets/hooks/aria-import-resolution-gate.mjs +330 -0
  103. package/dist/assets/hooks/aria-outcome-record.mjs +84 -0
  104. package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +294 -0
  105. package/dist/assets/hooks/aria-pre-text-gate.mjs +112 -0
  106. package/dist/assets/hooks/aria-pre-tool-gate.mjs +2133 -0
  107. package/dist/assets/hooks/aria-preprompt-consult.mjs +438 -0
  108. package/dist/assets/hooks/aria-preturn-memory-gate.mjs +570 -0
  109. package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +397 -0
  110. package/dist/assets/hooks/aria-stop-gate.mjs +1551 -0
  111. package/dist/assets/hooks/aria-trigger-autolearn.mjs +229 -0
  112. package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +192 -0
  113. package/dist/assets/hooks/doctrine_trigger_map.json +479 -0
  114. package/dist/assets/hooks/lib/canonical-lenses.mjs +64 -0
  115. package/dist/assets/hooks/lib/gate-audit.mjs +43 -0
  116. package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +245 -0
  117. package/dist/assets/hooks/test-tier-lens-labeling.mjs +399 -0
  118. package/dist/assets/opencode-plugins/harness-context/index.js +60 -0
  119. package/dist/assets/opencode-plugins/harness-context/inject-context.mjs +179 -0
  120. package/dist/assets/opencode-plugins/harness-context/package.json +9 -0
  121. package/dist/assets/opencode-plugins/harness-gate/index.js +248 -0
  122. package/dist/assets/opencode-plugins/harness-outcome/index.js +129 -0
  123. package/dist/assets/opencode-plugins/harness-role/index.js +77 -0
  124. package/dist/assets/opencode-plugins/harness-role/package.json +9 -0
  125. package/dist/assets/opencode-plugins/harness-stop/index.js +241 -0
  126. package/dist/runtime/discipline/CLAUDE.md +339 -0
  127. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/SKILL.md +63 -0
  128. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
  129. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
  130. package/dist/runtime/discipline/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
  131. package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
  132. package/dist/runtime/discipline/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
  133. package/dist/runtime/discipline/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
  134. package/dist/runtime/discipline/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
  135. package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
  136. package/dist/runtime/discipline/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
  137. package/dist/runtime/discipline/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
  138. package/dist/runtime/discipline/skills/aria-cognition/mizan/SKILL.md +72 -0
  139. package/dist/runtime/discipline/skills/aria-cognition/nadia/SKILL.md +38 -0
  140. package/dist/runtime/discipline/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
  141. package/dist/runtime/discipline/skills/aria-cognition/predictor/SKILL.md +25 -0
  142. package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
  143. package/dist/runtime/discipline/skills/aria-cognition/soul-domains/SKILL.md +25 -0
  144. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-intra-phase/SKILL.md +81 -0
  145. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-post-phase/SKILL.md +98 -0
  146. package/dist/runtime/discipline/skills/aria-harness/aria-aristotle-pre-phase/SKILL.md +99 -0
  147. package/dist/runtime/discipline/skills/aria-harness/aria-harness-deploy/SKILL.md +127 -0
  148. package/dist/runtime/discipline/skills/aria-harness/aria-harness-no-stripping/SKILL.md +117 -0
  149. package/dist/runtime/discipline/skills/aria-harness/aria-harness-onboarding/SKILL.md +112 -0
  150. package/dist/runtime/discipline/skills/aria-harness/aria-harness-output-discipline/SKILL.md +102 -0
  151. package/dist/runtime/discipline/skills/aria-harness/aria-harness-substrate-binding/SKILL.md +121 -0
  152. package/dist/runtime/doctor.mjs +23 -0
  153. package/dist/runtime/local-phase.mjs +650 -0
  154. package/dist/runtime/manifest.json +15 -0
  155. package/dist/runtime/mizan-scheduler.mjs +331 -0
  156. package/dist/runtime/package.json +6 -0
  157. package/dist/runtime/provider-proxy.mjs +594 -0
  158. package/dist/runtime/sdk/BUNDLED.json +5 -0
  159. package/dist/runtime/sdk/index.d.ts +477 -0
  160. package/dist/runtime/sdk/index.js +1469 -0
  161. package/dist/runtime/sdk/index.js.map +1 -0
  162. package/dist/runtime/sdk/package.json +8 -0
  163. package/dist/runtime/sdk/runWithCognition.d.ts +77 -0
  164. package/dist/runtime/sdk/runWithCognition.js +157 -0
  165. package/dist/runtime/sdk/runWithCognition.js.map +1 -0
  166. package/dist/runtime/service.mjs +3058 -0
  167. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts +53 -0
  168. package/dist/runtime/vendor/aria-gate-runtime/index.d.ts.map +1 -0
  169. package/dist/runtime/vendor/aria-gate-runtime/index.js +292 -0
  170. package/dist/runtime/vendor/aria-gate-runtime/index.js.map +1 -0
  171. package/dist/runtime/vendor/aria-gate-runtime/package.json +6 -0
  172. package/dist/sdk/BUNDLED.json +2 -2
  173. package/dist/sdk/index.d.ts +283 -0
  174. package/dist/sdk/index.js +622 -85
  175. package/dist/sdk/index.js.map +1 -1
  176. package/dist/sdk/runWithCognition.d.ts +77 -0
  177. package/dist/sdk/runWithCognition.js +157 -0
  178. package/dist/sdk/runWithCognition.js.map +1 -0
  179. package/hooks/aria-agent-handoff.mjs +11 -1
  180. package/hooks/aria-architect-fallback.mjs +109 -40
  181. package/hooks/aria-cognition-substrate-binding.mjs +668 -0
  182. package/hooks/aria-harness-via-sdk.mjs +34 -21
  183. package/hooks/aria-import-resolution-gate.mjs +330 -0
  184. package/hooks/aria-outcome-record.mjs +5 -1
  185. package/hooks/aria-pre-emit-dryrun.mjs +294 -0
  186. package/hooks/aria-pre-tool-gate.mjs +828 -41
  187. package/hooks/aria-preprompt-consult.mjs +113 -13
  188. package/hooks/aria-preturn-memory-gate.mjs +298 -6
  189. package/hooks/aria-repo-doctrine-gate.mjs +397 -0
  190. package/hooks/aria-stop-gate.mjs +739 -76
  191. package/hooks/aria-userprompt-abandon-detect.mjs +5 -1
  192. package/hooks/doctrine_trigger_map.json +209 -15
  193. package/hooks/lib/canonical-lenses.mjs +64 -0
  194. package/hooks/lib/gate-audit.mjs +43 -0
  195. package/opencode-plugins/harness-context/index.js +1 -1
  196. package/opencode-plugins/harness-context/inject-context.mjs +82 -23
  197. package/opencode-plugins/harness-gate/index.js +248 -0
  198. package/opencode-plugins/harness-outcome/index.js +129 -0
  199. package/opencode-plugins/harness-stop/index.js +241 -0
  200. package/package.json +9 -3
  201. package/runtime-src/doctor.mjs +23 -0
  202. package/runtime-src/local-phase.mjs +650 -0
  203. package/runtime-src/mizan-scheduler.mjs +331 -0
  204. package/runtime-src/provider-proxy.mjs +594 -0
  205. package/runtime-src/service.mjs +3058 -0
  206. package/scripts/bundle-sdk.mjs +317 -0
  207. package/scripts/install-client.sh +176 -0
  208. package/scripts/publish-all.sh +344 -0
  209. package/scripts/publish-docker.sh +27 -0
  210. package/scripts/validate-hook-contracts.mjs +54 -0
  211. package/scripts/validate-skill-prompts.mjs +95 -0
  212. package/skills/aria-cognition/aria-essence/SKILL.md +63 -0
  213. package/skills/aria-cognition/aria-essence/references/domain-matrix.md +80 -0
  214. package/skills/aria-cognition/aria-essence/references/evolution-loop.md +30 -0
  215. package/skills/aria-cognition/aria-essence/references/readable-cognition.md +27 -0
  216. package/skills/aria-cognition/aria-forge-guardrails/SKILL.md +35 -0
  217. package/skills/aria-cognition/aria-forge-guardrails/references/checklist.md +31 -0
  218. package/skills/aria-cognition/aria-repo-doctrine/SKILL.md +39 -0
  219. package/skills/aria-cognition/forge-quality-rules/SKILL.md +43 -0
  220. package/skills/aria-cognition/ghazali-8lens/SKILL.md +38 -0
  221. package/skills/aria-cognition/istiqra-induction/SKILL.md +26 -0
  222. package/skills/aria-cognition/ladunni-22/SKILL.md +35 -0
  223. package/skills/aria-cognition/mizan/SKILL.md +72 -0
  224. package/skills/aria-cognition/nadia/SKILL.md +38 -0
  225. package/skills/aria-cognition/nadia-psi/SKILL.md +38 -0
  226. package/skills/aria-cognition/predictor/SKILL.md +25 -0
  227. package/skills/aria-cognition/qiyas-analogy/SKILL.md +26 -0
  228. package/skills/aria-cognition/soul-domains/SKILL.md +25 -0
  229. package/src/auth-commands.ts +111 -45
  230. package/src/chat.ts +174 -13
  231. package/src/codebase-scanner.ts +4 -0
  232. package/src/config.ts +15 -0
  233. package/src/connectors/claude-code.ts +79 -25
  234. package/src/connectors/codebase-awareness.ts +408 -0
  235. package/src/connectors/codex.ts +274 -0
  236. package/src/connectors/cognitive-skills.ts +51 -0
  237. package/src/connectors/opencode.ts +93 -4
  238. package/src/connectors/repo-git-hooks.ts +86 -0
  239. package/src/connectors/repo-guard.ts +589 -0
  240. package/src/connectors/runtime.ts +374 -0
  241. package/src/connectors/shell.ts +83 -14
  242. package/src/connectors/syncd.ts +488 -0
  243. package/src/decisions.ts +469 -0
  244. package/src/garden-control-plane.ts +101 -26
  245. package/src/github-connect.ts +143 -0
  246. package/src/harness-client.ts +128 -3
  247. package/src/hive-client.ts +165 -5
  248. package/src/index.ts +41 -2
  249. package/src/lib/aristotle-noor-wire.ts +310 -0
  250. package/src/providers/types.ts +6 -0
  251. package/src/runtime-proof.ts +392 -0
  252. package/src/self-update.ts +89 -8
  253. package/src/setup-wizard.ts +37 -2
@@ -0,0 +1,488 @@
1
+ import chokidar from 'chokidar';
2
+ import { execFileSync } from 'child_process';
3
+ import { createHash } from 'crypto';
4
+ import {
5
+ existsSync,
6
+ mkdirSync,
7
+ readdirSync,
8
+ readFileSync,
9
+ statSync,
10
+ writeFileSync,
11
+ } from 'fs';
12
+ import { homedir } from 'os';
13
+ import * as path from 'path';
14
+ import { fileURLToPath } from 'node:url';
15
+
16
+ const ARIA_DIR = path.join(homedir(), '.aria');
17
+ const BIN_DIR = path.join(ARIA_DIR, 'bin');
18
+ const SYNCD_ENV_PATH = path.join(ARIA_DIR, 'syncd.env');
19
+ const SYNCD_STATE_PATH = path.join(ARIA_DIR, 'syncd-state.json');
20
+ const DEFAULT_DEBOUNCE_MS = Number(process.env.ARIA_SYNCD_DEBOUNCE_MS || 2000);
21
+
22
+ type SyncStatus = 'idle' | 'running' | 'watching' | 'skipped' | 'error';
23
+
24
+ interface SyncState {
25
+ status: SyncStatus;
26
+ sourceRoot: string | null;
27
+ lastTrigger: string | null;
28
+ lastSourceHash: string | null;
29
+ lastBundleHash: string | null;
30
+ lastSyncedAt: string | null;
31
+ lastError: string | null;
32
+ watchedPaths: string[];
33
+ updatedAt: string;
34
+ }
35
+
36
+ interface SyncOptions {
37
+ sourceRoot?: string;
38
+ force?: boolean;
39
+ reason?: string;
40
+ }
41
+
42
+ function connectorPackageRoot(): string {
43
+ const here = path.dirname(fileURLToPath(import.meta.url));
44
+ const candidates = [
45
+ path.resolve(here, '..', '..'),
46
+ path.resolve(here, '..', '..', '..', '..'),
47
+ ];
48
+
49
+ for (const candidate of candidates) {
50
+ if (existsSync(path.join(candidate, 'bin', 'aria.js')) && existsSync(path.join(candidate, 'package.json'))) {
51
+ return candidate;
52
+ }
53
+ }
54
+
55
+ return candidates[candidates.length - 1];
56
+ }
57
+
58
+ function looksLikeRepoRoot(candidate: string): boolean {
59
+ return (
60
+ existsSync(path.join(candidate, 'harness', 'packages', 'harness-http-client')) &&
61
+ existsSync(path.join(candidate, 'packages', 'aria-connector')) &&
62
+ existsSync(path.join(candidate, 'packages', 'aria-gate-runtime'))
63
+ );
64
+ }
65
+
66
+ function findRepoRoot(startDir: string): string | null {
67
+ let current = path.resolve(startDir);
68
+ while (true) {
69
+ if (looksLikeRepoRoot(current)) return current;
70
+ const parent = path.dirname(current);
71
+ if (parent === current) return null;
72
+ current = parent;
73
+ }
74
+ }
75
+
76
+ function resolveSourceRoot(explicit?: string): string | null {
77
+ if (explicit && looksLikeRepoRoot(explicit)) return path.resolve(explicit);
78
+
79
+ const fromEnv = process.env.ARIA_SYNC_SOURCE_ROOT;
80
+ if (fromEnv && looksLikeRepoRoot(fromEnv)) return path.resolve(fromEnv);
81
+
82
+ return findRepoRoot(process.cwd()) || findRepoRoot(connectorPackageRoot());
83
+ }
84
+
85
+ function syncWatchPaths(sourceRoot: string): string[] {
86
+ const candidates = [
87
+ path.join(sourceRoot, 'harness', 'packages', 'harness-http-client', 'src'),
88
+ path.join(sourceRoot, 'harness', 'packages', 'harness-http-client', 'skills'),
89
+ path.join(sourceRoot, 'harness', 'packages', 'harness-http-client', 'scripts'),
90
+ path.join(sourceRoot, 'harness', 'packages', 'harness-http-client', 'CLAUDE.md'),
91
+ path.join(sourceRoot, 'packages', 'aria-gate-runtime', 'src'),
92
+ path.join(sourceRoot, 'packages', 'aria-connector', 'src'),
93
+ path.join(sourceRoot, 'packages', 'aria-connector', 'package.json'),
94
+ path.join(sourceRoot, 'packages', 'aria-connector', 'CLIENT-ONBOARDING.md'),
95
+ path.join(sourceRoot, 'packages', 'aria-connector', 'skills'),
96
+ path.join(sourceRoot, 'packages', 'aria-connector', 'hooks'),
97
+ path.join(sourceRoot, 'packages', 'aria-connector', 'opencode-plugins'),
98
+ path.join(sourceRoot, 'packages', 'aria-connector', 'runtime-src'),
99
+ path.join(sourceRoot, 'packages', 'aria-connector', 'scripts', 'bundle-sdk.mjs'),
100
+ path.join(sourceRoot, 'packages', 'aria-connector', 'bin', 'aria.js'),
101
+ ];
102
+
103
+ return candidates.filter((candidate) => existsSync(candidate));
104
+ }
105
+
106
+ function readState(): SyncState {
107
+ try {
108
+ const raw = readFileSync(SYNCD_STATE_PATH, 'utf8');
109
+ const parsed = JSON.parse(raw) as Partial<SyncState>;
110
+ return {
111
+ status: parsed.status || 'idle',
112
+ sourceRoot: parsed.sourceRoot || null,
113
+ lastTrigger: parsed.lastTrigger || null,
114
+ lastSourceHash: parsed.lastSourceHash || null,
115
+ lastBundleHash: parsed.lastBundleHash || null,
116
+ lastSyncedAt: parsed.lastSyncedAt || null,
117
+ lastError: parsed.lastError || null,
118
+ watchedPaths: Array.isArray(parsed.watchedPaths) ? parsed.watchedPaths : [],
119
+ updatedAt: parsed.updatedAt || new Date(0).toISOString(),
120
+ };
121
+ } catch {
122
+ return {
123
+ status: 'idle',
124
+ sourceRoot: null,
125
+ lastTrigger: null,
126
+ lastSourceHash: null,
127
+ lastBundleHash: null,
128
+ lastSyncedAt: null,
129
+ lastError: null,
130
+ watchedPaths: [],
131
+ updatedAt: new Date(0).toISOString(),
132
+ };
133
+ }
134
+ }
135
+
136
+ function writeState(update: Partial<SyncState>): SyncState {
137
+ const next: SyncState = {
138
+ ...readState(),
139
+ ...update,
140
+ updatedAt: new Date().toISOString(),
141
+ };
142
+ mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
143
+ writeFileSync(SYNCD_STATE_PATH, JSON.stringify(next, null, 2) + '\n', { mode: 0o600 });
144
+ return next;
145
+ }
146
+
147
+ function hashTree(pathsToHash: string[]): string {
148
+ const hash = createHash('sha256');
149
+
150
+ function visit(entryPath: string): void {
151
+ const stat = statSync(entryPath);
152
+ if (stat.isDirectory()) {
153
+ const children = readdirSync(entryPath).sort();
154
+ for (const child of children) {
155
+ visit(path.join(entryPath, child));
156
+ }
157
+ return;
158
+ }
159
+ hash.update(entryPath);
160
+ hash.update('\0');
161
+ hash.update(readFileSync(entryPath));
162
+ hash.update('\0');
163
+ }
164
+
165
+ for (const entryPath of pathsToHash.filter((candidate) => existsSync(candidate)).sort()) {
166
+ visit(entryPath);
167
+ }
168
+
169
+ return hash.digest('hex');
170
+ }
171
+
172
+ function runStep(
173
+ command: string,
174
+ args: string[],
175
+ cwd: string,
176
+ env: NodeJS.ProcessEnv = {},
177
+ ): void {
178
+ execFileSync(command, args, {
179
+ cwd,
180
+ stdio: 'inherit',
181
+ env: {
182
+ ...process.env,
183
+ ...env,
184
+ },
185
+ });
186
+ }
187
+
188
+ function syncBundleHash(sourceRoot: string): string {
189
+ return hashTree([path.join(sourceRoot, 'packages', 'aria-connector', 'dist')]);
190
+ }
191
+
192
+ function writeSyncdEnv(sourceRoot: string): string {
193
+ mkdirSync(ARIA_DIR, { recursive: true, mode: 0o700 });
194
+ writeFileSync(
195
+ SYNCD_ENV_PATH,
196
+ [
197
+ `ARIA_SYNC_SOURCE_ROOT=${sourceRoot}`,
198
+ `ARIA_SYNCD_DEBOUNCE_MS=${DEFAULT_DEBOUNCE_MS}`,
199
+ 'ARIA_SKIP_SYNCD_INSTALL=1',
200
+ '',
201
+ ].join('\n'),
202
+ { mode: 0o600 },
203
+ );
204
+ return SYNCD_ENV_PATH;
205
+ }
206
+
207
+ function writeWrapper(binPath: string, args: string[]): void {
208
+ const ariaBin = path.join(connectorPackageRoot(), 'bin', 'aria.js');
209
+ writeFileSync(
210
+ binPath,
211
+ `#!/usr/bin/env bash\nexec node "${ariaBin}" ${args.join(' ')} "$@"\n`,
212
+ { mode: 0o755 },
213
+ );
214
+ }
215
+
216
+ function installSystemdUserService(sourceRoot: string, logs: string[]): void {
217
+ const systemctlPath = '/bin/systemctl';
218
+ if (process.platform !== 'linux' || !existsSync(systemctlPath)) {
219
+ return;
220
+ }
221
+
222
+ const serviceDir = path.join(homedir(), '.config', 'systemd', 'user');
223
+ const servicePath = path.join(serviceDir, 'aria-syncd.service');
224
+ mkdirSync(serviceDir, { recursive: true, mode: 0o755 });
225
+
226
+ const unit = [
227
+ '[Unit]',
228
+ 'Description=Aria Connector Auto Sync Daemon',
229
+ 'After=network.target',
230
+ '',
231
+ '[Service]',
232
+ 'Type=simple',
233
+ `EnvironmentFile=-${SYNCD_ENV_PATH}`,
234
+ `WorkingDirectory=${path.join(sourceRoot, 'packages', 'aria-connector')}`,
235
+ `ExecStart=${path.join(BIN_DIR, 'aria-syncd')}`,
236
+ 'Restart=always',
237
+ 'RestartSec=2',
238
+ '',
239
+ '[Install]',
240
+ 'WantedBy=default.target',
241
+ '',
242
+ ].join('\n');
243
+
244
+ writeFileSync(servicePath, unit, { mode: 0o644 });
245
+ logs.push(`Installed systemd user unit → ${servicePath}`);
246
+
247
+ try {
248
+ execFileSync(systemctlPath, ['--user', 'daemon-reload'], { stdio: 'ignore' });
249
+ execFileSync(systemctlPath, ['--user', 'enable', '--now', 'aria-syncd.service'], { stdio: 'ignore' });
250
+ logs.push('Enabled and started systemd user service: aria-syncd.service');
251
+ } catch (error) {
252
+ logs.push(`⚠ systemd sync daemon installed but not activated: ${error instanceof Error ? error.message : String(error)}`);
253
+ }
254
+ }
255
+
256
+ function installLaunchAgent(sourceRoot: string, logs: string[]): void {
257
+ if (process.platform !== 'darwin') return;
258
+
259
+ const launchAgentDir = path.join(homedir(), 'Library', 'LaunchAgents');
260
+ const plistPath = path.join(launchAgentDir, 'com.aria.syncd.plist');
261
+ mkdirSync(launchAgentDir, { recursive: true, mode: 0o755 });
262
+
263
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
264
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
265
+ <plist version="1.0">
266
+ <dict>
267
+ <key>Label</key>
268
+ <string>com.aria.syncd</string>
269
+ <key>ProgramArguments</key>
270
+ <array>
271
+ <string>${path.join(BIN_DIR, 'aria-syncd')}</string>
272
+ </array>
273
+ <key>WorkingDirectory</key>
274
+ <string>${path.join(sourceRoot, 'packages', 'aria-connector')}</string>
275
+ <key>EnvironmentVariables</key>
276
+ <dict>
277
+ <key>ARIA_SYNC_SOURCE_ROOT</key>
278
+ <string>${sourceRoot}</string>
279
+ <key>ARIA_SYNCD_DEBOUNCE_MS</key>
280
+ <string>${String(DEFAULT_DEBOUNCE_MS)}</string>
281
+ <key>ARIA_SKIP_SYNCD_INSTALL</key>
282
+ <string>1</string>
283
+ </dict>
284
+ <key>RunAtLoad</key>
285
+ <true/>
286
+ <key>KeepAlive</key>
287
+ <true/>
288
+ </dict>
289
+ </plist>
290
+ `;
291
+
292
+ writeFileSync(plistPath, plist, { mode: 0o644 });
293
+ logs.push(`Installed launchd agent → ${plistPath}`);
294
+
295
+ try {
296
+ execFileSync('/bin/launchctl', ['unload', plistPath], { stdio: 'ignore' });
297
+ } catch {}
298
+ try {
299
+ execFileSync('/bin/launchctl', ['load', plistPath], { stdio: 'ignore' });
300
+ logs.push('Loaded launchd agent: com.aria.syncd');
301
+ } catch (error) {
302
+ logs.push(`⚠ launchd sync daemon installed but not activated: ${error instanceof Error ? error.message : String(error)}`);
303
+ }
304
+ }
305
+
306
+ export async function installAriaSyncDaemon(options: SyncOptions = {}): Promise<string[]> {
307
+ const sourceRoot = resolveSourceRoot(options.sourceRoot);
308
+ const logs: string[] = [];
309
+
310
+ if (!sourceRoot) {
311
+ logs.push('Skipped sync daemon install: canonical Aria source repo not detected from this environment.');
312
+ return logs;
313
+ }
314
+
315
+ mkdirSync(BIN_DIR, { recursive: true, mode: 0o755 });
316
+ const envPath = writeSyncdEnv(sourceRoot);
317
+ writeWrapper(path.join(BIN_DIR, 'aria-syncd'), ['syncd', 'start']);
318
+ writeWrapper(path.join(BIN_DIR, 'aria-syncd-once'), ['syncd', 'once']);
319
+
320
+ installSystemdUserService(sourceRoot, logs);
321
+ installLaunchAgent(sourceRoot, logs);
322
+
323
+ logs.push(`Installed sync daemon wrapper → ${path.join(BIN_DIR, 'aria-syncd')}`);
324
+ logs.push(`Installed one-shot sync wrapper → ${path.join(BIN_DIR, 'aria-syncd-once')}`);
325
+ logs.push(`Installed sync daemon env → ${envPath}`);
326
+ logs.push(`Sync daemon source root → ${sourceRoot}`);
327
+ return logs;
328
+ }
329
+
330
+ export async function runSyncOnce(options: SyncOptions = {}): Promise<{ changed: boolean; bundleHash: string; sourceRoot: string; }> {
331
+ const sourceRoot = resolveSourceRoot(options.sourceRoot);
332
+ if (!sourceRoot) {
333
+ writeState({
334
+ status: 'error',
335
+ sourceRoot: null,
336
+ lastTrigger: options.reason || 'manual',
337
+ lastError: 'Canonical Aria source repo not detected',
338
+ watchedPaths: [],
339
+ });
340
+ throw new Error('Canonical Aria source repo not detected');
341
+ }
342
+
343
+ const watchPaths = syncWatchPaths(sourceRoot);
344
+ const sourceHash = hashTree(watchPaths);
345
+ writeState({
346
+ status: 'running',
347
+ sourceRoot,
348
+ lastTrigger: options.reason || 'manual',
349
+ lastError: null,
350
+ watchedPaths: watchPaths,
351
+ });
352
+
353
+ try {
354
+ const prior = readState();
355
+ if (!options.force && prior.lastSourceHash === sourceHash) {
356
+ writeState({
357
+ status: 'skipped',
358
+ sourceRoot,
359
+ lastTrigger: options.reason || 'manual',
360
+ lastSourceHash: sourceHash,
361
+ lastSyncedAt: new Date().toISOString(),
362
+ lastError: null,
363
+ watchedPaths: watchPaths,
364
+ });
365
+ return { changed: false, bundleHash: prior.lastBundleHash || 'unchanged', sourceRoot };
366
+ }
367
+
368
+ runStep('npm', ['run', 'build'], path.join(sourceRoot, 'harness', 'packages', 'harness-http-client'));
369
+ runStep('npm', ['run', 'build'], path.join(sourceRoot, 'packages', 'aria-gate-runtime'));
370
+ runStep('npm', ['run', 'build'], path.join(sourceRoot, 'packages', 'aria-connector'));
371
+
372
+ const bundleHash = syncBundleHash(sourceRoot);
373
+
374
+ runStep(
375
+ 'node',
376
+ ['bin/aria.js', 'connect', '--force'],
377
+ path.join(sourceRoot, 'packages', 'aria-connector'),
378
+ { ARIA_SKIP_SYNCD_INSTALL: '1' },
379
+ );
380
+
381
+ writeState({
382
+ status: 'watching',
383
+ sourceRoot,
384
+ lastTrigger: options.reason || 'manual',
385
+ lastSourceHash: sourceHash,
386
+ lastBundleHash: bundleHash,
387
+ lastSyncedAt: new Date().toISOString(),
388
+ lastError: null,
389
+ watchedPaths: watchPaths,
390
+ });
391
+ return { changed: true, bundleHash, sourceRoot };
392
+ } catch (error) {
393
+ writeState({
394
+ status: 'error',
395
+ sourceRoot,
396
+ lastTrigger: options.reason || 'manual',
397
+ lastError: error instanceof Error ? error.message : String(error),
398
+ watchedPaths: watchPaths,
399
+ });
400
+ throw error;
401
+ }
402
+ }
403
+
404
+ export function readSyncDaemonState(): SyncState {
405
+ return readState();
406
+ }
407
+
408
+ export async function startSyncDaemon(options: SyncOptions = {}): Promise<void> {
409
+ const sourceRoot = resolveSourceRoot(options.sourceRoot);
410
+ if (!sourceRoot) {
411
+ throw new Error('Canonical Aria source repo not detected');
412
+ }
413
+
414
+ const watchPaths = syncWatchPaths(sourceRoot);
415
+ writeState({
416
+ status: 'watching',
417
+ sourceRoot,
418
+ lastTrigger: options.reason || 'daemon-start',
419
+ lastError: null,
420
+ watchedPaths: watchPaths,
421
+ });
422
+
423
+ await runSyncOnce({
424
+ sourceRoot,
425
+ force: options.force,
426
+ reason: options.reason || 'daemon-startup',
427
+ });
428
+
429
+ const watcher = chokidar.watch(watchPaths, {
430
+ ignoreInitial: true,
431
+ ignored: [
432
+ /(^|[/\\])\../,
433
+ /[/\\]dist[/\\]/,
434
+ /[/\\]node_modules[/\\]/,
435
+ /[/\\]\.git[/\\]/,
436
+ ],
437
+ awaitWriteFinish: {
438
+ stabilityThreshold: 500,
439
+ pollInterval: 100,
440
+ },
441
+ });
442
+
443
+ let timer: NodeJS.Timeout | null = null;
444
+ let active = false;
445
+ let queuedReason: string | null = null;
446
+
447
+ const kick = (reason: string) => {
448
+ queuedReason = reason;
449
+ if (timer) clearTimeout(timer);
450
+ timer = setTimeout(async () => {
451
+ if (active) return;
452
+ active = true;
453
+ const nextReason = queuedReason || 'watch';
454
+ queuedReason = null;
455
+ try {
456
+ await runSyncOnce({ sourceRoot, reason: nextReason });
457
+ } catch (error) {
458
+ console.error(`[aria syncd] sync failed: ${error instanceof Error ? error.message : String(error)}`);
459
+ } finally {
460
+ active = false;
461
+ if (queuedReason) kick(queuedReason);
462
+ }
463
+ }, DEFAULT_DEBOUNCE_MS);
464
+ };
465
+
466
+ watcher.on('all', (eventName, changedPath) => {
467
+ const rel = path.relative(sourceRoot, changedPath);
468
+ console.log(`[aria syncd] ${eventName}: ${rel}`);
469
+ kick(`${eventName}:${rel}`);
470
+ });
471
+
472
+ const shutdown = async () => {
473
+ if (timer) clearTimeout(timer);
474
+ await watcher.close();
475
+ writeState({
476
+ status: 'idle',
477
+ sourceRoot,
478
+ lastTrigger: 'shutdown',
479
+ watchedPaths: watchPaths,
480
+ });
481
+ process.exit(0);
482
+ };
483
+
484
+ process.on('SIGINT', shutdown);
485
+ process.on('SIGTERM', shutdown);
486
+ console.log(`[aria syncd] watching ${watchPaths.length} paths under ${sourceRoot}`);
487
+ await new Promise(() => {});
488
+ }