@theokit/sdk 5.0.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/{agent-5BJF255U.cjs → agent-TKJBWGGQ.cjs} +7 -7
  3. package/dist/{agent-5BJF255U.cjs.map → agent-TKJBWGGQ.cjs.map} +1 -1
  4. package/dist/{agent-HACVHN2V.js → agent-UGYIYC3R.js} +6 -6
  5. package/dist/{agent-HACVHN2V.js.map → agent-UGYIYC3R.js.map} +1 -1
  6. package/dist/{chunk-SYVWE64W.cjs → chunk-5AXMNUCY.cjs} +5 -5
  7. package/dist/{chunk-SYVWE64W.cjs.map → chunk-5AXMNUCY.cjs.map} +1 -1
  8. package/dist/{chunk-4S5TWFIZ.js → chunk-7RHC7HMS.js} +3 -3
  9. package/dist/{chunk-4S5TWFIZ.js.map → chunk-7RHC7HMS.js.map} +1 -1
  10. package/dist/{chunk-WWZO2TTK.cjs → chunk-CC7EYKBJ.cjs} +4 -4
  11. package/dist/{chunk-WWZO2TTK.cjs.map → chunk-CC7EYKBJ.cjs.map} +1 -1
  12. package/dist/{chunk-VVJ7FQAQ.cjs → chunk-CQLVA4CO.cjs} +39 -39
  13. package/dist/{chunk-VVJ7FQAQ.cjs.map → chunk-CQLVA4CO.cjs.map} +1 -1
  14. package/dist/{chunk-XJZEBGXD.js → chunk-D7WAROJR.js} +3 -3
  15. package/dist/{chunk-XJZEBGXD.js.map → chunk-D7WAROJR.js.map} +1 -1
  16. package/dist/{chunk-GGZ5GPE3.cjs → chunk-DLRP7BI6.cjs} +3 -3
  17. package/dist/chunk-DLRP7BI6.cjs.map +1 -0
  18. package/dist/{chunk-67ADYSTW.js → chunk-GUKPXDGJ.js} +4 -4
  19. package/dist/chunk-GUKPXDGJ.js.map +1 -0
  20. package/dist/{chunk-H6YM3PV6.cjs → chunk-LTLPBGHC.cjs} +5 -5
  21. package/dist/{chunk-H6YM3PV6.cjs.map → chunk-LTLPBGHC.cjs.map} +1 -1
  22. package/dist/{chunk-OXQSNOYV.js → chunk-SVWMQCXF.js} +7 -7
  23. package/dist/{chunk-OXQSNOYV.js.map → chunk-SVWMQCXF.js.map} +1 -1
  24. package/dist/{chunk-M3QNTHMV.js → chunk-YEL3SP6X.js} +3 -3
  25. package/dist/{chunk-M3QNTHMV.js.map → chunk-YEL3SP6X.js.map} +1 -1
  26. package/dist/context-FM6UZPTL.js +6 -0
  27. package/dist/{context-Y7B7SI5X.js.map → context-FM6UZPTL.js.map} +1 -1
  28. package/dist/{context-NI33FS2R.cjs → context-XQJIGZMR.cjs} +7 -7
  29. package/dist/{context-NI33FS2R.cjs.map → context-XQJIGZMR.cjs.map} +1 -1
  30. package/dist/cron.cjs +6 -6
  31. package/dist/cron.js +5 -5
  32. package/dist/eval.cjs +5 -5
  33. package/dist/eval.js +4 -4
  34. package/dist/index.cjs +21 -21
  35. package/dist/index.js +7 -7
  36. package/dist/internal/persistence/index.cjs +4 -4
  37. package/dist/internal/persistence/index.js +1 -1
  38. package/dist/internal/runtime/compat/foreign-config-sources.d.ts +29 -6
  39. package/dist/subagents-loader-7ES7PJNM.js +7 -0
  40. package/dist/{subagents-loader-Y6JFYXAY.js.map → subagents-loader-7ES7PJNM.js.map} +1 -1
  41. package/dist/subagents-loader-OMOH6ERO.cjs +16 -0
  42. package/dist/{subagents-loader-TPZLTXYZ.cjs.map → subagents-loader-OMOH6ERO.cjs.map} +1 -1
  43. package/dist/subagents-loader.cjs +3 -3
  44. package/dist/subagents-loader.js +2 -2
  45. package/package.json +1 -1
  46. package/dist/chunk-67ADYSTW.js.map +0 -1
  47. package/dist/chunk-GGZ5GPE3.cjs.map +0 -1
  48. package/dist/context-Y7B7SI5X.js +0 -6
  49. package/dist/subagents-loader-TPZLTXYZ.cjs +0 -16
  50. package/dist/subagents-loader-Y6JFYXAY.js +0 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#564](https://github.com/usetheokit/theokit-sdk/pull/564) [`bed898c`](https://github.com/usetheokit/theokit-sdk/commit/bed898c21a51087c90745a2df762eeabc5f06bee) Thanks [@usetheodev](https://github.com/usetheodev)! - The undeclared-`.claude/` warning now reaches the consumer
