@wrongstack/tools 0.306.4 → 0.307.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/dist/audit.js +14 -8
- package/dist/auto-proceed-loop-guard.js +8 -2
- package/dist/bash.js +57 -22
- package/dist/builtin.d.ts +6 -6
- package/dist/builtin.js +11302 -9305
- package/dist/clarify.d.ts +32 -0
- package/dist/codebase-index/ast-invariant-engine.d.ts +102 -0
- package/dist/codebase-index/ast-symbol-mutator.d.ts +28 -0
- package/dist/codebase-index/background-indexer.d.ts +9 -0
- package/dist/codebase-index/codebase-ast-replace-tool.d.ts +31 -0
- package/dist/codebase-index/codebase-impact-analysis-tool.d.ts +40 -0
- package/dist/codebase-index/codebase-invariant-check-tool.d.ts +23 -0
- package/dist/codebase-index/codebase-repo-map-tool.d.ts +22 -0
- package/dist/codebase-index/codebase-skeleton-tool.d.ts +36 -0
- package/dist/codebase-index/codebase-targeted-test-tool.d.ts +30 -0
- package/dist/codebase-index/index.d.ts +11 -1
- package/dist/codebase-index/index.js +4141 -1479
- package/dist/codebase-index/project-server-client-state.d.ts +79 -0
- package/dist/codebase-index/project-server-client.d.ts +3 -71
- package/dist/codebase-index/project-server-protocol.d.ts +1 -0
- package/dist/codebase-index/project-server.js +751 -909
- package/dist/codebase-index/repo-map.d.ts +20 -0
- package/dist/codebase-index/skeleton-extractor.d.ts +64 -0
- package/dist/codebase-index/tree-sitter-parser.d.ts +11 -0
- package/dist/codebase-index/worker.js +723 -891
- package/dist/codebase-index/writer-mutations.d.ts +26 -0
- package/dist/codebase-index/writer-refs.d.ts +50 -0
- package/dist/codebase-index/writer-search.d.ts +30 -0
- package/dist/codebase-index/writer.d.ts +2 -320
- package/dist/edit.js +8558 -349
- package/dist/exec.js +73 -20
- package/dist/fetch.js +11 -9
- package/dist/format.js +14 -8
- package/dist/glob.js +5 -1
- package/dist/grep.js +19 -8
- package/dist/index.d.ts +3 -1
- package/dist/index.js +11386 -9416
- package/dist/install.js +14 -8
- package/dist/json.js +88 -15
- package/dist/kanban-board-actions.d.ts +4 -0
- package/dist/kanban-lifecycle-actions.d.ts +4 -0
- package/dist/kanban-serializer.d.ts +21 -0
- package/dist/kanban.js +985 -1034
- package/dist/languages/index.js +14 -8
- package/dist/lint.js +14 -8
- package/dist/logs.js +13 -3
- package/dist/next-steps.d.ts +8 -0
- package/dist/next-steps.js +18 -0
- package/dist/outdated.js +14 -8
- package/dist/pack.js +11295 -9305
- package/dist/patch.js +8301 -78
- package/dist/plan.js +1231 -1281
- package/dist/process-registry.js +14 -8
- package/dist/ps-slash.js +65 -30
- package/dist/read.js +751 -910
- package/dist/replace.js +8450 -224
- package/dist/search.js +21 -15
- package/dist/security-ast-scan-tool.d.ts +43 -0
- package/dist/session-kanban-graph.d.ts +9 -0
- package/dist/session-kanban-sync.d.ts +31 -0
- package/dist/session-kanban.d.ts +5 -141
- package/dist/session-kanban.js +367 -360
- package/dist/task.js +1157 -1207
- package/dist/test.js +14 -8
- package/dist/todo.js +2187 -2237
- package/dist/tool-diff.js +6 -1
- package/dist/tool-summary.js +4 -2
- package/dist/tool-tier.js +11302 -9305
- package/dist/typecheck.js +14 -8
- package/dist/write.js +8374 -153
- package/package.json +7 -7
package/dist/search.js
CHANGED
|
@@ -5,10 +5,7 @@ import { expectDefined } from "@wrongstack/core/utils";
|
|
|
5
5
|
// src/_fetch-guard.ts
|
|
6
6
|
import * as dns from "node:dns/promises";
|
|
7
7
|
import * as net from "node:net";
|
|
8
|
-
import {
|
|
9
|
-
isPrivateIPv4,
|
|
10
|
-
isPrivateIPv6
|
|
11
|
-
} from "@wrongstack/core/utils";
|
|
8
|
+
import { isPrivateIPv4, isPrivateIPv6 } from "@wrongstack/core/utils";
|
|
12
9
|
import { FetchError, ToolValidationError } from "@wrongstack/core/types";
|
|
13
10
|
import { Agent, fetch as undiciFetch } from "undici";
|
|
14
11
|
var nativeGlobalFetch = globalThis.fetch;
|
|
@@ -491,18 +488,27 @@ async function bingSearch(query, signal) {
|
|
|
491
488
|
}
|
|
492
489
|
function parseBingResults(html, num) {
|
|
493
490
|
const results = [];
|
|
494
|
-
const blocks = [
|
|
491
|
+
const blocks = [
|
|
492
|
+
...html.matchAll(
|
|
493
|
+
/<li\b[^>]*class=(["'])[^"']*\bb_algo\b[^"']*\1[^>]*>([\s\S]*?)(?=<li\b[^>]*class=(["'])[^"']*\bb_algo\b[^"']*\3|<\/ol>)/gi
|
|
494
|
+
)
|
|
495
|
+
].map((m) => expectDefined(m[2]));
|
|
495
496
|
const candidates = blocks.length > 0 ? blocks : [html];
|
|
496
|
-
const entries = takeFrom(
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
497
|
+
const entries = takeFrom(
|
|
498
|
+
candidates.flatMap((block) => {
|
|
499
|
+
const titleMatch = /<h2[^>]*>\s*<a\b([^>]*)>([\s\S]*?)<\/a>\s*<\/h2>/i.exec(block);
|
|
500
|
+
if (!titleMatch) return [];
|
|
501
|
+
const href = getHtmlAttr(expectDefined(titleMatch[1]), "href");
|
|
502
|
+
const title = stripTags(expectDefined(titleMatch[2]));
|
|
503
|
+
if (!href || !title) return [];
|
|
504
|
+
const snippetMatch = /<p\b[^>]*class=(["'])[^"']*\b(?:b_paractl|b_lineclamp\d*)\b[^"']*\1[^>]*>([\s\S]*?)<\/p>/i.exec(
|
|
505
|
+
block
|
|
506
|
+
) ?? /<p\b[^>]*>([\s\S]*?)<\/p>/i.exec(block);
|
|
507
|
+
const snippet = snippetMatch ? capSnippet(stripTags(expectDefined(snippetMatch.at(-1)))) : "";
|
|
508
|
+
return [{ url: normalizeBingUrl(href), title, snippet, score: 1 }];
|
|
509
|
+
}),
|
|
510
|
+
num
|
|
511
|
+
);
|
|
506
512
|
for (let i = 0; i < entries.length; i++) {
|
|
507
513
|
const entry = entries[i];
|
|
508
514
|
if (entry) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `security-ast-scan` tool — Contract-based Security & Performance AST Radar.
|
|
3
|
+
*
|
|
4
|
+
* Scans code files or snippets for anti-patterns that static types cannot catch:
|
|
5
|
+
* 1. N+1 Database Query loops (Performance critical)
|
|
6
|
+
* 2. SQL Injection / Raw query interpolation (Security critical)
|
|
7
|
+
* 3. Hardcoded secrets, API tokens, and private keys
|
|
8
|
+
* 4. Prototype Pollution vulnerabilities
|
|
9
|
+
* 5. ReDoS (Regular Expression Denial of Service) nested backtracking
|
|
10
|
+
* 6. Unsafe dynamic execution (eval, new Function, unsanitized child_process.exec)
|
|
11
|
+
*/
|
|
12
|
+
import type { Tool } from '@wrongstack/core/types';
|
|
13
|
+
export interface SecurityFinding {
|
|
14
|
+
ruleId: 'perf/n-plus-one-query' | 'sec/sql-injection' | 'sec/hardcoded-secret' | 'sec/prototype-pollution' | 'sec/redos-vulnerable-regex' | 'sec/unsafe-dynamic-exec';
|
|
15
|
+
category: 'security' | 'performance';
|
|
16
|
+
severity: 'critical' | 'warning' | 'info';
|
|
17
|
+
file: string;
|
|
18
|
+
line: number;
|
|
19
|
+
message: string;
|
|
20
|
+
snippet: string;
|
|
21
|
+
recommendation: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SecurityScanInput {
|
|
24
|
+
/** File path to scan (relative to project root or absolute). */
|
|
25
|
+
file?: string | undefined;
|
|
26
|
+
/** Direct code content to scan (optional, if scanning unwritten draft). */
|
|
27
|
+
content?: string | undefined;
|
|
28
|
+
/** Specific rule IDs to enable or filter by. */
|
|
29
|
+
rules?: string[] | undefined;
|
|
30
|
+
}
|
|
31
|
+
export interface SecurityScanOutput {
|
|
32
|
+
status: 'clean' | 'findings_detected' | 'error';
|
|
33
|
+
filesScanned: number;
|
|
34
|
+
totalFindings: number;
|
|
35
|
+
criticalCount: number;
|
|
36
|
+
warningCount: number;
|
|
37
|
+
findings: SecurityFinding[];
|
|
38
|
+
summary: string;
|
|
39
|
+
error?: string | undefined;
|
|
40
|
+
}
|
|
41
|
+
export declare function analyzeSecurityAndPerformance(filePath: string, content: string): SecurityFinding[];
|
|
42
|
+
export declare const securityAstScanTool: Tool<SecurityScanInput, SecurityScanOutput>;
|
|
43
|
+
//# sourceMappingURL=security-ast-scan-tool.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TodoItem } from '@wrongstack/core/agent';
|
|
2
|
+
import type { PlanItem } from '@wrongstack/core/storage';
|
|
3
|
+
import type { SerializedTaskGraph, TaskStatus } from '@wrongstack/core/types';
|
|
4
|
+
import type { TaskItem } from '@wrongstack/core/utils';
|
|
5
|
+
export declare const PLAN_STATUS_TO_TASK: Record<PlanItem['status'], TaskStatus>;
|
|
6
|
+
export declare function todoListToSerializedGraph(todos: readonly TodoItem[], sessionId: string): SerializedTaskGraph;
|
|
7
|
+
export declare function taskFileToSerializedGraph(tasks: readonly TaskItem[], sessionId: string): SerializedTaskGraph;
|
|
8
|
+
export declare function planFileToSerializedGraph(items: readonly PlanItem[], sessionId: string): SerializedTaskGraph;
|
|
9
|
+
//# sourceMappingURL=session-kanban-graph.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Context, TodoItem } from '@wrongstack/core/agent';
|
|
2
|
+
import { type PlanFile, type TaskFile } from '@wrongstack/core/storage';
|
|
3
|
+
import type { TaskStatus } from '@wrongstack/core/types';
|
|
4
|
+
import { type KanbanBoard, type KanbanTask } from '@wrongstack/kanban';
|
|
5
|
+
export interface SessionKanbanSourceUpdate {
|
|
6
|
+
source: 'todo' | 'task' | 'plan' | null;
|
|
7
|
+
todos?: TodoItem[] | undefined;
|
|
8
|
+
tasks?: TaskFile | undefined;
|
|
9
|
+
plan?: PlanFile | undefined;
|
|
10
|
+
}
|
|
11
|
+
export declare function sourceStatus(task: KanbanTask): TaskStatus;
|
|
12
|
+
export declare function todoStatus(task: KanbanTask): TodoItem['status'];
|
|
13
|
+
export declare function sessionTodoFromTask(task: KanbanTask, board?: KanbanBoard): TodoItem;
|
|
14
|
+
export declare function managedTodoFromTask(task: KanbanTask, board: KanbanBoard): TodoItem;
|
|
15
|
+
export declare function blockingTitles(board: KanbanBoard, task: KanbanTask): string[];
|
|
16
|
+
export declare function orderTasksForTodos(board: KanbanBoard, tasks: readonly KanbanTask[]): KanbanTask[];
|
|
17
|
+
export declare function sameTodos(left: readonly TodoItem[], right: readonly TodoItem[]): boolean;
|
|
18
|
+
export declare function broadcastTodoUpdate(context: Context, todos: readonly TodoItem[]): void;
|
|
19
|
+
export declare function notifyTodoUpdate(context: Context, todos: readonly TodoItem[]): void;
|
|
20
|
+
export declare function todosNeedingSessionMirror(todos: readonly TodoItem[], activeBoardId: string | undefined): readonly TodoItem[];
|
|
21
|
+
export declare function applySessionKanbanBoardToTodos(context: Context, board: KanbanBoard, options: {
|
|
22
|
+
sessionIdFromTags: (tags: readonly string[] | undefined) => string | null;
|
|
23
|
+
isOwnedSessionBoard: (tags: readonly string[] | undefined) => boolean;
|
|
24
|
+
hasInFlightTodoMirror: (projectRoot: string | undefined, sessionId: string) => boolean;
|
|
25
|
+
suppressedTodoMirrors: WeakSet<Context>;
|
|
26
|
+
}): TodoItem[];
|
|
27
|
+
export declare function applyManagedKanbanBoardToTodos(context: Context, board: KanbanBoard, suppressedTodoMirrors: WeakSet<Context>): TodoItem[];
|
|
28
|
+
export declare function applySessionKanbanTaskToSource(context: Context, task: KanbanTask, suppressedTodoMirrors: WeakSet<Context>, options?: {
|
|
29
|
+
remove?: boolean | undefined;
|
|
30
|
+
}): Promise<SessionKanbanSourceUpdate>;
|
|
31
|
+
//# sourceMappingURL=session-kanban-sync.d.ts.map
|
package/dist/session-kanban.d.ts
CHANGED
|
@@ -1,167 +1,31 @@
|
|
|
1
1
|
import type { Context, TodoItem } from '@wrongstack/core/agent';
|
|
2
|
-
import { type
|
|
3
|
-
import type {
|
|
4
|
-
import { type TaskItem } from '@wrongstack/core/utils';
|
|
2
|
+
import { type PlanItem } from '@wrongstack/core/storage';
|
|
3
|
+
import type { TaskItem } from '@wrongstack/core/utils';
|
|
5
4
|
import { type KanbanBoard, type KanbanColumn, type KanbanTask } from '@wrongstack/kanban';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
* Session boards now use the same 5 standard columns as every other board
|
|
10
|
-
* (backlog, todo, in-progress, review, done). Formerly this shipped a 4-column
|
|
11
|
-
* variant without a backlog; the column lock unified the layout. Existing
|
|
12
|
-
* 4-column session_mirror boards are migrated automatically on the next session
|
|
13
|
-
* touch: `ensureSessionKanbanBoard`'s `sameColumns` check detects the drift
|
|
14
|
-
* and `updateBoard` reconciles to DEFAULT_COLUMNS.
|
|
15
|
-
*/
|
|
5
|
+
import { type SessionKanbanSourceUpdate } from './session-kanban-sync.js';
|
|
6
|
+
export { PLAN_STATUS_TO_TASK, planFileToSerializedGraph, taskFileToSerializedGraph, todoListToSerializedGraph, } from './session-kanban-graph.js';
|
|
7
|
+
export { blockingTitles, orderTasksForTodos, type SessionKanbanSourceUpdate, todosNeedingSessionMirror, } from './session-kanban-sync.js';
|
|
16
8
|
export declare const SESSION_KANBAN_COLUMNS: KanbanColumn[];
|
|
17
|
-
/** Create (or migrate) the single Kanban board owned by a session. */
|
|
18
9
|
export declare function ensureSessionKanbanBoard(projectRoot: string | undefined, sessionId: string): Promise<KanbanBoard | null>;
|
|
19
|
-
/**
|
|
20
|
-
* Remove an inactive session's observational mirror, including its cards.
|
|
21
|
-
* The durable source remains the session todo/task/plan files; retaining the
|
|
22
|
-
* mirror after detach only creates historical duplicate work in project views.
|
|
23
|
-
*/
|
|
24
10
|
export declare function cleanupSessionKanbanBoard(projectRoot: string | undefined, sessionId: string): Promise<string[]>;
|
|
25
|
-
/** Remove a particular inactive session's system-owned board when it has no cards. */
|
|
26
11
|
export declare function cleanupSessionKanbanBoardIfEmpty(projectRoot: string | undefined, sessionId: string): Promise<string[]>;
|
|
27
|
-
/** Prune stale empty session boards while preserving manual and live boards. */
|
|
28
12
|
export declare function cleanupEmptySessionKanbanBoards(projectRoot: string | undefined, activeSessionId?: string): Promise<string[]>;
|
|
29
|
-
/**
|
|
30
|
-
* Consume the last unreported mirror failure for a session, if any.
|
|
31
|
-
*
|
|
32
|
-
* The mirror is asynchronous and fire-and-forget, so a rejected projection
|
|
33
|
-
* used to be observable only in stdout. The `todo` tool drains this on its
|
|
34
|
-
* next call and reports it as a warning, so a board that stopped tracking the
|
|
35
|
-
* session is surfaced where the divergence actually matters.
|
|
36
|
-
*/
|
|
37
13
|
export declare function takeSessionMirrorFailure(projectRoot: string | undefined, sessionId: string): string | undefined;
|
|
38
|
-
export declare function todoListToSerializedGraph(todos: readonly TodoItem[], sessionId: string): SerializedTaskGraph;
|
|
39
|
-
export declare function taskFileToSerializedGraph(tasks: readonly TaskItem[], sessionId: string): SerializedTaskGraph;
|
|
40
|
-
export declare function planFileToSerializedGraph(items: readonly PlanItem[], sessionId: string): SerializedTaskGraph;
|
|
41
14
|
export declare function projectSessionTodosToKanban(projectRoot: string | undefined, todos: readonly TodoItem[], sessionId: string): Promise<KanbanBoard | null>;
|
|
42
15
|
export declare function projectSessionTasksToKanban(projectRoot: string | undefined, tasks: readonly TaskItem[], sessionId: string): Promise<KanbanBoard | null>;
|
|
43
16
|
export declare function projectSessionPlanToKanban(projectRoot: string | undefined, items: readonly PlanItem[], sessionId: string): Promise<KanbanBoard | null>;
|
|
44
|
-
/**
|
|
45
|
-
* The todo rows that still need the session mirror: those not already cards on
|
|
46
|
-
* the board this session is working on.
|
|
47
|
-
*
|
|
48
|
-
* The rule used to be all-or-nothing — the mirror was skipped only when EVERY
|
|
49
|
-
* row was bound. A single unbound row (a todo the model added to the chat list
|
|
50
|
-
* without also filing a card) sent the whole list to a separate session board,
|
|
51
|
-
* so work already tracked on the real board showed up a second time there, and
|
|
52
|
-
* one stray row was enough to leave a session board holding a single card.
|
|
53
|
-
*
|
|
54
|
-
* With no active board every row still needs mirroring, since there is no other
|
|
55
|
-
* place the work is being recorded.
|
|
56
|
-
*/
|
|
57
|
-
export declare function todosNeedingSessionMirror(todos: readonly TodoItem[], activeBoardId: string | undefined): readonly TodoItem[];
|
|
58
17
|
export declare function mirrorSessionTodosToKanban(projectRoot: string | undefined, todos: readonly TodoItem[], sessionId: string): void;
|
|
59
18
|
export declare function mirrorSessionTasksToKanban(projectRoot: string | undefined, tasks: readonly TaskItem[], sessionId: string): void;
|
|
60
19
|
export declare function mirrorSessionPlanToKanban(projectRoot: string | undefined, items: readonly PlanItem[], sessionId: string): void;
|
|
61
|
-
/**
|
|
62
|
-
* Bind all live session work paths to Kanban. Todo changes are observed from
|
|
63
|
-
* ConversationState; plan/task sidecars are watched so slash commands, WebUI,
|
|
64
|
-
* plugins, and tools all pass through the same board.
|
|
65
|
-
*/
|
|
66
20
|
export declare function attachSessionKanbanMirror(context: Context): () => void;
|
|
67
|
-
/** Fully hydrate a session board before a host announces the session as ready. */
|
|
68
|
-
/**
|
|
69
|
-
* Re-bind the card this session was working, after a restart or `--resume`.
|
|
70
|
-
*
|
|
71
|
-
* The binding produced by `start_task` lives in `ctx.meta.kanban`, which is
|
|
72
|
-
* conversation state — nothing restores it. So a resumed session came back
|
|
73
|
-
* with `currentKanbanTaskId` undefined while its card still sat in Running on
|
|
74
|
-
* the board: file events lost their task attribution, and under
|
|
75
|
-
* `tools.kanbanGovernance` the run was un-bound until the model happened to
|
|
76
|
-
* call `start_task` again.
|
|
77
|
-
*
|
|
78
|
-
* Board presence is the durable anchor. It is keyed `<sessionId>:<agentId>`,
|
|
79
|
-
* carries the `taskId`, and is stored on the board record itself, so it
|
|
80
|
-
* survives the restart even though its derived `active` flag does not (the TTL
|
|
81
|
-
* is two minutes). Matching it against the cards that are actually still
|
|
82
|
-
* running gives an unambiguous answer without guessing from free-text agent
|
|
83
|
-
* ids.
|
|
84
|
-
*
|
|
85
|
-
* Deliberately conservative — it prefers to do nothing over binding the wrong
|
|
86
|
-
* card:
|
|
87
|
-
* - never overrides a binding this process already has;
|
|
88
|
-
* - only considers cards whose assignment is still `running`;
|
|
89
|
-
* - skips an expired lease, because `recover_stale` may have reassigned that
|
|
90
|
-
* card to another worker;
|
|
91
|
-
* - picks the most recently seen entry when a session touched several.
|
|
92
|
-
*
|
|
93
|
-
* Session mirrors and archived boards are excluded by the snapshot's default
|
|
94
|
-
* board-kind filter, which is correct: `start_task` never targets them.
|
|
95
|
-
*/
|
|
96
21
|
export declare function rebindSessionKanbanTask(context: Context): Promise<{
|
|
97
22
|
boardId: string;
|
|
98
23
|
taskId: string;
|
|
99
24
|
} | null>;
|
|
100
|
-
/**
|
|
101
|
-
* Why session Kanban is unavailable, or undefined while it is healthy.
|
|
102
|
-
*
|
|
103
|
-
* Surfaces exist so a startup path can tell the user their board will not sync
|
|
104
|
-
* without having to catch and classify the failure itself. Cleared on the
|
|
105
|
-
* first hydrate that succeeds, so a daemon that comes back stops being
|
|
106
|
-
* reported as down.
|
|
107
|
-
*/
|
|
108
25
|
export declare function sessionKanbanDegradation(): string | undefined;
|
|
109
|
-
/**
|
|
110
|
-
* Project the session's todos, plan, and tasks onto its Kanban board.
|
|
111
|
-
*
|
|
112
|
-
* Kanban is a projection: every card here is derived from state that lives
|
|
113
|
-
* somewhere else and is authoritative there. Losing the board costs the user a
|
|
114
|
-
* view, not any work — so an unreachable Kanban daemon degrades this to `null`
|
|
115
|
-
* rather than propagating.
|
|
116
|
-
*
|
|
117
|
-
* That distinction used to be missing, and it cost an entire session. When a
|
|
118
|
-
* killed daemon left a stale IPC endpoint behind, the connect error thrown
|
|
119
|
-
* here unwound through `setupSession` and killed `wstack` at startup: no
|
|
120
|
-
* prompt, no session, just a socket path in a stack trace — for a board the
|
|
121
|
-
* user had not asked to see. `bindProjectEndpoint` now stops the daemon from
|
|
122
|
-
* wedging in the first place, but the call site must still hold: an optional
|
|
123
|
-
* view may never take down the session it decorates.
|
|
124
|
-
*/
|
|
125
26
|
export declare function hydrateSessionKanban(context: Context): Promise<KanbanBoard | null>;
|
|
126
|
-
export interface SessionKanbanSourceUpdate {
|
|
127
|
-
source: 'todo' | 'task' | 'plan' | null;
|
|
128
|
-
todos?: TodoItem[] | undefined;
|
|
129
|
-
tasks?: TaskFile | undefined;
|
|
130
|
-
plan?: PlanFile | undefined;
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Human-readable titles of the unfinished dependencies blocking a card.
|
|
134
|
-
*
|
|
135
|
-
* The board recomputes readiness on every mutation; this only carries the
|
|
136
|
-
* result to the todo surface. Titles rather than ids, because the row is read
|
|
137
|
-
* by a model and a human, neither of whom can resolve a raw card id.
|
|
138
|
-
*/
|
|
139
|
-
export declare function blockingTitles(board: KanbanBoard, task: KanbanTask): string[];
|
|
140
|
-
/**
|
|
141
|
-
* Order cards the way they must actually be worked: dependencies first, then
|
|
142
|
-
* priority, then the board's own column/manual order.
|
|
143
|
-
*
|
|
144
|
-
* The managed projection previously sorted by `createdAt` — the moment a card
|
|
145
|
-
* happened to be created — which is unrelated to execution order, so the list
|
|
146
|
-
* the model reads top-to-bottom was not a plan. A dependency-respecting
|
|
147
|
-
* (Kahn) order makes the visible sequence the executable sequence; ties fall
|
|
148
|
-
* back to the deterministic board order so the list never reshuffles on its
|
|
149
|
-
* own. Any card left over by a dependency cycle is appended rather than
|
|
150
|
-
* dropped — the board rejects cycles, but a projection must never lose work.
|
|
151
|
-
*/
|
|
152
|
-
export declare function orderTasksForTodos(board: KanbanBoard, tasks: readonly KanbanTask[]): KanbanTask[];
|
|
153
|
-
/**
|
|
154
|
-
* Replace the tactical todo list from the current cards on a session-owned board.
|
|
155
|
-
*
|
|
156
|
-
* Existing mirrored todo cards retain their stable source ids. New cards created
|
|
157
|
-
* by a Kanban worker become todos under their card ids, so reassessment can add,
|
|
158
|
-
* split, merge, reprioritize, or remove work without being overwritten by the
|
|
159
|
-
* todo list that happened to exist when the run started.
|
|
160
|
-
*/
|
|
161
27
|
export declare function applySessionKanbanBoardToTodos(context: Context, board: KanbanBoard): TodoItem[];
|
|
162
|
-
/** Project a durable managed board into the session's compact todo surface. */
|
|
163
28
|
export declare function applyManagedKanbanBoardToTodos(context: Context, board: KanbanBoard): TodoItem[];
|
|
164
|
-
/** Reflect a TUI/WebUI Kanban card edit back to its originating work list. */
|
|
165
29
|
export declare function applySessionKanbanTaskToSource(context: Context, task: KanbanTask, options?: {
|
|
166
30
|
remove?: boolean | undefined;
|
|
167
31
|
}): Promise<SessionKanbanSourceUpdate>;
|