xtrm-tools 0.5.45 → 0.5.46

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/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtrm-cli",
3
- "version": "0.5.45",
3
+ "version": "0.5.46",
4
4
  "description": "Claude Code tools installer (skills, hooks, MCP servers)",
5
5
  "main": "./dist/index.js",
6
6
  "type": "module",
@@ -234,19 +234,22 @@ export default function (pi: ExtensionAPI) {
234
234
  if (!closedIssueId) return;
235
235
 
236
236
  memoryGateFired = true;
237
- pi.sendUserMessage(
238
- `🧠 Memory gate: claim \`${closedIssueId}\` was closed this session.\n` +
239
- `For each candidate insight, check ALL 4:\n` +
240
- ` 1. Hard to rediscover from code/docs?\n` +
241
- ` 2. Not obvious from the current implementation?\n` +
242
- ` 3. Will affect a future decision?\n` +
243
- ` 4. Still relevant in ~14 days?\n` +
244
- `KEEP (all 4 yes) \`bd remember "<insight>"\`\n` +
245
- `SKIP examples: file maps, flag inventories, per-issue summaries,\n` +
246
- ` wording tweaks, facts obvious from reading the source.\n` +
247
- `KEEP: \`bd kv set "memory-gate-done:${sessionId}" "saved: <key>"\`\n` +
248
- `SKIP: \`bd kv set "memory-gate-done:${sessionId}" "nothing novel — <one-line reason>"\``,
249
- );
237
+ if (ctx.hasUI) {
238
+ ctx.ui.notify(
239
+ `🧠 Memory gate: claim \`${closedIssueId}\` was closed this session.\n` +
240
+ `For each candidate insight, check ALL 4:\n` +
241
+ ` 1. Hard to rediscover from code/docs?\n` +
242
+ ` 2. Not obvious from the current implementation?\n` +
243
+ ` 3. Will affect a future decision?\n` +
244
+ ` 4. Still relevant in ~14 days?\n` +
245
+ `KEEP (all 4 yes) \`bd remember "<insight>"\`\n` +
246
+ `SKIP examples: file maps, flag inventories, per-issue summaries,\n` +
247
+ ` wording tweaks, facts obvious from reading the source.\n` +
248
+ `KEEP: \`bd kv set "memory-gate-done:${sessionId}" "saved: <key>"\`\n` +
249
+ `SKIP: \`bd kv set "memory-gate-done:${sessionId}" "nothing novel — <one-line reason>"\``,
250
+ "info",
251
+ );
252
+ }
250
253
  };
251
254
 
