@burmese/pi 3.1.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/LICENSE +21 -0
- package/dist/extension.d.ts +3 -0
- package/dist/extension.js +5 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/runtime.d.ts +59 -0
- package/dist/runtime.js +255 -0
- package/package.json +66 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenPets
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default } from "./extension.js";
|
|
2
|
+
export { allowedPiOpenPetsCommands, classifyPiEvent, classifyPiToolExecutionStart, createOpenPetsPiExtension, createOpenPetsPiRuntime, getPiOpenPetsHelp, normalizePiEvent, parseOpenPetsCommand, shouldIgnoreOpenPetsTool, validateManualSpeech, type OpenPetsPiCommand, type OpenPetsPiExtensionApi, type OpenPetsPiOptions, type OpenPetsPiRuntime, type PiEventEnvelope, type PiEventDecision, } from "./runtime.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { default } from "./extension.js";
|
|
2
|
+
export { allowedPiOpenPetsCommands, classifyPiEvent, classifyPiToolExecutionStart, createOpenPetsPiExtension, createOpenPetsPiRuntime, getPiOpenPetsHelp, normalizePiEvent, parseOpenPetsCommand, shouldIgnoreOpenPetsTool, validateManualSpeech, } from "./runtime.js";
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type OpenPetsClient, type OpenPetsReaction } from "@burmese/client";
|
|
2
|
+
export interface OpenPetsPiOptions {
|
|
3
|
+
readonly clientFactory?: () => OpenPetsClient;
|
|
4
|
+
readonly schedule?: (work: () => Promise<void>) => void;
|
|
5
|
+
readonly debug?: boolean;
|
|
6
|
+
readonly debugLog?: (message: string) => void;
|
|
7
|
+
readonly random?: () => number;
|
|
8
|
+
readonly now?: () => number;
|
|
9
|
+
}
|
|
10
|
+
export interface OpenPetsPiRuntime {
|
|
11
|
+
readonly handleEvent: (event: unknown) => void;
|
|
12
|
+
readonly handleCommand: (args: string, ctx?: OpenPetsPiCommandContext) => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export interface OpenPetsPiExtensionApi {
|
|
15
|
+
readonly on?: (eventName: string, handler: (event: unknown, ctx?: unknown) => unknown) => unknown;
|
|
16
|
+
readonly registerCommand?: (name: string, command: {
|
|
17
|
+
readonly description?: string;
|
|
18
|
+
readonly handler: (args: string, ctx?: unknown) => unknown;
|
|
19
|
+
}) => unknown;
|
|
20
|
+
}
|
|
21
|
+
export interface OpenPetsPiCommandContext {
|
|
22
|
+
readonly ui?: {
|
|
23
|
+
readonly notify?: (message: string, type?: "info" | "warning" | "error") => void;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface PiEventDecision {
|
|
27
|
+
readonly reaction?: OpenPetsReaction;
|
|
28
|
+
readonly speech?: "error";
|
|
29
|
+
readonly markError?: boolean;
|
|
30
|
+
readonly clearError?: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface PiEventEnvelope {
|
|
33
|
+
readonly type: string;
|
|
34
|
+
readonly payload?: unknown;
|
|
35
|
+
}
|
|
36
|
+
export type OpenPetsPiCommand = {
|
|
37
|
+
readonly kind: "help";
|
|
38
|
+
} | {
|
|
39
|
+
readonly kind: "status";
|
|
40
|
+
} | {
|
|
41
|
+
readonly kind: "test";
|
|
42
|
+
} | {
|
|
43
|
+
readonly kind: "react";
|
|
44
|
+
readonly reaction: OpenPetsReaction;
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: "say";
|
|
47
|
+
readonly message: string;
|
|
48
|
+
};
|
|
49
|
+
export declare const allowedPiOpenPetsCommands: readonly ["help", "status", "test", "react", "say"];
|
|
50
|
+
export declare function createOpenPetsPiExtension(pi: unknown, options?: OpenPetsPiOptions): OpenPetsPiRuntime;
|
|
51
|
+
export declare function createOpenPetsPiRuntime(options?: OpenPetsPiOptions): OpenPetsPiRuntime;
|
|
52
|
+
export declare function classifyPiEvent(event: unknown): PiEventDecision | undefined;
|
|
53
|
+
export declare function normalizePiEvent(event: unknown): PiEventEnvelope;
|
|
54
|
+
export declare function classifyPiToolExecutionStart(toolName: unknown, args?: unknown): OpenPetsReaction | undefined;
|
|
55
|
+
export declare function shouldIgnoreOpenPetsTool(toolName: string): boolean;
|
|
56
|
+
export declare function parseOpenPetsCommand(args: string): OpenPetsPiCommand;
|
|
57
|
+
export declare function validateManualSpeech(message: string): string;
|
|
58
|
+
export declare function getPiOpenPetsHelp(): string;
|
|
59
|
+
//# sourceMappingURL=runtime.d.ts.map
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { pickHookSpeech, validateHookSpeech } from "@burmese/agent-events";
|
|
2
|
+
import { allowedReactions, createOpenPetsClient } from "@burmese/client";
|
|
3
|
+
const automaticTimeoutMs = 500;
|
|
4
|
+
const errorSuccessSuppressionMs = 5_000;
|
|
5
|
+
const boundedCommandSliceLength = 300;
|
|
6
|
+
const openPetsClientLabel = "Pi";
|
|
7
|
+
export const allowedPiOpenPetsCommands = ["help", "status", "test", "react", "say"];
|
|
8
|
+
export function createOpenPetsPiExtension(pi, options = {}) {
|
|
9
|
+
const runtime = createOpenPetsPiRuntime(options);
|
|
10
|
+
const api = isPiApi(pi) ? pi : undefined;
|
|
11
|
+
if (!api)
|
|
12
|
+
return runtime;
|
|
13
|
+
const subscribe = (eventName) => {
|
|
14
|
+
api.on?.(eventName, (event) => runtime.handleEvent({ type: eventName, payload: event }));
|
|
15
|
+
};
|
|
16
|
+
for (const eventName of ["session_start", "session_shutdown", "agent_start", "agent_end", "turn_start", "tool_execution_start", "tool_execution_end"]) {
|
|
17
|
+
subscribe(eventName);
|
|
18
|
+
}
|
|
19
|
+
api.registerCommand?.("openpets", {
|
|
20
|
+
description: "Control OpenPets desktop pet reactions and check local connection status.",
|
|
21
|
+
handler: async (args, ctx) => runtime.handleCommand(args, isCommandContext(ctx) ? ctx : undefined),
|
|
22
|
+
});
|
|
23
|
+
return runtime;
|
|
24
|
+
}
|
|
25
|
+
export function createOpenPetsPiRuntime(options = {}) {
|
|
26
|
+
const clientFactory = options.clientFactory ?? (() => createOpenPetsClient({ connectTimeoutMs: automaticTimeoutMs, responseTimeoutMs: automaticTimeoutMs, source: "plugin" }));
|
|
27
|
+
const schedule = options.schedule ?? defaultSchedule;
|
|
28
|
+
const debug = options.debug === true || process.env.OPENPETS_PI_DEBUG === "1";
|
|
29
|
+
const debugLog = options.debugLog ?? ((message) => {
|
|
30
|
+
if (debug)
|
|
31
|
+
process.stderr.write(`${message}\n`);
|
|
32
|
+
});
|
|
33
|
+
let client;
|
|
34
|
+
let recentErrorAt = Number.NEGATIVE_INFINITY;
|
|
35
|
+
let lastErrorSpeechAt = Number.NEGATIVE_INFINITY;
|
|
36
|
+
const getClient = () => {
|
|
37
|
+
client ??= clientFactory();
|
|
38
|
+
return client;
|
|
39
|
+
};
|
|
40
|
+
const runAutomatic = (decision) => {
|
|
41
|
+
if (!decision?.reaction)
|
|
42
|
+
return;
|
|
43
|
+
const reaction = decision.reaction;
|
|
44
|
+
if (decision.markError)
|
|
45
|
+
recentErrorAt = options.now?.() ?? Date.now();
|
|
46
|
+
if (decision.clearError && (options.now?.() ?? Date.now()) - recentErrorAt < errorSuccessSuppressionMs)
|
|
47
|
+
return;
|
|
48
|
+
try {
|
|
49
|
+
schedule(async () => {
|
|
50
|
+
try {
|
|
51
|
+
if (decision.speech === "error" && shouldSendErrorSpeech()) {
|
|
52
|
+
await getClient().say(validateHookSpeech(pickHookSpeech("error", options.random)), { reaction, clientLabel: openPetsClientLabel });
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
await getClient().react(reaction, { clientLabel: openPetsClientLabel });
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
debugLog(`OpenPets Pi extension ignored error: ${sanitizeDebugError(error)}`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
debugLog(`OpenPets Pi extension scheduling ignored error: ${sanitizeDebugError(error)}`);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const shouldSendErrorSpeech = () => {
|
|
67
|
+
const now = options.now?.() ?? Date.now();
|
|
68
|
+
if (now - lastErrorSpeechAt < 20_000)
|
|
69
|
+
return false;
|
|
70
|
+
lastErrorSpeechAt = now;
|
|
71
|
+
return true;
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
handleEvent(event) {
|
|
75
|
+
try {
|
|
76
|
+
runAutomatic(classifyPiEvent(event));
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
debugLog(`OpenPets Pi event ignored error: ${sanitizeDebugError(error)}`);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
async handleCommand(args, ctx) {
|
|
83
|
+
try {
|
|
84
|
+
const command = parseOpenPetsCommand(args);
|
|
85
|
+
await executeCommand(command, getClient(), ctx);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
notify(ctx, sanitizeUserError(error), "error");
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function classifyPiEvent(event) {
|
|
94
|
+
const envelope = normalizePiEvent(event);
|
|
95
|
+
const type = envelope.type;
|
|
96
|
+
const record = isRecord(envelope.payload) ? envelope.payload : isRecord(event) ? event : {};
|
|
97
|
+
switch (type) {
|
|
98
|
+
case "session_start":
|
|
99
|
+
return { reaction: "waving" };
|
|
100
|
+
case "session_shutdown":
|
|
101
|
+
return { reaction: "idle" };
|
|
102
|
+
case "agent_start":
|
|
103
|
+
return { reaction: "thinking" };
|
|
104
|
+
case "turn_start":
|
|
105
|
+
return { reaction: "working" };
|
|
106
|
+
case "agent_end":
|
|
107
|
+
return { reaction: "success", clearError: true };
|
|
108
|
+
case "tool_execution_start": {
|
|
109
|
+
const reaction = classifyPiToolExecutionStart(record.toolName, record.args);
|
|
110
|
+
return reaction ? { reaction } : undefined;
|
|
111
|
+
}
|
|
112
|
+
case "tool_execution_end":
|
|
113
|
+
return record.isError === true ? { reaction: "error", speech: "error", markError: true } : undefined;
|
|
114
|
+
default:
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export function normalizePiEvent(event) {
|
|
119
|
+
if (isRecord(event) && typeof event.type === "string") {
|
|
120
|
+
return { type: event.type, payload: "payload" in event ? event.payload : event };
|
|
121
|
+
}
|
|
122
|
+
return { type: "", payload: event };
|
|
123
|
+
}
|
|
124
|
+
export function classifyPiToolExecutionStart(toolName, args) {
|
|
125
|
+
const normalized = typeof toolName === "string" ? toolName.toLowerCase() : "";
|
|
126
|
+
if (!normalized || shouldIgnoreOpenPetsTool(normalized))
|
|
127
|
+
return undefined;
|
|
128
|
+
if (/edit|write|patch|apply/.test(normalized))
|
|
129
|
+
return "editing";
|
|
130
|
+
if (/bash|shell|terminal|exec|command/.test(normalized))
|
|
131
|
+
return isTestLikeArgs(args) ? "testing" : "running";
|
|
132
|
+
return "working";
|
|
133
|
+
}
|
|
134
|
+
export function shouldIgnoreOpenPetsTool(toolName) {
|
|
135
|
+
const normalized = toolName.toLowerCase().replace(/[^a-z0-9_:/.-]+/g, "_");
|
|
136
|
+
return /(?:^|[_:/.-])openpets(?:[_:/.-]|$)/.test(normalized) || /^(?:openpets|burmese)_(?:status|say|react)$/.test(normalized);
|
|
137
|
+
}
|
|
138
|
+
export function parseOpenPetsCommand(args) {
|
|
139
|
+
const trimmed = args.trim();
|
|
140
|
+
if (!trimmed || trimmed === "help" || trimmed === "--help" || trimmed === "-h")
|
|
141
|
+
return { kind: "help" };
|
|
142
|
+
const [head = "", ...rest] = trimmed.split(/\s+/);
|
|
143
|
+
const tail = trimmed.slice(head.length).trim();
|
|
144
|
+
switch (head.toLowerCase()) {
|
|
145
|
+
case "status":
|
|
146
|
+
if (rest.length > 0)
|
|
147
|
+
throw new Error("Usage: /openpets status");
|
|
148
|
+
return { kind: "status" };
|
|
149
|
+
case "test":
|
|
150
|
+
if (rest.length > 0)
|
|
151
|
+
throw new Error("Usage: /openpets test");
|
|
152
|
+
return { kind: "test" };
|
|
153
|
+
case "react": {
|
|
154
|
+
if (rest.length !== 1)
|
|
155
|
+
throw new Error("Usage: /openpets react <reaction>");
|
|
156
|
+
return { kind: "react", reaction: validateReaction(rest[0] ?? "") };
|
|
157
|
+
}
|
|
158
|
+
case "say":
|
|
159
|
+
return { kind: "say", message: validateManualSpeech(tail) };
|
|
160
|
+
default:
|
|
161
|
+
throw new Error(`Unknown /openpets command: ${head}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
export function validateManualSpeech(message) {
|
|
165
|
+
const trimmed = message.trim();
|
|
166
|
+
if (/-----BEGIN [A-Z ]*PRIVATE KEY-----/i.test(trimmed))
|
|
167
|
+
throw new Error("OpenPets speech must not contain secrets.");
|
|
168
|
+
return validateHookSpeech(trimmed);
|
|
169
|
+
}
|
|
170
|
+
export function getPiOpenPetsHelp() {
|
|
171
|
+
return "OpenPets commands: /openpets status, /openpets test, /openpets react <reaction>, /openpets say <message>.";
|
|
172
|
+
}
|
|
173
|
+
async function executeCommand(command, client, ctx) {
|
|
174
|
+
switch (command.kind) {
|
|
175
|
+
case "help":
|
|
176
|
+
notify(ctx, getPiOpenPetsHelp(), "info");
|
|
177
|
+
return;
|
|
178
|
+
case "status": {
|
|
179
|
+
const status = await client.status();
|
|
180
|
+
notify(ctx, status.ok ? "OpenPets is connected." : `OpenPets unavailable: ${sanitizeStatusReason(status.unavailableReason)}`, status.ok ? "info" : "warning");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
case "test":
|
|
184
|
+
await client.say("Pi connected", { reaction: "waving", clientLabel: openPetsClientLabel });
|
|
185
|
+
notify(ctx, "OpenPets test sent.", "info");
|
|
186
|
+
return;
|
|
187
|
+
case "react":
|
|
188
|
+
await client.react(command.reaction, { clientLabel: openPetsClientLabel });
|
|
189
|
+
notify(ctx, `OpenPets reaction set: ${command.reaction}`, "info");
|
|
190
|
+
return;
|
|
191
|
+
case "say":
|
|
192
|
+
await client.say(command.message, { clientLabel: openPetsClientLabel });
|
|
193
|
+
notify(ctx, "OpenPets message sent.", "info");
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function isTestLikeArgs(args) {
|
|
198
|
+
const command = isRecord(args) && typeof args.command === "string" ? args.command.slice(0, boundedCommandSliceLength) : "";
|
|
199
|
+
return /\b(test|vitest|jest|pytest|npm\s+test|pnpm\s+test|yarn\s+test|cargo\s+test|go\s+test)\b/i.test(command);
|
|
200
|
+
}
|
|
201
|
+
function validateReaction(value) {
|
|
202
|
+
if (!allowedReactions.includes(value))
|
|
203
|
+
throw new Error("Invalid OpenPets reaction.");
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
function notify(ctx, message, type) {
|
|
207
|
+
ctx?.ui?.notify?.(message, type);
|
|
208
|
+
}
|
|
209
|
+
function defaultSchedule(work) {
|
|
210
|
+
void Promise.resolve().then(work).catch(() => undefined);
|
|
211
|
+
}
|
|
212
|
+
function sanitizeDebugError(error) {
|
|
213
|
+
if (!error)
|
|
214
|
+
return "unknown";
|
|
215
|
+
if (isRecord(error) && typeof error.code === "string")
|
|
216
|
+
return sanitizeKnownErrorCode(error.code);
|
|
217
|
+
if (error instanceof Error)
|
|
218
|
+
return error.name.replace(/[^a-z0-9_-]/gi, "_").slice(0, 80) || "Error";
|
|
219
|
+
return "unknown";
|
|
220
|
+
}
|
|
221
|
+
function sanitizeKnownErrorCode(code) {
|
|
222
|
+
const normalized = code.toLowerCase();
|
|
223
|
+
if (normalized.includes("enoent"))
|
|
224
|
+
return "ENOENT";
|
|
225
|
+
if (normalized.includes("econnrefused"))
|
|
226
|
+
return "ECONNREFUSED";
|
|
227
|
+
if (normalized.includes("connect_timeout"))
|
|
228
|
+
return "connect_timeout";
|
|
229
|
+
if (normalized.includes("response_timeout"))
|
|
230
|
+
return "response_timeout";
|
|
231
|
+
if (normalized.includes("connection_closed"))
|
|
232
|
+
return "connection_closed";
|
|
233
|
+
if (normalized.includes("unavailable"))
|
|
234
|
+
return "unavailable";
|
|
235
|
+
return "OpenPetsClientError";
|
|
236
|
+
}
|
|
237
|
+
function sanitizeUserError(error) {
|
|
238
|
+
return error instanceof Error ? error.message.replace(/[\r\n]+/g, " ").slice(0, 140) : "OpenPets command failed.";
|
|
239
|
+
}
|
|
240
|
+
function sanitizeStatusReason(reason) {
|
|
241
|
+
const text = typeof reason === "string" ? reason : "not running";
|
|
242
|
+
if (/ENOENT|ECONNREFUSED|connect_timeout|response_timeout|unavailable/i.test(text))
|
|
243
|
+
return "not running";
|
|
244
|
+
return "unavailable";
|
|
245
|
+
}
|
|
246
|
+
function isPiApi(value) {
|
|
247
|
+
return isRecord(value) && (typeof value.on === "function" || typeof value.registerCommand === "function");
|
|
248
|
+
}
|
|
249
|
+
function isCommandContext(value) {
|
|
250
|
+
return isRecord(value) && (value.ui === undefined || isRecord(value.ui));
|
|
251
|
+
}
|
|
252
|
+
function isRecord(value) {
|
|
253
|
+
return typeof value === "object" && value !== null;
|
|
254
|
+
}
|
|
255
|
+
//# sourceMappingURL=runtime.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@burmese/pi",
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/wannabeepolymath/pet-assistant.git",
|
|
8
|
+
"directory": "packages/pi"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"pi-package",
|
|
13
|
+
"openpets",
|
|
14
|
+
"coding-agent"
|
|
15
|
+
],
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist/extension.d.ts",
|
|
20
|
+
"dist/extension.js",
|
|
21
|
+
"dist/index.d.ts",
|
|
22
|
+
"dist/index.js",
|
|
23
|
+
"dist/runtime.d.ts",
|
|
24
|
+
"dist/runtime.js"
|
|
25
|
+
],
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./extension": {
|
|
35
|
+
"types": "./dist/extension.d.ts",
|
|
36
|
+
"default": "./dist/extension.js"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"pi": {
|
|
40
|
+
"extensions": [
|
|
41
|
+
"./dist/extension.js"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@burmese/agent-events": "3.1.0",
|
|
46
|
+
"@burmese/client": "3.1.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "^25.6.2",
|
|
50
|
+
"typescript": "^6.0.3"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@earendil-works/pi-coding-agent": {
|
|
57
|
+
"optional": true
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"test": "node dist/check-pi.js && node dist/check-pi-compat.js",
|
|
62
|
+
"check": "pnpm typecheck && pnpm build && pnpm test",
|
|
63
|
+
"typecheck": "tsc --noEmit",
|
|
64
|
+
"build": "tsc"
|
|
65
|
+
}
|
|
66
|
+
}
|