@spences10/pi-skills 0.0.7 → 0.0.9

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/README.md CHANGED
@@ -29,7 +29,8 @@ pi -e ./packages/pi-skills
29
29
  Pi already has native skill discovery. This package adds a management
30
30
  layer for mixed skill ecosystems:
31
31
 
32
- - discovers Pi-native skills in `~/.pi/agent/skills`
32
+ - discovers Pi-native skills in `$PI_CODING_AGENT_DIR/skills`
33
+ (default: `~/.pi/agent/skills`)
33
34
  - discovers user-local Claude skills in `~/.claude/skills`
34
35
  - discovers skills bundled inside installed Claude plugins
35
36
  - imports plugin skills into Pi-native skill storage
@@ -39,9 +40,13 @@ layer for mixed skill ecosystems:
39
40
  Imported skills are copied into:
40
41
 
41
42
  ```text
42
- ~/.pi/agent/skills/<skill-name>
43
+ $PI_CODING_AGENT_DIR/skills/<skill-name>
43
44
  ```
44
45
 
46
+ The `~/.claude` locations are intentional upstream discovery sources,
47
+ not Pi-managed state. Use `--no-skills` or `--untrusted` when sandbox
48
+ runs must not read user-local Claude skills/plugins.
49
+
45
50
  Import metadata is stored beside each imported skill so sync can
46
51
  detect local edits and upstream changes.
47
52
 
