@preapexis/pi-kit 1.0.0
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/.github/workflows/publish.yml +30 -0
- package/.pi/settings.json +3 -0
- package/AGENTS.md +199 -0
- package/CHANGELOG.md +71 -0
- package/LICENSE +15 -0
- package/README.md +370 -0
- package/extensions/brand-ui.ts +107 -0
- package/extensions/git-guard.ts +134 -0
- package/extensions/prompts.ts +53 -0
- package/extensions/safety.ts +242 -0
- package/extensions/sound-cues.ts +88 -0
- package/extensions/status.ts +86 -0
- package/extensions/update.ts +245 -0
- package/extensions/usage-tracker.ts +154 -0
- package/package.json +41 -0
- package/prompts/commit.md +79 -0
- package/prompts/implement.md +41 -0
- package/prompts/init.md +98 -0
- package/prompts/plan.md +142 -0
- package/prompts/review-safe.md +78 -0
- package/prompts/save-plan.md +65 -0
- package/prompts/security.md +100 -0
- package/settings.json +4 -0
- package/skills/component-implementation/SKILL.md +80 -0
- package/skills/frontend-onboarding/SKILL.md +76 -0
- package/skills/frontend-quality/SKILL.md +85 -0
- package/skills/safe-coding/SKILL.md +48 -0
- package/tests/extensions.test.ts +49 -0
- package/tests/helpers.ts +104 -0
- package/tests/package.test.ts +38 -0
- package/tests/prompts.test.ts +40 -0
- package/tests/skills.test.ts +42 -0
- package/tests/themes.test.ts +49 -0
- package/themes/latte-review.json +77 -0
- package/themes/neon-guardian.json +77 -0
- package/themes/safe-dark.json +75 -0
- package/themes/tokyo-midnight.json +77 -0
- package/tsconfig.json +14 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// cSpell:words Varun Gaikwad preapexis npm PowerShell
|
|
2
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
|
|
4
|
+
type EventContext = Parameters<Parameters<ExtensionAPI["on"]>[1]>[1];
|
|
5
|
+
|
|
6
|
+
type UpdateOption = {
|
|
7
|
+
id: string;
|
|
8
|
+
label: string;
|
|
9
|
+
shell: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ShellCommand = {
|
|
13
|
+
command: string;
|
|
14
|
+
args: string[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const RUN_CHOICE = "▶ Run selected updates";
|
|
18
|
+
const CANCEL_CHOICE = "✕ Cancel";
|
|
19
|
+
|
|
20
|
+
export default function (pi: ExtensionAPI): void {
|
|
21
|
+
const options: UpdateOption[] = [
|
|
22
|
+
{
|
|
23
|
+
id: "pi",
|
|
24
|
+
label: "Update Pi CLI globally",
|
|
25
|
+
shell:
|
|
26
|
+
"npm install -g --ignore-scripts @earendil-works/pi-coding-agent@latest"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: "kit-local",
|
|
30
|
+
label: "Re-link this local PreApeXis kit",
|
|
31
|
+
shell: "pi install -l ."
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: "kit-github",
|
|
35
|
+
label: "Update PreApeXis Pi Kit from GitHub",
|
|
36
|
+
shell: "pi install git:github.com/VarunGaikwad/preapexis-pi-kit@master"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "kit-npm",
|
|
40
|
+
label: "Update PreApeXis Pi Kit from npm",
|
|
41
|
+
shell: "pi install npm:preapexis-pi-kit"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "project-npm",
|
|
45
|
+
label: "Update current project npm packages",
|
|
46
|
+
shell: "npm update"
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
function shellCommand(command: string): ShellCommand {
|
|
51
|
+
if (process.platform === "win32") {
|
|
52
|
+
return {
|
|
53
|
+
command: "cmd",
|
|
54
|
+
args: ["/d", "/s", "/c", command]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
command: "sh",
|
|
60
|
+
args: ["-lc", command]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function optionLabel(
|
|
65
|
+
option: UpdateOption,
|
|
66
|
+
selected: Map<string, UpdateOption>
|
|
67
|
+
): string {
|
|
68
|
+
const marker = selected.has(option.id) ? "✓" : "×";
|
|
69
|
+
return `${marker} ${option.label}`;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function selectedSummary(selected: UpdateOption[]): string {
|
|
73
|
+
if (selected.length === 0) {
|
|
74
|
+
return "Selected: none";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return ["Selected:", ...selected.map((option) => `- ${option.label}`)].join(
|
|
78
|
+
"\n"
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function buildMenu(selected: Map<string, UpdateOption>): {
|
|
83
|
+
items: string[];
|
|
84
|
+
optionByMenuItem: Map<string, UpdateOption>;
|
|
85
|
+
} {
|
|
86
|
+
const optionByMenuItem = new Map<string, UpdateOption>();
|
|
87
|
+
|
|
88
|
+
const optionItems = options.map((option) => {
|
|
89
|
+
const label = optionLabel(option, selected);
|
|
90
|
+
optionByMenuItem.set(label, option);
|
|
91
|
+
return label;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
items: [...optionItems, RUN_CHOICE, CANCEL_CHOICE],
|
|
96
|
+
optionByMenuItem
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function chooseUpdates(ctx: EventContext): Promise<UpdateOption[]> {
|
|
101
|
+
const selected = new Map<string, UpdateOption>();
|
|
102
|
+
|
|
103
|
+
while (true) {
|
|
104
|
+
const { items, optionByMenuItem } = buildMenu(selected);
|
|
105
|
+
|
|
106
|
+
const choice = await ctx.ui.select(
|
|
107
|
+
[
|
|
108
|
+
"What do you want to update?",
|
|
109
|
+
"",
|
|
110
|
+
"Pick an item to toggle it.",
|
|
111
|
+
"✓ = selected, × = not selected",
|
|
112
|
+
"",
|
|
113
|
+
selectedSummary([...selected.values()])
|
|
114
|
+
].join("\n"),
|
|
115
|
+
items
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
if (!choice || choice === CANCEL_CHOICE) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (choice === RUN_CHOICE) {
|
|
123
|
+
if (selected.size === 0) {
|
|
124
|
+
ctx.ui.notify("Select at least one update first.", "warning");
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return [...selected.values()];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const option = optionByMenuItem.get(choice);
|
|
132
|
+
|
|
133
|
+
if (!option) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (selected.has(option.id)) {
|
|
138
|
+
selected.delete(option.id);
|
|
139
|
+
ctx.ui.notify(`Removed: ${option.label}`, "info");
|
|
140
|
+
} else {
|
|
141
|
+
selected.set(option.id, option);
|
|
142
|
+
ctx.ui.notify(`Added: ${option.label}`, "info");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function runUpdate(
|
|
148
|
+
option: UpdateOption,
|
|
149
|
+
ctx: EventContext
|
|
150
|
+
): Promise<boolean> {
|
|
151
|
+
ctx.ui.notify(`Running update:\n\n${option.shell}`, "info");
|
|
152
|
+
|
|
153
|
+
const shell = shellCommand(option.shell);
|
|
154
|
+
|
|
155
|
+
const result = await pi.exec(shell.command, shell.args, {
|
|
156
|
+
cwd: ctx.cwd
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const stdout = result.stdout?.trim() ?? "";
|
|
160
|
+
const stderr = result.stderr?.trim() ?? "";
|
|
161
|
+
const output = [stdout, stderr].filter(Boolean).join("\n\n");
|
|
162
|
+
|
|
163
|
+
if (result.code === 0) {
|
|
164
|
+
ctx.ui.notify(
|
|
165
|
+
[`Update completed: ${option.label}`, "", output || "No output."].join(
|
|
166
|
+
"\n"
|
|
167
|
+
),
|
|
168
|
+
"info"
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
ctx.ui.notify(
|
|
175
|
+
[
|
|
176
|
+
`Update failed: ${option.label}`,
|
|
177
|
+
"",
|
|
178
|
+
`Command: ${option.shell}`,
|
|
179
|
+
`Exit code: ${result.code}`,
|
|
180
|
+
"",
|
|
181
|
+
output ||
|
|
182
|
+
"No output captured. Try running this command manually in PowerShell."
|
|
183
|
+
].join("\n"),
|
|
184
|
+
"error"
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
pi.registerCommand("update", {
|
|
191
|
+
description: "Update Pi, this Pi kit, or project packages",
|
|
192
|
+
handler: async (_args, ctx) => {
|
|
193
|
+
if (!ctx.hasUI) {
|
|
194
|
+
console.log("The /update command requires the Pi UI.");
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const selected = await chooseUpdates(ctx);
|
|
199
|
+
|
|
200
|
+
if (selected.length === 0) {
|
|
201
|
+
ctx.ui.notify("Update cancelled.", "info");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const summary = selected
|
|
206
|
+
.map((option) => `- ${option.label}\n ${option.shell}`)
|
|
207
|
+
.join("\n");
|
|
208
|
+
|
|
209
|
+
const ok = await ctx.ui.confirm(
|
|
210
|
+
"Confirm updates",
|
|
211
|
+
`The following updates will run:\n\n${summary}\n\nContinue?`
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
if (!ok) {
|
|
215
|
+
ctx.ui.notify("Update cancelled.", "info");
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
let passed = 0;
|
|
220
|
+
let failed = 0;
|
|
221
|
+
|
|
222
|
+
for (const option of selected) {
|
|
223
|
+
const updateOk = await runUpdate(option, ctx);
|
|
224
|
+
|
|
225
|
+
if (updateOk) {
|
|
226
|
+
passed += 1;
|
|
227
|
+
} else {
|
|
228
|
+
failed += 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
ctx.ui.notify(
|
|
233
|
+
[
|
|
234
|
+
"Update finished.",
|
|
235
|
+
"",
|
|
236
|
+
`Passed: ${passed}`,
|
|
237
|
+
`Failed: ${failed}`,
|
|
238
|
+
"",
|
|
239
|
+
"Run /reload or restart Pi if needed."
|
|
240
|
+
].join("\n"),
|
|
241
|
+
failed > 0 ? "warning" : "info"
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
type EventContext = Parameters<Parameters<ExtensionAPI["on"]>[1]>[1];
|
|
4
|
+
|
|
5
|
+
type AssistantMessageLike = {
|
|
6
|
+
role: "assistant";
|
|
7
|
+
usage?: {
|
|
8
|
+
input?: number;
|
|
9
|
+
output?: number;
|
|
10
|
+
cacheRead?: number;
|
|
11
|
+
cacheWrite?: number;
|
|
12
|
+
cost?: {
|
|
13
|
+
total?: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type UsageTotals = {
|
|
18
|
+
input: number;
|
|
19
|
+
output: number;
|
|
20
|
+
cacheRead: number;
|
|
21
|
+
cacheWrite: number;
|
|
22
|
+
totalTokens: number;
|
|
23
|
+
cost: number;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default function (pi: ExtensionAPI): void {
|
|
27
|
+
const STATUS_KEY = "usage-tracker";
|
|
28
|
+
let baseline: UsageTotals = emptyTotals();
|
|
29
|
+
|
|
30
|
+
function emptyTotals(): UsageTotals {
|
|
31
|
+
return {
|
|
32
|
+
input: 0,
|
|
33
|
+
output: 0,
|
|
34
|
+
cacheRead: 0,
|
|
35
|
+
cacheWrite: 0,
|
|
36
|
+
totalTokens: 0,
|
|
37
|
+
cost: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function formatNumber(value: number): string {
|
|
42
|
+
if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(1)}m`;
|
|
43
|
+
if (value >= 1_000) return `${(value / 1_000).toFixed(1)}k`;
|
|
44
|
+
return String(value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function formatCost(value: number): string {
|
|
48
|
+
if (value < 0.001) return "$0.000";
|
|
49
|
+
return `$${value.toFixed(3)}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function subtractTotals(
|
|
53
|
+
current: UsageTotals,
|
|
54
|
+
base: UsageTotals
|
|
55
|
+
): UsageTotals {
|
|
56
|
+
return {
|
|
57
|
+
input: Math.max(0, current.input - base.input),
|
|
58
|
+
output: Math.max(0, current.output - base.output),
|
|
59
|
+
cacheRead: Math.max(0, current.cacheRead - base.cacheRead),
|
|
60
|
+
cacheWrite: Math.max(0, current.cacheWrite - base.cacheWrite),
|
|
61
|
+
totalTokens: Math.max(0, current.totalTokens - base.totalTokens),
|
|
62
|
+
cost: Math.max(0, current.cost - base.cost)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function getUsageTotals(ctx: EventContext): UsageTotals {
|
|
67
|
+
const totals = emptyTotals();
|
|
68
|
+
|
|
69
|
+
for (const entry of ctx.sessionManager.getBranch()) {
|
|
70
|
+
if (entry.type !== "message") continue;
|
|
71
|
+
if (entry.message.role !== "assistant") continue;
|
|
72
|
+
|
|
73
|
+
const message = entry.message as AssistantMessageLike;
|
|
74
|
+
const usage = message.usage;
|
|
75
|
+
|
|
76
|
+
if (!usage) continue;
|
|
77
|
+
|
|
78
|
+
totals.input += usage.input ?? 0;
|
|
79
|
+
totals.output += usage.output ?? 0;
|
|
80
|
+
totals.cacheRead += usage.cacheRead ?? 0;
|
|
81
|
+
totals.cacheWrite += usage.cacheWrite ?? 0;
|
|
82
|
+
totals.cost += usage.cost?.total ?? 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
totals.totalTokens =
|
|
86
|
+
totals.input + totals.output + totals.cacheRead + totals.cacheWrite;
|
|
87
|
+
|
|
88
|
+
return totals;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function updateStatus(ctx: EventContext): void {
|
|
92
|
+
if (!ctx.hasUI) return;
|
|
93
|
+
|
|
94
|
+
const totals = subtractTotals(getUsageTotals(ctx), baseline);
|
|
95
|
+
|
|
96
|
+
ctx.ui.setStatus(
|
|
97
|
+
STATUS_KEY,
|
|
98
|
+
`usage: ${formatNumber(totals.totalTokens)} ${formatCost(totals.cost)}`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function buildUsageReport(ctx: EventContext): string {
|
|
103
|
+
const totals = subtractTotals(getUsageTotals(ctx), baseline);
|
|
104
|
+
|
|
105
|
+
return [
|
|
106
|
+
"Token and price usage",
|
|
107
|
+
"",
|
|
108
|
+
`Input tokens: ${totals.input.toLocaleString()}`,
|
|
109
|
+
`Output tokens: ${totals.output.toLocaleString()}`,
|
|
110
|
+
`Cache read tokens: ${totals.cacheRead.toLocaleString()}`,
|
|
111
|
+
`Cache write tokens: ${totals.cacheWrite.toLocaleString()}`,
|
|
112
|
+
`Total tokens: ${totals.totalTokens.toLocaleString()}`,
|
|
113
|
+
`Estimated cost: ${formatCost(totals.cost)}`,
|
|
114
|
+
"",
|
|
115
|
+
`Model: ${ctx.model?.id ?? "unknown"}`
|
|
116
|
+
].join("\n");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
120
|
+
baseline = emptyTotals();
|
|
121
|
+
updateStatus(ctx);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
pi.on("message_end", async (event, ctx) => {
|
|
125
|
+
if (event.message.role === "assistant") {
|
|
126
|
+
updateStatus(ctx);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
pi.on("model_select", async (_event, ctx) => {
|
|
131
|
+
updateStatus(ctx);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
pi.registerCommand("usage", {
|
|
135
|
+
description: "Show token and price usage for this session",
|
|
136
|
+
handler: async (_args, ctx) => {
|
|
137
|
+
if (!ctx.hasUI) return;
|
|
138
|
+
ctx.ui.notify(buildUsageReport(ctx), "info");
|
|
139
|
+
updateStatus(ctx);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
pi.registerCommand("usage-reset", {
|
|
144
|
+
description: "Reset token and price tracker baseline",
|
|
145
|
+
handler: async (_args, ctx) => {
|
|
146
|
+
baseline = getUsageTotals(ctx);
|
|
147
|
+
|
|
148
|
+
if (ctx.hasUI) {
|
|
149
|
+
ctx.ui.notify("Usage tracker reset for this session.", "info");
|
|
150
|
+
updateStatus(ctx);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@preapexis/pi-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Personal Pi coding-agent kit with safety extensions, status UI, prompt workflows, skills, and themes.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-coding-agent",
|
|
8
|
+
"coding-agent",
|
|
9
|
+
"prompts",
|
|
10
|
+
"skills",
|
|
11
|
+
"extensions"
|
|
12
|
+
],
|
|
13
|
+
"pi": {
|
|
14
|
+
"extensions": [
|
|
15
|
+
"./extensions"
|
|
16
|
+
],
|
|
17
|
+
"skills": [
|
|
18
|
+
"./skills"
|
|
19
|
+
],
|
|
20
|
+
"prompts": [
|
|
21
|
+
"./prompts"
|
|
22
|
+
],
|
|
23
|
+
"themes": [
|
|
24
|
+
"./themes"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
29
|
+
},
|
|
30
|
+
"author": "Varun Gaikwad",
|
|
31
|
+
"license": "ISC",
|
|
32
|
+
"type": "module",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"typescript": "^5.5.0",
|
|
39
|
+
"vitest": "^2.0.0"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Git Commit Message
|
|
2
|
+
|
|
3
|
+
Analyze the current changes in this repository and propose a git commit message.
|
|
4
|
+
|
|
5
|
+
Do not create the commit. Only suggest the message.
|
|
6
|
+
|
|
7
|
+
## How to read the changes
|
|
8
|
+
|
|
9
|
+
Run safe git read commands only:
|
|
10
|
+
|
|
11
|
+
- `git status`
|
|
12
|
+
- `git diff`
|
|
13
|
+
- `git diff --cached`
|
|
14
|
+
- `git log --oneline -5` if useful for style
|
|
15
|
+
|
|
16
|
+
If there is nothing staged and nothing unstaged, report that no changes are ready to commit.
|
|
17
|
+
|
|
18
|
+
## Output format
|
|
19
|
+
|
|
20
|
+
Provide a commit message in this format:
|
|
21
|
+
|
|
22
|
+
```txt
|
|
23
|
+
<type>: <short summary>
|
|
24
|
+
|
|
25
|
+
<plain-language explanation>
|
|
26
|
+
|
|
27
|
+
<technical explanation>
|
|
28
|
+
|
|
29
|
+
- <specific change 1>
|
|
30
|
+
- <specific change 2>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Guidelines
|
|
34
|
+
|
|
35
|
+
1. Use a conventional commit type:
|
|
36
|
+
- `feat`
|
|
37
|
+
- `fix`
|
|
38
|
+
- `refactor`
|
|
39
|
+
- `docs`
|
|
40
|
+
- `test`
|
|
41
|
+
- `chore`
|
|
42
|
+
- `style`
|
|
43
|
+
- `build`
|
|
44
|
+
- `ci`
|
|
45
|
+
|
|
46
|
+
2. The short summary must be:
|
|
47
|
+
- one line
|
|
48
|
+
- concise
|
|
49
|
+
- imperative mood
|
|
50
|
+
- no period at the end
|
|
51
|
+
|
|
52
|
+
3. The plain-language paragraph should explain what changed and why.
|
|
53
|
+
|
|
54
|
+
4. The technical paragraph should explain the implementation details briefly.
|
|
55
|
+
|
|
56
|
+
5. The bullet list should include the most important changes.
|
|
57
|
+
|
|
58
|
+
## Split commits
|
|
59
|
+
|
|
60
|
+
If there are many unrelated changes, suggest splitting them into multiple commits.
|
|
61
|
+
|
|
62
|
+
For each group, provide:
|
|
63
|
+
|
|
64
|
+
```txt
|
|
65
|
+
Commit 1:
|
|
66
|
+
<message>
|
|
67
|
+
|
|
68
|
+
Commit 2:
|
|
69
|
+
<message>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Rules
|
|
73
|
+
|
|
74
|
+
- Do not commit.
|
|
75
|
+
- Do not stage files.
|
|
76
|
+
- Do not edit files.
|
|
77
|
+
- Do not run destructive git commands.
|
|
78
|
+
- Do not include secrets or long raw diffs in the message.
|
|
79
|
+
- Keep the message clear and useful for humans.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Implement Plan
|
|
2
|
+
|
|
3
|
+
Implement the plan below. Do not change scope unless you ask first.
|
|
4
|
+
|
|
5
|
+
## Plan
|
|
6
|
+
|
|
7
|
+
{PLAN_CONTENT}
|
|
8
|
+
|
|
9
|
+
Or, if the plan is saved as a file, provide the path and read it first.
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Read the plan carefully.
|
|
14
|
+
2. Read the project files mentioned in the plan.
|
|
15
|
+
3. Briefly explain the implementation approach before editing.
|
|
16
|
+
4. Implement the steps one by one.
|
|
17
|
+
5. Keep changes small and reviewable.
|
|
18
|
+
6. Run tests, lint, or type checks if available.
|
|
19
|
+
7. Do not delete files or rewrite history without approval.
|
|
20
|
+
|
|
21
|
+
## Rules
|
|
22
|
+
|
|
23
|
+
- Follow the plan closely.
|
|
24
|
+
- If something is unclear or blocked, stop and ask.
|
|
25
|
+
- Do not guess important missing details.
|
|
26
|
+
- Prefer editing existing files when it fits the existing project structure.
|
|
27
|
+
- Create new files only when the plan clearly requires it.
|
|
28
|
+
- Match the project's existing style and conventions.
|
|
29
|
+
- Add or update tests for new behavior when appropriate.
|
|
30
|
+
- Run available checks: tests, lint, type check.
|
|
31
|
+
- Do not touch secrets, env files, lockfiles, or generated files unless the plan explicitly requires it and the user approves.
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
At the end, summarize:
|
|
36
|
+
|
|
37
|
+
- What was implemented
|
|
38
|
+
- Files changed
|
|
39
|
+
- Tests added or updated
|
|
40
|
+
- Commands run
|
|
41
|
+
- Anything still pending
|
package/prompts/init.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Initialize Repository Understanding
|
|
2
|
+
|
|
3
|
+
Initialize your understanding of this repository.
|
|
4
|
+
|
|
5
|
+
Do not edit files.
|
|
6
|
+
|
|
7
|
+
Your job is to inspect the project and produce a clear onboarding report for future work.
|
|
8
|
+
|
|
9
|
+
If the repository is large, inspect the most important files first and clearly mention what was not inspected.
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Read the most important project files first:
|
|
14
|
+
- README.md
|
|
15
|
+
- AGENTS.md
|
|
16
|
+
- package.json / pyproject.toml / go.mod / Cargo.toml / pom.xml / build.gradle
|
|
17
|
+
- CONTRIBUTING.md
|
|
18
|
+
- docs/
|
|
19
|
+
- .github/workflows/
|
|
20
|
+
- docker-compose.yml / Dockerfile
|
|
21
|
+
- existing test configuration
|
|
22
|
+
|
|
23
|
+
2. Identify the project structure:
|
|
24
|
+
- main application entry points
|
|
25
|
+
- important directories
|
|
26
|
+
- test locations
|
|
27
|
+
- config files
|
|
28
|
+
- generated/build output directories
|
|
29
|
+
- files that should be treated carefully
|
|
30
|
+
|
|
31
|
+
3. Detect the development workflow:
|
|
32
|
+
- install command
|
|
33
|
+
- dev command
|
|
34
|
+
- build command
|
|
35
|
+
- test command
|
|
36
|
+
- lint command
|
|
37
|
+
- typecheck command
|
|
38
|
+
- formatting command
|
|
39
|
+
|
|
40
|
+
4. Identify safety risks:
|
|
41
|
+
- secrets or env files
|
|
42
|
+
- deployment files
|
|
43
|
+
- database migrations
|
|
44
|
+
- production config
|
|
45
|
+
- generated files
|
|
46
|
+
- lockfiles
|
|
47
|
+
- destructive scripts
|
|
48
|
+
- commands that should require confirmation
|
|
49
|
+
|
|
50
|
+
5. Infer coding conventions:
|
|
51
|
+
- language/framework
|
|
52
|
+
- naming style
|
|
53
|
+
- error handling style
|
|
54
|
+
- testing style
|
|
55
|
+
- API conventions
|
|
56
|
+
- dependency management
|
|
57
|
+
|
|
58
|
+
## Output
|
|
59
|
+
|
|
60
|
+
Return a repository onboarding report with these sections:
|
|
61
|
+
|
|
62
|
+
# Repository Summary
|
|
63
|
+
|
|
64
|
+
Briefly explain what this project appears to do.
|
|
65
|
+
|
|
66
|
+
# Tech Stack
|
|
67
|
+
|
|
68
|
+
List the detected languages, frameworks, libraries, and tools.
|
|
69
|
+
|
|
70
|
+
# Project Map
|
|
71
|
+
|
|
72
|
+
Explain the important folders and files.
|
|
73
|
+
|
|
74
|
+
# Common Commands
|
|
75
|
+
|
|
76
|
+
List install, dev, build, test, lint, typecheck, and format commands if found.
|
|
77
|
+
|
|
78
|
+
# Safety Notes
|
|
79
|
+
|
|
80
|
+
List files, directories, and commands that should be treated carefully.
|
|
81
|
+
|
|
82
|
+
# Coding Conventions
|
|
83
|
+
|
|
84
|
+
Summarize the project’s apparent patterns.
|
|
85
|
+
|
|
86
|
+
# Recommended Agent Rules
|
|
87
|
+
|
|
88
|
+
Suggest repo-specific rules that should be added to AGENTS.md or team instructions.
|
|
89
|
+
|
|
90
|
+
# Open Questions
|
|
91
|
+
|
|
92
|
+
List anything unclear or missing.
|
|
93
|
+
|
|
94
|
+
# Inspection Notes
|
|
95
|
+
|
|
96
|
+
Mention important files or areas that were not inspected.
|
|
97
|
+
|
|
98
|
+
Do not modify the repository unless I explicitly ask.
|