@inetafrica/open-claudia 2.14.8 → 3.0.0

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 (157) hide show
  1. package/.env.example +30 -4
  2. package/CHANGELOG.md +21 -0
  3. package/README.md +87 -66
  4. package/bin/agent.js +44 -18
  5. package/bin/cli.js +30 -28
  6. package/bin/dream.js +5 -11
  7. package/bin/loopback-client.js +29 -5
  8. package/bin/schedule.js +19 -5
  9. package/bin/tool.js +23 -5
  10. package/bot-agent.js +5 -2350
  11. package/bot.js +105 -7
  12. package/channels/telegram/adapter.js +6 -1
  13. package/channels/voice/adapter.js +1 -0
  14. package/channels/voice/manage.js +43 -5
  15. package/config-dir.js +3 -11
  16. package/core/actions.js +149 -40
  17. package/core/approvals.js +136 -29
  18. package/core/auth-flow.js +103 -19
  19. package/core/config-dir.js +19 -0
  20. package/core/config.js +127 -69
  21. package/core/doctor.js +111 -57
  22. package/core/dream.js +219 -62
  23. package/core/enforcer.js +0 -0
  24. package/core/entities.js +2 -1
  25. package/core/fsutil.js +55 -0
  26. package/core/handlers.js +503 -217
  27. package/core/ideas.js +2 -1
  28. package/core/identity.js +8 -11
  29. package/core/io.js +24 -3
  30. package/core/jobs.js +589 -72
  31. package/core/lessons.js +3 -2
  32. package/core/loopback.js +45 -8
  33. package/core/memory-mutation-queue.js +241 -0
  34. package/core/migration-backup.js +1060 -0
  35. package/core/pack-review.js +295 -88
  36. package/core/packs.js +4 -3
  37. package/core/persona.js +2 -1
  38. package/core/process-tree.js +19 -2
  39. package/core/provider-migration.js +39 -0
  40. package/core/provider-status.js +80 -0
  41. package/core/providers/claude-events.js +117 -0
  42. package/core/providers/claude-hook.js +114 -0
  43. package/core/providers/claude.js +296 -0
  44. package/core/providers/codex-events.js +121 -0
  45. package/core/providers/codex-hook.js +280 -0
  46. package/core/providers/codex.js +286 -0
  47. package/core/providers/contract.js +153 -0
  48. package/core/providers/env.js +148 -0
  49. package/core/providers/events.js +170 -0
  50. package/core/providers/hook-command.js +22 -0
  51. package/core/providers/index.js +240 -0
  52. package/core/providers/utility-policy.js +269 -0
  53. package/core/recall/classic.js +2 -2
  54. package/core/recall/discoverer.js +71 -22
  55. package/core/recall/metrics.js +27 -1
  56. package/core/recall/tuning.js +4 -1
  57. package/core/recall/warm-walker.js +151 -108
  58. package/core/recall-filter.js +86 -61
  59. package/core/router.js +79 -7
  60. package/core/run-context.js +185 -0
  61. package/core/runner.js +1415 -1282
  62. package/core/scheduler.js +515 -210
  63. package/core/side-chat.js +346 -0
  64. package/core/state.js +1096 -95
  65. package/core/subagent.js +72 -98
  66. package/core/system-prompt.js +462 -279
  67. package/core/tool-guard.js +73 -39
  68. package/core/tools.js +22 -5
  69. package/core/transcripts.js +30 -1
  70. package/core/usage-log.js +19 -4
  71. package/core/utility-agent.js +654 -0
  72. package/core/web-auth.js +29 -13
  73. package/core/web-sessions.js +78 -0
  74. package/docs/CHANNEL_DESIGN.md +181 -0
  75. package/docs/MULTI_CHANNEL_PLAN.md +254 -0
  76. package/docs/PROVIDER_MIGRATION.md +67 -0
  77. package/health.js +50 -39
  78. package/package.json +51 -4
  79. package/setup.js +198 -38
  80. package/soul.md +39 -0
  81. package/test-ability-extraction.js +5 -0
  82. package/test-approval-async.js +63 -4
  83. package/test-cursor-removal.js +334 -0
  84. package/test-delivery-contract.js +88 -0
  85. package/test-enforcer.js +70 -27
  86. package/test-fixtures/current-provider-parity.json +132 -0
  87. package/test-fixtures/fake-agent-cli.js +477 -0
  88. package/test-fixtures/migrations/claude-only/jobs.json +3 -0
  89. package/test-fixtures/migrations/claude-only/sessions.json +5 -0
  90. package/test-fixtures/migrations/claude-only/state.json +5 -0
  91. package/test-fixtures/migrations/cursor-selected/crons.json +3 -0
  92. package/test-fixtures/migrations/cursor-selected/jobs.json +3 -0
  93. package/test-fixtures/migrations/cursor-selected/sessions.json +5 -0
  94. package/test-fixtures/migrations/cursor-selected/state.json +6 -0
  95. package/test-fixtures/migrations/dual-provider/jobs.json +3 -0
  96. package/test-fixtures/migrations/dual-provider/sessions.json +7 -0
  97. package/test-fixtures/migrations/dual-provider/state.json +10 -0
  98. package/test-fixtures/migrations/malformed-partial/jobs.json +1 -0
  99. package/test-fixtures/migrations/malformed-partial/sessions.json +1 -0
  100. package/test-fixtures/migrations/malformed-partial/sessions.json.bak +3 -0
  101. package/test-fixtures/migrations/malformed-partial/state.json +1 -0
  102. package/test-fixtures/migrations/malformed-partial/state.json.bak +5 -0
  103. package/test-fixtures/migrations/missing-project/jobs.json +3 -0
  104. package/test-fixtures/migrations/missing-project/sessions.json +3 -0
  105. package/test-fixtures/migrations/missing-project/state.json +4 -0
  106. package/test-fixtures/migrations/multi-user/jobs.json +4 -0
  107. package/test-fixtures/migrations/multi-user/sessions.json +4 -0
  108. package/test-fixtures/migrations/multi-user/state.json +6 -0
  109. package/test-fixtures/provider-event-samples.json +17 -0
  110. package/test-learning-e2e.js +5 -0
  111. package/test-memory-mutation-queue.js +191 -0
  112. package/test-provider-boot-matrix.js +399 -0
  113. package/test-provider-bootstrap.js +158 -0
  114. package/test-provider-capabilities.js +232 -0
  115. package/test-provider-claude.js +206 -0
  116. package/test-provider-codex.js +228 -0
  117. package/test-provider-compaction.js +371 -0
  118. package/test-provider-core-prompt.js +264 -0
  119. package/test-provider-coupling-audit.js +90 -0
  120. package/test-provider-dream.js +312 -0
  121. package/test-provider-enforcer.js +252 -0
  122. package/test-provider-env-isolation.js +150 -0
  123. package/test-provider-events.js +141 -0
  124. package/test-provider-fixture.js +332 -0
  125. package/test-provider-gateway.js +508 -0
  126. package/test-provider-language.js +89 -0
  127. package/test-provider-migration-backup.js +424 -0
  128. package/test-provider-pack-review.js +436 -0
  129. package/test-provider-parity-e2e.js +537 -0
  130. package/test-provider-prompt-parity.js +89 -0
  131. package/test-provider-recall.js +271 -0
  132. package/test-provider-registry.js +251 -0
  133. package/test-provider-resume-parity.js +41 -0
  134. package/test-provider-run-lifecycle.js +349 -0
  135. package/test-provider-runner.js +271 -0
  136. package/test-provider-scheduler.js +689 -0
  137. package/test-provider-session-commands.js +185 -0
  138. package/test-provider-session-history.js +205 -0
  139. package/test-provider-side-chat.js +337 -0
  140. package/test-provider-state-migration.js +316 -0
  141. package/test-provider-stream-decoder.js +69 -0
  142. package/test-provider-subagent.js +228 -0
  143. package/test-provider-tool-hooks.js +360 -0
  144. package/test-recall-discoverer.js +1 -0
  145. package/test-recall-engine.js +3 -3
  146. package/test-recall-evolution.js +18 -0
  147. package/test-run-lock.js +63 -0
  148. package/test-runner-watchdog-static.js +16 -8
  149. package/test-single-runtime.js +35 -0
  150. package/test-telegram-poll-recovery.js +56 -0
  151. package/test-tool-guard.js +56 -0
  152. package/test-tools.js +19 -0
  153. package/test-unified-identity.js +3 -1
  154. package/test-usage-accounting.js +92 -20
  155. package/test-utility-provider-policy.js +486 -0
  156. package/test-web-sessions.js +74 -0
  157. package/web.js +159 -45
