@botbotgo/common 1.0.0
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/README.md +54 -0
- package/dist/chunk-DIIWJNRE.js +51 -0
- package/dist/chunk-DIIWJNRE.js.map +1 -0
- package/dist/chunk-H5BG6SXW.js +33 -0
- package/dist/chunk-H5BG6SXW.js.map +1 -0
- package/dist/chunk-HBCZVEUG.js +92 -0
- package/dist/chunk-HBCZVEUG.js.map +1 -0
- package/dist/chunk-OTWARMTU.js +182 -0
- package/dist/chunk-OTWARMTU.js.map +1 -0
- package/dist/chunk-QG6CT2GZ.js +31 -0
- package/dist/chunk-QG6CT2GZ.js.map +1 -0
- package/dist/chunk-RUIAZ7GO.js +463 -0
- package/dist/chunk-RUIAZ7GO.js.map +1 -0
- package/dist/chunk-X4TDNR4V.js +206 -0
- package/dist/chunk-X4TDNR4V.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +13 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/startup.d.ts +14 -0
- package/dist/config/hydrate.d.ts +15 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.js +27 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/kind.d.ts +28 -0
- package/dist/config/path.d.ts +14 -0
- package/dist/config/yaml.d.ts +32 -0
- package/dist/connectivity/check.d.ts +19 -0
- package/dist/connectivity/index.d.ts +3 -0
- package/dist/connectivity/index.js +102 -0
- package/dist/connectivity/index.js.map +1 -0
- package/dist/connectivity/types.d.ts +12 -0
- package/dist/context/default-context.d.ts +10 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.js +16 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/tokens.d.ts +29 -0
- package/dist/events/index.d.ts +17 -0
- package/dist/events/index.js +20 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/progress-listener.d.ts +8 -0
- package/dist/events/runtime2-tree-listener.d.ts +26 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/npm/cache.d.ts +9 -0
- package/dist/npm/command.d.ts +36 -0
- package/dist/npm/index.d.ts +1 -0
- package/dist/npm/index.js +29 -0
- package/dist/npm/index.js.map +1 -0
- package/dist/npm/install.d.ts +8 -0
- package/dist/npm/provider.d.ts +14 -0
- package/dist/npm/version.d.ts +11 -0
- package/dist/security-store/backends/file/index.d.ts +19 -0
- package/dist/security-store/backends/index.d.ts +7 -0
- package/dist/security-store/backends/keychain/constants.d.ts +4 -0
- package/dist/security-store/backends/keychain/index.d.ts +17 -0
- package/dist/security-store/backends/keychain/keytar.d.ts +5 -0
- package/dist/security-store/backends/keychain/swift-bridge.d.ts +17 -0
- package/dist/security-store/backends/keychain/utils.d.ts +11 -0
- package/dist/security-store/backends/memory/index.d.ts +10 -0
- package/dist/security-store/backends/types.d.ts +29 -0
- package/dist/security-store/backends/utils.d.ts +2 -0
- package/dist/security-store/index.d.ts +2 -0
- package/dist/security-store/index.js +819 -0
- package/dist/security-store/index.js.map +1 -0
- package/dist/security-store/store.d.ts +49 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +7 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/utils/agent-result.d.ts +4 -0
- package/dist/utils/checksum.d.ts +16 -0
- package/dist/utils/deep-merge.d.ts +4 -0
- package/dist/utils/frontmatter.d.ts +12 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.js +38 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/log.d.ts +1 -0
- package/dist/utils/object.d.ts +4 -0
- package/dist/utils/override-with-config.d.ts +12 -0
- package/dist/utils/parsing.d.ts +4 -0
- package/dist/utils/selection/tool-choice.d.ts +1 -0
- package/dist/utils/selection/tool-registry.d.ts +5 -0
- package/package.json +128 -0
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# @botbotgo/common
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
`@botbotgo/common` is the shared base package for the BotBotGo agent repos. It owns process-level context, event bus primitives, common config helpers, and a small set of shared subpath APIs used by the other packages.
|
|
6
|
+
|
|
7
|
+
## Exposed Interfaces
|
|
8
|
+
|
|
9
|
+
| Export | Type | Purpose |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `createAgentContext` | root | Create an isolated agent context. |
|
|
12
|
+
| `getDefaultAgentContext` | root | Access the process default context. |
|
|
13
|
+
| `AgentContextTokens` | root | Stable tokens shared across repos. |
|
|
14
|
+
| `createAgentEventBus` | root | Create the shared event bus. |
|
|
15
|
+
| `createConsoleAgentEventListener` | root | Console event listener. |
|
|
16
|
+
| `createProgressAgentEventListener` | root | Progress-oriented event listener. |
|
|
17
|
+
| `@botbotgo/common/config` | subpath | Config and YAML helpers. |
|
|
18
|
+
| `@botbotgo/common/cli` | subpath | CLI helpers. |
|
|
19
|
+
| `@botbotgo/common/connectivity` | subpath | Connectivity helpers. |
|
|
20
|
+
| `@botbotgo/common/context` | subpath | Context APIs. |
|
|
21
|
+
| `@botbotgo/common/events` | subpath | Event APIs. |
|
|
22
|
+
| `@botbotgo/common/npm` | subpath | npm helpers. |
|
|
23
|
+
| `@botbotgo/common/security-store` | subpath | Secret storage helpers. |
|
|
24
|
+
| `@botbotgo/common/testing` | subpath | Testing helpers. |
|
|
25
|
+
| `@botbotgo/common/utils` | subpath | Shared utilities. |
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
This repo does not define one fixed YAML schema. It provides shared config helpers used by other repos.
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { loadYamlFile } from "@botbotgo/common/config";
|
|
33
|
+
|
|
34
|
+
const config = await loadYamlFile("./config/app.yaml");
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm i @botbotgo/common
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
createAgentContext,
|
|
46
|
+
createAgentEventBus,
|
|
47
|
+
AgentContextTokens,
|
|
48
|
+
} from "@botbotgo/common";
|
|
49
|
+
|
|
50
|
+
const ctx = createAgentContext();
|
|
51
|
+
const bus = createAgentEventBus();
|
|
52
|
+
|
|
53
|
+
ctx.set(AgentContextTokens.EventBus, bus);
|
|
54
|
+
```
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// src/context/default-context.ts
|
|
2
|
+
var DefaultAgentContext = class {
|
|
3
|
+
registry = /* @__PURE__ */ new Map();
|
|
4
|
+
set(token, value) {
|
|
5
|
+
this.registry.set(token, value);
|
|
6
|
+
}
|
|
7
|
+
get(token) {
|
|
8
|
+
if (!this.registry.has(token)) {
|
|
9
|
+
throw new Error(`AgentContext: token not registered: ${token.toString()}`);
|
|
10
|
+
}
|
|
11
|
+
return this.registry.get(token);
|
|
12
|
+
}
|
|
13
|
+
has(token) {
|
|
14
|
+
return this.registry.has(token);
|
|
15
|
+
}
|
|
16
|
+
tryGet(token) {
|
|
17
|
+
return this.registry.get(token);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var DEFAULT_CONTEXT_KEY = "__botbotgo_agent_default_context__";
|
|
21
|
+
function getGlobalStore() {
|
|
22
|
+
return globalThis;
|
|
23
|
+
}
|
|
24
|
+
function createAgentContext() {
|
|
25
|
+
return new DefaultAgentContext();
|
|
26
|
+
}
|
|
27
|
+
function isAgentContext(value) {
|
|
28
|
+
return typeof value === "object" && value !== null && typeof value.get === "function" && typeof value.set === "function" && typeof value.has === "function";
|
|
29
|
+
}
|
|
30
|
+
function getDefaultAgentContext() {
|
|
31
|
+
const store = getGlobalStore();
|
|
32
|
+
const existing = store[DEFAULT_CONTEXT_KEY];
|
|
33
|
+
if (isAgentContext(existing)) return existing;
|
|
34
|
+
const created = createAgentContext();
|
|
35
|
+
store[DEFAULT_CONTEXT_KEY] = created;
|
|
36
|
+
return created;
|
|
37
|
+
}
|
|
38
|
+
function resetDefaultAgentContext() {
|
|
39
|
+
const store = getGlobalStore();
|
|
40
|
+
if (DEFAULT_CONTEXT_KEY in store) {
|
|
41
|
+
delete store[DEFAULT_CONTEXT_KEY];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
createAgentContext,
|
|
47
|
+
isAgentContext,
|
|
48
|
+
getDefaultAgentContext,
|
|
49
|
+
resetDefaultAgentContext
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=chunk-DIIWJNRE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context/default-context.ts"],"sourcesContent":["export interface AgentContext {\n set<T>(token: symbol, value: T): void;\n get<T>(token: symbol): T;\n has(token: symbol): boolean;\n tryGet<T>(token: symbol): T | undefined;\n}\n\nclass DefaultAgentContext implements AgentContext {\n private readonly registry = new Map<symbol, unknown>();\n\n set<T>(token: symbol, value: T): void {\n this.registry.set(token, value);\n }\n\n get<T>(token: symbol): T {\n if (!this.registry.has(token)) {\n throw new Error(`AgentContext: token not registered: ${token.toString()}`);\n }\n return this.registry.get(token) as T;\n }\n\n has(token: symbol): boolean {\n return this.registry.has(token);\n }\n\n tryGet<T>(token: symbol): T | undefined {\n return this.registry.get(token) as T | undefined;\n }\n}\n\nconst DEFAULT_CONTEXT_KEY = \"__botbotgo_agent_default_context__\";\n\nfunction getGlobalStore(): Record<string, unknown> {\n return globalThis as unknown as Record<string, unknown>;\n}\n\nexport function createAgentContext(): AgentContext {\n return new DefaultAgentContext();\n}\n\nexport function isAgentContext(value: unknown): value is AgentContext {\n return (\n typeof value === \"object\"\n && value !== null\n && typeof (value as AgentContext).get === \"function\"\n && typeof (value as AgentContext).set === \"function\"\n && typeof (value as AgentContext).has === \"function\"\n );\n}\n\nexport function getDefaultAgentContext(): AgentContext {\n const store = getGlobalStore();\n const existing = store[DEFAULT_CONTEXT_KEY];\n if (isAgentContext(existing)) return existing;\n const created = createAgentContext();\n store[DEFAULT_CONTEXT_KEY] = created;\n return created;\n}\n\nexport function resetDefaultAgentContext(): void {\n const store = getGlobalStore();\n if (DEFAULT_CONTEXT_KEY in store) {\n delete store[DEFAULT_CONTEXT_KEY];\n }\n}\n"],"mappings":";AAOA,IAAM,sBAAN,MAAkD;AAAA,EAC/B,WAAW,oBAAI,IAAqB;AAAA,EAErD,IAAO,OAAe,OAAgB;AACpC,SAAK,SAAS,IAAI,OAAO,KAAK;AAAA,EAChC;AAAA,EAEA,IAAO,OAAkB;AACvB,QAAI,CAAC,KAAK,SAAS,IAAI,KAAK,GAAG;AAC7B,YAAM,IAAI,MAAM,uCAAuC,MAAM,SAAS,CAAC,EAAE;AAAA,IAC3E;AACA,WAAO,KAAK,SAAS,IAAI,KAAK;AAAA,EAChC;AAAA,EAEA,IAAI,OAAwB;AAC1B,WAAO,KAAK,SAAS,IAAI,KAAK;AAAA,EAChC;AAAA,EAEA,OAAU,OAA8B;AACtC,WAAO,KAAK,SAAS,IAAI,KAAK;AAAA,EAChC;AACF;AAEA,IAAM,sBAAsB;AAE5B,SAAS,iBAA0C;AACjD,SAAO;AACT;AAEO,SAAS,qBAAmC;AACjD,SAAO,IAAI,oBAAoB;AACjC;AAEO,SAAS,eAAe,OAAuC;AACpE,SACE,OAAO,UAAU,YACd,UAAU,QACV,OAAQ,MAAuB,QAAQ,cACvC,OAAQ,MAAuB,QAAQ,cACvC,OAAQ,MAAuB,QAAQ;AAE9C;AAEO,SAAS,yBAAuC;AACrD,QAAM,QAAQ,eAAe;AAC7B,QAAM,WAAW,MAAM,mBAAmB;AAC1C,MAAI,eAAe,QAAQ,EAAG,QAAO;AACrC,QAAM,UAAU,mBAAmB;AACnC,QAAM,mBAAmB,IAAI;AAC7B,SAAO;AACT;AAEO,SAAS,2BAAiC;AAC/C,QAAM,QAAQ,eAAe;AAC7B,MAAI,uBAAuB,OAAO;AAChC,WAAO,MAAM,mBAAmB;AAAA,EAClC;AACF;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computeChecksum
|
|
3
|
+
} from "./chunk-QG6CT2GZ.js";
|
|
4
|
+
|
|
5
|
+
// src/context/tokens.ts
|
|
6
|
+
function createChecksummedToken(scope, name) {
|
|
7
|
+
const seed = `${scope}:${name}`;
|
|
8
|
+
const checksum = computeChecksum(seed, { length: 12 });
|
|
9
|
+
return /* @__PURE__ */ Symbol.for(`${scope}.${name}.${checksum}`);
|
|
10
|
+
}
|
|
11
|
+
var AgentContextTokens = {
|
|
12
|
+
/** The shared AgentEventBus instance */
|
|
13
|
+
EventBus: createChecksummedToken("botbotgo.agent.context", "eventBus"),
|
|
14
|
+
/** The primary chat model (BaseChatModel) */
|
|
15
|
+
ChatModel: createChecksummedToken("botbotgo.agent.context", "chatModel"),
|
|
16
|
+
/** The embedding model (Embeddings) */
|
|
17
|
+
EmbedModel: createChecksummedToken("botbotgo.agent.context", "embedModel"),
|
|
18
|
+
/** The vision-language chat model (BaseChatModel) */
|
|
19
|
+
VlmModel: createChecksummedToken("botbotgo.agent.context", "vlmModel"),
|
|
20
|
+
/** The memory client (AgentMemory) */
|
|
21
|
+
Memory: createChecksummedToken("botbotgo.agent.context", "memory"),
|
|
22
|
+
/** The initialized tool list */
|
|
23
|
+
Tools: createChecksummedToken("botbotgo.agent.context", "tools"),
|
|
24
|
+
/** The loaded skill set (SkillSet | undefined) */
|
|
25
|
+
SkillSet: createChecksummedToken("botbotgo.agent.context", "skillSet"),
|
|
26
|
+
/** The initialized agent runtime instance (react/deep) */
|
|
27
|
+
Runtime: createChecksummedToken("botbotgo.agent.context", "runtime")
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
AgentContextTokens
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=chunk-H5BG6SXW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context/tokens.ts"],"sourcesContent":["import { computeChecksum } from \"../utils/checksum.js\";\n\nfunction createChecksummedToken(scope: string, name: string): symbol {\n const seed = `${scope}:${name}`;\n const checksum = computeChecksum(seed, { length: 12 });\n return Symbol.for(`${scope}.${name}.${checksum}`);\n}\n\n/**\n * Well-known Symbol tokens for AgentContext.\n * Use these to register and retrieve modules from an AgentContext.\n *\n * @example\n * ```ts\n * ctx.set(AgentContextTokens.ChatModel, llm);\n * const llm = ctx.get<BaseChatModel>(AgentContextTokens.ChatModel);\n * ```\n */\nexport const AgentContextTokens = {\n /** The shared AgentEventBus instance */\n EventBus: createChecksummedToken(\"botbotgo.agent.context\", \"eventBus\"),\n /** The primary chat model (BaseChatModel) */\n ChatModel: createChecksummedToken(\"botbotgo.agent.context\", \"chatModel\"),\n /** The embedding model (Embeddings) */\n EmbedModel: createChecksummedToken(\"botbotgo.agent.context\", \"embedModel\"),\n /** The vision-language chat model (BaseChatModel) */\n VlmModel: createChecksummedToken(\"botbotgo.agent.context\", \"vlmModel\"),\n /** The memory client (AgentMemory) */\n Memory: createChecksummedToken(\"botbotgo.agent.context\", \"memory\"),\n /** The initialized tool list */\n Tools: createChecksummedToken(\"botbotgo.agent.context\", \"tools\"),\n /** The loaded skill set (SkillSet | undefined) */\n SkillSet: createChecksummedToken(\"botbotgo.agent.context\", \"skillSet\"),\n /** The initialized agent runtime instance (react/deep) */\n Runtime: createChecksummedToken(\"botbotgo.agent.context\", \"runtime\"),\n} as const;\n\nexport type AgentContextTokenKey = (typeof AgentContextTokens)[keyof typeof AgentContextTokens];\n"],"mappings":";;;;;AAEA,SAAS,uBAAuB,OAAe,MAAsB;AACnE,QAAM,OAAO,GAAG,KAAK,IAAI,IAAI;AAC7B,QAAM,WAAW,gBAAgB,MAAM,EAAE,QAAQ,GAAG,CAAC;AACrD,SAAO,uBAAO,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,QAAQ,EAAE;AAClD;AAYO,IAAM,qBAAqB;AAAA;AAAA,EAEhC,UAAU,uBAAuB,0BAA0B,UAAU;AAAA;AAAA,EAErE,WAAW,uBAAuB,0BAA0B,WAAW;AAAA;AAAA,EAEvE,YAAY,uBAAuB,0BAA0B,YAAY;AAAA;AAAA,EAEzE,UAAU,uBAAuB,0BAA0B,UAAU;AAAA;AAAA,EAErE,QAAQ,uBAAuB,0BAA0B,QAAQ;AAAA;AAAA,EAEjE,OAAO,uBAAuB,0BAA0B,OAAO;AAAA;AAAA,EAE/D,UAAU,uBAAuB,0BAA0B,UAAU;AAAA;AAAA,EAErE,SAAS,uBAAuB,0BAA0B,SAAS;AACrE;","names":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/cli/startup.ts
|
|
2
|
+
import { relative } from "path";
|
|
3
|
+
function toErrorMessage(error) {
|
|
4
|
+
return error instanceof Error ? error.message : String(error);
|
|
5
|
+
}
|
|
6
|
+
function formatLogPath(pathValue) {
|
|
7
|
+
const trimmed = pathValue.trim();
|
|
8
|
+
if (!trimmed) return "(unknown)";
|
|
9
|
+
const rel = relative(process.cwd(), trimmed);
|
|
10
|
+
if (!rel || rel.startsWith("..")) return trimmed;
|
|
11
|
+
return rel;
|
|
12
|
+
}
|
|
13
|
+
function formatDurationMs(durationMs) {
|
|
14
|
+
return durationMs === null ? "" : ` (${durationMs}ms)`;
|
|
15
|
+
}
|
|
16
|
+
var StartupProgressRenderer = class {
|
|
17
|
+
isDynamic = Boolean(process.stdout.isTTY);
|
|
18
|
+
frames = ["|", "/", "-", "\\"];
|
|
19
|
+
lineByStep = /* @__PURE__ */ new Map();
|
|
20
|
+
timerByStep = /* @__PURE__ */ new Map();
|
|
21
|
+
frameIndexByStep = /* @__PURE__ */ new Map();
|
|
22
|
+
lineCount = 0;
|
|
23
|
+
start(stepId, title) {
|
|
24
|
+
const baseLabel = `[startup] ${title}`;
|
|
25
|
+
if (!this.isDynamic) {
|
|
26
|
+
console.log(`${baseLabel} ...`);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const lineIndex = this.lineCount;
|
|
30
|
+
this.lineByStep.set(stepId, lineIndex);
|
|
31
|
+
this.frameIndexByStep.set(stepId, 0);
|
|
32
|
+
this.lineCount += 1;
|
|
33
|
+
process.stdout.write(`\r${baseLabel} ${this.frames[0]}
|
|
34
|
+
`);
|
|
35
|
+
const timer = setInterval(() => {
|
|
36
|
+
const current = this.frameIndexByStep.get(stepId);
|
|
37
|
+
if (current === void 0) return;
|
|
38
|
+
const next = (current + 1) % this.frames.length;
|
|
39
|
+
this.frameIndexByStep.set(stepId, next);
|
|
40
|
+
this.renderLine(stepId, `${baseLabel} ${this.frames[next]}`);
|
|
41
|
+
}, 80);
|
|
42
|
+
this.timerByStep.set(stepId, timer);
|
|
43
|
+
}
|
|
44
|
+
complete(stepId, title, ok, detail, elapsedMs) {
|
|
45
|
+
const baseLabel = `[startup] ${title}`;
|
|
46
|
+
const mark = ok ? "OK" : "ERR";
|
|
47
|
+
const detailPart = detail.trim().length > 0 ? ` ${detail}` : "";
|
|
48
|
+
const finalLine = `${mark} ${baseLabel}${detailPart}${formatDurationMs(elapsedMs)}`;
|
|
49
|
+
const timer = this.timerByStep.get(stepId);
|
|
50
|
+
if (timer) {
|
|
51
|
+
clearInterval(timer);
|
|
52
|
+
this.timerByStep.delete(stepId);
|
|
53
|
+
}
|
|
54
|
+
this.frameIndexByStep.delete(stepId);
|
|
55
|
+
if (!this.isDynamic) {
|
|
56
|
+
console.log(finalLine);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.renderLine(stepId, finalLine);
|
|
60
|
+
}
|
|
61
|
+
renderLine(stepId, line) {
|
|
62
|
+
const lineIndex = this.lineByStep.get(stepId);
|
|
63
|
+
if (lineIndex === void 0) return;
|
|
64
|
+
const up = this.lineCount - lineIndex;
|
|
65
|
+
if (up <= 0) return;
|
|
66
|
+
process.stdout.write(`\x1B[${up}A\r\x1B[2K${line}\x1B[${up}B\r`);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
async function runStartupStep(progress, title, fn, formatResult) {
|
|
70
|
+
const stepId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
71
|
+
const startedAt = Date.now();
|
|
72
|
+
progress.start(stepId, title);
|
|
73
|
+
try {
|
|
74
|
+
const result = await fn();
|
|
75
|
+
const detail = formatResult ? formatResult(result) : "";
|
|
76
|
+
const elapsed = Date.now() - startedAt;
|
|
77
|
+
progress.complete(stepId, title, true, detail, elapsed);
|
|
78
|
+
return result;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
const elapsed = Date.now() - startedAt;
|
|
81
|
+
progress.complete(stepId, title, false, toErrorMessage(error), elapsed);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export {
|
|
87
|
+
toErrorMessage,
|
|
88
|
+
formatLogPath,
|
|
89
|
+
StartupProgressRenderer,
|
|
90
|
+
runStartupStep
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-HBCZVEUG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/startup.ts"],"sourcesContent":["import { relative } from \"node:path\";\n\nexport function toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function formatLogPath(pathValue: string): string {\n const trimmed = pathValue.trim();\n if (!trimmed) return \"(unknown)\";\n const rel = relative(process.cwd(), trimmed);\n if (!rel || rel.startsWith(\"..\")) return trimmed;\n return rel;\n}\n\nfunction formatDurationMs(durationMs: number | null): string {\n return durationMs === null ? \"\" : ` (${durationMs}ms)`;\n}\n\nexport class StartupProgressRenderer {\n private readonly isDynamic = Boolean(process.stdout.isTTY);\n private readonly frames = [\"|\", \"/\", \"-\", \"\\\\\"];\n private readonly lineByStep = new Map<string, number>();\n private readonly timerByStep = new Map<string, NodeJS.Timeout>();\n private readonly frameIndexByStep = new Map<string, number>();\n private lineCount = 0;\n\n start(stepId: string, title: string): void {\n const baseLabel = `[startup] ${title}`;\n if (!this.isDynamic) {\n console.log(`${baseLabel} ...`);\n return;\n }\n const lineIndex = this.lineCount;\n this.lineByStep.set(stepId, lineIndex);\n this.frameIndexByStep.set(stepId, 0);\n this.lineCount += 1;\n process.stdout.write(`\\r${baseLabel} ${this.frames[0]}\\n`);\n const timer = setInterval(() => {\n const current = this.frameIndexByStep.get(stepId);\n if (current === undefined) return;\n const next = (current + 1) % this.frames.length;\n this.frameIndexByStep.set(stepId, next);\n this.renderLine(stepId, `${baseLabel} ${this.frames[next]}`);\n }, 80);\n this.timerByStep.set(stepId, timer);\n }\n\n complete(stepId: string, title: string, ok: boolean, detail: string, elapsedMs: number): void {\n const baseLabel = `[startup] ${title}`;\n const mark = ok ? \"OK\" : \"ERR\";\n const detailPart = detail.trim().length > 0 ? ` ${detail}` : \"\";\n const finalLine = `${mark} ${baseLabel}${detailPart}${formatDurationMs(elapsedMs)}`;\n const timer = this.timerByStep.get(stepId);\n if (timer) {\n clearInterval(timer);\n this.timerByStep.delete(stepId);\n }\n this.frameIndexByStep.delete(stepId);\n if (!this.isDynamic) {\n console.log(finalLine);\n return;\n }\n this.renderLine(stepId, finalLine);\n }\n\n private renderLine(stepId: string, line: string): void {\n const lineIndex = this.lineByStep.get(stepId);\n if (lineIndex === undefined) return;\n const up = this.lineCount - lineIndex;\n if (up <= 0) return;\n process.stdout.write(`\\x1b[${up}A\\r\\x1b[2K${line}\\x1b[${up}B\\r`);\n }\n}\n\nexport async function runStartupStep<T>(\n progress: StartupProgressRenderer,\n title: string,\n fn: () => Promise<T> | T,\n formatResult?: (result: T) => string,\n): Promise<T> {\n const stepId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const startedAt = Date.now();\n progress.start(stepId, title);\n\n try {\n const result = await fn();\n const detail = formatResult ? formatResult(result) : \"\";\n const elapsed = Date.now() - startedAt;\n progress.complete(stepId, title, true, detail, elapsed);\n return result;\n } catch (error) {\n const elapsed = Date.now() - startedAt;\n progress.complete(stepId, title, false, toErrorMessage(error), elapsed);\n throw error;\n }\n}\n\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseYamlContent
|
|
3
|
+
} from "./chunk-X4TDNR4V.js";
|
|
4
|
+
|
|
5
|
+
// src/utils/deep-merge.ts
|
|
6
|
+
function deepMerge(target, ...sources) {
|
|
7
|
+
for (const src of sources) {
|
|
8
|
+
if (!src || typeof src !== "object") continue;
|
|
9
|
+
for (const k of Object.keys(src)) {
|
|
10
|
+
const v = src[k];
|
|
11
|
+
if (v === void 0) continue;
|
|
12
|
+
const t = target[k];
|
|
13
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v) && t !== null && typeof t === "object" && !Array.isArray(t)) {
|
|
14
|
+
deepMerge(t, v);
|
|
15
|
+
} else {
|
|
16
|
+
target[k] = v;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return target;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/utils/agent-result.ts
|
|
24
|
+
function extractLastMessageText(result) {
|
|
25
|
+
const r = result;
|
|
26
|
+
const messages = r?.messages ?? r;
|
|
27
|
+
const lastContent = Array.isArray(messages) && messages.length > 0 ? messages.slice(-1)[0]?.content : r?.message?.content;
|
|
28
|
+
if (typeof lastContent === "string") return lastContent;
|
|
29
|
+
if (typeof lastContent === "object" && lastContent !== null && "text" in lastContent)
|
|
30
|
+
return String(lastContent.text);
|
|
31
|
+
return JSON.stringify(r ?? "");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// src/utils/object.ts
|
|
35
|
+
function stripNullishObjectFields(value) {
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
return value.map((item) => stripNullishObjectFields(item));
|
|
38
|
+
}
|
|
39
|
+
if (value && typeof value === "object") {
|
|
40
|
+
const out = {};
|
|
41
|
+
for (const [k, v] of Object.entries(value)) {
|
|
42
|
+
if (v === null || v === void 0) continue;
|
|
43
|
+
out[k] = stripNullishObjectFields(v);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/utils/log.ts
|
|
51
|
+
function summarizeForLog(value, maxLen = 220) {
|
|
52
|
+
const raw = typeof value === "string" ? value : value == null ? "" : (() => {
|
|
53
|
+
try {
|
|
54
|
+
return JSON.stringify(value);
|
|
55
|
+
} catch {
|
|
56
|
+
return String(value);
|
|
57
|
+
}
|
|
58
|
+
})();
|
|
59
|
+
const compact = raw.replace(/\s+/g, " ").trim();
|
|
60
|
+
if (!compact) return "(empty)";
|
|
61
|
+
return compact.length > maxLen ? compact.slice(0, maxLen) + "..." : compact;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/utils/parsing.ts
|
|
65
|
+
function asRecord(value) {
|
|
66
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
67
|
+
}
|
|
68
|
+
function asTrimmedString(value) {
|
|
69
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
70
|
+
}
|
|
71
|
+
function parseJsonObject(value) {
|
|
72
|
+
if (typeof value !== "string") return null;
|
|
73
|
+
try {
|
|
74
|
+
return asRecord(JSON.parse(value));
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function extractTextFromLlmOutput(output) {
|
|
80
|
+
const content = output?.content;
|
|
81
|
+
if (typeof content === "string") return content.trim();
|
|
82
|
+
if (Array.isArray(content)) {
|
|
83
|
+
return content.map((part) => {
|
|
84
|
+
if (typeof part === "string") return part;
|
|
85
|
+
if (part && typeof part === "object" && "text" in part) {
|
|
86
|
+
const text = part.text;
|
|
87
|
+
return typeof text === "string" ? text : "";
|
|
88
|
+
}
|
|
89
|
+
return "";
|
|
90
|
+
}).join(" ").trim();
|
|
91
|
+
}
|
|
92
|
+
if (typeof output === "string") return output.trim();
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// src/utils/selection/tool-registry.ts
|
|
97
|
+
function isToolContainer(value) {
|
|
98
|
+
return Boolean(value && typeof value === "object" && Array.isArray(value.tools));
|
|
99
|
+
}
|
|
100
|
+
function isNamedToolLike(value) {
|
|
101
|
+
return Boolean(
|
|
102
|
+
value && typeof value === "object" && typeof value.name === "string"
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
function normalizeToolList(raw, guard) {
|
|
106
|
+
if (Array.isArray(raw)) {
|
|
107
|
+
if (guard) return raw.filter((tool) => guard(tool));
|
|
108
|
+
return raw.filter((tool) => isNamedToolLike(tool));
|
|
109
|
+
}
|
|
110
|
+
if (isToolContainer(raw)) {
|
|
111
|
+
return normalizeToolList(raw.tools, guard);
|
|
112
|
+
}
|
|
113
|
+
return [];
|
|
114
|
+
}
|
|
115
|
+
function shortToolName(name) {
|
|
116
|
+
const parts = name.split(".");
|
|
117
|
+
return parts[parts.length - 1] ?? name;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/utils/override-with-config.ts
|
|
121
|
+
function overrideWithConfig(defaults, config) {
|
|
122
|
+
const c = config != null && typeof config === "object" && !Array.isArray(config) ? config : {};
|
|
123
|
+
const out = { ...defaults };
|
|
124
|
+
for (const key of Object.keys(defaults)) {
|
|
125
|
+
if (key in c && c[key] !== void 0) {
|
|
126
|
+
out[key] = c[key];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/utils/frontmatter.ts
|
|
133
|
+
function parseMarkdownYamlFrontmatter(content, filePath) {
|
|
134
|
+
const trimmed = content.trimStart();
|
|
135
|
+
if (!trimmed.startsWith("---")) {
|
|
136
|
+
throw new Error(`Markdown must start with YAML frontmatter (---): ${filePath}`);
|
|
137
|
+
}
|
|
138
|
+
const endIndex = trimmed.indexOf("\n---", 3);
|
|
139
|
+
if (endIndex === -1) {
|
|
140
|
+
throw new Error(`Markdown frontmatter is not closed (missing closing ---): ${filePath}`);
|
|
141
|
+
}
|
|
142
|
+
const yamlBlock = trimmed.slice(4, endIndex).trim();
|
|
143
|
+
let raw;
|
|
144
|
+
try {
|
|
145
|
+
raw = parseYamlContent(yamlBlock, { substituteEnv: false });
|
|
146
|
+
} catch (err) {
|
|
147
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
148
|
+
throw new Error(`Invalid YAML frontmatter in ${filePath}: ${message}`);
|
|
149
|
+
}
|
|
150
|
+
if (raw == null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
151
|
+
throw new Error(`YAML frontmatter must be an object (key: value): ${filePath}`);
|
|
152
|
+
}
|
|
153
|
+
const body = trimmed.slice(endIndex + 4).trim();
|
|
154
|
+
return { frontmatter: raw, body };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/utils/selection/tool-choice.ts
|
|
158
|
+
function applyDefaultToolChoice(model) {
|
|
159
|
+
const target = model;
|
|
160
|
+
const original = target.bindTools?.bind(model);
|
|
161
|
+
if (!original) return;
|
|
162
|
+
target.bindTools = function(tools, opts) {
|
|
163
|
+
return original(tools, { ...opts, tool_choice: "auto" });
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export {
|
|
168
|
+
deepMerge,
|
|
169
|
+
extractLastMessageText,
|
|
170
|
+
stripNullishObjectFields,
|
|
171
|
+
summarizeForLog,
|
|
172
|
+
asRecord,
|
|
173
|
+
asTrimmedString,
|
|
174
|
+
parseJsonObject,
|
|
175
|
+
extractTextFromLlmOutput,
|
|
176
|
+
normalizeToolList,
|
|
177
|
+
shortToolName,
|
|
178
|
+
overrideWithConfig,
|
|
179
|
+
parseMarkdownYamlFrontmatter,
|
|
180
|
+
applyDefaultToolChoice
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=chunk-OTWARMTU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/deep-merge.ts","../src/utils/agent-result.ts","../src/utils/object.ts","../src/utils/log.ts","../src/utils/parsing.ts","../src/utils/selection/tool-registry.ts","../src/utils/override-with-config.ts","../src/utils/frontmatter.ts","../src/utils/selection/tool-choice.ts"],"sourcesContent":["/**\n * Deep merge: overwrite target with each source (only defined values). Nested objects merged recursively.\n */\n\nexport function deepMerge<T extends object>(target: T, ...sources: Partial<T>[]): T {\n for (const src of sources) {\n if (!src || typeof src !== \"object\") continue;\n for (const k of Object.keys(src) as (keyof T)[]) {\n const v = src[k];\n if (v === undefined) continue;\n const t = (target as Record<keyof T, unknown>)[k];\n if (\n v !== null &&\n typeof v === \"object\" &&\n !Array.isArray(v) &&\n t !== null &&\n typeof t === \"object\" &&\n !Array.isArray(t)\n ) {\n deepMerge(t as object, v as object);\n } else {\n (target as Record<keyof T, unknown>)[k] = v;\n }\n }\n }\n return target;\n}\n","/**\n * Extract the final assistant text from a LangChain/DeepAgents invoke result.\n */\nexport function extractLastMessageText(result: unknown): string {\n const r = result as { messages?: unknown; message?: { content?: string } } | null | undefined;\n const messages = r?.messages ?? r;\n const lastContent =\n Array.isArray(messages) && messages.length > 0\n ? (messages as { content?: string }[]).slice(-1)[0]?.content\n : r?.message?.content;\n if (typeof lastContent === \"string\") return lastContent;\n if (\n typeof lastContent === \"object\" &&\n lastContent !== null &&\n \"text\" in (lastContent as object)\n )\n return String((lastContent as { text: string }).text);\n return JSON.stringify(r ?? \"\");\n}\n","/**\n * Recursively remove null and undefined fields from object values.\n */\nexport function stripNullishObjectFields(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => stripNullishObjectFields(item));\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n if (v === null || v === undefined) continue;\n out[k] = stripNullishObjectFields(v);\n }\n return out;\n }\n return value;\n}\n","export function summarizeForLog(value: unknown, maxLen = 220): string {\n const raw =\n typeof value === \"string\"\n ? value\n : value == null\n ? \"\"\n : (() => {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n })();\n const compact = raw.replace(/\\s+/g, \" \").trim();\n if (!compact) return \"(empty)\";\n return compact.length > maxLen ? compact.slice(0, maxLen) + \"...\" : compact;\n}\n\n","export function asRecord(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nexport function asTrimmedString(value: unknown): string | null {\n return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : null;\n}\n\nexport function parseJsonObject(value: unknown): Record<string, unknown> | null {\n if (typeof value !== \"string\") return null;\n try {\n return asRecord(JSON.parse(value));\n } catch {\n return null;\n }\n}\n\nexport function extractTextFromLlmOutput(output: unknown): string {\n const content = (output as { content?: unknown } | null)?.content;\n if (typeof content === \"string\") return content.trim();\n if (Array.isArray(content)) {\n return content\n .map((part) => {\n if (typeof part === \"string\") return part;\n if (part && typeof part === \"object\" && \"text\" in part) {\n const text = (part as { text?: unknown }).text;\n return typeof text === \"string\" ? text : \"\";\n }\n return \"\";\n })\n .join(\" \")\n .trim();\n }\n if (typeof output === \"string\") return output.trim();\n return \"\";\n}\n\n","export type NamedToolLike = {\n name: string;\n};\n\nfunction isToolContainer(value: unknown): value is { tools: unknown[] } {\n return Boolean(value && typeof value === \"object\" && Array.isArray((value as { tools?: unknown[] }).tools));\n}\n\nfunction isNamedToolLike(value: unknown): value is NamedToolLike {\n return Boolean(\n value\n && typeof value === \"object\"\n && typeof (value as { name?: unknown }).name === \"string\",\n );\n}\n\nexport function normalizeToolList<T extends NamedToolLike = NamedToolLike>(\n raw: unknown,\n guard?: (value: unknown) => value is T,\n): T[] {\n if (Array.isArray(raw)) {\n if (guard) return raw.filter((tool): tool is T => guard(tool));\n return raw.filter((tool): tool is T => isNamedToolLike(tool));\n }\n if (isToolContainer(raw)) {\n return normalizeToolList(raw.tools, guard);\n }\n return [];\n}\n\nexport function shortToolName(name: string): string {\n const parts = name.split(\".\");\n return parts[parts.length - 1] ?? name;\n}\n\n","/**\n * Overlay config values on top of typed defaults.\n * Only keys present in `defaults` are eligible for override; values from\n * `config` are applied only when they are not undefined.\n *\n * Typical use: set safe hardcoded defaults, then call overrideWithConfig to\n * let user/extension config win where provided.\n *\n * @example\n * const cfg = overrideWithConfig({ timeoutMs: 5000, maxBytes: 1048576 }, ctx.config);\n */\nexport function overrideWithConfig<T extends Record<string, unknown>>(\n defaults: T,\n config: unknown,\n): T {\n const c =\n config != null && typeof config === \"object\" && !Array.isArray(config)\n ? (config as Record<string, unknown>)\n : {};\n const out = { ...defaults };\n for (const key of Object.keys(defaults)) {\n if (key in c && c[key] !== undefined) {\n (out as Record<string, unknown>)[key] = c[key];\n }\n }\n return out;\n}\n","import { parseYamlContent } from \"../config/index.js\";\n\nexport interface ParsedMarkdownFrontmatter {\n frontmatter: Record<string, unknown>;\n body: string;\n}\n\n/**\n * Parse markdown content with YAML frontmatter:\n * ---\n * key: value\n * ---\n * body...\n */\nexport function parseMarkdownYamlFrontmatter(content: string, filePath: string): ParsedMarkdownFrontmatter {\n const trimmed = content.trimStart();\n if (!trimmed.startsWith(\"---\")) {\n throw new Error(`Markdown must start with YAML frontmatter (---): ${filePath}`);\n }\n\n const endIndex = trimmed.indexOf(\"\\n---\", 3);\n if (endIndex === -1) {\n throw new Error(`Markdown frontmatter is not closed (missing closing ---): ${filePath}`);\n }\n\n const yamlBlock = trimmed.slice(4, endIndex).trim();\n let raw: unknown;\n try {\n raw = parseYamlContent<unknown>(yamlBlock, { substituteEnv: false });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new Error(`Invalid YAML frontmatter in ${filePath}: ${message}`);\n }\n\n if (raw == null || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(`YAML frontmatter must be an object (key: value): ${filePath}`);\n }\n\n const body = trimmed.slice(endIndex + 4).trim();\n return { frontmatter: raw as Record<string, unknown>, body };\n}\n","export function applyDefaultToolChoice(model: unknown): void {\n const target = model as {\n bindTools?: (tools: unknown, opts?: Record<string, unknown>) => unknown;\n };\n const original = target.bindTools?.bind(model);\n if (!original) return;\n target.bindTools = function (tools: unknown, opts?: Record<string, unknown>) {\n return original(tools, { ...opts, tool_choice: \"auto\" });\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/utils/checksum.ts
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
function computeChecksum(input, options = {}) {
|
|
4
|
+
const algorithm = options.algorithm ?? "sha256";
|
|
5
|
+
const digest = createHash(algorithm).update(input).digest("hex");
|
|
6
|
+
const length = options.length;
|
|
7
|
+
if (!Number.isInteger(length) || length === void 0) return digest;
|
|
8
|
+
if (length <= 0) return "";
|
|
9
|
+
return digest.slice(0, length);
|
|
10
|
+
}
|
|
11
|
+
function createChecksumAccumulator(options = {}) {
|
|
12
|
+
const algorithm = options.algorithm ?? "sha256";
|
|
13
|
+
const hasher = createHash(algorithm);
|
|
14
|
+
return {
|
|
15
|
+
update(input) {
|
|
16
|
+
hasher.update(input);
|
|
17
|
+
},
|
|
18
|
+
digest(length) {
|
|
19
|
+
const full = hasher.digest("hex");
|
|
20
|
+
if (!Number.isInteger(length) || length === void 0) return full;
|
|
21
|
+
if (length <= 0) return "";
|
|
22
|
+
return full.slice(0, length);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
computeChecksum,
|
|
29
|
+
createChecksumAccumulator
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=chunk-QG6CT2GZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/checksum.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nexport interface ComputeChecksumOptions {\n algorithm?: \"sha256\";\n length?: number;\n}\n\nexport interface ChecksumAccumulator {\n update(input: string | Uint8Array): void;\n digest(length?: number): string;\n}\n\n/**\n * Deterministic short checksum for signatures/tokens.\n */\nexport function computeChecksum(input: string, options: ComputeChecksumOptions = {}): string {\n const algorithm = options.algorithm ?? \"sha256\";\n const digest = createHash(algorithm).update(input).digest(\"hex\");\n const length = options.length;\n if (!Number.isInteger(length) || length === undefined) return digest;\n if (length <= 0) return \"\";\n return digest.slice(0, length);\n}\n\n/**\n * Create an incremental checksum accumulator for streaming/chunked data.\n */\nexport function createChecksumAccumulator(options: Omit<ComputeChecksumOptions, \"length\"> = {}): ChecksumAccumulator {\n const algorithm = options.algorithm ?? \"sha256\";\n const hasher = createHash(algorithm);\n return {\n update(input: string | Uint8Array): void {\n hasher.update(input);\n },\n digest(length?: number): string {\n const full = hasher.digest(\"hex\");\n if (!Number.isInteger(length) || length === undefined) return full;\n if (length <= 0) return \"\";\n return full.slice(0, length);\n },\n };\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAepB,SAAS,gBAAgB,OAAe,UAAkC,CAAC,GAAW;AAC3F,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,SAAS,WAAW,SAAS,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAC/D,QAAM,SAAS,QAAQ;AACvB,MAAI,CAAC,OAAO,UAAU,MAAM,KAAK,WAAW,OAAW,QAAO;AAC9D,MAAI,UAAU,EAAG,QAAO;AACxB,SAAO,OAAO,MAAM,GAAG,MAAM;AAC/B;AAKO,SAAS,0BAA0B,UAAkD,CAAC,GAAwB;AACnH,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,SAAS,WAAW,SAAS;AACnC,SAAO;AAAA,IACL,OAAO,OAAkC;AACvC,aAAO,OAAO,KAAK;AAAA,IACrB;AAAA,IACA,OAAO,QAAyB;AAC9B,YAAM,OAAO,OAAO,OAAO,KAAK;AAChC,UAAI,CAAC,OAAO,UAAU,MAAM,KAAK,WAAW,OAAW,QAAO;AAC9D,UAAI,UAAU,EAAG,QAAO;AACxB,aAAO,KAAK,MAAM,GAAG,MAAM;AAAA,IAC7B;AAAA,EACF;AACF;","names":[]}
|