@aexol/opencode-wizard 0.3.7 → 0.3.9
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/README.md +14 -4
- package/dist/graphql-operations.d.ts +4 -4
- package/dist/graphql-operations.js +13 -5
- package/dist/graphql-operations.js.map +1 -1
- package/dist/plugin-tools.d.ts +6 -0
- package/dist/plugin-tools.js +11 -1
- package/dist/plugin-tools.js.map +1 -1
- package/dist/published-skills-transform.d.ts +10 -2
- package/dist/published-skills-transform.js +12 -3
- package/dist/published-skills-transform.js.map +1 -1
- package/dist/server/runtime.js +227 -61
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/types.d.ts +22 -9
- package/dist/server/types.js.map +1 -1
- package/dist/tui/components/status-content.js +44 -2
- package/dist/tui/components/status-content.js.map +1 -1
- package/dist/tui/plugin.js +97 -0
- package/dist/tui/plugin.js.map +1 -1
- package/dist/tui/skill-helpers.d.ts +6 -0
- package/dist/tui/skill-helpers.js +46 -0
- package/dist/tui/skill-helpers.js.map +1 -1
- package/dist/tui/types.d.ts +22 -0
- package/dist/tui/types.js.map +1 -1
- package/package.json +1 -1
package/dist/server/runtime.js
CHANGED
|
@@ -21,9 +21,34 @@ export { buildSystemNote, resolvePluginStatusSnapshot, toPluginAuthStateSummary,
|
|
|
21
21
|
const importOpencodePluginModule = new Function('specifier', 'return import(specifier)');
|
|
22
22
|
export { resolvePluginStatusSnapshotWithAuthBootstrap } from './auth-bootstrap.js';
|
|
23
23
|
export { setPublishedSkillIgnored, setPublishedSkillInstalled } from './preferences.js';
|
|
24
|
-
const getDetailCacheKey = (catalogCacheKey, skillVersionId) => {
|
|
25
|
-
return JSON.stringify([catalogCacheKey, skillVersionId]);
|
|
24
|
+
const getDetailCacheKey = (catalogCacheKey, skillVersionId, revision) => {
|
|
25
|
+
return JSON.stringify([catalogCacheKey, skillVersionId, revision]);
|
|
26
26
|
};
|
|
27
|
+
const getPublishedSkillRevision = item => {
|
|
28
|
+
return item.publishedArtifact.revision ?? `${item.publishedArtifact.checksum}:${item.publishedArtifact.updatedAtCursor ?? item.publishedArtifact.publishedAt}`;
|
|
29
|
+
};
|
|
30
|
+
const getCatalogCursor = (items, catalogItems) => {
|
|
31
|
+
return [...items.map(getPublishedSkillRevision), ...catalogItems.map(item => getPublishedSkillRevision({
|
|
32
|
+
...item,
|
|
33
|
+
assignmentSource: 'CATALOG',
|
|
34
|
+
assignmentType: 'PATH',
|
|
35
|
+
scopePath: '',
|
|
36
|
+
includeChildren: true
|
|
37
|
+
}))].sort().join('|');
|
|
38
|
+
};
|
|
39
|
+
const getWizardArtifactRevision = item => {
|
|
40
|
+
return item.artifactVersion.revision ?? `${item.artifactVersion.checksum}:${item.artifactVersion.updatedAtCursor ?? item.artifactVersion.publishedAt ?? 'unpublished'}`;
|
|
41
|
+
};
|
|
42
|
+
const getWizardArtifactCatalogCursor = (items, catalogItems) => {
|
|
43
|
+
return [...items.map(getWizardArtifactRevision), ...catalogItems.map(getWizardArtifactRevision)].sort().join('|');
|
|
44
|
+
};
|
|
45
|
+
const toWizardArtifactCatalogCursorItems = items => items.map(item => ({
|
|
46
|
+
...item,
|
|
47
|
+
assignmentSource: 'CATALOG',
|
|
48
|
+
assignmentType: 'PATH',
|
|
49
|
+
scopePath: '',
|
|
50
|
+
includeChildren: true
|
|
51
|
+
}));
|
|
27
52
|
const getDetailInflightKey = (catalogCacheKey, skillVersionId, purpose) => {
|
|
28
53
|
return JSON.stringify([catalogCacheKey, skillVersionId, purpose]);
|
|
29
54
|
};
|
|
@@ -102,7 +127,9 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
102
127
|
const cache = new Map();
|
|
103
128
|
const catalogInflight = new Map();
|
|
104
129
|
const detailCache = new Map();
|
|
130
|
+
const wizardArtifactDetailCache = new Map();
|
|
105
131
|
const detailInflight = new Map();
|
|
132
|
+
const wizardArtifactDetailInflight = new Map();
|
|
106
133
|
const initialAuthState = await resolveStoredAuthState(input.worktree, config);
|
|
107
134
|
const loginBootstrap = {
|
|
108
135
|
promise: null,
|
|
@@ -197,7 +224,9 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
197
224
|
cache.clear();
|
|
198
225
|
catalogInflight.clear();
|
|
199
226
|
detailCache.clear();
|
|
227
|
+
wizardArtifactDetailCache.clear();
|
|
200
228
|
detailInflight.clear();
|
|
229
|
+
wizardArtifactDetailInflight.clear();
|
|
201
230
|
};
|
|
202
231
|
const persistAuthState = async session => {
|
|
203
232
|
const authState = toAuthState(session);
|
|
@@ -337,7 +366,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
337
366
|
});
|
|
338
367
|
cache.set(cacheKey, {
|
|
339
368
|
result: fetchResult,
|
|
340
|
-
expiresAt: Date.now() + CACHE_TTL_MS
|
|
369
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
370
|
+
cursor: fetchResult.ok ? getCatalogCursor(fetchResult.payload.skills, fetchResult.payload.catalogSkills) : fetchResult.fetchedAt
|
|
341
371
|
});
|
|
342
372
|
return {
|
|
343
373
|
directoryPath,
|
|
@@ -362,7 +392,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
362
392
|
const directoryPath = workspaceResolution.directoryPath;
|
|
363
393
|
const preferenceContext = await resolvePublishedSkillPreferenceCacheContext(config);
|
|
364
394
|
const catalogCacheKey = getCatalogCacheKey(workspaceResolution, preferenceContext);
|
|
365
|
-
const
|
|
395
|
+
const itemRevision = getPublishedSkillRevision(item);
|
|
396
|
+
const cacheKey = getDetailCacheKey(catalogCacheKey, item.skillVersion.id, itemRevision);
|
|
366
397
|
const inflightKey = getDetailInflightKey(catalogCacheKey, item.skillVersion.id, purpose);
|
|
367
398
|
const cached = detailCache.get(cacheKey);
|
|
368
399
|
if (useCache && cached && cached.expiresAt > Date.now()) {
|
|
@@ -412,7 +443,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
412
443
|
}
|
|
413
444
|
detailCache.set(cacheKey, {
|
|
414
445
|
artifact: detailResult.artifact,
|
|
415
|
-
expiresAt: Date.now() + CACHE_TTL_MS
|
|
446
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
447
|
+
revision: itemRevision
|
|
416
448
|
});
|
|
417
449
|
return {
|
|
418
450
|
ok: true,
|
|
@@ -429,6 +461,62 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
429
461
|
detailInflight.delete(inflightKey);
|
|
430
462
|
}
|
|
431
463
|
};
|
|
464
|
+
const loadWizardArtifactDetail = async ({
|
|
465
|
+
workspaceResolution,
|
|
466
|
+
item,
|
|
467
|
+
signal,
|
|
468
|
+
useCache,
|
|
469
|
+
purpose,
|
|
470
|
+
artifactKind
|
|
471
|
+
}) => {
|
|
472
|
+
const preferenceContext = await resolvePublishedSkillPreferenceCacheContext(config);
|
|
473
|
+
const catalogCacheKey = getCatalogCacheKey(workspaceResolution, preferenceContext);
|
|
474
|
+
const itemRevision = getWizardArtifactRevision(item);
|
|
475
|
+
const cacheKey = getDetailCacheKey(catalogCacheKey, item.artifactVersion.id, itemRevision);
|
|
476
|
+
const inflightKey = JSON.stringify([catalogCacheKey, item.artifactVersion.id, itemRevision, purpose]);
|
|
477
|
+
const cached = wizardArtifactDetailCache.get(cacheKey);
|
|
478
|
+
if (useCache && cached && cached.expiresAt > Date.now()) {
|
|
479
|
+
return {
|
|
480
|
+
ok: true,
|
|
481
|
+
artifact: cached.artifact
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
const inflight = wizardArtifactDetailInflight.get(inflightKey);
|
|
485
|
+
if (useCache && inflight) {
|
|
486
|
+
const inflightResult = await inflight;
|
|
487
|
+
if (!inflightResult.ok) return inflightResult;
|
|
488
|
+
return {
|
|
489
|
+
ok: true,
|
|
490
|
+
artifact: inflightResult.artifact
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
const requestPromise = fetchWizardArtifactDetail({
|
|
494
|
+
worktree: input.worktree,
|
|
495
|
+
config,
|
|
496
|
+
resolution: workspaceResolution,
|
|
497
|
+
artifactKind,
|
|
498
|
+
artifactVersionId: item.artifactVersion.id,
|
|
499
|
+
signal,
|
|
500
|
+
onAuthStateChanged: clearPublishedSkillState,
|
|
501
|
+
purpose
|
|
502
|
+
});
|
|
503
|
+
wizardArtifactDetailInflight.set(inflightKey, requestPromise);
|
|
504
|
+
try {
|
|
505
|
+
const detailResult = await requestPromise;
|
|
506
|
+
if (!detailResult.ok) return detailResult;
|
|
507
|
+
wizardArtifactDetailCache.set(cacheKey, {
|
|
508
|
+
artifact: detailResult.artifact,
|
|
509
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
510
|
+
revision: itemRevision
|
|
511
|
+
});
|
|
512
|
+
return {
|
|
513
|
+
ok: true,
|
|
514
|
+
artifact: detailResult.artifact
|
|
515
|
+
};
|
|
516
|
+
} finally {
|
|
517
|
+
wizardArtifactDetailInflight.delete(inflightKey);
|
|
518
|
+
}
|
|
519
|
+
};
|
|
432
520
|
const executePublishedSkillsFetchTool = async ({
|
|
433
521
|
args,
|
|
434
522
|
context
|
|
@@ -520,13 +608,15 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
520
608
|
},
|
|
521
609
|
fetchedAt: filteredPublishedSkillsResult.fetchResult.fetchedAt,
|
|
522
610
|
source: filteredPublishedSkillsResult.fetchResult.source,
|
|
611
|
+
cacheCursor: getCatalogCursor(filteredPublishedSkillsResult.fetchResult.payload.skills, filteredPublishedSkillsResult.fetchResult.payload.catalogSkills),
|
|
523
612
|
cacheTtlMs: CACHE_TTL_MS,
|
|
524
|
-
message: args.refresh ? 'Catalog discovery refreshed from the backend. Provide `skill` for one identifier or prefer `skills` for comma/newline-separated multiple identifiers to fetch markdown bodies/details.' : 'Catalog discovery only. Cached results
|
|
613
|
+
message: args.refresh ? 'Catalog discovery refreshed from the backend. Provide `skill` for one identifier or prefer `skills` for comma/newline-separated multiple identifiers to fetch markdown bodies/details.' : 'Catalog discovery only. Cached results include deterministic revision cursors; pass `refresh: true` to force a backend refresh immediately. Provide `skill` for one identifier or prefer `skills` for comma/newline-separated multiple identifiers to fetch markdown bodies/details.'
|
|
525
614
|
}, null, 2),
|
|
526
615
|
metadata: {
|
|
527
616
|
status: 'ready',
|
|
528
617
|
...toWorkspaceResolutionMetadata(filteredPublishedSkillsResult.workspaceResolution),
|
|
529
618
|
source: filteredPublishedSkillsResult.fetchResult.source,
|
|
619
|
+
cacheCursor: getCatalogCursor(filteredPublishedSkillsResult.fetchResult.payload.skills, filteredPublishedSkillsResult.fetchResult.payload.catalogSkills),
|
|
530
620
|
publishedSkillCount: catalog.publishedSkillCount.toString(),
|
|
531
621
|
globalAssignmentCount: catalog.assignmentCounts.global.toString(),
|
|
532
622
|
projectAssignmentCount: catalog.assignmentCounts.project.toString(),
|
|
@@ -696,6 +786,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
696
786
|
pluginId: PLUGIN_ID,
|
|
697
787
|
availableTools: resolveAvailableTools(authState?.role ?? null)
|
|
698
788
|
});
|
|
789
|
+
const cacheCursor = getWizardArtifactCatalogCursor(fetchResult.payload.artifacts, toWizardArtifactCatalogCursorItems(fetchResult.payload.catalogArtifacts));
|
|
699
790
|
return {
|
|
700
791
|
output: JSON.stringify({
|
|
701
792
|
...catalog,
|
|
@@ -704,14 +795,18 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
704
795
|
workspaceResolution: toWorkspaceResolutionOutput(workspaceResolution),
|
|
705
796
|
fetchedAt: fetchResult.fetchedAt,
|
|
706
797
|
source: fetchResult.source,
|
|
707
|
-
|
|
798
|
+
cacheCursor,
|
|
799
|
+
cacheTtlMs: CACHE_TTL_MS,
|
|
800
|
+
message: 'Generic artifact catalog discovery only. Full bodies/files require opencode_wizard_artifact_fetch with artifactKind and artifact identifiers.'
|
|
708
801
|
}, null, 2),
|
|
709
802
|
metadata: {
|
|
710
803
|
status: 'ready',
|
|
711
804
|
artifactKind,
|
|
712
805
|
artifactCount: catalog.artifactCount.toString(),
|
|
713
806
|
...toWorkspaceResolutionMetadata(workspaceResolution),
|
|
714
|
-
source: fetchResult.source
|
|
807
|
+
source: fetchResult.source,
|
|
808
|
+
cacheCursor,
|
|
809
|
+
cacheTtlMs: CACHE_TTL_MS.toString()
|
|
715
810
|
}
|
|
716
811
|
};
|
|
717
812
|
}
|
|
@@ -775,6 +870,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
775
870
|
pluginId: PLUGIN_ID,
|
|
776
871
|
availableTools: resolveAvailableTools(authState?.role ?? null)
|
|
777
872
|
});
|
|
873
|
+
const cacheCursor = getWizardArtifactCatalogCursor(fetchResult.payload.artifacts, toWizardArtifactCatalogCursorItems(fetchResult.payload.catalogArtifacts));
|
|
778
874
|
return {
|
|
779
875
|
output: JSON.stringify({
|
|
780
876
|
...catalog,
|
|
@@ -783,11 +879,15 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
783
879
|
workspaceResolution: toWorkspaceResolutionOutput(workspaceResolution),
|
|
784
880
|
fetchedAt: fetchResult.fetchedAt,
|
|
785
881
|
source: fetchResult.source,
|
|
786
|
-
|
|
882
|
+
cacheCursor,
|
|
883
|
+
cacheTtlMs: CACHE_TTL_MS,
|
|
884
|
+
message: 'Provide artifact or artifacts to fetch artifact body/files.'
|
|
787
885
|
}, null, 2),
|
|
788
886
|
metadata: {
|
|
789
887
|
status: 'ready',
|
|
790
888
|
artifactKind,
|
|
889
|
+
cacheCursor,
|
|
890
|
+
cacheTtlMs: CACHE_TTL_MS.toString(),
|
|
791
891
|
...toWorkspaceResolutionMetadata(workspaceResolution)
|
|
792
892
|
}
|
|
793
893
|
};
|
|
@@ -811,15 +911,13 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
811
911
|
}
|
|
812
912
|
};
|
|
813
913
|
}
|
|
814
|
-
const detailResults = await Promise.all(selection.selectedItems.map(item =>
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
resolution: workspaceResolution,
|
|
818
|
-
artifactKind,
|
|
819
|
-
artifactVersionId: item.artifactVersion.id,
|
|
914
|
+
const detailResults = await Promise.all(selection.selectedItems.map(item => loadWizardArtifactDetail({
|
|
915
|
+
workspaceResolution,
|
|
916
|
+
item,
|
|
820
917
|
signal: context.abort,
|
|
821
|
-
|
|
822
|
-
purpose: 'TOOL_FETCH'
|
|
918
|
+
useCache: !args.refresh,
|
|
919
|
+
purpose: 'TOOL_FETCH',
|
|
920
|
+
artifactKind
|
|
823
921
|
})));
|
|
824
922
|
const failedDetail = detailResults.find(result => !result.ok);
|
|
825
923
|
if (failedDetail && !failedDetail.ok) {
|
|
@@ -849,6 +947,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
849
947
|
artifactVersion: result.artifact
|
|
850
948
|
});
|
|
851
949
|
});
|
|
950
|
+
const cacheCursor = getWizardArtifactCatalogCursor(selection.selectedItems, toWizardArtifactCatalogCursorItems(fetchResult.payload.catalogArtifacts));
|
|
852
951
|
return {
|
|
853
952
|
output: JSON.stringify({
|
|
854
953
|
pluginId: PLUGIN_ID,
|
|
@@ -859,6 +958,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
859
958
|
workspace: fetchResult.payload.workspace,
|
|
860
959
|
fetchedAt: fetchResult.fetchedAt,
|
|
861
960
|
source: fetchResult.source,
|
|
961
|
+
cacheCursor,
|
|
962
|
+
cacheTtlMs: CACHE_TTL_MS,
|
|
862
963
|
requestedArtifacts,
|
|
863
964
|
missingArtifacts: selection.missingIdentifiers,
|
|
864
965
|
artifacts: details
|
|
@@ -867,6 +968,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
867
968
|
status: selection.missingIdentifiers.length > 0 ? 'partial' : 'ready',
|
|
868
969
|
artifactKind,
|
|
869
970
|
matchedCount: details.length.toString(),
|
|
971
|
+
cacheTtlMs: CACHE_TTL_MS.toString(),
|
|
870
972
|
...toWorkspaceResolutionMetadata(workspaceResolution)
|
|
871
973
|
}
|
|
872
974
|
};
|
|
@@ -1139,6 +1241,99 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1139
1241
|
});
|
|
1140
1242
|
return withWizardArtifactEnvelope(result, artifactKind);
|
|
1141
1243
|
};
|
|
1244
|
+
const executeEditorCreateOrUpdateSkillMarkdown = async ({
|
|
1245
|
+
markdownContent,
|
|
1246
|
+
context,
|
|
1247
|
+
source,
|
|
1248
|
+
requestedSkillSlug
|
|
1249
|
+
}) => {
|
|
1250
|
+
const authState = await resolveStoredAuthState(input.worktree, config);
|
|
1251
|
+
if (!authState || authState.role !== 'EDITOR') {
|
|
1252
|
+
return {
|
|
1253
|
+
output: JSON.stringify({
|
|
1254
|
+
pluginId: PLUGIN_ID,
|
|
1255
|
+
status: 'forbidden',
|
|
1256
|
+
skillSlug: requestedSkillSlug ?? null,
|
|
1257
|
+
source,
|
|
1258
|
+
message: 'This tool requires EDITOR role. Your current session does not have the required editor permission.'
|
|
1259
|
+
}, null, 2),
|
|
1260
|
+
metadata: {
|
|
1261
|
+
status: 'forbidden',
|
|
1262
|
+
role: authState?.role ?? 'none'
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
if (!markdownContent.trim()) {
|
|
1267
|
+
throw new Error('Editor skill create/update requires non-empty markdownContent.');
|
|
1268
|
+
}
|
|
1269
|
+
const requestedDirectory = normalizeDirectoryArg(context.directory, undefined);
|
|
1270
|
+
const directoryPath = normalizeRepositoryPath(workspacePath, requestedDirectory);
|
|
1271
|
+
lastInteractiveDirectoryPath = directoryPath;
|
|
1272
|
+
const response = await fetchPublishedSkillsGraphQl({
|
|
1273
|
+
worktree: input.worktree,
|
|
1274
|
+
config,
|
|
1275
|
+
query: CREATE_OR_UPDATE_SKILL_FROM_MARKDOWN_MUTATION,
|
|
1276
|
+
variables: {
|
|
1277
|
+
markdownContent
|
|
1278
|
+
},
|
|
1279
|
+
signal: context.abort
|
|
1280
|
+
});
|
|
1281
|
+
if (!response.ok) {
|
|
1282
|
+
return {
|
|
1283
|
+
output: JSON.stringify({
|
|
1284
|
+
pluginId: PLUGIN_ID,
|
|
1285
|
+
status: 'request_failed',
|
|
1286
|
+
skillSlug: requestedSkillSlug ?? null,
|
|
1287
|
+
source,
|
|
1288
|
+
message: response.result.message
|
|
1289
|
+
}, null, 2),
|
|
1290
|
+
metadata: {
|
|
1291
|
+
status: 'request_failed',
|
|
1292
|
+
skillSlug: requestedSkillSlug ?? '',
|
|
1293
|
+
directoryPath
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
const payload = response.data.admin.createOrUpdateSkillFromMarkdown;
|
|
1298
|
+
await scheduleInteractivePresenceStart();
|
|
1299
|
+
return {
|
|
1300
|
+
output: JSON.stringify({
|
|
1301
|
+
pluginId: PLUGIN_ID,
|
|
1302
|
+
status: payload.success ? 'created_or_updated' : 'create_or_update_failed',
|
|
1303
|
+
source,
|
|
1304
|
+
skillSlug: payload.skillSlug,
|
|
1305
|
+
skillVersionId: payload.skillVersionId,
|
|
1306
|
+
artifactSlug: payload.artifactSlug,
|
|
1307
|
+
artifactVersionId: payload.artifactVersionId,
|
|
1308
|
+
requestedDirectoryPath: directoryPath,
|
|
1309
|
+
errors: payload.errors,
|
|
1310
|
+
message: source === 'direct_markdown' ? 'Skill markdown was sent directly to the backend; no local seed file was required.' : 'Local seed SKILL.md was published through the backend skill markdown mutation.'
|
|
1311
|
+
}, null, 2),
|
|
1312
|
+
metadata: {
|
|
1313
|
+
status: payload.success ? 'created_or_updated' : 'create_or_update_failed',
|
|
1314
|
+
skillSlug: payload.skillSlug,
|
|
1315
|
+
skillVersionId: payload.skillVersionId ?? '',
|
|
1316
|
+
source,
|
|
1317
|
+
directoryPath
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
};
|
|
1321
|
+
const executeEditorCreateOrUpdateSkillTool = async ({
|
|
1322
|
+
args,
|
|
1323
|
+
context
|
|
1324
|
+
}) => {
|
|
1325
|
+
const requestedDirectory = normalizeDirectoryArg(context.directory, args.directory);
|
|
1326
|
+
const directoryPath = normalizeRepositoryPath(workspacePath, requestedDirectory);
|
|
1327
|
+
lastInteractiveDirectoryPath = directoryPath;
|
|
1328
|
+
return executeEditorCreateOrUpdateSkillMarkdown({
|
|
1329
|
+
markdownContent: args.markdownContent,
|
|
1330
|
+
context: {
|
|
1331
|
+
...context,
|
|
1332
|
+
directory: requestedDirectory
|
|
1333
|
+
},
|
|
1334
|
+
source: 'direct_markdown'
|
|
1335
|
+
});
|
|
1336
|
+
};
|
|
1142
1337
|
const executeEditorPublishSkillTool = async ({
|
|
1143
1338
|
args,
|
|
1144
1339
|
context
|
|
@@ -1154,6 +1349,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1154
1349
|
pluginId: PLUGIN_ID,
|
|
1155
1350
|
status: 'forbidden',
|
|
1156
1351
|
skillSlug: requestedSkillSlug,
|
|
1352
|
+
source: 'seed_file',
|
|
1157
1353
|
message: 'This tool requires EDITOR role. Your current session does not have the required editor permission.'
|
|
1158
1354
|
}, null, 2),
|
|
1159
1355
|
metadata: {
|
|
@@ -1191,47 +1387,15 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1191
1387
|
}
|
|
1192
1388
|
};
|
|
1193
1389
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
markdownContent
|
|
1390
|
+
return executeEditorCreateOrUpdateSkillMarkdown({
|
|
1391
|
+
markdownContent,
|
|
1392
|
+
context: {
|
|
1393
|
+
...context,
|
|
1394
|
+
directory: requestedDirectory
|
|
1200
1395
|
},
|
|
1201
|
-
|
|
1396
|
+
source: 'seed_file',
|
|
1397
|
+
requestedSkillSlug
|
|
1202
1398
|
});
|
|
1203
|
-
if (!response.ok) {
|
|
1204
|
-
return {
|
|
1205
|
-
output: JSON.stringify({
|
|
1206
|
-
pluginId: PLUGIN_ID,
|
|
1207
|
-
status: 'request_failed',
|
|
1208
|
-
skillSlug: requestedSkillSlug,
|
|
1209
|
-
message: response.result.message
|
|
1210
|
-
}, null, 2),
|
|
1211
|
-
metadata: {
|
|
1212
|
-
status: 'request_failed',
|
|
1213
|
-
skillSlug: requestedSkillSlug,
|
|
1214
|
-
directoryPath
|
|
1215
|
-
}
|
|
1216
|
-
};
|
|
1217
|
-
}
|
|
1218
|
-
const payload = response.data.createOrUpdateSkillFromMarkdown;
|
|
1219
|
-
await scheduleInteractivePresenceStart();
|
|
1220
|
-
return {
|
|
1221
|
-
output: JSON.stringify({
|
|
1222
|
-
pluginId: PLUGIN_ID,
|
|
1223
|
-
status: payload.success ? 'published' : 'publish_failed',
|
|
1224
|
-
skillSlug: payload.skillSlug,
|
|
1225
|
-
skillVersionId: payload.skillVersionId,
|
|
1226
|
-
errors: payload.errors
|
|
1227
|
-
}, null, 2),
|
|
1228
|
-
metadata: {
|
|
1229
|
-
status: payload.success ? 'published' : 'publish_failed',
|
|
1230
|
-
skillSlug: payload.skillSlug,
|
|
1231
|
-
skillVersionId: payload.skillVersionId ?? '',
|
|
1232
|
-
directoryPath
|
|
1233
|
-
}
|
|
1234
|
-
};
|
|
1235
1399
|
};
|
|
1236
1400
|
const executeWizardArtifactImportTool = async ({
|
|
1237
1401
|
args,
|
|
@@ -1348,8 +1512,6 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1348
1512
|
}
|
|
1349
1513
|
};
|
|
1350
1514
|
};
|
|
1351
|
-
const role = initialAuthState?.role ?? null;
|
|
1352
|
-
const isEditor = role === 'EDITOR';
|
|
1353
1515
|
const {
|
|
1354
1516
|
sharedTools,
|
|
1355
1517
|
editorOnlyTools
|
|
@@ -1378,6 +1540,10 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1378
1540
|
args,
|
|
1379
1541
|
context
|
|
1380
1542
|
}),
|
|
1543
|
+
createOrUpdateEditorSkill: (args, context) => executeEditorCreateOrUpdateSkillTool({
|
|
1544
|
+
args,
|
|
1545
|
+
context
|
|
1546
|
+
}),
|
|
1381
1547
|
publishEditorSkill: (args, context) => executeEditorPublishSkillTool({
|
|
1382
1548
|
args,
|
|
1383
1549
|
context
|
|
@@ -1388,10 +1554,10 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1388
1554
|
})
|
|
1389
1555
|
});
|
|
1390
1556
|
return {
|
|
1391
|
-
tool: {
|
|
1557
|
+
tool: initialAuthState?.role === 'EDITOR' ? {
|
|
1392
1558
|
...sharedTools,
|
|
1393
|
-
...
|
|
1394
|
-
},
|
|
1559
|
+
...editorOnlyTools
|
|
1560
|
+
} : sharedTools,
|
|
1395
1561
|
'experimental.chat.system.transform': async (_hookInput, output) => {
|
|
1396
1562
|
let publishedSkillsResult = await loadPublishedSkillCatalog({
|
|
1397
1563
|
directory: input.directory,
|