@open-agent-toolkit/cli 0.1.74 → 0.1.76
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/docs/cli-utilities/configuration.md +18 -12
- package/assets/docs/provider-sync/commands.md +26 -0
- package/assets/docs/provider-sync/config.md +17 -6
- package/assets/docs/provider-sync/index.md +17 -5
- package/assets/docs/provider-sync/manifest-and-drift.md +39 -1
- package/assets/docs/provider-sync/providers.md +8 -2
- package/assets/docs/provider-sync/scope-and-surface.md +5 -1
- package/assets/docs/reference/file-locations.md +9 -3
- package/assets/docs/reference/oat-directory-structure.md +11 -3
- package/assets/docs/reference/troubleshooting.md +11 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/create-agnostic-skill/SKILL.md +1 -1
- package/assets/skills/create-agnostic-skill/references/docs/skills-guide.md +24 -15
- package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +9 -3
- package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +9 -3
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +55 -0
- package/dist/commands/init/index.d.ts +6 -2
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +90 -31
- package/dist/commands/remove/skill/remove-skill.d.ts +2 -0
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +20 -2
- package/dist/commands/shared/adopt-stray.d.ts.map +1 -1
- package/dist/commands/shared/adopt-stray.js +3 -0
- package/dist/commands/shared/cursor-skill-disposition.d.ts +17 -0
- package/dist/commands/shared/cursor-skill-disposition.d.ts.map +1 -0
- package/dist/commands/shared/cursor-skill-disposition.js +41 -0
- package/dist/commands/status/index.d.ts +10 -4
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +99 -31
- package/dist/config/oat-config.d.ts +0 -1
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +26 -23
- package/dist/config/sync-config.d.ts +6 -2
- package/dist/config/sync-config.d.ts.map +1 -1
- package/dist/config/sync-config.js +18 -6
- package/dist/config/user-sync-config.d.ts +11 -0
- package/dist/config/user-sync-config.d.ts.map +1 -0
- package/dist/config/user-sync-config.js +61 -0
- package/dist/drift/strays.d.ts +1 -1
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +2 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +154 -4
- package/dist/engine/engine.types.d.ts +2 -2
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/engine.types.js +1 -0
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +4 -0
- package/dist/manifest/manifest.types.d.ts +12 -12
- package/dist/providers/cursor/paths.d.ts.map +1 -1
- package/dist/providers/cursor/paths.js +6 -4
- package/dist/providers/shared/adapter.types.d.ts +6 -0
- package/dist/providers/shared/adapter.types.d.ts.map +1 -1
- package/dist/providers/shared/adapter.utils.d.ts +2 -1
- package/dist/providers/shared/adapter.utils.d.ts.map +1 -1
- package/dist/providers/shared/adapter.utils.js +29 -6
- package/package.json +2 -2
|
@@ -2,11 +2,12 @@ import { basename, join, relative } from 'node:path';
|
|
|
2
2
|
import { buildCommandContext, } from '../../app/command-context.js';
|
|
3
3
|
import { adoptStrayToCanonical, isAdoptionConflictError, } from '../shared/adopt-stray.js';
|
|
4
4
|
import { detectCodexRoleStrays, filterMaterializationManagedStrays, regenerateCodexAfterAdoption, } from '../shared/codex-strays.js';
|
|
5
|
+
import { applyCursorSkillDisposition, isCursorSkillCandidate, } from '../shared/cursor-skill-disposition.js';
|
|
5
6
|
import { withScopeOption } from '../shared/scope-option.js';
|
|
6
|
-
import { confirmAction, selectManyWithAbort, } from '../shared/shared.prompts.js';
|
|
7
|
+
import { confirmAction, selectManyWithAbort, selectWithAbort, } from '../shared/shared.prompts.js';
|
|
7
8
|
import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
|
|
8
9
|
import { DEFAULT_SYNC_CONFIG, loadSyncConfig, } from '../../config/index.js';
|
|
9
|
-
import {
|
|
10
|
+
import { resolveUserSyncConfig } from '../../config/user-sync-config.js';
|
|
10
11
|
import { detectDrift, detectStrays, filterKnownStrays, } from '../../drift/index.js';
|
|
11
12
|
import { HOOK_DRIFT_WARNING, HOOK_STRAY_INFO, scanBundledManagedAgents, scanCanonical, } from '../../engine/index.js';
|
|
12
13
|
import { normalizeToPosixPath, resolveProjectRoot, resolveScopeRoot, } from '../../fs/paths.js';
|
|
@@ -19,6 +20,7 @@ import { cursorAdapter } from '../../providers/cursor/index.js';
|
|
|
19
20
|
import { applyCursorProjectExtensionPlan, computeCursorProjectExtensionPlan, } from '../../providers/cursor/codec/sync-extension.js';
|
|
20
21
|
import { geminiAdapter } from '../../providers/gemini/index.js';
|
|
21
22
|
import { getActiveAdapters, getSyncMappings, } from '../../providers/shared/index.js';
|
|
23
|
+
import { getAdoptionSources } from '../../providers/shared/adapter.utils.js';
|
|
22
24
|
import { SCOPE_CONTENT_TYPES, } from '../../shared/types.js';
|
|
23
25
|
import { formatStatusTable } from '../../ui/output.js';
|
|
24
26
|
import { Command } from 'commander';
|
|
@@ -35,7 +37,7 @@ const DEFAULT_DEPENDENCIES = {
|
|
|
35
37
|
async loadSyncConfig(configPath) {
|
|
36
38
|
return loadSyncConfig(configPath, DEFAULT_SYNC_CONFIG);
|
|
37
39
|
},
|
|
38
|
-
|
|
40
|
+
resolveUserSyncConfig,
|
|
39
41
|
saveManifest,
|
|
40
42
|
scanCanonical,
|
|
41
43
|
scanBundledManagedAgents,
|
|
@@ -50,6 +52,7 @@ const DEFAULT_DEPENDENCIES = {
|
|
|
50
52
|
},
|
|
51
53
|
getActiveAdapters,
|
|
52
54
|
getSyncMappings,
|
|
55
|
+
getAdoptionSources,
|
|
53
56
|
detectDrift,
|
|
54
57
|
detectStrays,
|
|
55
58
|
detectCodexRoleStrays,
|
|
@@ -58,8 +61,10 @@ const DEFAULT_DEPENDENCIES = {
|
|
|
58
61
|
computeCursorProjectExtensionPlan,
|
|
59
62
|
applyCursorProjectExtensionPlan,
|
|
60
63
|
selectManyWithAbort,
|
|
64
|
+
selectWithAbort,
|
|
61
65
|
confirmAction,
|
|
62
66
|
adoptStray: adoptStrayDefault,
|
|
67
|
+
applyCursorSkillDisposition,
|
|
63
68
|
formatStatusTable,
|
|
64
69
|
};
|
|
65
70
|
function entryInsideMapping(entryProviderPath, mappingProviderDir) {
|
|
@@ -125,11 +130,11 @@ async function collectScopeReports(scope, context, dependencies) {
|
|
|
125
130
|
const manifestPath = join(scopeRoot, '.oat', 'sync', 'manifest.json');
|
|
126
131
|
const syncConfigPath = join(scopeRoot, '.oat', 'sync', 'config.json');
|
|
127
132
|
const userConfigDir = join(context.home, '.oat');
|
|
128
|
-
const [manifest, canonicalEntries, syncConfig,
|
|
133
|
+
const [manifest, canonicalEntries, syncConfig, userSyncConfig] = await Promise.all([
|
|
129
134
|
dependencies.loadManifest(manifestPath),
|
|
130
135
|
dependencies.scanCanonical(scopeRoot, scope),
|
|
131
136
|
dependencies.loadSyncConfig(syncConfigPath),
|
|
132
|
-
dependencies.
|
|
137
|
+
dependencies.resolveUserSyncConfig(userConfigDir),
|
|
133
138
|
]);
|
|
134
139
|
const adapters = dependencies.getAdapters();
|
|
135
140
|
const activeAdapters = await dependencies.getActiveAdapters(adapters, scopeRoot);
|
|
@@ -170,6 +175,7 @@ async function collectScopeReports(scope, context, dependencies) {
|
|
|
170
175
|
];
|
|
171
176
|
for (const adapter of activeAdapters) {
|
|
172
177
|
const mappings = dependencies.getSyncMappings(adapter, scope);
|
|
178
|
+
const adoptionSources = dependencies.getAdoptionSources(adapter, scope);
|
|
173
179
|
const mappingContentTypes = new Set(mappings.map((mapping) => mapping.contentType));
|
|
174
180
|
for (const entry of manifest.entries) {
|
|
175
181
|
if (entry.provider !== adapter.name) {
|
|
@@ -212,9 +218,9 @@ async function collectScopeReports(scope, context, dependencies) {
|
|
|
212
218
|
});
|
|
213
219
|
}
|
|
214
220
|
}
|
|
215
|
-
for (const
|
|
216
|
-
const providerDir = join(scopeRoot,
|
|
217
|
-
const strays = filterMaterializationManagedStrays((await dependencies.detectStrays(adapter.name, providerDir, manifest, canonicalEntries, mapping)).map((report) => ({ provider: adapter.name, report })), materializationPlans).map((candidate) => candidate.report);
|
|
221
|
+
for (const source of adoptionSources) {
|
|
222
|
+
const providerDir = join(scopeRoot, source.directory);
|
|
223
|
+
const strays = filterMaterializationManagedStrays((await dependencies.detectStrays(adapter.name, providerDir, manifest, canonicalEntries, source.mapping)).map((report) => ({ provider: adapter.name, report })), materializationPlans).map((candidate) => candidate.report);
|
|
218
224
|
reports.push(...strays);
|
|
219
225
|
for (const stray of strays) {
|
|
220
226
|
if (stray.state.status !== 'stray') {
|
|
@@ -223,7 +229,7 @@ async function collectScopeReports(scope, context, dependencies) {
|
|
|
223
229
|
strayCandidates.push({
|
|
224
230
|
provider: adapter.name,
|
|
225
231
|
report: stray,
|
|
226
|
-
mapping,
|
|
232
|
+
mapping: source.mapping,
|
|
227
233
|
});
|
|
228
234
|
}
|
|
229
235
|
}
|
|
@@ -287,13 +293,14 @@ async function collectScopeReports(scope, context, dependencies) {
|
|
|
287
293
|
candidates: strayCandidates,
|
|
288
294
|
knownStrays: {
|
|
289
295
|
project: syncConfig.knownStrays,
|
|
290
|
-
user:
|
|
296
|
+
user: userSyncConfig.knownStrays,
|
|
291
297
|
},
|
|
292
298
|
});
|
|
293
299
|
return {
|
|
294
300
|
scope,
|
|
295
301
|
scopeRoot,
|
|
296
302
|
manifestPath,
|
|
303
|
+
syncConfigPath,
|
|
297
304
|
manifest,
|
|
298
305
|
reports: filtered.reports,
|
|
299
306
|
strayCandidates: filtered.candidates,
|
|
@@ -340,44 +347,100 @@ async function runStatusCommand(context, dependencies, options = {}) {
|
|
|
340
347
|
}
|
|
341
348
|
if (summary.stray > 0) {
|
|
342
349
|
if (context.interactive) {
|
|
350
|
+
let migrationAborted = false;
|
|
343
351
|
for (const scopeCollection of scopeCollections) {
|
|
344
352
|
if (scopeCollection.strayCandidates.length === 0) {
|
|
345
353
|
continue;
|
|
346
354
|
}
|
|
347
355
|
let manifestChanged = false;
|
|
348
|
-
const selectedValues = await dependencies.selectManyWithAbort(`Select stray entries to adopt [${scopeCollection.scope}]`, scopeCollection.strayCandidates.map((strayCandidate, index) => ({
|
|
349
|
-
label: formatStrayChoiceLabel(scopeCollection.scope, strayCandidate.report.providerPath, strayCandidate.provider),
|
|
350
|
-
value: String(index),
|
|
351
|
-
description: formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath),
|
|
352
|
-
})), { interactive: context.interactive });
|
|
353
|
-
const selectedIndices = new Set((selectedValues ?? []).map((value) => Number.parseInt(value, 10)));
|
|
354
356
|
let adoptedCount = 0;
|
|
355
357
|
let codexStrayAdopted = false;
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
358
|
+
const cursorSkillStrays = scopeCollection.strayCandidates.filter(isCursorSkillCandidate);
|
|
359
|
+
const ordinaryStrays = scopeCollection.strayCandidates.filter((stray) => !isCursorSkillCandidate(stray));
|
|
360
|
+
for (const strayCandidate of cursorSkillStrays) {
|
|
361
|
+
const disposition = await dependencies.selectWithAbort(`Migrate Cursor skill [${scopeCollection.scope}]: ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}`, [
|
|
362
|
+
{
|
|
363
|
+
label: 'Adopt into canonical',
|
|
364
|
+
value: 'adopt',
|
|
365
|
+
description: `Move to ${strayCandidate.mapping.canonicalDir}.`,
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
label: 'Keep Cursor-only',
|
|
369
|
+
value: 'keep',
|
|
370
|
+
description: 'Leave in .cursor/skills and remember this choice.',
|
|
371
|
+
},
|
|
372
|
+
], { interactive: context.interactive });
|
|
373
|
+
if (disposition === null) {
|
|
374
|
+
migrationAborted = true;
|
|
375
|
+
break;
|
|
359
376
|
}
|
|
360
377
|
try {
|
|
361
|
-
scopeCollection.manifest =
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
378
|
+
scopeCollection.manifest =
|
|
379
|
+
await dependencies.applyCursorSkillDisposition(scopeCollection.scopeRoot, strayCandidate, scopeCollection.manifest, disposition, scopeCollection.syncConfigPath);
|
|
380
|
+
if (disposition === 'adopt') {
|
|
381
|
+
adoptedCount += 1;
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
context.logger.success(`Kept Cursor-only [${scopeCollection.scope}]: ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}.`);
|
|
385
|
+
}
|
|
366
386
|
}
|
|
367
387
|
catch (error) {
|
|
368
|
-
if (
|
|
388
|
+
if (error instanceof Error &&
|
|
389
|
+
error.message.startsWith('Cannot keep ')) {
|
|
390
|
+
context.logger.warn(error.message);
|
|
391
|
+
continue;
|
|
392
|
+
}
|
|
393
|
+
if (!isAdoptionConflictError(error) || disposition !== 'adopt') {
|
|
369
394
|
throw error;
|
|
370
395
|
}
|
|
371
396
|
const shouldReplace = await dependencies.confirmAction(`Conflict detected for ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}. Replace canonical with stray content?`, { interactive: context.interactive });
|
|
372
397
|
if (!shouldReplace) {
|
|
373
|
-
context.logger.warn(`Skipped adopting conflicting
|
|
398
|
+
context.logger.warn(`Skipped adopting conflicting Cursor skill [${scopeCollection.scope}] ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}.`);
|
|
374
399
|
continue;
|
|
375
400
|
}
|
|
376
|
-
scopeCollection.manifest =
|
|
401
|
+
scopeCollection.manifest =
|
|
402
|
+
await dependencies.applyCursorSkillDisposition(scopeCollection.scopeRoot, strayCandidate, scopeCollection.manifest, disposition, scopeCollection.syncConfigPath, { replaceCanonical: true });
|
|
377
403
|
adoptedCount += 1;
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (!migrationAborted && ordinaryStrays.length > 0) {
|
|
407
|
+
const selectedValues = await dependencies.selectManyWithAbort(`Select stray entries to adopt [${scopeCollection.scope}]`, ordinaryStrays.map((strayCandidate, index) => ({
|
|
408
|
+
label: formatStrayChoiceLabel(scopeCollection.scope, strayCandidate.report.providerPath, strayCandidate.provider),
|
|
409
|
+
value: String(index),
|
|
410
|
+
description: formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath),
|
|
411
|
+
})), { interactive: context.interactive });
|
|
412
|
+
if (selectedValues === null) {
|
|
413
|
+
migrationAborted = true;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
const selectedIndices = new Set(selectedValues.map((value) => Number.parseInt(value, 10)));
|
|
417
|
+
for (const [index, strayCandidate] of ordinaryStrays.entries()) {
|
|
418
|
+
if (!selectedIndices.has(index)) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
scopeCollection.manifest = await dependencies.adoptStray(scopeCollection.scopeRoot, strayCandidate, scopeCollection.manifest);
|
|
423
|
+
adoptedCount += 1;
|
|
424
|
+
manifestChanged = true;
|
|
425
|
+
codexStrayAdopted =
|
|
426
|
+
codexStrayAdopted || strayCandidate.provider === 'codex';
|
|
427
|
+
}
|
|
428
|
+
catch (error) {
|
|
429
|
+
if (!isAdoptionConflictError(error)) {
|
|
430
|
+
throw error;
|
|
431
|
+
}
|
|
432
|
+
const shouldReplace = await dependencies.confirmAction(`Conflict detected for ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}. Replace canonical with stray content?`, { interactive: context.interactive });
|
|
433
|
+
if (!shouldReplace) {
|
|
434
|
+
context.logger.warn(`Skipped adopting conflicting stray [${scopeCollection.scope}] ${formatPathForScope(scopeCollection.scope, strayCandidate.report.providerPath)}.`);
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
scopeCollection.manifest = await dependencies.adoptStray(scopeCollection.scopeRoot, strayCandidate, scopeCollection.manifest, { replaceCanonical: true });
|
|
438
|
+
adoptedCount += 1;
|
|
439
|
+
manifestChanged = true;
|
|
440
|
+
codexStrayAdopted =
|
|
441
|
+
codexStrayAdopted || strayCandidate.provider === 'codex';
|
|
442
|
+
}
|
|
443
|
+
}
|
|
381
444
|
}
|
|
382
445
|
}
|
|
383
446
|
if (codexStrayAdopted && scopeCollection.scope === 'project') {
|
|
@@ -395,11 +458,16 @@ async function runStatusCommand(context, dependencies, options = {}) {
|
|
|
395
458
|
}
|
|
396
459
|
if (manifestChanged) {
|
|
397
460
|
await dependencies.saveManifest(scopeCollection.manifestPath, scopeCollection.manifest);
|
|
461
|
+
}
|
|
462
|
+
if (adoptedCount > 0) {
|
|
398
463
|
context.logger.success(`Adopted ${adoptedCount} stray entr${adoptedCount === 1 ? 'y' : 'ies'} [${scopeCollection.scope}].`);
|
|
399
464
|
}
|
|
400
|
-
else {
|
|
465
|
+
else if (!migrationAborted) {
|
|
401
466
|
context.logger.info(`No stray entries adopted [${scopeCollection.scope}].`);
|
|
402
467
|
}
|
|
468
|
+
if (migrationAborted) {
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
403
471
|
}
|
|
404
472
|
}
|
|
405
473
|
else if (!context.json) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oat-config.d.ts","sourceRoot":"","sources":["../../src/config/oat-config.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"oat-config.d.ts","sourceRoot":"","sources":["../../src/config/oat-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { atomicWriteJson, dirExists, fileExists } from '../fs/io.js';
|
|
|
5
5
|
import { normalizeToPosixPath, validateRealPathWithinScope } from '../fs/paths.js';
|
|
6
6
|
import { normalizeDispatchMatrix, } from './dispatch-matrix.js';
|
|
7
7
|
import { parseJsonConfig } from './json.js';
|
|
8
|
+
import { resolveUserSyncConfig } from './user-sync-config.js';
|
|
8
9
|
export { VALID_DISPATCH_MATRIX_TIERS, isCodexMaterializedRouteTarget, isWorkflowDispatchCandidateLadder, isWorkflowDispatchFallbackRoute, toWorkflowDispatchCandidateLadder, validateDispatchRouteTarget, } from './dispatch-matrix.js';
|
|
9
10
|
export const MIN_GATE_TIMEOUT_MS = 1_000;
|
|
10
11
|
export const MAX_GATE_TIMEOUT_MS = 14_400_000;
|
|
@@ -397,24 +398,6 @@ function trimNonEmptyString(value) {
|
|
|
397
398
|
const trimmed = value.trim();
|
|
398
399
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
399
400
|
}
|
|
400
|
-
function normalizeKnownStrayPath(pathValue) {
|
|
401
|
-
const trimmed = pathValue.trim();
|
|
402
|
-
if (!trimmed) {
|
|
403
|
-
return undefined;
|
|
404
|
-
}
|
|
405
|
-
const normalized = trimPathValue(normalizeToPosixPath(trimmed));
|
|
406
|
-
return normalized && normalized !== '.' ? normalized : undefined;
|
|
407
|
-
}
|
|
408
|
-
function normalizeKnownStrays(value) {
|
|
409
|
-
if (!Array.isArray(value)) {
|
|
410
|
-
return undefined;
|
|
411
|
-
}
|
|
412
|
-
const normalized = value
|
|
413
|
-
.filter((pathValue) => typeof pathValue === 'string')
|
|
414
|
-
.map((pathValue) => normalizeKnownStrayPath(pathValue))
|
|
415
|
-
.filter((pathValue) => pathValue !== undefined);
|
|
416
|
-
return normalized.length > 0 ? [...new Set(normalized)].sort() : undefined;
|
|
417
|
-
}
|
|
418
401
|
export function normalizeProjectPath(repoRoot, pathValue) {
|
|
419
402
|
if (pathValue == null) {
|
|
420
403
|
return null;
|
|
@@ -717,6 +700,13 @@ export async function clearActiveProject(repoRoot, options) {
|
|
|
717
700
|
function getUserConfigPath(userConfigDir) {
|
|
718
701
|
return join(userConfigDir, 'config.json');
|
|
719
702
|
}
|
|
703
|
+
const USER_CONFIG_OWNED_KEYS = new Set([
|
|
704
|
+
'version',
|
|
705
|
+
'activeIdea',
|
|
706
|
+
'updateNotifications',
|
|
707
|
+
'workflow',
|
|
708
|
+
'knownStrays',
|
|
709
|
+
]);
|
|
720
710
|
function normalizeUserConfig(parsed) {
|
|
721
711
|
const next = { ...DEFAULT_USER_CONFIG };
|
|
722
712
|
if (!isRecord(parsed)) {
|
|
@@ -728,10 +718,6 @@ function normalizeUserConfig(parsed) {
|
|
|
728
718
|
? parsed.activeIdea.trim()
|
|
729
719
|
: null;
|
|
730
720
|
}
|
|
731
|
-
const knownStrays = normalizeKnownStrays(parsed.knownStrays);
|
|
732
|
-
if (knownStrays) {
|
|
733
|
-
next.knownStrays = knownStrays;
|
|
734
|
-
}
|
|
735
721
|
if (typeof parsed.updateNotifications === 'boolean') {
|
|
736
722
|
next.updateNotifications = parsed.updateNotifications;
|
|
737
723
|
}
|
|
@@ -741,6 +727,21 @@ function normalizeUserConfig(parsed) {
|
|
|
741
727
|
}
|
|
742
728
|
return next;
|
|
743
729
|
}
|
|
730
|
+
async function readUnknownUserConfigFields(configPath) {
|
|
731
|
+
try {
|
|
732
|
+
const parsed = parseJsonConfig(await readFile(configPath, 'utf8'), configPath);
|
|
733
|
+
if (!isRecord(parsed)) {
|
|
734
|
+
return {};
|
|
735
|
+
}
|
|
736
|
+
return Object.fromEntries(Object.entries(parsed).filter(([key]) => !USER_CONFIG_OWNED_KEYS.has(key)));
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
if (isMissingFileError(error)) {
|
|
740
|
+
return {};
|
|
741
|
+
}
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
744
745
|
export async function readUserConfig(userConfigDir) {
|
|
745
746
|
const configPath = getUserConfigPath(userConfigDir);
|
|
746
747
|
try {
|
|
@@ -756,8 +757,10 @@ export async function readUserConfig(userConfigDir) {
|
|
|
756
757
|
}
|
|
757
758
|
export async function writeUserConfig(userConfigDir, config) {
|
|
758
759
|
const configPath = getUserConfigPath(userConfigDir);
|
|
760
|
+
await resolveUserSyncConfig(userConfigDir);
|
|
761
|
+
const unknownFields = await readUnknownUserConfigFields(configPath);
|
|
759
762
|
const normalized = normalizeUserConfig(config);
|
|
760
|
-
await atomicWriteJson(configPath, normalized);
|
|
763
|
+
await atomicWriteJson(configPath, { ...unknownFields, ...normalized });
|
|
761
764
|
}
|
|
762
765
|
export async function resolveActiveIdea(repoRoot, userConfigDir) {
|
|
763
766
|
const localConfig = await readOatLocalConfig(repoRoot);
|
|
@@ -26,19 +26,19 @@ export declare const SyncConfigSchema: z.ZodObject<{
|
|
|
26
26
|
}, "strip", z.ZodTypeAny, {
|
|
27
27
|
version: 1;
|
|
28
28
|
defaultStrategy: "symlink" | "copy" | "auto";
|
|
29
|
+
knownStrays?: string[] | undefined;
|
|
29
30
|
providers?: Record<string, {
|
|
30
31
|
strategy?: "symlink" | "copy" | "auto" | undefined;
|
|
31
32
|
enabled?: boolean | undefined;
|
|
32
33
|
}> | undefined;
|
|
33
|
-
knownStrays?: string[] | undefined;
|
|
34
34
|
}, {
|
|
35
35
|
version: 1;
|
|
36
36
|
defaultStrategy: "symlink" | "copy" | "auto";
|
|
37
|
+
knownStrays?: string[] | undefined;
|
|
37
38
|
providers?: Record<string, {
|
|
38
39
|
strategy?: "symlink" | "copy" | "auto" | undefined;
|
|
39
40
|
enabled?: boolean | undefined;
|
|
40
41
|
}> | undefined;
|
|
41
|
-
knownStrays?: string[] | undefined;
|
|
42
42
|
}>;
|
|
43
43
|
export type ProviderSyncConfig = z.infer<typeof ProviderConfigSchema>;
|
|
44
44
|
export type SyncConfig = z.infer<typeof SyncConfigSchema> & {
|
|
@@ -46,8 +46,12 @@ export type SyncConfig = z.infer<typeof SyncConfigSchema> & {
|
|
|
46
46
|
providers: Record<string, ProviderSyncConfig>;
|
|
47
47
|
};
|
|
48
48
|
export declare const DEFAULT_SYNC_CONFIG: SyncConfig;
|
|
49
|
+
export declare function normalizeKnownStrayPath(pathValue: string): string | undefined;
|
|
50
|
+
export declare function normalizeKnownStrays(paths: readonly string[] | undefined): string[];
|
|
51
|
+
export declare function mergeKnownStrays(...pathSets: ReadonlyArray<readonly string[] | undefined>): string[];
|
|
49
52
|
export declare function loadSyncConfig(configPath: string, defaults?: SyncConfig): Promise<SyncConfig>;
|
|
50
53
|
export declare function saveSyncConfig(configPath: string, config: SyncConfig): Promise<SyncConfig>;
|
|
51
54
|
export declare function setProviderEnabled(configPath: string, providerName: string, enabled: boolean): Promise<SyncConfig>;
|
|
55
|
+
export declare function appendKnownStray(configPath: string, pathValue: string): Promise<SyncConfig>;
|
|
52
56
|
export {};
|
|
53
57
|
//# sourceMappingURL=sync-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-config.d.ts","sourceRoot":"","sources":["../../src/config/sync-config.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,oBAAoB;;;;;;;;;EAGxB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK3B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GAAG;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,UAKjC,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-config.d.ts","sourceRoot":"","sources":["../../src/config/sync-config.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,QAAA,MAAM,oBAAoB;;;;;;;;;EAGxB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK3B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GAAG;IAC1D,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,UAKjC,CAAC;AAkBF,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACnC,MAAM,EAAE,CAMV;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,QAAQ,EAAE,aAAa,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,GACxD,MAAM,EAAE,CAEV;AAqCD,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,QAAQ,GAAE,UAAgC,GACzC,OAAO,CAAC,UAAU,CAAC,CA6BrB;AAED,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,UAAU,CAAC,CAWrB;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,UAAU,CAAC,CAcrB;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,CAAC,CAcrB"}
|
|
@@ -31,7 +31,7 @@ function mergeProviderConfigs(base, override) {
|
|
|
31
31
|
}
|
|
32
32
|
return merged;
|
|
33
33
|
}
|
|
34
|
-
function normalizeKnownStrayPath(pathValue) {
|
|
34
|
+
export function normalizeKnownStrayPath(pathValue) {
|
|
35
35
|
const trimmed = pathValue.trim();
|
|
36
36
|
if (!trimmed) {
|
|
37
37
|
return undefined;
|
|
@@ -41,20 +41,20 @@ function normalizeKnownStrayPath(pathValue) {
|
|
|
41
41
|
.replace(/^\.\//, '');
|
|
42
42
|
return normalized && normalized !== '.' ? normalized : undefined;
|
|
43
43
|
}
|
|
44
|
-
function normalizeKnownStrays(paths) {
|
|
44
|
+
export function normalizeKnownStrays(paths) {
|
|
45
45
|
const normalized = paths
|
|
46
46
|
?.map((pathValue) => normalizeKnownStrayPath(pathValue))
|
|
47
47
|
.filter((pathValue) => pathValue !== undefined);
|
|
48
48
|
return [...new Set(normalized ?? [])].sort();
|
|
49
49
|
}
|
|
50
|
+
export function mergeKnownStrays(...pathSets) {
|
|
51
|
+
return normalizeKnownStrays(pathSets.flatMap((paths) => paths ?? []));
|
|
52
|
+
}
|
|
50
53
|
function normalizeConfig(config, defaults) {
|
|
51
54
|
return {
|
|
52
55
|
version: 1,
|
|
53
56
|
defaultStrategy: config.defaultStrategy ?? defaults.defaultStrategy,
|
|
54
|
-
knownStrays:
|
|
55
|
-
...defaults.knownStrays,
|
|
56
|
-
...(config.knownStrays ?? []),
|
|
57
|
-
]),
|
|
57
|
+
knownStrays: mergeKnownStrays(defaults.knownStrays, config.knownStrays),
|
|
58
58
|
providers: mergeProviderConfigs(defaults.providers, config.providers ?? {}),
|
|
59
59
|
};
|
|
60
60
|
}
|
|
@@ -117,3 +117,15 @@ export async function setProviderEnabled(configPath, providerName, enabled) {
|
|
|
117
117
|
};
|
|
118
118
|
return saveSyncConfig(configPath, next);
|
|
119
119
|
}
|
|
120
|
+
export async function appendKnownStray(configPath, pathValue) {
|
|
121
|
+
const current = await loadSyncConfig(configPath, DEFAULT_SYNC_CONFIG);
|
|
122
|
+
const knownStrays = mergeKnownStrays(current.knownStrays, [pathValue]);
|
|
123
|
+
if (knownStrays.length === current.knownStrays.length &&
|
|
124
|
+
knownStrays.every((path, index) => path === current.knownStrays[index])) {
|
|
125
|
+
return current;
|
|
126
|
+
}
|
|
127
|
+
return saveSyncConfig(configPath, {
|
|
128
|
+
...current,
|
|
129
|
+
knownStrays,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type SyncConfig } from './sync-config.js';
|
|
2
|
+
interface UserSyncConfigDependencies {
|
|
3
|
+
readFile: (path: string, encoding: 'utf8') => Promise<string>;
|
|
4
|
+
atomicWriteJson: (path: string, data: unknown) => Promise<void>;
|
|
5
|
+
loadSyncConfig: (path: string) => Promise<SyncConfig>;
|
|
6
|
+
saveSyncConfig: (path: string, config: SyncConfig) => Promise<SyncConfig>;
|
|
7
|
+
}
|
|
8
|
+
export declare function getUserSyncConfigPath(userConfigDir: string): string;
|
|
9
|
+
export declare function resolveUserSyncConfig(userConfigDir: string, overrides?: Partial<UserSyncConfigDependencies>): Promise<SyncConfig>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=user-sync-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-sync-config.d.ts","sourceRoot":"","sources":["../../src/config/user-sync-config.ts"],"names":[],"mappings":"AAMA,OAAO,EAKL,KAAK,UAAU,EAChB,MAAM,eAAe,CAAC;AAEvB,UAAU,0BAA0B;IAClC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9D,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CAC3E;AASD,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAAC,UAAU,CAAC,CAgCrB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { atomicWriteJson } from '../fs/io.js';
|
|
4
|
+
import { parseJsonConfig } from './json.js';
|
|
5
|
+
import { DEFAULT_SYNC_CONFIG, loadSyncConfig, mergeKnownStrays, saveSyncConfig, } from './sync-config.js';
|
|
6
|
+
const DEFAULT_DEPENDENCIES = {
|
|
7
|
+
readFile,
|
|
8
|
+
atomicWriteJson,
|
|
9
|
+
loadSyncConfig: (path) => loadSyncConfig(path, DEFAULT_SYNC_CONFIG),
|
|
10
|
+
saveSyncConfig,
|
|
11
|
+
};
|
|
12
|
+
export function getUserSyncConfigPath(userConfigDir) {
|
|
13
|
+
return join(userConfigDir, 'sync', 'config.json');
|
|
14
|
+
}
|
|
15
|
+
export async function resolveUserSyncConfig(userConfigDir, overrides = {}) {
|
|
16
|
+
const dependencies = {
|
|
17
|
+
...DEFAULT_DEPENDENCIES,
|
|
18
|
+
...overrides,
|
|
19
|
+
};
|
|
20
|
+
const legacyConfigPath = join(userConfigDir, 'config.json');
|
|
21
|
+
const syncConfigPath = getUserSyncConfigPath(userConfigDir);
|
|
22
|
+
const syncConfig = await dependencies.loadSyncConfig(syncConfigPath);
|
|
23
|
+
const legacyConfig = await readLegacyConfig(legacyConfigPath, dependencies.readFile);
|
|
24
|
+
if (!legacyConfig || !hasOwn(legacyConfig, 'knownStrays')) {
|
|
25
|
+
return syncConfig;
|
|
26
|
+
}
|
|
27
|
+
const legacyKnownStrays = Array.isArray(legacyConfig.knownStrays)
|
|
28
|
+
? legacyConfig.knownStrays.filter((value) => typeof value === 'string')
|
|
29
|
+
: [];
|
|
30
|
+
const migratedSyncConfig = await dependencies.saveSyncConfig(syncConfigPath, {
|
|
31
|
+
...syncConfig,
|
|
32
|
+
knownStrays: mergeKnownStrays(syncConfig.knownStrays, legacyKnownStrays),
|
|
33
|
+
});
|
|
34
|
+
const { knownStrays: _legacyKnownStrays, ...preservedLegacyConfig } = legacyConfig;
|
|
35
|
+
await dependencies.atomicWriteJson(legacyConfigPath, preservedLegacyConfig);
|
|
36
|
+
return migratedSyncConfig;
|
|
37
|
+
}
|
|
38
|
+
async function readLegacyConfig(configPath, read) {
|
|
39
|
+
try {
|
|
40
|
+
const parsed = parseJsonConfig(await read(configPath, 'utf8'), configPath);
|
|
41
|
+
return isRecord(parsed) ? parsed : null;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (isMissingFileError(error)) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function isRecord(value) {
|
|
51
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
52
|
+
}
|
|
53
|
+
function hasOwn(value, key) {
|
|
54
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
55
|
+
}
|
|
56
|
+
function isMissingFileError(error) {
|
|
57
|
+
return (typeof error === 'object' &&
|
|
58
|
+
error !== null &&
|
|
59
|
+
'code' in error &&
|
|
60
|
+
error.code === 'ENOENT');
|
|
61
|
+
}
|
package/dist/drift/strays.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ import type { Manifest } from '../manifest/manifest.types.js';
|
|
|
3
3
|
import type { PathMapping } from '../providers/shared/adapter.types.js';
|
|
4
4
|
import type { DriftReport } from './drift.types.js';
|
|
5
5
|
export declare function inferScopeRoot(providerDir: string): string;
|
|
6
|
-
export declare function detectStrays(provider: string, providerDir: string, manifest: Manifest, canonicalEntries: CanonicalEntry[], mapping?: Pick<PathMapping, 'contentType' | 'providerExtension'>): Promise<DriftReport[]>;
|
|
6
|
+
export declare function detectStrays(provider: string, providerDir: string, manifest: Manifest, canonicalEntries: CanonicalEntry[], mapping?: Pick<PathMapping, 'contentType' | 'nativeRead' | 'providerExtension'>): Promise<DriftReport[]>;
|
|
7
7
|
//# sourceMappingURL=strays.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strays.d.ts","sourceRoot":"","sources":["../../src/drift/strays.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAkBjD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAkJD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,cAAc,EAAE,EAClC,OAAO,CAAC,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"strays.d.ts","sourceRoot":"","sources":["../../src/drift/strays.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAkBjD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAoB1D;AAkJD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,QAAQ,EAClB,gBAAgB,EAAE,cAAc,EAAE,EAClC,OAAO,CAAC,EAAE,IAAI,CACZ,WAAW,EACX,aAAa,GAAG,YAAY,GAAG,mBAAmB,CACnD,GACA,OAAO,CAAC,WAAW,EAAE,CAAC,CA6DxB"}
|
package/dist/drift/strays.js
CHANGED
|
@@ -164,7 +164,8 @@ export async function detectStrays(provider, providerDir, manifest, canonicalEnt
|
|
|
164
164
|
const canonicalName = contentType === 'rule'
|
|
165
165
|
? canonicalRuleNameForProviderEntry(entry.name, mapping)
|
|
166
166
|
: entry.name;
|
|
167
|
-
if (
|
|
167
|
+
if (!mapping?.nativeRead &&
|
|
168
|
+
isCanonicalEntry(canonicalName, contentType, canonicalEntries)) {
|
|
168
169
|
continue;
|
|
169
170
|
}
|
|
170
171
|
reports.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/compute-plan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"compute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/compute-plan.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,KAAK,EACV,WAAW,EAEX,QAAQ,EAET,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,UAAU,mBAAmB;IAC3B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AA0dD,wBAAsB,eAAe,CAAC,EACpC,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,MAAM,EACN,SAAS,EAAE,iBAAiB,EAC5B,qBAAqB,GACtB,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAsIzC"}
|