@minidoll/agentkit-dsh-plugin 0.1.1 → 0.1.3
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/dist/index.js +42 -63
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -170,46 +170,9 @@ function findProjectRoot(candidates, sessionCwd) {
|
|
|
170
170
|
}
|
|
171
171
|
|
|
172
172
|
// src/inject.ts
|
|
173
|
-
import { randomUUID } from "node:crypto";
|
|
174
173
|
import { existsSync as existsSync4, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "node:fs";
|
|
175
174
|
import { join as join4 } from "node:path";
|
|
176
175
|
var MAX_CONTEXT_BYTES = 900;
|
|
177
|
-
var SOURCE_KIND = "agentkit-context";
|
|
178
|
-
var factoryLoader = null;
|
|
179
|
-
async function loadFactory() {
|
|
180
|
-
factoryLoader ??= (async () => {
|
|
181
|
-
try {
|
|
182
|
-
const pkg = "@deepseek-ai/dsh-llm";
|
|
183
|
-
const mod = await import(pkg);
|
|
184
|
-
return typeof mod.createUserMessage === "function" ? mod.createUserMessage : null;
|
|
185
|
-
} catch {
|
|
186
|
-
return null;
|
|
187
|
-
}
|
|
188
|
-
})();
|
|
189
|
-
return factoryLoader;
|
|
190
|
-
}
|
|
191
|
-
function handcraft(text) {
|
|
192
|
-
return {
|
|
193
|
-
role: "user",
|
|
194
|
-
id: randomUUID(),
|
|
195
|
-
content: [{ type: "text", text }],
|
|
196
|
-
source: { kind: SOURCE_KIND }
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
function assertUserMessage(value) {
|
|
200
|
-
if (typeof value !== "object" || value === null) return false;
|
|
201
|
-
const m = value;
|
|
202
|
-
if (m.role !== "user") return false;
|
|
203
|
-
if (typeof m.id !== "string" || m.id === "") return false;
|
|
204
|
-
const src = m.source;
|
|
205
|
-
if (src === void 0 || src.kind !== SOURCE_KIND) return false;
|
|
206
|
-
const content = m.content;
|
|
207
|
-
if (!Array.isArray(content) || content.length === 0) return false;
|
|
208
|
-
return content.every((b) => {
|
|
209
|
-
const blk = b;
|
|
210
|
-
return blk.type === "text" && typeof blk.text === "string" && blk.text.length > 0;
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
176
|
var INJECT_CONFIG_REL = ".agent/inject.json";
|
|
214
177
|
function injectEnabled(root) {
|
|
215
178
|
if (process.env.AGENTKIT_CONTEXT_INJECT === "1") return true;
|
|
@@ -225,19 +188,35 @@ function injectEnabled(root) {
|
|
|
225
188
|
}
|
|
226
189
|
var injected = /* @__PURE__ */ new Set();
|
|
227
190
|
var PATH_RULES = [
|
|
228
|
-
{
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
{
|
|
191
|
+
{
|
|
192
|
+
pattern: /^contracts\//,
|
|
193
|
+
hint: "\u5951\u7EA6\u53D8\u66F4\uFF1A\u5B9E\u73B0\u5FC5\u987B\u540C\u6B65\uFF08AGENTS \u94C1\u5F8B\uFF09\uFF0C\u5E76\u5728\u4EA4\u63A5\u5355\u58F0\u660E\u5951\u7EA6\u5F71\u54CD\u4E0E\u8BC1\u636E\u7EA7\u522B L1-L4"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
pattern: /^docs\/rules\//,
|
|
197
|
+
hint: "\u89C4\u5219\u6587\u6863\uFF1A\u6539\u5B83\u7B49\u4E8E\u6539\u6240\u6709\u4EBA\u7684\u884C\u4E3A\u7EA6\u675F \u2014\u2014 \u5148\u786E\u8BA4\u4E0E protocol.yml / AGENTS.md \u4E0D\u51B2\u7A81"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
pattern: /^docs\/design\//,
|
|
201
|
+
hint: '\u8BBE\u8BA1\u6587\u6863\uFF1A\u9700\u4E0E codemap \u91CC\u7684\u6A21\u5757\u5BF9\u5E94\uFF08M4 \u4F1A\u6821\u9A8C"\u6587\u6863\u63D0\u5230\u8BE5\u6A21\u5757"\uFF09'
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
pattern: /^\.agent\/decisions\/\d{4}-/,
|
|
205
|
+
hint: "ADR\uFF1Aaccepted \u7684\u6709\u7EA6\u675F\u529B \u2014\u2014 \u8981\u63A8\u7FFB\u5148\u5199\u65B0 ADR \u6807 superseded\uFF0C\u4E0D\u8981\u76F4\u63A5\u6539\u65E7\u7ED3\u8BBA"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
pattern: /^AGENTS\.md$/,
|
|
209
|
+
hint: "AGENTS.md \u662F\u6D3E\u751F\u6587\u4EF6\uFF08\u7531 protocol.yml \u751F\u6210\uFF09\u2014\u2014 \u6539\u5B83\u8BF7\u6539 protocol.yml \u518D akit sync"
|
|
210
|
+
}
|
|
233
211
|
];
|
|
234
212
|
function buildInjectText(input) {
|
|
235
213
|
const lines = [];
|
|
236
214
|
const rels = [];
|
|
237
215
|
if (input.filePath !== void 0 && input.filePath !== "") rels.push(input.filePath);
|
|
238
216
|
for (const p of input.extraPaths ?? []) if (p !== "") rels.push(p);
|
|
217
|
+
const norm = (p) => String(p).replace(/\\/g, "/").replace(/^\.\//, "");
|
|
239
218
|
for (const raw of rels) {
|
|
240
|
-
const rel =
|
|
219
|
+
const rel = norm(raw);
|
|
241
220
|
for (const rule of PATH_RULES) {
|
|
242
221
|
if (rule.pattern.test(rel)) {
|
|
243
222
|
lines.push(`- \u7EAA\u5F8B\uFF1A${rule.hint}`);
|
|
@@ -247,12 +226,12 @@ function buildInjectText(input) {
|
|
|
247
226
|
if (lines.length > 0) break;
|
|
248
227
|
}
|
|
249
228
|
for (const raw of rels) {
|
|
250
|
-
const rel =
|
|
229
|
+
const rel = norm(raw);
|
|
251
230
|
try {
|
|
252
231
|
const cm = join4(input.root, ".agent", "codemap.json");
|
|
253
232
|
if (!existsSync4(cm)) break;
|
|
254
233
|
const map = JSON.parse(readFileSync3(cm, "utf8"));
|
|
255
|
-
const mod = (map.modules ?? []).find((m) =>
|
|
234
|
+
const mod = (map.modules ?? []).find((m) => norm(m.path ?? "") === rel);
|
|
256
235
|
if (mod !== void 0) {
|
|
257
236
|
if (mod.purpose !== void 0 && mod.purpose !== "") lines.push(`- \u6A21\u5757\u804C\u8D23\uFF08codemap\uFF09\uFF1A${mod.purpose}`);
|
|
258
237
|
if (mod.doc !== void 0 && mod.doc !== "") lines.push(`- \u8BBE\u8BA1\u6587\u6863\uFF1A${mod.doc}`);
|
|
@@ -287,16 +266,16 @@ function buildInjectText(input) {
|
|
|
287
266
|
\u2026\uFF08\u5DF2\u622A\u65AD\uFF09`;
|
|
288
267
|
return text;
|
|
289
268
|
}
|
|
290
|
-
async function
|
|
269
|
+
async function buildInjectBlock(input) {
|
|
291
270
|
try {
|
|
292
271
|
if (!injectEnabled(input.root)) {
|
|
293
272
|
input.trace?.("inject skipped: disabled (no .agent/inject.json / env)");
|
|
294
|
-
return { ok: false, reason: "inject disabled
|
|
273
|
+
return { ok: false, reason: "inject disabled" };
|
|
295
274
|
}
|
|
296
275
|
const key = `${input.sessionId ?? ""}|${input.filePath ?? ""}`;
|
|
297
276
|
if (injected.has(key)) {
|
|
298
277
|
input.trace?.("inject skipped: already injected for this session+file");
|
|
299
|
-
return { ok: false, reason: "already injected
|
|
278
|
+
return { ok: false, reason: "already injected" };
|
|
300
279
|
}
|
|
301
280
|
const text = buildInjectText({
|
|
302
281
|
root: input.root,
|
|
@@ -305,19 +284,16 @@ async function buildAdditionalContexts(input) {
|
|
|
305
284
|
});
|
|
306
285
|
if (text === null) {
|
|
307
286
|
input.trace?.("inject skipped: nothing to inject for this path");
|
|
308
|
-
return { ok: false, reason: "nothing to inject
|
|
287
|
+
return { ok: false, reason: "nothing to inject" };
|
|
309
288
|
}
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
return { ok: false, reason: "shape check failed" };
|
|
289
|
+
const block = { type: "text", text };
|
|
290
|
+
if (block.type !== "text" || typeof block.text !== "string" || block.text.length === 0) {
|
|
291
|
+
input.trace?.("inject rejected: bad text block");
|
|
292
|
+
return { ok: false, reason: "bad text block" };
|
|
315
293
|
}
|
|
316
294
|
injected.add(key);
|
|
317
|
-
input.trace?.(
|
|
318
|
-
|
|
319
|
-
);
|
|
320
|
-
return { ok: true, messages: [msg] };
|
|
295
|
+
input.trace?.(`inject ok: ${String(text.length)}B as tool-result content block`);
|
|
296
|
+
return { ok: true, block };
|
|
321
297
|
} catch (err) {
|
|
322
298
|
input.trace?.(`inject skipped: ${err.message}`);
|
|
323
299
|
return { ok: false, reason: err.message };
|
|
@@ -508,13 +484,13 @@ function createProjectHooksPlugin(ctx) {
|
|
|
508
484
|
});
|
|
509
485
|
const filePath = inside[0];
|
|
510
486
|
const sessionId = exec.agent?.session?.id ?? null;
|
|
511
|
-
const r = await
|
|
487
|
+
const r = await buildInjectBlock({
|
|
512
488
|
root,
|
|
513
489
|
...filePath !== void 0 ? { filePath } : {},
|
|
514
490
|
...sessionId !== null ? { sessionId } : {},
|
|
515
491
|
trace: (line) => trace(process.env.DSH_HOME ?? join6(homedir(), ".dsh"), line)
|
|
516
492
|
});
|
|
517
|
-
return r.ok
|
|
493
|
+
return r.ok ? r : null;
|
|
518
494
|
} catch (err) {
|
|
519
495
|
trace(
|
|
520
496
|
process.env.DSH_HOME ?? join6(homedir(), ".dsh"),
|
|
@@ -523,12 +499,15 @@ function createProjectHooksPlugin(ctx) {
|
|
|
523
499
|
return null;
|
|
524
500
|
}
|
|
525
501
|
};
|
|
526
|
-
const handle = async (event, exec) => {
|
|
502
|
+
const handle = async (event, exec, result) => {
|
|
527
503
|
try {
|
|
528
504
|
const decision = await runHooks(event, exec);
|
|
529
505
|
if (event === "PostToolUse" && decision.kind === "allow") {
|
|
530
506
|
const injected2 = await tryInjectContext(exec);
|
|
531
|
-
if (injected2 !== null
|
|
507
|
+
if (injected2 !== null && injected2.block !== void 0) {
|
|
508
|
+
const original = Array.isArray(result?.content) ? result.content.filter((b) => typeof b === "object" && b !== null) : [];
|
|
509
|
+
return { kind: "accept", content: [...original, injected2.block] };
|
|
510
|
+
}
|
|
532
511
|
}
|
|
533
512
|
return decision;
|
|
534
513
|
} catch (err) {
|
|
@@ -654,7 +633,7 @@ function createProjectHooksPlugin(ctx) {
|
|
|
654
633
|
return decision;
|
|
655
634
|
};
|
|
656
635
|
ctx.on("tools/pre-execute", (exec) => handle("PreToolUse", exec));
|
|
657
|
-
ctx.on("tools/post-execute", (exec) => handle("PostToolUse", exec));
|
|
636
|
+
ctx.on("tools/post-execute", (exec, result) => handle("PostToolUse", exec, result));
|
|
658
637
|
return state;
|
|
659
638
|
}
|
|
660
639
|
function apply(ctx) {
|