xtrm-tools 2.1.21 → 2.1.23
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 +1 -1
- package/config/pi/extensions/beads.ts +33 -124
- package/config/pi/extensions/main-guard-post-push.ts +1 -1
- package/config/pi/extensions/main-guard.ts +1 -1
- package/config/pi/extensions/quality-gates.ts +1 -1
- package/config/pi/extensions/service-skills.ts +1 -1
- package/config/pi/extensions/xtrm-loader.ts +1 -1
- package/package.json +1 -1
- /package/config/pi/extensions/core/{index.ts → lib.ts} +0 -0
package/cli/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import type { ExtensionAPI, ToolCallEvent, ToolResultEvent } from "@mariozechner
|
|
|
2
2
|
import { isToolCallEventType, isBashToolResult } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
|
-
import { SubprocessRunner, EventAdapter, Logger } from "./core";
|
|
5
|
+
import { SubprocessRunner, EventAdapter, Logger } from "./core/lib";
|
|
6
6
|
|
|
7
7
|
const logger = new Logger({ namespace: "beads" });
|
|
8
8
|
|
|
@@ -16,24 +16,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
16
16
|
return null;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const setSessionClaim = async (sessionId: string, issueId: string, cwd: string): Promise<boolean> => {
|
|
20
|
-
const result = await SubprocessRunner.run("bd", ["kv", "set", `claimed:${sessionId}`, issueId], { cwd });
|
|
21
|
-
return result.code === 0;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
const clearSessionClaim = async (sessionId: string, cwd: string): Promise<boolean> => {
|
|
25
|
-
const result = await SubprocessRunner.run("bd", ["kv", "clear", `claimed:${sessionId}`], { cwd });
|
|
26
|
-
return result.code === 0;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const getInProgressSummary = async (cwd: string): Promise<string | null> => {
|
|
30
|
-
const result = await SubprocessRunner.run("bd", ["list", "--status=in_progress"], { cwd });
|
|
31
|
-
if (result.code === 0 && result.stdout.includes("Total:")) {
|
|
32
|
-
return result.stdout.trim();
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
19
|
const hasTrackableWork = async (cwd: string): Promise<boolean> => {
|
|
38
20
|
const result = await SubprocessRunner.run("bd", ["list"], { cwd });
|
|
39
21
|
if (result.code === 0 && result.stdout.includes("Total:")) {
|
|
@@ -47,83 +29,37 @@ export default function (pi: ExtensionAPI) {
|
|
|
47
29
|
return false;
|
|
48
30
|
};
|
|
49
31
|
|
|
50
|
-
// 0. Register Custom Commands
|
|
51
|
-
pi.registerCommand({
|
|
52
|
-
name: "claim",
|
|
53
|
-
description: "Claim a beads issue for this session",
|
|
54
|
-
async execute(args, ctx) {
|
|
55
|
-
const cwd = getCwd(ctx);
|
|
56
|
-
if (!isBeadsProject(cwd)) {
|
|
57
|
-
ctx.ui.notify("Not a beads project.", "error");
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const issueId = args[0];
|
|
62
|
-
if (!issueId) {
|
|
63
|
-
ctx.ui.notify("Usage: /claim <issue-id>", "warning");
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Ensure issue is in_progress first
|
|
68
|
-
await SubprocessRunner.run("bd", ["update", issueId, "--status=in_progress"], { cwd });
|
|
69
|
-
|
|
70
|
-
const ok = await setSessionClaim(ctx.sessionManager.sessionId, issueId, cwd);
|
|
71
|
-
if (ok) {
|
|
72
|
-
ctx.ui.notify(`Claimed issue: ${issueId}`, "info");
|
|
73
|
-
} else {
|
|
74
|
-
ctx.ui.notify(`Failed to claim issue: ${issueId}`, "error");
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
pi.registerCommand({
|
|
80
|
-
name: "unclaim",
|
|
81
|
-
description: "Clear the beads issue claim for this session",
|
|
82
|
-
async execute(_args, ctx) {
|
|
83
|
-
const cwd = getCwd(ctx);
|
|
84
|
-
if (!isBeadsProject(cwd)) return;
|
|
85
|
-
|
|
86
|
-
const ok = await clearSessionClaim(ctx.sessionManager.sessionId, cwd);
|
|
87
|
-
if (ok) {
|
|
88
|
-
ctx.ui.notify("Claim cleared.", "info");
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// 1. Tool Call Interception (Edit Gate & Commit Gate)
|
|
94
32
|
pi.on("tool_call", async (event, ctx) => {
|
|
95
33
|
const cwd = getCwd(ctx);
|
|
96
34
|
if (!isBeadsProject(cwd)) return undefined;
|
|
97
35
|
|
|
98
36
|
const sessionId = ctx.sessionManager.sessionId;
|
|
99
37
|
|
|
100
|
-
// A. Edit Gate
|
|
101
38
|
if (EventAdapter.isMutatingFileTool(event)) {
|
|
102
39
|
const claim = await getSessionClaim(sessionId, cwd);
|
|
103
|
-
if (claim)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
40
|
+
if (!claim) {
|
|
41
|
+
const hasWork = await hasTrackableWork(cwd);
|
|
42
|
+
if (hasWork) {
|
|
43
|
+
if (ctx.hasUI) {
|
|
44
|
+
ctx.ui.notify("Beads: Edit blocked. Claim an issue first.", "warning");
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
block: true,
|
|
48
|
+
reason: `No active issue claim for this session (${sessionId}).\n bd update <id> --claim\n bd kv set "claimed:${sessionId}" "<id>"`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
}
|
|
113
52
|
}
|
|
114
53
|
|
|
115
|
-
// B. Commit Gate
|
|
116
54
|
if (isToolCallEventType("bash", event)) {
|
|
117
55
|
const command = event.input.command;
|
|
118
|
-
if (/\bgit\s+commit\b/.test(command)) {
|
|
119
|
-
|
|
56
|
+
if (command && /\bgit\s+commit\b/.test(command)) {
|
|
57
|
+
const claim = await getSessionClaim(sessionId, cwd);
|
|
120
58
|
if (claim) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
return { block: true, reason };
|
|
59
|
+
return {
|
|
60
|
+
block: true,
|
|
61
|
+
reason: `Resolve open claim [${claim}] before committing.`,
|
|
62
|
+
};
|
|
127
63
|
}
|
|
128
64
|
}
|
|
129
65
|
}
|
|
@@ -131,55 +67,28 @@ export default function (pi: ExtensionAPI) {
|
|
|
131
67
|
return undefined;
|
|
132
68
|
});
|
|
133
69
|
|
|
134
|
-
// 2. Tool Result Interception (Memory Gate)
|
|
135
70
|
pi.on("tool_result", async (event, ctx) => {
|
|
136
|
-
const cwd = getCwd(ctx);
|
|
137
|
-
if (!isBeadsProject(cwd)) return undefined;
|
|
138
|
-
|
|
139
71
|
if (isBashToolResult(event)) {
|
|
140
72
|
const command = event.input.command;
|
|
141
|
-
// Also clear claim on bd close
|
|
142
|
-
if (/\bbd\s+close\b/.test(command) && !event.isError) {
|
|
143
|
-
await clearSessionClaim(ctx.sessionManager.sessionId, cwd);
|
|
144
73
|
|
|
74
|
+
if (command && /\bbd\s+update\b/.test(command) && /--claim\b/.test(command) && !event.isError) {
|
|
75
|
+
const issueMatch = command.match(/\bbd\s+update\s+(\S+)/);
|
|
76
|
+
if (issueMatch) {
|
|
77
|
+
const issueId = issueMatch[1];
|
|
78
|
+
const cwd = getCwd(ctx);
|
|
79
|
+
const sessionId = ctx.sessionManager.sessionId;
|
|
80
|
+
await SubprocessRunner.run("bd", ["kv", "set", `claimed:${sessionId}`, issueId], { cwd });
|
|
81
|
+
const claimNotice = `\n\n✅ **Beads**: Session \`${sessionId}\` claimed issue \`${issueId}\`. File edits are now unblocked.`;
|
|
82
|
+
return { content: [...event.content, { type: "text", text: claimNotice }] };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (command && /\bbd\s+close\b/.test(command) && !event.isError) {
|
|
145
87
|
const reminder = "\n\n**Beads Insight**: Work completed. Consider if this session produced insights worth persisting via `bd remember`.";
|
|
146
|
-
const newContent = [...event.content];
|
|
147
|
-
newContent.push({ type: "text", text: reminder });
|
|
88
|
+
const newContent = [...event.content, { type: "text", text: reminder }];
|
|
148
89
|
return { content: newContent };
|
|
149
90
|
}
|
|
150
91
|
}
|
|
151
92
|
return undefined;
|
|
152
93
|
});
|
|
153
|
-
|
|
154
|
-
// 3. Compaction Support
|
|
155
|
-
pi.on("session_before_compact", async (event, ctx) => {
|
|
156
|
-
const cwd = getCwd(ctx);
|
|
157
|
-
if (!isBeadsProject(cwd)) return undefined;
|
|
158
|
-
|
|
159
|
-
const sessionId = ctx.sessionManager.sessionId;
|
|
160
|
-
const claim = await getSessionClaim(sessionId, cwd);
|
|
161
|
-
|
|
162
|
-
if (claim) {
|
|
163
|
-
return {
|
|
164
|
-
compaction: {
|
|
165
|
-
summary: (event.compaction?.summary || "") + `\n\nActive Beads Claim: ${claim}`,
|
|
166
|
-
firstKeptEntryId: event.preparation.firstKeptEntryId,
|
|
167
|
-
}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
return undefined;
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
// 4. Shutdown Warning
|
|
174
|
-
pi.on("session_shutdown", async (_event, ctx) => {
|
|
175
|
-
const cwd = getCwd(ctx);
|
|
176
|
-
if (!isBeadsProject(cwd)) return;
|
|
177
|
-
|
|
178
|
-
const sessionId = ctx.sessionManager.sessionId;
|
|
179
|
-
const claim = await getSessionClaim(sessionId, cwd);
|
|
180
|
-
|
|
181
|
-
if (claim && ctx.hasUI) {
|
|
182
|
-
ctx.ui.notify(`Warning: Exiting with active Beads claim [${claim}].`, "warning");
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
94
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ToolResultEvent } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { isBashToolResult } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import { SubprocessRunner, Logger } from "./core";
|
|
3
|
+
import { SubprocessRunner, Logger } from "./core/lib";
|
|
4
4
|
|
|
5
5
|
const logger = new Logger({ namespace: "main-guard-post-push" });
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ToolCallEvent } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import { SubprocessRunner, EventAdapter, Logger } from "./core";
|
|
3
|
+
import { SubprocessRunner, EventAdapter, Logger } from "./core/lib";
|
|
4
4
|
|
|
5
5
|
const logger = new Logger({ namespace: "main-guard" });
|
|
6
6
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionAPI, ToolResultEvent } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import { SubprocessRunner, EventAdapter, Logger } from "./core";
|
|
2
|
+
import { SubprocessRunner, EventAdapter, Logger } from "./core/lib";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ExtensionAPI, ToolCallEvent, ToolResultEvent } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import { isToolCallEventType, isBashToolResult } from "@mariozechner/pi-coding-agent";
|
|
3
|
-
import { SubprocessRunner, Logger } from "./core";
|
|
3
|
+
import { SubprocessRunner, Logger } from "./core/lib";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import * as fs from "node:fs";
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { Logger } from "./core";
|
|
4
|
+
import { Logger } from "./core/lib";
|
|
5
5
|
|
|
6
6
|
const logger = new Logger({ namespace: "xtrm-loader" });
|
|
7
7
|
|
package/package.json
CHANGED
|
File without changes
|