@botbotgo/common 1.0.0 → 1.0.2

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.
@@ -67,46 +67,50 @@ function parseYamlContent(content, options = {}) {
67
67
  missingEnv: options.missingEnv ?? "keep"
68
68
  });
69
69
  }
70
- function readFromCache(filePath, mtimeMs) {
70
+ function buildCacheVersion(fileStat) {
71
+ const mtime = fileStat.mtimeNs ?? (typeof fileStat.mtimeMs === "bigint" ? fileStat.mtimeMs : BigInt(Math.trunc(fileStat.mtimeMs * 1e6)));
72
+ return `${mtime}:${fileStat.size.toString()}`;
73
+ }
74
+ function readFromCache(filePath, version) {
71
75
  const cached = YAML_CACHE.get(filePath);
72
76
  if (!cached) return void 0;
73
- if (cached.mtimeMs !== mtimeMs) return void 0;
77
+ if (cached.version !== version) return void 0;
74
78
  return cached.value;
75
79
  }
76
- function writeCache(filePath, mtimeMs, value) {
77
- YAML_CACHE.set(filePath, { mtimeMs, value });
80
+ function writeCache(filePath, version, value) {
81
+ YAML_CACHE.set(filePath, { version, value });
78
82
  }
79
83
  function loadYamlFileSync(filePath, options = {}) {
80
84
  const absPath = path2.resolve(filePath);
81
85
  if (!existsSync(absPath)) return void 0;
82
86
  const useCache = options.cache === true;
83
- const fileStat = statSync(absPath);
87
+ const fileStat = statSync(absPath, { bigint: true });
84
88
  if (useCache) {
85
- const cached = readFromCache(absPath, fileStat.mtimeMs);
89
+ const cached = readFromCache(absPath, buildCacheVersion(fileStat));
86
90
  if (cached !== void 0) return cached;
87
91
  }
88
92
  const content = readFileSync(absPath, "utf-8");
89
93
  const parsed = parseYamlContent(content, options);
90
- if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
94
+ if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);
91
95
  return parsed;
92
96
  }
93
97
  async function loadYamlFile(filePath, options = {}) {
94
98
  const absPath = path2.resolve(filePath);
95
99
  let fileStat;
96
100
  try {
97
- fileStat = await stat(absPath);
101
+ fileStat = await stat(absPath, { bigint: true });
98
102
  } catch (err) {
99
103
  if (err?.code === "ENOENT") return void 0;
100
104
  throw err;
101
105
  }
102
106
  const useCache = options.cache === true;
103
107
  if (useCache) {
104
- const cached = readFromCache(absPath, fileStat.mtimeMs);
108
+ const cached = readFromCache(absPath, buildCacheVersion(fileStat));
105
109
  if (cached !== void 0) return cached;
106
110
  }
107
111
  const content = await readFile(absPath, "utf-8");
108
112
  const parsed = parseYamlContent(content, options);
109
- if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);
113
+ if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);
110
114
  return parsed;
111
115
  }
112
116
 
@@ -203,4 +207,4 @@ export {
203
207
  isRefNode,
204
208
  resolveKindResourceFile
205
209
  };
