@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,111 @@
|
|
|
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 '../../utils/temp-dir.test.js';
|
|
6
|
+
import { runMemoryCli } from './memory.js';
|
|
7
|
+
import { writeConversationDigestSettings } from '../../services/digest/files.js';
|
|
8
|
+
import { DigestModelId } from '../../services/digest/types.js';
|
|
9
|
+
const tempDirs = createTempDirTracker();
|
|
10
|
+
afterEach(() => {
|
|
11
|
+
tempDirs.cleanup();
|
|
12
|
+
});
|
|
13
|
+
function writeInitState(workspace) {
|
|
14
|
+
writeConversationDigestSettings(workspace, {
|
|
15
|
+
enabled: true,
|
|
16
|
+
initialized: true,
|
|
17
|
+
modelId: DigestModelId.DEFAULT,
|
|
18
|
+
initializedAt: new Date().toISOString(),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function captureStdout(fn) {
|
|
22
|
+
const stdoutChunks = [];
|
|
23
|
+
const origWrite = process.stdout.write.bind(process.stdout);
|
|
24
|
+
process.stdout.write = (chunk) => {
|
|
25
|
+
stdoutChunks.push(String(chunk));
|
|
26
|
+
return true;
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const code = await fn();
|
|
30
|
+
return { code, output: stdoutChunks.join('') };
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
process.stdout.write = origWrite;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function withWorkspace(workspace, fn) {
|
|
37
|
+
const previous = process.env.WORKSPACE_DIR;
|
|
38
|
+
process.env.WORKSPACE_DIR = workspace;
|
|
39
|
+
try {
|
|
40
|
+
return await fn();
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
if (previous === undefined) {
|
|
44
|
+
delete process.env.WORKSPACE_DIR;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
process.env.WORKSPACE_DIR = previous;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
describe('cmdDigestPending CLI', () => {
|
|
52
|
+
test('digest-pending returns 0 and emits one JSON line matching DigestPendingResult', async () => {
|
|
53
|
+
const workspace = tempDirs.makeTempDir('cli-pending-c23-');
|
|
54
|
+
const { code, output } = await withWorkspace(workspace, () => captureStdout(() => runMemoryCli(['digest-pending'], {
|
|
55
|
+
...process.env,
|
|
56
|
+
WORKSPACE_DIR: workspace,
|
|
57
|
+
})));
|
|
58
|
+
assert.equal(code, 0);
|
|
59
|
+
const parsed = JSON.parse(output.trim());
|
|
60
|
+
assert.ok('ok' in parsed, 'result must have ok field');
|
|
61
|
+
assert.ok('action' in parsed, 'result must have action field');
|
|
62
|
+
});
|
|
63
|
+
test('--background returns launcher JSON without waiting for worker when no pending', async () => {
|
|
64
|
+
const workspace = tempDirs.makeTempDir('cli-pending-bg-');
|
|
65
|
+
writeInitState(workspace);
|
|
66
|
+
const { code, output } = await withWorkspace(workspace, () => captureStdout(() => runMemoryCli(['digest-pending', '--background'], {
|
|
67
|
+
...process.env,
|
|
68
|
+
WORKSPACE_DIR: workspace,
|
|
69
|
+
})));
|
|
70
|
+
assert.equal(code, 0);
|
|
71
|
+
const parsed = JSON.parse(output.trim());
|
|
72
|
+
assert.equal(parsed.mode, 'background-launcher');
|
|
73
|
+
assert.equal(parsed.spawned, false);
|
|
74
|
+
assert.equal(parsed.status.state, 'no-pending');
|
|
75
|
+
});
|
|
76
|
+
test('--background worker flag returns final worker status JSON', async () => {
|
|
77
|
+
const workspace = tempDirs.makeTempDir('cli-pending-worker-');
|
|
78
|
+
writeInitState(workspace);
|
|
79
|
+
const { code, output } = await withWorkspace(workspace, () => captureStdout(() => runMemoryCli(['digest-pending', '--background', '--__agent-kit-digest-worker'], {
|
|
80
|
+
...process.env,
|
|
81
|
+
WORKSPACE_DIR: workspace,
|
|
82
|
+
})));
|
|
83
|
+
assert.equal(code, 0);
|
|
84
|
+
const parsed = JSON.parse(output.trim());
|
|
85
|
+
assert.equal(parsed.state, 'no-pending');
|
|
86
|
+
assert.equal(fs.existsSync(path.join(workspace, '.agent-kit', 'wiki', 'digest', 'digest-worker.status.json')), true);
|
|
87
|
+
});
|
|
88
|
+
test('--background emits failed launcher JSON quickly when spawn preflight cannot find entrypoint', async () => {
|
|
89
|
+
const workspace = tempDirs.makeTempDir('cli-pending-bg-fast-');
|
|
90
|
+
writeInitState(workspace);
|
|
91
|
+
const rawDir = path.join(workspace, '.agent-kit', 'wiki', 'raw');
|
|
92
|
+
fs.mkdirSync(rawDir, { recursive: true });
|
|
93
|
+
fs.writeFileSync(path.join(rawDir, 'conv_2026-01-01T00-00-00-001Z.md'), '**User:** hello\n', 'utf8');
|
|
94
|
+
const previousArgv = process.argv[1];
|
|
95
|
+
process.argv[1] = '';
|
|
96
|
+
try {
|
|
97
|
+
const { code, output } = await withWorkspace(workspace, () => captureStdout(() => runMemoryCli(['digest-pending', '--background'], {
|
|
98
|
+
...process.env,
|
|
99
|
+
WORKSPACE_DIR: workspace,
|
|
100
|
+
})));
|
|
101
|
+
assert.equal(code, 0);
|
|
102
|
+
const parsed = JSON.parse(output.trim());
|
|
103
|
+
assert.equal(parsed.mode, 'background-launcher');
|
|
104
|
+
assert.equal(parsed.spawned, false);
|
|
105
|
+
assert.equal(parsed.status.state, 'failed');
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
process.argv[1] = previousArgv;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as assert from 'node:assert/strict';
|
|
2
|
+
import { afterEach, describe, test } from 'node:test';
|
|
3
|
+
import { createTempDirTracker } from '../../utils/temp-dir.test.js';
|
|
4
|
+
import { runMemoryCli } from './memory.js';
|
|
5
|
+
const tempDirs = createTempDirTracker();
|
|
6
|
+
afterEach(() => {
|
|
7
|
+
tempDirs.cleanup();
|
|
8
|
+
});
|
|
9
|
+
describe('memory CLI', () => {
|
|
10
|
+
test('digest-pending returns 0 when settings are missing', async () => {
|
|
11
|
+
const workspace = tempDirs.makeTempDir('digest-pending-');
|
|
12
|
+
const previous = process.env.WORKSPACE_DIR;
|
|
13
|
+
process.env.WORKSPACE_DIR = workspace;
|
|
14
|
+
try {
|
|
15
|
+
const code = await runMemoryCli(['digest-pending'], {
|
|
16
|
+
...process.env,
|
|
17
|
+
WORKSPACE_DIR: workspace,
|
|
18
|
+
});
|
|
19
|
+
assert.equal(code, 0);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
if (previous === undefined) {
|
|
23
|
+
delete process.env.WORKSPACE_DIR;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
process.env.WORKSPACE_DIR = previous;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
test('unknown command returns 1', async () => {
|
|
31
|
+
const code = await runMemoryCli(['unknown'], process.env);
|
|
32
|
+
assert.equal(code, 1);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runMemoryCli(args: string[], _env: NodeJS.ProcessEnv): Promise<number>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { initializeConversationDigestModel, digestConversationFile, digestPendingConversations, } from '../../services/digest/processor.js';
|
|
2
|
+
import { launchDigestPendingWorker, runDigestPendingWorker } from '../../services/digest/background.js';
|
|
3
|
+
import { isDigestWorkerInvocation, runDigestFileInWorker } from '../../services/digest/worker.js';
|
|
4
|
+
import { DEFAULT_DIGEST_MAX_INPUT_CHARS, DEFAULT_DIGEST_MODEL_ID, DEFAULT_DIGEST_TIMEOUT_MS, DIGEST_WORKER_FLAG, DIGEST_WORKER_RESULT_PREFIX, } from '../../services/digest/constants.js';
|
|
5
|
+
import { loadProjectSettings, resolveConversationDigestConfig } from '../../core/config/index.js';
|
|
6
|
+
import { parseArgs, stringFlag, numberFlag } from '../utils/args.js';
|
|
7
|
+
import { getWorkspaceRoot } from '../../utils/utils.js';
|
|
8
|
+
function writeDigestFileResult(result, workerMode) {
|
|
9
|
+
if (workerMode) {
|
|
10
|
+
process.stdout.write(DIGEST_WORKER_RESULT_PREFIX + JSON.stringify(result) + '\n');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
14
|
+
}
|
|
15
|
+
async function cmdDigestInit(args) {
|
|
16
|
+
const parsed = parseArgs(args);
|
|
17
|
+
const modelId = stringFlag(parsed.flags, 'model') ?? DEFAULT_DIGEST_MODEL_ID;
|
|
18
|
+
const result = await initializeConversationDigestModel({
|
|
19
|
+
workspaceRoot: getWorkspaceRoot(),
|
|
20
|
+
modelId,
|
|
21
|
+
allowDownload: true,
|
|
22
|
+
});
|
|
23
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
24
|
+
return result.initialized ? 0 : 1;
|
|
25
|
+
}
|
|
26
|
+
async function cmdDigestFile(args) {
|
|
27
|
+
const workerMode = isDigestWorkerInvocation(args);
|
|
28
|
+
const workerResult = runDigestFileInWorker(args);
|
|
29
|
+
if (workerResult !== undefined)
|
|
30
|
+
return workerResult;
|
|
31
|
+
const parsed = parseArgs(args);
|
|
32
|
+
const workspaceRoot = getWorkspaceRoot();
|
|
33
|
+
const digestConfig = resolveConversationDigestConfig(loadProjectSettings(workspaceRoot));
|
|
34
|
+
const modelId = stringFlag(parsed.flags, 'model') ?? digestConfig?.modelId ?? DEFAULT_DIGEST_MODEL_ID;
|
|
35
|
+
const inputPath = stringFlag(parsed.flags, 'input');
|
|
36
|
+
if (!inputPath) {
|
|
37
|
+
process.stderr.write('Usage: cli memory digest-file --input <path> --model <id>\n');
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
const result = await digestConversationFile({
|
|
41
|
+
workspaceRoot,
|
|
42
|
+
inputPath,
|
|
43
|
+
modelId,
|
|
44
|
+
outDir: stringFlag(parsed.flags, 'out'),
|
|
45
|
+
maxInputChars: numberFlag(parsed.flags, 'max-input-chars', DEFAULT_DIGEST_MAX_INPUT_CHARS),
|
|
46
|
+
timeoutMs: numberFlag(parsed.flags, 'timeout-ms', DEFAULT_DIGEST_TIMEOUT_MS),
|
|
47
|
+
});
|
|
48
|
+
writeDigestFileResult(result, workerMode);
|
|
49
|
+
return 0;
|
|
50
|
+
}
|
|
51
|
+
async function cmdDigestPending(args) {
|
|
52
|
+
const parsed = parseArgs(args);
|
|
53
|
+
const workspaceRoot = getWorkspaceRoot();
|
|
54
|
+
const isBackground = parsed.flags.get('background') === true;
|
|
55
|
+
if (isBackground && parsed.flags.get(DIGEST_WORKER_FLAG) === true) {
|
|
56
|
+
const result = await runDigestPendingWorker({ workspaceRoot });
|
|
57
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
if (isBackground) {
|
|
61
|
+
const result = launchDigestPendingWorker({
|
|
62
|
+
workspaceRoot,
|
|
63
|
+
args,
|
|
64
|
+
entrypoint: process.argv[1],
|
|
65
|
+
});
|
|
66
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
const result = await digestPendingConversations({ workspaceRoot });
|
|
70
|
+
process.stdout.write(JSON.stringify(result) + '\n');
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
export async function runMemoryCli(args, _env) {
|
|
74
|
+
const [command, ...rest] = args;
|
|
75
|
+
try {
|
|
76
|
+
if (command === 'digest-file')
|
|
77
|
+
return await cmdDigestFile(rest);
|
|
78
|
+
if (command === 'digest-init')
|
|
79
|
+
return await cmdDigestInit(rest);
|
|
80
|
+
if (command === 'digest-pending')
|
|
81
|
+
return await cmdDigestPending(rest);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
85
|
+
process.stderr.write('[agent-kit] memory ' + (command ?? '') + ' failed: ' + message + '\n');
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
process.stderr.write('Usage: cli memory <digest-file|digest-init|digest-pending>\n');
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runAgentKitCli(argv: string[], env: NodeJS.ProcessEnv): Promise<number>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { runMemoryCli } from './commands/memory.js';
|
|
2
|
+
export async function runAgentKitCli(argv, env) {
|
|
3
|
+
const [command, ...rest] = argv;
|
|
4
|
+
if (command === 'memory') {
|
|
5
|
+
return runMemoryCli(rest, env);
|
|
6
|
+
}
|
|
7
|
+
process.stderr.write('Usage: cli memory <digest-file|digest-init|digest-pending>\n');
|
|
8
|
+
return 1;
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface ParsedArgs {
|
|
2
|
+
flags: Map<string, string | boolean>;
|
|
3
|
+
positionals: string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function parseArgs(args: string[]): ParsedArgs;
|
|
6
|
+
export declare function stringFlag(flags: Map<string, string | boolean>, key: string): string | undefined;
|
|
7
|
+
export declare function numberFlag(flags: Map<string, string | boolean>, key: string, defaultValue: number | string): number;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function parseArgs(args) {
|
|
2
|
+
const flags = new Map();
|
|
3
|
+
const positionals = [];
|
|
4
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
5
|
+
const arg = args[index];
|
|
6
|
+
if (!arg.startsWith('--')) {
|
|
7
|
+
positionals.push(arg);
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
const key = arg.slice(2);
|
|
11
|
+
const next = args[index + 1];
|
|
12
|
+
if (!next || next.startsWith('--')) {
|
|
13
|
+
flags.set(key, true);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
flags.set(key, next);
|
|
17
|
+
index += 1;
|
|
18
|
+
}
|
|
19
|
+
return { flags, positionals };
|
|
20
|
+
}
|
|
21
|
+
export function stringFlag(flags, key) {
|
|
22
|
+
const value = flags.get(key);
|
|
23
|
+
return typeof value === 'string' ? value : undefined;
|
|
24
|
+
}
|
|
25
|
+
export function numberFlag(flags, key, defaultValue) {
|
|
26
|
+
const value = Number(stringFlag(flags, key) ?? defaultValue);
|
|
27
|
+
if (!Number.isFinite(value)) {
|
|
28
|
+
throw new Error(`--${key} must be a finite number`);
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|