@aexol/opencode-wizard 0.3.9 → 0.3.10
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 +3 -3
- package/dist/published-skills-system-note.d.ts +1 -1
- package/dist/published-skills-system-note.js +1 -17
- package/dist/published-skills-system-note.js.map +1 -1
- package/dist/server/runtime.js +9 -12
- package/dist/server/runtime.js.map +1 -1
- package/dist/server/status.d.ts +3 -2
- package/dist/server/status.js +9 -7
- package/dist/server/status.js.map +1 -1
- package/dist/tui/components/status-content.js +32 -45
- package/dist/tui/components/status-content.js.map +1 -1
- package/dist/tui/formatting.js +3 -4
- package/dist/tui/formatting.js.map +1 -1
- package/dist/tui/plugin.js +1 -1
- package/dist/tui/plugin.js.map +1 -1
- package/dist/tui/skill-helpers.d.ts +1 -0
- package/dist/tui/skill-helpers.js +10 -14
- package/dist/tui/skill-helpers.js.map +1 -1
- package/dist/tui/slots.js +2 -12
- package/dist/tui/slots.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- `./tui` → `dist/tui.js`
|
|
10
10
|
- no generated runtime skill directory is published; the plugin stays fetch-only at runtime
|
|
11
11
|
- native OpenCode `skills.urls` is treated as a public/static registry complement, not as the private wizard delivery authority
|
|
12
|
-
- the TUI is a compact
|
|
12
|
+
- the TUI is a compact status panel: it shows backend URL, signed-in identity, role, and catalog counts while mutations still run through guarded tools
|
|
13
13
|
|
|
14
14
|
## Local development
|
|
15
15
|
|
|
@@ -46,7 +46,7 @@ Use `skills.urls` only for public registries that are intentionally cacheable by
|
|
|
46
46
|
|
|
47
47
|
## Catalog discovery and auth bootstrap
|
|
48
48
|
|
|
49
|
-
Catalog discovery uses the backend-issued plugin session token stored at `~/.config/opencode/opencode-wizard.json` (`auth` field); the plugin does not persist or send Microsoft/Entra tokens to GraphQL. If no valid plugin session exists, no-arg `opencode_wizard_catalog_fetch`, compatibility no-arg `opencode_wizard_published_skills_fetch`, explicit `opencode_wizard_status`, and chat/system-context startup may start the browser Entra PKCE flow and exchange the callback for a fresh backend-issued plugin session. The TUI panel displays the resulting
|
|
49
|
+
Catalog discovery uses the backend-issued plugin session token stored at `~/.config/opencode/opencode-wizard.json` (`auth` field); the plugin does not persist or send Microsoft/Entra tokens to GraphQL. If no valid plugin session exists, no-arg `opencode_wizard_catalog_fetch`, compatibility no-arg `opencode_wizard_published_skills_fetch`, explicit `opencode_wizard_status`, and chat/system-context startup may start the browser Entra PKCE flow and exchange the callback for a fresh backend-issued plugin session. The TUI panel displays the resulting backend URL, auth identity, role, and catalog counts from that status payload.
|
|
50
50
|
|
|
51
51
|
The shared plugin tools `opencode_wizard_catalog_fetch`, `opencode_wizard_artifact_fetch`, `opencode_wizard_artifact_preference_set`, compatibility published-skill tools, and `opencode_wizard_status` are always exposed by the plugin. Missing auth, forbidden role, backend, or catalog problems are reported by tool output/status metadata instead of hiding these shared tools; only `opencode_wizard_editor_create_or_update_skill`, `opencode_wizard_editor_publish_skill`, and `opencode_wizard_artifact_import` stay editor-only.
|
|
52
52
|
|
|
@@ -58,7 +58,7 @@ Workspace delivery still follows the backend contract: the plugin sends `workspa
|
|
|
58
58
|
|
|
59
59
|
Published skill fetches still support `refresh: true`, but normal cache entries now self-expire after 30 seconds and fetch/status payloads surface `source`, `workspaceSlug`, and `workspaceSlugSource` so stale-vs-refreshed behavior is visible without relying on manual cache deletion. Try `refresh: true` and report the tool-output auth/catalog/source/cache/workspace-resolution state before deleting `~/.cache/opencode/*`.
|
|
60
60
|
|
|
61
|
-
Use `opencode_wizard_artifact_preference_set` or compatibility `opencode_wizard_published_skill_preference_set` for preference actions (`install`, `uninstall`, `ignore`, `unignore`); the TUI panel
|
|
61
|
+
Use `opencode_wizard_artifact_preference_set` or compatibility `opencode_wizard_published_skill_preference_set` for preference actions (`install`, `uninstall`, `ignore`, `unignore`); the TUI panel stays read-only and does not run preference mutations directly.
|
|
62
62
|
|
|
63
63
|
## EDITOR skill creation flow
|
|
64
64
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { PublishedSkillsSuccessState } from './published-skills-transform.js';
|
|
2
2
|
export declare const buildPublishedSkillsSystemNote: ({ workspace, directoryPath, catalog, details: _details, }: {
|
|
3
3
|
workspace: {
|
|
4
4
|
slug: string;
|
|
@@ -1,17 +1,4 @@
|
|
|
1
|
-
import { isUserPublishedSkillAssignment } from './published-skills-transform.js';
|
|
2
|
-
import { WIZARD_SCOPE_LABELS } from './published-skills-terminology.js';
|
|
3
1
|
const SYSTEM_NOTE_SKILL_NAME_LIMIT = 10;
|
|
4
|
-
const SYSTEM_NOTE_SKILL_DESCRIPTION_LIMIT = 140;
|
|
5
|
-
const truncateText = (value, maxLength) => {
|
|
6
|
-
const normalized = value.replace(/\s+/gu, ' ').trim();
|
|
7
|
-
if (normalized.length <= maxLength) return normalized;
|
|
8
|
-
return `${normalized.slice(0, Math.max(maxLength - 1, 0)).trimEnd()}…`;
|
|
9
|
-
};
|
|
10
|
-
const buildSkillCatalogLine = skill => {
|
|
11
|
-
const description = truncateText(skill.whenToUse || skill.artifactDescription || skill.skillName || skill.skillSlug, SYSTEM_NOTE_SKILL_DESCRIPTION_LIMIT);
|
|
12
|
-
const scopeLabel = isUserPublishedSkillAssignment(skill.assignmentSource) ? WIZARD_SCOPE_LABELS.user : WIZARD_SCOPE_LABELS[skill.contextKind] || WIZARD_SCOPE_LABELS.project;
|
|
13
|
-
return `- ${skill.artifactName || skill.skillName} (${skill.skillSlug}, ${scopeLabel}): ${description}`;
|
|
14
|
-
};
|
|
15
2
|
export const buildPublishedSkillsSystemNote = ({
|
|
16
3
|
workspace,
|
|
17
4
|
directoryPath,
|
|
@@ -22,9 +9,6 @@ export const buildPublishedSkillsSystemNote = ({
|
|
|
22
9
|
const renderedSkillNames = skillNames.length > 0 ? skillNames.slice(0, SYSTEM_NOTE_SKILL_NAME_LIMIT).join(', ') : 'none';
|
|
23
10
|
const remainingCount = Math.max(skillNames.length - SYSTEM_NOTE_SKILL_NAME_LIMIT, 0);
|
|
24
11
|
const renderedCountSuffix = remainingCount > 0 ? ` (+${remainingCount} more)` : '';
|
|
25
|
-
|
|
26
|
-
const projectSkills = catalog.skills.filter(skill => skill.contextKind === 'project' && !isUserPublishedSkillAssignment(skill.assignmentSource)).slice(0, 5).map(buildSkillCatalogLine);
|
|
27
|
-
const userSkills = catalog.skills.filter(skill => isUserPublishedSkillAssignment(skill.assignmentSource)).slice(0, 5).map(buildSkillCatalogLine);
|
|
28
|
-
return [workspace ? `Workspace: ${workspace.slug}.` : 'Workspace not found; workspace-scoped wizard skills are unavailable.', `Current directory: ${directoryPath}.`, `Active wizard skills: ${renderedSkillNames}${renderedCountSuffix}.`, `Runtime: runtimeMode=${catalog.runtimeMode}; deliveryModel=${catalog.deliveryModel}; rootSkillSeedPath=${catalog.rootSkillSeedPath}.`, `Counts: ${catalog.assignmentCounts.global} wizard global, ${catalog.assignmentCounts.project} wizard project, ${catalog.assignmentCounts.user} wizard user, ${catalog.assignmentCounts.other} other.`, 'Wizard artifacts support artifact kinds `SKILL` and `DESIGN_DOC`; catalogs stay metadata-only and full bodies/files require explicit authenticated artifact fetch for the effective workspace/directory assignment.', 'Canonical wizard artifact tools are `opencode_wizard_catalog_fetch`, `opencode_wizard_artifact_fetch`, and `opencode_wizard_artifact_preference_set`; catalog output is metadata-only and detail/body/files require explicit artifact fetch.', 'Wizard-listed skills are backend-published and tool-fetch-only; MUST fetch the body via `opencode_wizard_published_skills_fetch` before use (`skills`/`skill` for multiple/single). Same-named native OpenCode skills or local `.opencode/skills` seed bodies are not authoritative for wizard-listed skills; fetched wizard bodies are authoritative.', 'Action recipe: call `opencode_wizard_published_skills_fetch` with no args for auth/catalog bootstrap, use `skill` or `skills` to fetch bodies, try `refresh: true` before deleting caches, and report tool-output auth/catalog/source/cache/workspace-resolution state when unavailable or stale.', 'Source/cache/workspace hints: fetch/status outputs surface `source`, cache TTL/freshness, and workspace-resolution metadata when available; do not infer wizard scope from native/local skill files.', globalSkills.length > 0 ? `Wizard global skills:\n${globalSkills.join('\n')}` : 'Wizard global skills: none.', projectSkills.length > 0 ? `Wizard project skills:\n${projectSkills.join('\n')}` : 'Wizard project skills: none.', userSkills.length > 0 ? `Wizard user skills:\n${userSkills.join('\n')}` : 'Wizard user skills: none.'].filter(Boolean).join(' ');
|
|
12
|
+
return [workspace ? `Workspace: ${workspace.slug}.` : 'Workspace not found; workspace-scoped wizard skills are unavailable.', `Current directory: ${directoryPath}.`, `Active wizard skills (${skillNames.length}): ${renderedSkillNames}${renderedCountSuffix}.`, 'Fetch rule: wizard-listed skill bodies are backend-published and tool-fetch-only; fetch bodies with `opencode_wizard_published_skills_fetch` before use.', 'Status hint: use no-arg fetch/status for auth and catalog state; pass `refresh: true` before cache deletion.'].filter(Boolean).join(' ');
|
|
29
13
|
};
|
|
30
14
|
//# sourceMappingURL=published-skills-system-note.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["SYSTEM_NOTE_SKILL_NAME_LIMIT","buildPublishedSkillsSystemNote","workspace","directoryPath","catalog","details","_details","skillNames","skills","map","skill","artifactName","skillName","skillSlug","renderedSkillNames","length","slice","join","remainingCount","Math","max","renderedCountSuffix","slug","filter","Boolean"],"sources":["../src/published-skills-system-note.ts"],"sourcesContent":["import type { PublishedSkillsSuccessState } from './published-skills-transform.js';\n\nconst SYSTEM_NOTE_SKILL_NAME_LIMIT = 10;\n\nexport const buildPublishedSkillsSystemNote = ({\n workspace,\n directoryPath,\n catalog,\n details: _details,\n}: {\n workspace: { slug: string } | null;\n directoryPath: string;\n catalog: PublishedSkillsSuccessState;\n details: unknown[];\n}): string => {\n const skillNames = catalog.skills.map((skill) => skill.artifactName || skill.skillName || skill.skillSlug);\n const renderedSkillNames =\n skillNames.length > 0 ? skillNames.slice(0, SYSTEM_NOTE_SKILL_NAME_LIMIT).join(', ') : 'none';\n const remainingCount = Math.max(skillNames.length - SYSTEM_NOTE_SKILL_NAME_LIMIT, 0);\n const renderedCountSuffix = remainingCount > 0 ? ` (+${remainingCount} more)` : '';\n\n return [\n workspace ? `Workspace: ${workspace.slug}.` : 'Workspace not found; workspace-scoped wizard skills are unavailable.',\n `Current directory: ${directoryPath}.`,\n `Active wizard skills (${skillNames.length}): ${renderedSkillNames}${renderedCountSuffix}.`,\n 'Fetch rule: wizard-listed skill bodies are backend-published and tool-fetch-only; fetch bodies with `opencode_wizard_published_skills_fetch` before use.',\n 'Status hint: use no-arg fetch/status for auth and catalog state; pass `refresh: true` before cache deletion.',\n ]\n .filter(Boolean)\n .join(' ');\n};\n"],"mappings":"AAEA,MAAMA,4BAA4B,GAAG,EAAE;AAEvC,OAAO,MAAMC,8BAA8B,GAAGA,CAAC;EAC7CC,SAAS;EACTC,aAAa;EACbC,OAAO;EACPC,OAAO,EAAEC;AAMX,CAAC,KAAa;EACZ,MAAMC,UAAU,GAAGH,OAAO,CAACI,MAAM,CAACC,GAAG,CAAEC,KAAK,IAAKA,KAAK,CAACC,YAAY,IAAID,KAAK,CAACE,SAAS,IAAIF,KAAK,CAACG,SAAS,CAAC;EAC1G,MAAMC,kBAAkB,GACtBP,UAAU,CAACQ,MAAM,GAAG,CAAC,GAAGR,UAAU,CAACS,KAAK,CAAC,CAAC,EAAEhB,4BAA4B,CAAC,CAACiB,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM;EAC/F,MAAMC,cAAc,GAAGC,IAAI,CAACC,GAAG,CAACb,UAAU,CAACQ,MAAM,GAAGf,4BAA4B,EAAE,CAAC,CAAC;EACpF,MAAMqB,mBAAmB,GAAGH,cAAc,GAAG,CAAC,GAAG,MAAMA,cAAc,QAAQ,GAAG,EAAE;EAElF,OAAO,CACLhB,SAAS,GAAG,cAAcA,SAAS,CAACoB,IAAI,GAAG,GAAG,sEAAsE,EACpH,sBAAsBnB,aAAa,GAAG,EACtC,yBAAyBI,UAAU,CAACQ,MAAM,MAAMD,kBAAkB,GAAGO,mBAAmB,GAAG,EAC3F,0JAA0J,EAC1J,8GAA8G,CAC/G,CACEE,MAAM,CAACC,OAAO,CAAC,CACfP,IAAI,CAAC,GAAG,CAAC;AACd,CAAC","ignoreList":[]}
|
package/dist/server/runtime.js
CHANGED
|
@@ -131,6 +131,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
131
131
|
const detailInflight = new Map();
|
|
132
132
|
const wizardArtifactDetailInflight = new Map();
|
|
133
133
|
const initialAuthState = await resolveStoredAuthState(input.worktree, config);
|
|
134
|
+
const registeredTools = resolveAvailableTools(initialAuthState?.role ?? null);
|
|
134
135
|
const loginBootstrap = {
|
|
135
136
|
promise: null,
|
|
136
137
|
snapshot: createIdleLoginBootstrapSnapshot()
|
|
@@ -578,11 +579,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
578
579
|
const selection = selectPublishedSkills(filteredPublishedSkillsResult.fetchResult.payload, requestedSkills);
|
|
579
580
|
const isSingleRequest = requestedSkills.length === 1;
|
|
580
581
|
if (requestedSkills.length === 0) {
|
|
581
|
-
const
|
|
582
|
-
const catalog = {
|
|
583
|
-
...toPublishedSkillCatalog(filteredPublishedSkillsResult.fetchResult.payload),
|
|
584
|
-
availableTools: resolveAvailableTools(authState?.role ?? null)
|
|
585
|
-
};
|
|
582
|
+
const catalog = toPublishedSkillCatalog(filteredPublishedSkillsResult.fetchResult.payload, registeredTools);
|
|
586
583
|
context.metadata({
|
|
587
584
|
title: `opencode-wizard published skills catalog: ${catalog.publishedSkillCount} active`,
|
|
588
585
|
metadata: {
|
|
@@ -781,10 +778,9 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
781
778
|
}
|
|
782
779
|
};
|
|
783
780
|
}
|
|
784
|
-
const authState = await resolveStoredAuthState(input.worktree, config);
|
|
785
781
|
const catalog = toWizardArtifactCatalog(fetchResult.payload, {
|
|
786
782
|
pluginId: PLUGIN_ID,
|
|
787
|
-
availableTools:
|
|
783
|
+
availableTools: registeredTools
|
|
788
784
|
});
|
|
789
785
|
const cacheCursor = getWizardArtifactCatalogCursor(fetchResult.payload.artifacts, toWizardArtifactCatalogCursorItems(fetchResult.payload.catalogArtifacts));
|
|
790
786
|
return {
|
|
@@ -865,10 +861,9 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
865
861
|
}
|
|
866
862
|
const selection = selectWizardArtifacts(fetchResult.payload.artifacts, requestedArtifacts);
|
|
867
863
|
if (requestedArtifacts.length === 0) {
|
|
868
|
-
const authState = await resolveStoredAuthState(input.worktree, config);
|
|
869
864
|
const catalog = toWizardArtifactCatalog(fetchResult.payload, {
|
|
870
865
|
pluginId: PLUGIN_ID,
|
|
871
|
-
availableTools:
|
|
866
|
+
availableTools: registeredTools
|
|
872
867
|
});
|
|
873
868
|
const cacheCursor = getWizardArtifactCatalogCursor(fetchResult.payload.artifacts, toWizardArtifactCatalogCursorItems(fetchResult.payload.catalogArtifacts));
|
|
874
869
|
return {
|
|
@@ -992,7 +987,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
992
987
|
let snapshot = await resolvePluginStatusSnapshot({
|
|
993
988
|
worktree: input.worktree,
|
|
994
989
|
directory: requestedDirectory,
|
|
995
|
-
signal: context.abort
|
|
990
|
+
signal: context.abort,
|
|
991
|
+
registeredTools
|
|
996
992
|
});
|
|
997
993
|
if (snapshot.status === 'missing_auth') {
|
|
998
994
|
try {
|
|
@@ -1002,7 +998,8 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1002
998
|
snapshot = await resolvePluginStatusSnapshot({
|
|
1003
999
|
worktree: input.worktree,
|
|
1004
1000
|
directory: requestedDirectory,
|
|
1005
|
-
signal: context.abort
|
|
1001
|
+
signal: context.abort,
|
|
1002
|
+
registeredTools
|
|
1006
1003
|
});
|
|
1007
1004
|
} catch {
|
|
1008
1005
|
// Keep returning the safe missing-auth snapshot when interactive login is cancelled or fails.
|
|
@@ -1554,7 +1551,7 @@ export const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1554
1551
|
})
|
|
1555
1552
|
});
|
|
1556
1553
|
return {
|
|
1557
|
-
tool:
|
|
1554
|
+
tool: registeredTools.includes('opencode_wizard_editor_create_or_update_skill') ? {
|
|
1558
1555
|
...sharedTools,
|
|
1559
1556
|
...editorOnlyTools
|
|
1560
1557
|
} : sharedTools,
|