incitaciones 0.3.1 → 0.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incitaciones",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Reusable prompts and skills for CLI LLM tools, with native pi package support.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -2,6 +2,8 @@
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
+ import { homedir } from "node:os";
6
+ import process from "node:process";
5
7
 
6
8
  const __filename = fileURLToPath(import.meta.url);
7
9
  const __dirname = path.dirname(__filename);
@@ -32,6 +34,15 @@ function readText(filePath) {
32
34
  return fs.readFileSync(filePath, "utf8");
33
35
  }
34
36
 
37
+ function getPackageVersion() {
38
+ try {
39
+ const pkg = JSON.parse(readText(path.join(repoRoot, "package.json")));
40
+ return `npm:${pkg.version}`;
41
+ } catch {
42
+ return new Date().toISOString().slice(0, 10);
43
+ }
44
+ }
45
+
35
46
  function generateSkill(prompt) {
36
47
  const distilledPath = path.join(repoRoot, prompt.distilled);
37
48
  const skillDir = path.join(skillsOut, prompt.name);
@@ -83,6 +94,113 @@ function generatePromptTemplate(prompt) {
83
94
  fs.writeFileSync(path.join(promptsOut, `${prompt.name}.md`), template, "utf8");
84
95
  }
85
96
 
97
+ /**
98
+ * Detect flat-skills directories that already have incitaciones skills installed,
99
+ * and re-sync them with the latest pi-package content. This ensures that
100
+ * pi update / npm version bumps keep flat-install locations current.
101
+ *
102
+ * Flat installs (e.g. ~/.agents/skills/) are created by install.sh and
103
+ * npx incitaciones install, but are NOT managed by pi's package reader
104
+ * (which reads directly from pi-package/skills/). Without this re-sync,
105
+ * a version bump leaves those directories stale.
106
+ */
107
+ function reSyncFlatInstallSkills(manifest) {
108
+ const version = getPackageVersion();
109
+ const now = new Date().toISOString().replace("Z", "000Z");
110
+ const home = homedir();
111
+
112
+ // Candidate directories to check for incitaciones flat installs
113
+ const candidates = [
114
+ path.join(home, ".agents", "skills"),
115
+ path.join(home, ".config", "agents", "skills"),
116
+ ];
117
+
118
+ // Also check .agents/skills in cwd for project-local installs
119
+ try {
120
+ candidates.push(path.join(process.cwd(), ".agents", "skills"));
121
+ } catch {}
122
+
123
+ // Deduplicate
124
+ const checked = new Set();
125
+ const dirs = candidates.filter((d) => {
126
+ if (checked.has(d)) return false;
127
+ checked.add(d);
128
+ return fs.existsSync(d);
129
+ });
130
+
131
+ let synced = 0;
132
+ for (const dir of dirs) {
133
+ // Check if this directory has incitaciones-installed skills
134
+ // by reading the first SKILL.md we find and checking its frontmatter
135
+ let hasIncitaciones = false;
136
+ try {
137
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
138
+ if (!entry.isDirectory()) continue;
139
+ const skillFile = path.join(dir, entry.name, "SKILL.md");
140
+ if (!fs.existsSync(skillFile)) continue;
141
+ const content = fs.readFileSync(skillFile, "utf8");
142
+ if (content.includes("installed-from: incitaciones") || content.includes("installed-from: \"incitaciones\"")) {
143
+ hasIncitaciones = true;
144
+ break;
145
+ }
146
+ }
147
+ } catch {
148
+ // Permission issues, etc. — skip
149
+ continue;
150
+ }
151
+
152
+ if (!hasIncitaciones) continue;
153
+
154
+ // Re-sync: for each prompt in manifest, copy from pi-package/skills/ to flat dir
155
+ for (const prompt of manifest.prompts) {
156
+ const srcDir = path.join(skillsOut, prompt.name);
157
+ if (!fs.existsSync(srcDir)) continue;
158
+
159
+ const dstDir = path.join(dir, prompt.name);
160
+ fs.rmSync(dstDir, { recursive: true, force: true });
161
+ fs.mkdirSync(dstDir, { recursive: true });
162
+
163
+ // Generate flat-format frontmatter for SKILL.md
164
+ const distilledPath = path.join(repoRoot, prompt.distilled);
165
+ if (!fs.existsSync(distilledPath)) continue;
166
+
167
+ const description = escapeYamlDoubleQuoted(prompt.description || `Incitaciones prompt: ${prompt.name}`);
168
+ const frontmatter = [
169
+ "---",
170
+ `name: ${prompt.name}`,
171
+ `description: "${description}"`,
172
+ "installed-from: incitaciones",
173
+ `installed-version: "${version}"`,
174
+ `installed-at: "${now}"`,
175
+ "---",
176
+ "",
177
+ ].join("\n");
178
+
179
+ fs.writeFileSync(path.join(dstDir, "SKILL.md"), frontmatter + readText(distilledPath), "utf8");
180
+
181
+ // Copy references/ from the source skill directory
182
+ if (distilledPath.endsWith(`${path.sep}SKILL.md`)) {
183
+ const srcRefDir = path.dirname(distilledPath);
184
+ for (const entry of fs.readdirSync(srcRefDir, { withFileTypes: true })) {
185
+ if (entry.name === "SKILL.md") continue;
186
+ const s = path.join(srcRefDir, entry.name);
187
+ const d = path.join(dstDir, entry.name);
188
+ if (entry.isDirectory()) {
189
+ fs.cpSync(s, d, { recursive: true });
190
+ } else {
191
+ fs.copyFileSync(s, d);
192
+ }
193
+ }
194
+ }
195
+ }
196
+ synced++;
197
+ }
198
+
199
+ if (synced > 0) {
200
+ console.log(`Re-synced incitaciones skills in ${synced} flat-install director(ies)`);
201
+ }
202
+ }
203
+
86
204
  function main() {
87
205
  const manifest = JSON.parse(readText(manifestPath));
88
206
  resetDir(outRoot);
@@ -117,6 +235,9 @@ function main() {
117
235
  fs.writeFileSync(path.join(outRoot, "README.md"), readme, "utf8");
118
236
 
119
237
  console.log(`Generated pi resources for ${manifest.prompts.length} prompts in ${path.relative(repoRoot, outRoot)}/`);
238
+
239
+ // Re-sync any existing flat-install skill directories (e.g. ~/.agents/skills/)
240
+ reSyncFlatInstallSkills(manifest);
120
241
  }
121
242
 
122
- main();
243
+ main();