@@ -0,0 +1,2 @@
1
+ import type { ExtensionAPI } from '@mariozechner/pi-coding-agent';
2
+ export default function skills(pi: ExtensionAPI): Promise<void>;
@@ -0,0 +1,444 @@
1
+ import { show_input_modal, show_text_modal, } from '@spences10/pi-tui-modal';
2
+ import { create_skills_manager } from './manager.js';
3
+ import { find_skill, format_profile_detail, format_skill_detail, format_skill_list, profile_description, sort_skills, } from './skill-utils.js';
4
+ import { pick_profile, pick_skill, show_defaults_modal, show_profiles_modal, show_refresh_summary, show_skill_detail_modal, show_skill_list_modal, show_skills_home_modal, show_skills_manager_modal, } from './skills-ui.js';
5
+ export default async function skills(pi) {
6
+ const mgr = create_skills_manager();
7
+ const subs = [
8
+ 'list',
9
+ 'show',
10
+ 'import',
11
+ 'sync',
12
+ 'profile',
13
+ 'refresh',
14
+ 'defaults',
15
+ ];
16
+ pi.registerCommand('skills', {
17
+ description: 'Manage pi-native skills and import external skills',
18
+ getArgumentCompletions: (prefix) => {
19
+ const parts = prefix.trimStart().split(/\s+/);
20
+ const has_trailing_space = /\s$/.test(prefix);
21
+ if (parts.length <= 1 && !has_trailing_space) {
22
+ return subs
23
+ .filter((s) => s.startsWith(parts[0] || ''))
24
+ .map((s) => ({ value: s, label: s }));
25
+ }
26
+ if (parts[0] === 'show') {
27
+ const q = parts.slice(1).join(' ').toLowerCase();
28
+ return sort_skills([
29
+ ...mgr.discover(),
30
+ ...mgr.discover_importable(),
31
+ ])
32
+ .filter((s) => s.key.toLowerCase().includes(q) ||
33
+ s.name.toLowerCase().includes(q))
34
+ .slice(0, 20)
35
+ .map((s) => ({
36
+ value: `${parts[0]} ${s.key}`,
37
+ label: s.key,
38
+ }));
39
+ }
40
+ if (parts[0] === 'import') {
41
+ const q = parts.slice(1).join(' ').toLowerCase();
42
+ return sort_skills(mgr.discover_importable())
43
+ .filter((s) => s.key.toLowerCase().includes(q) ||
44
+ s.name.toLowerCase().includes(q))
45
+ .slice(0, 20)
46
+ .map((s) => ({
47
+ value: `${parts[0]} ${s.key}`,
48
+ label: s.key,
49
+ }));
50
+ }
51
+ if (parts[0] === 'sync') {
52
+ const q = parts.slice(1).join(' ').toLowerCase();
53
+ return sort_skills(mgr
54
+ .discover()
55
+ .filter((skill) => Boolean(skill.import_meta)))
56
+ .filter((s) => s.key.toLowerCase().includes(q) ||
57
+ s.name.toLowerCase().includes(q))
58
+ .slice(0, 20)
59
+ .map((s) => ({
60
+ value: `${parts[0]} ${s.key}`,
61
+ label: s.key,
62
+ }));
63
+ }
64
+ if (parts[0] === 'profile') {
65
+ const profile_subs = [
66
+ 'list',
67
+ 'show',
68
+ 'use',
69
+ 'create',
70
+ 'include',
71
+ 'exclude',
72
+ ];
73
+ if (parts.length <= 2 && !has_trailing_space) {
74
+ return profile_subs
75
+ .filter((s) => s.startsWith(parts[1] || ''))
76
+ .map((s) => ({ value: `profile ${s}`, label: s }));
77
+ }
78
+ if (['show', 'use', 'include', 'exclude'].includes(parts[1] ?? '')) {
79
+ const q = parts.slice(2).join(' ').toLowerCase();
80
+ return mgr
81
+ .list_profiles()
82
+ .filter((profile) => profile.name.toLowerCase().includes(q))
83
+ .slice(0, 20)
84
+ .map((profile) => ({
85
+ value: `profile ${parts[1]} ${profile.name}`,
86
+ label: profile.name,
87
+ }));
88
+ }
89
+ }
90
+ return null;
91
+ },
92
+ handler: async (args, ctx) => {
93
+ const trimmed = args.trim();
94
+ if (!trimmed && ctx.hasUI) {
95
+ while (true) {
96
+ const managed_count = mgr.discover().length;
97
+ const importable_count = mgr.discover_importable().length;
98
+ const selected = await show_skills_home_modal(ctx, managed_count, importable_count, mgr.get_active_profile());
99
+ if (!selected)
100
+ return;
101
+ if (selected === 'manage') {
102
+ if (await show_skills_manager_modal(ctx, mgr))
103
+ return;
104
+ }
105
+ else if (selected === 'browse') {
106
+ await show_skill_list_modal(ctx, mgr);
107
+ }
108
+ else if (selected === 'import') {
109
+ const key = await pick_skill(ctx, {
110
+ title: 'Import skill',
111
+ subtitle: 'Copy an external skill into Pi-native storage',
112
+ skills: sort_skills(mgr.discover_importable()),
113
+ empty_message: 'No importable skills found',
114
+ });
115
+ if (!key)
116
+ continue;
117
+ try {
118
+ const result = mgr.import_skill(key);
119
+ ctx.ui.notify(`Imported ${key} to ${result.skillDir}. Reloading...`, 'info');
120
+ await ctx.reload();
121
+ return;
122
+ }
123
+ catch (error) {
124
+ ctx.ui.notify(error instanceof Error
125
+ ? error.message
126
+ : String(error), 'warning');
127
+ }
128
+ }
129
+ else if (selected === 'sync') {
130
+ const key = await pick_skill(ctx, {
131
+ title: 'Sync imported skill',
132
+ subtitle: 'Update an imported skill from its upstream source',
133
+ skills: sort_skills(mgr
134
+ .discover()
135
+ .filter((skill) => Boolean(skill.import_meta))),
136
+ empty_message: 'No imported skills found',
137
+ });
138
+ if (!key)
139
+ continue;
140
+ try {
141
+ const result = mgr.sync_skill(key);
142
+ if (result.changed) {
143
+ ctx.ui.notify(`Synced ${key}. Reloading...`, 'info');
144
+ await ctx.reload();
145
+ return;
146
+ }
147
+ await show_text_modal(ctx, {
148
+ title: 'Skill already up to date',
149
+ text: `${key} is already up to date.`,
150
+ });
151
+ }
152
+ catch (error) {
153
+ ctx.ui.notify(error instanceof Error
154
+ ? error.message
155
+ : String(error), 'warning');
156
+ }
157
+ }
158
+ else if (selected === 'profiles') {
159
+ if (await show_profiles_modal(ctx, mgr))
160
+ return;
161
+ }
162
+ else if (selected === 'refresh') {
163
+ await show_refresh_summary(ctx, mgr);
164
+ }
165
+ else if (selected === 'defaults') {
166
+ await show_defaults_modal(ctx, mgr);
167
+ }
168
+ }
169
+ }
170
+ const [sub, ...rest] = (trimmed || 'list').split(/\s+/);
171
+ const arg = rest.join(' ');
172
+ switch (sub) {
173
+ case 'list': {
174
+ const skills = [
175
+ ...mgr.discover(),
176
+ ...mgr.discover_importable(),
177
+ ];
178
+ if (ctx.hasUI) {
179
+ await show_skill_list_modal(ctx, mgr);
180
+ }
181
+ else {
182
+ ctx.ui.notify(format_skill_list(skills));
183
+ }
184
+ break;
185
+ }
186
+ case 'show': {
187
+ const skills = [
188
+ ...mgr.discover(),
189
+ ...mgr.discover_importable(),
190
+ ];
191
+ let target = arg;
192
+ if (!target && ctx.hasUI) {
193
+ target =
194
+ (await pick_skill(ctx, {
195
+ title: 'Show skill details',
196
+ subtitle: 'Open a read-only skill detail view',
197
+ skills: sort_skills(skills),
198
+ empty_message: 'No skills found',
199
+ })) ?? '';
200
+ if (!target)
201
+ return;
202
+ }
203
+ if (!target) {
204
+ ctx.ui.notify('Usage: /skills show <key|name>', 'warning');
205
+ return;
206
+ }
207
+ try {
208
+ const skill = find_skill(skills, target);
209
+ if (ctx.hasUI) {
210
+ await show_skill_detail_modal(ctx, skill);
211
+ }
212
+ else {
213
+ ctx.ui.notify(format_skill_detail(skill));
214
+ }
215
+ }
216
+ catch (error) {
217
+ ctx.ui.notify(error instanceof Error ? error.message : String(error), 'warning');
218
+ }
219
+ break;
220
+ }
221
+ case 'import': {
222
+ let target = arg;
223
+ if (!target && ctx.hasUI) {
224
+ target =
225
+ (await pick_skill(ctx, {
226
+ title: 'Import skill',
227
+ subtitle: 'Copy an external skill into Pi-native storage',
228
+ skills: sort_skills(mgr.discover_importable()),
229
+ empty_message: 'No importable skills found',
230
+ })) ?? '';
231
+ if (!target)
232
+ return;
233
+ }
234
+ if (!target) {
235
+ ctx.ui.notify('Usage: /skills import <key|name>', 'warning');
236
+ return;
237
+ }
238
+ try {
239
+ const result = mgr.import_skill(target);
240
+ ctx.ui.notify(`Imported ${target} to ${result.skillDir}. Reloading...`, 'info');
241
+ await ctx.reload();
242
+ return;
243
+ }
244
+ catch (error) {
245
+ ctx.ui.notify(error instanceof Error ? error.message : String(error), 'warning');
246
+ return;
247
+ }
248
+ }
249
+ case 'sync': {
250
+ let target = arg;
251
+ if (!target && ctx.hasUI) {
252
+ target =
253
+ (await pick_skill(ctx, {
254
+ title: 'Sync imported skill',
255
+ subtitle: 'Update an imported skill from its upstream source',
256
+ skills: sort_skills(mgr
257
+ .discover()
258
+ .filter((skill) => Boolean(skill.import_meta))),
259
+ empty_message: 'No imported skills found',
260
+ })) ?? '';
261
+ if (!target)
262
+ return;
263
+ }
264
+ if (!target) {
265
+ ctx.ui.notify('Usage: /skills sync <key|name>', 'warning');
266
+ return;
267
+ }
268
+ try {
269
+ const result = mgr.sync_skill(target);
270
+ if (result.changed) {
271
+ ctx.ui.notify(`Synced ${target}. Reloading...`, 'info');
272
+ await ctx.reload();
273
+ return;
274
+ }
275
+ if (ctx.hasUI) {
276
+ await show_text_modal(ctx, {
277
+ title: 'Skill already up to date',
278
+ text: `${target} is already up to date.`,
279
+ });
280
+ }
281
+ else {
282
+ ctx.ui.notify(`${target} is already up to date.`, 'info');
283
+ }
284
+ return;
285
+ }
286
+ catch (error) {
287
+ ctx.ui.notify(error instanceof Error ? error.message : String(error), 'warning');
288
+ return;
289
+ }
290
+ }
291
+ case 'profile': {
292
+ const [action = 'list', name, ...pattern_parts] = rest;
293
+ const pattern = pattern_parts.join(' ');
294
+ if (!args.trim().startsWith('profile') && ctx.hasUI) {
295
+ if (await show_profiles_modal(ctx, mgr))
296
+ return;
297
+ break;
298
+ }
299
+ if (action === 'list') {
300
+ const text = mgr
301
+ .list_profiles()
302
+ .map((profile) => `${profile.active ? 'active' : ' '} ${profile.name} — ${profile_description(profile)}`)
303
+ .join('\n');
304
+ if (ctx.hasUI) {
305
+ await show_text_modal(ctx, {
306
+ title: 'Skill profiles',
307
+ text: text || 'No skill profiles found',
308
+ });
309
+ }
310
+ else {
311
+ ctx.ui.notify(text || 'No skill profiles found');
312
+ }
313
+ break;
314
+ }
315
+ if (action === 'show') {
316
+ let target = name;
317
+ if (!target && ctx.hasUI) {
318
+ target = await pick_profile(ctx, mgr, 'Show skill profile');
319
+ }
320
+ const profile = mgr
321
+ .list_profiles()
322
+ .find((candidate) => candidate.name === target);
323
+ if (!profile) {
324
+ ctx.ui.notify('Usage: /skills profile show <name>', 'warning');
325
+ break;
326
+ }
327
+ if (ctx.hasUI) {
328
+ await show_text_modal(ctx, {
329
+ title: profile.name,
330
+ text: format_profile_detail(profile),
331
+ });
332
+ }
333
+ else {
334
+ ctx.ui.notify(format_profile_detail(profile));
335
+ }
336
+ break;
337
+ }
338
+ if (action === 'use') {
339
+ let target = name;
340
+ if (!target && ctx.hasUI) {
341
+ target = await pick_profile(ctx, mgr, 'Use skill profile');
342
+ }
343
+ if (!target) {
344
+ ctx.ui.notify('Usage: /skills profile use <name>', 'warning');
345
+ break;
346
+ }
347
+ try {
348
+ mgr.use_profile(target);
349
+ ctx.ui.notify(`Using skill profile ${target}. Reloading...`, 'info');
350
+ await ctx.reload();
351
+ return;
352
+ }
353
+ catch (error) {
354
+ ctx.ui.notify(error instanceof Error
355
+ ? error.message
356
+ : String(error), 'warning');
357
+ }
358
+ break;
359
+ }
360
+ if (action === 'create') {
361
+ let target = name;
362
+ if (!target && ctx.hasUI) {
363
+ target = await show_input_modal(ctx, {
364
+ title: 'Create skill profile',
365
+ label: 'Profile name',
366
+ trim: true,
367
+ });
368
+ }
369
+ if (!target) {
370
+ ctx.ui.notify('Usage: /skills profile create <name>', 'warning');
371
+ break;
372
+ }
373
+ try {
374
+ mgr.create_profile(target, { extends: ['default'] });
375
+ ctx.ui.notify(`Created skill profile ${target}`);
376
+ }
377
+ catch (error) {
378
+ ctx.ui.notify(error instanceof Error
379
+ ? error.message
380
+ : String(error), 'warning');
381
+ }
382
+ break;
383
+ }
384
+ if (action === 'include' || action === 'exclude') {
385
+ if (!name || !pattern) {
386
+ ctx.ui.notify(`Usage: /skills profile ${action} <name> <pattern>`, 'warning');
387
+ break;
388
+ }
389
+ try {
390
+ if (action === 'include')
391
+ mgr.include_in_profile(name, pattern);
392
+ else
393
+ mgr.exclude_from_profile(name, pattern);
394
+ ctx.ui.notify(`Updated skill profile ${name}. Reloading...`, 'info');
395
+ await ctx.reload();
396
+ return;
397
+ }
398
+ catch (error) {
399
+ ctx.ui.notify(error instanceof Error
400
+ ? error.message
401
+ : String(error), 'warning');
402
+ }
403
+ break;
404
+ }
405
+ ctx.ui.notify('Usage: /skills profile <list|show|use|create|include|exclude>', 'warning');
406
+ break;
407
+ }
408
+ case 'refresh': {
409
+ if (ctx.hasUI) {
410
+ await show_refresh_summary(ctx, mgr);
411
+ break;
412
+ }
413
+ mgr.refresh();
414
+ ctx.ui.notify(`Rescanned: ${mgr.discover().length} managed skills, ${mgr.discover_importable().length} importable skills found`);
415
+ break;
416
+ }
417
+ case 'defaults': {
418
+ if (!arg && ctx.hasUI) {
419
+ await show_defaults_modal(ctx, mgr);
420
+ break;
421
+ }
422
+ if (arg !== 'all-enabled' && arg !== 'all-disabled') {
423
+ ctx.ui.notify('Usage: /skills defaults <all-enabled|all-disabled>', 'warning');
424
+ return;
425
+ }
426
+ mgr.set_defaults(arg);
427
+ if (ctx.hasUI) {
428
+ await show_text_modal(ctx, {
429
+ title: 'Skill defaults updated',
430
+ text: `Default policy: ${arg}`,
431
+ });
432
+ }
433
+ else {
434
+ ctx.ui.notify(`Default policy: ${arg}`);
435
+ }
436
+ break;
437
+ }
438
+ default:
439
+ ctx.ui.notify(`Unknown: ${sub}. Use: ${subs.join(', ')}`, 'warning');
440
+ }
441
+ },
442
+ });
443
+ }
444
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,9 +1,19 @@
1
+ export type SkillDefaultPolicy = 'all-enabled' | 'all-disabled';
2
+ export interface SkillProfileConfig {
3
+ description?: string;
4
+ extends?: string | string[];
5
+ include?: string[];
6
+ exclude?: string[];
7
+ }
1
8
  export interface SkillsConfig {
2
9
  version: number;
3
10
  enabled: Record<string, boolean>;
4
- defaults: 'all-enabled' | 'all-disabled';
11
+ defaults: SkillDefaultPolicy;
12
+ current_profile?: string;
13
+ profiles: Record<string, SkillProfileConfig>;
5
14
  }
