@zaowu-labs/cli 1.0.2 → 1.0.5
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/args.d.ts.map +1 -1
- package/dist/args.js +10 -13
- package/dist/args.js.map +1 -1
- package/dist/command-contracts.d.ts +7 -0
- package/dist/command-contracts.d.ts.map +1 -1
- package/dist/command-contracts.js +57 -36
- package/dist/command-contracts.js.map +1 -1
- package/dist/handler-utils.d.ts +17 -2
- package/dist/handler-utils.d.ts.map +1 -1
- package/dist/handler-utils.js +34 -1
- package/dist/handler-utils.js.map +1 -1
- package/dist/handlers/ai-handlers.d.ts.map +1 -1
- package/dist/handlers/ai-handlers.js +28 -20
- package/dist/handlers/ai-handlers.js.map +1 -1
- package/dist/handlers/auto-handlers.d.ts.map +1 -1
- package/dist/handlers/auto-handlers.js +3 -7
- package/dist/handlers/auto-handlers.js.map +1 -1
- package/dist/handlers/config-handlers.d.ts.map +1 -1
- package/dist/handlers/config-handlers.js +12 -21
- package/dist/handlers/config-handlers.js.map +1 -1
- package/dist/handlers/data-handlers.d.ts.map +1 -1
- package/dist/handlers/data-handlers.js +6 -9
- package/dist/handlers/data-handlers.js.map +1 -1
- package/dist/handlers/dev-handlers.d.ts.map +1 -1
- package/dist/handlers/dev-handlers.js +144 -182
- package/dist/handlers/dev-handlers.js.map +1 -1
- package/dist/handlers/doc-handlers.d.ts.map +1 -1
- package/dist/handlers/doc-handlers.js +12 -8
- package/dist/handlers/doc-handlers.js.map +1 -1
- package/dist/handlers/plugin-handlers.d.ts.map +1 -1
- package/dist/handlers/plugin-handlers.js +21 -26
- package/dist/handlers/plugin-handlers.js.map +1 -1
- package/dist/option-registry.d.ts +16 -0
- package/dist/option-registry.d.ts.map +1 -0
- package/dist/option-registry.js +84 -0
- package/dist/option-registry.js.map +1 -0
- package/dist/option-validation.d.ts.map +1 -1
- package/dist/option-validation.js +1 -48
- package/dist/option-validation.js.map +1 -1
- package/dist/root-doctor.d.ts.map +1 -1
- package/dist/root-doctor.js +2 -3
- package/dist/root-doctor.js.map +1 -1
- package/dist/root-help.d.ts +1 -2
- package/dist/root-help.d.ts.map +1 -1
- package/dist/root-help.js +7 -13
- package/dist/root-help.js.map +1 -1
- package/dist/root-init.d.ts +2 -1
- package/dist/root-init.d.ts.map +1 -1
- package/dist/root-init.js +7 -8
- package/dist/root-init.js.map +1 -1
- package/dist/run.d.ts +0 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +42 -24
- package/dist/run.js.map +1 -1
- package/dist/system-command.d.ts +2 -0
- package/dist/system-command.d.ts.map +1 -1
- package/dist/system-command.js +2 -1
- package/dist/system-command.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { findConfigPathOrThrow, getResolvedConfigValue, loadResolvedConfig, migrateResolvedConfig, setResolvedConfigValue, validateResolvedConfig, } from '@zaowu-labs/config';
|
|
2
|
-
import { assertOperationPlanFingerprint, createContentOperationSubjects, createOperationPlan, formatOperationPlan, hasFlag, requireSecondTarget, requireTarget, result, withOperationPlan, } from '../handler-utils.js';
|
|
2
|
+
import { assertOperationPlanFingerprint, createContentOperationSubjects, createOperationPlan, formatLabeledList, formatOperationPlan, hasFlag, requireSecondTarget, requireTarget, result, withOperationPlan, } from '../handler-utils.js';
|
|
3
3
|
export const handleConfigPath = async (_args, context) => {
|
|
4
4
|
const filePath = await findConfigPathOrThrow(context.cwd);
|
|
5
5
|
const payload = {
|
|
@@ -18,7 +18,7 @@ export const handleConfigShow = async (_args, context) => {
|
|
|
18
18
|
config: resolved.config,
|
|
19
19
|
};
|
|
20
20
|
const human = [
|
|
21
|
-
'ZaoWu Config',
|
|
21
|
+
'ZaoWu Config Show',
|
|
22
22
|
'',
|
|
23
23
|
`File: ${resolved.filePath}`,
|
|
24
24
|
`Project: ${resolved.config.project.name}`,
|
|
@@ -37,9 +37,7 @@ export const handleConfigValidate = async (_args, context) => {
|
|
|
37
37
|
`Status: ${validation.status}`,
|
|
38
38
|
`File: ${validation.filePath}`,
|
|
39
39
|
'',
|
|
40
|
-
validation.warnings
|
|
41
|
-
? ['Warnings:', ...validation.warnings.map((warning) => `- ${warning}`)].join('\n')
|
|
42
|
-
: 'Warnings: none',
|
|
40
|
+
formatLabeledList('Warnings', validation.warnings),
|
|
43
41
|
].join('\n');
|
|
44
42
|
return result(context, validation, human);
|
|
45
43
|
};
|
|
@@ -58,10 +56,11 @@ export const handleConfigSet = async (args, context) => {
|
|
|
58
56
|
const key = requireTarget(args, 'zw config set');
|
|
59
57
|
const value = requireSecondTarget(args, 'zw config set', 'value');
|
|
60
58
|
const isGlobal = hasFlag(context.parsed, '--global');
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
59
|
+
// One options object for both the preview and the confirmed call: the
|
|
60
|
+
// fingerprint the user confirms is computed from the preview, so the two
|
|
61
|
+
// calls must be structurally unable to drift apart.
|
|
62
|
+
const setOptions = { cwd: context.cwd, global: isGlobal };
|
|
63
|
+
const preview = await setResolvedConfigValue(key, value, setOptions);
|
|
65
64
|
const operationPlan = createOperationPlan({
|
|
66
65
|
risk: 'medium',
|
|
67
66
|
confirmationRequired: !context.yes,
|
|
@@ -77,11 +76,7 @@ export const handleConfigSet = async (args, context) => {
|
|
|
77
76
|
});
|
|
78
77
|
assertOperationPlanFingerprint(context, operationPlan);
|
|
79
78
|
const updated = context.yes
|
|
80
|
-
? await setResolvedConfigValue(key, value, {
|
|
81
|
-
cwd: context.cwd,
|
|
82
|
-
yes: true,
|
|
83
|
-
global: isGlobal,
|
|
84
|
-
})
|
|
79
|
+
? await setResolvedConfigValue(key, value, { ...setOptions, yes: true })
|
|
85
80
|
: preview;
|
|
86
81
|
const human = [
|
|
87
82
|
'ZaoWu Config Set',
|
|
@@ -100,9 +95,8 @@ export const handleConfigSet = async (args, context) => {
|
|
|
100
95
|
return result(context, withOperationPlan(updated, operationPlan), human);
|
|
101
96
|
};
|
|
102
97
|
export const handleConfigMigrate = async (_args, context) => {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
});
|
|
98
|
+
const migrateOptions = { cwd: context.cwd };
|
|
99
|
+
const preview = await migrateResolvedConfig(migrateOptions);
|
|
106
100
|
const operationPlan = createOperationPlan({
|
|
107
101
|
risk: 'medium',
|
|
108
102
|
confirmationRequired: preview.changed && !context.yes,
|
|
@@ -116,10 +110,7 @@ export const handleConfigMigrate = async (_args, context) => {
|
|
|
116
110
|
});
|
|
117
111
|
assertOperationPlanFingerprint(context, operationPlan);
|
|
118
112
|
const migrated = context.yes && preview.changed
|
|
119
|
-
? await migrateResolvedConfig({
|
|
120
|
-
cwd: context.cwd,
|
|
121
|
-
yes: true,
|
|
122
|
-
})
|
|
113
|
+
? await migrateResolvedConfig({ ...migrateOptions, yes: true })
|
|
123
114
|
: preview;
|
|
124
115
|
const human = [
|
|
125
116
|
'ZaoWu Config Migrate',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-handlers.js","sourceRoot":"","sources":["../../src/handlers/config-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,mBAAmB,EACnB,mBAAmB,EACnB,OAAO,EACP,mBAAmB,EACnB,aAAa,EACb,MAAM,EACN,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,MAAM,gBAAgB,GAAwB,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAC5E,MAAM,QAAQ,GAAG,MAAM,qBAAqB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG;QACd,aAAa,EAAE,CAAC;QAChB,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,QAAQ;KACf,CAAC;IAEF,OAAO,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,wBAAwB,QAAQ,EAAE,CAAC,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAwB,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAC5E,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG;QACd,aAAa,EAAE,QAAQ,CAAC,aAAa;QACrC,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;IACF,MAAM,KAAK,GAAG;QACZ,
|
|
1
|
+
{"version":3,"file":"config-handlers.js","sourceRoot":"","sources":["../../src/handlers/config-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/data-handlers.ts"],"names":[],"mappings":"AAQA,OAAO,EAYL,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,iBAAiB,EAAE,mBAgB/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,mBAkB/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,
|
|
1
|
+
{"version":3,"file":"data-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/data-handlers.ts"],"names":[],"mappings":"AAQA,OAAO,EAYL,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAE7B,eAAO,MAAM,iBAAiB,EAAE,mBAgB/B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,mBAkB/B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,mBA2D7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,mBAgB9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,mBAgB9B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,mBAY9B,CAAC"}
|
|
@@ -35,10 +35,11 @@ export const handleDataClean = async (args, context) => {
|
|
|
35
35
|
const target = requireTarget(args, 'zw data clean');
|
|
36
36
|
const outputPath = getValue(context.parsed, '--output');
|
|
37
37
|
const sheet = getValue(context.parsed, '--sheet');
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
38
|
+
// One options object for both the preview and the confirmed call: the
|
|
39
|
+
// fingerprint the user confirms is computed from the preview, so the two
|
|
40
|
+
// calls must be structurally unable to drift apart.
|
|
41
|
+
const cleanOptions = { outputPath, sheet };
|
|
42
|
+
const preview = await cleanData(target, cleanOptions);
|
|
42
43
|
const operationPlan = createOperationPlan({
|
|
43
44
|
risk: preview.outputPath ? 'medium' : 'low',
|
|
44
45
|
confirmationRequired: Boolean(preview.outputPath && !context.yes),
|
|
@@ -53,11 +54,7 @@ export const handleDataClean = async (args, context) => {
|
|
|
53
54
|
});
|
|
54
55
|
assertOperationPlanFingerprint(context, operationPlan);
|
|
55
56
|
const cleaned = context.yes && preview.outputPath
|
|
56
|
-
? await cleanData(target, {
|
|
57
|
-
outputPath,
|
|
58
|
-
sheet,
|
|
59
|
-
yes: true,
|
|
60
|
-
})
|
|
57
|
+
? await cleanData(target, { ...cleanOptions, yes: true })
|
|
61
58
|
: preview;
|
|
62
59
|
const confirmCommand = preview.outputPath && !context.yes
|
|
63
60
|
? formatConfirmCommand([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-handlers.js","sourceRoot":"","sources":["../../src/handlers/data-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,eAAe,EACf,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,EACnB,QAAQ,EACR,oBAAoB,EACpB,aAAa,EACb,MAAM,EACN,iBAAiB,GAElB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,CAAC,MAAM,iBAAiB,GAAwB,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAC5E,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE;QAC1C,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;KAC3C,CAAC,CAAC;IACH,MAAM,KAAK,GAAG;QACZ,oBAAoB;QACpB,EAAE;QACF,SAAS,SAAS,CAAC,QAAQ,EAAE;QAC7B,SAAS,SAAS,CAAC,QAAQ,EAAE;QAC7B,YAAY,SAAS,CAAC,WAAW,EAAE;QACnC,EAAE;QACF,YAAY,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAC3C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAwB,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAC5E,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE;QACzC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;KAC3C,CAAC,CAAC;IACH,MAAM,KAAK,GAAG;QACZ,oBAAoB;QACpB,EAAE;QACF,SAAS,QAAQ,CAAC,QAAQ,EAAE;QAC5B,oBAAoB,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE;QACpD,EAAE;QACF,GAAG,QAAQ,CAAC,cAAc,CAAC,GAAG,CAC5B,CAAC,MAAM,EAAE,EAAE,CACT,KAAK,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,KAAK,SAAS,MAAM,CAAC,GAAG,SAAS,MAAM,CAAC,GAAG,SAAS,MAAM,CAAC,OAAO,EAAE,CAC3G;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC1C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAwB,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAC1E,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"data-handlers.js","sourceRoot":"","sources":["../../src/handlers/data-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/dev-handlers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev-handlers.d.ts","sourceRoot":"","sources":["../../src/handlers/dev-handlers.ts"],"names":[],"mappings":"AAYA,OAAO,EAcL,KAAK,mBAAmB,EAIzB,MAAM,qBAAqB,CAAC;AA2F7B,eAAO,MAAM,eAAe,EAAE,mBA2E7B,CAAC;AAgBF,eAAO,MAAM,eAAe,EAAE,mBAuF7B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,mBA2B7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,mBA+C3B,CAAC"}
|
|
@@ -1,153 +1,153 @@
|
|
|
1
|
-
import { askAI
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
const getAiReviewOrCommit = async (context, prompt) => {
|
|
6
|
-
let providerId = getValue(context.parsed, '--provider');
|
|
7
|
-
if (!providerId) {
|
|
8
|
-
try {
|
|
9
|
-
const config = await loadResolvedConfig(context.cwd);
|
|
10
|
-
providerId = config.config.ai.provider ?? undefined;
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
// ignore — fall back to default provider
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const requestedModel = getValue(context.parsed, '--model');
|
|
17
|
-
const providerValidation = validateAIProviderConfig(providerId);
|
|
18
|
-
const provider = providerValidation.provider;
|
|
19
|
-
const resolvedModel = resolveAIModel(provider, { model: requestedModel });
|
|
20
|
-
if (provider.network && !context.yes) {
|
|
21
|
-
throw new ZaoWuError({
|
|
22
|
-
code: 'AI_NETWORK_CONFIRMATION_REQUIRED',
|
|
23
|
-
message: 'Network AI request requires confirmation.',
|
|
24
|
-
why: `The AI-assisted dev command sends diff context to the network provider \`${provider.id}\`.`,
|
|
25
|
-
fix: 'Run the command with the `--yes` flag to confirm sending the diff context.',
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
const response = await askAI({
|
|
29
|
-
prompt,
|
|
30
|
-
provider: providerId,
|
|
31
|
-
model: requestedModel,
|
|
32
|
-
allowNetwork: context.yes,
|
|
33
|
-
});
|
|
34
|
-
return {
|
|
35
|
-
output: response.output,
|
|
36
|
-
providerId: provider.id,
|
|
37
|
-
modelName: resolvedModel,
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
const getGitDiffText = (commandRunner, cwd, gitArgs) => {
|
|
41
|
-
let diffText = '';
|
|
1
|
+
import { askAI } from '@zaowu-labs/ai';
|
|
2
|
+
import { applyDevAiCommitSuggestion, buildDevAiCommitPrompt, buildDevAiReviewPrompt, getDevStatus, parseDevAiReviewFindings, previewDevCommit, reviewDevChanges, syncDevRepo, } from '@zaowu-labs/dev';
|
|
3
|
+
import { assertOperationPlanFingerprint, createContentOperationSubjects, createOperationPlan, formatConfirmCommand, formatCounts, formatFinding, formatList, formatOperationPlan, hasFlag, resolveAiProvider, result, withOperationPlan, ZaoWuError, } from '../handler-utils.js';
|
|
4
|
+
const getGitDiffText = (context, gitArgs) => {
|
|
42
5
|
try {
|
|
43
|
-
|
|
6
|
+
return context.commandRunner('git', gitArgs, { cwd: context.cwd });
|
|
44
7
|
}
|
|
45
8
|
catch {
|
|
46
9
|
// ignore — diff may be empty
|
|
10
|
+
return '';
|
|
47
11
|
}
|
|
48
|
-
if (diffText.length > 100000) {
|
|
49
|
-
diffText = diffText.slice(0, 100000) + '\n... [truncated] ...';
|
|
50
|
-
}
|
|
51
|
-
return diffText;
|
|
52
12
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Operation plan for an AI-assisted dev command. The exact prompt (instructions
|
|
15
|
+
* plus the truncated diff) is folded into the plan subjects, so the preview
|
|
16
|
+
* fingerprint only authorizes a confirmed run that sends identical content —
|
|
17
|
+
* a diff staged between preview and confirm invalidates the plan.
|
|
18
|
+
*/
|
|
19
|
+
const buildAiOperationPlan = (ai, prompt, context, options) => {
|
|
20
|
+
const actionName = options.isReview ? 'review' : 'suggestion';
|
|
57
21
|
return createOperationPlan({
|
|
58
|
-
risk: provider.network ? 'medium' : 'low',
|
|
59
|
-
|
|
60
|
-
|
|
22
|
+
risk: ai.provider.network ? 'medium' : 'low',
|
|
23
|
+
confirmationRequired: ai.provider.network && !context.yes,
|
|
24
|
+
subjects: [
|
|
25
|
+
`ai:${ai.providerId}`,
|
|
26
|
+
`model:${ai.resolvedModel}`,
|
|
27
|
+
...createContentOperationSubjects(prompt),
|
|
28
|
+
],
|
|
29
|
+
reads: options.isReview
|
|
30
|
+
? options.reviewUsesWorktree
|
|
61
31
|
? ['working-tree git diff', 'untracked git file list']
|
|
62
32
|
: ['staged git diff']
|
|
63
33
|
: ['staged git diff', 'staged git diff hunks'],
|
|
64
|
-
executes: isReview
|
|
65
|
-
? reviewUsesWorktree
|
|
34
|
+
executes: options.isReview
|
|
35
|
+
? options.reviewUsesWorktree
|
|
66
36
|
? ['git diff', 'git ls-files --others --exclude-standard']
|
|
67
37
|
: ['git diff --cached']
|
|
68
38
|
: ['git diff --cached'],
|
|
69
|
-
network: networkTarget ? [networkTarget] : [],
|
|
70
|
-
secrets: provider.requiredEnv,
|
|
71
|
-
notes: [
|
|
39
|
+
network: ai.networkTarget ? [ai.networkTarget] : [],
|
|
40
|
+
secrets: ai.provider.requiredEnv,
|
|
41
|
+
notes: [
|
|
42
|
+
ai.provider.network
|
|
43
|
+
? `AI ${actionName} sends the diff context to the ${ai.providerId} provider and requires --yes.`
|
|
44
|
+
: `AI ${actionName} was generated using the ${ai.providerId} provider.`,
|
|
45
|
+
],
|
|
72
46
|
});
|
|
73
47
|
};
|
|
48
|
+
const buildAiConfirmCommand = (commandParts, ai, operationPlan) => formatConfirmCommand([
|
|
49
|
+
...commandParts,
|
|
50
|
+
'--ai',
|
|
51
|
+
'--provider',
|
|
52
|
+
ai.providerId,
|
|
53
|
+
...(ai.requestedModel ? ['--model', ai.requestedModel] : []),
|
|
54
|
+
'--yes',
|
|
55
|
+
'--plan-fingerprint',
|
|
56
|
+
operationPlan.fingerprint,
|
|
57
|
+
]);
|
|
58
|
+
const formatAiPreviewHuman = (title, ai, operationPlan, confirmCommand) => [
|
|
59
|
+
title,
|
|
60
|
+
'',
|
|
61
|
+
'Status: preview',
|
|
62
|
+
`Provider: ${ai.providerId} (${ai.provider.name})`,
|
|
63
|
+
`Model: ${ai.resolvedModel}`,
|
|
64
|
+
`Endpoint: ${ai.networkTarget ?? 'local'}`,
|
|
65
|
+
'',
|
|
66
|
+
formatOperationPlan(operationPlan),
|
|
67
|
+
'',
|
|
68
|
+
'No provider request was sent.',
|
|
69
|
+
'',
|
|
70
|
+
'To send exactly this AI request, run:',
|
|
71
|
+
` ${confirmCommand}`,
|
|
72
|
+
].join('\n');
|
|
74
73
|
export const handleDevCommit = async (_args, context) => {
|
|
75
74
|
const preview = previewDevCommit(context.commandRunner, { cwd: context.cwd });
|
|
75
|
+
let payload = preview;
|
|
76
76
|
let operationPlan = createOperationPlan({
|
|
77
77
|
risk: 'low',
|
|
78
78
|
reads: ['staged git diff', 'staged git diff hunks'],
|
|
79
79
|
executes: ['git diff --cached'],
|
|
80
80
|
notes: ['No Git state is modified.'],
|
|
81
81
|
});
|
|
82
|
-
if (context.parsed
|
|
83
|
-
const diffText = getGitDiffText(context
|
|
84
|
-
const prompt =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
title,
|
|
108
|
-
body: body.length > 0 ? body : preview.suggestion.body,
|
|
109
|
-
};
|
|
110
|
-
preview.message = title;
|
|
111
|
-
operationPlan = buildAiOperationPlan(aiResponse.providerId, false, false);
|
|
82
|
+
if (hasFlag(context.parsed, '--ai')) {
|
|
83
|
+
const diffText = getGitDiffText(context, ['diff', '--cached']);
|
|
84
|
+
const prompt = buildDevAiCommitPrompt(diffText);
|
|
85
|
+
const ai = await resolveAiProvider(context);
|
|
86
|
+
operationPlan = buildAiOperationPlan(ai, prompt, context, {
|
|
87
|
+
isReview: false,
|
|
88
|
+
reviewUsesWorktree: false,
|
|
89
|
+
});
|
|
90
|
+
if (ai.provider.network && !context.yes) {
|
|
91
|
+
const confirmCommand = buildAiConfirmCommand(['zw', 'dev', 'commit'], ai, operationPlan);
|
|
92
|
+
const human = formatAiPreviewHuman('ZaoWu Dev Commit', ai, operationPlan, confirmCommand);
|
|
93
|
+
return result(context, withOperationPlan({ ...preview, status: 'preview' }, operationPlan), human);
|
|
94
|
+
}
|
|
95
|
+
// The fingerprint must be verified before any provider request is sent.
|
|
96
|
+
assertOperationPlanFingerprint(context, operationPlan);
|
|
97
|
+
const response = await askAI({
|
|
98
|
+
prompt,
|
|
99
|
+
provider: ai.providerId,
|
|
100
|
+
model: ai.requestedModel,
|
|
101
|
+
allowNetwork: context.yes,
|
|
102
|
+
});
|
|
103
|
+
payload = applyDevAiCommitSuggestion(preview, response.output);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
assertOperationPlanFingerprint(context, operationPlan);
|
|
112
107
|
}
|
|
113
|
-
assertOperationPlanFingerprint(context, operationPlan);
|
|
114
108
|
const human = [
|
|
115
109
|
'ZaoWu Dev Commit',
|
|
116
110
|
'',
|
|
117
111
|
'No Git state was modified.',
|
|
118
112
|
'',
|
|
119
|
-
`Files: ${
|
|
120
|
-
`Changes: +${
|
|
113
|
+
`Files: ${payload.summary.files.length}`,
|
|
114
|
+
`Changes: +${payload.summary.additions}/-${payload.summary.deletions}`,
|
|
121
115
|
'',
|
|
122
116
|
'Categories:',
|
|
123
|
-
formatCounts(
|
|
117
|
+
formatCounts(payload.summary.categories),
|
|
124
118
|
'',
|
|
125
119
|
'Suggested commit:',
|
|
126
|
-
|
|
120
|
+
payload.message,
|
|
127
121
|
'',
|
|
128
122
|
'Suggested body:',
|
|
129
|
-
formatList(
|
|
123
|
+
formatList(payload.suggestion.body),
|
|
130
124
|
'',
|
|
131
125
|
'Findings:',
|
|
132
|
-
...(
|
|
133
|
-
?
|
|
126
|
+
...(payload.findings.length > 0
|
|
127
|
+
? payload.findings.map((finding) => formatFinding(finding))
|
|
134
128
|
: ['- none']),
|
|
135
129
|
'',
|
|
136
130
|
'Recommended checks:',
|
|
137
|
-
formatList(
|
|
131
|
+
formatList(payload.recommendedChecks),
|
|
138
132
|
'',
|
|
139
133
|
formatOperationPlan(operationPlan),
|
|
140
134
|
].join('\n');
|
|
141
|
-
return result(context, withOperationPlan(
|
|
135
|
+
return result(context, withOperationPlan(payload, operationPlan), human);
|
|
136
|
+
};
|
|
137
|
+
const resolveReviewMode = (context) => {
|
|
138
|
+
if (hasFlag(context.parsed, '--staged')) {
|
|
139
|
+
return { mode: 'staged', modeFlags: ['--staged'] };
|
|
140
|
+
}
|
|
141
|
+
if (hasFlag(context.parsed, '--worktree')) {
|
|
142
|
+
return { mode: 'worktree', modeFlags: ['--worktree'] };
|
|
143
|
+
}
|
|
144
|
+
return { mode: 'auto', modeFlags: [] };
|
|
142
145
|
};
|
|
143
146
|
export const handleDevReview = async (_args, context) => {
|
|
144
|
-
const mode = context
|
|
145
|
-
? 'staged'
|
|
146
|
-
: context.parsed.flags.has('--worktree')
|
|
147
|
-
? 'worktree'
|
|
148
|
-
: 'auto';
|
|
147
|
+
const { mode, modeFlags } = resolveReviewMode(context);
|
|
149
148
|
const review = reviewDevChanges(context.commandRunner, { cwd: context.cwd, mode });
|
|
150
149
|
const reviewUsesWorktree = review.source === 'working-tree';
|
|
150
|
+
let payload = review;
|
|
151
151
|
let operationPlan = createOperationPlan({
|
|
152
152
|
risk: 'low',
|
|
153
153
|
reads: reviewUsesWorktree
|
|
@@ -158,100 +158,60 @@ export const handleDevReview = async (_args, context) => {
|
|
|
158
158
|
: ['git diff --cached'],
|
|
159
159
|
notes: ['No Git state is modified.'],
|
|
160
160
|
});
|
|
161
|
-
if (context.parsed
|
|
161
|
+
if (hasFlag(context.parsed, '--ai')) {
|
|
162
162
|
const gitArgs = reviewUsesWorktree ? ['diff'] : ['diff', '--cached'];
|
|
163
|
-
const diffText = getGitDiffText(context
|
|
164
|
-
const prompt =
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
' "detail": "Detailed explanation of the issue and fix.",',
|
|
175
|
-
' "filePath": "relative/path/to/file",',
|
|
176
|
-
' "line": 123,',
|
|
177
|
-
' "hunkHeader": "@@ ... @@"',
|
|
178
|
-
' }',
|
|
179
|
-
']',
|
|
180
|
-
'Respond ONLY with the JSON array. Do not wrap in markdown code blocks.',
|
|
181
|
-
'',
|
|
182
|
-
'Changes:',
|
|
183
|
-
diffText,
|
|
184
|
-
].join('\n');
|
|
185
|
-
const aiResponse = await getAiReviewOrCommit(context, prompt);
|
|
186
|
-
let cleanOutput = aiResponse.output.trim();
|
|
187
|
-
if (cleanOutput.startsWith('```')) {
|
|
188
|
-
cleanOutput = cleanOutput.replace(/^```[a-z]*\r?\n/, '').replace(/\r?\n```$/, '');
|
|
189
|
-
}
|
|
190
|
-
let aiFindings = [];
|
|
191
|
-
let isParsedArray = false;
|
|
192
|
-
try {
|
|
193
|
-
const parsed = JSON.parse(cleanOutput);
|
|
194
|
-
if (Array.isArray(parsed)) {
|
|
195
|
-
aiFindings = parsed;
|
|
196
|
-
isParsedArray = true;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
// Fall back to wrapping the raw AI output as a plain-text summary finding.
|
|
201
|
-
}
|
|
202
|
-
if (!isParsedArray) {
|
|
203
|
-
aiFindings = [
|
|
204
|
-
{
|
|
205
|
-
severity: 'info',
|
|
206
|
-
priority: 'medium',
|
|
207
|
-
category: 'quality',
|
|
208
|
-
title: 'AI Code Review Summary',
|
|
209
|
-
detail: aiResponse.output.trim(),
|
|
210
|
-
},
|
|
211
|
-
];
|
|
212
|
-
}
|
|
213
|
-
for (const item of aiFindings) {
|
|
214
|
-
const finding = item && typeof item === 'object' ? item : {};
|
|
215
|
-
review.findings.push({
|
|
216
|
-
severity: isDevFindingSeverity(finding.severity) ? finding.severity : 'info',
|
|
217
|
-
priority: isDevFindingPriority(finding.priority) ? finding.priority : 'medium',
|
|
218
|
-
category: isDevFindingCategory(finding.category) ? finding.category : 'quality',
|
|
219
|
-
title: typeof finding.title === 'string' ? finding.title : 'AI Review',
|
|
220
|
-
detail: typeof finding.detail === 'string' ? finding.detail : '',
|
|
221
|
-
filePath: typeof finding.filePath === 'string' ? finding.filePath : undefined,
|
|
222
|
-
line: Number.isInteger(finding.line) && Number(finding.line) > 0
|
|
223
|
-
? Number(finding.line)
|
|
224
|
-
: undefined,
|
|
225
|
-
hunkHeader: typeof finding.hunkHeader === 'string' ? finding.hunkHeader : undefined,
|
|
226
|
-
});
|
|
163
|
+
const diffText = getGitDiffText(context, gitArgs);
|
|
164
|
+
const prompt = buildDevAiReviewPrompt(diffText);
|
|
165
|
+
const ai = await resolveAiProvider(context);
|
|
166
|
+
operationPlan = buildAiOperationPlan(ai, prompt, context, {
|
|
167
|
+
isReview: true,
|
|
168
|
+
reviewUsesWorktree,
|
|
169
|
+
});
|
|
170
|
+
if (ai.provider.network && !context.yes) {
|
|
171
|
+
const confirmCommand = buildAiConfirmCommand(['zw', 'dev', 'review', ...modeFlags], ai, operationPlan);
|
|
172
|
+
const human = formatAiPreviewHuman('ZaoWu Dev Review', ai, operationPlan, confirmCommand);
|
|
173
|
+
return result(context, withOperationPlan({ ...review, status: 'preview' }, operationPlan), human);
|
|
227
174
|
}
|
|
228
|
-
|
|
175
|
+
// The fingerprint must be verified before any provider request is sent.
|
|
176
|
+
assertOperationPlanFingerprint(context, operationPlan);
|
|
177
|
+
const response = await askAI({
|
|
178
|
+
prompt,
|
|
179
|
+
provider: ai.providerId,
|
|
180
|
+
model: ai.requestedModel,
|
|
181
|
+
allowNetwork: context.yes,
|
|
182
|
+
});
|
|
183
|
+
payload = {
|
|
184
|
+
...review,
|
|
185
|
+
findings: [...review.findings, ...parseDevAiReviewFindings(response.output)],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
assertOperationPlanFingerprint(context, operationPlan);
|
|
229
190
|
}
|
|
230
|
-
assertOperationPlanFingerprint(context, operationPlan);
|
|
231
191
|
const human = [
|
|
232
192
|
'ZaoWu Dev Review',
|
|
233
193
|
'',
|
|
234
|
-
`Source: ${
|
|
235
|
-
`Files: ${
|
|
236
|
-
`Changes: +${
|
|
194
|
+
`Source: ${payload.source}`,
|
|
195
|
+
`Files: ${payload.summary.files.length}`,
|
|
196
|
+
`Changes: +${payload.summary.additions}/-${payload.summary.deletions}`,
|
|
237
197
|
'',
|
|
238
198
|
'Categories:',
|
|
239
|
-
formatCounts(
|
|
199
|
+
formatCounts(payload.summary.categories),
|
|
240
200
|
'',
|
|
241
201
|
'Findings:',
|
|
242
|
-
...
|
|
202
|
+
...payload.findings.map((finding) => formatFinding(finding)),
|
|
243
203
|
'',
|
|
244
204
|
'Diff hunks:',
|
|
245
|
-
...(
|
|
246
|
-
?
|
|
205
|
+
...(payload.diffHunks.length > 0
|
|
206
|
+
? payload.diffHunks.map((hunk) => `- ${hunk.filePath} ${hunk.header}: +${hunk.addedLines}/-${hunk.removedLines}`)
|
|
247
207
|
: ['- none']),
|
|
248
208
|
'',
|
|
249
209
|
'Recommended checks:',
|
|
250
|
-
formatList(
|
|
210
|
+
formatList(payload.recommendedChecks),
|
|
251
211
|
'',
|
|
252
212
|
formatOperationPlan(operationPlan),
|
|
253
213
|
].join('\n');
|
|
254
|
-
return result(context, withOperationPlan(
|
|
214
|
+
return result(context, withOperationPlan(payload, operationPlan), human);
|
|
255
215
|
};
|
|
256
216
|
export const handleDevStatus = async (_args, context) => {
|
|
257
217
|
const status = getDevStatus(context.commandRunner, { cwd: context.cwd });
|
|
@@ -297,13 +257,15 @@ export const handleDevSync = async (_args, context) => {
|
|
|
297
257
|
: preview;
|
|
298
258
|
const operationPlan = syncResult.operationPlan ?? preview.operationPlan;
|
|
299
259
|
const requiresDiscardLocal = operationPlan.notes.some((note) => note.includes('Confirmed sync requires both --yes and --discard-local'));
|
|
300
|
-
const confirmCommand = [
|
|
301
|
-
'zw
|
|
260
|
+
const confirmCommand = formatConfirmCommand([
|
|
261
|
+
'zw',
|
|
262
|
+
'dev',
|
|
263
|
+
'sync',
|
|
302
264
|
'--yes',
|
|
303
265
|
...(requiresDiscardLocal ? ['--discard-local'] : []),
|
|
304
266
|
'--plan-fingerprint',
|
|
305
267
|
operationPlan.fingerprint,
|
|
306
|
-
]
|
|
268
|
+
]);
|
|
307
269
|
const human = [
|
|
308
270
|
'ZaoWu Dev Sync',
|
|
309
271
|
'',
|