8
+
9
+ `5.0.0` made a project's `.claude/` opt-in, and its release note said the workspace "says so once,
10
+ on the diagnostics channel". It did not say so to anyone.
11
+
12
+ The warning went through `diag()`, which returns without doing anything when no diagnostics sink is
13
+ installed. The SDK installs none, and neither of the two observable hosts does either. So a
14
+ consumer upgrading `4.63.4` → `5.0.0` with a `.claude/` and no `compatSources` lost hooks, skills,
15
+ subagents and plugins **in silence** — along with the one line that reverses it:
16
+
17
+ ```ts
18
+ local: { compatSources: ["claude-code"] }
19
+ ```
20
+
21
+ It now goes through `diagFailure()`, which prefers an installed sink and falls back to stderr when
22
+ there is none. A host that intercepts diagnostics keeps owning its render surface; a host that does
23
+ not, still hears this one.
24
+
25
+ The cost is real and is now paid: a repository that wants `.claude/` ignored sees a line. It is
26
+ emitted once per directory per process, not per turn — and before `5.0.0` that repository was
27
+ having the directory imported anyway, so the line confirms the fix it wanted. There is no opt-out
28
+ yet; if the noise matters, say so. ([#563](https://github.com/usetheokit/theokit-sdk/issues/563))
29
+
3
30
  ## 5.0.0
4
31
 
5
32
  ### Major Changes
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
- var chunkVVJ7FQAQ_cjs = require('./chunk-VVJ7FQAQ.cjs');
3
+ var chunkCQLVA4CO_cjs = require('./chunk-CQLVA4CO.cjs');
4
4
  require('./chunk-KVSAY6NZ.cjs');
5
5
  require('./chunk-Y2KYR2ED.cjs');
6
6
  require('./chunk-BUUUWQMB.cjs');
7
7
  require('./chunk-Z2JFX372.cjs');
8
- require('./chunk-H6YM3PV6.cjs');
8
+ require('./chunk-LTLPBGHC.cjs');
9
9
  require('./chunk-BV2MWEMV.cjs');
10
10
  require('./chunk-D6POWE7E.cjs');
11
11
  require('./chunk-GHX4P3V2.cjs');
@@ -43,8 +43,8 @@ require('./chunk-BJUJT5ED.cjs');
43
43
  require('./chunk-ZF2LDKQQ.cjs');
44
44
  require('./chunk-HCT4HPCL.cjs');
45
45
  require('./chunk-JLRLCBJ4.cjs');
46
- require('./chunk-SYVWE64W.cjs');
47
- require('./chunk-GGZ5GPE3.cjs');
46
+ require('./chunk-5AXMNUCY.cjs');
47
+ require('./chunk-DLRP7BI6.cjs');
48
48
  require('./chunk-HW7SEELD.cjs');
49
49
  require('./chunk-ATT276RD.cjs');
50
50
  require('./chunk-3EE6LVWT.cjs');
@@ -61,7 +61,7 @@ require('./chunk-6LHQPOMI.cjs');
61
61
 
62
62
  Object.defineProperty(exports, "Agent", {
63
63
  enumerable: true,
64
- get: function () { return chunkVVJ7FQAQ_cjs.Agent; }
64
+ get: function () { return chunkCQLVA4CO_cjs.Agent; }
65
65
  });
66
- //# sourceMappingURL=agent-5BJF255U.cjs.map
67
- //# sourceMappingURL=agent-5BJF255U.cjs.map
66
+ //# sourceMappingURL=agent-TKJBWGGQ.cjs.map
67
+ //# sourceMappingURL=agent-TKJBWGGQ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-5BJF255U.cjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-TKJBWGGQ.cjs"}
@@ -1,9 +1,9 @@
1
- export { Agent } from './chunk-OXQSNOYV.js';
1
+ export { Agent } from './chunk-SVWMQCXF.js';
2
2
  import './chunk-K2VMFZQ5.js';
3
3
  import './chunk-AWINL3ZC.js';
4
4
  import './chunk-K2BQQ445.js';
5
5
  import './chunk-7SZAV6QG.js';
6
- import './chunk-XJZEBGXD.js';
6
+ import './chunk-D7WAROJR.js';
7
7
  import './chunk-2SFBB54R.js';
8
8
  import './chunk-55GB6JYQ.js';
9
9
  import './chunk-H73MEMQB.js';
@@ -41,8 +41,8 @@ import './chunk-TA3K7SBK.js';
41
41
  import './chunk-Q5EWJPRY.js';
42
42
  import './chunk-EIQFAOFD.js';
43
43
  import './chunk-3JHIFQ4I.js';
44
- import './chunk-4S5TWFIZ.js';
45
- import './chunk-67ADYSTW.js';
44
+ import './chunk-7RHC7HMS.js';
45
+ import './chunk-GUKPXDGJ.js';
46
46
  import './chunk-JNAA4G4H.js';
47
47
  import './chunk-6M2OIS4Y.js';
48
48
  import './chunk-R7WIIPUR.js';
@@ -54,5 +54,5 @@ import './chunk-V22DZIXO.js';
54
54
  import './chunk-NJWYQWDL.js';
55
55
  import './chunk-ALUN2B4W.js';
56
56
  import './chunk-CZJ6Q7CW.js';
57
- //# sourceMappingURL=agent-HACVHN2V.js.map
58
- //# sourceMappingURL=agent-HACVHN2V.js.map
57
+ //# sourceMappingURL=agent-UGYIYC3R.js.map
58
+ //# sourceMappingURL=agent-UGYIYC3R.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-HACVHN2V.js"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"agent-UGYIYC3R.js"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkGGZ5GPE3_cjs = require('./chunk-GGZ5GPE3.cjs');
3
+ var chunkDLRP7BI6_cjs = require('./chunk-DLRP7BI6.cjs');
4
4
  var chunkHW7SEELD_cjs = require('./chunk-HW7SEELD.cjs');
5
5
  var chunkJ7J7J2GN_cjs = require('./chunk-J7J7J2GN.cjs');
6
6
  var chunk6LHQPOMI_cjs = require('./chunk-6LHQPOMI.cjs');
@@ -9,7 +9,7 @@ var path = require('path');
9
9
 
10
10
  async function pluginBundleDirs(cwd, compatSources = []) {
11
11
  const dirs = [];
12
- for (const root of chunkGGZ5GPE3_cjs.pluginBundleRoots(cwd, compatSources)) {
12
+ for (const root of chunkDLRP7BI6_cjs.pluginBundleRoots(cwd, compatSources)) {
13
13
  let entries;
14
14
  try {
15
15
  entries = await promises.readdir(root, { withFileTypes: true });
@@ -41,7 +41,7 @@ async function loadSubagents(cwd, settingSourcesIncludeProject, inline, compatSo
41
41
  }
42
42
  async function readProjectSubagents(cwd, compatSources) {
43
43
  const subagents = {};
44
- for (const configRoot of chunkGGZ5GPE3_cjs.projectConfigRoots(cwd, compatSources, "subagents")) {
44
+ for (const configRoot of chunkDLRP7BI6_cjs.projectConfigRoots(cwd, compatSources, "subagents")) {
45
45
  await readSubagentsFrom(path.join(configRoot, "agents"), subagents);
46
46
  }
47
47
  for (const bundle of await pluginBundleDirs(cwd, compatSources)) {
@@ -168,5 +168,5 @@ function parseFrontmatterFields(frontmatter) {
168
168
 
169
169
  exports.loadSubagents = loadSubagents;
170
170
  exports.pluginBundleDirs = pluginBundleDirs;
171
- //# sourceMappingURL=chunk-SYVWE64W.cjs.map
172
- //# sourceMappingURL=chunk-SYVWE64W.cjs.map
171
+ //# sourceMappingURL=chunk-5AXMNUCY.cjs.map
172
+ //# sourceMappingURL=chunk-5AXMNUCY.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/runtime/plugin-loader/plugin-bundles.ts","../src/internal/runtime/skills/subagents-loader.ts"],"names":["pluginBundleRoots","readdir","join","projectConfigRoots","readWorkspaceDir","path","readFile","diag","ConfigurationError","parseSimpleYaml"],"mappings":"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","file":"chunk-SYVWE64W.cjs","sourcesContent":["/**\n * Locating the plugin bundles a project carries.\n *\n * Shared by the skills and subagents loaders, which both need the same answer to \"which folders in\n * this project are plugins\" and would otherwise each grow their own copy of the directory walk.\n *\n * @internal\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pluginBundleRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\n\n/**\n * Every plugin folder under the project's plugin roots.\n *\n * Returns the FOLDERS, not their contents — what a bundle contributes (`skills/`, `agents/`) is the\n * caller's business, and a loader that also knew the layout would have to change whenever the other\n * one did.\n *\n * A missing root is not an error: most projects carry no plugins, and treating their absence as a\n * failure would make \"none installed\" indistinguishable from \"the directory could not be read\".\n */\nexport async function pluginBundleDirs(\n cwd: string,\n /** Declared foreign dialects (#524). Empty reads `.theokit/plugins` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<string[]> {\n const dirs: string[] = [];\n for (const root of pluginBundleRoots(cwd, compatSources)) {\n let entries: Dirent[];\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) dirs.push(join(root, entry.name));\n }\n }\n return dirs;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport type { AgentDefinition } from \"../../../types/agent.js\";\nimport type { ModelSelection } from \"../../../types/agent-prims.js\";\nimport { diag } from \"../../diagnostics.js\";\nimport { projectConfigRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\nimport { pluginBundleDirs } from \"../plugin-loader/plugin-bundles.js\";\n\n/**\n * Load file-based subagents from `.theokit/agents/*.md` and merge with\n * inline definitions. Inline overrides file-based on name conflict.\n *\n * Each markdown file has YAML frontmatter (description + optional model)\n * and a body that becomes the subagent prompt.\n *\n * @internal\n */\nexport async function loadSubagents(\n cwd: string,\n settingSourcesIncludeProject: boolean,\n inline: Record<string, AgentDefinition> | undefined,\n /** Declared foreign dialects (#524). Empty reads `.theokit/` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<Record<string, AgentDefinition>> {\n const result: Record<string, AgentDefinition> = {};\n if (settingSourcesIncludeProject) {\n const projectAgents = await readProjectSubagents(cwd, compatSources);\n for (const [name, definition] of Object.entries(projectAgents)) {\n result[name] = definition;\n }\n }\n if (inline !== undefined) {\n for (const [name, definition] of Object.entries(inline)) {\n result[name] = definition;\n }\n }\n return result;\n}\n\n/**\n * Read agent declarations from every project config root (`.theokit`, then `.claude`).\n *\n * FIRST occurrence of a name wins, which is what makes `projectConfigRoots`' order a contract rather\n * than a detail: a project declaring the same agent in both means the explicit namespace.\n */\nasync function readProjectSubagents(\n cwd: string,\n compatSources: readonly CompatSourceDeclaration[],\n): Promise<Record<string, AgentDefinition>> {\n const subagents: Record<string, AgentDefinition> = {};\n for (const configRoot of projectConfigRoots(cwd, compatSources, \"subagents\")) {\n await readSubagentsFrom(join(configRoot, \"agents\"), subagents);\n }\n // A Claude Code plugin is a BUNDLE, and its `agents/` is what it exists to contribute. Read after\n // the project's own, so a project can shadow an agent a plugin ships without editing the plugin.\n for (const bundle of await pluginBundleDirs(cwd, compatSources)) {\n await readSubagentsFrom(join(bundle, \"agents\"), subagents);\n }\n return subagents;\n}\n\nasync function readSubagentsFrom(\n root: string,\n subagents: Record<string, AgentDefinition>,\n): Promise<void> {\n const entries = await readWorkspaceDir(root, \"subagents_read_error\", \"subagents directory\");\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const path = join(root, entry.name);\n const raw = await readFile(path, \"utf8\");\n // A markdown file with NO frontmatter is not an agent declaration — a directory of agents\n // written for the Claude Code CLI conventionally carries documentation beside them, and\n // `.claude/agents/README.md` exists in this repository. Throwing on it made ONE such file stop\n // every agent in the directory from loading.\n //\n // Skipped with a warn rather than in silence, and ONLY for the no-frontmatter case: a file that\n // HAS frontmatter and gets it wrong is a broken agent and still fails loudly, which is what\n // keeps a typo'd `sandbox` from returning as a silent gate through this door.\n if (!hasFrontmatter(raw)) {\n diag(`[theokit-sdk] ${entry.name} has no frontmatter — not an agent declaration, skipping`);\n continue;\n }\n const definition = parseSubagentMarkdown(raw, entry.name);\n if (subagents[definition.name] === undefined) {\n // `path` is computed above to read the file and was then dropped. Keeping it is the whole\n // visibility fix (#524): without it a listing cannot say which root an agent came from.\n subagents[definition.name] = { ...definition.definition, source: path };\n }\n }\n}\n\n// The frontmatter keys a disk subagent may declare. Any other key is a typed load\n// error rather than a silent drop — a dropped `sandbox` an operator wrote believing\n// it confines the child is exactly the silent-gate failure class this guards against.\nconst ACCEPTED_FIELDS = new Set([\n \"name\",\n \"description\",\n \"model\",\n \"tools\",\n \"reasoning_effort\",\n \"mcp\",\n \"sandbox\",\n]);\n\n// Fields the Claude Code CLI writes that carry NO behaviour for this runtime. Accepted and ignored,\n// so an agent authored for the CLI loads here unchanged — measured 2026-08-26 across the 59 agent\n// files on one machine, where `color` appeared in 38 of them and made every one of those a\n// `subagent_unknown_field` load error.\n//\n// Named explicitly instead of loosening the check above, because that check's reason is sound: a\n// dropped `sandbox` an operator wrote believing it confines the child is a silent gate. A field that\n// COULD change behaviour must still fail loudly. This set is the difference between \"we know this\n// one and it does nothing\" and \"we have never heard of this\" — two facts a bare allow-everything\n// would collapse into one.\n//\n// Anything added here needs the same justification: inert for THIS runtime, not merely unfamiliar.\nconst INERT_CLAUDE_CODE_FIELDS = new Set([\n /** The CLI's label colour for the agent. Presentation only. */\n \"color\",\n]);\n\nfunction parseSubagentMarkdown(\n raw: string,\n filename: string,\n): { name: string; definition: AgentDefinition } {\n const { frontmatter, body } = splitFrontmatter(raw, filename);\n const fields = parseFrontmatterFields(frontmatter);\n rejectUnknownFields(fields, filename);\n rejectMcp(fields, filename);\n\n const definition: AgentDefinition = {\n description: asString(fields.description) ?? \"\",\n prompt: body,\n };\n const model = resolveModel(fields, filename);\n if (model !== undefined) definition.model = model;\n const tools = toStringList(fields.tools);\n if (tools.length > 0) definition.tools = tools;\n const sandbox = resolveSandbox(fields, filename);\n if (sandbox !== undefined) definition.sandbox = sandbox;\n\n const name = asString(fields.name) ?? filename.replace(/\\.md$/, \"\");\n return { name, definition };\n}\n\nfunction rejectUnknownFields(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): void {\n for (const key of Object.keys(fields)) {\n if (INERT_CLAUDE_CODE_FIELDS.has(key)) continue;\n if (!ACCEPTED_FIELDS.has(key)) {\n throw new ConfigurationError(\n `Subagent ${filename}: unknown frontmatter field \"${key}\" (accepted: ${[...ACCEPTED_FIELDS].join(\", \")})`,\n { code: \"subagent_unknown_field\" },\n );\n }\n }\n}\n\n// mcp: a known field, but not yet honored on the LOCAL delegation path. The frontmatter YAML can only\n// express server NAMES (parseSimpleYaml has no nested-object support), while a child's `Agent.create`\n// needs `mcpServers` as a Record<name, config>; resolving names→config per-subagent in local delegation\n// is its own follow-up. Rather than silently drop it (the M26/M32 silent-gate class), it is a typed load\n// error that names the field and points at the alternative.\nfunction rejectMcp(fields: Record<string, FrontmatterValue | undefined>, filename: string): void {\n if (fields.mcp !== undefined) {\n throw new ConfigurationError(\n `Subagent ${filename}: per-subagent \"mcp\" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,\n { code: \"subagent_mcp_unsupported_local\" },\n );\n }\n}\n\n// model + reasoning_effort — effort rides inside `model.params[thinking]`, so it requires a concrete\n// model id to attach to (a child inheriting the parent's model cannot carry the parent's provider-\n// specific effort param safely).\nfunction resolveModel(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): ModelSelection | \"inherit\" | undefined {\n const modelId = asString(fields.model);\n const effort = asString(fields.reasoning_effort);\n // reasoning_effort rides in model.params[thinking], so it needs a CONCRETE model id to attach to.\n // Neither an absent model NOR `model: inherit` can carry it (the inherited id is unknown at load), so\n // both are typed errors rather than a silently-dropped effort — the silent-gate class this guards.\n if (effort !== undefined && (modelId === undefined || modelId === \"inherit\")) {\n throw new ConfigurationError(\n `Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or \"inherit\" cannot carry it)`,\n { code: \"subagent_reasoning_effort_without_model\" },\n );\n }\n if (modelId === undefined) return undefined;\n if (modelId === \"inherit\") return \"inherit\";\n return effort !== undefined\n ? { id: modelId, params: [{ id: \"thinking\", value: effort }] }\n : { id: modelId };\n}\n\n// sandbox: boolean only. A granular mode string (read-only/…) is unsupported by the SDK runtime and is\n// a typed error rather than a silent coercion to a boolean.\nfunction resolveSandbox(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): boolean | undefined {\n if (fields.sandbox === undefined) return undefined;\n if (typeof fields.sandbox !== \"boolean\") {\n throw new ConfigurationError(\n `Subagent ${filename}: sandbox must be a boolean (got \"${String(fields.sandbox)}\"); granular sandbox modes are not supported by the runtime`,\n { code: \"subagent_sandbox_not_boolean\" },\n );\n }\n return fields.sandbox;\n}\n\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n if (typeof v !== \"string\") return undefined;\n // parseSimpleYaml does not strip quotes (documented), and `model`/`reasoning_effort` are fields users\n // habitually quote (`model: \"openai/gpt-4o\"`). Strip a single matching surrounding quote pair so a\n // quoted id/effort does not slip past validation and fail only at the provider.\n const m = /^([\"'])(.*)\\1$/.exec(v);\n return m ? m[2] : v;\n}\n\n/** Accept a YAML list (`string[]`) or a comma/space-separated scalar; trim + drop empties. */\nfunction toStringList(v: FrontmatterValue | undefined): string[] {\n if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);\n if (typeof v === \"string\") {\n return v\n .split(/[\\s,]+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0);\n }\n return [];\n}\n\n/** Does this file open with a frontmatter block at all? Its ABSENCE means \"not an agent\". */\nfunction hasFrontmatter(raw: string): boolean {\n return /^---\\s*\\n/.test(raw);\n}\n\nfunction splitFrontmatter(raw: string, filename: string): { frontmatter: string; body: string } {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Subagent ${filename} is missing frontmatter`, {\n code: \"subagent_missing_frontmatter\",\n });\n }\n return { frontmatter: match[1] ?? \"\", body: (match[2] ?? \"\").trim() };\n}\n\nfunction parseFrontmatterFields(frontmatter: string): Record<string, FrontmatterValue | undefined> {\n // Preserve the rich YAML value types (boolean/number/string[]): `sandbox: true` and\n // `mcp: [a, b]` are meaningful here, so narrowing everything to string (as the\n // pre-M33 loader did) would drop them. Per-field validation happens in parseSubagentMarkdown.\n return parseSimpleYaml(frontmatter);\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/runtime/plugin-loader/plugin-bundles.ts","../src/internal/runtime/skills/subagents-loader.ts"],"names":["pluginBundleRoots","readdir","join","projectConfigRoots","readWorkspaceDir","path","readFile","diag","ConfigurationError","parseSimpleYaml"],"mappings":"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","file":"chunk-5AXMNUCY.cjs","sourcesContent":["/**\n * Locating the plugin bundles a project carries.\n *\n * Shared by the skills and subagents loaders, which both need the same answer to \"which folders in\n * this project are plugins\" and would otherwise each grow their own copy of the directory walk.\n *\n * @internal\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pluginBundleRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\n\n/**\n * Every plugin folder under the project's plugin roots.\n *\n * Returns the FOLDERS, not their contents — what a bundle contributes (`skills/`, `agents/`) is the\n * caller's business, and a loader that also knew the layout would have to change whenever the other\n * one did.\n *\n * A missing root is not an error: most projects carry no plugins, and treating their absence as a\n * failure would make \"none installed\" indistinguishable from \"the directory could not be read\".\n */\nexport async function pluginBundleDirs(\n cwd: string,\n /** Declared foreign dialects (#524). Empty reads `.theokit/plugins` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<string[]> {\n const dirs: string[] = [];\n for (const root of pluginBundleRoots(cwd, compatSources)) {\n let entries: Dirent[];\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) dirs.push(join(root, entry.name));\n }\n }\n return dirs;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport type { AgentDefinition } from \"../../../types/agent.js\";\nimport type { ModelSelection } from \"../../../types/agent-prims.js\";\nimport { diag } from \"../../diagnostics.js\";\nimport { projectConfigRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\nimport { pluginBundleDirs } from \"../plugin-loader/plugin-bundles.js\";\n\n/**\n * Load file-based subagents from `.theokit/agents/*.md` and merge with\n * inline definitions. Inline overrides file-based on name conflict.\n *\n * Each markdown file has YAML frontmatter (description + optional model)\n * and a body that becomes the subagent prompt.\n *\n * @internal\n */\nexport async function loadSubagents(\n cwd: string,\n settingSourcesIncludeProject: boolean,\n inline: Record<string, AgentDefinition> | undefined,\n /** Declared foreign dialects (#524). Empty reads `.theokit/` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<Record<string, AgentDefinition>> {\n const result: Record<string, AgentDefinition> = {};\n if (settingSourcesIncludeProject) {\n const projectAgents = await readProjectSubagents(cwd, compatSources);\n for (const [name, definition] of Object.entries(projectAgents)) {\n result[name] = definition;\n }\n }\n if (inline !== undefined) {\n for (const [name, definition] of Object.entries(inline)) {\n result[name] = definition;\n }\n }\n return result;\n}\n\n/**\n * Read agent declarations from every project config root (`.theokit`, then `.claude`).\n *\n * FIRST occurrence of a name wins, which is what makes `projectConfigRoots`' order a contract rather\n * than a detail: a project declaring the same agent in both means the explicit namespace.\n */\nasync function readProjectSubagents(\n cwd: string,\n compatSources: readonly CompatSourceDeclaration[],\n): Promise<Record<string, AgentDefinition>> {\n const subagents: Record<string, AgentDefinition> = {};\n for (const configRoot of projectConfigRoots(cwd, compatSources, \"subagents\")) {\n await readSubagentsFrom(join(configRoot, \"agents\"), subagents);\n }\n // A Claude Code plugin is a BUNDLE, and its `agents/` is what it exists to contribute. Read after\n // the project's own, so a project can shadow an agent a plugin ships without editing the plugin.\n for (const bundle of await pluginBundleDirs(cwd, compatSources)) {\n await readSubagentsFrom(join(bundle, \"agents\"), subagents);\n }\n return subagents;\n}\n\nasync function readSubagentsFrom(\n root: string,\n subagents: Record<string, AgentDefinition>,\n): Promise<void> {\n const entries = await readWorkspaceDir(root, \"subagents_read_error\", \"subagents directory\");\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const path = join(root, entry.name);\n const raw = await readFile(path, \"utf8\");\n // A markdown file with NO frontmatter is not an agent declaration — a directory of agents\n // written for the Claude Code CLI conventionally carries documentation beside them, and\n // `.claude/agents/README.md` exists in this repository. Throwing on it made ONE such file stop\n // every agent in the directory from loading.\n //\n // Skipped with a warn rather than in silence, and ONLY for the no-frontmatter case: a file that\n // HAS frontmatter and gets it wrong is a broken agent and still fails loudly, which is what\n // keeps a typo'd `sandbox` from returning as a silent gate through this door.\n if (!hasFrontmatter(raw)) {\n diag(`[theokit-sdk] ${entry.name} has no frontmatter — not an agent declaration, skipping`);\n continue;\n }\n const definition = parseSubagentMarkdown(raw, entry.name);\n if (subagents[definition.name] === undefined) {\n // `path` is computed above to read the file and was then dropped. Keeping it is the whole\n // visibility fix (#524): without it a listing cannot say which root an agent came from.\n subagents[definition.name] = { ...definition.definition, source: path };\n }\n }\n}\n\n// The frontmatter keys a disk subagent may declare. Any other key is a typed load\n// error rather than a silent drop — a dropped `sandbox` an operator wrote believing\n// it confines the child is exactly the silent-gate failure class this guards against.\nconst ACCEPTED_FIELDS = new Set([\n \"name\",\n \"description\",\n \"model\",\n \"tools\",\n \"reasoning_effort\",\n \"mcp\",\n \"sandbox\",\n]);\n\n// Fields the Claude Code CLI writes that carry NO behaviour for this runtime. Accepted and ignored,\n// so an agent authored for the CLI loads here unchanged — measured 2026-08-26 across the 59 agent\n// files on one machine, where `color` appeared in 38 of them and made every one of those a\n// `subagent_unknown_field` load error.\n//\n// Named explicitly instead of loosening the check above, because that check's reason is sound: a\n// dropped `sandbox` an operator wrote believing it confines the child is a silent gate. A field that\n// COULD change behaviour must still fail loudly. This set is the difference between \"we know this\n// one and it does nothing\" and \"we have never heard of this\" — two facts a bare allow-everything\n// would collapse into one.\n//\n// Anything added here needs the same justification: inert for THIS runtime, not merely unfamiliar.\nconst INERT_CLAUDE_CODE_FIELDS = new Set([\n /** The CLI's label colour for the agent. Presentation only. */\n \"color\",\n]);\n\nfunction parseSubagentMarkdown(\n raw: string,\n filename: string,\n): { name: string; definition: AgentDefinition } {\n const { frontmatter, body } = splitFrontmatter(raw, filename);\n const fields = parseFrontmatterFields(frontmatter);\n rejectUnknownFields(fields, filename);\n rejectMcp(fields, filename);\n\n const definition: AgentDefinition = {\n description: asString(fields.description) ?? \"\",\n prompt: body,\n };\n const model = resolveModel(fields, filename);\n if (model !== undefined) definition.model = model;\n const tools = toStringList(fields.tools);\n if (tools.length > 0) definition.tools = tools;\n const sandbox = resolveSandbox(fields, filename);\n if (sandbox !== undefined) definition.sandbox = sandbox;\n\n const name = asString(fields.name) ?? filename.replace(/\\.md$/, \"\");\n return { name, definition };\n}\n\nfunction rejectUnknownFields(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): void {\n for (const key of Object.keys(fields)) {\n if (INERT_CLAUDE_CODE_FIELDS.has(key)) continue;\n if (!ACCEPTED_FIELDS.has(key)) {\n throw new ConfigurationError(\n `Subagent ${filename}: unknown frontmatter field \"${key}\" (accepted: ${[...ACCEPTED_FIELDS].join(\", \")})`,\n { code: \"subagent_unknown_field\" },\n );\n }\n }\n}\n\n// mcp: a known field, but not yet honored on the LOCAL delegation path. The frontmatter YAML can only\n// express server NAMES (parseSimpleYaml has no nested-object support), while a child's `Agent.create`\n// needs `mcpServers` as a Record<name, config>; resolving names→config per-subagent in local delegation\n// is its own follow-up. Rather than silently drop it (the M26/M32 silent-gate class), it is a typed load\n// error that names the field and points at the alternative.\nfunction rejectMcp(fields: Record<string, FrontmatterValue | undefined>, filename: string): void {\n if (fields.mcp !== undefined) {\n throw new ConfigurationError(\n `Subagent ${filename}: per-subagent \"mcp\" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,\n { code: \"subagent_mcp_unsupported_local\" },\n );\n }\n}\n\n// model + reasoning_effort — effort rides inside `model.params[thinking]`, so it requires a concrete\n// model id to attach to (a child inheriting the parent's model cannot carry the parent's provider-\n// specific effort param safely).\nfunction resolveModel(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): ModelSelection | \"inherit\" | undefined {\n const modelId = asString(fields.model);\n const effort = asString(fields.reasoning_effort);\n // reasoning_effort rides in model.params[thinking], so it needs a CONCRETE model id to attach to.\n // Neither an absent model NOR `model: inherit` can carry it (the inherited id is unknown at load), so\n // both are typed errors rather than a silently-dropped effort — the silent-gate class this guards.\n if (effort !== undefined && (modelId === undefined || modelId === \"inherit\")) {\n throw new ConfigurationError(\n `Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or \"inherit\" cannot carry it)`,\n { code: \"subagent_reasoning_effort_without_model\" },\n );\n }\n if (modelId === undefined) return undefined;\n if (modelId === \"inherit\") return \"inherit\";\n return effort !== undefined\n ? { id: modelId, params: [{ id: \"thinking\", value: effort }] }\n : { id: modelId };\n}\n\n// sandbox: boolean only. A granular mode string (read-only/…) is unsupported by the SDK runtime and is\n// a typed error rather than a silent coercion to a boolean.\nfunction resolveSandbox(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): boolean | undefined {\n if (fields.sandbox === undefined) return undefined;\n if (typeof fields.sandbox !== \"boolean\") {\n throw new ConfigurationError(\n `Subagent ${filename}: sandbox must be a boolean (got \"${String(fields.sandbox)}\"); granular sandbox modes are not supported by the runtime`,\n { code: \"subagent_sandbox_not_boolean\" },\n );\n }\n return fields.sandbox;\n}\n\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n if (typeof v !== \"string\") return undefined;\n // parseSimpleYaml does not strip quotes (documented), and `model`/`reasoning_effort` are fields users\n // habitually quote (`model: \"openai/gpt-4o\"`). Strip a single matching surrounding quote pair so a\n // quoted id/effort does not slip past validation and fail only at the provider.\n const m = /^([\"'])(.*)\\1$/.exec(v);\n return m ? m[2] : v;\n}\n\n/** Accept a YAML list (`string[]`) or a comma/space-separated scalar; trim + drop empties. */\nfunction toStringList(v: FrontmatterValue | undefined): string[] {\n if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);\n if (typeof v === \"string\") {\n return v\n .split(/[\\s,]+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0);\n }\n return [];\n}\n\n/** Does this file open with a frontmatter block at all? Its ABSENCE means \"not an agent\". */\nfunction hasFrontmatter(raw: string): boolean {\n return /^---\\s*\\n/.test(raw);\n}\n\nfunction splitFrontmatter(raw: string, filename: string): { frontmatter: string; body: string } {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Subagent ${filename} is missing frontmatter`, {\n code: \"subagent_missing_frontmatter\",\n });\n }\n return { frontmatter: match[1] ?? \"\", body: (match[2] ?? \"\").trim() };\n}\n\nfunction parseFrontmatterFields(frontmatter: string): Record<string, FrontmatterValue | undefined> {\n // Preserve the rich YAML value types (boolean/number/string[]): `sandbox: true` and\n // `mcp: [a, b]` are meaningful here, so narrowing everything to string (as the\n // pre-M33 loader did) would drop them. Per-field validation happens in parseSubagentMarkdown.\n return parseSimpleYaml(frontmatter);\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { pluginBundleRoots, projectConfigRoots } from './chunk-67ADYSTW.js';
1
+ import { pluginBundleRoots, projectConfigRoots } from './chunk-GUKPXDGJ.js';
2
2
  import { readWorkspaceDir, parseSimpleYaml } from './chunk-JNAA4G4H.js';
3
3
  import { ConfigurationError } from './chunk-ALUN2B4W.js';
4
4
  import { diag } from './chunk-CZJ6Q7CW.js';
@@ -165,5 +165,5 @@ function parseFrontmatterFields(frontmatter) {
165
165
  }
166
166
 
167
167
  export { loadSubagents, pluginBundleDirs };
168
- //# sourceMappingURL=chunk-4S5TWFIZ.js.map
169
- //# sourceMappingURL=chunk-4S5TWFIZ.js.map
168
+ //# sourceMappingURL=chunk-7RHC7HMS.js.map
169
+ //# sourceMappingURL=chunk-7RHC7HMS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/runtime/plugin-loader/plugin-bundles.ts","../src/internal/runtime/skills/subagents-loader.ts"],"names":["join"],"mappings":"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","file":"chunk-4S5TWFIZ.js","sourcesContent":["/**\n * Locating the plugin bundles a project carries.\n *\n * Shared by the skills and subagents loaders, which both need the same answer to \"which folders in\n * this project are plugins\" and would otherwise each grow their own copy of the directory walk.\n *\n * @internal\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pluginBundleRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\n\n/**\n * Every plugin folder under the project's plugin roots.\n *\n * Returns the FOLDERS, not their contents — what a bundle contributes (`skills/`, `agents/`) is the\n * caller's business, and a loader that also knew the layout would have to change whenever the other\n * one did.\n *\n * A missing root is not an error: most projects carry no plugins, and treating their absence as a\n * failure would make \"none installed\" indistinguishable from \"the directory could not be read\".\n */\nexport async function pluginBundleDirs(\n cwd: string,\n /** Declared foreign dialects (#524). Empty reads `.theokit/plugins` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<string[]> {\n const dirs: string[] = [];\n for (const root of pluginBundleRoots(cwd, compatSources)) {\n let entries: Dirent[];\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) dirs.push(join(root, entry.name));\n }\n }\n return dirs;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport type { AgentDefinition } from \"../../../types/agent.js\";\nimport type { ModelSelection } from \"../../../types/agent-prims.js\";\nimport { diag } from \"../../diagnostics.js\";\nimport { projectConfigRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\nimport { pluginBundleDirs } from \"../plugin-loader/plugin-bundles.js\";\n\n/**\n * Load file-based subagents from `.theokit/agents/*.md` and merge with\n * inline definitions. Inline overrides file-based on name conflict.\n *\n * Each markdown file has YAML frontmatter (description + optional model)\n * and a body that becomes the subagent prompt.\n *\n * @internal\n */\nexport async function loadSubagents(\n cwd: string,\n settingSourcesIncludeProject: boolean,\n inline: Record<string, AgentDefinition> | undefined,\n /** Declared foreign dialects (#524). Empty reads `.theokit/` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<Record<string, AgentDefinition>> {\n const result: Record<string, AgentDefinition> = {};\n if (settingSourcesIncludeProject) {\n const projectAgents = await readProjectSubagents(cwd, compatSources);\n for (const [name, definition] of Object.entries(projectAgents)) {\n result[name] = definition;\n }\n }\n if (inline !== undefined) {\n for (const [name, definition] of Object.entries(inline)) {\n result[name] = definition;\n }\n }\n return result;\n}\n\n/**\n * Read agent declarations from every project config root (`.theokit`, then `.claude`).\n *\n * FIRST occurrence of a name wins, which is what makes `projectConfigRoots`' order a contract rather\n * than a detail: a project declaring the same agent in both means the explicit namespace.\n */\nasync function readProjectSubagents(\n cwd: string,\n compatSources: readonly CompatSourceDeclaration[],\n): Promise<Record<string, AgentDefinition>> {\n const subagents: Record<string, AgentDefinition> = {};\n for (const configRoot of projectConfigRoots(cwd, compatSources, \"subagents\")) {\n await readSubagentsFrom(join(configRoot, \"agents\"), subagents);\n }\n // A Claude Code plugin is a BUNDLE, and its `agents/` is what it exists to contribute. Read after\n // the project's own, so a project can shadow an agent a plugin ships without editing the plugin.\n for (const bundle of await pluginBundleDirs(cwd, compatSources)) {\n await readSubagentsFrom(join(bundle, \"agents\"), subagents);\n }\n return subagents;\n}\n\nasync function readSubagentsFrom(\n root: string,\n subagents: Record<string, AgentDefinition>,\n): Promise<void> {\n const entries = await readWorkspaceDir(root, \"subagents_read_error\", \"subagents directory\");\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const path = join(root, entry.name);\n const raw = await readFile(path, \"utf8\");\n // A markdown file with NO frontmatter is not an agent declaration — a directory of agents\n // written for the Claude Code CLI conventionally carries documentation beside them, and\n // `.claude/agents/README.md` exists in this repository. Throwing on it made ONE such file stop\n // every agent in the directory from loading.\n //\n // Skipped with a warn rather than in silence, and ONLY for the no-frontmatter case: a file that\n // HAS frontmatter and gets it wrong is a broken agent and still fails loudly, which is what\n // keeps a typo'd `sandbox` from returning as a silent gate through this door.\n if (!hasFrontmatter(raw)) {\n diag(`[theokit-sdk] ${entry.name} has no frontmatter — not an agent declaration, skipping`);\n continue;\n }\n const definition = parseSubagentMarkdown(raw, entry.name);\n if (subagents[definition.name] === undefined) {\n // `path` is computed above to read the file and was then dropped. Keeping it is the whole\n // visibility fix (#524): without it a listing cannot say which root an agent came from.\n subagents[definition.name] = { ...definition.definition, source: path };\n }\n }\n}\n\n// The frontmatter keys a disk subagent may declare. Any other key is a typed load\n// error rather than a silent drop — a dropped `sandbox` an operator wrote believing\n// it confines the child is exactly the silent-gate failure class this guards against.\nconst ACCEPTED_FIELDS = new Set([\n \"name\",\n \"description\",\n \"model\",\n \"tools\",\n \"reasoning_effort\",\n \"mcp\",\n \"sandbox\",\n]);\n\n// Fields the Claude Code CLI writes that carry NO behaviour for this runtime. Accepted and ignored,\n// so an agent authored for the CLI loads here unchanged — measured 2026-08-26 across the 59 agent\n// files on one machine, where `color` appeared in 38 of them and made every one of those a\n// `subagent_unknown_field` load error.\n//\n// Named explicitly instead of loosening the check above, because that check's reason is sound: a\n// dropped `sandbox` an operator wrote believing it confines the child is a silent gate. A field that\n// COULD change behaviour must still fail loudly. This set is the difference between \"we know this\n// one and it does nothing\" and \"we have never heard of this\" — two facts a bare allow-everything\n// would collapse into one.\n//\n// Anything added here needs the same justification: inert for THIS runtime, not merely unfamiliar.\nconst INERT_CLAUDE_CODE_FIELDS = new Set([\n /** The CLI's label colour for the agent. Presentation only. */\n \"color\",\n]);\n\nfunction parseSubagentMarkdown(\n raw: string,\n filename: string,\n): { name: string; definition: AgentDefinition } {\n const { frontmatter, body } = splitFrontmatter(raw, filename);\n const fields = parseFrontmatterFields(frontmatter);\n rejectUnknownFields(fields, filename);\n rejectMcp(fields, filename);\n\n const definition: AgentDefinition = {\n description: asString(fields.description) ?? \"\",\n prompt: body,\n };\n const model = resolveModel(fields, filename);\n if (model !== undefined) definition.model = model;\n const tools = toStringList(fields.tools);\n if (tools.length > 0) definition.tools = tools;\n const sandbox = resolveSandbox(fields, filename);\n if (sandbox !== undefined) definition.sandbox = sandbox;\n\n const name = asString(fields.name) ?? filename.replace(/\\.md$/, \"\");\n return { name, definition };\n}\n\nfunction rejectUnknownFields(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): void {\n for (const key of Object.keys(fields)) {\n if (INERT_CLAUDE_CODE_FIELDS.has(key)) continue;\n if (!ACCEPTED_FIELDS.has(key)) {\n throw new ConfigurationError(\n `Subagent ${filename}: unknown frontmatter field \"${key}\" (accepted: ${[...ACCEPTED_FIELDS].join(\", \")})`,\n { code: \"subagent_unknown_field\" },\n );\n }\n }\n}\n\n// mcp: a known field, but not yet honored on the LOCAL delegation path. The frontmatter YAML can only\n// express server NAMES (parseSimpleYaml has no nested-object support), while a child's `Agent.create`\n// needs `mcpServers` as a Record<name, config>; resolving names→config per-subagent in local delegation\n// is its own follow-up. Rather than silently drop it (the M26/M32 silent-gate class), it is a typed load\n// error that names the field and points at the alternative.\nfunction rejectMcp(fields: Record<string, FrontmatterValue | undefined>, filename: string): void {\n if (fields.mcp !== undefined) {\n throw new ConfigurationError(\n `Subagent ${filename}: per-subagent \"mcp\" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,\n { code: \"subagent_mcp_unsupported_local\" },\n );\n }\n}\n\n// model + reasoning_effort — effort rides inside `model.params[thinking]`, so it requires a concrete\n// model id to attach to (a child inheriting the parent's model cannot carry the parent's provider-\n// specific effort param safely).\nfunction resolveModel(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): ModelSelection | \"inherit\" | undefined {\n const modelId = asString(fields.model);\n const effort = asString(fields.reasoning_effort);\n // reasoning_effort rides in model.params[thinking], so it needs a CONCRETE model id to attach to.\n // Neither an absent model NOR `model: inherit` can carry it (the inherited id is unknown at load), so\n // both are typed errors rather than a silently-dropped effort — the silent-gate class this guards.\n if (effort !== undefined && (modelId === undefined || modelId === \"inherit\")) {\n throw new ConfigurationError(\n `Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or \"inherit\" cannot carry it)`,\n { code: \"subagent_reasoning_effort_without_model\" },\n );\n }\n if (modelId === undefined) return undefined;\n if (modelId === \"inherit\") return \"inherit\";\n return effort !== undefined\n ? { id: modelId, params: [{ id: \"thinking\", value: effort }] }\n : { id: modelId };\n}\n\n// sandbox: boolean only. A granular mode string (read-only/…) is unsupported by the SDK runtime and is\n// a typed error rather than a silent coercion to a boolean.\nfunction resolveSandbox(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): boolean | undefined {\n if (fields.sandbox === undefined) return undefined;\n if (typeof fields.sandbox !== \"boolean\") {\n throw new ConfigurationError(\n `Subagent ${filename}: sandbox must be a boolean (got \"${String(fields.sandbox)}\"); granular sandbox modes are not supported by the runtime`,\n { code: \"subagent_sandbox_not_boolean\" },\n );\n }\n return fields.sandbox;\n}\n\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n if (typeof v !== \"string\") return undefined;\n // parseSimpleYaml does not strip quotes (documented), and `model`/`reasoning_effort` are fields users\n // habitually quote (`model: \"openai/gpt-4o\"`). Strip a single matching surrounding quote pair so a\n // quoted id/effort does not slip past validation and fail only at the provider.\n const m = /^([\"'])(.*)\\1$/.exec(v);\n return m ? m[2] : v;\n}\n\n/** Accept a YAML list (`string[]`) or a comma/space-separated scalar; trim + drop empties. */\nfunction toStringList(v: FrontmatterValue | undefined): string[] {\n if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);\n if (typeof v === \"string\") {\n return v\n .split(/[\\s,]+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0);\n }\n return [];\n}\n\n/** Does this file open with a frontmatter block at all? Its ABSENCE means \"not an agent\". */\nfunction hasFrontmatter(raw: string): boolean {\n return /^---\\s*\\n/.test(raw);\n}\n\nfunction splitFrontmatter(raw: string, filename: string): { frontmatter: string; body: string } {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Subagent ${filename} is missing frontmatter`, {\n code: \"subagent_missing_frontmatter\",\n });\n }\n return { frontmatter: match[1] ?? \"\", body: (match[2] ?? \"\").trim() };\n}\n\nfunction parseFrontmatterFields(frontmatter: string): Record<string, FrontmatterValue | undefined> {\n // Preserve the rich YAML value types (boolean/number/string[]): `sandbox: true` and\n // `mcp: [a, b]` are meaningful here, so narrowing everything to string (as the\n // pre-M33 loader did) would drop them. Per-field validation happens in parseSubagentMarkdown.\n return parseSimpleYaml(frontmatter);\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/runtime/plugin-loader/plugin-bundles.ts","../src/internal/runtime/skills/subagents-loader.ts"],"names":["join"],"mappings":"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","file":"chunk-7RHC7HMS.js","sourcesContent":["/**\n * Locating the plugin bundles a project carries.\n *\n * Shared by the skills and subagents loaders, which both need the same answer to \"which folders in\n * this project are plugins\" and would otherwise each grow their own copy of the directory walk.\n *\n * @internal\n */\n\nimport type { Dirent } from \"node:fs\";\nimport { readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { pluginBundleRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\n\n/**\n * Every plugin folder under the project's plugin roots.\n *\n * Returns the FOLDERS, not their contents — what a bundle contributes (`skills/`, `agents/`) is the\n * caller's business, and a loader that also knew the layout would have to change whenever the other\n * one did.\n *\n * A missing root is not an error: most projects carry no plugins, and treating their absence as a\n * failure would make \"none installed\" indistinguishable from \"the directory could not be read\".\n */\nexport async function pluginBundleDirs(\n cwd: string,\n /** Declared foreign dialects (#524). Empty reads `.theokit/plugins` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<string[]> {\n const dirs: string[] = [];\n for (const root of pluginBundleRoots(cwd, compatSources)) {\n let entries: Dirent[];\n try {\n entries = await readdir(root, { withFileTypes: true });\n } catch {\n continue;\n }\n for (const entry of entries) {\n if (entry.isDirectory()) dirs.push(join(root, entry.name));\n }\n }\n return dirs;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ConfigurationError } from \"../../../errors.js\";\nimport type { AgentDefinition } from \"../../../types/agent.js\";\nimport type { ModelSelection } from \"../../../types/agent-prims.js\";\nimport { diag } from \"../../diagnostics.js\";\nimport { projectConfigRoots } from \"../../persistence/paths.js\";\nimport type { CompatSourceDeclaration } from \"../compat/foreign-config-sources.js\";\nimport { readWorkspaceDir } from \"../config/workspace-dir.js\";\nimport { type FrontmatterValue, parseSimpleYaml } from \"../context/yaml-frontmatter.js\";\nimport { pluginBundleDirs } from \"../plugin-loader/plugin-bundles.js\";\n\n/**\n * Load file-based subagents from `.theokit/agents/*.md` and merge with\n * inline definitions. Inline overrides file-based on name conflict.\n *\n * Each markdown file has YAML frontmatter (description + optional model)\n * and a body that becomes the subagent prompt.\n *\n * @internal\n */\nexport async function loadSubagents(\n cwd: string,\n settingSourcesIncludeProject: boolean,\n inline: Record<string, AgentDefinition> | undefined,\n /** Declared foreign dialects (#524). Empty reads `.theokit/` only. */\n compatSources: readonly CompatSourceDeclaration[] = [],\n): Promise<Record<string, AgentDefinition>> {\n const result: Record<string, AgentDefinition> = {};\n if (settingSourcesIncludeProject) {\n const projectAgents = await readProjectSubagents(cwd, compatSources);\n for (const [name, definition] of Object.entries(projectAgents)) {\n result[name] = definition;\n }\n }\n if (inline !== undefined) {\n for (const [name, definition] of Object.entries(inline)) {\n result[name] = definition;\n }\n }\n return result;\n}\n\n/**\n * Read agent declarations from every project config root (`.theokit`, then `.claude`).\n *\n * FIRST occurrence of a name wins, which is what makes `projectConfigRoots`' order a contract rather\n * than a detail: a project declaring the same agent in both means the explicit namespace.\n */\nasync function readProjectSubagents(\n cwd: string,\n compatSources: readonly CompatSourceDeclaration[],\n): Promise<Record<string, AgentDefinition>> {\n const subagents: Record<string, AgentDefinition> = {};\n for (const configRoot of projectConfigRoots(cwd, compatSources, \"subagents\")) {\n await readSubagentsFrom(join(configRoot, \"agents\"), subagents);\n }\n // A Claude Code plugin is a BUNDLE, and its `agents/` is what it exists to contribute. Read after\n // the project's own, so a project can shadow an agent a plugin ships without editing the plugin.\n for (const bundle of await pluginBundleDirs(cwd, compatSources)) {\n await readSubagentsFrom(join(bundle, \"agents\"), subagents);\n }\n return subagents;\n}\n\nasync function readSubagentsFrom(\n root: string,\n subagents: Record<string, AgentDefinition>,\n): Promise<void> {\n const entries = await readWorkspaceDir(root, \"subagents_read_error\", \"subagents directory\");\n for (const entry of entries) {\n if (!entry.isFile() || !entry.name.endsWith(\".md\")) continue;\n const path = join(root, entry.name);\n const raw = await readFile(path, \"utf8\");\n // A markdown file with NO frontmatter is not an agent declaration — a directory of agents\n // written for the Claude Code CLI conventionally carries documentation beside them, and\n // `.claude/agents/README.md` exists in this repository. Throwing on it made ONE such file stop\n // every agent in the directory from loading.\n //\n // Skipped with a warn rather than in silence, and ONLY for the no-frontmatter case: a file that\n // HAS frontmatter and gets it wrong is a broken agent and still fails loudly, which is what\n // keeps a typo'd `sandbox` from returning as a silent gate through this door.\n if (!hasFrontmatter(raw)) {\n diag(`[theokit-sdk] ${entry.name} has no frontmatter — not an agent declaration, skipping`);\n continue;\n }\n const definition = parseSubagentMarkdown(raw, entry.name);\n if (subagents[definition.name] === undefined) {\n // `path` is computed above to read the file and was then dropped. Keeping it is the whole\n // visibility fix (#524): without it a listing cannot say which root an agent came from.\n subagents[definition.name] = { ...definition.definition, source: path };\n }\n }\n}\n\n// The frontmatter keys a disk subagent may declare. Any other key is a typed load\n// error rather than a silent drop — a dropped `sandbox` an operator wrote believing\n// it confines the child is exactly the silent-gate failure class this guards against.\nconst ACCEPTED_FIELDS = new Set([\n \"name\",\n \"description\",\n \"model\",\n \"tools\",\n \"reasoning_effort\",\n \"mcp\",\n \"sandbox\",\n]);\n\n// Fields the Claude Code CLI writes that carry NO behaviour for this runtime. Accepted and ignored,\n// so an agent authored for the CLI loads here unchanged — measured 2026-08-26 across the 59 agent\n// files on one machine, where `color` appeared in 38 of them and made every one of those a\n// `subagent_unknown_field` load error.\n//\n// Named explicitly instead of loosening the check above, because that check's reason is sound: a\n// dropped `sandbox` an operator wrote believing it confines the child is a silent gate. A field that\n// COULD change behaviour must still fail loudly. This set is the difference between \"we know this\n// one and it does nothing\" and \"we have never heard of this\" — two facts a bare allow-everything\n// would collapse into one.\n//\n// Anything added here needs the same justification: inert for THIS runtime, not merely unfamiliar.\nconst INERT_CLAUDE_CODE_FIELDS = new Set([\n /** The CLI's label colour for the agent. Presentation only. */\n \"color\",\n]);\n\nfunction parseSubagentMarkdown(\n raw: string,\n filename: string,\n): { name: string; definition: AgentDefinition } {\n const { frontmatter, body } = splitFrontmatter(raw, filename);\n const fields = parseFrontmatterFields(frontmatter);\n rejectUnknownFields(fields, filename);\n rejectMcp(fields, filename);\n\n const definition: AgentDefinition = {\n description: asString(fields.description) ?? \"\",\n prompt: body,\n };\n const model = resolveModel(fields, filename);\n if (model !== undefined) definition.model = model;\n const tools = toStringList(fields.tools);\n if (tools.length > 0) definition.tools = tools;\n const sandbox = resolveSandbox(fields, filename);\n if (sandbox !== undefined) definition.sandbox = sandbox;\n\n const name = asString(fields.name) ?? filename.replace(/\\.md$/, \"\");\n return { name, definition };\n}\n\nfunction rejectUnknownFields(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): void {\n for (const key of Object.keys(fields)) {\n if (INERT_CLAUDE_CODE_FIELDS.has(key)) continue;\n if (!ACCEPTED_FIELDS.has(key)) {\n throw new ConfigurationError(\n `Subagent ${filename}: unknown frontmatter field \"${key}\" (accepted: ${[...ACCEPTED_FIELDS].join(\", \")})`,\n { code: \"subagent_unknown_field\" },\n );\n }\n }\n}\n\n// mcp: a known field, but not yet honored on the LOCAL delegation path. The frontmatter YAML can only\n// express server NAMES (parseSimpleYaml has no nested-object support), while a child's `Agent.create`\n// needs `mcpServers` as a Record<name, config>; resolving names→config per-subagent in local delegation\n// is its own follow-up. Rather than silently drop it (the M26/M32 silent-gate class), it is a typed load\n// error that names the field and points at the alternative.\nfunction rejectMcp(fields: Record<string, FrontmatterValue | undefined>, filename: string): void {\n if (fields.mcp !== undefined) {\n throw new ConfigurationError(\n `Subagent ${filename}: per-subagent \"mcp\" is not yet supported on the local delegation path; declare MCP servers in .theokit/mcp.json (or the parent) instead`,\n { code: \"subagent_mcp_unsupported_local\" },\n );\n }\n}\n\n// model + reasoning_effort — effort rides inside `model.params[thinking]`, so it requires a concrete\n// model id to attach to (a child inheriting the parent's model cannot carry the parent's provider-\n// specific effort param safely).\nfunction resolveModel(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): ModelSelection | \"inherit\" | undefined {\n const modelId = asString(fields.model);\n const effort = asString(fields.reasoning_effort);\n // reasoning_effort rides in model.params[thinking], so it needs a CONCRETE model id to attach to.\n // Neither an absent model NOR `model: inherit` can carry it (the inherited id is unknown at load), so\n // both are typed errors rather than a silently-dropped effort — the silent-gate class this guards.\n if (effort !== undefined && (modelId === undefined || modelId === \"inherit\")) {\n throw new ConfigurationError(\n `Subagent ${filename}: reasoning_effort requires a concrete model (effort is a model parameter; an absent model or \"inherit\" cannot carry it)`,\n { code: \"subagent_reasoning_effort_without_model\" },\n );\n }\n if (modelId === undefined) return undefined;\n if (modelId === \"inherit\") return \"inherit\";\n return effort !== undefined\n ? { id: modelId, params: [{ id: \"thinking\", value: effort }] }\n : { id: modelId };\n}\n\n// sandbox: boolean only. A granular mode string (read-only/…) is unsupported by the SDK runtime and is\n// a typed error rather than a silent coercion to a boolean.\nfunction resolveSandbox(\n fields: Record<string, FrontmatterValue | undefined>,\n filename: string,\n): boolean | undefined {\n if (fields.sandbox === undefined) return undefined;\n if (typeof fields.sandbox !== \"boolean\") {\n throw new ConfigurationError(\n `Subagent ${filename}: sandbox must be a boolean (got \"${String(fields.sandbox)}\"); granular sandbox modes are not supported by the runtime`,\n { code: \"subagent_sandbox_not_boolean\" },\n );\n }\n return fields.sandbox;\n}\n\nfunction asString(v: FrontmatterValue | undefined): string | undefined {\n if (typeof v !== \"string\") return undefined;\n // parseSimpleYaml does not strip quotes (documented), and `model`/`reasoning_effort` are fields users\n // habitually quote (`model: \"openai/gpt-4o\"`). Strip a single matching surrounding quote pair so a\n // quoted id/effort does not slip past validation and fail only at the provider.\n const m = /^([\"'])(.*)\\1$/.exec(v);\n return m ? m[2] : v;\n}\n\n/** Accept a YAML list (`string[]`) or a comma/space-separated scalar; trim + drop empties. */\nfunction toStringList(v: FrontmatterValue | undefined): string[] {\n if (Array.isArray(v)) return v.map((t) => t.trim()).filter((t) => t.length > 0);\n if (typeof v === \"string\") {\n return v\n .split(/[\\s,]+/)\n .map((t) => t.trim())\n .filter((t) => t.length > 0);\n }\n return [];\n}\n\n/** Does this file open with a frontmatter block at all? Its ABSENCE means \"not an agent\". */\nfunction hasFrontmatter(raw: string): boolean {\n return /^---\\s*\\n/.test(raw);\n}\n\nfunction splitFrontmatter(raw: string, filename: string): { frontmatter: string; body: string } {\n const match = /^---\\s*\\n([\\s\\S]*?)\\n---\\s*\\n([\\s\\S]*)$/.exec(raw);\n if (match === null) {\n throw new ConfigurationError(`Subagent ${filename} is missing frontmatter`, {\n code: \"subagent_missing_frontmatter\",\n });\n }\n return { frontmatter: match[1] ?? \"\", body: (match[2] ?? \"\").trim() };\n}\n\nfunction parseFrontmatterFields(frontmatter: string): Record<string, FrontmatterValue | undefined> {\n // Preserve the rich YAML value types (boolean/number/string[]): `sandbox: true` and\n // `mcp: [a, b]` are meaningful here, so narrowing everything to string (as the\n // pre-M33 loader did) would drop them. Per-field validation happens in parseSubagentMarkdown.\n return parseSimpleYaml(frontmatter);\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkVVJ7FQAQ_cjs = require('./chunk-VVJ7FQAQ.cjs');
3
+ var chunkCQLVA4CO_cjs = require('./chunk-CQLVA4CO.cjs');
4
4
  var chunkKVSAY6NZ_cjs = require('./chunk-KVSAY6NZ.cjs');
5
5
  var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
6
6
  var chunkJ7J7J2GN_cjs = require('./chunk-J7J7J2GN.cjs');
@@ -376,7 +376,7 @@ async function createCronJob(options) {
376
376
  const now = Date.now();
377
377
  const nextFireAt = nextRunAt(options.cron, timezone);
378
378
  const job = {
379
- id: chunkVVJ7FQAQ_cjs.generateCronId(),
379
+ id: chunkCQLVA4CO_cjs.generateCronId(),
380
380
  cron: options.cron,
381
381
  timezone,
382
382
  enabled: options.enabled ?? true,
@@ -453,5 +453,5 @@ async function updateJobStatus(jobId, enabled) {
453
453
  }
454
454
 
455
455
  exports.Cron = Cron2;
456
- //# sourceMappingURL=chunk-WWZO2TTK.cjs.map
457
- //# sourceMappingURL=chunk-WWZO2TTK.cjs.map
456
+ //# sourceMappingURL=chunk-CC7EYKBJ.cjs.map
457
+ //# sourceMappingURL=chunk-CC7EYKBJ.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/validate.ts","../src/internal/cron/scheduler.ts","../src/cron.ts"],"names":["ConfigurationError","getAgentFacade","UnknownAgentError","submit","Cron","Croner","resolveApiKey","generateCronId"],"mappings":"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","file":"chunk-WWZO2TTK.cjs","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron } from \"croner\";\nimport { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Shorthand (`@daily`, …) to the POSIX five-field form Croner parses.\n *\n * Moved here from the scheduler: interpreting a cron expression is this module's subject, and\n * {@link nextRunAt} needs the same mapping. Two copies would let the scheduler and the value stored\n * on the job disagree about what `@weekly` means.\n *\n * @internal\n */\nexport function normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n\n/**\n * When this expression next fires, or `undefined` when it never does again.\n *\n * This used to be `estimateNextRunAt`, which read neither of its parameters and returned\n * `Date.now() + 3600_000` for every input. Its docstring scoped it to fixture mode — \"real scheduling\n * uses a proper evaluator wired in by the local scheduler\" — and its one call site was\n * `Cron.create()`, so EVERY job created carried a `nextRunAt` one hour out whatever its schedule\n * said. A `@yearly` job reported that it would run in an hour. The scheduler corrected the value\n * later for jobs it picked up, so the fiction was visible exactly in the window between creating a\n * job and the scheduler reaching it — and permanently for a job the scheduler never runs.\n *\n * Croner is already a dependency and already computes this in the scheduler; this is the same call.\n * `undefined` rather than a filled-in number when there is no next run: `CronJob.nextRunAt` is\n * optional, and an absent next run is a real state (a one-shot date in the past), not a zero.\n *\n * @internal\n */\nexport function nextRunAt(cron: string, timezone: string): number | undefined {\n return new Cron(normalizeExpression(cron), { timezone }).nextRun()?.getTime();\n}\n","import { Cron as Croner } from \"croner\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\nimport { normalizeExpression } from \"./validate.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport { nextRunAt, validateCronExpression, validateTimezone } from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n // Computed, not estimated. The predecessor returned now+1h for every expression, so a @yearly job\n // reported that it would run within the hour until the scheduler corrected it — and forever if the\n // scheduler never picked it up. Spread conditionally below: `nextRunAt` is optional, and \"no next\n // run\" is a real answer for a one-shot date in the past.\n const nextFireAt = nextRunAt(options.cron, timezone);\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n ...(nextFireAt === undefined ? {} : { nextRunAt: nextFireAt }),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}
1
+ {"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/validate.ts","../src/internal/cron/scheduler.ts","../src/cron.ts"],"names":["ConfigurationError","getAgentFacade","UnknownAgentError","submit","Cron","Croner","resolveApiKey","generateCronId"],"mappings":"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","file":"chunk-CC7EYKBJ.cjs","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron } from \"croner\";\nimport { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Shorthand (`@daily`, …) to the POSIX five-field form Croner parses.\n *\n * Moved here from the scheduler: interpreting a cron expression is this module's subject, and\n * {@link nextRunAt} needs the same mapping. Two copies would let the scheduler and the value stored\n * on the job disagree about what `@weekly` means.\n *\n * @internal\n */\nexport function normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n\n/**\n * When this expression next fires, or `undefined` when it never does again.\n *\n * This used to be `estimateNextRunAt`, which read neither of its parameters and returned\n * `Date.now() + 3600_000` for every input. Its docstring scoped it to fixture mode — \"real scheduling\n * uses a proper evaluator wired in by the local scheduler\" — and its one call site was\n * `Cron.create()`, so EVERY job created carried a `nextRunAt` one hour out whatever its schedule\n * said. A `@yearly` job reported that it would run in an hour. The scheduler corrected the value\n * later for jobs it picked up, so the fiction was visible exactly in the window between creating a\n * job and the scheduler reaching it — and permanently for a job the scheduler never runs.\n *\n * Croner is already a dependency and already computes this in the scheduler; this is the same call.\n * `undefined` rather than a filled-in number when there is no next run: `CronJob.nextRunAt` is\n * optional, and an absent next run is a real state (a one-shot date in the past), not a zero.\n *\n * @internal\n */\nexport function nextRunAt(cron: string, timezone: string): number | undefined {\n return new Cron(normalizeExpression(cron), { timezone }).nextRun()?.getTime();\n}\n","import { Cron as Croner } from \"croner\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\nimport { normalizeExpression } from \"./validate.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport { nextRunAt, validateCronExpression, validateTimezone } from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n // Computed, not estimated. The predecessor returned now+1h for every expression, so a @yearly job\n // reported that it would run within the hour until the scheduler corrected it — and forever if the\n // scheduler never picked it up. Spread conditionally below: `nextRunAt` is optional, and \"no next\n // run\" is a real answer for a one-shot date in the past.\n const nextFireAt = nextRunAt(options.cron, timezone);\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n ...(nextFireAt === undefined ? {} : { nextRunAt: nextFireAt }),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}