@hanhnd/agent-kit 1.0.32 → 1.0.34

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 (111) hide show
  1. package/dist/cli/commands/cli-digest-pending.test.js +111 -0
  2. package/dist/cli/commands/cli-memory.test.js +34 -0
  3. package/dist/cli/{memory.js → commands/memory.js} +24 -11
  4. package/dist/cli/index.js +2 -2
  5. package/dist/{utils → cli/utils}/args.d.ts +2 -1
  6. package/dist/{kit-cli.js → cli.js} +342 -58
  7. package/dist/{tools/config.d.ts → core/config/index.d.ts} +2 -7
  8. package/dist/{tools/config.js → core/config/index.js} +2 -13
  9. package/dist/core/handoffs/index.d.ts +17 -0
  10. package/dist/{tools/handoffs.js → core/handoffs/index.js} +15 -7
  11. package/dist/core/handoffs/index.test.js +88 -0
  12. package/dist/{tools/security.d.ts → core/security/index.d.ts} +0 -19
  13. package/dist/{tools/security.js → core/security/index.js} +3 -76
  14. package/dist/entrypoints/cli.js +11 -0
  15. package/dist/entrypoints/server.js +37 -0
  16. package/dist/{tools → mcp}/agent.d.ts +1 -1
  17. package/dist/{tools → mcp}/agent.js +4 -4
  18. package/dist/mcp/core.d.ts +17 -0
  19. package/dist/mcp/core.js +60 -0
  20. package/dist/mcp/core.test.js +98 -0
  21. package/dist/{tools → mcp}/integration.js +3 -3
  22. package/dist/mcp/memory.d.ts +15 -0
  23. package/dist/{tools → mcp}/memory.js +15 -13
  24. package/dist/{kit-server.js → server.js} +129 -98
  25. package/dist/services/digest/background.d.ts +11 -0
  26. package/dist/services/digest/background.js +258 -0
  27. package/dist/{memory → services}/digest/constants.d.ts +4 -1
  28. package/dist/{memory → services}/digest/constants.js +6 -2
  29. package/dist/services/digest/digest-background.test.js +206 -0
  30. package/dist/{tools/__tests__ → services/digest}/digest-init.test.js +4 -3
  31. package/dist/{memory/__tests__ → services/digest}/digest-llama-local.test.js +1 -13
  32. package/dist/{memory/__tests__ → services/digest}/digest-pending.test.js +39 -11
  33. package/dist/{memory/__tests__ → services/digest}/digest-processor.test.js +5 -7
  34. package/dist/{memory → services}/digest/files.d.ts +0 -1
  35. package/dist/{memory → services}/digest/files.js +2 -2
  36. package/dist/services/digest/model-registry.d.ts +2 -0
  37. package/dist/{memory → services}/digest/model-registry.js +9 -8
  38. package/dist/services/digest/processor.d.ts +13 -0
  39. package/dist/{memory → services}/digest/processor.js +48 -31
  40. package/dist/services/digest/providers/llama-local.d.ts +2 -0
  41. package/dist/{memory → services}/digest/providers/llama-local.js +3 -4
  42. package/dist/{memory → services}/digest/types.d.ts +34 -2
  43. package/dist/services/digest/types.js +6 -0
  44. package/dist/{memory → services}/digest/worker.d.ts +0 -1
  45. package/dist/{memory → services}/digest/worker.js +2 -2
  46. package/dist/{utils → services/integration}/credentials.js +1 -1
  47. package/dist/{utils/parser.js → services/integration/parser/adf.js} +1 -0
  48. package/dist/{memory → services/memory}/chunker.d.ts +0 -2
  49. package/dist/{memory → services/memory}/chunker.js +3 -3
  50. package/dist/{memory/__tests__ → services/memory}/chunker.test.js +1 -34
  51. package/dist/{memory → services/memory}/constants.d.ts +1 -1
  52. package/dist/{memory → services/memory}/constants.js +2 -1
  53. package/dist/{memory → services/memory}/embedder.d.ts +2 -2
  54. package/dist/{memory → services/memory}/embedder.js +5 -5
  55. package/dist/services/memory/embedder.test.js +13 -0
  56. package/dist/{memory → services/memory}/indexer.d.ts +2 -1
  57. package/dist/{memory → services/memory}/indexer.js +1 -1
  58. package/dist/{memory/__tests__ → services/memory}/indexer.test.js +4 -3
  59. package/dist/{tools/__tests__ → services/memory}/memory.test.js +54 -13
  60. package/dist/{memory/__tests__ → services/memory}/store.test.js +3 -2
  61. package/dist/{memory → services/memory}/types.d.ts +7 -2
  62. package/dist/services/memory/types.js +6 -0
  63. package/dist/utils/files.d.ts +0 -1
  64. package/dist/utils/files.js +1 -1
  65. package/dist/{memory/__tests__/lockfile.test.js → utils/files.test.js} +14 -14
  66. package/dist/utils/index.d.ts +6 -0
  67. package/dist/utils/index.js +6 -0
  68. package/dist/utils/json.d.ts +0 -1
  69. package/dist/utils/json.js +0 -10
  70. package/dist/utils/paths.d.ts +0 -1
  71. package/dist/utils/paths.js +1 -1
  72. package/package.json +6 -6
  73. package/dist/memory/__tests__/digest-worker.test.js +0 -46
  74. package/dist/memory/__tests__/embedder.test.js +0 -14
  75. package/dist/memory/digest/model-registry.d.ts +0 -6
  76. package/dist/memory/digest/processor.d.ts +0 -7
  77. package/dist/memory/digest/providers/llama-local.d.ts +0 -7
  78. package/dist/tools/__tests__/cli-digest-pending.test.js +0 -51
  79. package/dist/tools/__tests__/cli-memory.test.js +0 -22
  80. package/dist/tools/core.d.ts +0 -10
  81. package/dist/tools/core.js +0 -46
  82. package/dist/tools/handoffs.d.ts +0 -22
  83. package/dist/tools/memory.d.ts +0 -16
  84. /package/dist/{tools/__tests__ → cli/commands}/cli-digest-pending.test.d.ts +0 -0
  85. /package/dist/{tools/__tests__ → cli/commands}/cli-memory.test.d.ts +0 -0
  86. /package/dist/cli/{memory.d.ts → commands/memory.d.ts} +0 -0
  87. /package/dist/{utils → cli/utils}/args.js +0 -0
  88. /package/dist/{memory/__tests__/chunker.test.d.ts → core/handoffs/index.test.d.ts} +0 -0
  89. /package/dist/{kit-cli.d.ts → entrypoints/cli.d.ts} +0 -0
  90. /package/dist/{kit-server.d.ts → entrypoints/server.d.ts} +0 -0
  91. /package/dist/{memory/__tests__/digest-llama-local.test.d.ts → mcp/core.test.d.ts} +0 -0
  92. /package/dist/{tools → mcp}/integration.d.ts +0 -0
  93. /package/dist/{memory/__tests__/digest-pending.test.d.ts → services/digest/digest-background.test.d.ts} +0 -0
  94. /package/dist/{tools/__tests__ → services/digest}/digest-init.test.d.ts +0 -0
  95. /package/dist/{memory/__tests__/digest-processor.test.d.ts → services/digest/digest-llama-local.test.d.ts} +0 -0
  96. /package/dist/{memory/__tests__/digest-worker.test.d.ts → services/digest/digest-pending.test.d.ts} +0 -0
  97. /package/dist/{memory/__tests__/embedder.test.d.ts → services/digest/digest-processor.test.d.ts} +0 -0
  98. /package/dist/{utils → services/integration}/credentials.d.ts +0 -0
  99. /package/dist/{utils/parser.d.ts → services/integration/parser/adf.d.ts} +0 -0
  100. /package/dist/{memory/__tests__/indexer.test.d.ts → services/memory/chunker.test.d.ts} +0 -0
  101. /package/dist/{memory/__tests__/lockfile.test.d.ts → services/memory/embedder.test.d.ts} +0 -0
  102. /package/dist/{memory → services/memory}/index.d.ts +0 -0
  103. /package/dist/{memory → services/memory}/index.js +0 -0
  104. /package/dist/{memory/__tests__/store.test.d.ts → services/memory/indexer.test.d.ts} +0 -0
  105. /package/dist/{tools/__tests__ → services/memory}/memory.test.d.ts +0 -0
  106. /package/dist/{memory → services/memory}/store.d.ts +0 -0
  107. /package/dist/{memory → services/memory}/store.js +0 -0
  108. /package/dist/{memory/digest/types.js → services/memory/store.test.d.ts} +0 -0
  109. /package/dist/{memory/types.js → utils/files.test.d.ts} +0 -0
  110. /package/dist/{__tests__/temp-dir.d.ts → utils/temp-dir.test.d.ts} +0 -0
  111. /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/tools/core.ts
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/tools/config.ts
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: "Xenova/bge-small-en-v1.5",
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/tools/config.ts
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/tools/handoffs.ts
36056
+ // src/core/handoffs/index.ts
36057
36057
  import * as path3 from "path";