206
- //# sourceMappingURL=chunk-X4TDNR4V.js.map
210
+ //# sourceMappingURL=chunk-2HMNFLD4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/yaml.ts","../src/config/path.ts","../src/config/kind.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { resolveConfigPath } from \"./path.js\";\n\nexport interface YamlEnvOptions {\n substituteEnv?: boolean;\n missingEnv?: \"keep\" | \"empty\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface LoadYamlOptions extends YamlEnvOptions {\n cache?: boolean;\n}\n\nexport interface LoadModuleConfigOptions<TConfig, TRaw = Record<string, unknown>> {\n path?: string;\n defaultPath?: string;\n appRoot?: string;\n yaml?: LoadYamlOptions;\n unwrapSpec?: boolean;\n fallback: TConfig;\n normalize?: (raw: TRaw, meta: { resolvedPath: string }) => TConfig;\n}\n\ninterface CacheEntry {\n version: string;\n value: unknown;\n}\n\nconst YAML_CACHE = new Map<string, CacheEntry>();\n\nexport function clearYamlFileCache(): void {\n YAML_CACHE.clear();\n}\n\nfunction substituteEnvInString(\n input: string,\n env: NodeJS.ProcessEnv,\n missingEnv: \"keep\" | \"empty\",\n): string {\n return input.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => {\n const value = env[name];\n if (value !== undefined) return value;\n return missingEnv === \"empty\" ? \"\" : `\\${${name}}`;\n });\n}\n\nfunction substituteEnvInValue(\n input: unknown,\n options: { env: NodeJS.ProcessEnv; missingEnv: \"keep\" | \"empty\" },\n): unknown {\n if (typeof input === \"string\") {\n return substituteEnvInString(input, options.env, options.missingEnv);\n }\n if (Array.isArray(input)) {\n return input.map((item) => substituteEnvInValue(item, options));\n }\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) {\n out[k] = substituteEnvInValue(v, options);\n }\n return out;\n }\n return input;\n}\n\nexport function parseYamlContent<T = unknown>(\n content: string,\n options: YamlEnvOptions = {},\n): T {\n const parsed = parseYaml(content) as unknown;\n if (options.substituteEnv === false) return parsed as T;\n return substituteEnvInValue(parsed, {\n env: options.env ?? process.env,\n missingEnv: options.missingEnv ?? \"keep\",\n }) as T;\n}\n\nfunction buildCacheVersion(\n fileStat: { mtimeNs?: bigint; mtimeMs: number | bigint; size: number | bigint },\n): string {\n const mtime = fileStat.mtimeNs\n ?? (typeof fileStat.mtimeMs === \"bigint\"\n ? fileStat.mtimeMs\n : BigInt(Math.trunc(fileStat.mtimeMs * 1_000_000)));\n return `${mtime}:${fileStat.size.toString()}`;\n}\n\nfunction readFromCache(filePath: string, version: string): unknown | undefined {\n const cached = YAML_CACHE.get(filePath);\n if (!cached) return undefined;\n if (cached.version !== version) return undefined;\n return cached.value;\n}\n\nfunction writeCache(filePath: string, version: string, value: unknown): void {\n YAML_CACHE.set(filePath, { version, value });\n}\n\nexport function loadYamlFileSync<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): T | undefined {\n const absPath = path.resolve(filePath);\n if (!existsSync(absPath)) return undefined;\n const useCache = options.cache === true;\n const fileStat = statSync(absPath, { bigint: true });\n if (useCache) {\n const cached = readFromCache(absPath, buildCacheVersion(fileStat));\n if (cached !== undefined) return cached as T;\n }\n const content = readFileSync(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);\n return parsed;\n}\n\nexport async function loadYamlFile<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<T | undefined> {\n const absPath = path.resolve(filePath);\n let fileStat;\n try {\n fileStat = await stat(absPath, { bigint: true });\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") return undefined;\n throw err;\n }\n const useCache = options.cache === true;\n if (useCache) {\n const cached = readFromCache(absPath, buildCacheVersion(fileStat));\n if (cached !== undefined) return cached as T;\n }\n const content = await readFile(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, buildCacheVersion(fileStat), parsed);\n return parsed;\n}\n\nexport async function loadYamlObject(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<Record<string, unknown>> {\n const parsed = await loadYamlFile<unknown>(filePath, options);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return {};\n}\n\n/**\n * Generic module config loader:\n * 1) resolve path (path || defaultPath) relative to appRoot\n * 2) load YAML as object\n * 3) normalize into module-owned config interface\n * 4) fallback when missing/invalid\n */\nexport async function loadModuleConfig<TConfig, TRaw = Record<string, unknown>>(\n options: LoadModuleConfigOptions<TConfig, TRaw>,\n): Promise<TConfig> {\n const selected = options.path ?? options.defaultPath;\n if (!selected) return options.fallback;\n\n const appRoot = options.appRoot ?? process.cwd();\n const resolvedPath = resolveConfigPath(selected, appRoot);\n const loaded = await loadYamlFile<unknown>(resolvedPath, options.yaml);\n if (!loaded || typeof loaded !== \"object\" || Array.isArray(loaded)) return options.fallback;\n const raw = options.unwrapSpec === true\n ? (\n typeof (loaded as { spec?: unknown }).spec === \"object\" &&\n (loaded as { spec?: unknown }).spec !== null &&\n !Array.isArray((loaded as { spec?: unknown }).spec)\n ? (loaded as { spec: unknown }).spec\n : loaded\n )\n : loaded;\n\n if (options.normalize) {\n return options.normalize(raw as TRaw, { resolvedPath });\n }\n return raw as TConfig;\n}\n","import path from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface ResolveConfigPathOptions {\n expandHome?: boolean;\n homeDir?: string;\n}\n\nexport type PathRef = { ref?: string };\n\nexport function isPathRef(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n (value.endsWith(\".yaml\") || value.endsWith(\".yml\"))\n );\n}\n\nexport function expandHomePath(inputPath: string, options: { homeDir?: string } = {}): string {\n const home = options.homeDir ?? homedir();\n if (inputPath === \"~\") return home;\n if (inputPath.startsWith(\"~/\")) return path.join(home, inputPath.slice(2));\n return inputPath;\n}\n\nexport function resolveConfigPath(\n pathRef: string,\n configDir: string,\n options: ResolveConfigPathOptions = {},\n): string {\n const expanded = options.expandHome === false ? pathRef : expandHomePath(pathRef, { homeDir: options.homeDir });\n return path.resolve(configDir, expanded);\n}\n\nexport function asObject(input: unknown): Record<string, unknown> | undefined {\n return typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : undefined;\n}\n\nexport function toPathRef(input: unknown): PathRef | undefined {\n if (typeof input === \"string\" && input.trim().length > 0) return { ref: input.trim() };\n const obj = asObject(input);\n if (!obj) return undefined;\n const value =\n (typeof (obj as { __filePath?: unknown }).__filePath === \"string\" &&\n (obj as { __filePath: string }).__filePath.trim().length > 0\n ? (obj as { __filePath: string }).__filePath.trim()\n : undefined) ??\n (typeof obj.ref === \"string\" && obj.ref.trim().length > 0 ? obj.ref.trim() : undefined);\n return value ? { ref: value } : undefined;\n}\n","import { dirname } from \"node:path\";\nimport { loadYamlFile, type LoadYamlOptions } from \"./yaml.js\";\nimport { asObject, resolveConfigPath } from \"./path.js\";\n\nexport interface ResourceMetadata {\n name?: string;\n labels?: Record<string, string>;\n}\n\nexport interface ResourceHeader {\n apiVersion: string;\n kind: string;\n metadata?: ResourceMetadata;\n spec: unknown;\n}\n\nexport type RefNode = { ref: string };\n\nexport type ResolvedResource<TSpec = unknown> = ResourceHeader & {\n spec: TSpec;\n __filePath: string;\n};\n\nexport interface ResolveKindResourceOptions {\n baseDir?: string;\n maxDepth?: number;\n cache?: boolean;\n yaml?: LoadYamlOptions;\n expectedKind?: string;\n expectedApiVersion?: string;\n}\n\nfunction toResourceHeader(input: unknown): ResourceHeader {\n const obj = asObject(input);\n if (!obj) throw new Error(\"Invalid config document: expected object root\");\n\n const apiVersion = typeof obj.apiVersion === \"string\" ? obj.apiVersion.trim() : \"\";\n const kind = typeof obj.kind === \"string\" ? obj.kind.trim() : \"\";\n const spec = (obj as { spec?: unknown }).spec;\n if (!apiVersion) throw new Error(\"Invalid config document: missing apiVersion\");\n if (!kind) throw new Error(\"Invalid config document: missing kind\");\n if (spec === undefined) throw new Error(\"Invalid config document: missing spec\");\n const metadataRaw = asObject(obj.metadata);\n const metadata: ResourceMetadata | undefined = metadataRaw\n ? {\n name: typeof metadataRaw.name === \"string\" ? metadataRaw.name : undefined,\n labels:\n metadataRaw.labels && typeof metadataRaw.labels === \"object\" && !Array.isArray(metadataRaw.labels)\n ? (metadataRaw.labels as Record<string, string>)\n : undefined,\n }\n : undefined;\n return { apiVersion, kind, metadata, spec };\n}\n\nexport function isRefNode(input: unknown): input is RefNode {\n const obj = asObject(input);\n return !!obj && typeof obj.ref === \"string\" && obj.ref.trim().length > 0;\n}\n\nexport async function resolveKindResourceFile<TSpec = unknown>(\n entryFile: string,\n options: ResolveKindResourceOptions = {},\n): Promise<ResolvedResource<TSpec>> {\n const baseDir = options.baseDir ?? process.cwd();\n const entryAbs = resolveConfigPath(entryFile, baseDir);\n const maxDepth = options.maxDepth ?? 50;\n const cache = new Map<string, ResolvedResource>();\n const visiting = new Set<string>();\n\n const resolveNode = async (node: unknown, currentDir: string, depth: number): Promise<unknown> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (isRefNode(node)) {\n const next = resolveConfigPath(node.ref, currentDir);\n return loadResource(next, depth + 1);\n }\n if (Array.isArray(node)) {\n return Promise.all(node.map((item) => resolveNode(item, currentDir, depth + 1)));\n }\n const obj = asObject(node);\n if (!obj) return node;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await resolveNode(v, currentDir, depth + 1);\n }\n return out;\n };\n\n const loadResource = async (absPath: string, depth: number): Promise<ResolvedResource> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (options.cache !== false) {\n const cached = cache.get(absPath);\n if (cached) return cached;\n }\n if (visiting.has(absPath)) {\n throw new Error(`Config ref cycle detected at: ${absPath}`);\n }\n visiting.add(absPath);\n try {\n const raw = await loadYamlFile(absPath, options.yaml);\n const header = toResourceHeader(raw);\n if (options.expectedApiVersion && header.apiVersion !== options.expectedApiVersion) {\n throw new Error(`Unexpected apiVersion \"${header.apiVersion}\" at ${absPath}`);\n }\n const resolvedSpec = await resolveNode(header.spec, dirname(absPath), depth + 1);\n const resolved: ResolvedResource = {\n ...header,\n spec: resolvedSpec,\n __filePath: absPath,\n };\n if (options.cache !== false) cache.set(absPath, resolved);\n return resolved;\n } finally {\n visiting.delete(absPath);\n }\n };\n\n const root = await loadResource(entryAbs, 0);\n if (options.expectedKind && root.kind !== options.expectedKind) {\n throw new Error(`Expected kind \"${options.expectedKind}\" but got \"${root.kind}\" at ${root.__filePath}`);\n }\n return root as ResolvedResource<TSpec>;\n}\n"],"mappings":";AAAA,SAAS,YAAY,cAAc,gBAAgB;AACnD,SAAS,UAAU,YAAY;AAC/B,OAAOA,WAAU;AACjB,SAAS,SAAS,iBAAiB;;;ACHnC,OAAO,UAAU;AACjB,SAAS,eAAe;AASjB,SAAS,UAAU,OAAiC;AACzD,SACE,OAAO,UAAU,YACjB,MAAM,SAAS,MACd,MAAM,SAAS,OAAO,KAAK,MAAM,SAAS,MAAM;AAErD;AAEO,SAAS,eAAe,WAAmB,UAAgC,CAAC,GAAW;AAC5F,QAAM,OAAO,QAAQ,WAAW,QAAQ;AACxC,MAAI,cAAc,IAAK,QAAO;AAC9B,MAAI,UAAU,WAAW,IAAI,EAAG,QAAO,KAAK,KAAK,MAAM,UAAU,MAAM,CAAC,CAAC;AACzE,SAAO;AACT;AAEO,SAAS,kBACd,SACA,WACA,UAAoC,CAAC,GAC7B;AACR,QAAM,WAAW,QAAQ,eAAe,QAAQ,UAAU,eAAe,SAAS,EAAE,SAAS,QAAQ,QAAQ,CAAC;AAC9G,SAAO,KAAK,QAAQ,WAAW,QAAQ;AACzC;AAEO,SAAS,SAAS,OAAqD;AAC5E,SAAO,OAAO,UAAU,YAAY,UAAU,OAAQ,QAAoC;AAC5F;AAEO,SAAS,UAAU,OAAqC;AAC7D,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,EAAG,QAAO,EAAE,KAAK,MAAM,KAAK,EAAE;AACrF,QAAM,MAAM,SAAS,KAAK;AAC1B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,SACH,OAAQ,IAAiC,eAAe,YACxD,IAA+B,WAAW,KAAK,EAAE,SAAS,IACtD,IAA+B,WAAW,KAAK,IAChD,YACH,OAAO,IAAI,QAAQ,YAAY,IAAI,IAAI,KAAK,EAAE,SAAS,IAAI,IAAI,IAAI,KAAK,IAAI;AAC/E,SAAO,QAAQ,EAAE,KAAK,MAAM,IAAI;AAClC;;;ADlBA,IAAM,aAAa,oBAAI,IAAwB;AAExC,SAAS,qBAA2B;AACzC,aAAW,MAAM;AACnB;AAEA,SAAS,sBACP,OACA,KACA,YACQ;AACR,SAAO,MAAM,QAAQ,gBAAgB,CAAC,GAAG,SAAiB;AACxD,UAAM,QAAQ,IAAI,IAAI;AACtB,QAAI,UAAU,OAAW,QAAO;AAChC,WAAO,eAAe,UAAU,KAAK,MAAM,IAAI;AAAA,EACjD,CAAC;AACH;AAEA,SAAS,qBACP,OACA,SACS;AACT,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,sBAAsB,OAAO,QAAQ,KAAK,QAAQ,UAAU;AAAA,EACrE;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,qBAAqB,MAAM,OAAO,CAAC;AAAA,EAChE;AACA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,UAAI,CAAC,IAAI,qBAAqB,GAAG,OAAO;AAAA,IAC1C;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,iBACd,SACA,UAA0B,CAAC,GACxB;AACH,QAAM,SAAS,UAAU,OAAO;AAChC,MAAI,QAAQ,kBAAkB,MAAO,QAAO;AAC5C,SAAO,qBAAqB,QAAQ;AAAA,IAClC,KAAK,QAAQ,OAAO,QAAQ;AAAA,IAC5B,YAAY,QAAQ,cAAc;AAAA,EACpC,CAAC;AACH;AAEA,SAAS,kBACP,UACQ;AACR,QAAM,QAAQ,SAAS,YACjB,OAAO,SAAS,YAAY,WAC5B,SAAS,UACT,OAAO,KAAK,MAAM,SAAS,UAAU,GAAS,CAAC;AACrD,SAAO,GAAG,KAAK,IAAI,SAAS,KAAK,SAAS,CAAC;AAC7C;AAEA,SAAS,cAAc,UAAkB,SAAsC;AAC7E,QAAM,SAAS,WAAW,IAAI,QAAQ;AACtC,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,OAAO,YAAY,QAAS,QAAO;AACvC,SAAO,OAAO;AAChB;AAEA,SAAS,WAAW,UAAkB,SAAiB,OAAsB;AAC3E,aAAW,IAAI,UAAU,EAAE,SAAS,MAAM,CAAC;AAC7C;AAEO,SAAS,iBACd,UACA,UAA2B,CAAC,GACb;AACf,QAAM,UAAUC,MAAK,QAAQ,QAAQ;AACrC,MAAI,CAAC,WAAW,OAAO,EAAG,QAAO;AACjC,QAAM,WAAW,QAAQ,UAAU;AACnC,QAAM,WAAW,SAAS,SAAS,EAAE,QAAQ,KAAK,CAAC;AACnD,MAAI,UAAU;AACZ,UAAM,SAAS,cAAc,SAAS,kBAAkB,QAAQ,CAAC;AACjE,QAAI,WAAW,OAAW,QAAO;AAAA,EACnC;AACA,QAAM,UAAU,aAAa,SAAS,OAAO;AAC7C,QAAM,SAAS,iBAAoB,SAAS,OAAO;AACnD,MAAI,SAAU,YAAW,SAAS,kBAAkB,QAAQ,GAAG,MAAM;AACrE,SAAO;AACT;AAEA,eAAsB,aACpB,UACA,UAA2B,CAAC,GACJ;AACxB,QAAM,UAAUA,MAAK,QAAQ,QAAQ;AACrC,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,KAAK,SAAS,EAAE,QAAQ,KAAK,CAAC;AAAA,EACjD,SAAS,KAAK;AACZ,QAAK,KAA+B,SAAS,SAAU,QAAO;AAC9D,UAAM;AAAA,EACR;AACA,QAAM,WAAW,QAAQ,UAAU;AACnC,MAAI,UAAU;AACZ,UAAM,SAAS,cAAc,SAAS,kBAAkB,QAAQ,CAAC;AACjE,QAAI,WAAW,OAAW,QAAO;AAAA,EACnC;AACA,QAAM,UAAU,MAAM,SAAS,SAAS,OAAO;AAC/C,QAAM,SAAS,iBAAoB,SAAS,OAAO;AACnD,MAAI,SAAU,YAAW,SAAS,kBAAkB,QAAQ,GAAG,MAAM;AACrE,SAAO;AACT;;;AE7IA,SAAS,eAAe;AAgCxB,SAAS,iBAAiB,OAAgC;AACxD,QAAM,MAAM,SAAS,KAAK;AAC1B,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,+CAA+C;AAEzE,QAAM,aAAa,OAAO,IAAI,eAAe,WAAW,IAAI,WAAW,KAAK,IAAI;AAChF,QAAM,OAAO,OAAO,IAAI,SAAS,WAAW,IAAI,KAAK,KAAK,IAAI;AAC9D,QAAM,OAAQ,IAA2B;AACzC,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,6CAA6C;AAC9E,MAAI,CAAC,KAAM,OAAM,IAAI,MAAM,uCAAuC;AAClE,MAAI,SAAS,OAAW,OAAM,IAAI,MAAM,uCAAuC;AAC/E,QAAM,cAAc,SAAS,IAAI,QAAQ;AACzC,QAAM,WAAyC,cAC3C;AAAA,IACE,MAAM,OAAO,YAAY,SAAS,WAAW,YAAY,OAAO;AAAA,IAChE,QACE,YAAY,UAAU,OAAO,YAAY,WAAW,YAAY,CAAC,MAAM,QAAQ,YAAY,MAAM,IAC5F,YAAY,SACb;AAAA,EACR,IACA;AACJ,SAAO,EAAE,YAAY,MAAM,UAAU,KAAK;AAC5C;AAEO,SAAS,UAAU,OAAkC;AAC1D,QAAM,MAAM,SAAS,KAAK;AAC1B,SAAO,CAAC,CAAC,OAAO,OAAO,IAAI,QAAQ,YAAY,IAAI,IAAI,KAAK,EAAE,SAAS;AACzE;AAEA,eAAsB,wBACpB,WACA,UAAsC,CAAC,GACL;AAClC,QAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;AAC/C,QAAM,WAAW,kBAAkB,WAAW,OAAO;AACrD,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,QAAQ,oBAAI,IAA8B;AAChD,QAAM,WAAW,oBAAI,IAAY;AAEjC,QAAM,cAAc,OAAO,MAAe,YAAoB,UAAoC;AAChG,QAAI,QAAQ,SAAU,OAAM,IAAI,MAAM,2CAA2C,QAAQ,EAAE;AAC3F,QAAI,UAAU,IAAI,GAAG;AACnB,YAAM,OAAO,kBAAkB,KAAK,KAAK,UAAU;AACnD,aAAO,aAAa,MAAM,QAAQ,CAAC;AAAA,IACrC;AACA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO,QAAQ,IAAI,KAAK,IAAI,CAAC,SAAS,YAAY,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC;AAAA,IACjF;AACA,UAAM,MAAM,SAAS,IAAI;AACzB,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,MAA+B,CAAC;AACtC,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACxC,UAAI,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,QAAQ,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAe,OAAO,SAAiB,UAA6C;AACxF,QAAI,QAAQ,SAAU,OAAM,IAAI,MAAM,2CAA2C,QAAQ,EAAE;AAC3F,QAAI,QAAQ,UAAU,OAAO;AAC3B,YAAM,SAAS,MAAM,IAAI,OAAO;AAChC,UAAI,OAAQ,QAAO;AAAA,IACrB;AACA,QAAI,SAAS,IAAI,OAAO,GAAG;AACzB,YAAM,IAAI,MAAM,iCAAiC,OAAO,EAAE;AAAA,IAC5D;AACA,aAAS,IAAI,OAAO;AACpB,QAAI;AACF,YAAM,MAAM,MAAM,aAAa,SAAS,QAAQ,IAAI;AACpD,YAAM,SAAS,iBAAiB,GAAG;AACnC,UAAI,QAAQ,sBAAsB,OAAO,eAAe,QAAQ,oBAAoB;AAClF,cAAM,IAAI,MAAM,0BAA0B,OAAO,UAAU,QAAQ,OAAO,EAAE;AAAA,MAC9E;AACA,YAAM,eAAe,MAAM,YAAY,OAAO,MAAM,QAAQ,OAAO,GAAG,QAAQ,CAAC;AAC/E,YAAM,WAA6B;AAAA,QACjC,GAAG;AAAA,QACH,MAAM;AAAA,QACN,YAAY;AAAA,MACd;AACA,UAAI,QAAQ,UAAU,MAAO,OAAM,IAAI,SAAS,QAAQ;AACxD,aAAO;AAAA,IACT,UAAE;AACA,eAAS,OAAO,OAAO;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,OAAO,MAAM,aAAa,UAAU,CAAC;AAC3C,MAAI,QAAQ,gBAAgB,KAAK,SAAS,QAAQ,cAAc;AAC9D,UAAM,IAAI,MAAM,kBAAkB,QAAQ,YAAY,cAAc,KAAK,IAAI,QAAQ,KAAK,UAAU,EAAE;AAAA,EACxG;AACA,SAAO;AACT;","names":["path","path"]}
@@ -3,7 +3,7 @@ import {
3
3
  asTrimmedString,
4
4
  parseJsonObject,
5
5
  shortToolName
6
- } from "./chunk-OTWARMTU.js";
6
+ } from "./chunk-OJWAEVSP.js";
7
7
  import {
8
8
  AgentContextTokens
9
9
  } from "./chunk-H5BG6SXW.js";
