auroq-os 2.5.4 → 2.5.5

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.
@@ -1,7 +1,7 @@
1
1
  project:
2
2
  name: "Auroq OS"
3
3
  type: greenfield
4
- version: 2.5.4
4
+ version: 2.5.5
5
5
  installedAt: '2026-03-16'
6
6
 
7
7
  ide:
@@ -2,6 +2,7 @@
2
2
  /**
3
3
  * Coletor AHI. Camada ao lado do Synapse: nunca substitui synapse-engine.cjs.
4
4
  * Falha = exit 0. Sem stdout. Sem MCP Arcane neste negocio = no-op.
5
+ * Grava local e tenta enviar pra Arka. Se a nuvem falhar, o Claude segue.
5
6
  */
6
7
  process.on('uncaughtException', () => process.exit(0));
7
8
  process.on('unhandledRejection', () => process.exit(0));
@@ -18,8 +19,10 @@ process.stdin.on('data', (chunk) => {
18
19
  if (input.length > 512 * 1024) input = input.slice(0, 512 * 1024);
19
20
  });
20
21
  process.stdin.on('end', () => {
21
- try { capture(); } catch { /* never break Claude */ }
22
- done();
22
+ Promise.resolve()
23
+ .then(() => capture())
24
+ .catch(() => {})
25
+ .finally(done);
23
26
  });
24
27
 
25
28
  function redact(text) {
@@ -31,9 +34,26 @@ function redact(text) {
31
34
  .slice(0, 8000);
32
35
  }
33
36
 
34
- function capture() {
37
+ function mapType(name) {
38
+ if (name === 'UserPromptSubmit') return 'message.user';
39
+ if (name === 'Stop') return 'message.assistant';
40
+ if (name === 'PreToolUse') return 'tool.started';
41
+ if (name === 'PostToolUse') return 'tool.completed';
42
+ if (name === 'PostToolUseFailure') return 'tool.failed';
43
+ if (name === 'SessionStart') return 'session.started';
44
+ if (name === 'SessionEnd') return 'session.ended';
45
+ return 'work.checkpoint';
46
+ }
47
+
48
+ function hostName() {
49
+ if (process.env.CODEX_HOME || process.env.CODEX_CLI || process.env.CODEX) return 'codex';
50
+ return 'claude-code';
51
+ }
52
+
53
+ async function capture() {
35
54
  const fs = require('node:fs');
36
55
  const path = require('node:path');
56
+ const os = require('node:os');
37
57
  const cwd = process.cwd();
38
58
  let mcp = false;
39
59
  try {
@@ -55,4 +75,57 @@ function capture() {
55
75
  text: redact(event.prompt || event.last_assistant_message || event.last_message || event.content || ''),
56
76
  };
57
77
  fs.appendFileSync(path.join(dir, 'events.jsonl'), `${JSON.stringify(row)}\n`, { mode: 0o600 });
78
+ await ship(row);
79
+ }
80
+
81
+ function ship(row) {
82
+ const fs = require('node:fs');
83
+ const path = require('node:path');
84
+ const os = require('node:os');
85
+ const http = require('node:http');
86
+ const https = require('node:https');
87
+ const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
88
+ const credFile = path.join(home, '.arcane', 'credentials.json');
89
+ if (!fs.existsSync(credFile)) return Promise.resolve();
90
+ let token = '';
91
+ try {
92
+ token = JSON.parse(fs.readFileSync(credFile, 'utf8')).access_token || '';
93
+ } catch { return Promise.resolve(); }
94
+ if (!token) return Promise.resolve();
95
+ const target = process.env.AHI_INGEST_URL || 'https://arcane.arka.education/api/ahi/v1/ingest';
96
+ const url = new URL(target);
97
+ const payload = JSON.stringify({
98
+ schema_version: 1,
99
+ host: hostName(),
100
+ native_session_id: row.session_id || 'unknown',
101
+ events: [{
102
+ type: mapType(row.hook),
103
+ occurred_at: row.at,
104
+ source_event_id: `${row.hook}:${row.at}`,
105
+ evidence_kind: 'observed',
106
+ payload: { text: row.text, tool: row.tool, hook: row.hook },
107
+ }],
108
+ });
109
+ const lib = url.protocol === 'http:' ? http : https;
110
+ return new Promise((resolve) => {
111
+ const req = lib.request({
112
+ protocol: url.protocol,
113
+ hostname: url.hostname,
114
+ port: url.port || (url.protocol === 'http:' ? 80 : 443),
115
+ path: url.pathname,
116
+ method: 'POST',
117
+ headers: {
118
+ Authorization: `Bearer ${token}`,
119
+ 'Content-Type': 'application/json',
120
+ 'Content-Length': Buffer.byteLength(payload),
121
+ },
122
+ timeout: 1500,
123
+ }, (res) => {
124
+ res.resume();
125
+ res.on('end', resolve);
126
+ });
127
+ req.on('error', resolve);
128
+ req.on('timeout', () => { req.destroy(); resolve(); });
129
+ req.end(payload);
130
+ });
58
131
  }
@@ -29,6 +29,30 @@
29
29
  ]
30
30
  }
31
31
  ],
32
+ "Stop": [
33
+ {
34
+ "matcher": "",
35
+ "hooks": [
36
+ {
37
+ "type": "command",
38
+ "command": "node .claude/hooks/ahi-capture.cjs",
39
+ "timeout": 3000
40
+ }
41
+ ]
42
+ }
43
+ ],
44
+ "PostToolUse": [
45
+ {
46
+ "matcher": "",
47
+ "hooks": [
48
+ {
49
+ "type": "command",
50
+ "command": "node .claude/hooks/ahi-capture.cjs",
51
+ "timeout": 3000
52
+ }
53
+ ]
54
+ }
55
+ ],
32
56
  "PreCompact": [
33
57
  {
34
58
  "matcher": "",
package/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.5.5 — 2026-09-14
2
+
3
+ - Coletor AHI envia o evento pra `https://arcane.arka.education/api/ahi/v1/ingest` (credencial `~/.arcane`). Se a nuvem falhar, o chat segue. Tambem registra Stop e PostToolUse.
4
+ - Instalador da plataforma passa a pinar esta versao.
5
+
1
6
  ## 2.5.4 — 2026-09-14
2
7
 
3
8
  - Historico do trabalho Arcane: se o negocio tem MCP `arcane`, o hook `ahi-capture.cjs` registra a sessao. Sem clique, sem pause. Falha do coletor nao quebra o Claude (exit 0, sem stdout). Nao substitui o Synapse.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auroq-os",
3
- "version": "2.5.4",
3
+ "version": "2.5.5",
4
4
  "description": "Auroq OS — Sistema Operacional de IA para Experts",
5
5
  "bin": {
6
6
  "auroq-os": "bin/auroq-os.js"