6
15
  export declare function get_config_path(): string;
16
+ export declare function safe_profile_name(value: string): string | undefined;
7
17
  export declare function load_skills_config(): SkillsConfig;
8
18
  export declare function save_skills_config(config: SkillsConfig): void;
9
19
  export declare function make_skill_key(name: string, source: string): string;
package/dist/config.js CHANGED
@@ -1,30 +1,99 @@
1
1
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { dirname, join } from 'node:path';
4
+ const DEFAULT_PROFILES = {
5
+ default: {
6
+ description: 'General-purpose skills profile.',
7
+ include: [],
8
+ exclude: [],
9
+ },
10
+ };
4
11
  const DEFAULT_CONFIG = {
5
- version: 1,
12
+ version: 2,
6
13
  enabled: {},
7
14
  defaults: 'all-disabled',
15
+ current_profile: 'default',
16
+ profiles: DEFAULT_PROFILES,
8
17
  };
9
18
  export function get_config_path() {
10
19
  const xdg = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
11
20
  return join(xdg, 'my-pi', 'skills.json');
12
21
  }
22
+ function string_array(value) {
23
+ if (!Array.isArray(value))
24
+ return undefined;
25
+ const values = value
26
+ .map((item) => (typeof item === 'string' ? item.trim() : ''))
27
+ .filter(Boolean);
28
+ return values.length ? [...new Set(values)] : undefined;
29
+ }
30
+ function normalize_profile(value) {
31
+ if (!value || typeof value !== 'object')
32
+ return {};
33
+ const parsed = value;
34
+ const description = typeof parsed.description === 'string' &&
35
+ parsed.description.trim()
36
+ ? parsed.description.trim()
37
+ : undefined;
38
+ const extends_value = Array.isArray(parsed.extends)
39
+ ? string_array(parsed.extends)
40
+ : typeof parsed.extends === 'string' && parsed.extends.trim()
41
+ ? parsed.extends.trim()
42
+ : undefined;
43
+ return {
44
+ ...(description ? { description } : {}),
45
+ ...(extends_value ? { extends: extends_value } : {}),
46
+ ...(string_array(parsed.include)
47
+ ? { include: string_array(parsed.include) }
48
+ : {}),
49
+ ...(string_array(parsed.exclude)
50
+ ? { exclude: string_array(parsed.exclude) }
51
+ : {}),
52
+ };
53
+ }
54
+ function normalize_profiles(value) {
55
+ if (!value || typeof value !== 'object') {
56
+ return { ...DEFAULT_PROFILES };
57
+ }
58
+ const profiles = {};
59
+ for (const [name, profile] of Object.entries(value)) {
60
+ if (!safe_profile_name(name))
61
+ continue;
62
+ profiles[name] = normalize_profile(profile);
63
+ }
64
+ return Object.keys(profiles).length
65
+ ? profiles
66
+ : { ...DEFAULT_PROFILES };
67
+ }
68
+ export function safe_profile_name(value) {
69
+ const trimmed = value.trim();
70
+ if (!trimmed || trimmed === '.' || trimmed === '..')
71
+ return undefined;
72
+ if (!/^[a-zA-Z0-9_.-]+$/.test(trimmed))
73
+ return undefined;
74
+ return trimmed;
75
+ }
13
76
  export function load_skills_config() {
14
77
  const path = get_config_path();
15
78
  if (!existsSync(path))
16
- return { ...DEFAULT_CONFIG };
79
+ return structuredClone(DEFAULT_CONFIG);
17
80
  try {
18
81
  const raw = readFileSync(path, 'utf-8');
19
82
  const parsed = JSON.parse(raw);
83
+ const profiles = normalize_profiles(parsed.profiles);
84
+ const current_profile = safe_profile_name(parsed.current_profile ?? 'default');
20
85
  return {
21
- version: parsed.version ?? 1,
86
+ version: parsed.version ?? 2,
22
87
  enabled: parsed.enabled ?? {},
23
88
  defaults: parsed.defaults ?? 'all-enabled',
89
+ ...(current_profile
90
+ ? { current_profile: current_profile }
91
+ : {}),
92
+ profiles,
24
93
  };
25
94
  }
26
95
  catch {
27
- return { ...DEFAULT_CONFIG };
96
+ return structuredClone(DEFAULT_CONFIG);
28
97
  }
29
98
  }
