@maintainer-pro/ai-cli 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Logger } from 'pino';
2
+ export { Logger } from 'pino';
1
3
  import { z } from 'zod';
2
4
 
3
5
  type AiCliProviderId = "claude" | "cursor" | "antigravity" | (string & {});
@@ -50,10 +52,15 @@ interface CallAiOptions {
50
52
  /** Absolute paths to screenshot/image files the agent should inspect. */
51
53
  attachmentPaths?: string[];
52
54
  /**
53
- * Compact excerpts from other `.maintainer-pro/chat` conversations.
55
+ * Compact excerpts from other project chats.
54
56
  * Injected into the prompt for the model to use when relevant.
55
57
  */
56
58
  priorConversationsContext?: string;
59
+ /**
60
+ * Explicit reply-to parent chain (oldest → newest ancestor of the current
61
+ * user message). Injected so the model anchors on the thread being answered.
62
+ */
63
+ parentChainContext?: string;
57
64
  /** Extra / override providers (e.g. future HTTP model backends). */
58
65
  providers?: AiProvider[];
59
66
  /** When true, skip the end-user chat footer so the agent can return structured output. */
@@ -84,18 +91,97 @@ declare function providerLabel(providerId: string): string;
84
91
  /** Extract ```json ... ``` tool blocks and strip them from assistant text. */
85
92
  declare function parseAiResponse(raw: string, provider: AiCliProviderId): AiResponse;
86
93
 
94
+ /** Stable delimiters so models can weight sections distinctly. */
95
+ declare const PROMPT_SECTION: {
96
+ readonly system: {
97
+ readonly begin: "<<<SYSTEM_BEGIN>>>";
98
+ readonly end: "<<<SYSTEM_END>>>";
99
+ };
100
+ readonly clientContext: {
101
+ readonly begin: "<<<CLIENT_CONTEXT_BEGIN>>>";
102
+ readonly end: "<<<CLIENT_CONTEXT_END>>>";
103
+ };
104
+ readonly priorConversations: {
105
+ readonly begin: "<<<PRIOR_CONVERSATIONS_BEGIN>>>";
106
+ readonly end: "<<<PRIOR_CONVERSATIONS_END>>>";
107
+ };
108
+ readonly parentChain: {
109
+ readonly begin: "<<<PARENT_CHAIN_BEGIN>>>";
110
+ readonly end: "<<<PARENT_CHAIN_END>>>";
111
+ };
112
+ readonly history: {
113
+ readonly begin: "<<<CONVERSATION_HISTORY_BEGIN>>>";
114
+ readonly end: "<<<CONVERSATION_HISTORY_END>>>";
115
+ };
116
+ readonly attachments: {
117
+ readonly begin: "<<<ATTACHMENTS_BEGIN>>>";
118
+ readonly end: "<<<ATTACHMENTS_END>>>";
119
+ };
120
+ readonly currentRequest: {
121
+ readonly begin: "<<<CURRENT_REQUEST_BEGIN>>>";
122
+ readonly end: "<<<CURRENT_REQUEST_END>>>";
123
+ };
124
+ };
87
125
  declare function buildConversationPrompt(messages: ChatMessage[]): string;
88
126
  declare function formatClientContext(context?: ClientContext): string;
89
127
  /** Full prompt for providers without a native --system-prompt flag (Cursor). */
90
- declare function buildCursorPrompt(systemPrompt: string, messages: ChatMessage[], context?: ClientContext, attachmentPaths?: string[], priorConversationsContext?: string, technical?: boolean): string;
128
+ declare function buildCursorPrompt(systemPrompt: string, messages: ChatMessage[], context?: ClientContext, attachmentPaths?: string[], priorConversationsContext?: string, technical?: boolean, parentChainContext?: string): string;
91
129
  /** Conversation + context for Claude (system prompt passed separately). */
92
- declare function buildClaudeUserPrompt(messages: ChatMessage[], context?: ClientContext, attachmentPaths?: string[], priorConversationsContext?: string, technical?: boolean): string;
130
+ declare function buildClaudeUserPrompt(messages: ChatMessage[], context?: ClientContext, attachmentPaths?: string[], priorConversationsContext?: string, technical?: boolean, parentChainContext?: string): string;
131
+
132
+ /** Stored row fields needed to walk reply-to links. */
133
+ type ParentChainSource = {
134
+ id: string;
135
+ role: string;
136
+ content: string;
137
+ parentMessageId?: string | null;
138
+ senderName?: string | null;
139
+ provider?: string | null;
140
+ };
141
+ type ParentChainEntry = {
142
+ id: string;
143
+ role: "user" | "assistant" | "system";
144
+ content: string;
145
+ senderName?: string;
146
+ };
147
+ /**
148
+ * Walk `parentMessageId` from `startId` up to the root (oldest first).
149
+ * Skips empty / working placeholders.
150
+ */
151
+ declare function collectParentChain(rows: ParentChainSource[], startId: string | null | undefined): ParentChainEntry[];
152
+ /**
153
+ * Resolve the reply-to id for the current user turn, then walk ancestors.
154
+ * `currentMessageId` is the user message being answered this turn.
155
+ */
156
+ declare function parentChainForTurn(rows: ParentChainSource[], currentMessageId: string | null | undefined, fallbackParentId?: string | null): ParentChainEntry[];
157
+ /** Prompt block so the model treats the chain as the reply target. */
158
+ declare function formatParentChainContext(chain: ParentChainEntry[]): string;
93
159
 
94
160
  declare function createDefaultSystemPrompt(input: {
95
161
  productDescription: string;
96
162
  relevantFilesHint?: string;
97
163
  runtimeToolsHint?: string;
164
+ /** Relative ignore globs (already merged with defaults). */
165
+ ignorePaths?: string[];
166
+ }): string;
167
+
168
+ /** Always blocked relative to the project folder (secrets / credentials). */
169
+ declare const DEFAULT_AI_IGNORE_PATHS: readonly [".env", ".env.*", "**/.env", "**/.env.*"];
170
+ declare function parseIgnorePathsEnv(raw: string | undefined | null): string[];
171
+ declare function normalizeIgnorePaths(paths: string[]): string[];
172
+ /** Partner paths plus built-in secret ignores (deduped). */
173
+ declare function resolveIgnorePaths(partnerPaths: string[]): string[];
174
+ declare function isInsideWorkspace(workspaceDir: string, targetPath: string): boolean;
175
+ declare function isIgnoredRelative(relativePath: string, patterns: string[]): boolean;
176
+ declare function isPathAllowed(workspaceDir: string, targetPath: string, ignorePaths: string[]): boolean;
177
+ declare function formatAccessPolicyPromptSection(input: {
178
+ ignorePaths: string[];
98
179
  }): string;
180
+ /** Marker block written into .cursorignore (and similar) by the bridge. */
181
+ declare const ACCESS_IGNORE_BEGIN = "# maintainer-pro:access-begin";
182
+ declare const ACCESS_IGNORE_END = "# maintainer-pro:access-end";
183
+ declare function renderManagedIgnoreBlock(ignorePaths: string[]): string;
184
+ declare function upsertManagedIgnoreFile(existing: string, ignorePaths: string[]): string;
99
185
 
100
186
  declare function createClaudeProvider(): AiProvider;
101
187
 
@@ -103,6 +189,29 @@ declare function createCursorProvider(): AiProvider;
103
189
 
104
190
  declare function createAntigravityProvider(): AiProvider;
105
191
 
192
+ /** True when NODE_ENV / AI_ENV is development (or AI_DEV=1). */
193
+ declare function isDevMode(): boolean;
194
+ /**
195
+ * Resolve log level from env.
196
+ * Defaults to `debug` in development, otherwise `info`.
197
+ * Override anytime with LOG_LEVEL / AI_LOG_LEVEL.
198
+ */
199
+ declare function resolveLogLevel(): string;
200
+ /**
201
+ * Shared logger for Maintainer Pro Node packages.
202
+ *
203
+ * Levels: fatal | error | warn | info | debug | trace | silent
204
+ * - Dev (`NODE_ENV=development` or unset on local sidecars): default `debug`
205
+ * - Production: default `info`
206
+ * - Override: `LOG_LEVEL=debug` / `AI_LOG_LEVEL`
207
+ * - Pretty TTY output (disable with `LOG_PRETTY=0`)
208
+ */
209
+ declare function createLogger(name: string): Logger;
210
+ /** Adapter for older `(msg) => void` callbacks — logs at info. */
211
+ declare function createInfoLogger(name: string): (msg: string) => void;
212
+ /** Short preview for debug logs (never dump huge prompts). */
213
+ declare function previewText(text: string | undefined | null, max?: number): string;
214
+
106
215
  type ToolSchemaMap = Record<string, z.ZodTypeAny>;
107
216
  declare function createToolValidator(schemas: ToolSchemaMap): (toolCall: ToolCall) => {
108
217
  valid: true;
@@ -120,13 +229,27 @@ interface ChatStoreLike {
120
229
  ensureConversation(id: string): Promise<void>;
121
230
  saveMessage(input: {
122
231
  conversationId: string;
232
+ id?: string;
123
233
  role: "user" | "assistant" | "system";
124
234
  content: string;
125
235
  provider?: string;
126
236
  attachmentPaths?: string[];
127
237
  senderType?: "client" | "developer" | "ai";
128
238
  senderName?: string;
129
- }): Promise<unknown>;
239
+ /** Reply chain: assistant/working rows point at the user message. */
240
+ parentMessageId?: string | null;
241
+ /** queue = persist only; run = this user turn starts the AI. */
242
+ intent?: "queue" | "run";
243
+ queueStatus?: "working" | "queued" | null;
244
+ }): Promise<{
245
+ id: string;
246
+ queueStatus?: string | null;
247
+ queuePosition?: number | null;
248
+ nextQueued?: {
249
+ id: string;
250
+ content: string;
251
+ } | null;
252
+ } | unknown>;
130
253
  listMessages?(conversationId: string): Promise<Array<{
131
254
  id: string;
132
255
  role: string;
@@ -136,9 +259,29 @@ interface ChatStoreLike {
136
259
  attachmentPaths?: string[];
137
260
  senderType?: "client" | "developer" | "ai" | null;
138
261
  senderName?: string | null;
262
+ parentMessageId?: string | null;
263
+ queueStatus?: string | null;
264
+ queuePosition?: number | null;
139
265
  }>>;
140
266
  /** Remove in-progress working placeholders (at most one per conversation). */
141
267
  clearWorkingMessages?(conversationId: string): Promise<void>;
268
+ /** Clear the working user turn and promote the oldest queued message. */
269
+ releaseWorkingTurn?(conversationId: string, parentMessageId?: string | null): Promise<{
270
+ nextQueued?: {
271
+ id: string;
272
+ content: string;
273
+ } | null;
274
+ } | void>;
275
+ /** Unstick working/queued turns after crashes or raced promotes. */
276
+ recoverQueue?(conversationId: string): Promise<{
277
+ action: string;
278
+ workingId?: string | null;
279
+ promotedId?: string | null;
280
+ nextQueued?: {
281
+ id: string;
282
+ content: string;
283
+ } | null;
284
+ } | void>;
142
285
  /** All conversations under the store (for prior-chat context). */
143
286
  listConversations?(): Promise<Array<{
144
287
  id: string;
@@ -156,23 +299,32 @@ interface ChatStoreLike {
156
299
  }>): Promise<void>;
157
300
  /**
158
301
  * Optional remote/local upload hook. When present, chat images are persisted
159
- * through the store instead of `.maintainer-pro/uploads`.
302
+ * through the store instead of the project data uploads folder.
160
303
  * `localPaths` are absolute paths for CLI inspection; `refs` are stored on messages.
161
304
  */
162
305
  uploadAttachments?(conversationId: string, attachments: ChatAttachment[] | undefined): Promise<{
163
306
  refs: string[];
164
307
  localPaths: string[];
165
308
  }>;
309
+ /**
310
+ * Download stored message images into the project data folder so the coding CLI can
311
+ * open them. Used on working turns where the chat POST has no image bytes.
312
+ */
313
+ materializeMessageAttachments?(conversationId: string, messageId: string | undefined, workspaceDir: string): Promise<string[]>;
166
314
  }
167
315
  interface ChatHandlerOptions {
168
316
  systemPrompt: string;
169
317
  workspaceDir?: string;
318
+ /** Bridge-owned data dir (~/.maintainer-pro/projects/<id>). */
319
+ dataDir?: string;
320
+ sandboxId?: string;
170
321
  providerPreference?: CallAiOptions["providerPreference"];
171
322
  providers?: AiProvider[];
172
323
  tools?: ToolSchemaMap;
173
324
  db?: ChatStoreLike;
174
325
  conversationId?: string | ((request: Request) => string | undefined);
175
326
  onToolCalls?: (toolCalls: ToolCall[], context?: ClientContext) => void | Promise<void>;
327
+ logger?: Logger;
176
328
  }
177
329
  interface ChatHandlers {
178
330
  GET: (request: Request) => Promise<Response>;
@@ -184,8 +336,11 @@ declare function toNextRoute(handlers: ChatHandlers): {
184
336
  POST: (request: Request) => Promise<Response>;
185
337
  };
186
338
 
187
- /** Persist chat image attachments under the workspace and return absolute paths. */
188
- declare function saveChatAttachments(attachments: ChatAttachment[] | undefined, workspaceDir: string): Promise<string[]>;
339
+ /** Persist chat image attachments under the project data dir and return absolute paths. */
340
+ declare function saveChatAttachments(attachments: ChatAttachment[] | undefined, workspaceDir: string, extra?: {
341
+ dataDir?: string | null;
342
+ sandboxId?: string | null;
343
+ }): Promise<string[]>;
189
344
 
190
345
  interface LocalStoredMessage {
191
346
  id: string;
@@ -197,6 +352,9 @@ interface LocalStoredMessage {
197
352
  attachmentPaths?: string[];
198
353
  senderType?: "client" | "developer" | "ai" | null;
199
354
  senderName?: string | null;
355
+ parentMessageId?: string | null;
356
+ queueStatus?: string | null;
357
+ queuePosition?: number | null;
200
358
  }
201
359
  /**
202
360
  * Persist conversations as JSON files under a local directory.
@@ -207,12 +365,62 @@ declare function createLocalDirectoryStore(baseDir: string): ChatStoreLike & {
207
365
  listConversations: NonNullable<ChatStoreLike["listConversations"]>;
208
366
  };
209
367
 
368
+ type CachedChatMessage = NonNullable<Awaited<ReturnType<NonNullable<ChatStoreLike["listMessages"]>>>>[number];
369
+ type CachedConversation = {
370
+ id: string;
371
+ updatedAt: string;
372
+ messages: CachedChatMessage[];
373
+ };
374
+ type SyncedStoreStats = {
375
+ conversations: number;
376
+ messages: number;
377
+ };
378
+ type SyncedChatStore = ChatStoreLike & {
379
+ uploadAttachments?: NonNullable<ChatStoreLike["uploadAttachments"]>;
380
+ ready: Promise<SyncedStoreStats>;
381
+ stop: () => void;
382
+ };
383
+ type RemoteStore = ChatStoreLike & {
384
+ uploadAttachments?: NonNullable<ChatStoreLike["uploadAttachments"]>;
385
+ materializeMessageAttachments?: NonNullable<ChatStoreLike["materializeMessageAttachments"]>;
386
+ listSnapshot?: () => Promise<CachedConversation[]>;
387
+ };
388
+ type WorkingTurnEvent = {
389
+ conversationId: string;
390
+ message: CachedChatMessage;
391
+ };
392
+ type SyncedChatStoreOptions = {
393
+ remote: RemoteStore;
394
+ maintainerProUrl: string;
395
+ apiKey: string;
396
+ /** Pino logger. Prefer this over `log`. */
397
+ logger?: Logger;
398
+ /** @deprecated Prefer `logger`. Info-level string messages only. */
399
+ log?: (msg: string) => void;
400
+ onWorkingTurn?: (event: WorkingTurnEvent) => void;
401
+ };
402
+ /**
403
+ * In-memory message cache in front of a remote Maintainer Pro store.
404
+ * Hydrates a full snapshot on start, writes through on local changes,
405
+ * and applies live WebSocket events from the other party.
406
+ */
407
+ declare function createSyncedChatStore(options: SyncedChatStoreOptions): SyncedChatStore;
408
+
210
409
  interface MaintainerProStoreOptions {
211
410
  baseUrl: string;
212
411
  apiKey: string;
213
412
  /** Directory for temporary local copies of images for CLI providers. */
214
413
  tempDir?: string;
215
414
  fetchImpl?: typeof fetch;
415
+ /**
416
+ * Keep a local message cache and live-sync over WebSocket.
417
+ * Default true. Set false for HTTP-only (tests / one-shot scripts).
418
+ */
419
+ sync?: boolean;
420
+ logger?: Logger;
421
+ /** @deprecated Prefer `logger`. */
422
+ log?: (msg: string) => void;
423
+ onWorkingTurn?: (event: WorkingTurnEvent) => void;
216
424
  }
217
425
  type UploadResult = {
218
426
  /** Refs persisted on messages (maintainer-pro://uuid). */
@@ -222,13 +430,18 @@ type UploadResult = {
222
430
  attachmentIds: string[];
223
431
  };
224
432
  /**
225
- * Persist chat data via Maintainer Pro HTTP API (no local .maintainer-pro writes).
433
+ * Persist chat data via Maintainer Pro HTTP API (no writes into the host app).
226
434
  */
227
- declare function createMaintainerProStore(options: MaintainerProStoreOptions): ChatStoreLike & {
435
+ declare function createMaintainerProStore(options: MaintainerProStoreOptions): SyncedChatStore & {
228
436
  uploadAttachments: (conversationId: string, attachments: ChatAttachment[] | undefined) => Promise<UploadResult>;
229
437
  };
230
438
  /** Build a Maintainer Pro store from env when configured. */
231
- declare function createMaintainerProStoreFromEnv(): ReturnType<typeof createMaintainerProStore> | null;
439
+ declare function createMaintainerProStoreFromEnv(options?: {
440
+ logger?: Logger;
441
+ log?: (msg: string) => void;
442
+ sync?: boolean;
443
+ onWorkingTurn?: (event: WorkingTurnEvent) => void;
444
+ }): ReturnType<typeof createMaintainerProStore> | null;
232
445
 
233
446
  interface PriorConversationOptions {
234
447
  excludeConversationId?: string;
@@ -271,6 +484,13 @@ interface WorkspaceInspectResult {
271
484
  provider: string;
272
485
  rawText: string;
273
486
  }
487
+ /**
488
+ * Read-only config analysis for interactive onboarding.
489
+ * Never instructs the agent to edit the repo; times out so UI stays responsive.
490
+ */
491
+ declare function inspectConfigOnly(input: WorkspaceInspectInput, opts?: {
492
+ timeoutMs?: number;
493
+ }): Promise<WorkspaceInspectResult>;
274
494
  /**
275
495
  * Ask the coding-agent CLI (via callAi) to inspect a workspace and optionally
276
496
  * repair setup issues. Used by ai-bridge so host-process planning uses the
@@ -278,4 +498,155 @@ interface WorkspaceInspectResult {
278
498
  */
279
499
  declare function inspectAndRepairWorkspace(input: WorkspaceInspectInput): Promise<WorkspaceInspectResult>;
280
500
 
281
- export { type AiCliProviderId, type AiProvider, type AiResponse, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, type LocalStoredMessage, type MaintainerProStoreOptions, type PriorConversationOptions, type ProviderPreference, type ToolCall, type ToolSchemaMap, WORKING_PROVIDER, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceKind, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createLocalDirectoryStore, createMaintainerProStore, createMaintainerProStoreFromEnv, createToolValidator, formatClientContext, getProviderPreference, inspectAndRepairWorkspace, parseAiResponse, providerLabel, resolveCliBinary, resolveProvider, saveChatAttachments, toNextRoute };
501
+ /** Top-level folder under the user home (bridge.json, per-project data). */
502
+ declare const MAINTAINER_PRO_HOME_DIR = ".maintainer-pro";
503
+ declare const HOST_APPS_FILE = "apps.json";
504
+ type ProjectDataInput = {
505
+ workspaceDir: string;
506
+ /** Distinguishes sandboxes when one bridge runs several apps. */
507
+ sandboxId?: string | null;
508
+ /** Absolute override (e.g. already resolved by the bridge). */
509
+ dataDir?: string | null;
510
+ };
511
+ declare function maintainerProHome(): string;
512
+ declare function projectIdForFolder(folder: string): string;
513
+ declare function sanitizeProjectId(id: string): string;
514
+ /**
515
+ * Per-project data lives next to the bridge, not in the host app:
516
+ * `~/.maintainer-pro/projects/<sandboxId or folder-hash>/`.
517
+ */
518
+ declare function resolveProjectDataDir(input: ProjectDataInput): string;
519
+ declare function projectUploadsDir(input: ProjectDataInput): string;
520
+ declare function hostAppsCachePath$1(input: ProjectDataInput): string;
521
+ declare function ensureProjectDataDir(input: ProjectDataInput): string;
522
+
523
+ /** @deprecated Host-apps cache lives under ~/.maintainer-pro/projects/<id>. */
524
+ declare const COLLABORATER_DIR = ".collaborater";
525
+ declare const AI_SERVER_APP_ID = "ai-server";
526
+ declare const AI_SERVER_DEFAULT_PORT = 3100;
527
+ type HostAppRole = "ai-server" | "ui" | "backend" | "app" | "custom";
528
+ type HostAppSource = "default" | "env" | "package" | "ai" | "manual";
529
+ type HostEnvMap = {
530
+ key: string;
531
+ sourceAppId: string;
532
+ };
533
+ type HostApp = {
534
+ id: string;
535
+ name: string;
536
+ role: HostAppRole;
537
+ port: number;
538
+ startCommand?: string | null;
539
+ source: HostAppSource;
540
+ locked?: boolean;
541
+ /** Share URL / CORS UI — the page the browser opens. */
542
+ host?: boolean;
543
+ envMaps?: HostEnvMap[];
544
+ };
545
+ type HostAppsResolveInput = {
546
+ workspaceDir: string;
547
+ appName?: string;
548
+ preferredAiPort?: number;
549
+ /** Desired list from Maintainer Pro — used as source of truth when present. */
550
+ desired?: HostApp[] | null;
551
+ /** Re-scan files / optionally ask the agent. */
552
+ force?: boolean;
553
+ /** Only call the coding-agent CLI when files are missing or conflicting. */
554
+ allowAi?: boolean;
555
+ sandboxId?: string | null;
556
+ dataDir?: string | null;
557
+ };
558
+ type HostAppsResolveResult = {
559
+ apps: HostApp[];
560
+ source: "desired" | "cache" | "env" | "ai" | "default";
561
+ cached: boolean;
562
+ usedAi: boolean;
563
+ confused: boolean;
564
+ reasons: string[];
565
+ fingerprint: string;
566
+ };
567
+ type SetupProposalConfidence = "high" | "medium" | "low";
568
+ type HostAppAlternative = {
569
+ /** Primary app id this alternative can replace. */
570
+ appId: string;
571
+ port: number;
572
+ startCommand?: string | null;
573
+ label: string;
574
+ source: HostAppSource;
575
+ };
576
+ type SetupProposal = {
577
+ apps: HostApp[];
578
+ alternatives: HostAppAlternative[];
579
+ reasons: string[];
580
+ confidence: SetupProposalConfidence;
581
+ projectSummary: string;
582
+ usedAi: boolean;
583
+ needsReview: boolean;
584
+ fingerprint: string;
585
+ };
586
+ type ProposeHostAppsInput = {
587
+ workspaceDir: string;
588
+ appName?: string;
589
+ preferredAiPort?: number;
590
+ /**
591
+ * When true (default), call read-only AI if file detect is confused / low confidence.
592
+ * Never edits the repo.
593
+ */
594
+ allowAi?: boolean;
595
+ };
596
+ declare function parsePort(value: unknown, fallback?: number): number;
597
+ declare function hostAppsCachePath(folder: string, extra?: {
598
+ sandboxId?: string | null;
599
+ dataDir?: string | null;
600
+ }): string;
601
+ declare function defaultAiServerApp(port?: number): HostApp;
602
+ declare function normalizeHostApp(raw: unknown): HostApp | null;
603
+ declare function normalizeEnvMaps(raw: unknown): HostEnvMap[];
604
+ declare function ensureSingleHost(apps: HostApp[]): HostApp[];
605
+ declare function normalizeHostApps(raw: unknown): HostApp[];
606
+ declare function ensureAiServerApp(apps: HostApp[], preferredPort?: number): HostApp[];
607
+ declare function readProjectEnvLayers(folder: string): {
608
+ merged: Record<string, string>;
609
+ layers: Array<{
610
+ file: string;
611
+ values: Record<string, string>;
612
+ }>;
613
+ };
614
+ declare function hostAppsFingerprint(folder: string): string;
615
+ declare function detectHostAppsFromFiles(folder: string, opts?: {
616
+ preferredAiPort?: number;
617
+ appName?: string;
618
+ }): {
619
+ apps: HostApp[];
620
+ reasons: string[];
621
+ confused: boolean;
622
+ };
623
+ declare function readHostAppsCache(folder: string, extra?: {
624
+ sandboxId?: string | null;
625
+ dataDir?: string | null;
626
+ }): {
627
+ apps: HostApp[];
628
+ fingerprint?: string;
629
+ updatedAt?: string;
630
+ } | null;
631
+ /** @deprecated Use readHostAppsCache. */
632
+ declare const readCollaboraterApps: typeof readHostAppsCache;
633
+ declare function writeHostAppsCache(folder: string, apps: HostApp[], extra?: Record<string, unknown>, loc?: {
634
+ sandboxId?: string | null;
635
+ dataDir?: string | null;
636
+ }): void;
637
+ /** @deprecated Use writeHostAppsCache. */
638
+ declare const writeCollaboraterApps: typeof writeHostAppsCache;
639
+ declare function mergeDesiredHostApps(desired: HostApp[], detected: HostApp[]): HostApp[];
640
+ /**
641
+ * Fast, interactive onboarding propose: file detect first, optional read-only AI.
642
+ * Never edits the repository.
643
+ */
644
+ declare function proposeHostAppsFromConfig(input: ProposeHostAppsInput): Promise<SetupProposal>;
645
+ /**
646
+ * Resolve host apps without calling the coding-agent CLI unless files are
647
+ * missing, conflicting, or the caller forced a redetect.
648
+ * When allowAi is set, uses read-only config inspect (does not edit the repo).
649
+ */
650
+ declare function resolveHostApps(input: HostAppsResolveInput): Promise<HostAppsResolveResult>;
651
+
652
+ export { ACCESS_IGNORE_BEGIN, ACCESS_IGNORE_END, AI_SERVER_APP_ID, AI_SERVER_DEFAULT_PORT, type AiCliProviderId, type AiProvider, type AiResponse, COLLABORATER_DIR, type CachedChatMessage, type CachedConversation, type CallAiOptions, type ChatAttachment, type ChatHandlerOptions, type ChatHandlers, type ChatMessage, type ChatSenderType, type ChatStoreLike, type ChatUser, type ClientContext, DEFAULT_AI_IGNORE_PATHS, HOST_APPS_FILE, type HostApp, type HostAppAlternative, type HostAppRole, type HostAppSource, type HostAppsResolveInput, type HostAppsResolveResult, type HostEnvMap, type LocalStoredMessage, MAINTAINER_PRO_HOME_DIR, type MaintainerProStoreOptions, PROMPT_SECTION, type ParentChainEntry, type ParentChainSource, type PriorConversationOptions, type ProjectDataInput, type ProposeHostAppsInput, type ProviderPreference, type SetupProposal, type SetupProposalConfidence, type SyncedChatStore, type SyncedChatStoreOptions, type SyncedStoreStats, type ToolCall, type ToolSchemaMap, WORKING_PROVIDER, type WorkingTurnEvent, type WorkspaceInspectInput, type WorkspaceInspectResult, type WorkspaceKind, buildClaudeUserPrompt, buildConversationPrompt, buildCursorPrompt, buildPriorConversationsContext, callAi, collectParentChain, commandExists, createAntigravityProvider, createBuiltinProviders, createChatHandler, createClaudeProvider, createCursorProvider, createDefaultSystemPrompt, createInfoLogger, createLocalDirectoryStore, createLogger, createMaintainerProStore, createMaintainerProStoreFromEnv, createSyncedChatStore, createToolValidator, defaultAiServerApp, detectHostAppsFromFiles, ensureAiServerApp, ensureProjectDataDir, ensureSingleHost, formatAccessPolicyPromptSection, formatClientContext, formatParentChainContext, getProviderPreference, hostAppsCachePath, hostAppsFingerprint, inspectAndRepairWorkspace, inspectConfigOnly, isDevMode, isIgnoredRelative, isInsideWorkspace, isPathAllowed, maintainerProHome, mergeDesiredHostApps, normalizeEnvMaps, normalizeHostApp, normalizeHostApps, normalizeIgnorePaths, parentChainForTurn, parseAiResponse, parseIgnorePathsEnv, parsePort, previewText, hostAppsCachePath$1 as projectHostAppsPath, projectIdForFolder, projectUploadsDir, proposeHostAppsFromConfig, providerLabel, readCollaboraterApps, readHostAppsCache, readProjectEnvLayers, renderManagedIgnoreBlock, resolveCliBinary, resolveHostApps, resolveIgnorePaths, resolveLogLevel, resolveProjectDataDir, resolveProvider, sanitizeProjectId, saveChatAttachments, toNextRoute, upsertManagedIgnoreFile, writeCollaboraterApps, writeHostAppsCache };