@hasna/todos 0.13.6 → 0.13.8
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/assignee-guard.d.ts +13 -0
- package/dist/cli/assignee-guard.d.ts.map +1 -0
- package/dist/cli/claim-guard.d.ts +3 -0
- package/dist/cli/claim-guard.d.ts.map +1 -0
- package/dist/cli/commands/query-commands.d.ts.map +1 -1
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/index.js +3299 -3076
- package/dist/contracts.js +81 -29
- package/dist/db/task-crud.d.ts.map +1 -1
- package/dist/db/task-lifecycle.d.ts.map +1 -1
- package/dist/index.js +114 -58
- package/dist/lib/agent-tasks.d.ts.map +1 -1
- package/dist/lib/assignee-context.d.ts +40 -0
- package/dist/lib/assignee-context.d.ts.map +1 -0
- package/dist/lib/assignee-validation.d.ts +72 -0
- package/dist/lib/assignee-validation.d.ts.map +1 -0
- package/dist/lib/claude-tasks.d.ts.map +1 -1
- package/dist/lib/creator-identity.d.ts +30 -0
- package/dist/lib/creator-identity.d.ts.map +1 -1
- package/dist/lib/sync-utils.d.ts +7 -0
- package/dist/lib/sync-utils.d.ts.map +1 -1
- package/dist/mcp/index.js +245 -112
- package/dist/mcp/tools/task-crud.d.ts.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/registry.js +81 -29
- package/dist/release-provenance.json +5 -5
- package/dist/server/index.js +249 -116
- package/dist/storage.js +66 -14
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"task-crud.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-crud.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"task-crud.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/task-crud.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAoBjD,UAAU,eAAe;IACvB,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACzD,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;IACnC,gBAAgB,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACvE,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAC3F;AAuBD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,eAAe,QAkY5E"}
|
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.13.
|
|
44
|
+
version: "0.13.8",
|
|
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
|
@@ -4336,6 +4336,7 @@ var init_database = __esm(() => {
|
|
|
4336
4336
|
|
|
4337
4337
|
// src/lib/sync-utils.ts
|
|
4338
4338
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync, readdirSync, statSync, writeFileSync } from "fs";
|
|
4339
|
+
import { createHash } from "crypto";
|
|
4339
4340
|
import { join as join2 } from "path";
|
|
4340
4341
|
function getHomeDir() {
|
|
4341
4342
|
return process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
@@ -4391,7 +4392,40 @@ function appendSyncConflict(metadata, conflict, limit = 5) {
|
|
|
4391
4392
|
const next = [conflict, ...current].slice(0, limit);
|
|
4392
4393
|
return { ...metadata, sync_conflicts: next };
|
|
4393
4394
|
}
|
|
4394
|
-
|
|
4395
|
+
function canonicalize(value) {
|
|
4396
|
+
if (Array.isArray(value))
|
|
4397
|
+
return value.map(canonicalize);
|
|
4398
|
+
if (!value || typeof value !== "object")
|
|
4399
|
+
return value;
|
|
4400
|
+
const entries = Object.entries(value).filter(([, entryValue]) => entryValue !== undefined).sort(([a], [b]) => a.localeCompare(b));
|
|
4401
|
+
return Object.fromEntries(entries.map(([key, entryValue]) => [key, canonicalize(entryValue)]));
|
|
4402
|
+
}
|
|
4403
|
+
function withoutSyncFingerprintMetadata(metadata) {
|
|
4404
|
+
const { [TODO_SYNC_FINGERPRINT_KEY]: _fingerprint, ...rest } = metadata;
|
|
4405
|
+
return rest;
|
|
4406
|
+
}
|
|
4407
|
+
function syncFingerprint(record) {
|
|
4408
|
+
const metadata = withoutSyncFingerprintMetadata(record.metadata || {});
|
|
4409
|
+
const canonical = canonicalize({ ...record, metadata });
|
|
4410
|
+
return `sha256:${createHash("sha256").update(JSON.stringify(canonical)).digest("hex")}`;
|
|
4411
|
+
}
|
|
4412
|
+
function withSyncFingerprint(record) {
|
|
4413
|
+
const metadata = withoutSyncFingerprintMetadata(record.metadata);
|
|
4414
|
+
return {
|
|
4415
|
+
...record,
|
|
4416
|
+
metadata: {
|
|
4417
|
+
...metadata,
|
|
4418
|
+
[TODO_SYNC_FINGERPRINT_KEY]: syncFingerprint({ ...record, metadata })
|
|
4419
|
+
}
|
|
4420
|
+
};
|
|
4421
|
+
}
|
|
4422
|
+
function hasSyncFingerprintChanged(record) {
|
|
4423
|
+
const stored = record.metadata?.[TODO_SYNC_FINGERPRINT_KEY];
|
|
4424
|
+
if (typeof stored !== "string" || stored.length === 0)
|
|
4425
|
+
return null;
|
|
4426
|
+
return stored !== syncFingerprint(record);
|
|
4427
|
+
}
|
|
4428
|
+
var TODO_SYNC_FINGERPRINT_KEY = "todos_sync_fingerprint", HOME;
|
|
4395
4429
|
var init_sync_utils = __esm(() => {
|
|
4396
4430
|
HOME = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
4397
4431
|
});
|
|
@@ -5502,7 +5536,7 @@ var init_runner_sandbox = __esm(() => {
|
|
|
5502
5536
|
});
|
|
5503
5537
|
|
|
5504
5538
|
// src/lib/event-hooks.ts
|
|
5505
|
-
import { createHash, randomUUID } from "crypto";
|
|
5539
|
+
import { createHash as createHash2, randomUUID } from "crypto";
|
|
5506
5540
|
import { appendFileSync, mkdirSync as mkdirSync3 } from "fs";
|
|
5507
5541
|
import { dirname as dirname3, resolve as resolve6 } from "path";
|
|
5508
5542
|
import { createConnection } from "net";
|
|
@@ -5569,7 +5603,7 @@ function buildEnvelope(type, payload, timestamp2 = new Date().toISOString()) {
|
|
|
5569
5603
|
payload: redactValue(payload ?? {}),
|
|
5570
5604
|
source: { package: "@hasna/todos", local_only: true }
|
|
5571
5605
|
};
|
|
5572
|
-
const digest =
|
|
5606
|
+
const digest = createHash2("sha256").update(canonicalEvent(base)).digest("hex");
|
|
5573
5607
|
return { ...base, integrity: { algorithm: "sha256", digest } };
|
|
5574
5608
|
}
|
|
5575
5609
|
function summarize(value) {
|
|
@@ -7479,6 +7513,14 @@ var init_checklists = __esm(() => {
|
|
|
7479
7513
|
init_database();
|
|
7480
7514
|
});
|
|
7481
7515
|
|
|
7516
|
+
// src/lib/creator-identity.ts
|
|
7517
|
+
function canonicalAgentRef(value) {
|
|
7518
|
+
return value.trim().toLowerCase();
|
|
7519
|
+
}
|
|
7520
|
+
var init_creator_identity = __esm(() => {
|
|
7521
|
+
init_sync_utils();
|
|
7522
|
+
});
|
|
7523
|
+
|
|
7482
7524
|
// src/lib/recurrence.ts
|
|
7483
7525
|
function parseRecurrenceRule(rule) {
|
|
7484
7526
|
const normalized = rule.trim().toLowerCase();
|
|
@@ -8185,6 +8227,11 @@ __export(exports_task_lifecycle, {
|
|
|
8185
8227
|
claimOrSteal: () => claimOrSteal,
|
|
8186
8228
|
claimNextTask: () => claimNextTask
|
|
8187
8229
|
});
|
|
8230
|
+
function sameHolder(stored, incoming) {
|
|
8231
|
+
if (!stored || !incoming)
|
|
8232
|
+
return false;
|
|
8233
|
+
return canonicalAgentRef(stored) === canonicalAgentRef(incoming);
|
|
8234
|
+
}
|
|
8188
8235
|
function lockExpiresAt(lockedAt) {
|
|
8189
8236
|
if (!lockedAt)
|
|
8190
8237
|
return null;
|
|
@@ -8235,13 +8282,13 @@ function startTask(id, agentId, db) {
|
|
|
8235
8282
|
const cutoff = lockExpiryCutoff();
|
|
8236
8283
|
const timestamp2 = now();
|
|
8237
8284
|
const result = d.run(`UPDATE tasks SET status = 'in_progress', assigned_to = ?, locked_by = ?, locked_at = ?, started_at = COALESCE(started_at, ?), version = version + 1, updated_at = ?
|
|
8238
|
-
WHERE id = ? AND status IN ('pending', 'in_progress') AND (locked_by IS NULL OR locked_by = ? OR locked_at < ?)`, [agentId, agentId, timestamp2, timestamp2, timestamp2, id, agentId, cutoff]);
|
|
8285
|
+
WHERE id = ? AND status IN ('pending', 'in_progress') AND (locked_by IS NULL OR LOWER(TRIM(locked_by)) = LOWER(TRIM(?)) OR locked_at < ?)`, [agentId, agentId, timestamp2, timestamp2, timestamp2, id, agentId, cutoff]);
|
|
8239
8286
|
if (result.changes === 0) {
|
|
8240
8287
|
const current = getTask(id, d);
|
|
8241
8288
|
if (!current)
|
|
8242
8289
|
throw new TaskNotFoundError(id);
|
|
8243
8290
|
assertStartable(current, agentId);
|
|
8244
|
-
if (current.locked_by && current.locked_by
|
|
8291
|
+
if (current.locked_by && !sameHolder(current.locked_by, agentId) && !isLockExpired(current.locked_at)) {
|
|
8245
8292
|
throw new LockError(id, current.locked_by);
|
|
8246
8293
|
}
|
|
8247
8294
|
throw new Error(`Task ${id} could not be started because it changed during claim`);
|
|
@@ -8266,7 +8313,7 @@ function completeTask(id, agentId, db, options) {
|
|
|
8266
8313
|
if (task.status === "cancelled") {
|
|
8267
8314
|
throw new Error(`Task ${id} is cancelled and cannot be completed`);
|
|
8268
8315
|
}
|
|
8269
|
-
if (agentId && task.locked_by && task.locked_by
|
|
8316
|
+
if (agentId && task.locked_by && !sameHolder(task.locked_by, agentId) && !isLockExpired(task.locked_at)) {
|
|
8270
8317
|
throw new LockError(id, task.locked_by);
|
|
8271
8318
|
}
|
|
8272
8319
|
checkCompletionGuard(task, agentId || null, d);
|
|
@@ -8388,16 +8435,16 @@ function lockTask(id, agentId, db) {
|
|
|
8388
8435
|
error: `Task is ${task.status} and cannot be locked`
|
|
8389
8436
|
};
|
|
8390
8437
|
}
|
|
8391
|
-
if (task.locked_by
|
|
8438
|
+
if (sameHolder(task.locked_by, agentId) && !isLockExpired(task.locked_at)) {
|
|
8392
8439
|
const timestamp3 = now();
|
|
8393
|
-
d.run(`UPDATE tasks SET locked_at = ?, updated_at = ?, version = version + 1 WHERE id = ? AND locked_by =
|
|
8440
|
+
d.run(`UPDATE tasks SET locked_at = ?, updated_at = ?, version = version + 1 WHERE id = ? AND LOWER(TRIM(locked_by)) = LOWER(TRIM(?))`, [timestamp3, timestamp3, id, agentId]);
|
|
8394
8441
|
logTaskChange(id, "lock_renew", "locked_by", agentId, agentId, agentId, d);
|
|
8395
8442
|
return { success: true, locked_by: agentId, locked_at: timestamp3, expires_at: lockExpiresAt(timestamp3) };
|
|
8396
8443
|
}
|
|
8397
8444
|
const cutoff = lockExpiryCutoff();
|
|
8398
8445
|
const timestamp2 = now();
|
|
8399
8446
|
const result = d.run(`UPDATE tasks SET locked_by = ?, locked_at = ?, version = version + 1, updated_at = ?
|
|
8400
|
-
WHERE id = ? AND status NOT IN ('completed', 'cancelled') AND (locked_by IS NULL OR locked_by = ? OR locked_at < ?)`, [agentId, timestamp2, timestamp2, id, agentId, cutoff]);
|
|
8447
|
+
WHERE id = ? AND status NOT IN ('completed', 'cancelled') AND (locked_by IS NULL OR LOWER(TRIM(locked_by)) = LOWER(TRIM(?)) OR locked_at < ?)`, [agentId, timestamp2, timestamp2, id, agentId, cutoff]);
|
|
8401
8448
|
if (result.changes === 0) {
|
|
8402
8449
|
const current = getTask(id, d);
|
|
8403
8450
|
if (!current)
|
|
@@ -8429,7 +8476,7 @@ function unlockTask(id, agentId, db) {
|
|
|
8429
8476
|
const task = getTask(id, d);
|
|
8430
8477
|
if (!task)
|
|
8431
8478
|
throw new TaskNotFoundError(id);
|
|
8432
|
-
if (agentId && task.locked_by && task.locked_by
|
|
8479
|
+
if (agentId && task.locked_by && !sameHolder(task.locked_by, agentId)) {
|
|
8433
8480
|
throw new LockError(id, task.locked_by);
|
|
8434
8481
|
}
|
|
8435
8482
|
const timestamp2 = now();
|
|
@@ -8722,6 +8769,7 @@ var MAX_SPAWN_DEPTH = 10;
|
|
|
8722
8769
|
var init_task_lifecycle = __esm(() => {
|
|
8723
8770
|
init_types();
|
|
8724
8771
|
init_database();
|
|
8772
|
+
init_creator_identity();
|
|
8725
8773
|
init_completion_guard();
|
|
8726
8774
|
init_event_emission_safety();
|
|
8727
8775
|
init_event_hooks();
|
|
@@ -9177,6 +9225,10 @@ function updateTask(id, input, db) {
|
|
|
9177
9225
|
sets.push("description = ?");
|
|
9178
9226
|
params.push(input.description);
|
|
9179
9227
|
}
|
|
9228
|
+
if (input.agent_id !== undefined) {
|
|
9229
|
+
sets.push("agent_id = ?");
|
|
9230
|
+
params.push(input.agent_id);
|
|
9231
|
+
}
|
|
9180
9232
|
if (input.status !== undefined) {
|
|
9181
9233
|
if (input.status === "completed") {
|
|
9182
9234
|
checkCompletionGuard(task, task.assigned_to || task.agent_id || null, d);
|
|
@@ -10486,7 +10538,7 @@ var init_boards = __esm(() => {
|
|
|
10486
10538
|
});
|
|
10487
10539
|
|
|
10488
10540
|
// src/lib/artifact-store.ts
|
|
10489
|
-
import { createHash as
|
|
10541
|
+
import { createHash as createHash3 } from "crypto";
|
|
10490
10542
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync3, rmSync, statSync as statSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
10491
10543
|
import { basename, dirname as dirname4, join as join5, resolve as resolve7 } from "path";
|
|
10492
10544
|
import { tmpdir as tmpdir2 } from "os";
|
|
@@ -10511,7 +10563,7 @@ function artifactStorePath(relativePath) {
|
|
|
10511
10563
|
return join5(artifactStoreRoot(), normalized);
|
|
10512
10564
|
}
|
|
10513
10565
|
function sha256(buffer) {
|
|
10514
|
-
return
|
|
10566
|
+
return createHash3("sha256").update(buffer).digest("hex");
|
|
10515
10567
|
}
|
|
10516
10568
|
function isTextLike(buffer, path) {
|
|
10517
10569
|
if (buffer.includes(0))
|
|
@@ -11921,7 +11973,7 @@ var init_tasks = __esm(() => {
|
|
|
11921
11973
|
// package.json
|
|
11922
11974
|
var package_default = {
|
|
11923
11975
|
name: "@hasna/todos",
|
|
11924
|
-
version: "0.13.
|
|
11976
|
+
version: "0.13.8",
|
|
11925
11977
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
11926
11978
|
type: "module",
|
|
11927
11979
|
main: "dist/index.js",
|
|
@@ -15636,7 +15688,7 @@ function importOnboardingFixture(options = {}) {
|
|
|
15636
15688
|
}
|
|
15637
15689
|
// src/lib/local-backups.ts
|
|
15638
15690
|
init_database();
|
|
15639
|
-
import { createHash as
|
|
15691
|
+
import { createHash as createHash4 } from "crypto";
|
|
15640
15692
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
15641
15693
|
import { dirname as dirname5, resolve as resolve8 } from "path";
|
|
15642
15694
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
@@ -15654,7 +15706,7 @@ function stableJson(value) {
|
|
|
15654
15706
|
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableJson(record[key])}`).join(",")}}`;
|
|
15655
15707
|
}
|
|
15656
15708
|
function sha2562(value) {
|
|
15657
|
-
return
|
|
15709
|
+
return createHash4("sha256").update(stableJson(value)).digest("hex");
|
|
15658
15710
|
}
|
|
15659
15711
|
function sqliteIntegrity(db) {
|
|
15660
15712
|
let quick = "unknown";
|
|
@@ -15932,7 +15984,7 @@ function checkLocalIntegrity(options = {}, db) {
|
|
|
15932
15984
|
}
|
|
15933
15985
|
// src/lib/local-snapshots.ts
|
|
15934
15986
|
init_database();
|
|
15935
|
-
import { createHash as
|
|
15987
|
+
import { createHash as createHash5 } from "crypto";
|
|
15936
15988
|
|
|
15937
15989
|
// src/lib/activity-timeline.ts
|
|
15938
15990
|
init_database();
|
|
@@ -16208,7 +16260,7 @@ function stable(value) {
|
|
|
16208
16260
|
return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => [key, stable(item)]));
|
|
16209
16261
|
}
|
|
16210
16262
|
function sha2563(value) {
|
|
16211
|
-
return
|
|
16263
|
+
return createHash5("sha256").update(JSON.stringify(stable(value))).digest("hex");
|
|
16212
16264
|
}
|
|
16213
16265
|
function latestTimestamp(items, fallback) {
|
|
16214
16266
|
const timestamps = [];
|
|
@@ -19420,20 +19472,20 @@ init_database();
|
|
|
19420
19472
|
init_task_runs();
|
|
19421
19473
|
init_config2();
|
|
19422
19474
|
init_redaction();
|
|
19423
|
-
import { createHash as
|
|
19475
|
+
import { createHash as createHash6 } from "crypto";
|
|
19424
19476
|
var LOCAL_AUDIT_LEDGER_SCHEMA_VERSION = 1;
|
|
19425
19477
|
var LOCAL_AUDIT_LEDGER_HASH_ALGORITHM = "sha256";
|
|
19426
19478
|
var LOCAL_AUDIT_LEDGER_INITIAL_HASH = "0".repeat(64);
|
|
19427
|
-
function
|
|
19479
|
+
function canonicalize2(value) {
|
|
19428
19480
|
if (value === null || typeof value !== "object")
|
|
19429
19481
|
return JSON.stringify(value);
|
|
19430
19482
|
if (Array.isArray(value))
|
|
19431
|
-
return `[${value.map(
|
|
19483
|
+
return `[${value.map(canonicalize2).join(",")}]`;
|
|
19432
19484
|
const object = value;
|
|
19433
|
-
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${
|
|
19485
|
+
return `{${Object.keys(object).sort().map((key) => `${JSON.stringify(key)}:${canonicalize2(object[key])}`).join(",")}}`;
|
|
19434
19486
|
}
|
|
19435
19487
|
function hash(value) {
|
|
19436
|
-
return
|
|
19488
|
+
return createHash6("sha256").update(value).digest("hex");
|
|
19437
19489
|
}
|
|
19438
19490
|
function parsePayload2(value) {
|
|
19439
19491
|
if (!value)
|
|
@@ -19566,7 +19618,7 @@ function toLedgerEntries(rows) {
|
|
|
19566
19618
|
let previous = LOCAL_AUDIT_LEDGER_INITIAL_HASH;
|
|
19567
19619
|
return ordered.map((row, index) => {
|
|
19568
19620
|
const payload = parsePayload2(row.payload_json);
|
|
19569
|
-
const payloadHash = hash(
|
|
19621
|
+
const payloadHash = hash(canonicalize2({ source: row.source, source_id: row.source_id, created_at: row.created_at, payload }));
|
|
19570
19622
|
const chainHash = hash(`${previous}
|
|
19571
19623
|
${payloadHash}`);
|
|
19572
19624
|
const entry = {
|
|
@@ -19953,7 +20005,7 @@ function renderReleaseCompatibilityMarkdown(report) {
|
|
|
19953
20005
|
`);
|
|
19954
20006
|
}
|
|
19955
20007
|
// src/db/inbox.ts
|
|
19956
|
-
import { createHash as
|
|
20008
|
+
import { createHash as createHash7 } from "crypto";
|
|
19957
20009
|
|
|
19958
20010
|
// src/lib/github.ts
|
|
19959
20011
|
import { execFileSync } from "child_process";
|
|
@@ -20038,7 +20090,7 @@ function compactWhitespace(value) {
|
|
|
20038
20090
|
function fingerprintInboxInput(input) {
|
|
20039
20091
|
const sourceType = input.source_type || detectInboxSourceType(input.body, input.source_url);
|
|
20040
20092
|
const normalized = compactWhitespace(sanitizePreWriteText(input.body, "inbox.fingerprint")).slice(0, 8000);
|
|
20041
|
-
return
|
|
20093
|
+
return createHash7("sha256").update(`${sourceType}
|
|
20042
20094
|
${input.source_url || ""}
|
|
20043
20095
|
${normalized}`).digest("hex");
|
|
20044
20096
|
}
|
|
@@ -21155,7 +21207,7 @@ function importExternalIssues(input, db) {
|
|
|
21155
21207
|
init_database();
|
|
21156
21208
|
init_tasks();
|
|
21157
21209
|
init_redaction();
|
|
21158
|
-
import { createHash as
|
|
21210
|
+
import { createHash as createHash8 } from "crypto";
|
|
21159
21211
|
var TESTERS_ISSUE_REPORT_SCHEMA_VERSION = "testers.issue_report.v1";
|
|
21160
21212
|
var TESTERS_ISSUE_REPORT_RESULT_SCHEMA_VERSION = "todos.tester_issue_report_result.v1";
|
|
21161
21213
|
var TESTERS_ISSUE_REPORT_BATCH_RESULT_SCHEMA_VERSION = "todos.tester_issue_report_batch_result.v1";
|
|
@@ -21344,7 +21396,7 @@ function fingerprintTesterIssueReport(report) {
|
|
|
21344
21396
|
normalizeText2(report.failure?.message || report.summary || report.title).slice(0, 240),
|
|
21345
21397
|
normalizeText2(stackTop).slice(0, 160)
|
|
21346
21398
|
].join("::");
|
|
21347
|
-
return `testers:${
|
|
21399
|
+
return `testers:${createHash8("sha256").update(raw).digest("hex").slice(0, 16)}`;
|
|
21348
21400
|
}
|
|
21349
21401
|
function priorityForSeverity(severity, fallback) {
|
|
21350
21402
|
return PRIORITIES3.includes(severity) ? severity : fallback;
|
|
@@ -22796,7 +22848,7 @@ function renderLocalReportMarkdown(report) {
|
|
|
22796
22848
|
init_config2();
|
|
22797
22849
|
init_redaction();
|
|
22798
22850
|
init_prewrite_secrets();
|
|
22799
|
-
import { createCipheriv, createDecipheriv, createHash as
|
|
22851
|
+
import { createCipheriv, createDecipheriv, createHash as createHash9, randomBytes, scryptSync, timingSafeEqual as timingSafeEqual2 } from "crypto";
|
|
22800
22852
|
var TODOS_ENCRYPTED_VALUE_KIND = "hasna.todos.encrypted-value";
|
|
22801
22853
|
var TODOS_ENCRYPTED_BRIDGE_KIND = "hasna.todos.encrypted-bridge";
|
|
22802
22854
|
var TODOS_ENCRYPTION_SCHEMA_VERSION = 1;
|
|
@@ -22822,7 +22874,7 @@ function now3() {
|
|
|
22822
22874
|
return new Date().toISOString();
|
|
22823
22875
|
}
|
|
22824
22876
|
function sha2564(value) {
|
|
22825
|
-
return
|
|
22877
|
+
return createHash9("sha256").update(value).digest("hex");
|
|
22826
22878
|
}
|
|
22827
22879
|
function normalizeProfileName(value) {
|
|
22828
22880
|
const name = (value || DEFAULT_ENCRYPTION_PROFILE).trim();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "@hasna/todos",
|
|
3
|
-
"packageVersion": "0.13.
|
|
3
|
+
"packageVersion": "0.13.8",
|
|
4
4
|
"repository": "https://github.com/hasna/todos.git",
|
|
5
|
-
"gitCommit": "
|
|
6
|
-
"gitTree": "
|
|
7
|
-
"sourceTreeSha256": "
|
|
8
|
-
"generatedAt": "2026-
|
|
5
|
+
"gitCommit": "43abf5a89f15b260a57a513bb8730792c558b8e5",
|
|
6
|
+
"gitTree": "713e275ea307439c6dc4f8b1fa2a974ab60e32cd",
|
|
7
|
+
"sourceTreeSha256": "5db901269ea0d4c87ed5a5d9a3d007fa7b8a41dec094542d1176f839f00a78a5",
|
|
8
|
+
"generatedAt": "2026-08-01T06:42:35.000Z"
|
|
9
9
|
}
|