30
99
  export function save_skills_config(config) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EACV,SAAS,EACT,YAAY,EACZ,UAAU,EACV,aAAa,GACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAQ1C,MAAM,cAAc,GAAiB;IACpC,OAAO,EAAE,CAAC;IACV,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,cAAc;CACxB,CAAC;AAEF,MAAM,UAAU,eAAe;IAC9B,MAAM,GAAG,GACR,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC3D,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB;IACjC,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAEpD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACxC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,OAAO;YACN,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;YAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,aAAa;SAC1C,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC9B,CAAC;AACF,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAoB;IACtD,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACxC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;QAC7D,IAAI,EAAE,KAAK;KACX,CAAC,CAAC;IACH,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,MAAc;IAC1D,OAAO,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC/B,MAAoB,EACpB,GAAW;IAEX,IAAI,GAAG,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC,QAAQ,KAAK,aAAa,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/importer.js CHANGED
@@ -1,11 +1,11 @@
1
+ import { getAgentDir } from '@mariozechner/pi-coding-agent';
1
2
  import { createHash } from 'node:crypto';
2
3
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from 'node:fs';
3
- import { homedir } from 'node:os';
4
4
  import { dirname, isAbsolute, join, relative, resolve, } from 'node:path';
5
5
  import { IMPORT_METADATA_FILE, } from './scanner.js';
6
6
  const IMPORT_METADATA_VERSION = 1;
7
7
  function get_managed_skills_dir() {
8
- return join(homedir(), '.pi', 'agent', 'skills');
8
+ return join(getAgentDir(), 'skills');
9
9
  }
10
10
  function ensure_dir(path) {
11
11
  mkdirSync(path, { recursive: true, mode: 0o700 });