@b0tts/template-dev-installer 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.
Files changed (34) hide show
  1. package/cli.mjs +129 -0
  2. package/files/.agents/skills/_explain-it-v1-disabled/SKILL.md +86 -0
  3. package/files/.agents/skills/close/SKILL.md +112 -0
  4. package/files/.agents/skills/closev2/REFERENCE.md +194 -0
  5. package/files/.agents/skills/closev2/SKILL.md +84 -0
  6. package/files/.agents/skills/create-nav-guide/SKILL.md +39 -0
  7. package/files/.agents/skills/docs-mcp/SKILL.md +91 -0
  8. package/files/.agents/skills/explain-it-v2/REFERENCE.md +213 -0
  9. package/files/.agents/skills/explain-it-v2/SKILL.md +133 -0
  10. package/files/.agents/skills/grill-me/SKILL.md +10 -0
  11. package/files/.agents/skills/grill-with-docs/ADR-FORMAT.md +47 -0
  12. package/files/.agents/skills/grill-with-docs/CONTEXT-FORMAT.md +63 -0
  13. package/files/.agents/skills/grill-with-docs/SKILL.md +88 -0
  14. package/files/.agents/skills/handoff/SKILL.md +34 -0
  15. package/files/.agents/skills/improve-codebase-architecture/DEEPENING.md +37 -0
  16. package/files/.agents/skills/improve-codebase-architecture/HTML-REPORT.md +123 -0
  17. package/files/.agents/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -0
  18. package/files/.agents/skills/improve-codebase-architecture/LANGUAGE.md +53 -0
  19. package/files/.agents/skills/improve-codebase-architecture/SKILL.md +81 -0
  20. package/files/.agents/skills/karpathy-guidelines/SKILL.md +0 -0
  21. package/files/.agents/skills/regenerate-minecraft-world/SKILL.md +46 -0
  22. package/files/.agents/skills/to-prd/SKILL.md +76 -0
  23. package/files/.agents/skills/tutorial/SKILL.md +43 -0
  24. package/files/.agents/skills/write-a-skill/SKILL.md +117 -0
  25. package/files/.agents/skills/zoom-out/SKILL.md +7 -0
  26. package/files/AGENTS.md +40 -0
  27. package/files/README.md +245 -0
  28. package/files/opencode/opencode.json +178 -0
  29. package/files/opencode/plugins/Notifications.js +66 -0
  30. package/files/opencode/settings.json +1 -0
  31. package/files/pi/extensions/context-tiers.ts +250 -0
  32. package/files/pi/mcp.json +12 -0
  33. package/files/pi/settings.json +13 -0
  34. package/package.json +23 -0
