@howaboua/pi-codex-conversion 1.5.0 → 1.5.1-dev.12.fbcf75f
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
package/src/index.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join, resolve } from "node:path";
|
|
2
5
|
import { getCodexRuntimeShell } from "./adapter/runtime-shell.ts";
|
|
3
6
|
import {
|
|
4
7
|
CORE_ADAPTER_TOOL_NAMES,
|
|
@@ -20,7 +23,7 @@ import {
|
|
|
20
23
|
registerOpenAICodexCustomProvider,
|
|
21
24
|
} from "./providers/openai-codex-custom-provider.ts";
|
|
22
25
|
import { registerImageGenerationTool, rewriteNativeImageGenerationTool, supportsNativeImageGeneration } from "./tools/image-generation-tool.ts";
|
|
23
|
-
import { buildCodexSystemPrompt, extractPiPromptSkills, type PromptSkill } from "./prompt/build-system-prompt.ts";
|
|
26
|
+
import { buildCodexSystemPrompt, extractPiPromptSkills, resolvePromptSkills, type PromptSkill } from "./prompt/build-system-prompt.ts";
|
|
24
27
|
import { registerViewImageTool, supportsOriginalImageDetail } from "./tools/view-image-tool.ts";
|
|
25
28
|
import {
|
|
26
29
|
registerWebSearchTool,
|
|
@@ -83,6 +86,11 @@ export default function codexConversion(pi: ExtensionAPI) {
|
|
|
83
86
|
syncAdapter(pi, ctx, state);
|
|
84
87
|
});
|
|
85
88
|
|
|
89
|
+
pi.on("resources_discover", async (event) => {
|
|
90
|
+
const skillPaths = getCodexSkillPaths(event.cwd);
|
|
91
|
+
return skillPaths.length > 0 ? { skillPaths } : undefined;
|
|
92
|
+
});
|
|
93
|
+
|
|
86
94
|
pi.on("model_select", async (_event, ctx) => {
|
|
87
95
|
state.cwd = ctx.cwd;
|
|
88
96
|
syncAdapter(pi, ctx, state);
|
|
@@ -118,9 +126,10 @@ export default function codexConversion(pi: ExtensionAPI) {
|
|
|
118
126
|
if (!isCodexLikeContext(ctx)) {
|
|
119
127
|
return undefined;
|
|
120
128
|
}
|
|
129
|
+
const skills = resolvePromptSkills(event.systemPromptOptions?.skills, state.promptSkills);
|
|
121
130
|
return {
|
|
122
131
|
systemPrompt: buildCodexSystemPrompt(event.systemPrompt, {
|
|
123
|
-
skills
|
|
132
|
+
skills,
|
|
124
133
|
shell: getCodexRuntimeShell(process.env.SHELL),
|
|
125
134
|
}),
|
|
126
135
|
};
|
|
@@ -149,6 +158,20 @@ export default function codexConversion(pi: ExtensionAPI) {
|
|
|
149
158
|
});
|
|
150
159
|
}
|
|
151
160
|
|
|
161
|
+
export function getCodexSkillPaths(cwd: string, home: string = homedir()): string[] {
|
|
162
|
+
const skillPaths = [join(home, ".agents", "skills")];
|
|
163
|
+
let currentDir = resolve(cwd);
|
|
164
|
+
while (true) {
|
|
165
|
+
skillPaths.push(join(currentDir, ".agents", "skills"));
|
|
166
|
+
const parentDir = resolve(currentDir, "..");
|
|
167
|
+
if (parentDir === currentDir) {
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
currentDir = parentDir;
|
|
171
|
+
}
|
|
172
|
+
return skillPaths.filter((path) => existsSync(path));
|
|
173
|
+
}
|
|
174
|
+
|
|
152
175
|
function syncAdapter(pi: ExtensionAPI, ctx: ExtensionContext, state: AdapterState): void {
|
|
153
176
|
state.promptSkills = extractPiPromptSkills(ctx.getSystemPrompt());
|
|
154
177
|
|
|
@@ -4,6 +4,13 @@ export interface PromptSkill {
|
|
|
4
4
|
filePath: string;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
export interface StructuredPromptSkill {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
filePath: string;
|
|
11
|
+
disableModelInvocation?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
const CODEX_GUIDELINES = [
|
|
8
15
|
"Use `exec_command` for shell commands, file inspection, builds, and tests; prefer `rg` / `rg --files` for discovery and focused commands over truncation.",
|
|
9
16
|
"Use `apply_patch` for text-file changes, including creates/deletes/moves; group related multi-file edits into one patch.",
|
|
@@ -56,6 +63,27 @@ export function extractPiPromptSkills(prompt: string): PromptSkill[] {
|
|
|
56
63
|
}));
|
|
57
64
|
}
|
|
58
65
|
|
|
66
|
+
export function promptSkillsFromStructuredSkills(skills: readonly StructuredPromptSkill[] | undefined): PromptSkill[] {
|
|
67
|
+
if (!Array.isArray(skills)) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return skills
|
|
72
|
+
.filter((skill) => !skill.disableModelInvocation)
|
|
73
|
+
.map((skill) => ({
|
|
74
|
+
name: skill.name,
|
|
75
|
+
description: skill.description,
|
|
76
|
+
filePath: skill.filePath,
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function resolvePromptSkills(
|
|
81
|
+
structuredSkills: readonly StructuredPromptSkill[] | undefined,
|
|
82
|
+
fallbackSkills: readonly PromptSkill[],
|
|
83
|
+
): PromptSkill[] {
|
|
84
|
+
return structuredSkills === undefined ? [...fallbackSkills] : promptSkillsFromStructuredSkills(structuredSkills);
|
|
85
|
+
}
|
|
86
|
+
|
|
59
87
|
function injectSkills(prompt: string, skills: PromptSkill[]): string {
|
|
60
88
|
if (skills.length === 0 || /\n## Skills\b/.test(prompt) || /<skills_instructions>/.test(prompt)) {
|
|
61
89
|
return prompt;
|
|
Binary file
|
|
Binary file
|