@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
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { access, lstat, readdir, readFile, readlink, stat, } from 'node:fs/promises';
|
|
3
|
+
import { basename, dirname, join, normalize, relative, resolve, } from 'node:path';
|
|
3
4
|
import { computeContentHash, computeStringHash } from '../manifest/hash.js';
|
|
4
5
|
import { findEntry } from '../manifest/manager.js';
|
|
5
6
|
import { getSyncMappings } from '../providers/shared/adapter.utils.js';
|
|
7
|
+
import { OAT_DIRECTORY_SENTINEL, OAT_MARKER_PREFIX } from './markers.js';
|
|
6
8
|
function buildUpLevels(depth) {
|
|
7
9
|
return Array.from({ length: depth }, () => '..');
|
|
8
10
|
}
|
|
@@ -88,6 +90,145 @@ function createRemovalEntry(manifestEntry, scopeRoot) {
|
|
|
88
90
|
reason: 'canonical entry no longer exists',
|
|
89
91
|
};
|
|
90
92
|
}
|
|
93
|
+
function createRetirementEntry(manifestEntry, scopeRoot, operation, reason) {
|
|
94
|
+
return {
|
|
95
|
+
...createRemovalEntry(manifestEntry, scopeRoot),
|
|
96
|
+
operation,
|
|
97
|
+
reason,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function manifestEntryInsideMapping(entry, mapping) {
|
|
101
|
+
if (entry.contentType !== mapping.contentType) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
const canonicalPath = normalize(entry.canonicalPath).replaceAll('\\', '/');
|
|
105
|
+
const canonicalDir = normalize(mapping.canonicalDir).replaceAll('\\', '/');
|
|
106
|
+
return (canonicalPath === canonicalDir ||
|
|
107
|
+
canonicalPath.startsWith(`${canonicalDir}/`));
|
|
108
|
+
}
|
|
109
|
+
async function computeManagedDirectoryCopyHash(providerPath, canonicalPath, contentType) {
|
|
110
|
+
const expectedMarker = `${OAT_MARKER_PREFIX} Source: ${canonicalPath} -->`;
|
|
111
|
+
const sentinelPath = join(providerPath, OAT_DIRECTORY_SENTINEL);
|
|
112
|
+
try {
|
|
113
|
+
const sentinel = await readFile(sentinelPath, 'utf8');
|
|
114
|
+
if (sentinel !== `${expectedMarker}\n`) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const files = [];
|
|
122
|
+
async function collectFiles(current) {
|
|
123
|
+
const entries = await readdir(current, { withFileTypes: true });
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
const fullPath = join(current, entry.name);
|
|
126
|
+
if (fullPath === sentinelPath) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (entry.isDirectory()) {
|
|
130
|
+
if (!(await collectFiles(fullPath))) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (!entry.isFile()) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
files.push(fullPath);
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
if (!(await collectFiles(providerPath))) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
files.sort((left, right) => relative(providerPath, left).localeCompare(relative(providerPath, right)));
|
|
147
|
+
const markerFileName = contentType === 'skill'
|
|
148
|
+
? 'SKILL.md'
|
|
149
|
+
: contentType === 'agent'
|
|
150
|
+
? 'AGENT.md'
|
|
151
|
+
: null;
|
|
152
|
+
const markerPath = markerFileName
|
|
153
|
+
? join(providerPath, markerFileName)
|
|
154
|
+
: null;
|
|
155
|
+
const hash = createHash('sha256');
|
|
156
|
+
for (const file of files) {
|
|
157
|
+
const relativePath = relative(providerPath, file);
|
|
158
|
+
let content = await readFile(file);
|
|
159
|
+
if (file === markerPath) {
|
|
160
|
+
const markerPrefix = Buffer.from(`${expectedMarker}\n`);
|
|
161
|
+
if (content.length < markerPrefix.length ||
|
|
162
|
+
!content.subarray(0, markerPrefix.length).equals(markerPrefix)) {
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
content = content.subarray(markerPrefix.length);
|
|
166
|
+
}
|
|
167
|
+
hash.update(relativePath);
|
|
168
|
+
hash.update('\0');
|
|
169
|
+
hash.update(content);
|
|
170
|
+
hash.update('\0');
|
|
171
|
+
}
|
|
172
|
+
return hash.digest('hex');
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function classifyObsoleteMappingRetirement(manifestEntry, scopeRoot) {
|
|
179
|
+
const providerPath = resolve(scopeRoot, manifestEntry.providerPath);
|
|
180
|
+
const canonicalPath = resolve(scopeRoot, manifestEntry.canonicalPath);
|
|
181
|
+
let providerStat;
|
|
182
|
+
try {
|
|
183
|
+
providerStat = await lstat(providerPath);
|
|
184
|
+
}
|
|
185
|
+
catch (error) {
|
|
186
|
+
if (typeof error === 'object' &&
|
|
187
|
+
error !== null &&
|
|
188
|
+
'code' in error &&
|
|
189
|
+
error.code === 'ENOENT') {
|
|
190
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is missing; detach manifest ownership');
|
|
191
|
+
}
|
|
192
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is unverified; preserve and detach manifest ownership');
|
|
193
|
+
}
|
|
194
|
+
if (manifestEntry.strategy === 'symlink') {
|
|
195
|
+
if (providerStat.isSymbolicLink()) {
|
|
196
|
+
try {
|
|
197
|
+
const linkTarget = await readlink(providerPath);
|
|
198
|
+
const resolvedTarget = resolve(dirname(providerPath), linkTarget);
|
|
199
|
+
await stat(resolvedTarget);
|
|
200
|
+
if (resolvedTarget === canonicalPath) {
|
|
201
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed symlink');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
// Broken or unreadable links are preserved and detached below.
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is changed or unverified; preserve and detach manifest ownership');
|
|
209
|
+
}
|
|
210
|
+
const expectedTypeMatches = manifestEntry.isFile
|
|
211
|
+
? providerStat.isFile()
|
|
212
|
+
: providerStat.isDirectory();
|
|
213
|
+
if (expectedTypeMatches && manifestEntry.contentHash) {
|
|
214
|
+
try {
|
|
215
|
+
const currentHash = await computeContentHash(providerPath, manifestEntry.isFile);
|
|
216
|
+
if (currentHash === manifestEntry.contentHash) {
|
|
217
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
// Hash failures are unverified and therefore non-destructive.
|
|
222
|
+
}
|
|
223
|
+
if (!manifestEntry.isFile) {
|
|
224
|
+
const managedHash = await computeManagedDirectoryCopyHash(providerPath, canonicalPath, manifestEntry.contentType);
|
|
225
|
+
if (managedHash === manifestEntry.contentHash) {
|
|
226
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'remove', 'obsolete mapping has verified clean managed copy');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return createRetirementEntry(manifestEntry, scopeRoot, 'detach', 'obsolete mapping provider path is changed or unverified; preserve and detach manifest ownership');
|
|
231
|
+
}
|
|
91
232
|
async function classifyOperation(canonicalEntry, providerPath, strategy, renderedContent) {
|
|
92
233
|
if (strategy === 'symlink') {
|
|
93
234
|
let stat;
|
|
@@ -180,16 +321,22 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
180
321
|
const scopeRoot = resolveScopeRoot(canonical, explicitScopeRoot);
|
|
181
322
|
const seenCanonicalKeys = new Set();
|
|
182
323
|
const activeProviderNames = new Set();
|
|
324
|
+
const activeMappingsByProvider = new Map();
|
|
183
325
|
const canonicalFilter = allowedCanonicalPaths
|
|
184
326
|
? new Set(allowedCanonicalPaths.map((canonicalPath) => normalize(canonicalPath)))
|
|
185
327
|
: null;
|
|
186
328
|
for (const adapter of adapters) {
|
|
329
|
+
if (resolveStrategy(adapter, config)) {
|
|
330
|
+
activeProviderNames.add(adapter.name);
|
|
331
|
+
}
|
|
187
332
|
for (const mapping of getSyncMappings(adapter, scope)) {
|
|
188
333
|
const mappingStrategy = resolveStrategy(adapter, config, Boolean(mapping.transformCanonical));
|
|
189
334
|
if (!mappingStrategy) {
|
|
190
335
|
continue;
|
|
191
336
|
}
|
|
192
|
-
|
|
337
|
+
const activeMappings = activeMappingsByProvider.get(adapter.name) ?? [];
|
|
338
|
+
activeMappings.push(mapping);
|
|
339
|
+
activeMappingsByProvider.set(adapter.name, activeMappings);
|
|
193
340
|
for (const canonicalEntry of canonical) {
|
|
194
341
|
if (!entryContentTypeMatches(canonicalEntry, mapping.contentType)) {
|
|
195
342
|
continue;
|
|
@@ -244,7 +391,10 @@ export async function computeSyncPlan({ canonical, adapters, manifest, scope, co
|
|
|
244
391
|
!canonicalFilter.has(normalize(manifestEntry.canonicalPath))) {
|
|
245
392
|
continue;
|
|
246
393
|
}
|
|
247
|
-
|
|
394
|
+
const mappingStillExists = (activeMappingsByProvider.get(manifestEntry.provider) ?? []).some((mapping) => manifestEntryInsideMapping(manifestEntry, mapping));
|
|
395
|
+
removals.push(mappingStillExists
|
|
396
|
+
? createRemovalEntry(manifestEntry, scopeRoot)
|
|
397
|
+
: await classifyObsoleteMappingRetirement(manifestEntry, scopeRoot));
|
|
248
398
|
}
|
|
249
399
|
return { scope, entries, removals };
|
|
250
400
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Scope } from '../shared/types.js';
|
|
2
2
|
import type { CanonicalEntry } from './scanner.js';
|
|
3
3
|
export type EngineScope = Exclude<Scope, 'all'>;
|
|
4
|
-
export declare const SYNC_OPERATION_TYPES: readonly ["create_symlink", "create_copy", "update_symlink", "update_copy", "remove", "skip"];
|
|
4
|
+
export declare const SYNC_OPERATION_TYPES: readonly ["create_symlink", "create_copy", "update_symlink", "update_copy", "remove", "detach", "skip"];
|
|
5
5
|
export type SyncOperationType = (typeof SYNC_OPERATION_TYPES)[number];
|
|
6
6
|
export interface SyncPlanEntry {
|
|
7
7
|
canonical: CanonicalEntry;
|
|
@@ -13,7 +13,7 @@ export interface SyncPlanEntry {
|
|
|
13
13
|
renderedContent?: string;
|
|
14
14
|
}
|
|
15
15
|
export type RemovalSyncPlanEntry = SyncPlanEntry & {
|
|
16
|
-
operation: 'remove';
|
|
16
|
+
operation: 'remove' | 'detach';
|
|
17
17
|
};
|
|
18
18
|
export interface SyncPlan {
|
|
19
19
|
scope: EngineScope;
|
|
@@ -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
|
|
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,yGAQvB,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;CAC1B;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG;IACjD,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAiB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG1E,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;
|
|
1
|
+
{"version":3,"file":"execute-plan.d.ts","sourceRoot":"","sources":["../../src/engine/execute-plan.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,0BAA0B,CAAC;AAExE,OAAO,KAAK,EAAE,QAAQ,EAAiB,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG1E,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAW5D;AA2JD,wBAAsB,eAAe,CACnC,IAAI,EAAE,QAAQ,EACd,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC,CA0BrB"}
|
|
@@ -98,6 +98,10 @@ async function applyEntry(planEntry, manifest) {
|
|
|
98
98
|
const { canonicalPath } = resolveManifestPaths(planEntry);
|
|
99
99
|
return removeEntry(manifest, canonicalPath, planEntry.provider);
|
|
100
100
|
}
|
|
101
|
+
case 'detach': {
|
|
102
|
+
const { canonicalPath } = resolveManifestPaths(planEntry);
|
|
103
|
+
return removeEntry(manifest, canonicalPath, planEntry.provider);
|
|
104
|
+
}
|
|
101
105
|
case 'skip': {
|
|
102
106
|
return manifest;
|
|
103
107
|
}
|
|
@@ -10,37 +10,37 @@ export declare const ManifestEntrySchema: z.ZodEffects<z.ZodObject<{
|
|
|
10
10
|
lastSynced: z.ZodString;
|
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
|
12
12
|
provider: string;
|
|
13
|
+
strategy: "symlink" | "copy";
|
|
13
14
|
canonicalPath: string;
|
|
14
15
|
providerPath: string;
|
|
15
16
|
contentType: "skill" | "agent" | "rule";
|
|
16
|
-
strategy: "symlink" | "copy";
|
|
17
17
|
contentHash: string | null;
|
|
18
18
|
isFile: boolean;
|
|
19
19
|
lastSynced: string;
|
|
20
20
|
}, {
|
|
21
21
|
provider: string;
|
|
22
|
+
strategy: "symlink" | "copy";
|
|
22
23
|
canonicalPath: string;
|
|
23
24
|
providerPath: string;
|
|
24
25
|
contentType: "skill" | "agent" | "rule";
|
|
25
|
-
strategy: "symlink" | "copy";
|
|
26
26
|
contentHash: string | null;
|
|
27
27
|
lastSynced: string;
|
|
28
28
|
isFile?: boolean | undefined;
|
|
29
29
|
}>, {
|
|
30
30
|
provider: string;
|
|
31
|
+
strategy: "symlink" | "copy";
|
|
31
32
|
canonicalPath: string;
|
|
32
33
|
providerPath: string;
|
|
33
34
|
contentType: "skill" | "agent" | "rule";
|
|
34
|
-
strategy: "symlink" | "copy";
|
|
35
35
|
contentHash: string | null;
|
|
36
36
|
isFile: boolean;
|
|
37
37
|
lastSynced: string;
|
|
38
38
|
}, {
|
|
39
39
|
provider: string;
|
|
40
|
+
strategy: "symlink" | "copy";
|
|
40
41
|
canonicalPath: string;
|
|
41
42
|
providerPath: string;
|
|
42
43
|
contentType: "skill" | "agent" | "rule";
|
|
43
|
-
strategy: "symlink" | "copy";
|
|
44
44
|
contentHash: string | null;
|
|
45
45
|
lastSynced: string;
|
|
46
46
|
isFile?: boolean | undefined;
|
|
@@ -59,37 +59,37 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
|
|
|
59
59
|
lastSynced: z.ZodString;
|
|
60
60
|
}, "strip", z.ZodTypeAny, {
|
|
61
61
|
provider: string;
|
|
62
|
+
strategy: "symlink" | "copy";
|
|
62
63
|
canonicalPath: string;
|
|
63
64
|
providerPath: string;
|
|
64
65
|
contentType: "skill" | "agent" | "rule";
|
|
65
|
-
strategy: "symlink" | "copy";
|
|
66
66
|
contentHash: string | null;
|
|
67
67
|
isFile: boolean;
|
|
68
68
|
lastSynced: string;
|
|
69
69
|
}, {
|
|
70
70
|
provider: string;
|
|
71
|
+
strategy: "symlink" | "copy";
|
|
71
72
|
canonicalPath: string;
|
|
72
73
|
providerPath: string;
|
|
73
74
|
contentType: "skill" | "agent" | "rule";
|
|
74
|
-
strategy: "symlink" | "copy";
|
|
75
75
|
contentHash: string | null;
|
|
76
76
|
lastSynced: string;
|
|
77
77
|
isFile?: boolean | undefined;
|
|
78
78
|
}>, {
|
|
79
79
|
provider: string;
|
|
80
|
+
strategy: "symlink" | "copy";
|
|
80
81
|
canonicalPath: string;
|
|
81
82
|
providerPath: string;
|
|
82
83
|
contentType: "skill" | "agent" | "rule";
|
|
83
|
-
strategy: "symlink" | "copy";
|
|
84
84
|
contentHash: string | null;
|
|
85
85
|
isFile: boolean;
|
|
86
86
|
lastSynced: string;
|
|
87
87
|
}, {
|
|
88
88
|
provider: string;
|
|
89
|
+
strategy: "symlink" | "copy";
|
|
89
90
|
canonicalPath: string;
|
|
90
91
|
providerPath: string;
|
|
91
92
|
contentType: "skill" | "agent" | "rule";
|
|
92
|
-
strategy: "symlink" | "copy";
|
|
93
93
|
contentHash: string | null;
|
|
94
94
|
lastSynced: string;
|
|
95
95
|
isFile?: boolean | undefined;
|
|
@@ -98,10 +98,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
|
|
|
98
98
|
}, "strip", z.ZodTypeAny, {
|
|
99
99
|
entries: {
|
|
100
100
|
provider: string;
|
|
101
|
+
strategy: "symlink" | "copy";
|
|
101
102
|
canonicalPath: string;
|
|
102
103
|
providerPath: string;
|
|
103
104
|
contentType: "skill" | "agent" | "rule";
|
|
104
|
-
strategy: "symlink" | "copy";
|
|
105
105
|
contentHash: string | null;
|
|
106
106
|
isFile: boolean;
|
|
107
107
|
lastSynced: string;
|
|
@@ -112,10 +112,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
|
|
|
112
112
|
}, {
|
|
113
113
|
entries: {
|
|
114
114
|
provider: string;
|
|
115
|
+
strategy: "symlink" | "copy";
|
|
115
116
|
canonicalPath: string;
|
|
116
117
|
providerPath: string;
|
|
117
118
|
contentType: "skill" | "agent" | "rule";
|
|
118
|
-
strategy: "symlink" | "copy";
|
|
119
119
|
contentHash: string | null;
|
|
120
120
|
lastSynced: string;
|
|
121
121
|
isFile?: boolean | undefined;
|
|
@@ -126,10 +126,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
|
|
|
126
126
|
}>, {
|
|
127
127
|
entries: {
|
|
128
128
|
provider: string;
|
|
129
|
+
strategy: "symlink" | "copy";
|
|
129
130
|
canonicalPath: string;
|
|
130
131
|
providerPath: string;
|
|
131
132
|
contentType: "skill" | "agent" | "rule";
|
|
132
|
-
strategy: "symlink" | "copy";
|
|
133
133
|
contentHash: string | null;
|
|
134
134
|
isFile: boolean;
|
|
135
135
|
lastSynced: string;
|
|
@@ -140,10 +140,10 @@ export declare const ManifestSchema: z.ZodEffects<z.ZodObject<{
|
|
|
140
140
|
}, {
|
|
141
141
|
entries: {
|
|
142
142
|
provider: string;
|
|
143
|
+
strategy: "symlink" | "copy";
|
|
143
144
|
canonicalPath: string;
|
|
144
145
|
providerPath: string;
|
|
145
146
|
contentType: "skill" | "agent" | "rule";
|
|
146
|
-
strategy: "symlink" | "copy";
|
|
147
147
|
contentHash: string | null;
|
|
148
148
|
lastSynced: string;
|
|
149
149
|
isFile?: boolean | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/providers/cursor/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAOnE,eAAO,MAAM,uBAAuB,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/providers/cursor/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAOnE,eAAO,MAAM,uBAAuB,EAAE,WAAW,EAuBhD,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,WAAW,EAc7C,CAAC"}
|
|
@@ -3,8 +3,9 @@ export const CURSOR_PROJECT_MAPPINGS = [
|
|
|
3
3
|
{
|
|
4
4
|
contentType: 'skill',
|
|
5
5
|
canonicalDir: '.agents/skills',
|
|
6
|
-
providerDir: '.
|
|
7
|
-
nativeRead:
|
|
6
|
+
providerDir: '.agents/skills',
|
|
7
|
+
nativeRead: true,
|
|
8
|
+
adoptionSourceDirs: ['.cursor/skills'],
|
|
8
9
|
},
|
|
9
10
|
{
|
|
10
11
|
contentType: 'agent',
|
|
@@ -26,8 +27,9 @@ export const CURSOR_USER_MAPPINGS = [
|
|
|
26
27
|
{
|
|
27
28
|
contentType: 'skill',
|
|
28
29
|
canonicalDir: '.agents/skills',
|
|
29
|
-
providerDir: '.
|
|
30
|
-
nativeRead:
|
|
30
|
+
providerDir: '.agents/skills',
|
|
31
|
+
nativeRead: true,
|
|
32
|
+
adoptionSourceDirs: ['.cursor/skills'],
|
|
31
33
|
},
|
|
32
34
|
{
|
|
33
35
|
contentType: 'agent',
|
|
@@ -4,10 +4,16 @@ export interface PathMapping {
|
|
|
4
4
|
canonicalDir: string;
|
|
5
5
|
providerDir: string;
|
|
6
6
|
nativeRead: boolean;
|
|
7
|
+
adoptionSourceDirs?: string[];
|
|
7
8
|
providerExtension?: string;
|
|
8
9
|
transformCanonical?: (canonicalContent: string, canonicalPath?: string) => string;
|
|
9
10
|
parseToCanonical?: (providerContent: string, providerPath?: string) => string;
|
|
10
11
|
}
|
|
12
|
+
export interface AdoptionSource {
|
|
13
|
+
contentType: ContentType;
|
|
14
|
+
directory: string;
|
|
15
|
+
mapping: PathMapping;
|
|
16
|
+
}
|
|
11
17
|
export interface ProviderAdapter {
|
|
12
18
|
name: string;
|
|
13
19
|
displayName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.types.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/adapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,CACnB,gBAAgB,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,MAAM,KACnB,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/E;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,YAAY,CAAC;IAC9B,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC9C;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC"}
|
|
1
|
+
{"version":3,"file":"adapter.types.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/adapter.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAEtE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,CACnB,gBAAgB,EAAE,MAAM,EACxB,aAAa,CAAC,EAAE,MAAM,KACnB,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/E;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,YAAY,CAAC;IAC9B,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC9C;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SyncConfig } from '../../config/sync-config.js';
|
|
2
2
|
import type { Scope } from '../../shared/types.js';
|
|
3
|
-
import type { PathMapping, ProviderAdapter } from './adapter.types.js';
|
|
3
|
+
import type { AdoptionSource, PathMapping, ProviderAdapter } from './adapter.types.js';
|
|
4
4
|
export declare function getActiveAdapters(adapters: ProviderAdapter[], scopeRoot: string): Promise<ProviderAdapter[]>;
|
|
5
5
|
export interface ConfigAwareAdaptersResult {
|
|
6
6
|
activeAdapters: ProviderAdapter[];
|
|
@@ -9,4 +9,5 @@ export interface ConfigAwareAdaptersResult {
|
|
|
9
9
|
}
|
|
10
10
|
export declare function getConfigAwareAdapters(adapters: ProviderAdapter[], scopeRoot: string, config: SyncConfig): Promise<ConfigAwareAdaptersResult>;
|
|
11
11
|
export declare function getSyncMappings(adapter: ProviderAdapter, scope: Scope): PathMapping[];
|
|
12
|
+
export declare function getAdoptionSources(adapter: ProviderAdapter, scope: Scope): AdoptionSource[];
|
|
12
13
|
//# sourceMappingURL=adapter.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.utils.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/adapter.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"adapter.utils.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/adapter.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAazB,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,EAAE,CAAC,CAW5B;AAED,MAAM,WAAW,yBAAyB;IACxC,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,yBAAyB,CAAC,CAqCpC;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,KAAK,GACX,WAAW,EAAE,CAcf;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,KAAK,GACX,cAAc,EAAE,CAsBlB"}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
function getScopeMappings(adapter, scope) {
|
|
2
|
+
return scope === 'project'
|
|
3
|
+
? adapter.projectMappings
|
|
4
|
+
: scope === 'user'
|
|
5
|
+
? adapter.userMappings
|
|
6
|
+
: [...adapter.projectMappings, ...adapter.userMappings];
|
|
7
|
+
}
|
|
1
8
|
export async function getActiveAdapters(adapters, scopeRoot) {
|
|
2
9
|
const detected = await Promise.all(adapters.map(async (adapter) => ({
|
|
3
10
|
adapter,
|
|
@@ -39,12 +46,7 @@ export async function getConfigAwareAdapters(adapters, scopeRoot, config) {
|
|
|
39
46
|
};
|
|
40
47
|
}
|
|
41
48
|
export function getSyncMappings(adapter, scope) {
|
|
42
|
-
const
|
|
43
|
-
? adapter.projectMappings
|
|
44
|
-
: scope === 'user'
|
|
45
|
-
? adapter.userMappings
|
|
46
|
-
: [...adapter.projectMappings, ...adapter.userMappings];
|
|
47
|
-
const syncMappings = scopeMappings.filter((mapping) => !mapping.nativeRead);
|
|
49
|
+
const syncMappings = getScopeMappings(adapter, scope).filter((mapping) => !mapping.nativeRead);
|
|
48
50
|
const seen = new Set();
|
|
49
51
|
return syncMappings.filter((mapping) => {
|
|
50
52
|
const key = `${mapping.contentType}::${mapping.canonicalDir}::${mapping.providerDir}`;
|
|
@@ -55,3 +57,24 @@ export function getSyncMappings(adapter, scope) {
|
|
|
55
57
|
return true;
|
|
56
58
|
});
|
|
57
59
|
}
|
|
60
|
+
export function getAdoptionSources(adapter, scope) {
|
|
61
|
+
const sources = getScopeMappings(adapter, scope).flatMap((mapping) => {
|
|
62
|
+
const directories = mapping.nativeRead
|
|
63
|
+
? (mapping.adoptionSourceDirs ?? [])
|
|
64
|
+
: [mapping.providerDir];
|
|
65
|
+
return directories.map((directory) => ({
|
|
66
|
+
contentType: mapping.contentType,
|
|
67
|
+
directory,
|
|
68
|
+
mapping,
|
|
69
|
+
}));
|
|
70
|
+
});
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
return sources.filter((source) => {
|
|
73
|
+
const key = `${source.contentType}::${source.directory}`;
|
|
74
|
+
if (seen.has(key)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
seen.add(key);
|
|
78
|
+
return true;
|
|
79
|
+
});
|
|
80
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.76",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"ora": "^9.0.0",
|
|
35
35
|
"yaml": "2.8.2",
|
|
36
36
|
"zod": "^3.25.76",
|
|
37
|
-
"@open-agent-toolkit/control-plane": "0.1.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.1.76"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|