@kb-labs/commit-cli 0.5.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/README.md +120 -0
- package/dist/cli/commands/apply.d.ts +22 -0
- package/dist/cli/commands/apply.js +132 -0
- package/dist/cli/commands/apply.js.map +1 -0
- package/dist/cli/commands/flags.d.ts +99 -0
- package/dist/cli/commands/flags.js +73 -0
- package/dist/cli/commands/flags.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +45 -0
- package/dist/cli/commands/generate.js +149 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.js +73 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/open.d.ts +50 -0
- package/dist/cli/commands/open.js +80 -0
- package/dist/cli/commands/open.js.map +1 -0
- package/dist/cli/commands/push.d.ts +18 -0
- package/dist/cli/commands/push.js +71 -0
- package/dist/cli/commands/push.js.map +1 -0
- package/dist/cli/commands/reset.d.ts +15 -0
- package/dist/cli/commands/reset.js +52 -0
- package/dist/cli/commands/reset.js.map +1 -0
- package/dist/cli/commands/run.d.ts +51 -0
- package/dist/cli/commands/run.js +190 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +916 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/setup.d.ts +53 -0
- package/dist/lifecycle/setup.js +96 -0
- package/dist/lifecycle/setup.js.map +1 -0
- package/dist/manifest.d.ts +207 -0
- package/dist/manifest.js +833 -0
- package/dist/manifest.js.map +1 -0
- package/dist/rest/handlers/actions-handler.d.ts +16 -0
- package/dist/rest/handlers/actions-handler.js +15 -0
- package/dist/rest/handlers/actions-handler.js.map +1 -0
- package/dist/rest/handlers/apply-handler.d.ts +26 -0
- package/dist/rest/handlers/apply-handler.js +115 -0
- package/dist/rest/handlers/apply-handler.js.map +1 -0
- package/dist/rest/handlers/diff-handler.d.ts +20 -0
- package/dist/rest/handlers/diff-handler.js +64 -0
- package/dist/rest/handlers/diff-handler.js.map +1 -0
- package/dist/rest/handlers/files-handler.d.ts +16 -0
- package/dist/rest/handlers/files-handler.js +143 -0
- package/dist/rest/handlers/files-handler.js.map +1 -0
- package/dist/rest/handlers/generate-handler.d.ts +66 -0
- package/dist/rest/handlers/generate-handler.js +97 -0
- package/dist/rest/handlers/generate-handler.js.map +1 -0
- package/dist/rest/handlers/git-status-handler.d.ts +13 -0
- package/dist/rest/handlers/git-status-handler.js +58 -0
- package/dist/rest/handlers/git-status-handler.js.map +1 -0
- package/dist/rest/handlers/patch-plan-handler.d.ts +23 -0
- package/dist/rest/handlers/patch-plan-handler.js +50 -0
- package/dist/rest/handlers/patch-plan-handler.js.map +1 -0
- package/dist/rest/handlers/plan-handler.d.ts +50 -0
- package/dist/rest/handlers/plan-handler.js +32 -0
- package/dist/rest/handlers/plan-handler.js.map +1 -0
- package/dist/rest/handlers/push-handler.d.ts +25 -0
- package/dist/rest/handlers/push-handler.js +75 -0
- package/dist/rest/handlers/push-handler.js.map +1 -0
- package/dist/rest/handlers/regenerate-handler.d.ts +37 -0
- package/dist/rest/handlers/regenerate-handler.js +124 -0
- package/dist/rest/handlers/regenerate-handler.js.map +1 -0
- package/dist/rest/handlers/reset-handler.d.ts +17 -0
- package/dist/rest/handlers/reset-handler.js +30 -0
- package/dist/rest/handlers/reset-handler.js.map +1 -0
- package/dist/rest/handlers/scope-resolver.d.ts +15 -0
- package/dist/rest/handlers/scope-resolver.js +12 -0
- package/dist/rest/handlers/scope-resolver.js.map +1 -0
- package/dist/rest/handlers/scopes-handler.d.ts +12 -0
- package/dist/rest/handlers/scopes-handler.js +24 -0
- package/dist/rest/handlers/scopes-handler.js.map +1 -0
- package/dist/rest/handlers/status-handler.d.ts +27 -0
- package/dist/rest/handlers/status-handler.js +91 -0
- package/dist/rest/handlers/status-handler.js.map +1 -0
- package/dist/rest/handlers/summarize-handler.d.ts +21 -0
- package/dist/rest/handlers/summarize-handler.js +106 -0
- package/dist/rest/handlers/summarize-handler.js.map +1 -0
- package/dist/widgets/220.js +446 -0
- package/dist/widgets/220.js.map +1 -0
- package/dist/widgets/331.js +2 -0
- package/dist/widgets/331.js.map +1 -0
- package/dist/widgets/403.js +2 -0
- package/dist/widgets/403.js.map +1 -0
- package/dist/widgets/406.js +35 -0
- package/dist/widgets/406.js.map +1 -0
- package/dist/widgets/455.js +2 -0
- package/dist/widgets/455.js.map +1 -0
- package/dist/widgets/482.js +2 -0
- package/dist/widgets/482.js.map +1 -0
- package/dist/widgets/485.js +2 -0
- package/dist/widgets/485.js.map +1 -0
- package/dist/widgets/527.js +2 -0
- package/dist/widgets/527.js.map +1 -0
- package/dist/widgets/628.js +2 -0
- package/dist/widgets/628.js.map +1 -0
- package/dist/widgets/694.js +2 -0
- package/dist/widgets/694.js.map +1 -0
- package/dist/widgets/712.js +2 -0
- package/dist/widgets/712.js.map +1 -0
- package/dist/widgets/866.js +2 -0
- package/dist/widgets/866.js.map +1 -0
- package/dist/widgets/915.js +39 -0
- package/dist/widgets/915.js.map +1 -0
- package/dist/widgets/957.js +10 -0
- package/dist/widgets/957.js.map +1 -0
- package/dist/widgets/983.js +2 -0
- package/dist/widgets/983.js.map +1 -0
- package/dist/widgets/@mf-types.d.ts +3 -0
- package/dist/widgets/@mf-types.zip +0 -0
- package/dist/widgets/__federation_expose_CommitOverview.js +2 -0
- package/dist/widgets/__federation_expose_CommitOverview.js.map +1 -0
- package/dist/widgets/mf-manifest.json +260 -0
- package/dist/widgets/mf-stats.json +302 -0
- package/dist/widgets/remoteEntry.js +7 -0
- package/dist/widgets/remoteEntry.js.map +1 -0
- package/package.json +95 -0
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# @kb-labs/plugin-template-cli
|
|
2
|
+
|
|
3
|
+
Reference CLI/REST/Studio plugin package for KB Labs Plugin Template.
|
|
4
|
+
|
|
5
|
+
## Vision & Purpose
|
|
6
|
+
|
|
7
|
+
**@kb-labs/plugin-template-cli** is the canonical example plugin package used by `@kb-labs/plugin-template`.
|
|
8
|
+
It shows how to implement a plugin that exposes:
|
|
9
|
+
|
|
10
|
+
- a **CLI command** (Hello),
|
|
11
|
+
- a **REST handler**, and
|
|
12
|
+
- a **Studio widget**,
|
|
13
|
+
|
|
14
|
+
all driven by a single manifest and contracts package.
|
|
15
|
+
|
|
16
|
+
## Package Status
|
|
17
|
+
|
|
18
|
+
- **Version**: 0.1.0
|
|
19
|
+
- **Stage**: Stable (template)
|
|
20
|
+
- **Status**: Reference Implementation ✅
|
|
21
|
+
|
|
22
|
+
## Architecture
|
|
23
|
+
|
|
24
|
+
### High-Level Overview
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
plugin-cli
|
|
28
|
+
│
|
|
29
|
+
├──► contracts (from @kb-labs/plugin-template-contracts)
|
|
30
|
+
├──► shared (constants/helpers)
|
|
31
|
+
├──► domain (Greeting entity and invariants)
|
|
32
|
+
├──► application (use-cases: create greeting, etc.)
|
|
33
|
+
├──► cli (Hello command wiring)
|
|
34
|
+
├──► rest (Hello REST handler + schema)
|
|
35
|
+
└──► studio (Hello Studio widget)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Key Components
|
|
39
|
+
|
|
40
|
+
- `src/domain/`: `Greeting` entity and domain rules
|
|
41
|
+
- `src/application/`: use-cases that orchestrate domain logic
|
|
42
|
+
- `src/cli/commands/hello/*`: CLI command implementation
|
|
43
|
+
- `src/rest/handlers/hello-handler.ts`: REST handler bound to manifest
|
|
44
|
+
- `src/studio/widgets/hello-widget.tsx`: Studio widget implementation
|
|
45
|
+
- `src/manifest.v2.ts`: Plugin manifest v2 (CLI/REST/Studio wiring)
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Single-source manifest** for CLI/REST/Studio surfaces
|
|
50
|
+
- **Layered architecture** (shared → domain → application → interface)
|
|
51
|
+
- **Type-safe contracts** via `@kb-labs/plugin-template-contracts`
|
|
52
|
+
- **Hello-world flow** demonstrating end-to-end plugin wiring
|
|
53
|
+
|
|
54
|
+
## Exports
|
|
55
|
+
|
|
56
|
+
From `src/index.ts`:
|
|
57
|
+
|
|
58
|
+
- `manifest`: Plugin Manifest V2
|
|
59
|
+
- All public surfaces:
|
|
60
|
+
- CLI command exports
|
|
61
|
+
- domain/application/shared re-exports
|
|
62
|
+
|
|
63
|
+
## Dependencies
|
|
64
|
+
|
|
65
|
+
### Runtime
|
|
66
|
+
|
|
67
|
+
- `@kb-labs/setup-operations`: reusable setup operations
|
|
68
|
+
- `@kb-labs/plugin-manifest`: manifest types and helpers
|
|
69
|
+
- `@kb-labs/plugin-template-contracts`: public contracts for this template plugin
|
|
70
|
+
- `@kb-labs/shared-cli-ui`: shared CLI UI helpers
|
|
71
|
+
- `react`, `react-dom`, `zod`
|
|
72
|
+
|
|
73
|
+
### Development
|
|
74
|
+
|
|
75
|
+
- `@kb-labs/devkit`: shared TS/ESLint/Vitest/TSUP presets
|
|
76
|
+
- `typescript`, `tsup`, `vitest`, `rimraf`
|
|
77
|
+
|
|
78
|
+
## Scripts
|
|
79
|
+
|
|
80
|
+
From `kb-labs-plugin-template` repo root:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm install
|
|
84
|
+
pnpm --filter @kb-labs/plugin-template-cli build
|
|
85
|
+
pnpm --filter @kb-labs/plugin-template-cli test
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
To run sandboxes, see the root `README.md` (`pnpm sandbox:cli`, `sandbox:rest`, `sandbox:studio`).
|
|
89
|
+
|
|
90
|
+
## Command Implementation
|
|
91
|
+
|
|
92
|
+
This template demonstrates **three different approaches** to implementing CLI commands:
|
|
93
|
+
|
|
94
|
+
1. **High-level wrapper (`defineCommand`)** - Recommended for most cases
|
|
95
|
+
2. **Low-level atomic tools** - For maximum control
|
|
96
|
+
3. **Hybrid approach** - Combining both
|
|
97
|
+
|
|
98
|
+
See [`COMMAND_IMPLEMENTATION_GUIDE.md`](./COMMAND_IMPLEMENTATION_GUIDE.md) for detailed explanations and examples.
|
|
99
|
+
|
|
100
|
+
### Quick Start
|
|
101
|
+
|
|
102
|
+
The `template:hello` command in `src/cli/commands/hello/run.ts` shows all three approaches with working code examples. The default implementation uses Approach 1 (`defineCommand`), which provides:
|
|
103
|
+
|
|
104
|
+
- ✅ Zero-boilerplate flag validation
|
|
105
|
+
- ✅ Automatic analytics integration
|
|
106
|
+
- ✅ Structured logging
|
|
107
|
+
- ✅ Error handling
|
|
108
|
+
- ✅ Timing tracking
|
|
109
|
+
- ✅ JSON output mode
|
|
110
|
+
|
|
111
|
+
## Customising for Your Plugin
|
|
112
|
+
|
|
113
|
+
When using this as a starting point:
|
|
114
|
+
|
|
115
|
+
- Rename the package in `package.json` (e.g. `@kb-labs/my-plugin-cli`)
|
|
116
|
+
- Update manifest IDs and the contracts package
|
|
117
|
+
- Replace the Hello flow with your own domain, use-cases, and surfaces
|
|
118
|
+
- Choose the command implementation approach that fits your needs (see `COMMAND_IMPLEMENTATION_GUIDE.md`)
|
|
119
|
+
|
|
120
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* commit:apply command
|
|
5
|
+
* Apply current commit plan
|
|
6
|
+
*/
|
|
7
|
+
type ApplyInput = {
|
|
8
|
+
force?: boolean;
|
|
9
|
+
json?: boolean;
|
|
10
|
+
scope?: string;
|
|
11
|
+
};
|
|
12
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, ApplyInput, {
|
|
13
|
+
commits: {
|
|
14
|
+
message: string;
|
|
15
|
+
id: string;
|
|
16
|
+
sha: string;
|
|
17
|
+
}[];
|
|
18
|
+
success: boolean;
|
|
19
|
+
errors: string[];
|
|
20
|
+
}>;
|
|
21
|
+
|
|
22
|
+
export { _default as default };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { defineCommand, findRepoRoot, useConfig, useLoader } from '@kb-labs/sdk';
|
|
2
|
+
import { loadPlan, applyCommitPlan, saveToHistory, clearPlan } from '@kb-labs/commit-core';
|
|
3
|
+
import { resolveCommitConfig } from '@kb-labs/commit-contracts';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
|
|
6
|
+
// src/cli/commands/apply.ts
|
|
7
|
+
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
|
|
8
|
+
const scopeDef = scopes?.find((s) => s.id === scopeId);
|
|
9
|
+
const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
|
|
10
|
+
return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// src/cli/commands/apply.ts
|
|
14
|
+
var apply_default = defineCommand({
|
|
15
|
+
id: "commit:apply",
|
|
16
|
+
description: "Apply current commit plan",
|
|
17
|
+
handler: {
|
|
18
|
+
async execute(ctx, input) {
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
const cwd = await findRepoRoot(ctx.cwd || process.cwd()) ?? process.cwd();
|
|
21
|
+
const scope = input.scope ?? "root";
|
|
22
|
+
const fileConfig = await useConfig();
|
|
23
|
+
const config = resolveCommitConfig(fileConfig ?? {});
|
|
24
|
+
const scopeCwd = resolveScopePath(cwd, scope, config.scope?.scopes);
|
|
25
|
+
const loadLoader = useLoader("Loading commit plan...");
|
|
26
|
+
loadLoader.start();
|
|
27
|
+
const plan = await loadPlan(cwd, scope);
|
|
28
|
+
if (!plan) {
|
|
29
|
+
loadLoader.fail("No commit plan found");
|
|
30
|
+
ctx.ui?.error?.("Run `kb commit:generate` first.");
|
|
31
|
+
return {
|
|
32
|
+
exitCode: 1
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
if (plan.commits.length === 0) {
|
|
36
|
+
loadLoader.stop();
|
|
37
|
+
ctx.ui?.warn?.("Commit plan is empty. Nothing to apply.");
|
|
38
|
+
return {
|
|
39
|
+
exitCode: 0,
|
|
40
|
+
result: {
|
|
41
|
+
success: true,
|
|
42
|
+
commits: [],
|
|
43
|
+
errors: []
|
|
44
|
+
},
|
|
45
|
+
meta: {
|
|
46
|
+
timing: Date.now() - startTime
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
loadLoader.succeed(`Loaded plan with ${plan.commits.length} commit(s)`);
|
|
51
|
+
const applyLoader = useLoader(`Applying ${plan.commits.length} commit(s)...`);
|
|
52
|
+
applyLoader.start();
|
|
53
|
+
const result = await applyCommitPlan(scopeCwd, plan, {
|
|
54
|
+
force: input.force
|
|
55
|
+
});
|
|
56
|
+
if (result.success) {
|
|
57
|
+
await saveToHistory(cwd, plan, result, scope);
|
|
58
|
+
await clearPlan(cwd, scope);
|
|
59
|
+
applyLoader.succeed(`Applied ${result.appliedCommits.length} commit(s) successfully`);
|
|
60
|
+
} else {
|
|
61
|
+
applyLoader.fail("Failed to apply commits");
|
|
62
|
+
}
|
|
63
|
+
const output = {
|
|
64
|
+
success: result.success,
|
|
65
|
+
commits: result.appliedCommits.map((c) => ({
|
|
66
|
+
id: c.groupId,
|
|
67
|
+
sha: c.sha,
|
|
68
|
+
message: c.message
|
|
69
|
+
})),
|
|
70
|
+
errors: result.errors
|
|
71
|
+
};
|
|
72
|
+
if (input.json) {
|
|
73
|
+
ctx.ui?.json?.(output);
|
|
74
|
+
} else {
|
|
75
|
+
if (result.success) {
|
|
76
|
+
const commitsItems = result.appliedCommits.map((commit) => {
|
|
77
|
+
return `${commit.sha.substring(0, 7)} ${commit.message}`;
|
|
78
|
+
});
|
|
79
|
+
const sections = [];
|
|
80
|
+
if (commitsItems.length > 0) {
|
|
81
|
+
sections.push({
|
|
82
|
+
header: "Applied Commits",
|
|
83
|
+
items: commitsItems
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const summaryItems = [
|
|
87
|
+
`Total commits: ${result.appliedCommits.length}`,
|
|
88
|
+
"Status: \u2705 Success"
|
|
89
|
+
];
|
|
90
|
+
sections.unshift({
|
|
91
|
+
header: "Summary",
|
|
92
|
+
items: summaryItems
|
|
93
|
+
});
|
|
94
|
+
const timing = Date.now() - startTime;
|
|
95
|
+
ctx.ui?.success?.("Commits applied successfully", {
|
|
96
|
+
title: "Apply Commit Plan",
|
|
97
|
+
sections,
|
|
98
|
+
timing
|
|
99
|
+
});
|
|
100
|
+
} else {
|
|
101
|
+
const errorItems = result.errors.map((error) => error);
|
|
102
|
+
const timing = Date.now() - startTime;
|
|
103
|
+
ctx.ui?.error?.("Failed to apply commits", {
|
|
104
|
+
title: "Apply Commit Plan",
|
|
105
|
+
sections: [
|
|
106
|
+
{
|
|
107
|
+
header: "Summary",
|
|
108
|
+
items: [`Total errors: ${result.errors.length}`]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
header: "Errors",
|
|
112
|
+
items: errorItems
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
timing
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
exitCode: result.success ? 0 : 1,
|
|
121
|
+
result: output,
|
|
122
|
+
meta: {
|
|
123
|
+
timing: Date.now() - startTime
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
export { apply_default as default };
|
|
131
|
+
//# sourceMappingURL=apply.js.map
|
|
132
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/rest/handlers/scope-resolver.ts","../../../src/cli/commands/apply.ts"],"names":[],"mappings":"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","file":"apply.js","sourcesContent":["import * as path from 'node:path';\nimport type { CommitScope } from '@kb-labs/commit-contracts';\n\n/**\n * Resolves a scope id to an absolute filesystem path.\n *\n * Looks up the scope in the provided scopes array by id.\n * Falls back to treating the id as a relative path from baseCwd (legacy compat).\n *\n * @param baseCwd - Workspace root (ctx.cwd)\n * @param scopeId - Scope identifier, e.g. \"root\", \"public/kb-labs\"\n * @param scopes - Configured scopes from CommitPluginConfig.scope.scopes\n */\nexport function resolveScopePath(\n baseCwd: string,\n scopeId: string = 'root',\n scopes?: CommitScope[],\n): string {\n const scopeDef = scopes?.find((s) => s.id === scopeId);\n const relativePath = scopeDef?.path ?? (scopeId === 'root' ? '.' : scopeId);\n return relativePath === '.' ? baseCwd : path.join(baseCwd, relativePath);\n}\n","/**\n * commit:apply command\n * Apply current commit plan\n */\n\nimport { defineCommand, useLoader, useConfig, findRepoRoot, type PluginContextV3 } from '@kb-labs/sdk';\nimport {\n applyCommitPlan,\n loadPlan,\n saveToHistory,\n clearPlan,\n} from '@kb-labs/commit-core';\nimport type { ApplyOutput, CommitPluginConfig } from '@kb-labs/commit-contracts';\nimport { resolveCommitConfig } from '@kb-labs/commit-contracts';\nimport { resolveScopePath } from '../../rest/handlers/scope-resolver';\n\ntype ApplyInput = {\n force?: boolean;\n json?: boolean;\n scope?: string;\n};\n\ntype ApplyResult = {\n exitCode: number;\n result?: ApplyOutput;\n meta?: Record<string, unknown>;\n};\n\nexport default defineCommand({\n id: 'commit:apply',\n description: 'Apply current commit plan',\n\n handler: {\n async execute(ctx: PluginContextV3, input: ApplyInput): Promise<ApplyResult> {\n const startTime = Date.now();\n const cwd = (await findRepoRoot(ctx.cwd || process.cwd())) ?? process.cwd();\n\n const scope = input.scope ?? 'root';\n const fileConfig = await useConfig<Partial<CommitPluginConfig>>();\n const config = resolveCommitConfig(fileConfig ?? {});\n const scopeCwd = resolveScopePath(cwd, scope, config.scope?.scopes);\n\n // Load current plan\n const loadLoader = useLoader('Loading commit plan...');\n loadLoader.start();\n const plan = await loadPlan(cwd, scope);\n\n if (!plan) {\n loadLoader.fail('No commit plan found');\n ctx.ui?.error?.('Run `kb commit:generate` first.');\n return {\n exitCode: 1,\n };\n }\n\n if (plan.commits.length === 0) {\n loadLoader.stop();\n ctx.ui?.warn?.('Commit plan is empty. Nothing to apply.');\n return {\n exitCode: 0,\n result: {\n success: true,\n commits: [],\n errors: [],\n },\n meta: {\n timing: Date.now() - startTime,\n },\n };\n }\n loadLoader.succeed(`Loaded plan with ${plan.commits.length} commit(s)`);\n\n // Apply plan\n const applyLoader = useLoader(`Applying ${plan.commits.length} commit(s)...`);\n applyLoader.start();\n const result = await applyCommitPlan(scopeCwd, plan, {\n force: input.force,\n });\n\n // Save to history and clear current plan on success\n if (result.success) {\n await saveToHistory(cwd, plan, result, scope);\n await clearPlan(cwd, scope);\n applyLoader.succeed(`Applied ${result.appliedCommits.length} commit(s) successfully`);\n } else {\n applyLoader.fail('Failed to apply commits');\n }\n\n // Output\n const output: ApplyOutput = {\n success: result.success,\n commits: result.appliedCommits.map((c) => ({\n id: c.groupId,\n sha: c.sha,\n message: c.message,\n })),\n errors: result.errors,\n };\n\n if (input.json) {\n ctx.ui?.json?.(output);\n } else {\n if (result.success) {\n // Build commits section\n const commitsItems = result.appliedCommits.map((commit) => {\n return `${commit.sha.substring(0, 7)} ${commit.message}`;\n });\n\n const sections: Array<{ header?: string; items: string[] }> = [];\n\n if (commitsItems.length > 0) {\n sections.push({\n header: 'Applied Commits',\n items: commitsItems,\n });\n }\n\n const summaryItems: string[] = [\n `Total commits: ${result.appliedCommits.length}`,\n 'Status: ✅ Success',\n ];\n\n sections.unshift({\n header: 'Summary',\n items: summaryItems,\n });\n\n const timing = Date.now() - startTime;\n\n ctx.ui?.success?.('Commits applied successfully', {\n title: 'Apply Commit Plan',\n sections,\n timing,\n });\n } else {\n const errorItems = result.errors.map((error) => error);\n const timing = Date.now() - startTime;\n\n ctx.ui?.error?.('Failed to apply commits', {\n title: 'Apply Commit Plan',\n sections: [\n {\n header: 'Summary',\n items: [`Total errors: ${result.errors.length}`],\n },\n {\n header: 'Errors',\n items: errorItems,\n },\n ],\n timing,\n });\n }\n }\n\n return {\n exitCode: result.success ? 0 : 1,\n result: output,\n meta: {\n timing: Date.now() - startTime,\n },\n };\n },\n },\n});\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared command flags definitions
|
|
3
|
+
*
|
|
4
|
+
* DRY pattern: Define flags once, use in both manifest and command handlers.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Flags for commit:generate command
|
|
8
|
+
*/
|
|
9
|
+
declare const generateFlags: {
|
|
10
|
+
readonly scope: {
|
|
11
|
+
readonly type: "string";
|
|
12
|
+
readonly description: "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)";
|
|
13
|
+
readonly alias: "s";
|
|
14
|
+
};
|
|
15
|
+
readonly json: {
|
|
16
|
+
readonly type: "boolean";
|
|
17
|
+
readonly description: "Output JSON";
|
|
18
|
+
readonly default: false;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
type GenerateFlags = typeof generateFlags;
|
|
22
|
+
/**
|
|
23
|
+
* Flags for commit:apply command
|
|
24
|
+
*/
|
|
25
|
+
declare const applyFlags: {
|
|
26
|
+
readonly force: {
|
|
27
|
+
readonly type: "boolean";
|
|
28
|
+
readonly description: "Apply even if working tree changed";
|
|
29
|
+
readonly default: false;
|
|
30
|
+
readonly alias: "f";
|
|
31
|
+
};
|
|
32
|
+
readonly json: {
|
|
33
|
+
readonly type: "boolean";
|
|
34
|
+
readonly description: "Output JSON";
|
|
35
|
+
readonly default: false;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
type ApplyFlags = typeof applyFlags;
|
|
39
|
+
/**
|
|
40
|
+
* Flags for commit:push command
|
|
41
|
+
*/
|
|
42
|
+
declare const pushFlags: {
|
|
43
|
+
readonly force: {
|
|
44
|
+
readonly type: "boolean";
|
|
45
|
+
readonly description: "Force push (dangerous!)";
|
|
46
|
+
readonly default: false;
|
|
47
|
+
readonly alias: "f";
|
|
48
|
+
};
|
|
49
|
+
readonly json: {
|
|
50
|
+
readonly type: "boolean";
|
|
51
|
+
readonly description: "Output JSON";
|
|
52
|
+
readonly default: false;
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
type PushFlags = typeof pushFlags;
|
|
56
|
+
/**
|
|
57
|
+
* Flags for commit (run) command - combines generate + apply + optional push
|
|
58
|
+
*/
|
|
59
|
+
declare const runFlags: {
|
|
60
|
+
readonly scope: {
|
|
61
|
+
readonly type: "string";
|
|
62
|
+
readonly description: "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)";
|
|
63
|
+
readonly alias: "s";
|
|
64
|
+
};
|
|
65
|
+
readonly json: {
|
|
66
|
+
readonly type: "boolean";
|
|
67
|
+
readonly description: "Output JSON";
|
|
68
|
+
readonly default: false;
|
|
69
|
+
};
|
|
70
|
+
readonly 'dry-run': {
|
|
71
|
+
readonly type: "boolean";
|
|
72
|
+
readonly description: "Generate plan only, do not apply";
|
|
73
|
+
readonly default: false;
|
|
74
|
+
};
|
|
75
|
+
readonly 'with-push': {
|
|
76
|
+
readonly type: "boolean";
|
|
77
|
+
readonly description: "Push after apply";
|
|
78
|
+
readonly default: false;
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
type RunFlags = typeof runFlags;
|
|
82
|
+
/**
|
|
83
|
+
* Common json-only flags for simple commands
|
|
84
|
+
*/
|
|
85
|
+
declare const jsonOnlyFlags: {
|
|
86
|
+
readonly json: {
|
|
87
|
+
readonly type: "boolean";
|
|
88
|
+
readonly description: "Output JSON";
|
|
89
|
+
readonly default: false;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
type JsonOnlyFlags = typeof jsonOnlyFlags;
|
|
93
|
+
/**
|
|
94
|
+
* Empty flags for commands that take no arguments
|
|
95
|
+
*/
|
|
96
|
+
declare const emptyFlags: {};
|
|
97
|
+
type EmptyFlags = typeof emptyFlags;
|
|
98
|
+
|
|
99
|
+
export { type ApplyFlags, type EmptyFlags, type GenerateFlags, type JsonOnlyFlags, type PushFlags, type RunFlags, applyFlags, emptyFlags, generateFlags, jsonOnlyFlags, pushFlags, runFlags };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// src/cli/commands/flags.ts
|
|
2
|
+
var generateFlags = {
|
|
3
|
+
scope: {
|
|
4
|
+
type: "string",
|
|
5
|
+
description: "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)",
|
|
6
|
+
alias: "s"
|
|
7
|
+
},
|
|
8
|
+
json: {
|
|
9
|
+
type: "boolean",
|
|
10
|
+
description: "Output JSON",
|
|
11
|
+
default: false
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
var applyFlags = {
|
|
15
|
+
force: {
|
|
16
|
+
type: "boolean",
|
|
17
|
+
description: "Apply even if working tree changed",
|
|
18
|
+
default: false,
|
|
19
|
+
alias: "f"
|
|
20
|
+
},
|
|
21
|
+
json: {
|
|
22
|
+
type: "boolean",
|
|
23
|
+
description: "Output JSON",
|
|
24
|
+
default: false
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
var pushFlags = {
|
|
28
|
+
force: {
|
|
29
|
+
type: "boolean",
|
|
30
|
+
description: "Force push (dangerous!)",
|
|
31
|
+
default: false,
|
|
32
|
+
alias: "f"
|
|
33
|
+
},
|
|
34
|
+
json: {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Output JSON",
|
|
37
|
+
default: false
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var runFlags = {
|
|
41
|
+
scope: {
|
|
42
|
+
type: "string",
|
|
43
|
+
description: "Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)",
|
|
44
|
+
alias: "s"
|
|
45
|
+
},
|
|
46
|
+
json: {
|
|
47
|
+
type: "boolean",
|
|
48
|
+
description: "Output JSON",
|
|
49
|
+
default: false
|
|
50
|
+
},
|
|
51
|
+
"dry-run": {
|
|
52
|
+
type: "boolean",
|
|
53
|
+
description: "Generate plan only, do not apply",
|
|
54
|
+
default: false
|
|
55
|
+
},
|
|
56
|
+
"with-push": {
|
|
57
|
+
type: "boolean",
|
|
58
|
+
description: "Push after apply",
|
|
59
|
+
default: false
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
var jsonOnlyFlags = {
|
|
63
|
+
json: {
|
|
64
|
+
type: "boolean",
|
|
65
|
+
description: "Output JSON",
|
|
66
|
+
default: false
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
var emptyFlags = {};
|
|
70
|
+
|
|
71
|
+
export { applyFlags, emptyFlags, generateFlags, jsonOnlyFlags, pushFlags, runFlags };
|
|
72
|
+
//# sourceMappingURL=flags.js.map
|
|
73
|
+
//# sourceMappingURL=flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/commands/flags.ts"],"names":[],"mappings":";AASO,IAAM,aAAA,GAAgB;AAAA,EAC3B,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,8FAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACT;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,aAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAOO,IAAM,UAAA,GAAa;AAAA,EACxB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,oCAAA;AAAA,IACb,OAAA,EAAS,KAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACT;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,aAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAOO,IAAM,SAAA,GAAY;AAAA,EACvB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,yBAAA;AAAA,IACb,OAAA,EAAS,KAAA;AAAA,IACT,KAAA,EAAO;AAAA,GACT;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,aAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAOO,IAAM,QAAA,GAAW;AAAA,EACtB,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,QAAA;AAAA,IACN,WAAA,EAAa,8FAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACT;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,aAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,SAAA,EAAW;AAAA,IACT,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,kCAAA;AAAA,IACb,OAAA,EAAS;AAAA,GACX;AAAA,EACA,WAAA,EAAa;AAAA,IACX,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,kBAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAOO,IAAM,aAAA,GAAgB;AAAA,EAC3B,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,SAAA;AAAA,IACN,WAAA,EAAa,aAAA;AAAA,IACb,OAAA,EAAS;AAAA;AAEb;AAOO,IAAM,aAAa","file":"flags.js","sourcesContent":["/**\n * Shared command flags definitions\n *\n * DRY pattern: Define flags once, use in both manifest and command handlers.\n */\n\n/**\n * Flags for commit:generate command\n */\nexport const generateFlags = {\n scope: {\n type: 'string',\n description: 'Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)',\n alias: 's',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type GenerateFlags = typeof generateFlags;\n\n/**\n * Flags for commit:apply command\n */\nexport const applyFlags = {\n force: {\n type: 'boolean',\n description: 'Apply even if working tree changed',\n default: false,\n alias: 'f',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type ApplyFlags = typeof applyFlags;\n\n/**\n * Flags for commit:push command\n */\nexport const pushFlags = {\n force: {\n type: 'boolean',\n description: 'Force push (dangerous!)',\n default: false,\n alias: 'f',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type PushFlags = typeof pushFlags;\n\n/**\n * Flags for commit (run) command - combines generate + apply + optional push\n */\nexport const runFlags = {\n scope: {\n type: 'string',\n description: 'Filter by package name (@kb-labs/core), wildcard (@kb-labs/*), or path pattern (packages/**)',\n alias: 's',\n },\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n 'dry-run': {\n type: 'boolean',\n description: 'Generate plan only, do not apply',\n default: false,\n },\n 'with-push': {\n type: 'boolean',\n description: 'Push after apply',\n default: false,\n },\n} as const;\n\nexport type RunFlags = typeof runFlags;\n\n/**\n * Common json-only flags for simple commands\n */\nexport const jsonOnlyFlags = {\n json: {\n type: 'boolean',\n description: 'Output JSON',\n default: false,\n },\n} as const;\n\nexport type JsonOnlyFlags = typeof jsonOnlyFlags;\n\n/**\n * Empty flags for commands that take no arguments\n */\nexport const emptyFlags = {} as const;\n\nexport type EmptyFlags = typeof emptyFlags;\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* commit:generate command
|
|
5
|
+
* Generate commit plan from git changes
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, any, {
|
|
8
|
+
plan: {
|
|
9
|
+
schemaVersion: "1.0";
|
|
10
|
+
createdAt: string;
|
|
11
|
+
repoRoot: string;
|
|
12
|
+
gitStatus: {
|
|
13
|
+
staged: string[];
|
|
14
|
+
unstaged: string[];
|
|
15
|
+
untracked: string[];
|
|
16
|
+
};
|
|
17
|
+
commits: {
|
|
18
|
+
message: string;
|
|
19
|
+
type: "feat" | "fix" | "refactor" | "chore" | "docs" | "test" | "build" | "ci" | "perf";
|
|
20
|
+
id: string;
|
|
21
|
+
files: string[];
|
|
22
|
+
releaseHint: "none" | "patch" | "minor" | "major";
|
|
23
|
+
breaking: boolean;
|
|
24
|
+
scope?: string | undefined;
|
|
25
|
+
body?: string | undefined;
|
|
26
|
+
reasoning?: {
|
|
27
|
+
newBehavior: boolean;
|
|
28
|
+
fixesBug: boolean;
|
|
29
|
+
internalOnly: boolean;
|
|
30
|
+
explanation: string;
|
|
31
|
+
confidence: number;
|
|
32
|
+
} | undefined;
|
|
33
|
+
}[];
|
|
34
|
+
metadata: {
|
|
35
|
+
totalFiles: number;
|
|
36
|
+
totalCommits: number;
|
|
37
|
+
llmUsed: boolean;
|
|
38
|
+
tokensUsed?: number | undefined;
|
|
39
|
+
escalated?: boolean | undefined;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
planPath: string;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
export { _default as default };
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { defineCommand, useLLM, findRepoRoot, useConfig, useLoader, displayArtifacts } from '@kb-labs/sdk';
|
|
2
|
+
import { stat } from 'fs/promises';
|
|
3
|
+
import { getGitStatus, hasChanges, generateCommitPlan, savePlan, getCurrentPlanPath } from '@kb-labs/commit-core';
|
|
4
|
+
import { commitEnv, resolveCommitConfig } from '@kb-labs/commit-contracts';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
|
|
7
|
+
// src/cli/commands/generate.ts
|
|
8
|
+
function resolveScopePath(baseCwd, scopeId = "root", scopes) {
|
|
9
|
+
const scopeDef = scopes?.find((s) => s.id === scopeId);
|
|
10
|
+
const relativePath = scopeDef?.path ?? (scopeId === "root" ? "." : scopeId);
|
|
11
|
+
return relativePath === "." ? baseCwd : path.join(baseCwd, relativePath);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/cli/commands/generate.ts
|
|
15
|
+
var generate_default = defineCommand({
|
|
16
|
+
id: "commit:generate",
|
|
17
|
+
description: "Generate commit plan from git changes",
|
|
18
|
+
handler: {
|
|
19
|
+
async execute(ctx, input) {
|
|
20
|
+
const startTime = Date.now();
|
|
21
|
+
const llm = useLLM();
|
|
22
|
+
const cwd = await findRepoRoot(ctx.cwd || process.cwd()) ?? process.cwd();
|
|
23
|
+
const fileConfig = await useConfig();
|
|
24
|
+
const env = commitEnv.parse(ctx.runtime);
|
|
25
|
+
const config = resolveCommitConfig(fileConfig ?? {}, env);
|
|
26
|
+
const flags = input.flags ?? input;
|
|
27
|
+
const effectiveScope = flags.scope ?? config.scope?.default ?? "root";
|
|
28
|
+
const scopeCwd = resolveScopePath(cwd, effectiveScope, config.scope?.scopes);
|
|
29
|
+
const allowSecrets = flags["allow-secrets"] ?? false;
|
|
30
|
+
const autoConfirm = flags.yes ?? false;
|
|
31
|
+
const statusLoader = useLoader("Checking git status...");
|
|
32
|
+
statusLoader.start();
|
|
33
|
+
const status = await getGitStatus(scopeCwd);
|
|
34
|
+
if (!hasChanges(status)) {
|
|
35
|
+
statusLoader.stop();
|
|
36
|
+
ctx.ui?.warn?.("No changes to commit");
|
|
37
|
+
return {
|
|
38
|
+
exitCode: 1
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
statusLoader.succeed("Found changes to commit");
|
|
42
|
+
const analyzeLoader = useLoader("Analyzing changes...");
|
|
43
|
+
analyzeLoader.start();
|
|
44
|
+
const llmComplete = llm && config.llm.enabled ? async (prompt, options) => {
|
|
45
|
+
const result = await llm.complete(prompt, {
|
|
46
|
+
...options,
|
|
47
|
+
temperature: options?.temperature ?? config.llm.temperature,
|
|
48
|
+
maxTokens: options?.maxTokens ?? config.llm.maxTokens
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
content: result.content,
|
|
52
|
+
tokensUsed: result.usage ? result.usage.promptTokens + result.usage.completionTokens : void 0
|
|
53
|
+
};
|
|
54
|
+
} : void 0;
|
|
55
|
+
const plan = await generateCommitPlan({
|
|
56
|
+
cwd: scopeCwd,
|
|
57
|
+
llmComplete,
|
|
58
|
+
config,
|
|
59
|
+
allowSecrets,
|
|
60
|
+
autoConfirm,
|
|
61
|
+
onProgress: (message) => analyzeLoader.update({ text: message })
|
|
62
|
+
});
|
|
63
|
+
const saveLoader = useLoader("Saving plan...");
|
|
64
|
+
saveLoader.start();
|
|
65
|
+
await savePlan(cwd, plan, effectiveScope);
|
|
66
|
+
const planPath = getCurrentPlanPath(cwd, effectiveScope);
|
|
67
|
+
saveLoader.succeed("Plan saved");
|
|
68
|
+
analyzeLoader.succeed(`Generated commit plan with ${plan.commits.length} commit(s)`);
|
|
69
|
+
const output = {
|
|
70
|
+
plan,
|
|
71
|
+
planPath
|
|
72
|
+
};
|
|
73
|
+
if (input.json) {
|
|
74
|
+
ctx.ui?.json?.(output);
|
|
75
|
+
} else {
|
|
76
|
+
const commitsItems = plan.commits.map((commit) => {
|
|
77
|
+
const scope = commit.scope ? `(${commit.scope})` : "";
|
|
78
|
+
return `${commit.type}${scope}: ${commit.message} [${commit.files.length} file(s)]`;
|
|
79
|
+
});
|
|
80
|
+
const artifacts = [];
|
|
81
|
+
try {
|
|
82
|
+
const planStats = await stat(planPath);
|
|
83
|
+
artifacts.push({
|
|
84
|
+
name: "Commit Plan",
|
|
85
|
+
path: planPath,
|
|
86
|
+
size: planStats.size,
|
|
87
|
+
modified: planStats.mtime,
|
|
88
|
+
description: "Generated commit plan in JSON format"
|
|
89
|
+
});
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
const sections = [];
|
|
93
|
+
if (commitsItems.length > 0) {
|
|
94
|
+
sections.push({
|
|
95
|
+
header: "Commits",
|
|
96
|
+
items: commitsItems
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (artifacts.length > 0) {
|
|
100
|
+
const artifactsLines = displayArtifacts(artifacts, {
|
|
101
|
+
showSize: true,
|
|
102
|
+
showTime: true,
|
|
103
|
+
showDescription: true,
|
|
104
|
+
maxItems: 10,
|
|
105
|
+
title: ""
|
|
106
|
+
});
|
|
107
|
+
sections.push({
|
|
108
|
+
header: "Artifacts",
|
|
109
|
+
items: artifactsLines
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const summaryItems = [
|
|
113
|
+
`Files: ${plan.metadata.totalFiles}`,
|
|
114
|
+
`Commits: ${plan.metadata.totalCommits}`
|
|
115
|
+
];
|
|
116
|
+
if (plan.metadata.llmUsed) {
|
|
117
|
+
const llmPhase = plan.metadata.escalated ? "Phase 2 (with diff)" : "Phase 1";
|
|
118
|
+
summaryItems.push(`LLM: ${llmPhase}`);
|
|
119
|
+
if (plan.metadata.tokensUsed) {
|
|
120
|
+
summaryItems.push(`Tokens: ${plan.metadata.tokensUsed}`);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
summaryItems.push("Generator: Heuristics");
|
|
124
|
+
}
|
|
125
|
+
sections.unshift({
|
|
126
|
+
header: "Summary",
|
|
127
|
+
items: summaryItems
|
|
128
|
+
});
|
|
129
|
+
const timing = Date.now() - startTime;
|
|
130
|
+
ctx.ui?.success?.("Plan generated and saved", {
|
|
131
|
+
title: "Generate Commit Plan",
|
|
132
|
+
sections,
|
|
133
|
+
timing
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
exitCode: 0,
|
|
138
|
+
result: output,
|
|
139
|
+
meta: {
|
|
140
|
+
timing: Date.now() - startTime
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
export { generate_default as default };
|
|
148
|
+
//# sourceMappingURL=generate.js.map
|
|
149
|
+
//# sourceMappingURL=generate.js.map
|