xtrm-tools 0.7.7 → 0.7.10

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 (123) hide show
  1. package/.xtrm/config/hooks.json +0 -3
  2. package/.xtrm/registry.json +537 -565
  3. package/.xtrm/skills/default/gitnexus-cli/SKILL.md +82 -0
  4. package/.xtrm/skills/default/gitnexus-exploring/SKILL.md +78 -0
  5. package/.xtrm/skills/default/gitnexus-guide/SKILL.md +64 -0
  6. package/.xtrm/skills/default/init-session/SKILL.md +3 -0
  7. package/.xtrm/skills/default/last30days/SKILL.md +1 -1
  8. package/.xtrm/skills/default/last30days/scripts/lib/youtube_yt.py +59 -40
  9. package/.xtrm/skills/default/sync-docs/references/doc-structure.md +1 -1
  10. package/.xtrm/skills/default/sync-docs/references/schema.md +1 -1
  11. package/.xtrm/skills/default/sync-docs/scripts/doc_structure_analyzer.py +2 -2
  12. package/.xtrm/skills/default/using-specialists/SKILL.md +346 -138
  13. package/.xtrm/skills/default/using-specialists/SKILL.safe.md +1082 -0
  14. package/.xtrm/skills/default/using-specialists/SKILL.ultra.md +1082 -0
  15. package/.xtrm/skills/default/vaultctl/SKILL.md +150 -0
  16. package/CHANGELOG.md +4 -4
  17. package/cli/dist/index.cjs +328 -192
  18. package/cli/dist/index.cjs.map +1 -1
  19. package/cli/package.json +1 -1
  20. package/package.json +8 -8
  21. package/packages/pi-extensions/MIGRATION_NOTES.md +39 -0
  22. package/packages/pi-extensions/README.md +43 -0
  23. package/packages/pi-extensions/extensions/README.md +5 -0
  24. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/beads/index.ts +1 -1
  25. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/beads/package.json +1 -4
  26. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/custom-footer/index.ts +1 -1
  27. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/custom-footer/package.json +1 -4
  28. package/packages/pi-extensions/extensions/custom-provider-qwen-cli/package.json +16 -0
  29. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/pi-serena-compact/package.json +9 -2
  30. package/{.xtrm/ext-src → packages/pi-extensions/extensions}/quality-gates/index.ts +1 -1
  31. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/quality-gates/package.json +1 -4
  32. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/service-skills/index.ts +1 -1
  33. package/{.xtrm/ext-src → packages/pi-extensions/extensions}/service-skills/package.json +1 -4
  34. package/{.xtrm/ext-src → packages/pi-extensions/extensions}/session-flow/index.ts +1 -1
  35. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/session-flow/package.json +1 -4
  36. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/xtrm-loader/index.ts +1 -1
  37. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/xtrm-loader/package.json +1 -4
  38. package/{.xtrm/config/pi → packages/pi-extensions}/extensions/xtrm-ui/index.ts +1 -1
  39. package/packages/pi-extensions/package.json +46 -0
  40. package/packages/pi-extensions/src/core/README.md +9 -0
  41. package/{.xtrm/ext-src/core/lib.ts → packages/pi-extensions/src/core/index.ts} +3 -1
  42. package/packages/pi-extensions/src/extensions/auto-session-name.ts +3 -0
  43. package/packages/pi-extensions/src/extensions/auto-update.ts +3 -0
  44. package/packages/pi-extensions/src/extensions/beads.ts +3 -0
  45. package/packages/pi-extensions/src/extensions/compact-header.ts +3 -0
  46. package/packages/pi-extensions/src/extensions/custom-footer.ts +3 -0
  47. package/packages/pi-extensions/src/extensions/custom-provider-qwen-cli.ts +3 -0
  48. package/packages/pi-extensions/src/extensions/git-checkpoint.ts +3 -0
  49. package/packages/pi-extensions/src/extensions/lsp-bootstrap.ts +3 -0
  50. package/packages/pi-extensions/src/extensions/pi-serena-compact.ts +3 -0
  51. package/packages/pi-extensions/src/extensions/quality-gates.ts +3 -0
  52. package/packages/pi-extensions/src/extensions/service-skills.ts +3 -0
  53. package/packages/pi-extensions/src/extensions/session-flow.ts +3 -0
  54. package/packages/pi-extensions/src/extensions/xtrm-loader.ts +3 -0
  55. package/packages/pi-extensions/src/extensions/xtrm-ui.ts +3 -0
  56. package/packages/pi-extensions/src/index.ts +9 -0
  57. package/packages/pi-extensions/src/registry.ts +52 -0
  58. package/packages/pi-extensions/src/shared/index.ts +1 -0
  59. package/packages/pi-extensions/src/shared/legacy-path-map.ts +23 -0
  60. package/.xtrm/config/pi/extensions/core/package.json +0 -18
  61. package/.xtrm/config/pi/extensions/custom-provider-qwen-cli/package.json +0 -1
  62. package/.xtrm/config/pi/extensions/quality-gates/index.ts +0 -66
  63. package/.xtrm/config/pi/extensions/service-skills/package.json +0 -19
  64. package/.xtrm/config/pi/extensions/session-flow/index.ts +0 -96
  65. package/.xtrm/config/pi/extensions/xtrm-ui/themes/pidex-dark.json +0 -89
  66. package/.xtrm/config/pi/extensions/xtrm-ui/themes/pidex-light.json +0 -89
  67. package/.xtrm/ext-src/auto-session-name/index.ts +0 -29
  68. package/.xtrm/ext-src/auto-session-name/package.json +0 -16
  69. package/.xtrm/ext-src/auto-update/index.ts +0 -71
  70. package/.xtrm/ext-src/auto-update/package.json +0 -16
  71. package/.xtrm/ext-src/beads/index.ts +0 -232
  72. package/.xtrm/ext-src/beads/package.json +0 -19
  73. package/.xtrm/ext-src/compact-header/index.ts +0 -69
  74. package/.xtrm/ext-src/compact-header/package.json +0 -16
  75. package/.xtrm/ext-src/core/adapter.ts +0 -52
  76. package/.xtrm/ext-src/core/guard-rules.ts +0 -100
  77. package/.xtrm/ext-src/core/logger.ts +0 -45
  78. package/.xtrm/ext-src/core/package.json +0 -18
  79. package/.xtrm/ext-src/core/runner.ts +0 -71
  80. package/.xtrm/ext-src/core/session-state.ts +0 -59
  81. package/.xtrm/ext-src/custom-footer/index.ts +0 -398
  82. package/.xtrm/ext-src/custom-footer/package.json +0 -19
  83. package/.xtrm/ext-src/custom-provider-qwen-cli/index.ts +0 -363
  84. package/.xtrm/ext-src/custom-provider-qwen-cli/package.json +0 -1
  85. package/.xtrm/ext-src/git-checkpoint/index.ts +0 -53
  86. package/.xtrm/ext-src/git-checkpoint/package.json +0 -16
  87. package/.xtrm/ext-src/lsp-bootstrap/index.ts +0 -134
  88. package/.xtrm/ext-src/lsp-bootstrap/package.json +0 -17
  89. package/.xtrm/ext-src/pi-serena-compact/index.ts +0 -121
  90. package/.xtrm/ext-src/pi-serena-compact/package.json +0 -16
  91. package/.xtrm/ext-src/quality-gates/package.json +0 -19
  92. package/.xtrm/ext-src/service-skills/index.ts +0 -108
  93. package/.xtrm/ext-src/session-flow/package.json +0 -19
  94. package/.xtrm/ext-src/xtrm-loader/index.ts +0 -152
  95. package/.xtrm/ext-src/xtrm-loader/package.json +0 -19
  96. package/.xtrm/ext-src/xtrm-ui/format.ts +0 -282
  97. package/.xtrm/ext-src/xtrm-ui/index.ts +0 -1112
  98. package/.xtrm/ext-src/xtrm-ui/package.json +0 -21
  99. /package/.xtrm/{ext-src → config/pi/extensions}/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.combined.log +0 -0
  100. /package/.xtrm/{ext-src → config/pi/extensions}/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.stderr.log +0 -0
  101. /package/.xtrm/{ext-src → config/pi/extensions}/custom-footer/.pi/structured-returns/83051fe4-97da-4e2c-bdaa-343b32f4e714.stdout.log +0 -0
  102. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/auto-session-name/index.ts +0 -0
  103. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/auto-session-name/package.json +0 -0
  104. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/auto-update/index.ts +0 -0
  105. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/auto-update/package.json +0 -0
  106. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/compact-header/index.ts +0 -0
  107. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/compact-header/package.json +0 -0
  108. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/custom-provider-qwen-cli/index.ts +0 -0
  109. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/git-checkpoint/index.ts +0 -0
  110. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/git-checkpoint/package.json +0 -0
  111. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/lsp-bootstrap/index.ts +0 -0
  112. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/lsp-bootstrap/package.json +0 -0
  113. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/pi-serena-compact/index.ts +0 -0
  114. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/xtrm-ui/format.ts +0 -0
  115. /package/{.xtrm/config/pi → packages/pi-extensions}/extensions/xtrm-ui/package.json +0 -0
  116. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/adapter.ts +0 -0
  117. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/guard-rules.ts +0 -0
  118. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/lib.ts +0 -0
  119. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/logger.ts +0 -0
  120. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/runner.ts +0 -0
  121. /package/{.xtrm/config/pi/extensions → packages/pi-extensions/src}/core/session-state.ts +0 -0
  122. /package/{.xtrm/ext-src/xtrm-ui/themes → packages/pi-extensions/themes/xtrm-ui}/pidex-dark.json +0 -0
  123. /package/{.xtrm/ext-src/xtrm-ui/themes → packages/pi-extensions/themes/xtrm-ui}/pidex-light.json +0 -0
