noumen 0.5.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/README.md +237 -93
  2. package/dist/a2a/index.d.ts +5 -7
  3. package/dist/a2a/index.js +3 -4
  4. package/dist/a2a/index.js.map +1 -1
  5. package/dist/acp/index.d.ts +5 -7
  6. package/dist/acp/index.js +0 -1
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/{agent-C3eDRsxs.d.ts → agent-D0gl-qYi.d.ts} +259 -31
  9. package/dist/{chunk-WPCYGZOE.js → chunk-5HY4IYNT.js} +2062 -2545
  10. package/dist/chunk-5HY4IYNT.js.map +1 -0
  11. package/dist/chunk-BC5BLWBC.js +21 -0
  12. package/dist/chunk-BC5BLWBC.js.map +1 -0
  13. package/dist/{chunk-XZN4QZLK.js → chunk-CX4BL6PC.js} +25 -15
  14. package/dist/chunk-CX4BL6PC.js.map +1 -0
  15. package/dist/{chunk-5GEX6ZSB.js → chunk-HQISH4D7.js} +60 -1
  16. package/dist/chunk-HQISH4D7.js.map +1 -0
  17. package/dist/{chunk-Y45R3PQL.js → chunk-NUCJXOUV.js} +32 -18
  18. package/dist/{chunk-Y45R3PQL.js.map → chunk-NUCJXOUV.js.map} +1 -1
  19. package/dist/chunk-OPFFLQZL.js +40 -0
  20. package/dist/chunk-OPFFLQZL.js.map +1 -0
  21. package/dist/chunk-PDEAJ272.js +660 -0
  22. package/dist/chunk-PDEAJ272.js.map +1 -0
  23. package/dist/chunk-PKHLGGEC.js +115 -0
  24. package/dist/chunk-PKHLGGEC.js.map +1 -0
  25. package/dist/chunk-XQTNXRE7.js +176 -0
  26. package/dist/chunk-XQTNXRE7.js.map +1 -0
  27. package/dist/chunk-XZPAA5TO.js +817 -0
  28. package/dist/chunk-XZPAA5TO.js.map +1 -0
  29. package/dist/cli/index.js +77 -42
  30. package/dist/cli/index.js.map +1 -1
  31. package/dist/client/index.d.ts +1 -2
  32. package/dist/client/index.js +0 -2
  33. package/dist/client/index.js.map +1 -1
  34. package/dist/client-JJFLE6RT.js +9 -0
  35. package/dist/{computer-BPdxSo6X.d.ts → computer-DzMR92tK.d.ts} +1 -1
  36. package/dist/docker.d.ts +2 -2
  37. package/dist/docker.js +0 -1
  38. package/dist/docker.js.map +1 -1
  39. package/dist/e2b.d.ts +2 -2
  40. package/dist/e2b.js +0 -1
  41. package/dist/e2b.js.map +1 -1
  42. package/dist/freestyle.d.ts +2 -2
  43. package/dist/freestyle.js +0 -1
  44. package/dist/freestyle.js.map +1 -1
  45. package/dist/{headless-FFU2DESQ.js → headless-25DU4MJQ.js} +1 -3
  46. package/dist/{headless-FFU2DESQ.js.map → headless-25DU4MJQ.js.map} +1 -1
  47. package/dist/{history-snip-64GYP4ZL.js → history-snip-HAWNAYKY.js} +1 -2
  48. package/dist/index.d.ts +358 -72
  49. package/dist/index.js +68 -55
  50. package/dist/jsonrpc/index.js +0 -1
  51. package/dist/local.d.ts +168 -0
  52. package/dist/local.js +40 -0
  53. package/dist/local.js.map +1 -0
  54. package/dist/lsp/index.d.ts +4 -5
  55. package/dist/lsp/index.js +0 -1
  56. package/dist/{lsp-PS3BWIHC.js → lsp-3APWNKB2.js} +1 -2
  57. package/dist/{manager-DLXK63XC.js → manager-Z5EQ7YYV.js} +1 -2
  58. package/dist/mcp/index.d.ts +16 -8
  59. package/dist/mcp/index.js +5 -6
  60. package/dist/mcp/index.js.map +1 -1
  61. package/dist/{mcp-auth-AEI2R4ZC.js → mcp-auth-NOIQPF7W.js} +1 -2
  62. package/dist/{provider-factory-KI7OZUY3.js → provider-factory-KNBSHXJ6.js} +3 -3
  63. package/dist/{render-GRN4ZSSW.js → render-4VEODRK7.js} +1 -2
  64. package/dist/{resolve-GDSHNMG6.js → resolve-AGQZFMKD.js} +3 -3
  65. package/dist/sandbox-DAqQo0Tj.d.ts +49 -0
  66. package/dist/sandbox-index-ODNREIFA.js +32 -0
  67. package/dist/sandbox-index-ODNREIFA.js.map +1 -0
  68. package/dist/server/index.d.ts +18 -7
  69. package/dist/server/index.js +9 -5
  70. package/dist/server/index.js.map +1 -1
  71. package/dist/{server-Cu9gv1dk.d.ts → server-DFXdlqyX.d.ts} +1 -1
  72. package/dist/{spinner-OJNR6NFO.js → spinner-72JEISPK.js} +1 -2
  73. package/dist/sprites.d.ts +2 -2
  74. package/dist/sprites.js +0 -1
  75. package/dist/sprites.js.map +1 -1
  76. package/dist/ssh.d.ts +2 -2
  77. package/dist/ssh.js +0 -1
  78. package/dist/ssh.js.map +1 -1
  79. package/dist/{types-BA87bHPV.d.ts → types-BX4ALqoN.d.ts} +76 -4
  80. package/dist/{types-LrU4LRmX.d.ts → types-DLZNyF5t.d.ts} +164 -2
  81. package/dist/unsandboxed.d.ts +59 -0
  82. package/dist/unsandboxed.js +32 -0
  83. package/dist/unsandboxed.js.map +1 -0
  84. package/dist/{uuid-RVN2T26F.js → uuid-CVTNAPEB.js} +1 -2
  85. package/dist/{zod-7YXKWYMC.js → zod-VKURGPRT.js} +1 -2
  86. package/package.json +35 -50
  87. package/dist/cache-DsRqxx6v.d.ts +0 -38
  88. package/dist/chunk-5GEX6ZSB.js.map +0 -1
  89. package/dist/chunk-CS6WNDCF.js +0 -171
  90. package/dist/chunk-CS6WNDCF.js.map +0 -1
  91. package/dist/chunk-DGUM43GV.js +0 -11
  92. package/dist/chunk-EKOGVTBT.js +0 -472
  93. package/dist/chunk-EKOGVTBT.js.map +0 -1
  94. package/dist/chunk-HEQQQGK5.js +0 -131
  95. package/dist/chunk-HEQQQGK5.js.map +0 -1
  96. package/dist/chunk-L3L3FG5T.js +0 -16
  97. package/dist/chunk-L3L3FG5T.js.map +0 -1
  98. package/dist/chunk-WPCYGZOE.js.map +0 -1
  99. package/dist/chunk-WTLK2ZAR.js +0 -94
  100. package/dist/chunk-WTLK2ZAR.js.map +0 -1
  101. package/dist/chunk-XZN4QZLK.js.map +0 -1
  102. package/dist/client-CRRO2376.js +0 -10
  103. package/dist/providers/anthropic.d.ts +0 -19
  104. package/dist/providers/anthropic.js +0 -35
  105. package/dist/providers/anthropic.js.map +0 -1
  106. package/dist/providers/bedrock.d.ts +0 -39
  107. package/dist/providers/bedrock.js +0 -56
  108. package/dist/providers/bedrock.js.map +0 -1
  109. package/dist/providers/gemini.d.ts +0 -17
  110. package/dist/providers/gemini.js +0 -262
  111. package/dist/providers/gemini.js.map +0 -1
  112. package/dist/providers/ollama.d.ts +0 -13
  113. package/dist/providers/ollama.js +0 -20
  114. package/dist/providers/ollama.js.map +0 -1
  115. package/dist/providers/openai.d.ts +0 -21
  116. package/dist/providers/openai.js +0 -9
  117. package/dist/providers/openrouter.d.ts +0 -16
  118. package/dist/providers/openrouter.js +0 -24
  119. package/dist/providers/openrouter.js.map +0 -1
  120. package/dist/providers/vertex.d.ts +0 -42
  121. package/dist/providers/vertex.js +0 -67
  122. package/dist/providers/vertex.js.map +0 -1
  123. package/dist/sandbox-9qeMTNrD.d.ts +0 -126
  124. package/dist/types-CD0rUKKT.d.ts +0 -109
  125. package/dist/uuid-RVN2T26F.js.map +0 -1
  126. package/dist/zod-7YXKWYMC.js.map +0 -1
  127. /package/dist/{chunk-DGUM43GV.js.map → client-JJFLE6RT.js.map} +0 -0
  128. /package/dist/{client-CRRO2376.js.map → history-snip-HAWNAYKY.js.map} +0 -0
  129. /package/dist/{history-snip-64GYP4ZL.js.map → lsp-3APWNKB2.js.map} +0 -0
  130. /package/dist/{lsp-PS3BWIHC.js.map → manager-Z5EQ7YYV.js.map} +0 -0
  131. /package/dist/{manager-DLXK63XC.js.map → mcp-auth-NOIQPF7W.js.map} +0 -0
  132. /package/dist/{mcp-auth-AEI2R4ZC.js.map → provider-factory-KNBSHXJ6.js.map} +0 -0
  133. /package/dist/{provider-factory-KI7OZUY3.js.map → render-4VEODRK7.js.map} +0 -0
  134. /package/dist/{providers/openai.js.map → resolve-AGQZFMKD.js.map} +0 -0
  135. /package/dist/{render-GRN4ZSSW.js.map → spinner-72JEISPK.js.map} +0 -0
  136. /package/dist/{resolve-GDSHNMG6.js.map → uuid-CVTNAPEB.js.map} +0 -0
  137. /package/dist/{spinner-OJNR6NFO.js.map → zod-VKURGPRT.js.map} +0 -0
@@ -1,10 +1,21 @@
1
- import { A as AIProvider, S as StreamEvent, b as ChatMessage, E as Entry, U as UUID, d as FileCheckpointSnapshot, f as ContentReplacementRecord$1, g as SessionInfo, M as ModelPricing, h as UsageRecord, i as CostSummary, j as ModelUsageSummary, k as ChatCompletionUsage, l as ThinkingConfig, m as MemoryConfig, O as OutputFormat, e as ContentPart, R as RunOptions, c as CheckpointConfig, n as ToolResult } from './types-LrU4LRmX.js';
2
- import { S as Sandbox } from './sandbox-9qeMTNrD.js';
3
- import { T as Tool, H as HookDefinition, S as SubagentConfig, i as SubagentRun, j as TaskStore, e as LspServerManager, F as FileCheckpointManager, k as FileStateCacheConfig, L as LspServerConfig } from './types-BA87bHPV.js';
4
- import { C as CacheControlConfig } from './cache-DsRqxx6v.js';
1
+ import { A as AIProvider, e as ChatMessage, T as ToolDefinition, S as StreamEvent, E as Entry, U as UUID, a as FileCheckpointSnapshot, f as ContentReplacementRecord$1, g as SessionInfo, M as ModelPricing, h as UsageRecord, i as CostSummary, j as ModelUsageSummary, k as ChatCompletionUsage, l as PermissionHandler, m as PermissionConfig, n as ThinkingConfig, o as MemoryConfig, O as OutputFormat, d as ContentPart, R as RunOptions, C as CheckpointConfig, p as ToolResult } from './types-DLZNyF5t.js';
2
+ import { S as Sandbox } from './sandbox-DAqQo0Tj.js';
3
+ import { T as Tool, j as DotDirConfig, H as HookDefinition, S as SubagentConfig, k as SubagentRun, l as TaskStore, e as LspServerManager, F as FileCheckpointManager, m as FileStateCacheConfig, i as DotDirResolver, L as LspServerConfig } from './types-BX4ALqoN.js';
5
4
  import { M as McpServerConfig, T as TokenStorage } from './types-2kTLUCnD.js';
