@opellen/scaff 0.1.14 → 0.1.15
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 +1 -1
- package/templates/commands/go.md +1 -1
- package/templates/skills/scaff-flow/SKILL.md +5 -6
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -235
- package/dist/extend.d.ts +0 -12
- package/dist/extend.js +0 -242
- package/dist/hook-parser.d.ts +0 -15
- package/dist/hook-parser.js +0 -95
- package/dist/i18n/index.d.ts +0 -5
- package/dist/i18n/index.js +0 -20
- package/dist/i18n/messages.d.ts +0 -28
- package/dist/i18n/messages.js +0 -49
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/installer.d.ts +0 -10
- package/dist/installer.js +0 -74
- package/dist/marker.d.ts +0 -11
- package/dist/marker.js +0 -25
- package/dist/platforms/amazon-q.d.ts +0 -2
- package/dist/platforms/amazon-q.js +0 -12
- package/dist/platforms/antigravity.d.ts +0 -2
- package/dist/platforms/antigravity.js +0 -12
- package/dist/platforms/auggie.d.ts +0 -2
- package/dist/platforms/auggie.js +0 -15
- package/dist/platforms/claude.d.ts +0 -2
- package/dist/platforms/claude.js +0 -7
- package/dist/platforms/cline.d.ts +0 -2
- package/dist/platforms/cline.js +0 -11
- package/dist/platforms/codebuddy.d.ts +0 -2
- package/dist/platforms/codebuddy.js +0 -16
- package/dist/platforms/codex.d.ts +0 -2
- package/dist/platforms/codex.js +0 -7
- package/dist/platforms/continue.d.ts +0 -2
- package/dist/platforms/continue.js +0 -16
- package/dist/platforms/costrict.d.ts +0 -2
- package/dist/platforms/costrict.js +0 -15
- package/dist/platforms/crush.d.ts +0 -2
- package/dist/platforms/crush.js +0 -19
- package/dist/platforms/cursor.d.ts +0 -2
- package/dist/platforms/cursor.js +0 -18
- package/dist/platforms/factory.d.ts +0 -2
- package/dist/platforms/factory.js +0 -15
- package/dist/platforms/gemini.d.ts +0 -2
- package/dist/platforms/gemini.js +0 -14
- package/dist/platforms/github-copilot.d.ts +0 -2
- package/dist/platforms/github-copilot.js +0 -12
- package/dist/platforms/iflow.d.ts +0 -2
- package/dist/platforms/iflow.js +0 -18
- package/dist/platforms/index.d.ts +0 -10
- package/dist/platforms/index.js +0 -68
- package/dist/platforms/kilocode.d.ts +0 -2
- package/dist/platforms/kilocode.js +0 -8
- package/dist/platforms/kiro.d.ts +0 -2
- package/dist/platforms/kiro.js +0 -12
- package/dist/platforms/opencode.d.ts +0 -2
- package/dist/platforms/opencode.js +0 -12
- package/dist/platforms/pi.d.ts +0 -2
- package/dist/platforms/pi.js +0 -12
- package/dist/platforms/qoder.d.ts +0 -2
- package/dist/platforms/qoder.js +0 -19
- package/dist/platforms/qwen.d.ts +0 -2
- package/dist/platforms/qwen.js +0 -14
- package/dist/platforms/roocode.d.ts +0 -2
- package/dist/platforms/roocode.js +0 -11
- package/dist/platforms/toml.d.ts +0 -9
- package/dist/platforms/toml.js +0 -18
- package/dist/platforms/trae.d.ts +0 -2
- package/dist/platforms/trae.js +0 -11
- package/dist/platforms/types.d.ts +0 -19
- package/dist/platforms/types.js +0 -1
- package/dist/platforms/windsurf.d.ts +0 -2
- package/dist/platforms/windsurf.js +0 -19
- package/dist/platforms/yaml.d.ts +0 -10
- package/dist/platforms/yaml.js +0 -30
- package/dist/prompts/platform-select.d.ts +0 -1
- package/dist/prompts/platform-select.js +0 -174
- package/dist/skills/generate.d.ts +0 -13
- package/dist/skills/generate.js +0 -16
- package/dist/templates.d.ts +0 -18
- package/dist/templates.js +0 -96
- package/dist/ui/ascii-logo.d.ts +0 -6
- package/dist/ui/ascii-logo.js +0 -38
- package/dist/ui/colors.d.ts +0 -2
- package/dist/ui/colors.js +0 -3
- package/dist/ui/welcome.d.ts +0 -1
- package/dist/ui/welcome.js +0 -77
package/dist/platforms/pi.d.ts
DELETED
package/dist/platforms/pi.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { stripFrontmatter, yamlFrontmatter } from "./yaml.js";
|
|
2
|
-
export const pi = {
|
|
3
|
-
id: "pi",
|
|
4
|
-
displayName: "Pi",
|
|
5
|
-
configDir: ".pi",
|
|
6
|
-
commandPath: (name) => `.pi/prompts/scaff-${name}.md`,
|
|
7
|
-
formatCommand: (body, meta) => {
|
|
8
|
-
const stripped = stripFrontmatter(body);
|
|
9
|
-
const fm = yamlFrontmatter({ description: meta.description });
|
|
10
|
-
return fm + stripped;
|
|
11
|
-
},
|
|
12
|
-
};
|
package/dist/platforms/qoder.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { stripFrontmatter, yamlFrontmatter, } from "./yaml.js";
|
|
2
|
-
export const qoder = {
|
|
3
|
-
id: "qoder",
|
|
4
|
-
displayName: "Qoder",
|
|
5
|
-
configDir: ".qoder",
|
|
6
|
-
commandPath: (name) => `.qoder/commands/scaff/${name}.md`,
|
|
7
|
-
formatCommand: (body, meta) => {
|
|
8
|
-
const stripped = stripFrontmatter(body);
|
|
9
|
-
const fields = {
|
|
10
|
-
name: `scaff:${meta.name}`,
|
|
11
|
-
description: meta.description,
|
|
12
|
-
};
|
|
13
|
-
if (meta.category)
|
|
14
|
-
fields.category = meta.category;
|
|
15
|
-
if (meta.tags && meta.tags.length > 0)
|
|
16
|
-
fields.tags = meta.tags;
|
|
17
|
-
return yamlFrontmatter(fields) + stripped;
|
|
18
|
-
},
|
|
19
|
-
};
|
package/dist/platforms/qwen.d.ts
DELETED
package/dist/platforms/qwen.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { stripFrontmatter } from "./yaml.js";
|
|
2
|
-
import { escapeTomlString, escapeTomlMultiline } from "./toml.js";
|
|
3
|
-
export const qwen = {
|
|
4
|
-
id: "qwen",
|
|
5
|
-
displayName: "Qwen Code",
|
|
6
|
-
configDir: ".qwen",
|
|
7
|
-
commandPath: (name) => `.qwen/commands/scaff-${name}.toml`,
|
|
8
|
-
formatCommand: (body, meta) => {
|
|
9
|
-
const stripped = stripFrontmatter(body);
|
|
10
|
-
const description = escapeTomlString(meta.description);
|
|
11
|
-
const prompt = escapeTomlMultiline(stripped.trimEnd());
|
|
12
|
-
return `description = "${description}"\n\nprompt = """\n${prompt}\n"""\n`;
|
|
13
|
-
},
|
|
14
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { stripFrontmatter } from "./yaml.js";
|
|
2
|
-
export const roocode = {
|
|
3
|
-
id: "roocode",
|
|
4
|
-
displayName: "RooCode",
|
|
5
|
-
configDir: ".roo",
|
|
6
|
-
commandPath: (name) => `.roo/commands/scaff-${name}.md`,
|
|
7
|
-
formatCommand: (body, meta) => {
|
|
8
|
-
const stripped = stripFrontmatter(body);
|
|
9
|
-
return `# scaff-${meta.name}\n\n${meta.description}\n\n${stripped}`;
|
|
10
|
-
},
|
|
11
|
-
};
|
package/dist/platforms/toml.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Escapes a TOML basic string (double-quoted).
|
|
3
|
-
*/
|
|
4
|
-
export declare function escapeTomlString(value: string): string;
|
|
5
|
-
/**
|
|
6
|
-
* Escapes a TOML multi-line basic string (triple-quoted).
|
|
7
|
-
* Only the sequence `"""` needs escaping inside the body.
|
|
8
|
-
*/
|
|
9
|
-
export declare function escapeTomlMultiline(value: string): string;
|
package/dist/platforms/toml.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Escapes a TOML basic string (double-quoted).
|
|
3
|
-
*/
|
|
4
|
-
export function escapeTomlString(value) {
|
|
5
|
-
return value
|
|
6
|
-
.replace(/\\/g, "\\\\")
|
|
7
|
-
.replace(/"/g, '\\"')
|
|
8
|
-
.replace(/\n/g, "\\n")
|
|
9
|
-
.replace(/\r/g, "\\r")
|
|
10
|
-
.replace(/\t/g, "\\t");
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Escapes a TOML multi-line basic string (triple-quoted).
|
|
14
|
-
* Only the sequence `"""` needs escaping inside the body.
|
|
15
|
-
*/
|
|
16
|
-
export function escapeTomlMultiline(value) {
|
|
17
|
-
return value.replace(/"""/g, '\\"\\"\\"');
|
|
18
|
-
}
|
package/dist/platforms/trae.d.ts
DELETED
package/dist/platforms/trae.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const trae = {
|
|
2
|
-
id: "trae",
|
|
3
|
-
displayName: "Trae",
|
|
4
|
-
configDir: ".trae",
|
|
5
|
-
supportsCommands: false,
|
|
6
|
-
// Trae is skills-only; commandPath/formatCommand are never invoked by the
|
|
7
|
-
// installer because supportsCommands=false. They exist to satisfy the
|
|
8
|
-
// interface contract.
|
|
9
|
-
commandPath: (name) => `.trae/commands/scaff-${name}.md`,
|
|
10
|
-
formatCommand: (body) => body,
|
|
11
|
-
};
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export interface CommandMeta {
|
|
2
|
-
name: string;
|
|
3
|
-
description: string;
|
|
4
|
-
category?: string;
|
|
5
|
-
tags?: string[];
|
|
6
|
-
}
|
|
7
|
-
export interface PlatformAdapter {
|
|
8
|
-
id: string;
|
|
9
|
-
displayName: string;
|
|
10
|
-
configDir: string;
|
|
11
|
-
/**
|
|
12
|
-
* Whether this platform supports slash commands. When false, only skills
|
|
13
|
-
* are installed (e.g. Trae). Defaults to true.
|
|
14
|
-
*/
|
|
15
|
-
supportsCommands?: boolean;
|
|
16
|
-
commandPath(name: string): string;
|
|
17
|
-
formatCommand(body: string, meta: CommandMeta): string;
|
|
18
|
-
}
|
|
19
|
-
export declare const DEFAULT_PLATFORM = "claude";
|
package/dist/platforms/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_PLATFORM = "claude";
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { stripFrontmatter, yamlFrontmatter, } from "./yaml.js";
|
|
2
|
-
export const windsurf = {
|
|
3
|
-
id: "windsurf",
|
|
4
|
-
displayName: "Windsurf",
|
|
5
|
-
configDir: ".windsurf",
|
|
6
|
-
commandPath: (name) => `.windsurf/workflows/scaff-${name}.md`,
|
|
7
|
-
formatCommand: (body, meta) => {
|
|
8
|
-
const stripped = stripFrontmatter(body);
|
|
9
|
-
const fields = {
|
|
10
|
-
name: `scaff:${meta.name}`,
|
|
11
|
-
description: meta.description,
|
|
12
|
-
};
|
|
13
|
-
if (meta.category)
|
|
14
|
-
fields.category = meta.category;
|
|
15
|
-
if (meta.tags && meta.tags.length > 0)
|
|
16
|
-
fields.tags = meta.tags;
|
|
17
|
-
return yamlFrontmatter(fields) + stripped;
|
|
18
|
-
},
|
|
19
|
-
};
|
package/dist/platforms/yaml.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare function stripFrontmatter(content: string): string;
|
|
2
|
-
/**
|
|
3
|
-
* Escapes a string value for safe YAML output.
|
|
4
|
-
* Returns a plain scalar when possible; double-quotes only when the value
|
|
5
|
-
* contains special YAML characters or looks ambiguous.
|
|
6
|
-
*/
|
|
7
|
-
export declare function escapeYamlValue(value: string): string;
|
|
8
|
-
export declare function formatYamlArray(items: string[]): string;
|
|
9
|
-
export type YamlFieldValue = string | string[];
|
|
10
|
-
export declare function yamlFrontmatter(fields: Record<string, YamlFieldValue>): string;
|
package/dist/platforms/yaml.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export function stripFrontmatter(content) {
|
|
2
|
-
const match = content.match(/^---\n[\s\S]*?\n---\n/);
|
|
3
|
-
return match ? content.slice(match[0].length) : content;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Escapes a string value for safe YAML output.
|
|
7
|
-
* Returns a plain scalar when possible; double-quotes only when the value
|
|
8
|
-
* contains special YAML characters or looks ambiguous.
|
|
9
|
-
*/
|
|
10
|
-
export function escapeYamlValue(value) {
|
|
11
|
-
const needsQuoting = /[:\n\r#{}[\],&*!|>'"%@`]|^\s|\s$/.test(value);
|
|
12
|
-
if (needsQuoting) {
|
|
13
|
-
const escaped = value
|
|
14
|
-
.replace(/\\/g, "\\\\")
|
|
15
|
-
.replace(/"/g, '\\"')
|
|
16
|
-
.replace(/\n/g, "\\n");
|
|
17
|
-
return `"${escaped}"`;
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
export function formatYamlArray(items) {
|
|
22
|
-
return `[${items.map(escapeYamlValue).join(", ")}]`;
|
|
23
|
-
}
|
|
24
|
-
export function yamlFrontmatter(fields) {
|
|
25
|
-
const lines = Object.entries(fields).map(([k, v]) => {
|
|
26
|
-
const rendered = Array.isArray(v) ? formatYamlArray(v) : escapeYamlValue(v);
|
|
27
|
-
return `${k}: ${rendered}`;
|
|
28
|
-
});
|
|
29
|
-
return `---\n${lines.join("\n")}\n---\n`;
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function selectPlatforms(projectRoot: string): Promise<string[]>;
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import { createPrompt, useState, useKeypress, useMemo, useRef, usePagination, isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isEnterKey, } from "@inquirer/core";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
import { getAllAdapters, detectInstalledPlatforms, DEFAULT_PLATFORM } from "../platforms/index.js";
|
|
4
|
-
import { t } from "../i18n/index.js";
|
|
5
|
-
import { brand } from "../ui/colors.js";
|
|
6
|
-
const PAGE_SIZE = 15;
|
|
7
|
-
function buildChoices(projectRoot) {
|
|
8
|
-
const detected = new Set(detectInstalledPlatforms(projectRoot));
|
|
9
|
-
const adapters = getAllAdapters();
|
|
10
|
-
const choices = adapters.map((a) => ({
|
|
11
|
-
id: a.id,
|
|
12
|
-
displayName: a.displayName,
|
|
13
|
-
detected: detected.has(a.id),
|
|
14
|
-
}));
|
|
15
|
-
choices.sort((a, b) => {
|
|
16
|
-
if (a.detected !== b.detected)
|
|
17
|
-
return a.detected ? -1 : 1;
|
|
18
|
-
return a.displayName.localeCompare(b.displayName);
|
|
19
|
-
});
|
|
20
|
-
return choices;
|
|
21
|
-
}
|
|
22
|
-
const platformSelect = createPrompt((config, done) => {
|
|
23
|
-
const { projectRoot } = config;
|
|
24
|
-
const allChoices = useRef(null);
|
|
25
|
-
if (allChoices.current === null) {
|
|
26
|
-
allChoices.current = buildChoices(projectRoot);
|
|
27
|
-
}
|
|
28
|
-
const initialSelected = useRef(null);
|
|
29
|
-
if (initialSelected.current === null) {
|
|
30
|
-
const s = new Set();
|
|
31
|
-
s.add(DEFAULT_PLATFORM);
|
|
32
|
-
for (const c of allChoices.current) {
|
|
33
|
-
if (c.detected)
|
|
34
|
-
s.add(c.id);
|
|
35
|
-
}
|
|
36
|
-
initialSelected.current = s;
|
|
37
|
-
}
|
|
38
|
-
const [selected, setSelected] = useState(() => new Set(initialSelected.current));
|
|
39
|
-
const [search, setSearch] = useState("");
|
|
40
|
-
const [cursorIndex, setCursorIndex] = useState(0);
|
|
41
|
-
const [submitted, setSubmitted] = useState(false);
|
|
42
|
-
const [errorMsg, setErrorMsg] = useState("");
|
|
43
|
-
const visibleChoices = useMemo(() => {
|
|
44
|
-
if (!search)
|
|
45
|
-
return allChoices.current;
|
|
46
|
-
const lower = search.toLowerCase();
|
|
47
|
-
return allChoices.current.filter((c) => c.displayName.toLowerCase().includes(lower));
|
|
48
|
-
}, [search]);
|
|
49
|
-
const clampedCursor = useMemo(() => {
|
|
50
|
-
if (visibleChoices.length === 0)
|
|
51
|
-
return 0;
|
|
52
|
-
return Math.min(cursorIndex, visibleChoices.length - 1);
|
|
53
|
-
}, [cursorIndex, visibleChoices.length]);
|
|
54
|
-
useKeypress((event, rl) => {
|
|
55
|
-
if (event.ctrl && event.name === "c") {
|
|
56
|
-
process.exit(0);
|
|
57
|
-
}
|
|
58
|
-
if (submitted)
|
|
59
|
-
return;
|
|
60
|
-
if (isEnterKey(event)) {
|
|
61
|
-
if (selected.size === 0) {
|
|
62
|
-
setErrorMsg(t("select.error.empty"));
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
setSubmitted(true);
|
|
66
|
-
done([...selected]);
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (isUpKey(event)) {
|
|
70
|
-
if (clampedCursor > 0) {
|
|
71
|
-
setCursorIndex(clampedCursor - 1);
|
|
72
|
-
}
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (isDownKey(event)) {
|
|
76
|
-
if (clampedCursor < visibleChoices.length - 1) {
|
|
77
|
-
setCursorIndex(clampedCursor + 1);
|
|
78
|
-
}
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (isSpaceKey(event)) {
|
|
82
|
-
if (visibleChoices.length === 0)
|
|
83
|
-
return;
|
|
84
|
-
const choice = visibleChoices[clampedCursor];
|
|
85
|
-
if (!choice)
|
|
86
|
-
return;
|
|
87
|
-
const next = new Set(selected);
|
|
88
|
-
if (next.has(choice.id)) {
|
|
89
|
-
next.delete(choice.id);
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
next.add(choice.id);
|
|
93
|
-
}
|
|
94
|
-
setSelected(next);
|
|
95
|
-
setErrorMsg("");
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (isBackspaceKey(event)) {
|
|
99
|
-
if (search.length > 0) {
|
|
100
|
-
setSearch(search.slice(0, -1));
|
|
101
|
-
setCursorIndex(0);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
if (selected.size > 0) {
|
|
105
|
-
const arr = [...selected];
|
|
106
|
-
const last = arr[arr.length - 1];
|
|
107
|
-
const next = new Set(selected);
|
|
108
|
-
next.delete(last);
|
|
109
|
-
setSelected(next);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
if (event.name && event.name.length === 1 && !event.ctrl) {
|
|
115
|
-
setSearch(search + event.name);
|
|
116
|
-
setCursorIndex(0);
|
|
117
|
-
setErrorMsg("");
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
if (submitted) {
|
|
121
|
-
const names = allChoices.current
|
|
122
|
-
.filter((c) => selected.has(c.id))
|
|
123
|
-
.map((c) => brand(c.displayName))
|
|
124
|
-
.join(", ");
|
|
125
|
-
return `${chalk.green("✔")} ${config.message} ${names}`;
|
|
126
|
-
}
|
|
127
|
-
const pills = allChoices.current
|
|
128
|
-
.filter((c) => selected.has(c.id))
|
|
129
|
-
.map((c) => brand(`[${c.displayName}]`))
|
|
130
|
-
.join(" ");
|
|
131
|
-
const searchDisplay = search
|
|
132
|
-
? chalk.yellow(search)
|
|
133
|
-
: chalk.dim(t("select.typeToFilter"));
|
|
134
|
-
const page = usePagination({
|
|
135
|
-
items: visibleChoices,
|
|
136
|
-
active: clampedCursor,
|
|
137
|
-
pageSize: PAGE_SIZE,
|
|
138
|
-
loop: false,
|
|
139
|
-
renderItem({ item, isActive }) {
|
|
140
|
-
const isSelected = selected.has(item.id);
|
|
141
|
-
const icon = isSelected ? brand("●") : "○";
|
|
142
|
-
const arrow = isActive ? brand("›") : " ";
|
|
143
|
-
const label = isActive ? brand(item.displayName) : item.displayName;
|
|
144
|
-
const suffix = item.detected
|
|
145
|
-
? chalk.dim(` (${t("select.detected")})`)
|
|
146
|
-
: isSelected
|
|
147
|
-
? chalk.dim(` (${t("select.selected")})`)
|
|
148
|
-
: "";
|
|
149
|
-
return ` ${arrow} ${icon} ${label}${suffix}`;
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
const totalPages = Math.ceil(visibleChoices.length / PAGE_SIZE);
|
|
153
|
-
const currentPage = totalPages > 0
|
|
154
|
-
? Math.floor(clampedCursor / PAGE_SIZE) + 1
|
|
155
|
-
: 0;
|
|
156
|
-
const pageIndicator = totalPages > 1
|
|
157
|
-
? chalk.dim(` (${currentPage}/${totalPages})`)
|
|
158
|
-
: "";
|
|
159
|
-
const error = errorMsg ? `\n${chalk.red(errorMsg)}` : "";
|
|
160
|
-
const header = `${brand.bold("?")} ${config.message} (${allChoices.current.length} ${t("select.available")})`;
|
|
161
|
-
const selectedLine = ` ${t("select.selectedLabel")} ${pills || chalk.dim(t("select.none"))}`;
|
|
162
|
-
const searchLine = ` ${t("select.searchLabel")} [${searchDisplay}]`;
|
|
163
|
-
const hint = chalk.dim(` ${t("select.hint")}`);
|
|
164
|
-
return [
|
|
165
|
-
`${header}\n${selectedLine}\n${searchLine}\n${hint}\n${page}${pageIndicator}${error}`,
|
|
166
|
-
undefined,
|
|
167
|
-
];
|
|
168
|
-
});
|
|
169
|
-
export async function selectPlatforms(projectRoot) {
|
|
170
|
-
return platformSelect({
|
|
171
|
-
message: t("select.message"),
|
|
172
|
-
projectRoot,
|
|
173
|
-
});
|
|
174
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { PlatformAdapter } from "../platforms/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Skill installation path per platform.
|
|
4
|
-
* Skill content is universal (single format across all platforms);
|
|
5
|
-
* platforms differ only in where the SKILL.md file is placed.
|
|
6
|
-
*/
|
|
7
|
-
export declare function skillInstallPath(adapter: PlatformAdapter, skillName: string): string;
|
|
8
|
-
/**
|
|
9
|
-
* Produces the final skill file content.
|
|
10
|
-
* Currently a passthrough — reserved for future enrichment
|
|
11
|
-
* (license, compatibility, metadata.author/version/generatedBy).
|
|
12
|
-
*/
|
|
13
|
-
export declare function formatSkill(body: string): string;
|
package/dist/skills/generate.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Skill installation path per platform.
|
|
3
|
-
* Skill content is universal (single format across all platforms);
|
|
4
|
-
* platforms differ only in where the SKILL.md file is placed.
|
|
5
|
-
*/
|
|
6
|
-
export function skillInstallPath(adapter, skillName) {
|
|
7
|
-
return `${adapter.configDir}/skills/${skillName}/SKILL.md`;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Produces the final skill file content.
|
|
11
|
-
* Currently a passthrough — reserved for future enrichment
|
|
12
|
-
* (license, compatibility, metadata.author/version/generatedBy).
|
|
13
|
-
*/
|
|
14
|
-
export function formatSkill(body) {
|
|
15
|
-
return body;
|
|
16
|
-
}
|
package/dist/templates.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type PlatformAdapter, type CommandMeta } from "./platforms/index.js";
|
|
2
|
-
export interface ScaffConfig {
|
|
3
|
-
tools: string[];
|
|
4
|
-
subagent: boolean;
|
|
5
|
-
root: string;
|
|
6
|
-
docsDir: string;
|
|
7
|
-
codebaseDir: string;
|
|
8
|
-
force?: boolean;
|
|
9
|
-
}
|
|
10
|
-
export interface TemplateEntry {
|
|
11
|
-
src: string;
|
|
12
|
-
dst: string;
|
|
13
|
-
adapter: PlatformAdapter;
|
|
14
|
-
meta: CommandMeta;
|
|
15
|
-
rawContent: string;
|
|
16
|
-
}
|
|
17
|
-
export declare function resolveTemplates(config: ScaffConfig): TemplateEntry[];
|
|
18
|
-
export declare function renderFile(entry: TemplateEntry, config: ScaffConfig): string;
|
package/dist/templates.js
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from "node:fs";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { renderTemplate } from "./marker.js";
|
|
5
|
-
import { getAdapters } from "./platforms/index.js";
|
|
6
|
-
import { skillInstallPath, formatSkill } from "./skills/generate.js";
|
|
7
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
-
const TEMPLATE_DIR = join(__dirname, "..", "templates");
|
|
9
|
-
// Installed CLI version — injected into skill metadata.generatedBy.
|
|
10
|
-
// Read once at module load from the shipped package.json.
|
|
11
|
-
const SCAFF_VERSION = (() => {
|
|
12
|
-
try {
|
|
13
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
14
|
-
return String(pkg.version ?? "0.0.0");
|
|
15
|
-
}
|
|
16
|
-
catch {
|
|
17
|
-
return "0.0.0";
|
|
18
|
-
}
|
|
19
|
-
})();
|
|
20
|
-
const COMMAND_TEMPLATES = [
|
|
21
|
-
"scout", "goal", "context", "design",
|
|
22
|
-
"roadmap", "verify", "recap", "overview", "go",
|
|
23
|
-
];
|
|
24
|
-
const SKILL_TEMPLATES = [
|
|
25
|
-
{ src: "skills/scaff-subagent/SKILL.md", skillName: "scaff-subagent" },
|
|
26
|
-
{ src: "skills/scaff-flow/SKILL.md", skillName: "scaff-flow" },
|
|
27
|
-
];
|
|
28
|
-
function parseMeta(content) {
|
|
29
|
-
const normalized = content.replace(/\r\n/g, "\n");
|
|
30
|
-
const fmMatch = normalized.match(/^---\n([\s\S]*?)\n---/);
|
|
31
|
-
if (!fmMatch)
|
|
32
|
-
return { name: "", description: "" };
|
|
33
|
-
const fm = fmMatch[1];
|
|
34
|
-
const nameMatch = fm.match(/name:\s*"?scaff:(\w+)"?/);
|
|
35
|
-
const descMatch = fm.match(/description:\s*"([^"]+)"/);
|
|
36
|
-
const categoryMatch = fm.match(/category:\s*(\S+)/);
|
|
37
|
-
const tagsMatch = fm.match(/tags:\s*\[([^\]]*)\]/);
|
|
38
|
-
const tags = tagsMatch
|
|
39
|
-
? tagsMatch[1]
|
|
40
|
-
.split(",")
|
|
41
|
-
.map((s) => s.trim().replace(/^["']|["']$/g, ""))
|
|
42
|
-
.filter(Boolean)
|
|
43
|
-
: undefined;
|
|
44
|
-
return {
|
|
45
|
-
name: nameMatch?.[1] ?? "",
|
|
46
|
-
description: descMatch?.[1] ?? "",
|
|
47
|
-
category: categoryMatch?.[1],
|
|
48
|
-
tags,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
export function resolveTemplates(config) {
|
|
52
|
-
const adapters = getAdapters(config.tools);
|
|
53
|
-
const entries = [];
|
|
54
|
-
const commandMetas = COMMAND_TEMPLATES.map((cmd) => {
|
|
55
|
-
const src = `commands/${cmd}.md`;
|
|
56
|
-
const rawContent = readFileSync(join(TEMPLATE_DIR, src), "utf-8");
|
|
57
|
-
return { cmd, src, rawContent, meta: parseMeta(rawContent) };
|
|
58
|
-
});
|
|
59
|
-
const skillContents = SKILL_TEMPLATES.map((skill) => ({
|
|
60
|
-
...skill,
|
|
61
|
-
rawContent: readFileSync(join(TEMPLATE_DIR, skill.src), "utf-8"),
|
|
62
|
-
}));
|
|
63
|
-
for (const adapter of adapters) {
|
|
64
|
-
if (adapter.supportsCommands !== false) {
|
|
65
|
-
for (const { cmd, src, rawContent, meta } of commandMetas) {
|
|
66
|
-
entries.push({ src, dst: adapter.commandPath(cmd), adapter, meta, rawContent });
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
for (const skill of skillContents) {
|
|
70
|
-
entries.push({
|
|
71
|
-
src: skill.src,
|
|
72
|
-
dst: skillInstallPath(adapter, skill.skillName),
|
|
73
|
-
adapter,
|
|
74
|
-
meta: { name: skill.skillName, description: "" },
|
|
75
|
-
rawContent: skill.rawContent,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return entries;
|
|
80
|
-
}
|
|
81
|
-
export function renderFile(entry, config) {
|
|
82
|
-
const content = entry.rawContent.replace(/\r\n/g, "\n");
|
|
83
|
-
const rendered = renderTemplate(content, {
|
|
84
|
-
conditions: {
|
|
85
|
-
subagent: config.subagent,
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
const substituted = rendered
|
|
89
|
-
.replace(/\$DocsDir/g, config.docsDir)
|
|
90
|
-
.replace(/\$CodebaseDir/g, config.codebaseDir)
|
|
91
|
-
.replace(/\$ScaffVersion/g, SCAFF_VERSION);
|
|
92
|
-
if (entry.src.startsWith("skills/")) {
|
|
93
|
-
return formatSkill(substituted);
|
|
94
|
-
}
|
|
95
|
-
return entry.adapter.formatCommand(substituted, entry.meta);
|
|
96
|
-
}
|
package/dist/ui/ascii-logo.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare const SCAFF_LOGO: {
|
|
2
|
-
readonly frame: readonly [" ████ ████ ", " █ █ ", "█████ █████", " █ █ ", " █ █ ", " █ █ ", " █ █ ", " █ █ ", "█████ █████", " █ █ ", " ████ ████ "];
|
|
3
|
-
readonly inner: readonly [" ", " ", " ██ ████ ", " ▒█ █▒ ", " ▒█ █▒ ", " ▒██▒ ", " ▒█ █▒ ", " ▒█ █▒ ", " ████ ██ ", " ", " "];
|
|
4
|
-
};
|
|
5
|
-
export declare const SCAFF_LOGO_WIDTH: number;
|
|
6
|
-
export declare const SCAFF_LOGO_HEIGHT: 11;
|
package/dist/ui/ascii-logo.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
// Two-layer logo. Layers are overlaid at render time: any non-space char in
|
|
2
|
-
// `inner` wins over `frame`. This lets the same block char (█, ▒, ...) carry
|
|
3
|
-
// a different color depending on which layer it belongs to, without a parallel
|
|
4
|
-
// mask array to keep in sync.
|
|
5
|
-
//
|
|
6
|
-
// Palette: █ (full), ▓ (dark), ▒ (medium), ░ (light) — shade blocks give a
|
|
7
|
-
// pseudo-anti-aliased gradient on diagonal edges that renders uniformly across
|
|
8
|
-
// monospace fonts, unlike slash/diagonal glyphs (╲ ╱ ╳) which frequently break.
|
|
9
|
-
export const SCAFF_LOGO = {
|
|
10
|
-
frame: [
|
|
11
|
-
" ████ ████ ",
|
|
12
|
-
" █ █ ",
|
|
13
|
-
"█████ █████",
|
|
14
|
-
" █ █ ",
|
|
15
|
-
" █ █ ",
|
|
16
|
-
" █ █ ",
|
|
17
|
-
" █ █ ",
|
|
18
|
-
" █ █ ",
|
|
19
|
-
"█████ █████",
|
|
20
|
-
" █ █ ",
|
|
21
|
-
" ████ ████ ",
|
|
22
|
-
],
|
|
23
|
-
inner: [
|
|
24
|
-
" ",
|
|
25
|
-
" ",
|
|
26
|
-
" ██ ████ ",
|
|
27
|
-
" ▒█ █▒ ",
|
|
28
|
-
" ▒█ █▒ ",
|
|
29
|
-
" ▒██▒ ",
|
|
30
|
-
" ▒█ █▒ ",
|
|
31
|
-
" ▒█ █▒ ",
|
|
32
|
-
" ████ ██ ",
|
|
33
|
-
" ",
|
|
34
|
-
" ",
|
|
35
|
-
],
|
|
36
|
-
};
|
|
37
|
-
export const SCAFF_LOGO_WIDTH = SCAFF_LOGO.frame[0].length;
|
|
38
|
-
export const SCAFF_LOGO_HEIGHT = SCAFF_LOGO.frame.length;
|
package/dist/ui/colors.d.ts
DELETED
package/dist/ui/colors.js
DELETED
package/dist/ui/welcome.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function showWelcome(): Promise<void>;
|