@open-agent-toolkit/cli 0.2.51 → 0.2.53
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/bootstrap.md +6 -2
- package/assets/docs/cli-utilities/tool-packs.md +87 -33
- package/assets/docs/provider-sync/commands.md +30 -2
- package/assets/docs/provider-sync/config.md +19 -0
- package/assets/docs/provider-sync/manifest-and-drift.md +37 -0
- package/assets/docs/provider-sync/providers.md +69 -2
- package/assets/docs/provider-sync/scope-and-surface.md +44 -0
- package/assets/docs/reference/cli-reference.md +1 -0
- package/assets/docs/reference/oat-directory-structure.md +11 -4
- package/assets/docs/workflows/projects/evidence-layers.md +110 -1
- package/assets/docs/workflows/projects/implementation-execution.md +13 -0
- package/assets/docs/workflows/projects/orchestration-model.md +18 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +57 -1
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +77 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +24 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +11 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-review-provide/SKILL.md +12 -1
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -1
- package/dist/agents/canonical/index.d.ts +2 -0
- package/dist/agents/canonical/index.d.ts.map +1 -1
- package/dist/agents/canonical/index.js +1 -0
- package/dist/agents/canonical/resolve.d.ts +45 -0
- package/dist/agents/canonical/resolve.d.ts.map +1 -0
- package/dist/agents/canonical/resolve.js +175 -0
- package/dist/commands/decision/agents-guidance.d.ts +2 -2
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +1 -4
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +25 -6
- package/dist/commands/docs/init/index.d.ts +7 -1
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +53 -20
- package/dist/commands/doctor/index.d.ts +8 -2
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +157 -46
- package/dist/commands/init/index.d.ts +8 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +66 -28
- package/dist/commands/init/tools/index.d.ts +12 -12
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +430 -99
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-guidance.d.ts +49 -0
- package/dist/commands/init/tools/project-guidance.d.ts.map +1 -0
- package/dist/commands/init/tools/project-guidance.js +144 -0
- package/dist/commands/init/tools/workflows/index.d.ts +7 -0
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +160 -7
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +28 -3
- package/dist/commands/pjm/init.d.ts +5 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +19 -3
- package/dist/commands/project/dispatch/index.d.ts +10 -0
- package/dist/commands/project/dispatch/index.d.ts.map +1 -0
- package/dist/commands/project/dispatch/index.js +137 -0
- package/dist/commands/project/dispatch/record.d.ts +91 -0
- package/dist/commands/project/dispatch/record.d.ts.map +1 -0
- package/dist/commands/project/dispatch/record.js +402 -0
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +2 -0
- package/dist/commands/providers/inspect/inspect.d.ts +8 -1
- package/dist/commands/providers/inspect/inspect.d.ts.map +1 -1
- package/dist/commands/providers/inspect/inspect.js +146 -26
- package/dist/commands/providers/list/list.d.ts +8 -1
- package/dist/commands/providers/list/list.d.ts.map +1 -1
- package/dist/commands/providers/list/list.js +139 -23
- package/dist/commands/providers/providers.types.d.ts +25 -1
- package/dist/commands/providers/providers.types.d.ts.map +1 -1
- package/dist/commands/providers/set/index.d.ts +9 -1
- package/dist/commands/providers/set/index.d.ts.map +1 -1
- package/dist/commands/providers/set/index.js +43 -33
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +11 -0
- package/dist/commands/shared/agents-md.d.ts +42 -14
- package/dist/commands/shared/agents-md.d.ts.map +1 -1
- package/dist/commands/shared/agents-md.js +364 -70
- package/dist/commands/status/index.d.ts +8 -3
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +149 -37
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +220 -29
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +30 -6
- package/dist/commands/sync/index.d.ts +17 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +108 -43
- package/dist/commands/sync/sync.types.d.ts +39 -2
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts +5 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +73 -0
- package/dist/commands/tools/info/info-tool.d.ts +2 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +34 -12
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +19 -3
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +36 -7
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +150 -21
- package/dist/commands/tools/remove/remove-tools.d.ts +20 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +122 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +19 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +109 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +66 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-evidence.js +132 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts +1 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +44 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +91 -0
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +74 -4
- package/dist/commands/tools/update/update-tools.d.ts +5 -0
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +64 -2
- package/dist/config/oat-config.d.ts +5 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +17 -5
- package/dist/config/user-sync-config.d.ts +1 -0
- package/dist/config/user-sync-config.d.ts.map +1 -1
- package/dist/config/user-sync-config.js +8 -0
- package/dist/drift/detector.d.ts +2 -2
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/drift/detector.js +18 -0
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +5 -0
- package/dist/engine/collection-sync.d.ts +14 -0
- package/dist/engine/collection-sync.d.ts.map +1 -0
- package/dist/engine/collection-sync.js +282 -0
- package/dist/engine/compute-plan.d.ts +8 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +303 -12
- package/dist/engine/engine.types.d.ts +61 -0
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/execute-plan.d.ts +22 -2
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +459 -27
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +1 -1
- package/dist/engine/provider-path-safety.d.ts +1 -0
- package/dist/engine/provider-path-safety.d.ts.map +1 -1
- package/dist/engine/provider-path-safety.js +15 -0
- package/dist/engine/scanner.d.ts +9 -2
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +58 -4
- package/dist/fs/io.d.ts +67 -0
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +536 -3
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/manager.d.ts +2 -2
- package/dist/manifest/manager.d.ts.map +1 -1
- package/dist/manifest/manager.js +20 -3
- package/dist/manifest/manifest.types.d.ts +704 -13
- package/dist/manifest/manifest.types.d.ts.map +1 -1
- package/dist/manifest/manifest.types.js +131 -15
- package/dist/providers/codex/codec/sync-extension.d.ts +1 -1
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +48 -17
- package/dist/providers/cursor/codec/sync-extension.d.ts +1 -1
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/cursor/codec/sync-extension.js +52 -23
- package/dist/providers/identity/absolute-paths.d.ts +68 -0
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -0
- package/dist/providers/identity/absolute-paths.js +144 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts +105 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +40 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +146 -0
- package/dist/providers/identity/claude-runtime-observation.js +229 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts +75 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts +37 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.js +539 -0
- package/dist/providers/identity/codex-runtime-observation.js +255 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts +313 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/generic-dispatch-record.js +539 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts +1964 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/oat-dispatch-record.js +691 -0
- package/dist/providers/identity/runtime-observation.d.ts +100 -0
- package/dist/providers/identity/runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/runtime-observation.js +169 -0
- package/dist/providers/shared/index.d.ts +2 -0
- package/dist/providers/shared/index.d.ts.map +1 -1
- package/dist/providers/shared/index.js +1 -0
- package/dist/providers/shared/materialization-extension.d.ts +12 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -1
- package/dist/providers/shared/registry.d.ts +69 -0
- package/dist/providers/shared/registry.d.ts.map +1 -0
- package/dist/providers/shared/registry.js +252 -0
- package/dist/providers/shared/restart-adviser.d.ts +26 -0
- package/dist/providers/shared/restart-adviser.d.ts.map +1 -0
- package/dist/providers/shared/restart-adviser.js +96 -0
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -4,6 +4,7 @@ import { basename, dirname, join, normalize, relative, resolve, } from 'node:pat
|
|
|
4
4
|
import { computeContentHash, computeStringHash } from '../manifest/hash.js';
|
|
5
5
|
import { findEntry } from '../manifest/manager.js';
|
|
6
6
|
import { getSyncMappings } from '../providers/shared/adapter.utils.js';
|
|
7
|
+
import { proveCollectionIdentity } from './collection-sync.js';
|
|
7
8
|
import { OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX } from './markers.js';
|
|
8
9
|
import { assertSafeProviderMutationPath } from './provider-path-safety.js';
|
|
9
10
|
function buildUpLevels(depth) {
|
|
@@ -65,6 +66,32 @@ function resolveStrategy(adapter, config, transformCanonical) {
|
|
|
65
66
|
}
|
|
66
67
|
return 'symlink';
|
|
67
68
|
}
|
|
69
|
+
function resolveConfiguredStrategy(adapter, config) {
|
|
70
|
+
const providerConfig = config.providers[adapter.name];
|
|
71
|
+
if (providerConfig?.enabled === false) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
return (providerConfig?.strategy ??
|
|
75
|
+
config.defaultStrategy ??
|
|
76
|
+
adapter.defaultStrategy);
|
|
77
|
+
}
|
|
78
|
+
function relativeManifestPath(scopeRoot, path) {
|
|
79
|
+
return relative(scopeRoot, path).replaceAll('\\', '/');
|
|
80
|
+
}
|
|
81
|
+
function collectionFallbackReason(reason) {
|
|
82
|
+
if (reason === 'real-directory') {
|
|
83
|
+
return 'provider collection is a real directory; use per-entry sync';
|
|
84
|
+
}
|
|
85
|
+
return `collection identity is ${reason}; preserve the provider collection without child mutation`;
|
|
86
|
+
}
|
|
87
|
+
function collectionCreationIdentityMatches(collection, proof) {
|
|
88
|
+
return (collection.ownership === 'oat-created' &&
|
|
89
|
+
collection.createdLink !== undefined &&
|
|
90
|
+
proof.status === 'exact-link' &&
|
|
91
|
+
collection.createdLink.device === proof.providerLink.device &&
|
|
92
|
+
collection.createdLink.inode === proof.providerLink.inode &&
|
|
93
|
+
collection.createdLink.linkText === proof.linkText);
|
|
94
|
+
}
|
|
68
95
|
async function pathExists(path) {
|
|
69
96
|
try {
|
|
70
97
|
await access(path);
|
|
@@ -98,6 +125,22 @@ function createRetirementEntry(manifestEntry, scopeRoot, operation, reason) {
|
|
|
98
125
|
reason,
|
|
99
126
|
};
|
|
100
127
|
}
|
|
128
|
+
function createCollectionDetachmentEntry(manifestEntry, scopeRoot) {
|
|
129
|
+
const canonicalRelative = manifestEntry.canonicalPath;
|
|
130
|
+
return {
|
|
131
|
+
canonical: {
|
|
132
|
+
name: basename(canonicalRelative),
|
|
133
|
+
type: manifestEntry.contentType,
|
|
134
|
+
canonicalPath: resolve(scopeRoot, canonicalRelative),
|
|
135
|
+
isFile: manifestEntry.isFile,
|
|
136
|
+
},
|
|
137
|
+
provider: manifestEntry.provider,
|
|
138
|
+
providerPath: resolve(scopeRoot, manifestEntry.providerPath),
|
|
139
|
+
operation: 'detach',
|
|
140
|
+
strategy: 'symlink',
|
|
141
|
+
reason: 'collection inheritance no longer includes canonical entry',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
101
144
|
function manifestEntryInsideMapping(entry, mapping) {
|
|
102
145
|
if (entry.contentType !== mapping.contentType) {
|
|
103
146
|
return false;
|
|
@@ -316,13 +359,16 @@ function canonicalPathAllowed(relativeCanonicalPath, canonicalFilter) {
|
|
|
316
359
|
}
|
|
317
360
|
return canonicalFilter.has(normalize(relativeCanonicalPath));
|
|
318
361
|
}
|
|
319
|
-
export async function computeSyncPlan({ canonical, adapters, manifest, scope, config, scopeRoot: explicitScopeRoot, allowedCanonicalPaths, }) {
|
|
362
|
+
export async function computeSyncPlan({ canonical, adapters, manifest, scope, config, scopeRoot: explicitScopeRoot, allowedCanonicalPaths, extensionOwnedCanonicalPathsByProvider, collectionAliasEligibleMappings = [], collectionAliasCreationAvailable = false, }) {
|
|
320
363
|
const entries = [];
|
|
321
364
|
const removals = [];
|
|
365
|
+
const collections = [];
|
|
322
366
|
const scopeRoot = resolveScopeRoot(canonical, explicitScopeRoot);
|
|
323
367
|
const seenCanonicalKeys = new Set();
|
|
324
368
|
const activeProviderNames = new Set();
|
|
325
369
|
const activeMappingsByProvider = new Map();
|
|
370
|
+
const manifestV2 = manifest;
|
|
371
|
+
const collectionAliasEligibility = new Set(collectionAliasEligibleMappings.map(({ provider, contentType }) => `${provider}::${contentType}`));
|
|
326
372
|
const canonicalFilter = allowedCanonicalPaths
|
|
327
373
|
? new Set(allowedCanonicalPaths.map((canonicalPath) => normalize(canonicalPath)))
|
|
328
374
|
: null;
|
|
@@ -338,11 +384,204 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
338
384
|
const activeMappings = activeMappingsByProvider.get(adapter.name) ?? [];
|
|
339
385
|
activeMappings.push(mapping);
|
|
340
386
|
activeMappingsByProvider.set(adapter.name, activeMappings);
|
|
387
|
+
const configuredStrategy = resolveConfiguredStrategy(adapter, config);
|
|
388
|
+
const collectionCandidates = canonical.filter((canonicalEntry) => {
|
|
389
|
+
if (!entryContentTypeMatches(canonicalEntry, mapping.contentType)) {
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
const relativeCanonicalPath = canonicalRelativePath(canonicalEntry);
|
|
393
|
+
const extensionOwnedPaths = extensionOwnedCanonicalPathsByProvider?.[adapter.name] ?? [];
|
|
394
|
+
return (!extensionOwnedPaths.some((ownedPath) => normalize(ownedPath) === normalize(relativeCanonicalPath)) &&
|
|
395
|
+
canonicalPathAllowed(relativeCanonicalPath, canonicalFilter) &&
|
|
396
|
+
entryInsideMapping(canonicalEntry, mapping.canonicalDir));
|
|
397
|
+
});
|
|
398
|
+
let inheritCollection = false;
|
|
399
|
+
let deferredCollectionTransition = false;
|
|
400
|
+
const canonicalDir = scopeRoot
|
|
401
|
+
? resolve(scopeRoot, mapping.canonicalDir)
|
|
402
|
+
: null;
|
|
403
|
+
const providerDir = scopeRoot
|
|
404
|
+
? resolve(scopeRoot, mapping.providerDir)
|
|
405
|
+
: null;
|
|
406
|
+
const existingCollection = scopeRoot && canonicalDir && providerDir
|
|
407
|
+
? manifest.collections.find((collection) => collection.provider === adapter.name &&
|
|
408
|
+
collection.contentType === mapping.contentType &&
|
|
409
|
+
collection.canonicalDir ===
|
|
410
|
+
relativeManifestPath(scopeRoot, canonicalDir) &&
|
|
411
|
+
collection.providerDir ===
|
|
412
|
+
relativeManifestPath(scopeRoot, providerDir))
|
|
413
|
+
: undefined;
|
|
414
|
+
const existingInheritedEntries = existingCollection
|
|
415
|
+
? manifestV2.entries
|
|
416
|
+
.filter((entry) => entry.strategy === 'collection' &&
|
|
417
|
+
entry.collectionId === existingCollection.id)
|
|
418
|
+
.map((entry) => entry.canonicalPath)
|
|
419
|
+
.sort()
|
|
420
|
+
: [];
|
|
421
|
+
const collectionEligible = configuredStrategy === 'auto' &&
|
|
422
|
+
mapping.contentType === 'skill' &&
|
|
423
|
+
collectionAliasEligibility.has(`${adapter.name}::${mapping.contentType}`) &&
|
|
424
|
+
adapter.defaultStrategy !== 'copy' &&
|
|
425
|
+
!mapping.transformCanonical &&
|
|
426
|
+
!mapping.providerExtension &&
|
|
427
|
+
canonicalDir !== null &&
|
|
428
|
+
providerDir !== null &&
|
|
429
|
+
collectionCandidates.length > 0;
|
|
430
|
+
if (existingCollection !== undefined &&
|
|
431
|
+
!collectionEligible &&
|
|
432
|
+
canonicalDir !== null &&
|
|
433
|
+
providerDir !== null) {
|
|
434
|
+
const proof = await proveCollectionIdentity({
|
|
435
|
+
root: scopeRoot,
|
|
436
|
+
canonicalDir,
|
|
437
|
+
providerDir,
|
|
438
|
+
});
|
|
439
|
+
const safelyClear = proof.status === 'absent' ||
|
|
440
|
+
collectionCreationIdentityMatches(existingCollection, proof);
|
|
441
|
+
if (safelyClear) {
|
|
442
|
+
collections.push({
|
|
443
|
+
provider: adapter.name,
|
|
444
|
+
scope,
|
|
445
|
+
contentType: mapping.contentType,
|
|
446
|
+
canonicalDir,
|
|
447
|
+
providerDir,
|
|
448
|
+
action: 'detach-collection',
|
|
449
|
+
ownership: existingCollection.ownership,
|
|
450
|
+
configuredStrategy: configuredStrategy ?? 'auto',
|
|
451
|
+
proof,
|
|
452
|
+
createdLink: existingCollection.createdLink,
|
|
453
|
+
transitionToPerEntry: true,
|
|
454
|
+
inheritedEntries: existingInheritedEntries,
|
|
455
|
+
reason: proof.status === 'absent'
|
|
456
|
+
? 'collection alias is absent in this plan; revalidate absence before transitioning to explicit per-entry sync'
|
|
457
|
+
: 'collection alias requires guarded removal before transitioning to explicit per-entry sync',
|
|
458
|
+
});
|
|
459
|
+
deferredCollectionTransition = true;
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
collections.push({
|
|
463
|
+
provider: adapter.name,
|
|
464
|
+
scope,
|
|
465
|
+
contentType: mapping.contentType,
|
|
466
|
+
canonicalDir,
|
|
467
|
+
providerDir,
|
|
468
|
+
action: 'reject-collection',
|
|
469
|
+
ownership: existingCollection.ownership,
|
|
470
|
+
configuredStrategy: configuredStrategy ?? 'auto',
|
|
471
|
+
proof,
|
|
472
|
+
createdLink: existingCollection.createdLink,
|
|
473
|
+
inheritedEntries: existingInheritedEntries,
|
|
474
|
+
reason: 'collection alias cannot be safely cleared with durable creation identity; preserve it and resolve the collection path before retrying per-entry sync',
|
|
475
|
+
});
|
|
476
|
+
inheritCollection = true;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
if (collectionEligible && canonicalDir !== null && providerDir !== null) {
|
|
480
|
+
const proof = await proveCollectionIdentity({
|
|
481
|
+
root: scopeRoot,
|
|
482
|
+
canonicalDir,
|
|
483
|
+
providerDir,
|
|
484
|
+
});
|
|
485
|
+
const inheritedEntries = collectionCandidates.map((entry) => relativeManifestPath(scopeRoot, entry.canonicalPath));
|
|
486
|
+
const inheritedEntriesUnchanged = existingCollection !== undefined &&
|
|
487
|
+
existingInheritedEntries.length === inheritedEntries.length &&
|
|
488
|
+
existingInheritedEntries.every((entry, index) => entry === [...inheritedEntries].sort()[index]);
|
|
489
|
+
if (proof.status === 'absent') {
|
|
490
|
+
collections.push({
|
|
491
|
+
provider: adapter.name,
|
|
492
|
+
scope,
|
|
493
|
+
contentType: mapping.contentType,
|
|
494
|
+
canonicalDir,
|
|
495
|
+
providerDir,
|
|
496
|
+
action: collectionAliasCreationAvailable
|
|
497
|
+
? 'create-collection-link'
|
|
498
|
+
: 'fallback-per-entry',
|
|
499
|
+
ownership: collectionAliasCreationAvailable
|
|
500
|
+
? 'oat-created'
|
|
501
|
+
: 'none',
|
|
502
|
+
configuredStrategy: 'auto',
|
|
503
|
+
proof,
|
|
504
|
+
inheritedEntries,
|
|
505
|
+
reason: collectionAliasCreationAvailable
|
|
506
|
+
? 'provider collection is absent and a guarded creation primitive is available'
|
|
507
|
+
: 'provider collection is absent, but this runtime has no securely guarded parent-relative collection-link primitive; use safe per-entry sync',
|
|
508
|
+
});
|
|
509
|
+
inheritCollection = collectionAliasCreationAvailable;
|
|
510
|
+
}
|
|
511
|
+
else if (proof.status === 'exact-link') {
|
|
512
|
+
if (!inheritedEntriesUnchanged) {
|
|
513
|
+
collections.push({
|
|
514
|
+
provider: adapter.name,
|
|
515
|
+
scope,
|
|
516
|
+
contentType: mapping.contentType,
|
|
517
|
+
canonicalDir,
|
|
518
|
+
providerDir,
|
|
519
|
+
action: existingCollection === undefined
|
|
520
|
+
? 'adopt-collection-link'
|
|
521
|
+
: 'inherit-collection',
|
|
522
|
+
ownership: existingCollection?.ownership ?? 'adopted-exact',
|
|
523
|
+
configuredStrategy: 'auto',
|
|
524
|
+
createdLink: existingCollection?.createdLink,
|
|
525
|
+
proof,
|
|
526
|
+
inheritedEntries,
|
|
527
|
+
reason: existingCollection === undefined
|
|
528
|
+
? 'existing collection alias exactly matches canonical target'
|
|
529
|
+
: 'owned collection alias inheritance changed',
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
inheritCollection = true;
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
if (existingCollection !== undefined) {
|
|
536
|
+
collections.push({
|
|
537
|
+
provider: adapter.name,
|
|
538
|
+
scope,
|
|
539
|
+
contentType: mapping.contentType,
|
|
540
|
+
canonicalDir,
|
|
541
|
+
providerDir,
|
|
542
|
+
action: 'detach-collection',
|
|
543
|
+
ownership: existingCollection.ownership,
|
|
544
|
+
configuredStrategy: 'auto',
|
|
545
|
+
createdLink: existingCollection.createdLink,
|
|
546
|
+
proof,
|
|
547
|
+
inheritedEntries: existingInheritedEntries,
|
|
548
|
+
reason: 'owned collection alias changed or became unverifiable; preserve and detach ownership',
|
|
549
|
+
});
|
|
550
|
+
inheritCollection = true;
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
const fallback = proof.reason === 'real-directory';
|
|
554
|
+
collections.push({
|
|
555
|
+
provider: adapter.name,
|
|
556
|
+
scope,
|
|
557
|
+
contentType: mapping.contentType,
|
|
558
|
+
canonicalDir,
|
|
559
|
+
providerDir,
|
|
560
|
+
action: fallback ? 'fallback-per-entry' : 'reject-collection',
|
|
561
|
+
ownership: 'none',
|
|
562
|
+
configuredStrategy: 'auto',
|
|
563
|
+
proof,
|
|
564
|
+
inheritedEntries,
|
|
565
|
+
reason: collectionFallbackReason(proof.reason),
|
|
566
|
+
});
|
|
567
|
+
inheritCollection = !fallback;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
if (inheritCollection) {
|
|
571
|
+
for (const canonicalEntry of collectionCandidates) {
|
|
572
|
+
seenCanonicalKeys.add(`${normalize(canonicalRelativePath(canonicalEntry))}::${adapter.name}`);
|
|
573
|
+
}
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
341
576
|
for (const canonicalEntry of canonical) {
|
|
342
577
|
if (!entryContentTypeMatches(canonicalEntry, mapping.contentType)) {
|
|
343
578
|
continue;
|
|
344
579
|
}
|
|
345
580
|
const relativeCanonicalPath = canonicalRelativePath(canonicalEntry);
|
|
581
|
+
const extensionOwnedPaths = extensionOwnedCanonicalPathsByProvider?.[adapter.name] ?? [];
|
|
582
|
+
if (extensionOwnedPaths.some((ownedPath) => normalize(ownedPath) === normalize(relativeCanonicalPath))) {
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
346
585
|
if (!canonicalPathAllowed(relativeCanonicalPath, canonicalFilter)) {
|
|
347
586
|
continue;
|
|
348
587
|
}
|
|
@@ -359,9 +598,21 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
359
598
|
const manifestEntry = findEntry(manifest, normalize(relativeCanonicalPath), adapter.name);
|
|
360
599
|
const entryStrategy = mapping.transformCanonical
|
|
361
600
|
? 'copy'
|
|
362
|
-
:
|
|
363
|
-
|
|
364
|
-
|
|
601
|
+
: manifestEntry?.strategy === 'symlink' ||
|
|
602
|
+
manifestEntry?.strategy === 'copy'
|
|
603
|
+
? manifestEntry.strategy
|
|
604
|
+
: mappingStrategy;
|
|
605
|
+
const operation = deferredCollectionTransition
|
|
606
|
+
? {
|
|
607
|
+
operation: entryStrategy === 'copy'
|
|
608
|
+
? 'create_copy'
|
|
609
|
+
: 'create_symlink',
|
|
610
|
+
reason: 'collection alias will be safely detached before per-entry reconciliation',
|
|
611
|
+
}
|
|
612
|
+
: await (async () => {
|
|
613
|
+
await assertSafeProviderMutationPath(entryScopeRoot, providerPath);
|
|
614
|
+
return classifyOperation(canonicalEntry, providerPath, entryStrategy, renderedContent);
|
|
615
|
+
})();
|
|
365
616
|
entries.push({
|
|
366
617
|
canonical: canonicalEntry,
|
|
367
618
|
provider: adapter.name,
|
|
@@ -370,21 +621,61 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
370
621
|
strategy: entryStrategy,
|
|
371
622
|
reason: operation.reason,
|
|
372
623
|
renderedContent,
|
|
624
|
+
...(deferredCollectionTransition
|
|
625
|
+
? { deferredUntilCollectionDetached: true }
|
|
626
|
+
: {}),
|
|
373
627
|
});
|
|
374
628
|
seenCanonicalKeys.add(`${normalize(relativeCanonicalPath)}::${adapter.name}`);
|
|
375
629
|
}
|
|
376
630
|
}
|
|
377
631
|
}
|
|
378
632
|
if (!scopeRoot) {
|
|
379
|
-
return { scope, entries, removals };
|
|
633
|
+
return { scope, entries, removals, collections };
|
|
380
634
|
}
|
|
381
|
-
for (const
|
|
382
|
-
if (
|
|
635
|
+
for (const collection of manifest.collections) {
|
|
636
|
+
if (activeProviderNames.has(collection.provider)) {
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
639
|
+
const canonicalDir = resolve(scopeRoot, collection.canonicalDir);
|
|
640
|
+
const providerDir = resolve(scopeRoot, collection.providerDir);
|
|
641
|
+
const proof = await proveCollectionIdentity({
|
|
642
|
+
root: scopeRoot,
|
|
643
|
+
canonicalDir,
|
|
644
|
+
providerDir,
|
|
645
|
+
});
|
|
646
|
+
collections.push({
|
|
647
|
+
provider: collection.provider,
|
|
648
|
+
scope,
|
|
649
|
+
contentType: collection.contentType,
|
|
650
|
+
canonicalDir,
|
|
651
|
+
providerDir,
|
|
652
|
+
action: 'detach-collection',
|
|
653
|
+
ownership: collection.ownership,
|
|
654
|
+
configuredStrategy: 'auto',
|
|
655
|
+
proof,
|
|
656
|
+
createdLink: collection.createdLink,
|
|
657
|
+
inheritedEntries: manifestV2.entries
|
|
658
|
+
.filter((entry) => entry.strategy === 'collection' &&
|
|
659
|
+
entry.collectionId === collection.id)
|
|
660
|
+
.map((entry) => entry.canonicalPath),
|
|
661
|
+
reason: 'provider is disabled; reconcile collection ownership',
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
for (const manifestEntry of manifestV2.entries) {
|
|
665
|
+
if (manifestEntry.strategy === 'collection') {
|
|
666
|
+
if (!activeProviderNames.has(manifestEntry.provider)) {
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
const canonicalKey = `${normalize(manifestEntry.canonicalPath)}::${manifestEntry.provider}`;
|
|
670
|
+
if (!seenCanonicalKeys.has(canonicalKey)) {
|
|
671
|
+
removals.push(createCollectionDetachmentEntry(manifestEntry, scopeRoot));
|
|
672
|
+
}
|
|
383
673
|
continue;
|
|
384
674
|
}
|
|
385
|
-
if (
|
|
675
|
+
if (!activeProviderNames.has(manifestEntry.provider)) {
|
|
386
676
|
continue;
|
|
387
677
|
}
|
|
678
|
+
const perEntryManifestEntry = manifestEntry;
|
|
388
679
|
const canonicalKey = `${normalize(manifestEntry.canonicalPath)}::${manifestEntry.provider}`;
|
|
389
680
|
if (seenCanonicalKeys.has(canonicalKey)) {
|
|
390
681
|
continue;
|
|
@@ -393,14 +684,14 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
393
684
|
!canonicalFilter.has(normalize(manifestEntry.canonicalPath))) {
|
|
394
685
|
continue;
|
|
395
686
|
}
|
|
396
|
-
const mappingStillExists = (activeMappingsByProvider.get(manifestEntry.provider) ?? []).some((mapping) => manifestEntryInsideMapping(
|
|
687
|
+
const mappingStillExists = (activeMappingsByProvider.get(manifestEntry.provider) ?? []).some((mapping) => manifestEntryInsideMapping(perEntryManifestEntry, mapping));
|
|
397
688
|
const removal = mappingStillExists
|
|
398
|
-
? createRemovalEntry(
|
|
399
|
-
: await classifyObsoleteMappingRetirement(
|
|
689
|
+
? createRemovalEntry(perEntryManifestEntry, scopeRoot)
|
|
690
|
+
: await classifyObsoleteMappingRetirement(perEntryManifestEntry, scopeRoot);
|
|
400
691
|
if (removal.operation === 'remove') {
|
|
401
692
|
await assertSafeProviderMutationPath(scopeRoot, removal.providerPath);
|
|
402
693
|
}
|
|
403
694
|
removals.push(removal);
|
|
404
695
|
}
|
|
405
|
-
return { scope, entries, removals };
|
|
696
|
+
return { scope, entries, removals, collections };
|
|
406
697
|
}
|
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
import type { Scope } from '../shared/types.js';
|
|
2
2
|
import type { CanonicalEntry } from './scanner.js';
|
|
3
|
+
export interface CollectionPathIdentity {
|
|
4
|
+
device: string;
|
|
5
|
+
inode: string;
|
|
6
|
+
type: 'directory' | 'symlink';
|
|
7
|
+
modifiedAtNanoseconds: string;
|
|
8
|
+
}
|
|
9
|
+
export interface CollectionLinkIdentity {
|
|
10
|
+
device: string;
|
|
11
|
+
inode: string;
|
|
12
|
+
linkText: string;
|
|
13
|
+
}
|
|
14
|
+
export type CollectionIdentityProof = {
|
|
15
|
+
status: 'absent';
|
|
16
|
+
canonicalDirectory: CollectionPathIdentity;
|
|
17
|
+
providerParent: CollectionPathIdentity;
|
|
18
|
+
checkedAt: string;
|
|
19
|
+
} | {
|
|
20
|
+
status: 'exact-link';
|
|
21
|
+
providerLink: CollectionPathIdentity;
|
|
22
|
+
canonicalDirectory: CollectionPathIdentity;
|
|
23
|
+
linkTextKind: 'relative' | 'absolute';
|
|
24
|
+
linkText: string;
|
|
25
|
+
resolvedTarget: string;
|
|
26
|
+
entrySetDigest: string;
|
|
27
|
+
checkedAt: string;
|
|
28
|
+
} | {
|
|
29
|
+
status: 'ineligible';
|
|
30
|
+
reason: 'real-directory' | 'broken-link' | 'foreign-target' | 'divergent-entries' | 'unsafe-ancestry' | 'identity-unavailable';
|
|
31
|
+
observedIdentity?: CollectionPathIdentity;
|
|
32
|
+
checkedAt: string;
|
|
33
|
+
};
|
|
34
|
+
export type CollectionSyncAction = 'create-collection-link' | 'adopt-collection-link' | 'inherit-collection' | 'fallback-per-entry' | 'detach-collection' | 'reject-collection';
|
|
35
|
+
export interface CollectionProjectionPlan {
|
|
36
|
+
provider: string;
|
|
37
|
+
scope: EngineScope;
|
|
38
|
+
contentType: CanonicalEntry['type'];
|
|
39
|
+
canonicalDir: string;
|
|
40
|
+
providerDir: string;
|
|
41
|
+
action: CollectionSyncAction;
|
|
42
|
+
ownership: 'oat-created' | 'adopted-exact' | 'none';
|
|
43
|
+
configuredStrategy: 'auto' | 'symlink' | 'copy';
|
|
44
|
+
createdLink?: CollectionLinkIdentity;
|
|
45
|
+
transitionToPerEntry?: boolean;
|
|
46
|
+
proof: CollectionIdentityProof;
|
|
47
|
+
inheritedEntries: readonly string[];
|
|
48
|
+
reason: string;
|
|
49
|
+
}
|
|
3
50
|
export type EngineScope = Exclude<Scope, 'all'>;
|
|
4
51
|
export declare const SYNC_OPERATION_TYPES: readonly ['create_symlink', 'create_copy', 'update_symlink', 'update_copy', 'remove', 'detach', 'skip'];
|
|
5
52
|
export type SyncOperationType = (typeof SYNC_OPERATION_TYPES)[number];
|
|
@@ -11,6 +58,7 @@ export interface SyncPlanEntry {
|
|
|
11
58
|
strategy: 'symlink' | 'copy';
|
|
12
59
|
reason: string;
|
|
13
60
|
renderedContent?: string;
|
|
61
|
+
deferredUntilCollectionDetached?: boolean;
|
|
14
62
|
}
|
|
15
63
|
export type RemovalSyncPlanEntry = SyncPlanEntry & {
|
|
16
64
|
operation: 'remove' | 'detach';
|
|
@@ -19,10 +67,23 @@ export interface SyncPlan {
|
|
|
19
67
|
scope: EngineScope;
|
|
20
68
|
entries: SyncPlanEntry[];
|
|
21
69
|
removals: RemovalSyncPlanEntry[];
|
|
70
|
+
collections?: CollectionProjectionPlan[];
|
|
71
|
+
}
|
|
72
|
+
export type SyncOperationStatus = 'planned' | 'changed' | 'current' | 'missing' | 'failed' | 'unsupported' | 'unknown';
|
|
73
|
+
export interface SyncOperationResult {
|
|
74
|
+
scope: EngineScope;
|
|
75
|
+
provider: string;
|
|
76
|
+
contentKind: CanonicalEntry['type'];
|
|
77
|
+
asset: string;
|
|
78
|
+
action: SyncOperationType;
|
|
79
|
+
status: SyncOperationStatus;
|
|
80
|
+
failure?: string;
|
|
22
81
|
}
|
|
23
82
|
export interface SyncResult {
|
|
24
83
|
applied: number;
|
|
25
84
|
failed: number;
|
|
26
85
|
skipped: number;
|
|
86
|
+
/** Additive per-operation evidence; optional for legacy execution adapters. */
|
|
87
|
+
operations?: SyncOperationResult[];
|
|
27
88
|
}
|
|
28
89
|
//# sourceMappingURL=engine.types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAEhD,eAAO,MAAM,oBAAoB,YAC/B,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,MAAM,CACE,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,SAAS,GAAG,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.types.d.ts","sourceRoot":"","sources":["../../src/engine/engine.types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,29 @@
|
|
|
1
|
+
import { copyDirectory, createCollectionSymlinkNoClobber, createSymlinkNoClobber, removeCollectionSymlinkIfUnchanged } from '../fs/io.js';
|
|
2
|
+
import { saveManifest as persistManifest } from '../manifest/manager.js';
|
|
1
3
|
import type { Manifest } from '../manifest/manifest.types.js';
|
|
2
|
-
import
|
|
4
|
+
import { proveCollectionIdentity } from './collection-sync.js';
|
|
5
|
+
import type { CollectionProjectionPlan, SyncPlan, SyncResult } from './engine.types.js';
|
|
3
6
|
interface ExecuteSyncPlanDependencies {
|
|
4
7
|
beforeFirstMutation?: () => Promise<void>;
|
|
8
|
+
saveManifest?: typeof persistManifest;
|
|
9
|
+
copyDirectory?: typeof copyDirectory;
|
|
10
|
+
createSymlinkNoClobber?: typeof createSymlinkNoClobber;
|
|
11
|
+
createCollectionSymlinkNoClobber?: typeof createCollectionSymlinkNoClobber;
|
|
12
|
+
removeCollectionSymlinkIfUnchanged?: typeof removeCollectionSymlinkIfUnchanged;
|
|
13
|
+
proveCollectionIdentity?: typeof proveCollectionIdentity;
|
|
5
14
|
}
|
|
15
|
+
export interface CollectionOperationResult {
|
|
16
|
+
provider: string;
|
|
17
|
+
contentType: CollectionProjectionPlan['contentType'];
|
|
18
|
+
action: CollectionProjectionPlan['action'];
|
|
19
|
+
ownership: CollectionProjectionPlan['ownership'];
|
|
20
|
+
status: 'changed' | 'current' | 'fallback' | 'rejected' | 'failed' | 'partial';
|
|
21
|
+
reason: string;
|
|
22
|
+
}
|
|
23
|
+
export type CollectionSyncResult = SyncResult & {
|
|
24
|
+
collectionResults: CollectionOperationResult[];
|
|
25
|
+
};
|
|
6
26
|
export declare function inferScopeRoot(canonicalPath: string): string;
|
|
7
|
-
export declare function executeSyncPlan(plan: SyncPlan, manifest: Manifest, manifestPath: string, dependencies?: ExecuteSyncPlanDependencies): Promise<
|
|
27
|
+
export declare function executeSyncPlan(plan: SyncPlan, manifest: Manifest, manifestPath: string, dependencies?: ExecuteSyncPlanDependencies): Promise<CollectionSyncResult>;
|
|
8
28
|
export {};
|
|
9
29
|
//# sourceMappingURL=execute-plan.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EAGb,gCAAgC,EAEhC,sBAAsB,EACtB,kCAAkC,EAGnC,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAAE,YAAY,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EACV,QAAQ,EAGT,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAGL,uBAAuB,EACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACV,wBAAwB,EAExB,QAAQ,EAER,UAAU,EACX,MAAM,gBAAgB,CAAC;AAIxB,UAAU,2BAA2B;IACnC,mBAAmB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,YAAY,CAAC,EAAE,OAAO,eAAe,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,aAAa,CAAC;IACrC,sBAAsB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IACvD,gCAAgC,CAAC,EAAE,OAAO,gCAAgC,CAAC;IAC3E,kCAAkC,CAAC,EAAE,OAAO,kCAAkC,CAAC;IAC/E,uBAAuB,CAAC,EAAE,OAAO,uBAAuB,CAAC;CAC1D;AAID,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,EAAE,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAC3C,SAAS,EAAE,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,EACF,SAAS,GACT,SAAS,GACT,UAAU,GACV,UAAU,GACV,QAAQ,GACR,SAAS,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,iBAAiB,EAAE,yBAAyB,EAAE,CAAC;CAChD,CAAC;AAiFF,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;AAiqBD,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,EACpB,YAAY,GAAE,2BAAoE,GACjF,OAAO,CAAC,oBAAoB,CAAC,CA+J/B"}
|