6
- import { c as PermissionHandler, d as PermissionConfig } from './types-CD0rUKKT.js';
7
- import { a as VirtualFs, V as VirtualComputer } from './computer-BPdxSo6X.js';
5
+ import { V as VirtualFs, a as VirtualComputer } from './computer-DzMR92tK.js';
6
+
7
+ /**
8
+ * CLI-facing provider resolver.
9
+ *
10
+ * Builds an `AiSdkProvider` wrapping any Vercel AI SDK `LanguageModelV3`.
11
+ * Each vendor SDK is dynamically imported so CLI users only need to install
12
+ * the packages for the providers they actually use.
13
+ *
14
+ * Programmatic callers should prefer constructing `AiSdkProvider` directly
15
+ * with their own language model — that path supports metering proxies,
16
+ * bespoke auth, and any other knob the AI SDK exposes. This resolver exists
17
+ * so `noumen <provider>` still works out of the box.
18
+ */
8
19
 
9
20
  type ProviderName = "openai" | "anthropic" | "gemini" | "openrouter" | "bedrock" | "vertex" | "ollama";
10
21
  declare const DEFAULT_MODELS: Record<string, string>;
@@ -16,10 +27,11 @@ interface ResolveProviderOptions {
16
27
  }
17
28
  /**
18
29
  * Resolve a provider from a name string or pass through an AIProvider instance.
30
+ *
19
31
  * API key resolution order:
20
- * 1. Explicit apiKey option
21
- * 2. Provider-specific env var (OPENAI_API_KEY, etc.)
22
- * 3. NOUMEN_API_KEY generic env var
32
+ * 1. Explicit `apiKey` option
33
+ * 2. Provider-specific env var (`OPENAI_API_KEY`, etc.)
34
+ * 3. `NOUMEN_API_KEY` generic env var
23
35
  */
24
36
  declare function resolveProvider(input: AIProvider | ProviderName, opts?: ResolveProviderOptions): Promise<AIProvider>;
