@aexol/opencode-wizard 0.4.0 → 0.4.2
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/dist/graphql-operations.d.ts +3 -1
- package/dist/graphql-operations.js +43 -7
- package/dist/graphql-operations.js.map +1 -1
- package/dist/plugin-tools.d.ts +1 -0
- package/dist/plugin-tools.js +5 -4
- package/dist/plugin-tools.js.map +1 -1
- package/dist/server/client.d.ts +2 -1
- package/dist/server/client.js +31 -14
- package/dist/server/client.js.map +1 -1
- package/dist/server/runtime.js +152 -12
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/types.d.ts +52 -7
- package/dist/server/types.js.map +1 -1
- package/package.json +1 -1
package/dist/server/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { CREATE_OR_UPDATE_SKILL_FROM_MARKDOWN_MUTATION, IMPORT_WIZARD_ARTIFACT_SNAPSHOT_MUTATION, SET_WIZARD_ARTIFACT_PREFERENCE_MUTATION } from '../graphql-operations.js';
|
|
4
|
-
import { createPublishedSkillToolDefinitions, resolveAvailableTools } from '../plugin-tools.js';
|
|
3
|
+
import { BULK_CREATE_SKILL_ASSIGNMENTS_MUTATION, CREATE_OR_UPDATE_SKILL_FROM_MARKDOWN_MUTATION, EDITOR_SKILL_WORKSPACE_ASSIGNMENT_LOOKUP_QUERY, IMPORT_WIZARD_ARTIFACT_SNAPSHOT_MUTATION, SET_WIZARD_ARTIFACT_PREFERENCE_MUTATION } from '../graphql-operations.js';
|
|
4
|
+
import { createPublishedSkillToolDefinitions, hasPrivilegedWizardToolRole, resolveAvailableTools } from '../plugin-tools.js';
|
|
5
5
|
import { resolveStoredAuthState, toAuthState, writeAuthState } from './auth-store.js';
|
|
6
6
|
import { resolveConfig } from './config.js';
|
|
7
7
|
export { resolveConfig } from './config.js';
|
|
@@ -537,7 +537,9 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
537
537
|
requestedDirectoryPath: directoryPath,
|
|
538
538
|
workspaceResolution: toWorkspaceResolutionOutput(workspaceResolution),
|
|
539
539
|
requestedSkillVersionId: item.skillVersion.id,
|
|
540
|
+
requestedArtifactVersionId: item.publishedArtifact.id,
|
|
540
541
|
message: detailResult.result.message,
|
|
542
|
+
graphQlErrors: 'graphQlErrors' in detailResult.result ? detailResult.result.graphQlErrors : undefined,
|
|
541
543
|
fetchedAt: detailResult.result.fetchedAt,
|
|
542
544
|
source: detailResult.result.source
|
|
543
545
|
}, null, 2),
|
|
@@ -1387,6 +1389,127 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1387
1389
|
});
|
|
1388
1390
|
return withWizardArtifactEnvelope(result, artifactKind);
|
|
1389
1391
|
};
|
|
1392
|
+
const createEditorWorkspaceSkillAssignment = async ({
|
|
1393
|
+
skillSlug,
|
|
1394
|
+
skillVersionId,
|
|
1395
|
+
workspaceResolution,
|
|
1396
|
+
signal
|
|
1397
|
+
}) => {
|
|
1398
|
+
if (!skillSlug || !skillVersionId) {
|
|
1399
|
+
return {
|
|
1400
|
+
status: 'skipped',
|
|
1401
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1402
|
+
workspaceSlug: workspaceResolution.workspaceSlug,
|
|
1403
|
+
message: 'Skill creation did not return a skill slug or version id, so no workspace assignment was created.'
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1406
|
+
if (!workspaceResolution.workspaceSlug) {
|
|
1407
|
+
return {
|
|
1408
|
+
status: 'skipped',
|
|
1409
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1410
|
+
workspaceSlug: null,
|
|
1411
|
+
message: 'No resolved workspace slug was available for this directory context.'
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
const lookupResponse = await fetchPublishedSkillsGraphQl({
|
|
1415
|
+
worktree: input.worktree,
|
|
1416
|
+
config,
|
|
1417
|
+
query: EDITOR_SKILL_WORKSPACE_ASSIGNMENT_LOOKUP_QUERY,
|
|
1418
|
+
variables: {
|
|
1419
|
+
skillSlug,
|
|
1420
|
+
workspaceSlug: workspaceResolution.workspaceSlug
|
|
1421
|
+
},
|
|
1422
|
+
signal,
|
|
1423
|
+
operationName: 'editorSkillWorkspaceAssignmentLookup'
|
|
1424
|
+
});
|
|
1425
|
+
if (!lookupResponse.ok) {
|
|
1426
|
+
return {
|
|
1427
|
+
status: 'failed',
|
|
1428
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1429
|
+
workspaceSlug: workspaceResolution.workspaceSlug,
|
|
1430
|
+
message: lookupResponse.result.message
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
const {
|
|
1434
|
+
skill,
|
|
1435
|
+
workspace
|
|
1436
|
+
} = lookupResponse.data.admin;
|
|
1437
|
+
if (!skill) {
|
|
1438
|
+
return {
|
|
1439
|
+
status: 'failed',
|
|
1440
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1441
|
+
workspaceSlug: workspaceResolution.workspaceSlug,
|
|
1442
|
+
message: `Created skill ${skillSlug} could not be resolved for workspace assignment.`
|
|
1443
|
+
};
|
|
1444
|
+
}
|
|
1445
|
+
if (!workspace) {
|
|
1446
|
+
return {
|
|
1447
|
+
status: 'skipped',
|
|
1448
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1449
|
+
workspaceSlug: workspaceResolution.workspaceSlug,
|
|
1450
|
+
message: `Resolved workspace ${workspaceResolution.workspaceSlug} was not found in the backend.`
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
const assignmentResponse = await fetchPublishedSkillsGraphQl({
|
|
1454
|
+
worktree: input.worktree,
|
|
1455
|
+
config,
|
|
1456
|
+
query: BULK_CREATE_SKILL_ASSIGNMENTS_MUTATION,
|
|
1457
|
+
variables: {
|
|
1458
|
+
input: {
|
|
1459
|
+
scopePathAssignments: [{
|
|
1460
|
+
workspaceId: workspace.id,
|
|
1461
|
+
skillId: skill.id,
|
|
1462
|
+
skillVersionId,
|
|
1463
|
+
assignmentType: 'PATH',
|
|
1464
|
+
scopePath: workspaceResolution.directoryPath,
|
|
1465
|
+
includeChildren: true,
|
|
1466
|
+
status: 'ACTIVE',
|
|
1467
|
+
notes: 'Created by opencode-wizard editor skill publishing.'
|
|
1468
|
+
}]
|
|
1469
|
+
}
|
|
1470
|
+
},
|
|
1471
|
+
signal,
|
|
1472
|
+
operationName: 'bulkCreateSkillAssignments'
|
|
1473
|
+
});
|
|
1474
|
+
if (!assignmentResponse.ok) {
|
|
1475
|
+
return {
|
|
1476
|
+
status: 'failed',
|
|
1477
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1478
|
+
workspaceSlug: workspace.slug,
|
|
1479
|
+
workspaceId: workspace.id,
|
|
1480
|
+
message: assignmentResponse.result.message
|
|
1481
|
+
};
|
|
1482
|
+
}
|
|
1483
|
+
const assignmentResult = assignmentResponse.data.admin.bulkCreateSkillAssignments;
|
|
1484
|
+
const [createdAssignment] = assignmentResult.scopePathAssignments;
|
|
1485
|
+
if (createdAssignment) {
|
|
1486
|
+
return {
|
|
1487
|
+
status: 'created',
|
|
1488
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1489
|
+
workspaceSlug: workspace.slug,
|
|
1490
|
+
workspaceId: workspace.id,
|
|
1491
|
+
assignmentId: createdAssignment.id
|
|
1492
|
+
};
|
|
1493
|
+
}
|
|
1494
|
+
const [skippedAssignment] = assignmentResult.skippedScopePathAssignments;
|
|
1495
|
+
if (skippedAssignment) {
|
|
1496
|
+
return {
|
|
1497
|
+
status: 'already_exists',
|
|
1498
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1499
|
+
workspaceSlug: workspace.slug,
|
|
1500
|
+
workspaceId: workspace.id,
|
|
1501
|
+
assignmentId: skippedAssignment.id
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
const conflictMessage = assignmentResult.conflicts.map(conflict => conflict.message).join('; ');
|
|
1505
|
+
return {
|
|
1506
|
+
status: 'failed',
|
|
1507
|
+
directoryPath: workspaceResolution.directoryPath,
|
|
1508
|
+
workspaceSlug: workspace.slug,
|
|
1509
|
+
workspaceId: workspace.id,
|
|
1510
|
+
message: conflictMessage || 'Workspace assignment was not created and no existing matching assignment was returned.'
|
|
1511
|
+
};
|
|
1512
|
+
};
|
|
1390
1513
|
const executeEditorCreateOrUpdateSkillMarkdown = async ({
|
|
1391
1514
|
markdownContent,
|
|
1392
1515
|
context,
|
|
@@ -1394,14 +1517,14 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1394
1517
|
requestedSkillSlug
|
|
1395
1518
|
}) => {
|
|
1396
1519
|
const authState = await resolveStoredAuthState(input.worktree, config);
|
|
1397
|
-
if (!authState || authState.role
|
|
1520
|
+
if (!authState || !hasPrivilegedWizardToolRole(authState.role)) {
|
|
1398
1521
|
return {
|
|
1399
1522
|
output: JSON.stringify({
|
|
1400
1523
|
pluginId: PLUGIN_ID,
|
|
1401
1524
|
status: 'forbidden',
|
|
1402
1525
|
skillSlug: requestedSkillSlug ?? null,
|
|
1403
1526
|
source,
|
|
1404
|
-
message: 'This tool requires EDITOR role. Your current session does not have the required
|
|
1527
|
+
message: 'This tool requires ADMIN or EDITOR role. Your current session does not have the required privileged permission.'
|
|
1405
1528
|
}, null, 2),
|
|
1406
1529
|
metadata: {
|
|
1407
1530
|
status: 'forbidden',
|
|
@@ -1413,7 +1536,11 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1413
1536
|
throw new Error('Editor skill create/update requires non-empty markdownContent.');
|
|
1414
1537
|
}
|
|
1415
1538
|
const requestedDirectory = normalizeDirectoryArg(context.directory, undefined);
|
|
1416
|
-
const
|
|
1539
|
+
const workspaceResolution = await resolveWorkspace({
|
|
1540
|
+
config,
|
|
1541
|
+
directory: requestedDirectory
|
|
1542
|
+
});
|
|
1543
|
+
const directoryPath = workspaceResolution.directoryPath;
|
|
1417
1544
|
lastInteractiveDirectoryPath = directoryPath;
|
|
1418
1545
|
const response = await fetchPublishedSkillsGraphQl({
|
|
1419
1546
|
worktree: input.worktree,
|
|
@@ -1441,6 +1568,15 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1441
1568
|
};
|
|
1442
1569
|
}
|
|
1443
1570
|
const payload = response.data.admin.createOrUpdateSkillFromMarkdown;
|
|
1571
|
+
const workspaceAssignment = payload.success ? await createEditorWorkspaceSkillAssignment({
|
|
1572
|
+
skillSlug: payload.skillSlug,
|
|
1573
|
+
skillVersionId: payload.skillVersionId,
|
|
1574
|
+
workspaceResolution,
|
|
1575
|
+
signal: context.abort
|
|
1576
|
+
}) : null;
|
|
1577
|
+
if (payload.success) {
|
|
1578
|
+
clearPublishedSkillState();
|
|
1579
|
+
}
|
|
1444
1580
|
await scheduleInteractivePresenceStart();
|
|
1445
1581
|
return {
|
|
1446
1582
|
output: JSON.stringify({
|
|
@@ -1451,16 +1587,20 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1451
1587
|
skillVersionId: payload.skillVersionId,
|
|
1452
1588
|
artifactSlug: payload.artifactSlug,
|
|
1453
1589
|
artifactVersionId: payload.artifactVersionId,
|
|
1590
|
+
workspaceAssignment,
|
|
1454
1591
|
requestedDirectoryPath: directoryPath,
|
|
1592
|
+
workspaceResolution: toWorkspaceResolutionOutput(workspaceResolution),
|
|
1455
1593
|
errors: payload.errors,
|
|
1456
|
-
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.'
|
|
1594
|
+
message: source === 'direct_markdown' ? 'Skill markdown was sent directly to the backend; no local seed file was required. Workspace assignments are created when a backend workspace resolves for the directory.' : 'Local seed SKILL.md was published through the backend skill markdown mutation. Workspace assignments are created when a backend workspace resolves for the directory.'
|
|
1457
1595
|
}, null, 2),
|
|
1458
1596
|
metadata: {
|
|
1459
1597
|
status: payload.success ? 'created_or_updated' : 'create_or_update_failed',
|
|
1460
1598
|
skillSlug: payload.skillSlug,
|
|
1461
1599
|
skillVersionId: payload.skillVersionId ?? '',
|
|
1462
1600
|
source,
|
|
1463
|
-
directoryPath
|
|
1601
|
+
directoryPath,
|
|
1602
|
+
workspaceAssignmentStatus: workspaceAssignment?.status ?? '',
|
|
1603
|
+
workspaceAssignmentId: workspaceAssignment?.assignmentId ?? ''
|
|
1464
1604
|
}
|
|
1465
1605
|
};
|
|
1466
1606
|
};
|
|
@@ -1489,14 +1629,14 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1489
1629
|
throw new Error('Editor publish requires a non-empty skill slug.');
|
|
1490
1630
|
}
|
|
1491
1631
|
const authState = await resolveStoredAuthState(input.worktree, config);
|
|
1492
|
-
if (!authState || authState.role
|
|
1632
|
+
if (!authState || !hasPrivilegedWizardToolRole(authState.role)) {
|
|
1493
1633
|
return {
|
|
1494
1634
|
output: JSON.stringify({
|
|
1495
1635
|
pluginId: PLUGIN_ID,
|
|
1496
1636
|
status: 'forbidden',
|
|
1497
1637
|
skillSlug: requestedSkillSlug,
|
|
1498
1638
|
source: 'seed_file',
|
|
1499
|
-
message: 'This tool requires EDITOR role. Your current session does not have the required
|
|
1639
|
+
message: 'This tool requires ADMIN or EDITOR role. Your current session does not have the required privileged permission.'
|
|
1500
1640
|
}, null, 2),
|
|
1501
1641
|
metadata: {
|
|
1502
1642
|
status: 'forbidden',
|
|
@@ -1554,14 +1694,14 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1554
1694
|
slug: args.slug,
|
|
1555
1695
|
skill: args.skill
|
|
1556
1696
|
});
|
|
1557
|
-
if (!authState || authState.role
|
|
1697
|
+
if (!authState || !hasPrivilegedWizardToolRole(authState.role)) {
|
|
1558
1698
|
return {
|
|
1559
1699
|
output: JSON.stringify({
|
|
1560
1700
|
pluginId: PLUGIN_ID,
|
|
1561
1701
|
status: 'forbidden',
|
|
1562
1702
|
artifactKind: importPlan.artifactKind,
|
|
1563
1703
|
source: importPlan.source,
|
|
1564
|
-
message: 'This tool requires EDITOR role. Your current session does not have the required
|
|
1704
|
+
message: 'This tool requires ADMIN or EDITOR role. Your current session does not have the required privileged permission.'
|
|
1565
1705
|
}, null, 2),
|
|
1566
1706
|
metadata: {
|
|
1567
1707
|
status: 'forbidden',
|
|
@@ -1632,7 +1772,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1632
1772
|
}
|
|
1633
1773
|
};
|
|
1634
1774
|
}
|
|
1635
|
-
const payload = response.data.importWizardArtifactSnapshot;
|
|
1775
|
+
const payload = response.data.admin.importWizardArtifactSnapshot;
|
|
1636
1776
|
await scheduleInteractivePresenceStart();
|
|
1637
1777
|
return {
|
|
1638
1778
|
output: JSON.stringify({
|