@@ -0,0 +1,250 @@
1
+ /**
2
+ * Context Tiers — 3-line custom footer with tiered context + cost colours.
3
+ *
4
+ * Layout:
5
+ * Line 1: /full/path/to/project
6
+ * Line 2: ↑tokens ↓tokens 62,000/200,000 (31%)
7
+ * Line 3: model-id (branch) $0.023 ext-status…
8
+ *
9
+ * Context numbers (line 2): 16 tiers — dim-gray → animated rainbow.
10
+ * Cost number (line 3): 18 tiers — dim-gray → copper→bronze→
11
+ * green→silver→teal→blue→purple→ruby→orange→gold→diamond◆→
12
+ * bright-gold✦→rainbow★.
13
+ *
14
+ * All non-tier text uses uniform ANSI-256 grays in the same colour
15
+ * space as the tier colours so everything sits on one visual plane.
16
+ *
17
+ * Unknown / post-compaction context → `???` (reverse video), no %.
18
+ */
19
+
20
+ import type { AssistantMessage } from "@earendil-works/pi-ai";
21
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
22
+ import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
23
+
24
+ // ── Number formatting ────────────────────────────────────────────────────────
25
+
26
+ function fmt(n: number): string {
27
+ return String(Math.floor(n)).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
28
+ }
29
+
30
+ // ── ANSI escape helpers ──────────────────────────────────────────────────────
31
+
32
+ const BOLD = "\x1b[1m";
33
+ const UNDERLINE = "\x1b[4m";
34
+ const REVERSE = "\x1b[7m";
35
+ const REV_OFF = "\x1b[27m";
36
+ const RESET = "\x1b[0m";
37
+
38
+ function fg(n: number): string { return `\x1b[38;5;${n}m`; }
39
+
40
+ /** Uniform ANSI-256 gray helpers — same colour-space as the tier colours */
41
+ const GRAY = {
42
+ path: fg(245), // medium — project directory
43
+ labels: fg(245), // medium — ↑ ↓ $ symbols
44
+ stats: fg(247), // lighter — input/output/cost numbers
45
+ pct: fg(245), // medium — (31%)
46
+ model: fg(242), // dim — model id, branch, ext statuses
47
+ };
48
+
49
+ // ── Tier definitions (16 tiers, absolute tokens) ─────────────────────────────
50
+
51
+ interface Tier {
52
+ max: number;
53
+ color: number;
54
+ bold?: boolean;
55
+ underline?: boolean;
56
+ sparkle?: boolean;
57
+ diamond?: boolean; // always-on ◆ (no flicker)
58
+ rainbow?: boolean;
59
+ }
60
+
61
+ const TIERS: Tier[] = [
62
+ { max: 1_000, color: 242 }, // 1: dim gray
63
+ { max: 3_000, color: 252 }, // 2: white
64
+ { max: 7_000, color: 249 }, // 3: light gray
65
+ { max: 15_000, color: 108 }, // 4: light green
66
+ { max: 30_000, color: 41 }, // 5: green
67
+ { max: 50_000, color: 43 }, // 6: teal
68
+ { max: 75_000, color: 51 }, // 7: cyan
69
+ { max: 100_000, color: 33 }, // 8: blue
70
+ { max: 200_000, color: 39 }, // 9: bright blue
71
+ { max: 500_000, color: 201 }, // 10: magenta
72
+ { max: 1_000_000, color: 93 }, // 11: purple
73
+ { max: 10_000_000, color: 208 }, // 12: orange
74
+ { max: 100_000_000, color: 202, bold: true }, // 13: amber bold
75
+ { max: 500_000_000, color: 220, bold: true, underline: true }, // 14: gold b+u
76
+ { max: 999_999_999, color: 226, bold: true, underline: true, // 15: bright gold ✦
77
+ sparkle: true },
78
+ { max: Infinity, rainbow: true, bold: true }, // 16: rainbow ★
79
+ ];
80
+
81
+ const RAINBOW = [196, 208, 220, 226, 46, 51, 39, 33, 93, 201];
82
+
83
+ // ── Cost tier definitions (18 tiers, $0 → $1 000 000) ────────────────────────
84
+
85
+ const COST_TIERS: Tier[] = [
86
+ { max: 0.01, color: 242 }, // 1: dim gray
87
+ { max: 0.05, color: 248 }, // 2: light gray
88
+ { max: 0.10, color: 252 }, // 3: white
89
+ { max: 0.25, color: 137 }, // 4: copper
90
+ { max: 0.50, color: 179 }, // 5: bronze
91
+ { max: 1.00, color: 143 }, // 6: sage green
92
+ { max: 2, color: 71 }, // 7: deep green
93
+ { max: 5, color: 35 }, // 8: bright green
94
+ { max: 10, color: 247 }, // 9: silver
95
+ { max: 25, color: 43 }, // 10: teal
96
+ { max: 50, color: 39 }, // 11: blue
97
+ { max: 100, color: 134 }, // 12: purple
98
+ { max: 500, color: 196 }, // 13: ruby red
99
+ { max: 1_000, color: 202, bold: true }, // 14: deep orange bold
100
+ { max: 10_000, color: 220, bold: true, underline: true }, // 15: gold b+u
101
+ { max: 100_000, color: 255, bold: true, underline: true, // 16: diamond white ◆
102
+ diamond: true },
103
+ { max: 999_999, color: 226, bold: true, underline: true, // 17: bright gold ✦
104
+ sparkle: true },
105
+ { max: Infinity, rainbow: true, bold: true }, // 18: rainbow ★
106
+ ];
107
+
108
+ // ── Context tier helpers ─────────────────────────────────────────────────────
109
+
110
+ function getCtxTier(n: number): Tier {
111
+ for (const t of TIERS) if (n <= t.max) return t;
112
+ return TIERS[TIERS.length - 1]!;
113
+ }
114
+
115
+ function styledCtx(n: number, tier: Tier, frame: number): string {
116
+ return applyTierStyle(fmt(n), tier, frame);
117
+ }
118
+
119
+ // ── Cost tier helpers ────────────────────────────────────────────────────────
120
+
121
+ function getCostTier(n: number): Tier {
122
+ for (const t of COST_TIERS) if (n <= t.max) return t;
123
+ return COST_TIERS[COST_TIERS.length - 1]!;
124
+ }
125
+
126
+ function styledCost(n: number, tier: Tier, frame: number): string {
127
+ return applyTierStyle(`$${n.toFixed(3)}`, tier, frame);
128
+ }
129
+
130
+ // ── Shared style application ─────────────────────────────────────────────────
131
+
132
+ function applyTierStyle(text: string, tier: Tier, frame: number): string {
133
+ let color: number;
134
+ let prefix = "";
135
+ let suffix = "";
136
+
137
+ if (tier.rainbow) {
138
+ color = RAINBOW[frame % RAINBOW.length]!;
139
+ suffix = " ★";
140
+ } else if (tier.sparkle && Math.random() > 0.5) {
141
+ color = tier.color;
142
+ prefix = "✦ ";
143
+ } else if (tier.diamond) {
144
+ color = tier.color;
145
+ prefix = "◆ ";
146
+ } else {
147
+ color = tier.color;
148
+ }
149
+
150
+ let style = fg(color);
151
+ if (tier.bold) style += BOLD;
152
+ if (tier.underline) style += UNDERLINE;
153
+
154
+ return `${style}${prefix}${text}${suffix}${RESET}`;
155
+ }
156
+
157
+ // ── Extension entry ──────────────────────────────────────────────────────────
158
+
159
+ export default function (pi: ExtensionAPI) {
160
+ pi.on("session_start", (_event, ctx) => {
161
+ let frame = 0;
162
+ let animTimer: ReturnType<typeof setInterval> | null = null;
163
+
164
+ ctx.ui.setFooter((tui, _theme, footerData) => {
165
+ if (!animTimer) {
166
+ animTimer = setInterval(() => { frame++; tui.requestRender(); }, 800);
167
+ }
168
+
169
+ const unsub = footerData.onBranchChange(() => tui.requestRender());
170
+
171
+ return {
172
+ dispose: () => {
173
+ unsub();
174
+ if (animTimer) { clearInterval(animTimer); animTimer = null; }
175
+ },
176
+ invalidate: () => {},
177
+
178
+ render(width: number): string[] {
179
+ // ── Line 1: project directory ─────────────────────────────────
180
+ const dirLine = `${GRAY.path}${process.cwd()}${RESET}`;
181
+
182
+ // ── Line 2: token stats + context usage ───────────────────────
183
+ let input = 0, output = 0, cost = 0;
184
+ for (const e of ctx.sessionManager.getBranch()) {
185
+ if (e.type === "message" && e.message.role === "assistant") {
186
+ const msg = e.message as AssistantMessage;
187
+ input += msg.usage.input;
188
+ output += msg.usage.output;
189
+ cost += msg.usage.cost.total;
190
+ }
191
+ }
192
+
193
+ const statsStr =
194
+ `${GRAY.labels}↑${GRAY.stats}${fmt(input)}` +
195
+ `${GRAY.labels} ↓${GRAY.stats}${fmt(output)}${RESET}`;
196
+
197
+ const cu = ctx.getContextUsage();
198
+ let ctxStr = "";
199
+
200
+ if (cu) {
201
+ const usedOk = cu.tokens != null;
202
+ const maxOk = cu.contextWindow > 0;
203
+
204
+ const usedStr = usedOk
205
+ ? styledCtx(cu.tokens!, getCtxTier(cu.tokens!), frame)
206
+ : `${REVERSE}???${REV_OFF}`;
207
+
208
+ const maxStr = maxOk
209
+ ? styledCtx(cu.contextWindow, getCtxTier(cu.contextWindow), frame)
210
+ : `${REVERSE}???${REV_OFF}`;
211
+
212
+ const slash = usedOk && maxOk ? "/" : " / ";
213
+
214
+ // Percentage: only show when both numbers are valid
215
+ const pctStr = (usedOk && maxOk && cu.percent != null)
216
+ ? ` ${GRAY.pct}(${cu.percent.toFixed(2)}%)${RESET}`
217
+ : "";
218
+
219
+ ctxStr = `${usedStr}${GRAY.stats}${slash}${maxStr}${pctStr}`;
220
+ }
221
+
222
+ const line2parts = [statsStr, ctxStr].filter(Boolean);
223
+ const line2 = line2parts.join(" ");
224
+
225
+ // ── Line 3: model + branch + cost + extension statuses ────────
226
+ const branch = footerData.getGitBranch();
227
+ const modelText = `${ctx.model?.id || "no-model"}${branch ? ` (${branch})` : ""}`;
228
+
229
+ const costSty = styledCost(cost, getCostTier(cost), frame);
230
+ const costText = `${costSty}`;
231
+
232
+ const statuses = footerData.getExtensionStatuses();
233
+ let statusText = "";
234
+ if (statuses.size > 0) {
235
+ statusText = " " + [...statuses.values()].join(" ");
236
+ }
237
+
238
+ const line3 = `${GRAY.model}${modelText} ${costText}${statusText}${RESET}`;
239
+
240
+ // ── Render ────────────────────────────────────────────────────
241
+ return [
242
+ truncateToWidth(dirLine, width),
243
+ truncateToWidth(line2, width),
244
+ truncateToWidth(line3, width),
245
+ ];
246
+ },
247
+ };
248
+ });
249
+ });
250
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "mcpServers": {
3
+ "context7": {
4
+ "transport": "streamable-http",
5
+ "url": "https://mcp.context7.com/mcp",
6
+ "headers": {
7
+ "CONTEXT7_API_KEY": "ctx7sk-YOUR_KEY_HERE"
8
+ },
9
+ "lifecycle": "eager"
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "lastChangelogVersion": "0.79.6",
3
+ "theme": "dark",
4
+ "defaultProvider": "deepseek",
5
+ "defaultModel": "deepseek-v4-pro",
6
+ "defaultThinkingLevel": "high",
7
+ "packages": [
8
+ "npm:pi-web-access",
9
+ "npm:pi-subagents",
10
+ "npm:pi-mcp-extension"
11
+ ],
12
+ "hideThinkingBlock": false
13
+ }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@b0tts/template-dev-installer",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Interactive installer for the DevelopmentTemplate — pick Skills, OpenCode, Pi, or install everything at once.",
6
+ "bin": {
7
+ "template-dev-installer": "./cli.mjs"
8
+ },
9
+ "files": [
10
+ "cli.mjs",
11
+ "files/"
12
+ ],
13
+ "dependencies": {
14
+ "@inquirer/prompts": "^5.0.0"
15
+ },
16
+ "keywords": [
17
+ "template",
18
+ "installer",
19
+ "dev-setup",
20
+ "scaffold"
21
+ ],
22
+ "license": "MIT"
23
+ }