25
37
  /**
@@ -27,6 +39,86 @@ declare function resolveProvider(input: AIProvider | ProviderName, opts?: Resolv
27
39
  */
28
40
  declare function detectProvider(): Promise<ProviderName | undefined>;
29
41
 
42
+ /**
43
+ * AI-generated session title helper.
44
+ *
45
+ * Given a short prompt sourced from recent messages, ask a provider to
46
+ * produce a 3–7 word sentence-case title suitable for a session list.
47
+ *
48
+ * This is a pure helper: it never touches the filesystem and never knows
49
+ * about `SessionStorage`. Callers (e.g. `Agent.autoTitleIfMissing`) own
50
+ * persistence and event emission.
51
+ */
52
+
53
+ /**
54
+ * Config for the Agent's opt-in auto-title feature.
55
+ *
56
+ * Pass `true` for defaults (use the Agent's own provider + its
57
+ * `defaultModel`). Pass an object to customise the provider, model,
58
+ * system prompt, or input cap.
59
+ */
60
+ interface AutoTitleConfig {
61
+ /** Master switch. Default false on `AgentOptions.autoTitle`. */
62
+ enabled?: boolean;
63
+ /**
64
+ * Override provider used for title generation. Falls back to the
65
+ * Agent's main provider.
66
+ */
67
+ provider?: AIProvider;
68
+ /**
69
+ * Override model (e.g. `"claude-haiku-4-5"`). Falls back to the
70
+ * provider's `defaultModel`.
71
+ */
72
+ model?: string;
73
+ /** Override system prompt. */
74
+ systemPrompt?: string;
75
+ /** Cap on seed-text characters. Defaults to 2 000. */
76
+ maxInputChars?: number;
77
+ }
78
+ /** Default cap on characters fed to the title model. */
79
+ declare const DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS = 2000;
80
+ /**
81
+ * System prompt for the auto-title generator. Mirrors the shape used by
82
+ * Claude Code so that output quality is familiar.
83
+ */
84
+ declare const DEFAULT_AUTO_TITLE_SYSTEM_PROMPT = "Generate a concise, sentence-case title (3-7 words) that captures the main topic or goal of this coding session. The title should be clear enough that the user recognizes the session in a list. Use sentence case: capitalize only the first word and proper nouns.\n\nReturn JSON with a single \"title\" field.\n\nGood examples:\n{\"title\": \"Fix login button on mobile\"}\n{\"title\": \"Add OAuth authentication\"}\n{\"title\": \"Debug failing CI tests\"}\n{\"title\": \"Refactor API client error handling\"}\n\nBad (too vague): {\"title\": \"Code changes\"}\nBad (too long): {\"title\": \"Investigate and fix the issue where the login button does not respond on mobile devices\"}\nBad (wrong case): {\"title\": \"Fix Login Button On Mobile\"}";
85
+ interface GenerateAutoTitleOptions {
86
+ provider: AIProvider;
87
+ /** Model override. When omitted, uses `provider.defaultModel`. */
88
+ model?: string;
89
+ /** System prompt override. Falls back to the built-in prompt. */
90
+ systemPrompt?: string;
91
+ /** Character cap on the flattened input. Defaults to 2 000. */
92
+ maxInputChars?: number;
93
+ signal?: AbortSignal;
94
+ }
95
+ /**
96
+ * Flatten recent user + assistant text into a single block of plain text
97
+ * suitable for the title model. Tool results are skipped; image parts
98
+ * are skipped; only the tail of the concatenated text is kept when long
99
+ * so the most recent context wins.
100
+ */
101
+ declare function extractTitleSeedText(messages: ChatMessage[], maxChars?: number): string;
102
+ /**
103
+ * Attempt to pull a title out of a free-form model response.
104
+ *
105
+ * Strategy, cheapest-first:
106
+ * 1. Parse the whole string as JSON; return `.title` if present.
107
+ * 2. Slice out the first `{...}` block and `JSON.parse` that.
108
+ * 3. Fall back to the first bare quoted substring in the response.
109
+ *
110
+ * Going through `JSON.parse` (instead of a bespoke regex-unescape) means
111
+ * `\n`, `\\`, `\uXXXX`, and any other valid JSON string escapes round-trip
112
+ * correctly — the previous regex only handled `\"`.
113
+ */
114
+ declare function extractTitleFromResponse(raw: string): string | null;
115
+ declare function generateAutoTitle(messages: ChatMessage[], opts: GenerateAutoTitleOptions): Promise<string | null>;
116
+ /**
117
+ * Trim, collapse whitespace, strip wrapping quotes, clamp length.
118
+ * Returns null if the cleaned string would be empty.
119
+ */
120
+ declare function normalizeTitle(raw: string): string | null;
121
+
30
122
  interface SkillDefinition {
31
123
  name: string;
32
124
  /** Skill body content (after frontmatter is stripped) */
@@ -43,6 +135,41 @@ interface SkillDefinition {
43
135
  argumentHint?: string;
44
136
  }
45
137
 
138
+ /**
139
+ * Provider-agnostic prompt caching utilities.
140
+ *
141
+ * Stable tool ordering prevents cache invalidation when the tool set is
142
+ * unchanged. The breakpoint index helper determines which message gets a
143
+ * single cache_control marker per request (matching claude-code's strategy).
144
+ */
145
+
146
+ type CacheScope = "global" | "org";
147
+ interface CacheControlConfig {
148
+ enabled: boolean;
149
+ /** TTL for cached content. When set, produces `ttl: '1h'` in cache_control. */
150
+ ttl?: "1h";
151
+ /** Scope for shared cache across sessions/orgs. */
152
+ scope?: CacheScope;
153
+ }
154
+ /**
155
+ * Sort tool definitions deterministically for prompt cache stability.
156
+ *
157
+ * Strategy (matching claude-code's assembleToolPool): built-in tools form a
158
+ * contiguous prefix sorted by name, followed by MCP/external tools sorted by
159
+ * name. Tools with `mcpInfo` on the original Tool object are treated as MCP;
160
+ * everything else is built-in. Since ToolDefinition doesn't carry mcpInfo,
161
+ * callers can pass an optional set of MCP tool names to partition correctly.
162
+ */
163
+ declare function sortToolDefinitionsForCache(tools: ToolDefinition[], mcpToolNames?: ReadonlySet<string>): ToolDefinition[];
164
+ /**
165
+ * Determine which message index should receive the cache_control breakpoint.
166
+ *
167
+ * Exactly one message per request is marked. Normally the last message;
168
+ * for forked agents with skipCacheWrite the second-to-last so the fork
169
+ * doesn't write its own tail into the cache.
170
+ */
171
+ declare function getMessageCacheBreakpointIndex(messages: ChatMessage[], skipCacheWrite?: boolean): number;
172
+
46
173
  interface WebSearchResult {
47
174
  title: string;
48
175
  url: string;
@@ -219,13 +346,36 @@ declare class SessionStorage {
219
346
  appendContentReplacement(sessionId: string, replacements: ContentReplacementRecord$1[]): Promise<void>;
220
347
  appendMetadata(sessionId: string, key: string, value: unknown): Promise<void>;
221
348
  /**
222
- * Re-append custom-title and key metadata entries after a compact boundary
223
- * so they remain discoverable in the active-entries window.
349
+ * Append a user-set session title. Wins over any `ai-title` when read.
350
+ * Idempotent-ish: callers may append as many as they like; the last one
351
+ * wins according to file order.
352
+ */
353
+ appendCustomTitle(sessionId: string, title: string): Promise<void>;
354
+ /**
355
+ * Append an AI-generated session title. A `custom-title` (if present)
356
+ * always takes precedence on read.
357
+ */
358
+ appendAiTitle(sessionId: string, title: string): Promise<void>;
359
+ /**
360
+ * Re-append custom-title, ai-title, and key metadata entries after a
361
+ * compact boundary so they remain discoverable in the active-entries
362
+ * window. Written as a single batched append so a crash mid-write can't
363
+ * leave the transcript with only a subset of the re-emitted entries.
224
364
  */
225
365
  reAppendMetadataAfterCompact(sessionId: string): Promise<void>;
226
366
  loadMessages(sessionId: string): Promise<ChatMessage[]>;
227
367
  loadAllEntries(sessionId: string): Promise<Entry[]>;
228
368
  sessionExists(sessionId: string): Promise<boolean>;
369
+ /**
370
+ * Return the currently persisted titles for a session. `title` reflects
371
+ * the display preference (custom > ai). Returns all-undefined if the
372
+ * session file doesn't exist.
373
+ */
374
+ getSessionTitles(sessionId: string): Promise<{
375
+ title?: string;
376
+ customTitle?: string;
377
+ aiTitle?: string;
378
+ }>;
229
379
  deleteSession(sessionId: string): Promise<void>;
230
380
  listSessions(): Promise<SessionInfo[]>;
231
381
  }
@@ -390,8 +540,16 @@ interface ProjectContextConfig {
390
540
  excludes?: string[];
391
541
  /** Maximum include depth for @ references. Default: 5. */
392
542
  maxIncludeDepth?: number;
393
- /** Whether to load .claude/ files in addition to .noumen/ files. Default: true. */
394
- loadClaudeMd?: boolean;
543
+ /**
544
+ * Dot-directory names to scan for `<NAME>.md`, `<NAME>.local.md`, and
545
+ * `<dotDir>/rules/**`. Defaults to `{ names: [".noumen", ".claude"] }`.
546
+ *
547
+ * Markdown filenames derive from the dot-dir name: `.noumen` →
548
+ * `NOUMEN.md` / `NOUMEN.local.md`, `.claude` → `CLAUDE.md` /
549
+ * `CLAUDE.local.md`. The dir name (minus the leading dot, uppercased)
550
+ * is the filename stem.
551
+ */
552
+ dotDirs?: DotDirConfig;
395
553
  /** Enable loading user-scope context from homeDir. Default: true. */
396
554
  loadUserContext?: boolean;
397
555
  /** Enable loading project-scope context from cwd ancestors. Default: true. */
@@ -516,6 +674,8 @@ interface ThreadConfig {
516
674
  mcpToolNames?: ReadonlySet<string>;
517
675
  /** Loaded project context files (NOUMEN.md / CLAUDE.md) for system prompt injection. */
518
676
  projectContext?: ContextFile[];
677
+ /** Dot-directory resolver — threaded to tools that write under dotdirs (e.g. worktrees). */
678
+ dotDirResolver?: DotDirResolver;
519
679
  /** Default structured output format for all runs on this thread. */
520
680
  outputFormat?: OutputFormat;
521
681
  /** Default structured output mode for all runs on this thread. */
@@ -620,20 +780,15 @@ interface AgentOptions {
620
780
  * `createThread()`, or `init()`.
621
781
  */
622
782
  provider: AIProvider | ProviderName;
623
- /**
624
- * Working directory. When set without an explicit `sandbox`, an
625
- * `UnsandboxedLocal({ cwd })` is created automatically.
626
- */
783
+ /** Working directory. Used for path resolution inside the agent. */
627
784
  cwd?: string;
628
785
  /**
629
786
  * Bundled sandbox providing both filesystem and shell execution.
787
+ * Required — the root barrel deliberately doesn't pull in a default
788
+ * implementation, so callers must pick a backend explicitly:
630
789
  *
631
- * Local backends live on the root barrel:
632
- * - `LocalSandbox()` — OS-level sandboxing (requires `@anthropic-ai/sandbox-runtime`).
633
- * - `UnsandboxedLocal()` — raw host access.
634
- *
635
- * Remote backends are subpath imports so their optional peer deps do
636
- * not enter the module graph unless opted into:
790
+ * - `import { UnsandboxedLocal } from "noumen/unsandboxed"` — raw host access.
791
+ * - `import { LocalSandbox } from "noumen/local"` — OS-level sandboxing.
637
792
  * - `import { DockerSandbox } from "noumen/docker"`
638
793
  * - `import { E2BSandbox } from "noumen/e2b"`
639
794
  * - `import { FreestyleSandbox } from "noumen/freestyle"`
@@ -641,13 +796,13 @@ interface AgentOptions {
641
796
  * - `import { SpritesSandbox } from "noumen/sprites"`
642
797
  *
643
798
  * You can also pass any `{ fs: VirtualFs; computer: VirtualComputer }`
644
- * for custom sandboxes.
645
- *
646
- * Defaults to `UnsandboxedLocal({ cwd })` when omitted — the library
647
- * default is non-sandboxed for backward compatibility. The CLI defaults
648
- * to `LocalSandbox()` when sandbox-runtime is available.
799
+ * for custom sandboxes. Keeping this required ensures that importing
800
+ * the root barrel (`codingAgent`, `Agent`, …) never transitively pulls
801
+ * in `node:fs/promises` or `node:child_process` from the unsandboxed
802
+ * local adapter which would bloat bundlers' dependency traces (NFT
803
+ * etc.) in apps that only use a remote sandbox.
649
804
  */
650
- sandbox?: Sandbox;
805
+ sandbox: Sandbox;
651
806
  options?: {
652
807
  sessionDir?: string;
653
808
  skills?: SkillDefinition[];
@@ -700,10 +855,29 @@ interface AgentOptions {
700
855
  historySnip?: SnipConfig;
701
856
  /** Project context loading (NOUMEN.md / CLAUDE.md). Pass true for defaults or a config object. */
702
857
  projectContext?: ProjectContextConfig | boolean;
858
+ /**
859
+ * Dot-directory configuration — controls which hidden directories are
860
+ * recognized for config, sessions, tasks, checkpoints, rules, skills,
861
+ * MCP tokens, and worktrees. Defaults to `{ names: [".noumen", ".claude"] }`
862
+ * with `.noumen` as the canonical write target. Applies to both project
863
+ * scope (cwd ancestors) and user scope (home directory).
864
+ */
865
+ dotDirs?: DotDirConfig;
703
866
  /** Default structured output format for all threads. */
704
867
  outputFormat?: OutputFormat;
705
868
  /** Default structured output mode for all threads. */
706
869
  structuredOutputMode?: "alongside_tools" | "final_response";
870
+ /**
871
+ * Opt-in AI-generated session titles. When enabled, callers can invoke
872
+ * `agent.autoTitleIfMissing(sessionId)` (typically once per session,
873
+ * e.g. after the first assistant turn) to produce a short title and
874
+ * persist it as an `ai-title` JSONL entry. User-set `custom-title`
875
+ * entries (see `agent.setCustomTitle`) always take precedence on read.
876
+ *
877
+ * Pass `true` for defaults (same provider as the Agent, provider's
878
+ * default model, built-in prompt) or an object to customise.
879
+ */
880
+ autoTitle?: AutoTitleConfig | boolean;
707
881
  };
708
882
  }
709
883
  interface RunCallbacks {
@@ -770,6 +944,7 @@ declare class Agent {
770
944
  private toolSearchEnabled;
771
945
  private projectContextConfig?;
772
946
  private resolvedProjectContext;
947
+ private dotDirResolver;
773
948
  private checkpointManager;
774
949
  private promptCachingConfig;
775
950
  private fileStateCacheConfig;
@@ -777,6 +952,14 @@ declare class Agent {
777
952
  private historySnipConfig;
778
953
  private outputFormat;
779
954
  private structuredOutputMode;
955
+ private autoTitleConfig;
956
+ /**
957
+ * Keyed by `${sessionId}:${force ? "force" : "normal"}`. Parallel calls
958
+ * that pass the same `force` mode coalesce to one in-flight request; a
959
+ * `force: true` call arriving during a normal in-flight request runs its
960
+ * own pass so the caller's intent isn't silently dropped.
961
+ */
962
+ private autoTitleInFlight;
780
963
  private providerPromise;
781
964
  private initPromise;
782
965
  constructor(opts: AgentOptions);
@@ -787,6 +970,52 @@ declare class Agent {
787
970
  private createSpawnSubagent;
788
971
  createThread(opts?: ThreadOptions): Promise<Thread>;
789
972
  listSessions(): Promise<SessionInfo[]>;
973
+ /**
974
+ * Load the message history for a stored session, respecting compact
975
+ * boundaries and history snips. Returns `[]` when the session does
976
+ * not exist. Use this to rehydrate a UI — resuming a Thread for
977
+ * further execution should go through `resumeThread()` instead.
978
+ */
979
+ getMessages(sessionId: string): Promise<ChatMessage[]>;
980
+ /**
981
+ * Persist a user-set title for a session. Takes precedence over any
982
+ * AI-generated title on read. No-op on empty / whitespace-only input.
983
+ */
984
+ setCustomTitle(sessionId: string, title: string): Promise<void>;
985
+ /**
986
+ * Persist an AI-generated title for a session. A user-set title
987
+ * (see `setCustomTitle`) always wins on read, so writing this after a
988
+ * user has renamed the session is harmless.
989
+ */
990
+ setAiTitle(sessionId: string, title: string): Promise<void>;
991
+ /**
992
+ * Delete a session's persisted transcript. Does not affect any
993
+ * currently-running `Thread` reading from the same session id.
994
+ */
995
+ deleteSession(sessionId: string): Promise<void>;
996
+ /**
997
+ * Return the currently persisted titles for a session.
998
+ * `title` reflects the display preference (custom > ai).
999
+ */
1000
+ getSessionTitles(sessionId: string): Promise<{
1001
+ title?: string;
1002
+ customTitle?: string;
1003
+ aiTitle?: string;
1004
+ }>;
1005
+ /**
1006
+ * When `autoTitle` is enabled and the session has no title yet,
1007
+ * generate one via the configured provider + model and persist it
1008
+ * as an `ai-title` entry. Returns the new title on success, or `null`
1009
+ * when skipped (feature disabled, title already present, empty seed,
1010
+ * or provider error).
1011
+ *
1012
+ * Concurrency-safe: parallel calls for the same session coalesce to
1013
+ * a single in-flight request.
1014
+ */
1015
+ autoTitleIfMissing(sessionId: string, opts?: {
1016
+ signal?: AbortSignal;
1017
+ force?: boolean;
1018
+ }): Promise<string | null>;
790
1019
  getCostSummary(): CostSummary | null;
791
1020
  /**
792
1021
  * Create a thread that resumes an existing session. Automatically restores
@@ -831,7 +1060,6 @@ declare class Agent {
831
1060
  * @param timeoutMs Per-check timeout in milliseconds (default 10 000).
832
1061
  */
833
1062
  diagnose(timeoutMs?: number): Promise<DiagnoseResult>;
834
- private get sandboxIndexPath();
835
1063
  private loadSandboxId;
836
1064
  private storeSandboxId;
837
1065
  /**
@@ -840,4 +1068,4 @@ declare class Agent {
840
1068
  close(): Promise<void>;
841
1069
  }
842
1070
 
843
- export { createAutoCompactConfig as $, Agent as A, type BudgetState as B, type ContextFile as C, DEFAULT_MODELS as D, type RunCallbacks as E, type RunResult as F, SUPPORTED_PROVIDERS as G, type SnipConfig as H, type SnipResult as I, Thread as J, type ThreadOptions as K, type ToolResultBudgetConfig as L, type MicrocompactConfig as M, type ToolResultBudgetResult as N, type ContentReplacementRecord as O, type ProjectContextConfig as P, type ToolResultSpillResult as Q, type RetryConfig as R, type SkillDefinition as S, type ThreadConfig as T, type ToolResultStorageConfig as U, type TracingConfig as V, type WebSearchConfig as W, type WebSearchResult as X, applyPersistedReplacements as Y, applySnipRemovals as Z, canAutoCompact as _, SessionStorage as a, createAutoCompactTracking as a0, createBudgetState as a1, createContentReplacementState as a2, createWebSearchTool as a3, detectProvider as a4, enforceToolResultBudget as a5, enforceToolResultStorageBudget as a6, microcompactMessages as a7, persistToolResult as a8, projectSnippedView as a9, reconstructContentReplacementState as aa, recordAutoCompactFailure as ab, recordAutoCompactSuccess as ac, resolveProvider as ad, shouldAutoCompact as ae, snipMessagesByUuids as af, tryReactiveCompact as ag, webSearchToolPlaceholder as ah, type ContextScope as b, type RetryContext as c, type RetryEngineOptions as d, type Span as e, type SpanAttributeValue as f, SpanStatusCode as g, type Tracer as h, type SpanOptions as i, type StoredCostState as j, type AgentOptions as k, type AutoCompactConfig as l, type AutoCompactTrackingState as m, CLEARED_PLACEHOLDER as n, COMPACTABLE_TOOLS as o, type ContentReplacementState as p, CostTracker as q, DEFAULT_RETRY_CONFIG as r, type DiagnoseCheckResult as s, type DiagnoseResult as t, type MicrocompactResult as u, type ProviderName as v, type ReactiveCompactConfig as w, type ReactiveCompactResult as x, type ResolveProviderOptions as y, type RetryEvent as z };
1071
+ export { type TracingConfig as $, type AgentOptions as A, type BudgetState as B, type CacheControlConfig as C, DEFAULT_AUTO_TITLE_MAX_INPUT_CHARS as D, type ProviderName as E, type ReactiveCompactConfig as F, type GenerateAutoTitleOptions as G, type ReactiveCompactResult as H, type ResolveProviderOptions as I, type RetryEvent as J, type RunCallbacks as K, type RunResult as L, type MicrocompactConfig as M, SUPPORTED_PROVIDERS as N, type SnipConfig as O, type ProjectContextConfig as P, type SnipResult as Q, type RetryConfig as R, type SkillDefinition as S, type ThreadConfig as T, Thread as U, type ThreadOptions as V, type ToolResultBudgetConfig as W, type ToolResultBudgetResult as X, type ContentReplacementRecord as Y, type ToolResultSpillResult as Z, type ToolResultStorageConfig as _, Agent as a, type WebSearchConfig as a0, type WebSearchResult as a1, applyPersistedReplacements as a2, applySnipRemovals as a3, canAutoCompact as a4, createAutoCompactConfig as a5, createAutoCompactTracking as a6, createBudgetState as a7, createContentReplacementState as a8, createWebSearchTool as a9, detectProvider as aa, enforceToolResultBudget as ab, enforceToolResultStorageBudget as ac, extractTitleFromResponse as ad, extractTitleSeedText as ae, generateAutoTitle as af, getMessageCacheBreakpointIndex as ag, microcompactMessages as ah, normalizeTitle as ai, persistToolResult as aj, projectSnippedView as ak, reconstructContentReplacementState as al, recordAutoCompactFailure as am, recordAutoCompactSuccess as an, resolveProvider as ao, shouldAutoCompact as ap, snipMessagesByUuids as aq, sortToolDefinitionsForCache as ar, tryReactiveCompact as as, webSearchToolPlaceholder as at, type AutoTitleConfig as b, SessionStorage as c, type ContextFile as d, type ContextScope as e, type RetryContext as f, type RetryEngineOptions as g, type Span as h, type SpanAttributeValue as i, SpanStatusCode as j, type Tracer as k, type SpanOptions as l, type StoredCostState as m, type AutoCompactConfig as n, type AutoCompactTrackingState as o, CLEARED_PLACEHOLDER as p, COMPACTABLE_TOOLS as q, type CacheScope as r, type ContentReplacementState as s, CostTracker as t, DEFAULT_AUTO_TITLE_SYSTEM_PROMPT as u, DEFAULT_MODELS as v, DEFAULT_RETRY_CONFIG as w, type DiagnoseCheckResult as x, type DiagnoseResult as y, type MicrocompactResult as z };