@hanhnd/agent-kit 1.0.31 → 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/commands/memory.d.ts +1 -0
- package/dist/cli/commands/memory.js +90 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +9 -0
- package/dist/cli/utils/args.d.ts +8 -0
- package/dist/cli/utils/args.js +31 -0
- package/dist/cli.js +16489 -0
- package/dist/{tools/config.d.ts → core/config/index.d.ts} +4 -9
- package/dist/{tools/config.js → core/config/index.js} +20 -23
- package/dist/core/handoffs/index.d.ts +16 -0
- package/dist/{tools/handoffs.js → core/handoffs/index.js} +4 -5
- package/dist/{tools/security.d.ts → core/security/index.d.ts} +0 -19
- package/dist/{tools/security.js → core/security/index.js} +3 -80
- package/dist/entrypoints/cli.d.ts +2 -0
- package/dist/entrypoints/cli.js +11 -0
- package/dist/entrypoints/server.js +37 -0
- package/dist/{tools → mcp}/agent.js +3 -14
- package/dist/{tools → mcp}/core.d.ts +1 -1
- package/dist/{tools → mcp}/core.js +3 -5
- package/dist/{tools → mcp}/integration.js +5 -11
- package/dist/mcp/memory.d.ts +15 -0
- package/dist/{tools → mcp}/memory.js +40 -12
- package/dist/{kit-server.js → server.js} +720 -224
- package/dist/services/digest/background.d.ts +11 -0
- package/dist/services/digest/background.js +258 -0
- package/dist/services/digest/constants.d.ts +17 -0
- package/dist/services/digest/constants.js +19 -0
- package/dist/services/digest/digest-background.test.js +206 -0
- package/dist/services/digest/digest-init.test.js +33 -0
- package/dist/services/digest/digest-llama-local.test.js +21 -0
- package/dist/services/digest/digest-pending.test.d.ts +1 -0
- package/dist/services/digest/digest-pending.test.js +192 -0
- package/dist/services/digest/digest-processor.test.d.ts +1 -0
- package/dist/services/digest/digest-processor.test.js +32 -0
- package/dist/services/digest/files.d.ts +6 -0
- package/dist/services/digest/files.js +45 -0
- package/dist/services/digest/model-registry.d.ts +2 -0
- package/dist/services/digest/model-registry.js +49 -0
- package/dist/services/digest/processor.d.ts +13 -0
- package/dist/services/digest/processor.js +188 -0
- package/dist/services/digest/providers/llama-local.d.ts +2 -0
- package/dist/services/digest/providers/llama-local.js +135 -0
- package/dist/services/digest/types.d.ts +117 -0
- package/dist/services/digest/types.js +6 -0
- package/dist/services/digest/worker.d.ts +2 -0
- package/dist/services/digest/worker.js +51 -0
- package/dist/{utils → services/integration}/credentials.js +1 -1
- package/dist/{utils/parser.js → services/integration/parser/adf.js} +3 -6
- package/dist/{memory → services/memory}/chunker.d.ts +0 -2
- package/dist/{memory → services/memory}/chunker.js +5 -7
- package/dist/services/memory/chunker.test.d.ts +1 -0
- package/dist/{memory/__tests__ → services/memory}/chunker.test.js +1 -34
- package/dist/services/memory/constants.d.ts +5 -0
- package/dist/services/memory/constants.js +13 -0
- package/dist/{memory → services/memory}/embedder.d.ts +3 -2
- package/dist/{memory → services/memory}/embedder.js +15 -6
- package/dist/services/memory/embedder.test.d.ts +1 -0
- package/dist/services/memory/embedder.test.js +13 -0
- package/dist/{memory → services/memory}/index.d.ts +1 -1
- package/dist/{memory → services/memory}/index.js +1 -1
- package/dist/{memory → services/memory}/indexer.d.ts +6 -2
- package/dist/{memory → services/memory}/indexer.js +15 -37
- package/dist/services/memory/indexer.test.d.ts +1 -0
- package/dist/{memory/__tests__ → services/memory}/indexer.test.js +11 -15
- package/dist/services/memory/memory.test.d.ts +1 -0
- package/dist/{tools/__tests__ → services/memory}/memory.test.js +82 -19
- package/dist/{memory → services/memory}/store.js +6 -18
- package/dist/services/memory/store.test.d.ts +1 -0
- package/dist/{memory/__tests__ → services/memory}/store.test.js +18 -5
- package/dist/{memory → services/memory}/types.d.ts +8 -2
- package/dist/services/memory/types.js +6 -0
- package/dist/utils/async.d.ts +1 -0
- package/dist/utils/async.js +15 -0
- package/dist/utils/files.d.ts +7 -0
- package/dist/utils/files.js +77 -0
- package/dist/utils/files.test.d.ts +1 -0
- package/dist/utils/files.test.js +81 -0
- package/dist/utils/hash.d.ts +1 -0
- package/dist/utils/hash.js +4 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/json.d.ts +1 -0
- package/dist/utils/json.js +3 -0
- package/dist/utils/paths.d.ts +0 -1
- package/dist/utils/paths.js +1 -1
- package/dist/utils/temp-dir.test.d.ts +4 -0
- package/dist/utils/temp-dir.test.js +20 -0
- package/package.json +8 -6
- package/dist/memory/__tests__/embedder.test.js +0 -14
- package/dist/memory/types.js +0 -9
- package/dist/tools/handoffs.d.ts +0 -22
- package/dist/tools/memory.d.ts +0 -16
- /package/dist/{memory/__tests__/chunker.test.d.ts → cli/commands/cli-digest-pending.test.d.ts} +0 -0
- /package/dist/{memory/__tests__/embedder.test.d.ts → cli/commands/cli-memory.test.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__/indexer.test.d.ts → services/digest/digest-background.test.d.ts} +0 -0
- /package/dist/{memory/__tests__/store.test.d.ts → services/digest/digest-init.test.d.ts} +0 -0
- /package/dist/{tools/__tests__/memory.test.d.ts → services/digest/digest-llama-local.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 → services/memory}/store.d.ts +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as assert from 'node:assert/strict';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { afterEach, describe, test } from 'node:test';
|
|
5
|
+
import { createTempDirTracker } from './temp-dir.test.js';
|
|
6
|
+
import { DIGEST_LOCKFILE_REL_PATH } from '../services/digest/constants.js';
|
|
7
|
+
import { releaseLock, tryAcquireProcessLock } from './files.js';
|
|
8
|
+
const tempDirs = createTempDirTracker();
|
|
9
|
+
afterEach(() => {
|
|
10
|
+
tempDirs.cleanup();
|
|
11
|
+
});
|
|
12
|
+
function lockPath(workspace) {
|
|
13
|
+
return path.join(workspace, DIGEST_LOCKFILE_REL_PATH);
|
|
14
|
+
}
|
|
15
|
+
function lockDir(workspace) {
|
|
16
|
+
return path.dirname(lockPath(workspace));
|
|
17
|
+
}
|
|
18
|
+
describe('tryAcquireProcessLock', () => {
|
|
19
|
+
test('C1: no lockfile → creates it with current PID and returns true', () => {
|
|
20
|
+
const workspace = tempDirs.makeTempDir('lockfile-c1-');
|
|
21
|
+
const acquired = tryAcquireProcessLock(lockPath(workspace));
|
|
22
|
+
assert.equal(acquired, true);
|
|
23
|
+
const lockFile = lockPath(workspace);
|
|
24
|
+
const content = JSON.parse(fs.readFileSync(lockFile, 'utf8'));
|
|
25
|
+
assert.equal(content.pid, process.pid);
|
|
26
|
+
});
|
|
27
|
+
test('C2: lockfile with live foreign PID → returns false without modifying file', () => {
|
|
28
|
+
const workspace = tempDirs.makeTempDir('lockfile-c2-');
|
|
29
|
+
const lockFile = lockPath(workspace);
|
|
30
|
+
fs.mkdirSync(lockDir(workspace), { recursive: true });
|
|
31
|
+
// Use process.pid as "live" pid (current process is definitely alive)
|
|
32
|
+
const livePid = process.pid;
|
|
33
|
+
fs.writeFileSync(lockFile, JSON.stringify({ pid: livePid }), 'utf8');
|
|
34
|
+
const originalContent = fs.readFileSync(lockFile, 'utf8');
|
|
35
|
+
const acquired = tryAcquireProcessLock(lockPath(workspace));
|
|
36
|
+
assert.equal(acquired, false);
|
|
37
|
+
// File must be unchanged
|
|
38
|
+
assert.equal(fs.readFileSync(lockFile, 'utf8'), originalContent);
|
|
39
|
+
});
|
|
40
|
+
test('C3: lockfile with dead PID (ESRCH) → deletes stale lock, creates new one, returns true', () => {
|
|
41
|
+
const workspace = tempDirs.makeTempDir('lockfile-c3-');
|
|
42
|
+
const lockFile = lockPath(workspace);
|
|
43
|
+
fs.mkdirSync(lockDir(workspace), { recursive: true });
|
|
44
|
+
// PID 999999999 is virtually guaranteed to be dead
|
|
45
|
+
fs.writeFileSync(lockFile, JSON.stringify({ pid: 999999999 }), 'utf8');
|
|
46
|
+
const acquired = tryAcquireProcessLock(lockPath(workspace));
|
|
47
|
+
assert.equal(acquired, true);
|
|
48
|
+
const content = JSON.parse(fs.readFileSync(lockFile, 'utf8'));
|
|
49
|
+
assert.equal(content.pid, process.pid);
|
|
50
|
+
});
|
|
51
|
+
test('C4: concurrent callers — only one returns true (wx atomicity)', async () => {
|
|
52
|
+
const workspace = tempDirs.makeTempDir('lockfile-c4-');
|
|
53
|
+
// Call twice in the same tick; first wins, second sees EEXIST with live PID.
|
|
54
|
+
const r1 = tryAcquireProcessLock(lockPath(workspace));
|
|
55
|
+
const r2 = tryAcquireProcessLock(lockPath(workspace));
|
|
56
|
+
assert.equal(r1, true);
|
|
57
|
+
assert.equal(r2, false);
|
|
58
|
+
});
|
|
59
|
+
test('stale unparseable lockfile → treated as stale, returns true', () => {
|
|
60
|
+
const workspace = tempDirs.makeTempDir('lockfile-stale-');
|
|
61
|
+
const lockFile = lockPath(workspace);
|
|
62
|
+
fs.mkdirSync(lockDir(workspace), { recursive: true });
|
|
63
|
+
fs.writeFileSync(lockFile, 'not-json', 'utf8');
|
|
64
|
+
const acquired = tryAcquireProcessLock(lockPath(workspace));
|
|
65
|
+
assert.equal(acquired, true);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('releaseLock', () => {
|
|
69
|
+
test('C5: lockfile exists → deletes it', () => {
|
|
70
|
+
const workspace = tempDirs.makeTempDir('lockfile-c5-');
|
|
71
|
+
assert.equal(tryAcquireProcessLock(lockPath(workspace)), true);
|
|
72
|
+
const lockFile = lockPath(workspace);
|
|
73
|
+
assert.equal(fs.existsSync(lockFile), true);
|
|
74
|
+
releaseLock(lockPath(workspace));
|
|
75
|
+
assert.equal(fs.existsSync(lockFile), false);
|
|
76
|
+
});
|
|
77
|
+
test('C6: no lockfile → does not throw', () => {
|
|
78
|
+
const workspace = tempDirs.makeTempDir('lockfile-c6-');
|
|
79
|
+
assert.doesNotThrow(() => releaseLock(lockPath(workspace)));
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sha256Hex(content: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
package/dist/utils/paths.d.ts
CHANGED
package/dist/utils/paths.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as os from 'os';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
|
|
3
|
+
const AGENT_KIT_HOME = path.join(os.homedir(), '.agent-kit');
|
|
4
4
|
export const CREDENTIALS_FILE = path.join(AGENT_KIT_HOME, 'credentials');
|
|
5
5
|
export const MODEL_CACHE_DIR = path.join(AGENT_KIT_HOME, 'cache', 'models');
|
|
6
6
|
export const FASTEMBED_CACHE_DIR = path.join(MODEL_CACHE_DIR, 'fastembed');
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as os from 'node:os';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
export function createTempDirTracker() {
|
|
5
|
+
const tempDirs = [];
|
|
6
|
+
return {
|
|
7
|
+
makeTempDir(prefix) {
|
|
8
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
|
9
|
+
tempDirs.push(tempDir);
|
|
10
|
+
return tempDir;
|
|
11
|
+
},
|
|
12
|
+
cleanup() {
|
|
13
|
+
while (tempDirs.length > 0) {
|
|
14
|
+
const tempDir = tempDirs.pop();
|
|
15
|
+
if (tempDir)
|
|
16
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hanhnd/agent-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.33",
|
|
4
4
|
"description": "Agent Kit MCP server for software development agent workflows",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/
|
|
6
|
+
"main": "dist/server.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"agent-kit": "dist/
|
|
8
|
+
"agent-kit": "dist/server.js",
|
|
9
|
+
"cli": "dist/cli.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist",
|
|
@@ -20,13 +21,14 @@
|
|
|
20
21
|
"directory": "mcp"
|
|
21
22
|
},
|
|
22
23
|
"scripts": {
|
|
23
|
-
"build": "tsc && npm run bundle",
|
|
24
|
-
"bundle": "esbuild src/
|
|
24
|
+
"build": "rm -rf dist && tsc && npm run bundle",
|
|
25
|
+
"bundle": "esbuild src/entrypoints/server.ts src/entrypoints/cli.ts --bundle --platform=node --format=esm --outdir=dist --external:node:* --external:better-sqlite3 --external:sqlite-vec --external:fastembed --external:node-llama-cpp --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url);\"",
|
|
25
26
|
"dev": "tsc --watch",
|
|
26
27
|
"prepublishOnly": "npm run build",
|
|
27
|
-
"test": "tsc && node --test $(find dist
|
|
28
|
+
"test": "tsc && node --test $(find dist -name '*.test.js' | tr '\\n' ' ')"
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
31
|
+
"node-llama-cpp": "^3.0.0",
|
|
30
32
|
"@modelcontextprotocol/sdk": "^1.13.1",
|
|
31
33
|
"better-sqlite3": "^11.0.0",
|
|
32
34
|
"dedent": "^1.5.3",
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as assert from 'node:assert/strict';
|
|
2
|
-
import * as os from 'node:os';
|
|
3
|
-
import * as path from 'node:path';
|
|
4
|
-
import { describe, test } from 'node:test';
|
|
5
|
-
import { DEFAULT_MODEL_CACHE_DIR, FASTEMBED_CACHE_DIR } from '../embedder.js';
|
|
6
|
-
import { AGENT_KIT_HOME, CREDENTIALS_FILE } from '../../utils/paths.js';
|
|
7
|
-
describe('Embedder cache paths', () => {
|
|
8
|
-
test('uses global Agent Kit home for user-level files', () => {
|
|
9
|
-
assert.equal(AGENT_KIT_HOME, path.join(os.homedir(), '.agent-kit'));
|
|
10
|
-
assert.equal(CREDENTIALS_FILE, path.join(AGENT_KIT_HOME, 'credentials'));
|
|
11
|
-
assert.equal(DEFAULT_MODEL_CACHE_DIR, path.join(AGENT_KIT_HOME, 'cache', 'models'));
|
|
12
|
-
assert.equal(FASTEMBED_CACHE_DIR, path.join(DEFAULT_MODEL_CACHE_DIR, 'fastembed'));
|
|
13
|
-
});
|
|
14
|
-
});
|
package/dist/memory/types.js
DELETED
package/dist/tools/handoffs.d.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export declare const HANDOFF_TYPES: readonly ["brainstorm", "clarification", "plan", "ticket", "research", "scenario", "investigation"];
|
|
2
|
-
export type HandoffType = (typeof HANDOFF_TYPES)[number];
|
|
3
|
-
export type CanonicalHandoffType = 'brainstorm' | 'clarification' | 'plan' | 'ticket' | 'research' | 'scenario' | 'investigation';
|
|
4
|
-
export interface SavedHandoffLocation {
|
|
5
|
-
featureSlug: string;
|
|
6
|
-
canonicalType: CanonicalHandoffType;
|
|
7
|
-
filePath: string;
|
|
8
|
-
relativePath: string;
|
|
9
|
-
}
|
|
10
|
-
export declare function sanitizeFeatureSlug(value: string): string;
|
|
11
|
-
export declare function normalizeHandoffType(type: HandoffType): CanonicalHandoffType;
|
|
12
|
-
export declare function deriveFeatureSlug(input: {
|
|
13
|
-
requestedSlug: string;
|
|
14
|
-
content: string;
|
|
15
|
-
type: CanonicalHandoffType;
|
|
16
|
-
}): string;
|
|
17
|
-
export declare function resolveHandoffPath(input: {
|
|
18
|
-
workspaceRoot: string;
|
|
19
|
-
type: HandoffType;
|
|
20
|
-
slug: string;
|
|
21
|
-
content: string;
|
|
22
|
-
}): SavedHandoffLocation;
|
package/dist/tools/memory.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { MemoryIndexer } from '../memory/indexer.js';
|
|
3
|
-
import { MemoryStore } from '../memory/store.js';
|
|
4
|
-
import type { MemoryConfig } from '../memory/types.js';
|
|
5
|
-
import { type ProjectSettings } from './config.js';
|
|
6
|
-
/**
|
|
7
|
-
* Registers tool handlers onto an already-constructed indexer/store pair.
|
|
8
|
-
* Exported for unit testing with mocks.
|
|
9
|
-
*/
|
|
10
|
-
export declare function registerMemoryToolHandlers(server: McpServer, indexer: MemoryIndexer, store: MemoryStore, config: MemoryConfig): void;
|
|
11
|
-
/**
|
|
12
|
-
* Initializes the memory subsystem and registers all memory tools.
|
|
13
|
-
* Returns the MemoryIndexer so the caller can fire startupIndex() after server.connect().
|
|
14
|
-
* Returns null when memory is disabled (settings.memory.enabled !== true).
|
|
15
|
-
*/
|
|
16
|
-
export declare function registerMemoryTools(server: McpServer, settings: ProjectSettings, workspaceRoot: string): MemoryIndexer | null;
|
/package/dist/{memory/__tests__/chunker.test.d.ts → cli/commands/cli-digest-pending.test.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/{memory/__tests__/indexer.test.d.ts → services/digest/digest-background.test.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
/package/dist/{tools/__tests__/memory.test.d.ts → services/digest/digest-llama-local.test.d.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|