@@ -291,12 +291,13 @@ function buildTreeLines(event, payload, currentRunThread, toolCalls) {
291
291
  if (id) {
292
292
  toolCalls.delete(id);
293
293
  }
294
+ const fallbackToolName = event.name === "agent.runtime2.tool.call.blocked" ? to : from;
294
295
  const icon = event.name === "agent.runtime2.tool.call.done" ? "OK" : event.name === "agent.runtime2.tool.call.blocked" ? "BLOCKED" : "ERROR";
295
296
  const combined = compactFields([
296
- summarizeToolArgs(remembered?.args),
297
+ summarizeToolArgs(remembered?.args ?? asRecord2(payload?.args)),
297
298
  details
298
299
  ]);
299
- return [`\u251C\u2500 ${icon} ${remembered?.toolName ?? from}${combined ? ` | ${combined}` : ""}`];
300
+ return [`\u251C\u2500 ${icon} ${remembered?.toolName ?? fallbackToolName}${combined ? ` | ${combined}` : ""}`];
300
301
  }
301
302
  const prefix = currentRunThread ? "\u251C\u2500" : "\u2022";
302
303
  return [`${prefix} ${from} -> ${to} | ${action}${suffix}`];
@@ -460,4 +461,4 @@ export {
460
461
  createAgentEventBus,
461
462
  createConsoleAgentEventListener
462
463
  };
