@mcoda/integrations 0.1.8 → 0.1.10
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/CHANGELOG.md +3 -0
- package/README.md +3 -1
- package/dist/docdex/DocdexClient.d.ts +19 -4
- package/dist/docdex/DocdexClient.d.ts.map +1 -1
- package/dist/docdex/DocdexClient.js +359 -133
- package/dist/docdex/DocdexRuntime.d.ts +59 -0
- package/dist/docdex/DocdexRuntime.d.ts.map +1 -0
- package/dist/docdex/DocdexRuntime.js +219 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/qa/ChromiumQaAdapter.d.ts +59 -1
- package/dist/qa/ChromiumQaAdapter.d.ts.map +1 -1
- package/dist/qa/ChromiumQaAdapter.js +1634 -42
- package/dist/qa/CliQaAdapter.d.ts +2 -0
- package/dist/qa/CliQaAdapter.d.ts.map +1 -1
- package/dist/qa/CliQaAdapter.js +88 -33
- package/dist/qa/QaTypes.d.ts +4 -0
- package/dist/qa/QaTypes.d.ts.map +1 -1
- package/dist/telemetry/TelemetryClient.d.ts +13 -0
- package/dist/telemetry/TelemetryClient.d.ts.map +1 -1
- package/dist/vcs/VcsClient.d.ts +20 -1
- package/dist/vcs/VcsClient.d.ts.map +1 -1
- package/dist/vcs/VcsClient.js +123 -10
- package/package.json +3 -2
|
@@ -5,6 +5,8 @@ export declare class CliQaAdapter implements QaAdapter {
|
|
|
5
5
|
private resolveCwd;
|
|
6
6
|
ensureInstalled(profile: QaProfile, ctx: QaContext): Promise<QaEnsureResult>;
|
|
7
7
|
private persistLogs;
|
|
8
|
+
private formatCommandHeader;
|
|
9
|
+
private runCommand;
|
|
8
10
|
invoke(profile: QaProfile, ctx: QaContext): Promise<QaRunResult>;
|
|
9
11
|
}
|
|
10
12
|
//# sourceMappingURL=CliQaAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CliQaAdapter.d.ts","sourceRoot":"","sources":["../../src/qa/CliQaAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKtE,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,UAAU;IASZ,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;YAapE,WAAW;
|
|
1
|
+
{"version":3,"file":"CliQaAdapter.d.ts","sourceRoot":"","sources":["../../src/qa/CliQaAdapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKtE,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,UAAU;IASZ,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC;YAapE,WAAW;IAkBzB,OAAO,CAAC,mBAAmB;YAWb,UAAU;IAiDlB,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC;CAoEvE"}
|
package/dist/qa/CliQaAdapter.js
CHANGED
|
@@ -26,33 +26,25 @@ export class CliQaAdapter {
|
|
|
26
26
|
return { ok: false, message: error?.message ?? 'QA install failed' };
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
async persistLogs(ctx, stdout, stderr) {
|
|
29
|
+
async persistLogs(ctx, stdout, stderr, suffix) {
|
|
30
30
|
const artifacts = [];
|
|
31
31
|
if (!ctx.artifactDir)
|
|
32
32
|
return artifacts;
|
|
33
33
|
await fs.mkdir(ctx.artifactDir, { recursive: true });
|
|
34
|
-
const
|
|
35
|
-
const
|
|
34
|
+
const suffixLabel = suffix ? `-${suffix}` : '';
|
|
35
|
+
const outPath = path.join(ctx.artifactDir, `stdout${suffixLabel}.log`);
|
|
36
|
+
const errPath = path.join(ctx.artifactDir, `stderr${suffixLabel}.log`);
|
|
36
37
|
await fs.writeFile(outPath, stdout ?? '', 'utf8');
|
|
37
38
|
await fs.writeFile(errPath, stderr ?? '', 'utf8');
|
|
38
39
|
artifacts.push(path.relative(ctx.workspaceRoot, outPath), path.relative(ctx.workspaceRoot, errPath));
|
|
39
40
|
return artifacts;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
-
const
|
|
42
|
+
formatCommandHeader(command, index, total, outcome, exitCode) {
|
|
43
|
+
const label = total > 1 ? `command ${index}/${total}` : 'command';
|
|
44
|
+
return `=== ${label} outcome=${outcome} exit=${exitCode ?? 'null'} cmd=${command} ===`;
|
|
45
|
+
}
|
|
46
|
+
async runCommand(command, profile, ctx, index, total) {
|
|
43
47
|
const startedAt = new Date().toISOString();
|
|
44
|
-
if (!command) {
|
|
45
|
-
const finishedAt = new Date().toISOString();
|
|
46
|
-
return {
|
|
47
|
-
outcome: 'infra_issue',
|
|
48
|
-
exitCode: null,
|
|
49
|
-
stdout: '',
|
|
50
|
-
stderr: 'No test_command configured for QA profile',
|
|
51
|
-
artifacts: [],
|
|
52
|
-
startedAt,
|
|
53
|
-
finishedAt,
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
48
|
const cwd = this.resolveCwd(profile, ctx);
|
|
57
49
|
try {
|
|
58
50
|
const { stdout, stderr } = await exec(command, {
|
|
@@ -60,15 +52,18 @@ export class CliQaAdapter {
|
|
|
60
52
|
env: { ...process.env, ...profile.env, ...ctx.env },
|
|
61
53
|
});
|
|
62
54
|
const finishedAt = new Date().toISOString();
|
|
63
|
-
const artifacts = await this.persistLogs(ctx, stdout, stderr);
|
|
55
|
+
const artifacts = await this.persistLogs(ctx, stdout, stderr, total > 1 ? String(index) : undefined);
|
|
64
56
|
return {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
57
|
+
command,
|
|
58
|
+
result: {
|
|
59
|
+
outcome: 'pass',
|
|
60
|
+
exitCode: 0,
|
|
61
|
+
stdout,
|
|
62
|
+
stderr,
|
|
63
|
+
artifacts,
|
|
64
|
+
startedAt,
|
|
65
|
+
finishedAt,
|
|
66
|
+
},
|
|
72
67
|
};
|
|
73
68
|
}
|
|
74
69
|
catch (error) {
|
|
@@ -76,16 +71,76 @@ export class CliQaAdapter {
|
|
|
76
71
|
const stderr = error?.stderr ?? String(error);
|
|
77
72
|
const exitCode = typeof error?.code === 'number' ? error.code : null;
|
|
78
73
|
const finishedAt = new Date().toISOString();
|
|
79
|
-
const artifacts = await this.persistLogs(ctx, stdout, stderr);
|
|
74
|
+
const artifacts = await this.persistLogs(ctx, stdout, stderr, total > 1 ? String(index) : undefined);
|
|
80
75
|
return {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
command,
|
|
77
|
+
result: {
|
|
78
|
+
outcome: exitCode === null ? 'infra_issue' : exitCode === 0 ? 'pass' : 'fail',
|
|
79
|
+
exitCode,
|
|
80
|
+
stdout,
|
|
81
|
+
stderr,
|
|
82
|
+
artifacts,
|
|
83
|
+
startedAt,
|
|
84
|
+
finishedAt,
|
|
85
|
+
},
|
|
88
86
|
};
|
|
89
87
|
}
|
|
90
88
|
}
|
|
89
|
+
async invoke(profile, ctx) {
|
|
90
|
+
const commandList = (ctx.commands ?? []).map((cmd) => cmd.trim()).filter(Boolean);
|
|
91
|
+
const fallback = ctx.testCommandOverride ?? profile.test_command;
|
|
92
|
+
const commands = commandList.length ? commandList : fallback ? [fallback] : [];
|
|
93
|
+
if (!commands.length) {
|
|
94
|
+
const now = new Date().toISOString();
|
|
95
|
+
return {
|
|
96
|
+
outcome: 'infra_issue',
|
|
97
|
+
exitCode: null,
|
|
98
|
+
stdout: '',
|
|
99
|
+
stderr: 'No test_command configured for QA profile',
|
|
100
|
+
artifacts: [],
|
|
101
|
+
startedAt: now,
|
|
102
|
+
finishedAt: now,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
if (commands.length === 1) {
|
|
106
|
+
return (await this.runCommand(commands[0], profile, ctx, 1, 1)).result;
|
|
107
|
+
}
|
|
108
|
+
const runs = [];
|
|
109
|
+
for (let index = 0; index < commands.length; index += 1) {
|
|
110
|
+
runs.push(await this.runCommand(commands[index], profile, ctx, index + 1, commands.length));
|
|
111
|
+
}
|
|
112
|
+
const outcome = runs.some((run) => run.result.outcome === 'infra_issue')
|
|
113
|
+
? 'infra_issue'
|
|
114
|
+
: runs.some((run) => run.result.outcome === 'fail')
|
|
115
|
+
? 'fail'
|
|
116
|
+
: 'pass';
|
|
117
|
+
const exitCode = outcome === 'infra_issue'
|
|
118
|
+
? null
|
|
119
|
+
: outcome === 'pass'
|
|
120
|
+
? 0
|
|
121
|
+
: runs.find((run) => typeof run.result.exitCode === 'number' && run.result.exitCode !== 0)?.result
|
|
122
|
+
.exitCode ?? 1;
|
|
123
|
+
const stdout = runs
|
|
124
|
+
.map((run, index) => [this.formatCommandHeader(run.command, index + 1, runs.length, run.result.outcome, run.result.exitCode), run.result.stdout]
|
|
125
|
+
.filter(Boolean)
|
|
126
|
+
.join('\n'))
|
|
127
|
+
.join('\n\n');
|
|
128
|
+
const stderr = runs
|
|
129
|
+
.map((run, index) => [this.formatCommandHeader(run.command, index + 1, runs.length, run.result.outcome, run.result.exitCode), run.result.stderr]
|
|
130
|
+
.filter(Boolean)
|
|
131
|
+
.join('\n'))
|
|
132
|
+
.join('\n\n');
|
|
133
|
+
const artifacts = runs.flatMap((run) => run.result.artifacts ?? []);
|
|
134
|
+
const startedAt = runs.reduce((min, run) => (run.result.startedAt < min ? run.result.startedAt : min), runs[0].result.startedAt);
|
|
135
|
+
const finishedAt = runs.reduce((max, run) => (run.result.finishedAt > max ? run.result.finishedAt : max), runs[0].result.finishedAt);
|
|
136
|
+
return {
|
|
137
|
+
outcome,
|
|
138
|
+
exitCode,
|
|
139
|
+
stdout,
|
|
140
|
+
stderr,
|
|
141
|
+
artifacts,
|
|
142
|
+
startedAt,
|
|
143
|
+
finishedAt,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
91
146
|
}
|
package/dist/qa/QaTypes.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { QaBrowserAction } from '@mcoda/shared/qa/QaPlan.js';
|
|
1
2
|
export type QaOutcome = 'pass' | 'fail' | 'infra_issue';
|
|
2
3
|
export interface QaRunResult {
|
|
3
4
|
outcome: QaOutcome;
|
|
@@ -19,6 +20,9 @@ export interface QaContext {
|
|
|
19
20
|
taskKey: string;
|
|
20
21
|
env: NodeJS.ProcessEnv;
|
|
21
22
|
testCommandOverride?: string;
|
|
23
|
+
commands?: string[];
|
|
24
|
+
browserActions?: QaBrowserAction[];
|
|
25
|
+
browserBaseUrl?: string;
|
|
22
26
|
artifactDir?: string;
|
|
23
27
|
}
|
|
24
28
|
//# sourceMappingURL=QaTypes.d.ts.map
|
package/dist/qa/QaTypes.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QaTypes.d.ts","sourceRoot":"","sources":["../../src/qa/QaTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"QaTypes.d.ts","sourceRoot":"","sources":["../../src/qa/QaTypes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,eAAe,EAAE,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
|
@@ -11,6 +11,10 @@ export interface TokenUsageSummaryRow {
|
|
|
11
11
|
tokens_prompt: number;
|
|
12
12
|
tokens_completion: number;
|
|
13
13
|
tokens_total: number;
|
|
14
|
+
tokens_cached?: number;
|
|
15
|
+
tokens_cache_read?: number;
|
|
16
|
+
tokens_cache_write?: number;
|
|
17
|
+
duration_ms?: number;
|
|
14
18
|
cost_estimate: number | null;
|
|
15
19
|
}
|
|
16
20
|
export interface TokenUsageRow {
|
|
@@ -27,11 +31,20 @@ export interface TokenUsageRow {
|
|
|
27
31
|
tokens_prompt: number | null;
|
|
28
32
|
tokens_completion: number | null;
|
|
29
33
|
tokens_total: number | null;
|
|
34
|
+
tokens_cached?: number | null;
|
|
35
|
+
tokens_cache_read?: number | null;
|
|
36
|
+
tokens_cache_write?: number | null;
|
|
30
37
|
cost_estimate: number | null;
|
|
31
38
|
duration_seconds: number | null;
|
|
39
|
+
duration_ms?: number | null;
|
|
40
|
+
started_at?: string | null;
|
|
41
|
+
finished_at?: string | null;
|
|
32
42
|
timestamp: string;
|
|
33
43
|
command_name?: string | null;
|
|
34
44
|
action?: string | null;
|
|
45
|
+
invocation_kind?: string | null;
|
|
46
|
+
provider?: string | null;
|
|
47
|
+
currency?: string | null;
|
|
35
48
|
error_kind?: string | null;
|
|
36
49
|
metadata?: Record<string, unknown>;
|
|
37
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TelemetryClient.d.ts","sourceRoot":"","sources":["../../src/telemetry/TelemetryClient.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TelemetryClient.d.ts","sourceRoot":"","sources":["../../src/telemetry/TelemetryClient.ts"],"names":[],"mappings":"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"}
|
package/dist/vcs/VcsClient.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare class VcsClient {
|
|
2
2
|
private runGit;
|
|
3
3
|
private gitDirExists;
|
|
4
|
+
isRepo(cwd: string): Promise<boolean>;
|
|
4
5
|
ensureRepo(cwd: string): Promise<void>;
|
|
5
6
|
hasRemote(cwd: string): Promise<boolean>;
|
|
6
7
|
currentBranch(cwd: string): Promise<string | null>;
|
|
@@ -10,19 +11,37 @@ export declare class VcsClient {
|
|
|
10
11
|
ensureBaseBranch(cwd: string, base: string): Promise<void>;
|
|
11
12
|
checkoutBranch(cwd: string, branch: string): Promise<void>;
|
|
12
13
|
createOrCheckoutBranch(cwd: string, branch: string, base: string): Promise<void>;
|
|
14
|
+
addWorktree(cwd: string, worktreePath: string, branch: string, options?: {
|
|
15
|
+
detach?: boolean;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
removeWorktree(cwd: string, worktreePath: string): Promise<void>;
|
|
18
|
+
cherryPick(cwd: string, commit: string): Promise<void>;
|
|
19
|
+
abortCherryPick(cwd: string): Promise<void>;
|
|
13
20
|
applyPatch(cwd: string, patch: string): Promise<void>;
|
|
21
|
+
applyPatchWithReject(cwd: string, patch: string): Promise<{
|
|
22
|
+
stdout?: string;
|
|
23
|
+
stderr?: string;
|
|
24
|
+
error?: string;
|
|
25
|
+
}>;
|
|
14
26
|
stage(cwd: string, paths: string[]): Promise<void>;
|
|
15
27
|
commit(cwd: string, message: string, options?: {
|
|
16
28
|
noVerify?: boolean;
|
|
17
29
|
noGpgSign?: boolean;
|
|
30
|
+
env?: NodeJS.ProcessEnv;
|
|
18
31
|
}): Promise<void>;
|
|
19
32
|
merge(cwd: string, source: string, target: string, ensureClean?: boolean): Promise<void>;
|
|
33
|
+
abortMerge(cwd: string): Promise<void>;
|
|
34
|
+
resolveMergeConflicts(cwd: string, strategy: "theirs" | "ours", paths?: string[]): Promise<string[]>;
|
|
20
35
|
push(cwd: string, remote: string, branch: string): Promise<void>;
|
|
21
36
|
pull(cwd: string, remote: string, branch: string, ffOnly?: boolean): Promise<void>;
|
|
22
37
|
status(cwd: string): Promise<string>;
|
|
23
38
|
dirtyPaths(cwd: string): Promise<string[]>;
|
|
24
39
|
conflictPaths(cwd: string): Promise<string[]>;
|
|
25
|
-
ensureClean(cwd: string, ignoreDotMcoda?: boolean): Promise<void>;
|
|
40
|
+
ensureClean(cwd: string, ignoreDotMcoda?: boolean, ignorePaths?: string[]): Promise<void>;
|
|
41
|
+
resetHard(cwd: string, options?: {
|
|
42
|
+
exclude?: string[];
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
restorePaths(cwd: string, paths: string[]): Promise<void>;
|
|
26
45
|
lastCommitSha(cwd: string): Promise<string>;
|
|
27
46
|
diff(cwd: string, base: string, head: string, paths?: string[]): Promise<string>;
|
|
28
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VcsClient.d.ts","sourceRoot":"","sources":["../../src/vcs/VcsClient.ts"],"names":[],"mappings":"AAQA,qBAAa,SAAS;YACN,MAAM;
|
|
1
|
+
{"version":3,"file":"VcsClient.d.ts","sourceRoot":"","sources":["../../src/vcs/VcsClient.ts"],"names":[],"mappings":"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"}
|
package/dist/vcs/VcsClient.js
CHANGED
|
@@ -5,9 +5,12 @@ import path from "node:path";
|
|
|
5
5
|
const exec = promisify(execCb);
|
|
6
6
|
const execFile = promisify(execFileCb);
|
|
7
7
|
export class VcsClient {
|
|
8
|
-
async runGit(cwd, args) {
|
|
9
|
-
const { stdout, stderr } = await execFile("git", args, { cwd });
|
|
10
|
-
return {
|
|
8
|
+
async runGit(cwd, args, options = {}) {
|
|
9
|
+
const { stdout, stderr } = await execFile("git", args, { cwd, ...options });
|
|
10
|
+
return {
|
|
11
|
+
stdout: typeof stdout === "string" ? stdout : stdout?.toString?.() ?? "",
|
|
12
|
+
stderr: typeof stderr === "string" ? stderr : stderr?.toString?.() ?? "",
|
|
13
|
+
};
|
|
11
14
|
}
|
|
12
15
|
async gitDirExists(cwd) {
|
|
13
16
|
try {
|
|
@@ -18,6 +21,15 @@ export class VcsClient {
|
|
|
18
21
|
return false;
|
|
19
22
|
}
|
|
20
23
|
}
|
|
24
|
+
async isRepo(cwd) {
|
|
25
|
+
try {
|
|
26
|
+
await this.runGit(cwd, ["rev-parse", "--is-inside-work-tree"]);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return this.gitDirExists(cwd);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
21
33
|
async ensureRepo(cwd) {
|
|
22
34
|
if (await this.gitDirExists(cwd))
|
|
23
35
|
return;
|
|
@@ -95,6 +107,28 @@ export class VcsClient {
|
|
|
95
107
|
}
|
|
96
108
|
await this.runGit(cwd, ["checkout", "-b", branch, base]);
|
|
97
109
|
}
|
|
110
|
+
async addWorktree(cwd, worktreePath, branch, options) {
|
|
111
|
+
const args = ["worktree", "add", "--force"];
|
|
112
|
+
if (options?.detach) {
|
|
113
|
+
args.push("--detach");
|
|
114
|
+
}
|
|
115
|
+
args.push(worktreePath, branch);
|
|
116
|
+
await this.runGit(cwd, args);
|
|
117
|
+
}
|
|
118
|
+
async removeWorktree(cwd, worktreePath) {
|
|
119
|
+
try {
|
|
120
|
+
await this.runGit(cwd, ["worktree", "remove", "--force", worktreePath]);
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// ignore; cleanup caller will remove directory
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async cherryPick(cwd, commit) {
|
|
127
|
+
await this.runGit(cwd, ["cherry-pick", commit]);
|
|
128
|
+
}
|
|
129
|
+
async abortCherryPick(cwd) {
|
|
130
|
+
await this.runGit(cwd, ["cherry-pick", "--abort"]);
|
|
131
|
+
}
|
|
98
132
|
async applyPatch(cwd, patch) {
|
|
99
133
|
const opts = { cwd, shell: true };
|
|
100
134
|
const applyCmd = `cat <<'__PATCH__' | git apply --whitespace=nowarn\n${patch}\n__PATCH__`;
|
|
@@ -103,17 +137,42 @@ export class VcsClient {
|
|
|
103
137
|
return;
|
|
104
138
|
}
|
|
105
139
|
catch (error) {
|
|
106
|
-
//
|
|
107
|
-
const
|
|
140
|
+
// Retry with 3-way merge for drifted files.
|
|
141
|
+
const apply3wayCmd = `cat <<'__PATCH__' | git apply --3way --whitespace=nowarn\n${patch}\n__PATCH__`;
|
|
108
142
|
try {
|
|
109
|
-
await exec(
|
|
143
|
+
await exec(apply3wayCmd, opts);
|
|
110
144
|
return;
|
|
111
145
|
}
|
|
112
146
|
catch {
|
|
113
|
-
|
|
147
|
+
// If the patch is already applied, a reverse --check succeeds; treat that as a no-op.
|
|
148
|
+
const reverseCheckCmd = `cat <<'__PATCH__' | git apply --reverse --check --whitespace=nowarn\n${patch}\n__PATCH__`;
|
|
149
|
+
try {
|
|
150
|
+
await exec(reverseCheckCmd, opts);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
114
156
|
}
|
|
115
157
|
}
|
|
116
158
|
}
|
|
159
|
+
async applyPatchWithReject(cwd, patch) {
|
|
160
|
+
const opts = { cwd, shell: true };
|
|
161
|
+
const applyCmd = `cat <<'__PATCH__' | git apply --reject --whitespace=nowarn\n${patch}\n__PATCH__`;
|
|
162
|
+
try {
|
|
163
|
+
const { stdout, stderr } = await exec(applyCmd, opts);
|
|
164
|
+
return {
|
|
165
|
+
stdout: typeof stdout === "string" ? stdout : stdout?.toString?.() ?? "",
|
|
166
|
+
stderr: typeof stderr === "string" ? stderr : stderr?.toString?.() ?? "",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
const stdout = typeof error?.stdout === "string" ? error.stdout : error?.stdout?.toString?.() ?? "";
|
|
171
|
+
const stderr = typeof error?.stderr === "string" ? error.stderr : error?.stderr?.toString?.() ?? "";
|
|
172
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
173
|
+
return { stdout, stderr, error: stderr || message };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
117
176
|
async stage(cwd, paths) {
|
|
118
177
|
await this.runGit(cwd, ["add", ...paths]);
|
|
119
178
|
}
|
|
@@ -123,7 +182,8 @@ export class VcsClient {
|
|
|
123
182
|
args.push("--no-verify");
|
|
124
183
|
if (options.noGpgSign)
|
|
125
184
|
args.push("--no-gpg-sign");
|
|
126
|
-
|
|
185
|
+
const execOptions = options.env ? { env: options.env } : {};
|
|
186
|
+
await this.runGit(cwd, args, execOptions);
|
|
127
187
|
}
|
|
128
188
|
async merge(cwd, source, target, ensureClean = false) {
|
|
129
189
|
await this.checkoutBranch(cwd, target);
|
|
@@ -132,6 +192,24 @@ export class VcsClient {
|
|
|
132
192
|
}
|
|
133
193
|
await this.runGit(cwd, ["merge", "--no-edit", source]);
|
|
134
194
|
}
|
|
195
|
+
async abortMerge(cwd) {
|
|
196
|
+
try {
|
|
197
|
+
await this.runGit(cwd, ["merge", "--abort"]);
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// Ignore when no merge is in progress.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async resolveMergeConflicts(cwd, strategy, paths) {
|
|
204
|
+
const conflicts = paths?.length ? paths : await this.conflictPaths(cwd);
|
|
205
|
+
if (!conflicts.length)
|
|
206
|
+
return [];
|
|
207
|
+
const flag = strategy === "theirs" ? "--theirs" : "--ours";
|
|
208
|
+
await this.runGit(cwd, ["checkout", flag, "--", ...conflicts]);
|
|
209
|
+
await this.runGit(cwd, ["add", "--", ...conflicts]);
|
|
210
|
+
await this.runGit(cwd, ["commit", "--no-edit"]);
|
|
211
|
+
return conflicts;
|
|
212
|
+
}
|
|
135
213
|
async push(cwd, remote, branch) {
|
|
136
214
|
await this.runGit(cwd, ["push", remote, branch]);
|
|
137
215
|
}
|
|
@@ -179,13 +257,48 @@ export class VcsClient {
|
|
|
179
257
|
return [];
|
|
180
258
|
}
|
|
181
259
|
}
|
|
182
|
-
async ensureClean(cwd, ignoreDotMcoda = true) {
|
|
260
|
+
async ensureClean(cwd, ignoreDotMcoda = true, ignorePaths = []) {
|
|
183
261
|
const dirty = await this.dirtyPaths(cwd);
|
|
184
|
-
const
|
|
262
|
+
const normalize = (value) => value.replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/^\/+/, "");
|
|
263
|
+
const normalizedIgnore = ignorePaths
|
|
264
|
+
.map((entry) => normalize(entry.trim()))
|
|
265
|
+
.filter(Boolean)
|
|
266
|
+
.map((entry) => (entry.endsWith("/") ? `${entry.replace(/\/+$/, "")}/` : entry));
|
|
267
|
+
const isIgnored = (value) => {
|
|
268
|
+
const normalized = normalize(value);
|
|
269
|
+
if (ignoreDotMcoda && normalized.startsWith(".mcoda"))
|
|
270
|
+
return true;
|
|
271
|
+
return normalizedIgnore.some((entry) => {
|
|
272
|
+
if (entry.endsWith("/")) {
|
|
273
|
+
const dir = entry.slice(0, -1);
|
|
274
|
+
return normalized === dir || normalized.startsWith(entry);
|
|
275
|
+
}
|
|
276
|
+
return normalized === entry || normalized.startsWith(`${entry}/`);
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
const filtered = dirty.filter((p) => !isIgnored(p));
|
|
185
280
|
if (filtered.length) {
|
|
186
281
|
throw new Error(`Working tree dirty: ${filtered.join(", ")}`);
|
|
187
282
|
}
|
|
188
283
|
}
|
|
284
|
+
async resetHard(cwd, options) {
|
|
285
|
+
await this.runGit(cwd, ["reset", "--hard"]);
|
|
286
|
+
const args = ["clean", "-fd"];
|
|
287
|
+
(options?.exclude ?? [])
|
|
288
|
+
.map((entry) => entry.trim())
|
|
289
|
+
.filter(Boolean)
|
|
290
|
+
.forEach((entry) => {
|
|
291
|
+
args.push("-e", entry);
|
|
292
|
+
});
|
|
293
|
+
await this.runGit(cwd, args);
|
|
294
|
+
}
|
|
295
|
+
async restorePaths(cwd, paths) {
|
|
296
|
+
const cleaned = paths.map((entry) => entry.trim()).filter(Boolean);
|
|
297
|
+
if (!cleaned.length)
|
|
298
|
+
return;
|
|
299
|
+
await this.runGit(cwd, ["checkout", "--", ...cleaned]);
|
|
300
|
+
await this.runGit(cwd, ["clean", "-fd", "--", ...cleaned]);
|
|
301
|
+
}
|
|
189
302
|
async lastCommitSha(cwd) {
|
|
190
303
|
const { stdout } = await this.runGit(cwd, ["rev-parse", "HEAD"]);
|
|
191
304
|
return stdout.trim();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcoda/integrations",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "External integrations for mcoda (vcs, QA, telemetry).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"
|
|
40
|
+
"docdex": "^0.2.22",
|
|
41
|
+
"@mcoda/shared": "0.1.10"
|
|
41
42
|
},
|
|
42
43
|
"scripts": {
|
|
43
44
|
"build": "tsc -p tsconfig.json",
|