package/core/ideas.js CHANGED
@@ -10,6 +10,7 @@
10
10
  const fs = require("fs");
11
11
  const path = require("path");
12
12
  const crypto = require("crypto");
13
+ const { atomicWriteFileSync } = require("./fsutil");
13
14
  const CONFIG_DIR = require("../config-dir");
14
15
  const { dayStamp } = require("./day-seeds");
15
16
 
@@ -66,7 +67,7 @@ function writeIdeas(ideas) {
66
67
  const body = ideas.map(ideaLine).join("\n");
67
68
  const content = FILE_HEADER + "\n" + body + (body ? "\n" : "");
68
69
  fs.mkdirSync(path.dirname(IDEAS_FILE), { recursive: true, mode: 0o700 });
69
- fs.writeFileSync(IDEAS_FILE, content, { mode: 0o600 });
70
+ atomicWriteFileSync(IDEAS_FILE, content, { mode: 0o600, backup: true });
70
71
  return IDEAS_FILE;
71
72
  }
72
73
 
package/core/identity.js CHANGED
@@ -3,8 +3,8 @@
3
3
  // transport. Default canonical is `<transport>:<channelId>`; the user
4
4
  // can override with /link <email-or-id> to merge state across channels.
5
5
 
6
- const fs = require("fs");
7
6
  const { IDENTITIES_FILE } = require("./config");
7
+ const { atomicWriteFileSync, readJsonWithFallback } = require("./fsutil");
8
8
 
9
9
  function normalizeCanonicalUserId(value) {
10
10
  return String(value || "").trim().toLowerCase();
@@ -19,21 +19,18 @@ function defaultCanonicalForChannel(transport, channelId) {
19
19
  }
20
20
 
21
21
  function loadIdentities() {
22
- try {
23
- const raw = JSON.parse(fs.readFileSync(IDENTITIES_FILE, "utf-8"));
24
- return {
25
- channels: raw && typeof raw.channels === "object" ? raw.channels : {},
26
- preferred: raw && typeof raw.preferred === "object" ? raw.preferred : {},
27
- };
28
- } catch (e) {
29
- return { channels: {}, preferred: {} };
30
- }
22
+ const raw = readJsonWithFallback(IDENTITIES_FILE, null);
23
+ return {
24
+ channels: raw && typeof raw.channels === "object" ? raw.channels : {},
25
+ preferred: raw && typeof raw.preferred === "object" ? raw.preferred : {},
26
+ };
31
27
  }
32
28
 
33
29
  const identities = loadIdentities();
34
30
 
35
31
  function saveIdentities() {
36
- try { fs.writeFileSync(IDENTITIES_FILE, JSON.stringify(identities, null, 2)); } catch (e) {}
32
+ try { atomicWriteFileSync(IDENTITIES_FILE, JSON.stringify(identities, null, 2), { backup: true }); }
33
+ catch (e) { console.error("saveIdentities: write failed:", e.message); }
37
34
  }
38
35
 
39
36
  // A channel is a "configured owner channel" when its (transport, channelId)
package/core/io.js CHANGED
@@ -4,14 +4,35 @@
4
4
 
5
5
  const { currentAdapter, currentChannelId, currentUserId } = require("./context");
6
6
 
7
+ // Adapters historically overloaded their send() return value: a message id
8
+ // (Telegram numeric, Kazee ObjectId string) on success, a bare `true` when
9
+ // delivery succeeded but no editable id came back (server fast-ack), or a
10
+ // falsy value (null/false/undefined) on failure. Callers then guessed —
11
+ // `if (!sent)` read an idless success as a failure (the Kazee double-send),
12
+ // and a `typeof === "string"` edit-guard silently rejected Telegram's numeric
13
+ // id. Collapse every adapter's raw return into ONE explicit shape so no caller
14
+ // has to guess: { ok, messageId, editable }. messageId is always a string or
15
+ // null, so downstream typeof/edit-target checks are uniform across transports.
16
+ function normalizeSendResult(raw) {
17
+ if (raw === null || raw === undefined || raw === false) {
18
+ return { ok: false, messageId: null, editable: false };
19
+ }
20
+ if (raw === true) {
21
+ return { ok: true, messageId: null, editable: false };
22
+ }
23
+ const id = String(raw);
24
+ if (!id) return { ok: true, messageId: null, editable: false };
25
+ return { ok: true, messageId: id, editable: true };
26
+ }
27
+
7
28
  async function send(text, opts = {}) {
8
29
  const adapter = currentAdapter();
9
30
  const channelId = opts.channelId || currentChannelId();
10
31
  if (!adapter || !channelId) {
11
32
  console.error("send() called outside chat context");
12
- return null;
33
+ return { ok: false, messageId: null, editable: false };
13
34
  }
14
- return adapter.send(channelId, text, opts);
35
+ return normalizeSendResult(await adapter.send(channelId, text, opts));
15
36
  }
16
37
 
17
38
  async function editMessage(messageId, text, opts = {}) {
@@ -75,4 +96,4 @@ function splitMessage(text, maxLen = 4000) {
75
96
  return chunks;
76
97
  }
77
98
 
78
- module.exports = { send, editMessage, deleteMessage, sendVoice, sendVoiceEnd, sendFile, typing, splitMessage };
99
+ module.exports = { send, editMessage, deleteMessage, sendVoice, sendVoiceEnd, sendFile, typing, splitMessage, normalizeSendResult };