463
- //# sourceMappingURL=chunk-RUIAZ7GO.js.map
464
+ //# sourceMappingURL=chunk-6VW5AW43.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/events/progress-listener.ts","../src/events/runtime2-tree-listener.ts","../src/events/index.ts"],"sourcesContent":["import type { AgentEvent, AgentEventListener } from \"./index.js\";\nimport { asRecord, asTrimmedString, parseJsonObject, shortToolName } from \"../utils/index.js\";\n\ninterface ToolStep {\n action: string;\n startedAtMs: number;\n}\n\ninterface ProgressState {\n runStartedAtMs: number | null;\n startedSteps: number;\n completedSteps: number;\n currentStep: number;\n steps: Map<number, ToolStep>;\n pendingStepNumbers: number[];\n}\n\nexport interface ProgressEventListenerOptions {\n writer?: (line: string) => void;\n runLabelReact?: string;\n runLabelDeep?: string;\n reasonForAction?: (action: string) => string | null;\n}\n\nfunction formatElapsed(ms: number): string {\n return `${Math.max(0, Math.round(ms))}ms`;\n}\n\nfunction formatStepNumber(stepNumber: number): string {\n return String(Math.max(0, stepNumber)).padStart(2, \"0\");\n}\n\nfunction hasAny(record: Record<string, unknown>, keys: string[]): boolean {\n return keys.some((key) => key in record);\n}\n\nfunction summarizeAction(args: unknown, toolName: string, fallback: string): string {\n const record = asRecord(args) ?? parseJsonObject(args);\n if (!record) return fallback;\n const tool = shortToolName(toolName);\n const command = asTrimmedString(record.command);\n const path = asTrimmedString(record.path);\n const isListDirShape = hasAny(record, [\"maxEntries\", \"recursive\", \"maxDepth\", \"includeHidden\"]);\n const isReadTextShape = hasAny(record, [\"maxBytes\", \"startLine\", \"endLine\", \"encoding\"]);\n if (tool === \"runCommand\" && command) return `run command: ${command}`;\n if (tool.includes(\"itermRunCommandInSession\") && command) return `run command: ${command}`;\n if (tool === \"listDir\" || (Boolean(path) && isListDirShape)) {\n if (!path || path === \".\") return \"list directory\";\n return `list directory: ${path}`;\n }\n if (tool === \"readText\" || (Boolean(path) && isReadTextShape)) {\n if (!path) return \"read file\";\n return `read file: ${path}`;\n }\n if (command) return `run command: ${command}`;\n const query = asTrimmedString(record.query);\n if (query) return `search/query: ${query}`;\n if (path) return `read path: ${path}`;\n return fallback;\n}\n\nfunction getResultError(payload: unknown): string | null {\n const payloadRecord = asRecord(payload);\n const result = payloadRecord?.result;\n const resultRecord = asRecord(result) ?? parseJsonObject(result);\n const nestedResult = asRecord(resultRecord?.result);\n return asTrimmedString(nestedResult?.error) ?? asTrimmedString(resultRecord?.error);\n}\n\nfunction getResultPreview(payload: unknown): string | null {\n const payloadRecord = asRecord(payload);\n const directPreview = asTrimmedString(payloadRecord?.resultPreview);\n if (directPreview) return directPreview;\n\n const result = payloadRecord?.result;\n const resultRecord = asRecord(result) ?? parseJsonObject(result);\n const nestedResult = asRecord(resultRecord?.result);\n const preview =\n asTrimmedString(nestedResult?.outputText)\n ?? asTrimmedString(nestedResult?.output)\n ?? asTrimmedString(resultRecord?.output)\n ?? asTrimmedString(resultRecord?.outputText);\n return preview ? preview.replace(/\\s+/g, \" \").trim() : null;\n}\n\nfunction writeProgress(writer: (line: string) => void, state: ProgressState): void {\n writer(` progress ${state.completedSteps}/${state.startedSteps}`);\n}\n\nfunction onRunStart(writer: (line: string) => void, state: ProgressState, runLabelText: string): void {\n state.runStartedAtMs = Date.now();\n state.startedSteps = 0;\n state.completedSteps = 0;\n state.currentStep = 0;\n state.steps.clear();\n state.pendingStepNumbers = [];\n writer(\"\");\n writer(`=== Steps: ${runLabelText} ===`);\n writer(`[${formatStepNumber(0)}] ▶ understand request and plan next action`);\n}\n\nfunction onRunDone(writer: (line: string) => void, state: ProgressState): void {\n const elapsed = state.runStartedAtMs === null ? \"?\" : formatElapsed(Date.now() - state.runStartedAtMs);\n writer(`[${formatStepNumber(0)}] ✓ understand request and plan next action`);\n writeProgress(writer, state);\n writer(`=== Steps complete: ${state.completedSteps} step(s), ${elapsed} ===`);\n writer(\"\");\n}\n\nfunction onToolStart(\n writer: (line: string) => void,\n state: ProgressState,\n event: AgentEvent,\n reasonForAction?: (action: string) => string | null,\n): void {\n state.currentStep += 1;\n state.startedSteps += 1;\n const stepNumber = state.currentStep;\n const payload = asRecord(event.payload);\n const action = summarizeAction(payload?.args, event.to, `invoke tool: ${shortToolName(event.to)}`);\n state.steps.set(stepNumber, { action, startedAtMs: Date.now() });\n state.pendingStepNumbers.push(stepNumber);\n writer(`[${formatStepNumber(stepNumber)}] ▶ ${action}`);\n writer(` tool: ${shortToolName(event.to)}`);\n const reason = reasonForAction?.(action);\n if (reason) writer(` reason: ${reason}`);\n}\n\nfunction onToolDoneWithPayload(writer: (line: string) => void, state: ProgressState, event: AgentEvent): void {\n const stepNumber = state.pendingStepNumbers.shift() ?? state.currentStep;\n const step = state.steps.get(stepNumber);\n const error = getResultError(event.payload);\n const preview = getResultPreview(event.payload);\n const elapsed = step ? formatElapsed(Date.now() - step.startedAtMs) : \"?\";\n if (error) {\n writer(`[${formatStepNumber(stepNumber)}] ✖ ${step?.action ?? \"tool invocation\"}`);\n writer(` error: ${error}`);\n } else {\n writer(`[${formatStepNumber(stepNumber)}] ✓ ${step?.action ?? \"tool invocation\"} (${elapsed})`);\n if (preview) writer(` observation: ${preview}`);\n }\n state.steps.delete(stepNumber);\n state.completedSteps += 1;\n writeProgress(writer, state);\n}\n\nfunction onToolError(writer: (line: string) => void, state: ProgressState, event: AgentEvent): void {\n const stepNumber = state.pendingStepNumbers.shift() ?? state.currentStep;\n const step = state.steps.get(stepNumber);\n const payload = asRecord(event.payload);\n const error = asTrimmedString(payload?.error) ?? \"unknown error\";\n writer(`[${formatStepNumber(stepNumber)}] ✖ ${step?.action ?? \"tool invocation\"}`);\n writer(` error: ${error}`);\n state.steps.delete(stepNumber);\n state.completedSteps += 1;\n writeProgress(writer, state);\n}\n\nexport function createProgressAgentEventListener(options: ProgressEventListenerOptions = {}): AgentEventListener {\n const writer = options.writer ?? console.log;\n const runLabelReact = options.runLabelReact ?? \"analysis\";\n const runLabelDeep = options.runLabelDeep ?? \"deep analysis\";\n\n const state: ProgressState = {\n runStartedAtMs: null,\n startedSteps: 0,\n completedSteps: 0,\n currentStep: 0,\n steps: new Map(),\n pendingStepNumbers: [],\n };\n\n return (event: AgentEvent): void => {\n switch (event.name) {\n case \"agent.react.run.start\":\n onRunStart(writer, state, runLabelReact);\n return;\n case \"agent.deep.run.start\":\n onRunStart(writer, state, runLabelDeep);\n return;\n case \"agent.react.skill.matched\":\n case \"agent.deep.skill.matched\": {\n const payload = asRecord(event.payload);\n const skillName = asTrimmedString(payload?.skill) ?? \"unknown\";\n writer(` skill: ${skillName}`);\n return;\n }\n case \"agent.react.context.truncated\":\n case \"agent.deep.context.truncated\":\n writer(\" context: truncated and compacted\");\n return;\n case \"agent.react.tool.invoke.start\":\n onToolStart(writer, state, event, options.reasonForAction);\n return;\n case \"agent.react.tool.invoke.done\":\n onToolDoneWithPayload(writer, state, event);\n return;\n case \"agent.react.tool.invoke.error\":\n onToolError(writer, state, event);\n return;\n case \"agent.react.memory.write.start\":\n writer(\" memory: write started\");\n return;\n case \"agent.react.memory.write.done\":\n writer(\" memory: write completed\");\n return;\n case \"agent.react.memory.write.error\":\n writer(\" memory: write failed\");\n return;\n case \"agent.react.ptc.retry\": {\n const payload = asRecord(event.payload);\n const retry = payload?.retry;\n const reason = asTrimmedString(payload?.reason);\n writer(` planning retry: attempt ${String(retry ?? \"?\")}${reason ? `, reason=${reason}` : \"\"}`);\n return;\n }\n case \"agent.react.run.done\":\n case \"agent.deep.run.done\":\n onRunDone(writer, state);\n return;\n default:\n return;\n }\n };\n}\n","import type { AgentEvent, AgentEventListener } from \"./index.js\";\n\nexport interface Runtime2EventDebugConfig {\n run?: boolean;\n workspace?: boolean;\n toolCall?: boolean;\n stream?: boolean;\n close?: boolean;\n}\n\nexport interface Runtime2EventRuntimeConfig {\n debug?: Runtime2EventDebugConfig;\n eventLogLevel?: \"silent\" | \"lifecycle\" | \"tools\" | \"verbose\";\n}\n\nexport interface Runtime2TreeEventListenerOptions {\n runtimeConfig?: Runtime2EventRuntimeConfig;\n writer?: (line: string) => void;\n}\n\ninterface ResolvedDebugConfig {\n run: boolean;\n workspace: boolean;\n toolCall: boolean;\n stream: boolean;\n close: boolean;\n}\n\nexport function createRuntime2TreeEventListener(\n options: Runtime2TreeEventListenerOptions = {}\n): AgentEventListener {\n const writer = options.writer ?? console.error;\n const debugConfig = resolveRuntime2DebugConfig(options.runtimeConfig);\n let currentRunThread: string | null = null;\n const toolCalls = new Map<string, { toolName: string; args?: Record<string, unknown> }>();\n\n return (event: AgentEvent): void => {\n const payload = asRecord(event.payload);\n if (shouldSkipRuntime2Event(event.name, debugConfig)) {\n return;\n }\n\n const lines = buildTreeLines(event, payload, currentRunThread, toolCalls);\n if (event.name === \"agent.runtime2.run.start\") {\n currentRunThread = typeof payload?.threadId === \"string\" ? payload.threadId : null;\n toolCalls.clear();\n } else if (event.name === \"agent.runtime2.run.done\" || event.name === \"agent.runtime2.run.error\") {\n currentRunThread = null;\n toolCalls.clear();\n }\n\n for (const line of lines) {\n writer(line);\n }\n };\n}\n\nexport function resolveRuntime2DebugConfig(\n runtimeConfig?: Runtime2EventRuntimeConfig\n): ResolvedDebugConfig {\n if (runtimeConfig?.debug) {\n return {\n run: runtimeConfig.debug.run ?? true,\n workspace: runtimeConfig.debug.workspace ?? true,\n toolCall: runtimeConfig.debug.toolCall ?? true,\n stream: runtimeConfig.debug.stream ?? false,\n close: runtimeConfig.debug.close ?? true,\n };\n }\n\n switch (runtimeConfig?.eventLogLevel ?? \"tools\") {\n case \"silent\":\n return { run: false, workspace: false, toolCall: false, stream: false, close: false };\n case \"lifecycle\":\n return { run: true, workspace: true, toolCall: false, stream: false, close: true };\n case \"verbose\":\n return { run: true, workspace: true, toolCall: true, stream: true, close: true };\n case \"tools\":\n default:\n return { run: true, workspace: true, toolCall: true, stream: false, close: true };\n }\n}\n\nfunction shouldSkipRuntime2Event(name: string, debugConfig: ResolvedDebugConfig): boolean {\n if (name.startsWith(\"agent.runtime2.stream.\")) {\n return !debugConfig.stream;\n }\n if (name.startsWith(\"agent.runtime2.tool.call.\")) {\n return !debugConfig.toolCall;\n }\n if (name.startsWith(\"agent.runtime2.workspace.\")) {\n if (name === \"agent.runtime2.workspace.prepare\" || name === \"agent.runtime2.workspace.run.update\") {\n return true;\n }\n return !debugConfig.workspace;\n }\n if (name.startsWith(\"agent.runtime2.run.\")) {\n if (name === \"agent.runtime2.run.prepare\") {\n return true;\n }\n return !debugConfig.run;\n }\n if (name.startsWith(\"agent.runtime2.close.\")) {\n return !debugConfig.close;\n }\n return false;\n}\n\nfunction buildTreeLines(\n event: Pick<AgentEvent, \"name\" | \"from\" | \"to\">,\n payload: Record<string, unknown> | undefined,\n currentRunThread: string | null,\n toolCalls: Map<string, { toolName: string; args?: Record<string, unknown> }>,\n): string[] {\n const from = shortComponent(event.from);\n const to = shortComponent(event.to);\n const action = event.name.replace(/^agent\\.runtime2\\./, \"\");\n const details = summarizePayload(event.name, payload);\n const suffix = details ? ` | ${details}` : \"\";\n\n if (event.name === \"agent.runtime2.run.start\") {\n return [\n `run ${typeof payload?.threadId === \"string\" ? payload.threadId : \"\"}`.trim(),\n `├─ ${from} -> ${to} | ${action}${suffix}`,\n ];\n }\n\n if (event.name === \"agent.runtime2.run.done\" || event.name === \"agent.runtime2.run.error\") {\n return [`└─ ${from} -> ${to} | ${action}${suffix}`];\n }\n\n if (event.name === \"agent.runtime2.tool.call.start\") {\n const id = typeof payload?.toolCallId === \"string\" ? payload.toolCallId : \"\";\n if (id) {\n toolCalls.set(id, {\n toolName: to,\n args: asRecord(payload?.args),\n });\n }\n return [];\n }\n\n if (\n event.name === \"agent.runtime2.tool.call.done\"\n || event.name === \"agent.runtime2.tool.call.error\"\n || event.name === \"agent.runtime2.tool.call.blocked\"\n ) {\n const id = typeof payload?.toolCallId === \"string\" ? payload.toolCallId : \"\";\n const remembered = id ? toolCalls.get(id) : undefined;\n if (id) {\n toolCalls.delete(id);\n }\n const fallbackToolName = event.name === \"agent.runtime2.tool.call.blocked\" ? to : from;\n const icon = event.name === \"agent.runtime2.tool.call.done\"\n ? \"OK\"\n : event.name === \"agent.runtime2.tool.call.blocked\"\n ? \"BLOCKED\"\n : \"ERROR\";\n const combined = compactFields([\n summarizeToolArgs(remembered?.args ?? asRecord(payload?.args)),\n details,\n ]);\n return [`├─ ${icon} ${remembered?.toolName ?? fallbackToolName}${combined ? ` | ${combined}` : \"\"}`];\n }\n\n const prefix = currentRunThread ? \"├─\" : \"•\";\n return [`${prefix} ${from} -> ${to} | ${action}${suffix}`];\n}\n\nfunction summarizePayload(name: string, payload?: Record<string, unknown>): string | null {\n switch (name) {\n case \"agent.runtime2.run.start\":\n return typeof payload?.threadId === \"string\" ? `thread=${payload.threadId}` : null;\n case \"agent.runtime2.run.done\":\n return compactFields([\n formatField(\"steps\", payload?.stepCount),\n formatDuration(payload?.durationMs),\n formatField(\"summary\", payload?.lastSummary),\n ]);\n case \"agent.runtime2.run.error\":\n return compactFields([\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"error\", payload?.error),\n ]);\n case \"agent.runtime2.stream.summary\":\n return typeof payload?.summary === \"string\" ? payload.summary : null;\n case \"agent.runtime2.stream.heartbeat\":\n return formatDuration(payload?.elapsedMs);\n case \"agent.runtime2.tool.call.done\":\n case \"agent.runtime2.tool.call.error\":\n case \"agent.runtime2.tool.call.blocked\":\n return compactFields([\n formatDuration(payload?.durationMs),\n formatField(\"reason\", payload?.reason),\n formatField(\"error\", payload?.error),\n ]);\n case \"agent.runtime2.workspace.run.update\":\n case \"agent.runtime2.workspace.run.finish\":\n return compactFields([\n formatField(\"steps\", payload?.stepCount),\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"status\", payload?.status),\n ]);\n case \"agent.runtime2.run.retry.empty\":\n case \"agent.runtime2.run.retry.incomplete\":\n case \"agent.runtime2.run.retry.idle_timeout\":\n case \"agent.runtime2.run.retry.transient_model\":\n case \"agent.runtime2.run.retry.tool_call\":\n return compactFields([\n formatField(\"attempt\", formatAttempt(payload?.attempt, payload?.maxRetries)),\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"error\", payload?.error),\n ]);\n default:\n return compactFields([\n formatField(\"thread\", payload?.threadId),\n formatField(\"steps\", payload?.stepCount),\n formatField(\"status\", payload?.status),\n ]);\n }\n}\n\nfunction summarizeToolArgs(args: Record<string, unknown> | undefined): string | null {\n if (!args) {\n return null;\n }\n\n return compactFields([\n formatArg(\"path\", args.file_path ?? args.path),\n formatArg(\"query\", args.query),\n formatArg(\"symbol\", args.symbol),\n formatArg(\"ticker\", args.ticker),\n formatArg(\"command\", args.command),\n formatArg(\"subagent_type\", args.subagent_type),\n ]);\n}\n\nfunction formatArg(key: string, value: unknown): string | null {\n if (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") {\n return null;\n }\n const text = String(value).trim();\n if (!text) {\n return null;\n }\n return `${key}=${truncate(text, 80)}`;\n}\n\nfunction formatField(key: string, value: unknown): string | null {\n if (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") {\n return null;\n }\n const text = String(value).trim();\n if (!text) {\n return null;\n }\n return `${key}=${truncate(text, 80)}`;\n}\n\nfunction formatAttempt(attempt: unknown, maxRetries: unknown): string | null {\n if (typeof attempt !== \"number\") {\n return null;\n }\n return typeof maxRetries === \"number\" ? `${attempt}/${maxRetries}` : String(attempt);\n}\n\nfunction formatDuration(durationMs: unknown): string | null {\n if (typeof durationMs !== \"number\") {\n return null;\n }\n if (durationMs < 1_000) {\n return `elapsed=${Math.round(durationMs)}ms`;\n }\n if (durationMs < 10_000) {\n return `elapsed=${(durationMs / 1000).toFixed(2)}s`;\n }\n return `elapsed=${(durationMs / 1000).toFixed(1)}s`;\n}\n\nfunction shortComponent(value: string | undefined): string {\n return (value ?? \"?\").replace(/^agent-runtime2\\./, \"\");\n}\n\nfunction compactFields(fields: Array<string | null>): string | null {\n const items = fields.filter((field): field is string => Boolean(field));\n return items.length > 0 ? items.join(\", \") : null;\n}\n\nfunction truncate(value: string, maxLength: number): string {\n return value.length > maxLength ? `${value.slice(0, maxLength - 3)}...` : value;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined;\n}\n","import { getDefaultAgentContext, AgentContextTokens } from \"../context/index.js\";\n\nexport interface AgentEvent<TPayload = unknown> {\n id: string;\n name: string;\n from: string;\n to: string;\n at: string;\n payload?: TPayload;\n}\n\nexport interface AgentEventBus {\n publish<TPayload = unknown>(event: Omit<AgentEvent<TPayload>, \"id\" | \"at\">): AgentEvent<TPayload>;\n subscribe(listener: AgentEventListener): () => void;\n}\n\nexport type AgentEventListener = (event: AgentEvent) => void;\n\nclass DefaultAgentEventBus implements AgentEventBus {\n private listeners = new Set<AgentEventListener>();\n\n publish<TPayload = unknown>(\n event: Omit<AgentEvent<TPayload>, \"id\" | \"at\">\n ): AgentEvent<TPayload> {\n const resolved: AgentEvent<TPayload> = {\n ...event,\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,\n at: new Date().toISOString(),\n };\n for (const listener of this.listeners) {\n try {\n listener(resolved);\n } catch {\n // Listener failures must not break agent runtime.\n }\n }\n return resolved;\n }\n\n subscribe(listener: AgentEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n\nexport function createAgentEventBus(): AgentEventBus {\n const bus = new DefaultAgentEventBus();\n getDefaultAgentContext().set(AgentContextTokens.EventBus, bus);\n return bus;\n}\n\nexport function createConsoleAgentEventListener(\n writer: (line: string) => void = console.error\n): AgentEventListener {\n return (event) => {\n writer(`[${event.at}] ${event.from} -> ${event.to} ${event.name}`);\n };\n}\n\nexport {\n createProgressAgentEventListener,\n type ProgressEventListenerOptions,\n} from \"./progress-listener.js\";\nexport {\n createRuntime2TreeEventListener,\n resolveRuntime2DebugConfig,\n type Runtime2EventDebugConfig,\n type Runtime2EventRuntimeConfig,\n type Runtime2TreeEventListenerOptions,\n} from \"./runtime2-tree-listener.js\";\n"],"mappings":"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","names":["asRecord"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  parseYamlContent
3
- } from "./chunk-X4TDNR4V.js";
3
+ } from "./chunk-2HMNFLD4.js";
4
4
 
