kimaki 0.0.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 +0 -0
- package/bin.js +5 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +35 -0
- package/dist/cli.js.map +1 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +150 -0
- package/dist/utils.js.map +1 -0
- package/package.json +43 -0
- package/src/cli.ts +42 -0
- package/src/utils.ts +163 -0
package/README.md
ADDED
|
File without changes
|
package/bin.js
ADDED
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,GAAG,mBAAgB,CAAA"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { cac } from 'cac';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
export const cli = cac('kimaki');
|
|
4
|
+
cli.help();
|
|
5
|
+
// Check if running in TTY environment
|
|
6
|
+
const isTTY = process.stdout.isTTY && process.stdin.isTTY;
|
|
7
|
+
cli.command('', '')
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
try {
|
|
10
|
+
import { Modality } from '@google/genai';
|
|
11
|
+
import * as webAudioApi from 'node-web-audio-api';
|
|
12
|
+
// @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
|
|
13
|
+
import { mediaDevices } from 'node-web-audio-api';
|
|
14
|
+
const token = process.env.TOKEN;
|
|
15
|
+
Object.assign(globalThis, webAudioApi);
|
|
16
|
+
// @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
|
|
17
|
+
navigator.mediaDevices = mediaDevices;
|
|
18
|
+
const { LiveAPIClient } = await import('liveapi');
|
|
19
|
+
const newClient = new LiveAPIClient({
|
|
20
|
+
apiKey: token,
|
|
21
|
+
config: {
|
|
22
|
+
responseModalities: [Modality.AUDIO],
|
|
23
|
+
// tools: callableTools,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
// Connect to the API
|
|
27
|
+
const connected = await newClient.connect();
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(pc.red('\nError initializing project:'));
|
|
31
|
+
console.error(pc.red(error));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAA;AAEhC,GAAG,CAAC,IAAI,EAAE,CAAA;AAEV,sCAAsC;AACtC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAA;AAEzD,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC;KAEd,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;QACxC,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAA;QACjD,8FAA8F;QAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;QAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;QAE/B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;QACtC,8FAA8F;QAC9F,SAAS,CAAC,YAAY,GAAG,YAAY,CAAA;QAErC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC;YAChC,MAAM,EAAE,KAAM;YACd,MAAM,EAAE;gBACJ,kBAAkB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACpC,wBAAwB;aAC3B;SACJ,CAAC,CAAA;QAEF,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAA;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC,CAAC,CAAA"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function getCurrentGitBranch(): Promise<string | undefined>;
|
|
2
|
+
export declare function openUrlInBrowser(url: string): void;
|
|
3
|
+
export declare function safeParseJson<T = any>(str: string): T | undefined;
|
|
4
|
+
export declare function getGitRepoRoot(): string | undefined;
|
|
5
|
+
export declare function getGitRemoteUrl(): string | undefined;
|
|
6
|
+
export declare function getGitHubInfo(): {
|
|
7
|
+
githubOwner: string;
|
|
8
|
+
githubRepo: string;
|
|
9
|
+
name: string;
|
|
10
|
+
} | undefined;
|
|
11
|
+
export declare function checkGitStatus(): {
|
|
12
|
+
hasUncommittedChanges: boolean;
|
|
13
|
+
hasUnpushedCommits: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAOA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgCvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,QAqB3C;AAED,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAMjE;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CASnD;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAQpD;AAED,wBAAgB,aAAa,IACvB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzD,SAAS,CAad;AAED,wBAAgB,cAAc,IAAI;IAC9B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAgDA"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
export async function getCurrentGitBranch() {
|
|
5
|
+
try {
|
|
6
|
+
// First check if we're in a git repository
|
|
7
|
+
try {
|
|
8
|
+
execSync('git rev-parse --git-dir', { stdio: 'ignore' });
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
// Check if HEAD exists and has commits
|
|
14
|
+
try {
|
|
15
|
+
execSync('git rev-parse --verify HEAD', { stdio: 'ignore' });
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// No commits yet, check if we're on a branch
|
|
19
|
+
try {
|
|
20
|
+
const branch = execSync('git symbolic-ref --short HEAD', {
|
|
21
|
+
encoding: 'utf-8',
|
|
22
|
+
}).trim();
|
|
23
|
+
return branch;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Normal case: get current branch
|
|
30
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
31
|
+
encoding: 'utf-8',
|
|
32
|
+
}).trim();
|
|
33
|
+
return branch === 'HEAD' ? undefined : branch;
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function openUrlInBrowser(url) {
|
|
40
|
+
let command;
|
|
41
|
+
switch (os.platform()) {
|
|
42
|
+
case 'darwin':
|
|
43
|
+
command = `open "${url}"`;
|
|
44
|
+
break;
|
|
45
|
+
case 'win32':
|
|
46
|
+
command = `start "" "${url}"`;
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
// linux, unix, etc.
|
|
50
|
+
command = `xdg-open "${url}"`;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
execSync(command, { stdio: 'ignore' });
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('Failed to open URL in browser:', error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export function safeParseJson(str) {
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(str);
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function getGitRepoRoot() {
|
|
69
|
+
try {
|
|
70
|
+
const repoRoot = execSync('git rev-parse --show-toplevel', {
|
|
71
|
+
encoding: 'utf-8',
|
|
72
|
+
}).trim();
|
|
73
|
+
return path.resolve(repoRoot);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function getGitRemoteUrl() {
|
|
80
|
+
try {
|
|
81
|
+
return execSync('git remote get-url origin', {
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
}).trim();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export function getGitHubInfo() {
|
|
90
|
+
const remoteUrl = getGitRemoteUrl();
|
|
91
|
+
if (!remoteUrl)
|
|
92
|
+
return undefined;
|
|
93
|
+
const match = remoteUrl.match(/github\.com[\/:]([^\/]+)\/([^\/\.]+)/);
|
|
94
|
+
if (match) {
|
|
95
|
+
return {
|
|
96
|
+
githubOwner: match[1],
|
|
97
|
+
githubRepo: match[2],
|
|
98
|
+
name: match[2],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
export function checkGitStatus() {
|
|
104
|
+
try {
|
|
105
|
+
// Check for uncommitted changes using porcelain format for machine readable output
|
|
106
|
+
const gitStatus = execSync('git status --porcelain', {
|
|
107
|
+
encoding: 'utf-8',
|
|
108
|
+
}).trim();
|
|
109
|
+
const hasUncommittedChanges = gitStatus.length > 0;
|
|
110
|
+
// Check for unpushed commits
|
|
111
|
+
let hasUnpushedCommits = false;
|
|
112
|
+
try {
|
|
113
|
+
const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
114
|
+
encoding: 'utf-8',
|
|
115
|
+
}).trim();
|
|
116
|
+
if (currentBranch && currentBranch !== 'HEAD') {
|
|
117
|
+
// Check if remote branch exists
|
|
118
|
+
try {
|
|
119
|
+
execSync(`git rev-parse --verify origin/${currentBranch}`, {
|
|
120
|
+
stdio: 'ignore',
|
|
121
|
+
});
|
|
122
|
+
// Remote branch exists, check for unpushed commits
|
|
123
|
+
const unpushedCommits = execSync(`git log origin/${currentBranch}..${currentBranch} --oneline`, { encoding: 'utf-8' }).trim();
|
|
124
|
+
hasUnpushedCommits = unpushedCommits.length > 0;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Remote branch doesn't exist, so we have unpushed commits
|
|
128
|
+
hasUnpushedCommits = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
// Could not determine branch or remote status
|
|
134
|
+
return {
|
|
135
|
+
hasUncommittedChanges,
|
|
136
|
+
hasUnpushedCommits: false,
|
|
137
|
+
error: 'Could not check remote branch status',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return { hasUncommittedChanges, hasUnpushedCommits };
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
return {
|
|
144
|
+
hasUncommittedChanges: false,
|
|
145
|
+
hasUnpushedCommits: false,
|
|
146
|
+
error: e.message,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kimaki",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"repository": "https://github.com/remorses/kimaki",
|
|
7
|
+
"bin": "./bin.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src",
|
|
11
|
+
"bin.js"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>",
|
|
15
|
+
"license": "",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@google/genai": "^1.16.0",
|
|
18
|
+
"cac": "^6.7.14",
|
|
19
|
+
"chokidar": "^4.0.3",
|
|
20
|
+
"cli-table3": "^0.6.5",
|
|
21
|
+
"globby": "^14.1.0",
|
|
22
|
+
"mime-types": "^2.1.35",
|
|
23
|
+
"node-web-audio-api": "^1.0.4",
|
|
24
|
+
"picocolors": "^1.1.1",
|
|
25
|
+
"prompts": "^2.4.2",
|
|
26
|
+
"sema4": "^0.1.3",
|
|
27
|
+
"tiny-jsonc": "^1.0.2",
|
|
28
|
+
"ws": "^8.18.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/mime-types": "^2.1.4",
|
|
32
|
+
"@types/node": "^24.3.0",
|
|
33
|
+
"@types/prompts": "^2.4.9",
|
|
34
|
+
"@types/ws": "^8.18.1"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc ",
|
|
38
|
+
"typecheck": "tsc",
|
|
39
|
+
"_prepublishOnly": "tsc",
|
|
40
|
+
"holocron": "node bin.js",
|
|
41
|
+
"watch": "tsc -w"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { cac } from 'cac'
|
|
2
|
+
import pc from 'picocolors'
|
|
3
|
+
|
|
4
|
+
export const cli = cac('kimaki')
|
|
5
|
+
|
|
6
|
+
cli.help()
|
|
7
|
+
|
|
8
|
+
// Check if running in TTY environment
|
|
9
|
+
const isTTY = process.stdout.isTTY && process.stdin.isTTY
|
|
10
|
+
|
|
11
|
+
cli.command('', '')
|
|
12
|
+
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
try {
|
|
15
|
+
import { Modality } from '@google/genai'
|
|
16
|
+
import * as webAudioApi from 'node-web-audio-api'
|
|
17
|
+
// @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
|
|
18
|
+
import { mediaDevices } from 'node-web-audio-api'
|
|
19
|
+
|
|
20
|
+
const token = process.env.TOKEN
|
|
21
|
+
|
|
22
|
+
Object.assign(globalThis, webAudioApi)
|
|
23
|
+
// @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
|
|
24
|
+
navigator.mediaDevices = mediaDevices
|
|
25
|
+
|
|
26
|
+
const { LiveAPIClient } = await import('liveapi')
|
|
27
|
+
const newClient = new LiveAPIClient({
|
|
28
|
+
apiKey: token!,
|
|
29
|
+
config: {
|
|
30
|
+
responseModalities: [Modality.AUDIO],
|
|
31
|
+
// tools: callableTools,
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Connect to the API
|
|
36
|
+
const connected = await newClient.connect()
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(pc.red('\nError initializing project:'))
|
|
39
|
+
console.error(pc.red(error))
|
|
40
|
+
process.exit(1)
|
|
41
|
+
}
|
|
42
|
+
})
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import os from 'node:os'
|
|
2
|
+
import JSONC from 'tiny-jsonc'
|
|
3
|
+
import fs from 'node:fs'
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
|
|
6
|
+
import { execSync } from 'node:child_process'
|
|
7
|
+
|
|
8
|
+
export async function getCurrentGitBranch(): Promise<string | undefined> {
|
|
9
|
+
try {
|
|
10
|
+
// First check if we're in a git repository
|
|
11
|
+
try {
|
|
12
|
+
execSync('git rev-parse --git-dir', { stdio: 'ignore' })
|
|
13
|
+
} catch {
|
|
14
|
+
return undefined
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// Check if HEAD exists and has commits
|
|
18
|
+
try {
|
|
19
|
+
execSync('git rev-parse --verify HEAD', { stdio: 'ignore' })
|
|
20
|
+
} catch {
|
|
21
|
+
// No commits yet, check if we're on a branch
|
|
22
|
+
try {
|
|
23
|
+
const branch = execSync('git symbolic-ref --short HEAD', {
|
|
24
|
+
encoding: 'utf-8',
|
|
25
|
+
}).trim()
|
|
26
|
+
return branch
|
|
27
|
+
} catch {
|
|
28
|
+
return undefined
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Normal case: get current branch
|
|
33
|
+
const branch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
34
|
+
encoding: 'utf-8',
|
|
35
|
+
}).trim()
|
|
36
|
+
return branch === 'HEAD' ? undefined : branch
|
|
37
|
+
} catch (e) {
|
|
38
|
+
return undefined
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function openUrlInBrowser(url: string) {
|
|
43
|
+
let command: string
|
|
44
|
+
|
|
45
|
+
switch (os.platform()) {
|
|
46
|
+
case 'darwin':
|
|
47
|
+
command = `open "${url}"`
|
|
48
|
+
break
|
|
49
|
+
case 'win32':
|
|
50
|
+
command = `start "" "${url}"`
|
|
51
|
+
break
|
|
52
|
+
default:
|
|
53
|
+
// linux, unix, etc.
|
|
54
|
+
command = `xdg-open "${url}"`
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
execSync(command, { stdio: 'ignore' })
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error('Failed to open URL in browser:', error)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function safeParseJson<T = any>(str: string): T | undefined {
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(str) as T
|
|
68
|
+
} catch (e) {
|
|
69
|
+
return undefined
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function getGitRepoRoot(): string | undefined {
|
|
74
|
+
try {
|
|
75
|
+
const repoRoot = execSync('git rev-parse --show-toplevel', {
|
|
76
|
+
encoding: 'utf-8',
|
|
77
|
+
}).trim()
|
|
78
|
+
return path.resolve(repoRoot)
|
|
79
|
+
} catch {
|
|
80
|
+
return undefined
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function getGitRemoteUrl(): string | undefined {
|
|
85
|
+
try {
|
|
86
|
+
return execSync('git remote get-url origin', {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
}).trim()
|
|
89
|
+
} catch {
|
|
90
|
+
return undefined
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function getGitHubInfo():
|
|
95
|
+
| { githubOwner: string; githubRepo: string; name: string }
|
|
96
|
+
| undefined {
|
|
97
|
+
const remoteUrl = getGitRemoteUrl()
|
|
98
|
+
if (!remoteUrl) return undefined
|
|
99
|
+
|
|
100
|
+
const match = remoteUrl.match(/github\.com[\/:]([^\/]+)\/([^\/\.]+)/)
|
|
101
|
+
if (match) {
|
|
102
|
+
return {
|
|
103
|
+
githubOwner: match[1],
|
|
104
|
+
githubRepo: match[2],
|
|
105
|
+
name: match[2],
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function checkGitStatus(): {
|
|
112
|
+
hasUncommittedChanges: boolean
|
|
113
|
+
hasUnpushedCommits: boolean
|
|
114
|
+
error?: string
|
|
115
|
+
} {
|
|
116
|
+
try {
|
|
117
|
+
// Check for uncommitted changes using porcelain format for machine readable output
|
|
118
|
+
const gitStatus = execSync('git status --porcelain', {
|
|
119
|
+
encoding: 'utf-8',
|
|
120
|
+
}).trim()
|
|
121
|
+
const hasUncommittedChanges = gitStatus.length > 0
|
|
122
|
+
|
|
123
|
+
// Check for unpushed commits
|
|
124
|
+
let hasUnpushedCommits = false
|
|
125
|
+
try {
|
|
126
|
+
const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
|
|
127
|
+
encoding: 'utf-8',
|
|
128
|
+
}).trim()
|
|
129
|
+
if (currentBranch && currentBranch !== 'HEAD') {
|
|
130
|
+
// Check if remote branch exists
|
|
131
|
+
try {
|
|
132
|
+
execSync(`git rev-parse --verify origin/${currentBranch}`, {
|
|
133
|
+
stdio: 'ignore',
|
|
134
|
+
})
|
|
135
|
+
// Remote branch exists, check for unpushed commits
|
|
136
|
+
const unpushedCommits = execSync(
|
|
137
|
+
`git log origin/${currentBranch}..${currentBranch} --oneline`,
|
|
138
|
+
{ encoding: 'utf-8' },
|
|
139
|
+
).trim()
|
|
140
|
+
hasUnpushedCommits = unpushedCommits.length > 0
|
|
141
|
+
} catch {
|
|
142
|
+
// Remote branch doesn't exist, so we have unpushed commits
|
|
143
|
+
hasUnpushedCommits = true
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (e) {
|
|
147
|
+
// Could not determine branch or remote status
|
|
148
|
+
return {
|
|
149
|
+
hasUncommittedChanges,
|
|
150
|
+
hasUnpushedCommits: false,
|
|
151
|
+
error: 'Could not check remote branch status',
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return { hasUncommittedChanges, hasUnpushedCommits }
|
|
156
|
+
} catch (e) {
|
|
157
|
+
return {
|
|
158
|
+
hasUncommittedChanges: false,
|
|
159
|
+
hasUnpushedCommits: false,
|
|
160
|
+
error: e.message,
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|