@hasna/todos 0.11.71 → 0.11.72
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/query-commands.d.ts.map +1 -1
- package/dist/cli/index.js +444 -53
- package/dist/contracts.js +24 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +765 -422
- package/dist/lib/shared-events.d.ts.map +1 -1
- package/dist/lib/task-route-contract.d.ts +2 -1
- package/dist/lib/task-route-contract.d.ts.map +1 -1
- package/dist/lib/task-route-sources.d.ts +68 -0
- package/dist/lib/task-route-sources.d.ts.map +1 -0
- package/dist/lib/task-routing.d.ts.map +1 -1
- package/dist/mcp/index.js +24 -5
- package/dist/registry.js +24 -5
- package/dist/release-provenance.json +3 -3
- package/dist/server/index.js +26 -7
- package/dist/storage.js +24 -5
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1011,7 +1011,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1011
1011
|
this._exitCallback = (err) => {
|
|
1012
1012
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
1013
1013
|
throw err;
|
|
1014
|
-
}
|
|
1014
|
+
} else {}
|
|
1015
1015
|
};
|
|
1016
1016
|
}
|
|
1017
1017
|
return this;
|
|
@@ -7215,8 +7215,6 @@ function routeEnabledForTask(task, taskList) {
|
|
|
7215
7215
|
const explicit = booleanField(task.metadata.route_enabled);
|
|
7216
7216
|
if (explicit !== undefined)
|
|
7217
7217
|
return explicit;
|
|
7218
|
-
if (task.tags.includes("auto:route") || task.tags.includes("route:enabled"))
|
|
7219
|
-
return true;
|
|
7220
7218
|
const taskListDefault = taskList ? booleanField(taskList.metadata.route_enabled) : undefined;
|
|
7221
7219
|
if (taskListDefault !== undefined)
|
|
7222
7220
|
return taskListDefault;
|
|
@@ -7238,8 +7236,26 @@ function workflowPointersFromMetadata(metadata) {
|
|
|
7238
7236
|
function compactWorkflowPointers(pointers) {
|
|
7239
7237
|
return Object.fromEntries(Object.entries(pointers).filter(([, value]) => typeof value === "string" && value.length > 0));
|
|
7240
7238
|
}
|
|
7241
|
-
function
|
|
7242
|
-
|
|
7239
|
+
function metadataStringField(record, keys) {
|
|
7240
|
+
if (!record)
|
|
7241
|
+
return;
|
|
7242
|
+
for (const key of keys) {
|
|
7243
|
+
const value = record[key];
|
|
7244
|
+
if (typeof value === "string" && value.trim())
|
|
7245
|
+
return value.trim();
|
|
7246
|
+
}
|
|
7247
|
+
return;
|
|
7248
|
+
}
|
|
7249
|
+
function projectKindFromMetadata(...records) {
|
|
7250
|
+
for (const record of records) {
|
|
7251
|
+
const value = metadataStringField(record ?? undefined, ["project_kind", "projectKind", "source_kind", "sourceKind"]);
|
|
7252
|
+
if (value)
|
|
7253
|
+
return value;
|
|
7254
|
+
}
|
|
7255
|
+
return null;
|
|
7256
|
+
}
|
|
7257
|
+
function classifyProjectKind(_path, metadata) {
|
|
7258
|
+
return projectKindFromMetadata(metadata);
|
|
7243
7259
|
}
|
|
7244
7260
|
function isWorktreePath(path) {
|
|
7245
7261
|
return path.includes("/.codewith/worktrees/") || path.includes("/.worktrees/");
|
|
@@ -7312,7 +7328,6 @@ function taskEventMetadata(task) {
|
|
|
7312
7328
|
metadata.project_canonical_path = projectPath;
|
|
7313
7329
|
}
|
|
7314
7330
|
if (projectPath) {
|
|
7315
|
-
metadata.project_kind = classifyProjectKind(projectPath);
|
|
7316
7331
|
metadata.project_is_worktree = isWorktreePath(projectPath);
|
|
7317
7332
|
metadata.working_dir = task.working_dir ?? projectPath;
|
|
7318
7333
|
}
|
|
@@ -7324,6 +7339,10 @@ function taskEventMetadata(task) {
|
|
|
7324
7339
|
metadata.task_list_project_id = taskList.project_id;
|
|
7325
7340
|
metadata.task_list_is_project_default = Boolean(project?.task_list_id && taskList.slug === project.task_list_id);
|
|
7326
7341
|
}
|
|
7342
|
+
const projectKind = projectKindFromMetadata(task.metadata, taskList?.metadata);
|
|
7343
|
+
if (projectKind) {
|
|
7344
|
+
metadata.project_kind = classifyProjectKind(projectPath ?? "", { project_kind: projectKind });
|
|
7345
|
+
}
|
|
7327
7346
|
const routeEnabled = routeEnabledForTask(task, taskList);
|
|
7328
7347
|
if (routeEnabled !== undefined) {
|
|
7329
7348
|
metadata.route_enabled = routeEnabled;
|
|
@@ -12742,11 +12761,6 @@ __export(exports_task_routing, {
|
|
|
12742
12761
|
setTaskWorkflowPointers: () => setTaskWorkflowPointers,
|
|
12743
12762
|
getTaskRouteState: () => getTaskRouteState
|
|
12744
12763
|
});
|
|
12745
|
-
function classifyProjectKind2(path) {
|
|
12746
|
-
if (!path)
|
|
12747
|
-
return null;
|
|
12748
|
-
return path.includes("/hasna/opensource/") ? "open-source" : "unknown";
|
|
12749
|
-
}
|
|
12750
12764
|
function machineLocalPath(project, db) {
|
|
12751
12765
|
const machineId = process.env["TODOS_MACHINE_ID"];
|
|
12752
12766
|
if (!machineId)
|
|
@@ -12794,6 +12808,7 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
12794
12808
|
const automation = routingAutomationMetadata(task, taskList) ?? {};
|
|
12795
12809
|
const routeEnabled = routeEnabledForTask(task, taskList) === true;
|
|
12796
12810
|
const tagOptIn = task.tags.includes("auto:route") || task.tags.includes("route:enabled");
|
|
12811
|
+
const projectKind = projectKindFromMetadata(task.metadata, taskList?.metadata);
|
|
12797
12812
|
const locked = Boolean(task.locked_by && !isLockExpired(task.locked_at));
|
|
12798
12813
|
const blockers = getBlockingDeps(task.id, d);
|
|
12799
12814
|
const blocked = blockers.length > 0;
|
|
@@ -12856,7 +12871,7 @@ function getTaskRouteState(taskOrId, db) {
|
|
|
12856
12871
|
project_id: project?.id ?? task.project_id,
|
|
12857
12872
|
project_path: projectPath,
|
|
12858
12873
|
working_dir: task.working_dir ?? projectPath,
|
|
12859
|
-
project_kind:
|
|
12874
|
+
project_kind: projectKind,
|
|
12860
12875
|
task_list_id: taskList?.id ?? task.task_list_id,
|
|
12861
12876
|
task_list_slug: taskList?.slug ?? null,
|
|
12862
12877
|
task_list_name: taskList?.name ?? null,
|
|
@@ -55219,6 +55234,339 @@ var init_config_serve_commands = __esm(() => {
|
|
|
55219
55234
|
init_helpers();
|
|
55220
55235
|
});
|
|
55221
55236
|
|
|
55237
|
+
// src/lib/task-route-sources.ts
|
|
55238
|
+
var exports_task_route_sources = {};
|
|
55239
|
+
__export(exports_task_route_sources, {
|
|
55240
|
+
discoverTaskRouteSources: () => discoverTaskRouteSources,
|
|
55241
|
+
TASK_ROUTE_SOURCE_DISCOVERY_SCHEMA_VERSION: () => TASK_ROUTE_SOURCE_DISCOVERY_SCHEMA_VERSION
|
|
55242
|
+
});
|
|
55243
|
+
import { Database as Database3 } from "bun:sqlite";
|
|
55244
|
+
import { createHash as createHash13 } from "crypto";
|
|
55245
|
+
import { existsSync as existsSync21, readdirSync as readdirSync5, statSync as statSync9 } from "fs";
|
|
55246
|
+
import { basename as basename9, dirname as dirname12, join as join21, resolve as resolve21 } from "path";
|
|
55247
|
+
function normalizePath5(input) {
|
|
55248
|
+
return resolve21(input);
|
|
55249
|
+
}
|
|
55250
|
+
function sourceStoreId(sourceDbPath) {
|
|
55251
|
+
const digest = createHash13("sha256").update(sourceDbPath).digest("hex").slice(0, 16);
|
|
55252
|
+
return `sqlite:${digest}`;
|
|
55253
|
+
}
|
|
55254
|
+
function inferSourceRepoPath(sourceDbPath) {
|
|
55255
|
+
const normalized = normalizePath5(sourceDbPath);
|
|
55256
|
+
if (normalized.endsWith(TODO_STORE_RELATIVE_PATH)) {
|
|
55257
|
+
return dirname12(dirname12(dirname12(normalized)));
|
|
55258
|
+
}
|
|
55259
|
+
return dirname12(normalized);
|
|
55260
|
+
}
|
|
55261
|
+
function createStoreRef(sourceDbPath) {
|
|
55262
|
+
const normalized = normalizePath5(sourceDbPath);
|
|
55263
|
+
return {
|
|
55264
|
+
source_store_id: sourceStoreId(normalized),
|
|
55265
|
+
source_repo_path: inferSourceRepoPath(normalized),
|
|
55266
|
+
source_db_path: normalized
|
|
55267
|
+
};
|
|
55268
|
+
}
|
|
55269
|
+
function normalizePatterns(patterns) {
|
|
55270
|
+
return (patterns ?? []).map((pattern) => pattern.trim()).filter(Boolean);
|
|
55271
|
+
}
|
|
55272
|
+
function escapeRegExp(value) {
|
|
55273
|
+
return value.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
|
|
55274
|
+
}
|
|
55275
|
+
function globPatternToRegExp(pattern) {
|
|
55276
|
+
let source3 = "";
|
|
55277
|
+
for (const char of pattern) {
|
|
55278
|
+
if (char === "*")
|
|
55279
|
+
source3 += ".*";
|
|
55280
|
+
else if (char === "?")
|
|
55281
|
+
source3 += ".";
|
|
55282
|
+
else
|
|
55283
|
+
source3 += escapeRegExp(char);
|
|
55284
|
+
}
|
|
55285
|
+
return new RegExp(`^${source3}$`);
|
|
55286
|
+
}
|
|
55287
|
+
function matchesPattern4(value, pattern) {
|
|
55288
|
+
const normalizedValue = value.replace(/\\/g, "/");
|
|
55289
|
+
const normalizedPattern = pattern.replace(/\\/g, "/");
|
|
55290
|
+
if (normalizedPattern.includes("*") || normalizedPattern.includes("?")) {
|
|
55291
|
+
return globPatternToRegExp(normalizedPattern).test(normalizedValue);
|
|
55292
|
+
}
|
|
55293
|
+
return normalizedValue.includes(normalizedPattern);
|
|
55294
|
+
}
|
|
55295
|
+
function storeMatchesAny(ref, patterns) {
|
|
55296
|
+
if (patterns.length === 0)
|
|
55297
|
+
return false;
|
|
55298
|
+
const paths = [ref.source_db_path, ref.source_repo_path].filter((value) => Boolean(value));
|
|
55299
|
+
const values = paths.flatMap((value) => [value, basename9(value)]);
|
|
55300
|
+
return patterns.some((pattern) => values.some((value) => matchesPattern4(value, pattern)));
|
|
55301
|
+
}
|
|
55302
|
+
function shouldIncludeStore(ref, include, exclude) {
|
|
55303
|
+
const included = include.length === 0 || storeMatchesAny(ref, include);
|
|
55304
|
+
return included && !storeMatchesAny(ref, exclude);
|
|
55305
|
+
}
|
|
55306
|
+
function discoverStoresUnderRoot(sourceRoot) {
|
|
55307
|
+
const rootPath = normalizePath5(sourceRoot);
|
|
55308
|
+
const errors2 = [];
|
|
55309
|
+
const stores = [];
|
|
55310
|
+
if (!existsSync21(rootPath)) {
|
|
55311
|
+
const ref = createStoreRef(join21(rootPath, TODO_STORE_RELATIVE_PATH));
|
|
55312
|
+
errors2.push({
|
|
55313
|
+
...ref,
|
|
55314
|
+
code: "SOURCE_ROOT_MISSING",
|
|
55315
|
+
message: `Source root does not exist: ${rootPath}`
|
|
55316
|
+
});
|
|
55317
|
+
return { stores, errors: errors2 };
|
|
55318
|
+
}
|
|
55319
|
+
let rootStat;
|
|
55320
|
+
try {
|
|
55321
|
+
rootStat = statSync9(rootPath);
|
|
55322
|
+
} catch (error) {
|
|
55323
|
+
const ref = createStoreRef(join21(rootPath, TODO_STORE_RELATIVE_PATH));
|
|
55324
|
+
errors2.push({
|
|
55325
|
+
...ref,
|
|
55326
|
+
code: "SOURCE_ROOT_UNREADABLE",
|
|
55327
|
+
message: error instanceof Error ? error.message : `Unable to read source root: ${rootPath}`
|
|
55328
|
+
});
|
|
55329
|
+
return { stores, errors: errors2 };
|
|
55330
|
+
}
|
|
55331
|
+
if (rootStat.isFile()) {
|
|
55332
|
+
stores.push(createStoreRef(rootPath));
|
|
55333
|
+
return { stores, errors: errors2 };
|
|
55334
|
+
}
|
|
55335
|
+
function scanDirectory(dir, depth) {
|
|
55336
|
+
const candidate = join21(dir, TODO_STORE_RELATIVE_PATH);
|
|
55337
|
+
if (existsSync21(candidate)) {
|
|
55338
|
+
stores.push(createStoreRef(candidate));
|
|
55339
|
+
}
|
|
55340
|
+
if (depth >= ROOT_SCAN_MAX_DEPTH)
|
|
55341
|
+
return;
|
|
55342
|
+
let entries;
|
|
55343
|
+
try {
|
|
55344
|
+
entries = readdirSync5(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
55345
|
+
} catch (error) {
|
|
55346
|
+
const ref = createStoreRef(candidate);
|
|
55347
|
+
errors2.push({
|
|
55348
|
+
...ref,
|
|
55349
|
+
code: "SOURCE_ROOT_UNREADABLE",
|
|
55350
|
+
message: error instanceof Error ? error.message : `Unable to read source root: ${dir}`
|
|
55351
|
+
});
|
|
55352
|
+
return;
|
|
55353
|
+
}
|
|
55354
|
+
for (const entry of entries) {
|
|
55355
|
+
if (!entry.isDirectory() || SKIPPED_SCAN_DIRS.has(entry.name))
|
|
55356
|
+
continue;
|
|
55357
|
+
scanDirectory(join21(dir, entry.name), depth + 1);
|
|
55358
|
+
}
|
|
55359
|
+
}
|
|
55360
|
+
scanDirectory(rootPath, 0);
|
|
55361
|
+
return { stores, errors: errors2 };
|
|
55362
|
+
}
|
|
55363
|
+
function collectStoreRefs(input) {
|
|
55364
|
+
const byPath = new Map;
|
|
55365
|
+
const errors2 = [];
|
|
55366
|
+
for (const storePath of input.sourceStores ?? []) {
|
|
55367
|
+
const ref = createStoreRef(storePath);
|
|
55368
|
+
byPath.set(ref.source_db_path, ref);
|
|
55369
|
+
}
|
|
55370
|
+
for (const sourceRoot of input.sourceRoots ?? []) {
|
|
55371
|
+
const discovered = discoverStoresUnderRoot(sourceRoot);
|
|
55372
|
+
for (const ref of discovered.stores) {
|
|
55373
|
+
byPath.set(ref.source_db_path, ref);
|
|
55374
|
+
}
|
|
55375
|
+
errors2.push(...discovered.errors);
|
|
55376
|
+
}
|
|
55377
|
+
return {
|
|
55378
|
+
stores: [...byPath.values()].sort((a, b) => a.source_db_path.localeCompare(b.source_db_path)),
|
|
55379
|
+
errors: errors2.sort((a, b) => a.source_db_path.localeCompare(b.source_db_path))
|
|
55380
|
+
};
|
|
55381
|
+
}
|
|
55382
|
+
function openReadonlyStore(ref) {
|
|
55383
|
+
if (!existsSync21(ref.source_db_path)) {
|
|
55384
|
+
throw Object.assign(new Error(`Store does not exist: ${ref.source_db_path}`), { code: "STORE_MISSING" });
|
|
55385
|
+
}
|
|
55386
|
+
return new Database3(ref.source_db_path, { readonly: true, create: false });
|
|
55387
|
+
}
|
|
55388
|
+
function hasTable2(db, tableName) {
|
|
55389
|
+
const row = db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = ?").get(tableName);
|
|
55390
|
+
return Boolean(row);
|
|
55391
|
+
}
|
|
55392
|
+
function tableColumns2(db, tableName) {
|
|
55393
|
+
const rows = db.query(`PRAGMA table_info(${tableName})`).all();
|
|
55394
|
+
return new Set(rows.map((row) => row.name));
|
|
55395
|
+
}
|
|
55396
|
+
function listPendingTasksReadonly(db) {
|
|
55397
|
+
if (!hasTable2(db, "tasks")) {
|
|
55398
|
+
throw Object.assign(new Error("Store does not contain a tasks table"), { code: "STORE_INVALID" });
|
|
55399
|
+
}
|
|
55400
|
+
const columns = tableColumns2(db, "tasks");
|
|
55401
|
+
const conditions = ["status = 'pending'"];
|
|
55402
|
+
if (columns.has("archived_at"))
|
|
55403
|
+
conditions.push("archived_at IS NULL");
|
|
55404
|
+
const rows = db.query(`SELECT * FROM tasks WHERE ${conditions.join(" AND ")}
|
|
55405
|
+
ORDER BY CASE priority WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 END, created_at DESC`).all();
|
|
55406
|
+
return rows.map(rowToTask);
|
|
55407
|
+
}
|
|
55408
|
+
function isReadyTask(task2, db) {
|
|
55409
|
+
if (task2.locked_by && !isLockExpired(task2.locked_at))
|
|
55410
|
+
return false;
|
|
55411
|
+
return getBlockingDeps(task2.id, db).length === 0;
|
|
55412
|
+
}
|
|
55413
|
+
function metadataFingerprint(metadata) {
|
|
55414
|
+
const value = metadata.fingerprint;
|
|
55415
|
+
if (typeof value === "string" && value.trim())
|
|
55416
|
+
return value;
|
|
55417
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
55418
|
+
return String(value);
|
|
55419
|
+
return null;
|
|
55420
|
+
}
|
|
55421
|
+
function boundedMetadataValue(value, depth = 0) {
|
|
55422
|
+
if (depth > 6)
|
|
55423
|
+
return "[TRUNCATED]";
|
|
55424
|
+
if (typeof value === "string") {
|
|
55425
|
+
return value.length > 2000 ? `${value.slice(0, 2000)}[TRUNCATED]` : value;
|
|
55426
|
+
}
|
|
55427
|
+
if (Array.isArray(value)) {
|
|
55428
|
+
return value.slice(0, 50).map((item) => boundedMetadataValue(item, depth + 1));
|
|
55429
|
+
}
|
|
55430
|
+
if (value && typeof value === "object") {
|
|
55431
|
+
const result = {};
|
|
55432
|
+
for (const [key, child] of Object.entries(value).slice(0, 80)) {
|
|
55433
|
+
const normalized = key.toLowerCase();
|
|
55434
|
+
if (normalized === "comment" || normalized === "comments" || normalized === "task_comments") {
|
|
55435
|
+
result[key] = "[REDACTED_COMMENT]";
|
|
55436
|
+
continue;
|
|
55437
|
+
}
|
|
55438
|
+
result[key] = boundedMetadataValue(child, depth + 1);
|
|
55439
|
+
}
|
|
55440
|
+
return result;
|
|
55441
|
+
}
|
|
55442
|
+
return value;
|
|
55443
|
+
}
|
|
55444
|
+
function discoveryMetadata(metadata) {
|
|
55445
|
+
return redactValue(boundedMetadataValue(metadata));
|
|
55446
|
+
}
|
|
55447
|
+
function sourceCandidate(ref, task2, db) {
|
|
55448
|
+
const routeState = getTaskRouteState(task2, db);
|
|
55449
|
+
const autoRoute = task2.tags.includes("auto:route") || task2.tags.includes("route:enabled");
|
|
55450
|
+
return {
|
|
55451
|
+
source_store_id: ref.source_store_id,
|
|
55452
|
+
source_repo_path: ref.source_repo_path,
|
|
55453
|
+
source_db_path: ref.source_db_path,
|
|
55454
|
+
source_task_key: `${ref.source_store_id}:${task2.id}`,
|
|
55455
|
+
source_selected_by_input: true,
|
|
55456
|
+
task_id: task2.id,
|
|
55457
|
+
task_short_id: task2.short_id,
|
|
55458
|
+
title: task2.title,
|
|
55459
|
+
status: task2.status,
|
|
55460
|
+
priority: task2.priority,
|
|
55461
|
+
project_path: routeState.route.project_path ?? task2.working_dir ?? ref.source_repo_path,
|
|
55462
|
+
task_version: task2.version,
|
|
55463
|
+
task_updated_at: task2.updated_at,
|
|
55464
|
+
task_fingerprint: metadataFingerprint(task2.metadata),
|
|
55465
|
+
tags: task2.tags,
|
|
55466
|
+
task_intent: {
|
|
55467
|
+
auto_route: autoRoute
|
|
55468
|
+
},
|
|
55469
|
+
metadata: discoveryMetadata(task2.metadata),
|
|
55470
|
+
route_state: routeState
|
|
55471
|
+
};
|
|
55472
|
+
}
|
|
55473
|
+
function discoveryError(ref, code, error) {
|
|
55474
|
+
return {
|
|
55475
|
+
...ref,
|
|
55476
|
+
code,
|
|
55477
|
+
message: error instanceof Error ? error.message : String(error)
|
|
55478
|
+
};
|
|
55479
|
+
}
|
|
55480
|
+
function errorCode(error) {
|
|
55481
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "STORE_MISSING") {
|
|
55482
|
+
return "STORE_MISSING";
|
|
55483
|
+
}
|
|
55484
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "STORE_INVALID") {
|
|
55485
|
+
return "STORE_INVALID";
|
|
55486
|
+
}
|
|
55487
|
+
return "STORE_UNREADABLE";
|
|
55488
|
+
}
|
|
55489
|
+
function discoverTaskRouteSources(input) {
|
|
55490
|
+
const include = normalizePatterns(input.include);
|
|
55491
|
+
const exclude = normalizePatterns(input.exclude);
|
|
55492
|
+
const sourceRoots = (input.sourceRoots ?? []).map(normalizePath5).sort();
|
|
55493
|
+
const sourceStores = (input.sourceStores ?? []).map(normalizePath5).sort();
|
|
55494
|
+
const limit = Number.isFinite(input.limit ?? NaN) && (input.limit ?? 0) >= 0 ? Math.floor(input.limit ?? 0) : null;
|
|
55495
|
+
const collected = collectStoreRefs(input);
|
|
55496
|
+
const stores = [];
|
|
55497
|
+
const errors2 = [...collected.errors];
|
|
55498
|
+
const candidates = [];
|
|
55499
|
+
let totalCandidateCount = 0;
|
|
55500
|
+
for (const ref of collected.stores) {
|
|
55501
|
+
if (!shouldIncludeStore(ref, include, exclude))
|
|
55502
|
+
continue;
|
|
55503
|
+
const storeErrors = [];
|
|
55504
|
+
let db = null;
|
|
55505
|
+
try {
|
|
55506
|
+
db = openReadonlyStore(ref);
|
|
55507
|
+
const readyTasks = listPendingTasksReadonly(db).filter((task2) => isReadyTask(task2, db));
|
|
55508
|
+
totalCandidateCount += readyTasks.length;
|
|
55509
|
+
const remaining = limit === null ? readyTasks.length : Math.max(0, limit - candidates.length);
|
|
55510
|
+
const selectedTasks = limit === null ? readyTasks : readyTasks.slice(0, remaining);
|
|
55511
|
+
candidates.push(...selectedTasks.map((task2) => sourceCandidate(ref, task2, db)));
|
|
55512
|
+
stores.push({
|
|
55513
|
+
...ref,
|
|
55514
|
+
status: "ok",
|
|
55515
|
+
candidate_count: readyTasks.length,
|
|
55516
|
+
returned_candidate_count: selectedTasks.length,
|
|
55517
|
+
errors: []
|
|
55518
|
+
});
|
|
55519
|
+
} catch (error) {
|
|
55520
|
+
const storeError = discoveryError(ref, errorCode(error), error);
|
|
55521
|
+
storeErrors.push(storeError);
|
|
55522
|
+
errors2.push(storeError);
|
|
55523
|
+
stores.push({
|
|
55524
|
+
...ref,
|
|
55525
|
+
status: storeError.code === "STORE_MISSING" ? "missing" : "error",
|
|
55526
|
+
candidate_count: 0,
|
|
55527
|
+
returned_candidate_count: 0,
|
|
55528
|
+
errors: storeErrors
|
|
55529
|
+
});
|
|
55530
|
+
} finally {
|
|
55531
|
+
db?.close();
|
|
55532
|
+
}
|
|
55533
|
+
}
|
|
55534
|
+
return {
|
|
55535
|
+
schema_version: TASK_ROUTE_SOURCE_DISCOVERY_SCHEMA_VERSION,
|
|
55536
|
+
sourceRoots,
|
|
55537
|
+
sourceStores,
|
|
55538
|
+
include,
|
|
55539
|
+
exclude,
|
|
55540
|
+
limit,
|
|
55541
|
+
total_candidate_count: totalCandidateCount,
|
|
55542
|
+
returned_candidate_count: candidates.length,
|
|
55543
|
+
truncated: limit !== null && totalCandidateCount > candidates.length,
|
|
55544
|
+
stores,
|
|
55545
|
+
candidates,
|
|
55546
|
+
errors: errors2
|
|
55547
|
+
};
|
|
55548
|
+
}
|
|
55549
|
+
var TASK_ROUTE_SOURCE_DISCOVERY_SCHEMA_VERSION = "todos.task_route_sources.v1", TODO_STORE_RELATIVE_PATH, ROOT_SCAN_MAX_DEPTH = 5, SKIPPED_SCAN_DIRS;
|
|
55550
|
+
var init_task_route_sources = __esm(() => {
|
|
55551
|
+
init_database();
|
|
55552
|
+
init_task_lifecycle();
|
|
55553
|
+
init_task_crud();
|
|
55554
|
+
init_redaction();
|
|
55555
|
+
init_task_routing();
|
|
55556
|
+
TODO_STORE_RELATIVE_PATH = join21(".hasna", "todos", "todos.db");
|
|
55557
|
+
SKIPPED_SCAN_DIRS = new Set([
|
|
55558
|
+
".git",
|
|
55559
|
+
".hg",
|
|
55560
|
+
".svn",
|
|
55561
|
+
"node_modules",
|
|
55562
|
+
"dist",
|
|
55563
|
+
"build",
|
|
55564
|
+
".next",
|
|
55565
|
+
".turbo",
|
|
55566
|
+
".cache"
|
|
55567
|
+
]);
|
|
55568
|
+
});
|
|
55569
|
+
|
|
55222
55570
|
// src/lib/tester-issue-reports.ts
|
|
55223
55571
|
var exports_tester_issue_reports = {};
|
|
55224
55572
|
__export(exports_tester_issue_reports, {
|
|
@@ -55231,7 +55579,7 @@ __export(exports_tester_issue_reports, {
|
|
|
55231
55579
|
TESTERS_ISSUE_REPORT_RESULT_SCHEMA_VERSION: () => TESTERS_ISSUE_REPORT_RESULT_SCHEMA_VERSION,
|
|
55232
55580
|
TESTERS_ISSUE_REPORT_BATCH_RESULT_SCHEMA_VERSION: () => TESTERS_ISSUE_REPORT_BATCH_RESULT_SCHEMA_VERSION
|
|
55233
55581
|
});
|
|
55234
|
-
import { createHash as
|
|
55582
|
+
import { createHash as createHash14 } from "crypto";
|
|
55235
55583
|
function asObject3(value) {
|
|
55236
55584
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
55237
55585
|
}
|
|
@@ -55403,7 +55751,7 @@ function fingerprintTesterIssueReport(report) {
|
|
|
55403
55751
|
normalizeText4(report.failure?.message || report.summary || report.title).slice(0, 240),
|
|
55404
55752
|
normalizeText4(stackTop).slice(0, 160)
|
|
55405
55753
|
].join("::");
|
|
55406
|
-
return `testers:${
|
|
55754
|
+
return `testers:${createHash14("sha256").update(raw).digest("hex").slice(0, 16)}`;
|
|
55407
55755
|
}
|
|
55408
55756
|
function priorityForSeverity(severity, fallback) {
|
|
55409
55757
|
return PRIORITIES5.includes(severity) ? severity : fallback;
|
|
@@ -55722,6 +56070,15 @@ function parseCsvOption(value) {
|
|
|
55722
56070
|
const values = value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
55723
56071
|
return values.length > 0 ? values : undefined;
|
|
55724
56072
|
}
|
|
56073
|
+
function collectOption2(value, previous = []) {
|
|
56074
|
+
return [...previous, value];
|
|
56075
|
+
}
|
|
56076
|
+
function expandRepeatedCsvOption(value) {
|
|
56077
|
+
if (!value || value.length === 0)
|
|
56078
|
+
return;
|
|
56079
|
+
const values = value.flatMap((item) => item.split(",").map((part) => part.trim()).filter(Boolean));
|
|
56080
|
+
return values.length > 0 ? values : undefined;
|
|
56081
|
+
}
|
|
55725
56082
|
function resolveOptionalId(table, value) {
|
|
55726
56083
|
if (!value)
|
|
55727
56084
|
return;
|
|
@@ -56360,13 +56717,13 @@ Repairs`));
|
|
|
56360
56717
|
try {
|
|
56361
56718
|
const db = getDatabase();
|
|
56362
56719
|
const row = db.query("SELECT COUNT(*) as count FROM tasks").get();
|
|
56363
|
-
const { statSync:
|
|
56364
|
-
const { join:
|
|
56720
|
+
const { statSync: statSync10 } = await import("fs");
|
|
56721
|
+
const { join: join22 } = await import("path");
|
|
56365
56722
|
const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
|
|
56366
|
-
const dbPath = process.env["HASNA_TODOS_DB_PATH"] || process.env["TODOS_DB_PATH"] ||
|
|
56723
|
+
const dbPath = process.env["HASNA_TODOS_DB_PATH"] || process.env["TODOS_DB_PATH"] || join22(home, ".hasna", "todos", "todos.db");
|
|
56367
56724
|
let size = "unknown";
|
|
56368
56725
|
try {
|
|
56369
|
-
size = `${(
|
|
56726
|
+
size = `${(statSync10(dbPath).size / 1024 / 1024).toFixed(1)} MB`;
|
|
56370
56727
|
} catch {}
|
|
56371
56728
|
checks.push({ name: "Database", ok: true, message: `${row.count} tasks \xB7 ${size} \xB7 ${chalk7.dim(dbPath)}` });
|
|
56372
56729
|
} catch (e) {
|
|
@@ -56856,8 +57213,42 @@ Repairs`));
|
|
|
56856
57213
|
console.log(` ${chalk7.dim(time2)} ${chalk7.cyan(entry.source)} ${chalk7.dim(ref)} ${entry.event_type}${message}${agent}`);
|
|
56857
57214
|
}
|
|
56858
57215
|
});
|
|
56859
|
-
program2.command("ready").description("Show all tasks ready to be claimed (pending, unblocked, unlocked)").option("-j, --json", "Output as JSON").option("--project <id>", "Filter to project").option("--limit <n>", "Max tasks to show", "20").action(async (opts) => {
|
|
57216
|
+
program2.command("ready").description("Show all tasks ready to be claimed (pending, unblocked, unlocked)").option("-j, --json", "Output as JSON").option("--project <id>", "Filter to project").option("--limit <n>", "Max tasks to show", "20").option("--source-root <path>", "Read-only source root to scan for .hasna/todos/todos.db (repeatable)", collectOption2, []).option("--source-store <path>", "Read-only todos SQLite store path to scan (repeatable)", collectOption2, []).option("--include <pattern>", "Include source repo/store paths matching substring or glob (repeatable or comma-separated)", collectOption2, []).option("--exclude <pattern>", "Exclude source repo/store paths matching substring or glob (repeatable or comma-separated)", collectOption2, []).action(async (opts) => {
|
|
56860
57217
|
const globalOpts = program2.opts();
|
|
57218
|
+
const sourceRoots = expandRepeatedCsvOption(opts.sourceRoot);
|
|
57219
|
+
const sourceStores = expandRepeatedCsvOption(opts.sourceStore);
|
|
57220
|
+
const include = expandRepeatedCsvOption(opts.include);
|
|
57221
|
+
const exclude = expandRepeatedCsvOption(opts.exclude);
|
|
57222
|
+
if (sourceRoots || sourceStores || include || exclude) {
|
|
57223
|
+
const { discoverTaskRouteSources: discoverTaskRouteSources2 } = await Promise.resolve().then(() => (init_task_route_sources(), exports_task_route_sources));
|
|
57224
|
+
const result = discoverTaskRouteSources2({
|
|
57225
|
+
sourceRoots,
|
|
57226
|
+
sourceStores,
|
|
57227
|
+
include,
|
|
57228
|
+
exclude,
|
|
57229
|
+
limit: parseInt(opts.limit, 10)
|
|
57230
|
+
});
|
|
57231
|
+
if (opts.json || globalOpts.json) {
|
|
57232
|
+
console.log(JSON.stringify(result));
|
|
57233
|
+
return;
|
|
57234
|
+
}
|
|
57235
|
+
if (result.candidates.length === 0) {
|
|
57236
|
+
console.log(chalk7.dim(" No source tasks ready to claim."));
|
|
57237
|
+
} else {
|
|
57238
|
+
console.log(chalk7.bold(`Ready source tasks (${result.candidates.length}):
|
|
57239
|
+
`));
|
|
57240
|
+
for (const candidate of result.candidates) {
|
|
57241
|
+
const source3 = candidate.source_repo_path ?? candidate.source_db_path;
|
|
57242
|
+
const pri = candidate.priority === "critical" ? chalk7.bgRed.white(" CRIT ") : candidate.priority === "high" ? chalk7.red("[high]") : candidate.priority === "medium" ? chalk7.yellow("[med]") : "";
|
|
57243
|
+
console.log(` ${chalk7.cyan(candidate.task_short_id || candidate.task_id.slice(0, 8))} ${candidate.title} ${pri}${chalk7.dim(` ${source3}`)}`);
|
|
57244
|
+
}
|
|
57245
|
+
}
|
|
57246
|
+
if (result.errors.length > 0) {
|
|
57247
|
+
console.log(chalk7.yellow(`
|
|
57248
|
+
${result.errors.length} source error${result.errors.length === 1 ? "" : "s"} isolated; rerun with --json for details.`));
|
|
57249
|
+
}
|
|
57250
|
+
return;
|
|
57251
|
+
}
|
|
56861
57252
|
const db = getDatabase();
|
|
56862
57253
|
const { getBlockingDeps: getBlockingDeps2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
|
|
56863
57254
|
const { isLockExpired: isLockExpired2 } = await Promise.resolve().then(() => (init_database(), exports_database));
|
|
@@ -58179,21 +58570,21 @@ __export(exports_mcp_hooks_commands, {
|
|
|
58179
58570
|
});
|
|
58180
58571
|
import chalk8 from "chalk";
|
|
58181
58572
|
import { execSync as execSync3 } from "child_process";
|
|
58182
|
-
import { existsSync as
|
|
58183
|
-
import { dirname as
|
|
58573
|
+
import { existsSync as existsSync22, readFileSync as readFileSync17, writeFileSync as writeFileSync10, mkdirSync as mkdirSync11, chmodSync as chmodSync2 } from "fs";
|
|
58574
|
+
import { dirname as dirname13, join as join22 } from "path";
|
|
58184
58575
|
function getMcpBinaryPath() {
|
|
58185
58576
|
try {
|
|
58186
58577
|
const p = execSync3("which todos-mcp", { encoding: "utf-8" }).trim();
|
|
58187
58578
|
if (p)
|
|
58188
58579
|
return p;
|
|
58189
58580
|
} catch {}
|
|
58190
|
-
const bunBin =
|
|
58191
|
-
if (
|
|
58581
|
+
const bunBin = join22(HOME2, ".bun", "bin", "todos-mcp");
|
|
58582
|
+
if (existsSync22(bunBin))
|
|
58192
58583
|
return bunBin;
|
|
58193
58584
|
return "todos-mcp";
|
|
58194
58585
|
}
|
|
58195
58586
|
function readJsonFile2(path) {
|
|
58196
|
-
if (!
|
|
58587
|
+
if (!existsSync22(path))
|
|
58197
58588
|
return {};
|
|
58198
58589
|
try {
|
|
58199
58590
|
return JSON.parse(readFileSync17(path, "utf-8"));
|
|
@@ -58202,20 +58593,20 @@ function readJsonFile2(path) {
|
|
|
58202
58593
|
}
|
|
58203
58594
|
}
|
|
58204
58595
|
function writeJsonFile2(path, data) {
|
|
58205
|
-
const dir =
|
|
58206
|
-
if (!
|
|
58596
|
+
const dir = dirname13(path);
|
|
58597
|
+
if (!existsSync22(dir))
|
|
58207
58598
|
mkdirSync11(dir, { recursive: true });
|
|
58208
58599
|
writeFileSync10(path, JSON.stringify(data, null, 2) + `
|
|
58209
58600
|
`);
|
|
58210
58601
|
}
|
|
58211
58602
|
function readTomlFile(path) {
|
|
58212
|
-
if (!
|
|
58603
|
+
if (!existsSync22(path))
|
|
58213
58604
|
return "";
|
|
58214
58605
|
return readFileSync17(path, "utf-8");
|
|
58215
58606
|
}
|
|
58216
58607
|
function writeTomlFile(path, content) {
|
|
58217
|
-
const dir =
|
|
58218
|
-
if (!
|
|
58608
|
+
const dir = dirname13(path);
|
|
58609
|
+
if (!existsSync22(dir))
|
|
58219
58610
|
mkdirSync11(dir, { recursive: true });
|
|
58220
58611
|
writeFileSync10(path, content);
|
|
58221
58612
|
}
|
|
@@ -58281,7 +58672,7 @@ function unregisterClaude(_global) {
|
|
|
58281
58672
|
}
|
|
58282
58673
|
}
|
|
58283
58674
|
function registerCodex(binPath) {
|
|
58284
|
-
const configPath =
|
|
58675
|
+
const configPath = join22(HOME2, ".codex", "config.toml");
|
|
58285
58676
|
let content = readTomlFile(configPath);
|
|
58286
58677
|
content = removeTomlBlock(content, "mcp_servers.todos");
|
|
58287
58678
|
const block = `
|
|
@@ -58295,7 +58686,7 @@ args = []
|
|
|
58295
58686
|
console.log(chalk8.green(`Codex CLI: registered in ${configPath}`));
|
|
58296
58687
|
}
|
|
58297
58688
|
function unregisterCodex() {
|
|
58298
|
-
const configPath =
|
|
58689
|
+
const configPath = join22(HOME2, ".codex", "config.toml");
|
|
58299
58690
|
let content = readTomlFile(configPath);
|
|
58300
58691
|
if (!content.includes("[mcp_servers.todos]")) {
|
|
58301
58692
|
console.log(chalk8.dim(`Codex CLI: todos not found in ${configPath}`));
|
|
@@ -58307,7 +58698,7 @@ function unregisterCodex() {
|
|
|
58307
58698
|
console.log(chalk8.green(`Codex CLI: unregistered from ${configPath}`));
|
|
58308
58699
|
}
|
|
58309
58700
|
function registerGemini(binPath) {
|
|
58310
|
-
const configPath =
|
|
58701
|
+
const configPath = join22(HOME2, ".gemini", "settings.json");
|
|
58311
58702
|
const config = readJsonFile2(configPath);
|
|
58312
58703
|
if (!config["mcpServers"]) {
|
|
58313
58704
|
config["mcpServers"] = {};
|
|
@@ -58321,7 +58712,7 @@ function registerGemini(binPath) {
|
|
|
58321
58712
|
console.log(chalk8.green(`Gemini CLI: registered in ${configPath}`));
|
|
58322
58713
|
}
|
|
58323
58714
|
function unregisterGemini() {
|
|
58324
|
-
const configPath =
|
|
58715
|
+
const configPath = join22(HOME2, ".gemini", "settings.json");
|
|
58325
58716
|
const config = readJsonFile2(configPath);
|
|
58326
58717
|
const servers = config["mcpServers"];
|
|
58327
58718
|
if (!servers || !("todos" in servers)) {
|
|
@@ -58378,8 +58769,8 @@ function registerMcpHooksCommands(program2) {
|
|
|
58378
58769
|
if (p)
|
|
58379
58770
|
todosBin = p;
|
|
58380
58771
|
} catch {}
|
|
58381
|
-
const hooksDir =
|
|
58382
|
-
if (!
|
|
58772
|
+
const hooksDir = join22(process.cwd(), ".claude", "hooks");
|
|
58773
|
+
if (!existsSync22(hooksDir))
|
|
58383
58774
|
mkdirSync11(hooksDir, { recursive: true });
|
|
58384
58775
|
const hookScript = `#!/usr/bin/env bash
|
|
58385
58776
|
# Auto-generated by: todos hooks install
|
|
@@ -58404,11 +58795,11 @@ esac
|
|
|
58404
58795
|
|
|
58405
58796
|
exit 0
|
|
58406
58797
|
`;
|
|
58407
|
-
const hookPath =
|
|
58798
|
+
const hookPath = join22(hooksDir, "todos-sync.sh");
|
|
58408
58799
|
writeFileSync10(hookPath, hookScript);
|
|
58409
58800
|
execSync3(`chmod +x "${hookPath}"`);
|
|
58410
58801
|
console.log(chalk8.green(`Hook script created: ${hookPath}`));
|
|
58411
|
-
const settingsPath =
|
|
58802
|
+
const settingsPath = join22(process.cwd(), ".claude", "settings.json");
|
|
58412
58803
|
const settings = readJsonFile2(settingsPath);
|
|
58413
58804
|
if (!settings["hooks"]) {
|
|
58414
58805
|
settings["hooks"] = {};
|
|
@@ -59277,7 +59668,7 @@ Artifacts:`));
|
|
|
59277
59668
|
const gitDir = execSync3("git rev-parse --git-dir", { encoding: "utf-8" }).trim();
|
|
59278
59669
|
const hookPath = `${gitDir}/hooks/post-commit`;
|
|
59279
59670
|
const marker = "# todos-auto-link";
|
|
59280
|
-
if (
|
|
59671
|
+
if (existsSync22(hookPath)) {
|
|
59281
59672
|
const existing = readFileSync17(hookPath, "utf-8");
|
|
59282
59673
|
if (existing.includes(marker)) {
|
|
59283
59674
|
console.log(chalk8.yellow("Hook already installed."));
|
|
@@ -59305,7 +59696,7 @@ $(dirname "$0")/../../scripts/post-commit-hook.sh
|
|
|
59305
59696
|
const gitDir = execSync3("git rev-parse --git-dir", { encoding: "utf-8" }).trim();
|
|
59306
59697
|
const hookPath = `${gitDir}/hooks/post-commit`;
|
|
59307
59698
|
const marker = "# todos-auto-link";
|
|
59308
|
-
if (!
|
|
59699
|
+
if (!existsSync22(hookPath)) {
|
|
59309
59700
|
console.log(chalk8.dim("No post-commit hook found."));
|
|
59310
59701
|
return;
|
|
59311
59702
|
}
|
|
@@ -59491,7 +59882,7 @@ import chalk10 from "chalk";
|
|
|
59491
59882
|
import { execSync as execSync4 } from "child_process";
|
|
59492
59883
|
import { readFileSync as readFileSync18, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
59493
59884
|
import { tmpdir as tmpdir4 } from "os";
|
|
59494
|
-
import { join as
|
|
59885
|
+
import { join as join23 } from "path";
|
|
59495
59886
|
function getOrCreateLocalMachineName() {
|
|
59496
59887
|
return process.env["TODOS_MACHINE_NAME"] || __require("os").hostname() || "unknown";
|
|
59497
59888
|
}
|
|
@@ -59529,7 +59920,7 @@ function remoteTempPath(sshAddress) {
|
|
|
59529
59920
|
}
|
|
59530
59921
|
function readRemoteBridgeBundle(sshAddress) {
|
|
59531
59922
|
const remotePath = remoteTempPath(sshAddress);
|
|
59532
|
-
const localPath =
|
|
59923
|
+
const localPath = join23(tmpdir4(), `todos-bridge-pull-${uuid()}.json`);
|
|
59533
59924
|
try {
|
|
59534
59925
|
runSsh(sshAddress, `todos export --format bridge --allow-plaintext-sensitive --output ${shellQuote(remotePath)}`, 120000);
|
|
59535
59926
|
scpFromRemote(sshAddress, remotePath, localPath);
|
|
@@ -59544,7 +59935,7 @@ function readRemoteBridgeBundle(sshAddress) {
|
|
|
59544
59935
|
}
|
|
59545
59936
|
}
|
|
59546
59937
|
function writeLocalBridgeBundle() {
|
|
59547
|
-
const localPath =
|
|
59938
|
+
const localPath = join23(tmpdir4(), `todos-bridge-push-${uuid()}.json`);
|
|
59548
59939
|
writeFileSync11(localPath, JSON.stringify(createLocalBridgeBundle(), null, 2));
|
|
59549
59940
|
return localPath;
|
|
59550
59941
|
}
|
|
@@ -60608,7 +60999,7 @@ __export(exports_onboarding_commands, {
|
|
|
60608
60999
|
registerOnboardingCommands: () => registerOnboardingCommands
|
|
60609
61000
|
});
|
|
60610
61001
|
import chalk17 from "chalk";
|
|
60611
|
-
import { resolve as
|
|
61002
|
+
import { resolve as resolve22 } from "path";
|
|
60612
61003
|
function registerOnboardingCommands(program2) {
|
|
60613
61004
|
program2.command("onboarding").alias("demo-fixtures").description("List, show, write, or import bundled local onboarding fixtures").option("--show <name>", "Show one fixture bridge bundle as JSON").option("--write <dir>", "Write all bundled fixture bridge bundles to a directory").option("--import <name>", "Dry-run or apply an onboarding fixture import").option("--apply", "Apply an onboarding fixture import. Defaults to dry-run.").option("--resolve-conflicts", "Safely merge existing local tasks while preserving divergent fields").action(async (opts) => {
|
|
60614
61005
|
const globalOpts = program2.opts();
|
|
@@ -60624,7 +61015,7 @@ function registerOnboardingCommands(program2) {
|
|
|
60624
61015
|
return;
|
|
60625
61016
|
}
|
|
60626
61017
|
if (opts.write) {
|
|
60627
|
-
const result = writeOnboardingFixtureFiles2(
|
|
61018
|
+
const result = writeOnboardingFixtureFiles2(resolve22(opts.write));
|
|
60628
61019
|
if (globalOpts.json) {
|
|
60629
61020
|
output(result, true);
|
|
60630
61021
|
return;
|
|
@@ -64073,7 +64464,7 @@ __export(exports_sdk_integration_fixtures, {
|
|
|
64073
64464
|
TODOS_SDK_INTEGRATION_FIXTURE_GENERATED_AT: () => TODOS_SDK_INTEGRATION_FIXTURE_GENERATED_AT
|
|
64074
64465
|
});
|
|
64075
64466
|
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
64076
|
-
import { join as
|
|
64467
|
+
import { join as join24 } from "path";
|
|
64077
64468
|
function source5(version) {
|
|
64078
64469
|
return {
|
|
64079
64470
|
packageName: "@hasna/todos",
|
|
@@ -64180,7 +64571,7 @@ function writeSdkIntegrationFixtures(directory, options = {}) {
|
|
|
64180
64571
|
];
|
|
64181
64572
|
const written = [];
|
|
64182
64573
|
for (const [name, payload] of files) {
|
|
64183
|
-
const file =
|
|
64574
|
+
const file = join24(directory, name);
|
|
64184
64575
|
writeFileSync12(file, `${JSON.stringify(payload, null, 2)}
|
|
64185
64576
|
`, "utf-8");
|
|
64186
64577
|
written.push(file);
|
|
@@ -64204,7 +64595,7 @@ __export(exports_sdk_fixture_commands, {
|
|
|
64204
64595
|
registerSdkFixtureCommands: () => registerSdkFixtureCommands
|
|
64205
64596
|
});
|
|
64206
64597
|
import chalk19 from "chalk";
|
|
64207
|
-
import { resolve as
|
|
64598
|
+
import { resolve as resolve23 } from "path";
|
|
64208
64599
|
function registerSdkFixtureCommands(program2) {
|
|
64209
64600
|
program2.command("sdk-fixtures").description("List, show, or write local SDK integration fixtures").option("--show", "Print the full fixture pack JSON").option("--write <dir>", "Write fixture pack, bridge fixture, contract snapshots, and example index to a directory").action(async (opts) => {
|
|
64210
64601
|
const globalOpts = program2.opts();
|
|
@@ -64215,7 +64606,7 @@ function registerSdkFixtureCommands(program2) {
|
|
|
64215
64606
|
writeSdkIntegrationFixtures: writeSdkIntegrationFixtures2
|
|
64216
64607
|
} = await Promise.resolve().then(() => (init_sdk_integration_fixtures(), exports_sdk_integration_fixtures));
|
|
64217
64608
|
if (opts.write) {
|
|
64218
|
-
const result = writeSdkIntegrationFixtures2(
|
|
64609
|
+
const result = writeSdkIntegrationFixtures2(resolve23(opts.write));
|
|
64219
64610
|
if (globalOpts.json) {
|
|
64220
64611
|
console.log(JSON.stringify(result));
|
|
64221
64612
|
return;
|
|
@@ -65037,7 +65428,7 @@ __export(exports_local_backup_commands, {
|
|
|
65037
65428
|
registerLocalBackupCommands: () => registerLocalBackupCommands
|
|
65038
65429
|
});
|
|
65039
65430
|
import chalk26 from "chalk";
|
|
65040
|
-
import { resolve as
|
|
65431
|
+
import { resolve as resolve24 } from "path";
|
|
65041
65432
|
function globalOptions6(program2) {
|
|
65042
65433
|
const command = program2;
|
|
65043
65434
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
@@ -65059,10 +65450,10 @@ function registerLocalBackupCommands(program2) {
|
|
|
65059
65450
|
const projectId = opts.projectId ?? autoProject(globalOpts);
|
|
65060
65451
|
const backupBundle = createLocalBackup2({
|
|
65061
65452
|
project_id: projectId,
|
|
65062
|
-
output_path: opts.output ?
|
|
65453
|
+
output_path: opts.output ? resolve24(opts.output) : undefined
|
|
65063
65454
|
});
|
|
65064
65455
|
const result = {
|
|
65065
|
-
output_path: opts.output ?
|
|
65456
|
+
output_path: opts.output ? resolve24(opts.output) : null,
|
|
65066
65457
|
backup: backupBundle
|
|
65067
65458
|
};
|
|
65068
65459
|
if (opts.json || globalOpts.json) {
|
|
@@ -66866,7 +67257,7 @@ var init_factory = __esm(() => {
|
|
|
66866
67257
|
});
|
|
66867
67258
|
|
|
66868
67259
|
// src/storage/s3-artifacts.ts
|
|
66869
|
-
import { createHash as
|
|
67260
|
+
import { createHash as createHash15, createHmac as createHmac2 } from "crypto";
|
|
66870
67261
|
function createTodosS3ArtifactStore(options) {
|
|
66871
67262
|
const requestFetch = options.fetch ?? fetch;
|
|
66872
67263
|
const now4 = options.now ?? (() => new Date);
|
|
@@ -67038,7 +67429,7 @@ function toAmzDate(date) {
|
|
|
67038
67429
|
return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
67039
67430
|
}
|
|
67040
67431
|
function sha256Hex(value) {
|
|
67041
|
-
return
|
|
67432
|
+
return createHash15("sha256").update(value).digest("hex");
|
|
67042
67433
|
}
|
|
67043
67434
|
function hmac(key, value) {
|
|
67044
67435
|
return createHmac2("sha256", key).update(value).digest();
|