5
5
  // src/utils/deep-merge.ts
6
6
  function deepMerge(target, ...sources) {
@@ -179,4 +179,4 @@ export {
179
179
  parseMarkdownYamlFrontmatter,
180
180
  applyDefaultToolChoice
181
181
  };
182
- //# sourceMappingURL=chunk-OTWARMTU.js.map
182
+ //# sourceMappingURL=chunk-OJWAEVSP.js.map
@@ -10,7 +10,7 @@ import {
10
10
  resolveConfigPath,
11
11
  resolveKindResourceFile,
12
12
  toPathRef
13
- } from "../chunk-X4TDNR4V.js";
13
+ } from "../chunk-2HMNFLD4.js";
14
14
  export {
15
15
  asObject,
16
16
  clearYamlFileCache,
@@ -4,9 +4,9 @@ import {
4
4
  createProgressAgentEventListener,
5
5
  createRuntime2TreeEventListener,
6
6
  resolveRuntime2DebugConfig
7
- } from "../chunk-RUIAZ7GO.js";
8
- import "../chunk-OTWARMTU.js";
9
- import "../chunk-X4TDNR4V.js";
7
+ } from "../chunk-6VW5AW43.js";
8
+ import "../chunk-OJWAEVSP.js";
9
+ import "../chunk-2HMNFLD4.js";
10
10
  import "../chunk-H5BG6SXW.js";
11
11
  import "../chunk-DIIWJNRE.js";
12
12
  import "../chunk-QG6CT2GZ.js";
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  createConsoleAgentEventListener,
10
10
  createProgressAgentEventListener,
11
11
  createRuntime2TreeEventListener
12
- } from "./chunk-RUIAZ7GO.js";
12
+ } from "./chunk-6VW5AW43.js";
13
13
  import {
14
14
  asRecord,
15
15
  extractTextFromLlmOutput,
@@ -17,8 +17,8 @@ import {
17
17
  shortToolName,
18
18
  stripNullishObjectFields,
19
19
  summarizeForLog
20
- } from "./chunk-OTWARMTU.js";
21
- import "./chunk-X4TDNR4V.js";
20
+ } from "./chunk-OJWAEVSP.js";
21
+ import "./chunk-2HMNFLD4.js";
22
22
  import {
23
23
  AgentContextTokens
24
24
  } from "./chunk-H5BG6SXW.js";
