chore: clean repo quality gates

This commit is contained in:
Mikael Hugo 2026-05-05 14:55:11 +02:00
parent 00a118ea71
commit 2d9c2018af
12 changed files with 1812 additions and 1489 deletions

View file

@ -417,7 +417,7 @@ describe("RetryHandler — long-context entitlement 429 (#2803)", () => {
const expensiveModel = createMockModel("openrouter", "openai/gpt-5-pro");
expensiveModel.maxTokens = 128000;
const { deps, emittedEvents } = createMockDeps({
const { deps, emittedEvents, onModelChangeFn } = createMockDeps({
model: expensiveModel,
markUsageLimitReachedResult: false,
fallbackResult: null,

View file

@ -1395,7 +1395,6 @@ export class InteractiveMode {
},
},
shutdownHandler: () => {
this.shutdownRequested = true;
if (!this.session.isStreaming) {
void this.shutdown();
}
@ -1488,7 +1487,9 @@ export class InteractiveMode {
abort: () => this.session.abort(),
hasPendingMessages: () => this.session.pendingMessageCount > 0,
shutdown: () => {
this.shutdownRequested = true;
if (!this.session.isStreaming) {
void this.shutdown();
}
},
getContextUsage: () => this.session.getContextUsage(),
compact: (options) => {

View file

@ -294,7 +294,7 @@ export class RpcClient {
if (resolve) {
const r = resolve;
resolve = null;
r();
r(undefined);
}
};
@ -304,7 +304,7 @@ export class RpcClient {
if (resolve) {
const r = resolve;
resolve = null;
r();
r(undefined);
}
};

View file

@ -5,11 +5,11 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Session Export</title>
<style>
{{CSS}}
/*__SF_EXPORT_CSS__*/
</style>
</head>
<body>
<button id="hamburger" title="Open sidebar"><svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><rect x="5" y="6" width="2" height="12"/><path d="M6 12h10c1 0 2 0 2-2V8"/></svg></button>
<button type="button" id="hamburger" title="Open sidebar"><svg aria-hidden="true" width="14" height="14" viewBox="0 0 24 24" fill="currentColor" stroke="none"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><rect x="5" y="6" width="2" height="12"/><path d="M6 12h10c1 0 2 0 2-2V8"/></svg></button>
<div id="sidebar-overlay"></div>
<div id="app">
<aside id="sidebar">
@ -18,12 +18,12 @@
<input type="text" class="sidebar-search" id="tree-search" placeholder="Search...">
</div>
<div class="sidebar-filters">
<button class="filter-btn active" data-filter="default" title="Hide settings entries">Default</button>
<button class="filter-btn" data-filter="no-tools" title="Default minus tool results">No-tools</button>
<button class="filter-btn" data-filter="user-only" title="Only user messages">User</button>
<button class="filter-btn" data-filter="labeled-only" title="Only labeled entries">Labeled</button>
<button class="filter-btn" data-filter="all" title="Show everything">All</button>
<button class="sidebar-close" id="sidebar-close" title="Close"></button>
<button type="button" class="filter-btn active" data-filter="default" title="Hide settings entries">Default</button>
<button type="button" class="filter-btn" data-filter="no-tools" title="Default minus tool results">No-tools</button>
<button type="button" class="filter-btn" data-filter="user-only" title="Only user messages">User</button>
<button type="button" class="filter-btn" data-filter="labeled-only" title="Only labeled entries">Labeled</button>
<button type="button" class="filter-btn" data-filter="all" title="Show everything">All</button>
<button type="button" class="sidebar-close" id="sidebar-close" title="Close"></button>
</div>
</div>
<div class="tree-container" id="tree-container"></div>
@ -38,17 +38,16 @@
</div>
</div>
<script id="session-data" type="application/json">{{SESSION_DATA}}</script>
<script id="session-data" type="application/json">"__SF_SESSION_DATA__"</script>
<!-- Vendored libraries -->
<script>{{MARKED_JS}}</script>
<script>/*__SF_EXPORT_MARKED_JS__*/</script>
<!-- highlight.js -->
<script>{{HIGHLIGHT_JS}}</script>
<script>/*__SF_EXPORT_HIGHLIGHT_JS__*/</script>
<!-- Main application code -->
<script>
{{JS}}
<script>/*__SF_EXPORT_JS__*/
</script>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -147,7 +147,7 @@ export function repairMissingSfSymlinkForHeadless(
if (!externalPath || !hasExternalProjectState(externalPath)) return null;
const linkedPath = ensureSfSymlink(basePath);
return existsSync(sfDir) ? linkedPath : null;
return existsSync(sfDir) ? (linkedPath ?? sfDir) : null;
}
/**
@ -831,7 +831,7 @@ async function runHeadlessOnce(
const trace = initTraceCollector(
cwd,
sessionId ?? null,
options.command,
options.command ?? "run",
options.model ?? null,
);
if (trace) traceActive = true;

View file

@ -1,10 +1,22 @@
interface DocCheckSummary {
total: number;
ok: number;
empty: number;
stub: number;
missing: number;
}
interface DocCheckReport {
checkedAt: string;
repoRoot: string;
checks: unknown[];
summary: DocCheckSummary;
}
export function checkDocsScaffold(repoRoot: string): {
summary: string;
issues?: string[];
score?: number;
checkedAt: string;
repoRoot: string;
checks: unknown[];
summary: DocCheckSummary;
};
export function formatDocCheckReport(report: {
summary: string;
issues?: string[];
score?: number;
}): string;
export function formatDocCheckReport(report: DocCheckReport): string;

View file

@ -1,2 +1,11 @@
export function validateTitle(title: string): boolean;
export function buildStateMarkdown(state: Record<string, unknown>): string;
export function runSFDoctor(
basePath: string,
options?: Record<string, unknown>,
): Promise<{ ok: boolean; [key: string]: unknown }>;
export function formatDoctorReport(
report: Record<string, unknown>,
options?: Record<string, unknown>,
): string;
export function formatDoctorReportJson(report: Record<string, unknown>): string;

View file

@ -0,0 +1,2 @@
export function printScheduleBanner(basePath: string): void;
export function showScheduleBanner(basePath: string): void;

View file

@ -0,0 +1,37 @@
export type ScheduleScope = "project" | "global";
export type ScheduleStatus = "pending" | "done" | "cancelled" | "snoozed";
export type ScheduleKind =
| "reminder"
| "milestone_check"
| "review_due"
| "recurring";
export interface ScheduleEntry {
id: string;
kind: ScheduleKind;
status: ScheduleStatus;
due_at: string;
created_at: string;
payload: Record<string, unknown>;
created_by: "auto" | "user" | "system";
auto_dispatch?: boolean;
snoozed_at?: string;
}
export interface ScheduleStore {
appendEntry(scope: ScheduleScope, entry: ScheduleEntry): void;
readEntries(scope: ScheduleScope): ScheduleEntry[];
findDue(scope: ScheduleScope, now: string | number | Date): ScheduleEntry[];
findUpcoming(
scope: ScheduleScope,
now: string | number | Date,
windowDays: number,
): ScheduleEntry[];
_filePathForScope(scope: ScheduleScope): string;
}
export function createScheduleStore(basePath: string): ScheduleStore;
export function resolveSchedulePath(
basePath: string,
scope: ScheduleScope,
): string;

View file

@ -18,9 +18,9 @@ export interface Trace {
export function isTraceEnabled(): boolean;
export function initTraceCollector(
projectRoot: string,
sessionId: string,
sessionId: string | null,
command: string,
model: string,
model: string | null,
): unknown;
export function flushTrace(projectRoot: string): void;
export function getActiveTrace(): Trace | null;

View file

@ -2,4 +2,10 @@ export interface SFState {
milestones: unknown[];
slices: unknown[];
tasks: unknown[];
phase: string;
nextAction: string;
activeMilestone: { id: string; title?: string } | null;
lastCompletedMilestone: { id: string; title?: string } | null;
activeSlice: { id: string; title?: string } | null;
activeTask: { id: string; title?: string } | null;
}