@@ -1,66 +0,0 @@
1
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
- import { SubprocessRunner, EventAdapter } from "@xtrm/pi-core";
3
- import * as path from "node:path";
4
- import * as fs from "node:fs";
5
-
6
- function resolveQualityHook(cwd: string, ext: string): { runner: string; scriptPath: string } | null {
7
- if ([".ts", ".tsx", ".js", ".jsx", ".cjs", ".mjs"].includes(ext)) {
8
- const scriptPath = path.join(cwd, ".claude", "hooks", "quality-check.cjs");
9
- return { runner: "node", scriptPath };
10
- }
11
- if (ext === ".py") {
12
- const scriptPath = path.join(cwd, ".claude", "hooks", "quality-check.py");
13
- return { runner: "python3", scriptPath };
14
- }
15
- return null;
16
- }
17
-
18
- export default function (pi: ExtensionAPI) {
19
- pi.on("tool_result", async (event, ctx) => {
20
- if (!EventAdapter.isMutatingFileTool(event)) return undefined;
21
-
22
- const cwd = ctx.cwd || process.cwd();
23
- const filePath = EventAdapter.extractPathFromToolInput(event, cwd);
24
- if (!filePath) return undefined;
25
-
26
- const fullPath = path.isAbsolute(filePath) ? filePath : path.join(cwd, filePath);
27
- const ext = path.extname(fullPath);
28
- const resolved = resolveQualityHook(cwd, ext);
29
- if (!resolved) return undefined;
30
- if (!fs.existsSync(resolved.scriptPath)) return undefined;
31
-
32
- const hookInput = JSON.stringify({
33
- tool_name: event.toolName,
34
- tool_input: event.input,
35
- cwd,
36
- });
37
-
38
- const result = await SubprocessRunner.run(resolved.runner, [resolved.scriptPath], {
39
- cwd,
40
- input: hookInput,
41
- env: { ...process.env, CLAUDE_PROJECT_DIR: cwd },
42
- timeoutMs: 30000,
43
- });
44
-
45
- if (result.code === 0) {
46
- const details = (result.stdout || result.stderr || "").trim();
47
- if (!details) return undefined;
48
- return {
49
- content: [...event.content, { type: "text", text: `\n\n**Quality Gate**: ${details}` }],
50
- };
51
- }
52
-
53
- if (result.code === 2) {
54
- const details = (result.stderr || result.stdout || "Unknown error").trim();
55
- if (ctx.hasUI) {
56
- ctx.ui.notify(`Quality Gate failed for ${path.basename(fullPath)}`, "error");
57
- }
58
- return {
59
- isError: true,
60
- content: [...event.content, { type: "text", text: `\n\n**Quality Gate FAILED**:\n${details}` }],
61
- };
62
- }
63
-
64
- return undefined;
65
- });
66
- }
@@ -1,19 +0,0 @@
1
- {
2
- "name": "@xtrm/pi-service-skills",
3
- "version": "1.0.0",
4
- "description": "xtrm Pi extension: service-skills",
5
- "type": "module",
6
- "exports": {
7
- ".": "./index.ts"
8
- },
9
- "keywords": [
10
- "pi",
11
- "extension",
12
- "xtrm"
13
- ],
14
- "author": "xtrm",
15
- "license": "MIT",
16
- "dependencies": {
17
- "@xtrm/pi-core": "^1.0.0"
18
- }
19
- }
@@ -1,96 +0,0 @@
1
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
- import { isBashToolResult } from "@mariozechner/pi-coding-agent";
3
- import { SubprocessRunner, EventAdapter } from "@xtrm/pi-core";
4
-
5
- function isClaimCommand(command: string): { isClaim: boolean; issueId: string | null } {
6
- if (!/\bbd\s+update\b/.test(command) || !/--claim\b/.test(command)) {
7
- return { isClaim: false, issueId: null };
8
- }
9
- const match = command.match(/\bbd\s+update\s+(\S+)/);
10
- return { isClaim: true, issueId: match?.[1] ?? null };
11
- }
12
-
13
- function isWorktree(cwd: string): boolean {
14
- return cwd.includes("/.xtrm/worktrees/") || cwd.includes("/.claude/worktrees/");
15
- }
16
-
17
- function getSessionId(ctx: any): string {
18
- return ctx?.sessionManager?.getSessionId?.() ?? ctx?.sessionId ?? ctx?.session_id ?? process.pid.toString();
19
- }
20
-
21
- async function getSessionClaim(cwd: string, sessionId: string): Promise<string | null> {
22
- const claimResult = await SubprocessRunner.run("bd", ["kv", "get", `claimed:${sessionId}`], { cwd });
23
- if (claimResult.code !== 0) return null;
24
- const claimId = claimResult.stdout.trim();
25
- return claimId.length > 0 ? claimId : null;
26
- }
27
-
28
- async function isClaimStillInProgress(cwd: string, issueId: string): Promise<boolean> {
29
- const showResult = await SubprocessRunner.run("bd", ["show", issueId, "--json"], { cwd });
30
- if (showResult.code === 0 && showResult.stdout.trim()) {
31
- try {
32
- const parsed = JSON.parse(showResult.stdout);
33
- const record = Array.isArray(parsed) ? parsed[0] : parsed;
34
- if (record?.status) return record.status === "in_progress";
35
- } catch {
36
- // fall back to text parsing below
37
- }
38
- }
39
-
40
- const listResult = await SubprocessRunner.run("bd", ["list", "--status=in_progress"], { cwd });
41
- if (listResult.code !== 0) return false;
42
- const issuePattern = new RegExp(`^\\s*[◐●]?\\s*${issueId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`, "m");
43
- return issuePattern.test(listResult.stdout);
44
- }
45
-
46
- export default function (pi: ExtensionAPI) {
47
- const getCwd = (ctx: any) => ctx.cwd || process.cwd();
48
- let lastStopNoticeIssue: string | null = null;
49
- let lastWorktreeReminderCwd: string | null = null;
50
-
51
- // Claim sync: notify when a bd update --claim command is run.
52
- pi.on("tool_result", async (event, ctx) => {
53
- if (!isBashToolResult(event)) return undefined;
54
- const cwd = getCwd(ctx);
55
- if (!EventAdapter.isBeadsProject(cwd)) return undefined;
56
-
57
- const command = event.input.command || "";
58
- const { isClaim, issueId } = isClaimCommand(command);
59
- if (!isClaim || !issueId) return undefined;
60
-
61
- const text = `\n\nSession Flow: claimed ${issueId}. Work in this session is tracked.`;
62
- return { content: [...event.content, { type: "text", text }] };
63
- });
64
-
65
- // Stop gate: warn (non-blocking) if this session's claimed issue is still in progress.
66
- // IMPORTANT: never call sendUserMessage() from agent_end, it always triggers a new turn.
67
- pi.on("agent_end", async (_event, ctx) => {
68
- const cwd = getCwd(ctx);
69
- if (!EventAdapter.isBeadsProject(cwd)) return undefined;
70
-
71
- const sessionId = getSessionId(ctx);
72
- const claimId = await getSessionClaim(cwd, sessionId);
73
-
74
- if (claimId) {
75
- const inProgress = await isClaimStillInProgress(cwd, claimId);
76
- if (inProgress) {
77
- if (lastStopNoticeIssue !== claimId && ctx.hasUI) {
78
- ctx.ui.notify(`Stop blocked: close your issue first: bd close ${claimId}`, "warning");
79
- lastStopNoticeIssue = claimId;
80
- }
81
- return undefined;
82
- }
83
-
84
- if (lastStopNoticeIssue === claimId) {
85
- lastStopNoticeIssue = null;
86
- }
87
- }
88
-
89
- if (isWorktree(cwd) && ctx.hasUI && lastWorktreeReminderCwd !== cwd) {
90
- ctx.ui.notify("Run `xt end` to create a PR and clean up this worktree.", "info");
91
- lastWorktreeReminderCwd = cwd;
92
- }
93
-
94
- return undefined;
95
- });
96
- }
@@ -1,89 +0,0 @@
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": "surface",
41
- "toolSuccessBg": "surface",
42
- "toolErrorBg": "surface",
43
- "toolUseBg": "surface",
44
- "toolUsePendingBg": "surface",
45
- "toolUseSuccessBg": "surface",
46
- "toolUseErrorBg": "surface",
47
- "toolTitle": "",
48
- "toolOutput": "gray",
49
-
50
- "mdHeading": "warningAmber",
51
- "mdLink": "accentBlue",
52
- "mdLinkUrl": "dimGray",
53
- "mdCode": "accentCyan",
54
- "mdCodeBlock": "gray",
55
- "mdCodeBlockBorder": "borderGray",
56
- "mdQuote": "gray",
57
- "mdQuoteBorder": "borderGray",
58
- "mdHr": "borderGray",
59
- "mdListBullet": "accentTeal",
60
-
61
- "toolDiffAdded": "successGreen",
62
- "toolDiffRemoved": "errorRed",
63
- "toolDiffContext": "gray",
64
-
65
- "syntaxComment": "#6b7280",
66
- "syntaxKeyword": "#7aa2f7",
67
- "syntaxFunction": "#c0caf5",
68
- "syntaxVariable": "#a9b1d6",
69
- "syntaxString": "#9ece6a",
70
- "syntaxNumber": "#ff9e64",
71
- "syntaxType": "#73daca",
72
- "syntaxOperator": "#c0caf5",
73
- "syntaxPunctuation": "#8f9bb3",
74
-
75
- "thinkingOff": "borderGray",
76
- "thinkingMinimal": "#707070",
77
- "thinkingLow": "#7a7a7a",
78
- "thinkingMedium": "#858585",
79
- "thinkingHigh": "#8f8f8f",
80
- "thinkingXhigh": "#999999",
81
-
82
- "bashMode": "accentTeal"
83
- },
84
- "export": {
85
- "pageBg": "#12161d",
86
- "cardBg": "#171b22",
87
- "infoBg": "#28230f"
88
- }
89
- }
@@ -1,89 +0,0 @@
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
- "toolUseBg": "surfaceAlt",
44
- "toolUsePendingBg": "surfaceAlt",
45
- "toolUseSuccessBg": "surfaceAlt",
46
- "toolUseErrorBg": "surfaceAlt",
47
- "toolTitle": "",
48
- "toolOutput": "gray",
49
-
50
- "mdHeading": "warningAmber",
51
- "mdLink": "accentBlue",
52
- "mdLinkUrl": "dimGray",
53
- "mdCode": "accentCyan",
54
- "mdCodeBlock": "gray",
55
- "mdCodeBlockBorder": "borderGray",
56
- "mdQuote": "gray",
57
- "mdQuoteBorder": "borderGray",
58
- "mdHr": "borderGray",
59
- "mdListBullet": "accentTeal",
60
-
61
- "toolDiffAdded": "successGreen",
62
- "toolDiffRemoved": "errorRed",
63
- "toolDiffContext": "gray",
64
-
65
- "syntaxComment": "#6b7280",
66
- "syntaxKeyword": "#3569c8",
67
- "syntaxFunction": "#3b4351",
68
- "syntaxVariable": "#364152",
69
- "syntaxString": "#3f7d3d",
70
- "syntaxNumber": "#b06500",
71
- "syntaxType": "#2c7a7b",
72
- "syntaxOperator": "#3b4351",
73
- "syntaxPunctuation": "#55606f",
74
-
75
- "thinkingOff": "borderGray",
76
- "thinkingMinimal": "#9d9d9d",
77
- "thinkingLow": "#979797",
78
- "thinkingMedium": "#919191",
79
- "thinkingHigh": "#8b8b8b",
80
- "thinkingXhigh": "#858585",
81
-
82
- "bashMode": "accentTeal"
83
- },
84
- "export": {
85
- "pageBg": "#f5f7fa",
86
- "cardBg": "#ffffff",
87
- "infoBg": "#fff5e6"
88
- }
89
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * oh-pi Auto Session Name Extension
3
- *
4
- * Automatically names sessions based on the first user message.
5
- */
6
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
7
-
8
- export default function (pi: ExtensionAPI) {
9
- let named = false;
10
-
11
- pi.on("session_start", async (_event, ctx) => {
12
- named = !!pi.getSessionName();
13
- });
14
-
15
- pi.on("agent_end", async (event) => {
16
- if (named) return;
17
- const userMsg = event.messages.find((m) => m.role === "user");
18
- if (!userMsg) return;
19
- const text = typeof userMsg.content === "string"
20
- ? userMsg.content
21
- : userMsg.content.filter((b) => b.type === "text").map((b) => (b as { text: string }).text).join(" ");
22
- if (!text) return;
23
- const name = text.slice(0, 60).replace(/\n/g, " ").trim();
24
- if (name) {
25
- pi.setSessionName(name);
26
- named = true;
27
- }
28
- });
29
- }
@@ -1,16 +0,0 @@
1
- {
2
- "name": "@xtrm/pi-auto-session-name",
3
- "version": "1.0.0",
4
- "description": "xtrm Pi extension: auto-session-name",
5
- "type": "module",
6
- "exports": {
7
- ".": "./index.ts"
8
- },
9
- "keywords": [
10
- "pi",
11
- "extension",
12
- "xtrm"
13
- ],
14
- "author": "xtrm",
15
- "license": "MIT"
16
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * oh-pi Auto Update — check for new oh-pi version on session start
3
- */
4
- import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
5
- import { execSync } from "node:child_process";
6
- import { readFileSync, writeFileSync, existsSync } from "node:fs";
7
- import { join } from "node:path";
8
- import { homedir } from "node:os";
9
-
10
- const CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24h
11
- const STAMP_FILE = join(homedir(), ".pi", "agent", ".update-check");
12
-
13
- function readStamp(): number {
14
- try { return Number(readFileSync(STAMP_FILE, "utf8").trim()) || 0; } catch { return 0; }
15
- }
16
-
17
- function writeStamp() {
18
- try { writeFileSync(STAMP_FILE, String(Date.now())); } catch {}
19
- }
20
-
21
- function getLatestVersion(): string | null {
22
- try {
23
- return execSync("npm view oh-pi version", { encoding: "utf8", timeout: 8000 }).trim();
24
- } catch { return null; }
25
- }
26
-
27
- function getCurrentVersion(): string | null {
28
- // Read from the installed package.json
29
- try {
30
- const pkgPath = join(__dirname, "..", "..", "package.json");
31
- if (existsSync(pkgPath)) {
32
- return JSON.parse(readFileSync(pkgPath, "utf8")).version;
33
- }
34
- } catch {}
35
- // Fallback: npm list
36
- try {
37
- const out = JSON.parse(execSync("npm list -g oh-pi --json --depth=0", { encoding: "utf8", timeout: 8000 }));
38
- return out.dependencies?.["oh-pi"]?.version ?? null;
39
- } catch { return null; }
40
- }
41
-
42
- export function isNewer(latest: string, current: string): boolean {
43
- const a = latest.split(".").map(Number);
44
- const b = current.split(".").map(Number);
45
- for (let i = 0; i < 3; i++) {
46
- if ((a[i] ?? 0) > (b[i] ?? 0)) return true;
47
- if ((a[i] ?? 0) < (b[i] ?? 0)) return false;
48
- }
49
- return false;
50
- }
51
-
52
- export default function (pi: ExtensionAPI) {
53
- pi.on("session_start", async (_event, ctx) => {
54
- // Non-blocking: run check in background
55
- setTimeout(async () => {
56
- try {
57
- if (Date.now() - readStamp() < CHECK_INTERVAL) return;
58
- writeStamp();
59
-
60
- const current = getCurrentVersion();
61
- const latest = getLatestVersion();
62
- if (!current || !latest || !isNewer(latest, current)) return;
63
-
64
- const msg = `oh-pi ${latest} available (current: ${current}). Run: npx oh-pi@latest`;
65
- if (ctx.hasUI) {
66
- ctx.ui.toast?.(msg) ?? console.log(`\n💡 ${msg}\n`);
67
- }
68
- } catch {}
69
- }, 2000);
70
- });
71
- }
@@ -1,16 +0,0 @@
1
- {
2
- "name": "@xtrm/pi-auto-update",
3
- "version": "1.0.0",
4
- "description": "xtrm Pi extension: auto-update",
5
- "type": "module",
6
- "exports": {
7
- ".": "./index.ts"
8
- },
9
- "keywords": [
10
- "pi",
11
- "extension",
12
- "xtrm"
13
- ],
14
- "author": "xtrm",
15
- "license": "MIT"
16
- }