@kevin0181/memoc 1.4.10 → 1.4.12

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/bin/cli.js CHANGED
@@ -3812,10 +3812,42 @@ function readJsonLoose(fp) {
3812
3812
  return JSON.parse(cleaned);
3813
3813
  } catch { return null; }
3814
3814
  }
3815
-
3816
- function runInstallPlugin() {
3817
- const os = require('os');
3818
- const PLUGIN_KEY = 'memoc@memoc';
3815
+
3816
+ function writePiMemocExtension(dest, skillNames) {
3817
+ const lines = [
3818
+ 'import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";',
3819
+ '',
3820
+ 'const SKILLS: Array<[string, string]> = [',
3821
+ ...skillNames.map((name) => {
3822
+ const command = name;
3823
+ return ` ["${command}", "${name}"],`;
3824
+ }),
3825
+ '];',
3826
+ '',
3827
+ 'export default function memocPiExtension(pi: ExtensionAPI) {',
3828
+ ' for (const [command, skillName] of SKILLS) {',
3829
+ ' pi.registerCommand(command, {',
3830
+ ' description: `Run ${skillName} skill`,',
3831
+ ' handler: async (args, ctx) => {',
3832
+ ' const message = args.trim() ? `/skill:${skillName} ${args.trim()}` : `/skill:${skillName}`;',
3833
+ ' if (ctx.isIdle()) pi.sendUserMessage(message);',
3834
+ ' else {',
3835
+ ' pi.sendUserMessage(message, { deliverAs: "followUp" });',
3836
+ ' ctx.ui.notify(`Queued ${skillName}`, "info");',
3837
+ ' }',
3838
+ ' },',
3839
+ ' });',
3840
+ ' }',
3841
+ '}',
3842
+ '',
3843
+ ];
3844
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
3845
+ fs.writeFileSync(dest, lines.join('\n'));
3846
+ }
3847
+
3848
+ function runInstallPlugin() {
3849
+ const os = require('os');
3850
+ const PLUGIN_KEY = 'memoc@memoc';
3819
3851
 
3820
3852
  const pkgRoot = path.join(__dirname, '..');
3821
3853
  const pluginSrc = path.join(pkgRoot, 'plugins', 'memoc');
@@ -3928,9 +3960,12 @@ function runInstallPlugin() {
3928
3960
  const agentsDir = path.join(os.homedir(), '.agents');
3929
3961
  const agentSkills = path.join(agentsDir, 'skills');
3930
3962
  const skillLockPath = path.join(agentsDir, '.skill-lock.json');
3931
- const skillsSrc = path.join(pkgRoot, 'skills');
3932
-
3933
- if (fs.existsSync(skillsSrc)) {
3963
+ const skillsSrc = path.join(pkgRoot, 'skills');
3964
+ const piDir = process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), '.pi', 'agent');
3965
+ const piExtension = path.join(piDir, 'extensions', 'memoc.ts');
3966
+ const piSettingsPath = path.join(piDir, 'settings.json');
3967
+
3968
+ if (fs.existsSync(skillsSrc)) {
3934
3969
  const skillLock = readJsonLoose(skillLockPath) || { version: 3, skills: {} };
3935
3970
  if (!skillLock.skills) skillLock.skills = {};
3936
3971
  for (const name of DEPRECATED_SKILL_NAMES) {
@@ -3939,11 +3974,11 @@ function runInstallPlugin() {
3939
3974
  delete skillLock.skills[name];
3940
3975
  }
3941
3976
  for (const name of SKILL_NAMES) {
3942
- const src = path.join(skillsSrc, name);
3943
- if (!fs.existsSync(src)) continue;
3944
- copyDirSync(src, path.join(agentSkills, name));
3945
- const prev = skillLock.skills[name] || {};
3946
- skillLock.skills[name] = {
3977
+ const src = path.join(skillsSrc, name);
3978
+ if (!fs.existsSync(src)) continue;
3979
+ copyDirSync(src, path.join(agentSkills, name));
3980
+ const prev = skillLock.skills[name] || {};
3981
+ skillLock.skills[name] = {
3947
3982
  source: 'neneee0181/memoc',
3948
3983
  sourceType: 'npm',
3949
3984
  sourceUrl: 'https://github.com/neneee0181/memoc.git',
@@ -3953,14 +3988,27 @@ function runInstallPlugin() {
3953
3988
  updatedAt: now,
3954
3989
  };
3955
3990
  }
3956
- fs.mkdirSync(agentsDir, { recursive: true });
3957
- fs.writeFileSync(skillLockPath, JSON.stringify(skillLock, null, 2) + '\n');
3958
- }
3959
-
3991
+ fs.mkdirSync(agentsDir, { recursive: true });
3992
+ fs.writeFileSync(skillLockPath, JSON.stringify(skillLock, null, 2) + '\n');
3993
+
3994
+ // Pi Dev also reads ~/.agents/skills. Keep only the extension in ~/.pi/agent
3995
+ // so startup does not report duplicate skill conflicts.
3996
+ for (const name of [...SKILL_NAMES, ...DEPRECATED_SKILL_NAMES]) {
3997
+ const oldPiDest = path.join(piDir, 'skills', name);
3998
+ if (fs.existsSync(oldPiDest)) fs.rmSync(oldPiDest, { recursive: true, force: true });
3999
+ }
4000
+ writePiMemocExtension(piExtension, SKILL_NAMES);
4001
+ const piSettings = readJsonLoose(piSettingsPath) || {};
4002
+ piSettings.enableSkillCommands = true;
4003
+ fs.mkdirSync(path.dirname(piSettingsPath), { recursive: true });
4004
+ fs.writeFileSync(piSettingsPath, JSON.stringify(piSettings, null, 2) + '\n');
4005
+ }
4006
+
3960
4007
  console.log('\n memoc plugin installed\n');
3961
4008
  console.log(' Claude Code ~/.claude/plugins/cache/memoc/ + ~/.claude/plugins/marketplaces/memoc/');
3962
4009
  console.log(' Codex Desktop ~/.agents/skills/');
3963
4010
  console.log(' Skills spec ~/.agents/skills/ (Cursor, Windsurf, and other supported agents)');
4011
+ console.log(' Pi Dev ~/.pi/agent/extensions/memoc.ts (uses ~/.agents/skills/)');
3964
4012
  console.log('\n Skills:');
3965
4013
  for (const s of SKILL_NAMES) console.log(` /${s}`);
3966
4014
  console.log('\n Restart open agent apps to reload skills.\n');
@@ -3995,12 +4043,17 @@ function runUninstallPlugin() {
3995
4043
  }
3996
4044
 
3997
4045
  // remove from ~/.agents/skills/
3998
- const agentsDir = path.join(os.homedir(), '.agents');
3999
- const skillLockPath = path.join(agentsDir, '.skill-lock.json');
4000
- for (const name of SKILL_NAMES) {
4001
- const d = path.join(agentsDir, 'skills', name);
4002
- if (fs.existsSync(d)) fs.rmSync(d, { recursive: true, force: true });
4003
- }
4046
+ const agentsDir = path.join(os.homedir(), '.agents');
4047
+ const skillLockPath = path.join(agentsDir, '.skill-lock.json');
4048
+ const piDir = process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), '.pi', 'agent');
4049
+ const piExtension = path.join(piDir, 'extensions', 'memoc.ts');
4050
+ for (const name of SKILL_NAMES) {
4051
+ const d = path.join(agentsDir, 'skills', name);
4052
+ if (fs.existsSync(d)) fs.rmSync(d, { recursive: true, force: true });
4053
+ const piSkillDir = path.join(piDir, 'skills', name);
4054
+ if (fs.existsSync(piSkillDir)) fs.rmSync(piSkillDir, { recursive: true, force: true });
4055
+ }
4056
+ if (fs.existsSync(piExtension)) fs.rmSync(piExtension, { force: true });
4004
4057
  const skillLock = readJsonLoose(skillLockPath);
4005
4058
  if (skillLock && skillLock.skills) {
4006
4059
  for (const name of SKILL_NAMES) delete skillLock.skills[name];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevin0181/memoc",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Give AI agents a memory. Scaffolds session-to-session context for Claude Code, Codex, Cursor, and more.",
5
5
  "keywords": [
6
6
  "ai",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "memoc",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Agent memory skills for memoc — scaffold, maintain, and query session-to-session AI memory.",
5
5
  "author": {
6
6
  "name": "kevin0181",