@open-agent-toolkit/cli 0.1.73 → 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/config/dispatch-matrix-recommendation.json +13 -17
- package/assets/docs/cli-utilities/configuration.md +53 -72
- package/assets/docs/cli-utilities/workflow-gates.md +38 -2
- 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 +23 -19
- 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/docs/workflows/projects/artifacts.md +1 -1
- package/assets/docs/workflows/projects/dispatch-ceiling.md +29 -33
- package/assets/docs/workflows/projects/implementation-execution.md +7 -4
- package/assets/docs/workflows/projects/lifecycle.md +4 -3
- 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/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
- package/assets/skills/oat-dispatch-subagents/references/provider-cursor.md +27 -15
- package/assets/skills/oat-project-autonomous/SKILL.md +1 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +17 -15
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +15 -9
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/phase-execution.md +11 -5
- package/assets/skills/oat-project-import-plan/SKILL.md +30 -8
- package/assets/skills/oat-project-plan/SKILL.md +30 -8
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -9
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/SKILL.md +30 -8
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-review-provide/SKILL.md +19 -11
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +27 -4
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +55 -0
- package/dist/commands/doctor/index.d.ts +2 -1
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +37 -1
- package/dist/commands/gate/index.d.ts +1 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +35 -3
- package/dist/commands/init/index.d.ts +7 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +129 -38
- package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
- package/dist/commands/project/dispatch-ceiling/index.js +17 -9
- 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/codex-strays.d.ts +9 -0
- package/dist/commands/shared/codex-strays.d.ts.map +1 -1
- package/dist/commands/shared/codex-strays.js +4 -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 +17 -5
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +151 -47
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +50 -24
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +31 -18
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +34 -25
- package/dist/commands/sync/sync.types.d.ts +26 -11
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +3 -2
- 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/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/scanner.d.ts +3 -1
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +4 -2
- package/dist/manifest/manifest.types.d.ts +12 -12
- package/dist/providers/ceiling/registry.d.ts +2 -0
- package/dist/providers/ceiling/registry.d.ts.map +1 -1
- package/dist/providers/ceiling/registry.js +20 -4
- package/dist/providers/codex/codec/sync-extension.d.ts +11 -10
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +42 -14
- package/dist/providers/cursor/codec/catalog.d.ts +18 -0
- package/dist/providers/cursor/codec/catalog.d.ts.map +1 -0
- package/dist/providers/cursor/codec/catalog.js +39 -0
- package/dist/providers/cursor/codec/materialize.d.ts +24 -0
- package/dist/providers/cursor/codec/materialize.d.ts.map +1 -0
- package/dist/providers/cursor/codec/materialize.js +166 -0
- package/dist/providers/cursor/codec/shared.d.ts +14 -0
- package/dist/providers/cursor/codec/shared.d.ts.map +1 -0
- package/dist/providers/cursor/codec/shared.js +76 -0
- package/dist/providers/cursor/codec/sync-extension.d.ts +37 -0
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -0
- package/dist/providers/cursor/codec/sync-extension.js +393 -0
- package/dist/providers/cursor/index.d.ts +3 -0
- package/dist/providers/cursor/index.d.ts.map +1 -1
- package/dist/providers/cursor/index.js +3 -0
- package/dist/providers/cursor/paths.d.ts.map +1 -1
- package/dist/providers/cursor/paths.js +6 -4
- package/dist/providers/identity/availability.d.ts +7 -0
- package/dist/providers/identity/availability.d.ts.map +1 -1
- package/dist/providers/identity/availability.js +23 -0
- 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/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 +44 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -0
- package/dist/providers/shared/materialization-extension.js +26 -0
- package/package.json +2 -2
|
@@ -6,15 +6,17 @@ import { applyOatCoreGitignore, } from '../init/gitignore.js';
|
|
|
6
6
|
import { applyGitignore } from '../local/apply.js';
|
|
7
7
|
import { addLocalPaths } from '../local/manage.js';
|
|
8
8
|
import { adoptStrayToCanonical, isAdoptionConflictError, } from '../shared/adopt-stray.js';
|
|
9
|
-
import { detectCodexRoleStrays, regenerateCodexAfterAdoption, } from '../shared/codex-strays.js';
|
|
9
|
+
import { detectCodexRoleStrays, filterMaterializationManagedStrays, regenerateCodexAfterAdoption, } from '../shared/codex-strays.js';
|
|
10
|
+
import { applyCursorSkillDisposition, isCursorSkillCandidate, } from '../shared/cursor-skill-disposition.js';
|
|
10
11
|
import { PROVIDER_CONFIG_REMEDIATION } from '../shared/messages.js';
|
|
11
12
|
import { withScopeOption } from '../shared/scope-option.js';
|
|
12
13
|
import { confirmAction, inputWithDefault, selectManyWithAbort, selectWithAbort, } from '../shared/shared.prompts.js';
|
|
13
14
|
import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
|
|
14
15
|
import { DEFAULT_SYNC_CONFIG, loadSyncConfig, saveSyncConfig, } from '../../config/index.js';
|
|
15
|
-
import { detectDefaultBranch,
|
|
16
|
+
import { detectDefaultBranch, readOatConfig, resolveLocalPaths, writeOatConfig, } from '../../config/oat-config.js';
|
|
17
|
+
import { resolveUserSyncConfig } from '../../config/user-sync-config.js';
|
|
16
18
|
import { detectStrays, filterKnownStrays, } from '../../drift/index.js';
|
|
17
|
-
import { configureLocalHooksPath, getHookInstallInfo, installHook, isHookInstalled, scanCanonical, uninstallHook, } from '../../engine/index.js';
|
|
19
|
+
import { configureLocalHooksPath, getHookInstallInfo, installHook, isHookInstalled, scanBundledManagedAgents, scanCanonical, uninstallHook, } from '../../engine/index.js';
|
|
18
20
|
import { dirExists, fileExists } from '../../fs/io.js';
|
|
19
21
|
import { resolveProjectRoot, resolveScopeRoot } from '../../fs/paths.js';
|
|
20
22
|
import { normalizeToPosixPath } from '../../fs/paths.js';
|
|
@@ -24,8 +26,10 @@ import { codexAdapter } from '../../providers/codex/index.js';
|
|
|
24
26
|
import { applyCodexProjectExtensionPlan, computeCodexProjectExtensionPlan, } from '../../providers/codex/codec/sync-extension.js';
|
|
25
27
|
import { copilotAdapter } from '../../providers/copilot/index.js';
|
|
26
28
|
import { cursorAdapter } from '../../providers/cursor/index.js';
|
|
29
|
+
import { applyCursorProjectExtensionPlan, computeCursorProjectExtensionPlan, } from '../../providers/cursor/codec/sync-extension.js';
|
|
27
30
|
import { geminiAdapter } from '../../providers/gemini/index.js';
|
|
28
|
-
import { getActiveAdapters, getConfigAwareAdapters,
|
|
31
|
+
import { getActiveAdapters, getConfigAwareAdapters, } from '../../providers/shared/index.js';
|
|
32
|
+
import { getAdoptionSources } from '../../providers/shared/adapter.utils.js';
|
|
29
33
|
import { Command } from 'commander';
|
|
30
34
|
import { detectExistingDocs, } from './detect-docs.js';
|
|
31
35
|
import { createInitToolsCommand, runInitToolsWithDefaults, } from './tools/index.js';
|
|
@@ -49,15 +53,43 @@ async function ensureCanonicalDirectories(scopeRoot, scope) {
|
|
|
49
53
|
await mkdir(join(scopeRoot, '.agents', 'rules'), { recursive: true });
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
|
-
async function collectStraysDefault(scopeRoot, scope, manifest, canonicalEntries, activeAdapters) {
|
|
56
|
+
async function collectStraysDefault(scopeRoot, scope, manifest, canonicalEntries, activeAdapters, userConfigDir = join(scopeRoot, '.oat')) {
|
|
53
57
|
const adaptersToScan = activeAdapters ??
|
|
54
58
|
(await getActiveAdapters(getDefaultAdapters(), scopeRoot));
|
|
55
59
|
const candidates = [];
|
|
60
|
+
const hasMaterializationAdapter = adaptersToScan.some((adapter) => adapter.name === 'codex' || adapter.name === 'cursor');
|
|
61
|
+
const materializationCanonicalEntries = scope === 'user' && hasMaterializationAdapter
|
|
62
|
+
? [...canonicalEntries, ...(await scanBundledManagedAgents())]
|
|
63
|
+
: canonicalEntries;
|
|
64
|
+
const codexExtensionPlan = adaptersToScan.some((adapter) => adapter.name === 'codex')
|
|
65
|
+
? await computeCodexProjectExtensionPlan(scopeRoot, materializationCanonicalEntries, undefined, { userConfigDir })
|
|
66
|
+
: undefined;
|
|
67
|
+
const cursorExtensionPlan = adaptersToScan.some((adapter) => adapter.name === 'cursor')
|
|
68
|
+
? await computeCursorProjectExtensionPlan(scopeRoot, materializationCanonicalEntries, undefined, { userConfigDir })
|
|
69
|
+
: undefined;
|
|
70
|
+
const materializationPlans = [
|
|
71
|
+
...(codexExtensionPlan
|
|
72
|
+
? [
|
|
73
|
+
{
|
|
74
|
+
provider: 'codex',
|
|
75
|
+
operations: codexExtensionPlan.operations.map((operation) => ({
|
|
76
|
+
...operation,
|
|
77
|
+
provider: 'codex',
|
|
78
|
+
entryName: operation.roleName,
|
|
79
|
+
})),
|
|
80
|
+
managedEntries: codexExtensionPlan.managedRoles,
|
|
81
|
+
aggregateHash: codexExtensionPlan.aggregateConfigHash,
|
|
82
|
+
metadata: codexExtensionPlan.metadata,
|
|
83
|
+
},
|
|
84
|
+
]
|
|
85
|
+
: []),
|
|
86
|
+
...(cursorExtensionPlan ? [cursorExtensionPlan] : []),
|
|
87
|
+
];
|
|
56
88
|
for (const adapter of adaptersToScan) {
|
|
57
|
-
const
|
|
58
|
-
for (const
|
|
59
|
-
const providerDir = join(scopeRoot,
|
|
60
|
-
const strays = await detectStrays(adapter.name, providerDir, manifest, canonicalEntries, mapping);
|
|
89
|
+
const adoptionSources = getAdoptionSources(adapter, scope);
|
|
90
|
+
for (const source of adoptionSources) {
|
|
91
|
+
const providerDir = join(scopeRoot, source.directory);
|
|
92
|
+
const strays = filterMaterializationManagedStrays((await detectStrays(adapter.name, providerDir, manifest, canonicalEntries, source.mapping)).map((report) => ({ provider: adapter.name, report })), materializationPlans).map((candidate) => candidate.report);
|
|
61
93
|
for (const report of strays) {
|
|
62
94
|
if (report.state.status !== 'stray') {
|
|
63
95
|
continue;
|
|
@@ -65,14 +97,12 @@ async function collectStraysDefault(scopeRoot, scope, manifest, canonicalEntries
|
|
|
65
97
|
candidates.push({
|
|
66
98
|
provider: adapter.name,
|
|
67
99
|
report,
|
|
68
|
-
mapping,
|
|
100
|
+
mapping: source.mapping,
|
|
69
101
|
});
|
|
70
102
|
}
|
|
71
103
|
}
|
|
72
104
|
}
|
|
73
|
-
if (
|
|
74
|
-
adaptersToScan.some((adapter) => adapter.name === 'codex')) {
|
|
75
|
-
const codexExtensionPlan = await computeCodexProjectExtensionPlan(scopeRoot, canonicalEntries);
|
|
105
|
+
if (adaptersToScan.some((adapter) => adapter.name === 'codex')) {
|
|
76
106
|
const codexStrays = await detectCodexRoleStrays(scopeRoot, canonicalEntries, new Set(codexExtensionPlan.managedRoles));
|
|
77
107
|
for (const stray of codexStrays) {
|
|
78
108
|
candidates.push({
|
|
@@ -131,7 +161,7 @@ function createDependencies() {
|
|
|
131
161
|
async loadSyncConfig(configPath) {
|
|
132
162
|
return loadSyncConfig(configPath, DEFAULT_SYNC_CONFIG);
|
|
133
163
|
},
|
|
134
|
-
|
|
164
|
+
resolveUserSyncConfig,
|
|
135
165
|
saveSyncConfig,
|
|
136
166
|
getConfigAwareAdapters,
|
|
137
167
|
applyOatCoreGitignore,
|
|
@@ -146,6 +176,7 @@ function createDependencies() {
|
|
|
146
176
|
fileExists,
|
|
147
177
|
inputWithDefault,
|
|
148
178
|
selectWithAbort,
|
|
179
|
+
applyCursorSkillDisposition,
|
|
149
180
|
runGuidedSetup: runGuidedSetupImpl,
|
|
150
181
|
runToolPacks: runInitToolsWithDefaults,
|
|
151
182
|
async runProviderSync(projectRoot) {
|
|
@@ -427,12 +458,13 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag) {
|
|
|
427
458
|
let projectRoot = null;
|
|
428
459
|
let oatDirExistedBefore = true;
|
|
429
460
|
const scopeSummaries = [];
|
|
461
|
+
let migrationAborted = false;
|
|
430
462
|
for (const scope of scopes) {
|
|
431
463
|
const scopeRoot = await dependencies.resolveScopeRoot(scope, context);
|
|
432
464
|
const syncConfigPath = join(scopeRoot, '.oat', 'sync', 'config.json');
|
|
433
465
|
const userConfigDir = join(context.home, '.oat');
|
|
434
466
|
let syncConfig = await dependencies.loadSyncConfig(syncConfigPath);
|
|
435
|
-
const
|
|
467
|
+
const userSyncConfig = await dependencies.resolveUserSyncConfig(userConfigDir);
|
|
436
468
|
let activeAdaptersForStrays;
|
|
437
469
|
if (scope === 'project') {
|
|
438
470
|
projectRoot = scopeRoot;
|
|
@@ -481,51 +513,105 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag) {
|
|
|
481
513
|
manifest = createEmptyManifest();
|
|
482
514
|
}
|
|
483
515
|
const canonicalEntries = await dependencies.scanCanonical(scopeRoot, scope);
|
|
484
|
-
const collectedStrays = await dependencies.collectStrays(scopeRoot, scope, manifest, canonicalEntries, activeAdaptersForStrays);
|
|
516
|
+
const collectedStrays = await dependencies.collectStrays(scopeRoot, scope, manifest, canonicalEntries, activeAdaptersForStrays, userConfigDir);
|
|
485
517
|
const { candidates: strays } = filterKnownStrays({
|
|
486
518
|
reports: collectedStrays.map((stray) => stray.report),
|
|
487
519
|
candidates: collectedStrays,
|
|
488
520
|
knownStrays: {
|
|
489
521
|
project: syncConfig.knownStrays,
|
|
490
|
-
user:
|
|
522
|
+
user: userSyncConfig.knownStrays,
|
|
491
523
|
},
|
|
492
524
|
});
|
|
493
525
|
let straysAdopted = 0;
|
|
526
|
+
let codexStrayAdopted = false;
|
|
527
|
+
const cursorSkillStrays = strays.filter(isCursorSkillCandidate);
|
|
528
|
+
const ordinaryStrays = strays.filter((stray) => !isCursorSkillCandidate(stray));
|
|
494
529
|
if (!context.interactive && strays.length > 0) {
|
|
495
530
|
context.logger.warn(ADOPT_REMEDIATION);
|
|
496
531
|
}
|
|
497
|
-
if (context.interactive && strays.length > 0) {
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
532
|
+
if (context.interactive && strays.length > 0 && !migrationAborted) {
|
|
533
|
+
for (const stray of cursorSkillStrays) {
|
|
534
|
+
const disposition = await dependencies.selectWithAbort(`Migrate Cursor skill [${scope}]: ${formatPathForScope(scope, stray.report.providerPath)}`, [
|
|
535
|
+
{
|
|
536
|
+
label: 'Adopt into canonical',
|
|
537
|
+
value: 'adopt',
|
|
538
|
+
description: `Move to ${stray.mapping.canonicalDir}.`,
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
label: 'Keep Cursor-only',
|
|
542
|
+
value: 'keep',
|
|
543
|
+
description: 'Leave in .cursor/skills and remember this choice.',
|
|
544
|
+
},
|
|
545
|
+
], { interactive: context.interactive });
|
|
546
|
+
if (disposition === null) {
|
|
547
|
+
migrationAborted = true;
|
|
548
|
+
break;
|
|
509
549
|
}
|
|
510
550
|
try {
|
|
511
|
-
manifest = await dependencies.
|
|
512
|
-
|
|
513
|
-
|
|
551
|
+
manifest = await dependencies.applyCursorSkillDisposition(scopeRoot, stray, manifest, disposition, syncConfigPath);
|
|
552
|
+
if (disposition === 'adopt') {
|
|
553
|
+
straysAdopted += 1;
|
|
554
|
+
}
|
|
555
|
+
else {
|
|
556
|
+
context.logger.success(`Kept Cursor-only [${scope}]: ${formatPathForScope(scope, stray.report.providerPath)}.`);
|
|
557
|
+
}
|
|
514
558
|
}
|
|
515
559
|
catch (error) {
|
|
516
|
-
if (
|
|
560
|
+
if (error instanceof Error &&
|
|
561
|
+
error.message.startsWith('Cannot keep ')) {
|
|
562
|
+
context.logger.warn(error.message);
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
if (!isAdoptionConflictError(error) || disposition !== 'adopt') {
|
|
517
566
|
throw error;
|
|
518
567
|
}
|
|
519
568
|
const shouldReplace = await dependencies.confirmAction(`Conflict detected for ${formatPathForScope(scope, stray.report.providerPath)}. Replace canonical content with stray content?`, { interactive: context.interactive });
|
|
520
569
|
if (!shouldReplace) {
|
|
521
|
-
context.logger.warn(`Skipped conflicting
|
|
570
|
+
context.logger.warn(`Skipped conflicting Cursor skill [${scope}]: ${formatPathForScope(scope, stray.report.providerPath)}`);
|
|
522
571
|
continue;
|
|
523
572
|
}
|
|
524
|
-
manifest = await dependencies.
|
|
525
|
-
replaceCanonical: true,
|
|
526
|
-
});
|
|
573
|
+
manifest = await dependencies.applyCursorSkillDisposition(scopeRoot, stray, manifest, disposition, syncConfigPath, { replaceCanonical: true });
|
|
527
574
|
straysAdopted += 1;
|
|
528
|
-
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (!migrationAborted && ordinaryStrays.length > 0) {
|
|
578
|
+
const selectedValues = await dependencies.selectManyWithAbort(`Select stray entries to adopt [${scope}]`, ordinaryStrays.map((stray, index) => ({
|
|
579
|
+
label: formatStrayChoiceLabel(scope, stray.report.providerPath, stray.provider),
|
|
580
|
+
value: String(index),
|
|
581
|
+
description: formatPathForScope(scope, stray.report.providerPath),
|
|
582
|
+
})), { interactive: context.interactive });
|
|
583
|
+
if (selectedValues === null) {
|
|
584
|
+
migrationAborted = true;
|
|
585
|
+
}
|
|
586
|
+
else {
|
|
587
|
+
const selectedIndices = new Set(selectedValues.map((value) => Number.parseInt(value, 10)));
|
|
588
|
+
for (const [index, stray] of ordinaryStrays.entries()) {
|
|
589
|
+
if (!selectedIndices.has(index)) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
try {
|
|
593
|
+
manifest = await dependencies.adoptStray(scopeRoot, stray, manifest);
|
|
594
|
+
straysAdopted += 1;
|
|
595
|
+
codexStrayAdopted =
|
|
596
|
+
codexStrayAdopted || stray.provider === 'codex';
|
|
597
|
+
}
|
|
598
|
+
catch (error) {
|
|
599
|
+
if (!isAdoptionConflictError(error)) {
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
const shouldReplace = await dependencies.confirmAction(`Conflict detected for ${formatPathForScope(scope, stray.report.providerPath)}. Replace canonical content with stray content?`, { interactive: context.interactive });
|
|
603
|
+
if (!shouldReplace) {
|
|
604
|
+
context.logger.warn(`Skipped conflicting stray entry [${scope}]: ${formatPathForScope(scope, stray.report.providerPath)}`);
|
|
605
|
+
continue;
|
|
606
|
+
}
|
|
607
|
+
manifest = await dependencies.adoptStray(scopeRoot, stray, manifest, {
|
|
608
|
+
replaceCanonical: true,
|
|
609
|
+
});
|
|
610
|
+
straysAdopted += 1;
|
|
611
|
+
codexStrayAdopted =
|
|
612
|
+
codexStrayAdopted || stray.provider === 'codex';
|
|
613
|
+
}
|
|
614
|
+
}
|
|
529
615
|
}
|
|
530
616
|
}
|
|
531
617
|
if (codexStrayAdopted && scope === 'project') {
|
|
@@ -535,6 +621,11 @@ async function runInitCommand(context, dependencies, hookFlag, setupFlag) {
|
|
|
535
621
|
computeExtensionPlan: computeCodexProjectExtensionPlan,
|
|
536
622
|
applyExtensionPlan: applyCodexProjectExtensionPlan,
|
|
537
623
|
});
|
|
624
|
+
if (activeAdaptersForStrays?.some((adapter) => adapter.name === 'cursor')) {
|
|
625
|
+
const refreshedCanonical = await dependencies.scanCanonical(scopeRoot, scope);
|
|
626
|
+
const cursorPlan = await computeCursorProjectExtensionPlan(scopeRoot, refreshedCanonical, undefined, { userConfigDir });
|
|
627
|
+
await applyCursorProjectExtensionPlan(scopeRoot, cursorPlan);
|
|
628
|
+
}
|
|
538
629
|
}
|
|
539
630
|
if (straysAdopted > 0) {
|
|
540
631
|
context.logger.success(`Adopted ${straysAdopted} stray entr${straysAdopted === 1 ? 'y' : 'ies'} [${scope}].`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/commands/project/dispatch-ceiling/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAa9B,OAAO,EAUL,KAAK,uBAAuB,EAY7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAsBzB,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAiC5C,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,cAAc,CAAC;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,sBAAsB,EAAE,CACtB,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7B,oBAAoB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC7E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC;CAC/B;AAmnFD,wBAAgB,mCAAmC,CACjD,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAkGT"}
|
|
@@ -210,10 +210,10 @@ function uncappedPreferredTier(provider, role, preferredValue) {
|
|
|
210
210
|
}
|
|
211
211
|
function dispatchValueFromRouteTarget(target) {
|
|
212
212
|
const adapter = getCeilingAdapter(target.harness);
|
|
213
|
-
if (adapter.
|
|
213
|
+
if (adapter.selectionAxis === 'model-effort') {
|
|
214
214
|
return target.effort ?? null;
|
|
215
215
|
}
|
|
216
|
-
if (adapter.
|
|
216
|
+
if (adapter.selectionAxis === 'model' || adapter.selectionAxis === 'tier') {
|
|
217
217
|
return target.model ?? null;
|
|
218
218
|
}
|
|
219
219
|
return null;
|
|
@@ -226,7 +226,7 @@ function routeTargetFromBareValue(provider, value, routeIndex, routeLength) {
|
|
|
226
226
|
routeIndex,
|
|
227
227
|
routeLength,
|
|
228
228
|
};
|
|
229
|
-
if (adapter.
|
|
229
|
+
if (adapter.selectionAxis === 'model-effort') {
|
|
230
230
|
target.effort = value;
|
|
231
231
|
}
|
|
232
232
|
else {
|
|
@@ -398,13 +398,15 @@ function candidatePrimaryTarget(provider, tier, candidate) {
|
|
|
398
398
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: direct dispatch role names are not candidate models.`);
|
|
399
399
|
}
|
|
400
400
|
const targetAdapter = getCeilingAdapter(target.harness);
|
|
401
|
-
if (targetAdapter.
|
|
401
|
+
if (targetAdapter.selectionAxis === 'model-effort' &&
|
|
402
402
|
(!target.model ||
|
|
403
403
|
!target.effort ||
|
|
404
404
|
!CODEX_VALUES.includes(target.effort))) {
|
|
405
405
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: Codex candidates require a model and supported effort.`);
|
|
406
406
|
}
|
|
407
|
-
if (targetAdapter.
|
|
407
|
+
if ((targetAdapter.selectionAxis === 'model' ||
|
|
408
|
+
targetAdapter.selectionAxis === 'tier') &&
|
|
409
|
+
!target.model) {
|
|
408
410
|
throw new Error(`Malformed ${provider} candidate ordering in ${tier}: model-argument candidates require a model.`);
|
|
409
411
|
}
|
|
410
412
|
return target;
|
|
@@ -1053,7 +1055,7 @@ function selectDispatchValue(provider, role, policy, preferredValue) {
|
|
|
1053
1055
|
target: selectedTarget,
|
|
1054
1056
|
};
|
|
1055
1057
|
}
|
|
1056
|
-
function
|
|
1058
|
+
function hasVariantDispatchArgs(dispatchArgs) {
|
|
1057
1059
|
return (dispatchArgs !== null &&
|
|
1058
1060
|
'variant' in dispatchArgs &&
|
|
1059
1061
|
typeof dispatchArgs.variant === 'string' &&
|
|
@@ -1065,20 +1067,26 @@ function hasModelDispatchArgs(dispatchArgs) {
|
|
|
1065
1067
|
typeof dispatchArgs.model === 'string' &&
|
|
1066
1068
|
dispatchArgs.model.length > 0);
|
|
1067
1069
|
}
|
|
1068
|
-
function modelAxis(selection, dispatchArgs) {
|
|
1070
|
+
function modelAxis(provider, selection, dispatchArgs) {
|
|
1069
1071
|
if (selection.target?.model && dispatchArgs) {
|
|
1070
1072
|
return `selected:${selection.target.model}`;
|
|
1071
1073
|
}
|
|
1072
1074
|
if (hasModelDispatchArgs(dispatchArgs)) {
|
|
1073
1075
|
return `selected:${dispatchArgs.model}`;
|
|
1074
1076
|
}
|
|
1077
|
+
if (provider === 'cursor' &&
|
|
1078
|
+
hasVariantDispatchArgs(dispatchArgs) &&
|
|
1079
|
+
selection.target === null &&
|
|
1080
|
+
selection.selectedValue) {
|
|
1081
|
+
return `selected:${selection.selectedValue}`;
|
|
1082
|
+
}
|
|
1075
1083
|
if (selection.selectionMode === 'inherit-default') {
|
|
1076
1084
|
return 'inherited';
|
|
1077
1085
|
}
|
|
1078
1086
|
return 'unresolved';
|
|
1079
1087
|
}
|
|
1080
1088
|
function codexEffortAxis(selection, dispatchArgs) {
|
|
1081
|
-
if (
|
|
1089
|
+
if (hasVariantDispatchArgs(dispatchArgs) && selection.target?.effort) {
|
|
1082
1090
|
return `selected:${selection.target.effort}`;
|
|
1083
1091
|
}
|
|
1084
1092
|
if (selection.selectionMode === 'inherit-default' ||
|
|
@@ -1149,7 +1157,7 @@ function buildProviderResolution(provider, policy, role, orchestratorTier, prefe
|
|
|
1149
1157
|
mode,
|
|
1150
1158
|
mechanism: adapter.mechanism,
|
|
1151
1159
|
dispatchArgs,
|
|
1152
|
-
modelAxis: modelAxis(selection, dispatchArgs),
|
|
1160
|
+
modelAxis: modelAxis(provider, selection, dispatchArgs),
|
|
1153
1161
|
effortAxis: provider === 'codex'
|
|
1154
1162
|
? codexEffortAxis(selection, dispatchArgs)
|
|
1155
1163
|
: 'not-applicable',
|
|
@@ -3,6 +3,7 @@ import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
|
3
3
|
import { type SyncConfig } from '../../../config/sync-config.js';
|
|
4
4
|
import { type Manifest } from '../../../manifest/index.js';
|
|
5
5
|
import { type ConfigAwareAdaptersResult, type PathMapping, type ProviderAdapter } from '../../../providers/shared/index.js';
|
|
6
|
+
import type { AdoptionSource } from '../../../providers/shared/adapter.types.js';
|
|
6
7
|
import type { ConcreteScope, Scope } from '../../../shared/types.js';
|
|
7
8
|
import { Command } from 'commander';
|
|
8
9
|
export interface RemoveSkillDependencies {
|
|
@@ -14,6 +15,7 @@ export interface RemoveSkillDependencies {
|
|
|
14
15
|
getAdapters: () => ProviderAdapter[];
|
|
15
16
|
getConfigAwareAdapters: (adapters: ProviderAdapter[], scopeRoot: string, config: SyncConfig) => Promise<ConfigAwareAdaptersResult>;
|
|
16
17
|
getSyncMappings: (adapter: ProviderAdapter, scope: Scope) => PathMapping[];
|
|
18
|
+
getAdoptionSources: (adapter: ProviderAdapter, scope: Scope) => AdoptionSource[];
|
|
17
19
|
pathExists: (path: string) => Promise<boolean>;
|
|
18
20
|
removeDirectory: (path: string) => Promise<void>;
|
|
19
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove-skill.d.ts","sourceRoot":"","sources":["../../../../src/commands/remove/skill/remove-skill.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EACL,iBAAiB,EAElB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACL,KAAK,yBAAyB,EAG9B,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAC1C,cAAc,CAAC;IACpB,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,eAAe,EAAE,CAAC;IACrC,sBAAsB,EAAE,CACtB,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;IAC3E,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,wBAAgB,oCAAoC,IAAI,uBAAuB,
|
|
1
|
+
{"version":3,"file":"remove-skill.d.ts","sourceRoot":"","sources":["../../../../src/commands/remove/skill/remove-skill.ts"],"names":[],"mappings":"AAGA,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EACL,iBAAiB,EAElB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACL,KAAK,yBAAyB,EAG9B,KAAK,WAAW,EAChB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEtE,OAAO,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8BpC,MAAM,WAAW,uBAAuB;IACtC,mBAAmB,EAAE,CACnB,OAAO,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,KAC1C,cAAc,CAAC;IACpB,gBAAgB,EAAE,CAChB,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE,cAAc,KACpB,OAAO,CAAC,MAAM,CAAC,CAAC;IACrB,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,cAAc,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,WAAW,EAAE,MAAM,eAAe,EAAE,CAAC;IACrC,sBAAsB,EAAE,CACtB,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,KACf,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACxC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;IAC3E,kBAAkB,EAAE,CAClB,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,KAAK,KACT,cAAc,EAAE,CAAC;IACtB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,wBAAgB,oCAAoC,IAAI,uBAAuB,CAiC9E;AAuLD,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,OAAO,EACf,YAAY,EAAE,uBAAuB,GACpC,OAAO,CAAC,OAAO,CAAC,CAsDlB;AAED,wBAAgB,wBAAwB,CACtC,SAAS,GAAE,OAAO,CAAC,uBAAuB,CAAM,GAC/C,OAAO,CAwCT"}
|
|
@@ -13,6 +13,7 @@ import { copilotAdapter } from '../../../providers/copilot/index.js';
|
|
|
13
13
|
import { cursorAdapter } from '../../../providers/cursor/index.js';
|
|
14
14
|
import { geminiAdapter } from '../../../providers/gemini/index.js';
|
|
15
15
|
import { getConfigAwareAdapters, getSyncMappings, } from '../../../providers/shared/index.js';
|
|
16
|
+
import { getAdoptionSources } from '../../../providers/shared/adapter.utils.js';
|
|
16
17
|
import { Command } from 'commander';
|
|
17
18
|
export function createDefaultRemoveSkillDependencies() {
|
|
18
19
|
return {
|
|
@@ -39,6 +40,7 @@ export function createDefaultRemoveSkillDependencies() {
|
|
|
39
40
|
},
|
|
40
41
|
getConfigAwareAdapters,
|
|
41
42
|
getSyncMappings,
|
|
43
|
+
getAdoptionSources,
|
|
42
44
|
async pathExists(path) {
|
|
43
45
|
return (await fileExists(path)) || (await dirExists(path));
|
|
44
46
|
},
|
|
@@ -76,10 +78,10 @@ async function buildScopePlan(scope, scopeRoot, skillName, dependencies) {
|
|
|
76
78
|
const managedProviderViews = [];
|
|
77
79
|
const unmanagedProviderViews = [];
|
|
78
80
|
for (const adapter of activeAdapters) {
|
|
79
|
-
const
|
|
81
|
+
const syncMappings = dependencies
|
|
80
82
|
.getSyncMappings(adapter, scope)
|
|
81
83
|
.filter((mapping) => mapping.contentType === 'skill');
|
|
82
|
-
for (const mapping of
|
|
84
|
+
for (const mapping of syncMappings) {
|
|
83
85
|
const relativePath = join(mapping.providerDir, skillName);
|
|
84
86
|
const absolutePath = join(scopeRoot, relativePath);
|
|
85
87
|
const hasManifestEntry = manifest.entries.some((entry) => entry.canonicalPath === canonicalRelativePath &&
|
|
@@ -101,6 +103,22 @@ async function buildScopePlan(scope, scopeRoot, skillName, dependencies) {
|
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
}
|
|
106
|
+
const syncProviderDirs = new Set(syncMappings.map((mapping) => mapping.providerDir));
|
|
107
|
+
const localAdoptionSources = dependencies
|
|
108
|
+
.getAdoptionSources(adapter, scope)
|
|
109
|
+
.filter((source) => source.contentType === 'skill' &&
|
|
110
|
+
!syncProviderDirs.has(source.directory));
|
|
111
|
+
for (const source of localAdoptionSources) {
|
|
112
|
+
const relativePath = join(source.directory, skillName);
|
|
113
|
+
const absolutePath = join(scopeRoot, relativePath);
|
|
114
|
+
if (await dependencies.pathExists(absolutePath)) {
|
|
115
|
+
unmanagedProviderViews.push({
|
|
116
|
+
provider: adapter.name,
|
|
117
|
+
absolutePath,
|
|
118
|
+
relativePath,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
104
122
|
}
|
|
105
123
|
return {
|
|
106
124
|
scope,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adopt-stray.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/adopt-stray.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKzC,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,UAAU,iBAAiB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEzE;AAWD,wBAAsB,qBAAqB,CACzC,UAAU,SAAS,sBAAsB,EAEzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"adopt-stray.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/adopt-stray.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKzC,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAGnE,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT,IAAI,EAAE,YAAY,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,UAAU,iBAAiB;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAEzE;AAWD,wBAAsB,qBAAqB,CACzC,UAAU,SAAS,sBAAsB,EAEzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,QAAQ,CAAC,CA8EnB"}
|
|
@@ -53,6 +53,9 @@ export async function adoptStrayToCanonical(scopeRoot, stray, manifest, options
|
|
|
53
53
|
else {
|
|
54
54
|
await rename(providerAbsolutePath, canonicalAbsolutePath);
|
|
55
55
|
}
|
|
56
|
+
if (stray.mapping.nativeRead) {
|
|
57
|
+
return manifest;
|
|
58
|
+
}
|
|
56
59
|
const strategy = await createSymlink(canonicalAbsolutePath, providerAbsolutePath, undefined, isFile);
|
|
57
60
|
const canonicalPath = toPosixPath(relative(scopeRoot, canonicalAbsolutePath));
|
|
58
61
|
const providerPath = toPosixPath(relative(scopeRoot, providerAbsolutePath));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CanonicalEntry } from '../../engine/index.js';
|
|
2
2
|
import type { CodexExtensionPlan } from '../../providers/codex/codec/sync-extension.js';
|
|
3
|
+
import type { MaterializationPlan } from '../../providers/shared/index.js';
|
|
3
4
|
export interface CodexRoleStray {
|
|
4
5
|
roleName: string;
|
|
5
6
|
providerPath: string;
|
|
@@ -11,6 +12,14 @@ export interface CodexRegenerationDependencies {
|
|
|
11
12
|
computeExtensionPlan: (scopeRoot: string, canonicalEntries: CanonicalEntry[]) => Promise<CodexExtensionPlan>;
|
|
12
13
|
applyExtensionPlan: (scopeRoot: string, plan: CodexExtensionPlan) => Promise<unknown>;
|
|
13
14
|
}
|
|
15
|
+
interface ProviderStrayCandidate {
|
|
16
|
+
provider: string;
|
|
17
|
+
report: {
|
|
18
|
+
providerPath: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function filterMaterializationManagedStrays<TCandidate extends ProviderStrayCandidate>(candidates: TCandidate[], plans: readonly MaterializationPlan[]): TCandidate[];
|
|
14
22
|
export declare function detectCodexRoleStrays(scopeRoot: string, canonicalEntries: CanonicalEntry[], managedRoleNames?: Set<string>): Promise<CodexRoleStray[]>;
|
|
15
23
|
export declare function regenerateCodexAfterAdoption({ scopeRoot, scanCanonical, computeExtensionPlan, applyExtensionPlan, }: CodexRegenerationDependencies): Promise<void>;
|
|
24
|
+
export {};
|
|
16
25
|
//# sourceMappingURL=codex-strays.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-strays.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/codex-strays.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"codex-strays.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/codex-strays.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/C,oBAAoB,EAAE,CACpB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,KAC/B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,kBAAkB,EAAE,CAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,kBAAkB,KACrB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,UAAU,sBAAsB;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAClC;AAED,wBAAgB,kCAAkC,CAChD,UAAU,SAAS,sBAAsB,EAEzC,UAAU,EAAE,UAAU,EAAE,EACxB,KAAK,EAAE,SAAS,mBAAmB,EAAE,GACpC,UAAU,EAAE,CAed;AAgJD,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,cAAc,EAAE,EAClC,gBAAgB,GAAE,GAAG,CAAC,MAAM,CAAa,GACxC,OAAO,CAAC,cAAc,EAAE,CAAC,CAuB3B;AAED,wBAAsB,4BAA4B,CAAC,EACjD,SAAS,EACT,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GACnB,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/C"}
|
|
@@ -2,6 +2,10 @@ import { readdir, readFile, stat } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import TOML from '@iarna/toml';
|
|
4
4
|
import { isOatManagedCodexRoleFile } from '../../providers/codex/codec/shared.js';
|
|
5
|
+
export function filterMaterializationManagedStrays(candidates, plans) {
|
|
6
|
+
const managedPaths = new Set(plans.flatMap((plan) => plan.operations.map((operation) => `${plan.provider}|${operation.path.replaceAll('\\', '/')}`)));
|
|
7
|
+
return candidates.filter((candidate) => !managedPaths.has(`${candidate.provider}|${candidate.report.providerPath.replaceAll('\\', '/')}`));
|
|
8
|
+
}
|
|
5
9
|
function canonicalRoleNames(canonicalEntries) {
|
|
6
10
|
return new Set(canonicalEntries
|
|
7
11
|
.filter((entry) => entry.type === 'agent' && entry.isFile)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Manifest } from '../../manifest/manifest.types.js';
|
|
2
|
+
import type { PathMapping } from '../../providers/shared/adapter.types.js';
|
|
3
|
+
export type CursorSkillDisposition = 'adopt' | 'keep';
|
|
4
|
+
export interface CursorSkillCandidate {
|
|
5
|
+
provider: string;
|
|
6
|
+
report: {
|
|
7
|
+
providerPath: string;
|
|
8
|
+
};
|
|
9
|
+
mapping: PathMapping;
|
|
10
|
+
}
|
|
11
|
+
interface ApplyCursorSkillDispositionOptions {
|
|
12
|
+
replaceCanonical?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function isCursorSkillCandidate(candidate: CursorSkillCandidate): boolean;
|
|
15
|
+
export declare function applyCursorSkillDisposition(scopeRoot: string, candidate: CursorSkillCandidate, manifest: Manifest, disposition: CursorSkillDisposition, syncConfigPath: string, options?: ApplyCursorSkillDispositionOptions): Promise<Manifest>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=cursor-skill-disposition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-skill-disposition.d.ts","sourceRoot":"","sources":["../../../src/commands/shared/cursor-skill-disposition.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAInE,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,kCAAkC;IAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,oBAAoB,GAC9B,OAAO,CAST;AAED,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,oBAAoB,EAC/B,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,sBAAsB,EACnC,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,kCAAuC,GAC/C,OAAO,CAAC,QAAQ,CAAC,CAcnB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import { basename, relative, resolve } from 'node:path';
|
|
3
|
+
import { appendKnownStray } from '../../config/sync-config.js';
|
|
4
|
+
import { CliError } from '../../errors/index.js';
|
|
5
|
+
import { toPosixPath } from '../../fs/paths.js';
|
|
6
|
+
import { adoptStrayToCanonical } from './adopt-stray.js';
|
|
7
|
+
export function isCursorSkillCandidate(candidate) {
|
|
8
|
+
const providerPath = toPosixPath(candidate.report.providerPath);
|
|
9
|
+
return (candidate.provider === 'cursor' &&
|
|
10
|
+
candidate.mapping.contentType === 'skill' &&
|
|
11
|
+
candidate.mapping.nativeRead &&
|
|
12
|
+
(providerPath === '.cursor/skills' ||
|
|
13
|
+
providerPath.startsWith('.cursor/skills/')));
|
|
14
|
+
}
|
|
15
|
+
export async function applyCursorSkillDisposition(scopeRoot, candidate, manifest, disposition, syncConfigPath, options = {}) {
|
|
16
|
+
if (!isCursorSkillCandidate(candidate)) {
|
|
17
|
+
throw new CliError(`Cannot apply a Cursor skill disposition to ${candidate.report.providerPath}.`);
|
|
18
|
+
}
|
|
19
|
+
if (disposition === 'adopt') {
|
|
20
|
+
return adoptStrayToCanonical(scopeRoot, candidate, manifest, options);
|
|
21
|
+
}
|
|
22
|
+
await assertCursorOnlyNameAvailable(scopeRoot, candidate);
|
|
23
|
+
await appendKnownStray(syncConfigPath, candidate.report.providerPath);
|
|
24
|
+
return manifest;
|
|
25
|
+
}
|
|
26
|
+
async function assertCursorOnlyNameAvailable(scopeRoot, candidate) {
|
|
27
|
+
const canonicalPath = resolve(scopeRoot, candidate.mapping.canonicalDir, basename(candidate.report.providerPath));
|
|
28
|
+
if (!(await pathExists(canonicalPath))) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
throw new CliError(`Cannot keep ${candidate.report.providerPath} Cursor-only because canonical skill ${toPosixPath(relative(scopeRoot, canonicalPath))} has the same name. Rename one skill, then run the command again.`);
|
|
32
|
+
}
|
|
33
|
+
async function pathExists(path) {
|
|
34
|
+
try {
|
|
35
|
+
await access(path);
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { type CommandContext, type GlobalOptions } from '../../app/command-context.js';
|
|
2
2
|
import { type CodexRoleStray } from '../shared/codex-strays.js';
|
|
3
|
-
import { type
|
|
3
|
+
import { type CursorSkillDisposition } from '../shared/cursor-skill-disposition.js';
|
|
4
|
+
import { type MultiSelectChoice, type PromptContext, type SelectChoice } from '../shared/shared.prompts.js';
|
|
4
5
|
import { type SyncConfig } from '../../config/index.js';
|
|
5
|
-
import { type UserConfig } from '../../config/oat-config.js';
|
|
6
6
|
import { type CopyTransform, type DriftReport } from '../../drift/index.js';
|
|
7
7
|
import { type CanonicalEntry } from '../../engine/index.js';
|
|
8
8
|
import type { Manifest } from '../../manifest/index.js';
|
|
9
9
|
import { type CodexExtensionPlan } from '../../providers/codex/codec/sync-extension.js';
|
|
10
|
+
import { type CursorExtensionPlan } from '../../providers/cursor/codec/sync-extension.js';
|
|
10
11
|
import { type PathMapping, type ProviderAdapter } from '../../providers/shared/index.js';
|
|
12
|
+
import type { AdoptionSource } from '../../providers/shared/adapter.types.js';
|
|
11
13
|
import { type ConcreteScope, type Scope } from '../../shared/types.js';
|
|
12
14
|
import { Command } from 'commander';
|
|
13
15
|
interface StatusDependencies {
|
|
@@ -15,26 +17,36 @@ interface StatusDependencies {
|
|
|
15
17
|
resolveScopeRoot: (scope: ConcreteScope, context: CommandContext) => Promise<string>;
|
|
16
18
|
loadManifest: (manifestPath: string) => Promise<Manifest>;
|
|
17
19
|
loadSyncConfig: (configPath: string) => Promise<SyncConfig>;
|
|
18
|
-
|
|
20
|
+
resolveUserSyncConfig: (userConfigDir: string) => Promise<SyncConfig>;
|
|
19
21
|
saveManifest: (manifestPath: string, manifest: Manifest) => Promise<void>;
|
|
20
22
|
scanCanonical: (scopeRoot: string, scope: ConcreteScope) => Promise<CanonicalEntry[]>;
|
|
21
|
-
|
|
23
|
+
scanBundledManagedAgents: () => Promise<CanonicalEntry[]>;
|
|
22
24
|
getAdapters: () => ProviderAdapter[];
|
|
23
25
|
getActiveAdapters: (adapters: ProviderAdapter[], scopeRoot: string) => Promise<ProviderAdapter[]>;
|
|
24
26
|
getSyncMappings: (adapter: ProviderAdapter, scope: Scope) => PathMapping[];
|
|
27
|
+
getAdoptionSources: (adapter: ProviderAdapter, scope: Scope) => AdoptionSource[];
|
|
25
28
|
detectDrift: (entry: Manifest['entries'][number], scopeRoot: string, copyTransform?: CopyTransform) => Promise<DriftReport>;
|
|
26
|
-
detectStrays: (provider: string, providerDir: string, manifest: Manifest, canonicalEntries: CanonicalEntry[], mapping?: Pick<PathMapping, 'contentType' | 'providerExtension'>) => Promise<DriftReport[]>;
|
|
29
|
+
detectStrays: (provider: string, providerDir: string, manifest: Manifest, canonicalEntries: CanonicalEntry[], mapping?: Pick<PathMapping, 'contentType' | 'nativeRead' | 'providerExtension'>) => Promise<DriftReport[]>;
|
|
27
30
|
detectCodexRoleStrays: (scopeRoot: string, canonicalEntries: CanonicalEntry[], managedRoleNames?: Set<string>) => Promise<CodexRoleStray[]>;
|
|
28
31
|
computeCodexProjectExtensionPlan: (scopeRoot: string, canonicalEntries: CanonicalEntry[], allowedCanonicalPaths?: string[], options?: {
|
|
29
32
|
userConfigDir?: string;
|
|
30
33
|
env?: NodeJS.ProcessEnv;
|
|
31
34
|
}) => Promise<CodexExtensionPlan>;
|
|
32
35
|
applyCodexProjectExtensionPlan: (scopeRoot: string, plan: CodexExtensionPlan) => Promise<unknown>;
|
|
36
|
+
computeCursorProjectExtensionPlan: (scopeRoot: string, canonicalEntries: CanonicalEntry[], allowedCanonicalPaths?: string[], options?: {
|
|
37
|
+
userConfigDir?: string;
|
|
38
|
+
env?: NodeJS.ProcessEnv;
|
|
39
|
+
}) => Promise<CursorExtensionPlan>;
|
|
40
|
+
applyCursorProjectExtensionPlan: (scopeRoot: string, plan: CursorExtensionPlan) => Promise<unknown>;
|
|
33
41
|
selectManyWithAbort: <T extends string>(message: string, choices: MultiSelectChoice<T>[], ctx: PromptContext) => Promise<T[] | null>;
|
|
42
|
+
selectWithAbort: <T extends string>(message: string, choices: SelectChoice<T>[], ctx: PromptContext) => Promise<T | null>;
|
|
34
43
|
confirmAction: (message: string, ctx: PromptContext) => Promise<boolean>;
|
|
35
44
|
adoptStray: (scopeRoot: string, stray: StatusStrayCandidate, manifest: Manifest, options?: {
|
|
36
45
|
replaceCanonical?: boolean;
|
|
37
46
|
}) => Promise<Manifest>;
|
|
47
|
+
applyCursorSkillDisposition: (scopeRoot: string, stray: StatusStrayCandidate, manifest: Manifest, disposition: CursorSkillDisposition, syncConfigPath: string, options?: {
|
|
48
|
+
replaceCanonical?: boolean;
|
|
49
|
+
}) => Promise<Manifest>;
|
|
38
50
|
formatStatusTable: (reports: DriftReport[]) => string;
|
|
39
51
|
}
|
|
40
52
|
interface StatusStrayCandidate {
|