@spotpatch/dev-server 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import { applyPreparedAgentChange, executeAgentChange, inspectAgentWorkspace, pr
2
2
  import { AgentJobEvent, AgentJobSnapshot, AgentJobCreateRequest, AgentCapabilityRequest, AgentCapabilitySnapshot, AgentJobResultResponse, AgentWorkspaceHealthSnapshot, ResolvedAiOptions, ExternalHandoffFramework, ExternalHandoffCapability, ExternalHandoffPublishRequest, SpotAnnotation, ExternalHandoffPublishResult, ExternalHandoffStatusResult, ExternalAgentControlStatus, ExternalAgentControlConnectRequest, ExternalAgentControlDisconnectRequest, ExternalAgentControlCancelRequest, ExternalAgentManagedResult, SpotPatchEditorPreference, ContextBudget, SpotPatchLocalePreference, DataFlowLimits, ContextualAskExecutorPreference, AiProviderProtocol, AiProviderAuthentication, AiExecutionOptions, AiOptions, ContextualAskOptions, RuntimeAiConfig, RuntimeDataFlowConfig, ResolvedAgentCheckDefinition, AgentLimits, SpotSelectionContext, AskJobEvent, AskJobSnapshot, ContextualAskCapability, AskJobCreateRequest, AskJobResultResponse, ContextualAskErrorCode, SpotPatchRuntimeConfig } from '@spotpatch/shared';
3
3
  import { SourceFilterEntry } from '@spotpatch/compiler';
4
4
  import { IncomingMessage, ServerResponse } from 'node:http';
5
+ import { StaticDataFlowAnalyzerOptions } from '@spotpatch/analyzer';
5
6
 
6
7
  type WorkspaceActivityKind = "ask" | "change";
7
8
  interface WorkspaceActivityLease {
@@ -207,13 +208,6 @@ declare function readIntegrationFile(absolutePath: string): Promise<string>;
207
208
  declare function createIntegrationFileChange(appRoot: string, absolutePath: string, nextContent: string, previousContent: string | undefined): IntegrationFileChange | undefined;
208
209
  declare function applyIntegrationPlan(plan: IntegrationPlan): Promise<void>;
209
210
 
210
- interface ResolveProjectOptionsInput {
211
- readonly appRoot: string;
212
- readonly environmentAi?: false | SimpleAiOptions;
213
- readonly options?: SpotPatchOptions;
214
- }
215
- declare function resolveProjectOptions(input: ResolveProjectOptionsInput): Promise<ResolvedSpotPatchOptions>;
216
-
217
211
  interface DiscoverProjectValidationCheckOptions {
218
212
  readonly appRoot: string;
219
213
  readonly timeoutMs: number;
@@ -233,6 +227,14 @@ declare function discoverProjectValidationCheck(options: DiscoverProjectValidati
233
227
  declare function resolveProjectValidationChecks(options: ResolveProjectValidationChecksOptions): Promise<Readonly<Record<string, ResolvedAgentCheckDefinition>>>;
234
228
  declare function resolveManagedExecutionValidation(options: ResolveManagedExecutionValidationOptions): Promise<ResolvedManagedExecutionValidation>;
235
229
 
230
+ interface ResolveProjectOptionsInput {
231
+ readonly appRoot: string;
232
+ readonly environmentAi?: false | SimpleAiOptions;
233
+ readonly options?: SpotPatchOptions;
234
+ readonly resolveValidationChecks?: typeof resolveProjectValidationChecks;
235
+ }
236
+ declare function resolveProjectOptions(input: ResolveProjectOptionsInput): Promise<ResolvedSpotPatchOptions>;
237
+
236
238
  type SourceIdFactory = () => string;
237
239
 
238
240
  interface SourceRegistry {
@@ -268,6 +270,7 @@ interface CapturedAskReadSnapshot {
268
270
  }>;
269
271
  }
270
272
  interface CaptureAskReadSnapshotOptions {
273
+ readonly resolveSourceImports?: (absolutePath: string, code: string) => readonly string[] | undefined;
271
274
  readonly root: string;
272
275
  readonly registry: SourceRegistry;
273
276
  readonly selection: SpotSelectionContext;
@@ -293,6 +296,7 @@ interface ContextualAskManagerDependencies {
293
296
  readonly now: () => Date;
294
297
  }
295
298
  interface CreateContextualAskManagerOptions {
299
+ readonly resolveSourceImports?: CaptureAskReadSnapshotOptions["resolveSourceImports"];
296
300
  readonly coordinator: WorkspaceActivityCoordinator;
297
301
  readonly enabled: boolean;
298
302
  readonly executors?: readonly ContextualAskExecutor[];
@@ -354,6 +358,7 @@ interface SpotPatchServerLogger {
354
358
  warn(message: string): void;
355
359
  }
356
360
  interface CreateMiddlewareOptions {
361
+ readonly projectDataFlowSource?: StaticDataFlowAnalyzerOptions["projectSource"];
357
362
  readonly agentManager?: AgentJobManager;
358
363
  readonly contextualAskManager?: ContextualAskManager;
359
364
  readonly bootstrap?: RuntimeBootstrapOptions;
@@ -428,4 +433,20 @@ interface SerializedSpotPatchOptions {
428
433
  declare function serializeResolvedSpotPatchOptions(options: ResolvedSpotPatchOptions): SerializedSpotPatchOptions;
429
434
  declare function parseSerializedSpotPatchOptions(value: unknown): ResolvedSpotPatchOptions;
430
435
 
431
- export { type AgentJobEventListener, type AgentJobManager, type CaptureAskReadSnapshotOptions, type CapturedAskReadSnapshot, type ComposeContextualAskExecutorsOptions, ContextualAskError, type ContextualAskJobEventListener, type ContextualAskManager, type ContextualAskRoute, type CreateAgentJobManagerOptions, type CreateConfiguredKeyAskExecutorsOptions, type CreateContextualAskManagerOptions, type CreateExternalHandoffServiceOptions, type CreateMiddlewareOptions, DEFAULT_EXCLUDE, DEFAULT_OPTIONS, type DiscoverProjectValidationCheckOptions, type EnvironmentAiConfiguration, type ExternalAgentControlPort, type ExternalHandoffService, type FilterEntry, type IntegrationFileChange, type IntegrationPlan, type ResolveManagedExecutionValidationOptions, type ResolveProjectOptionsInput, type ResolveProjectValidationChecksOptions, type ResolvedContextualAskOptions, type ResolvedManagedExecutionValidation, type ResolvedRuntimeBootstrapOptions, type ResolvedSpotPatchDataFlowOptions, type ResolvedSpotPatchOptions, type RuntimeBootstrapOptions, type SerializedFilterEntry, type SerializedSpotPatchOptions, type SimpleAiOptions, type SourceRegistrationHandler, type SourceRegistrationService, type SourceRegistrationServiceOptions, type SourceRegistry, type SpotPatchAiOptions, type SpotPatchDataFlowOptions, type SpotPatchMiddleware, type SpotPatchNext, type SpotPatchOptions, type SpotPatchServerLogger, type SpotPatchSession, type WorkspaceActivityCoordinator, type WorkspaceActivityKind, type WorkspaceActivityLease, applyIntegrationPlan, captureAskReadSnapshot, composeContextualAskExecutors, createAgentJobManager, createConfiguredKeyAskExecutors, createContextualAskManager, createExternalHandoffService, createIntegrationFileChange, createRuntimeAiConfig, createRuntimeDataFlowConfig, createSession, createSourceRegistrationService, createSourceRegistry, createSpotPatchMiddleware, createWorkspaceActivityCoordinator, discoverProjectValidationCheck, handleContextualAskRequest, integrationPathExists, isLoopbackHostname, matchContextualAskPath, parseSerializedSpotPatchOptions, readIntegrationFile, readJsonRequestBody, readRuntimeBootstrap, resolveCredentialEnvironment, resolveEnvironmentAiConfiguration, resolveManagedExecutionValidation, resolveOptions, resolveProjectOptions, resolveProjectValidationChecks, resolveRuntimeBootstrapOptions, serializeResolvedSpotPatchOptions };
436
+ interface DevelopmentSessionInput extends Omit<CreateMiddlewareOptions, "agentManager" | "contextualAskManager" | "externalAgentControl" | "externalHandoffService"> {
437
+ readonly framework: ExternalHandoffFramework;
438
+ readonly resolveSourceImports?: CreateContextualAskManagerOptions["resolveSourceImports"];
439
+ readonly environment: Readonly<Record<string, string | undefined>>;
440
+ readonly executionRoot?: string;
441
+ readonly createManagedAskExecutor: () => ContextualAskExecutor;
442
+ readonly createExternalAgentControl: (validation: ResolvedManagedExecutionValidation) => Promise<ExternalAgentControlPort>;
443
+ readonly resolveValidation?: () => Promise<ResolvedManagedExecutionValidation>;
444
+ }
445
+ interface DevelopmentSession {
446
+ readonly middleware: SpotPatchMiddleware;
447
+ readonly close: () => Promise<void>;
448
+ }
449
+ /** Owns feature services, not HTTP listeners or framework-specific transports. */
450
+ declare function createDevelopmentSession(input: DevelopmentSessionInput): Promise<DevelopmentSession>;
451
+
452
+ export { type AgentJobEventListener, type AgentJobManager, type CaptureAskReadSnapshotOptions, type CapturedAskReadSnapshot, type ComposeContextualAskExecutorsOptions, ContextualAskError, type ContextualAskJobEventListener, type ContextualAskManager, type ContextualAskRoute, type CreateAgentJobManagerOptions, type CreateConfiguredKeyAskExecutorsOptions, type CreateContextualAskManagerOptions, type CreateExternalHandoffServiceOptions, type CreateMiddlewareOptions, DEFAULT_EXCLUDE, DEFAULT_OPTIONS, type DevelopmentSession, type DevelopmentSessionInput, type DiscoverProjectValidationCheckOptions, type EnvironmentAiConfiguration, type ExternalAgentControlPort, type ExternalHandoffService, type FilterEntry, type IntegrationFileChange, type IntegrationPlan, type ResolveManagedExecutionValidationOptions, type ResolveProjectOptionsInput, type ResolveProjectValidationChecksOptions, type ResolvedContextualAskOptions, type ResolvedManagedExecutionValidation, type ResolvedRuntimeBootstrapOptions, type ResolvedSpotPatchDataFlowOptions, type ResolvedSpotPatchOptions, type RuntimeBootstrapOptions, type SerializedFilterEntry, type SerializedSpotPatchOptions, type SimpleAiOptions, type SourceRegistrationHandler, type SourceRegistrationService, type SourceRegistrationServiceOptions, type SourceRegistry, type SpotPatchAiOptions, type SpotPatchDataFlowOptions, type SpotPatchMiddleware, type SpotPatchNext, type SpotPatchOptions, type SpotPatchServerLogger, type SpotPatchSession, type WorkspaceActivityCoordinator, type WorkspaceActivityKind, type WorkspaceActivityLease, applyIntegrationPlan, captureAskReadSnapshot, composeContextualAskExecutors, createAgentJobManager, createConfiguredKeyAskExecutors, createContextualAskManager, createDevelopmentSession, createExternalHandoffService, createIntegrationFileChange, createRuntimeAiConfig, createRuntimeDataFlowConfig, createSession, createSourceRegistrationService, createSourceRegistry, createSpotPatchMiddleware, createWorkspaceActivityCoordinator, discoverProjectValidationCheck, handleContextualAskRequest, integrationPathExists, isLoopbackHostname, matchContextualAskPath, parseSerializedSpotPatchOptions, readIntegrationFile, readJsonRequestBody, readRuntimeBootstrap, resolveCredentialEnvironment, resolveEnvironmentAiConfiguration, resolveManagedExecutionValidation, resolveOptions, resolveProjectOptions, resolveProjectValidationChecks, resolveRuntimeBootstrapOptions, serializeResolvedSpotPatchOptions };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import { applyPreparedAgentChange, executeAgentChange, inspectAgentWorkspace, pr
2
2
  import { AgentJobEvent, AgentJobSnapshot, AgentJobCreateRequest, AgentCapabilityRequest, AgentCapabilitySnapshot, AgentJobResultResponse, AgentWorkspaceHealthSnapshot, ResolvedAiOptions, ExternalHandoffFramework, ExternalHandoffCapability, ExternalHandoffPublishRequest, SpotAnnotation, ExternalHandoffPublishResult, ExternalHandoffStatusResult, ExternalAgentControlStatus, ExternalAgentControlConnectRequest, ExternalAgentControlDisconnectRequest, ExternalAgentControlCancelRequest, ExternalAgentManagedResult, SpotPatchEditorPreference, ContextBudget, SpotPatchLocalePreference, DataFlowLimits, ContextualAskExecutorPreference, AiProviderProtocol, AiProviderAuthentication, AiExecutionOptions, AiOptions, ContextualAskOptions, RuntimeAiConfig, RuntimeDataFlowConfig, ResolvedAgentCheckDefinition, AgentLimits, SpotSelectionContext, AskJobEvent, AskJobSnapshot, ContextualAskCapability, AskJobCreateRequest, AskJobResultResponse, ContextualAskErrorCode, SpotPatchRuntimeConfig } from '@spotpatch/shared';
3
3
  import { SourceFilterEntry } from '@spotpatch/compiler';
4
4
  import { IncomingMessage, ServerResponse } from 'node:http';
5
+ import { StaticDataFlowAnalyzerOptions } from '@spotpatch/analyzer';
5
6
 
6
7
  type WorkspaceActivityKind = "ask" | "change";
7
8
  interface WorkspaceActivityLease {
@@ -207,13 +208,6 @@ declare function readIntegrationFile(absolutePath: string): Promise<string>;
207
208
  declare function createIntegrationFileChange(appRoot: string, absolutePath: string, nextContent: string, previousContent: string | undefined): IntegrationFileChange | undefined;
208
209
  declare function applyIntegrationPlan(plan: IntegrationPlan): Promise<void>;
209
210
 
210
- interface ResolveProjectOptionsInput {
211
- readonly appRoot: string;
212
- readonly environmentAi?: false | SimpleAiOptions;
213
- readonly options?: SpotPatchOptions;
214
- }
215
- declare function resolveProjectOptions(input: ResolveProjectOptionsInput): Promise<ResolvedSpotPatchOptions>;
216
-
217
211
  interface DiscoverProjectValidationCheckOptions {
218
212
  readonly appRoot: string;
219
213
  readonly timeoutMs: number;
@@ -233,6 +227,14 @@ declare function discoverProjectValidationCheck(options: DiscoverProjectValidati
233
227
  declare function resolveProjectValidationChecks(options: ResolveProjectValidationChecksOptions): Promise<Readonly<Record<string, ResolvedAgentCheckDefinition>>>;
234
228
  declare function resolveManagedExecutionValidation(options: ResolveManagedExecutionValidationOptions): Promise<ResolvedManagedExecutionValidation>;
235
229
 
230
+ interface ResolveProjectOptionsInput {
231
+ readonly appRoot: string;
232
+ readonly environmentAi?: false | SimpleAiOptions;
233
+ readonly options?: SpotPatchOptions;
234
+ readonly resolveValidationChecks?: typeof resolveProjectValidationChecks;
235
+ }
236
+ declare function resolveProjectOptions(input: ResolveProjectOptionsInput): Promise<ResolvedSpotPatchOptions>;
237
+
236
238
  type SourceIdFactory = () => string;
237
239
 
238
240
  interface SourceRegistry {
@@ -268,6 +270,7 @@ interface CapturedAskReadSnapshot {
268
270
  }>;
269
271
  }
270
272
  interface CaptureAskReadSnapshotOptions {
273
+ readonly resolveSourceImports?: (absolutePath: string, code: string) => readonly string[] | undefined;
271
274
  readonly root: string;
272
275
  readonly registry: SourceRegistry;
273
276
  readonly selection: SpotSelectionContext;
@@ -293,6 +296,7 @@ interface ContextualAskManagerDependencies {
293
296
  readonly now: () => Date;
294
297
  }
295
298
  interface CreateContextualAskManagerOptions {
299
+ readonly resolveSourceImports?: CaptureAskReadSnapshotOptions["resolveSourceImports"];
296
300
  readonly coordinator: WorkspaceActivityCoordinator;
297
301
  readonly enabled: boolean;
298
302
  readonly executors?: readonly ContextualAskExecutor[];
@@ -354,6 +358,7 @@ interface SpotPatchServerLogger {
354
358
  warn(message: string): void;
355
359
  }
356
360
  interface CreateMiddlewareOptions {
361
+ readonly projectDataFlowSource?: StaticDataFlowAnalyzerOptions["projectSource"];
357
362
  readonly agentManager?: AgentJobManager;
358
363
  readonly contextualAskManager?: ContextualAskManager;
359
364
  readonly bootstrap?: RuntimeBootstrapOptions;
@@ -428,4 +433,20 @@ interface SerializedSpotPatchOptions {
428
433
  declare function serializeResolvedSpotPatchOptions(options: ResolvedSpotPatchOptions): SerializedSpotPatchOptions;
429
434
  declare function parseSerializedSpotPatchOptions(value: unknown): ResolvedSpotPatchOptions;
430
435
 
431
- export { type AgentJobEventListener, type AgentJobManager, type CaptureAskReadSnapshotOptions, type CapturedAskReadSnapshot, type ComposeContextualAskExecutorsOptions, ContextualAskError, type ContextualAskJobEventListener, type ContextualAskManager, type ContextualAskRoute, type CreateAgentJobManagerOptions, type CreateConfiguredKeyAskExecutorsOptions, type CreateContextualAskManagerOptions, type CreateExternalHandoffServiceOptions, type CreateMiddlewareOptions, DEFAULT_EXCLUDE, DEFAULT_OPTIONS, type DiscoverProjectValidationCheckOptions, type EnvironmentAiConfiguration, type ExternalAgentControlPort, type ExternalHandoffService, type FilterEntry, type IntegrationFileChange, type IntegrationPlan, type ResolveManagedExecutionValidationOptions, type ResolveProjectOptionsInput, type ResolveProjectValidationChecksOptions, type ResolvedContextualAskOptions, type ResolvedManagedExecutionValidation, type ResolvedRuntimeBootstrapOptions, type ResolvedSpotPatchDataFlowOptions, type ResolvedSpotPatchOptions, type RuntimeBootstrapOptions, type SerializedFilterEntry, type SerializedSpotPatchOptions, type SimpleAiOptions, type SourceRegistrationHandler, type SourceRegistrationService, type SourceRegistrationServiceOptions, type SourceRegistry, type SpotPatchAiOptions, type SpotPatchDataFlowOptions, type SpotPatchMiddleware, type SpotPatchNext, type SpotPatchOptions, type SpotPatchServerLogger, type SpotPatchSession, type WorkspaceActivityCoordinator, type WorkspaceActivityKind, type WorkspaceActivityLease, applyIntegrationPlan, captureAskReadSnapshot, composeContextualAskExecutors, createAgentJobManager, createConfiguredKeyAskExecutors, createContextualAskManager, createExternalHandoffService, createIntegrationFileChange, createRuntimeAiConfig, createRuntimeDataFlowConfig, createSession, createSourceRegistrationService, createSourceRegistry, createSpotPatchMiddleware, createWorkspaceActivityCoordinator, discoverProjectValidationCheck, handleContextualAskRequest, integrationPathExists, isLoopbackHostname, matchContextualAskPath, parseSerializedSpotPatchOptions, readIntegrationFile, readJsonRequestBody, readRuntimeBootstrap, resolveCredentialEnvironment, resolveEnvironmentAiConfiguration, resolveManagedExecutionValidation, resolveOptions, resolveProjectOptions, resolveProjectValidationChecks, resolveRuntimeBootstrapOptions, serializeResolvedSpotPatchOptions };
436
+ interface DevelopmentSessionInput extends Omit<CreateMiddlewareOptions, "agentManager" | "contextualAskManager" | "externalAgentControl" | "externalHandoffService"> {
437
+ readonly framework: ExternalHandoffFramework;
438
+ readonly resolveSourceImports?: CreateContextualAskManagerOptions["resolveSourceImports"];
439
+ readonly environment: Readonly<Record<string, string | undefined>>;
440
+ readonly executionRoot?: string;
441
+ readonly createManagedAskExecutor: () => ContextualAskExecutor;
442
+ readonly createExternalAgentControl: (validation: ResolvedManagedExecutionValidation) => Promise<ExternalAgentControlPort>;
443
+ readonly resolveValidation?: () => Promise<ResolvedManagedExecutionValidation>;
444
+ }
445
+ interface DevelopmentSession {
446
+ readonly middleware: SpotPatchMiddleware;
447
+ readonly close: () => Promise<void>;
448
+ }
449
+ /** Owns feature services, not HTTP listeners or framework-specific transports. */
450
+ declare function createDevelopmentSession(input: DevelopmentSessionInput): Promise<DevelopmentSession>;
451
+
452
+ export { type AgentJobEventListener, type AgentJobManager, type CaptureAskReadSnapshotOptions, type CapturedAskReadSnapshot, type ComposeContextualAskExecutorsOptions, ContextualAskError, type ContextualAskJobEventListener, type ContextualAskManager, type ContextualAskRoute, type CreateAgentJobManagerOptions, type CreateConfiguredKeyAskExecutorsOptions, type CreateContextualAskManagerOptions, type CreateExternalHandoffServiceOptions, type CreateMiddlewareOptions, DEFAULT_EXCLUDE, DEFAULT_OPTIONS, type DevelopmentSession, type DevelopmentSessionInput, type DiscoverProjectValidationCheckOptions, type EnvironmentAiConfiguration, type ExternalAgentControlPort, type ExternalHandoffService, type FilterEntry, type IntegrationFileChange, type IntegrationPlan, type ResolveManagedExecutionValidationOptions, type ResolveProjectOptionsInput, type ResolveProjectValidationChecksOptions, type ResolvedContextualAskOptions, type ResolvedManagedExecutionValidation, type ResolvedRuntimeBootstrapOptions, type ResolvedSpotPatchDataFlowOptions, type ResolvedSpotPatchOptions, type RuntimeBootstrapOptions, type SerializedFilterEntry, type SerializedSpotPatchOptions, type SimpleAiOptions, type SourceRegistrationHandler, type SourceRegistrationService, type SourceRegistrationServiceOptions, type SourceRegistry, type SpotPatchAiOptions, type SpotPatchDataFlowOptions, type SpotPatchMiddleware, type SpotPatchNext, type SpotPatchOptions, type SpotPatchServerLogger, type SpotPatchSession, type WorkspaceActivityCoordinator, type WorkspaceActivityKind, type WorkspaceActivityLease, applyIntegrationPlan, captureAskReadSnapshot, composeContextualAskExecutors, createAgentJobManager, createConfiguredKeyAskExecutors, createContextualAskManager, createDevelopmentSession, createExternalHandoffService, createIntegrationFileChange, createRuntimeAiConfig, createRuntimeDataFlowConfig, createSession, createSourceRegistrationService, createSourceRegistry, createSpotPatchMiddleware, createWorkspaceActivityCoordinator, discoverProjectValidationCheck, handleContextualAskRequest, integrationPathExists, isLoopbackHostname, matchContextualAskPath, parseSerializedSpotPatchOptions, readIntegrationFile, readJsonRequestBody, readRuntimeBootstrap, resolveCredentialEnvironment, resolveEnvironmentAiConfiguration, resolveManagedExecutionValidation, resolveOptions, resolveProjectOptions, resolveProjectValidationChecks, resolveRuntimeBootstrapOptions, serializeResolvedSpotPatchOptions };
package/dist/index.js CHANGED
@@ -1057,10 +1057,13 @@ import {
1057
1057
  } from "@spotpatch/shared";
1058
1058
  import {
1059
1059
  computeExternalHandoffProjectKey,
1060
+ assertPrivateExternalHandoffPath,
1060
1061
  externalHandoffDescriptorSchema,
1062
+ initializePrivateExternalHandoffFile,
1061
1063
  resolveExternalHandoffRuntimeDirectory
1062
1064
  } from "@spotpatch/shared/external-agent-node";
1063
1065
  async function syncDirectory(directory) {
1066
+ if (process.platform === "win32") return;
1064
1067
  const handle = await open(directory, "r");
1065
1068
  try {
1066
1069
  await handle.sync();
@@ -1110,14 +1113,11 @@ async function publishExternalHandoffDescriptor(options) {
1110
1113
  } finally {
1111
1114
  await handle.close();
1112
1115
  }
1116
+ await initializePrivateExternalHandoffFile(temporary);
1113
1117
  await rename(temporary, destination);
1114
1118
  temporaryExists = false;
1115
1119
  published = true;
1116
- const status = await lstat(destination);
1117
- const uid = process.getuid?.();
1118
- if (!status.isFile() || status.isSymbolicLink() || uid === void 0 || status.uid !== uid || (status.mode & 63) !== 0) {
1119
- throw new Error("SpotPatch external Agent descriptor is not private.");
1120
- }
1120
+ const status = await assertPrivateExternalHandoffPath(destination, "file");
1121
1121
  descriptorIdentity = Object.freeze({ device: status.dev, inode: status.ino });
1122
1122
  await syncDirectory(directory);
1123
1123
  } catch (error) {
@@ -2457,14 +2457,14 @@ async function resolveProjectOptions(input) {
2457
2457
  "SpotPatch trustedFastMode cannot be combined with applyMode auto."
2458
2458
  );
2459
2459
  }
2460
- const checks = await resolveProjectValidationChecks({
2460
+ const checks = await (input.resolveValidationChecks ?? resolveProjectValidationChecks)({
2461
2461
  appRoot: input.appRoot,
2462
2462
  checks: resolved.ai.execution.checks,
2463
2463
  timeoutMs: resolved.ai.execution.limits.checkTimeoutMs
2464
2464
  });
2465
2465
  if (!Object.values(checks).some((check) => check.required)) {
2466
2466
  throw new RangeError(
2467
- "SpotPatch trustedFastMode requires a configured required check or a local TypeScript project with tsconfig.json."
2467
+ "SpotPatch trustedFastMode requires a configured required check or an available framework-compatible local project check."
2468
2468
  );
2469
2469
  }
2470
2470
  const ai = Object.freeze({
@@ -2591,6 +2591,7 @@ import {
2591
2591
  } from "@spotpatch/shared";
2592
2592
  import { parseSync, Visitor } from "oxc-parser";
2593
2593
  var SOURCE_EXTENSIONS = Object.freeze([
2594
+ ".astro",
2594
2595
  ".ts",
2595
2596
  ".tsx",
2596
2597
  ".js",
@@ -2899,7 +2900,8 @@ async function captureAskReadSnapshot(options) {
2899
2900
  content: read.content
2900
2901
  });
2901
2902
  captured.push(entry);
2902
- for (const specifier of localSpecifiers(candidate.absolutePath, read.content)) {
2903
+ const specifiers = options.resolveSourceImports?.(candidate.absolutePath, read.content) ?? localSpecifiers(candidate.absolutePath, read.content);
2904
+ for (const specifier of specifiers.filter((value) => value.startsWith("."))) {
2903
2905
  options.signal?.throwIfAborted();
2904
2906
  for (const importPath of importCandidates(candidate.absolutePath, specifier)) {
2905
2907
  if (capturedPaths.has(importPath)) continue;
@@ -3035,6 +3037,7 @@ function fingerprint(request) {
3035
3037
  JSON.stringify({
3036
3038
  envelope: request.envelope,
3037
3039
  executorId: request.executorId,
3040
+ model: request.model,
3038
3041
  providerDataConsent: request.providerDataConsent
3039
3042
  })
3040
3043
  ).digest("hex");
@@ -3325,7 +3328,8 @@ function createContextualAskManager(options) {
3325
3328
  registry: options.registry,
3326
3329
  selection: job.request.envelope.selection,
3327
3330
  signal: job.controller.signal,
3328
- createHandleId: dependencies.createId
3331
+ createHandleId: dependencies.createId,
3332
+ ...options.resolveSourceImports === void 0 ? {} : { resolveSourceImports: options.resolveSourceImports }
3329
3333
  });
3330
3334
  if (job.controller.signal.aborted) {
3331
3335
  captured.dispose();
@@ -3339,6 +3343,7 @@ function createContextualAskManager(options) {
3339
3343
  job.executor.execute(
3340
3344
  {
3341
3345
  jobId: job.id,
3346
+ ...job.request.model === void 0 ? {} : { model: job.request.model },
3342
3347
  envelope: job.request.envelope,
3343
3348
  grant: captured.grant,
3344
3349
  snapshot: instrumentSnapshot(job, captured.snapshot, () => {
@@ -3458,6 +3463,9 @@ function createContextualAskManager(options) {
3458
3463
  )
3459
3464
  );
3460
3465
  if (isClosed()) throw new ContextualAskError("ASK_DISABLED");
3466
+ if (request.model !== void 0 && !capability.models?.includes(request.model)) {
3467
+ throw new ContextualAskError("ASK_EXECUTOR_UNAVAILABLE");
3468
+ }
3461
3469
  if (capability.executorId !== executor.executorId || capability.state !== "ready" || !capability.readOnlyProven) {
3462
3470
  throw new ContextualAskError("ASK_EXECUTOR_UNAVAILABLE");
3463
3471
  }
@@ -3474,7 +3482,11 @@ function createContextualAskManager(options) {
3474
3482
  createdAt,
3475
3483
  events: [],
3476
3484
  executor,
3477
- executorCapability: capability,
3485
+ executorCapability: request.model === void 0 ? capability : {
3486
+ ...capability,
3487
+ requestedModelLabel: request.model,
3488
+ effectiveModelLabel: request.model
3489
+ },
3478
3490
  fingerprint: requestFingerprint,
3479
3491
  id: dependencies.createId(),
3480
3492
  lease,
@@ -4119,6 +4131,7 @@ function nearbyContext(options) {
4119
4131
  });
4120
4132
  }
4121
4133
  function extractCodeContext(options) {
4134
+ if (options.language === "astro") return nearbyContext(options);
4122
4135
  const component = findComponentSpan(options);
4123
4136
  if (component !== void 0) {
4124
4137
  const range = componentRange(options.source, component);
@@ -4142,7 +4155,7 @@ function extractCodeContext(options) {
4142
4155
  import { realpath as realpath4, stat as stat2 } from "fs/promises";
4143
4156
  import path6 from "path";
4144
4157
  import { ERROR_CODES as ERROR_CODES7, SpotPatchError as SpotPatchError7 } from "@spotpatch/shared";
4145
- var ALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([".jsx", ".tsx"]);
4158
+ var ALLOWED_EXTENSIONS = /* @__PURE__ */ new Set([".jsx", ".tsx", ".astro"]);
4146
4159
  function isMissingFileError(error) {
4147
4160
  return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
4148
4161
  }
@@ -4228,7 +4241,7 @@ async function readSourceContext(options) {
4228
4241
  source,
4229
4242
  sourcePath,
4230
4243
  relativePath: toDisplayPath(await realpath5(options.root), sourcePath),
4231
- language: extension === ".tsx" ? "tsx" : "jsx",
4244
+ language: extension === ".astro" ? "astro" : extension === ".tsx" ? "tsx" : "jsx",
4232
4245
  line: options.request.line,
4233
4246
  column: options.request.column,
4234
4247
  maxLines: Math.min(options.request.maxLines, options.maxLines),
@@ -4258,7 +4271,7 @@ function compactSourceRef(source) {
4258
4271
  });
4259
4272
  }
4260
4273
  async function authorizeSourceRef(source, registry, root) {
4261
- const markerOrigin = source.origin === "jsx-host" || source.origin === "dom-ancestor";
4274
+ const markerOrigin = source.origin === "jsx-host" || source.origin === "astro-host" || source.origin === "dom-ancestor";
4262
4275
  if (markerOrigin && (source.fileId === void 0 || source.line === void 0 || source.column === void 0)) {
4263
4276
  throw new SpotPatchError9(ERROR_CODES9.INVALID_REQUEST);
4264
4277
  }
@@ -4974,7 +4987,8 @@ function createDataFlowAnalyzer(options) {
4974
4987
  root: options.root,
4975
4988
  registryEpoch: options.session.id,
4976
4989
  registerSource: (absolutePath) => options.registry.register(absolutePath),
4977
- limits: options.options.dataFlow.limits
4990
+ limits: options.options.dataFlow.limits,
4991
+ ...options.projectDataFlowSource === void 0 ? {} : { projectSource: options.projectDataFlowSource }
4978
4992
  });
4979
4993
  }
4980
4994
  async function analyzeTarget(request, analyzer, options) {
@@ -5938,6 +5952,113 @@ function parseSerializedSpotPatchOptions(value) {
5938
5952
  });
5939
5953
  }
5940
5954
  }
5955
+
5956
+ // src/development-session.ts
5957
+ async function createDevelopmentSession(input) {
5958
+ const cleanups = [
5959
+ () => {
5960
+ input.registry.clear();
5961
+ }
5962
+ ];
5963
+ let closing;
5964
+ const close = () => closing ??= (async () => {
5965
+ const errors = [];
5966
+ for (const cleanup of cleanups.splice(0).reverse()) {
5967
+ try {
5968
+ await cleanup();
5969
+ } catch (error) {
5970
+ errors.push(error);
5971
+ }
5972
+ }
5973
+ if (errors.length > 0)
5974
+ throw new AggregateError(errors, "SpotPatch service cleanup failed.");
5975
+ })();
5976
+ const warn = (message) => {
5977
+ input.logger?.warn(`[spotpatch:${input.framework}] ${message}`);
5978
+ };
5979
+ try {
5980
+ const { options, root, registry } = input;
5981
+ const coordinator = createWorkspaceActivityCoordinator();
5982
+ const agentManager = options.ai === false ? void 0 : createAgentJobManager({
5983
+ ai: options.ai,
5984
+ environment: input.environment,
5985
+ root: input.executionRoot ?? root,
5986
+ coordinator
5987
+ });
5988
+ if (agentManager !== void 0) cleanups.push(() => agentManager.close());
5989
+ const preference = options.contextualAsk.defaultExecutor === void 0 ? {} : { defaultExecutor: options.contextualAsk.defaultExecutor };
5990
+ const contextualAskManager = !options.contextualAsk.enabled ? void 0 : createContextualAskManager({
5991
+ coordinator,
5992
+ enabled: true,
5993
+ registry,
5994
+ root,
5995
+ ...input.resolveSourceImports === void 0 ? {} : { resolveSourceImports: input.resolveSourceImports },
5996
+ executors: composeContextualAskExecutors({
5997
+ configuredKey: options.ai === false ? [] : createConfiguredKeyAskExecutors({
5998
+ ai: options.ai,
5999
+ environment: input.environment,
6000
+ ...preference
6001
+ }),
6002
+ managedCodex: input.createManagedAskExecutor(),
6003
+ ...preference
6004
+ })
6005
+ });
6006
+ if (contextualAskManager !== void 0)
6007
+ cleanups.push(() => contextualAskManager.close());
6008
+ const externalHandoffService = !options.externalAgent.enabled ? void 0 : createExternalHandoffService({
6009
+ framework: input.framework,
6010
+ root,
6011
+ sessionId: input.session.id
6012
+ });
6013
+ let externalAgentControl;
6014
+ if (externalHandoffService !== void 0) {
6015
+ cleanups.push(() => externalHandoffService.close());
6016
+ try {
6017
+ await externalHandoffService.start();
6018
+ } catch {
6019
+ warn("External Agent handoff is unavailable; core tools remain active.");
6020
+ }
6021
+ if (externalHandoffService.capability().brokerReady) {
6022
+ try {
6023
+ const validation = await (input.resolveValidation?.() ?? resolveManagedExecutionValidation({ ai: options.ai, appRoot: root }));
6024
+ const control = await input.createExternalAgentControl(validation);
6025
+ externalAgentControl = control;
6026
+ cleanups.push(() => control.dispose());
6027
+ } catch {
6028
+ warn("Managed Agent control is unavailable; Inbox remains active.");
6029
+ }
6030
+ }
6031
+ }
6032
+ const middleware = createSpotPatchMiddleware({
6033
+ options,
6034
+ root,
6035
+ registry,
6036
+ session: input.session,
6037
+ ...input.projectDataFlowSource === void 0 ? {} : { projectDataFlowSource: input.projectDataFlowSource },
6038
+ ...input.bootstrap === void 0 ? {} : { bootstrap: input.bootstrap },
6039
+ ...input.logger === void 0 ? {} : { logger: input.logger },
6040
+ ...input.editorLauncher === void 0 ? {} : { editorLauncher: input.editorLauncher },
6041
+ ...agentManager === void 0 ? {} : { agentManager },
6042
+ ...contextualAskManager === void 0 ? {} : { contextualAskManager },
6043
+ ...externalHandoffService === void 0 ? {} : { externalHandoffService },
6044
+ ...externalAgentControl === void 0 ? {} : { externalAgentControl }
6045
+ });
6046
+ cleanups.push(() => {
6047
+ middleware.dispose();
6048
+ });
6049
+ return Object.freeze({ middleware, close });
6050
+ } catch (error) {
6051
+ try {
6052
+ await close();
6053
+ } catch (cleanupError) {
6054
+ throw new AggregateError(
6055
+ [error, cleanupError],
6056
+ "SpotPatch service startup and cleanup failed."
6057
+ );
6058
+ }
6059
+ throw error;
6060
+ }
6061
+ }
5941
6062
  export {
5942
6063
  ContextualAskError,
5943
6064
  DEFAULT_EXCLUDE,
@@ -5948,6 +6069,7 @@ export {
5948
6069
  createAgentJobManager,
5949
6070
  createConfiguredKeyAskExecutors,
5950
6071
  createContextualAskManager,
6072
+ createDevelopmentSession,
5951
6073
  createExternalHandoffService,
5952
6074
  createIntegrationFileChange,
5953
6075
  createRuntimeAiConfig,