@hasna/todos 0.15.4 → 0.15.6
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/cli/commands/delegate.d.ts +51 -0
- package/dist/cli/commands/delegate.d.ts.map +1 -0
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/index.js +723 -229
- package/dist/cli/stage-a.d.ts.map +1 -1
- package/dist/contracts.js +13 -1
- package/dist/db/task-crud.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/lib/comment-cursor.d.ts +40 -0
- package/dist/lib/comment-cursor.d.ts.map +1 -0
- package/dist/lib/delegation-brief.d.ts +31 -0
- package/dist/lib/delegation-brief.d.ts.map +1 -0
- package/dist/lib/delegation-policy.d.ts +32 -0
- package/dist/lib/delegation-policy.d.ts.map +1 -0
- package/dist/lib/delegation-record.d.ts +50 -0
- package/dist/lib/delegation-record.d.ts.map +1 -0
- package/dist/lib/delegation-verify.d.ts +57 -0
- package/dist/lib/delegation-verify.d.ts.map +1 -0
- package/dist/mcp/index.js +36 -21
- package/dist/mcp.js +1 -1
- package/dist/registry.js +13 -1
- package/dist/release-provenance.json +5 -5
- package/dist/server/index.js +36 -21
- package/dist/server/v1.d.ts.map +1 -1
- package/dist/storage.js +12 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stage-a.d.ts","sourceRoot":"","sources":["../../src/cli/stage-a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,WAAW,CAAC;AAO1C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,+BAA+B,GACvC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;AAyB/E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;CA8BgB,CAAC;
|
|
1
|
+
{"version":3,"file":"stage-a.d.ts","sourceRoot":"","sources":["../../src/cli/stage-a.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAQ,MAAM,WAAW,CAAC;AAO1C,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE9C,MAAM,MAAM,+BAA+B,GACvC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,IAAI,CAAA;CAAE,GACrC;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1D;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,aAAa,GAAG,YAAY,CAAC;AAyB/E,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;CA8BgB,CAAC;AAyEvD,wBAAgB,kCAAkC,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE9F;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAC9C,OAAO,CAKT;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,OAAO,CAAC,GAAG,IAAI,CASnH;AAuWD;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,GAAE,MAAM,EAA0B,EACtC,GAAG,GAAE,GAAwB,GAC5B,+BAA+B,CAgBjC"}
|
package/dist/contracts.js
CHANGED
|
@@ -9313,6 +9313,18 @@ function updateTask(id, input, db) {
|
|
|
9313
9313
|
sets.push("assigned_to = ?");
|
|
9314
9314
|
params.push(input.assigned_to);
|
|
9315
9315
|
}
|
|
9316
|
+
if (input.assigned_by !== undefined) {
|
|
9317
|
+
sets.push("assigned_by = ?");
|
|
9318
|
+
params.push(input.assigned_by);
|
|
9319
|
+
}
|
|
9320
|
+
if (input.delegated_from !== undefined) {
|
|
9321
|
+
sets.push("delegated_from = ?");
|
|
9322
|
+
params.push(input.delegated_from);
|
|
9323
|
+
}
|
|
9324
|
+
if (input.delegation_depth !== undefined) {
|
|
9325
|
+
sets.push("delegation_depth = ?");
|
|
9326
|
+
params.push(input.delegation_depth);
|
|
9327
|
+
}
|
|
9316
9328
|
if (input.working_dir !== undefined) {
|
|
9317
9329
|
sets.push("working_dir = ?");
|
|
9318
9330
|
params.push(input.working_dir);
|
|
@@ -12032,7 +12044,7 @@ var init_tasks = __esm(() => {
|
|
|
12032
12044
|
// package.json
|
|
12033
12045
|
var package_default = {
|
|
12034
12046
|
name: "@hasna/todos",
|
|
12035
|
-
version: "0.15.
|
|
12047
|
+
version: "0.15.6",
|
|
12036
12048
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
12037
12049
|
type: "module",
|
|
12038
12050
|
main: "dist/index.js",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-crud.d.ts","sourceRoot":"","sources":["../../src/db/task-crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EACV,eAAe,EACf,IAAI,EACJ,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,eAAe,EACf,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAY5F,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAS5C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAMjF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGlF;AAwCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAwFtE;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAK9D;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,EACV,EAAE,CAAC,EAAE,QAAQ,GACZ,iBAAiB,GAAG,IAAI,CA4D1B;AAQD,wBAAgB,SAAS,CAAC,MAAM,GAAE,UAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,CA0JxE;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,GAAG,IAAI,CAKb;AAcD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,EACnC,EAAE,CAAC,EAAE,QAAQ,GACZ,6BAA6B,CAmD/B;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0HnG;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,
|
|
1
|
+
{"version":3,"file":"task-crud.d.ts","sourceRoot":"","sources":["../../src/db/task-crud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAoB,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EACV,eAAe,EACf,IAAI,EACJ,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,eAAe,EACf,4BAA4B,EAC5B,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAY5F,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAS5C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAMjF;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGlF;AAwCD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAwFtE;AAED,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,CAK9D;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,EACV,EAAE,CAAC,EAAE,QAAQ,GACZ,iBAAiB,GAAG,IAAI,CA4D1B;AAQD,wBAAgB,SAAS,CAAC,MAAM,GAAE,UAAe,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,EAAE,CA0JxE;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,GAAG,IAAI,CAKb;AAcD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,EACnC,EAAE,CAAC,EAAE,QAAQ,GACZ,6BAA6B,CAmD/B;AAED,wBAAgB,UAAU,CAAC,MAAM,GAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,QAAQ,CAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0HnG;AAED,wBAAgB,UAAU,CACxB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,eAAe,EACtB,EAAE,CAAC,EAAE,QAAQ,GACZ,IAAI,CAsRN;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAY7D"}
|
package/dist/index.js
CHANGED
|
@@ -9313,6 +9313,18 @@ function updateTask(id, input, db) {
|
|
|
9313
9313
|
sets.push("assigned_to = ?");
|
|
9314
9314
|
params.push(input.assigned_to);
|
|
9315
9315
|
}
|
|
9316
|
+
if (input.assigned_by !== undefined) {
|
|
9317
|
+
sets.push("assigned_by = ?");
|
|
9318
|
+
params.push(input.assigned_by);
|
|
9319
|
+
}
|
|
9320
|
+
if (input.delegated_from !== undefined) {
|
|
9321
|
+
sets.push("delegated_from = ?");
|
|
9322
|
+
params.push(input.delegated_from);
|
|
9323
|
+
}
|
|
9324
|
+
if (input.delegation_depth !== undefined) {
|
|
9325
|
+
sets.push("delegation_depth = ?");
|
|
9326
|
+
params.push(input.delegation_depth);
|
|
9327
|
+
}
|
|
9316
9328
|
if (input.working_dir !== undefined) {
|
|
9317
9329
|
sets.push("working_dir = ?");
|
|
9318
9330
|
params.push(input.working_dir);
|
|
@@ -12145,7 +12157,7 @@ var init_dispatches = __esm(() => {
|
|
|
12145
12157
|
// package.json
|
|
12146
12158
|
var package_default = {
|
|
12147
12159
|
name: "@hasna/todos",
|
|
12148
|
-
version: "0.15.
|
|
12160
|
+
version: "0.15.6",
|
|
12149
12161
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
12150
12162
|
type: "module",
|
|
12151
12163
|
main: "dist/index.js",
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { TaskComment } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Keyset cursor for the task-comment read model, and the pure pager that walks
|
|
4
|
+
* it. Both the `/v1` server and the CLI encode and decode the same cursor, so
|
|
5
|
+
* the codec lives here rather than beside either consumer — a second copy of
|
|
6
|
+
* this keyset logic is exactly how the two ends drift into disagreeing about
|
|
7
|
+
* what a cursor means.
|
|
8
|
+
*
|
|
9
|
+
* ORDERING CONTRACT, measured against the live deployment rather than assumed:
|
|
10
|
+
* a page carries the NEWEST `limit` comments in ASCENDING display order, so the
|
|
11
|
+
* newest comment is the LAST element. `next_cursor` encodes the FIRST (oldest)
|
|
12
|
+
* element of the page, and walking it moves toward OLDER history.
|
|
13
|
+
*/
|
|
14
|
+
export interface CommentCursor {
|
|
15
|
+
created_at: string;
|
|
16
|
+
id: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const MAX_COMMENT_CURSOR_LENGTH = 1024;
|
|
19
|
+
export declare function encodeCommentCursor(comment: Pick<TaskComment, "created_at" | "id">): string;
|
|
20
|
+
export declare function decodeCommentCursor(value: string): CommentCursor;
|
|
21
|
+
/** True when `comment` sorts strictly before `before` on the `(created_at, id)` keyset. */
|
|
22
|
+
export declare function isStrictlyOlder(comment: Pick<TaskComment, "created_at" | "id">, before: CommentCursor): boolean;
|
|
23
|
+
export interface CommentPageResult<T> {
|
|
24
|
+
comments: T[];
|
|
25
|
+
count: number;
|
|
26
|
+
has_more: boolean;
|
|
27
|
+
next_cursor: string | null;
|
|
28
|
+
limit: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Page an already-materialised, ascending comment list. Used by the local
|
|
32
|
+
* (SQLite) read path, where the whole history is in hand; the cloud path gets
|
|
33
|
+
* the identical shape from the server, which applies the same rule against the
|
|
34
|
+
* database.
|
|
35
|
+
*/
|
|
36
|
+
export declare function pageComments<T extends Pick<TaskComment, "created_at" | "id">>(all: readonly T[], options: {
|
|
37
|
+
limit: number;
|
|
38
|
+
before?: CommentCursor;
|
|
39
|
+
}): CommentPageResult<T>;
|
|
40
|
+
//# sourceMappingURL=comment-cursor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-cursor.d.ts","sourceRoot":"","sources":["../../src/lib/comment-cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,yBAAyB,OAAQ,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC,GAAG,MAAM,CAG3F;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAgBhE;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC,EAC/C,MAAM,EAAE,aAAa,GACpB,OAAO,CAGT;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI,CAAC,EAC3E,GAAG,EAAE,SAAS,CAAC,EAAE,EACjB,OAAO,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,GACjD,iBAAiB,CAAC,CAAC,CAAC,CAetB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface DelegationBriefInput {
|
|
2
|
+
/** `--brief <path>`; the literal `-` means stdin. */
|
|
3
|
+
briefPath?: string | undefined;
|
|
4
|
+
/** `--brief-text <text>`. Mutually exclusive with {@link briefPath}. */
|
|
5
|
+
briefText?: string | undefined;
|
|
6
|
+
}
|
|
7
|
+
/** The two reads the gate needs, injected so every branch is testable. */
|
|
8
|
+
export interface DelegationBriefSources {
|
|
9
|
+
/** Reads a file as utf8; THROWS when the path cannot be read. */
|
|
10
|
+
readFile(path: string): string;
|
|
11
|
+
/** Reads stdin to end as utf8. */
|
|
12
|
+
readStdin(): string;
|
|
13
|
+
}
|
|
14
|
+
export type DelegationBriefRefusal = "missing" | "conflict" | "unreadable" | "empty";
|
|
15
|
+
export type DelegationBriefVerdict = {
|
|
16
|
+
ok: true;
|
|
17
|
+
/** The brief exactly as read — never trimmed. */
|
|
18
|
+
text: string;
|
|
19
|
+
/** Where it came from, for the [DISPATCH] record: a path, `(stdin)`, or `(--brief-text)`. */
|
|
20
|
+
source: string;
|
|
21
|
+
/** sha256 of the utf8 bytes of {@link text}. */
|
|
22
|
+
sha256: string;
|
|
23
|
+
/** Byte length of {@link text}. */
|
|
24
|
+
bytes: number;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
reason: DelegationBriefRefusal;
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
export declare function resolveDelegationBrief(input: DelegationBriefInput, sources: DelegationBriefSources): DelegationBriefVerdict;
|
|
31
|
+
//# sourceMappingURL=delegation-brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-brief.d.ts","sourceRoot":"","sources":["../../src/lib/delegation-brief.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,oBAAoB;IACnC,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC/B,kCAAkC;IAClC,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;AAErF,MAAM,MAAM,sBAAsB,GAC9B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,6FAA6F;IAC7F,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,sBAAsB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAInE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,EAAE,sBAAsB,GAC9B,sBAAsB,CA6ExB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare function defaultDelegationEmbargoPath(): string;
|
|
2
|
+
/**
|
|
3
|
+
* Normalised names that must not receive a delegation.
|
|
4
|
+
*
|
|
5
|
+
* Accepts either `{ "embargoed": ["name", ...] }` or a bare array, and tolerates
|
|
6
|
+
* entries shaped `{ "slug": "name" }` so the file can carry a reason alongside
|
|
7
|
+
* each name without the reader needing a schema version.
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadDelegationEmbargo(path?: string): Set<string>;
|
|
10
|
+
export interface DelegationDepthThreshold {
|
|
11
|
+
/** `null` means no threshold is armed: report the count, never park. */
|
|
12
|
+
value: number | null;
|
|
13
|
+
source: "flag" | "env" | "unset";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the open-task count above which a delegation parks.
|
|
17
|
+
*
|
|
18
|
+
* THE DEFAULT IS DELIBERATELY UNSET, and this is the clause with a cost
|
|
19
|
+
* attached. Seat queues on this fleet were measured at 190 open rows, so any
|
|
20
|
+
* plausible shipped number would park essentially every delegation — and a gate
|
|
21
|
+
* that fires on every invocation is one operators learn to type past, which
|
|
22
|
+
* converts a real signal into a formality. What the step is actually worth is
|
|
23
|
+
* the PRINTED NUMBER and the RECORDED OVERRIDE, and those are delivered
|
|
24
|
+
* unconditionally.
|
|
25
|
+
*
|
|
26
|
+
* So parking is opt-in until per-seat data justifies a number, and the number
|
|
27
|
+
* lives in configuration rather than in a release when it does.
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveDelegationDepthThreshold(flagValue?: string | number | undefined): DelegationDepthThreshold;
|
|
30
|
+
/** Minutes a dispatched row may sit unclaimed before the steering pass owns it. */
|
|
31
|
+
export declare const DEFAULT_CLAIM_WINDOW_MINUTES = 30;
|
|
32
|
+
//# sourceMappingURL=delegation-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-policy.d.ts","sourceRoot":"","sources":["../../src/lib/delegation-policy.ts"],"names":[],"mappings":"AA8BA,wBAAgB,4BAA4B,IAAI,MAAM,CAKrD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,GAAE,MAAuC,GAAG,GAAG,CAAC,MAAM,CAAC,CAiBhG;AAED,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;CAClC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,wBAAwB,CAQjH;AASD,mFAAmF;AACnF,eAAO,MAAM,4BAA4B,KAAK,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `[DISPATCH]` record, and the one-line channel notice.
|
|
3
|
+
*
|
|
4
|
+
* These are separated from the command so the exact text is testable without
|
|
5
|
+
* spawning a CLI, and so the record's SHAPE is a decision made once rather than
|
|
6
|
+
* a template string buried in an action handler.
|
|
7
|
+
*
|
|
8
|
+
* WHY NOT `lib/dispatch-formatter.ts`, which already exists and already formats
|
|
9
|
+
* a dispatch: that module builds a HUMAN PROMPT to be typed into a tmux pane —
|
|
10
|
+
* it is the message body of the legacy `dispatch` verb. This builds a
|
|
11
|
+
* MACHINE-GREPPABLE AUDIT LINE that lands in a task comment. Bending the
|
|
12
|
+
* existing formatter to do both would couple the record this verb is measured
|
|
13
|
+
* by to the message format of the verb it replaces.
|
|
14
|
+
*
|
|
15
|
+
* The first line is a fixed, anchored marker because the terminal-state
|
|
16
|
+
* counters read it: N1 counts directive-cited rows with NO `[DISPATCH]`
|
|
17
|
+
* comment, and N2 counts `[DISPATCH]` comments older than the claim window
|
|
18
|
+
* whose row still has a null `started_at`. Both are greps, so the marker must
|
|
19
|
+
* be stable and must start the comment.
|
|
20
|
+
*/
|
|
21
|
+
export interface DelegationRecordInput {
|
|
22
|
+
taskId: string;
|
|
23
|
+
worker: string;
|
|
24
|
+
dispatcher: string;
|
|
25
|
+
runtime: string | null;
|
|
26
|
+
briefSource: string;
|
|
27
|
+
briefSha256: string;
|
|
28
|
+
briefBytes: number;
|
|
29
|
+
depth: number;
|
|
30
|
+
reportsTo: string;
|
|
31
|
+
seatSlug: string;
|
|
32
|
+
seatOpenTasks: number;
|
|
33
|
+
depthThreshold: number | null;
|
|
34
|
+
override: "despite-depth" | "owner-directive" | null;
|
|
35
|
+
identityOutcome: "created" | "reused" | "skipped";
|
|
36
|
+
dispatchedAt: string;
|
|
37
|
+
claimDeadline: string;
|
|
38
|
+
}
|
|
39
|
+
/** The marker every reader and counter greps for. Anchored at line start. */
|
|
40
|
+
export declare const DISPATCH_COMMENT_MARKER = "[DISPATCH]";
|
|
41
|
+
export declare function formatDispatchComment(input: DelegationRecordInput): string;
|
|
42
|
+
/**
|
|
43
|
+
* The channel notice. ONE line, because it goes to a shared channel that
|
|
44
|
+
* several seats read, and a multi-line dispatch log there is how a channel
|
|
45
|
+
* stops being read at all.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatDispatchNotice(input: DelegationRecordInput): string;
|
|
48
|
+
/** Dispatch time plus the claim window, as an ISO instant. */
|
|
49
|
+
export declare function claimDeadlineFrom(dispatchedAt: Date, windowMinutes: number): string;
|
|
50
|
+
//# sourceMappingURL=delegation-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-record.d.ts","sourceRoot":"","sources":["../../src/lib/delegation-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,eAAe,GAAG,iBAAiB,GAAG,IAAI,CAAC;IACrD,eAAe,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,eAAe,CAAC;AAEpD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAkB1E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAOzE;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-back verification for a delegation: did the authority ACTUALLY persist
|
|
3
|
+
* the lineage, or did it accept the patch and drop it?
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS IS NOT PARANOIA. `todos delegate` writes through
|
|
6
|
+
* `PATCH /v1/tasks/:id`, and the authority serving that route is a separately
|
|
7
|
+
* deployed build with its own release cadence. Before this change, NOTHING in
|
|
8
|
+
* the server or storage layer handled `assigned_by`, `delegated_from` or
|
|
9
|
+
* `delegation_depth` — the columns existed, were indexed, and had no write path
|
|
10
|
+
* — so any authority running an earlier build accepts the patch, returns 200
|
|
11
|
+
* with a bumped version, and writes none of the lineage.
|
|
12
|
+
*
|
|
13
|
+
* That produces the one failure shape this verb cannot afford: a successful
|
|
14
|
+
* exit code, a [DISPATCH] comment asserting a lineage, and a row that is
|
|
15
|
+
* indistinguishable from a plain `todos assign`. The whole claim of `delegate`
|
|
16
|
+
* over `assign` is the handover record; reporting one that was silently
|
|
17
|
+
* discarded is worse than not having the verb.
|
|
18
|
+
*
|
|
19
|
+
* So: `secrets exec` returning 0 means the command ran, not that the credential
|
|
20
|
+
* arrived — same shape. A 200 means the request was accepted, not that the
|
|
21
|
+
* field was stored. Verify the PROPERTY, not the CALL.
|
|
22
|
+
*
|
|
23
|
+
* Kept as a pure function over a plain row so both arms are testable without an
|
|
24
|
+
* old server to point at. A check that can only ever be observed passing is not
|
|
25
|
+
* evidence about anything.
|
|
26
|
+
*/
|
|
27
|
+
/** The subset of a task row this verification reads. */
|
|
28
|
+
export interface PersistedLineage {
|
|
29
|
+
assigned_to?: string | null;
|
|
30
|
+
assigned_by?: string | null;
|
|
31
|
+
delegated_from?: string | null;
|
|
32
|
+
delegation_depth?: number | null;
|
|
33
|
+
}
|
|
34
|
+
export interface ExpectedLineage {
|
|
35
|
+
assignedTo: string;
|
|
36
|
+
assignedBy: string;
|
|
37
|
+
delegatedFrom: string;
|
|
38
|
+
depth: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Field names the authority did not persist as asked. Empty means the handover
|
|
42
|
+
* is fully recorded.
|
|
43
|
+
*
|
|
44
|
+
* Names are compared case-insensitively: agent names are a case-INSENSITIVE
|
|
45
|
+
* identity across this codebase, so a server that canonicalises casing is
|
|
46
|
+
* behaving correctly and must not be reported as having dropped the field.
|
|
47
|
+
* Depth is compared exactly, and `0` is a legitimate value rather than absence
|
|
48
|
+
* — a truthiness test here would call every root dispatch a failure.
|
|
49
|
+
*/
|
|
50
|
+
export declare function missingDelegationLineage(persisted: PersistedLineage, expected: ExpectedLineage): string[];
|
|
51
|
+
/**
|
|
52
|
+
* The refusal text for a partial delegation. It names what DID land, so nobody
|
|
53
|
+
* re-runs blindly against a row that is already half-changed, and it names the
|
|
54
|
+
* real remedy rather than sending the reader to debug their connection.
|
|
55
|
+
*/
|
|
56
|
+
export declare function partialDelegationMessage(missing: readonly string[], taskId: string): string;
|
|
57
|
+
//# sourceMappingURL=delegation-verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delegation-verify.d.ts","sourceRoot":"","sources":["../../src/lib/delegation-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,wDAAwD;AACxD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,eAAe,GACxB,MAAM,EAAE,CAOV;AAMD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAS3F"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -13960,6 +13960,18 @@ function updateTask(id, input, db) {
|
|
|
13960
13960
|
sets.push("assigned_to = ?");
|
|
13961
13961
|
params.push(input.assigned_to);
|
|
13962
13962
|
}
|
|
13963
|
+
if (input.assigned_by !== undefined) {
|
|
13964
|
+
sets.push("assigned_by = ?");
|
|
13965
|
+
params.push(input.assigned_by);
|
|
13966
|
+
}
|
|
13967
|
+
if (input.delegated_from !== undefined) {
|
|
13968
|
+
sets.push("delegated_from = ?");
|
|
13969
|
+
params.push(input.delegated_from);
|
|
13970
|
+
}
|
|
13971
|
+
if (input.delegation_depth !== undefined) {
|
|
13972
|
+
sets.push("delegation_depth = ?");
|
|
13973
|
+
params.push(input.delegation_depth);
|
|
13974
|
+
}
|
|
13963
13975
|
if (input.working_dir !== undefined) {
|
|
13964
13976
|
sets.push("working_dir = ?");
|
|
13965
13977
|
params.push(input.working_dir);
|
|
@@ -34914,7 +34926,7 @@ var package_default;
|
|
|
34914
34926
|
var init_package = __esm(() => {
|
|
34915
34927
|
package_default = {
|
|
34916
34928
|
name: "@hasna/todos",
|
|
34917
|
-
version: "0.15.
|
|
34929
|
+
version: "0.15.6",
|
|
34918
34930
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
34919
34931
|
type: "module",
|
|
34920
34932
|
main: "dist/index.js",
|
|
@@ -50900,6 +50912,29 @@ var init_pr_groups = __esm(() => {
|
|
|
50900
50912
|
JSON_HEADERS = { "Content-Type": "application/json" };
|
|
50901
50913
|
});
|
|
50902
50914
|
|
|
50915
|
+
// src/lib/comment-cursor.ts
|
|
50916
|
+
function encodeCommentCursor(comment) {
|
|
50917
|
+
return Buffer.from(JSON.stringify({ created_at: comment.created_at, id: comment.id }), "utf8").toString("base64url");
|
|
50918
|
+
}
|
|
50919
|
+
function decodeCommentCursor(value) {
|
|
50920
|
+
if (value.length > MAX_COMMENT_CURSOR_LENGTH)
|
|
50921
|
+
throw new Error("invalid comment cursor");
|
|
50922
|
+
let parsed;
|
|
50923
|
+
try {
|
|
50924
|
+
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
50925
|
+
} catch {
|
|
50926
|
+
throw new Error("invalid comment cursor");
|
|
50927
|
+
}
|
|
50928
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
50929
|
+
throw new Error("invalid comment cursor");
|
|
50930
|
+
const cursor = parsed;
|
|
50931
|
+
if (typeof cursor["created_at"] !== "string" || cursor["created_at"].length > 64 || !Number.isFinite(Date.parse(cursor["created_at"])) || typeof cursor["id"] !== "string" || !cursor["id"] || cursor["id"].length > 256) {
|
|
50932
|
+
throw new Error("invalid comment cursor");
|
|
50933
|
+
}
|
|
50934
|
+
return { created_at: cursor["created_at"], id: cursor["id"] };
|
|
50935
|
+
}
|
|
50936
|
+
var MAX_COMMENT_CURSOR_LENGTH = 1024;
|
|
50937
|
+
|
|
50903
50938
|
// src/server/v1.ts
|
|
50904
50939
|
var exports_v1 = {};
|
|
50905
50940
|
__export(exports_v1, {
|
|
@@ -51189,26 +51224,6 @@ function contextFromPrincipal(principal, body) {
|
|
|
51189
51224
|
function redactComment3(comment) {
|
|
51190
51225
|
return { ...comment, content: redactEvidenceText(comment.content) };
|
|
51191
51226
|
}
|
|
51192
|
-
function encodeCommentCursor(comment) {
|
|
51193
|
-
return Buffer.from(JSON.stringify({ created_at: comment.created_at, id: comment.id }), "utf8").toString("base64url");
|
|
51194
|
-
}
|
|
51195
|
-
function decodeCommentCursor(value) {
|
|
51196
|
-
if (value.length > 1024)
|
|
51197
|
-
throw new Error("invalid comment cursor");
|
|
51198
|
-
let parsed;
|
|
51199
|
-
try {
|
|
51200
|
-
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
51201
|
-
} catch {
|
|
51202
|
-
throw new Error("invalid comment cursor");
|
|
51203
|
-
}
|
|
51204
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
51205
|
-
throw new Error("invalid comment cursor");
|
|
51206
|
-
const cursor = parsed;
|
|
51207
|
-
if (typeof cursor["created_at"] !== "string" || cursor["created_at"].length > 64 || !Number.isFinite(Date.parse(cursor["created_at"])) || typeof cursor["id"] !== "string" || !cursor["id"] || cursor["id"].length > 256) {
|
|
51208
|
-
throw new Error("invalid comment cursor");
|
|
51209
|
-
}
|
|
51210
|
-
return { created_at: cursor["created_at"], id: cursor["id"] };
|
|
51211
|
-
}
|
|
51212
51227
|
function normalizeImportSnapshot(raw) {
|
|
51213
51228
|
const body = raw && typeof raw === "object" ? raw : {};
|
|
51214
51229
|
const arr = (v) => Array.isArray(v) ? v : [];
|
package/dist/mcp.js
CHANGED
|
@@ -41,7 +41,7 @@ var __require = import.meta.require;
|
|
|
41
41
|
// package.json
|
|
42
42
|
var package_default = {
|
|
43
43
|
name: "@hasna/todos",
|
|
44
|
-
version: "0.15.
|
|
44
|
+
version: "0.15.6",
|
|
45
45
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
46
46
|
type: "module",
|
|
47
47
|
main: "dist/index.js",
|
package/dist/registry.js
CHANGED
|
@@ -9313,6 +9313,18 @@ function updateTask(id, input, db) {
|
|
|
9313
9313
|
sets.push("assigned_to = ?");
|
|
9314
9314
|
params.push(input.assigned_to);
|
|
9315
9315
|
}
|
|
9316
|
+
if (input.assigned_by !== undefined) {
|
|
9317
|
+
sets.push("assigned_by = ?");
|
|
9318
|
+
params.push(input.assigned_by);
|
|
9319
|
+
}
|
|
9320
|
+
if (input.delegated_from !== undefined) {
|
|
9321
|
+
sets.push("delegated_from = ?");
|
|
9322
|
+
params.push(input.delegated_from);
|
|
9323
|
+
}
|
|
9324
|
+
if (input.delegation_depth !== undefined) {
|
|
9325
|
+
sets.push("delegation_depth = ?");
|
|
9326
|
+
params.push(input.delegation_depth);
|
|
9327
|
+
}
|
|
9316
9328
|
if (input.working_dir !== undefined) {
|
|
9317
9329
|
sets.push("working_dir = ?");
|
|
9318
9330
|
params.push(input.working_dir);
|
|
@@ -12032,7 +12044,7 @@ var init_tasks = __esm(() => {
|
|
|
12032
12044
|
// package.json
|
|
12033
12045
|
var package_default = {
|
|
12034
12046
|
name: "@hasna/todos",
|
|
12035
|
-
version: "0.15.
|
|
12047
|
+
version: "0.15.6",
|
|
12036
12048
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
12037
12049
|
type: "module",
|
|
12038
12050
|
main: "dist/index.js",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "@hasna/todos",
|
|
3
|
-
"packageVersion": "0.15.
|
|
3
|
+
"packageVersion": "0.15.6",
|
|
4
4
|
"repository": "https://github.com/hasna/todos.git",
|
|
5
|
-
"gitCommit": "
|
|
6
|
-
"gitTree": "
|
|
7
|
-
"sourceTreeSha256": "
|
|
8
|
-
"generatedAt": "2026-08-
|
|
5
|
+
"gitCommit": "912706df4217032e0fa328b8e63c631cbd2dbaaa",
|
|
6
|
+
"gitTree": "55ffcbf22946c2823608bf05b7db8c77c3d1837f",
|
|
7
|
+
"sourceTreeSha256": "6d97deaa19cf1aca86ae5d2ac810239a96079987884dffad727762b91dbbe660",
|
|
8
|
+
"generatedAt": "2026-08-06T09:35:27.000Z"
|
|
9
9
|
}
|
package/dist/server/index.js
CHANGED
|
@@ -70,7 +70,7 @@ var package_default;
|
|
|
70
70
|
var init_package = __esm(() => {
|
|
71
71
|
package_default = {
|
|
72
72
|
name: "@hasna/todos",
|
|
73
|
-
version: "0.15.
|
|
73
|
+
version: "0.15.6",
|
|
74
74
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
75
75
|
type: "module",
|
|
76
76
|
main: "dist/index.js",
|
|
@@ -14223,6 +14223,18 @@ function updateTask2(id, input, db) {
|
|
|
14223
14223
|
sets.push("assigned_to = ?");
|
|
14224
14224
|
params.push(input.assigned_to);
|
|
14225
14225
|
}
|
|
14226
|
+
if (input.assigned_by !== undefined) {
|
|
14227
|
+
sets.push("assigned_by = ?");
|
|
14228
|
+
params.push(input.assigned_by);
|
|
14229
|
+
}
|
|
14230
|
+
if (input.delegated_from !== undefined) {
|
|
14231
|
+
sets.push("delegated_from = ?");
|
|
14232
|
+
params.push(input.delegated_from);
|
|
14233
|
+
}
|
|
14234
|
+
if (input.delegation_depth !== undefined) {
|
|
14235
|
+
sets.push("delegation_depth = ?");
|
|
14236
|
+
params.push(input.delegation_depth);
|
|
14237
|
+
}
|
|
14226
14238
|
if (input.working_dir !== undefined) {
|
|
14227
14239
|
sets.push("working_dir = ?");
|
|
14228
14240
|
params.push(input.working_dir);
|
|
@@ -22300,6 +22312,29 @@ var init_pr_groups = __esm(() => {
|
|
|
22300
22312
|
JSON_HEADERS = { "Content-Type": "application/json" };
|
|
22301
22313
|
});
|
|
22302
22314
|
|
|
22315
|
+
// src/lib/comment-cursor.ts
|
|
22316
|
+
function encodeCommentCursor(comment) {
|
|
22317
|
+
return Buffer.from(JSON.stringify({ created_at: comment.created_at, id: comment.id }), "utf8").toString("base64url");
|
|
22318
|
+
}
|
|
22319
|
+
function decodeCommentCursor(value) {
|
|
22320
|
+
if (value.length > MAX_COMMENT_CURSOR_LENGTH)
|
|
22321
|
+
throw new Error("invalid comment cursor");
|
|
22322
|
+
let parsed;
|
|
22323
|
+
try {
|
|
22324
|
+
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
22325
|
+
} catch {
|
|
22326
|
+
throw new Error("invalid comment cursor");
|
|
22327
|
+
}
|
|
22328
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
22329
|
+
throw new Error("invalid comment cursor");
|
|
22330
|
+
const cursor = parsed;
|
|
22331
|
+
if (typeof cursor["created_at"] !== "string" || cursor["created_at"].length > 64 || !Number.isFinite(Date.parse(cursor["created_at"])) || typeof cursor["id"] !== "string" || !cursor["id"] || cursor["id"].length > 256) {
|
|
22332
|
+
throw new Error("invalid comment cursor");
|
|
22333
|
+
}
|
|
22334
|
+
return { created_at: cursor["created_at"], id: cursor["id"] };
|
|
22335
|
+
}
|
|
22336
|
+
var MAX_COMMENT_CURSOR_LENGTH = 1024;
|
|
22337
|
+
|
|
22303
22338
|
// src/server/v1.ts
|
|
22304
22339
|
var exports_v1 = {};
|
|
22305
22340
|
__export(exports_v1, {
|
|
@@ -22589,26 +22624,6 @@ function contextFromPrincipal(principal, body) {
|
|
|
22589
22624
|
function redactComment2(comment) {
|
|
22590
22625
|
return { ...comment, content: redactEvidenceText(comment.content) };
|
|
22591
22626
|
}
|
|
22592
|
-
function encodeCommentCursor(comment) {
|
|
22593
|
-
return Buffer.from(JSON.stringify({ created_at: comment.created_at, id: comment.id }), "utf8").toString("base64url");
|
|
22594
|
-
}
|
|
22595
|
-
function decodeCommentCursor(value) {
|
|
22596
|
-
if (value.length > 1024)
|
|
22597
|
-
throw new Error("invalid comment cursor");
|
|
22598
|
-
let parsed;
|
|
22599
|
-
try {
|
|
22600
|
-
parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
22601
|
-
} catch {
|
|
22602
|
-
throw new Error("invalid comment cursor");
|
|
22603
|
-
}
|
|
22604
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
22605
|
-
throw new Error("invalid comment cursor");
|
|
22606
|
-
const cursor = parsed;
|
|
22607
|
-
if (typeof cursor["created_at"] !== "string" || cursor["created_at"].length > 64 || !Number.isFinite(Date.parse(cursor["created_at"])) || typeof cursor["id"] !== "string" || !cursor["id"] || cursor["id"].length > 256) {
|
|
22608
|
-
throw new Error("invalid comment cursor");
|
|
22609
|
-
}
|
|
22610
|
-
return { created_at: cursor["created_at"], id: cursor["id"] };
|
|
22611
|
-
}
|
|
22612
22627
|
function normalizeImportSnapshot(raw) {
|
|
22613
22628
|
const body = raw && typeof raw === "object" ? raw : {};
|
|
22614
22629
|
const arr = (v) => Array.isArray(v) ? v : [];
|
package/dist/server/v1.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAuB,oBAAoB,EAAmD,MAAM,0BAA0B,CAAC;AAC3I,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"v1.d.ts","sourceRoot":"","sources":["../../src/server/v1.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAuB,oBAAoB,EAAmD,MAAM,0BAA0B,CAAC;AAC3I,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMhH,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACtC,YAAY,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACxC,iBAAiB,CAAC,EAAE,OAAO,sBAAsB,CAAC;IAClD,gBAAgB,CAAC,EAAE,OAAO,qBAAqB,CAAC;CACjD;AAuSD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAiB1E;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAapE;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,YAAY,GAAE,qBAA0B,GACvC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAu6B1B"}
|
package/dist/storage.js
CHANGED
|
@@ -9313,6 +9313,18 @@ function updateTask(id, input, db) {
|
|
|
9313
9313
|
sets.push("assigned_to = ?");
|
|
9314
9314
|
params.push(input.assigned_to);
|
|
9315
9315
|
}
|
|
9316
|
+
if (input.assigned_by !== undefined) {
|
|
9317
|
+
sets.push("assigned_by = ?");
|
|
9318
|
+
params.push(input.assigned_by);
|
|
9319
|
+
}
|
|
9320
|
+
if (input.delegated_from !== undefined) {
|
|
9321
|
+
sets.push("delegated_from = ?");
|
|
9322
|
+
params.push(input.delegated_from);
|
|
9323
|
+
}
|
|
9324
|
+
if (input.delegation_depth !== undefined) {
|
|
9325
|
+
sets.push("delegation_depth = ?");
|
|
9326
|
+
params.push(input.delegation_depth);
|
|
9327
|
+
}
|
|
9316
9328
|
if (input.working_dir !== undefined) {
|
|
9317
9329
|
sets.push("working_dir = ?");
|
|
9318
9330
|
params.push(input.working_dir);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -562,6 +562,24 @@ export interface UpdateTaskInput {
|
|
|
562
562
|
requires_approval?: boolean;
|
|
563
563
|
approved_by?: string;
|
|
564
564
|
recurrence_rule?: string | null;
|
|
565
|
+
/**
|
|
566
|
+
* Who handed this row over. Stamped at creation from `agent_id` and, until
|
|
567
|
+
* `todos delegate`, WRITE-ONCE by omission rather than by design — there was
|
|
568
|
+
* no update branch, so a task filed by one agent and later dispatched by
|
|
569
|
+
* another kept naming the filer. Distinct from `agent_id` (who owns the row)
|
|
570
|
+
* and `created_by` (who filed it, which stays write-once).
|
|
571
|
+
*/
|
|
572
|
+
assigned_by?: string | null;
|
|
573
|
+
/**
|
|
574
|
+
* The parent in the delegation chain. Column present since migration 520 and
|
|
575
|
+
* hardcoded to `null` at every creation site, so nothing could ever set it.
|
|
576
|
+
*/
|
|
577
|
+
delegated_from?: string | null;
|
|
578
|
+
/**
|
|
579
|
+
* How deep this row sits in the delegation chain. Column present since
|
|
580
|
+
* migration 521 and hardcoded to `0` at every creation site.
|
|
581
|
+
*/
|
|
582
|
+
delegation_depth?: number;
|
|
565
583
|
version: number;
|
|
566
584
|
task_type?: string | null;
|
|
567
585
|
}
|