@openagentpack/sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as CloudAgent, a as CloudEnvironment, b as CloudVault, R as ResourceAddress, c as ResourceType, E as EventStreamOptions, P as ProviderSessionEvent, d as EventListOptions, e as ProviderSessionEventList, f as PlannedAction, D as Diagnostic, A as AgentDefinition, g as AgentWithReadiness, h as AgentSyncRun } from './session-event-5kLRNMHC.js';
2
- export { i as ActionType, j as ActionTypeSchema, k as AgentDefinitionSchema, l as AgentDriftSeverity, m as AgentDriftSeveritySchema, n as AgentModel, o as AgentModelSchema, p as AgentReadiness, q as AgentReadinessSchema, r as AgentReadinessStatus, s as AgentReadinessStatusSchema, t as AgentRecoveryAction, u as AgentRecoveryActionSchema, v as AgentSkillRef, w as AgentSkillRefSchema, x as AgentSyncResult, y as AgentSyncResultSchema, z as AgentSyncRunSchema, B as AgentSyncStatus, F as AgentSyncStatusSchema, G as AgentWithReadinessSchema, H as CloudAgentSchema, I as CloudEnvironmentSchema, J as CloudVaultSchema, K as CreateSessionRequest, L as CreateSessionRequestSchema, M as CreateSessionResponse, N as CreateSessionResponseSchema, O as DiagnosticSchema, Q as DiagnosticSeverity, S as DiagnosticSeveritySchema, T as DriftKind, U as DriftKindSchema, V as GetSessionRequest, W as GetSessionRequestSchema, X as KNOWN_SESSION_EVENT_TYPES, Y as KnownSessionEventType, Z as ListCloudAgentsResponse, _ as ListCloudAgentsResponseSchema, $ as ListCloudEnvironmentsResponse, a0 as ListCloudEnvironmentsResponseSchema, a1 as ListSessionEventsRequest, a2 as ListSessionEventsRequestSchema, a3 as ListSessionEventsResponse, a4 as ListSessionEventsResponseSchema, a5 as ListSessionsRequest, a6 as ListSessionsRequestSchema, a7 as ListSessionsResponse, a8 as ListSessionsResponseSchema, a9 as PlanReadinessImpact, aa as PlanReadinessImpactSchema, ab as PlannedActionSchema, ac as ResourceAddressSchema, ad as ResourceTypeSchema, ae as SendEventRequest, af as SendEventRequestSchema, ag as SendEventResponse, ah as SendEventResponseSchema, ai as Session, aj as SessionAgent, ak as SessionAgentSchema, al as SessionContentBlock, am as SessionContentBlockSchema, an as SessionEvent, ao as SessionEventSchema, ap as SessionEventType, aq as SessionEventTypeName, ar as SessionEventTypeSchema, as as SessionSchema } from './session-event-5kLRNMHC.js';
1
+ import { C as CloudAgent, a as CloudEnvironment, b as CloudVault, R as ResourceAddress, c as ResourceType, E as EventStreamOptions, P as ProviderSessionEvent, d as EventListOptions, e as ProviderSessionEventList, f as PlannedAction, D as Diagnostic, A as AgentDefinition, g as AgentReadiness, h as AgentWithReadiness, i as AgentSyncRun } from './session-event-B63Rbjim.js';
2
+ export { j as ActionType, k as ActionTypeSchema, l as AgentDefinitionSchema, m as AgentDriftSeverity, n as AgentDriftSeveritySchema, o as AgentModel, p as AgentModelSchema, q as AgentReadinessSchema, r as AgentReadinessStatus, s as AgentReadinessStatusSchema, t as AgentRecoveryAction, u as AgentRecoveryActionSchema, v as AgentSkillRef, w as AgentSkillRefSchema, x as AgentSyncReason, y as AgentSyncReasonSchema, z as AgentSyncResult, B as AgentSyncResultSchema, F as AgentSyncRunSchema, G as AgentSyncStatus, H as AgentSyncStatusSchema, I as AgentWithReadinessSchema, J as CloudAgentSchema, K as CloudEnvironmentSchema, L as CloudVaultSchema, M as CreateSessionRequest, N as CreateSessionRequestSchema, O as CreateSessionResponse, Q as CreateSessionResponseSchema, S as DiagnosticSchema, T as DiagnosticSeverity, U as DiagnosticSeveritySchema, V as DriftKind, W as DriftKindSchema, X as GetSessionRequest, Y as GetSessionRequestSchema, Z as KNOWN_SESSION_EVENT_TYPES, _ as KnownSessionEventType, $ as ListCloudAgentsResponse, a0 as ListCloudAgentsResponseSchema, a1 as ListCloudEnvironmentsResponse, a2 as ListCloudEnvironmentsResponseSchema, a3 as ListSessionEventsRequest, a4 as ListSessionEventsRequestSchema, a5 as ListSessionEventsResponse, a6 as ListSessionEventsResponseSchema, a7 as ListSessionsRequest, a8 as ListSessionsRequestSchema, a9 as ListSessionsResponse, aa as ListSessionsResponseSchema, ab as PlanReadinessImpact, ac as PlanReadinessImpactSchema, ad as PlannedActionSchema, ae as ResourceAddressSchema, af as ResourceTypeSchema, ag as SendEventRequest, ah as SendEventRequestSchema, ai as SendEventResponse, aj as SendEventResponseSchema, ak as Session, al as SessionAgent, am as SessionAgentSchema, an as SessionContentBlock, ao as SessionContentBlockSchema, ap as SessionEvent, aq as SessionEventSchema, ar as SessionEventType, as as SessionEventTypeName, at as SessionEventTypeSchema, au as SessionSchema } from './session-event-B63Rbjim.js';
3
3
  import { P as ProviderFileInfo } from './file-Cj5-Vx27.js';
4
4
  import 'zod';
5
5
 
@@ -90,6 +90,15 @@ interface VaultDecl {
90
90
  metadata?: Record<string, string>;
91
91
  }
92
92
  type CredentialType = "static_bearer" | "environment_variable";
