negotium 0.2.3 → 0.2.5

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 (99) hide show
  1. package/dist/agent-helpers.js +3366 -3048
  2. package/dist/agent-helpers.js.map +49 -48
  3. package/dist/background-bash.js +1 -3
  4. package/dist/background-bash.js.map +4 -4
  5. package/dist/browser-runtime.js +137 -23
  6. package/dist/browser-runtime.js.map +11 -10
  7. package/dist/chunk-qmbcbhyy.js +2407 -0
  8. package/dist/chunk-qmbcbhyy.js.map +35 -0
  9. package/dist/hosted-agent.js +56 -39
  10. package/dist/hosted-agent.js.map +13 -13
  11. package/dist/main.js +3276 -2808
  12. package/dist/main.js.map +54 -51
  13. package/dist/mcp-factories.js +6471 -6148
  14. package/dist/mcp-factories.js.map +49 -48
  15. package/dist/prompts.js +1 -3
  16. package/dist/prompts.js.map +4 -4
  17. package/dist/query-runtime.js +22 -4
  18. package/dist/query-runtime.js.map +6 -6
  19. package/dist/registry.js +169 -213
  20. package/dist/registry.js.map +8 -9
  21. package/dist/rollout.js +1 -1
  22. package/dist/runtime/src/agents/api-topic-agent-switch.ts +6 -12
  23. package/dist/runtime/src/agents/claude-provider.ts +2 -2
  24. package/dist/runtime/src/agents/codex-app-server.ts +136 -0
  25. package/dist/runtime/src/agents/codex-native-multi-agent.ts +1 -1
  26. package/dist/runtime/src/agents/codex-provider.ts +22 -11
  27. package/dist/runtime/src/agents/codex-registry.ts +9 -17
  28. package/dist/runtime/src/agents/contracts.ts +2 -0
  29. package/dist/runtime/src/agents/execution-host.ts +6 -0
  30. package/dist/runtime/src/agents/fork.ts +24 -18
  31. package/dist/runtime/src/agents/idle-archiver.ts +7 -2
  32. package/dist/runtime/src/agents/index.ts +21 -15
  33. package/dist/runtime/src/agents/maestro-provider.ts +1 -1
  34. package/dist/runtime/src/agents/maestro-registry.ts +26 -7
  35. package/dist/runtime/src/agents/memory-archive-policy.ts +20 -0
  36. package/dist/runtime/src/agents/rollout/codex.ts +31 -23
  37. package/dist/runtime/src/agents/self-config-core.ts +2 -4
  38. package/dist/runtime/src/agents/topic-agent-switch.ts +4 -10
  39. package/dist/runtime/src/application/submit-runtime-gateway-turn.ts +77 -19
  40. package/dist/runtime/src/application/switch-topic-model.ts +7 -10
  41. package/dist/runtime/src/index.ts +4 -0
  42. package/dist/runtime/src/mcp/factories/session-comm.ts +12 -0
  43. package/dist/runtime/src/mcp/session-comm/default-host.ts +16 -0
  44. package/dist/runtime/src/mcp/session-comm/server.ts +25 -0
  45. package/dist/runtime/src/mcp/wiki-server.ts +19 -12
  46. package/dist/runtime/src/platform/config.ts +4 -3
  47. package/dist/runtime/src/platform/log-rotation.ts +45 -0
  48. package/dist/runtime/src/platform/mcp-config.ts +9 -3
  49. package/dist/runtime/src/platform/playwright/manager.ts +57 -1
  50. package/dist/runtime/src/platform/playwright/profile-management.ts +33 -0
  51. package/dist/runtime/src/platform/playwright/public-runtime.ts +5 -0
  52. package/dist/runtime/src/platform/playwright/vault-broker.ts +9 -10
  53. package/dist/runtime/src/query/active-rooms.ts +7 -1
  54. package/dist/runtime/src/runtime/errors.ts +1 -0
  55. package/dist/runtime/src/runtime/turn-event-stream.ts +46 -1
  56. package/dist/runtime/src/runtime/turn-runner.ts +176 -100
  57. package/dist/runtime/src/runtime/user-turn-envelope.ts +19 -0
  58. package/dist/runtime/src/storage/browser-profiles.ts +35 -10
  59. package/dist/runtime/src/storage/runtime-gateway-submissions.ts +12 -3
  60. package/dist/runtime/src/storage/runtime-turn-requests.ts +68 -7
  61. package/dist/runtime/src/storage/storage-host.ts +31 -5
  62. package/dist/runtime/src/storage/vault.ts +30 -2
  63. package/dist/runtime/src/topics/derive.ts +38 -2
  64. package/dist/runtime/src/topics/lifecycle.ts +12 -2
  65. package/dist/runtime/src/types.ts +2 -0
  66. package/dist/runtime/src/version.ts +1 -1
  67. package/dist/runtime-helpers.js +22 -4
  68. package/dist/runtime-helpers.js.map +5 -5
  69. package/dist/storage.js +22 -2
  70. package/dist/storage.js.map +5 -5
  71. package/dist/types/packages/core/src/agents/api-topic-agent-switch.d.ts +1 -1
  72. package/dist/types/packages/core/src/agents/codex-app-server.d.ts +13 -0
  73. package/dist/types/packages/core/src/agents/codex-native-multi-agent.d.ts +1 -0
  74. package/dist/types/packages/core/src/agents/contracts.d.ts +2 -0
  75. package/dist/types/packages/core/src/agents/execution-host.d.ts +2 -0
  76. package/dist/types/packages/core/src/agents/fork.d.ts +8 -7
  77. package/dist/types/packages/core/src/agents/memory-archive-policy.d.ts +10 -0
  78. package/dist/types/packages/core/src/agents/rollout/codex.d.ts +4 -2
  79. package/dist/types/packages/core/src/agents/self-config-core.d.ts +1 -1
  80. package/dist/types/packages/core/src/mcp/factories/session-comm.d.ts +1 -0
  81. package/dist/types/packages/core/src/platform/config.d.ts +0 -1
  82. package/dist/types/packages/core/src/platform/mcp-config.d.ts +3 -0
  83. package/dist/types/packages/core/src/platform/playwright/manager.d.ts +15 -0
  84. package/dist/types/packages/core/src/platform/playwright/profile-management.d.ts +8 -0
  85. package/dist/types/packages/core/src/platform/playwright/public-runtime.d.ts +2 -1
  86. package/dist/types/packages/core/src/query/active-rooms.d.ts +7 -1
  87. package/dist/types/packages/core/src/runtime/turn-runner.d.ts +42 -1
  88. package/dist/types/packages/core/src/runtime/user-turn-envelope.d.ts +7 -0
  89. package/dist/types/packages/core/src/storage/browser-profiles.d.ts +3 -1
  90. package/dist/types/packages/core/src/storage/runtime-turn-requests.d.ts +17 -0
  91. package/dist/types/packages/core/src/storage/storage-host.d.ts +1 -0
  92. package/dist/types/packages/core/src/storage/vault.d.ts +8 -0
  93. package/dist/types/packages/core/src/types.d.ts +2 -0
  94. package/dist/types/packages/core/src/version.d.ts +1 -1
  95. package/dist/vault.js +19 -5
  96. package/dist/vault.js.map +5 -5
  97. package/package.json +2 -2
  98. package/dist/chunk-hsqgb2hw.js +0 -1223
  99. package/dist/chunk-hsqgb2hw.js.map +0 -19
