@hanhnd/agent-kit 1.0.32 → 1.0.33
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/cli/commands/cli-digest-pending.test.js +111 -0
- package/dist/cli/commands/cli-memory.test.js +34 -0
- package/dist/cli/{memory.js → commands/memory.js} +24 -11
- package/dist/cli/index.js +2 -2
- package/dist/{utils → cli/utils}/args.d.ts +2 -1
- package/dist/{kit-cli.js → cli.js} +342 -58
- package/dist/{tools/config.d.ts → core/config/index.d.ts} +2 -7
- package/dist/{tools/config.js → core/config/index.js} +2 -13
- package/dist/core/handoffs/index.d.ts +16 -0
- package/dist/{tools/handoffs.js → core/handoffs/index.js} +3 -3
- package/dist/{tools/security.d.ts → core/security/index.d.ts} +0 -19
- package/dist/{tools/security.js → core/security/index.js} +3 -76
- package/dist/entrypoints/cli.js +11 -0
- package/dist/entrypoints/server.js +37 -0
- package/dist/{tools → mcp}/agent.js +1 -1
- package/dist/{tools → mcp}/core.d.ts +1 -1
- package/dist/{tools → mcp}/core.js +2 -2
- package/dist/{tools → mcp}/integration.js +3 -3
- package/dist/mcp/memory.d.ts +15 -0
- package/dist/{tools → mcp}/memory.js +15 -13
- package/dist/{kit-server.js → server.js} +80 -70
- package/dist/services/digest/background.d.ts +11 -0
- package/dist/services/digest/background.js +258 -0
- package/dist/{memory → services}/digest/constants.d.ts +4 -1
- package/dist/{memory → services}/digest/constants.js +6 -2
- package/dist/services/digest/digest-background.test.js +206 -0
- package/dist/{tools/__tests__ → services/digest}/digest-init.test.js +4 -3
- package/dist/{memory/__tests__ → services/digest}/digest-llama-local.test.js +1 -13
- package/dist/{memory/__tests__ → services/digest}/digest-pending.test.js +39 -11
- package/dist/{memory/__tests__ → services/digest}/digest-processor.test.js +5 -7
- package/dist/{memory → services}/digest/files.d.ts +0 -1
- package/dist/{memory → services}/digest/files.js +2 -2
- package/dist/services/digest/model-registry.d.ts +2 -0
- package/dist/{memory → services}/digest/model-registry.js +9 -8
- package/dist/services/digest/processor.d.ts +13 -0
- package/dist/{memory → services}/digest/processor.js +48 -31
- package/dist/services/digest/providers/llama-local.d.ts +2 -0
- package/dist/{memory → services}/digest/providers/llama-local.js +3 -4
- package/dist/{memory → services}/digest/types.d.ts +34 -2
- package/dist/services/digest/types.js +6 -0
- package/dist/{memory → services}/digest/worker.d.ts +0 -1
- package/dist/{memory → services}/digest/worker.js +2 -2
- package/dist/{utils → services/integration}/credentials.js +1 -1
- package/dist/{utils/parser.js → services/integration/parser/adf.js} +1 -0
- package/dist/{memory → services/memory}/chunker.d.ts +0 -2
- package/dist/{memory → services/memory}/chunker.js +3 -3
- package/dist/{memory/__tests__ → services/memory}/chunker.test.js +1 -34
- package/dist/{memory → services/memory}/constants.d.ts +1 -1
- package/dist/{memory → services/memory}/constants.js +2 -1
- package/dist/{memory → services/memory}/embedder.d.ts +2 -2
- package/dist/{memory → services/memory}/embedder.js +5 -5
- package/dist/services/memory/embedder.test.js +13 -0
- package/dist/{memory → services/memory}/indexer.d.ts +2 -1
- package/dist/{memory → services/memory}/indexer.js +1 -1
- package/dist/{memory/__tests__ → services/memory}/indexer.test.js +4 -3
- package/dist/{tools/__tests__ → services/memory}/memory.test.js +54 -13
- package/dist/{memory/__tests__ → services/memory}/store.test.js +3 -2
- package/dist/{memory → services/memory}/types.d.ts +7 -2
- package/dist/services/memory/types.js +6 -0
- package/dist/utils/files.d.ts +0 -1
- package/dist/utils/files.js +1 -1
- package/dist/{memory/__tests__/lockfile.test.js → utils/files.test.js} +14 -14
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/json.d.ts +0 -1
- package/dist/utils/json.js +0 -10
- package/dist/utils/paths.d.ts +0 -1
- package/dist/utils/paths.js +1 -1
- package/package.json +6 -6
- package/dist/memory/__tests__/digest-worker.test.js +0 -46
- package/dist/memory/__tests__/embedder.test.js +0 -14
- package/dist/memory/digest/model-registry.d.ts +0 -6
- package/dist/memory/digest/processor.d.ts +0 -7
- package/dist/memory/digest/providers/llama-local.d.ts +0 -7
- package/dist/memory/digest/types.js +0 -1
- package/dist/memory/types.js +0 -1
- package/dist/tools/__tests__/cli-digest-pending.test.js +0 -51
- package/dist/tools/__tests__/cli-memory.test.js +0 -22
- package/dist/tools/handoffs.d.ts +0 -22
- package/dist/tools/memory.d.ts +0 -16
- /package/dist/{tools/__tests__ → cli/commands}/cli-digest-pending.test.d.ts +0 -0
- /package/dist/{tools/__tests__ → cli/commands}/cli-memory.test.d.ts +0 -0
- /package/dist/cli/{memory.d.ts → commands/memory.d.ts} +0 -0
- /package/dist/{utils → cli/utils}/args.js +0 -0
- /package/dist/{kit-cli.d.ts → entrypoints/cli.d.ts} +0 -0
- /package/dist/{kit-server.d.ts → entrypoints/server.d.ts} +0 -0
- /package/dist/{tools → mcp}/agent.d.ts +0 -0
- /package/dist/{tools → mcp}/integration.d.ts +0 -0
- /package/dist/{memory/__tests__/chunker.test.d.ts → services/digest/digest-background.test.d.ts} +0 -0
- /package/dist/{tools/__tests__ → services/digest}/digest-init.test.d.ts +0 -0
- /package/dist/{memory/__tests__ → services/digest}/digest-llama-local.test.d.ts +0 -0
- /package/dist/{memory/__tests__ → services/digest}/digest-pending.test.d.ts +0 -0
- /package/dist/{memory/__tests__ → services/digest}/digest-processor.test.d.ts +0 -0
- /package/dist/{utils → services/integration}/credentials.d.ts +0 -0
- /package/dist/{utils/parser.d.ts → services/integration/parser/adf.d.ts} +0 -0
- /package/dist/{memory/__tests__/digest-worker.test.d.ts → services/memory/chunker.test.d.ts} +0 -0
- /package/dist/{memory/__tests__ → services/memory}/embedder.test.d.ts +0 -0
- /package/dist/{memory → services/memory}/index.d.ts +0 -0
- /package/dist/{memory → services/memory}/index.js +0 -0
- /package/dist/{memory/__tests__ → services/memory}/indexer.test.d.ts +0 -0
- /package/dist/{tools/__tests__ → services/memory}/memory.test.d.ts +0 -0
- /package/dist/{memory → services/memory}/store.d.ts +0 -0
- /package/dist/{memory → services/memory}/store.js +0 -0
- /package/dist/{memory/__tests__ → services/memory}/store.test.d.ts +0 -0
- /package/dist/{memory/__tests__/lockfile.test.d.ts → utils/files.test.d.ts} +0 -0
- /package/dist/{__tests__/temp-dir.d.ts → utils/temp-dir.test.d.ts} +0 -0
- /package/dist/{__tests__/temp-dir.js → utils/temp-dir.test.js} +0 -0
|
@@ -35883,7 +35883,7 @@ var StdioServerTransport = class {
|
|
|
35883
35883
|
}
|
|
35884
35884
|
};
|
|
35885
35885
|
|
|
35886
|
-
// src/
|
|
35886
|
+
// src/mcp/core.ts
|
|
35887
35887
|
import * as fs3 from "fs";
|
|
35888
35888
|
import * as path4 from "path";
|
|
35889
35889
|
|
|
@@ -35898,18 +35898,18 @@ function mcpJson(obj) {
|
|
|
35898
35898
|
return mcpText(JSON.stringify(obj, null, 2));
|
|
35899
35899
|
}
|
|
35900
35900
|
|
|
35901
|
-
// src/
|
|
35901
|
+
// src/core/config/index.ts
|
|
35902
35902
|
import * as fs2 from "fs";
|
|
35903
35903
|
import * as path2 from "path";
|
|
35904
35904
|
|
|
35905
|
-
// src/memory/constants.ts
|
|
35905
|
+
// src/services/memory/constants.ts
|
|
35906
35906
|
var DEFAULT_MEMORY_CONFIG = {
|
|
35907
35907
|
enabled: false,
|
|
35908
35908
|
wikiDir: "",
|
|
35909
35909
|
topK: 5,
|
|
35910
35910
|
chunkSize: 1500,
|
|
35911
35911
|
overlapLines: 2,
|
|
35912
|
-
embeddingModel: "
|
|
35912
|
+
embeddingModel: "small" /* SMALL */,
|
|
35913
35913
|
vectorDimension: 384
|
|
35914
35914
|
};
|
|
35915
35915
|
var LOCK_RETRY_MS = 50;
|
|
@@ -35982,7 +35982,7 @@ function tryAcquireProcessLock(lockPath) {
|
|
|
35982
35982
|
return tryWriteFileExclusive(lockPath, lockContent);
|
|
35983
35983
|
}
|
|
35984
35984
|
|
|
35985
|
-
// src/
|
|
35985
|
+
// src/core/config/index.ts
|
|
35986
35986
|
function resolveMemoryConfig(settings2, workspaceRoot2) {
|
|
35987
35987
|
const override = settings2.memory ?? {};
|
|
35988
35988
|
return {
|
|
@@ -36053,7 +36053,7 @@ var FORBIDDEN_PATTERNS = [
|
|
|
36053
36053
|
];
|
|
36054
36054
|
var FORBIDDEN_DIRS = [".git", ".ssh", ".aws", ".kube", ".gnupg", ".docker"];
|
|
36055
36055
|
|
|
36056
|
-
// src/
|
|
36056
|
+
// src/core/handoffs/index.ts
|
|
36057
36057
|
import * as path3 from "path";
|
|
36058
36058
|
var HANDOFF_TYPES = [
|
|
36059
36059
|
"brainstorm",
|
|
@@ -36106,7 +36106,7 @@ function resolveHandoffPath(input) {
|
|
|
36106
36106
|
};
|
|
36107
36107
|
}
|
|
36108
36108
|
|
|
36109
|
-
// src/
|
|
36109
|
+
// src/mcp/core.ts
|
|
36110
36110
|
function registerCoreTools(server2) {
|
|
36111
36111
|
server2.tool(
|
|
36112
36112
|
"kit_save_handoff",
|
|
@@ -36139,13 +36139,13 @@ function registerCoreTools(server2) {
|
|
|
36139
36139
|
);
|
|
36140
36140
|
}
|
|
36141
36141
|
|
|
36142
|
-
// src/
|
|
36142
|
+
// src/mcp/agent.ts
|
|
36143
36143
|
import { spawn } from "child_process";
|
|
36144
36144
|
import { randomUUID } from "crypto";
|
|
36145
36145
|
import * as fs4 from "fs";
|
|
36146
36146
|
import * as path6 from "path";
|
|
36147
36147
|
|
|
36148
|
-
// src/
|
|
36148
|
+
// src/core/security/index.ts
|
|
36149
36149
|
import { execFileSync } from "child_process";
|
|
36150
36150
|
import * as path5 from "path";
|
|
36151
36151
|
function sanitize(input) {
|
|
@@ -36171,7 +36171,6 @@ function validatePath(filePath, baseDir = process.cwd()) {
|
|
|
36171
36171
|
}
|
|
36172
36172
|
return resolved;
|
|
36173
36173
|
}
|
|
36174
|
-
var GIT_TIMEOUT = parseInt(process.env.GEMINI_KIT_GIT_TIMEOUT || "30000", 10);
|
|
36175
36174
|
function commandExists(cmd) {
|
|
36176
36175
|
try {
|
|
36177
36176
|
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
@@ -36196,7 +36195,7 @@ function sanitizeOutput(text) {
|
|
|
36196
36195
|
// AWS access keys
|
|
36197
36196
|
/xox[baprs]-[A-Za-z0-9-]{10,}/g,
|
|
36198
36197
|
// Slack tokens
|
|
36199
|
-
/[Aa]tlassian[_
|
|
36198
|
+
/[Aa]tlassian[_-]?[Aa][Pp][Ii][_-]?[Tt]oken[^\s]*\s*[:=]\s*\S+/g
|
|
36200
36199
|
// Atlassian token patterns
|
|
36201
36200
|
];
|
|
36202
36201
|
let sanitized = text;
|
|
@@ -36206,7 +36205,7 @@ function sanitizeOutput(text) {
|
|
|
36206
36205
|
return sanitized;
|
|
36207
36206
|
}
|
|
36208
36207
|
|
|
36209
|
-
// src/
|
|
36208
|
+
// src/mcp/agent.ts
|
|
36210
36209
|
var AGENT_TIMEOUT = parseInt(process.env.KIT_AGENT_TIMEOUT || "300000", 10);
|
|
36211
36210
|
var jobRegistry = /* @__PURE__ */ new Map();
|
|
36212
36211
|
var INSTALL_HINTS = {
|
|
@@ -36356,10 +36355,10 @@ function registerAgentTools(server2) {
|
|
|
36356
36355
|
);
|
|
36357
36356
|
}
|
|
36358
36357
|
|
|
36359
|
-
// src/
|
|
36358
|
+
// src/mcp/integration.ts
|
|
36360
36359
|
import { writeFileSync as writeFileSync4 } from "fs";
|
|
36361
36360
|
|
|
36362
|
-
// src/
|
|
36361
|
+
// src/services/integration/credentials.ts
|
|
36363
36362
|
import * as fs5 from "fs";
|
|
36364
36363
|
|
|
36365
36364
|
// src/utils/paths.ts
|
|
@@ -36370,7 +36369,7 @@ var CREDENTIALS_FILE = path7.join(AGENT_KIT_HOME, "credentials");
|
|
|
36370
36369
|
var MODEL_CACHE_DIR = path7.join(AGENT_KIT_HOME, "cache", "models");
|
|
36371
36370
|
var FASTEMBED_CACHE_DIR = path7.join(MODEL_CACHE_DIR, "fastembed");
|
|
36372
36371
|
|
|
36373
|
-
// src/
|
|
36372
|
+
// src/services/integration/credentials.ts
|
|
36374
36373
|
var cachedCredentials = null;
|
|
36375
36374
|
function parseIni(content) {
|
|
36376
36375
|
const result = {};
|
|
@@ -36429,7 +36428,7 @@ function getCredential(key) {
|
|
|
36429
36428
|
return loadCredentials()[key];
|
|
36430
36429
|
}
|
|
36431
36430
|
|
|
36432
|
-
// src/
|
|
36431
|
+
// src/services/integration/parser/adf.ts
|
|
36433
36432
|
function adfToMarkdown(adf) {
|
|
36434
36433
|
if (!adf || typeof adf !== "object") return "No description";
|
|
36435
36434
|
const content = adf.content;
|
|
@@ -36551,7 +36550,7 @@ ${renderNodes(node.content, listDepth, node.type).trim()}
|
|
|
36551
36550
|
return renderNodes(content).trim() || "No description";
|
|
36552
36551
|
}
|
|
36553
36552
|
|
|
36554
|
-
// src/
|
|
36553
|
+
// src/mcp/integration.ts
|
|
36555
36554
|
var BitbucketPrSchema = external_exports.object({
|
|
36556
36555
|
id: external_exports.number(),
|
|
36557
36556
|
title: external_exports.string(),
|
|
@@ -36737,10 +36736,10 @@ ${ticket.fields.labels?.join(", ") || "None"}`;
|
|
|
36737
36736
|
);
|
|
36738
36737
|
}
|
|
36739
36738
|
|
|
36740
|
-
// src/
|
|
36739
|
+
// src/mcp/memory.ts
|
|
36741
36740
|
import * as path14 from "path";
|
|
36742
36741
|
|
|
36743
|
-
// src/memory/embedder.ts
|
|
36742
|
+
// src/services/memory/embedder.ts
|
|
36744
36743
|
var EmbedderError = class extends Error {
|
|
36745
36744
|
constructor(message, cause) {
|
|
36746
36745
|
super(message);
|
|
@@ -36786,9 +36785,9 @@ var Embedder = class {
|
|
|
36786
36785
|
try {
|
|
36787
36786
|
const { EmbeddingModel, FlagEmbedding } = await import("fastembed");
|
|
36788
36787
|
const modelMap = {
|
|
36789
|
-
"
|
|
36790
|
-
"
|
|
36791
|
-
"
|
|
36788
|
+
["tiny" /* TINY */]: EmbeddingModel.AllMiniLML6V2,
|
|
36789
|
+
["small" /* SMALL */]: EmbeddingModel.BGESmallENV15,
|
|
36790
|
+
["large" /* LARGE */]: EmbeddingModel.BGEBaseENV15
|
|
36792
36791
|
};
|
|
36793
36792
|
const model = modelMap[this.modelName] ?? EmbeddingModel.BGESmallENV15;
|
|
36794
36793
|
const embedder = await FlagEmbedding.init({
|
|
@@ -36811,7 +36810,7 @@ var Embedder = class {
|
|
|
36811
36810
|
}
|
|
36812
36811
|
};
|
|
36813
36812
|
|
|
36814
|
-
// src/memory/indexer.ts
|
|
36813
|
+
// src/services/memory/indexer.ts
|
|
36815
36814
|
import * as fs6 from "fs";
|
|
36816
36815
|
import * as path8 from "path";
|
|
36817
36816
|
|
|
@@ -36821,7 +36820,7 @@ function sha256Hex(content) {
|
|
|
36821
36820
|
return createHash("sha256").update(content).digest("hex");
|
|
36822
36821
|
}
|
|
36823
36822
|
|
|
36824
|
-
// src/memory/chunker.ts
|
|
36823
|
+
// src/services/memory/chunker.ts
|
|
36825
36824
|
function computeChunkId(content) {
|
|
36826
36825
|
return sha256Hex(content).slice(0, 16);
|
|
36827
36826
|
}
|
|
@@ -36952,7 +36951,7 @@ ${sectionText}` : sectionText;
|
|
|
36952
36951
|
return chunks;
|
|
36953
36952
|
}
|
|
36954
36953
|
|
|
36955
|
-
// src/memory/indexer.ts
|
|
36954
|
+
// src/services/memory/indexer.ts
|
|
36956
36955
|
var MemoryIndexer = class {
|
|
36957
36956
|
constructor(store, embedder, config2) {
|
|
36958
36957
|
this.store = store;
|
|
@@ -37135,7 +37134,7 @@ ${content}
|
|
|
37135
37134
|
}
|
|
37136
37135
|
};
|
|
37137
37136
|
|
|
37138
|
-
// src/memory/store.ts
|
|
37137
|
+
// src/services/memory/store.ts
|
|
37139
37138
|
var import_stopword = __toESM(require_stopword_cjs(), 1);
|
|
37140
37139
|
import Database from "better-sqlite3";
|
|
37141
37140
|
import * as fs7 from "fs";
|
|
@@ -37381,25 +37380,28 @@ var MemoryStore = class {
|
|
|
37381
37380
|
}
|
|
37382
37381
|
};
|
|
37383
37382
|
|
|
37384
|
-
// src/
|
|
37383
|
+
// src/services/digest/processor.ts
|
|
37385
37384
|
import * as fs10 from "node:fs";
|
|
37386
37385
|
import * as path13 from "node:path";
|
|
37387
37386
|
|
|
37388
|
-
// src/
|
|
37387
|
+
// src/services/digest/constants.ts
|
|
37389
37388
|
import * as path10 from "node:path";
|
|
37390
|
-
var DEFAULT_DIGEST_MODEL_ID = "
|
|
37389
|
+
var DEFAULT_DIGEST_MODEL_ID = "default" /* DEFAULT */;
|
|
37391
37390
|
var DEFAULT_DIGEST_MAX_INPUT_CHARS = 3e3;
|
|
37392
37391
|
var DEFAULT_DIGEST_TIMEOUT_MS = 12e4;
|
|
37393
37392
|
var KIT_DIR = ".agent-kit";
|
|
37394
37393
|
var WIKI_DIR = path10.join(KIT_DIR, "wiki");
|
|
37395
37394
|
var WIKI_RAW_DIR = path10.join(WIKI_DIR, "raw");
|
|
37396
37395
|
var PROVISIONAL_DIGEST_DIR = path10.join(WIKI_DIR, "compiled", "provisional", "conversation-digests");
|
|
37397
|
-
var
|
|
37396
|
+
var DIGEST_WORKER_DIR = path10.join(WIKI_DIR, "digest");
|
|
37397
|
+
var DIGEST_LOCKFILE_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.lock");
|
|
37398
|
+
var DIGEST_WORKER_STATUS_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.status.json");
|
|
37399
|
+
var DIGEST_WORKER_LOG_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.log");
|
|
37398
37400
|
var LLAMA_CONTEXT_SIZE = 4096;
|
|
37399
37401
|
var LLAMA_MAX_GENERATED_TOKENS = 512;
|
|
37400
37402
|
var LLAMA_TEMPERATURE = 0.1;
|
|
37401
37403
|
|
|
37402
|
-
// src/
|
|
37404
|
+
// src/services/digest/files.ts
|
|
37403
37405
|
import * as fs8 from "node:fs";
|
|
37404
37406
|
import * as path11 from "node:path";
|
|
37405
37407
|
function defaultProvisionalDigestDir(workspaceRoot2) {
|
|
@@ -37439,7 +37441,7 @@ function writeConversationDigestSettings(workspaceRoot2, digest) {
|
|
|
37439
37441
|
});
|
|
37440
37442
|
}
|
|
37441
37443
|
|
|
37442
|
-
// src/
|
|
37444
|
+
// src/services/digest/model-registry.ts
|
|
37443
37445
|
var DigestModelRegistryError = class extends Error {
|
|
37444
37446
|
constructor(message) {
|
|
37445
37447
|
super(message);
|
|
@@ -37447,24 +37449,24 @@ var DigestModelRegistryError = class extends Error {
|
|
|
37447
37449
|
}
|
|
37448
37450
|
};
|
|
37449
37451
|
var DIGEST_MODEL_REGISTRY = {
|
|
37450
|
-
"
|
|
37451
|
-
id: "
|
|
37452
|
+
["tiny" /* TINY */]: {
|
|
37453
|
+
id: "tiny" /* TINY */,
|
|
37452
37454
|
ggufUri: "hf:bartowski/Qwen2.5-0.5B-Instruct-GGUF/Qwen2.5-0.5B-Instruct-Q4_K_M.gguf",
|
|
37453
37455
|
approxSizeBytes: 4e8,
|
|
37454
37456
|
license: "Apache-2.0",
|
|
37455
37457
|
sourceUrl: "https://huggingface.co/bartowski/Qwen2.5-0.5B-Instruct-GGUF",
|
|
37456
37458
|
enabled: true
|
|
37457
37459
|
},
|
|
37458
|
-
"
|
|
37459
|
-
id: "
|
|
37460
|
+
["default" /* DEFAULT */]: {
|
|
37461
|
+
id: "default" /* DEFAULT */,
|
|
37460
37462
|
ggufUri: "hf:bartowski/Qwen2.5-1.5B-Instruct-GGUF/Qwen2.5-1.5B-Instruct-Q4_K_M.gguf",
|
|
37461
37463
|
approxSizeBytes: 1e9,
|
|
37462
37464
|
license: "Apache-2.0",
|
|
37463
37465
|
sourceUrl: "https://huggingface.co/bartowski/Qwen2.5-1.5B-Instruct-GGUF",
|
|
37464
37466
|
enabled: true
|
|
37465
37467
|
},
|
|
37466
|
-
"
|
|
37467
|
-
id: "
|
|
37468
|
+
["large" /* LARGE */]: {
|
|
37469
|
+
id: "large" /* LARGE */,
|
|
37468
37470
|
ggufUri: "hf:bartowski/Qwen2.5-3B-Instruct-GGUF/Qwen2.5-3B-Instruct-Q4_K_M.gguf",
|
|
37469
37471
|
approxSizeBytes: 19e8,
|
|
37470
37472
|
license: "Apache-2.0",
|
|
@@ -37489,7 +37491,7 @@ function getDigestModelSpec(modelId) {
|
|
|
37489
37491
|
return spec;
|
|
37490
37492
|
}
|
|
37491
37493
|
|
|
37492
|
-
// src/
|
|
37494
|
+
// src/services/digest/providers/llama-local.ts
|
|
37493
37495
|
import * as fs9 from "node:fs";
|
|
37494
37496
|
import * as path12 from "node:path";
|
|
37495
37497
|
import { getLlama, LlamaChatSession, createModelDownloader } from "node-llama-cpp";
|
|
@@ -37509,7 +37511,7 @@ async function withTimeout(promise, timeoutMs, createError) {
|
|
|
37509
37511
|
}
|
|
37510
37512
|
}
|
|
37511
37513
|
|
|
37512
|
-
// src/
|
|
37514
|
+
// src/services/digest/providers/llama-local.ts
|
|
37513
37515
|
var LlamaLocalDigestProviderError = class extends Error {
|
|
37514
37516
|
constructor(message) {
|
|
37515
37517
|
super(message);
|
|
@@ -37529,7 +37531,6 @@ function trimConversationExport(content, maxInputChars) {
|
|
|
37529
37531
|
}
|
|
37530
37532
|
function buildPrompt(input, maxInputChars) {
|
|
37531
37533
|
const conversationExport = trimConversationExport(input.content, maxInputChars);
|
|
37532
|
-
const sourceName = path12.basename(input.sourcePath);
|
|
37533
37534
|
return [
|
|
37534
37535
|
{
|
|
37535
37536
|
role: "system",
|
|
@@ -37637,10 +37638,32 @@ async function createLlamaLocalDigestProvider(modelId) {
|
|
|
37637
37638
|
};
|
|
37638
37639
|
}
|
|
37639
37640
|
|
|
37640
|
-
// src/
|
|
37641
|
+
// src/services/digest/processor.ts
|
|
37641
37642
|
function digestLockPath(workspaceRoot2) {
|
|
37642
37643
|
return path13.join(workspaceRoot2, DIGEST_LOCKFILE_REL_PATH);
|
|
37643
37644
|
}
|
|
37645
|
+
function discoverPendingConversationFiles(workspaceRoot2) {
|
|
37646
|
+
const rawDir = path13.join(workspaceRoot2, WIKI_RAW_DIR);
|
|
37647
|
+
let files;
|
|
37648
|
+
try {
|
|
37649
|
+
files = fs10.readdirSync(rawDir).filter((f) => f.startsWith("conv_") && f.endsWith(".md")).map((f) => path13.join(rawDir, f)).sort((a, b) => fs10.statSync(a).mtimeMs - fs10.statSync(b).mtimeMs);
|
|
37650
|
+
} catch (err) {
|
|
37651
|
+
if (err.code === "ENOENT") {
|
|
37652
|
+
files = [];
|
|
37653
|
+
} else {
|
|
37654
|
+
throw err;
|
|
37655
|
+
}
|
|
37656
|
+
}
|
|
37657
|
+
const outDir = defaultProvisionalDigestDir(workspaceRoot2);
|
|
37658
|
+
return files.filter((f) => {
|
|
37659
|
+
try {
|
|
37660
|
+
const input = readConversationDigestInput(workspaceRoot2, f);
|
|
37661
|
+
return !findExistingProvisionalDigest(outDir, input);
|
|
37662
|
+
} catch {
|
|
37663
|
+
return false;
|
|
37664
|
+
}
|
|
37665
|
+
});
|
|
37666
|
+
}
|
|
37644
37667
|
async function indexProvisionalDigestFile(workspaceRoot2, markdownPath) {
|
|
37645
37668
|
try {
|
|
37646
37669
|
const settings2 = loadProjectSettings(workspaceRoot2);
|
|
@@ -37692,7 +37715,8 @@ async function digestConversationFile(options) {
|
|
|
37692
37715
|
}
|
|
37693
37716
|
async function digestPendingConversations({
|
|
37694
37717
|
workspaceRoot: workspaceRoot2,
|
|
37695
|
-
digestFn = digestConversationFile
|
|
37718
|
+
digestFn = digestConversationFile,
|
|
37719
|
+
onProgress
|
|
37696
37720
|
}) {
|
|
37697
37721
|
const digestConfig = resolveConversationDigestConfig(loadProjectSettings(workspaceRoot2));
|
|
37698
37722
|
if (!digestConfig || digestConfig.enabled === false) {
|
|
@@ -37703,26 +37727,7 @@ async function digestPendingConversations({
|
|
|
37703
37727
|
return { ok: true, initialized: true, action: "noop", reason: "locked" };
|
|
37704
37728
|
}
|
|
37705
37729
|
try {
|
|
37706
|
-
const
|
|
37707
|
-
let files;
|
|
37708
|
-
try {
|
|
37709
|
-
files = fs10.readdirSync(rawDir).filter((f) => f.startsWith("conv_") && f.endsWith(".md")).map((f) => path13.join(rawDir, f)).sort((a, b) => fs10.statSync(a).mtimeMs - fs10.statSync(b).mtimeMs);
|
|
37710
|
-
} catch (err) {
|
|
37711
|
-
if (err.code === "ENOENT") {
|
|
37712
|
-
files = [];
|
|
37713
|
-
} else {
|
|
37714
|
-
throw err;
|
|
37715
|
-
}
|
|
37716
|
-
}
|
|
37717
|
-
const outDir = defaultProvisionalDigestDir(workspaceRoot2);
|
|
37718
|
-
const candidates = files.filter((f) => {
|
|
37719
|
-
try {
|
|
37720
|
-
const input = readConversationDigestInput(workspaceRoot2, f);
|
|
37721
|
-
return !findExistingProvisionalDigest(outDir, input);
|
|
37722
|
-
} catch {
|
|
37723
|
-
return false;
|
|
37724
|
-
}
|
|
37725
|
-
});
|
|
37730
|
+
const candidates = discoverPendingConversationFiles(workspaceRoot2);
|
|
37726
37731
|
if (candidates.length === 0) {
|
|
37727
37732
|
return { ok: true, initialized: true, action: "noop", reason: "no-pending" };
|
|
37728
37733
|
}
|
|
@@ -37744,6 +37749,9 @@ async function digestPendingConversations({
|
|
|
37744
37749
|
} catch {
|
|
37745
37750
|
errors++;
|
|
37746
37751
|
}
|
|
37752
|
+
if (onProgress) {
|
|
37753
|
+
await onProgress({ processed: count, skipped, errors });
|
|
37754
|
+
}
|
|
37747
37755
|
}
|
|
37748
37756
|
return { ok: true, initialized: true, action: "digested", count, skipped, errors };
|
|
37749
37757
|
} catch (err) {
|
|
@@ -37788,7 +37796,7 @@ async function initializeConversationDigestModel(input) {
|
|
|
37788
37796
|
}
|
|
37789
37797
|
}
|
|
37790
37798
|
|
|
37791
|
-
// src/
|
|
37799
|
+
// src/mcp/memory.ts
|
|
37792
37800
|
function registerMemoryToolHandlers(server2, indexer, store, config2, workspaceRoot2 = process.cwd()) {
|
|
37793
37801
|
server2.tool(
|
|
37794
37802
|
"kit_memory_search",
|
|
@@ -37868,17 +37876,19 @@ ${content}`;
|
|
|
37868
37876
|
}
|
|
37869
37877
|
);
|
|
37870
37878
|
}
|
|
37871
|
-
function registerMemoryTools(server2, settings2, workspaceRoot2) {
|
|
37879
|
+
function registerMemoryTools(server2, settings2, workspaceRoot2, overrides) {
|
|
37872
37880
|
if (settings2.memory?.enabled !== true) return null;
|
|
37873
|
-
const config2 = resolveMemoryConfig(settings2, workspaceRoot2);
|
|
37874
|
-
const store = new MemoryStore(path14.join(config2.wikiDir, "index.db"), config2);
|
|
37875
|
-
const
|
|
37876
|
-
|
|
37881
|
+
const config2 = overrides?.config ?? resolveMemoryConfig(settings2, workspaceRoot2);
|
|
37882
|
+
const store = overrides?.store ?? new MemoryStore(path14.join(config2.wikiDir, "index.db"), config2);
|
|
37883
|
+
const indexer = overrides?.indexer ?? (() => {
|
|
37884
|
+
const embedder = new Embedder(config2.embeddingModel);
|
|
37885
|
+
return new MemoryIndexer(store, embedder, config2);
|
|
37886
|
+
})();
|
|
37877
37887
|
registerMemoryToolHandlers(server2, indexer, store, config2, workspaceRoot2);
|
|
37878
37888
|
return indexer;
|
|
37879
37889
|
}
|
|
37880
37890
|
|
|
37881
|
-
// src/
|
|
37891
|
+
// src/entrypoints/server.ts
|
|
37882
37892
|
var server = new McpServer({
|
|
37883
37893
|
name: "kit-agents",
|
|
37884
37894
|
version: "1.0.0"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DigestPendingLauncherResult, DigestWorkerStatus, DigestFileOptions, ProvisionalDigestResult } from './types.js';
|
|
2
|
+
export declare function runDigestPendingWorker(input: {
|
|
3
|
+
workspaceRoot: string;
|
|
4
|
+
pendingAtStart?: number;
|
|
5
|
+
digestFn?: (opts: DigestFileOptions) => Promise<ProvisionalDigestResult>;
|
|
6
|
+
}): Promise<DigestWorkerStatus>;
|
|
7
|
+
export declare function launchDigestPendingWorker(input: {
|
|
8
|
+
workspaceRoot: string;
|
|
9
|
+
args: string[];
|
|
10
|
+
entrypoint: string | undefined;
|
|
11
|
+
}): DigestPendingLauncherResult;
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { DIGEST_LOCKFILE_REL_PATH, DIGEST_WORKER_FLAG, DIGEST_WORKER_LOG_REL_PATH, DIGEST_WORKER_STATUS_REL_PATH, } from './constants.js';
|
|
5
|
+
import { digestPendingConversations, summarizePendingConversations } from './processor.js';
|
|
6
|
+
import { atomicWriteJsonFile } from '../../utils/files.js';
|
|
7
|
+
import { isRecord } from '../../utils/json.js';
|
|
8
|
+
function digestWorkerStatusPath(workspaceRoot) {
|
|
9
|
+
return path.join(workspaceRoot, DIGEST_WORKER_STATUS_REL_PATH);
|
|
10
|
+
}
|
|
11
|
+
function digestWorkerLogPath(workspaceRoot) {
|
|
12
|
+
return path.join(workspaceRoot, DIGEST_WORKER_LOG_REL_PATH);
|
|
13
|
+
}
|
|
14
|
+
function digestWorkerLockPath(workspaceRoot) {
|
|
15
|
+
return path.join(workspaceRoot, DIGEST_LOCKFILE_REL_PATH);
|
|
16
|
+
}
|
|
17
|
+
function isoNow() {
|
|
18
|
+
return new Date().toISOString();
|
|
19
|
+
}
|
|
20
|
+
function errorMessage(err) {
|
|
21
|
+
return err instanceof Error ? err.message : String(err);
|
|
22
|
+
}
|
|
23
|
+
function emptyStatus(state, pendingAtStart, startedAt = isoNow()) {
|
|
24
|
+
return {
|
|
25
|
+
state,
|
|
26
|
+
pid: null,
|
|
27
|
+
startedAt,
|
|
28
|
+
updatedAt: startedAt,
|
|
29
|
+
pendingAtStart,
|
|
30
|
+
processed: 0,
|
|
31
|
+
skipped: 0,
|
|
32
|
+
errors: 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const WORKER_STATES = new Set([
|
|
36
|
+
'running',
|
|
37
|
+
'complete',
|
|
38
|
+
'failed',
|
|
39
|
+
'not-initialized',
|
|
40
|
+
'no-pending',
|
|
41
|
+
'locked',
|
|
42
|
+
'stale',
|
|
43
|
+
]);
|
|
44
|
+
function isDigestWorkerStatus(value) {
|
|
45
|
+
if (!isRecord(value))
|
|
46
|
+
return false;
|
|
47
|
+
return (typeof value.state === 'string' &&
|
|
48
|
+
WORKER_STATES.has(value.state) &&
|
|
49
|
+
(typeof value.pid === 'number' || value.pid === null) &&
|
|
50
|
+
typeof value.startedAt === 'string' &&
|
|
51
|
+
typeof value.updatedAt === 'string' &&
|
|
52
|
+
typeof value.pendingAtStart === 'number' &&
|
|
53
|
+
typeof value.processed === 'number' &&
|
|
54
|
+
typeof value.skipped === 'number' &&
|
|
55
|
+
typeof value.errors === 'number' &&
|
|
56
|
+
(value.lastError === undefined || typeof value.lastError === 'string'));
|
|
57
|
+
}
|
|
58
|
+
function readDigestWorkerStatus(workspaceRoot) {
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(fs.readFileSync(digestWorkerStatusPath(workspaceRoot), 'utf8'));
|
|
61
|
+
return isDigestWorkerStatus(parsed) ? parsed : undefined;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function writeDigestWorkerStatus(workspaceRoot, status) {
|
|
68
|
+
atomicWriteJsonFile(digestWorkerStatusPath(workspaceRoot), status);
|
|
69
|
+
}
|
|
70
|
+
function appendDigestWorkerLog(workspaceRoot, message) {
|
|
71
|
+
try {
|
|
72
|
+
const logPath = digestWorkerLogPath(workspaceRoot);
|
|
73
|
+
fs.mkdirSync(path.dirname(logPath), { recursive: true });
|
|
74
|
+
fs.appendFileSync(logPath, `[${isoNow()}] ${message}\n`, 'utf8');
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Diagnostics must never block hook startup or worker completion.
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function isLivePid(pid) {
|
|
81
|
+
if (pid === null || !Number.isInteger(pid) || pid <= 0)
|
|
82
|
+
return false;
|
|
83
|
+
try {
|
|
84
|
+
process.kill(pid, 0);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
return err.code !== 'ESRCH';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function readLockPid(workspaceRoot) {
|
|
92
|
+
const lockPath = digestWorkerLockPath(workspaceRoot);
|
|
93
|
+
if (!fs.existsSync(lockPath))
|
|
94
|
+
return undefined;
|
|
95
|
+
try {
|
|
96
|
+
const parsed = JSON.parse(fs.readFileSync(lockPath, 'utf8'));
|
|
97
|
+
return isRecord(parsed) && typeof parsed.pid === 'number' ? parsed.pid : null;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function statusFromPendingResult(result, startedAt, pendingAtStart) {
|
|
104
|
+
const updatedAt = isoNow();
|
|
105
|
+
if (!result.ok) {
|
|
106
|
+
return {
|
|
107
|
+
...emptyStatus('failed', pendingAtStart, startedAt),
|
|
108
|
+
updatedAt,
|
|
109
|
+
errors: 1,
|
|
110
|
+
lastError: result.error,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (result.action === 'digested') {
|
|
114
|
+
return {
|
|
115
|
+
state: 'complete',
|
|
116
|
+
pid: null,
|
|
117
|
+
startedAt,
|
|
118
|
+
updatedAt,
|
|
119
|
+
pendingAtStart,
|
|
120
|
+
processed: result.count,
|
|
121
|
+
skipped: result.skipped,
|
|
122
|
+
errors: result.errors,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
...emptyStatus(result.reason, pendingAtStart, startedAt),
|
|
127
|
+
updatedAt,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
export async function runDigestPendingWorker(input) {
|
|
131
|
+
const startedAt = isoNow();
|
|
132
|
+
let pendingAtStart = input.pendingAtStart ?? 0;
|
|
133
|
+
try {
|
|
134
|
+
const summary = summarizePendingConversations(input.workspaceRoot);
|
|
135
|
+
if (input.pendingAtStart === undefined) {
|
|
136
|
+
pendingAtStart = summary.initialized ? summary.pending : 0;
|
|
137
|
+
}
|
|
138
|
+
const runningStatus = {
|
|
139
|
+
...emptyStatus('running', pendingAtStart, startedAt),
|
|
140
|
+
pid: process.pid,
|
|
141
|
+
};
|
|
142
|
+
writeDigestWorkerStatus(input.workspaceRoot, runningStatus);
|
|
143
|
+
appendDigestWorkerLog(input.workspaceRoot, `worker started pid=${process.pid} pending=${pendingAtStart}`);
|
|
144
|
+
const result = await digestPendingConversations({
|
|
145
|
+
workspaceRoot: input.workspaceRoot,
|
|
146
|
+
digestFn: input.digestFn,
|
|
147
|
+
onProgress: (progress) => {
|
|
148
|
+
const currentStatus = {
|
|
149
|
+
...runningStatus,
|
|
150
|
+
updatedAt: isoNow(),
|
|
151
|
+
processed: progress.processed,
|
|
152
|
+
skipped: progress.skipped,
|
|
153
|
+
errors: progress.errors,
|
|
154
|
+
};
|
|
155
|
+
writeDigestWorkerStatus(input.workspaceRoot, currentStatus);
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
const status = statusFromPendingResult(result, startedAt, pendingAtStart);
|
|
159
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
160
|
+
appendDigestWorkerLog(input.workspaceRoot, `worker finished state=${status.state} processed=${status.processed} skipped=${status.skipped} errors=${status.errors}`);
|
|
161
|
+
return status;
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
const status = {
|
|
165
|
+
...emptyStatus('failed', pendingAtStart, startedAt),
|
|
166
|
+
updatedAt: isoNow(),
|
|
167
|
+
errors: 1,
|
|
168
|
+
lastError: errorMessage(err),
|
|
169
|
+
};
|
|
170
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
171
|
+
appendDigestWorkerLog(input.workspaceRoot, `worker failed error=${status.lastError}`);
|
|
172
|
+
return status;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export function launchDigestPendingWorker(input) {
|
|
176
|
+
const startedAt = isoNow();
|
|
177
|
+
let pendingAtStart = 0;
|
|
178
|
+
try {
|
|
179
|
+
const previousStatus = readDigestWorkerStatus(input.workspaceRoot);
|
|
180
|
+
if (previousStatus?.state === 'running' && isLivePid(previousStatus.pid)) {
|
|
181
|
+
const status = {
|
|
182
|
+
...previousStatus,
|
|
183
|
+
state: 'locked',
|
|
184
|
+
updatedAt: isoNow(),
|
|
185
|
+
lastError: undefined,
|
|
186
|
+
};
|
|
187
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
188
|
+
return { ok: true, mode: 'background-launcher', status, spawned: false, reason: 'locked' };
|
|
189
|
+
}
|
|
190
|
+
const lockPid = readLockPid(input.workspaceRoot);
|
|
191
|
+
if (lockPid !== undefined && isLivePid(lockPid)) {
|
|
192
|
+
const status = emptyStatus('locked', 0, startedAt);
|
|
193
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
194
|
+
return { ok: true, mode: 'background-launcher', status, spawned: false, reason: 'locked' };
|
|
195
|
+
}
|
|
196
|
+
const summary = summarizePendingConversations(input.workspaceRoot);
|
|
197
|
+
if (!summary.initialized) {
|
|
198
|
+
const status = emptyStatus('not-initialized', 0, startedAt);
|
|
199
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
200
|
+
return { ok: true, mode: 'background-launcher', status, spawned: false, reason: 'not-initialized' };
|
|
201
|
+
}
|
|
202
|
+
if (summary.pending === 0) {
|
|
203
|
+
const status = emptyStatus('no-pending', 0, startedAt);
|
|
204
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
205
|
+
return { ok: true, mode: 'background-launcher', status, spawned: false, reason: 'no-pending' };
|
|
206
|
+
}
|
|
207
|
+
pendingAtStart = summary.pending;
|
|
208
|
+
if (!input.entrypoint) {
|
|
209
|
+
const status = {
|
|
210
|
+
...emptyStatus('failed', pendingAtStart, startedAt),
|
|
211
|
+
errors: 1,
|
|
212
|
+
lastError: 'CLI entrypoint is unavailable',
|
|
213
|
+
};
|
|
214
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
215
|
+
return {
|
|
216
|
+
ok: false,
|
|
217
|
+
mode: 'background-launcher',
|
|
218
|
+
status,
|
|
219
|
+
spawned: false,
|
|
220
|
+
reason: 'spawn-failed',
|
|
221
|
+
error: status.lastError,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
const child = spawn(process.execPath, [input.entrypoint, 'memory', 'digest-pending', ...input.args, `--${DIGEST_WORKER_FLAG}`], {
|
|
225
|
+
cwd: input.workspaceRoot,
|
|
226
|
+
detached: true,
|
|
227
|
+
stdio: 'ignore',
|
|
228
|
+
});
|
|
229
|
+
child.unref();
|
|
230
|
+
if (!child.pid) {
|
|
231
|
+
throw new Error('worker process did not expose a pid');
|
|
232
|
+
}
|
|
233
|
+
const status = {
|
|
234
|
+
...emptyStatus('running', pendingAtStart, startedAt),
|
|
235
|
+
pid: child.pid,
|
|
236
|
+
};
|
|
237
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
238
|
+
appendDigestWorkerLog(input.workspaceRoot, `launcher spawned pid=${child.pid} pending=${pendingAtStart}`);
|
|
239
|
+
return { ok: true, mode: 'background-launcher', status, spawned: true, pid: child.pid };
|
|
240
|
+
}
|
|
241
|
+
catch (err) {
|
|
242
|
+
const status = {
|
|
243
|
+
...emptyStatus('failed', pendingAtStart, startedAt),
|
|
244
|
+
errors: 1,
|
|
245
|
+
lastError: errorMessage(err),
|
|
246
|
+
};
|
|
247
|
+
writeDigestWorkerStatus(input.workspaceRoot, status);
|
|
248
|
+
appendDigestWorkerLog(input.workspaceRoot, `launcher failed error=${status.lastError}`);
|
|
249
|
+
return {
|
|
250
|
+
ok: false,
|
|
251
|
+
mode: 'background-launcher',
|
|
252
|
+
status,
|
|
253
|
+
spawned: false,
|
|
254
|
+
reason: 'spawn-failed',
|
|
255
|
+
error: status.lastError,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|