@aexol/opencode-wizard 0.1.9 → 0.1.12
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/server.d.ts +5 -0
- package/dist/server.js +96 -3
- package/dist/server.js.map +1 -1
- package/dist/tui.d.ts +8 -20
- package/dist/tui.js +437 -152
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -226,6 +226,11 @@ export declare const resolvePluginStatusSnapshot: ({ worktree, directory, signal
|
|
|
226
226
|
directory: string;
|
|
227
227
|
signal: AbortSignal;
|
|
228
228
|
}) => Promise<PluginStatusSnapshot>;
|
|
229
|
+
export declare const resolvePluginStatusSnapshotWithAuthBootstrap: ({ worktree, directory, signal, }: {
|
|
230
|
+
worktree: string;
|
|
231
|
+
directory: string;
|
|
232
|
+
signal: AbortSignal;
|
|
233
|
+
}) => Promise<PluginStatusSnapshot>;
|
|
229
234
|
declare const _default: {
|
|
230
235
|
id: string;
|
|
231
236
|
server: OpencodePluginServer;
|
package/dist/server.js
CHANGED
|
@@ -43,6 +43,13 @@ const createIdleLoginBootstrapSnapshot = () => ({
|
|
|
43
43
|
email: null,
|
|
44
44
|
message: null
|
|
45
45
|
});
|
|
46
|
+
const STATUS_PATH_LOGIN_RETRY_COOLDOWN_MS = 60_000;
|
|
47
|
+
const statusPathLoginBootstrap = {
|
|
48
|
+
promise: null,
|
|
49
|
+
status: 'idle',
|
|
50
|
+
message: null,
|
|
51
|
+
failedAt: null
|
|
52
|
+
};
|
|
46
53
|
const importOpencodePluginModule = new Function('specifier', 'return import(specifier)');
|
|
47
54
|
export const AVAILABLE_PUBLISHED_SKILL_TOOLS = ['opencode_wizard_published_skills_fetch', 'opencode_wizard_status'];
|
|
48
55
|
export const NATIVE_SKILLS_URL_COMPATIBILITY = {
|
|
@@ -672,6 +679,76 @@ export const resolvePluginStatusSnapshot = async ({
|
|
|
672
679
|
catalog: fetchResult.ok ? toPublishedSkillCatalog(fetchResult.payload) : null
|
|
673
680
|
};
|
|
674
681
|
};
|
|
682
|
+
const withStatusMessage = (snapshot, message) => ({
|
|
683
|
+
...snapshot,
|
|
684
|
+
message
|
|
685
|
+
});
|
|
686
|
+
const startStatusPathLoginBootstrap = (worktree, config) => {
|
|
687
|
+
if (statusPathLoginBootstrap.promise) return;
|
|
688
|
+
if (statusPathLoginBootstrap.status === 'failed' && statusPathLoginBootstrap.failedAt && Date.now() - statusPathLoginBootstrap.failedAt < STATUS_PATH_LOGIN_RETRY_COOLDOWN_MS) {
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
statusPathLoginBootstrap.status = 'pending';
|
|
692
|
+
statusPathLoginBootstrap.message = 'Browser login started automatically from the TUI/status path.';
|
|
693
|
+
statusPathLoginBootstrap.failedAt = null;
|
|
694
|
+
statusPathLoginBootstrap.promise = (async () => {
|
|
695
|
+
const loginSignal = AbortSignal.timeout(LOGIN_TIMEOUT_MS);
|
|
696
|
+
const loginStart = await startLoginFlow(loginSignal);
|
|
697
|
+
const browserOpenError = await openBrowser(loginStart.browserUrl);
|
|
698
|
+
if (browserOpenError) {
|
|
699
|
+
statusPathLoginBootstrap.message = `Automatic browser open failed. Open ${loginStart.browserUrl} manually.`;
|
|
700
|
+
}
|
|
701
|
+
try {
|
|
702
|
+
const callbackPayload = await loginStart.callbackPromise;
|
|
703
|
+
if (callbackPayload.status === 'error') {
|
|
704
|
+
throw new Error(callbackPayload.message);
|
|
705
|
+
}
|
|
706
|
+
if (callbackPayload.state !== loginStart.expectedState) {
|
|
707
|
+
throw new Error('OAuth callback state did not match the original login request.');
|
|
708
|
+
}
|
|
709
|
+
const pluginSession = await createPluginSession({
|
|
710
|
+
code: callbackPayload.code,
|
|
711
|
+
codeVerifier: loginStart.codeVerifier,
|
|
712
|
+
redirectUri: OIDC_CALLBACK_URL,
|
|
713
|
+
config,
|
|
714
|
+
signal: loginSignal
|
|
715
|
+
});
|
|
716
|
+
const authState = toAuthState(pluginSession);
|
|
717
|
+
await writeAuthState(path.resolve(worktree, config.authStatePath), authState);
|
|
718
|
+
statusPathLoginBootstrap.status = 'authenticated';
|
|
719
|
+
statusPathLoginBootstrap.message = `Browser login completed successfully for ${authState.email}.`;
|
|
720
|
+
return authState;
|
|
721
|
+
} finally {
|
|
722
|
+
await loginStart.closeCallbackServer().catch(() => undefined);
|
|
723
|
+
}
|
|
724
|
+
})().catch(error => {
|
|
725
|
+
statusPathLoginBootstrap.status = 'failed';
|
|
726
|
+
statusPathLoginBootstrap.failedAt = Date.now();
|
|
727
|
+
statusPathLoginBootstrap.message = error instanceof Error ? error.message : 'Browser login failed.';
|
|
728
|
+
throw error;
|
|
729
|
+
}).finally(() => {
|
|
730
|
+
statusPathLoginBootstrap.promise = null;
|
|
731
|
+
});
|
|
732
|
+
statusPathLoginBootstrap.promise.catch(() => undefined);
|
|
733
|
+
};
|
|
734
|
+
export const resolvePluginStatusSnapshotWithAuthBootstrap = async ({
|
|
735
|
+
worktree,
|
|
736
|
+
directory,
|
|
737
|
+
signal
|
|
738
|
+
}) => {
|
|
739
|
+
const snapshot = await resolvePluginStatusSnapshot({
|
|
740
|
+
worktree,
|
|
741
|
+
directory,
|
|
742
|
+
signal
|
|
743
|
+
});
|
|
744
|
+
if (snapshot.status !== 'missing_auth') return snapshot;
|
|
745
|
+
const config = await resolveConfig(worktree);
|
|
746
|
+
startStatusPathLoginBootstrap(worktree, config);
|
|
747
|
+
if (statusPathLoginBootstrap.message) {
|
|
748
|
+
return withStatusMessage(snapshot, statusPathLoginBootstrap.message);
|
|
749
|
+
}
|
|
750
|
+
return withStatusMessage(snapshot, 'Browser login is pending from the TUI/status path.');
|
|
751
|
+
};
|
|
675
752
|
const toPluginStatusMetadata = snapshot => ({
|
|
676
753
|
backendOrigin: snapshot.backendOrigin,
|
|
677
754
|
graphqlUrl: snapshot.graphqlUrl,
|
|
@@ -1798,14 +1875,30 @@ const OpencodeWizardSkillsPlugin = async input => {
|
|
|
1798
1875
|
})
|
|
1799
1876
|
},
|
|
1800
1877
|
'experimental.chat.system.transform': async (_hookInput, output) => {
|
|
1801
|
-
|
|
1878
|
+
let publishedSkillsResult = await loadPublishedSkillCatalog({
|
|
1802
1879
|
directory: input.directory,
|
|
1803
1880
|
useCache: true,
|
|
1804
1881
|
signal: AbortSignal.timeout(5_000)
|
|
1805
1882
|
});
|
|
1806
1883
|
if (!publishedSkillsResult.fetchResult.ok && publishedSkillsResult.fetchResult.status === 'missing_auth') {
|
|
1807
|
-
|
|
1808
|
-
|
|
1884
|
+
try {
|
|
1885
|
+
await startLoginCompletion('status').then(async authState => {
|
|
1886
|
+
await schedulePresenceStart(authState);
|
|
1887
|
+
});
|
|
1888
|
+
publishedSkillsResult = await loadPublishedSkillCatalog({
|
|
1889
|
+
directory: input.directory,
|
|
1890
|
+
useCache: false,
|
|
1891
|
+
signal: AbortSignal.timeout(5_000)
|
|
1892
|
+
});
|
|
1893
|
+
} catch {
|
|
1894
|
+
const loginMessage = loginBootstrap.snapshot.message ? ` Last login status: ${loginBootstrap.snapshot.message}` : '';
|
|
1895
|
+
output.system.push(`opencode-wizard plugin stored auth is missing, expired, or rejected. Startup browser login was started but did not complete successfully.${loginMessage} Use opencode_wizard_status or opencode_wizard_published_skills_fetch to retry authentication when published skills are needed. No tokens are exposed.`);
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
if (!publishedSkillsResult.fetchResult.ok) {
|
|
1899
|
+
output.system.push(`opencode-wizard plugin startup login completed, but published skills are still unavailable: ${publishedSkillsResult.fetchResult.message} No tokens are exposed.`);
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1809
1902
|
}
|
|
1810
1903
|
const details = await loadSystemNoteDetails({
|
|
1811
1904
|
publishedSkillsResult,
|