@opellen/opengoal 1.0.3 → 1.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/dist/platforms/codex.js +22 -0
- package/dist/platforms/types.d.ts +28 -0
- package/dist/templates.d.ts +2 -0
- package/dist/templates.js +24 -8
- package/package.json +2 -2
package/dist/platforms/codex.js
CHANGED
|
@@ -1,7 +1,29 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
3
|
+
// Codex labels a skill from agents/openai.yaml when present; without it the
|
|
4
|
+
// label is derived from the frontmatter name with the casing flattened
|
|
5
|
+
// ("opengoal:go" shows as "Opengoal: Go").
|
|
6
|
+
const commandLabel = (name) => `OpenGoal: ${capitalize(name)}`;
|
|
7
|
+
function displayName(target) {
|
|
8
|
+
return target.kind === "command"
|
|
9
|
+
? commandLabel(target.name)
|
|
10
|
+
: `OpenGoal ${capitalize(target.name.replace(/^opengoal-/, ""))}`;
|
|
11
|
+
}
|
|
1
12
|
export const codex = {
|
|
2
13
|
id: "codex",
|
|
3
14
|
displayName: "Codex",
|
|
4
15
|
configDir: ".codex",
|
|
5
16
|
commandPath: (name, prefix) => `.codex/skills/${prefix}-${name}/SKILL.md`,
|
|
6
17
|
formatCommand: (body) => body,
|
|
18
|
+
// Skills are invoked from Codex's picker, so prose refers to them by the
|
|
19
|
+
// label the picker shows, not by a slash form.
|
|
20
|
+
commandRef: (name) => commandLabel(name),
|
|
21
|
+
companionFiles: (target) => [
|
|
22
|
+
{
|
|
23
|
+
dst: `${dirname(target.dst).replace(/\\/g, "/")}/agents/openai.yaml`,
|
|
24
|
+
content: "interface:\n" +
|
|
25
|
+
` display_name: ${JSON.stringify(displayName(target))}\n` +
|
|
26
|
+
` short_description: ${JSON.stringify(target.description)}\n`,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
7
29
|
};
|
|
@@ -4,6 +4,21 @@ export interface CommandMeta {
|
|
|
4
4
|
category?: string;
|
|
5
5
|
tags?: string[];
|
|
6
6
|
}
|
|
7
|
+
/** An extra file a platform wants installed next to a command or skill. */
|
|
8
|
+
export interface CompanionFile {
|
|
9
|
+
/** Install path relative to the project root. */
|
|
10
|
+
dst: string;
|
|
11
|
+
content: string;
|
|
12
|
+
}
|
|
13
|
+
export interface CompanionTarget {
|
|
14
|
+
kind: "command" | "skill";
|
|
15
|
+
/** Command name ("go") or skill name ("opengoal-flow"). */
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
/** Install path of the file the companions accompany. */
|
|
19
|
+
dst: string;
|
|
20
|
+
prefix: string;
|
|
21
|
+
}
|
|
7
22
|
export interface PlatformAdapter {
|
|
8
23
|
id: string;
|
|
9
24
|
displayName: string;
|
|
@@ -15,5 +30,18 @@ export interface PlatformAdapter {
|
|
|
15
30
|
supportsCommands?: boolean;
|
|
16
31
|
commandPath(name: string, prefix: string): string;
|
|
17
32
|
formatCommand(body: string, meta: CommandMeta, prefix: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* How an installed command is invoked on this platform, as written in the
|
|
35
|
+
* prose that templates emit ("run /opgl:go"). Platforms whose invocation
|
|
36
|
+
* differs from the Claude Code slash form `/<prefix>:<name>` override this;
|
|
37
|
+
* when omitted that form is used.
|
|
38
|
+
*/
|
|
39
|
+
commandRef?(name: string, prefix: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Extra files the platform needs beside an installed command or skill, such
|
|
42
|
+
* as Codex's `agents/openai.yaml` display manifest. They are installed and
|
|
43
|
+
* uninstalled together with the file they accompany.
|
|
44
|
+
*/
|
|
45
|
+
companionFiles?(target: CompanionTarget): CompanionFile[];
|
|
18
46
|
}
|
|
19
47
|
export declare const DEFAULT_PLATFORM = "claude";
|
package/dist/templates.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export interface TemplateEntry {
|
|
|
15
15
|
adapter: PlatformAdapter;
|
|
16
16
|
meta: CommandMeta;
|
|
17
17
|
rawContent: string;
|
|
18
|
+
/** Companion file produced by the adapter; rawContent is final, no rendering. */
|
|
19
|
+
generated?: boolean;
|
|
18
20
|
}
|
|
19
21
|
export declare function resolveTemplates(config: OpenGoalConfig): TemplateEntry[];
|
|
20
22
|
export declare function renderFile(entry: TemplateEntry, config: OpenGoalConfig): string;
|
package/dist/templates.js
CHANGED
|
@@ -18,6 +18,18 @@ const OPENGOAL_VERSION = (() => {
|
|
|
18
18
|
}
|
|
19
19
|
})();
|
|
20
20
|
export const DEFAULT_PREFIX = "opgl";
|
|
21
|
+
function companionEntries(adapter, target, meta) {
|
|
22
|
+
if (!adapter.companionFiles)
|
|
23
|
+
return [];
|
|
24
|
+
return adapter.companionFiles(target).map((file) => ({
|
|
25
|
+
src: `generated/${target.kind}/${target.name}`,
|
|
26
|
+
dst: file.dst,
|
|
27
|
+
adapter,
|
|
28
|
+
meta,
|
|
29
|
+
rawContent: file.content,
|
|
30
|
+
generated: true,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
21
33
|
const COMMAND_TEMPLATES = [
|
|
22
34
|
"scout", "goal", "context", "design",
|
|
23
35
|
"roadmap", "verify", "recap", "overview", "go",
|
|
@@ -64,32 +76,36 @@ export function resolveTemplates(config) {
|
|
|
64
76
|
for (const adapter of adapters) {
|
|
65
77
|
if (adapter.supportsCommands !== false) {
|
|
66
78
|
for (const { cmd, src, rawContent, meta } of commandMetas) {
|
|
67
|
-
|
|
79
|
+
const dst = adapter.commandPath(cmd, config.prefix);
|
|
80
|
+
entries.push({ src, dst, adapter, meta, rawContent });
|
|
81
|
+
entries.push(...companionEntries(adapter, { kind: "command", name: cmd, description: meta.description, dst, prefix: config.prefix }, meta));
|
|
68
82
|
}
|
|
69
83
|
}
|
|
70
84
|
for (const skill of skillContents) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
rawContent: skill.rawContent,
|
|
77
|
-
});
|
|
85
|
+
const dst = skillInstallPath(adapter, skill.skillName);
|
|
86
|
+
const description = skill.rawContent.replace(/\r\n/g, "\n").match(/^description:\s*(.+)$/m)?.[1]?.trim() ?? "";
|
|
87
|
+
const meta = { name: skill.skillName, description };
|
|
88
|
+
entries.push({ src: skill.src, dst, adapter, meta, rawContent: skill.rawContent });
|
|
89
|
+
entries.push(...companionEntries(adapter, { kind: "skill", name: skill.skillName, description, dst, prefix: config.prefix }, meta));
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
return entries;
|
|
81
93
|
}
|
|
82
94
|
export function renderFile(entry, config) {
|
|
95
|
+
if (entry.generated)
|
|
96
|
+
return entry.rawContent;
|
|
83
97
|
const content = entry.rawContent.replace(/\r\n/g, "\n");
|
|
84
98
|
const rendered = renderTemplate(content, {
|
|
85
99
|
conditions: {
|
|
86
100
|
subagent: config.subagent,
|
|
87
101
|
},
|
|
88
102
|
});
|
|
103
|
+
const commandRef = entry.adapter.commandRef ?? ((name, prefix) => `/${prefix}:${name}`);
|
|
89
104
|
const substituted = rendered
|
|
90
105
|
.replace(/\$DocsDir/g, config.docsDir)
|
|
91
106
|
.replace(/\$CodebaseDir/g, config.codebaseDir)
|
|
92
107
|
.replace(/\$OpenGoalVersion/g, OPENGOAL_VERSION)
|
|
108
|
+
.replace(/\/\$CommandPrefix:([a-z-]+)/g, (_match, name) => commandRef(name, config.prefix))
|
|
93
109
|
.replace(/\$CommandPrefix/g, config.prefix);
|
|
94
110
|
if (entry.src.startsWith("skills/")) {
|
|
95
111
|
return formatSkill(substituted);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opellen/opengoal",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Goal-centric AI harness. Plain markdown, zero runtime — nothing runs but your agent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,4 +48,4 @@
|
|
|
48
48
|
"chalk": "^5.6.2",
|
|
49
49
|
"yaml": "^2.8.3"
|
|
50
50
|
}
|
|
51
|
-
}
|
|
51
|
+
}
|