my-pi 0.0.2 → 0.0.4
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 +24 -5
- package/dist/api-B6KnhtN9.js +1893 -0
- package/dist/api-B6KnhtN9.js.map +1 -0
- package/dist/api.js +1 -49
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/src/extensions/config.test.ts +88 -0
- package/src/extensions/config.ts +189 -0
- package/src/extensions/extensions.ts +366 -0
- package/src/extensions/recall.ts +29 -226
- package/src/extensions/skills.ts +496 -75
- package/src/skills/importer.test.ts +301 -0
- package/src/skills/importer.ts +221 -0
- package/src/skills/manager.ts +129 -30
- package/src/skills/scanner.ts +172 -72
- package/dist/api.js.map +0 -1
package/src/skills/manager.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type DiscoveredSkill, scan_all_skills } from './scanner.js';
|
|
2
1
|
import {
|
|
3
2
|
type SkillsConfig,
|
|
4
3
|
is_skill_enabled,
|
|
@@ -6,6 +5,17 @@ import {
|
|
|
6
5
|
make_skill_key,
|
|
7
6
|
save_skills_config,
|
|
8
7
|
} from './config.js';
|
|
8
|
+
import {
|
|
9
|
+
type ImportSkillResult,
|
|
10
|
+
type SyncSkillResult,
|
|
11
|
+
import_external_skill,
|
|
12
|
+
sync_imported_skill,
|
|
13
|
+
} from './importer.js';
|
|
14
|
+
import {
|
|
15
|
+
type DiscoveredSkill,
|
|
16
|
+
scan_importable_skills,
|
|
17
|
+
scan_managed_skills,
|
|
18
|
+
} from './scanner.js';
|
|
9
19
|
|
|
10
20
|
export interface ManagedSkill extends DiscoveredSkill {
|
|
11
21
|
key: string;
|
|
@@ -14,71 +24,120 @@ export interface ManagedSkill extends DiscoveredSkill {
|
|
|
14
24
|
|
|
15
25
|
export interface SkillsManager {
|
|
16
26
|
discover(): ManagedSkill[];
|
|
27
|
+
discover_importable(): ManagedSkill[];
|
|
17
28
|
get_enabled_skill_paths(): string[];
|
|
18
|
-
/** Check if a skill should pass through
|
|
29
|
+
/** Check if a skill should pass through pi's skillsOverride */
|
|
19
30
|
is_enabled_by_skill(name: string, filePath: string): boolean;
|
|
20
31
|
enable(key: string): boolean;
|
|
21
32
|
disable(key: string): boolean;
|
|
22
33
|
toggle(key: string): boolean;
|
|
23
34
|
search(query: string): ManagedSkill[];
|
|
35
|
+
search_importable(query: string): ManagedSkill[];
|
|
24
36
|
set_defaults(policy: 'all-enabled' | 'all-disabled'): void;
|
|
37
|
+
import_skill(
|
|
38
|
+
key_or_name: string,
|
|
39
|
+
): ImportSkillResult & { key: string };
|
|
40
|
+
sync_skill(key_or_name: string): SyncSkillResult & { key: string };
|
|
25
41
|
refresh(): void;
|
|
26
42
|
}
|
|
27
43
|
|
|
44
|
+
function resolve_skill_key(skill: DiscoveredSkill): string {
|
|
45
|
+
return make_skill_key(skill.name, skill.source);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function match_skill_by_key_or_name(
|
|
49
|
+
skills: DiscoveredSkill[],
|
|
50
|
+
key_or_name: string,
|
|
51
|
+
): DiscoveredSkill {
|
|
52
|
+
const exact_key = skills.find(
|
|
53
|
+
(skill) => resolve_skill_key(skill) === key_or_name,
|
|
54
|
+
);
|
|
55
|
+
if (exact_key) return exact_key;
|
|
56
|
+
|
|
57
|
+
const by_name = skills.filter(
|
|
58
|
+
(skill) => skill.name === key_or_name,
|
|
59
|
+
);
|
|
60
|
+
if (by_name.length === 1) {
|
|
61
|
+
return by_name[0]!;
|
|
62
|
+
}
|
|
63
|
+
if (by_name.length > 1) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Multiple skills named ${key_or_name}. Use an exact key instead.`,
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
throw new Error(`Unknown skill: ${key_or_name}`);
|
|
70
|
+
}
|
|
71
|
+
|
|
28
72
|
export function create_skills_manager(): SkillsManager {
|
|
29
73
|
let config: SkillsConfig = load_skills_config();
|
|
30
|
-
let
|
|
74
|
+
let managed_cache: DiscoveredSkill[] | null = null;
|
|
75
|
+
let importable_cache: DiscoveredSkill[] | null = null;
|
|
31
76
|
|
|
32
|
-
function
|
|
33
|
-
if (!
|
|
34
|
-
|
|
77
|
+
function get_managed(): DiscoveredSkill[] {
|
|
78
|
+
if (!managed_cache) {
|
|
79
|
+
managed_cache = scan_managed_skills();
|
|
35
80
|
}
|
|
36
|
-
return
|
|
81
|
+
return managed_cache;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function get_importable(): DiscoveredSkill[] {
|
|
85
|
+
if (!importable_cache) {
|
|
86
|
+
importable_cache = scan_importable_skills();
|
|
87
|
+
}
|
|
88
|
+
return importable_cache;
|
|
37
89
|
}
|
|
38
90
|
|
|
39
91
|
function to_managed(skill: DiscoveredSkill): ManagedSkill {
|
|
40
|
-
const key =
|
|
92
|
+
const key = resolve_skill_key(skill);
|
|
41
93
|
return {
|
|
42
94
|
...skill,
|
|
43
95
|
key,
|
|
44
|
-
enabled:
|
|
96
|
+
enabled:
|
|
97
|
+
skill.kind === 'managed'
|
|
98
|
+
? is_skill_enabled(config, key)
|
|
99
|
+
: false,
|
|
45
100
|
};
|
|
46
101
|
}
|
|
47
102
|
|
|
103
|
+
function get_enabled_managed_skills(): ManagedSkill[] {
|
|
104
|
+
return get_managed()
|
|
105
|
+
.filter((skill) =>
|
|
106
|
+
is_skill_enabled(config, resolve_skill_key(skill)),
|
|
107
|
+
)
|
|
108
|
+
.map(to_managed);
|
|
109
|
+
}
|
|
110
|
+
|
|
48
111
|
return {
|
|
49
112
|
discover(): ManagedSkill[] {
|
|
50
|
-
return
|
|
113
|
+
return get_managed().map(to_managed);
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
discover_importable(): ManagedSkill[] {
|
|
117
|
+
return get_importable().map(to_managed);
|
|
51
118
|
},
|
|
52
119
|
|
|
53
120
|
is_enabled_by_skill(name: string, filePath: string): boolean {
|
|
54
|
-
|
|
55
|
-
const discovered = get_discovered();
|
|
121
|
+
const discovered = get_managed();
|
|
56
122
|
const match = discovered.find((s) => s.skillPath === filePath);
|
|
57
123
|
if (match) {
|
|
58
|
-
return is_skill_enabled(
|
|
59
|
-
config,
|
|
60
|
-
make_skill_key(match.name, match.source),
|
|
61
|
-
);
|
|
124
|
+
return is_skill_enabled(config, resolve_skill_key(match));
|
|
62
125
|
}
|
|
63
|
-
|
|
64
|
-
// Fall back to checking by name with a generic source
|
|
126
|
+
|
|
65
127
|
const by_name = discovered.find((s) => s.name === name);
|
|
66
128
|
if (by_name) {
|
|
67
|
-
return is_skill_enabled(
|
|
68
|
-
config,
|
|
69
|
-
make_skill_key(by_name.name, by_name.source),
|
|
70
|
-
);
|
|
129
|
+
return is_skill_enabled(config, resolve_skill_key(by_name));
|
|
71
130
|
}
|
|
72
|
-
|
|
73
|
-
|
|
131
|
+
|
|
132
|
+
// Unknown skill sources should remain enabled so pi's native
|
|
133
|
+
// discovery keeps working for project and other default locations.
|
|
134
|
+
return true;
|
|
74
135
|
},
|
|
75
136
|
|
|
76
137
|
get_enabled_skill_paths(): string[] {
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
)
|
|
81
|
-
.map((s) => s.baseDir);
|
|
138
|
+
return get_enabled_managed_skills().map(
|
|
139
|
+
(skill) => skill.baseDir,
|
|
140
|
+
);
|
|
82
141
|
},
|
|
83
142
|
|
|
84
143
|
enable(key: string): boolean {
|
|
@@ -110,13 +169,53 @@ export function create_skills_manager(): SkillsManager {
|
|
|
110
169
|
);
|
|
111
170
|
},
|
|
112
171
|
|
|
172
|
+
search_importable(query: string): ManagedSkill[] {
|
|
173
|
+
const q = query.toLowerCase();
|
|
174
|
+
return this.discover_importable().filter(
|
|
175
|
+
(s) =>
|
|
176
|
+
s.name.toLowerCase().includes(q) ||
|
|
177
|
+
s.description.toLowerCase().includes(q) ||
|
|
178
|
+
s.source.toLowerCase().includes(q),
|
|
179
|
+
);
|
|
180
|
+
},
|
|
181
|
+
|
|
113
182
|
set_defaults(policy: 'all-enabled' | 'all-disabled'): void {
|
|
114
183
|
config.defaults = policy;
|
|
115
184
|
save_skills_config(config);
|
|
116
185
|
},
|
|
117
186
|
|
|
187
|
+
import_skill(key_or_name: string) {
|
|
188
|
+
const skill = match_skill_by_key_or_name(
|
|
189
|
+
get_importable(),
|
|
190
|
+
key_or_name,
|
|
191
|
+
);
|
|
192
|
+
const result = import_external_skill(skill);
|
|
193
|
+
const managed_key = make_skill_key(skill.name, 'pi-native');
|
|
194
|
+
config.enabled[managed_key] = true;
|
|
195
|
+
save_skills_config(config);
|
|
196
|
+
this.refresh();
|
|
197
|
+
return {
|
|
198
|
+
...result,
|
|
199
|
+
key: managed_key,
|
|
200
|
+
};
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
sync_skill(key_or_name: string) {
|
|
204
|
+
const skill = match_skill_by_key_or_name(
|
|
205
|
+
get_managed(),
|
|
206
|
+
key_or_name,
|
|
207
|
+
);
|
|
208
|
+
const result = sync_imported_skill(skill);
|
|
209
|
+
this.refresh();
|
|
210
|
+
return {
|
|
211
|
+
...result,
|
|
212
|
+
key: resolve_skill_key(skill),
|
|
213
|
+
};
|
|
214
|
+
},
|
|
215
|
+
|
|
118
216
|
refresh(): void {
|
|
119
|
-
|
|
217
|
+
managed_cache = null;
|
|
218
|
+
importable_cache = null;
|
|
120
219
|
config = load_skills_config();
|
|
121
220
|
},
|
|
122
221
|
};
|
package/src/skills/scanner.ts
CHANGED
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import { existsSync, globSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { basename, dirname, join, resolve } from 'node:path';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
1
|
import {
|
|
5
2
|
parseFrontmatter,
|
|
6
3
|
type SkillFrontmatter,
|
|
7
4
|
} from '@mariozechner/pi-coding-agent';
|
|
5
|
+
import { existsSync, globSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { homedir } from 'node:os';
|
|
7
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
name: string;
|
|
11
|
-
description: string;
|
|
12
|
-
skillPath: string;
|
|
13
|
-
baseDir: string;
|
|
14
|
-
source: string;
|
|
15
|
-
}
|
|
9
|
+
export const IMPORT_METADATA_FILE = '.my-pi-source.json';
|
|
16
10
|
|
|
17
|
-
interface InstalledPlugin {
|
|
11
|
+
export interface InstalledPlugin {
|
|
18
12
|
scope: string;
|
|
19
13
|
installPath: string;
|
|
20
14
|
version: string;
|
|
15
|
+
installedAt?: string;
|
|
16
|
+
lastUpdated?: string;
|
|
17
|
+
gitCommitSha?: string;
|
|
21
18
|
}
|
|
22
19
|
|
|
23
20
|
interface InstalledPluginsFile {
|
|
@@ -25,6 +22,38 @@ interface InstalledPluginsFile {
|
|
|
25
22
|
plugins: Record<string, InstalledPlugin[]>;
|
|
26
23
|
}
|
|
27
24
|
|
|
25
|
+
export interface ImportedSkillMetadata {
|
|
26
|
+
version: number;
|
|
27
|
+
source: string;
|
|
28
|
+
upstream_skill_path: string;
|
|
29
|
+
upstream_base_dir: string;
|
|
30
|
+
upstream_install_path?: string;
|
|
31
|
+
upstream_version?: string;
|
|
32
|
+
upstream_git_commit_sha?: string;
|
|
33
|
+
imported_at: string;
|
|
34
|
+
last_synced_at: string;
|
|
35
|
+
imported_hash: string;
|
|
36
|
+
upstream_hash: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PluginSkillSource {
|
|
40
|
+
pluginId: string;
|
|
41
|
+
installPath: string;
|
|
42
|
+
version: string;
|
|
43
|
+
gitCommitSha?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface DiscoveredSkill {
|
|
47
|
+
name: string;
|
|
48
|
+
description: string;
|
|
49
|
+
skillPath: string;
|
|
50
|
+
baseDir: string;
|
|
51
|
+
source: string;
|
|
52
|
+
kind: 'managed' | 'external';
|
|
53
|
+
plugin?: PluginSkillSource;
|
|
54
|
+
import_meta?: ImportedSkillMetadata;
|
|
55
|
+
}
|
|
56
|
+
|
|
28
57
|
function read_installed_plugins(): InstalledPluginsFile | null {
|
|
29
58
|
const path = join(
|
|
30
59
|
homedir(),
|
|
@@ -60,41 +89,74 @@ function parse_skill_md(
|
|
|
60
89
|
}
|
|
61
90
|
}
|
|
62
91
|
|
|
92
|
+
function read_import_metadata(
|
|
93
|
+
base_dir: string,
|
|
94
|
+
): ImportedSkillMetadata | undefined {
|
|
95
|
+
const metadata_path = join(base_dir, IMPORT_METADATA_FILE);
|
|
96
|
+
if (!existsSync(metadata_path)) return undefined;
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
return JSON.parse(
|
|
100
|
+
readFileSync(metadata_path, 'utf-8'),
|
|
101
|
+
) as ImportedSkillMetadata;
|
|
102
|
+
} catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
63
107
|
function scan_dir_for_skills(
|
|
64
108
|
dir: string,
|
|
65
|
-
|
|
109
|
+
options: {
|
|
110
|
+
source: string;
|
|
111
|
+
kind: 'managed' | 'external';
|
|
112
|
+
plugin?: PluginSkillSource;
|
|
113
|
+
include_direct_root_skill?: boolean;
|
|
114
|
+
},
|
|
66
115
|
): DiscoveredSkill[] {
|
|
67
116
|
if (!existsSync(dir)) return [];
|
|
68
117
|
|
|
69
118
|
const results: DiscoveredSkill[] = [];
|
|
70
|
-
|
|
71
|
-
// Direct SKILL.md in this dir
|
|
72
119
|
const direct = join(dir, 'SKILL.md');
|
|
73
|
-
|
|
120
|
+
const include_direct_root_skill =
|
|
121
|
+
options.include_direct_root_skill ?? true;
|
|
122
|
+
|
|
123
|
+
if (include_direct_root_skill && existsSync(direct)) {
|
|
74
124
|
const parsed = parse_skill_md(direct);
|
|
75
125
|
if (parsed) {
|
|
76
126
|
results.push({
|
|
77
127
|
...parsed,
|
|
78
128
|
skillPath: direct,
|
|
79
129
|
baseDir: dir,
|
|
80
|
-
source,
|
|
130
|
+
source: options.source,
|
|
131
|
+
kind: options.kind,
|
|
132
|
+
plugin: options.plugin,
|
|
133
|
+
import_meta:
|
|
134
|
+
options.kind === 'managed'
|
|
135
|
+
? read_import_metadata(dir)
|
|
136
|
+
: undefined,
|
|
81
137
|
});
|
|
82
138
|
}
|
|
83
|
-
return results;
|
|
139
|
+
return results;
|
|
84
140
|
}
|
|
85
141
|
|
|
86
|
-
// Glob for skills in subdirs
|
|
87
142
|
try {
|
|
88
143
|
const matches = globSync('*/SKILL.md', { cwd: dir });
|
|
89
144
|
for (const match of matches) {
|
|
90
145
|
const full_path = resolve(dir, match);
|
|
91
146
|
const parsed = parse_skill_md(full_path);
|
|
92
147
|
if (parsed) {
|
|
148
|
+
const base_dir = dirname(full_path);
|
|
93
149
|
results.push({
|
|
94
150
|
...parsed,
|
|
95
151
|
skillPath: full_path,
|
|
96
|
-
baseDir:
|
|
97
|
-
source,
|
|
152
|
+
baseDir: base_dir,
|
|
153
|
+
source: options.source,
|
|
154
|
+
kind: options.kind,
|
|
155
|
+
plugin: options.plugin,
|
|
156
|
+
import_meta:
|
|
157
|
+
options.kind === 'managed'
|
|
158
|
+
? read_import_metadata(base_dir)
|
|
159
|
+
: undefined,
|
|
98
160
|
});
|
|
99
161
|
}
|
|
100
162
|
}
|
|
@@ -105,71 +167,109 @@ function scan_dir_for_skills(
|
|
|
105
167
|
return results;
|
|
106
168
|
}
|
|
107
169
|
|
|
108
|
-
|
|
109
|
-
|
|
170
|
+
function dedupe_by_skill_path(
|
|
171
|
+
skills: DiscoveredSkill[],
|
|
172
|
+
): DiscoveredSkill[] {
|
|
110
173
|
const seen = new Set<string>();
|
|
174
|
+
const deduped: DiscoveredSkill[] = [];
|
|
111
175
|
|
|
112
|
-
const
|
|
113
|
-
if (seen.has(skill.skillPath))
|
|
176
|
+
for (const skill of skills) {
|
|
177
|
+
if (seen.has(skill.skillPath)) continue;
|
|
114
178
|
seen.add(skill.skillPath);
|
|
115
|
-
|
|
116
|
-
}
|
|
179
|
+
deduped.push(skill);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return deduped;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function scan_managed_skills(): DiscoveredSkill[] {
|
|
186
|
+
const skills: DiscoveredSkill[] = [];
|
|
187
|
+
|
|
188
|
+
for (const skill of scan_dir_for_skills(
|
|
189
|
+
join(homedir(), '.claude', 'skills'),
|
|
190
|
+
{
|
|
191
|
+
source: 'user-local',
|
|
192
|
+
kind: 'managed',
|
|
193
|
+
},
|
|
194
|
+
)) {
|
|
195
|
+
skills.push(skill);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
for (const skill of scan_dir_for_skills(
|
|
199
|
+
join(homedir(), '.pi', 'agent', 'skills'),
|
|
200
|
+
{
|
|
201
|
+
source: 'pi-native',
|
|
202
|
+
kind: 'managed',
|
|
203
|
+
include_direct_root_skill: false,
|
|
204
|
+
},
|
|
205
|
+
)) {
|
|
206
|
+
skills.push(skill);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return dedupe_by_skill_path(skills);
|
|
210
|
+
}
|
|
117
211
|
|
|
118
|
-
|
|
212
|
+
export function scan_importable_skills(): DiscoveredSkill[] {
|
|
213
|
+
const skills: DiscoveredSkill[] = [];
|
|
119
214
|
const plugins = read_installed_plugins();
|
|
120
|
-
if (plugins?.plugins)
|
|
121
|
-
for (const [key, entries] of Object.entries(plugins.plugins)) {
|
|
122
|
-
const entry = entries[0]; // first scope entry
|
|
123
|
-
if (!entry?.installPath || !existsSync(entry.installPath))
|
|
124
|
-
continue;
|
|
215
|
+
if (!plugins?.plugins) return skills;
|
|
125
216
|
|
|
126
|
-
|
|
217
|
+
for (const [plugin_id, entries] of Object.entries(
|
|
218
|
+
plugins.plugins,
|
|
219
|
+
)) {
|
|
220
|
+
const entry = entries[0];
|
|
221
|
+
if (!entry?.installPath || !existsSync(entry.installPath))
|
|
222
|
+
continue;
|
|
127
223
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
224
|
+
const source = `plugin:${plugin_id}`;
|
|
225
|
+
const plugin: PluginSkillSource = {
|
|
226
|
+
pluginId: plugin_id,
|
|
227
|
+
installPath: entry.installPath,
|
|
228
|
+
version: entry.version,
|
|
229
|
+
gitCommitSha: entry.gitCommitSha,
|
|
230
|
+
};
|
|
135
231
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
baseDir: direct,
|
|
147
|
-
source,
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
232
|
+
for (const skill of scan_dir_for_skills(
|
|
233
|
+
join(entry.installPath, 'skills'),
|
|
234
|
+
{
|
|
235
|
+
source,
|
|
236
|
+
kind: 'external',
|
|
237
|
+
plugin,
|
|
238
|
+
},
|
|
239
|
+
)) {
|
|
240
|
+
skills.push(skill);
|
|
241
|
+
}
|
|
151
242
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
243
|
+
for (const skill of scan_dir_for_skills(
|
|
244
|
+
join(entry.installPath, '.pi', 'skills'),
|
|
245
|
+
{
|
|
155
246
|
source,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
247
|
+
kind: 'external',
|
|
248
|
+
plugin,
|
|
249
|
+
},
|
|
250
|
+
)) {
|
|
251
|
+
skills.push(skill);
|
|
159
252
|
}
|
|
160
|
-
}
|
|
161
253
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
254
|
+
const direct_root_skill = join(entry.installPath, 'SKILL.md');
|
|
255
|
+
if (existsSync(direct_root_skill)) {
|
|
256
|
+
const parsed = parse_skill_md(direct_root_skill);
|
|
257
|
+
if (parsed) {
|
|
258
|
+
skills.push({
|
|
259
|
+
...parsed,
|
|
260
|
+
skillPath: direct_root_skill,
|
|
261
|
+
baseDir: entry.installPath,
|
|
262
|
+
source,
|
|
263
|
+
kind: 'external',
|
|
264
|
+
plugin,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
166
268
|
}
|
|
167
269
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
for (const s of scan_dir_for_skills(pi_skills, 'pi-native')) {
|
|
171
|
-
add(s);
|
|
172
|
-
}
|
|
270
|
+
return dedupe_by_skill_path(skills);
|
|
271
|
+
}
|
|
173
272
|
|
|
174
|
-
|
|
273
|
+
export function scan_all_skills(): DiscoveredSkill[] {
|
|
274
|
+
return [...scan_managed_skills(), ...scan_importable_skills()];
|
|
175
275
|
}
|
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","names":[],"sources":["../src/api.ts"],"sourcesContent":["// Composable programmatic API for my-pi\n// Extension loading patterns inspired by https://github.com/disler/pi-vs-claude-code\n\nimport {\n\ttype AgentSessionRuntime,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionRuntime,\n\ttype CreateAgentSessionRuntimeFactory,\n\tcreateAgentSessionServices,\n\ttype ExtensionFactory,\n\tgetAgentDir,\n\tSessionManager,\n\tSettingsManager,\n} from '@mariozechner/pi-coding-agent';\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst ext_dir = resolve(__dirname, '..', 'src', 'extensions');\n\nexport interface CreateMyPiOptions {\n\tcwd?: string;\n\textensions?: string[];\n\textensionFactories?: ExtensionFactory[];\n\t/** Enable MCP extension (default true) */\n\tmcp?: boolean;\n\t/** Enable skills extension (default true) */\n\tskills?: boolean;\n\t/** Enable chain extension (default true) */\n\tchain?: boolean;\n\t/** Enable filter-output extension for secret redaction (default true) */\n\tfilter_output?: boolean;\n\t/** Enable handoff extension (default true) */\n\thandoff?: boolean;\n\t/** Enable recall extension for searching past sessions (default true) */\n\trecall?: boolean;\n\t/** Override the default model (e.g. \"claude-sonnet-4-5-20241022\") */\n\tmodel?: string;\n}\n\nexport async function create_my_pi(\n\toptions: CreateMyPiOptions = {},\n): Promise<AgentSessionRuntime> {\n\tconst {\n\t\tcwd = process.cwd(),\n\t\textensions = [],\n\t\textensionFactories: user_factories = [],\n\t\tmcp = true,\n\t\tskills = true,\n\t\tchain = true,\n\t\tfilter_output = true,\n\t\thandoff = true,\n\t\trecall = true,\n\t\tmodel,\n\t} = options;\n\n\tconst resolved_extensions = extensions.map((p) => resolve(cwd, p));\n\n\t// All built-in extensions loaded by path so Pi shows filenames\n\tconst builtin_extension_paths: string[] = [\n\t\t...(mcp ? [resolve(ext_dir, 'mcp.ts')] : []),\n\t\t...(skills ? [resolve(ext_dir, 'skills.ts')] : []),\n\t\t...(chain ? [resolve(ext_dir, 'chain.ts')] : []),\n\t\t...(filter_output ? [resolve(ext_dir, 'filter-output.ts')] : []),\n\t\t...(handoff ? [resolve(ext_dir, 'handoff.ts')] : []),\n\t\t...(recall ? [resolve(ext_dir, 'recall.ts')] : []),\n\t];\n\n\tconst create_runtime: CreateAgentSessionRuntimeFactory = async ({\n\t\tcwd: runtime_cwd,\n\t\tsessionManager,\n\t\tsessionStartEvent,\n\t}) => {\n\t\tconst settings_manager = model\n\t\t\t? (() => {\n\t\t\t\t\tconst sm = SettingsManager.create(runtime_cwd);\n\t\t\t\t\tsm.setDefaultModel(model);\n\t\t\t\t\treturn sm;\n\t\t\t\t})()\n\t\t\t: undefined;\n\n\t\tconst services = await createAgentSessionServices({\n\t\t\tcwd: runtime_cwd,\n\t\t\t...(settings_manager && { settingsManager: settings_manager }),\n\t\t\tresourceLoaderOptions: {\n\t\t\t\tadditionalExtensionPaths: [\n\t\t\t\t\t...builtin_extension_paths,\n\t\t\t\t\t...resolved_extensions,\n\t\t\t\t],\n\t\t\t\textensionFactories: [...user_factories],\n\t\t\t},\n\t\t});\n\n\t\treturn {\n\t\t\t...(await createAgentSessionFromServices({\n\t\t\t\tservices,\n\t\t\t\tsessionManager,\n\t\t\t\tsessionStartEvent,\n\t\t\t})),\n\t\t\tservices,\n\t\t\tdiagnostics: services.diagnostics,\n\t\t};\n\t};\n\n\treturn createAgentSessionRuntime(create_runtime, {\n\t\tcwd,\n\t\tagentDir: getAgentDir(),\n\t\tsessionManager: SessionManager.create(cwd),\n\t});\n}\n\nexport {\n\tInteractiveMode,\n\trunPrintMode,\n} from '@mariozechner/pi-coding-agent';\n\nexport type {\n\tAgentSessionRuntime,\n\tExtensionFactory,\n\tInteractiveModeOptions,\n\tPrintModeOptions,\n} from '@mariozechner/pi-coding-agent';\n"],"mappings":";;;;AAkBA,MAAM,UAAU,QADE,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACtB,MAAM,OAAO,aAAa;AAsB7D,eAAsB,aACrB,UAA6B,EAAE,EACA;CAC/B,MAAM,EACL,MAAM,QAAQ,KAAK,EACnB,aAAa,EAAE,EACf,oBAAoB,iBAAiB,EAAE,EACvC,MAAM,MACN,SAAS,MACT,QAAQ,MACR,gBAAgB,MAChB,UAAU,MACV,SAAS,MACT,UACG;CAEJ,MAAM,sBAAsB,WAAW,KAAK,MAAM,QAAQ,KAAK,EAAE,CAAC;CAGlE,MAAM,0BAAoC;EACzC,GAAI,MAAM,CAAC,QAAQ,SAAS,SAAS,CAAC,GAAG,EAAE;EAC3C,GAAI,SAAS,CAAC,QAAQ,SAAS,YAAY,CAAC,GAAG,EAAE;EACjD,GAAI,QAAQ,CAAC,QAAQ,SAAS,WAAW,CAAC,GAAG,EAAE;EAC/C,GAAI,gBAAgB,CAAC,QAAQ,SAAS,mBAAmB,CAAC,GAAG,EAAE;EAC/D,GAAI,UAAU,CAAC,QAAQ,SAAS,aAAa,CAAC,GAAG,EAAE;EACnD,GAAI,SAAS,CAAC,QAAQ,SAAS,YAAY,CAAC,GAAG,EAAE;EACjD;CAED,MAAM,iBAAmD,OAAO,EAC/D,KAAK,aACL,gBACA,wBACK;EACL,MAAM,mBAAmB,eACf;GACP,MAAM,KAAK,gBAAgB,OAAO,YAAY;AAC9C,MAAG,gBAAgB,MAAM;AACzB,UAAO;MACJ,GACH,KAAA;EAEH,MAAM,WAAW,MAAM,2BAA2B;GACjD,KAAK;GACL,GAAI,oBAAoB,EAAE,iBAAiB,kBAAkB;GAC7D,uBAAuB;IACtB,0BAA0B,CACzB,GAAG,yBACH,GAAG,oBACH;IACD,oBAAoB,CAAC,GAAG,eAAe;IACvC;GACD,CAAC;AAEF,SAAO;GACN,GAAI,MAAM,+BAA+B;IACxC;IACA;IACA;IACA,CAAC;GACF;GACA,aAAa,SAAS;GACtB;;AAGF,QAAO,0BAA0B,gBAAgB;EAChD;EACA,UAAU,aAAa;EACvB,gBAAgB,eAAe,OAAO,IAAI;EAC1C,CAAC"}
|