@kosuke-ai/cli 0.0.33 ā 0.0.35
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/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/kosuke/commands/build.d.ts +8 -4
- package/dist/kosuke/commands/build.d.ts.map +1 -1
- package/dist/kosuke/commands/build.js +75 -31
- package/dist/kosuke/commands/build.js.map +1 -1
- package/dist/kosuke/commands/getcode.d.ts.map +1 -1
- package/dist/kosuke/commands/getcode.js +1 -0
- package/dist/kosuke/commands/getcode.js.map +1 -1
- package/dist/kosuke/commands/lint.d.ts.map +1 -1
- package/dist/kosuke/commands/lint.js +7 -39
- package/dist/kosuke/commands/lint.js.map +1 -1
- package/dist/kosuke/commands/review.d.ts.map +1 -1
- package/dist/kosuke/commands/review.js +34 -34
- package/dist/kosuke/commands/review.js.map +1 -1
- package/dist/kosuke/commands/ship.d.ts +3 -3
- package/dist/kosuke/commands/ship.d.ts.map +1 -1
- package/dist/kosuke/commands/ship.js +57 -268
- package/dist/kosuke/commands/ship.js.map +1 -1
- package/dist/kosuke/commands/sync-rules.d.ts.map +1 -1
- package/dist/kosuke/commands/sync-rules.js +2 -0
- package/dist/kosuke/commands/sync-rules.js.map +1 -1
- package/dist/kosuke/commands/test.d.ts.map +1 -1
- package/dist/kosuke/commands/test.js +1 -23
- package/dist/kosuke/commands/test.js.map +1 -1
- package/dist/kosuke/types.d.ts +9 -5
- package/dist/kosuke/types.d.ts.map +1 -1
- package/dist/kosuke/utils/claude-agent.d.ts +2 -1
- package/dist/kosuke/utils/claude-agent.d.ts.map +1 -1
- package/dist/kosuke/utils/claude-agent.js +49 -10
- package/dist/kosuke/utils/claude-agent.js.map +1 -1
- package/dist/kosuke/utils/logger.d.ts.map +1 -1
- package/dist/kosuke/utils/logger.js +8 -2
- package/dist/kosuke/utils/logger.js.map +1 -1
- package/dist/kosuke/utils/tickets-manager.d.ts +28 -0
- package/dist/kosuke/utils/tickets-manager.d.ts.map +1 -0
- package/dist/kosuke/utils/tickets-manager.js +54 -0
- package/dist/kosuke/utils/tickets-manager.js.map +1 -0
- package/dist/package.json +1 -1
- package/package.json +1 -1
|
@@ -9,35 +9,36 @@
|
|
|
9
9
|
* Usage:
|
|
10
10
|
* kosuke review # Review current git diff
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import { join } from 'path';
|
|
14
|
-
import { runAgent, formatCostBreakdown } from '../utils/claude-agent.js';
|
|
12
|
+
import { formatCostBreakdown, runAgent } from '../utils/claude-agent.js';
|
|
15
13
|
import { getGitDiff, hasUncommittedChanges } from '../utils/git.js';
|
|
16
|
-
import { runComprehensiveLinting } from '../utils/validator.js';
|
|
17
14
|
import { logger, setupCancellationHandler } from '../utils/logger.js';
|
|
18
|
-
|
|
19
|
-
* Load CLAUDE.md rules
|
|
20
|
-
*/
|
|
21
|
-
function loadClaudeRules(cwd = process.cwd()) {
|
|
22
|
-
const claudePath = join(cwd, 'CLAUDE.md');
|
|
23
|
-
if (!existsSync(claudePath)) {
|
|
24
|
-
throw new Error(`CLAUDE.md not found in workspace root.\n` +
|
|
25
|
-
`Please ensure CLAUDE.md exists at: ${claudePath}`);
|
|
26
|
-
}
|
|
27
|
-
return readFileSync(claudePath, 'utf-8');
|
|
28
|
-
}
|
|
15
|
+
import { runComprehensiveLinting } from '../utils/validator.js';
|
|
29
16
|
/**
|
|
30
17
|
* Build system prompt for code review (git diff only)
|
|
31
18
|
*/
|
|
32
|
-
function buildReviewSystemPrompt(
|
|
33
|
-
|
|
19
|
+
function buildReviewSystemPrompt(gitDiff, context) {
|
|
20
|
+
const ticketContextSection = context
|
|
21
|
+
? `
|
|
22
|
+
**š« Ticket Being Implemented:**
|
|
23
|
+
- ID: ${context.ticketId}
|
|
24
|
+
- Title: ${context.ticketTitle}
|
|
25
|
+
- Description:
|
|
26
|
+
${context.ticketDescription}
|
|
34
27
|
|
|
35
|
-
**
|
|
36
|
-
|
|
28
|
+
**Ticket-Specific Review Requirements:**
|
|
29
|
+
- Verify changes align with the ticket description above
|
|
30
|
+
- Ensure all requirements from the ticket are addressed in the diff
|
|
31
|
+
- Check that the implementation matches the intended feature/fix
|
|
32
|
+
- Look for any obvious missing functionality described in the ticket
|
|
33
|
+
- Fix any misalignments between the code changes and ticket requirements
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
`
|
|
36
|
+
: '';
|
|
37
|
+
return `You are a senior code reviewer conducting a code quality review of recent changes.
|
|
40
38
|
|
|
39
|
+
**Your Task:**
|
|
40
|
+
Review the git diff below for compliance with the project's coding guidelines (CLAUDE.md will be loaded automatically).
|
|
41
|
+
${ticketContextSection}
|
|
41
42
|
**Git Diff to Review:**
|
|
42
43
|
\`\`\`diff
|
|
43
44
|
${gitDiff}
|
|
@@ -77,13 +78,16 @@ Review the changes shown in the diff and fix any issues you find.`;
|
|
|
77
78
|
/**
|
|
78
79
|
* Core review logic - reviews git diff only
|
|
79
80
|
*/
|
|
80
|
-
export async function reviewCore(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
export async function reviewCore(options = {}) {
|
|
82
|
+
const cwd = options.directory || process.cwd();
|
|
83
|
+
const { context } = options;
|
|
84
|
+
// Log ticket context if provided
|
|
85
|
+
if (context) {
|
|
86
|
+
console.log(`š« Reviewing changes for: ${context.ticketId} - ${context.ticketTitle}\n`);
|
|
87
|
+
}
|
|
84
88
|
// 1. Check for uncommitted changes
|
|
85
89
|
console.log('š Checking for uncommitted changes...');
|
|
86
|
-
const hasChanges = await hasUncommittedChanges();
|
|
90
|
+
const hasChanges = await hasUncommittedChanges(cwd);
|
|
87
91
|
if (!hasChanges) {
|
|
88
92
|
console.log(' ā¹ļø No uncommitted changes found. Nothing to review.\n');
|
|
89
93
|
return {
|
|
@@ -102,7 +106,7 @@ options = {}) {
|
|
|
102
106
|
console.log(' ā
Found uncommitted changes\n');
|
|
103
107
|
// 2. Get git diff
|
|
104
108
|
console.log('š Getting git diff...');
|
|
105
|
-
const gitDiff = await getGitDiff();
|
|
109
|
+
const gitDiff = await getGitDiff(cwd);
|
|
106
110
|
if (!gitDiff || gitDiff.trim().length === 0) {
|
|
107
111
|
console.log(' ā¹ļø No diff available. Nothing to review.\n');
|
|
108
112
|
return {
|
|
@@ -119,15 +123,11 @@ options = {}) {
|
|
|
119
123
|
};
|
|
120
124
|
}
|
|
121
125
|
console.log(` ā
Got diff (${gitDiff.length} characters)\n`);
|
|
122
|
-
// 3.
|
|
123
|
-
console.log('š Loading CLAUDE.md rules...');
|
|
124
|
-
const claudeRules = loadClaudeRules(cwd);
|
|
125
|
-
console.log(` ā
Loaded rules (${claudeRules.length} characters)\n`);
|
|
126
|
-
// 4. Review phase
|
|
126
|
+
// 3. Review phase
|
|
127
127
|
console.log(`\n${'='.repeat(60)}`);
|
|
128
128
|
console.log(`š Phase 1: Code Review of Git Diff`);
|
|
129
129
|
console.log(`${'='.repeat(60)}\n`);
|
|
130
|
-
const systemPrompt = buildReviewSystemPrompt(
|
|
130
|
+
const systemPrompt = buildReviewSystemPrompt(gitDiff, context);
|
|
131
131
|
const reviewResult = await runAgent('Review the git diff for compliance with CLAUDE.md rules and fix all issues found', {
|
|
132
132
|
systemPrompt,
|
|
133
133
|
cwd,
|
|
@@ -142,7 +142,7 @@ options = {}) {
|
|
|
142
142
|
console.log(`\n${'='.repeat(60)}`);
|
|
143
143
|
console.log(`š§ Phase 2: Linting & Quality Checks`);
|
|
144
144
|
console.log(`${'='.repeat(60)}\n`);
|
|
145
|
-
const lintResult = await runComprehensiveLinting();
|
|
145
|
+
const lintResult = await runComprehensiveLinting(cwd);
|
|
146
146
|
console.log(`\nā
Linting completed (${lintResult.fixCount} additional fixes applied)`);
|
|
147
147
|
return {
|
|
148
148
|
success: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../kosuke/commands/review.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../kosuke/commands/review.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;GAEG;AACH,SAAS,uBAAuB,CAAC,OAAe,EAAE,OAAuB;IACvE,MAAM,oBAAoB,GAAG,OAAO;QAClC,CAAC,CAAC;;QAEE,OAAO,CAAC,QAAQ;WACb,OAAO,CAAC,WAAW;;EAE5B,OAAO,CAAC,iBAAiB;;;;;;;;;CAS1B;QACG,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;;;;EAIP,oBAAoB;;;EAGpB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEAgCyD,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAyB,EAAE;IAC1D,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE5B,iCAAiC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,CAAC,QAAQ,MAAM,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC;IAC1F,CAAC;IAED,mCAAmC;IACnC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAEpD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,CAAC;YACf,UAAU,EAAE;gBACV,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;gBACT,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;aACb;YACD,IAAI,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAEhD,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IAEtC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,CAAC;YACf,UAAU,EAAE;gBACV,KAAK,EAAE,CAAC;gBACR,MAAM,EAAE,CAAC;gBACT,aAAa,EAAE,CAAC;gBAChB,SAAS,EAAE,CAAC;aACb;YACD,IAAI,EAAE,CAAC;SACR,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC;IAE9D,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,YAAY,GAAG,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE/D,MAAM,YAAY,GAAG,MAAM,QAAQ,CACjC,kFAAkF,EAClF;QACE,YAAY;QACZ,GAAG;QACH,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,QAAQ;KACpB,CACF,CAAC;IAEF,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,sBAAsB,mBAAmB,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAEvE,mBAAmB;IACnB,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,UAAU,GAAG,MAAM,uBAAuB,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,0BAA0B,UAAU,CAAC,QAAQ,4BAA4B,CAAC,CAAC;IAEvF,OAAO;QACL,OAAO,EAAE,IAAI;QACb,WAAW;QACX,YAAY,EAAE,WAAW,GAAG,UAAU,CAAC,QAAQ;QAC/C,UAAU,EAAE,YAAY,CAAC,UAAU;QACnC,IAAI,EAAE,YAAY,CAAC,IAAI;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAyB,EAAE;IAC7D,MAAM,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAEvD,6BAA6B;IAC7B,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAE5D,IAAI,CAAC;QACH,uBAAuB;QACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACxE,CAAC;QAED,wDAAwD;QACxD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QAEzC,gBAAgB;QAChB,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAClD,UAAU,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QAE9C,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC,IAAI,MAAM,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;YACvD,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAC7C,cAAc,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,2BAA2B,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,mBAAmB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAE5B,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAEhD,2BAA2B;QAC3B,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC7C,cAAc,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAE3C,uBAAuB;QACvB,MAAM,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,KAAc,CAAC,CAAC;QAC3D,cAAc,EAAE,CAAC;QAEjB,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
* Ship command - Implement a ticket from tickets.json
|
|
3
3
|
*
|
|
4
4
|
* This command takes a ticket ID, implements it following CLAUDE.md rules,
|
|
5
|
-
* runs linting
|
|
5
|
+
* runs linting, and optionally performs code review with ticket context.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* kosuke ship --ticket=SCHEMA-1 # Implement ticket (local only)
|
|
9
|
-
* kosuke ship --ticket=BACKEND-2 --review # Implement with review
|
|
9
|
+
* kosuke ship --ticket=BACKEND-2 --review # Implement with code review
|
|
10
10
|
* kosuke ship --ticket=FRONTEND-1 --commit # Implement and commit to current branch
|
|
11
|
-
* kosuke ship --ticket=BACKEND-3 --
|
|
11
|
+
* kosuke ship --ticket=BACKEND-3 --review --commit # Implement, review, then commit
|
|
12
12
|
* kosuke ship --ticket=FRONTEND-1 --test # Implement and run tests
|
|
13
13
|
* kosuke ship --ticket=SCHEMA-1 --tickets=path/to/tickets.json
|
|
14
14
|
* kosuke ship --ticket=SCHEMA-1 --db-url=postgres://user:pass@host:5432/db
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ship.d.ts","sourceRoot":"","sources":["../../../kosuke/commands/ship.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ship.d.ts","sourceRoot":"","sources":["../../../kosuke/commands/ship.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAU,MAAM,aAAa,CAAC;AA8DnE;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAoQxE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAiErE"}
|
|
@@ -2,88 +2,30 @@
|
|
|
2
2
|
* Ship command - Implement a ticket from tickets.json
|
|
3
3
|
*
|
|
4
4
|
* This command takes a ticket ID, implements it following CLAUDE.md rules,
|
|
5
|
-
* runs linting
|
|
5
|
+
* runs linting, and optionally performs code review with ticket context.
|
|
6
6
|
*
|
|
7
7
|
* Usage:
|
|
8
8
|
* kosuke ship --ticket=SCHEMA-1 # Implement ticket (local only)
|
|
9
|
-
* kosuke ship --ticket=BACKEND-2 --review # Implement with review
|
|
9
|
+
* kosuke ship --ticket=BACKEND-2 --review # Implement with code review
|
|
10
10
|
* kosuke ship --ticket=FRONTEND-1 --commit # Implement and commit to current branch
|
|
11
|
-
* kosuke ship --ticket=BACKEND-3 --
|
|
11
|
+
* kosuke ship --ticket=BACKEND-3 --review --commit # Implement, review, then commit
|
|
12
12
|
* kosuke ship --ticket=FRONTEND-1 --test # Implement and run tests
|
|
13
13
|
* kosuke ship --ticket=SCHEMA-1 --tickets=path/to/tickets.json
|
|
14
14
|
* kosuke ship --ticket=SCHEMA-1 --db-url=postgres://user:pass@host:5432/db
|
|
15
15
|
*/
|
|
16
|
-
import { existsSync,
|
|
16
|
+
import { existsSync, statSync } from 'fs';
|
|
17
17
|
import { join, resolve } from 'path';
|
|
18
18
|
import { formatCostBreakdown, runAgent } from '../utils/claude-agent.js';
|
|
19
19
|
import { commitAndPushCurrentBranch } from '../utils/git.js';
|
|
20
20
|
import { logger, setupCancellationHandler } from '../utils/logger.js';
|
|
21
|
-
import {
|
|
21
|
+
import { findTicket, loadTicketsFile, updateTicketStatus } from '../utils/tickets-manager.js';
|
|
22
22
|
import { runComprehensiveLinting } from '../utils/validator.js';
|
|
23
23
|
import { reviewCore } from './review.js';
|
|
24
24
|
import { testCore } from './test.js';
|
|
25
|
-
/**
|
|
26
|
-
* Load tickets from file
|
|
27
|
-
*/
|
|
28
|
-
function loadTicketsFile(ticketsPath) {
|
|
29
|
-
if (!existsSync(ticketsPath)) {
|
|
30
|
-
throw new Error(`Tickets file not found: ${ticketsPath}\n` +
|
|
31
|
-
`Please generate tickets first using: kosuke tickets`);
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
const content = readFileSync(ticketsPath, 'utf-8');
|
|
35
|
-
return JSON.parse(content);
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
throw new Error(`Failed to parse tickets file: ${error instanceof Error ? error.message : String(error)}`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Save tickets to file
|
|
43
|
-
*/
|
|
44
|
-
function saveTicketsFile(ticketsPath, ticketsData) {
|
|
45
|
-
writeFileSync(ticketsPath, JSON.stringify(ticketsData, null, 2), 'utf-8');
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Find ticket by ID
|
|
49
|
-
*/
|
|
50
|
-
function findTicket(ticketsData, ticketId) {
|
|
51
|
-
return ticketsData.tickets.find((t) => t.id === ticketId);
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Update ticket status in file
|
|
55
|
-
*/
|
|
56
|
-
function updateTicketStatus(ticketsPath, ticketId, status, error) {
|
|
57
|
-
const ticketsData = loadTicketsFile(ticketsPath);
|
|
58
|
-
const ticket = findTicket(ticketsData, ticketId);
|
|
59
|
-
if (!ticket) {
|
|
60
|
-
console.warn(`ā ļø Ticket ${ticketId} not found, skipping status update`);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
ticket.status = status;
|
|
64
|
-
if (error) {
|
|
65
|
-
ticket.error = error;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
delete ticket.error;
|
|
69
|
-
}
|
|
70
|
-
saveTicketsFile(ticketsPath, ticketsData);
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Load CLAUDE.md rules
|
|
74
|
-
*/
|
|
75
|
-
function loadClaudeRules(cwd = process.cwd()) {
|
|
76
|
-
const claudePath = join(cwd, 'CLAUDE.md');
|
|
77
|
-
if (!existsSync(claudePath)) {
|
|
78
|
-
throw new Error(`CLAUDE.md not found in workspace root.\n` +
|
|
79
|
-
`Please ensure CLAUDE.md exists at: ${claudePath}`);
|
|
80
|
-
}
|
|
81
|
-
return readFileSync(claudePath, 'utf-8');
|
|
82
|
-
}
|
|
83
25
|
/**
|
|
84
26
|
* Build system prompt for ticket implementation
|
|
85
27
|
*/
|
|
86
|
-
function buildImplementationPrompt(ticket,
|
|
28
|
+
function buildImplementationPrompt(ticket, dbUrl) {
|
|
87
29
|
const isSchemaTicket = ticket.id.toUpperCase().startsWith('SCHEMA-');
|
|
88
30
|
const schemaMigrationInstructions = isSchemaTicket
|
|
89
31
|
? `
|
|
@@ -91,21 +33,20 @@ function buildImplementationPrompt(ticket, claudeRules, dbUrl) {
|
|
|
91
33
|
**Database Schema Changes (CRITICAL FOR SCHEMA TICKETS):**
|
|
92
34
|
This is a SCHEMA ticket. After making changes to database schema files:
|
|
93
35
|
1. Run \`bun run db:generate\` to generate Drizzle migrations
|
|
94
|
-
2. Run \`POSTGRES_URL="${dbUrl}" bun run db:migrate\` to apply migrations to the database
|
|
36
|
+
2. **CRITICAL**: Run \`POSTGRES_URL="${dbUrl}" bun run db:migrate\` to apply migrations to the database
|
|
37
|
+
ā ļø **MIGRATIONS MUST BE APPLIED AFTER GENERATION** - Generating migrations alone does NOT update the database!
|
|
38
|
+
ā ļø The database schema will NOT change until you run \`db:migrate\` to apply the generated migrations
|
|
39
|
+
ā ļø Skipping this step will cause runtime errors when the app expects the new schema
|
|
95
40
|
3. Run \`POSTGRES_URL="${dbUrl}" bun run db:seed\` to seed the database with initial data
|
|
96
41
|
4. Verify migration files were created in lib/db/migrations/
|
|
97
42
|
5. Handle any migration errors before proceeding
|
|
98
|
-
6. Ensure schema changes follow Drizzle ORM best practices from
|
|
99
|
-
|
|
100
|
-
**Database Connection:**
|
|
101
|
-
- Using database URL: ${dbUrl}
|
|
102
|
-
- Ensure the database is accessible before running migration commands
|
|
43
|
+
6. Ensure schema changes follow Drizzle ORM best practices from project guidelines
|
|
103
44
|
`
|
|
104
45
|
: '';
|
|
105
46
|
return `You are an expert software engineer implementing a feature ticket.
|
|
106
47
|
|
|
107
48
|
**Your Task:**
|
|
108
|
-
Implement the following ticket according to the project's coding standards and architecture patterns.
|
|
49
|
+
Implement the following ticket according to the project's coding standards and architecture patterns (CLAUDE.md will be loaded automatically).
|
|
109
50
|
|
|
110
51
|
**Ticket Information:**
|
|
111
52
|
- ID: ${ticket.id}
|
|
@@ -113,11 +54,8 @@ Implement the following ticket according to the project's coding standards and a
|
|
|
113
54
|
- Description:
|
|
114
55
|
${ticket.description}
|
|
115
56
|
|
|
116
|
-
**Project Rules (CLAUDE.md):**
|
|
117
|
-
${claudeRules}
|
|
118
|
-
|
|
119
57
|
**Implementation Requirements:**
|
|
120
|
-
1. Follow ALL guidelines
|
|
58
|
+
1. Follow ALL project guidelines from CLAUDE.md
|
|
121
59
|
2. Explore the current codebase to understand existing patterns and architecture
|
|
122
60
|
3. Write clean, well-documented code
|
|
123
61
|
4. Ensure TypeScript type safety
|
|
@@ -134,45 +72,6 @@ ${claudeRules}
|
|
|
134
72
|
|
|
135
73
|
Begin by exploring the current codebase, then implement the ticket systematically.`;
|
|
136
74
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Build system prompt for review
|
|
139
|
-
*/
|
|
140
|
-
function buildReviewPrompt(ticket, claudeRules) {
|
|
141
|
-
return `You are a senior code reviewer ensuring compliance with project standards.
|
|
142
|
-
|
|
143
|
-
**Your Task:**
|
|
144
|
-
Review the implementation of ticket ${ticket.id} and ensure it follows CLAUDE.md rules.
|
|
145
|
-
|
|
146
|
-
**Ticket Context:**
|
|
147
|
-
- ID: ${ticket.id}
|
|
148
|
-
- Title: ${ticket.title}
|
|
149
|
-
|
|
150
|
-
**Project Rules (CLAUDE.md):**
|
|
151
|
-
${claudeRules}
|
|
152
|
-
|
|
153
|
-
**Review Requirements:**
|
|
154
|
-
1. Check compliance with CLAUDE.md guidelines
|
|
155
|
-
2. Verify code quality and best practices
|
|
156
|
-
3. Ensure TypeScript type safety
|
|
157
|
-
4. Check error handling
|
|
158
|
-
5. Verify naming conventions
|
|
159
|
-
6. Check for security issues
|
|
160
|
-
7. Ensure proper documentation
|
|
161
|
-
|
|
162
|
-
**If Issues Found:**
|
|
163
|
-
- Use search_replace or write tools to FIX them immediately
|
|
164
|
-
- Don't just report issues - FIX them!
|
|
165
|
-
- Make minimal necessary changes
|
|
166
|
-
- Ensure fixes don't break functionality
|
|
167
|
-
|
|
168
|
-
**Critical Instructions:**
|
|
169
|
-
- Read the files that were recently modified for this ticket
|
|
170
|
-
- Identify any violations of CLAUDE.md rules
|
|
171
|
-
- Fix ALL issues found
|
|
172
|
-
- Ensure the code is production-ready after your review
|
|
173
|
-
|
|
174
|
-
Begin by reading recent changes and reviewing them against the standards.`;
|
|
175
|
-
}
|
|
176
75
|
/**
|
|
177
76
|
* Core ship logic (git-agnostic, reusable)
|
|
178
77
|
*/
|
|
@@ -210,12 +109,10 @@ export async function shipCore(options) {
|
|
|
210
109
|
console.log('š Updating ticket status to InProgress...');
|
|
211
110
|
updateTicketStatus(ticketsPath, ticketId, 'InProgress');
|
|
212
111
|
console.log(' ā
Status updated\n');
|
|
213
|
-
// 3.
|
|
214
|
-
console.log('š Loading CLAUDE.md rules...');
|
|
215
|
-
const claudeRules = loadClaudeRules(cwd);
|
|
216
|
-
console.log(` ā
Loaded rules (${claudeRules.length} characters)\n`);
|
|
217
|
-
// 4. Context ready (using current working directory)
|
|
112
|
+
// 3. Context ready (using current working directory)
|
|
218
113
|
console.log('š Working in current directory context\n');
|
|
114
|
+
// Determine ticket type
|
|
115
|
+
const isSchemaTicket = ticket.id.toUpperCase().startsWith('SCHEMA-');
|
|
219
116
|
// Track metrics
|
|
220
117
|
let totalInputTokens = 0;
|
|
221
118
|
let totalOutputTokens = 0;
|
|
@@ -229,7 +126,7 @@ export async function shipCore(options) {
|
|
|
229
126
|
console.log(`\n${'='.repeat(60)}`);
|
|
230
127
|
console.log(`š Phase 1: Implementation`);
|
|
231
128
|
console.log(`${'='.repeat(60)}\n`);
|
|
232
|
-
const systemPrompt = buildImplementationPrompt(ticket,
|
|
129
|
+
const systemPrompt = buildImplementationPrompt(ticket, dbUrl);
|
|
233
130
|
const implementationResult = await runAgent(`Implement ticket ${ticketId}: ${ticket.title}`, {
|
|
234
131
|
systemPrompt,
|
|
235
132
|
cwd,
|
|
@@ -250,33 +147,29 @@ export async function shipCore(options) {
|
|
|
250
147
|
console.log(`${'='.repeat(60)}\n`);
|
|
251
148
|
const lintResult = await runComprehensiveLinting(cwd);
|
|
252
149
|
console.log(`\nā
Linting completed (${lintResult.fixCount} fixes applied)`);
|
|
253
|
-
// 7. Review phase (if review flag is set)
|
|
254
|
-
|
|
255
|
-
if (review) {
|
|
150
|
+
// 7. Review phase (if review flag is set) - SKIP for SCHEMA tickets
|
|
151
|
+
if (review && !isSchemaTicket) {
|
|
256
152
|
console.log(`\n${'='.repeat(60)}`);
|
|
257
|
-
console.log(`š Phase 3:
|
|
153
|
+
console.log(`š Phase 3: Code Review (Git Diff)`);
|
|
258
154
|
console.log(`${'='.repeat(60)}\n`);
|
|
259
|
-
const
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
155
|
+
const reviewResult = await reviewCore({
|
|
156
|
+
directory: cwd,
|
|
157
|
+
context: {
|
|
158
|
+
ticketId: ticket.id,
|
|
159
|
+
ticketTitle: ticket.title,
|
|
160
|
+
ticketDescription: ticket.description,
|
|
161
|
+
},
|
|
265
162
|
});
|
|
266
|
-
reviewFixCount = reviewResult.
|
|
163
|
+
reviewFixCount = reviewResult.fixesApplied;
|
|
267
164
|
totalInputTokens += reviewResult.tokensUsed.input;
|
|
268
165
|
totalOutputTokens += reviewResult.tokensUsed.output;
|
|
269
166
|
totalCacheCreationTokens += reviewResult.tokensUsed.cacheCreation;
|
|
270
167
|
totalCacheReadTokens += reviewResult.tokensUsed.cacheRead;
|
|
271
168
|
totalCost += reviewResult.cost;
|
|
272
|
-
console.log(`\nāØ
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
console.log('\nš§ Running linting after review fixes...');
|
|
277
|
-
await runComprehensiveLinting(cwd);
|
|
278
|
-
}
|
|
279
|
-
reviewPerformed = true;
|
|
169
|
+
console.log(`\n⨠Review completed (${reviewResult.issuesFound} issues found, ${reviewFixCount} fixes applied)`);
|
|
170
|
+
}
|
|
171
|
+
else if (review && isSchemaTicket) {
|
|
172
|
+
console.log('\nā¹ļø Skipping code review for SCHEMA ticket (review focuses on application code, not database migrations)');
|
|
280
173
|
}
|
|
281
174
|
// 8. Test phase (if test flag is set) - ITERATIVE
|
|
282
175
|
let testFixCount = 0;
|
|
@@ -345,10 +238,7 @@ export async function shipCore(options) {
|
|
|
345
238
|
success: true,
|
|
346
239
|
implementationFixCount,
|
|
347
240
|
lintFixCount: lintResult.fixCount,
|
|
348
|
-
reviewPerformed,
|
|
349
241
|
reviewFixCount,
|
|
350
|
-
gitDiffReviewed: false,
|
|
351
|
-
gitDiffReviewFixCount: 0,
|
|
352
242
|
tokensUsed: {
|
|
353
243
|
input: totalInputTokens,
|
|
354
244
|
output: totalOutputTokens,
|
|
@@ -368,10 +258,7 @@ export async function shipCore(options) {
|
|
|
368
258
|
success: false,
|
|
369
259
|
implementationFixCount,
|
|
370
260
|
lintFixCount: 0,
|
|
371
|
-
reviewPerformed: false,
|
|
372
261
|
reviewFixCount,
|
|
373
|
-
gitDiffReviewed: false,
|
|
374
|
-
gitDiffReviewFixCount: 0,
|
|
375
262
|
tokensUsed: {
|
|
376
263
|
input: totalInputTokens,
|
|
377
264
|
output: totalOutputTokens,
|
|
@@ -383,27 +270,13 @@ export async function shipCore(options) {
|
|
|
383
270
|
};
|
|
384
271
|
}
|
|
385
272
|
}
|
|
386
|
-
/**
|
|
387
|
-
* Review git diff after implementation
|
|
388
|
-
*/
|
|
389
|
-
async function reviewGitDiff(cwd) {
|
|
390
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
391
|
-
console.log(`š Reviewing Git Diff Against CLAUDE.md`);
|
|
392
|
-
console.log(`${'='.repeat(60)}\n`);
|
|
393
|
-
const result = await reviewCore({ directory: cwd });
|
|
394
|
-
return {
|
|
395
|
-
fixCount: result.fixesApplied,
|
|
396
|
-
cost: result.cost,
|
|
397
|
-
tokensUsed: result.tokensUsed,
|
|
398
|
-
};
|
|
399
|
-
}
|
|
400
273
|
/**
|
|
401
274
|
* Main ship command
|
|
402
275
|
*/
|
|
403
276
|
export async function shipCommand(options) {
|
|
404
|
-
const { ticket: ticketId, commit = false,
|
|
277
|
+
const { ticket: ticketId, commit = false, directory, noLogs = false } = options;
|
|
405
278
|
console.log(`š¢ Shipping Ticket: ${ticketId}\n`);
|
|
406
|
-
// Resolve directory
|
|
279
|
+
// Resolve directory
|
|
407
280
|
const cwd = directory ? resolve(directory) : process.cwd();
|
|
408
281
|
// Initialize logging context
|
|
409
282
|
const logContext = logger.createContext('ship', { noLogs });
|
|
@@ -413,122 +286,38 @@ export async function shipCommand(options) {
|
|
|
413
286
|
if (!process.env.ANTHROPIC_API_KEY) {
|
|
414
287
|
throw new Error('ANTHROPIC_API_KEY environment variable is required');
|
|
415
288
|
}
|
|
416
|
-
// Validate mutually exclusive flags
|
|
417
|
-
if (commit && pr) {
|
|
418
|
-
throw new Error('Cannot use --commit and --pr together.\n' +
|
|
419
|
-
'Use --commit to push to current branch, or --pr to create a new branch with pull request.');
|
|
420
|
-
}
|
|
421
|
-
if (pr && !process.env.GITHUB_TOKEN) {
|
|
422
|
-
throw new Error('GITHUB_TOKEN environment variable is required for --pr flag');
|
|
423
|
-
}
|
|
424
289
|
if (commit && !process.env.GITHUB_TOKEN) {
|
|
425
290
|
throw new Error('GITHUB_TOKEN environment variable is required for --commit flag');
|
|
426
291
|
}
|
|
427
|
-
//
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
const { result: shipResult, prInfo } = await runWithPR({
|
|
432
|
-
branchPrefix: `feat/ticket-${ticketId}`,
|
|
433
|
-
baseBranch: options.baseBranch,
|
|
434
|
-
commitMessage: `feat: implement ${ticketId}`,
|
|
435
|
-
prTitle: `feat: Implement ${ticketId}`,
|
|
436
|
-
prBody: `## š« Ticket Implementation
|
|
437
|
-
|
|
438
|
-
Implements ticket **${ticketId}** from tickets.json.
|
|
439
|
-
|
|
440
|
-
### š Details
|
|
441
|
-
- Implementation fixes: ${0} (will be filled by result)
|
|
442
|
-
- Linting fixes: ${0}
|
|
443
|
-
- Review performed: ${options.review ? 'Yes' : 'No'}
|
|
444
|
-
|
|
445
|
-
---
|
|
446
|
-
|
|
447
|
-
š¤ *Generated by Kosuke CLI (\`kosuke ship --ticket=${ticketId} ${options.review ? '--review ' : ''}--pr\`)*`,
|
|
448
|
-
cwd,
|
|
449
|
-
}, async () => {
|
|
450
|
-
// Run core implementation
|
|
451
|
-
const result = await shipCore(options);
|
|
452
|
-
// Track metrics
|
|
453
|
-
logger.trackTokens(logContext, result.tokensUsed);
|
|
454
|
-
logContext.fixesApplied +=
|
|
455
|
-
result.implementationFixCount + result.lintFixCount + result.reviewFixCount;
|
|
456
|
-
// Review git diff before committing
|
|
457
|
-
const diffReview = await reviewGitDiff(cwd);
|
|
458
|
-
diffReviewCost = diffReview.cost;
|
|
459
|
-
diffReviewFixCount = diffReview.fixCount;
|
|
460
|
-
// Track diff review metrics
|
|
461
|
-
logger.trackTokens(logContext, diffReview.tokensUsed);
|
|
462
|
-
logContext.fixesApplied += diffReview.fixCount;
|
|
463
|
-
return result;
|
|
464
|
-
});
|
|
465
|
-
// Display summary with updated values
|
|
466
|
-
console.log('\nā
Ship completed successfully!');
|
|
467
|
-
console.log(`š Implementation fixes: ${shipResult.implementationFixCount}`);
|
|
468
|
-
console.log(`š§ Linting fixes: ${shipResult.lintFixCount}`);
|
|
469
|
-
if (shipResult.reviewPerformed) {
|
|
470
|
-
console.log(`š Pre-review fixes: ${shipResult.reviewFixCount}`);
|
|
471
|
-
}
|
|
472
|
-
console.log(`š Git diff review fixes: ${diffReviewFixCount}`);
|
|
473
|
-
console.log(`š° Total cost: $${(shipResult.cost + diffReviewCost).toFixed(4)}`);
|
|
474
|
-
console.log(`š PR: ${prInfo.prUrl}`);
|
|
475
|
-
// Log successful execution
|
|
476
|
-
await logger.complete(logContext, 'success');
|
|
477
|
-
cleanupHandler();
|
|
292
|
+
// Run core implementation
|
|
293
|
+
const result = await shipCore(options);
|
|
294
|
+
if (!result.success) {
|
|
295
|
+
throw new Error(result.error || 'Ship failed');
|
|
478
296
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
// Track core metrics
|
|
486
|
-
logger.trackTokens(logContext, result.tokensUsed);
|
|
487
|
-
logContext.fixesApplied +=
|
|
488
|
-
result.implementationFixCount + result.lintFixCount + result.reviewFixCount;
|
|
489
|
-
// Review git diff before committing
|
|
490
|
-
const diffReview = await reviewGitDiff(cwd);
|
|
491
|
-
// Track diff review metrics
|
|
492
|
-
logger.trackTokens(logContext, diffReview.tokensUsed);
|
|
493
|
-
logContext.fixesApplied += diffReview.fixCount;
|
|
494
|
-
// Commit and push to current branch
|
|
297
|
+
// Track metrics
|
|
298
|
+
logger.trackTokens(logContext, result.tokensUsed);
|
|
299
|
+
logContext.fixesApplied =
|
|
300
|
+
result.implementationFixCount + result.lintFixCount + result.reviewFixCount;
|
|
301
|
+
// Commit if flag is set
|
|
302
|
+
if (commit) {
|
|
495
303
|
console.log('\nš Committing and pushing to current branch...');
|
|
496
304
|
await commitAndPushCurrentBranch(`feat: implement ${ticketId}`, cwd);
|
|
497
305
|
console.log(' ā
Changes committed and pushed\n');
|
|
498
|
-
console.log('\nā
Ship completed successfully!');
|
|
499
|
-
console.log(`š Implementation fixes: ${result.implementationFixCount}`);
|
|
500
|
-
console.log(`š§ Linting fixes: ${result.lintFixCount}`);
|
|
501
|
-
if (result.reviewPerformed) {
|
|
502
|
-
console.log(`š Pre-review fixes: ${result.reviewFixCount}`);
|
|
503
|
-
}
|
|
504
|
-
console.log(`š Git diff review fixes: ${diffReview.fixCount}`);
|
|
505
|
-
console.log(`š° Total cost: $${(result.cost + diffReview.cost).toFixed(4)}`);
|
|
506
|
-
// Log successful execution
|
|
507
|
-
await logger.complete(logContext, 'success');
|
|
508
|
-
cleanupHandler();
|
|
509
306
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
console.log('\nā
Ship completed successfully!');
|
|
521
|
-
console.log(`š Implementation fixes: ${result.implementationFixCount}`);
|
|
522
|
-
console.log(`š§ Linting fixes: ${result.lintFixCount}`);
|
|
523
|
-
if (result.reviewPerformed) {
|
|
524
|
-
console.log(`š Review fixes: ${result.reviewFixCount}`);
|
|
525
|
-
}
|
|
526
|
-
console.log(`š° Total cost: $${result.cost.toFixed(4)}`);
|
|
527
|
-
console.log('\nā¹ļø Changes applied locally. Use --commit to push or --pr to create a pull request.');
|
|
528
|
-
// Log successful execution
|
|
529
|
-
await logger.complete(logContext, 'success');
|
|
530
|
-
cleanupHandler();
|
|
307
|
+
// Display summary
|
|
308
|
+
console.log('\nā
Ship completed successfully!');
|
|
309
|
+
console.log(`š Implementation fixes: ${result.implementationFixCount}`);
|
|
310
|
+
console.log(`š§ Linting fixes: ${result.lintFixCount}`);
|
|
311
|
+
if (result.reviewFixCount > 0) {
|
|
312
|
+
console.log(`š Review fixes: ${result.reviewFixCount}`);
|
|
313
|
+
}
|
|
314
|
+
console.log(`š° Total cost: $${result.cost.toFixed(4)}`);
|
|
315
|
+
if (!commit) {
|
|
316
|
+
console.log('\nā¹ļø Changes applied locally. Use --commit to push to current branch.');
|
|
531
317
|
}
|
|
318
|
+
// Log successful execution
|
|
319
|
+
await logger.complete(logContext, 'success');
|
|
320
|
+
cleanupHandler();
|
|
532
321
|
}
|
|
533
322
|
catch (error) {
|
|
534
323
|
console.error('\nā Ship failed:', error);
|