feat(lanes): add a read-only feature picker to the Workspace page (B)

This commit is contained in:
2026-08-04 15:00:41 +07:00
parent 5b2f98ab4d
commit 3a83e849cf
6 changed files with 121 additions and 3 deletions
+19 -1
View File
@@ -2013,8 +2013,26 @@ export const api = {
method: "POST",
body: JSON.stringify(body),
}),
/**
* GET /api/lanes/:id/features — list all archived features for a lane.
* @param id The lane id.
* @returns `{ features }` — all {@link LaneFeature} records.
*/
features: {
list: (id: number) =>
request<{ features: import("./types").LaneFeature[] }>(`/lanes/${id}/features`),
/**
* GET /api/lanes/:id/features/:slug — fetch an archived feature snapshot.
* @param id The lane id.
* @param slug The feature slug.
* @returns `{ feature }` — the {@link LaneFeature} record.
*/
show: (id: number, slug: string) =>
request<{ feature: import("./types").LaneFeature }>(
`/lanes/${id}/features/${encodeURIComponent(slug)}`
),
},
},
// ──────────────────────────────── Locks API ────────────────────────────────
/** Named locks across all lanes: used for serialization and gating.
* Maps to `server/routes/locks.js`. */
+13
View File
@@ -2291,6 +2291,19 @@ export interface LaneNode {
}
/** A durable unit of parallel agent work: one cwd, one pipeline, many sessions over time. */
/** An archived snapshot of a lane's feature state: a pipeline at a point in time. */
export interface LaneFeature {
id: number;
lane_id: number;
slug: string;
title: string;
stage: string;
status: string;
archived_at: string | null;
pipeline_nodes: LaneNode[];
progress: number;
}
export interface Lane {
id: number;
title: string;