36058
36058
  var HANDOFF_TYPES = [
36059
36059
  "brainstorm",
@@ -36062,7 +36062,8 @@ var HANDOFF_TYPES = [
36062
36062
  "ticket",
36063
36063
  "research",
36064
36064
  "scenario",
36065
- "investigation"
36065
+ "investigation",
36066
+ "code"
36066
36067
  ];
36067
36068
  var TICKET_ID_PATTERN = /\b[A-Z][A-Z0-9]+-\d+\b/;
36068
36069
  function findTicketId(value) {
@@ -36090,62 +36091,82 @@ function deriveFeatureSlug(input) {
36090
36091
  if (contentTicketSlug) return contentTicketSlug;
36091
36092
  return sanitizeFeatureSlug(contentSlugCandidate(input.content)) || "untitled-handoff";
36092
36093
  }
36093
- function resolveHandoffPath(input) {
36094
+ function resolveHandoffFolder(input) {
36094
36095
  const canonicalType = normalizeHandoffType(input.type);
36095
36096
  const featureSlug = deriveFeatureSlug({
36096
36097
  requestedSlug: input.slug,
36097
- content: input.content,
36098
+ content: input.primaryContent,
36098
36099
  type: canonicalType
36099
36100
  });
36100
- const relativePath = path3.join(".agent-kit", "handoffs", featureSlug, `${canonicalType}.md`);
36101
+ const relativePath = path3.join(".agent-kit", "handoffs", featureSlug, canonicalType);
36101
36102
  return {
36102
36103
  featureSlug,
36103
36104
  canonicalType,
36104
- filePath: path3.join(input.workspaceRoot, relativePath),
36105
+ folderPath: path3.join(input.workspaceRoot, relativePath),
36105
36106
  relativePath
36106
36107
  };
36107
36108
  }
36109
+ function validateHandoffFilename(name) {
36110
+ const normalized = name.trim().replace(/^["']|["']$/g, "");
36111
+ if (!/^[A-Za-z0-9_-]+\.md$/.test(normalized)) {
36112
+ throw new Error(`Unsafe handoff filename: ${name}`);
36113
+ }
36114
+ return normalized;
36115
+ }
36108
36116
 
36109
- // src/tools/core.ts
36117
+ // src/mcp/core.ts
36118
+ function handleSaveHandoff(args, workspaceRoot2) {
36119
+ try {
36120
+ if (Object.keys(args.files).length === 0) {
36121
+ return mcpText("Error saving handoff: files cannot be empty");
36122
+ }
36123
+ for (const name of Object.keys(args.files)) {
36124
+ try {
36125
+ validateHandoffFilename(name);
36126
+ } catch (err) {
36127
+ return mcpText(`Error saving handoff: ${err instanceof Error ? err.message : err}`);
36128
+ }
36129
+ }
36130
+ const primaryContent = args.files["README.md"] ?? Object.values(args.files)[0];
36131
+ const location = resolveHandoffFolder({
36132
+ workspaceRoot: workspaceRoot2,
36133
+ type: args.type,
36134
+ slug: args.slug,
36135
+ primaryContent
36136
+ });
36137
+ fs3.mkdirSync(location.folderPath, { recursive: true });
36138
+ for (const [name, content] of Object.entries(args.files)) {
36139
+ fs3.writeFileSync(path4.join(location.folderPath, name), content, "utf8");
36140
+ }
36141
+ return mcpText(`\u2705 Saved to: ${location.folderPath}`);
36142
+ } catch (error2) {
36143
+ return mcpText(`Error saving handoff: ${error2 instanceof Error ? error2.message : error2}`);
36144
+ }
36145
+ }
36110
36146
  function registerCoreTools(server2) {
36111
36147
  server2.tool(
36112
36148
  "kit_save_handoff",
36113
- `Save a handoff artifact to .agent-kit/handoffs/. Returns the saved file path to use in next-step instructions. Do NOT append version numbers (v2, v3, etc.) to the slug.`,
36149
+ `Save a handoff artifact to .agent-kit/handoffs/. Returns the saved folder path to use in next-step instructions. Do NOT append version numbers (v2, v3, etc.) to the slug.`,
36114
36150
  {
36115
36151
  type: external_exports.enum(HANDOFF_TYPES).describe("Handoff type"),
36116
- content: external_exports.string().describe("Full markdown content to save"),
36152
+ files: external_exports.record(external_exports.string(), external_exports.string()).describe(
36153
+ "Markdown files to write into the handoff folder. May include one or many files per call; repeated calls with the same type and slug add or overwrite the provided files. Filenames must match /^[A-Za-z0-9_-]+\\.md$/."
36154
+ ),
36117
36155
  slug: external_exports.string().describe(
36118
- 'Short identifier for the filename, e.g. "user-auth" or "PROJ-123". Do NOT append version numbers (v2, v3, etc.).'
36156
+ 'Short identifier for the folder, e.g. "user-auth" or "PROJ-123". Do NOT append version numbers (v2, v3, etc.).'
36119
36157
  )
36120
36158
  },
36121
- async ({ type, content, slug }) => {
36122
- try {
36123
- const location = resolveHandoffPath({
36124
- workspaceRoot: getWorkspaceRoot(),
36125
- type,
36126
- slug,
36127
- content
36128
- });
36129
- const handoffDir = path4.dirname(location.filePath);
36130
- if (!fs3.existsSync(handoffDir)) {
36131
- fs3.mkdirSync(handoffDir, { recursive: true });
36132
- }
36133
- fs3.writeFileSync(location.filePath, content, "utf8");
36134
- return mcpText(`\u2705 Saved to: ${location.filePath}`);
36135
- } catch (error2) {
36136
- return mcpText(`Error saving handoff: ${error2}`);
36137
- }
36138
- }
36159
+ async (args) => handleSaveHandoff(args, getWorkspaceRoot())
36139
36160
  );
36140
36161
  }
36141
36162
 
36142
- // src/tools/agent.ts
36163
+ // src/mcp/agent.ts
36143
36164
  import { spawn } from "child_process";
36144
36165
  import { randomUUID } from "crypto";
36145
36166
  import * as fs4 from "fs";
36146
36167
  import * as path6 from "path";
36147
36168
 
36148
- // src/tools/security.ts
36169
+ // src/core/security/index.ts
36149
36170
  import { execFileSync } from "child_process";
36150
36171
  import * as path5 from "path";
36151
36172
  function sanitize(input) {
@@ -36171,7 +36192,6 @@ function validatePath(filePath, baseDir = process.cwd()) {
36171
36192
  }
36172
36193
  return resolved;
36173
36194
  }
36174
- var GIT_TIMEOUT = parseInt(process.env.GEMINI_KIT_GIT_TIMEOUT || "30000", 10);
36175
36195
  function commandExists(cmd) {
36176
36196
  try {
36177
36197
  const checkCmd = process.platform === "win32" ? "where" : "which";
@@ -36196,7 +36216,7 @@ function sanitizeOutput(text) {
36196
36216
  // AWS access keys
36197
36217
  /xox[baprs]-[A-Za-z0-9-]{10,}/g,
36198
36218
  // Slack tokens
36199
- /[Aa]tlassian[_\-]?[Aa][Pp][Ii][_\-]?[Tt]oken[^\s]*\s*[:=]\s*\S+/g
36219
+ /[Aa]tlassian[_-]?[Aa][Pp][Ii][_-]?[Tt]oken[^\s]*\s*[:=]\s*\S+/g
36200
36220
  // Atlassian token patterns
36201
36221
  ];
36202
36222
  let sanitized = text;
@@ -36206,7 +36226,7 @@ function sanitizeOutput(text) {
36206
36226
  return sanitized;
36207
36227
  }
36208
36228
 
36209
- // src/tools/agent.ts
36229
+ // src/mcp/agent.ts
36210
36230
  var AGENT_TIMEOUT = parseInt(process.env.KIT_AGENT_TIMEOUT || "300000", 10);
36211
36231
  var jobRegistry = /* @__PURE__ */ new Map();
36212
36232
  var INSTALL_HINTS = {
@@ -36246,10 +36266,10 @@ ${"\u2500".repeat(60)}
36246
36266
  function registerAgentTools(server2) {
36247
36267
  server2.tool(
36248
36268
  "kit_trigger_agent",
36249
- "!Important: Trigger only when user explicitly asks to delegate a task to an external agent CLI (gemini, claude, or codex). The task can be a direct message or a path to a handoff file (.agent-kit/handoffs/feature-slug/plan.md).",
36269
+ "!Important: Trigger only when user explicitly asks to delegate a task to an external agent CLI (gemini, claude, or codex). The task can be a direct message or a path to a handoff folder (.agent-kit/handoffs/feature-slug/plan).",
36250
36270
  {
36251
36271
  agent: external_exports.enum(["gemini", "claude", "codex"]).describe('The agent CLI to invoke: "gemini", "claude", or "codex"'),
36252
- task: external_exports.string().describe('Task message or path to a handoff file (e.g., ".agent-kit/handoffs/feature-slug/plan.md")')
36272
+ task: external_exports.string().describe('Task message or path to a handoff folder (e.g., ".agent-kit/handoffs/feature-slug/plan")')
36253
36273
  },
36254
36274
  async ({ agent, task }, extra) => {
36255
36275
  const workspaceRoot2 = getWorkspaceRoot();
@@ -36356,10 +36376,10 @@ function registerAgentTools(server2) {
36356
36376
  );
36357
36377
  }
36358
36378
 
36359
- // src/tools/integration.ts
36379
+ // src/mcp/integration.ts
36360
36380
  import { writeFileSync as writeFileSync4 } from "fs";
36361
36381
 
36362
- // src/utils/credentials.ts
36382
+ // src/services/integration/credentials.ts
36363
36383
  import * as fs5 from "fs";
36364
36384
 
36365
36385
  // src/utils/paths.ts
@@ -36370,7 +36390,7 @@ var CREDENTIALS_FILE = path7.join(AGENT_KIT_HOME, "credentials");
36370
36390
  var MODEL_CACHE_DIR = path7.join(AGENT_KIT_HOME, "cache", "models");
36371
36391
  var FASTEMBED_CACHE_DIR = path7.join(MODEL_CACHE_DIR, "fastembed");
36372
36392
 
36373
- // src/utils/credentials.ts
36393
+ // src/services/integration/credentials.ts
36374
36394
  var cachedCredentials = null;
36375
36395
  function parseIni(content) {
36376
36396
  const result = {};
@@ -36429,7 +36449,7 @@ function getCredential(key) {
36429
36449
  return loadCredentials()[key];
36430
36450
  }
36431
36451
 
36432
- // src/utils/parser.ts
36452
+ // src/services/integration/parser/adf.ts
36433
36453
  function adfToMarkdown(adf) {
36434
36454
  if (!adf || typeof adf !== "object") return "No description";
36435
36455
  const content = adf.content;
@@ -36551,7 +36571,7 @@ ${renderNodes(node.content, listDepth, node.type).trim()}
36551
36571
  return renderNodes(content).trim() || "No description";
36552
36572
  }
36553
36573
 
36554
- // src/tools/integration.ts
36574
+ // src/mcp/integration.ts
36555
36575
  var BitbucketPrSchema = external_exports.object({
36556
36576
  id: external_exports.number(),
36557
36577
  title: external_exports.string(),
@@ -36737,10 +36757,10 @@ ${ticket.fields.labels?.join(", ") || "None"}`;
36737
36757
  );
36738
36758
  }
36739
36759
 
36740
- // src/tools/memory.ts
36760
+ // src/mcp/memory.ts
36741
36761
  import * as path14 from "path";
36742
36762
 
36743
- // src/memory/embedder.ts
36763
+ // src/services/memory/embedder.ts
36744
36764
  var EmbedderError = class extends Error {
36745
36765
  constructor(message, cause) {
36746
36766
  super(message);
@@ -36786,9 +36806,9 @@ var Embedder = class {
36786
36806
  try {
36787
36807
  const { EmbeddingModel, FlagEmbedding } = await import("fastembed");
36788
36808
  const modelMap = {
36789
- "Xenova/bge-small-en-v1.5": EmbeddingModel.BGESmallENV15,
36790
- "Xenova/bge-base-en-v1.5": EmbeddingModel.BGEBaseENV15,
36791
- "Xenova/all-MiniLM-L6-v2": EmbeddingModel.AllMiniLML6V2
36809
+ ["tiny" /* TINY */]: EmbeddingModel.AllMiniLML6V2,
36810
+ ["small" /* SMALL */]: EmbeddingModel.BGESmallENV15,
36811
+ ["large" /* LARGE */]: EmbeddingModel.BGEBaseENV15
36792
36812
  };
36793
36813
  const model = modelMap[this.modelName] ?? EmbeddingModel.BGESmallENV15;
36794
36814
  const embedder = await FlagEmbedding.init({
@@ -36811,7 +36831,7 @@ var Embedder = class {
36811
36831
  }
36812
36832
  };
36813
36833
 
36814
- // src/memory/indexer.ts
36834
+ // src/services/memory/indexer.ts
36815
36835
  import * as fs6 from "fs";
36816
36836
  import * as path8 from "path";
36817
36837
 
@@ -36821,7 +36841,7 @@ function sha256Hex(content) {
36821
36841
  return createHash("sha256").update(content).digest("hex");
36822
36842
  }
36823
36843
 
36824
- // src/memory/chunker.ts
36844
+ // src/services/memory/chunker.ts
36825
36845
  function computeChunkId(content) {
36826
36846
  return sha256Hex(content).slice(0, 16);
36827
36847
  }
@@ -36952,7 +36972,7 @@ ${sectionText}` : sectionText;
36952
36972
  return chunks;
36953
36973
  }
36954
36974
 
36955
- // src/memory/indexer.ts
36975
+ // src/services/memory/indexer.ts
36956
36976
  var MemoryIndexer = class {
36957
36977
  constructor(store, embedder, config2) {
36958
36978
  this.store = store;
@@ -37135,7 +37155,7 @@ ${content}
37135
37155
  }
37136
37156
  };
37137
37157
 
37138
- // src/memory/store.ts
37158
+ // src/services/memory/store.ts
37139
37159
  var import_stopword = __toESM(require_stopword_cjs(), 1);
37140
37160
  import Database from "better-sqlite3";
37141
37161
  import * as fs7 from "fs";
@@ -37381,25 +37401,28 @@ var MemoryStore = class {
37381
37401
  }
37382
37402
  };
37383
37403
 
37384
- // src/memory/digest/processor.ts
37404
+ // src/services/digest/processor.ts
37385
37405
  import * as fs10 from "node:fs";
37386
37406
  import * as path13 from "node:path";
37387
37407
 
37388
- // src/memory/digest/constants.ts
37408
+ // src/services/digest/constants.ts
37389
37409
  import * as path10 from "node:path";
37390
- var DEFAULT_DIGEST_MODEL_ID = "qwen2.5-1.5b-instruct-q4";
37410
+ var DEFAULT_DIGEST_MODEL_ID = "default" /* DEFAULT */;
37391
37411
  var DEFAULT_DIGEST_MAX_INPUT_CHARS = 3e3;
37392
37412
  var DEFAULT_DIGEST_TIMEOUT_MS = 12e4;
37393
37413
  var KIT_DIR = ".agent-kit";
37394
37414
  var WIKI_DIR = path10.join(KIT_DIR, "wiki");
37395
37415
  var WIKI_RAW_DIR = path10.join(WIKI_DIR, "raw");
37396
37416
  var PROVISIONAL_DIGEST_DIR = path10.join(WIKI_DIR, "compiled", "provisional", "conversation-digests");
37397
- var DIGEST_LOCKFILE_REL_PATH = path10.join(KIT_DIR, "digest-worker.lock");
37417
+ var DIGEST_WORKER_DIR = path10.join(WIKI_DIR, "digest");
37418
+ var DIGEST_LOCKFILE_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.lock");
37419
+ var DIGEST_WORKER_STATUS_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.status.json");
37420
+ var DIGEST_WORKER_LOG_REL_PATH = path10.join(DIGEST_WORKER_DIR, "digest-worker.log");
37398
37421
  var LLAMA_CONTEXT_SIZE = 4096;
37399
37422
  var LLAMA_MAX_GENERATED_TOKENS = 512;
37400
37423
  var LLAMA_TEMPERATURE = 0.1;
37401
37424
 
37402
- // src/memory/digest/files.ts
37425
+ // src/services/digest/files.ts
37403
37426
  import * as fs8 from "node:fs";
37404
37427
  import * as path11 from "node:path";
37405
37428
  function defaultProvisionalDigestDir(workspaceRoot2) {
@@ -37439,7 +37462,7 @@ function writeConversationDigestSettings(workspaceRoot2, digest) {
37439
37462
  });
37440
37463
  }
37441
37464
 
37442
- // src/memory/digest/model-registry.ts
37465
+ // src/services/digest/model-registry.ts
37443
37466
  var DigestModelRegistryError = class extends Error {
37444
37467
  constructor(message) {
37445
37468
  super(message);
@@ -37447,24 +37470,24 @@ var DigestModelRegistryError = class extends Error {
37447
37470
  }
37448
37471
  };
37449
37472
  var DIGEST_MODEL_REGISTRY = {
37450
- "qwen2.5-0.5b-instruct-q4": {
37451
- id: "qwen2.5-0.5b-instruct-q4",
37473
+ ["tiny" /* TINY */]: {
37474
+ id: "tiny" /* TINY */,
37452
37475
  ggufUri: "hf:bartowski/Qwen2.5-0.5B-Instruct-GGUF/Qwen2.5-0.5B-Instruct-Q4_K_M.gguf",
37453
37476
  approxSizeBytes: 4e8,
37454
37477
  license: "Apache-2.0",
37455
37478
  sourceUrl: "https://huggingface.co/bartowski/Qwen2.5-0.5B-Instruct-GGUF",
37456
37479
  enabled: true
37457
37480
  },
37458
- "qwen2.5-1.5b-instruct-q4": {
37459
- id: "qwen2.5-1.5b-instruct-q4",
37481
+ ["default" /* DEFAULT */]: {
37482
+ id: "default" /* DEFAULT */,
37460
37483
  ggufUri: "hf:bartowski/Qwen2.5-1.5B-Instruct-GGUF/Qwen2.5-1.5B-Instruct-Q4_K_M.gguf",
37461
37484
  approxSizeBytes: 1e9,
37462
37485
  license: "Apache-2.0",
37463
37486
  sourceUrl: "https://huggingface.co/bartowski/Qwen2.5-1.5B-Instruct-GGUF",
37464
37487
  enabled: true
37465
37488
  },
37466
- "qwen2.5-3b-instruct-q4": {
37467
- id: "qwen2.5-3b-instruct-q4",
37489
+ ["large" /* LARGE */]: {
37490
+ id: "large" /* LARGE */,
37468
37491
  ggufUri: "hf:bartowski/Qwen2.5-3B-Instruct-GGUF/Qwen2.5-3B-Instruct-Q4_K_M.gguf",
37469
37492
  approxSizeBytes: 19e8,
37470
37493
  license: "Apache-2.0",
@@ -37489,7 +37512,7 @@ function getDigestModelSpec(modelId) {
37489
37512
  return spec;
37490
37513
  }
37491
37514
 
37492
- // src/memory/digest/providers/llama-local.ts
37515
+ // src/services/digest/providers/llama-local.ts
37493
37516
  import * as fs9 from "node:fs";
37494
37517
  import * as path12 from "node:path";
37495
37518
  import { getLlama, LlamaChatSession, createModelDownloader } from "node-llama-cpp";
@@ -37509,7 +37532,7 @@ async function withTimeout(promise, timeoutMs, createError) {
37509
37532
  }
37510
37533
  }
37511
37534
 
37512
- // src/memory/digest/providers/llama-local.ts
37535
+ // src/services/digest/providers/llama-local.ts
37513
37536
  var LlamaLocalDigestProviderError = class extends Error {
37514
37537
  constructor(message) {
37515
37538
  super(message);
@@ -37529,7 +37552,6 @@ function trimConversationExport(content, maxInputChars) {
37529
37552
  }
37530
37553
  function buildPrompt(input, maxInputChars) {
37531
37554
  const conversationExport = trimConversationExport(input.content, maxInputChars);
37532
- const sourceName = path12.basename(input.sourcePath);
37533
37555
  return [
37534
37556
  {
37535
37557
  role: "system",
@@ -37637,10 +37659,32 @@ async function createLlamaLocalDigestProvider(modelId) {
37637
37659
  };
37638
37660
  }
37639
37661
 
37640
- // src/memory/digest/processor.ts
37662
+ // src/services/digest/processor.ts
37641
37663
  function digestLockPath(workspaceRoot2) {
37642
37664
  return path13.join(workspaceRoot2, DIGEST_LOCKFILE_REL_PATH);
37643
37665
  }
37666
+ function discoverPendingConversationFiles(workspaceRoot2) {
37667
+ const rawDir = path13.join(workspaceRoot2, WIKI_RAW_DIR);
37668
+ let files;
37669
+ try {
37670
+ 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);
37671
+ } catch (err) {
37672
+ if (err.code === "ENOENT") {
37673
+ files = [];
37674
+ } else {
37675
+ throw err;
37676
+ }
37677
+ }
37678
+ const outDir = defaultProvisionalDigestDir(workspaceRoot2);
37679
+ return files.filter((f) => {
37680
+ try {
37681
+ const input = readConversationDigestInput(workspaceRoot2, f);
37682
+ return !findExistingProvisionalDigest(outDir, input);
37683
+ } catch {
37684
+ return false;
37685
+ }
37686
+ });
37687
+ }
37644
37688
  async function indexProvisionalDigestFile(workspaceRoot2, markdownPath) {
37645
37689
  try {
37646
37690
  const settings2 = loadProjectSettings(workspaceRoot2);
@@ -37692,7 +37736,8 @@ async function digestConversationFile(options) {
37692
37736
  }
37693
37737
  async function digestPendingConversations({
37694
37738
  workspaceRoot: workspaceRoot2,
37695
- digestFn = digestConversationFile
37739
+ digestFn = digestConversationFile,
37740
+ onProgress
37696
37741
  }) {
37697
37742
  const digestConfig = resolveConversationDigestConfig(loadProjectSettings(workspaceRoot2));
37698
37743
  if (!digestConfig || digestConfig.enabled === false) {
@@ -37703,26 +37748,7 @@ async function digestPendingConversations({
37703
37748
  return { ok: true, initialized: true, action: "noop", reason: "locked" };
37704
37749
  }
37705
37750
  try {
37706
- const rawDir = path13.join(workspaceRoot2, WIKI_RAW_DIR);
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
- });
37751
+ const candidates = discoverPendingConversationFiles(workspaceRoot2);
37726
37752
  if (candidates.length === 0) {
37727
37753
  return { ok: true, initialized: true, action: "noop", reason: "no-pending" };
37728
37754
  }
@@ -37744,6 +37770,9 @@ async function digestPendingConversations({
37744
37770
  } catch {
37745
37771
  errors++;
37746
37772
  }
37773
+ if (onProgress) {
37774
+ await onProgress({ processed: count, skipped, errors });
37775
+ }
37747
37776
  }
37748
37777
  return { ok: true, initialized: true, action: "digested", count, skipped, errors };
37749
37778
  } catch (err) {
@@ -37788,7 +37817,7 @@ async function initializeConversationDigestModel(input) {
37788
37817
  }
37789
37818
  }
37790
37819
 
37791
- // src/tools/memory.ts
37820
+ // src/mcp/memory.ts
37792
37821
  function registerMemoryToolHandlers(server2, indexer, store, config2, workspaceRoot2 = process.cwd()) {
37793
37822
  server2.tool(
37794
37823
  "kit_memory_search",
@@ -37868,17 +37897,19 @@ ${content}`;
37868
37897
  }
37869
37898
  );
37870
37899
  }
37871
- function registerMemoryTools(server2, settings2, workspaceRoot2) {
37900
+ function registerMemoryTools(server2, settings2, workspaceRoot2, overrides) {
37872
37901
  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 embedder = new Embedder(config2.embeddingModel);
37876
- const indexer = new MemoryIndexer(store, embedder, config2);
37902
+ const config2 = overrides?.config ?? resolveMemoryConfig(settings2, workspaceRoot2);
37903
+ const store = overrides?.store ?? new MemoryStore(path14.join(config2.wikiDir, "index.db"), config2);
37904
+ const indexer = overrides?.indexer ?? (() => {
37905
+ const embedder = new Embedder(config2.embeddingModel);
37906
+ return new MemoryIndexer(store, embedder, config2);
37907
+ })();
37877
37908
  registerMemoryToolHandlers(server2, indexer, store, config2, workspaceRoot2);
37878
37909
  return indexer;
37879
37910
  }
37880
37911
 
37881
- // src/kit-server.ts
37912
+ // src/entrypoints/server.ts
37882
37913
  var server = new McpServer({
37883
37914
  name: "kit-agents",
37884
37915
  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;