sequant 1.20.3 → 2.0.1
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/.claude-plugin/marketplace.json +2 -4
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +36 -15
- package/dist/bin/cli.js +25 -2
- package/dist/src/commands/doctor.js +42 -9
- package/dist/src/commands/init.d.ts +1 -0
- package/dist/src/commands/init.js +52 -0
- package/dist/src/commands/logs.d.ts +1 -0
- package/dist/src/commands/logs.js +18 -2
- package/dist/src/commands/run.d.ts +7 -0
- package/dist/src/commands/run.js +235 -68
- package/dist/src/commands/serve.d.ts +13 -0
- package/dist/src/commands/serve.js +131 -0
- package/dist/src/commands/stats.d.ts +1 -0
- package/dist/src/commands/stats.js +185 -26
- package/dist/src/commands/status.d.ts +2 -0
- package/dist/src/commands/status.js +99 -50
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.js +4 -1
- package/dist/src/lib/ac-parser.d.ts +2 -0
- package/dist/src/lib/ac-parser.js +12 -2
- package/dist/src/lib/assess-comment-parser.d.ts +137 -0
- package/dist/src/lib/assess-comment-parser.js +344 -0
- package/dist/src/lib/ci/config.d.ts +22 -0
- package/dist/src/lib/ci/config.js +134 -0
- package/dist/src/lib/ci/index.d.ts +12 -0
- package/dist/src/lib/ci/index.js +10 -0
- package/dist/src/lib/ci/inputs.d.ts +29 -0
- package/dist/src/lib/ci/inputs.js +103 -0
- package/dist/src/lib/ci/labels.d.ts +34 -0
- package/dist/src/lib/ci/labels.js +101 -0
- package/dist/src/lib/ci/outputs.d.ts +25 -0
- package/dist/src/lib/ci/outputs.js +84 -0
- package/dist/src/lib/ci/triggers.d.ts +9 -0
- package/dist/src/lib/ci/triggers.js +86 -0
- package/dist/src/lib/ci/types.d.ts +131 -0
- package/dist/src/lib/ci/types.js +47 -0
- package/dist/src/lib/mcp-config.d.ts +54 -0
- package/dist/src/lib/mcp-config.js +172 -0
- package/dist/src/lib/merge-check/index.js +6 -12
- package/dist/src/lib/merge-check/types.d.ts +20 -7
- package/dist/src/lib/merge-check/types.js +11 -0
- package/dist/src/lib/phase-signal.d.ts +3 -3
- package/dist/src/lib/phase-signal.js +5 -3
- package/dist/src/lib/settings.d.ts +52 -0
- package/dist/src/lib/settings.js +41 -0
- package/dist/src/lib/shutdown.d.ts +16 -5
- package/dist/src/lib/shutdown.js +32 -12
- package/dist/src/lib/solve-comment-parser.d.ts +9 -102
- package/dist/src/lib/solve-comment-parser.js +13 -248
- package/dist/src/lib/stacks.d.ts +8 -0
- package/dist/src/lib/stacks.js +34 -0
- package/dist/src/lib/system.js +3 -7
- package/dist/src/lib/test-tautology-detector.d.ts +10 -0
- package/dist/src/lib/test-tautology-detector.js +43 -4
- package/dist/src/lib/upstream/assessment.js +9 -59
- package/dist/src/lib/upstream/issues.js +12 -75
- package/dist/src/lib/version-check.d.ts +2 -2
- package/dist/src/lib/version-check.js +6 -3
- package/dist/src/lib/version.d.ts +4 -0
- package/dist/src/lib/version.js +25 -0
- package/dist/src/lib/workflow/batch-executor.d.ts +26 -86
- package/dist/src/lib/workflow/batch-executor.js +269 -55
- package/dist/src/lib/workflow/drivers/agent-driver.d.ts +56 -0
- package/dist/src/lib/workflow/drivers/agent-driver.js +8 -0
- package/dist/src/lib/workflow/drivers/aider.d.ts +18 -0
- package/dist/src/lib/workflow/drivers/aider.js +160 -0
- package/dist/src/lib/workflow/drivers/claude-code.d.ts +17 -0
- package/dist/src/lib/workflow/drivers/claude-code.js +165 -0
- package/dist/src/lib/workflow/drivers/index.d.ts +20 -0
- package/dist/src/lib/workflow/drivers/index.js +27 -0
- package/dist/src/lib/workflow/error-classifier.d.ts +16 -0
- package/dist/src/lib/workflow/error-classifier.js +90 -0
- package/dist/src/lib/workflow/log-writer.d.ts +6 -3
- package/dist/src/lib/workflow/log-writer.js +57 -27
- package/dist/src/lib/workflow/metrics-schema.d.ts +9 -9
- package/dist/src/lib/workflow/phase-detection.d.ts +23 -0
- package/dist/src/lib/workflow/phase-detection.js +45 -29
- package/dist/src/lib/workflow/phase-executor.d.ts +42 -3
- package/dist/src/lib/workflow/phase-executor.js +375 -229
- package/dist/src/lib/workflow/phase-mapper.d.ts +1 -1
- package/dist/src/lib/workflow/phase-mapper.js +7 -7
- package/dist/src/lib/workflow/platforms/github.d.ts +157 -0
- package/dist/src/lib/workflow/platforms/github.js +466 -0
- package/dist/src/lib/workflow/platforms/index.d.ts +17 -0
- package/dist/src/lib/workflow/platforms/index.js +25 -0
- package/dist/src/lib/workflow/platforms/platform-provider.d.ts +67 -0
- package/dist/src/lib/workflow/platforms/platform-provider.js +8 -0
- package/dist/src/lib/workflow/pr-status.d.ts +2 -4
- package/dist/src/lib/workflow/pr-status.js +3 -16
- package/dist/src/lib/workflow/qa-cache.d.ts +58 -0
- package/dist/src/lib/workflow/qa-cache.js +88 -0
- package/dist/src/lib/workflow/reconcile.d.ts +69 -0
- package/dist/src/lib/workflow/reconcile.js +290 -0
- package/dist/src/lib/workflow/ring-buffer.d.ts +17 -0
- package/dist/src/lib/workflow/ring-buffer.js +37 -0
- package/dist/src/lib/workflow/run-log-schema.d.ts +115 -24
- package/dist/src/lib/workflow/run-log-schema.js +47 -12
- package/dist/src/lib/workflow/run-reflect.js +1 -1
- package/dist/src/lib/workflow/state-cleanup.js +21 -0
- package/dist/src/lib/workflow/state-manager.d.ts +34 -3
- package/dist/src/lib/workflow/state-manager.js +278 -126
- package/dist/src/lib/workflow/state-schema.d.ts +34 -30
- package/dist/src/lib/workflow/state-schema.js +35 -25
- package/dist/src/lib/workflow/state-utils.d.ts +3 -1
- package/dist/src/lib/workflow/state-utils.js +1 -0
- package/dist/src/lib/workflow/types.d.ts +224 -6
- package/dist/src/lib/workflow/types.js +20 -1
- package/dist/src/lib/workflow/worktree-discovery.d.ts +1 -1
- package/dist/src/lib/workflow/worktree-discovery.js +6 -14
- package/dist/src/lib/workflow/worktree-manager.js +33 -51
- package/dist/src/mcp/index.d.ts +4 -0
- package/dist/src/mcp/index.js +4 -0
- package/dist/src/mcp/resources.d.ts +7 -0
- package/dist/src/mcp/resources.js +111 -0
- package/dist/src/mcp/run-registry.d.ts +34 -0
- package/dist/src/mcp/run-registry.js +42 -0
- package/dist/src/mcp/server.d.ts +12 -0
- package/dist/src/mcp/server.js +50 -0
- package/dist/src/mcp/tools/logs.d.ts +7 -0
- package/dist/src/mcp/tools/logs.js +149 -0
- package/dist/src/mcp/tools/run.d.ts +121 -0
- package/dist/src/mcp/tools/run.js +591 -0
- package/dist/src/mcp/tools/status.d.ts +7 -0
- package/dist/src/mcp/tools/status.js +127 -0
- package/package.json +26 -7
- package/templates/hooks/post-tool.sh +19 -8
- package/templates/hooks/pre-tool.sh +36 -49
- package/templates/mcp.json +6 -0
- package/templates/skills/assess/SKILL.md +354 -352
- package/templates/skills/exec/SKILL.md +64 -1
- package/templates/skills/fullsolve/SKILL.md +35 -4
- package/templates/skills/qa/SKILL.md +486 -9
- package/templates/skills/qa/scripts/quality-checks.sh +1 -1
- package/templates/skills/setup/SKILL.md +386 -0
- package/templates/skills/solve/SKILL.md +38 -664
- package/templates/skills/spec/SKILL.md +90 -31
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform provider registry.
|
|
3
|
+
*
|
|
4
|
+
* Simple map-based registry — not a plugin system.
|
|
5
|
+
* New providers are registered by adding entries to PLATFORMS.
|
|
6
|
+
*/
|
|
7
|
+
import { GitHubProvider } from "./github.js";
|
|
8
|
+
export { GitHubProvider } from "./github.js";
|
|
9
|
+
const PLATFORMS = {
|
|
10
|
+
github: () => new GitHubProvider(),
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Get a platform provider by name.
|
|
14
|
+
*
|
|
15
|
+
* @param name - Provider name (default: "github")
|
|
16
|
+
* @throws Error if provider name is unknown
|
|
17
|
+
*/
|
|
18
|
+
export function getPlatform(name = "github") {
|
|
19
|
+
const factory = PLATFORMS[name];
|
|
20
|
+
if (!factory) {
|
|
21
|
+
const available = Object.keys(PLATFORMS).join(", ");
|
|
22
|
+
throw new Error(`Unknown platform provider "${name}". Available providers: ${available}`);
|
|
23
|
+
}
|
|
24
|
+
return factory();
|
|
25
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlatformProvider interface — decouples workflow orchestration from
|
|
3
|
+
* platform operations (issue fetching, PR creation, comments, labels).
|
|
4
|
+
*
|
|
5
|
+
* GitHub is the default implementation; alternatives can be added by
|
|
6
|
+
* implementing this interface without touching orchestration logic.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Normalized issue representation.
|
|
10
|
+
*/
|
|
11
|
+
export interface Issue {
|
|
12
|
+
id: string;
|
|
13
|
+
number: number;
|
|
14
|
+
title: string;
|
|
15
|
+
body: string;
|
|
16
|
+
labels: string[];
|
|
17
|
+
state: "open" | "closed";
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Options for creating a pull request.
|
|
21
|
+
*/
|
|
22
|
+
export interface CreatePROptions {
|
|
23
|
+
title: string;
|
|
24
|
+
body: string;
|
|
25
|
+
head: string;
|
|
26
|
+
base: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Information about a created pull request.
|
|
30
|
+
*/
|
|
31
|
+
export interface PRInfo {
|
|
32
|
+
number: number;
|
|
33
|
+
url: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Status of a pull request.
|
|
37
|
+
*/
|
|
38
|
+
export interface PRStatus {
|
|
39
|
+
state: "open" | "closed" | "merged";
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* A comment on an issue or pull request.
|
|
43
|
+
*/
|
|
44
|
+
export interface Comment {
|
|
45
|
+
body: string;
|
|
46
|
+
createdAt: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Interface that all platform backends must implement.
|
|
50
|
+
*/
|
|
51
|
+
export interface PlatformProvider {
|
|
52
|
+
/** Platform name for logging/display */
|
|
53
|
+
name: string;
|
|
54
|
+
/** Issue operations */
|
|
55
|
+
fetchIssue(id: string): Promise<Issue>;
|
|
56
|
+
postComment(issueId: string, body: string): Promise<void>;
|
|
57
|
+
addLabel(issueId: string, label: string): Promise<void>;
|
|
58
|
+
removeLabel(issueId: string, label: string): Promise<void>;
|
|
59
|
+
/** PR operations */
|
|
60
|
+
createPR(opts: CreatePROptions): Promise<PRInfo>;
|
|
61
|
+
getPRStatus(prId: string): Promise<PRStatus>;
|
|
62
|
+
postPRComment(prId: string, body: string): Promise<void>;
|
|
63
|
+
/** Auth and health */
|
|
64
|
+
checkAuth(): Promise<boolean>;
|
|
65
|
+
/** Phase marker operations */
|
|
66
|
+
getIssueComments(issueId: string): Promise<Comment[]>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PlatformProvider interface — decouples workflow orchestration from
|
|
3
|
+
* platform operations (issue fetching, PR creation, comments, labels).
|
|
4
|
+
*
|
|
5
|
+
* GitHub is the default implementation; alternatives can be added by
|
|
6
|
+
* implementing this interface without touching orchestration logic.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
@@ -16,10 +16,8 @@
|
|
|
16
16
|
* const isMerged = isBranchMergedIntoMain('feature/123-some-feature');
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
*/
|
|
22
|
-
export type PRMergeStatus = "MERGED" | "CLOSED" | "OPEN" | null;
|
|
19
|
+
import type { PRMergeStatus } from "./platforms/github.js";
|
|
20
|
+
export type { PRMergeStatus };
|
|
23
21
|
/**
|
|
24
22
|
* Check the merge status of a PR using the gh CLI
|
|
25
23
|
*
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
19
|
import { spawnSync } from "child_process";
|
|
20
|
+
import { GitHubProvider } from "./platforms/github.js";
|
|
20
21
|
/**
|
|
21
22
|
* Check the merge status of a PR using the gh CLI
|
|
22
23
|
*
|
|
@@ -24,22 +25,8 @@ import { spawnSync } from "child_process";
|
|
|
24
25
|
* @returns "MERGED" | "CLOSED" | "OPEN" | null (null if PR not found or gh unavailable)
|
|
25
26
|
*/
|
|
26
27
|
export function checkPRMergeStatus(prNumber) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (result.status === 0 && result.stdout) {
|
|
30
|
-
const state = result.stdout.toString().trim().toUpperCase();
|
|
31
|
-
if (state === "MERGED")
|
|
32
|
-
return "MERGED";
|
|
33
|
-
if (state === "CLOSED")
|
|
34
|
-
return "CLOSED";
|
|
35
|
-
if (state === "OPEN")
|
|
36
|
-
return "OPEN";
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
// gh not available or error - return null
|
|
41
|
-
}
|
|
42
|
-
return null;
|
|
28
|
+
const github = new GitHubProvider();
|
|
29
|
+
return github.getPRMergeStatusSync(prNumber);
|
|
43
30
|
}
|
|
44
31
|
/**
|
|
45
32
|
* Check if a branch has been merged into a base branch using git
|
|
@@ -56,6 +56,28 @@ export declare const CachedCheckResultSchema: z.ZodObject<{
|
|
|
56
56
|
}, z.core.$strip>;
|
|
57
57
|
}, z.core.$strip>;
|
|
58
58
|
export type CachedCheckResult = z.infer<typeof CachedCheckResultSchema>;
|
|
59
|
+
/**
|
|
60
|
+
* Schema for QA run context - stores metadata from the last QA run
|
|
61
|
+
* for incremental re-run optimization
|
|
62
|
+
*/
|
|
63
|
+
export declare const QARunContextSchema: z.ZodObject<{
|
|
64
|
+
lastQACommitSHA: z.ZodString;
|
|
65
|
+
lastQADiffHash: z.ZodString;
|
|
66
|
+
acStatuses: z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
67
|
+
pending: "pending";
|
|
68
|
+
blocked: "blocked";
|
|
69
|
+
met: "met";
|
|
70
|
+
not_met: "not_met";
|
|
71
|
+
partially_met: "partially_met";
|
|
72
|
+
}>>;
|
|
73
|
+
timestamp: z.ZodString;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
export type QARunContext = z.infer<typeof QARunContextSchema>;
|
|
76
|
+
/**
|
|
77
|
+
* Checks that are always re-run on every QA invocation, regardless of cache.
|
|
78
|
+
* These are either cheap or can regress independently of code changes.
|
|
79
|
+
*/
|
|
80
|
+
export declare const ALWAYS_RERUN_CHECKS: readonly string[];
|
|
59
81
|
/**
|
|
60
82
|
* Schema for the complete cache file
|
|
61
83
|
*/
|
|
@@ -84,6 +106,18 @@ export declare const QACacheSchema: z.ZodObject<{
|
|
|
84
106
|
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
85
107
|
}, z.core.$strip>;
|
|
86
108
|
}, z.core.$strip>>;
|
|
109
|
+
runContext: z.ZodOptional<z.ZodObject<{
|
|
110
|
+
lastQACommitSHA: z.ZodString;
|
|
111
|
+
lastQADiffHash: z.ZodString;
|
|
112
|
+
acStatuses: z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
113
|
+
pending: "pending";
|
|
114
|
+
blocked: "blocked";
|
|
115
|
+
met: "met";
|
|
116
|
+
not_met: "not_met";
|
|
117
|
+
partially_met: "partially_met";
|
|
118
|
+
}>>;
|
|
119
|
+
timestamp: z.ZodString;
|
|
120
|
+
}, z.core.$strip>>;
|
|
87
121
|
}, z.core.$strip>;
|
|
88
122
|
export type QACacheState = z.infer<typeof QACacheSchema>;
|
|
89
123
|
/**
|
|
@@ -171,6 +205,30 @@ export declare class QACache {
|
|
|
171
205
|
* Clear all cached results
|
|
172
206
|
*/
|
|
173
207
|
clearAll(): Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Get the QA run context from the last QA run
|
|
210
|
+
*/
|
|
211
|
+
getRunContext(): Promise<QARunContext | undefined>;
|
|
212
|
+
/**
|
|
213
|
+
* Set the QA run context after a QA run completes
|
|
214
|
+
*/
|
|
215
|
+
setRunContext(context: QARunContext): Promise<void>;
|
|
216
|
+
/**
|
|
217
|
+
* Compute hash of git diff between a specific commit and HEAD.
|
|
218
|
+
* Used for incremental QA to detect changes since last QA run.
|
|
219
|
+
*
|
|
220
|
+
* @param sinceCommit - The commit SHA to diff from
|
|
221
|
+
* @returns Hash of the diff, or null if the commit is invalid/missing
|
|
222
|
+
*/
|
|
223
|
+
computeIncrementalDiffHash(sinceCommit: string): string | null;
|
|
224
|
+
/**
|
|
225
|
+
* Get files changed since a specific commit.
|
|
226
|
+
* Used for incremental QA to determine which checks need re-running.
|
|
227
|
+
*
|
|
228
|
+
* @param sinceCommit - The commit SHA to diff from
|
|
229
|
+
* @returns Array of changed file paths, or null if the commit is invalid
|
|
230
|
+
*/
|
|
231
|
+
getChangedFilesSince(sinceCommit: string): string[] | null;
|
|
174
232
|
/**
|
|
175
233
|
* Get cache status for all check types
|
|
176
234
|
*/
|
|
@@ -67,6 +67,25 @@ export const CachedCheckResultSchema = z.object({
|
|
|
67
67
|
details: z.record(z.string(), z.unknown()).optional(),
|
|
68
68
|
}),
|
|
69
69
|
});
|
|
70
|
+
/**
|
|
71
|
+
* Schema for QA run context - stores metadata from the last QA run
|
|
72
|
+
* for incremental re-run optimization
|
|
73
|
+
*/
|
|
74
|
+
export const QARunContextSchema = z.object({
|
|
75
|
+
/** Git HEAD SHA at the time of QA completion */
|
|
76
|
+
lastQACommitSHA: z.string(),
|
|
77
|
+
/** Diff hash (main...HEAD) at the time of QA */
|
|
78
|
+
lastQADiffHash: z.string(),
|
|
79
|
+
/** Map of AC ID → status from the last QA run */
|
|
80
|
+
acStatuses: z.record(z.string(), z.enum(["met", "not_met", "partially_met", "pending", "blocked"])),
|
|
81
|
+
/** ISO 8601 timestamp of last QA completion */
|
|
82
|
+
timestamp: z.string().datetime(),
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Checks that are always re-run on every QA invocation, regardless of cache.
|
|
86
|
+
* These are either cheap or can regress independently of code changes.
|
|
87
|
+
*/
|
|
88
|
+
export const ALWAYS_RERUN_CHECKS = ["build"];
|
|
70
89
|
/**
|
|
71
90
|
* Schema for the complete cache file
|
|
72
91
|
*/
|
|
@@ -77,6 +96,8 @@ export const QACacheSchema = z.object({
|
|
|
77
96
|
lastUpdated: z.string().datetime(),
|
|
78
97
|
/** Cached check results keyed by check type */
|
|
79
98
|
checks: z.record(z.string(), CachedCheckResultSchema),
|
|
99
|
+
/** QA run context for incremental re-runs (optional for backward compat) */
|
|
100
|
+
runContext: QARunContextSchema.optional(),
|
|
80
101
|
});
|
|
81
102
|
/**
|
|
82
103
|
* Default TTL: 1 hour
|
|
@@ -382,6 +403,73 @@ export class QACache {
|
|
|
382
403
|
await this.saveState(emptyState);
|
|
383
404
|
this.log("Cleared all cache");
|
|
384
405
|
}
|
|
406
|
+
/**
|
|
407
|
+
* Get the QA run context from the last QA run
|
|
408
|
+
*/
|
|
409
|
+
async getRunContext() {
|
|
410
|
+
const state = await this.getState();
|
|
411
|
+
return state.runContext;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Set the QA run context after a QA run completes
|
|
415
|
+
*/
|
|
416
|
+
async setRunContext(context) {
|
|
417
|
+
const state = await this.getState();
|
|
418
|
+
state.runContext = context;
|
|
419
|
+
await this.saveState(state);
|
|
420
|
+
this.log("Saved QA run context");
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Compute hash of git diff between a specific commit and HEAD.
|
|
424
|
+
* Used for incremental QA to detect changes since last QA run.
|
|
425
|
+
*
|
|
426
|
+
* @param sinceCommit - The commit SHA to diff from
|
|
427
|
+
* @returns Hash of the diff, or null if the commit is invalid/missing
|
|
428
|
+
*/
|
|
429
|
+
computeIncrementalDiffHash(sinceCommit) {
|
|
430
|
+
if (!/^[a-f0-9]{4,40}$/.test(sinceCommit)) {
|
|
431
|
+
this.log(`Invalid commit SHA format: ${sinceCommit}`);
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
const diff = execSync(`git diff ${sinceCommit}...HEAD`, {
|
|
436
|
+
encoding: "utf-8",
|
|
437
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
438
|
+
});
|
|
439
|
+
return crypto
|
|
440
|
+
.createHash("sha256")
|
|
441
|
+
.update(diff)
|
|
442
|
+
.digest("hex")
|
|
443
|
+
.slice(0, 16);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
this.log(`Failed to compute incremental diff from ${sinceCommit}`);
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get files changed since a specific commit.
|
|
452
|
+
* Used for incremental QA to determine which checks need re-running.
|
|
453
|
+
*
|
|
454
|
+
* @param sinceCommit - The commit SHA to diff from
|
|
455
|
+
* @returns Array of changed file paths, or null if the commit is invalid
|
|
456
|
+
*/
|
|
457
|
+
getChangedFilesSince(sinceCommit) {
|
|
458
|
+
if (!/^[a-f0-9]{4,40}$/.test(sinceCommit)) {
|
|
459
|
+
this.log(`Invalid commit SHA format: ${sinceCommit}`);
|
|
460
|
+
return null;
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
const output = execSync(`git diff ${sinceCommit}...HEAD --name-only`, {
|
|
464
|
+
encoding: "utf-8",
|
|
465
|
+
});
|
|
466
|
+
return output.trim().split("\n").filter(Boolean);
|
|
467
|
+
}
|
|
468
|
+
catch {
|
|
469
|
+
this.log(`Failed to get changed files since ${sinceCommit}`);
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
385
473
|
/**
|
|
386
474
|
* Get cache status for all check types
|
|
387
475
|
*/
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reconciliation engine for sequant status
|
|
3
|
+
*
|
|
4
|
+
* Reconciles local state.json with GitHub API and filesystem
|
|
5
|
+
* to provide accurate, up-to-date status information.
|
|
6
|
+
*
|
|
7
|
+
* @module reconcile
|
|
8
|
+
*/
|
|
9
|
+
import { StateManager } from "./state-manager.js";
|
|
10
|
+
import { type BatchIssueInfo, type BatchPRInfo } from "./platforms/github.js";
|
|
11
|
+
import type { IssueState } from "./state-schema.js";
|
|
12
|
+
/**
|
|
13
|
+
* Classification of detected drift between local state and reality.
|
|
14
|
+
*/
|
|
15
|
+
export type DriftType = "unambiguous" | "ambiguous" | "none";
|
|
16
|
+
/**
|
|
17
|
+
* A single drift action detected during reconciliation.
|
|
18
|
+
*/
|
|
19
|
+
export interface DriftAction {
|
|
20
|
+
issueNumber: number;
|
|
21
|
+
type: DriftType;
|
|
22
|
+
action: string;
|
|
23
|
+
description: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result of a reconciliation operation.
|
|
27
|
+
*/
|
|
28
|
+
export interface ReconcileResult {
|
|
29
|
+
success: boolean;
|
|
30
|
+
/** Actions taken (unambiguous drift auto-healed). */
|
|
31
|
+
healed: DriftAction[];
|
|
32
|
+
/** Ambiguous drift flagged to user. */
|
|
33
|
+
warnings: DriftAction[];
|
|
34
|
+
/** ISO timestamp of when reconciliation completed. */
|
|
35
|
+
lastSynced: string;
|
|
36
|
+
/** Whether GitHub was reachable. */
|
|
37
|
+
githubReachable: boolean;
|
|
38
|
+
/** Error message if reconciliation failed entirely. */
|
|
39
|
+
error?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Options for reconciliation.
|
|
43
|
+
*/
|
|
44
|
+
export interface ReconcileOptions {
|
|
45
|
+
/** Skip GitHub API queries (offline mode). */
|
|
46
|
+
offline?: boolean;
|
|
47
|
+
/** State manager to use. */
|
|
48
|
+
stateManager?: StateManager;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Classify drift for a single issue based on GitHub and filesystem state.
|
|
52
|
+
*/
|
|
53
|
+
export declare function classifyDrift(issue: IssueState, githubIssue?: BatchIssueInfo, githubPR?: BatchPRInfo, worktreeExists?: boolean): DriftAction | null;
|
|
54
|
+
/**
|
|
55
|
+
* Get a next-action hint for an issue based on its current state.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getNextActionHint(issue: IssueState): string;
|
|
58
|
+
/**
|
|
59
|
+
* Format a relative time string from an ISO timestamp.
|
|
60
|
+
*/
|
|
61
|
+
export declare function formatRelativeTime(isoTimestamp: string | undefined): string;
|
|
62
|
+
/**
|
|
63
|
+
* Reconcile local workflow state with GitHub and filesystem.
|
|
64
|
+
*
|
|
65
|
+
* This is the main entry point for reconciliation. Called by:
|
|
66
|
+
* - `sequant status` (CLI)
|
|
67
|
+
* - `sequant_status` (MCP tool)
|
|
68
|
+
*/
|
|
69
|
+
export declare function reconcileState(options?: ReconcileOptions): Promise<ReconcileResult>;
|