@inetafrica/open-claudia 2.6.21 → 2.6.22

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 (2) hide show
  1. package/core/handlers.js +30 -16
  2. package/package.json +1 -1
package/core/handlers.js CHANGED
@@ -25,6 +25,7 @@ const { isNewerVersion } = require("./version");
25
25
  const jobs = require("./jobs");
26
26
  const scheduler = require("./scheduler");
27
27
  const skillsLib = require("./skills");
28
+ const packsLib = require("./packs");
28
29
  const {
29
30
  runClaude, compactActiveSession, getActiveSessionId, effectiveCompactThreshold,
30
31
  } = require("./runner");
@@ -946,7 +947,10 @@ register({
946
947
  },
947
948
  });
948
949
 
949
- // ── Learned skills ──────────────────────────────────────────────────
950
+ // ── Learned skills (now backed by context packs) ────────────────────
951
+ // Skills migrated into context packs (~/.open-claudia/packs). /skills is a
952
+ // thin window onto that store; any stragglers still in the legacy
953
+ // ~/.claude/skills dir get surfaced as a one-line migration nudge.
950
954
 
951
955
  register({
952
956
  name: "skills", description: "List, show, or remove learned skills", args: "[show|remove <name>]",
@@ -956,26 +960,35 @@ register({
956
960
  const name = rest.join(" ");
957
961
 
958
962
  if (sub === "show" && name) {
959
- const skill = skillsLib.findSkill(name);
960
- if (!skill) return send(`No skill named "${name}". /skills to list.`);
963
+ const pack = packsLib.findPack(name);
964
+ if (!pack) return send(`No skill named "${name}". /skills to list.`);
965
+ const file = path.join(packsLib.PACKS_DIR, pack.dir, "PACK.md");
961
966
  let content;
962
- try { content = fs.readFileSync(skill.file, "utf-8"); } catch (e) { return send(`Could not read ${skill.file}: ${e.message}`); }
967
+ try { content = fs.readFileSync(file, "utf-8"); } catch (e) { return send(`Could not read ${file}: ${e.message}`); }
963
968
  const preview = content.length > 3500 ? content.slice(0, 3500) + "\n…(truncated)" : content;
964
969
  await send(preview);
965
- return send(`File: ${skill.file}`);
970
+ return send(`File: ${file}`);
966
971
  }
967
972
 
968
973
  if (sub === "remove" && name) {
969
- const skill = skillsLib.findSkill(name);
970
- if (!skill) return send(`No skill named "${name}". /skills to list.`);
971
- skillsLib.removeSkill(name);
972
- return send(`Removed skill: ${skill.name} (${skill.file})`);
974
+ const pack = packsLib.findPack(name);
975
+ if (!pack) return send(`No skill named "${name}". /skills to list.`);
976
+ packsLib.removePack(pack.dir);
977
+ return send(`Removed skill pack: ${pack.name} (${pack.dir})`);
973
978
  }
974
979
 
975
- const skills = skillsLib.listSkills();
976
- if (skills.length === 0) return send("No learned skills yet. I save them automatically after complex tasks, or use /learn to capture the last piece of work.");
977
- const lines = skills.map((s) => `• ${s.dir} — ${s.description || "(no description)"}`);
978
- return send(`Learned skills (${skills.length}):\n\n${lines.join("\n")}\n\n/skills show <name> · /skills remove <name> · /learn [hint]`);
980
+ const packs = packsLib.listPacks();
981
+ const legacy = skillsLib.listSkills();
982
+ if (packs.length === 0 && legacy.length === 0) {
983
+ return send("No skills yet. I save them automatically as context packs after complex tasks, or use /learn to capture the last piece of work.");
984
+ }
985
+ const lines = packs.map((p) => `• ${p.dir} — ${p.description || p.name || "(no description)"}`);
986
+ let msg = `Skills / context packs (${packs.length}):\n\n${lines.join("\n")}`;
987
+ if (legacy.length) {
988
+ msg += `\n\n${legacy.length} legacy skill(s) still in ~/.claude/skills — run open-claudia pack migrate to fold them in.`;
989
+ }
990
+ msg += `\n\n/skills show <name> · /skills remove <name> · /learn [hint]`;
991
+ return send(msg);
979
992
  },
980
993
  });
981
994
 
@@ -988,9 +1001,10 @@ register({
988
1001
  const hint = tail ? ` The user's hint about what to capture: "${tail}".` : "";
989
1002
  const prompt =
990
1003
  `The user typed /learn: capture the most recent substantial piece of work in this conversation as a reusable skill.${hint} ` +
991
- `Follow the Skill learning rules in your system prompt: check ~/.claude/skills/ first and patch an existing skill instead of duplicating; ` +
992
- `otherwise write ~/.claude/skills/<kebab-name>/SKILL.md with name + a when-to-use description in the frontmatter, then prerequisites, exact commands in order, and pitfalls. ` +
993
- `No secrets or tokens. When done, reply with one short line saying which skill you created or updated and what it covers. ` +
1004
+ `Skills live in context packs (~/.open-claudia/packs/<dir>/PACK.md), NOT the legacy ~/.claude/skills dir. ` +
1005
+ `First check the already-injected packs and 'open-claudia pack list' for a pack this work belongs to; if one fits, fold the reusable how-to into that pack's Procedure section (exact commands in order, prerequisites, pitfalls) and append a dated Journal line — edit the PACK.md directly. ` +
1006
+ `Only if no pack fits, create a new one: 'open-claudia pack' has no create subcommand, so write ~/.open-claudia/packs/<kebab-name>/PACK.md following the four-section format (Stance, Procedure, State, Journal) with name + a when-to-use description in the frontmatter. ` +
1007
+ `No secrets or tokens. When done, reply with one short line naming the pack you created or updated and what it covers. ` +
994
1008
  `If the recent work is genuinely not reusable, say so instead of forcing a skill.`;
995
1009
  await runClaude(prompt, currentState().currentSession.dir, env.messageId);
996
1010
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inetafrica/open-claudia",
3
- "version": "2.6.21",
3
+ "version": "2.6.22",
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": {