@@ -3,7 +3,7 @@ import type { AgentKind, EffortLevel } from "../types";
3
3
  export type ApiTopicSwitchOutcome = {
4
4
  kind: "fresh";
5
5
  agent: AgentKind;
6
- reason: "no-history" | "bridge-failed";
6
+ reason: "no-history";
7
7
  } | {
8
8
  kind: "bridged";
9
9
  agent: AgentKind;
@@ -0,0 +1,13 @@
1
+ import { type ChildProcessWithoutNullStreams } from "node:child_process";
2
+ interface CodexAppServerForkResult {
3
+ forkId: string;
4
+ rolloutPath: string;
5
+ }
6
+ interface CodexAppServerForkHost {
7
+ spawnServer(): ChildProcessWithoutNullStreams;
8
+ findRolloutPath(threadId: string): string | undefined;
9
+ timeoutMs: number;
10
+ }
11
+ export declare function createCodexAppServerForker(host: CodexAppServerForkHost): (parentThreadId: string) => Promise<CodexAppServerForkResult>;
12
+ export declare function forkCodexSession(parentThreadId: string): Promise<CodexAppServerForkResult>;
13
+ export {};
@@ -1,4 +1,5 @@
1
1
  export declare const BUNDLED_CODEX_VERSION: string;
2
+ export declare function codexCliScriptPath(): string;
2
3
  export declare function bundledCodexModelCachePath(authFilePath: string): string;
3
4
  export declare function ensureCodexModelCache(authFilePath: string, bootstrap?: (codexHome: string, cachePath: string) => Promise<void>): Promise<string>;
4
5
  /**
@@ -39,6 +39,8 @@ export interface ForkRegistryOptions {
39
39
  export interface ForkRegistryResult {
40
40
  forkId: string;
41
41
  rolloutPath: string;
42
+ /** Additional provider-owned files created for the fork. */
43
+ cleanupPaths?: string[];
42
44
  }
