jerad-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +149 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/link.d.ts +3 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +49 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +35 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +31 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/next.d.ts +3 -0
- package/dist/commands/next.d.ts.map +1 -0
- package/dist/commands/next.js +163 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +79 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +44 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +49 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +83 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/claude-code.d.ts +11 -0
- package/dist/lib/claude-code.d.ts.map +1 -0
- package/dist/lib/claude-code.js +67 -0
- package/dist/lib/claude-code.js.map +1 -0
- package/dist/lib/config.d.ts +26 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +87 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/git.d.ts +10 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +77 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/ui/task-display.d.ts +22 -0
- package/dist/ui/task-display.d.ts.map +1 -0
- package/dist/ui/task-display.js +177 -0
- package/dist/ui/task-display.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { isAuthenticated, getUser, getApiUrl } from '../lib/config.js';
|
|
5
|
+
import { getApiClient } from '../lib/api.js';
|
|
6
|
+
import { displayError, displayWarning } from '../ui/task-display.js';
|
|
7
|
+
export const whoamiCommand = new Command('whoami')
|
|
8
|
+
.description('Show current authentication status')
|
|
9
|
+
.option('-r, --refresh', 'Refresh user info from server')
|
|
10
|
+
.action(async (options) => {
|
|
11
|
+
if (!isAuthenticated()) {
|
|
12
|
+
displayWarning('Not logged in. Run: jerad login <token>');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
const cachedUser = getUser();
|
|
16
|
+
if (options.refresh || !cachedUser) {
|
|
17
|
+
const spinner = ora('Fetching user info...').start();
|
|
18
|
+
try {
|
|
19
|
+
const api = getApiClient();
|
|
20
|
+
const user = await api.validateToken();
|
|
21
|
+
spinner.stop();
|
|
22
|
+
console.log();
|
|
23
|
+
console.log(chalk.bold('Logged in as:'));
|
|
24
|
+
console.log(` Name: ${chalk.cyan(user.name)}`);
|
|
25
|
+
console.log(` Email: ${chalk.cyan(user.email)}`);
|
|
26
|
+
console.log(` API: ${chalk.gray(getApiUrl())}`);
|
|
27
|
+
console.log();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
spinner.stop();
|
|
31
|
+
displayError(error instanceof Error ? error.message : 'Failed to fetch user info');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log();
|
|
37
|
+
console.log(chalk.bold('Logged in as:'));
|
|
38
|
+
console.log(` Name: ${chalk.cyan(cachedUser.name)}`);
|
|
39
|
+
console.log(` Email: ${chalk.cyan(cachedUser.email)}`);
|
|
40
|
+
console.log(` API: ${chalk.gray(getApiUrl())}`);
|
|
41
|
+
console.log();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAErE,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,eAAe,EAAE,+BAA+B,CAAC;KACxD,MAAM,CAAC,KAAK,EAAE,OAA8B,EAAE,EAAE;IAC/C,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,cAAc,CAAC,yCAAyC,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,EAAE,CAAC;IAE7B,IAAI,OAAO,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;QAErD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,EAAE,CAAC;YACvC,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,OAAO,CAAC,GAAG,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,YAAY,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC;YACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { loginCommand } from './commands/login.js';
|
|
4
|
+
import { logoutCommand } from './commands/logout.js';
|
|
5
|
+
import { whoamiCommand } from './commands/whoami.js';
|
|
6
|
+
import { linkCommand } from './commands/link.js';
|
|
7
|
+
import { statusCommand } from './commands/status.js';
|
|
8
|
+
import { devCommand } from './commands/dev.js';
|
|
9
|
+
import { nextCommand } from './commands/next.js';
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name('jerad')
|
|
13
|
+
.description('CLI companion for Jerad - AI-powered SDLC tool')
|
|
14
|
+
.version('0.1.0');
|
|
15
|
+
// Authentication commands
|
|
16
|
+
program.addCommand(loginCommand);
|
|
17
|
+
program.addCommand(logoutCommand);
|
|
18
|
+
program.addCommand(whoamiCommand);
|
|
19
|
+
// Project commands
|
|
20
|
+
program.addCommand(linkCommand);
|
|
21
|
+
program.addCommand(statusCommand);
|
|
22
|
+
// Development commands
|
|
23
|
+
program.addCommand(devCommand);
|
|
24
|
+
program.addCommand(nextCommand);
|
|
25
|
+
program.parse();
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,0BAA0B;AAC1B,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAClC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,mBAAmB;AACnB,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAChC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,uBAAuB;AACvB,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAC/B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;AAEhC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
interface UserInfo {
|
|
2
|
+
id: string;
|
|
3
|
+
email: string;
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
interface Project {
|
|
7
|
+
_id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
slug: string;
|
|
10
|
+
description: string;
|
|
11
|
+
status: string;
|
|
12
|
+
}
|
|
13
|
+
interface Story {
|
|
14
|
+
_id: string;
|
|
15
|
+
projectId: string;
|
|
16
|
+
epicId: string;
|
|
17
|
+
epicTitle: string;
|
|
18
|
+
title: string;
|
|
19
|
+
description: string;
|
|
20
|
+
acceptanceCriteria: string[];
|
|
21
|
+
technicalNotes: string;
|
|
22
|
+
storyPoints: number;
|
|
23
|
+
status: string;
|
|
24
|
+
prototypeScreenIds: string[];
|
|
25
|
+
order: number;
|
|
26
|
+
branch?: string;
|
|
27
|
+
prUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
interface StoryWithPrompt extends Story {
|
|
30
|
+
prompt: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class ApiClient {
|
|
33
|
+
private baseUrl;
|
|
34
|
+
private token;
|
|
35
|
+
constructor();
|
|
36
|
+
private fetch;
|
|
37
|
+
validateToken(): Promise<UserInfo>;
|
|
38
|
+
getProject(projectId: string): Promise<Project>;
|
|
39
|
+
getProjectBySlug(slug: string): Promise<Project>;
|
|
40
|
+
getStories(projectId: string, status?: string): Promise<Story[]>;
|
|
41
|
+
getStory(projectId: string, storyId: string): Promise<StoryWithPrompt>;
|
|
42
|
+
updateStoryStatus(projectId: string, storyId: string, status: string, branch?: string): Promise<Story>;
|
|
43
|
+
getNextTodoStory(projectId: string): Promise<Story | null>;
|
|
44
|
+
getInProgressStories(projectId: string): Promise<Story[]>;
|
|
45
|
+
}
|
|
46
|
+
export declare function getApiClient(): ApiClient;
|
|
47
|
+
export declare function resetApiClient(): void;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAMA,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,OAAO;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,KAAK;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAgB,SAAQ,KAAK;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAqB;;YAOpB,KAAK;IAwBb,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC;IAQlC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAK/C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMhD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAMhE,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAKtE,iBAAiB,CACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC;IAWX,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAK1D,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;CAGhE;AAKD,wBAAgB,YAAY,IAAI,SAAS,CAKxC;AAED,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
package/dist/lib/api.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { getToken, getApiUrl } from './config.js';
|
|
2
|
+
export class ApiClient {
|
|
3
|
+
baseUrl;
|
|
4
|
+
token;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.baseUrl = getApiUrl();
|
|
7
|
+
this.token = getToken();
|
|
8
|
+
}
|
|
9
|
+
async fetch(path, options) {
|
|
10
|
+
if (!this.token) {
|
|
11
|
+
throw new Error('Not authenticated. Run: jerad login <token>');
|
|
12
|
+
}
|
|
13
|
+
const url = `${this.baseUrl}${path}`;
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
...options,
|
|
16
|
+
headers: {
|
|
17
|
+
'Authorization': `Bearer ${this.token}`,
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
...options?.headers,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
const data = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
24
|
+
throw new Error(data.error || `HTTP ${response.status}`);
|
|
25
|
+
}
|
|
26
|
+
return response.json();
|
|
27
|
+
}
|
|
28
|
+
// Authentication
|
|
29
|
+
async validateToken() {
|
|
30
|
+
const data = await this.fetch('/api/cli/auth', {
|
|
31
|
+
method: 'POST',
|
|
32
|
+
});
|
|
33
|
+
return data.user;
|
|
34
|
+
}
|
|
35
|
+
// Projects
|
|
36
|
+
async getProject(projectId) {
|
|
37
|
+
const data = await this.fetch(`/api/cli/projects/${projectId}`);
|
|
38
|
+
return data.project;
|
|
39
|
+
}
|
|
40
|
+
async getProjectBySlug(slug) {
|
|
41
|
+
const data = await this.fetch(`/api/cli/projects/by-slug/${slug}`);
|
|
42
|
+
return data.project;
|
|
43
|
+
}
|
|
44
|
+
// Stories
|
|
45
|
+
async getStories(projectId, status) {
|
|
46
|
+
const params = status ? `?status=${status}` : '';
|
|
47
|
+
const data = await this.fetch(`/api/cli/projects/${projectId}/stories${params}`);
|
|
48
|
+
return data.stories;
|
|
49
|
+
}
|
|
50
|
+
async getStory(projectId, storyId) {
|
|
51
|
+
const data = await this.fetch(`/api/cli/projects/${projectId}/stories/${storyId}`);
|
|
52
|
+
return data.story;
|
|
53
|
+
}
|
|
54
|
+
async updateStoryStatus(projectId, storyId, status, branch) {
|
|
55
|
+
const body = { status };
|
|
56
|
+
if (branch)
|
|
57
|
+
body.branch = branch;
|
|
58
|
+
const data = await this.fetch(`/api/cli/projects/${projectId}/stories/${storyId}`, {
|
|
59
|
+
method: 'PATCH',
|
|
60
|
+
body: JSON.stringify(body),
|
|
61
|
+
});
|
|
62
|
+
return data.story;
|
|
63
|
+
}
|
|
64
|
+
async getNextTodoStory(projectId) {
|
|
65
|
+
const stories = await this.getStories(projectId, 'todo');
|
|
66
|
+
return stories.length > 0 ? stories[0] : null;
|
|
67
|
+
}
|
|
68
|
+
async getInProgressStories(projectId) {
|
|
69
|
+
return this.getStories(projectId, 'in_progress');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Singleton instance
|
|
73
|
+
let apiClient = null;
|
|
74
|
+
export function getApiClient() {
|
|
75
|
+
if (!apiClient) {
|
|
76
|
+
apiClient = new ApiClient();
|
|
77
|
+
}
|
|
78
|
+
return apiClient;
|
|
79
|
+
}
|
|
80
|
+
export function resetApiClient() {
|
|
81
|
+
apiClient = null;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function checkClaudeInstalled(): Promise<boolean>;
|
|
2
|
+
export declare function getClaudeVersion(): Promise<string | null>;
|
|
3
|
+
export interface ClaudeCodeOptions {
|
|
4
|
+
prompt: string;
|
|
5
|
+
interactive?: boolean;
|
|
6
|
+
onOutput?: (data: string) => void;
|
|
7
|
+
onError?: (data: string) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function runClaudeCode(options: ClaudeCodeOptions): Promise<number>;
|
|
10
|
+
export declare function runClaudeCodeInteractive(prompt: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=claude-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/lib/claude-code.ts"],"names":[],"mappings":"AAKA,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO7D;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO/D;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCzE;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { spawn, exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
const execAsync = promisify(exec);
|
|
4
|
+
export async function checkClaudeInstalled() {
|
|
5
|
+
try {
|
|
6
|
+
await execAsync('claude --version');
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function getClaudeVersion() {
|
|
14
|
+
try {
|
|
15
|
+
const { stdout } = await execAsync('claude --version');
|
|
16
|
+
return stdout.trim();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function runClaudeCode(options) {
|
|
23
|
+
const { prompt, interactive = true, onOutput, onError } = options;
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
// Build arguments - prompt is passed as first positional argument
|
|
26
|
+
const args = [prompt];
|
|
27
|
+
if (!interactive) {
|
|
28
|
+
args.push('--print');
|
|
29
|
+
}
|
|
30
|
+
const claude = spawn('claude', args, {
|
|
31
|
+
stdio: interactive ? ['inherit', 'inherit', 'inherit'] : ['pipe', 'pipe', 'pipe'],
|
|
32
|
+
shell: false, // Avoid shell to prevent security warnings and properly escape args
|
|
33
|
+
});
|
|
34
|
+
if (!interactive) {
|
|
35
|
+
if (claude.stdout && onOutput) {
|
|
36
|
+
claude.stdout.on('data', (data) => {
|
|
37
|
+
onOutput(data.toString());
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (claude.stderr && onError) {
|
|
41
|
+
claude.stderr.on('data', (data) => {
|
|
42
|
+
onError(data.toString());
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
claude.on('error', (error) => {
|
|
47
|
+
reject(new Error(`Failed to start Claude Code: ${error.message}`));
|
|
48
|
+
});
|
|
49
|
+
claude.on('close', (code) => {
|
|
50
|
+
resolve(code ?? 0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export async function runClaudeCodeInteractive(prompt) {
|
|
55
|
+
const isInstalled = await checkClaudeInstalled();
|
|
56
|
+
if (!isInstalled) {
|
|
57
|
+
throw new Error('Claude Code is not installed. Install it with: npm install -g @anthropic-ai/claude-code');
|
|
58
|
+
}
|
|
59
|
+
const exitCode = await runClaudeCode({
|
|
60
|
+
prompt,
|
|
61
|
+
interactive: true,
|
|
62
|
+
});
|
|
63
|
+
if (exitCode !== 0) {
|
|
64
|
+
throw new Error(`Claude Code exited with code ${exitCode}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=claude-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/lib/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,SAAS,CAAC,kBAAkB,CAAC,CAAC;QACvD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AASD,MAAM,UAAU,aAAa,CAAC,OAA0B;IACtD,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAElE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,kEAAkE;QAClE,MAAM,IAAI,GAAa,CAAC,MAAM,CAAC,CAAC;QAEhC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;YACnC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YACjF,KAAK,EAAE,KAAK,EAAE,oEAAoE;SACnF,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;gBAC9B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;oBACxC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5B,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;oBACxC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC3B,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAAc;IAC3D,MAAM,WAAW,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACjD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC;QACnC,MAAM;QACN,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface ProjectConfig {
|
|
2
|
+
projectId: string;
|
|
3
|
+
projectName: string;
|
|
4
|
+
projectSlug: string;
|
|
5
|
+
linkedAt: string;
|
|
6
|
+
}
|
|
7
|
+
interface UserInfo {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function getToken(): string | undefined;
|
|
13
|
+
export declare function setToken(token: string): void;
|
|
14
|
+
export declare function clearToken(): void;
|
|
15
|
+
export declare function isAuthenticated(): boolean;
|
|
16
|
+
export declare function getUser(): UserInfo | undefined;
|
|
17
|
+
export declare function setUser(user: UserInfo): void;
|
|
18
|
+
export declare function getApiUrl(): string;
|
|
19
|
+
export declare function setApiUrl(url: string): void;
|
|
20
|
+
export declare function getProjectConfigPath(): string;
|
|
21
|
+
export declare function getProjectConfig(): ProjectConfig | null;
|
|
22
|
+
export declare function setProjectConfig(config: ProjectConfig): void;
|
|
23
|
+
export declare function clearProjectConfig(): void;
|
|
24
|
+
export declare function isProjectLinked(): boolean;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AA6BA,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAGD,wBAAgB,QAAQ,IAAI,MAAM,GAAG,SAAS,CAE7C;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAE5C;AAED,wBAAgB,UAAU,IAAI,IAAI,CAGjC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAGD,wBAAgB,OAAO,IAAI,QAAQ,GAAG,SAAS,CAE9C;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAE5C;AAMD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE3C;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,IAAI,CAavD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAG5D;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
// Global config stored in ~/.jerad/config.json
|
|
5
|
+
const globalConfig = new Conf({
|
|
6
|
+
projectName: 'jerad',
|
|
7
|
+
schema: {
|
|
8
|
+
token: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
},
|
|
11
|
+
user: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
id: { type: 'string' },
|
|
15
|
+
email: { type: 'string' },
|
|
16
|
+
name: { type: 'string' },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
apiUrl: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
default: 'https://jerad-olive.vercel.app',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
// Project link config stored in ./.jerad.json
|
|
26
|
+
const PROJECT_CONFIG_FILE = '.jerad.json';
|
|
27
|
+
// Token management
|
|
28
|
+
export function getToken() {
|
|
29
|
+
return globalConfig.get('token');
|
|
30
|
+
}
|
|
31
|
+
export function setToken(token) {
|
|
32
|
+
globalConfig.set('token', token);
|
|
33
|
+
}
|
|
34
|
+
export function clearToken() {
|
|
35
|
+
globalConfig.delete('token');
|
|
36
|
+
globalConfig.delete('user');
|
|
37
|
+
}
|
|
38
|
+
export function isAuthenticated() {
|
|
39
|
+
return !!getToken();
|
|
40
|
+
}
|
|
41
|
+
// User info management
|
|
42
|
+
export function getUser() {
|
|
43
|
+
return globalConfig.get('user');
|
|
44
|
+
}
|
|
45
|
+
export function setUser(user) {
|
|
46
|
+
globalConfig.set('user', user);
|
|
47
|
+
}
|
|
48
|
+
// API URL management
|
|
49
|
+
// Default to production, override with JERAD_API_URL for local dev
|
|
50
|
+
const DEFAULT_API_URL = 'https://jerad-olive.vercel.app';
|
|
51
|
+
export function getApiUrl() {
|
|
52
|
+
return (process.env.JERAD_API_URL || globalConfig.get('apiUrl') || DEFAULT_API_URL);
|
|
53
|
+
}
|
|
54
|
+
export function setApiUrl(url) {
|
|
55
|
+
globalConfig.set('apiUrl', url);
|
|
56
|
+
}
|
|
57
|
+
// Project link management
|
|
58
|
+
export function getProjectConfigPath() {
|
|
59
|
+
return path.join(process.cwd(), PROJECT_CONFIG_FILE);
|
|
60
|
+
}
|
|
61
|
+
export function getProjectConfig() {
|
|
62
|
+
const configPath = getProjectConfigPath();
|
|
63
|
+
if (!fs.existsSync(configPath)) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
68
|
+
return JSON.parse(content);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export function setProjectConfig(config) {
|
|
75
|
+
const configPath = getProjectConfigPath();
|
|
76
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
77
|
+
}
|
|
78
|
+
export function clearProjectConfig() {
|
|
79
|
+
const configPath = getProjectConfigPath();
|
|
80
|
+
if (fs.existsSync(configPath)) {
|
|
81
|
+
fs.unlinkSync(configPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export function isProjectLinked() {
|
|
85
|
+
return getProjectConfig() !== null;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function isGitRepo(): Promise<boolean>;
|
|
2
|
+
export declare function getCurrentBranch(): Promise<string>;
|
|
3
|
+
export declare function branchExists(name: string): Promise<boolean>;
|
|
4
|
+
export declare function createBranch(name: string): Promise<void>;
|
|
5
|
+
export declare function commitChanges(message: string): Promise<void>;
|
|
6
|
+
export declare function pushBranch(name: string): Promise<void>;
|
|
7
|
+
export declare function hasRemote(): Promise<boolean>;
|
|
8
|
+
export declare function sanitizeBranchName(name: string): string;
|
|
9
|
+
export declare function createStoryBranchName(storyId: string, title: string): string;
|
|
10
|
+
//# sourceMappingURL=git.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"AAKA,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAOlD;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGxD;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAe9D;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYlE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE5D;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAOlD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG5E"}
|
package/dist/lib/git.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { exec } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
const execAsync = promisify(exec);
|
|
4
|
+
export async function isGitRepo() {
|
|
5
|
+
try {
|
|
6
|
+
await execAsync('git rev-parse --git-dir');
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function getCurrentBranch() {
|
|
14
|
+
const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');
|
|
15
|
+
return stdout.trim();
|
|
16
|
+
}
|
|
17
|
+
export async function branchExists(name) {
|
|
18
|
+
try {
|
|
19
|
+
await execAsync(`git rev-parse --verify ${name}`);
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export async function createBranch(name) {
|
|
27
|
+
// First ensure we're on a clean state
|
|
28
|
+
const { stdout: status } = await execAsync('git status --porcelain');
|
|
29
|
+
if (status.trim()) {
|
|
30
|
+
throw new Error('Working directory has uncommitted changes. Please commit or stash them first.');
|
|
31
|
+
}
|
|
32
|
+
// Check if branch already exists
|
|
33
|
+
if (await branchExists(name)) {
|
|
34
|
+
// Switch to existing branch
|
|
35
|
+
await execAsync(`git checkout ${name}`);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Create and switch to new branch
|
|
39
|
+
await execAsync(`git checkout -b ${name}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function commitChanges(message) {
|
|
43
|
+
// Stage all changes
|
|
44
|
+
await execAsync('git add -A');
|
|
45
|
+
// Check if there are changes to commit
|
|
46
|
+
const { stdout: status } = await execAsync('git status --porcelain');
|
|
47
|
+
if (!status.trim()) {
|
|
48
|
+
throw new Error('No changes to commit');
|
|
49
|
+
}
|
|
50
|
+
// Commit
|
|
51
|
+
await execAsync(`git commit -m "${message.replace(/"/g, '\\"')}"`);
|
|
52
|
+
}
|
|
53
|
+
export async function pushBranch(name) {
|
|
54
|
+
await execAsync(`git push -u origin ${name}`);
|
|
55
|
+
}
|
|
56
|
+
export async function hasRemote() {
|
|
57
|
+
try {
|
|
58
|
+
const { stdout } = await execAsync('git remote');
|
|
59
|
+
return stdout.trim().length > 0;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
export function sanitizeBranchName(name) {
|
|
66
|
+
return name
|
|
67
|
+
.toLowerCase()
|
|
68
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
69
|
+
.replace(/-+/g, '-')
|
|
70
|
+
.replace(/^-|-$/g, '')
|
|
71
|
+
.substring(0, 50);
|
|
72
|
+
}
|
|
73
|
+
export function createStoryBranchName(storyId, title) {
|
|
74
|
+
const sanitizedTitle = sanitizeBranchName(title);
|
|
75
|
+
return `jerad/${storyId}-${sanitizedTitle}`;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/lib/git.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface Story {
|
|
2
|
+
_id: string;
|
|
3
|
+
epicId: string;
|
|
4
|
+
epicTitle: string;
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
acceptanceCriteria: string[];
|
|
8
|
+
technicalNotes: string;
|
|
9
|
+
storyPoints: number;
|
|
10
|
+
status: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function displayHeader(projectName: string, status?: string): void;
|
|
13
|
+
export declare function displayTaskCard(story: Story): void;
|
|
14
|
+
export declare function displaySuccess(message: string): void;
|
|
15
|
+
export declare function displayError(message: string): void;
|
|
16
|
+
export declare function displayWarning(message: string): void;
|
|
17
|
+
export declare function displayInfo(message: string): void;
|
|
18
|
+
export declare function displayBranchCreated(branchName: string): void;
|
|
19
|
+
export declare function displayStartingClaude(): void;
|
|
20
|
+
export declare function displayClaudeComplete(): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=task-display.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"task-display.d.ts","sourceRoot":"","sources":["../../src/ui/task-display.ts"],"names":[],"mappings":"AAEA,UAAU,KAAK;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AA6CD,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,GAAE,MAAgC,GAAG,IAAI,CAyCjG;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAuHlD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|