@hasna/todos 0.11.73 → 0.11.74
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/index.js
CHANGED
|
@@ -25336,7 +25336,7 @@ init_task_crud();
|
|
|
25336
25336
|
init_redaction();
|
|
25337
25337
|
import { Database as Database3 } from "bun:sqlite";
|
|
25338
25338
|
import { createHash as createHash10 } from "crypto";
|
|
25339
|
-
import { existsSync as
|
|
25339
|
+
import { existsSync as existsSync10, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
|
|
25340
25340
|
import { basename as basename2, dirname as dirname7, join as join10, resolve as resolve10 } from "path";
|
|
25341
25341
|
|
|
25342
25342
|
// src/lib/task-routing.ts
|
|
@@ -25345,6 +25345,22 @@ init_projects();
|
|
|
25345
25345
|
init_task_crud();
|
|
25346
25346
|
init_task_lifecycle();
|
|
25347
25347
|
init_task_lists();
|
|
25348
|
+
import { existsSync as existsSync9, statSync as statSync3 } from "fs";
|
|
25349
|
+
var DEFAULT_STALE_IN_PROGRESS_MS = 3 * 24 * 60 * 60 * 1000;
|
|
25350
|
+
var TERMINAL_WORKFLOW_STATES = new Set([
|
|
25351
|
+
"failed",
|
|
25352
|
+
"cancelled",
|
|
25353
|
+
"canceled",
|
|
25354
|
+
"completed",
|
|
25355
|
+
"complete",
|
|
25356
|
+
"done",
|
|
25357
|
+
"error",
|
|
25358
|
+
"errored",
|
|
25359
|
+
"timeout",
|
|
25360
|
+
"timed_out",
|
|
25361
|
+
"aborted",
|
|
25362
|
+
"superseded"
|
|
25363
|
+
]);
|
|
25348
25364
|
function machineLocalPath(project, db) {
|
|
25349
25365
|
const machineId = process.env["TODOS_MACHINE_ID"];
|
|
25350
25366
|
if (!machineId)
|
|
@@ -25382,7 +25398,33 @@ function routeConcurrencyKey(task2, project, taskList, projectPath) {
|
|
|
25382
25398
|
return `path:${projectPath}`;
|
|
25383
25399
|
return `task:${task2.id}`;
|
|
25384
25400
|
}
|
|
25385
|
-
function
|
|
25401
|
+
function directoryExists(path) {
|
|
25402
|
+
try {
|
|
25403
|
+
return existsSync9(path) && statSync3(path).isDirectory();
|
|
25404
|
+
} catch {
|
|
25405
|
+
return false;
|
|
25406
|
+
}
|
|
25407
|
+
}
|
|
25408
|
+
function classifyRoute(input) {
|
|
25409
|
+
if (input.terminal)
|
|
25410
|
+
return "terminal";
|
|
25411
|
+
if (input.notPending)
|
|
25412
|
+
return "in_progress";
|
|
25413
|
+
if (input.blocked)
|
|
25414
|
+
return "blocked";
|
|
25415
|
+
if (input.locked)
|
|
25416
|
+
return "locked";
|
|
25417
|
+
if (input.missingProjectRoot)
|
|
25418
|
+
return "missing_metadata";
|
|
25419
|
+
if (!input.eligible)
|
|
25420
|
+
return "unroutable";
|
|
25421
|
+
if (input.workflowPointerActive)
|
|
25422
|
+
return "deduped_active";
|
|
25423
|
+
if (input.workflowPointerTerminal)
|
|
25424
|
+
return "terminal_requeue_needed";
|
|
25425
|
+
return "eligible";
|
|
25426
|
+
}
|
|
25427
|
+
function getTaskRouteState(taskOrId, db, options = {}) {
|
|
25386
25428
|
const d = db || getDatabase();
|
|
25387
25429
|
const task2 = typeof taskOrId === "string" ? getTask(taskOrId, d) : taskOrId;
|
|
25388
25430
|
if (!task2)
|
|
@@ -25390,8 +25432,10 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
25390
25432
|
const { project, projectPath } = resolveProject(task2, d);
|
|
25391
25433
|
const taskList = resolveTaskList(task2, project, d);
|
|
25392
25434
|
const automation = routingAutomationMetadata(task2, taskList) ?? {};
|
|
25393
|
-
const
|
|
25435
|
+
const explicitRouteEnabled = routeEnabledForTask(task2, taskList);
|
|
25394
25436
|
const tagOptIn = task2.tags.includes("auto:route") || task2.tags.includes("route:enabled");
|
|
25437
|
+
const routeEnabled = explicitRouteEnabled === undefined ? tagOptIn : explicitRouteEnabled;
|
|
25438
|
+
const tagNoAuto = task2.tags.includes("no-auto") || task2.tags.includes("noauto") || task2.tags.includes("no:auto");
|
|
25395
25439
|
const projectKind = projectKindFromMetadata(task2.metadata, taskList?.metadata);
|
|
25396
25440
|
const locked = Boolean(task2.locked_by && !isLockExpired(task2.locked_at));
|
|
25397
25441
|
const blockers = getBlockingDeps(task2.id, d);
|
|
@@ -25400,10 +25444,21 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
25400
25444
|
const requiresApproval = automation.requires_approval === true || task2.requires_approval === true;
|
|
25401
25445
|
const approvalRequired = automation.approval_required === true;
|
|
25402
25446
|
const approved = Boolean(task2.approved_by);
|
|
25447
|
+
const pointers = workflowPointersFromMetadata(task2.metadata);
|
|
25448
|
+
const workflowState = (pointers.workflow_state ?? "").trim().toLowerCase();
|
|
25449
|
+
const hasWorkflowPointer = Boolean(pointers.current_workflow_invocation_id || pointers.current_run_id || workflowState);
|
|
25450
|
+
const workflowPointerTerminal = hasWorkflowPointer && TERMINAL_WORKFLOW_STATES.has(workflowState);
|
|
25451
|
+
const workflowPointerActive = hasWorkflowPointer && !workflowPointerTerminal;
|
|
25452
|
+
const verifyProjectRoot = options.verifyProjectRoot === true;
|
|
25453
|
+
let projectRootExists = null;
|
|
25454
|
+
if (verifyProjectRoot) {
|
|
25455
|
+
projectRootExists = projectPath ? directoryExists(projectPath) : false;
|
|
25456
|
+
}
|
|
25457
|
+
const missingProjectRoot = verifyProjectRoot && projectRootExists !== true;
|
|
25403
25458
|
const gates = {
|
|
25404
25459
|
route_enabled: routeEnabled,
|
|
25405
25460
|
tag_opt_in: tagOptIn,
|
|
25406
|
-
no_auto: automation.no_auto === true,
|
|
25461
|
+
no_auto: automation.no_auto === true || tagNoAuto,
|
|
25407
25462
|
manual: automation.manual === true,
|
|
25408
25463
|
manual_required: automation.manual_required === true,
|
|
25409
25464
|
requires_approval: requiresApproval,
|
|
@@ -25411,7 +25466,10 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
25411
25466
|
approved,
|
|
25412
25467
|
locked,
|
|
25413
25468
|
blocked,
|
|
25414
|
-
terminal
|
|
25469
|
+
terminal,
|
|
25470
|
+
missing_project_root: missingProjectRoot,
|
|
25471
|
+
workflow_pointer_active: workflowPointerActive,
|
|
25472
|
+
workflow_pointer_terminal: workflowPointerTerminal
|
|
25415
25473
|
};
|
|
25416
25474
|
const reasons = [];
|
|
25417
25475
|
if (task2.status !== "pending")
|
|
@@ -25436,12 +25494,44 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
25436
25494
|
reasons.push("approval_required");
|
|
25437
25495
|
if (automation.allowed === false)
|
|
25438
25496
|
reasons.push("automation_disallowed");
|
|
25497
|
+
if (missingProjectRoot)
|
|
25498
|
+
reasons.push("missing_project_root");
|
|
25499
|
+
const eligible = reasons.length === 0;
|
|
25500
|
+
const staleAfterMs = options.staleInProgressAfterMs ?? DEFAULT_STALE_IN_PROGRESS_MS;
|
|
25501
|
+
const updatedAtMs = Date.parse(task2.updated_at);
|
|
25502
|
+
const ageMs = Number.isNaN(updatedAtMs) ? 0 : Math.max(0, Date.now() - updatedAtMs);
|
|
25503
|
+
const evidence = {
|
|
25504
|
+
owner: task2.assigned_to ?? task2.locked_by ?? null,
|
|
25505
|
+
assigned_to: task2.assigned_to ?? null,
|
|
25506
|
+
locked_by: task2.locked_by ?? null,
|
|
25507
|
+
locked_at: task2.locked_at ?? null,
|
|
25508
|
+
updated_at: task2.updated_at,
|
|
25509
|
+
age_ms: ageMs,
|
|
25510
|
+
stale: task2.status === "in_progress" && ageMs > staleAfterMs,
|
|
25511
|
+
stale_after_ms: staleAfterMs,
|
|
25512
|
+
current_run_id: pointers.current_run_id ?? null,
|
|
25513
|
+
current_workflow_invocation_id: pointers.current_workflow_invocation_id ?? null,
|
|
25514
|
+
workflow_state: pointers.workflow_state ?? null,
|
|
25515
|
+
project_root_verified: verifyProjectRoot,
|
|
25516
|
+
project_root_exists: projectRootExists
|
|
25517
|
+
};
|
|
25518
|
+
const route_class = classifyRoute({
|
|
25519
|
+
terminal,
|
|
25520
|
+
notPending: task2.status !== "pending",
|
|
25521
|
+
blocked,
|
|
25522
|
+
locked,
|
|
25523
|
+
missingProjectRoot,
|
|
25524
|
+
eligible,
|
|
25525
|
+
workflowPointerActive,
|
|
25526
|
+
workflowPointerTerminal
|
|
25527
|
+
});
|
|
25439
25528
|
return {
|
|
25440
25529
|
schema_version: TODOS_TASK_ROUTE_STATE_SCHEMA_VERSION,
|
|
25441
25530
|
task_id: task2.id,
|
|
25442
25531
|
task_short_id: task2.short_id,
|
|
25443
25532
|
status: task2.status,
|
|
25444
|
-
eligible
|
|
25533
|
+
eligible,
|
|
25534
|
+
route_class,
|
|
25445
25535
|
reasons,
|
|
25446
25536
|
blockers: blockers.map((blocker) => ({
|
|
25447
25537
|
id: blocker.id,
|
|
@@ -25461,7 +25551,8 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
25461
25551
|
task_list_name: taskList?.name ?? null,
|
|
25462
25552
|
concurrency_key: routeConcurrencyKey(task2, project, taskList, projectPath)
|
|
25463
25553
|
},
|
|
25464
|
-
pointers
|
|
25554
|
+
pointers,
|
|
25555
|
+
evidence
|
|
25465
25556
|
};
|
|
25466
25557
|
}
|
|
25467
25558
|
function setTaskWorkflowPointers(taskId, input, db) {
|
|
@@ -25586,7 +25677,7 @@ function discoverStoresUnderRoot(sourceRoot) {
|
|
|
25586
25677
|
const rootPath = normalizePath3(sourceRoot);
|
|
25587
25678
|
const errors = [];
|
|
25588
25679
|
const stores = [];
|
|
25589
|
-
if (!
|
|
25680
|
+
if (!existsSync10(rootPath)) {
|
|
25590
25681
|
const ref = createStoreRef(join10(rootPath, TODO_STORE_RELATIVE_PATH));
|
|
25591
25682
|
errors.push({
|
|
25592
25683
|
...ref,
|
|
@@ -25597,7 +25688,7 @@ function discoverStoresUnderRoot(sourceRoot) {
|
|
|
25597
25688
|
}
|
|
25598
25689
|
let rootStat;
|
|
25599
25690
|
try {
|
|
25600
|
-
rootStat =
|
|
25691
|
+
rootStat = statSync4(rootPath);
|
|
25601
25692
|
} catch (error) {
|
|
25602
25693
|
const ref = createStoreRef(join10(rootPath, TODO_STORE_RELATIVE_PATH));
|
|
25603
25694
|
errors.push({
|
|
@@ -25613,7 +25704,7 @@ function discoverStoresUnderRoot(sourceRoot) {
|
|
|
25613
25704
|
}
|
|
25614
25705
|
function scanDirectory(dir, depth) {
|
|
25615
25706
|
const candidate = join10(dir, TODO_STORE_RELATIVE_PATH);
|
|
25616
|
-
if (
|
|
25707
|
+
if (existsSync10(candidate)) {
|
|
25617
25708
|
stores.push(createStoreRef(candidate));
|
|
25618
25709
|
}
|
|
25619
25710
|
if (depth >= ROOT_SCAN_MAX_DEPTH)
|
|
@@ -25659,7 +25750,7 @@ function collectStoreRefs(input) {
|
|
|
25659
25750
|
};
|
|
25660
25751
|
}
|
|
25661
25752
|
function openReadonlyStore(ref) {
|
|
25662
|
-
if (!
|
|
25753
|
+
if (!existsSync10(ref.source_db_path)) {
|
|
25663
25754
|
throw Object.assign(new Error(`Store does not exist: ${ref.source_db_path}`), { code: "STORE_MISSING" });
|
|
25664
25755
|
}
|
|
25665
25756
|
return new Database3(ref.source_db_path, { readonly: true, create: false });
|
|
@@ -25970,7 +26061,7 @@ init_plans();
|
|
|
25970
26061
|
init_database();
|
|
25971
26062
|
init_projects();
|
|
25972
26063
|
init_tasks();
|
|
25973
|
-
import { existsSync as
|
|
26064
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
25974
26065
|
import { join as join11, resolve as resolve11 } from "path";
|
|
25975
26066
|
var PLAN_MARKDOWN_SCHEMA = "hasna.todos.plan/v1";
|
|
25976
26067
|
function assertSafePathSegment(value, label) {
|
|
@@ -26207,7 +26298,7 @@ function readPlanArtifact(plan, db) {
|
|
|
26207
26298
|
return null;
|
|
26208
26299
|
const d = db || getDatabase();
|
|
26209
26300
|
const paths = resolvePlanArtifactCandidatePaths(plan, d);
|
|
26210
|
-
const path =
|
|
26301
|
+
const path = existsSync11(paths.primary.file_path) ? paths.primary.file_path : existsSync11(paths.legacy.file_path) ? paths.legacy.file_path : null;
|
|
26211
26302
|
if (!path)
|
|
26212
26303
|
return null;
|
|
26213
26304
|
const markdown = readFileSync7(path, "utf8");
|
|
@@ -26222,7 +26313,7 @@ function inspectPlanArtifact(plan, db) {
|
|
|
26222
26313
|
return null;
|
|
26223
26314
|
const d = db || getDatabase();
|
|
26224
26315
|
const paths = resolvePlanArtifactCandidatePaths(plan, d);
|
|
26225
|
-
const path =
|
|
26316
|
+
const path = existsSync11(paths.primary.file_path) ? paths.primary.file_path : existsSync11(paths.legacy.file_path) ? paths.legacy.file_path : null;
|
|
26226
26317
|
if (!path) {
|
|
26227
26318
|
return {
|
|
26228
26319
|
path: paths.primary.file_path,
|
|
@@ -27311,11 +27402,11 @@ function renderRetrospectiveMarkdown(record) {
|
|
|
27311
27402
|
init_database();
|
|
27312
27403
|
init_projects();
|
|
27313
27404
|
init_task_lists();
|
|
27314
|
-
import { existsSync as
|
|
27405
|
+
import { existsSync as existsSync12, readFileSync as readFileSync8, statSync as statSync5 } from "fs";
|
|
27315
27406
|
import { basename as basename3, dirname as dirname8, resolve as resolve12 } from "path";
|
|
27316
27407
|
function safeStat(path) {
|
|
27317
27408
|
try {
|
|
27318
|
-
return
|
|
27409
|
+
return statSync5(path);
|
|
27319
27410
|
} catch {
|
|
27320
27411
|
return null;
|
|
27321
27412
|
}
|
|
@@ -27330,7 +27421,7 @@ function canonicalPath(input) {
|
|
|
27330
27421
|
function findUp(start, marker) {
|
|
27331
27422
|
let current = canonicalPath(start);
|
|
27332
27423
|
while (true) {
|
|
27333
|
-
if (
|
|
27424
|
+
if (existsSync12(resolve12(current, marker)))
|
|
27334
27425
|
return current;
|
|
27335
27426
|
const parent = dirname8(current);
|
|
27336
27427
|
if (parent === current)
|
|
@@ -27342,7 +27433,7 @@ function readPackageJson2(path) {
|
|
|
27342
27433
|
if (!path)
|
|
27343
27434
|
return null;
|
|
27344
27435
|
const file = resolve12(path, "package.json");
|
|
27345
|
-
if (!
|
|
27436
|
+
if (!existsSync12(file))
|
|
27346
27437
|
return null;
|
|
27347
27438
|
try {
|
|
27348
27439
|
const parsed = JSON.parse(readFileSync8(file, "utf-8"));
|
|
@@ -27364,7 +27455,7 @@ function workspaceMarker(root, rootPackage) {
|
|
|
27364
27455
|
if (rootPackage?.workspaces)
|
|
27365
27456
|
markers.push("package.json#workspaces");
|
|
27366
27457
|
for (const marker of ["pnpm-workspace.yaml", "turbo.json", "nx.json", "lerna.json", "rush.json", "bun.lock", "bun.lockb"]) {
|
|
27367
|
-
if (
|
|
27458
|
+
if (existsSync12(resolve12(root, marker)))
|
|
27368
27459
|
markers.push(marker);
|
|
27369
27460
|
}
|
|
27370
27461
|
const kind = markers.find((marker) => marker !== "bun.lock" && marker !== "bun.lockb") ?? null;
|
|
@@ -27702,7 +27793,7 @@ var gatherTrainingData = async (options = {}) => {
|
|
|
27702
27793
|
};
|
|
27703
27794
|
// src/lib/model-config.ts
|
|
27704
27795
|
init_sync_utils();
|
|
27705
|
-
import { existsSync as
|
|
27796
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync9, readFileSync as readFileSync9, writeFileSync as writeFileSync7 } from "fs";
|
|
27706
27797
|
import { join as join12 } from "path";
|
|
27707
27798
|
var DEFAULT_MODEL = "gpt-4o-mini";
|
|
27708
27799
|
function getConfigDir() {
|
|
@@ -27713,7 +27804,7 @@ function getConfigPath2() {
|
|
|
27713
27804
|
}
|
|
27714
27805
|
function readConfig() {
|
|
27715
27806
|
const configPath = getConfigPath2();
|
|
27716
|
-
if (!
|
|
27807
|
+
if (!existsSync13(configPath))
|
|
27717
27808
|
return {};
|
|
27718
27809
|
try {
|
|
27719
27810
|
const raw = readFileSync9(configPath, "utf-8");
|
|
@@ -27724,7 +27815,7 @@ function readConfig() {
|
|
|
27724
27815
|
}
|
|
27725
27816
|
function writeConfig(config) {
|
|
27726
27817
|
const configDir = getConfigDir();
|
|
27727
|
-
if (!
|
|
27818
|
+
if (!existsSync13(configDir)) {
|
|
27728
27819
|
mkdirSync9(configDir, { recursive: true });
|
|
27729
27820
|
}
|
|
27730
27821
|
writeFileSync7(getConfigPath2(), JSON.stringify(config, null, 2) + `
|
|
@@ -28469,7 +28560,7 @@ init_database();
|
|
|
28469
28560
|
init_tasks();
|
|
28470
28561
|
init_config();
|
|
28471
28562
|
init_redaction();
|
|
28472
|
-
import { existsSync as
|
|
28563
|
+
import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
|
|
28473
28564
|
var DEFAULT_RETRY = {
|
|
28474
28565
|
attempts: 1,
|
|
28475
28566
|
backoff_ms: 0
|
|
@@ -28632,7 +28723,7 @@ Timed out after ${provider.timeout_ms}ms`);
|
|
|
28632
28723
|
};
|
|
28633
28724
|
}
|
|
28634
28725
|
function runCiLogProvider(input) {
|
|
28635
|
-
const text = input.log_text ?? (input.log_path &&
|
|
28726
|
+
const text = input.log_text ?? (input.log_path && existsSync14(input.log_path) ? readFileSync10(input.log_path, "utf-8") : "");
|
|
28636
28727
|
return {
|
|
28637
28728
|
status: classifyLog(text),
|
|
28638
28729
|
attempts: 1,
|
|
@@ -28644,7 +28735,7 @@ function runBrowserProvider(input) {
|
|
|
28644
28735
|
if (!input.artifact_path) {
|
|
28645
28736
|
return { status: "unknown", attempts: 1, exit_code: null, output_summary: "browser provider needs a screenshot or artifact path" };
|
|
28646
28737
|
}
|
|
28647
|
-
if (!
|
|
28738
|
+
if (!existsSync14(input.artifact_path)) {
|
|
28648
28739
|
return { status: "failed", attempts: 1, exit_code: null, output_summary: `artifact not found: ${input.artifact_path}` };
|
|
28649
28740
|
}
|
|
28650
28741
|
return {
|
|
@@ -29289,7 +29380,7 @@ function resourceDiagnostics() {
|
|
|
29289
29380
|
};
|
|
29290
29381
|
}
|
|
29291
29382
|
// src/lib/sandbox-profiles.ts
|
|
29292
|
-
import { existsSync as
|
|
29383
|
+
import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync9, mkdirSync as mkdirSync11 } from "fs";
|
|
29293
29384
|
import { join as join13, dirname as dirname10 } from "path";
|
|
29294
29385
|
var SANDBOX_PROFILE_VERSION = "todos.sandbox-profile.v1";
|
|
29295
29386
|
function getProfilesPath() {
|
|
@@ -29298,9 +29389,9 @@ function getProfilesPath() {
|
|
|
29298
29389
|
}
|
|
29299
29390
|
const localDir = join13(process.cwd(), ".todos");
|
|
29300
29391
|
const local = join13(localDir, "sandbox-profiles.json");
|
|
29301
|
-
if (
|
|
29392
|
+
if (existsSync15(localDir))
|
|
29302
29393
|
return local;
|
|
29303
|
-
if (
|
|
29394
|
+
if (existsSync15(local))
|
|
29304
29395
|
return local;
|
|
29305
29396
|
const home = process.env["HOME"] || "~";
|
|
29306
29397
|
return join13(home, ".hasna", "todos", "sandbox-profiles.json");
|
|
@@ -29335,7 +29426,7 @@ function loadSandboxProfiles() {
|
|
|
29335
29426
|
if (cached2)
|
|
29336
29427
|
return cached2;
|
|
29337
29428
|
const path = getProfilesPath();
|
|
29338
|
-
if (!
|
|
29429
|
+
if (!existsSync15(path)) {
|
|
29339
29430
|
cached2 = getDefaultSandboxProfiles();
|
|
29340
29431
|
return cached2;
|
|
29341
29432
|
}
|
|
@@ -29715,7 +29806,7 @@ init_task_commits();
|
|
|
29715
29806
|
|
|
29716
29807
|
// src/lib/git-traceability.ts
|
|
29717
29808
|
init_task_commits();
|
|
29718
|
-
import { existsSync as
|
|
29809
|
+
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
29719
29810
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
29720
29811
|
import { resolve as resolve14 } from "path";
|
|
29721
29812
|
var GIT_TRACEABILITY_SCHEMA_VERSION = "todos.git_traceability.v1";
|
|
@@ -29761,7 +29852,7 @@ function inspectGitCommit(sha, cwd) {
|
|
|
29761
29852
|
}
|
|
29762
29853
|
function loadCiSnapshot(path) {
|
|
29763
29854
|
const target = path ? resolve14(path) : resolve14(process.cwd(), ".todos", "ci-snapshot.json");
|
|
29764
|
-
if (!
|
|
29855
|
+
if (!existsSync16(target))
|
|
29765
29856
|
return null;
|
|
29766
29857
|
try {
|
|
29767
29858
|
const parsed = JSON.parse(readFileSync12(target, "utf8"));
|
|
@@ -29857,7 +29948,7 @@ function formatTraceabilityReport(report) {
|
|
|
29857
29948
|
`);
|
|
29858
29949
|
}
|
|
29859
29950
|
// src/lib/mention-resolver.ts
|
|
29860
|
-
import { existsSync as
|
|
29951
|
+
import { existsSync as existsSync17, readdirSync as readdirSync3, readFileSync as readFileSync13, statSync as statSync6 } from "fs";
|
|
29861
29952
|
import { basename as basename4, isAbsolute, join as join14, relative as relative4, resolve as resolve15, sep as sep2 } from "path";
|
|
29862
29953
|
init_database();
|
|
29863
29954
|
init_plans();
|
|
@@ -30012,11 +30103,11 @@ function resolveFile(parsed, workspace) {
|
|
|
30012
30103
|
return resolution;
|
|
30013
30104
|
}
|
|
30014
30105
|
resolution.path = relPath;
|
|
30015
|
-
if (!
|
|
30106
|
+
if (!existsSync17(absolutePath)) {
|
|
30016
30107
|
resolution.warnings.push("file does not exist in the local workspace");
|
|
30017
30108
|
return resolution;
|
|
30018
30109
|
}
|
|
30019
|
-
const stats2 =
|
|
30110
|
+
const stats2 = statSync6(absolutePath);
|
|
30020
30111
|
if (!stats2.isFile()) {
|
|
30021
30112
|
resolution.warnings.push("path exists but is not a file");
|
|
30022
30113
|
return resolution;
|
|
@@ -30054,7 +30145,7 @@ function walkSourceFiles(root, current = root, files = []) {
|
|
|
30054
30145
|
if (!entry2.isFile())
|
|
30055
30146
|
continue;
|
|
30056
30147
|
const extension = `.${basename4(entry2.name).split(".").pop() || ""}`;
|
|
30057
|
-
if (SOURCE_EXTENSIONS.has(extension) &&
|
|
30148
|
+
if (SOURCE_EXTENSIONS.has(extension) && statSync6(absolutePath).size <= 512 * 1024) {
|
|
30058
30149
|
files.push(absolutePath);
|
|
30059
30150
|
}
|
|
30060
30151
|
}
|
|
@@ -31943,7 +32034,7 @@ function getAdapterDocsFingerprint() {
|
|
|
31943
32034
|
// src/lib/inbox-intake.ts
|
|
31944
32035
|
init_database();
|
|
31945
32036
|
init_tasks();
|
|
31946
|
-
import { existsSync as
|
|
32037
|
+
import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
|
|
31947
32038
|
import { basename as basename5 } from "path";
|
|
31948
32039
|
import { createHash as createHash12 } from "crypto";
|
|
31949
32040
|
init_secret_redaction();
|
|
@@ -31989,7 +32080,7 @@ function loadRawContent(input) {
|
|
|
31989
32080
|
}
|
|
31990
32081
|
}
|
|
31991
32082
|
if (input.file_path) {
|
|
31992
|
-
if (!
|
|
32083
|
+
if (!existsSync18(input.file_path))
|
|
31993
32084
|
throw new Error(`File not found: ${input.file_path}`);
|
|
31994
32085
|
const raw = readFileSync14(input.file_path, "utf8");
|
|
31995
32086
|
const name = basename5(input.file_path).toLowerCase();
|
|
@@ -32610,7 +32701,7 @@ function formatNlIntakePreviewText(preview) {
|
|
|
32610
32701
|
// src/lib/issue-importers.ts
|
|
32611
32702
|
init_database();
|
|
32612
32703
|
init_tasks();
|
|
32613
|
-
import { existsSync as
|
|
32704
|
+
import { existsSync as existsSync19, readFileSync as readFileSync15 } from "fs";
|
|
32614
32705
|
var ISSUE_IMPORT_SCHEMA = "todos.issue_import.v1";
|
|
32615
32706
|
var ISSUE_SOURCES = ["github", "linear", "jira", "auto"];
|
|
32616
32707
|
var GITHUB_LABEL_PRIORITY = {
|
|
@@ -32829,7 +32920,7 @@ function parseIssueExport(data, source9 = "auto") {
|
|
|
32829
32920
|
return normalized;
|
|
32830
32921
|
}
|
|
32831
32922
|
function loadIssueExportFromFile(path) {
|
|
32832
|
-
if (!
|
|
32923
|
+
if (!existsSync19(path))
|
|
32833
32924
|
throw new Error(`File not found: ${path}`);
|
|
32834
32925
|
return JSON.parse(readFileSync15(path, "utf8"));
|
|
32835
32926
|
}
|
|
@@ -32989,7 +33080,7 @@ todos import issues ./linear.json --source linear --dry-run
|
|
|
32989
33080
|
// src/lib/run-records.ts
|
|
32990
33081
|
init_database();
|
|
32991
33082
|
init_secret_redaction();
|
|
32992
|
-
import { existsSync as
|
|
33083
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync12, writeFileSync as writeFileSync10 } from "fs";
|
|
32993
33084
|
import { join as join15, dirname as dirname11 } from "path";
|
|
32994
33085
|
var RUN_RECORD_SCHEMA = "todos.run_record.v1";
|
|
32995
33086
|
var RUN_RECORD_STATUSES = ["active", "completed", "failed", "archived"];
|
|
@@ -33224,14 +33315,14 @@ function formatRunRecordMarkdown(record) {
|
|
|
33224
33315
|
}
|
|
33225
33316
|
function getDefaultReplayDir() {
|
|
33226
33317
|
const local = join15(process.cwd(), ".todos", "replays");
|
|
33227
|
-
if (
|
|
33318
|
+
if (existsSync20(join15(process.cwd(), ".todos")))
|
|
33228
33319
|
return local;
|
|
33229
33320
|
const home = process.env["HOME"] || "~";
|
|
33230
33321
|
return join15(home, ".hasna", "todos", "replays");
|
|
33231
33322
|
}
|
|
33232
33323
|
// src/lib/release-checks.ts
|
|
33233
33324
|
init_secret_redaction();
|
|
33234
|
-
import { existsSync as
|
|
33325
|
+
import { existsSync as existsSync21, readFileSync as readFileSync16, readdirSync as readdirSync4, statSync as statSync7 } from "fs";
|
|
33235
33326
|
import { join as join16, relative as relative5 } from "path";
|
|
33236
33327
|
var RELEASE_CHECK_SCHEMA = "todos.release_check.v1";
|
|
33237
33328
|
var FORBIDDEN_DIST_PATTERNS = [
|
|
@@ -33246,16 +33337,16 @@ var FORBIDDEN_DIST_PATTERNS = [
|
|
|
33246
33337
|
var REQUIRED_BINS = ["todos", "todos-mcp", "todos-serve"];
|
|
33247
33338
|
function readPackageJson3(root) {
|
|
33248
33339
|
const path = join16(root, "package.json");
|
|
33249
|
-
if (!
|
|
33340
|
+
if (!existsSync21(path))
|
|
33250
33341
|
throw new Error(`package.json not found in ${root}`);
|
|
33251
33342
|
return JSON.parse(readFileSync16(path, "utf8"));
|
|
33252
33343
|
}
|
|
33253
33344
|
function walkFiles(dir, acc = []) {
|
|
33254
|
-
if (!
|
|
33345
|
+
if (!existsSync21(dir))
|
|
33255
33346
|
return acc;
|
|
33256
33347
|
for (const entry2 of readdirSync4(dir)) {
|
|
33257
33348
|
const full = join16(dir, entry2);
|
|
33258
|
-
const st =
|
|
33349
|
+
const st = statSync7(full);
|
|
33259
33350
|
if (st.isDirectory())
|
|
33260
33351
|
walkFiles(full, acc);
|
|
33261
33352
|
else if (/\.(js|mjs|cjs|json|d\.ts)$/.test(entry2))
|
|
@@ -33273,7 +33364,7 @@ function auditPackageContents(root) {
|
|
|
33273
33364
|
}
|
|
33274
33365
|
for (const pattern of files) {
|
|
33275
33366
|
const target = join16(root, pattern);
|
|
33276
|
-
if (!
|
|
33367
|
+
if (!existsSync21(target)) {
|
|
33277
33368
|
checks.push({ id: `files_missing_${pattern}`, severity: "error", message: `Published file path missing: ${pattern}` });
|
|
33278
33369
|
}
|
|
33279
33370
|
}
|
|
@@ -33288,7 +33379,7 @@ function auditPackageContents(root) {
|
|
|
33288
33379
|
continue;
|
|
33289
33380
|
}
|
|
33290
33381
|
const binPath = join16(root, rel);
|
|
33291
|
-
if (!
|
|
33382
|
+
if (!existsSync21(binPath)) {
|
|
33292
33383
|
checks.push({ id: `bin_path_${name}`, severity: "error", message: `Bin file missing: ${rel}` });
|
|
33293
33384
|
} else {
|
|
33294
33385
|
checks.push({ id: `bin_ok_${name}`, severity: "info", message: `Bin present: ${name} \u2192 ${rel}` });
|
|
@@ -33306,7 +33397,7 @@ function auditPackageContents(root) {
|
|
|
33306
33397
|
function scanDistArtifacts(root) {
|
|
33307
33398
|
const checks = [];
|
|
33308
33399
|
const distDir = join16(root, "dist");
|
|
33309
|
-
if (!
|
|
33400
|
+
if (!existsSync21(distDir)) {
|
|
33310
33401
|
checks.push({ id: "dist_missing", severity: "error", message: "dist/ directory not found \u2014 run bun run build" });
|
|
33311
33402
|
return checks;
|
|
33312
33403
|
}
|
|
@@ -33616,7 +33707,7 @@ function renderReleaseNotesMarkdown(document) {
|
|
|
33616
33707
|
// src/lib/db-backup.ts
|
|
33617
33708
|
init_database();
|
|
33618
33709
|
init_migrations();
|
|
33619
|
-
import { existsSync as
|
|
33710
|
+
import { existsSync as existsSync22, copyFileSync, mkdirSync as mkdirSync13, readFileSync as readFileSync17, renameSync, statSync as statSync8, writeFileSync as writeFileSync11, unlinkSync } from "fs";
|
|
33620
33711
|
import { dirname as dirname12, join as join17, resolve as resolve16 } from "path";
|
|
33621
33712
|
import { Database as Database4 } from "bun:sqlite";
|
|
33622
33713
|
var DB_BACKUP_SCHEMA = "todos.db_backup.v1";
|
|
@@ -33634,7 +33725,7 @@ function resolveDbPath(dbPath) {
|
|
|
33634
33725
|
}
|
|
33635
33726
|
function backupDatabase(outputPath, sourcePath) {
|
|
33636
33727
|
const source9 = resolveDbPath(sourcePath);
|
|
33637
|
-
if (!
|
|
33728
|
+
if (!existsSync22(source9))
|
|
33638
33729
|
throw new Error(`Database not found: ${source9}`);
|
|
33639
33730
|
mkdirSync13(dirname12(outputPath), { recursive: true });
|
|
33640
33731
|
closeDatabase();
|
|
@@ -33646,7 +33737,7 @@ function backupDatabase(outputPath, sourcePath) {
|
|
|
33646
33737
|
src.close();
|
|
33647
33738
|
writeFileSync11(outputPath, image);
|
|
33648
33739
|
const method = "file_copy";
|
|
33649
|
-
const bytes =
|
|
33740
|
+
const bytes = statSync8(outputPath).size;
|
|
33650
33741
|
return {
|
|
33651
33742
|
schema_version: DB_BACKUP_SCHEMA,
|
|
33652
33743
|
source_path: source9,
|
|
@@ -33657,7 +33748,7 @@ function backupDatabase(outputPath, sourcePath) {
|
|
|
33657
33748
|
};
|
|
33658
33749
|
}
|
|
33659
33750
|
function restoreDatabase(backupPath, targetPath) {
|
|
33660
|
-
if (!
|
|
33751
|
+
if (!existsSync22(backupPath))
|
|
33661
33752
|
throw new Error(`Backup not found: ${backupPath}`);
|
|
33662
33753
|
const integrity = checkDatabaseIntegrity(backupPath);
|
|
33663
33754
|
if (!integrity.ok) {
|
|
@@ -33673,7 +33764,7 @@ function restoreDatabase(backupPath, targetPath) {
|
|
|
33673
33764
|
copyFileSync(backupPath, staging);
|
|
33674
33765
|
for (const sidecar of [`${target}-wal`, `${target}-shm`]) {
|
|
33675
33766
|
try {
|
|
33676
|
-
if (
|
|
33767
|
+
if (existsSync22(sidecar))
|
|
33677
33768
|
unlinkSync(sidecar);
|
|
33678
33769
|
} catch {}
|
|
33679
33770
|
}
|
|
@@ -33682,7 +33773,7 @@ function restoreDatabase(backupPath, targetPath) {
|
|
|
33682
33773
|
schema_version: DB_BACKUP_SCHEMA,
|
|
33683
33774
|
source_path: backupPath,
|
|
33684
33775
|
backup_path: target,
|
|
33685
|
-
bytes:
|
|
33776
|
+
bytes: statSync8(target).size,
|
|
33686
33777
|
method: "file_copy",
|
|
33687
33778
|
created_at: new Date().toISOString()
|
|
33688
33779
|
};
|
|
@@ -33690,7 +33781,7 @@ function restoreDatabase(backupPath, targetPath) {
|
|
|
33690
33781
|
function checkDatabaseIntegrity(dbPath) {
|
|
33691
33782
|
const path = dbPath ? resolve16(dbPath) : resolveDbPath();
|
|
33692
33783
|
const errors = [];
|
|
33693
|
-
if (!
|
|
33784
|
+
if (!existsSync22(path)) {
|
|
33694
33785
|
return {
|
|
33695
33786
|
schema_version: DB_BACKUP_SCHEMA,
|
|
33696
33787
|
path,
|
|
@@ -33754,11 +33845,11 @@ function checkDatabaseIntegrity(dbPath) {
|
|
|
33754
33845
|
}
|
|
33755
33846
|
function compactDatabase(dbPath) {
|
|
33756
33847
|
const path = dbPath ? resolve16(dbPath) : resolveDbPath();
|
|
33757
|
-
const before =
|
|
33848
|
+
const before = statSync8(path).size;
|
|
33758
33849
|
const db = new Database4(path);
|
|
33759
33850
|
db.exec("VACUUM");
|
|
33760
33851
|
db.close();
|
|
33761
|
-
const after =
|
|
33852
|
+
const after = statSync8(path).size;
|
|
33762
33853
|
closeDatabase();
|
|
33763
33854
|
return { path, bytes_before: before, bytes_after: after };
|
|
33764
33855
|
}
|
|
@@ -33793,7 +33884,7 @@ function defaultBackupPath(dbPath) {
|
|
|
33793
33884
|
}
|
|
33794
33885
|
function readBackupManifest(backupPath) {
|
|
33795
33886
|
const manifestPath = `${backupPath}.json`;
|
|
33796
|
-
if (!
|
|
33887
|
+
if (!existsSync22(manifestPath))
|
|
33797
33888
|
return null;
|
|
33798
33889
|
try {
|
|
33799
33890
|
return JSON.parse(readFileSync17(manifestPath, "utf8"));
|
|
@@ -37494,7 +37585,7 @@ init_tasks();
|
|
|
37494
37585
|
init_redaction();
|
|
37495
37586
|
init_sync_utils();
|
|
37496
37587
|
import { createHash as createHash13 } from "crypto";
|
|
37497
|
-
import { existsSync as
|
|
37588
|
+
import { existsSync as existsSync23, readFileSync as readFileSync20, statSync as statSync9 } from "fs";
|
|
37498
37589
|
import { hostname as hostname3, platform, arch } from "os";
|
|
37499
37590
|
import { dirname as dirname16, join as join19, resolve as resolve17 } from "path";
|
|
37500
37591
|
import { tmpdir as tmpdir3 } from "os";
|
|
@@ -37519,9 +37610,9 @@ function sha2565(value) {
|
|
|
37519
37610
|
}
|
|
37520
37611
|
function fileRecord(root, relativePath) {
|
|
37521
37612
|
const path = join19(root, relativePath);
|
|
37522
|
-
if (!
|
|
37613
|
+
if (!existsSync23(path))
|
|
37523
37614
|
return null;
|
|
37524
|
-
const stat =
|
|
37615
|
+
const stat = statSync9(path);
|
|
37525
37616
|
if (!stat.isFile())
|
|
37526
37617
|
return null;
|
|
37527
37618
|
const content = readFileSync20(path);
|
|
@@ -38446,7 +38537,7 @@ todos report export --kind retrospective --days 14 --format markdown --out retro
|
|
|
38446
38537
|
`;
|
|
38447
38538
|
}
|
|
38448
38539
|
// src/lib/command-aliases.ts
|
|
38449
|
-
import { existsSync as
|
|
38540
|
+
import { existsSync as existsSync24, readFileSync as readFileSync21, writeFileSync as writeFileSync18, mkdirSync as mkdirSync20 } from "fs";
|
|
38450
38541
|
import { join as join21 } from "path";
|
|
38451
38542
|
var COMMAND_ALIASES_SCHEMA = "todos.command_aliases.v1";
|
|
38452
38543
|
var RESERVED = new Set([...listTopLevelCommands(), "help", "version", "alias", "shortcuts"]);
|
|
@@ -38483,7 +38574,7 @@ function validateAliasName(name) {
|
|
|
38483
38574
|
}
|
|
38484
38575
|
function loadAliasStore(cwd) {
|
|
38485
38576
|
const path = aliasesPath(cwd);
|
|
38486
|
-
if (!
|
|
38577
|
+
if (!existsSync24(path))
|
|
38487
38578
|
return emptyStore();
|
|
38488
38579
|
const parsed = JSON.parse(readFileSync21(path, "utf8"));
|
|
38489
38580
|
if (parsed.schema_version !== COMMAND_ALIASES_SCHEMA) {
|
|
@@ -39148,7 +39239,7 @@ function createBranchWorkPlan(input, db) {
|
|
|
39148
39239
|
init_database();
|
|
39149
39240
|
init_templates();
|
|
39150
39241
|
init_plans();
|
|
39151
|
-
import { existsSync as
|
|
39242
|
+
import { existsSync as existsSync25, readFileSync as readFileSync22, writeFileSync as writeFileSync19, mkdirSync as mkdirSync21 } from "fs";
|
|
39152
39243
|
import { join as join22 } from "path";
|
|
39153
39244
|
var USER_SCAFFOLD_SCHEMA = "todos.user_scaffold.v1";
|
|
39154
39245
|
var SCAFFOLD_KINDS = ["task", "project", "plan", "checklist", "contract", "verification_policy"];
|
|
@@ -39169,7 +39260,7 @@ function emptyStore2() {
|
|
|
39169
39260
|
}
|
|
39170
39261
|
function loadUserScaffoldStore(cwd) {
|
|
39171
39262
|
const path = storePath(cwd);
|
|
39172
|
-
if (!
|
|
39263
|
+
if (!existsSync25(path))
|
|
39173
39264
|
return emptyStore2();
|
|
39174
39265
|
const parsed = JSON.parse(readFileSync22(path, "utf8"));
|
|
39175
39266
|
if (parsed.schema_version !== USER_SCAFFOLD_SCHEMA) {
|
|
@@ -41786,7 +41877,7 @@ function runSearchView(idOrName, db) {
|
|
|
41786
41877
|
init_tasks();
|
|
41787
41878
|
init_config();
|
|
41788
41879
|
init_sync_utils();
|
|
41789
|
-
import { existsSync as
|
|
41880
|
+
import { existsSync as existsSync26, readFileSync as readFileSync23, readdirSync as readdirSync5, writeFileSync as writeFileSync20 } from "fs";
|
|
41790
41881
|
import { join as join24 } from "path";
|
|
41791
41882
|
function getTaskListDir(taskListId) {
|
|
41792
41883
|
return join24(HOME, ".claude", "tasks", taskListId);
|
|
@@ -41808,7 +41899,7 @@ function toSqliteStatus(status) {
|
|
|
41808
41899
|
}
|
|
41809
41900
|
function readPrefixCounter(dir) {
|
|
41810
41901
|
const path = join24(dir, ".prefix-counter");
|
|
41811
|
-
if (!
|
|
41902
|
+
if (!existsSync26(path))
|
|
41812
41903
|
return 0;
|
|
41813
41904
|
const val = parseInt(readFileSync23(path, "utf-8").trim(), 10);
|
|
41814
41905
|
return isNaN(val) ? 0 : val;
|
|
@@ -41841,7 +41932,7 @@ function taskToClaudeTask(task2, claudeTaskId, existingMeta) {
|
|
|
41841
41932
|
}
|
|
41842
41933
|
function pushToClaudeTaskList(taskListId, projectId, options = {}) {
|
|
41843
41934
|
const dir = getTaskListDir(taskListId);
|
|
41844
|
-
if (!
|
|
41935
|
+
if (!existsSync26(dir))
|
|
41845
41936
|
ensureDir2(dir);
|
|
41846
41937
|
const filter = {};
|
|
41847
41938
|
if (projectId)
|
|
@@ -41937,7 +42028,7 @@ function pushToClaudeTaskList(taskListId, projectId, options = {}) {
|
|
|
41937
42028
|
}
|
|
41938
42029
|
function pullFromClaudeTaskList(taskListId, projectId, options = {}) {
|
|
41939
42030
|
const dir = getTaskListDir(taskListId);
|
|
41940
|
-
if (!
|
|
42031
|
+
if (!existsSync26(dir)) {
|
|
41941
42032
|
return { pushed: 0, pulled: 0, errors: [`Task list directory not found: ${dir}`] };
|
|
41942
42033
|
}
|
|
41943
42034
|
const files = readdirSync5(dir).filter((f) => f.endsWith(".json"));
|
|
@@ -42028,7 +42119,7 @@ function syncClaudeTaskList(taskListId, projectId, options = {}) {
|
|
|
42028
42119
|
init_tasks();
|
|
42029
42120
|
init_sync_utils();
|
|
42030
42121
|
init_config();
|
|
42031
|
-
import { existsSync as
|
|
42122
|
+
import { existsSync as existsSync27 } from "fs";
|
|
42032
42123
|
import { join as join25 } from "path";
|
|
42033
42124
|
function agentBaseDir(agent) {
|
|
42034
42125
|
const key = `TODOS_${agent.toUpperCase()}_TASKS_DIR`;
|
|
@@ -42066,7 +42157,7 @@ function metadataKey(agent) {
|
|
|
42066
42157
|
}
|
|
42067
42158
|
function pushToAgentTaskList(agent, taskListId, projectId, options = {}) {
|
|
42068
42159
|
const dir = getTaskListDir2(agent, taskListId);
|
|
42069
|
-
if (!
|
|
42160
|
+
if (!existsSync27(dir))
|
|
42070
42161
|
ensureDir2(dir);
|
|
42071
42162
|
const filter = {};
|
|
42072
42163
|
if (projectId)
|
|
@@ -42149,7 +42240,7 @@ function pushToAgentTaskList(agent, taskListId, projectId, options = {}) {
|
|
|
42149
42240
|
}
|
|
42150
42241
|
function pullFromAgentTaskList(agent, taskListId, projectId, options = {}) {
|
|
42151
42242
|
const dir = getTaskListDir2(agent, taskListId);
|
|
42152
|
-
if (!
|
|
42243
|
+
if (!existsSync27(dir)) {
|
|
42153
42244
|
return { pushed: 0, pulled: 0, errors: [`Task list directory not found: ${dir}`] };
|
|
42154
42245
|
}
|
|
42155
42246
|
const files = listJsonFiles(dir);
|
|
@@ -42308,7 +42399,7 @@ function syncWithAgents(agents, taskListIdByAgent, projectId, direction = "both"
|
|
|
42308
42399
|
// src/lib/extract.ts
|
|
42309
42400
|
init_tasks();
|
|
42310
42401
|
init_task_files();
|
|
42311
|
-
import { existsSync as
|
|
42402
|
+
import { existsSync as existsSync28, readFileSync as readFileSync24, statSync as statSync10 } from "fs";
|
|
42312
42403
|
import { createHash as createHash15 } from "crypto";
|
|
42313
42404
|
import { relative as relative6, resolve as resolve18, join as join26 } from "path";
|
|
42314
42405
|
var EXTRACT_TAGS = ["TODO", "FIXME", "HACK", "XXX", "BUG", "NOTE"];
|
|
@@ -42380,9 +42471,9 @@ function normalizePathForMatch(value) {
|
|
|
42380
42471
|
return value.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
42381
42472
|
}
|
|
42382
42473
|
function readGitignorePatterns(basePath) {
|
|
42383
|
-
const root =
|
|
42474
|
+
const root = statSync10(basePath).isFile() ? resolve18(basePath, "..") : basePath;
|
|
42384
42475
|
const gitignorePath = join26(root, ".gitignore");
|
|
42385
|
-
if (!
|
|
42476
|
+
if (!existsSync28(gitignorePath))
|
|
42386
42477
|
return [];
|
|
42387
42478
|
try {
|
|
42388
42479
|
return readFileSync24(gitignorePath, "utf-8").split(`
|
|
@@ -42491,7 +42582,7 @@ function extractFromSource(source9, filePath, tags = [...EXTRACT_TAGS]) {
|
|
|
42491
42582
|
return results;
|
|
42492
42583
|
}
|
|
42493
42584
|
function collectFiles(basePath, extensions, excludes, respectGitignore) {
|
|
42494
|
-
const stat =
|
|
42585
|
+
const stat = statSync10(basePath);
|
|
42495
42586
|
if (stat.isFile()) {
|
|
42496
42587
|
return [basePath];
|
|
42497
42588
|
}
|
|
@@ -42524,10 +42615,10 @@ function buildCodebaseIndex(options) {
|
|
|
42524
42615
|
const files = collectFiles(basePath, extensions, excludes, respectGitignore);
|
|
42525
42616
|
const indexed = [];
|
|
42526
42617
|
for (const file of files) {
|
|
42527
|
-
const fullPath =
|
|
42618
|
+
const fullPath = statSync10(basePath).isFile() ? basePath : join26(basePath, file);
|
|
42528
42619
|
try {
|
|
42529
42620
|
const source9 = readFileSync24(fullPath, "utf-8");
|
|
42530
|
-
const relPath =
|
|
42621
|
+
const relPath = statSync10(basePath).isFile() ? relative6(resolve18(basePath, ".."), fullPath) : file;
|
|
42531
42622
|
indexed.push({
|
|
42532
42623
|
file: relPath,
|
|
42533
42624
|
checksum: stableHash(source9).slice(0, 24),
|
|
@@ -42555,10 +42646,10 @@ function extractTodos(options, db) {
|
|
|
42555
42646
|
const files = collectFiles(basePath, extensions, excludes, respectGitignore);
|
|
42556
42647
|
const allComments = [];
|
|
42557
42648
|
for (const file of files) {
|
|
42558
|
-
const fullPath =
|
|
42649
|
+
const fullPath = statSync10(basePath).isFile() ? basePath : join26(basePath, file);
|
|
42559
42650
|
try {
|
|
42560
42651
|
const source9 = readFileSync24(fullPath, "utf-8");
|
|
42561
|
-
const relPath =
|
|
42652
|
+
const relPath = statSync10(basePath).isFile() ? relative6(resolve18(basePath, ".."), fullPath) : file;
|
|
42562
42653
|
const comments = extractFromSource(source9, relPath, tags);
|
|
42563
42654
|
allComments.push(...comments);
|
|
42564
42655
|
} catch {}
|
|
@@ -43532,7 +43623,7 @@ function renderAgentReplaySimulationMarkdown(simulation) {
|
|
|
43532
43623
|
// src/lib/local-extensions.ts
|
|
43533
43624
|
init_config();
|
|
43534
43625
|
import { createHash as createHash17, createVerify } from "crypto";
|
|
43535
|
-
import { existsSync as
|
|
43626
|
+
import { existsSync as existsSync29, readdirSync as readdirSync6, readFileSync as readFileSync26, statSync as statSync11 } from "fs";
|
|
43536
43627
|
import { basename as basename6, join as join27, resolve as resolve19 } from "path";
|
|
43537
43628
|
init_redaction();
|
|
43538
43629
|
init_runner_sandbox();
|
|
@@ -43815,10 +43906,10 @@ function verifyExtensionSignature(input) {
|
|
|
43815
43906
|
}
|
|
43816
43907
|
function inspectExtensionSource(source9) {
|
|
43817
43908
|
const resolved = resolve19(source9);
|
|
43818
|
-
if (!
|
|
43909
|
+
if (!existsSync29(resolved))
|
|
43819
43910
|
throw new Error(`extension source not found: ${source9}`);
|
|
43820
|
-
const stat =
|
|
43821
|
-
const manifestPath = stat.isDirectory() ? [join27(resolved, "todos.extension.json"), join27(resolved, "extension.json")].find(
|
|
43911
|
+
const stat = statSync11(resolved);
|
|
43912
|
+
const manifestPath = stat.isDirectory() ? [join27(resolved, "todos.extension.json"), join27(resolved, "extension.json")].find(existsSync29) : resolved;
|
|
43822
43913
|
if (!manifestPath)
|
|
43823
43914
|
throw new Error(`extension directory ${source9} is missing todos.extension.json`);
|
|
43824
43915
|
const raw = readFileSync26(manifestPath);
|
|
@@ -43918,16 +44009,16 @@ function projectExtensionSources(projectPath) {
|
|
|
43918
44009
|
join27(root, ".todos", "todos.extension.json")
|
|
43919
44010
|
];
|
|
43920
44011
|
const extensionDir = join27(root, ".todos", "extensions");
|
|
43921
|
-
if (
|
|
44012
|
+
if (existsSync29(extensionDir)) {
|
|
43922
44013
|
for (const entry2 of readdirSync6(extensionDir)) {
|
|
43923
44014
|
if (entry2.startsWith("."))
|
|
43924
44015
|
continue;
|
|
43925
44016
|
const full = join27(extensionDir, entry2);
|
|
43926
|
-
if (
|
|
44017
|
+
if (statSync11(full).isDirectory() || entry2.endsWith(".json"))
|
|
43927
44018
|
candidates.push(full);
|
|
43928
44019
|
}
|
|
43929
44020
|
}
|
|
43930
|
-
return candidates.filter(
|
|
44021
|
+
return candidates.filter(existsSync29);
|
|
43931
44022
|
}
|
|
43932
44023
|
function discoverLocalExtensions(options = {}) {
|
|
43933
44024
|
const config = loadConfig();
|
|
@@ -44799,7 +44890,7 @@ init_redaction();
|
|
|
44799
44890
|
// src/lib/retention-cleanup.ts
|
|
44800
44891
|
init_artifact_store();
|
|
44801
44892
|
init_database();
|
|
44802
|
-
import { existsSync as
|
|
44893
|
+
import { existsSync as existsSync30, unlinkSync as unlinkSync2 } from "fs";
|
|
44803
44894
|
var RETENTION_CLEANUP_CONFIRMATION = "delete-local-retention-data";
|
|
44804
44895
|
var ALL_SCOPES = ["comments", "runs", "verifications", "expired_artifacts"];
|
|
44805
44896
|
var EMPTY_COUNTS = {
|
|
@@ -45010,7 +45101,7 @@ function applyRetentionCleanup(input, db) {
|
|
|
45010
45101
|
for (const artifact of report.candidates.artifact_files) {
|
|
45011
45102
|
try {
|
|
45012
45103
|
const path = artifactStorePath(artifact.relative_path);
|
|
45013
|
-
if (!
|
|
45104
|
+
if (!existsSync30(path)) {
|
|
45014
45105
|
report.warnings.push(`stored artifact already missing: ${artifact.relative_path}`);
|
|
45015
45106
|
continue;
|
|
45016
45107
|
}
|
|
@@ -45254,7 +45345,7 @@ init_database();
|
|
|
45254
45345
|
init_migrations();
|
|
45255
45346
|
init_schema();
|
|
45256
45347
|
init_recurrence();
|
|
45257
|
-
import { chmodSync, copyFileSync as copyFileSync2, existsSync as
|
|
45348
|
+
import { chmodSync, copyFileSync as copyFileSync2, existsSync as existsSync31, mkdirSync as mkdirSync22, statSync as statSync12 } from "fs";
|
|
45258
45349
|
import { basename as basename7, dirname as dirname19, join as join28 } from "path";
|
|
45259
45350
|
var REQUIRED_TABLES2 = [
|
|
45260
45351
|
"_migrations",
|
|
@@ -45362,7 +45453,7 @@ function findMissingProjectRoots(db) {
|
|
|
45362
45453
|
continue;
|
|
45363
45454
|
if (!row.path.startsWith("/"))
|
|
45364
45455
|
continue;
|
|
45365
|
-
if (!
|
|
45456
|
+
if (!existsSync31(row.path))
|
|
45366
45457
|
missing++;
|
|
45367
45458
|
}
|
|
45368
45459
|
return missing;
|
|
@@ -45414,7 +45505,7 @@ function databasePermissionsAreUnsafe(dbPath) {
|
|
|
45414
45505
|
if (dbPath === ":memory:" || dbPath.startsWith("file::memory:"))
|
|
45415
45506
|
return false;
|
|
45416
45507
|
try {
|
|
45417
|
-
return (
|
|
45508
|
+
return (statSync12(dbPath).mode & 63) !== 0;
|
|
45418
45509
|
} catch {
|
|
45419
45510
|
return false;
|
|
45420
45511
|
}
|
|
@@ -45422,14 +45513,14 @@ function databasePermissionsAreUnsafe(dbPath) {
|
|
|
45422
45513
|
function createBackup(dbPath) {
|
|
45423
45514
|
if (dbPath === ":memory:" || dbPath.startsWith("file::memory:"))
|
|
45424
45515
|
return;
|
|
45425
|
-
if (!
|
|
45516
|
+
if (!existsSync31(dbPath))
|
|
45426
45517
|
return;
|
|
45427
45518
|
const stamp = now().replace(/[:.]/g, "-");
|
|
45428
45519
|
const backupDir = join28(dirname19(dbPath), `${basename7(dbPath)}.backup-${stamp}`);
|
|
45429
45520
|
const files = [];
|
|
45430
45521
|
mkdirSync22(backupDir, { recursive: true });
|
|
45431
45522
|
for (const source9 of [dbPath, `${dbPath}-wal`, `${dbPath}-shm`]) {
|
|
45432
|
-
if (!
|
|
45523
|
+
if (!existsSync31(source9))
|
|
45433
45524
|
continue;
|
|
45434
45525
|
const target = join28(backupDir, basename7(source9));
|
|
45435
45526
|
copyFileSync2(source9, target);
|