43
45
  export interface CleanupRolloutsOptions {
44
46
  cwd: string;
@@ -31,3 +31,5 @@ export declare function shouldRedirectHostedVaultTool(userId: string, toolName:
31
31
  export declare function transformHostedQueryOptions(opts: AgentQueryOptions): AgentQueryOptions;
32
32
  export declare function hostedClaudeCodeExecutablePath(): string | undefined;
33
33
  export declare function hostedCodexAuthFilePath(): string;
34
+ /** The one Codex state root used by auth, rollouts, native forks, and SDK resume. */
35
+ export declare function hostedCodexHomePath(): string;
@@ -1,11 +1,13 @@
1
+ import type { ForkRegistryResult } from "./contracts";
1
2
  import type { AgentKind, EffortLevel } from "../types";
2
3
  /**
3
4
  * Agent-aware fork primitives.
4
5
  *
5
6
  * Strategy lives in each agent's registry (`*-registry.ts:forkSession`).
6
- * Claude uses the SDK's native `forkSession` (byte-equivalent rollout copy);
7
- * Codex synthesizes a rollout from the provider-agnostic conversation log
8
- * because the SDK has no fork API. Both surfaces converge on `ForkHandle`.
7
+ * Claude uses the SDK's native `forkSession`, Codex uses App Server's native
8
+ * `thread/fork`, and Maestro uses the SDK's `forkSessionAt`. Providers without
9
+ * a native branch primitive synthesize from the provider-agnostic conversation
10
+ * log. All surfaces converge on ForkHandle.
9
11
  */
10
12
  export interface ForkAgentSessionOptions {
11
13
  agent: AgentKind;
@@ -29,12 +31,11 @@ export interface ForkHandle {
29
31
  forkId: string;
30
32
  /** Absolute path of the rollout file to remove on cleanup. */
31
33
  rolloutPath: string;
34
+ /** Additional provider-owned files removed with the primary rollout. */
35
+ cleanupPaths?: string[];
32
36
  }
33
37
  export interface AgentForkHost {
34
- forkSession(agent: AgentKind, options: Omit<ForkAgentSessionOptions, "agent">): Promise<{
35
- forkId: string;
36
- rolloutPath: string;
37
- }>;
38
+ forkSession(agent: AgentKind, options: Omit<ForkAgentSessionOptions, "agent">): Promise<ForkRegistryResult>;
38
39
  exists(path: string): boolean;
39
40
  unlink(path: string): void;
40
41
  warn(details: Record<string, unknown>, message: string): void;
@@ -10,5 +10,15 @@ export interface MemoryArchiveMessage {
10
10
  * mirrors Clawgram's lifecycle-level MIN_EXCHANGE_COUNT policy.
11
11
  */
12
12
  export declare const MIN_MEMORY_ARCHIVE_EXCHANGES = 6;
13
+ export interface MemoryArchiveTopicContext {
14
+ isSubagent?: boolean;
15
+ memoryTopicId?: string;
16
+ }
17
+ /**
18
+ * Explicit-memory subagents are usually short, focused turns. Persist one
19
+ * completed exchange back to their selected memory topic, while retaining the
20
+ * normal threshold for regular topics and incomplete/failed turns.
21
+ */
22
+ export declare function meetsMemoryArchiveExchangeThreshold(exchangeCount: number, minExchanges: number, topic: MemoryArchiveTopicContext): boolean;
13
23
  /** Count completed conversational exchanges while ignoring system/tool/card noise. */
14
24
  export declare function countMemoryArchiveExchanges(rows: readonly MemoryArchiveMessage[]): number;
@@ -10,8 +10,9 @@
10
10
  * synthesized `response_item`/`event_msg` pairs per turn.
11
11
  *
12
12
  * Tool history is folded into assistant text as `[Tool: ...]` annotations
13
- * (see shared.ts:extractChatPairs) — the SDK has no fork API and synthetic
14
- * tool_use IDs across SDKs are too fragile to reconstruct structurally.
13
+ * (see shared.ts:extractChatPairs). Native same-agent forks use App Server's
14
+ * `thread/fork`; this encoder remains the fallback and cross-agent bridge,
15
+ * where synthetic tool_use IDs are too fragile to reconstruct structurally.
15
16
  */
16
17
  import { type ChatPair } from "./shared";
17
18
  import type { ConversationEntry } from "../../storage/conversations";
@@ -71,6 +72,7 @@ export declare function readLatestCodexContextUsage(threadId: string): CodexCont
71
72
  * the same thread can resume without losing provider conversation history.
72
73
  */
73
74
  export declare function migrateCodexRolloutNativeMultiAgentMetadata(threadId: string): boolean;
75
+ export declare function latestCodexRolloutPath(threadId: string): string | undefined;
74
76
  /**
75
77
  * Materialize a Codex rollout JSONL with the provided dialogue and place it
76
78
  * at `~/.codex/sessions/<yyyy>/<mm>/<dd>/rollout-<ts>-<threadId>.jsonl` so a
@@ -67,7 +67,7 @@ export type SelfConfigAgentSwitchResult = {
67
67
  outcome: {
68
68
  kind: "fresh";
69
69
  agent: AgentKind;
70
- reason: "no-history" | "bridge-failed";
70
+ reason: "no-history";
71
71
  } | {
72
72
  kind: "bridged";
73
73
  agent: AgentKind;
@@ -9,6 +9,7 @@ export interface SessionCommMcpHost {
9
9
  getMcpConfig(context: SessionCommContext): MaybePromise<SessionCommMcpResult>;
10
10
  getBrowserProfile?(context: SessionCommContext): MaybePromise<SessionCommMcpResult>;
11
11
  setBrowserProfile?(context: SessionCommContext, profile: string): MaybePromise<SessionCommMcpResult>;
12
+ deleteBrowserProfile?(context: SessionCommContext, profile: string): MaybePromise<SessionCommMcpResult>;
12
13
  peekSession(context: SessionCommContext): MaybePromise<SessionCommMcpResult>;
13
14
  setDescription(context: SessionCommContext, description: string): MaybePromise<SessionCommMcpResult>;
14
15
  askSession(context: SessionCommContext, input: {
@@ -10,7 +10,6 @@ export declare const BROWSER_DIR: string;
10
10
  export declare const BROWSER_PROFILES_DIR: string;
11
11
  export declare const BINARIES_DIR: string;
12
12
  export declare const SECRETS_DIR: string;
13
- export declare const CONTEXTS_DIR: string;
14
13
  export declare const DM_WORKSPACE_DIR: string;
15
14
  export declare const SESSION_WORKSPACE_DIR: string;
16
15
  export declare const CLAUDE_EXECUTABLE: string | undefined;
@@ -64,6 +64,8 @@ export declare function consumePlaywrightUnavailable(userId: string, topic: stri
64
64
  */
65
65
  export interface RuntimeMcpBuildContext {
66
66
  userId: string;
67
+ /** Vault namespace when credentials belong to a different principal. */
68
+ vaultUserId?: string;
67
69
  /** "dm" for DM scope, topic/session name for forum/fork. */
68
70
  session: string;
69
71
  /** REST/WS topic id when known. Prefer for authorization/scope checks. */
@@ -183,6 +185,7 @@ export declare function getManagerMcpServers(opts: {
183
185
  */
184
186
  export declare function getForumMcpServers(opts: {
185
187
  userId: string;
188
+ vaultUserId?: string;
186
189
  session: string;
187
190
  topicId?: string;
188
191
  subagentParentTopicId?: string;
@@ -26,6 +26,8 @@ export interface PlaywrightManagerHost {
26
26
  readonly createChildEnvironment: (context: PlaywrightChildEnvironmentContext) => NodeJS.ProcessEnv;
27
27
  /** Reap an orphan that owns this exact host-managed data directory. */
28
28
  readonly cleanupBrowserProcessesForDataDir: (userDataDir: string) => void;
29
+ /** Remove an exact host-managed profile directory, rejecting paths outside the host's root. */
30
+ readonly removeProfileDataDir?: (userDataDir: string) => boolean;
29
31
  /** Reap host-managed browsers that are not represented by the supplied live directories. */
30
32
  readonly reapOrphanBrowsers: (liveUserDataDirs: Iterable<string>) => void;
31
33
  }
@@ -59,6 +61,19 @@ export declare function stopPlaywrightInstance(instanceKey: string): Promise<boo
59
61
  export declare function withPlaywrightProfileMaintenance<T>(ownerId: string, rawProfile: string, operation: (binding: PlaywrightProfileBinding, control: PlaywrightMaintenanceControl) => Promise<T>): Promise<T>;
60
62
  /** Stop a named profile before deleting or replacing its host-managed data directory. */
61
63
  export declare function stopPlaywrightProfile(ownerId: string, rawProfile: string): Promise<boolean>;
64
+ export interface RemovePlaywrightProfileDataResult {
65
+ dataDir: string;
66
+ processStopped: boolean;
67
+ dataRemoved: boolean;
68
+ }
69
+ export interface RemovePlaywrightProfileDataOptions {
70
+ /** Revalidate external ownership immediately before the synchronous removal. */
71
+ beforeRemove?: () => void;
72
+ /** Commit external metadata before releasing the profile lifecycle barrier. */
73
+ afterRemove?: () => void;
74
+ }
75
+ /** Stop all exact-profile processes and remove its data through the configured host boundary. */
76
+ export declare function removePlaywrightProfileData(ownerId: string, rawProfile: string, options?: RemovePlaywrightProfileDataOptions): Promise<RemovePlaywrightProfileDataResult>;
62
77
  export declare function pinPlaywrightInstance(instanceKey: string): void;
63
78
  export declare function unpinPlaywrightInstance(instanceKey: string): void;
64
79
  export declare function getPlaywrightCapability(instanceKey: string): string | undefined;
@@ -0,0 +1,8 @@
1
+ export interface DeleteManagedBrowserProfileResult {
2
+ profile: string;
3
+ metadataRemoved: boolean;
4
+ dataRemoved: boolean;
5
+ processStopped: boolean;
6
+ }
7
+ /** Delete an unused named profile while serialized against browser startup. */
8
+ export declare function deleteManagedBrowserProfile(ownerId: string, rawProfile: string): Promise<DeleteManagedBrowserProfileResult>;
@@ -1,4 +1,5 @@
1
1
  export { isBrowserJanitorOwner, selectOrphanBrowserPids, } from "./browser-processes";
2
- export { closeBrowserOwnerTabs, configurePlaywrightManagerHost, ensureBrowserProfile, ensurePlaywright, getPlaywrightCapability, getPlaywrightManagerHost, killAllPlaywright, makeBrowserProfileInstanceKey, makeInstanceKey, onPlaywrightFailure, type PlaywrightChildEnvironmentContext, type PlaywrightFailure, type PlaywrightMaintenanceControl, type PlaywrightManagerHost, type PlaywrightProfileBinding, pinPlaywrightInstance, reapPlaywrightOrphans, resetPlaywrightManagerHost, resolvePlaywrightCapabilityOwner, resolvePlaywrightProfileBinding, resolvePlaywrightTopicBinding, resolveTopicProfileDir, stopPlaywrightInstance, stopPlaywrightProfile, unpinPlaywrightInstance, withPlaywrightInstanceMaintenance, withPlaywrightProfileMaintenance, } from "./manager";
2
+ export { closeBrowserOwnerTabs, configurePlaywrightManagerHost, ensureBrowserProfile, ensurePlaywright, getPlaywrightCapability, getPlaywrightManagerHost, killAllPlaywright, makeBrowserProfileInstanceKey, makeInstanceKey, onPlaywrightFailure, type PlaywrightChildEnvironmentContext, type PlaywrightFailure, type PlaywrightMaintenanceControl, type PlaywrightManagerHost, type PlaywrightProfileBinding, pinPlaywrightInstance, reapPlaywrightOrphans, removePlaywrightProfileData, resetPlaywrightManagerHost, resolvePlaywrightCapabilityOwner, resolvePlaywrightProfileBinding, resolvePlaywrightTopicBinding, resolveTopicProfileDir, stopPlaywrightInstance, stopPlaywrightProfile, unpinPlaywrightInstance, withPlaywrightInstanceMaintenance, withPlaywrightProfileMaintenance, } from "./manager";
3
3
  export { browserProcessMatchesExpectedProfile, extractUserDataDirArg, selectIdleEvictionKey, selectReusablePort, waitForChildProcessExit, waitForChildProcessSpawnError, } from "./manager-utils";
4
+ export { type DeleteManagedBrowserProfileResult, deleteManagedBrowserProfile, } from "./profile-management";
4
5
  export { probeMcpTransport, probePlaywrightMcpTransports, } from "./transport-probe";
@@ -28,6 +28,8 @@ export interface DeferredInject {
28
28
  /** Topic execution epoch captured when this work was accepted. */
29
29
  runtimeEpoch?: number;
30
30
  userId: string;
31
+ /** Credential namespace when the executor and Vault owner differ. */
32
+ vaultUserId?: string;
31
33
  prompt: string;
32
34
  /** Inject source — the topic name/id this inject came from (never "user"). */
33
35
  origin: string;
@@ -105,8 +107,12 @@ export interface RoomQueryControl {
105
107
  durableRequestIds?: string[];
106
108
  /** Attachment ids currently being processed. User-turn preemption carries them forward. */
107
109
  attachments?: string[];
108
- /** Provider session id this turn resumed from. Superseding user turns restart from this base. */
110
+ /** Latest provider session id observed for this turn. */
109
111
  sessionId?: string | null;
112
+ /** True once the provider has published the native session backing this turn. */
113
+ providerSessionObserved?: boolean;
114
+ /** True once provider output proves that this turn's prompt reached the native session. */
115
+ providerTurnContentObserved?: boolean;
110
116
  abortController: AbortController;
111
117
  abortReason: AbortReason;
112
118
  /** Specific failure surfaced when infrastructure aborts the turn. */
@@ -12,7 +12,7 @@ export * from "./channel-context";
12
12
  export * from "./errors";
13
13
  export * from "./tasks";
14
14
  export * from "./turn-session";
15
- export { renderUserPromptBatch } from "./user-turn-envelope";
15
+ export { renderUserPromptBatch, renderUserTurnBatch } from "./user-turn-envelope";
16
16
  export * from "./visuals";
17
17
  /** Browser and background shell tools are part of every ordinary topic. */
18
18
  export declare function withDefaultPlaywright(configuredMcp: string[], isManager: boolean): string[];
@@ -48,6 +48,45 @@ export declare function deliverAskCallbackToCaller(pending: AskPendingFileRef &
48
48
  callerTopicId: string;
49
49
  callerUserId: string;
50
50
  }, sourceLabel: string, body: string, kind: "reply" | "error"): Promise<boolean>;
51
+ export type TopicRolloutReconstruction = {
52
+ kind: "rebuilt";
53
+ sessionId: string;
54
+ } | {
55
+ kind: "no-history";
56
+ } | {
57
+ kind: "failed";
58
+ error: string;
59
+ };
60
+ export declare function tryReconstructTopicRollout(opts: {
61
+ topicId: string;
62
+ topicTitle: string;
63
+ userId: string;
64
+ agent: AgentKind;
65
+ sessionId: string | null | undefined;
66
+ cwd: string;
67
+ model: string;
68
+ effort?: EffortLevel;
69
+ }): TopicRolloutReconstruction;
70
+ export type SessionRetryResolution = {
71
+ kind: "retry";
72
+ sessionId: string | null;
73
+ } | {
74
+ kind: "failed";
75
+ error: string;
76
+ };
77
+ export declare function resolveSessionRetry(opts: {
78
+ topicId: string;
79
+ topicTitle: string;
80
+ userId: string;
81
+ agent: AgentKind;
82
+ sessionId: string | null | undefined;
83
+ cwd: string;
84
+ silent: boolean;
85
+ model: string;
86
+ effort?: EffortLevel;
87
+ externalSessionOwner?: boolean;
88
+ onSessionReset?: () => void;
89
+ }): SessionRetryResolution;
51
90
  export interface AiTurnSettlement {
52
91
  queryId: string;
53
92
  kind: "completed" | "aborted" | "error";
@@ -106,6 +145,8 @@ export interface AiTurnExecutionOptions {
106
145
  export interface StartAiTurnParams extends AiTurnExecutionOptions {
107
146
  topic: AiTurnTopic;
108
147
  userId: string;
148
+ /** Credential namespace. Defaults to userId for backwards compatibility. */
149
+ vaultUserId?: string;
109
150
  prompt: string;
110
151
  allowAutoContinue: boolean;
111
152
  agentOverride?: AgentKind;
@@ -2,7 +2,14 @@
2
2
  export interface UserTurnEnvelope {
3
3
  prompt: string;
4
4
  attachments?: string[];
5
+ /** Authenticated human author. Execution may still run as the local principal. */
6
+ actorUserId?: string;
7
+ /** Display-only author label captured by the trusted ingress. */
8
+ actorLabel?: string;
5
9
  }
6
10
  export declare function legacyUserTurnEnvelope(prompt: string, attachments?: string[]): UserTurnEnvelope;
7
11
  export declare function flattenUserTurnAttachments(messages: readonly UserTurnEnvelope[]): string[] | undefined;
8
12
  export declare function renderUserPromptBatch(prompts: readonly string[]): string;
13
+ export declare function renderUserTurnPrompt(message: UserTurnEnvelope): string;
14
+ /** Render ordered user submissions while retaining their structured authorship. */
15
+ export declare function renderUserTurnBatch(messages: readonly UserTurnEnvelope[]): string;
@@ -6,6 +6,7 @@ export interface BrowserProfileRecord {
6
6
  id: string;
7
7
  title: string;
8
8
  }>;
9
+ deletable: boolean;
9
10
  }
10
11
  export declare function normalizeBrowserProfileName(name: string): string;
11
12
  export declare function getBrowserProfileOwner(topicId: string, fallbackUserId: string): string;
@@ -22,4 +23,5 @@ export declare function assignTopicBrowserProfile(opts: {
22
23
  profile: string;
23
24
  };
24
25
  export declare function listBrowserProfiles(ownerId: string): BrowserProfileRecord[];
25
- export declare function deleteBrowserProfile(ownerId: string, rawName: string): void;
26
+ export declare function assertBrowserProfileDeletable(ownerId: string, rawName: string): string;
27
+ export declare function deleteBrowserProfile(ownerId: string, rawName: string): boolean;
@@ -19,10 +19,14 @@ export interface RuntimeUserTurnExecution {
19
19
  bridgeSessionFromHistory?: boolean;
20
20
  peerBridge?: PeerRuntimeBridgeContext;
21
21
  from?: string;
22
+ /** Vault namespace for this turn, independent from the local execution principal. */
23
+ vaultUserId?: string;
22
24
  /** Newly accepted user texts not yet recorded in the unified conversation log. */
23
25
  conversationPrompts?: string[];
24
26
  /** Number of leading userMessages already present in the unified conversation log. */
25
27
  loggedUserMessageCount?: number;
28
+ /** Native session whose provider output proves it accepted this request's user turn. */
29
+ providerSessionId?: string;
26
30
  /** Request ids whose ordered messages were folded into this replacement. */
27
31
  supersededRequestIds?: string[];
28
32
  }
@@ -71,10 +75,23 @@ export declare function mergeRuntimeUserTurnRequest(input: {
71
75
  execution: RuntimeUserTurnExecution;
72
76
  topicEpoch: number;
73
77
  alreadyIncludedRequestIds?: string[];
78
+ /** Requests already committed to the provider's native session; keep their lineage, not prompts. */
79
+ omitRequestIds?: string[];
74
80
  }): {
75
81
  requestId: string;
76
82
  supersededRequestIds: string[];
77
83
  };
84
+ /**
85
+ * Record that provider output proves the native session contains this durable
86
+ * turn. A session-id event alone is insufficient: some providers publish it
87
+ * before appending the user prompt. This marker lets a different runtime
88
+ * process omit only a demonstrably committed prompt when it merges a steering
89
+ * message after preemption.
90
+ *
91
+ * Match only the exact request id. A late session event from a superseded turn
92
+ * must not mark its replacement (whose prompts have not reached the provider).
93
+ */
94
+ export declare function markRuntimeUserTurnProviderSessionObserved(topicId: string, requestId: string, sessionId: string): boolean;
78
95
  export declare function markRuntimeUserTurnMessagesLogged(topicId: string, requestId: string, ownerId: string, loggedUserMessages: readonly UserTurnEnvelope[]): boolean;
79
96
  export declare function claimNextRuntimeUserTurnRequest(ownerId: string, now?: number): RuntimeUserTurnRequest | null;
80
97
  export declare function markRuntimeUserTurnRunning(topicId: string, requestId: string, ownerId: string, queryId: string): boolean;
@@ -3,6 +3,7 @@ import type { StorageDatabase, StorageHostConfig } from "./storage-contract";
3
3
  export type { StorageDatabase, StorageDatabaseAdapter, StorageDatabaseInput, StorageHostConfig, StorageHostOptions, StorageStatement, StorageTransaction, } from "./storage-contract";
4
4
  type InternalStorageDatabase = InstanceType<typeof Database>;
5
5
  type StorageSchemaInitializer = (database: InternalStorageDatabase) => void;
6
+ export declare function initializeDatabase(database: InternalStorageDatabase): void;
6
7
  export declare function resolveStorageDatabase(): InternalStorageDatabase;
7
8
  export declare function resolveStorageDataDir(): string;
8
9
  export declare function resolveStorageLogDir(): string;
@@ -21,6 +21,14 @@ export declare const VAULT_DESCRIPTION_MAX_LENGTH = 500;
21
21
  export declare function normalizeVaultKey(key: string): string;
22
22
  export declare function validateVaultKey(key: string): boolean;
23
23
  export declare function vaultListWithValues(userId: string): VaultEntryWithValue[];
24
+ /**
25
+ * Return only rows that can still be authenticated with the active master key.
26
+ *
27
+ * This is intentionally limited to redaction indexes: one damaged credential
28
+ * must not disable unrelated tools, while direct access to that credential
29
+ * continues to fail closed through vaultGetValue().
30
+ */
31
+ export declare function vaultListDecryptableValues(userId: string): VaultEntryWithValue[];
24
32
  export declare function vaultSet(userId: string, key: string, value: string, description?: string): void;
25
33
  export declare function vaultHasKey(userId: string, key: string): boolean;
26
34
  export declare function vaultDel(userId: string, key: string): boolean;
@@ -169,6 +169,8 @@ export interface AgentQueryOptions {
169
169
  cwd: string;
170
170
  systemPrompt: string;
171
171
  userId?: string;
172
+ /** Credential namespace when it differs from the execution principal. */
173
+ vaultUserId?: string;
172
174
  session?: string;
173
175
  playwrightPort?: number;
174
176
  playwrightCapability?: string;
@@ -1 +1 @@
1
- export declare const NEGOTIUM_VERSION = "0.2.3";
1
+ export declare const NEGOTIUM_VERSION = "0.2.5";
package/dist/vault.js CHANGED
@@ -106,7 +106,6 @@ var BROWSER_DIR = resolveLocalStateDir("NEGOTIUM_BROWSER_DIR", "browser");
106
106
  var BROWSER_PROFILES_DIR = resolve(BROWSER_DIR, "profiles");
107
107
  var BINARIES_DIR = resolve(STATE_DIR, "binaries");
108
108
  var SECRETS_DIR = resolve(STATE_DIR, "secrets");
109
- var CONTEXTS_DIR = resolve(STATE_DIR, "data", "contexts");
110
109
  var DM_WORKSPACE_DIR = resolve(STATE_DIR, "data", "dm");
111
110
  var SESSION_WORKSPACE_DIR = resolve(STATE_DIR, "data", "sessions");
112
111
  var CLAUDE_EXECUTABLE_ENV = envText("NEGOTIUM_CLAUDE_EXECUTABLE");
@@ -249,7 +248,6 @@ mkdirSync(WORKSPACE_DIR, { recursive: true });
249
248
  mkdirSync(TOPIC_WORKSPACE_DIR, { recursive: true });
250
249
  mkdirSync(SHARED_WIKI_DIR, { recursive: true });
251
250
  mkdirSync(CRON_WORKSPACE_DIR, { recursive: true });
252
- mkdirSync(CONTEXTS_DIR, { recursive: true });
253
251
  mkdirSync(DM_WORKSPACE_DIR, { recursive: true });
254
252
  mkdirSync(SESSION_WORKSPACE_DIR, { recursive: true });
255
253
  mkdirSync(BROWSER_DIR, { recursive: true });
@@ -480,6 +478,20 @@ function vaultListWithValues(userId) {
480
478
  value: decryptRow(userId, row.key, row.value)
481
479
  }));
482
480
  }
481
+ function vaultListDecryptableValues(userId) {
482
+ const rows = activeVaultDatabase().prepare("SELECT key, description, value FROM vault WHERE user_id = ? ORDER BY key").all(userId);
483
+ const entries = [];
484
+ for (const row of rows) {
485
+ try {
486
+ entries.push({
487
+ key: row.key,
488
+ description: row.description,
489
+ value: decryptRow(userId, row.key, row.value)
490
+ });
491
+ } catch {}
492
+ }
493
+ return entries;
494
+ }
483
495
  function vaultSet(userId, key, value, description = "") {
484
496
  const normalizedKey = normalizeVaultKey(key);
485
497
  activeVaultDatabase().prepare(`INSERT INTO vault (user_id, key, value, description) VALUES (?, ?, ?, ?)
@@ -507,10 +519,12 @@ function vaultGetValue(userId, key) {
507
519
  return row ? decryptRow(userId, row.key, row.value) : undefined;
508
520
  }
509
521
  function vaultSubstituteDetailed(userId, text) {
510
- const entries = new Map(vaultListWithValues(userId).map((entry) => [entry.key, entry.value]));
522
+ const entries = new Map;
511
523
  const usedKeys = new Set;
512
524
  const substituted = text.replace(/\{\{([^}]+)\}\}/g, (match, rawKey) => {
513
525
  const key = normalizeVaultKey(rawKey);
526
+ if (!entries.has(key))
527
+ entries.set(key, vaultGetValue(userId, key));
514
528
  const value = entries.get(key);
515
529
  if (value === undefined)
516
530
  return match;
@@ -550,7 +564,7 @@ function encodedSecretForms(value) {
550
564
  return [...forms].sort((a, b) => b.length - a.length);
551
565
  }
552
566
  function redactVaultSecrets(userId, text) {
553
- const candidates = vaultListWithValues(userId).flatMap((entry) => encodedSecretForms(entry.value).map((form) => ({ form, key: entry.key }))).sort((a, b) => b.form.length - a.form.length || a.key.localeCompare(b.key));
567
+ const candidates = vaultListDecryptableValues(userId).flatMap((entry) => encodedSecretForms(entry.value).map((form) => ({ form, key: entry.key }))).sort((a, b) => b.form.length - a.form.length || a.key.localeCompare(b.key));
554
568
  if (candidates.length === 0)
555
569
  return text;
556
570
  const candidatesByFirstCharacter = new Map;
@@ -599,4 +613,4 @@ export {
599
613
  VAULT_DESCRIPTION_MAX_LENGTH
600
614
  };
601
615
 
602
- //# debugId=D6C5CDDC478A1CCC64756E2164756E21
616
+ //# debugId=330AC50C00EFAF5164756E2164756E21