@co0ontty/wand 4.11.2 → 4.12.0
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/build-info.json +3 -3
- package/dist/git-quick-commit.d.ts +6 -1
- package/dist/git-quick-commit.js +50 -9
- package/dist/session-ai-context.d.ts +2 -0
- package/dist/session-ai-context.js +9 -1
- package/dist/web-ui/content/scripts.js +46 -46
- package/dist/web-ui/embedded-assets.d.ts +1 -1
- package/dist/web-ui/embedded-assets.js +2 -2
- package/package.json +1 -1
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"commit": "
|
|
3
|
-
"builtAt": "2026-07-
|
|
4
|
-
"version": "4.
|
|
2
|
+
"commit": "c1870fda254528fbd1c34b8907f4f1be5a229c54",
|
|
3
|
+
"builtAt": "2026-07-17T11:06:16.718Z",
|
|
4
|
+
"version": "4.12.0",
|
|
5
5
|
"channel": "stable"
|
|
6
6
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { GitStatusResult, PushResult, QuickCommitResult, SessionProvider, SessionSnapshot, TagHeadResult } from "./types.js";
|
|
2
|
-
export type QuickCommitErrorCode = "CWD_MISSING" | "NO_CWD" | "NOT_A_GIT_REPO" | "NO_COMMIT" | "NOTHING_TO_COMMIT" | "NOTHING_TO_PUSH" | "EMPTY_MESSAGE" | "EMPTY_TAG" | "EMPTY_AI_MESSAGE" | "INVALID_AI_TAG" | "TAG_EXISTS" | "GIT_ADD_FAILED" | "GIT_DIFF_FAILED" | "GIT_COMMIT_FAILED" | "GIT_TAG_FAILED" | "CLAUDE_CLI_MISSING" | "CLAUDE_CLI_FAILED" | "CLAUDE_TIMEOUT";
|
|
2
|
+
export type QuickCommitErrorCode = "CWD_MISSING" | "NO_CWD" | "NOT_A_GIT_REPO" | "NO_COMMIT" | "NOTHING_TO_COMMIT" | "NOTHING_TO_PUSH" | "EMPTY_MESSAGE" | "EMPTY_TAG" | "EMPTY_AI_MESSAGE" | "AI_FALLBACK_FAILED" | "INVALID_AI_TAG" | "TAG_EXISTS" | "GIT_ADD_FAILED" | "GIT_DIFF_FAILED" | "GIT_COMMIT_FAILED" | "GIT_TAG_FAILED" | "CLAUDE_CLI_MISSING" | "CLAUDE_CLI_FAILED" | "CLAUDE_TIMEOUT";
|
|
3
3
|
export declare function getGitStatus(cwd: string): GitStatusResult;
|
|
4
4
|
/** Non-blocking status implementation used by HTTP routes. */
|
|
5
5
|
export declare function getGitStatusAsync(cwd: string): Promise<GitStatusResult>;
|
|
@@ -10,6 +10,8 @@ interface QuickCommitOptions {
|
|
|
10
10
|
model?: string | null;
|
|
11
11
|
thinkingEffort?: SessionSnapshot["thinkingEffort"];
|
|
12
12
|
inheritEnv?: boolean;
|
|
13
|
+
/** Direct API to try when the selected Commit source is a CLI. */
|
|
14
|
+
fallbackSystemAi?: import("./types.js").SystemAiConfig;
|
|
13
15
|
systemAi?: import("./types.js").SystemAiConfig;
|
|
14
16
|
autoMessage: boolean;
|
|
15
17
|
customMessage?: string;
|
|
@@ -28,6 +30,7 @@ interface QuickCommitAiOptions {
|
|
|
28
30
|
model?: string | null;
|
|
29
31
|
thinkingEffort?: SessionSnapshot["thinkingEffort"];
|
|
30
32
|
inheritEnv?: boolean;
|
|
33
|
+
fallbackSystemAi?: import("./types.js").SystemAiConfig;
|
|
31
34
|
systemAi?: import("./types.js").SystemAiConfig;
|
|
32
35
|
}
|
|
33
36
|
export declare class QuickCommitError extends Error {
|
|
@@ -47,6 +50,8 @@ interface TagHeadOptions {
|
|
|
47
50
|
model?: string | null;
|
|
48
51
|
thinkingEffort?: SessionSnapshot["thinkingEffort"];
|
|
49
52
|
inheritEnv?: boolean;
|
|
53
|
+
fallbackSystemAi?: import("./types.js").SystemAiConfig;
|
|
54
|
+
systemAi?: import("./types.js").SystemAiConfig;
|
|
50
55
|
/** Explicit tag name. If empty and `autoTag` is true, ask the session provider to generate one. */
|
|
51
56
|
tag?: string;
|
|
52
57
|
autoTag?: boolean;
|
package/dist/git-quick-commit.js
CHANGED
|
@@ -605,9 +605,7 @@ async function callOpenCodeText(prompt, cwd, opts) {
|
|
|
605
605
|
throw new QuickCommitError("OpenCode 返回了空的 commit message。", "EMPTY_AI_MESSAGE");
|
|
606
606
|
return text;
|
|
607
607
|
}
|
|
608
|
-
async function
|
|
609
|
-
if (opts.systemAi?.enabled)
|
|
610
|
-
return callSystemAiText(prompt, opts.systemAi);
|
|
608
|
+
async function callCliAiText(prompt, cwd, language, opts) {
|
|
611
609
|
const provider = normalizeProvider(opts.provider);
|
|
612
610
|
if (provider === "codex") {
|
|
613
611
|
return callCodexText(prompt, cwd, opts);
|
|
@@ -616,6 +614,49 @@ async function callAiText(prompt, cwd, language, opts) {
|
|
|
616
614
|
return callOpenCodeText(prompt, cwd, opts);
|
|
617
615
|
return callClaudeText(prompt, cwd, language, opts.model);
|
|
618
616
|
}
|
|
617
|
+
async function callDirectApiText(prompt, systemAi) {
|
|
618
|
+
const text = await callSystemAiText(prompt, systemAi);
|
|
619
|
+
if (!text.trim()) {
|
|
620
|
+
throw new QuickCommitError("直连 API 返回了空结果。", "EMPTY_AI_MESSAGE");
|
|
621
|
+
}
|
|
622
|
+
return text;
|
|
623
|
+
}
|
|
624
|
+
function aiFallbackFailed(primary, primaryError, fallbackError) {
|
|
625
|
+
const fallback = primary === "直连 API" ? "CLI" : "直连 API";
|
|
626
|
+
return new QuickCommitError(`${primary} 与 ${fallback} 均失败:${getGitErrorMessage(primaryError)};${getGitErrorMessage(fallbackError)}`, "AI_FALLBACK_FAILED");
|
|
627
|
+
}
|
|
628
|
+
async function callAiText(prompt, cwd, language, opts) {
|
|
629
|
+
if (opts.systemAi?.enabled) {
|
|
630
|
+
try {
|
|
631
|
+
return await callDirectApiText(prompt, opts.systemAi);
|
|
632
|
+
}
|
|
633
|
+
catch (apiError) {
|
|
634
|
+
try {
|
|
635
|
+
// The user selected the direct API first. If it is unavailable or
|
|
636
|
+
// empty, retry this exact request through their selected CLI.
|
|
637
|
+
return await callCliAiText(prompt, cwd, language, opts);
|
|
638
|
+
}
|
|
639
|
+
catch (cliError) {
|
|
640
|
+
throw aiFallbackFailed("直连 API", apiError, cliError);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
try {
|
|
645
|
+
return await callCliAiText(prompt, cwd, language, opts);
|
|
646
|
+
}
|
|
647
|
+
catch (cliError) {
|
|
648
|
+
if (!opts.fallbackSystemAi?.enabled)
|
|
649
|
+
throw cliError;
|
|
650
|
+
try {
|
|
651
|
+
// The user selected the CLI first. A complete direct-API profile is only
|
|
652
|
+
// provided here as the reciprocal fallback, never as a second CLI try.
|
|
653
|
+
return await callDirectApiText(prompt, opts.fallbackSystemAi);
|
|
654
|
+
}
|
|
655
|
+
catch (apiError) {
|
|
656
|
+
throw aiFallbackFailed("CLI", cliError, apiError);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
619
660
|
async function collectStagedDiff(cwd) {
|
|
620
661
|
let diff;
|
|
621
662
|
try {
|
|
@@ -854,6 +895,8 @@ export async function runTagHead(opts) {
|
|
|
854
895
|
model: opts.model,
|
|
855
896
|
thinkingEffort: opts.thinkingEffort,
|
|
856
897
|
inheritEnv: opts.inheritEnv,
|
|
898
|
+
fallbackSystemAi: opts.fallbackSystemAi,
|
|
899
|
+
systemAi: opts.systemAi,
|
|
857
900
|
});
|
|
858
901
|
}
|
|
859
902
|
if (!tagName) {
|
|
@@ -1246,11 +1289,7 @@ async function runQuickCommitFallbackCli(opts, priorError) {
|
|
|
1246
1289
|
pushed: false,
|
|
1247
1290
|
};
|
|
1248
1291
|
}
|
|
1249
|
-
function shouldFallbackToCli(error
|
|
1250
|
-
// An explicit direct-API selection is a hard boundary: never execute a local
|
|
1251
|
-
// provider CLI (especially the permission-bypassing fallback) behind it.
|
|
1252
|
-
if (opts.systemAi?.enabled)
|
|
1253
|
-
return false;
|
|
1292
|
+
function shouldFallbackToCli(error) {
|
|
1254
1293
|
return ![
|
|
1255
1294
|
"CWD_MISSING",
|
|
1256
1295
|
"NO_CWD",
|
|
@@ -1260,6 +1299,7 @@ function shouldFallbackToCli(error, opts) {
|
|
|
1260
1299
|
"NOTHING_TO_PUSH",
|
|
1261
1300
|
"EMPTY_MESSAGE",
|
|
1262
1301
|
"EMPTY_TAG",
|
|
1302
|
+
"AI_FALLBACK_FAILED",
|
|
1263
1303
|
"TAG_EXISTS",
|
|
1264
1304
|
].includes(error.code);
|
|
1265
1305
|
}
|
|
@@ -1268,7 +1308,7 @@ export async function runQuickCommitWithFallback(opts) {
|
|
|
1268
1308
|
return await runQuickCommit(opts);
|
|
1269
1309
|
}
|
|
1270
1310
|
catch (error) {
|
|
1271
|
-
if (error instanceof QuickCommitError && shouldFallbackToCli(error
|
|
1311
|
+
if (error instanceof QuickCommitError && shouldFallbackToCli(error)) {
|
|
1272
1312
|
return runQuickCommitFallbackCli(opts, error.message);
|
|
1273
1313
|
}
|
|
1274
1314
|
throw error;
|
|
@@ -1281,6 +1321,7 @@ export async function runQuickCommit(opts) {
|
|
|
1281
1321
|
model: opts.model,
|
|
1282
1322
|
thinkingEffort: opts.thinkingEffort,
|
|
1283
1323
|
inheritEnv: opts.inheritEnv,
|
|
1324
|
+
fallbackSystemAi: opts.fallbackSystemAi,
|
|
1284
1325
|
systemAi: opts.systemAi,
|
|
1285
1326
|
};
|
|
1286
1327
|
await assertGitWorkTreeAsync(cwd);
|
|
@@ -4,6 +4,8 @@ export interface SessionAiContext {
|
|
|
4
4
|
model?: string;
|
|
5
5
|
thinkingEffort: SessionSnapshot["thinkingEffort"];
|
|
6
6
|
inheritEnv?: boolean;
|
|
7
|
+
/** Direct API to try when Commit is configured to prefer its CLI. */
|
|
8
|
+
fallbackSystemAi?: SystemAiConfig;
|
|
7
9
|
systemAi?: SystemAiConfig;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
@@ -44,6 +44,11 @@ function normalizeModel(value) {
|
|
|
44
44
|
const model = value?.trim();
|
|
45
45
|
return model && model !== "default" ? model : undefined;
|
|
46
46
|
}
|
|
47
|
+
function usableSystemAi(config) {
|
|
48
|
+
if (!config.baseUrl.trim() || !config.apiKey.trim() || !config.model.trim())
|
|
49
|
+
return undefined;
|
|
50
|
+
return { ...config, enabled: true };
|
|
51
|
+
}
|
|
47
52
|
/** Build the provider-specific settings used by session-adjacent AI actions. */
|
|
48
53
|
export function resolveSessionAiContext(snapshot, config) {
|
|
49
54
|
const provider = resolveSessionProvider(snapshot);
|
|
@@ -66,10 +71,13 @@ export function resolveCommitAiContext(snapshot, config) {
|
|
|
66
71
|
apiKey: "",
|
|
67
72
|
model: "",
|
|
68
73
|
};
|
|
74
|
+
const readyDirectApi = usableSystemAi(directApi);
|
|
69
75
|
return {
|
|
70
76
|
...sessionContext,
|
|
71
77
|
provider: config.commitCli === "codex" || config.commitCli === "opencode" ? config.commitCli : "claude",
|
|
72
78
|
model: normalizeModel(config.commitModel),
|
|
73
|
-
...(config.commitAiSource === "api"
|
|
79
|
+
...(config.commitAiSource === "api"
|
|
80
|
+
? { systemAi: { ...directApi, enabled: true } }
|
|
81
|
+
: readyDirectApi ? { fallbackSystemAi: readyDirectApi } : {}),
|
|
74
82
|
};
|
|
75
83
|
}
|