93
+ interface CredentialNetworking {
94
+ /** Legacy policy type; Bailian requests use allowed_hosts instead. */
95
+ type?: "unrestricted" | "limited";
96
+ allowed_hosts?: string[];
97
+ }
98
+ interface CredentialInjectionLocation {
99
+ header?: boolean;
100
+ body?: boolean;
101
+ }
93
102
  interface CredentialDecl {
94
103
  name: string;
95
104
  type: CredentialType;
@@ -99,9 +108,8 @@ interface CredentialDecl {
99
108
  protocol?: "sse" | "streamable_http";
100
109
  secret_name?: string;
101
110
  secret_value?: string;
102
- networking?: {
103
- type: "unrestricted" | "limited";
104
- };
111
+ networking?: CredentialNetworking;
112
+ injection_location?: CredentialInjectionLocation;
105
113
  }
106
114
  interface MemoryStoreDecl {
107
115
  description: string;
@@ -123,6 +131,7 @@ interface SkillDecl {
123
131
  }
124
132
  interface FileDecl {
125
133
  source: string;
134
+ /** Local label only; declarative uploads preserve the source file's basename. */
126
135
  name?: string;
127
136
  purpose?: string;
128
137
  provider?: ProviderName;
@@ -144,9 +153,9 @@ interface AgentDecl {
144
153
  mcp_servers?: McpServerDecl[];
145
154
  skills?: AgentSkillDecl[];
146
155
  vault?: string;
147
- /** File declarations inherited by a Qoder Forward Template. */
148
- files?: string[];
149
156
  memory_stores?: string[];
157
+ /** String refs are inherited by Qoder Forward Templates; object refs mount Files into Sessions. */
158
+ files?: Array<string | AgentFileMountDecl>;
150
159
  /** Desired display metadata for Qoder Forward's system-managed writable Store. */
151
160
  default_memory_store?: DefaultMemoryStoreDecl;
152
161
  /** Resources mounted into every managed session created for this agent. */
@@ -160,6 +169,12 @@ interface AgentDecl {
160
169
  /** Provider-specific remote materialization. Omitted means the existing managed Agent resource. */
161
170
  delivery?: Record<ProviderName, AgentDeliveryDecl>;
162
171
  }
172
+ interface AgentFileMountDecl {
173
+ /** Logical key under the top-level files section. */
174
+ file: string;
175
+ /** Provider sandbox path. Bailian paths live under /mnt. */
176
+ mount_path: string;
177
+ }
163
178
  interface DefaultMemoryStoreDecl {
164
179
  name: string;
165
180
  description?: string;
@@ -335,6 +350,8 @@ interface VaultCredentialInfo {
335
350
  secret_name?: string;
336
351
  mcp_server_url?: string;
337
352
  networking_type?: string;
353
+ networking?: CredentialNetworking;
354
+ injection_location?: CredentialInjectionLocation;
338
355
  metadata?: Record<string, string>;
339
356
  }
340
357
  interface SkillListOptions extends CursorListOptions {
@@ -1013,11 +1030,15 @@ interface ResolveProjectConfigOptions {
1013
1030
  projectName?: string;
1014
1031
  /** Expand `${env:...}` references while loading (defaults to true). */
1015
1032
  resolveEnv?: boolean;
1033
+ /** Project-local fallback values; the process environment takes precedence. Never mutates process.env. */
1034
+ environment?: Record<string, string>;
1016
1035
  }
1017
1036
  interface LoadedProjectConfig {
1018
1037
  configPath: string;
1019
1038
  projectName: string;
1020
1039
  config: ResolvedProjectConfig;
1040
+ /** Root config and local files/directories that influence the resolved project. */
1041
+ sourcePaths: string[];
1021
1042
  }
1022
1043
  /**
1023
1044
  * Shared config-resolution spine for every host: load the config file, raise
@@ -1030,6 +1051,10 @@ interface ResolveProjectConfigFromObjectOptions {
1030
1051
  projectName: string;
1031
1052
  /** Base path used to resolve any `file:` references (defaults to process.cwd()). */
1032
1053
  basePath?: string;
1054
+ /** Resolve `${ENV_VAR}` references recursively before schema validation. */
1055
+ resolveEnv?: boolean;
1056
+ /** Project-local fallback values; the process environment takes precedence. */
1057
+ environment?: Record<string, string>;
1033
1058
  }
1034
1059
  /**
1035
1060
  * Object-level twin of {@link resolveProjectConfig}: validate an in-memory config
@@ -1063,6 +1088,7 @@ interface ResourceRuntimeOptions extends DestructiveDecisionOptions {
1063
1088
  refreshOnly?: boolean;
1064
1089
  quiet?: boolean;
1065
1090
  onFeedback?: RuntimeFeedbackSink;
1091
+ concurrency?: number;
1066
1092
  }
1067
1093
  type ResourceSyncMode = "reconcile" | "create-only";
1068
1094
  interface ResourcePlanScope {
@@ -1128,6 +1154,14 @@ declare function validateProjectConfig(config: ProjectConfig, options?: Validate
1128
1154
  */
1129
1155
  declare function collectConfigReferences(config: ProjectConfig): Diagnostic[];
1130
1156
 
1157
+ interface ProjectSourceInspection {
1158
+ diagnostics: Diagnostic[];
1159
+ redacted_source: string;
1160
+ sensitive_literals: string[];
1161
+ }
1162
+ /** Validates a complete agents.yaml source and produces a display-safe copy. */
1163
+ declare function inspectProjectSource(source: string, configPath: string): Promise<ProjectSourceInspection>;
1164
+
1131
1165
  interface SyncProjectOptions {
1132
1166
  /** Provider to read remote resources from (single provider, not "all"). */
1133
1167
  provider: string;
@@ -1497,6 +1531,7 @@ declare function buildAgentDecl(base: AgentDecl | undefined, input: AgentBuildIn
1497
1531
  interface AgentResourcePlan {
1498
1532
  agentId: string;
1499
1533
  provider: string;
1534
+ fingerprint: string;
1500
1535
  actions: PlannedAction[];
1501
1536
  diagnostics: Diagnostic[];
1502
1537
  destructiveActions: PlannedAction[];
@@ -1505,12 +1540,17 @@ interface AgentResourcePlan {
1505
1540
  interface AgentResourcePlanOptions {
1506
1541
  refresh?: boolean;
1507
1542
  quiet?: boolean;
1543
+ onFeedback?: RuntimeFeedbackSink;
1544
+ /** Strict Agent runtime closure; excludes downstream resources such as deployments. */
1545
+ scope?: "runtime";
1508
1546
  mode?: AgentResourceSyncMode;
1509
1547
  }
1510
1548
  type AgentResourceSyncMode = ResourceSyncMode;
1511
1549
  interface AgentResourceSyncOptions extends AgentResourcePlanOptions {
1512
1550
  policy?: DestructivePolicy;
1513
1551
  confirm?: (actions: PlannedAction[]) => boolean | Promise<boolean>;
1552
+ /** Refuse execution when a fresh plan no longer matches the plan shown to the user. */
1553
+ expectedPlanFingerprint?: string;
1514
1554
  }
1515
1555
  /**
1516
1556
  * List RAW cloud agents from the provider — the actual remote objects, not the local
@@ -1567,6 +1607,7 @@ declare function getAgent(ctx: ProjectRuntimeContext, agentId: string): AgentDef
1567
1607
  declare function listAgentsWithReadiness(ctx: ProjectRuntimeContext, options?: {
1568
1608
  refresh?: boolean;
1569
1609
  }): Promise<AgentWithReadiness[]>;
1610
+ declare function isAgentRunnable(readiness: AgentReadiness): boolean;
1570
1611
  declare function planAgentResources(ctx: ProjectRuntimeContext, agentId: string, options?: AgentResourcePlanOptions): Promise<AgentResourcePlan>;
1571
1612
  declare function planAgentResourcesWithStateBackend(input: BackendRuntimeInput, agentId: string, options?: AgentResourcePlanOptions): Promise<AgentResourcePlan>;
1572
1613
  declare function syncAgentResourcesWithStateBackend(input: BackendRuntimeInput, agentId: string, options?: AgentResourceSyncOptions): Promise<AgentSyncRun>;
@@ -1797,4 +1838,4 @@ declare function inspectSkillSource(source: string, options?: {
1797
1838
  basePath?: string;
1798
1839
  }): Promise<SkillSourceInspection>;
1799
1840
 
1800
- export { AGENTS_CONFIG_PROVIDERS, AGENTS_PROVIDER_FIELDS, type AgentBuildInput, AgentDefinition, type AgentListOptions, type AgentMcpBuildInput, type AgentPage, type AgentResourcePlan, type AgentResourcePlanOptions, type AgentResourceSyncMode, type AgentResourceSyncOptions, type AgentSkillBuildInput, AgentSyncRun, type AgentVersionListOptions, AgentWithReadiness, ApiError, type BackendRuntimeInput, type BatchCreateMemoryInput, type BatchCreateMemoryResult, CloudAgent, CloudEnvironment, CloudVault, type CollectedSessionEvents, ConflictError, type CreateMemoryInput, type CreateMemoryStoreInput, type CredentialDecl, type CursorListOptions, type CursorPage, type DeploymentDecl, type DeploymentInfo$1 as DeploymentInfo, type DeploymentListFilter, type DeploymentListResult, type DeploymentRunInfo, type DeploymentRunPage, type DeploymentRunResult$1 as DeploymentRunResult, type DestroyDefaultMemoryStoreResult, type DestroyResourceResult, type DestructivePolicy, Diagnostic, type EnvironmentDecl, type EnvironmentListOptions, type EnvironmentPage, EventListOptions, EventStreamOptions, type FetchLike, type FileListOptions, type FilePage, type IStateManager, type LoadedProjectConfig, LocalFileStateBackend, type ManagedAgentOperationAuth, type ManagedAgentOperationCapability, type ManagedAgentProviderCapabilities, type ManagedApiTarget, type MemoryInfo, type MemoryListItem, type MemoryListOptions, type MemoryPage, type MemoryPrefixInfo, type MemoryProviderCapabilities, type MemoryStoreInfo, type MemoryStoreListOptions, type MemoryVersionInfo, type MemoryVersionListOptions, type MigrateOptions, type MigrateResult, PlannedAction, type ProjectConfig, type ProjectRuntimeContext, type ProviderConfig, type ProviderConfigProvider, ProviderFileInfo, ProviderSessionEvent, ProviderSessionEventList, type ProviderSessionInfo, type ProviderSkillInfo, type ResolvedProjectConfig, type ResourceActionResult, ResourceAddress, type ResourceExecutionResult, type ResourcePlanResult, type ResourcePlanScope, type ResourceRefreshResult, type ResourceRuntimeOptions, type ResourceState, type ResourceSyncMode, type ResourceSyncRun, ResourceType, type RuntimeFeedbackEvent, type RuntimeFeedbackSink, type SecretPlaceholder, type SessionEventInput, type SessionEventSendResult, type SessionFilter, type SessionListResult, type SessionUpdateInput, type SkillDecl, type SkillDownloadInfo, type SkillFile, type SkillListOptions, type SkillPage, type SkillSourceInspection, type SkillVersionInfo, type SkillVersionListOptions, type SkillVersionPage, StateManager, type StateScope, type SyncProjectOptions, type SyncProjectResult, type UpdateMemoryInput, type UpdateMemoryStoreInput, UserError, type ValidateProjectConfigOptions, type VaultCredentialCreateOptions, type VaultCredentialCreatePlan, type VaultCredentialCreateResult, type VaultCredentialInfo, type VaultDecl, type VaultListOptions, type VaultPage, applyProviderConfigToEnv, archiveCloudAgent, archiveMemoryStore, archiveRemoteSession, areRuntimeCredentialsReady, batchCreateMemories, bootstrapRuntimeCredentials, bootstrapRuntimeCredentialsSync, buildAgentDecl, collectConfigReferences, createCloudEnvironment, createCloudVault, createMemory, createMemoryStore, createProjectRuntime, createSessionForAgent, createSkillFromFileId, createVaultCredential, createVaultCredentialWithStateBackend, decideDestructive, deleteCloudEnvironment, deleteCloudVault, deleteFile, deleteMemory, deleteMemoryStore, deleteSession, deleteSkill, destroyPlannedProjectResources, downloadRemoteFile, downloadRemoteSkill, executePlannedProject, extractSkillZipFiles, getAgent, getDeploymentDetailsForContext, getDeploymentRuntimeProviderForContext, getFileDownloadUrl, getFileInfo, getManagedAgentProviderCapabilities, getMemory, getMemoryProviderCapabilities, getMemoryStore, getMemoryVersion, getRemoteAgent, getRemoteDeployment, getRemoteDeploymentRun, getRemoteEnvironment, getRemoteSkill, getRemoteSkillDownloadInfo, getRemoteSkillVersion, getRemoteVault, getSession, getSkillInfo, importResource, inspectSkillSource, isTerminalSessionStatus, listAgentsWithReadiness, listCloudAgents, listCloudEnvironments, listCloudVaults, listDeploymentsForContext, listFiles, listMemories, listMemoryStores, listMemoryVersions, listProviderModelsForContext, listProviderNames, listRemoteAgentVersions, listRemoteAgents, listRemoteDeploymentRuns, listRemoteDeployments, listRemoteDeploymentsForContext, listRemoteEnvironments, listRemoteFiles, listRemoteSkillVersions, listRemoteSkills, listRemoteVaults, listSessionEvents, listSessionSummaries, listSkills, loadDotEnv, loadProviderConfigIntoEnv, loadProviderConfigIntoEnvSync, migrateConfig, parseStateAddress, pauseDeploymentForContext, planAgentResources, planAgentResourcesWithStateBackend, planDestroyProjectContext, planProjectContext, planProjectWithStateBackend, planVaultCredentialCreate, planVaultCredentialCreateWithStateBackend, prepareInitialSessionPrompt, preparePromptForProvider, prependFileHint, providerConfigPath, readProjectRuntime, redactMemoryVersion, resolveActiveProvider, resolveProjectConfig, resolveProjectConfigFromObject, resolveProviderConfigFromEnv, resolveRepositoryMountPath, resolveSessionProvider, resolveSyncProvider, rewriteFileMentions, runDeploymentForContext, runRemoteDeployment, sendRemoteSessionEvents, sendSessionMessagePolling, sendSessionMessageStreaming, setDefaultFetch, setRemoteDeploymentPaused, startSessionRun, startSessionRunPolling, streamSessionEvents, syncAgentResourcesWithStateBackend, syncProjectResourcesWithStateBackend, syncProviderResourcesFromContext, syncProviderResourcesFromEnv, updateMemory, updateMemoryStore, updateRemoteSession, uploadFile, validateProjectConfig, writeProjectRuntime };
1841
+ export { AGENTS_CONFIG_PROVIDERS, AGENTS_PROVIDER_FIELDS, type AgentBuildInput, AgentDefinition, type AgentListOptions, type AgentMcpBuildInput, type AgentPage, AgentReadiness, type AgentResourcePlan, type AgentResourcePlanOptions, type AgentResourceSyncMode, type AgentResourceSyncOptions, type AgentSkillBuildInput, AgentSyncRun, type AgentVersionListOptions, AgentWithReadiness, ApiError, type BackendRuntimeInput, type BatchCreateMemoryInput, type BatchCreateMemoryResult, CloudAgent, CloudEnvironment, CloudVault, type CollectedSessionEvents, ConflictError, type CreateMemoryInput, type CreateMemoryStoreInput, type CredentialDecl, type CredentialInjectionLocation, type CredentialNetworking, type CursorListOptions, type CursorPage, type DeploymentDecl, type DeploymentInfo$1 as DeploymentInfo, type DeploymentListFilter, type DeploymentListResult, type DeploymentRunInfo, type DeploymentRunPage, type DeploymentRunResult$1 as DeploymentRunResult, type DestroyDefaultMemoryStoreResult, type DestroyResourceResult, type DestructivePolicy, Diagnostic, type EnvironmentDecl, type EnvironmentListOptions, type EnvironmentPage, EventListOptions, EventStreamOptions, type FetchLike, type FileListOptions, type FilePage, type IStateManager, type LoadedProjectConfig, LocalFileStateBackend, type ManagedAgentOperationAuth, type ManagedAgentOperationCapability, type ManagedAgentProviderCapabilities, type ManagedApiTarget, type MemoryInfo, type MemoryListItem, type MemoryListOptions, type MemoryPage, type MemoryPrefixInfo, type MemoryProviderCapabilities, type MemoryStoreInfo, type MemoryStoreListOptions, type MemoryVersionInfo, type MemoryVersionListOptions, type MigrateOptions, type MigrateResult, PlannedAction, type ProjectConfig, type ProjectRuntimeContext, type ProjectSourceInspection, type ProviderConfig, type ProviderConfigProvider, ProviderFileInfo, ProviderSessionEvent, ProviderSessionEventList, type ProviderSessionInfo, type ProviderSkillInfo, type ResolvedProjectConfig, type ResourceActionResult, ResourceAddress, type ResourceExecutionResult, type ResourcePlanResult, type ResourcePlanScope, type ResourceRefreshResult, type ResourceRuntimeOptions, type ResourceState, type ResourceSyncMode, type ResourceSyncRun, ResourceType, type RuntimeFeedbackEvent, type RuntimeFeedbackSink, type SecretPlaceholder, type SessionEventInput, type SessionEventSendResult, type SessionFilter, type SessionListResult, type SessionUpdateInput, type SkillDecl, type SkillDownloadInfo, type SkillFile, type SkillListOptions, type SkillPage, type SkillSourceInspection, type SkillVersionInfo, type SkillVersionListOptions, type SkillVersionPage, StateManager, type StateScope, type SyncProjectOptions, type SyncProjectResult, type UpdateMemoryInput, type UpdateMemoryStoreInput, UserError, type ValidateProjectConfigOptions, type VaultCredentialCreateOptions, type VaultCredentialCreatePlan, type VaultCredentialCreateResult, type VaultCredentialInfo, type VaultDecl, type VaultListOptions, type VaultPage, applyProviderConfigToEnv, archiveCloudAgent, archiveMemoryStore, archiveRemoteSession, areRuntimeCredentialsReady, batchCreateMemories, bootstrapRuntimeCredentials, bootstrapRuntimeCredentialsSync, buildAgentDecl, collectConfigReferences, createCloudEnvironment, createCloudVault, createMemory, createMemoryStore, createProjectRuntime, createSessionForAgent, createSkillFromFileId, createVaultCredential, createVaultCredentialWithStateBackend, decideDestructive, deleteCloudEnvironment, deleteCloudVault, deleteFile, deleteMemory, deleteMemoryStore, deleteSession, deleteSkill, destroyPlannedProjectResources, downloadRemoteFile, downloadRemoteSkill, executePlannedProject, extractSkillZipFiles, getAgent, getDeploymentDetailsForContext, getDeploymentRuntimeProviderForContext, getFileDownloadUrl, getFileInfo, getManagedAgentProviderCapabilities, getMemory, getMemoryProviderCapabilities, getMemoryStore, getMemoryVersion, getRemoteAgent, getRemoteDeployment, getRemoteDeploymentRun, getRemoteEnvironment, getRemoteSkill, getRemoteSkillDownloadInfo, getRemoteSkillVersion, getRemoteVault, getSession, getSkillInfo, importResource, inspectProjectSource, inspectSkillSource, isAgentRunnable, isTerminalSessionStatus, listAgentsWithReadiness, listCloudAgents, listCloudEnvironments, listCloudVaults, listDeploymentsForContext, listFiles, listMemories, listMemoryStores, listMemoryVersions, listProviderModelsForContext, listProviderNames, listRemoteAgentVersions, listRemoteAgents, listRemoteDeploymentRuns, listRemoteDeployments, listRemoteDeploymentsForContext, listRemoteEnvironments, listRemoteFiles, listRemoteSkillVersions, listRemoteSkills, listRemoteVaults, listSessionEvents, listSessionSummaries, listSkills, loadDotEnv, loadProviderConfigIntoEnv, loadProviderConfigIntoEnvSync, migrateConfig, parseStateAddress, pauseDeploymentForContext, planAgentResources, planAgentResourcesWithStateBackend, planDestroyProjectContext, planProjectContext, planProjectWithStateBackend, planVaultCredentialCreate, planVaultCredentialCreateWithStateBackend, prepareInitialSessionPrompt, preparePromptForProvider, prependFileHint, providerConfigPath, readProjectRuntime, redactMemoryVersion, resolveActiveProvider, resolveProjectConfig, resolveProjectConfigFromObject, resolveProviderConfigFromEnv, resolveRepositoryMountPath, resolveSessionProvider, resolveSyncProvider, rewriteFileMentions, runDeploymentForContext, runRemoteDeployment, sendRemoteSessionEvents, sendSessionMessagePolling, sendSessionMessageStreaming, setDefaultFetch, setRemoteDeploymentPaused, startSessionRun, startSessionRunPolling, streamSessionEvents, syncAgentResourcesWithStateBackend, syncProjectResourcesWithStateBackend, syncProviderResourcesFromContext, syncProviderResourcesFromEnv, updateMemory, updateMemoryStore, updateRemoteSession, uploadFile, validateProjectConfig, writeProjectRuntime };
package/dist/index.js CHANGED
@@ -3662,12 +3662,16 @@ function mapCredential2(cred) {
3662
3662
  `credential '${cred.name}': Bailian only supports credential type 'environment_variable', but '${cred.type}' was declared.`
3663
3663
  );
3664
3664
  }
3665
+ if (cred.networking?.type === "limited" && cred.networking.allowed_hosts === void 0) {
3666
+ throw new UserError(`credential '${cred.name}': Bailian limited networking requires networking.allowed_hosts.`);
3667
+ }
3665
3668
  const body = {
3666
3669
  auth: {
3667
3670
  type: "environment_variable",
3668
3671
  secret_name: cred.secret_name,
3669
3672
  secret_value: cred.secret_value,
3670
- networking: cred.networking ?? { type: "unrestricted" }
3673
+ networking: { allowed_hosts: cred.networking?.allowed_hosts ?? ["*"] },
3674
+ injection_location: cred.injection_location ?? { header: true, body: false }
3671
3675
  },
3672
3676
  display_name: cred.name
3673
3677
  };
@@ -3688,13 +3692,15 @@ function credToDecl3(raw, vaultName) {
3688
3692
  };
3689
3693
  }
3690
3694
  const networking = auth.networking;
3695
+ const injectionLocation = auth.injection_location;
3691
3696
  return {
3692
3697
  name,
3693
3698
  type: "environment_variable",
3694
3699
  metadata: stripAgentsMetadata(raw.metadata),
3695
3700
  secret_name: auth.secret_name ?? name,
3696
3701
  secret_value: placeholder,
3697
- networking: networking ?? { type: "unrestricted" }
3702
+ networking: networking ?? { type: "unrestricted" },
3703
+ ...injectionLocation ? { injection_location: injectionLocation } : {}
3698
3704
  };
3699
3705
  }
3700
3706
  function vaultToDecl3(raw, rawCredentials, resourceName) {
@@ -4360,6 +4366,8 @@ var BailianAdapter = class _BailianAdapter {
4360
4366
  secret_name: auth.secret_name,
4361
4367
  mcp_server_url: auth.mcp_server_url,
4362
4368
  networking_type: networking?.type,
4369
+ networking,
4370
+ injection_location: auth.injection_location,
4363
4371
  metadata: metadata ? Object.fromEntries(
4364
4372
  Object.entries(metadata).filter((entry) => typeof entry[1] === "string")
4365
4373
  ) : void 0
@@ -5726,6 +5734,30 @@ async function resolveFileReferences(config, configPath) {
5726
5734
  // src/internal/parser/resolve-project-config.ts
5727
5735
  import { basename as basename5, dirname as dirname7, resolve as resolve7 } from "path";
5728
5736
 
5737
+ // src/internal/utils/env.ts
5738
+ var ENV_VAR_PATTERN = /\$\{([^}]+)\}/g;
5739
+ function interpolateEnvVars(value, resolve13 = false, environment = process.env) {
5740
+ return value.replace(ENV_VAR_PATTERN, (match, varName) => {
5741
+ if (!resolve13) return match;
5742
+ const resolvedValue = environment[varName];
5743
+ if (resolvedValue === void 0) {
5744
+ throw new UserError(`Environment variable '${varName}' is not set`);
5745
+ }
5746
+ return resolvedValue;
5747
+ });
5748
+ }
5749
+ function interpolateObjectEnv(value, environment = process.env) {
5750
+ if (typeof value === "string") return interpolateEnvVars(value, true, environment);
5751
+ if (Array.isArray(value)) return value.map((entry) => interpolateObjectEnv(entry, environment));
5752
+ if (!value || typeof value !== "object") return value;
5753
+ return Object.fromEntries(
5754
+ Object.entries(value).map(([key, entry]) => [
5755
+ key,
5756
+ interpolateObjectEnv(entry, environment)
5757
+ ])
5758
+ );
5759
+ }
5760
+
5729
5761
  // src/internal/parser/schema.ts
5730
5762
  import { z as z5 } from "zod";
5731
5763
  var networkingSchema = z5.object({
@@ -5781,7 +5813,14 @@ var environmentVariableCredentialSchema = z5.object({
5781
5813
  metadata: z5.record(z5.string(), z5.string()).optional(),
5782
5814
  secret_name: z5.string(),
5783
5815
  secret_value: coerceString,
5784
- networking: z5.object({ type: z5.enum(["unrestricted", "limited"]) }).optional()
5816
+ networking: z5.object({
5817
+ type: z5.enum(["unrestricted", "limited"]).optional(),
5818
+ allowed_hosts: z5.array(z5.string()).optional()
5819
+ }).optional(),
5820
+ injection_location: z5.object({
5821
+ header: z5.boolean().optional(),
5822
+ body: z5.boolean().optional()
5823
+ }).optional()
5785
5824
  });
5786
5825
  var credentialSchema = z5.discriminatedUnion("type", [
5787
5826
  staticBearerCredentialSchema,
@@ -5921,6 +5960,10 @@ var agentSkillRefSchema = z5.object({
5921
5960
  var agentDeliverySchema = z5.object({
5922
5961
  type: z5.enum(["managed", "forward"])
5923
5962
  });
5963
+ var agentFileMountSchema = z5.object({
5964
+ file: z5.string().min(1),
5965
+ mount_path: z5.string().min(1)
5966
+ });
5924
5967
  var managedToolConfigSchema = z5.object({
5925
5968
  enabled_tools: z5.array(z5.string().min(1))
5926
5969
  });
@@ -5945,8 +5988,8 @@ var agentSchema = z5.object({
5945
5988
  mcp_servers: z5.array(mcpServerSchema).optional(),
5946
5989
  skills: z5.array(z5.union([z5.string(), agentSkillRefSchema])).optional(),
5947
5990
  vault: z5.string().optional(),
5948
- files: z5.array(z5.string()).optional(),
5949
5991
  memory_stores: z5.array(z5.string()).optional(),
5992
+ files: z5.array(z5.union([z5.string().min(1), agentFileMountSchema])).optional(),
5950
5993
  default_memory_store: z5.object({
5951
5994
  name: z5.string().trim().min(1).max(255),
5952
5995
  description: z5.string().max(1024).optional(),
@@ -6049,22 +6092,7 @@ var projectConfigSchema = z5.object({
6049
6092
  // src/internal/parser/yaml-loader.ts
6050
6093
  import { readFile as readFile3 } from "fs/promises";
6051
6094
  import { parse as parseYaml } from "yaml";
6052
-
6053
- // src/internal/utils/env.ts
6054
- var ENV_VAR_PATTERN = /\$\{([^}]+)\}/g;
6055
- function interpolateEnvVars(value, resolve13 = false) {
6056
- return value.replace(ENV_VAR_PATTERN, (match, varName) => {
6057
- if (!resolve13) return match;
6058
- const val = process.env[varName];
6059
- if (val === void 0) {
6060
- throw new UserError(`Environment variable '${varName}' is not set`);
6061
- }
6062
- return val;
6063
- });
6064
- }
6065
-
6066
- // src/internal/parser/yaml-loader.ts
6067
- async function loadConfig(filePath, resolveEnv = false) {
6095
+ async function loadConfig(filePath, resolveEnv = false, environment) {
6068
6096
  let raw;
6069
6097
  try {
6070
6098
  raw = await readFile3(filePath, "utf8");
@@ -6075,7 +6103,7 @@ async function loadConfig(filePath, resolveEnv = false) {
6075
6103
  const msg = err instanceof Error ? err.message : String(err);
6076
6104
  return { config: null, errors: [`Failed to read file: ${msg}`] };
6077
6105
  }
6078
- if (resolveEnv) {
6106
+ if (resolveEnv && !environment) {
6079
6107
  raw = interpolateEnvVars(raw, true);
6080
6108
  }
6081
6109
  let parsed;
@@ -6085,6 +6113,7 @@ async function loadConfig(filePath, resolveEnv = false) {
6085
6113
  const msg = e instanceof Error ? e.message : String(e);
6086
6114
  return { config: null, errors: [`YAML parse error: ${msg}`] };
6087
6115
  }
6116
+ if (resolveEnv && environment) parsed = interpolateObjectEnv(parsed, environment);
6088
6117
  const result = projectConfigSchema.safeParse(parsed);
6089
6118
  if (!result.success) {
6090
6119
  const errors = result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`);
@@ -6097,27 +6126,73 @@ async function loadConfig(filePath, resolveEnv = false) {
6097
6126
  async function resolveProjectConfig(filePath, options = {}) {
6098
6127
  const configPath = resolve7(filePath);
6099
6128
  const projectName = options.projectName ?? basename5(dirname7(configPath));
6100
- const { config: parsed, errors } = await loadConfig(configPath, options.resolveEnv ?? true);
6129
+ const { config: parsed, errors } = await loadConfig(
6130
+ configPath,
6131
+ options.resolveEnv ?? true,
6132
+ options.environment ? { ...options.environment, ...process.env } : void 0
6133
+ );
6101
6134
  if (errors.length > 0) {
6102
6135
  throw new UserError(errors.join("\n"));
6103
6136
  }
6104
- const config = await resolveFileReferences(parsed, configPath);
6105
- return { configPath, projectName, config };
6137
+ const sourcePaths = collectProjectSourcePaths(parsed, configPath, true);
6138
+ let config;
6139
+ try {
6140
+ config = await resolveFileReferences(parsed, configPath);
6141
+ } catch (error) {
6142
+ if (error && typeof error === "object") {
6143
+ Object.assign(error, { sourcePaths });
6144
+ }
6145
+ throw error;
6146
+ }
6147
+ return { configPath, projectName, config, sourcePaths };
6106
6148
  }
6107
6149
  async function resolveProjectConfigFromObject(rawConfig, options) {
6108
6150
  const basePath = resolve7(options.basePath ?? process.cwd());
6109
- const result = projectConfigSchema.safeParse(rawConfig);
6151
+ const input = options.resolveEnv ? interpolateObjectEnv(rawConfig, { ...options.environment, ...process.env }) : rawConfig;
6152
+ const result = projectConfigSchema.safeParse(input);
6110
6153
  if (!result.success) {
6111
6154
  const errors = result.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`);
6112
6155
  throw new UserError(errors.join("\n"));
6113
6156
  }
6114
6157
  const anchor = resolve7(basePath, "__in_memory_config__");
6115
- const config = await resolveFileReferences(result.data, anchor);
6116
- return { configPath: basePath, projectName: options.projectName, config };
6158
+ const parsed = result.data;
6159
+ const sourcePaths = collectProjectSourcePaths(parsed, anchor, false);
6160
+ const config = await resolveFileReferences(parsed, anchor);
6161
+ return { configPath: basePath, projectName: options.projectName, config, sourcePaths };
6162
+ }
6163
+ function collectProjectSourcePaths(config, configPath, includeConfigPath) {
6164
+ const baseDirectory = dirname7(configPath);
6165
+ const paths = /* @__PURE__ */ new Set();
6166
+ if (includeConfigPath) paths.add(configPath);
6167
+ const addLocalPath = (value, requirePathSyntax = false) => {
6168
+ if (!value || /^https?:\/\//i.test(value)) return;
6169
+ if (requirePathSyntax && !isLocalPathReference(value)) return;
6170
+ paths.add(resolve7(baseDirectory, value));
6171
+ };
6172
+ for (const agent of Object.values(config.agents ?? {})) {
6173
+ addLocalPath(agent.instructions, true);
6174
+ }
6175
+ for (const store of Object.values(config.memory_stores ?? {})) {
6176
+ for (const entry of store.entries ?? []) addLocalPath(entry.content, true);
6177
+ }
6178
+ for (const skill of Object.values(config.skills ?? {})) addLocalPath(skill.source);
6179
+ for (const file of Object.values(config.files ?? {})) addLocalPath(file.source);
6180
+ for (const deployment of Object.values(config.deployments ?? {})) {
6181
+ for (const resource of deployment.resources ?? []) {
6182
+ if (resource.type === "file") addLocalPath(resource.source);
6183
+ }
6184
+ for (const event of deployment.initial_events ?? []) {
6185
+ if (event.type === "user.define_outcome") addLocalPath(event.rubric_file, true);
6186
+ }
6187
+ }
6188
+ return [...paths].sort();
6189
+ }
6190
+ function isLocalPathReference(value) {
6191
+ return value.startsWith("./") || value.startsWith("../") || value.startsWith("/");
6117
6192
  }
6118
6193
 
6119
6194
  // src/internal/executor/executor.ts
6120
- import { dirname as dirname10, resolve as resolve11 } from "path";
6195
+ import { basename as basename7, dirname as dirname10, resolve as resolve11 } from "path";
6121
6196
 
6122
6197
  // src/internal/utils/hash.ts
6123
6198
  import { createHash } from "crypto";
@@ -6231,8 +6306,9 @@ async function computeResourceHash(address, config, basePath, state) {
6231
6306
  }
6232
6307
  if (address.type === "template") {
6233
6308
  const refs = resolveTemplateReferenceIds(decl, config, address.provider, state);
6234
- return contentHash({ decl, refs });
6309
+ return contentHash({ decl: withoutLocalSessionFileMounts(decl), refs });
6235
6310
  }
6311
+ if (address.type === "agent") return contentHash(withoutLocalSessionFileMounts(decl));
6236
6312
  if (address.type === "channel") {
6237
6313
  const refs = resolveChannelReferenceIds(
6238
6314
  decl,
@@ -6244,6 +6320,12 @@ async function computeResourceHash(address, config, basePath, state) {
6244
6320
  }
6245
6321
  return contentHash(decl);
6246
6322
  }
6323
+ function withoutLocalSessionFileMounts(decl) {
6324
+ if (!decl || typeof decl !== "object" || Array.isArray(decl)) return decl;
6325
+ const { files, ...remoteDeclaration } = decl;
6326
+ const templateFiles = Array.isArray(files) ? files.filter((file) => typeof file === "string") : [];
6327
+ return templateFiles.length ? { ...remoteDeclaration, files: templateFiles } : remoteDeclaration;
6328
+ }
6247
6329
  function resolveQoderApiMode(type, name, provider, config) {
6248
6330
  if (provider !== "qoder") return void 0;
6249
6331
  if (type === "environment" && config.environments?.[name]?.environment_id) return "auto";
@@ -6251,7 +6333,7 @@ function resolveQoderApiMode(type, name, provider, config) {
6251
6333
  if (agent.provider && agent.provider !== provider) continue;
6252
6334
  const referenced = type === "environment" ? agent.environment === name : type === "skill" ? agent.skills?.some(
6253
6335
  (skill) => typeof skill === "string" ? skill === name : skill.type === "custom" && skill.skill_id === name
6254
- ) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.includes(name);
6336
+ ) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.some((file) => (typeof file === "string" ? file : file.file) === name);
6255
6337
  if (referenced && agent.delivery?.qoder?.type === "forward") return "forward";
6256
6338
  }
6257
6339
  return "managed";
@@ -6292,9 +6374,7 @@ function resolveTemplateReferenceIds(decl, config, provider, state) {
6292
6374
  memory_store_ids: (decl.memory_stores ?? []).map(
6293
6375
  (memoryStore) => state?.getResource({ type: "memory_store", name: memoryStore, provider })?.remote_id ?? memoryStore
6294
6376
  ),
6295
- file_ids: (decl.files ?? []).map(
6296
- (file) => state?.getResource({ type: "file", name: file, provider })?.remote_id ?? file
6297
- ),
6377
+ file_ids: (decl.files ?? []).filter((file) => typeof file === "string").map((file) => state?.getResource({ type: "file", name: file, provider })?.remote_id ?? file),
6298
6378
  identity_id: decl.memory_stores?.length && config.defaults?.identity ? state?.getResource({ type: "identity", name: config.defaults.identity, provider })?.remote_id : void 0
6299
6379
  };
6300
6380
  }
@@ -6484,7 +6564,7 @@ function resolveTemplateRefs(agentName, config, provider, state) {
6484
6564
  environment_id: environment.environment_id ?? requireRef(state, { type: "environment", name: agent.environment, provider }),
6485
6565
  ...agent.tunnel ? { tunnel_id: resolveTunnelIdFromConfig(config, agent.tunnel, provider) } : {},
6486
6566
  vault_ids: agent.vault ? [requireRef(state, { type: "vault", name: agent.vault, provider })] : [],
6487
- file_ids: (agent.files ?? []).map((file) => requireRef(state, { type: "file", name: file, provider })),
6567
+ file_ids: (agent.files ?? []).filter((file) => typeof file === "string").map((file) => requireRef(state, { type: "file", name: file, provider })),
6488
6568
  memory_store_ids: memoryStoreIds,
6489
6569
  owned_memory_store_ids: state.listResources().filter(
6490
6570
  (resource) => resource.address.provider === provider && resource.address.type === "memory_store" && resource.api_mode === "forward" && typeof resource.remote_id === "string"
@@ -7262,7 +7342,16 @@ async function executeActionInner(action, provider, ctx) {
7262
7342
  }
7263
7343
  }
7264
7344
  }
7265
- const info = await provider.uploadFile(filePath, { name: decl.name, purpose: decl.purpose }, apiMode);
7345
+ const info = await provider.uploadFile(
7346
+ filePath,
7347
+ {
7348
+ // Keep the source filename and extension; a declaration label must not
7349
+ // change the multipart filename or the provider's inferred MIME type.
7350
+ name: basename7(filePath),
7351
+ purpose: decl.purpose
7352
+ },
7353
+ apiMode
7354
+ );
7266
7355
  result = { id: info.id, type: "file" };
7267
7356
  break;
7268
7357
  }
@@ -7314,7 +7403,7 @@ function resolveResourceApiMode(type, name, provider, config) {
7314
7403
  if (agent.provider && agent.provider !== provider) continue;
7315
7404
  const referenced = type === "environment" ? agent.environment === name : type === "skill" ? agent.skills?.some(
7316
7405
  (skill) => typeof skill === "string" ? skill === name : skill.type === "custom" && skill.skill_id === name
7317
- ) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.includes(name);
7406
+ ) : type === "vault" ? agent.vault === name : type === "memory_store" ? agent.memory_stores?.includes(name) : agent.files?.some((file) => (typeof file === "string" ? file : file.file) === name);
7318
7407
  if (!referenced) continue;
7319
7408
  if (agent.delivery?.qoder?.type === "forward") forward = true;
7320
7409
  else managed = true;
@@ -7374,16 +7463,16 @@ function resolveAgentMaterialization(provider, agent) {
7374
7463
  // src/internal/graph/dependency.ts
7375
7464
  function collectDependencyClosure(graph, roots) {
7376
7465
  const selected = /* @__PURE__ */ new Map();
7377
- function visit(address) {
7466
+ function visit2(address) {
7378
7467
  const key = addressKey(address);
7379
7468
  if (selected.has(key)) return;
7380
7469
  selected.set(key, graph.nodes.get(key) ?? address);
7381
7470
  for (const dependencyKey of graph.edges.get(key) ?? []) {
7382
7471
  const dependency = graph.nodes.get(dependencyKey);
7383
- if (dependency) visit(dependency);
7472
+ if (dependency) visit2(dependency);
7384
7473
  }
7385
7474
  }
7386
- for (const root of roots) visit(root);
7475
+ for (const root of roots) visit2(root);
7387
7476
  return [...selected.values()];
7388
7477
  }
7389
7478
  function buildDependencyGraph(config, targetProviders) {
@@ -7486,7 +7575,8 @@ function buildDependencyGraph(config, targetProviders) {
7486
7575
  }
7487
7576
  }
7488
7577
  if (decl.files) {
7489
- for (const fileName of decl.files) {
7578
+ for (const file of decl.files) {
7579
+ const fileName = typeof file === "string" ? file : file.file;
7490
7580
  const fileAddr = { type: "file", name: fileName, provider };
7491
7581
  if (nodes.has(addressKey(fileAddr))) addEdge(agentAddr, fileAddr);
7492
7582
  }
@@ -7574,7 +7664,7 @@ function topologicalSort(graph) {
7574
7664
  const visited = /* @__PURE__ */ new Set();
7575
7665
  const sorted = [];
7576
7666
  const visiting = /* @__PURE__ */ new Set();
7577
- function visit(key) {
7667
+ function visit2(key) {
7578
7668
  if (visited.has(key)) return;
7579
7669
  if (visiting.has(key)) {
7580
7670
  throw new UserError(`Circular dependency detected involving: ${key}`);
@@ -7582,14 +7672,14 @@ function topologicalSort(graph) {
7582
7672
  visiting.add(key);
7583
7673
  const deps = graph.edges.get(key) ?? /* @__PURE__ */ new Set();
7584
7674
  for (const dep of deps) {
7585
- visit(dep);
7675
+ visit2(dep);
7586
7676
  }
7587
7677
  visiting.delete(key);
7588
7678
  visited.add(key);
7589
7679
  sorted.push(graph.nodes.get(key));
7590
7680
  }
7591
7681
  for (const key of graph.nodes.keys()) {
7592
- visit(key);
7682
+ visit2(key);
7593
7683
  }
7594
7684
  return sorted;
7595
7685
  }
@@ -7716,8 +7806,9 @@ function collectReferenceDiagnostics(config, diagnostics) {
7716
7806
  diagnostics.error("config.agent.vault.unknown", `agent.${name}: references unknown vault '${agent.vault}'`);
7717
7807
  }
7718
7808
  for (const file of agent.files ?? []) {
7719
- if (!fileNames.has(file)) {
7720
- diagnostics.error("config.agent.file.unknown", `agent.${name}: references unknown file '${file}'`);
7809
+ const fileName = typeof file === "string" ? file : file.file;
7810
+ if (!fileNames.has(fileName)) {
7811
+ diagnostics.error("config.agent.file.unknown", `agent.${name}: references unknown file '${fileName}'`);
7721
7812
  }
7722
7813
  }
7723
7814
  for (const memory of agent.memory_stores ?? []) {
@@ -7782,6 +7873,16 @@ function collectProviderCapabilities(config, providers, diagnostics) {
7782
7873
  continue;
7783
7874
  }
7784
7875
  const caps = def.capabilities;
7876
+ for (const [name, vault] of Object.entries(config.vaults ?? {})) {
7877
+ if (vault.provider && vault.provider !== providerName) continue;
7878
+ if (providerName !== "bailian" && vault.credentials.some((credential) => credential.injection_location !== void 0)) {
7879
+ diagnostics.error(
7880
+ `${providerName}.vault.injection_location.unsupported`,
7881
+ `vault.${name}: provider '${providerName}' does not support credential injection_location; pin this vault to bailian.`,
7882
+ { type: "vault", name, provider: providerName }
7883
+ );
7884
+ }
7885
+ }
7785
7886
  for (const [name, environment] of Object.entries(config.environments ?? {})) {
7786
7887
  if (environment.provider && environment.provider !== providerName) continue;
7787
7888
  if (environment.environment_id) continue;
@@ -7901,7 +8002,7 @@ function collectProviderCapabilities(config, providers, diagnostics) {
7901
8002
  ),
7902
8003
  ...agent.vault ? [`vault:${agent.vault}`] : [],
7903
8004
  ...(agent.memory_stores ?? []).map((store) => `memory_store:${store}`),
7904
- ...(agent.files ?? []).map((file) => `file:${file}`)
8005
+ ...(agent.files ?? []).map((file) => `file:${typeof file === "string" ? file : file.file}`)
7905
8006
  ];
7906
8007
  for (const ref of refs) {
7907
8008
  const modes = domains.get(ref) ?? /* @__PURE__ */ new Set();
@@ -7921,7 +8022,7 @@ function collectProviderCapabilities(config, providers, diagnostics) {
7921
8022
  }
7922
8023
  for (const [name, agent] of Object.entries(config.agents ?? {})) {
7923
8024
  if (agent.provider && agent.provider !== providerName) continue;
7924
- if (agent.files?.length && (providerName !== "qoder" || agent.delivery?.qoder?.type !== "forward")) {
8025
+ if (agent.files?.some((file) => typeof file === "string") && (providerName !== "qoder" || agent.delivery?.qoder?.type !== "forward")) {
7925
8026
  diagnostics.error(
7926
8027
  "config.agent.files.unsupported",
7927
8028
  `agent.${name}: files are supported only by Qoder Forward Templates.`,
@@ -7945,6 +8046,30 @@ function collectProviderCapabilities(config, providers, diagnostics) {
7945
8046
  address
7946
8047
  );
7947
8048
  }
8049
+ const normalizedFileMountPaths = /* @__PURE__ */ new Set();
8050
+ for (const file of agent.files ?? []) {
8051
+ if (typeof file === "string") continue;
8052
+ let normalizedMountPath;
8053
+ try {
8054
+ normalizedMountPath = resolveSandboxMountPath(providerName, file.mount_path);
8055
+ } catch (error) {
8056
+ diagnostics.error(
8057
+ `${providerName}.agent.file.mount_path.invalid`,
8058
+ `agent.${name}: ${error instanceof Error ? error.message : String(error)}`,
8059
+ address
8060
+ );
8061
+ continue;
8062
+ }
8063
+ if (normalizedFileMountPaths.has(normalizedMountPath)) {
8064
+ diagnostics.error(
8065
+ `${providerName}.agent.file.mount_path.duplicate`,
8066
+ `agent.${name}: file mount_path '${normalizedMountPath}' is duplicated after normalization.`,
8067
+ address
8068
+ );
8069
+ } else {
8070
+ normalizedFileMountPaths.add(normalizedMountPath);
8071
+ }
8072
+ }
7948
8073
  for (const resource of agent.resources ?? []) {
7949
8074
  if (!def.features.session_resources.includes(resource.type)) {
7950
8075
  diagnostics.error(
@@ -8666,7 +8791,8 @@ async function syncProjectResourcesWithStateBackend(input, options = {}) {
8666
8791
  execution: await executePlannedProject(planned, {
8667
8792
  onFeedback: options.onFeedback,
8668
8793
  policy: options.policy,
8669
- confirm: options.confirm
8794
+ confirm: options.confirm,
8795
+ concurrency: options.concurrency
8670
8796
  })
8671
8797
  };
8672
8798
  });
@@ -8889,6 +9015,124 @@ function toResourceExecutionResult(result) {
8889
9015
  };
8890
9016
  }
8891
9017
 
9018
+ // src/internal/core/project-source-security.ts
9019
+ import { basename as basename8, dirname as dirname11 } from "path";
9020
+ import { isScalar, parseDocument, visit } from "yaml";
9021
+ var REDACTED = "[redacted]";
9022
+ var ENVIRONMENT_REFERENCE = /^\$\{[A-Za-z_][A-Za-z0-9_]*\}$/;
9023
+ var SENSITIVE_KEY = /(access[_-]?key(?:[_-]?id)?|api[_-]?key|authorization|credential|headers?|password|secret(?![_-]?name)|signature|token)/i;
9024
+ async function inspectProjectSource(source, configPath) {
9025
+ const document = parseDocument(source, { keepSourceTokens: true, prettyErrors: true });
9026
+ if (document.errors.length > 0) {
9027
+ return {
9028
+ diagnostics: document.errors.map(() => ({
9029
+ severity: "error",
9030
+ code: "project.config.invalid",
9031
+ message: "agents.yaml contains invalid YAML. Fix the syntax before creating or restoring a version."
9032
+ })),
9033
+ redacted_source: "# Invalid agents.yaml source omitted from the safe preview.\n",
9034
+ sensitive_literals: []
9035
+ };
9036
+ }
9037
+ const rawConfig = document.toJS({ mapAsMap: false });
9038
+ const displaySecrets = collectSensitiveScalars(rawConfig);
9039
+ const sensitiveLiterals = [...displaySecrets].filter((value) => !ENVIRONMENT_REFERENCE.test(value));
9040
+ let diagnostics;
9041
+ try {
9042
+ const loaded = await resolveProjectConfigFromObject(rawConfig, {
9043
+ projectName: basename8(dirname11(configPath)),
9044
+ basePath: dirname11(configPath)
9045
+ });
9046
+ diagnostics = validateProjectConfig(loaded.config);
9047
+ } catch (error) {
9048
+ diagnostics = [
9049
+ {
9050
+ severity: "error",
9051
+ code: "project.config.invalid",
9052
+ message: error instanceof Error ? error.message : String(error)
9053
+ }
9054
+ ];
9055
+ }
9056
+ if (sensitiveLiterals.length > 0) {
9057
+ diagnostics.push({
9058
+ severity: "error",
9059
+ code: "project.version.sensitive_literal",
9060
+ message: "agents.yaml contains a credential value in a sensitive field. Replace it with an environment variable reference before creating or restoring a version."
9061
+ });
9062
+ }
9063
+ return {
9064
+ diagnostics: redactDiagnostics(diagnostics, displaySecrets),
9065
+ redacted_source: redactDocumentSource(source, document, displaySecrets),
9066
+ sensitive_literals: sensitiveLiterals.map(() => REDACTED)
9067
+ };
9068
+ }
9069
+ function collectSensitiveScalars(value, result = /* @__PURE__ */ new Set(), key = "", ancestorSensitive = false) {
9070
+ if (Array.isArray(value)) {
9071
+ const nestedSensitive = ancestorSensitive || isSensitiveValueKey(key);
9072
+ for (const entry of value) collectSensitiveScalars(entry, result, key, nestedSensitive);
9073
+ return result;
9074
+ }
9075
+ if (isRecord2(value)) {
9076
+ const nestedSensitive = ancestorSensitive || isSensitiveContainerKey(key);
9077
+ for (const [entryKey, entry] of Object.entries(value)) {
9078
+ collectSensitiveScalars(entry, result, entryKey, nestedSensitive);
9079
+ }
9080
+ return result;
9081
+ }
9082
+ if ((ancestorSensitive || isSensitiveValueKey(key)) && (typeof value === "string" || typeof value === "number") && String(value).length > 0) {
9083
+ result.add(String(value));
9084
+ }
9085
+ return result;
9086
+ }
9087
+ function isSensitiveContainerKey(key) {
9088
+ return ["header", "headers", "authorization"].includes(key.toLowerCase().replaceAll("-", "_"));
9089
+ }
9090
+ function isSensitiveValueKey(key) {
9091
+ const normalized = key.toLowerCase().replaceAll("-", "_");
9092
+ if (normalized === "secret_name" || normalized === "credentials") return false;
9093
+ return SENSITIVE_KEY.test(normalized);
9094
+ }
9095
+ function redactDocumentSource(source, document, secrets) {
9096
+ if (secrets.size === 0) return source;
9097
+ const redactedDocument = document.clone();
9098
+ visit(redactedDocument, (_key, node) => {
9099
+ if (isScalar(node) && (typeof node.value === "string" || typeof node.value === "number")) {
9100
+ const value = String(node.value);
9101
+ const redacted = redactText(value, secrets);
9102
+ if (redacted !== value) {
9103
+ node.value = redacted;
9104
+ node.source = redacted;
9105
+ node.type = "PLAIN";
9106
+ }
9107
+ }
9108
+ redactComments(node, secrets);
9109
+ });
9110
+ redactComments(redactedDocument, secrets);
9111
+ return redactedDocument.toString();
9112
+ }
9113
+ function redactText(source, secrets) {
9114
+ let redacted = source;
9115
+ for (const secret of [...secrets].sort((left, right) => right.length - left.length)) {
9116
+ redacted = redacted.replaceAll(secret, REDACTED);
9117
+ }
9118
+ return redacted;
9119
+ }
9120
+ function redactComments(value, secrets) {
9121
+ if (!value || typeof value !== "object") return;
9122
+ const commented = value;
9123
+ if (commented.comment) commented.comment = redactText(commented.comment, secrets);
9124
+ if (commented.commentBefore) commented.commentBefore = redactText(commented.commentBefore, secrets);
9125
+ }
9126
+ function redactDiagnostics(diagnostics, secrets) {
9127
+ return diagnostics.map((diagnostic) => ({
9128
+ ...diagnostic,
9129
+ message: redactText(diagnostic.message, secrets)
9130
+ }));
9131
+ }
9132
+ function isRecord2(value) {
9133
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9134
+ }
9135
+
8892
9136
  // src/internal/core/sync-runtime.ts
8893
9137
  import { stringify as stringifyYaml } from "yaml";
8894
9138
  var SYNCABLE_GROUP = {
@@ -9571,7 +9815,16 @@ function resolveVaultProvider(ctx, declaredProvider, requestedProvider) {
9571
9815
  function credentialMatches(remote, desired) {
9572
9816
  if (remote.auth_type !== desired.type || !metadataMatches(remote.metadata, desired.metadata)) return false;
9573
9817
  if (desired.type === "static_bearer") return remote.mcp_server_url === desired.mcp_server_url;
9574
- return remote.secret_name === desired.secret_name && (remote.networking_type ?? "unrestricted") === (desired.networking?.type ?? "unrestricted");
9818
+ const desiredHosts = credentialHosts(desired.networking);
9819
+ const remoteHosts = credentialHosts(remote.networking ?? { type: remote.networking_type });
9820
+ const desiredLocation = desired.injection_location;
9821
+ const remoteLocation = remote.injection_location;
9822
+ if (desiredLocation && !remoteLocation) return false;
9823
+ return remote.secret_name === desired.secret_name && desiredHosts !== void 0 && remoteHosts !== void 0 && desiredHosts.length === remoteHosts.length && desiredHosts.every((host) => remoteHosts.includes(host)) && (desiredLocation?.header ?? true) === (remoteLocation?.header ?? true) && (desiredLocation?.body ?? false) === (remoteLocation?.body ?? false);
9824
+ }
9825
+ function credentialHosts(networking) {
9826
+ if (networking?.allowed_hosts !== void 0) return [...new Set(networking.allowed_hosts)];
9827
+ return networking?.type === "limited" ? void 0 : ["*"];
9575
9828
  }
9576
9829
  function metadataMatches(remote, desired) {
9577
9830
  const remoteEntries = Object.entries(remote ?? {});
@@ -10165,6 +10418,7 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
10165
10418
  throw new UserError(`Agent '${agentName}' not found in config. Available agents: ${available || "(none)"}`);
10166
10419
  }
10167
10420
  const sessionResources = options.resources ?? agent.resources;
10421
+ const sessionFiles = resolveSessionFiles(agentName, agent, provider, state, options.files ?? []);
10168
10422
  const environmentVariables = options.environmentVariables ?? agent.environment_variables;
10169
10423
  if (environmentVariables && provider !== "qoder") {
10170
10424
  throw new UserError("Session environment variables are supported only by Qoder.");
@@ -10195,7 +10449,7 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
10195
10449
  delivery: "forward",
10196
10450
  template_id: templateId,
10197
10451
  identity_id: identityId,
10198
- files: (options.files ?? []).map((file) => ({ file_id: file.fileId, mount_path: file.mountPath })),
10452
+ files: sessionFiles,
10199
10453
  title: options.title,
10200
10454
  metadata: options.metadata,
10201
10455
  environment_variables: environmentVariables
@@ -10240,13 +10494,41 @@ function buildSessionBindings(agentName, config, provider, state, options = {})
10240
10494
  tunnel_id: tunnelId,
10241
10495
  vault_ids: vaultIds,
10242
10496
  memory_store_ids: memoryStoreIds,
10243
- files: (options.files ?? []).map((f) => ({ file_id: f.fileId, mount_path: f.mountPath })),
10497
+ files: sessionFiles,
10244
10498
  resources: sessionResources,
10245
10499
  title: options.title,
10246
10500
  metadata: options.metadata,
10247
10501
  environment_variables: environmentVariables
10248
10502
  };
10249
10503
  }
10504
+ function resolveSessionFiles(agentName, agent, provider, state, explicitFiles) {
10505
+ const resolved = [];
10506
+ const mountOwners = /* @__PURE__ */ new Map();
10507
+ for (const file of agent.files ?? []) {
10508
+ if (typeof file === "string") continue;
10509
+ const mountPath = resolveSandboxMountPath(provider, file.mount_path);
10510
+ assertUniqueMountPath(mountOwners, mountPath, `declared file '${file.file}'`, agentName);
10511
+ resolved.push({
10512
+ file_id: requireRef(state, { type: "file", name: file.file, provider }),
10513
+ mount_path: mountPath
10514
+ });
10515
+ }
10516
+ for (const file of explicitFiles) {
10517
+ const mountPath = resolveSandboxMountPath(provider, file.mountPath);
10518
+ assertUniqueMountPath(mountOwners, mountPath, `Session file '${file.fileId}'`, agentName);
10519
+ resolved.push({ file_id: file.fileId, mount_path: mountPath });
10520
+ }
10521
+ return resolved;
10522
+ }
10523
+ function assertUniqueMountPath(mountOwners, mountPath, owner, agentName) {
10524
+ const existing = mountOwners.get(mountPath);
10525
+ if (existing) {
10526
+ throw new UserError(
10527
+ `Agent '${agentName}' cannot mount ${owner} at '${mountPath}'; the path is already used by ${existing}.`
10528
+ );
10529
+ }
10530
+ mountOwners.set(mountPath, owner);
10531
+ }
10250
10532
  function resolveTunnelId(agent, config, options, provider) {
10251
10533
  const tunnelName = options.tunnel ?? agent.tunnel;
10252
10534
  if (!options.tunnelId && !tunnelName) return void 0;
@@ -10266,6 +10548,74 @@ function validateResourceInConfig(name, type, resources) {
10266
10548
  }
10267
10549
  }
10268
10550
 
10551
+ // src/internal/state/backend.ts
10552
+ function cloneStateFile(state) {
10553
+ return structuredClone(state);
10554
+ }
10555
+
10556
+ // src/internal/state/in-memory-state-manager.ts
10557
+ var InMemoryStateManager = class _InMemoryStateManager {
10558
+ state;
10559
+ index;
10560
+ constructor(state) {
10561
+ this.state = state;
10562
+ this.index = this.buildIndex();
10563
+ }
10564
+ buildIndex() {
10565
+ const idx = /* @__PURE__ */ new Map();
10566
+ for (let i = 0; i < this.state.resources.length; i++) {
10567
+ idx.set(addressKey(this.state.resources[i].address), i);
10568
+ }
10569
+ return idx;
10570
+ }
10571
+ static fromJSON(data) {
10572
+ return new _InMemoryStateManager(structuredClone(data));
10573
+ }
10574
+ static empty() {
10575
+ return new _InMemoryStateManager({ resources: [] });
10576
+ }
10577
+ getResource(address) {
10578
+ const i = this.index.get(addressKey(address));
10579
+ return i !== void 0 ? this.state.resources[i] : void 0;
10580
+ }
10581
+ setResource(resource) {
10582
+ const key = addressKey(resource.address);
10583
+ const i = this.index.get(key);
10584
+ if (i !== void 0) {
10585
+ this.state.resources[i] = resource;
10586
+ } else {
10587
+ this.index.set(key, this.state.resources.length);
10588
+ this.state.resources.push(resource);
10589
+ }
10590
+ }
10591
+ removeResource(address) {
10592
+ const key = addressKey(address);
10593
+ const i = this.index.get(key);
10594
+ if (i === void 0) return;
10595
+ this.state.resources.splice(i, 1);
10596
+ this.index.delete(key);
10597
+ for (let j = i; j < this.state.resources.length; j++) {
10598
+ this.index.set(addressKey(this.state.resources[j].address), j);
10599
+ }
10600
+ }
10601
+ listResources() {
10602
+ return [...this.state.resources];
10603
+ }
10604
+ findResource(query2) {
10605
+ return this.state.resources.find((resource) => {
10606
+ const matchType = resource.address.type === query2.type;
10607
+ const matchName = resource.address.name === query2.name;
10608
+ const matchProvider = !query2.provider || resource.address.provider === query2.provider;
10609
+ return matchType && matchName && matchProvider;
10610
+ });
10611
+ }
10612
+ getStateFile() {
10613
+ return this.state;
10614
+ }
10615
+ async save() {
10616
+ }
10617
+ };
10618
+
10269
10619
  // src/internal/core/agent-runtime.ts
10270
10620
  function listAgents(ctx) {
10271
10621
  const agents = ctx.config.agents ?? {};
@@ -10356,21 +10706,26 @@ async function listAgentsWithReadiness(ctx, options = {}) {
10356
10706
  readiness: getAgentReadinessFromPlan(ctx, agent.id, planResult.plan)
10357
10707
  }));
10358
10708
  }
10709
+ function isAgentRunnable(readiness) {
10710
+ return readiness.status === "ready" || readiness.status === "drifted" && readiness.driftSeverity === "non_blocking";
10711
+ }
10359
10712
  async function planAgentResources(ctx, agentId, options = {}) {
10360
10713
  const agent = getAgent(ctx, agentId);
10361
- const rootAddress = collectAgentAddresses(ctx.config, agent.agentName, agent.provider)[0];
10714
+ const addresses = collectAgentAddresses(ctx.config, agent.agentName, agent.provider);
10362
10715
  const planned = await planProjectContext(ctx, {
10363
10716
  provider: agent.provider,
10364
- scope: { roots: [rootAddress] },
10717
+ scope: { roots: options.scope === "runtime" ? addresses : [addresses[0]] },
10365
10718
  mode: options.mode,
10366
10719
  refresh: options.refresh,
10367
- quiet: options.quiet ?? true
10720
+ quiet: options.quiet ?? true,
10721
+ onFeedback: options.onFeedback
10368
10722
  });
10369
10723
  const actions = planned.plan.actions;
10370
10724
  const diagnostics = planned.plan.diagnostics;
10371
10725
  return {
10372
10726
  agentId,
10373
10727
  provider: agent.provider,
10728
+ fingerprint: computeAgentPlanFingerprint(agentId, agent.provider, actions, diagnostics),
10374
10729
  actions,
10375
10730
  diagnostics,
10376
10731
  destructiveActions: selectDestructive(actions),
@@ -10384,14 +10739,31 @@ async function syncAgentResources(ctx, agentId, options = {}) {
10384
10739
  return runAgentSync(ctx, agentId, options);
10385
10740
  }
10386
10741
  async function runAgentSync(ctx, agentId, options) {
10387
- const fullPlan = await planAgentResources(ctx, agentId, {
10742
+ const transactionalState = options.expectedPlanFingerprint ? InMemoryStateManager.fromJSON(cloneStateFile(ctx.state.getStateFile())) : void 0;
10743
+ const planningContext = transactionalState ? { ...ctx, state: transactionalState } : ctx;
10744
+ const fullPlan = await planAgentResources(planningContext, agentId, {
10388
10745
  refresh: options.refresh,
10389
10746
  quiet: options.quiet,
10747
+ onFeedback: options.onFeedback,
10748
+ scope: options.scope,
10390
10749
  mode: options.mode
10391
10750
  });
10392
10751
  const actions = fullPlan.actions;
10393
10752
  const destructiveActions = fullPlan.destructiveActions;
10394
10753
  const errorDiagnostic = fullPlan.diagnostics.find((diagnostic) => diagnostic.severity === "error");
10754
+ if (options.expectedPlanFingerprint && options.expectedPlanFingerprint !== fullPlan.fingerprint) {
10755
+ return {
10756
+ agentId,
10757
+ provider: fullPlan.provider,
10758
+ status: "blocked",
10759
+ reason: "plan_stale",
10760
+ actions,
10761
+ diagnostics: fullPlan.diagnostics,
10762
+ destructiveActions,
10763
+ results: [],
10764
+ error: "The project or remote resources changed after planning. Create a new plan before applying."
10765
+ };
10766
+ }
10395
10767
  const decision = await decideDestructive(destructiveActions, {
10396
10768
  policy: options.policy,
10397
10769
  confirm: options.confirm
@@ -10401,6 +10773,7 @@ async function runAgentSync(ctx, agentId, options) {
10401
10773
  agentId,
10402
10774
  provider: fullPlan.provider,
10403
10775
  status: "blocked",
10776
+ reason: decision === "cancelled" ? "cancelled" : "destructive_blocked",
10404
10777
  actions,
10405
10778
  diagnostics: fullPlan.diagnostics,
10406
10779
  destructiveActions,
@@ -10413,6 +10786,7 @@ async function runAgentSync(ctx, agentId, options) {
10413
10786
  agentId,
10414
10787
  provider: fullPlan.provider,
10415
10788
  status: "blocked",
10789
+ reason: "diagnostic_error",
10416
10790
  actions,
10417
10791
  diagnostics: fullPlan.diagnostics,
10418
10792
  destructiveActions,
@@ -10422,8 +10796,10 @@ async function runAgentSync(ctx, agentId, options) {
10422
10796
  }
10423
10797
  try {
10424
10798
  const execution = await executePlannedProject(fullPlan.planned, {
10799
+ onFeedback: options.onFeedback,
10425
10800
  policy: "force"
10426
10801
  });
10802
+ if (transactionalState) await replaceState(ctx.state, transactionalState);
10427
10803
  const results = toAgentSyncResults(execution);
10428
10804
  const failed = results.find((result) => result.status === "failed");
10429
10805
  return {
@@ -10437,6 +10813,7 @@ async function runAgentSync(ctx, agentId, options) {
10437
10813
  error: failed?.error
10438
10814
  };
10439
10815
  } catch (error) {
10816
+ if (transactionalState) await replaceState(ctx.state, transactionalState);
10440
10817
  return {
10441
10818
  agentId,
10442
10819
  provider: fullPlan.provider,
@@ -10449,6 +10826,11 @@ async function runAgentSync(ctx, agentId, options) {
10449
10826
  };
10450
10827
  }
10451
10828
  }
10829
+ async function replaceState(target, source) {
10830
+ for (const resource of target.listResources()) target.removeResource(resource.address);
10831
+ for (const resource of source.listResources()) target.setResource(resource);
10832
+ await target.save();
10833
+ }
10452
10834
  async function syncAgentResourcesWithStateBackend(input, agentId, options = {}) {
10453
10835
  return writeProjectRuntime(input, (ctx) => syncAgentResources(ctx, agentId, options));
10454
10836
  }
@@ -10525,6 +10907,10 @@ function getAgentReadinessFromPlan(ctx, agentId, plan) {
10525
10907
  plannedActions: relevantActions
10526
10908
  };
10527
10909
  }
10910
+ function actionKey(action) {
10911
+ const address = action.address;
10912
+ return `${action.action}:${address.provider}:${address.type}:${address.name}`;
10913
+ }
10528
10914
  function isNonBlockingAgentDrift(action) {
10529
10915
  if (action.action === "no-op") return true;
10530
10916
  return action.readinessImpact === "non_blocking";
@@ -10542,7 +10928,42 @@ function collectAgentAddresses(config, agentName, provider) {
10542
10928
  provider: resolvedProvider
10543
10929
  };
10544
10930
  const graph = buildDependencyGraph(config, [resolvedProvider]);
10545
- return collectDependencyClosure(graph, [rootAddress]);
10931
+ const roots = [rootAddress];
10932
+ const visited = /* @__PURE__ */ new Set();
10933
+ function collectRuntimeRoots(name) {
10934
+ if (visited.has(name)) return;
10935
+ visited.add(name);
10936
+ const declaration = config.agents?.[name];
10937
+ if (!declaration) return;
10938
+ const type = resolveAgentMaterialization(resolvedProvider, declaration).resourceType;
10939
+ if (type === "template" && config.defaults?.identity) {
10940
+ roots.push({ type: "identity", name: config.defaults.identity, provider: resolvedProvider });
10941
+ }
10942
+ for (const subAgentName of declaration.multiagent?.agents ?? []) {
10943
+ const subAgent = config.agents?.[subAgentName];
10944
+ if (!subAgent) continue;
10945
+ roots.push({
10946
+ type: resolveAgentMaterialization(resolvedProvider, subAgent).resourceType,
10947
+ name: subAgentName,
10948
+ provider: resolvedProvider
10949
+ });
10950
+ collectRuntimeRoots(subAgentName);
10951
+ }
10952
+ }
10953
+ collectRuntimeRoots(agentName);
10954
+ return collectDependencyClosure(graph, roots);
10955
+ }
10956
+ function computeAgentPlanFingerprint(agentId, provider, actions, diagnostics) {
10957
+ const normalizedActions = actions.map((action) => ({
10958
+ ...action,
10959
+ dependencies: [...action.dependencies].sort((left, right) => addressKey(left).localeCompare(addressKey(right)))
10960
+ })).sort((left, right) => actionKey(left).localeCompare(actionKey(right)));
10961
+ const normalizedDiagnostics = [...diagnostics].sort((left, right) => {
10962
+ const leftKey = `${left.resource ? addressKey(left.resource) : ""}:${left.severity}:${left.code}:${left.message}`;
10963
+ const rightKey = `${right.resource ? addressKey(right.resource) : ""}:${right.severity}:${right.code}:${right.message}`;
10964
+ return leftKey.localeCompare(rightKey);
10965
+ });
10966
+ return contentHash({ agentId, provider, actions: normalizedActions, diagnostics: normalizedDiagnostics });
10546
10967
  }
10547
10968
  function toAgentDefinition(config, agentName, agent) {
10548
10969
  return {
@@ -10987,7 +11408,7 @@ function delay2(ms) {
10987
11408
  import { readFileSync as readFileSync8 } from "fs";
10988
11409
  import { readFile as readFile5 } from "fs/promises";
10989
11410
  import { homedir } from "os";
10990
- import { dirname as dirname11, join } from "path";
11411
+ import { dirname as dirname12, join } from "path";
10991
11412
  var AGENTS_CONFIG_PROVIDERS = ["bailian", "qoder", "ark", "claude"];
10992
11413
  var AGENTS_PROVIDER_FIELDS = {
10993
11414
  bailian: [
@@ -11056,7 +11477,7 @@ function loadDotEnv(startDir = process.cwd()) {
11056
11477
  return envPath;
11057
11478
  } catch {
11058
11479
  }
11059
- const parent = dirname11(dir);
11480
+ const parent = dirname12(dir);
11060
11481
  if (parent === dir) break;
11061
11482
  dir = parent;
11062
11483
  }
@@ -11140,7 +11561,7 @@ function parseStateAddress(address, options = {}) {
11140
11561
 
11141
11562
  // src/internal/state/state-manager.ts
11142
11563
  import { mkdir, readFile as readFile6, rename, unlink, writeFile } from "fs/promises";
11143
- import { dirname as dirname12 } from "path";
11564
+ import { dirname as dirname13 } from "path";
11144
11565
  var StateManager = class _StateManager {
11145
11566
  state;
11146
11567
  path;
@@ -11231,7 +11652,7 @@ var StateManager = class _StateManager {
11231
11652
  return this.state;
11232
11653
  }
11233
11654
  async save() {
11234
- await mkdir(dirname12(this.path), { recursive: true });
11655
+ await mkdir(dirname13(this.path), { recursive: true });
11235
11656
  const tmpPath = `${this.path}.${Date.now()}.${Math.random().toString(36).slice(2)}.tmp`;
11236
11657
  try {
11237
11658
  await writeFile(tmpPath, `${JSON.stringify(this.state, null, 2)}
@@ -11253,74 +11674,6 @@ function deriveStatePath(configPath) {
11253
11674
  return /\.ya?ml$/i.test(configPath) ? configPath.replace(/\.ya?ml$/i, ".state.json") : `${configPath}.state.json`;
11254
11675
  }
11255
11676
 
11256
- // src/internal/state/backend.ts
11257
- function cloneStateFile(state) {
11258
- return structuredClone(state);
11259
- }
11260
-
11261
- // src/internal/state/in-memory-state-manager.ts
11262
- var InMemoryStateManager = class _InMemoryStateManager {
11263
- state;
11264
- index;
11265
- constructor(state) {
11266
- this.state = state;
11267
- this.index = this.buildIndex();
11268
- }
11269
- buildIndex() {
11270
- const idx = /* @__PURE__ */ new Map();
11271
- for (let i = 0; i < this.state.resources.length; i++) {
11272
- idx.set(addressKey(this.state.resources[i].address), i);
11273
- }
11274
- return idx;
11275
- }
11276
- static fromJSON(data) {
11277
- return new _InMemoryStateManager(structuredClone(data));
11278
- }
11279
- static empty() {
11280
- return new _InMemoryStateManager({ resources: [] });
11281
- }
11282
- getResource(address) {
11283
- const i = this.index.get(addressKey(address));
11284
- return i !== void 0 ? this.state.resources[i] : void 0;
11285
- }
11286
- setResource(resource) {
11287
- const key = addressKey(resource.address);
11288
- const i = this.index.get(key);
11289
- if (i !== void 0) {
11290
- this.state.resources[i] = resource;
11291
- } else {
11292
- this.index.set(key, this.state.resources.length);
11293
- this.state.resources.push(resource);
11294
- }
11295
- }
11296
- removeResource(address) {
11297
- const key = addressKey(address);
11298
- const i = this.index.get(key);
11299
- if (i === void 0) return;
11300
- this.state.resources.splice(i, 1);
11301
- this.index.delete(key);
11302
- for (let j = i; j < this.state.resources.length; j++) {
11303
- this.index.set(addressKey(this.state.resources[j].address), j);
11304
- }
11305
- }
11306
- listResources() {
11307
- return [...this.state.resources];
11308
- }
11309
- findResource(query2) {
11310
- return this.state.resources.find((resource) => {
11311
- const matchType = resource.address.type === query2.type;
11312
- const matchName = resource.address.name === query2.name;
11313
- const matchProvider = !query2.provider || resource.address.provider === query2.provider;
11314
- return matchType && matchName && matchProvider;
11315
- });
11316
- }
11317
- getStateFile() {
11318
- return this.state;
11319
- }
11320
- async save() {
11321
- }
11322
- };
11323
-
11324
11677
  // src/internal/state/local-file-state-backend.ts
11325
11678
  var LocalFileStateBackend = class {
11326
11679
  configPath;
@@ -11493,6 +11846,7 @@ var SessionEventTypeSchema = z6.enum([
11493
11846
  "unknown"
11494
11847
  ]);
11495
11848
  var AgentSyncStatusSchema = z6.enum(["completed", "blocked", "failed"]);
11849
+ var AgentSyncReasonSchema = z6.enum(["destructive_blocked", "cancelled", "diagnostic_error", "plan_stale"]);
11496
11850
  var AgentSyncResultSchema = z6.object({
11497
11851
  action: PlannedActionSchema,
11498
11852
  status: z6.enum(["success", "failed", "skipped"]),
@@ -11502,6 +11856,7 @@ var AgentSyncRunSchema = z6.object({
11502
11856
  agentId: z6.string(),
11503
11857
  provider: z6.string().optional(),
11504
11858
  status: AgentSyncStatusSchema,
11859
+ reason: AgentSyncReasonSchema.optional(),
11505
11860
  actions: z6.array(PlannedActionSchema),
11506
11861
  diagnostics: z6.array(DiagnosticSchema),
11507
11862
  destructiveActions: z6.array(PlannedActionSchema),
@@ -11619,6 +11974,7 @@ export {
11619
11974
  AgentReadinessStatusSchema,
11620
11975
  AgentRecoveryActionSchema,
11621
11976
  AgentSkillRefSchema,
11977
+ AgentSyncReasonSchema,
11622
11978
  AgentSyncResultSchema,
11623
11979
  AgentSyncRunSchema,
11624
11980
  AgentSyncStatusSchema,
@@ -11708,7 +12064,9 @@ export {
11708
12064
  getSession,
11709
12065
  getSkillInfo,
11710
12066
  importResource,
12067
+ inspectProjectSource,
11711
12068
  inspectSkillSource,
12069
+ isAgentRunnable,
11712
12070
  isTerminalSessionStatus,
11713
12071
  listAgentsWithReadiness,
11714
12072
  listCloudAgents,
@@ -590,6 +590,13 @@ declare const AgentSyncStatusSchema: z.ZodEnum<{
590
590
  failed: "failed";
591
591
  }>;
592
592
  type AgentSyncStatus = z.infer<typeof AgentSyncStatusSchema>;
593
+ declare const AgentSyncReasonSchema: z.ZodEnum<{
594
+ destructive_blocked: "destructive_blocked";
595
+ cancelled: "cancelled";
596
+ diagnostic_error: "diagnostic_error";
597
+ plan_stale: "plan_stale";
598
+ }>;
599
+ type AgentSyncReason = z.infer<typeof AgentSyncReasonSchema>;
593
600
  declare const AgentSyncResultSchema: z.ZodObject<{
594
601
  action: z.ZodObject<{
595
602
  action: z.ZodEnum<{
@@ -678,6 +685,12 @@ declare const AgentSyncRunSchema: z.ZodObject<{
678
685
  blocked: "blocked";
679
686
  failed: "failed";
680
687
  }>;
688
+ reason: z.ZodOptional<z.ZodEnum<{
689
+ destructive_blocked: "destructive_blocked";
690
+ cancelled: "cancelled";
691
+ diagnostic_error: "diagnostic_error";
692
+ plan_stale: "plan_stale";
693
+ }>>;
681
694
  actions: z.ZodArray<z.ZodObject<{
682
695
  action: z.ZodEnum<{
683
696
  create: "create";
@@ -1133,4 +1146,4 @@ interface ProviderSessionEventList {
1133
1146
  next_page?: string;
1134
1147
  }
1135
1148
 
1136
- export { type ListCloudEnvironmentsResponse as $, type AgentDefinition as A, type AgentSyncStatus as B, type CloudAgent as C, type Diagnostic as D, type EventStreamOptions as E, AgentSyncStatusSchema as F, AgentWithReadinessSchema as G, CloudAgentSchema as H, CloudEnvironmentSchema as I, CloudVaultSchema as J, type CreateSessionRequest as K, CreateSessionRequestSchema as L, type CreateSessionResponse as M, CreateSessionResponseSchema as N, DiagnosticSchema as O, type ProviderSessionEvent as P, type DiagnosticSeverity as Q, type ResourceAddress as R, DiagnosticSeveritySchema as S, type DriftKind as T, DriftKindSchema as U, type GetSessionRequest as V, GetSessionRequestSchema as W, KNOWN_SESSION_EVENT_TYPES as X, type KnownSessionEventType as Y, type ListCloudAgentsResponse as Z, ListCloudAgentsResponseSchema as _, type CloudEnvironment as a, ListCloudEnvironmentsResponseSchema as a0, type ListSessionEventsRequest as a1, ListSessionEventsRequestSchema as a2, type ListSessionEventsResponse as a3, ListSessionEventsResponseSchema as a4, type ListSessionsRequest as a5, ListSessionsRequestSchema as a6, type ListSessionsResponse as a7, ListSessionsResponseSchema as a8, type PlanReadinessImpact as a9, PlanReadinessImpactSchema as aa, PlannedActionSchema as ab, ResourceAddressSchema as ac, ResourceTypeSchema as ad, type SendEventRequest as ae, SendEventRequestSchema as af, type SendEventResponse as ag, SendEventResponseSchema as ah, type Session as ai, type SessionAgent as aj, SessionAgentSchema as ak, type SessionContentBlock as al, SessionContentBlockSchema as am, type SessionEvent as an, SessionEventSchema as ao, type SessionEventType as ap, type SessionEventTypeName as aq, SessionEventTypeSchema as ar, SessionSchema as as, type CloudVault as b, type ResourceType as c, type EventListOptions as d, type ProviderSessionEventList as e, type PlannedAction as f, type AgentWithReadiness as g, type AgentSyncRun as h, type ActionType as i, ActionTypeSchema as j, AgentDefinitionSchema as k, type AgentDriftSeverity as l, AgentDriftSeveritySchema as m, type AgentModel as n, AgentModelSchema as o, type AgentReadiness as p, AgentReadinessSchema as q, type AgentReadinessStatus as r, AgentReadinessStatusSchema as s, type AgentRecoveryAction as t, AgentRecoveryActionSchema as u, type AgentSkillRef as v, AgentSkillRefSchema as w, type AgentSyncResult as x, AgentSyncResultSchema as y, AgentSyncRunSchema as z };
1149
+ export { type ListCloudAgentsResponse as $, type AgentDefinition as A, AgentSyncResultSchema as B, type CloudAgent as C, type Diagnostic as D, type EventStreamOptions as E, AgentSyncRunSchema as F, type AgentSyncStatus as G, AgentSyncStatusSchema as H, AgentWithReadinessSchema as I, CloudAgentSchema as J, CloudEnvironmentSchema as K, CloudVaultSchema as L, type CreateSessionRequest as M, CreateSessionRequestSchema as N, type CreateSessionResponse as O, type ProviderSessionEvent as P, CreateSessionResponseSchema as Q, type ResourceAddress as R, DiagnosticSchema as S, type DiagnosticSeverity as T, DiagnosticSeveritySchema as U, type DriftKind as V, DriftKindSchema as W, type GetSessionRequest as X, GetSessionRequestSchema as Y, KNOWN_SESSION_EVENT_TYPES as Z, type KnownSessionEventType as _, type CloudEnvironment as a, ListCloudAgentsResponseSchema as a0, type ListCloudEnvironmentsResponse as a1, ListCloudEnvironmentsResponseSchema as a2, type ListSessionEventsRequest as a3, ListSessionEventsRequestSchema as a4, type ListSessionEventsResponse as a5, ListSessionEventsResponseSchema as a6, type ListSessionsRequest as a7, ListSessionsRequestSchema as a8, type ListSessionsResponse as a9, ListSessionsResponseSchema as aa, type PlanReadinessImpact as ab, PlanReadinessImpactSchema as ac, PlannedActionSchema as ad, ResourceAddressSchema as ae, ResourceTypeSchema as af, type SendEventRequest as ag, SendEventRequestSchema as ah, type SendEventResponse as ai, SendEventResponseSchema as aj, type Session as ak, type SessionAgent as al, SessionAgentSchema as am, type SessionContentBlock as an, SessionContentBlockSchema as ao, type SessionEvent as ap, SessionEventSchema as aq, type SessionEventType as ar, type SessionEventTypeName as as, SessionEventTypeSchema as at, SessionSchema as au, type CloudVault as b, type ResourceType as c, type EventListOptions as d, type ProviderSessionEventList as e, type PlannedAction as f, type AgentReadiness as g, type AgentWithReadiness as h, type AgentSyncRun as i, type ActionType as j, ActionTypeSchema as k, AgentDefinitionSchema as l, type AgentDriftSeverity as m, AgentDriftSeveritySchema as n, type AgentModel as o, AgentModelSchema as p, AgentReadinessSchema as q, type AgentReadinessStatus as r, AgentReadinessStatusSchema as s, type AgentRecoveryAction as t, AgentRecoveryActionSchema as u, type AgentSkillRef as v, AgentSkillRefSchema as w, type AgentSyncReason as x, AgentSyncReasonSchema as y, type AgentSyncResult as z };
@@ -1,4 +1,4 @@
1
- import { P as ProviderSessionEvent, an as SessionEvent } from './session-event-5kLRNMHC.js';
1
+ import { P as ProviderSessionEvent, ap as SessionEvent } from './session-event-B63Rbjim.js';
2
2
  import 'zod';
3
3
 
4
4
  declare function sanitizeSessionEvents(events: ProviderSessionEvent[], options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openagentpack/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "OpenAgentPack SDK (Node-compatible runtime)",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [