@inetafrica/open-claudia 2.6.1 → 2.6.3

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/core/runner.js CHANGED
@@ -647,6 +647,15 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
647
647
  };
648
648
 
649
649
  const args = buildClaudeArgs(prompt, opts);
650
+ // Recall announcements: mirror the write-side "🧠 jotted down" notes with
651
+ // a read-side line whenever packs/entities freshly enter context this turn.
652
+ try {
653
+ const { packs, entities } = require("./system-prompt").consumeLastInjected();
654
+ const recalled = [...packs, ...entities];
655
+ if (recalled.length > 0) {
656
+ chatContext.run(store, () => send(`šŸ“– Recalled my notes on: ${recalled.join(", ")}`).catch(() => {}));
657
+ }
658
+ } catch (e) { /* announcements are best-effort */ }
650
659
  const binaryPath = getActiveBinary();
651
660
  const proc = spawn(binaryPath, args, {
652
661
  cwd,
@@ -214,6 +214,7 @@ If you tell the user "I'll check back in N minutes" or "I'll run this every morn
214
214
 
215
215
  ## Guidelines
216
216
  - Keep responses concise — many users are on mobile.
217
+ - Be time-aware: the Runtime state block carries the current local time. Before suggesting that the user contact, test with, or wait on a colleague, check it against that person's working hours (entity notes often record their timezone). Late evening / night / early morning → schedule a wakeup for their next working morning instead of suggesting it now.
217
218
  - Markdown: use simple chat-safe formatting only. On Telegram follow the Telegram formatting section exactly; on Kazee use short bullets/paragraphs and avoid tables unless requested.
218
219
  - For long output (logs, diffs, large code), save to a file and send it as an artifact instead of pasting walls of text.
219
220
  - Act on screenshots (fix bugs, implement designs) — don't just describe what you see.
@@ -245,8 +246,13 @@ function buildDynamicContextBlock() {
245
246
  const state = currentState();
246
247
  const adapter = currentAdapter();
247
248
  const channelId = currentChannelId();
249
+ const now = new Date();
250
+ const localTime = now.toLocaleString("en-GB", { weekday: "long", hour: "2-digit", minute: "2-digit", hour12: false, timeZoneName: "short" });
251
+ const hour = now.getHours();
252
+ const offHours = hour >= 19 || hour < 7;
248
253
  const lines = [
249
254
  "## Runtime state (current turn)",
255
+ `- Local time: ${localTime}${offHours ? " — outside normal working hours: don't suggest contacting, testing with, or waiting on colleagues right now; schedule it for their next working morning instead" : ""}`,
250
256
  `- Vault: ${vault.isUnlocked() ? "unlocked" : "locked"}`,
251
257
  `- Session: ${state.lastSessionId ? "resuming existing conversation" : "new conversation"}`,
252
258
  ];
@@ -278,6 +284,16 @@ function buildDynamicContextBlock() {
278
284
  const packsInjectedFor = new Map(); // `${adapterId}:${channelId}:${dir}` -> `${sessionId}:${updated}`
279
285
  const PACK_INJECT_MAX_CHARS = 4000;
280
286
 
287
+ // What the last promptWithDynamicContext call freshly injected (not the
288
+ // deduped repeats) — consumed by the runner to announce recalls in chat,
289
+ // mirroring the write-side announcements.
290
+ let lastInjected = { packs: [], entities: [] };
291
+ function consumeLastInjected() {
292
+ const out = lastInjected;
293
+ lastInjected = { packs: [], entities: [] };
294
+ return out;
295
+ }
296
+
281
297
  function formatPackForContext(pack, packsLib) {
282
298
  const clip = (s, n) => (s.length > n ? s.slice(0, n) + "\n…[truncated — read the full pack file]" : s);
283
299
  const parts = [`### Pack: ${pack.name} (${pack.dir})`];
@@ -319,6 +335,7 @@ function buildPackBlock(prompt) {
319
335
  const stamp = `${sess}:${pack.updated}`;
320
336
  if (packsInjectedFor.get(key) === stamp) continue;
321
337
  packsInjectedFor.set(key, stamp);
338
+ lastInjected.packs.push(pack.name || m.dir);
322
339
  blocks.push(formatPackForContext(pack, packsLib));
323
340
  }
324
341
  if (used.length > 0) setImmediate(() => { try { packsLib.touchUsed(used); } catch (e) {} });
@@ -365,6 +382,7 @@ function buildEntityBlock(prompt) {
365
382
  const stamp = `${sess}:${ent.updated}`;
366
383
  if (entitiesInjectedFor.get(key) === stamp) continue;
367
384
  entitiesInjectedFor.set(key, stamp);
385
+ lastInjected.entities.push(ent.name || m.slug);
368
386
  blocks.push(formatEntityForContext(ent));
369
387
  }
370
388
  if (seen.length > 0) setImmediate(() => { try { entitiesLib.touchSeen(seen); } catch (e) {} });
@@ -376,6 +394,7 @@ function buildEntityBlock(prompt) {
376
394
  }
377
395
 
378
396
  function promptWithDynamicContext(prompt) {
397
+ lastInjected = { packs: [], entities: [] };
379
398
  try {
380
399
  return `${buildDynamicContextBlock()}${buildPackBlock(prompt)}${buildEntityBlock(prompt)}\n\nCurrent user request:\n${prompt}`;
381
400
  } catch (e) {
@@ -383,4 +402,4 @@ function promptWithDynamicContext(prompt) {
383
402
  }
384
403
  }
385
404
 
386
- module.exports = { loadSoul, buildSystemPrompt, buildDynamicContextBlock, promptWithDynamicContext };
405
+ module.exports = { loadSoul, buildSystemPrompt, buildDynamicContextBlock, promptWithDynamicContext, consumeLastInjected };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "2.6.1",
3
+ "version": "2.6.3",
4
4
  "description": "Your always-on AI coding assistant — Claude Code, Cursor Agent, and OpenAI Codex via Telegram or Kazee Chat",
5
5
  "main": "bot.js",
6
6
  "bin": {