@@ -12,8 +12,8 @@ import {
12
12
  shortToolName,
13
13
  stripNullishObjectFields,
14
14
  summarizeForLog
15
- } from "../chunk-OTWARMTU.js";
16
- import "../chunk-X4TDNR4V.js";
15
+ } from "../chunk-OJWAEVSP.js";
16
+ import "../chunk-2HMNFLD4.js";
17
17
  import {
18
18
  computeChecksum,
19
19
  createChecksumAccumulator
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/common",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Shared runtime utilities for BotBotGo agent projects",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/events/progress-listener.ts","../src/events/runtime2-tree-listener.ts","../src/events/index.ts"],"sourcesContent":["import type { AgentEvent, AgentEventListener } from \"./index.js\";\nimport { asRecord, asTrimmedString, parseJsonObject, shortToolName } from \"../utils/index.js\";\n\ninterface ToolStep {\n action: string;\n startedAtMs: number;\n}\n\ninterface ProgressState {\n runStartedAtMs: number | null;\n startedSteps: number;\n completedSteps: number;\n currentStep: number;\n steps: Map<number, ToolStep>;\n pendingStepNumbers: number[];\n}\n\nexport interface ProgressEventListenerOptions {\n writer?: (line: string) => void;\n runLabelReact?: string;\n runLabelDeep?: string;\n reasonForAction?: (action: string) => string | null;\n}\n\nfunction formatElapsed(ms: number): string {\n return `${Math.max(0, Math.round(ms))}ms`;\n}\n\nfunction formatStepNumber(stepNumber: number): string {\n return String(Math.max(0, stepNumber)).padStart(2, \"0\");\n}\n\nfunction hasAny(record: Record<string, unknown>, keys: string[]): boolean {\n return keys.some((key) => key in record);\n}\n\nfunction summarizeAction(args: unknown, toolName: string, fallback: string): string {\n const record = asRecord(args) ?? parseJsonObject(args);\n if (!record) return fallback;\n const tool = shortToolName(toolName);\n const command = asTrimmedString(record.command);\n const path = asTrimmedString(record.path);\n const isListDirShape = hasAny(record, [\"maxEntries\", \"recursive\", \"maxDepth\", \"includeHidden\"]);\n const isReadTextShape = hasAny(record, [\"maxBytes\", \"startLine\", \"endLine\", \"encoding\"]);\n if (tool === \"runCommand\" && command) return `run command: ${command}`;\n if (tool.includes(\"itermRunCommandInSession\") && command) return `run command: ${command}`;\n if (tool === \"listDir\" || (Boolean(path) && isListDirShape)) {\n if (!path || path === \".\") return \"list directory\";\n return `list directory: ${path}`;\n }\n if (tool === \"readText\" || (Boolean(path) && isReadTextShape)) {\n if (!path) return \"read file\";\n return `read file: ${path}`;\n }\n if (command) return `run command: ${command}`;\n const query = asTrimmedString(record.query);\n if (query) return `search/query: ${query}`;\n if (path) return `read path: ${path}`;\n return fallback;\n}\n\nfunction getResultError(payload: unknown): string | null {\n const payloadRecord = asRecord(payload);\n const result = payloadRecord?.result;\n const resultRecord = asRecord(result) ?? parseJsonObject(result);\n const nestedResult = asRecord(resultRecord?.result);\n return asTrimmedString(nestedResult?.error) ?? asTrimmedString(resultRecord?.error);\n}\n\nfunction getResultPreview(payload: unknown): string | null {\n const payloadRecord = asRecord(payload);\n const directPreview = asTrimmedString(payloadRecord?.resultPreview);\n if (directPreview) return directPreview;\n\n const result = payloadRecord?.result;\n const resultRecord = asRecord(result) ?? parseJsonObject(result);\n const nestedResult = asRecord(resultRecord?.result);\n const preview =\n asTrimmedString(nestedResult?.outputText)\n ?? asTrimmedString(nestedResult?.output)\n ?? asTrimmedString(resultRecord?.output)\n ?? asTrimmedString(resultRecord?.outputText);\n return preview ? preview.replace(/\\s+/g, \" \").trim() : null;\n}\n\nfunction writeProgress(writer: (line: string) => void, state: ProgressState): void {\n writer(` progress ${state.completedSteps}/${state.startedSteps}`);\n}\n\nfunction onRunStart(writer: (line: string) => void, state: ProgressState, runLabelText: string): void {\n state.runStartedAtMs = Date.now();\n state.startedSteps = 0;\n state.completedSteps = 0;\n state.currentStep = 0;\n state.steps.clear();\n state.pendingStepNumbers = [];\n writer(\"\");\n writer(`=== Steps: ${runLabelText} ===`);\n writer(`[${formatStepNumber(0)}] ▶ understand request and plan next action`);\n}\n\nfunction onRunDone(writer: (line: string) => void, state: ProgressState): void {\n const elapsed = state.runStartedAtMs === null ? \"?\" : formatElapsed(Date.now() - state.runStartedAtMs);\n writer(`[${formatStepNumber(0)}] ✓ understand request and plan next action`);\n writeProgress(writer, state);\n writer(`=== Steps complete: ${state.completedSteps} step(s), ${elapsed} ===`);\n writer(\"\");\n}\n\nfunction onToolStart(\n writer: (line: string) => void,\n state: ProgressState,\n event: AgentEvent,\n reasonForAction?: (action: string) => string | null,\n): void {\n state.currentStep += 1;\n state.startedSteps += 1;\n const stepNumber = state.currentStep;\n const payload = asRecord(event.payload);\n const action = summarizeAction(payload?.args, event.to, `invoke tool: ${shortToolName(event.to)}`);\n state.steps.set(stepNumber, { action, startedAtMs: Date.now() });\n state.pendingStepNumbers.push(stepNumber);\n writer(`[${formatStepNumber(stepNumber)}] ▶ ${action}`);\n writer(` tool: ${shortToolName(event.to)}`);\n const reason = reasonForAction?.(action);\n if (reason) writer(` reason: ${reason}`);\n}\n\nfunction onToolDoneWithPayload(writer: (line: string) => void, state: ProgressState, event: AgentEvent): void {\n const stepNumber = state.pendingStepNumbers.shift() ?? state.currentStep;\n const step = state.steps.get(stepNumber);\n const error = getResultError(event.payload);\n const preview = getResultPreview(event.payload);\n const elapsed = step ? formatElapsed(Date.now() - step.startedAtMs) : \"?\";\n if (error) {\n writer(`[${formatStepNumber(stepNumber)}] ✖ ${step?.action ?? \"tool invocation\"}`);\n writer(` error: ${error}`);\n } else {\n writer(`[${formatStepNumber(stepNumber)}] ✓ ${step?.action ?? \"tool invocation\"} (${elapsed})`);\n if (preview) writer(` observation: ${preview}`);\n }\n state.steps.delete(stepNumber);\n state.completedSteps += 1;\n writeProgress(writer, state);\n}\n\nfunction onToolError(writer: (line: string) => void, state: ProgressState, event: AgentEvent): void {\n const stepNumber = state.pendingStepNumbers.shift() ?? state.currentStep;\n const step = state.steps.get(stepNumber);\n const payload = asRecord(event.payload);\n const error = asTrimmedString(payload?.error) ?? \"unknown error\";\n writer(`[${formatStepNumber(stepNumber)}] ✖ ${step?.action ?? \"tool invocation\"}`);\n writer(` error: ${error}`);\n state.steps.delete(stepNumber);\n state.completedSteps += 1;\n writeProgress(writer, state);\n}\n\nexport function createProgressAgentEventListener(options: ProgressEventListenerOptions = {}): AgentEventListener {\n const writer = options.writer ?? console.log;\n const runLabelReact = options.runLabelReact ?? \"analysis\";\n const runLabelDeep = options.runLabelDeep ?? \"deep analysis\";\n\n const state: ProgressState = {\n runStartedAtMs: null,\n startedSteps: 0,\n completedSteps: 0,\n currentStep: 0,\n steps: new Map(),\n pendingStepNumbers: [],\n };\n\n return (event: AgentEvent): void => {\n switch (event.name) {\n case \"agent.react.run.start\":\n onRunStart(writer, state, runLabelReact);\n return;\n case \"agent.deep.run.start\":\n onRunStart(writer, state, runLabelDeep);\n return;\n case \"agent.react.skill.matched\":\n case \"agent.deep.skill.matched\": {\n const payload = asRecord(event.payload);\n const skillName = asTrimmedString(payload?.skill) ?? \"unknown\";\n writer(` skill: ${skillName}`);\n return;\n }\n case \"agent.react.context.truncated\":\n case \"agent.deep.context.truncated\":\n writer(\" context: truncated and compacted\");\n return;\n case \"agent.react.tool.invoke.start\":\n onToolStart(writer, state, event, options.reasonForAction);\n return;\n case \"agent.react.tool.invoke.done\":\n onToolDoneWithPayload(writer, state, event);\n return;\n case \"agent.react.tool.invoke.error\":\n onToolError(writer, state, event);\n return;\n case \"agent.react.memory.write.start\":\n writer(\" memory: write started\");\n return;\n case \"agent.react.memory.write.done\":\n writer(\" memory: write completed\");\n return;\n case \"agent.react.memory.write.error\":\n writer(\" memory: write failed\");\n return;\n case \"agent.react.ptc.retry\": {\n const payload = asRecord(event.payload);\n const retry = payload?.retry;\n const reason = asTrimmedString(payload?.reason);\n writer(` planning retry: attempt ${String(retry ?? \"?\")}${reason ? `, reason=${reason}` : \"\"}`);\n return;\n }\n case \"agent.react.run.done\":\n case \"agent.deep.run.done\":\n onRunDone(writer, state);\n return;\n default:\n return;\n }\n };\n}\n","import type { AgentEvent, AgentEventListener } from \"./index.js\";\n\nexport interface Runtime2EventDebugConfig {\n run?: boolean;\n workspace?: boolean;\n toolCall?: boolean;\n stream?: boolean;\n close?: boolean;\n}\n\nexport interface Runtime2EventRuntimeConfig {\n debug?: Runtime2EventDebugConfig;\n eventLogLevel?: \"silent\" | \"lifecycle\" | \"tools\" | \"verbose\";\n}\n\nexport interface Runtime2TreeEventListenerOptions {\n runtimeConfig?: Runtime2EventRuntimeConfig;\n writer?: (line: string) => void;\n}\n\ninterface ResolvedDebugConfig {\n run: boolean;\n workspace: boolean;\n toolCall: boolean;\n stream: boolean;\n close: boolean;\n}\n\nexport function createRuntime2TreeEventListener(\n options: Runtime2TreeEventListenerOptions = {}\n): AgentEventListener {\n const writer = options.writer ?? console.error;\n const debugConfig = resolveRuntime2DebugConfig(options.runtimeConfig);\n let currentRunThread: string | null = null;\n const toolCalls = new Map<string, { toolName: string; args?: Record<string, unknown> }>();\n\n return (event: AgentEvent): void => {\n const payload = asRecord(event.payload);\n if (shouldSkipRuntime2Event(event.name, debugConfig)) {\n return;\n }\n\n const lines = buildTreeLines(event, payload, currentRunThread, toolCalls);\n if (event.name === \"agent.runtime2.run.start\") {\n currentRunThread = typeof payload?.threadId === \"string\" ? payload.threadId : null;\n toolCalls.clear();\n } else if (event.name === \"agent.runtime2.run.done\" || event.name === \"agent.runtime2.run.error\") {\n currentRunThread = null;\n toolCalls.clear();\n }\n\n for (const line of lines) {\n writer(line);\n }\n };\n}\n\nexport function resolveRuntime2DebugConfig(\n runtimeConfig?: Runtime2EventRuntimeConfig\n): ResolvedDebugConfig {\n if (runtimeConfig?.debug) {\n return {\n run: runtimeConfig.debug.run ?? true,\n workspace: runtimeConfig.debug.workspace ?? true,\n toolCall: runtimeConfig.debug.toolCall ?? true,\n stream: runtimeConfig.debug.stream ?? false,\n close: runtimeConfig.debug.close ?? true,\n };\n }\n\n switch (runtimeConfig?.eventLogLevel ?? \"tools\") {\n case \"silent\":\n return { run: false, workspace: false, toolCall: false, stream: false, close: false };\n case \"lifecycle\":\n return { run: true, workspace: true, toolCall: false, stream: false, close: true };\n case \"verbose\":\n return { run: true, workspace: true, toolCall: true, stream: true, close: true };\n case \"tools\":\n default:\n return { run: true, workspace: true, toolCall: true, stream: false, close: true };\n }\n}\n\nfunction shouldSkipRuntime2Event(name: string, debugConfig: ResolvedDebugConfig): boolean {\n if (name.startsWith(\"agent.runtime2.stream.\")) {\n return !debugConfig.stream;\n }\n if (name.startsWith(\"agent.runtime2.tool.call.\")) {\n return !debugConfig.toolCall;\n }\n if (name.startsWith(\"agent.runtime2.workspace.\")) {\n if (name === \"agent.runtime2.workspace.prepare\" || name === \"agent.runtime2.workspace.run.update\") {\n return true;\n }\n return !debugConfig.workspace;\n }\n if (name.startsWith(\"agent.runtime2.run.\")) {\n if (name === \"agent.runtime2.run.prepare\") {\n return true;\n }\n return !debugConfig.run;\n }\n if (name.startsWith(\"agent.runtime2.close.\")) {\n return !debugConfig.close;\n }\n return false;\n}\n\nfunction buildTreeLines(\n event: Pick<AgentEvent, \"name\" | \"from\" | \"to\">,\n payload: Record<string, unknown> | undefined,\n currentRunThread: string | null,\n toolCalls: Map<string, { toolName: string; args?: Record<string, unknown> }>,\n): string[] {\n const from = shortComponent(event.from);\n const to = shortComponent(event.to);\n const action = event.name.replace(/^agent\\.runtime2\\./, \"\");\n const details = summarizePayload(event.name, payload);\n const suffix = details ? ` | ${details}` : \"\";\n\n if (event.name === \"agent.runtime2.run.start\") {\n return [\n `run ${typeof payload?.threadId === \"string\" ? payload.threadId : \"\"}`.trim(),\n `├─ ${from} -> ${to} | ${action}${suffix}`,\n ];\n }\n\n if (event.name === \"agent.runtime2.run.done\" || event.name === \"agent.runtime2.run.error\") {\n return [`└─ ${from} -> ${to} | ${action}${suffix}`];\n }\n\n if (event.name === \"agent.runtime2.tool.call.start\") {\n const id = typeof payload?.toolCallId === \"string\" ? payload.toolCallId : \"\";\n if (id) {\n toolCalls.set(id, {\n toolName: to,\n args: asRecord(payload?.args),\n });\n }\n return [];\n }\n\n if (\n event.name === \"agent.runtime2.tool.call.done\"\n || event.name === \"agent.runtime2.tool.call.error\"\n || event.name === \"agent.runtime2.tool.call.blocked\"\n ) {\n const id = typeof payload?.toolCallId === \"string\" ? payload.toolCallId : \"\";\n const remembered = id ? toolCalls.get(id) : undefined;\n if (id) {\n toolCalls.delete(id);\n }\n const icon = event.name === \"agent.runtime2.tool.call.done\"\n ? \"OK\"\n : event.name === \"agent.runtime2.tool.call.blocked\"\n ? \"BLOCKED\"\n : \"ERROR\";\n const combined = compactFields([\n summarizeToolArgs(remembered?.args),\n details,\n ]);\n return [`├─ ${icon} ${remembered?.toolName ?? from}${combined ? ` | ${combined}` : \"\"}`];\n }\n\n const prefix = currentRunThread ? \"├─\" : \"•\";\n return [`${prefix} ${from} -> ${to} | ${action}${suffix}`];\n}\n\nfunction summarizePayload(name: string, payload?: Record<string, unknown>): string | null {\n switch (name) {\n case \"agent.runtime2.run.start\":\n return typeof payload?.threadId === \"string\" ? `thread=${payload.threadId}` : null;\n case \"agent.runtime2.run.done\":\n return compactFields([\n formatField(\"steps\", payload?.stepCount),\n formatDuration(payload?.durationMs),\n formatField(\"summary\", payload?.lastSummary),\n ]);\n case \"agent.runtime2.run.error\":\n return compactFields([\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"error\", payload?.error),\n ]);\n case \"agent.runtime2.stream.summary\":\n return typeof payload?.summary === \"string\" ? payload.summary : null;\n case \"agent.runtime2.stream.heartbeat\":\n return formatDuration(payload?.elapsedMs);\n case \"agent.runtime2.tool.call.done\":\n case \"agent.runtime2.tool.call.error\":\n case \"agent.runtime2.tool.call.blocked\":\n return compactFields([\n formatDuration(payload?.durationMs),\n formatField(\"reason\", payload?.reason),\n formatField(\"error\", payload?.error),\n ]);\n case \"agent.runtime2.workspace.run.update\":\n case \"agent.runtime2.workspace.run.finish\":\n return compactFields([\n formatField(\"steps\", payload?.stepCount),\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"status\", payload?.status),\n ]);\n case \"agent.runtime2.run.retry.empty\":\n case \"agent.runtime2.run.retry.incomplete\":\n case \"agent.runtime2.run.retry.idle_timeout\":\n case \"agent.runtime2.run.retry.transient_model\":\n case \"agent.runtime2.run.retry.tool_call\":\n return compactFields([\n formatField(\"attempt\", formatAttempt(payload?.attempt, payload?.maxRetries)),\n formatField(\"summary\", payload?.lastSummary),\n formatField(\"error\", payload?.error),\n ]);\n default:\n return compactFields([\n formatField(\"thread\", payload?.threadId),\n formatField(\"steps\", payload?.stepCount),\n formatField(\"status\", payload?.status),\n ]);\n }\n}\n\nfunction summarizeToolArgs(args: Record<string, unknown> | undefined): string | null {\n if (!args) {\n return null;\n }\n\n return compactFields([\n formatArg(\"path\", args.file_path ?? args.path),\n formatArg(\"query\", args.query),\n formatArg(\"symbol\", args.symbol),\n formatArg(\"ticker\", args.ticker),\n formatArg(\"command\", args.command),\n formatArg(\"subagent_type\", args.subagent_type),\n ]);\n}\n\nfunction formatArg(key: string, value: unknown): string | null {\n if (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") {\n return null;\n }\n const text = String(value).trim();\n if (!text) {\n return null;\n }\n return `${key}=${truncate(text, 80)}`;\n}\n\nfunction formatField(key: string, value: unknown): string | null {\n if (typeof value !== \"string\" && typeof value !== \"number\" && typeof value !== \"boolean\") {\n return null;\n }\n const text = String(value).trim();\n if (!text) {\n return null;\n }\n return `${key}=${truncate(text, 80)}`;\n}\n\nfunction formatAttempt(attempt: unknown, maxRetries: unknown): string | null {\n if (typeof attempt !== \"number\") {\n return null;\n }\n return typeof maxRetries === \"number\" ? `${attempt}/${maxRetries}` : String(attempt);\n}\n\nfunction formatDuration(durationMs: unknown): string | null {\n if (typeof durationMs !== \"number\") {\n return null;\n }\n if (durationMs < 1_000) {\n return `elapsed=${Math.round(durationMs)}ms`;\n }\n if (durationMs < 10_000) {\n return `elapsed=${(durationMs / 1000).toFixed(2)}s`;\n }\n return `elapsed=${(durationMs / 1000).toFixed(1)}s`;\n}\n\nfunction shortComponent(value: string | undefined): string {\n return (value ?? \"?\").replace(/^agent-runtime2\\./, \"\");\n}\n\nfunction compactFields(fields: Array<string | null>): string | null {\n const items = fields.filter((field): field is string => Boolean(field));\n return items.length > 0 ? items.join(\", \") : null;\n}\n\nfunction truncate(value: string, maxLength: number): string {\n return value.length > maxLength ? `${value.slice(0, maxLength - 3)}...` : value;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined;\n}\n","import { getDefaultAgentContext, AgentContextTokens } from \"../context/index.js\";\n\nexport interface AgentEvent<TPayload = unknown> {\n id: string;\n name: string;\n from: string;\n to: string;\n at: string;\n payload?: TPayload;\n}\n\nexport interface AgentEventBus {\n publish<TPayload = unknown>(event: Omit<AgentEvent<TPayload>, \"id\" | \"at\">): AgentEvent<TPayload>;\n subscribe(listener: AgentEventListener): () => void;\n}\n\nexport type AgentEventListener = (event: AgentEvent) => void;\n\nclass DefaultAgentEventBus implements AgentEventBus {\n private listeners = new Set<AgentEventListener>();\n\n publish<TPayload = unknown>(\n event: Omit<AgentEvent<TPayload>, \"id\" | \"at\">\n ): AgentEvent<TPayload> {\n const resolved: AgentEvent<TPayload> = {\n ...event,\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`,\n at: new Date().toISOString(),\n };\n for (const listener of this.listeners) {\n try {\n listener(resolved);\n } catch {\n // Listener failures must not break agent runtime.\n }\n }\n return resolved;\n }\n\n subscribe(listener: AgentEventListener): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n}\n\nexport function createAgentEventBus(): AgentEventBus {\n const bus = new DefaultAgentEventBus();\n getDefaultAgentContext().set(AgentContextTokens.EventBus, bus);\n return bus;\n}\n\nexport function createConsoleAgentEventListener(\n writer: (line: string) => void = console.error\n): AgentEventListener {\n return (event) => {\n writer(`[${event.at}] ${event.from} -> ${event.to} ${event.name}`);\n };\n}\n\nexport {\n createProgressAgentEventListener,\n type ProgressEventListenerOptions,\n} from \"./progress-listener.js\";\nexport {\n createRuntime2TreeEventListener,\n resolveRuntime2DebugConfig,\n type Runtime2EventDebugConfig,\n type Runtime2EventRuntimeConfig,\n type Runtime2TreeEventListenerOptions,\n} from \"./runtime2-tree-listener.js\";\n"],"mappings":"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","names":["asRecord"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config/yaml.ts","../src/config/path.ts","../src/config/kind.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { resolveConfigPath } from \"./path.js\";\n\nexport interface YamlEnvOptions {\n substituteEnv?: boolean;\n missingEnv?: \"keep\" | \"empty\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface LoadYamlOptions extends YamlEnvOptions {\n cache?: boolean;\n}\n\nexport interface LoadModuleConfigOptions<TConfig, TRaw = Record<string, unknown>> {\n path?: string;\n defaultPath?: string;\n appRoot?: string;\n yaml?: LoadYamlOptions;\n unwrapSpec?: boolean;\n fallback: TConfig;\n normalize?: (raw: TRaw, meta: { resolvedPath: string }) => TConfig;\n}\n\ninterface CacheEntry {\n mtimeMs: number;\n value: unknown;\n}\n\nconst YAML_CACHE = new Map<string, CacheEntry>();\n\nexport function clearYamlFileCache(): void {\n YAML_CACHE.clear();\n}\n\nfunction substituteEnvInString(\n input: string,\n env: NodeJS.ProcessEnv,\n missingEnv: \"keep\" | \"empty\",\n): string {\n return input.replace(/\\$\\{(\\w+)\\}/g, (_, name: string) => {\n const value = env[name];\n if (value !== undefined) return value;\n return missingEnv === \"empty\" ? \"\" : `\\${${name}}`;\n });\n}\n\nfunction substituteEnvInValue(\n input: unknown,\n options: { env: NodeJS.ProcessEnv; missingEnv: \"keep\" | \"empty\" },\n): unknown {\n if (typeof input === \"string\") {\n return substituteEnvInString(input, options.env, options.missingEnv);\n }\n if (Array.isArray(input)) {\n return input.map((item) => substituteEnvInValue(item, options));\n }\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) {\n out[k] = substituteEnvInValue(v, options);\n }\n return out;\n }\n return input;\n}\n\nexport function parseYamlContent<T = unknown>(\n content: string,\n options: YamlEnvOptions = {},\n): T {\n const parsed = parseYaml(content) as unknown;\n if (options.substituteEnv === false) return parsed as T;\n return substituteEnvInValue(parsed, {\n env: options.env ?? process.env,\n missingEnv: options.missingEnv ?? \"keep\",\n }) as T;\n}\n\nfunction readFromCache(filePath: string, mtimeMs: number): unknown | undefined {\n const cached = YAML_CACHE.get(filePath);\n if (!cached) return undefined;\n if (cached.mtimeMs !== mtimeMs) return undefined;\n return cached.value;\n}\n\nfunction writeCache(filePath: string, mtimeMs: number, value: unknown): void {\n YAML_CACHE.set(filePath, { mtimeMs, value });\n}\n\nexport function loadYamlFileSync<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): T | undefined {\n const absPath = path.resolve(filePath);\n if (!existsSync(absPath)) return undefined;\n const useCache = options.cache === true;\n const fileStat = statSync(absPath);\n if (useCache) {\n const cached = readFromCache(absPath, fileStat.mtimeMs);\n if (cached !== undefined) return cached as T;\n }\n const content = readFileSync(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);\n return parsed;\n}\n\nexport async function loadYamlFile<T = unknown>(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<T | undefined> {\n const absPath = path.resolve(filePath);\n let fileStat;\n try {\n fileStat = await stat(absPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === \"ENOENT\") return undefined;\n throw err;\n }\n const useCache = options.cache === true;\n if (useCache) {\n const cached = readFromCache(absPath, fileStat.mtimeMs);\n if (cached !== undefined) return cached as T;\n }\n const content = await readFile(absPath, \"utf-8\");\n const parsed = parseYamlContent<T>(content, options);\n if (useCache) writeCache(absPath, fileStat.mtimeMs, parsed);\n return parsed;\n}\n\nexport async function loadYamlObject(\n filePath: string,\n options: LoadYamlOptions = {},\n): Promise<Record<string, unknown>> {\n const parsed = await loadYamlFile<unknown>(filePath, options);\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n return {};\n}\n\n/**\n * Generic module config loader:\n * 1) resolve path (path || defaultPath) relative to appRoot\n * 2) load YAML as object\n * 3) normalize into module-owned config interface\n * 4) fallback when missing/invalid\n */\nexport async function loadModuleConfig<TConfig, TRaw = Record<string, unknown>>(\n options: LoadModuleConfigOptions<TConfig, TRaw>,\n): Promise<TConfig> {\n const selected = options.path ?? options.defaultPath;\n if (!selected) return options.fallback;\n\n const appRoot = options.appRoot ?? process.cwd();\n const resolvedPath = resolveConfigPath(selected, appRoot);\n const loaded = await loadYamlFile<unknown>(resolvedPath, options.yaml);\n if (!loaded || typeof loaded !== \"object\" || Array.isArray(loaded)) return options.fallback;\n const raw = options.unwrapSpec === true\n ? (\n typeof (loaded as { spec?: unknown }).spec === \"object\" &&\n (loaded as { spec?: unknown }).spec !== null &&\n !Array.isArray((loaded as { spec?: unknown }).spec)\n ? (loaded as { spec: unknown }).spec\n : loaded\n )\n : loaded;\n\n if (options.normalize) {\n return options.normalize(raw as TRaw, { resolvedPath });\n }\n return raw as TConfig;\n}\n","import path from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface ResolveConfigPathOptions {\n expandHome?: boolean;\n homeDir?: string;\n}\n\nexport type PathRef = { ref?: string };\n\nexport function isPathRef(value: unknown): value is string {\n return (\n typeof value === \"string\" &&\n value.length > 0 &&\n (value.endsWith(\".yaml\") || value.endsWith(\".yml\"))\n );\n}\n\nexport function expandHomePath(inputPath: string, options: { homeDir?: string } = {}): string {\n const home = options.homeDir ?? homedir();\n if (inputPath === \"~\") return home;\n if (inputPath.startsWith(\"~/\")) return path.join(home, inputPath.slice(2));\n return inputPath;\n}\n\nexport function resolveConfigPath(\n pathRef: string,\n configDir: string,\n options: ResolveConfigPathOptions = {},\n): string {\n const expanded = options.expandHome === false ? pathRef : expandHomePath(pathRef, { homeDir: options.homeDir });\n return path.resolve(configDir, expanded);\n}\n\nexport function asObject(input: unknown): Record<string, unknown> | undefined {\n return typeof input === \"object\" && input !== null ? (input as Record<string, unknown>) : undefined;\n}\n\nexport function toPathRef(input: unknown): PathRef | undefined {\n if (typeof input === \"string\" && input.trim().length > 0) return { ref: input.trim() };\n const obj = asObject(input);\n if (!obj) return undefined;\n const value =\n (typeof (obj as { __filePath?: unknown }).__filePath === \"string\" &&\n (obj as { __filePath: string }).__filePath.trim().length > 0\n ? (obj as { __filePath: string }).__filePath.trim()\n : undefined) ??\n (typeof obj.ref === \"string\" && obj.ref.trim().length > 0 ? obj.ref.trim() : undefined);\n return value ? { ref: value } : undefined;\n}\n","import { dirname } from \"node:path\";\nimport { loadYamlFile, type LoadYamlOptions } from \"./yaml.js\";\nimport { asObject, resolveConfigPath } from \"./path.js\";\n\nexport interface ResourceMetadata {\n name?: string;\n labels?: Record<string, string>;\n}\n\nexport interface ResourceHeader {\n apiVersion: string;\n kind: string;\n metadata?: ResourceMetadata;\n spec: unknown;\n}\n\nexport type RefNode = { ref: string };\n\nexport type ResolvedResource<TSpec = unknown> = ResourceHeader & {\n spec: TSpec;\n __filePath: string;\n};\n\nexport interface ResolveKindResourceOptions {\n baseDir?: string;\n maxDepth?: number;\n cache?: boolean;\n yaml?: LoadYamlOptions;\n expectedKind?: string;\n expectedApiVersion?: string;\n}\n\nfunction toResourceHeader(input: unknown): ResourceHeader {\n const obj = asObject(input);\n if (!obj) throw new Error(\"Invalid config document: expected object root\");\n\n const apiVersion = typeof obj.apiVersion === \"string\" ? obj.apiVersion.trim() : \"\";\n const kind = typeof obj.kind === \"string\" ? obj.kind.trim() : \"\";\n const spec = (obj as { spec?: unknown }).spec;\n if (!apiVersion) throw new Error(\"Invalid config document: missing apiVersion\");\n if (!kind) throw new Error(\"Invalid config document: missing kind\");\n if (spec === undefined) throw new Error(\"Invalid config document: missing spec\");\n const metadataRaw = asObject(obj.metadata);\n const metadata: ResourceMetadata | undefined = metadataRaw\n ? {\n name: typeof metadataRaw.name === \"string\" ? metadataRaw.name : undefined,\n labels:\n metadataRaw.labels && typeof metadataRaw.labels === \"object\" && !Array.isArray(metadataRaw.labels)\n ? (metadataRaw.labels as Record<string, string>)\n : undefined,\n }\n : undefined;\n return { apiVersion, kind, metadata, spec };\n}\n\nexport function isRefNode(input: unknown): input is RefNode {\n const obj = asObject(input);\n return !!obj && typeof obj.ref === \"string\" && obj.ref.trim().length > 0;\n}\n\nexport async function resolveKindResourceFile<TSpec = unknown>(\n entryFile: string,\n options: ResolveKindResourceOptions = {},\n): Promise<ResolvedResource<TSpec>> {\n const baseDir = options.baseDir ?? process.cwd();\n const entryAbs = resolveConfigPath(entryFile, baseDir);\n const maxDepth = options.maxDepth ?? 50;\n const cache = new Map<string, ResolvedResource>();\n const visiting = new Set<string>();\n\n const resolveNode = async (node: unknown, currentDir: string, depth: number): Promise<unknown> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (isRefNode(node)) {\n const next = resolveConfigPath(node.ref, currentDir);\n return loadResource(next, depth + 1);\n }\n if (Array.isArray(node)) {\n return Promise.all(node.map((item) => resolveNode(item, currentDir, depth + 1)));\n }\n const obj = asObject(node);\n if (!obj) return node;\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(obj)) {\n out[k] = await resolveNode(v, currentDir, depth + 1);\n }\n return out;\n };\n\n const loadResource = async (absPath: string, depth: number): Promise<ResolvedResource> => {\n if (depth > maxDepth) throw new Error(`Config ref resolution exceeded maxDepth=${maxDepth}`);\n if (options.cache !== false) {\n const cached = cache.get(absPath);\n if (cached) return cached;\n }\n if (visiting.has(absPath)) {\n throw new Error(`Config ref cycle detected at: ${absPath}`);\n }\n visiting.add(absPath);\n try {\n const raw = await loadYamlFile(absPath, options.yaml);\n const header = toResourceHeader(raw);\n if (options.expectedApiVersion && header.apiVersion !== options.expectedApiVersion) {\n throw new Error(`Unexpected apiVersion \"${header.apiVersion}\" at ${absPath}`);\n }\n const resolvedSpec = await resolveNode(header.spec, dirname(absPath), depth + 1);\n const resolved: ResolvedResource = {\n ...header,\n spec: resolvedSpec,\n __filePath: absPath,\n };\n if (options.cache !== false) cache.set(absPath, resolved);\n return resolved;\n } finally {\n visiting.delete(absPath);\n }\n };\n\n const root = await loadResource(entryAbs, 0);\n if (options.expectedKind && root.kind !== options.expectedKind) {\n throw new Error(`Expected kind \"${options.expectedKind}\" but got \"${root.kind}\" at ${root.__filePath}`);\n }\n return root as ResolvedResource<TSpec>;\n}\n"],"mappings":"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","names":["path","path"]}