252
255
  pi.on("agent_end", async (_event, ctx) => {
@@ -264,12 +264,11 @@ export default function (pi: ExtensionAPI) {
264
264
 
265
265
  const BOLD = "\x1b[1m";
266
266
  const BOLD_OFF = "\x1b[22m";
267
- const brand = `${BOLD}${theme.fg("accent", "XTRM")}${BOLD_OFF}`;
267
+ const brand = `${BOLD}${theme.fg("dim", "XTRM")}${BOLD_OFF}`;
268
268
 
269
269
  const usage = ctx.getContextUsage();
270
270
  const pct = usage?.percent ?? 0;
271
- const pctColor = pct > 75 ? "error" : pct > 50 ? "warning" : "success";
272
- const usageStr = theme.fg(pctColor, `[${pct.toFixed(0)}%]`);
271
+ const usageStr = theme.fg("dim", `[${pct.toFixed(0)}%]`);
273
272
 
274
273
  const modelId = ctx.model?.id || "no-model";
275
274
  const modelStr = `${modelId} ${usageStr}`;
@@ -0,0 +1,331 @@
1
+ /**
2
+ * XTRM UI Extension
3
+ *
4
+ * Wraps pi-dex functionality with XTRM-specific preferences:
5
+ * - Uses pi-dex themes and header
6
+ * - Disables pi-dex footer (let custom-footer handle it)
7
+ * - Provides /xtrm-ui commands for theme/density switching
8
+ *
9
+ * This eliminates the race condition between pi-dex's footer and
10
+ * XTRM's custom-footer extension.
11
+ */
12
+
13
+ import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
14
+ import { Box, Text, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
15
+ import { basename } from "node:path";
16
+
17
+ // ============================================================================
18
+ // Types
19
+ // ============================================================================
20
+
21
+ export type XtrmThemeName = "pidex-dark" | "pidex-light";
22
+ export type XtrmDensity = "compact" | "comfortable";
23
+
24
+ export interface XtrmUiPrefs {
25
+ themeName: XtrmThemeName;
26
+ density: XtrmDensity;
27
+ showHeader: boolean;
28
+ compactTools: boolean;
29
+ showFooter: boolean; // Our key addition - when false, skip setFooter()
30
+ }
31
+
32
+ // ============================================================================
33
+ // Defaults
34
+ // ============================================================================
35
+
36
+ export const XTRM_UI_PREFS_ENTRY = "xtrm-ui-prefs";
37
+
38
+ export const DEFAULT_PREFS: XtrmUiPrefs = {
39
+ themeName: "pidex-light",
40
+ density: "compact",
41
+ showHeader: true,
42
+ compactTools: true,
43
+ showFooter: false, // XTRM: disable pi-dex footer, use custom-footer
44
+ };
45
+
46
+ // ============================================================================
47
+ // Preferences
48
+ // ============================================================================
49
+
50
+ type MaybeCustomEntry = {
51
+ type?: string;
52
+ customType?: string;
53
+ data?: unknown;
54
+ };
55
+
56
+ function normalizePrefs(input: unknown): XtrmUiPrefs {
57
+ if (!input || typeof input !== "object") return { ...DEFAULT_PREFS };
58
+ const source = input as Partial<XtrmUiPrefs>;
59
+ return {
60
+ themeName: source.themeName === "pidex-dark" ? "pidex-dark" : "pidex-light",
61
+ density: source.density === "comfortable" ? "comfortable" : "compact",
62
+ showHeader: source.showHeader ?? DEFAULT_PREFS.showHeader,
63
+ compactTools: source.compactTools ?? DEFAULT_PREFS.compactTools,
64
+ showFooter: source.showFooter ?? DEFAULT_PREFS.showFooter,
65
+ };
66
+ }
67
+
68
+ function loadPrefs(entries: ReadonlyArray<MaybeCustomEntry>): XtrmUiPrefs {
69
+ for (let i = entries.length - 1; i >= 0; i--) {
70
+ const entry = entries[i];
71
+ if (entry?.type === "custom" && entry.customType === XTRM_UI_PREFS_ENTRY) {
72
+ return normalizePrefs(entry.data);
73
+ }
74
+ }
75
+ return { ...DEFAULT_PREFS };
76
+ }
77
+
78
+ function persistPrefs(pi: ExtensionAPI, prefs: XtrmUiPrefs): void {
79
+ pi.appendEntry(XTRM_UI_PREFS_ENTRY, prefs);
80
+ }
81
+
82
+ // ============================================================================
83
+ // Chrome Application
84
+ // ============================================================================
85
+
86
+ function fitVisible(text: string, width: number): string {
87
+ const truncated = truncateToWidth(text, width);
88
+ return truncated + " ".repeat(Math.max(0, width - visibleWidth(truncated)));
89
+ }
90
+
91
+ function applyXtrmChrome(
92
+ ctx: ExtensionContext,
93
+ prefs: XtrmUiPrefs,
94
+ getThinkingLevel: () => string
95
+ ): void {
96
+ // Theme
97
+ ctx.ui.setTheme(prefs.themeName);
98
+
99
+ // Tool expansion
100
+ ctx.ui.setToolsExpanded(!prefs.compactTools);
101
+
102
+ // Header (optional)
103
+ if (prefs.showHeader) {
104
+ ctx.ui.setHeader((_tui, theme) => ({
105
+ invalidate() {},
106
+ render(width: number): string[] {
107
+ const boxWidth = width >= 54 ? 50 : Math.max(24, width);
108
+ const model = ctx.model?.id ?? "no-model";
109
+ const thinking = getThinkingLevel();
110
+ const border = (text: string) => theme.fg("borderAccent", text);
111
+ const leftPad = "";
112
+
113
+ const top = leftPad + border(`╭${"─".repeat(Math.max(0, boxWidth - 2))}╮`);
114
+ const line1 =
115
+ leftPad +
116
+ border("│") +
117
+ fitVisible(
118
+ ` ${theme.fg("dim", ">_")} ${theme.bold("XTRM")} ${theme.fg("dim", `(v1.0.0)`)}`,
119
+ boxWidth - 2
120
+ ) +
121
+ border("│");
122
+ const gap = leftPad + border("│") + fitVisible("", boxWidth - 2) + border("│");
123
+ const line2 =
124
+ leftPad +
125
+ border("│") +
126
+ fitVisible(
127
+ ` ${theme.fg("dim", "model:".padEnd(11))}${model} ${thinking}${theme.fg("accent", " /model")}${theme.fg("dim", " to change")}`,
128
+ boxWidth - 2
129
+ ) +
130
+ border("│");
131
+ const line3 =
132
+ leftPad +
133
+ border("│") +
134
+ fitVisible(
135
+ ` ${theme.fg("dim", "directory:".padEnd(11))}${basename(ctx.cwd)}`,
136
+ boxWidth - 2
137
+ ) +
138
+ border("│");
139
+ const bottom = leftPad + border(`╰${"─".repeat(Math.max(0, boxWidth - 2))}╯`);
140
+
141
+ return [top, line1, gap, line2, line3, bottom];
142
+ },
143
+ }));
144
+ } else {
145
+ ctx.ui.setHeader(undefined);
146
+ }
147
+
148
+ // Footer - ONLY if showFooter is true (default false for XTRM)
149
+ // This is the key difference from pi-dex - we let custom-footer handle it
150
+ if (prefs.showFooter) {
151
+ ctx.ui.setFooter((tui, theme, footerData) => {
152
+ const unsubscribe = footerData.onBranchChange(() => tui.requestRender());
153
+ return {
154
+ dispose: unsubscribe,
155
+ invalidate() {},
156
+ render(width: number): string[] {
157
+ const modelId = ctx.model?.id ?? "no-model";
158
+ const thinking = getThinkingLevel();
159
+ const contextUsage = ctx.getContextUsage();
160
+ const leftPct = contextUsage?.percent != null ? `${100 - Math.round(contextUsage.percent)}% left` : undefined;
161
+ const line = theme.fg(
162
+ "dim",
163
+ [`${modelId} ${thinking}`, leftPct, basename(ctx.cwd)]
164
+ .filter(Boolean)
165
+ .join(" · ")
166
+ );
167
+ return [truncateToWidth(line, width)];
168
+ },
169
+ };
170
+ });
171
+ }
172
+ // If showFooter is false, we do NOT call setFooter - custom-footer will handle it
173
+ }
174
+
175
+ // ============================================================================
176
+ // Commands
177
+ // ============================================================================
178
+
179
+ function sendInfoMessage(pi: ExtensionAPI, title: string, content: string): void {
180
+ pi.sendMessage({
181
+ customType: "xtrm-ui-info",
182
+ content,
183
+ display: true,
184
+ details: { title },
185
+ });
186
+ }
187
+
188
+ function parseThemeArg(arg: string): XtrmThemeName | undefined {
189
+ const normalized = arg.trim().toLowerCase();
190
+ if (normalized === "dark" || normalized === "pidex-dark") return "pidex-dark";
191
+ if (normalized === "light" || normalized === "pidex-light") return "pidex-light";
192
+ return undefined;
193
+ }
194
+
195
+ function parseDensityArg(arg: string): XtrmDensity | undefined {
196
+ const normalized = arg.trim().toLowerCase();
197
+ if (normalized === "compact") return "compact";
198
+ if (normalized === "comfortable" || normalized === "normal") return "comfortable";
199
+ return undefined;
200
+ }
201
+
202
+ function registerCommands(pi: ExtensionAPI, getPrefs: () => XtrmUiPrefs, setPrefs: (p: XtrmUiPrefs) => void) {
203
+ pi.registerMessageRenderer("xtrm-ui-info", (message, _options, theme) => {
204
+ const title = (message.details as { title?: string } | undefined)?.title ?? "XTRM UI";
205
+ const box = new Box(1, 1, (text) => theme.bg("customMessageBg", text));
206
+ box.addChild(new Text(theme.fg("customMessageLabel", theme.bold(title)), 0, 0));
207
+ box.addChild(new Text(theme.fg("customMessageText", String(message.content ?? "")), 0, 0));
208
+ return box;
209
+ });
210
+
211
+ pi.registerCommand("xtrm-ui", {
212
+ description: "Show XTRM UI status and active preferences",
213
+ handler: async (_args, ctx) => {
214
+ const prefs = getPrefs();
215
+ const contextUsage = ctx.getContextUsage();
216
+ const lines = [
217
+ `Theme: ${prefs.themeName}`,
218
+ `Density: ${prefs.density}`,
219
+ `Compact tools: ${prefs.compactTools ? "on" : "off"}`,
220
+ `Show header: ${prefs.showHeader ? "yes" : "no"}`,
221
+ `Show footer: ${prefs.showFooter ? "yes" : "no"} (custom-footer handles this)`,
222
+ `Model: ${ctx.model?.id ?? "none"}`,
223
+ `Context: ${contextUsage?.tokens ?? "unknown"}/${contextUsage?.contextWindow ?? "unknown"}`,
224
+ ];
225
+ sendInfoMessage(pi, "XTRM UI status", lines.join("\\n"));
226
+ },
227
+ });
228
+
229
+ pi.registerCommand("xtrm-ui-theme", {
230
+ description: "Switch XTRM UI theme: dark|light",
231
+ getArgumentCompletions: (prefix) => {
232
+ const values = ["dark", "light"].filter((item) => item.startsWith(prefix));
233
+ return values.length > 0 ? values.map((value) => ({ value, label: value })) : null;
234
+ },
235
+ handler: async (args, ctx) => {
236
+ const themeName = parseThemeArg(args);
237
+ if (!themeName) {
238
+ ctx.ui.notify("Usage: /xtrm-ui-theme dark|light", "warning");
239
+ return;
240
+ }
241
+ const prefs = { ...getPrefs(), themeName };
242
+ setPrefs(prefs);
243
+ persistPrefs(pi, prefs);
244
+ applyXtrmChrome(ctx, prefs, () => "standard");
245
+ ctx.ui.notify(`XTRM UI theme set to ${themeName}`, "info");
246
+ },
247
+ });
248
+
249
+ pi.registerCommand("xtrm-ui-density", {
250
+ description: "Switch XTRM UI density: compact|comfortable",
251
+ getArgumentCompletions: (prefix) => {
252
+ const values = ["compact", "comfortable"].filter((item) => item.startsWith(prefix));
253
+ return values.length > 0 ? values.map((value) => ({ value, label: value })) : null;
254
+ },
255
+ handler: async (args, ctx) => {
256
+ const density = parseDensityArg(args);
257
+ if (!density) {
258
+ ctx.ui.notify("Usage: /xtrm-ui-density compact|comfortable", "warning");
259
+ return;
260
+ }
261
+ const prefs = { ...getPrefs(), density };
262
+ setPrefs(prefs);
263
+ persistPrefs(pi, prefs);
264
+ applyXtrmChrome(ctx, prefs, () => "standard");
265
+ ctx.ui.notify(`XTRM UI density set to ${density}`, "info");
266
+ },
267
+ });
268
+
269
+ pi.registerCommand("xtrm-ui-header", {
270
+ description: "Toggle XTRM UI header: on|off",
271
+ getArgumentCompletions: (prefix) => {
272
+ const values = ["on", "off"].filter((item) => item.startsWith(prefix));
273
+ return values.length > 0 ? values.map((value) => ({ value, label: value })) : null;
274
+ },
275
+ handler: async (args, ctx) => {
276
+ const showHeader = args.trim().toLowerCase() === "on";
277
+ const prefs = { ...getPrefs(), showHeader };
278
+ setPrefs(prefs);
279
+ persistPrefs(pi, prefs);
280
+ applyXtrmChrome(ctx, prefs, () => "standard");
281
+ ctx.ui.notify(`XTRM UI header ${showHeader ? "enabled" : "disabled"}`, "info");
282
+ },
283
+ });
284
+
285
+ pi.registerCommand("xtrm-ui-reset", {
286
+ description: "Restore XTRM UI defaults",
287
+ handler: async (_args, ctx) => {
288
+ const prefs = { ...DEFAULT_PREFS };
289
+ setPrefs(prefs);
290
+ persistPrefs(pi, prefs);
291
+ applyXtrmChrome(ctx, prefs, () => "standard");
292
+ ctx.ui.notify("XTRM UI reset to defaults", "info");
293
+ },
294
+ });
295
+ }
296
+
297
+ // ============================================================================
298
+ // Main Extension
299
+ // ============================================================================
300
+
301
+ export default function xtrmUiExtension(pi: ExtensionAPI): void {
302
+ let prefs: XtrmUiPrefs = { ...DEFAULT_PREFS };
303
+
304
+ const getPrefs = () => prefs;
305
+ const setPrefs = (p: XtrmUiPrefs) => { prefs = p; };
306
+
307
+ registerCommands(pi, getPrefs, setPrefs);
308
+
309
+ const refresh = (ctx: ExtensionContext) => {
310
+ applyXtrmChrome(ctx, prefs, () => "standard");
311
+ };
312
+
313
+ pi.on("session_start", async (_event, ctx) => {
314
+ prefs = loadPrefs(
315
+ ctx.sessionManager.getEntries() as Array<MaybeCustomEntry>
316
+ );
317
+ refresh(ctx);
318
+ });
319
+
320
+ pi.on("session_switch", async (_event, ctx) => {
321
+ refresh(ctx);
322
+ });
323
+
324
+ pi.on("session_fork", async (_event, ctx) => {
325
+ refresh(ctx);
326
+ });
327
+
328
+ pi.on("model_select", async (_event, ctx) => {
329
+ refresh(ctx);
330
+ });
331
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "xtrm-ui",
3
+ "version": "1.0.0",
4
+ "description": "XTRM UI: pi-dex theme/header + custom XTRM footer",
5
+ "license": "MIT",
6
+ "pi": {
7
+ "extensions": ["./index.ts"],
8
+ "themes": ["./themes"]
9
+ }
10
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "pidex-dark",
4
+ "vars": {
5
+ "accentBlue": "#b8d3ff",
6
+ "accentCyan": "#b8d3ff",
7
+ "accentTeal": "#c7d2e0",
8
+ "successGreen": "#9fd59f",
9
+ "errorRed": "#ff9a9a",
10
+ "warningAmber": "#d2b48c",
11
+ "surface": "#000000",
12
+ "surfaceAlt": "#111111",
13
+ "surfaceMuted": "#1a1a1a",
14
+ "surfaceUser": "#1f1f1f",
15
+ "surfaceCustom": "#161616",
16
+ "gray": "#a7a7a7",
17
+ "dimGray": "#8a8a8a",
18
+ "borderGray": "#666666",
19
+ "borderBright": "#9a9a9a"
20
+ },
21
+ "colors": {
22
+ "accent": "accentBlue",
23
+ "border": "borderGray",
24
+ "borderAccent": "borderBright",
25
+ "borderMuted": "borderGray",
26
+ "success": "successGreen",
27
+ "error": "errorRed",
28
+ "warning": "warningAmber",
29
+ "muted": "gray",
30
+ "dim": "dimGray",
31
+ "text": "",
32
+ "thinkingText": "gray",
33
+
34
+ "selectedBg": "surfaceMuted",
35
+ "userMessageBg": "surfaceUser",
36
+ "userMessageText": "",
37
+ "customMessageBg": "surfaceCustom",
38
+ "customMessageText": "",
39
+ "customMessageLabel": "accentBlue",
40
+ "toolPendingBg": "surfaceAlt",
41
+ "toolSuccessBg": "surfaceAlt",
42
+ "toolErrorBg": "surfaceAlt",
43
+ "toolTitle": "",
44
+ "toolOutput": "gray",
45
+
46
+ "mdHeading": "warningAmber",
47
+ "mdLink": "accentBlue",
48
+ "mdLinkUrl": "dimGray",
49
+ "mdCode": "accentCyan",
50
+ "mdCodeBlock": "gray",
51
+ "mdCodeBlockBorder": "borderGray",
52
+ "mdQuote": "gray",
53
+ "mdQuoteBorder": "borderGray",
54
+ "mdHr": "borderGray",
55
+ "mdListBullet": "accentTeal",
56
+
57
+ "toolDiffAdded": "successGreen",
58
+ "toolDiffRemoved": "errorRed",
59
+ "toolDiffContext": "gray",
60
+
61
+ "syntaxComment": "#6b7280",
62
+ "syntaxKeyword": "#7aa2f7",
63
+ "syntaxFunction": "#c0caf5",
64
+ "syntaxVariable": "#a9b1d6",
65
+ "syntaxString": "#9ece6a",
66
+ "syntaxNumber": "#ff9e64",
67
+ "syntaxType": "#73daca",
68
+ "syntaxOperator": "#c0caf5",
69
+ "syntaxPunctuation": "#8f9bb3",
70
+
71
+ "thinkingOff": "borderGray",
72
+ "thinkingMinimal": "#707070",
73
+ "thinkingLow": "#7a7a7a",
74
+ "thinkingMedium": "#858585",
75
+ "thinkingHigh": "#8f8f8f",
76
+ "thinkingXhigh": "#999999",
77
+
78
+ "bashMode": "accentTeal"
79
+ },
80
+ "export": {
81
+ "pageBg": "#12161d",
82
+ "cardBg": "#171b22",
83
+ "infoBg": "#28230f"
84
+ }
85
+ }
@@ -0,0 +1,85 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/badlogic/pi-mono/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3
+ "name": "pidex-light",
4
+ "vars": {
5
+ "accentBlue": "#44546a",
6
+ "accentCyan": "#5f6b7a",
7
+ "accentTeal": "#5f6b7a",
8
+ "successGreen": "#587558",
9
+ "errorRed": "#a85f5f",
10
+ "warningAmber": "#8e7348",
11
+ "surface": "#ffffff",
12
+ "surfaceAlt": "#f1f1f1",
13
+ "surfaceMuted": "#e6e6e6",
14
+ "surfaceUser": "#f0f0f0",
15
+ "surfaceCustom": "#f5f5f5",
16
+ "gray": "#5f5f5f",
17
+ "dimGray": "#7a7a7a",
18
+ "borderGray": "#b9b9b9",
19
+ "borderBright": "#9f9f9f"
20
+ },
21
+ "colors": {
22
+ "accent": "accentBlue",
23
+ "border": "borderGray",
24
+ "borderAccent": "borderBright",
25
+ "borderMuted": "borderGray",
26
+ "success": "successGreen",
27
+ "error": "errorRed",
28
+ "warning": "warningAmber",
29
+ "muted": "gray",
30
+ "dim": "dimGray",
31
+ "text": "",
32
+ "thinkingText": "gray",
33
+
34
+ "selectedBg": "surfaceMuted",
35
+ "userMessageBg": "surfaceUser",
36
+ "userMessageText": "",
37
+ "customMessageBg": "surfaceCustom",
38
+ "customMessageText": "",
39
+ "customMessageLabel": "accentBlue",
40
+ "toolPendingBg": "surfaceAlt",
41
+ "toolSuccessBg": "surfaceAlt",
42
+ "toolErrorBg": "surfaceAlt",
43
+ "toolTitle": "",
44
+ "toolOutput": "gray",
45
+
46
+ "mdHeading": "warningAmber",
47
+ "mdLink": "accentBlue",
48
+ "mdLinkUrl": "dimGray",
49
+ "mdCode": "accentCyan",
50
+ "mdCodeBlock": "gray",
51
+ "mdCodeBlockBorder": "borderGray",
52
+ "mdQuote": "gray",
53
+ "mdQuoteBorder": "borderGray",
54
+ "mdHr": "borderGray",
55
+ "mdListBullet": "accentTeal",
56
+
57
+ "toolDiffAdded": "successGreen",
58
+ "toolDiffRemoved": "errorRed",
59
+ "toolDiffContext": "gray",
60
+
61
+ "syntaxComment": "#6b7280",
62
+ "syntaxKeyword": "#3569c8",
63
+ "syntaxFunction": "#3b4351",
64
+ "syntaxVariable": "#364152",
65
+ "syntaxString": "#3f7d3d",
66
+ "syntaxNumber": "#b06500",
67
+ "syntaxType": "#2c7a7b",
68
+ "syntaxOperator": "#3b4351",
69
+ "syntaxPunctuation": "#55606f",
70
+
71
+ "thinkingOff": "borderGray",
72
+ "thinkingMinimal": "#9d9d9d",
73
+ "thinkingLow": "#979797",
74
+ "thinkingMedium": "#919191",
75
+ "thinkingHigh": "#8b8b8b",
76
+ "thinkingXhigh": "#858585",
77
+
78
+ "bashMode": "accentTeal"
79
+ },
80
+ "export": {
81
+ "pageBg": "#f5f7fa",
82
+ "cardBg": "#ffffff",
83
+ "infoBg": "#fff5e6"
84
+ }
85
+ }
@@ -34,7 +34,6 @@
34
34
  }
35
35
  ],
36
36
  "packages": [
37
- "npm:pi-dex",
38
37
  "npm:pi-gitnexus",
39
38
  "npm:pi-serena-tools",
40
39
  "npm:lsp-pi",
@@ -1,4 +1,14 @@
1
1
  {
2
- "hashes": {},
3
- "mappings": {}
2
+ "hashes": {
3
+ "/home/dawid/projects/specialists/tsconfig.json": "84f37aa64b949b7aaba41974cb6137341a36730b7d3e174803cb9289eae1e7c7"
4
+ },
5
+ "mappings": {
6
+ "src/**/*": {
7
+ "configPath": "/home/dawid/projects/specialists/tsconfig.json",
8
+ "excludes": [
9
+ "node_modules",
10
+ "dist"
11
+ ]
12
+ }
13
+ }
4
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtrm-tools",
3
- "version": "0.5.45",
3
+ "version": "0.5.46",
4
4
  "description": "Claude Code tools installer (skills, hooks, MCP servers)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtrm-tools",
3
- "version": "0.5.45",
3
+ "version": "0.5.46",
4
4
  "description": "xtrm-tools: dual-runtime workflow enforcement (Claude Code + Pi) — hooks, extensions, skills, and MCP servers",
5
5
  "author": {
6
6
  "name": "jaggers"
@@ -1,4 +1,14 @@
1
1
  {
2
- "hashes": {},
3
- "mappings": {}
2
+ "hashes": {
3
+ "/home/dawid/projects/specialists/tsconfig.json": "84f37aa64b949b7aaba41974cb6137341a36730b7d3e174803cb9289eae1e7c7"
4
+ },
5
+ "mappings": {
6
+ "src/**/*": {
7
+ "configPath": "/home/dawid/projects/specialists/tsconfig.json",
8
+ "excludes": [
9
+ "node_modules",
10
+ "dist"
11
+ ]
12
+ }
13
+ }
4
14
  }