@hasna/todos 0.13.1 → 0.13.2
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/README.md +2 -1
- package/dist/cli/cloud-router.d.ts +21 -5
- package/dist/cli/cloud-router.d.ts.map +1 -1
- package/dist/cli/commands/config-serve-commands.d.ts.map +1 -1
- package/dist/cli/commands/task-commands.d.ts.map +1 -1
- package/dist/cli/index.js +289 -236
- package/dist/contracts.js +20 -10
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/task-crud.d.ts.map +1 -1
- package/dist/index.js +31 -16
- package/dist/lib/dependency-graph.d.ts +18 -10
- package/dist/lib/dependency-graph.d.ts.map +1 -1
- package/dist/lib/redaction.d.ts.map +1 -1
- package/dist/mcp/index.js +28 -13
- package/dist/mcp.js +2 -2
- package/dist/registry.js +20 -10
- package/dist/release-provenance.json +5 -5
- package/dist/server/index.js +65 -30
- package/dist/server/port.d.ts +52 -0
- package/dist/server/port.d.ts.map +1 -0
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/storage/interfaces.d.ts +14 -0
- package/dist/storage/interfaces.d.ts.map +1 -1
- package/dist/storage.js +21 -9
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -2123,7 +2123,7 @@ var package_default;
|
|
|
2123
2123
|
var init_package = __esm(() => {
|
|
2124
2124
|
package_default = {
|
|
2125
2125
|
name: "@hasna/todos",
|
|
2126
|
-
version: "0.13.
|
|
2126
|
+
version: "0.13.2",
|
|
2127
2127
|
description: "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
2128
2128
|
type: "module",
|
|
2129
2129
|
main: "dist/index.js",
|
|
@@ -2175,7 +2175,7 @@ var init_package = __esm(() => {
|
|
|
2175
2175
|
"backfill:comment-redaction": "bun run src/server/index.ts redact-comments",
|
|
2176
2176
|
"generate:sdk": "bun run scripts/generate-sdk.ts",
|
|
2177
2177
|
"build:dashboard": "cd dashboard && bun install --frozen-lockfile && bun run build",
|
|
2178
|
-
typecheck: "tsc --noEmit",
|
|
2178
|
+
typecheck: "tsc --noEmit -p tsconfig.typecheck.json",
|
|
2179
2179
|
test: "bun test",
|
|
2180
2180
|
"test:no-cloud": "bun test src/no-cloud-boundary.test.ts src/local-first.test.ts src/lib/public-release-gate.test.ts",
|
|
2181
2181
|
"dev:cli": "bun run src/cli/index.tsx",
|
|
@@ -2250,6 +2250,161 @@ var init_package_version = __esm(() => {
|
|
|
2250
2250
|
init_package();
|
|
2251
2251
|
});
|
|
2252
2252
|
|
|
2253
|
+
// src/types/index.ts
|
|
2254
|
+
function isBlockingDependencyStatus(status) {
|
|
2255
|
+
return status !== "completed" && status !== "cancelled";
|
|
2256
|
+
}
|
|
2257
|
+
var TASK_STATUSES, TASK_PRIORITIES, VersionConflictError, TaskNotFoundError, ProjectNotFoundError, ResourceConflictError, PlanNotFoundError, LockError, AgentNotFoundError, IdentityAliasAmbiguousError, IdentityIdImmutableError, TaskListNotFoundError, DependencyCycleError, CompletionGuardError, DispatchNotFoundError;
|
|
2258
|
+
var init_types = __esm(() => {
|
|
2259
|
+
TASK_STATUSES = [
|
|
2260
|
+
"pending",
|
|
2261
|
+
"in_progress",
|
|
2262
|
+
"completed",
|
|
2263
|
+
"failed",
|
|
2264
|
+
"cancelled"
|
|
2265
|
+
];
|
|
2266
|
+
TASK_PRIORITIES = [
|
|
2267
|
+
"low",
|
|
2268
|
+
"medium",
|
|
2269
|
+
"high",
|
|
2270
|
+
"critical"
|
|
2271
|
+
];
|
|
2272
|
+
VersionConflictError = class VersionConflictError extends Error {
|
|
2273
|
+
taskId;
|
|
2274
|
+
expectedVersion;
|
|
2275
|
+
actualVersion;
|
|
2276
|
+
static code = "VERSION_CONFLICT";
|
|
2277
|
+
static suggestion = "Fetch the task with get_task to get the current version before updating.";
|
|
2278
|
+
constructor(taskId, expectedVersion, actualVersion) {
|
|
2279
|
+
super(`Version conflict for task ${taskId}: expected ${expectedVersion}, got ${actualVersion}`);
|
|
2280
|
+
this.taskId = taskId;
|
|
2281
|
+
this.expectedVersion = expectedVersion;
|
|
2282
|
+
this.actualVersion = actualVersion;
|
|
2283
|
+
this.name = "VersionConflictError";
|
|
2284
|
+
}
|
|
2285
|
+
};
|
|
2286
|
+
TaskNotFoundError = class TaskNotFoundError extends Error {
|
|
2287
|
+
taskId;
|
|
2288
|
+
static code = "TASK_NOT_FOUND";
|
|
2289
|
+
static suggestion = "Verify the task ID. Use list_tasks or search_tasks to find the correct ID.";
|
|
2290
|
+
constructor(taskId) {
|
|
2291
|
+
super(`Task not found: ${taskId}`);
|
|
2292
|
+
this.taskId = taskId;
|
|
2293
|
+
this.name = "TaskNotFoundError";
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
ProjectNotFoundError = class ProjectNotFoundError extends Error {
|
|
2297
|
+
projectId;
|
|
2298
|
+
static code = "PROJECT_NOT_FOUND";
|
|
2299
|
+
static suggestion = "Use list_projects to see available projects.";
|
|
2300
|
+
constructor(projectId) {
|
|
2301
|
+
super(`Project not found: ${projectId}`);
|
|
2302
|
+
this.projectId = projectId;
|
|
2303
|
+
this.name = "ProjectNotFoundError";
|
|
2304
|
+
}
|
|
2305
|
+
};
|
|
2306
|
+
ResourceConflictError = class ResourceConflictError extends Error {
|
|
2307
|
+
code;
|
|
2308
|
+
constructor(code, message) {
|
|
2309
|
+
super(message);
|
|
2310
|
+
this.code = code;
|
|
2311
|
+
this.name = "ResourceConflictError";
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
PlanNotFoundError = class PlanNotFoundError extends Error {
|
|
2315
|
+
planId;
|
|
2316
|
+
static code = "PLAN_NOT_FOUND";
|
|
2317
|
+
static suggestion = "Use list_plans to see available plans.";
|
|
2318
|
+
constructor(planId) {
|
|
2319
|
+
super(`Plan not found: ${planId}`);
|
|
2320
|
+
this.planId = planId;
|
|
2321
|
+
this.name = "PlanNotFoundError";
|
|
2322
|
+
}
|
|
2323
|
+
};
|
|
2324
|
+
LockError = class LockError extends Error {
|
|
2325
|
+
taskId;
|
|
2326
|
+
lockedBy;
|
|
2327
|
+
static code = "LOCK_ERROR";
|
|
2328
|
+
static suggestion = "Wait for the lock to expire (30 min) or contact the lock holder.";
|
|
2329
|
+
constructor(taskId, lockedBy) {
|
|
2330
|
+
super(`Task ${taskId} is locked by ${lockedBy}`);
|
|
2331
|
+
this.taskId = taskId;
|
|
2332
|
+
this.lockedBy = lockedBy;
|
|
2333
|
+
this.name = "LockError";
|
|
2334
|
+
}
|
|
2335
|
+
};
|
|
2336
|
+
AgentNotFoundError = class AgentNotFoundError extends Error {
|
|
2337
|
+
agentId;
|
|
2338
|
+
static code = "AGENT_NOT_FOUND";
|
|
2339
|
+
static suggestion = "Use register_agent to create the agent first, or list_agents to find existing ones.";
|
|
2340
|
+
constructor(agentId) {
|
|
2341
|
+
super(`Agent not found: ${agentId}`);
|
|
2342
|
+
this.agentId = agentId;
|
|
2343
|
+
this.name = "AgentNotFoundError";
|
|
2344
|
+
}
|
|
2345
|
+
};
|
|
2346
|
+
IdentityAliasAmbiguousError = class IdentityAliasAmbiguousError extends Error {
|
|
2347
|
+
code = "IDENTITY_ALIAS_AMBIGUOUS";
|
|
2348
|
+
candidates;
|
|
2349
|
+
constructor(subject, candidates = []) {
|
|
2350
|
+
super(`Identity alias or source is ambiguous: ${subject}`);
|
|
2351
|
+
this.name = "IdentityAliasAmbiguousError";
|
|
2352
|
+
this.candidates = [...new Set(candidates)].sort();
|
|
2353
|
+
}
|
|
2354
|
+
};
|
|
2355
|
+
IdentityIdImmutableError = class IdentityIdImmutableError extends Error {
|
|
2356
|
+
code = "IDENTITY_ID_IMMUTABLE";
|
|
2357
|
+
constructor(agentId) {
|
|
2358
|
+
super(`IDENTITY_ID_IMMUTABLE: canonical identity for agent ${agentId} cannot be replaced`);
|
|
2359
|
+
this.name = "IdentityIdImmutableError";
|
|
2360
|
+
}
|
|
2361
|
+
};
|
|
2362
|
+
TaskListNotFoundError = class TaskListNotFoundError extends Error {
|
|
2363
|
+
taskListId;
|
|
2364
|
+
static code = "TASK_LIST_NOT_FOUND";
|
|
2365
|
+
static suggestion = "Use list_task_lists to see available lists.";
|
|
2366
|
+
constructor(taskListId) {
|
|
2367
|
+
super(`Task list not found: ${taskListId}`);
|
|
2368
|
+
this.taskListId = taskListId;
|
|
2369
|
+
this.name = "TaskListNotFoundError";
|
|
2370
|
+
}
|
|
2371
|
+
};
|
|
2372
|
+
DependencyCycleError = class DependencyCycleError extends Error {
|
|
2373
|
+
taskId;
|
|
2374
|
+
dependsOn;
|
|
2375
|
+
static code = "DEPENDENCY_CYCLE";
|
|
2376
|
+
static suggestion = "Check the dependency chain with get_task to avoid circular references.";
|
|
2377
|
+
constructor(taskId, dependsOn) {
|
|
2378
|
+
super(`Adding dependency ${taskId} -> ${dependsOn} would create a cycle`);
|
|
2379
|
+
this.taskId = taskId;
|
|
2380
|
+
this.dependsOn = dependsOn;
|
|
2381
|
+
this.name = "DependencyCycleError";
|
|
2382
|
+
}
|
|
2383
|
+
};
|
|
2384
|
+
CompletionGuardError = class CompletionGuardError extends Error {
|
|
2385
|
+
reason;
|
|
2386
|
+
retryAfterSeconds;
|
|
2387
|
+
static code = "COMPLETION_BLOCKED";
|
|
2388
|
+
static suggestion = "Wait for the cooldown period, then retry.";
|
|
2389
|
+
constructor(reason, retryAfterSeconds) {
|
|
2390
|
+
super(reason);
|
|
2391
|
+
this.reason = reason;
|
|
2392
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
2393
|
+
this.name = "CompletionGuardError";
|
|
2394
|
+
}
|
|
2395
|
+
};
|
|
2396
|
+
DispatchNotFoundError = class DispatchNotFoundError extends Error {
|
|
2397
|
+
dispatchId;
|
|
2398
|
+
static code = "DISPATCH_NOT_FOUND";
|
|
2399
|
+
static suggestion = "Check the dispatch ID with list_dispatches.";
|
|
2400
|
+
constructor(dispatchId) {
|
|
2401
|
+
super(`Dispatch not found: ${dispatchId}`);
|
|
2402
|
+
this.dispatchId = dispatchId;
|
|
2403
|
+
this.name = "DispatchNotFoundError";
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
});
|
|
2407
|
+
|
|
2253
2408
|
// src/lib/sync-utils.ts
|
|
2254
2409
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "fs";
|
|
2255
2410
|
import { join } from "path";
|
|
@@ -2472,11 +2627,15 @@ function secretPatterns() {
|
|
|
2472
2627
|
return [...customPatterns(), ...DEFAULT_SECRET_PATTERNS];
|
|
2473
2628
|
}
|
|
2474
2629
|
function isRedactionPlaceholderMatch(match) {
|
|
2475
|
-
const placeholder = String.raw`\[REDACTED(?:_[A-Z_]+)?\]`;
|
|
2476
2630
|
const trimmed = match.trim();
|
|
2477
|
-
return new RegExp(`^${
|
|
2631
|
+
return new RegExp(`^${REDACTION_PLACEHOLDER}$`).test(trimmed) || new RegExp(`=\\s*['"]?${REDACTION_PLACEHOLDER}['"]?$`).test(trimmed);
|
|
2632
|
+
}
|
|
2633
|
+
function isRedactionPlaceholderKey(key) {
|
|
2634
|
+
return new RegExp(`^${REDACTION_PLACEHOLDER}$`).test(key.trim());
|
|
2478
2635
|
}
|
|
2479
2636
|
function isSecretKey(key) {
|
|
2637
|
+
if (isRedactionPlaceholderKey(key))
|
|
2638
|
+
return false;
|
|
2480
2639
|
if (NON_SECRET_USAGE_KEYS.has(key.toLowerCase()))
|
|
2481
2640
|
return false;
|
|
2482
2641
|
if (DEFAULT_SECRET_KEY_PATTERN.test(key))
|
|
@@ -2537,7 +2696,7 @@ function upsertSecretSafetyConfig(input) {
|
|
|
2537
2696
|
saveConfig({ ...config, secret_safety: next });
|
|
2538
2697
|
return next;
|
|
2539
2698
|
}
|
|
2540
|
-
var DEFAULT_SECRET_PATTERNS, DEFAULT_SECRET_KEY_PATTERN, NON_SECRET_USAGE_KEYS;
|
|
2699
|
+
var DEFAULT_SECRET_PATTERNS, DEFAULT_SECRET_KEY_PATTERN, NON_SECRET_USAGE_KEYS, REDACTION_PLACEHOLDER;
|
|
2541
2700
|
var init_redaction = __esm(() => {
|
|
2542
2701
|
init_config();
|
|
2543
2702
|
DEFAULT_SECRET_PATTERNS = [
|
|
@@ -2561,11 +2720,12 @@ var init_redaction = __esm(() => {
|
|
|
2561
2720
|
"completion_tokens",
|
|
2562
2721
|
"cost_tokens"
|
|
2563
2722
|
]);
|
|
2723
|
+
REDACTION_PLACEHOLDER = String.raw`\[REDACTED(?:_[A-Z_]+)?\]`;
|
|
2564
2724
|
});
|
|
2565
2725
|
|
|
2566
2726
|
// src/pr-groups/types.ts
|
|
2567
2727
|
var PR_GROUP_LEDGER_SCHEMA_VERSION = 1, PR_GROUP_REPAIR_CYCLE_LIMIT = 2, PrGroupLedgerError;
|
|
2568
|
-
var
|
|
2728
|
+
var init_types2 = __esm(() => {
|
|
2569
2729
|
PrGroupLedgerError = class PrGroupLedgerError extends Error {
|
|
2570
2730
|
code;
|
|
2571
2731
|
details;
|
|
@@ -3920,7 +4080,7 @@ class PrGroupLedger {
|
|
|
3920
4080
|
}
|
|
3921
4081
|
var SHA_PATTERN, SAFE_REFERENCE_PATTERN, SAFE_PROFILE_PATTERN, FORBIDDEN_METADATA_KEY, EMAIL_PATTERN, CREDENTIAL_PATTERN, AUTH_PATH_PATTERN, STATE_VIEW_ATTEMPT_LIMIT = 100, STATE_VIEW_EVENT_LIMIT = 500, PR_GROUP_WRITER_STALE_AFTER_MS = 30000, APPENDABLE_EVENT_TYPES, EVENT_OUTCOMES, RECEIPT_EVENT_TYPES;
|
|
3922
4082
|
var init_ledger = __esm(() => {
|
|
3923
|
-
|
|
4083
|
+
init_types2();
|
|
3924
4084
|
SHA_PATTERN = /^[0-9a-f]{40}$/;
|
|
3925
4085
|
SAFE_REFERENCE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/;
|
|
3926
4086
|
SAFE_PROFILE_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
@@ -4722,7 +4882,7 @@ class PrGroupHttpClient {
|
|
|
4722
4882
|
var LEDGER_CODES, GROUP_STATES, ATTEMPT_STATES, EVENT_TYPES, EVENT_OUTCOMES2;
|
|
4723
4883
|
var init_http_client = __esm(() => {
|
|
4724
4884
|
init_ledger();
|
|
4725
|
-
|
|
4885
|
+
init_types2();
|
|
4726
4886
|
LEDGER_CODES = new Set([
|
|
4727
4887
|
"PR_GROUP_INVALID_INPUT",
|
|
4728
4888
|
"PR_GROUP_NOT_FOUND",
|
|
@@ -5539,7 +5699,7 @@ async function cloudUnlockTask(client, id, agentId, force = false) {
|
|
|
5539
5699
|
async function cloudGetDependencies(client, id) {
|
|
5540
5700
|
const raw = await client.transport.get(`/tasks/${encodeURIComponent(id)}/dependencies`);
|
|
5541
5701
|
const env = raw ?? {};
|
|
5542
|
-
return { dependencies: env.dependencies ?? [],
|
|
5702
|
+
return { dependencies: env.dependencies ?? [], blocks: env.blocks ?? env.blocked_by ?? [] };
|
|
5543
5703
|
}
|
|
5544
5704
|
function unresolvedRelatedTask(id) {
|
|
5545
5705
|
const now = new Date(0).toISOString();
|
|
@@ -5600,7 +5760,7 @@ function unresolvedRelatedTask(id) {
|
|
|
5600
5760
|
async function cloudGetTaskRelations(client, id) {
|
|
5601
5761
|
const edges = await cloudGetDependencies(client, id);
|
|
5602
5762
|
const upstream = dedupe(edges.dependencies.map((edge) => edge.depends_on));
|
|
5603
|
-
const downstream = dedupe(edges.
|
|
5763
|
+
const downstream = dedupe(edges.blocks.map((edge) => edge.task_id));
|
|
5604
5764
|
const wanted = dedupe([...upstream, ...downstream]).filter((ref) => ref !== id);
|
|
5605
5765
|
const rows = new Map;
|
|
5606
5766
|
let cursor = 0;
|
|
@@ -5616,7 +5776,9 @@ async function cloudGetTaskRelations(client, id) {
|
|
|
5616
5776
|
});
|
|
5617
5777
|
await Promise.all(workers);
|
|
5618
5778
|
const materialize = (ref) => rows.get(ref) ?? unresolvedRelatedTask(ref);
|
|
5619
|
-
|
|
5779
|
+
const dependencies = upstream.map(materialize);
|
|
5780
|
+
const blocked_by = dependencies.filter((dep) => isBlockingDependencyStatus(dep.status));
|
|
5781
|
+
return { dependencies, blocked_by, blocks: downstream.map(materialize) };
|
|
5620
5782
|
}
|
|
5621
5783
|
function dedupe(ids) {
|
|
5622
5784
|
const seen = new Set;
|
|
@@ -5938,6 +6100,7 @@ async function cloudTimeline(client, options = {}) {
|
|
|
5938
6100
|
}
|
|
5939
6101
|
var UUID_RE, CLOUD_MODES, VALID_STORAGE_MODES, COMPLETION_EVIDENCE_FIELDS, completionCapabilityCache, RELATION_HYDRATION_CONCURRENCY = 6, PRIORITY_RANK;
|
|
5940
6102
|
var init_cloud_router = __esm(() => {
|
|
6103
|
+
init_types();
|
|
5941
6104
|
init_redaction();
|
|
5942
6105
|
init_http_client();
|
|
5943
6106
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -9769,158 +9932,6 @@ var init_machines = __esm(() => {
|
|
|
9769
9932
|
];
|
|
9770
9933
|
});
|
|
9771
9934
|
|
|
9772
|
-
// src/types/index.ts
|
|
9773
|
-
var TASK_STATUSES, TASK_PRIORITIES, VersionConflictError, TaskNotFoundError, ProjectNotFoundError, ResourceConflictError, PlanNotFoundError, LockError, AgentNotFoundError, IdentityAliasAmbiguousError, IdentityIdImmutableError, TaskListNotFoundError, DependencyCycleError, CompletionGuardError, DispatchNotFoundError;
|
|
9774
|
-
var init_types2 = __esm(() => {
|
|
9775
|
-
TASK_STATUSES = [
|
|
9776
|
-
"pending",
|
|
9777
|
-
"in_progress",
|
|
9778
|
-
"completed",
|
|
9779
|
-
"failed",
|
|
9780
|
-
"cancelled"
|
|
9781
|
-
];
|
|
9782
|
-
TASK_PRIORITIES = [
|
|
9783
|
-
"low",
|
|
9784
|
-
"medium",
|
|
9785
|
-
"high",
|
|
9786
|
-
"critical"
|
|
9787
|
-
];
|
|
9788
|
-
VersionConflictError = class VersionConflictError extends Error {
|
|
9789
|
-
taskId;
|
|
9790
|
-
expectedVersion;
|
|
9791
|
-
actualVersion;
|
|
9792
|
-
static code = "VERSION_CONFLICT";
|
|
9793
|
-
static suggestion = "Fetch the task with get_task to get the current version before updating.";
|
|
9794
|
-
constructor(taskId, expectedVersion, actualVersion) {
|
|
9795
|
-
super(`Version conflict for task ${taskId}: expected ${expectedVersion}, got ${actualVersion}`);
|
|
9796
|
-
this.taskId = taskId;
|
|
9797
|
-
this.expectedVersion = expectedVersion;
|
|
9798
|
-
this.actualVersion = actualVersion;
|
|
9799
|
-
this.name = "VersionConflictError";
|
|
9800
|
-
}
|
|
9801
|
-
};
|
|
9802
|
-
TaskNotFoundError = class TaskNotFoundError extends Error {
|
|
9803
|
-
taskId;
|
|
9804
|
-
static code = "TASK_NOT_FOUND";
|
|
9805
|
-
static suggestion = "Verify the task ID. Use list_tasks or search_tasks to find the correct ID.";
|
|
9806
|
-
constructor(taskId) {
|
|
9807
|
-
super(`Task not found: ${taskId}`);
|
|
9808
|
-
this.taskId = taskId;
|
|
9809
|
-
this.name = "TaskNotFoundError";
|
|
9810
|
-
}
|
|
9811
|
-
};
|
|
9812
|
-
ProjectNotFoundError = class ProjectNotFoundError extends Error {
|
|
9813
|
-
projectId;
|
|
9814
|
-
static code = "PROJECT_NOT_FOUND";
|
|
9815
|
-
static suggestion = "Use list_projects to see available projects.";
|
|
9816
|
-
constructor(projectId) {
|
|
9817
|
-
super(`Project not found: ${projectId}`);
|
|
9818
|
-
this.projectId = projectId;
|
|
9819
|
-
this.name = "ProjectNotFoundError";
|
|
9820
|
-
}
|
|
9821
|
-
};
|
|
9822
|
-
ResourceConflictError = class ResourceConflictError extends Error {
|
|
9823
|
-
code;
|
|
9824
|
-
constructor(code, message) {
|
|
9825
|
-
super(message);
|
|
9826
|
-
this.code = code;
|
|
9827
|
-
this.name = "ResourceConflictError";
|
|
9828
|
-
}
|
|
9829
|
-
};
|
|
9830
|
-
PlanNotFoundError = class PlanNotFoundError extends Error {
|
|
9831
|
-
planId;
|
|
9832
|
-
static code = "PLAN_NOT_FOUND";
|
|
9833
|
-
static suggestion = "Use list_plans to see available plans.";
|
|
9834
|
-
constructor(planId) {
|
|
9835
|
-
super(`Plan not found: ${planId}`);
|
|
9836
|
-
this.planId = planId;
|
|
9837
|
-
this.name = "PlanNotFoundError";
|
|
9838
|
-
}
|
|
9839
|
-
};
|
|
9840
|
-
LockError = class LockError extends Error {
|
|
9841
|
-
taskId;
|
|
9842
|
-
lockedBy;
|
|
9843
|
-
static code = "LOCK_ERROR";
|
|
9844
|
-
static suggestion = "Wait for the lock to expire (30 min) or contact the lock holder.";
|
|
9845
|
-
constructor(taskId, lockedBy) {
|
|
9846
|
-
super(`Task ${taskId} is locked by ${lockedBy}`);
|
|
9847
|
-
this.taskId = taskId;
|
|
9848
|
-
this.lockedBy = lockedBy;
|
|
9849
|
-
this.name = "LockError";
|
|
9850
|
-
}
|
|
9851
|
-
};
|
|
9852
|
-
AgentNotFoundError = class AgentNotFoundError extends Error {
|
|
9853
|
-
agentId;
|
|
9854
|
-
static code = "AGENT_NOT_FOUND";
|
|
9855
|
-
static suggestion = "Use register_agent to create the agent first, or list_agents to find existing ones.";
|
|
9856
|
-
constructor(agentId) {
|
|
9857
|
-
super(`Agent not found: ${agentId}`);
|
|
9858
|
-
this.agentId = agentId;
|
|
9859
|
-
this.name = "AgentNotFoundError";
|
|
9860
|
-
}
|
|
9861
|
-
};
|
|
9862
|
-
IdentityAliasAmbiguousError = class IdentityAliasAmbiguousError extends Error {
|
|
9863
|
-
code = "IDENTITY_ALIAS_AMBIGUOUS";
|
|
9864
|
-
candidates;
|
|
9865
|
-
constructor(subject, candidates = []) {
|
|
9866
|
-
super(`Identity alias or source is ambiguous: ${subject}`);
|
|
9867
|
-
this.name = "IdentityAliasAmbiguousError";
|
|
9868
|
-
this.candidates = [...new Set(candidates)].sort();
|
|
9869
|
-
}
|
|
9870
|
-
};
|
|
9871
|
-
IdentityIdImmutableError = class IdentityIdImmutableError extends Error {
|
|
9872
|
-
code = "IDENTITY_ID_IMMUTABLE";
|
|
9873
|
-
constructor(agentId) {
|
|
9874
|
-
super(`IDENTITY_ID_IMMUTABLE: canonical identity for agent ${agentId} cannot be replaced`);
|
|
9875
|
-
this.name = "IdentityIdImmutableError";
|
|
9876
|
-
}
|
|
9877
|
-
};
|
|
9878
|
-
TaskListNotFoundError = class TaskListNotFoundError extends Error {
|
|
9879
|
-
taskListId;
|
|
9880
|
-
static code = "TASK_LIST_NOT_FOUND";
|
|
9881
|
-
static suggestion = "Use list_task_lists to see available lists.";
|
|
9882
|
-
constructor(taskListId) {
|
|
9883
|
-
super(`Task list not found: ${taskListId}`);
|
|
9884
|
-
this.taskListId = taskListId;
|
|
9885
|
-
this.name = "TaskListNotFoundError";
|
|
9886
|
-
}
|
|
9887
|
-
};
|
|
9888
|
-
DependencyCycleError = class DependencyCycleError extends Error {
|
|
9889
|
-
taskId;
|
|
9890
|
-
dependsOn;
|
|
9891
|
-
static code = "DEPENDENCY_CYCLE";
|
|
9892
|
-
static suggestion = "Check the dependency chain with get_task to avoid circular references.";
|
|
9893
|
-
constructor(taskId, dependsOn) {
|
|
9894
|
-
super(`Adding dependency ${taskId} -> ${dependsOn} would create a cycle`);
|
|
9895
|
-
this.taskId = taskId;
|
|
9896
|
-
this.dependsOn = dependsOn;
|
|
9897
|
-
this.name = "DependencyCycleError";
|
|
9898
|
-
}
|
|
9899
|
-
};
|
|
9900
|
-
CompletionGuardError = class CompletionGuardError extends Error {
|
|
9901
|
-
reason;
|
|
9902
|
-
retryAfterSeconds;
|
|
9903
|
-
static code = "COMPLETION_BLOCKED";
|
|
9904
|
-
static suggestion = "Wait for the cooldown period, then retry.";
|
|
9905
|
-
constructor(reason, retryAfterSeconds) {
|
|
9906
|
-
super(reason);
|
|
9907
|
-
this.reason = reason;
|
|
9908
|
-
this.retryAfterSeconds = retryAfterSeconds;
|
|
9909
|
-
this.name = "CompletionGuardError";
|
|
9910
|
-
}
|
|
9911
|
-
};
|
|
9912
|
-
DispatchNotFoundError = class DispatchNotFoundError extends Error {
|
|
9913
|
-
dispatchId;
|
|
9914
|
-
static code = "DISPATCH_NOT_FOUND";
|
|
9915
|
-
static suggestion = "Check the dispatch ID with list_dispatches.";
|
|
9916
|
-
constructor(dispatchId) {
|
|
9917
|
-
super(`Dispatch not found: ${dispatchId}`);
|
|
9918
|
-
this.dispatchId = dispatchId;
|
|
9919
|
-
this.name = "DispatchNotFoundError";
|
|
9920
|
-
}
|
|
9921
|
-
};
|
|
9922
|
-
});
|
|
9923
|
-
|
|
9924
9935
|
// src/db/identity-mapping.ts
|
|
9925
9936
|
function timestamp() {
|
|
9926
9937
|
return new Date().toISOString();
|
|
@@ -10075,8 +10086,8 @@ function recordAgentAlias(agentId, label, db) {
|
|
|
10075
10086
|
}
|
|
10076
10087
|
var IDENTITY_PROJECTION_CONTRACT, IDENTITY_MIGRATION_ID = 65;
|
|
10077
10088
|
var init_identity_mapping = __esm(() => {
|
|
10078
|
-
|
|
10079
|
-
|
|
10089
|
+
init_types();
|
|
10090
|
+
init_types();
|
|
10080
10091
|
IDENTITY_PROJECTION_CONTRACT = Object.freeze({
|
|
10081
10092
|
name: "hasna.todos.agent-identity-projection/v1",
|
|
10082
10093
|
version: 1,
|
|
@@ -10467,8 +10478,8 @@ function ensureDir2(filePath) {
|
|
|
10467
10478
|
function openDatabase(path) {
|
|
10468
10479
|
ensureDir2(path);
|
|
10469
10480
|
const db = new Database(path);
|
|
10470
|
-
db.run("PRAGMA journal_mode = WAL");
|
|
10471
10481
|
db.run("PRAGMA busy_timeout = 5000");
|
|
10482
|
+
db.run("PRAGMA journal_mode = WAL");
|
|
10472
10483
|
db.run("PRAGMA foreign_keys = ON");
|
|
10473
10484
|
runMigrations(db);
|
|
10474
10485
|
ensureAgentIdentitySchema(db);
|
|
@@ -10601,7 +10612,7 @@ var init_database = __esm(() => {
|
|
|
10601
10612
|
init_schema();
|
|
10602
10613
|
init_machines();
|
|
10603
10614
|
init_identity_mapping();
|
|
10604
|
-
|
|
10615
|
+
init_types();
|
|
10605
10616
|
ALLOWED_TABLES = new Set(["tasks", "projects", "agents", "plans", "task_lists", "task_templates", "project_knowledge_records", "project_risks", "local_retrospectives"]);
|
|
10606
10617
|
});
|
|
10607
10618
|
|
|
@@ -11042,7 +11053,7 @@ function removeMachineLocalPath(projectId, machineId, db) {
|
|
|
11042
11053
|
return result.changes > 0;
|
|
11043
11054
|
}
|
|
11044
11055
|
var init_projects = __esm(() => {
|
|
11045
|
-
|
|
11056
|
+
init_types();
|
|
11046
11057
|
init_database();
|
|
11047
11058
|
init_machines();
|
|
11048
11059
|
init_storage_tombstones();
|
|
@@ -11387,7 +11398,7 @@ function checkCompletionGuard(task, agentId, db, configOverride) {
|
|
|
11387
11398
|
}
|
|
11388
11399
|
}
|
|
11389
11400
|
var init_completion_guard = __esm(() => {
|
|
11390
|
-
|
|
11401
|
+
init_types();
|
|
11391
11402
|
init_config();
|
|
11392
11403
|
init_projects();
|
|
11393
11404
|
});
|
|
@@ -12811,7 +12822,7 @@ function ensureTaskList(name, slug, projectId, db) {
|
|
|
12811
12822
|
return createTaskList({ name, slug, project_id: projectId }, d);
|
|
12812
12823
|
}
|
|
12813
12824
|
var init_task_lists = __esm(() => {
|
|
12814
|
-
|
|
12825
|
+
init_types();
|
|
12815
12826
|
init_database();
|
|
12816
12827
|
init_projects();
|
|
12817
12828
|
init_storage_tombstones();
|
|
@@ -13101,7 +13112,7 @@ function scanTextForSecrets(text, options = {}) {
|
|
|
13101
13112
|
};
|
|
13102
13113
|
}
|
|
13103
13114
|
function redactText(text, options = {}) {
|
|
13104
|
-
const placeholder = options.placeholder ??
|
|
13115
|
+
const placeholder = options.placeholder ?? REDACTION_PLACEHOLDER2;
|
|
13105
13116
|
let out = text;
|
|
13106
13117
|
for (const { pattern, allowlist_ok } of DEFAULT_PATTERNS) {
|
|
13107
13118
|
out = out.replace(new RegExp(pattern.source, pattern.flags), (match) => {
|
|
@@ -13128,7 +13139,7 @@ function redactExportRecord(record) {
|
|
|
13128
13139
|
}
|
|
13129
13140
|
return base;
|
|
13130
13141
|
}
|
|
13131
|
-
var SECRET_REDACTION_SCHEMA,
|
|
13142
|
+
var SECRET_REDACTION_SCHEMA, REDACTION_PLACEHOLDER2 = "[REDACTED]", DEFAULT_PATTERNS, DEFAULT_ALLOWLIST, customRedactors;
|
|
13132
13143
|
var init_secret_redaction = __esm(() => {
|
|
13133
13144
|
init_redaction();
|
|
13134
13145
|
SECRET_REDACTION_SCHEMA = ["todos", "secret_redaction", "v1"].join(".");
|
|
@@ -14435,7 +14446,7 @@ function wouldCreateCycle(taskId, dependsOn, db) {
|
|
|
14435
14446
|
return false;
|
|
14436
14447
|
}
|
|
14437
14448
|
var init_task_graph = __esm(() => {
|
|
14438
|
-
|
|
14449
|
+
init_types();
|
|
14439
14450
|
init_database();
|
|
14440
14451
|
init_task_crud();
|
|
14441
14452
|
});
|
|
@@ -14994,7 +15005,7 @@ function spawnNextRecurrence(completedTask, db, completedAt) {
|
|
|
14994
15005
|
}
|
|
14995
15006
|
var MAX_SPAWN_DEPTH = 10;
|
|
14996
15007
|
var init_task_lifecycle = __esm(() => {
|
|
14997
|
-
|
|
15008
|
+
init_types();
|
|
14998
15009
|
init_database();
|
|
14999
15010
|
init_completion_guard();
|
|
15000
15011
|
init_event_emission_safety();
|
|
@@ -15153,10 +15164,11 @@ function getTaskWithRelations(id, db) {
|
|
|
15153
15164
|
JOIN task_dependencies td ON td.depends_on = t.id
|
|
15154
15165
|
WHERE td.task_id = ?`).all(id);
|
|
15155
15166
|
const dependencies = depRows.map(rowToTask);
|
|
15156
|
-
const
|
|
15167
|
+
const blocked_by = dependencies.filter((dep) => isBlockingDependencyStatus(dep.status));
|
|
15168
|
+
const blocksRows = d.query(`SELECT t.* FROM tasks t
|
|
15157
15169
|
JOIN task_dependencies td ON td.task_id = t.id
|
|
15158
15170
|
WHERE td.depends_on = ?`).all(id);
|
|
15159
|
-
const
|
|
15171
|
+
const blocks = blocksRows.map(rowToTask);
|
|
15160
15172
|
const comments = d.query("SELECT * FROM task_comments WHERE task_id = ? ORDER BY created_at").all(id);
|
|
15161
15173
|
const parent = task.parent_id ? getTask(task.parent_id, d) : null;
|
|
15162
15174
|
const checklist = getChecklist(id, d);
|
|
@@ -15165,6 +15177,7 @@ function getTaskWithRelations(id, db) {
|
|
|
15165
15177
|
subtasks,
|
|
15166
15178
|
dependencies,
|
|
15167
15179
|
blocked_by,
|
|
15180
|
+
blocks,
|
|
15168
15181
|
comments,
|
|
15169
15182
|
parent,
|
|
15170
15183
|
checklist
|
|
@@ -15622,7 +15635,7 @@ function deleteTask(id, db) {
|
|
|
15622
15635
|
return result.changes > 0;
|
|
15623
15636
|
}
|
|
15624
15637
|
var init_task_crud = __esm(() => {
|
|
15625
|
-
|
|
15638
|
+
init_types();
|
|
15626
15639
|
init_database();
|
|
15627
15640
|
init_completion_guard();
|
|
15628
15641
|
init_event_emission_safety();
|
|
@@ -15808,7 +15821,7 @@ function getTaskStats(filters, db) {
|
|
|
15808
15821
|
return { total: totalRow.count, by_status, by_priority, completion_rate, by_agent };
|
|
15809
15822
|
}
|
|
15810
15823
|
var init_task_status = __esm(() => {
|
|
15811
|
-
|
|
15824
|
+
init_types();
|
|
15812
15825
|
init_database();
|
|
15813
15826
|
init_task_crud();
|
|
15814
15827
|
init_task_graph();
|
|
@@ -16489,7 +16502,7 @@ function deletePlan(id, db) {
|
|
|
16489
16502
|
return result.changes > 0;
|
|
16490
16503
|
}
|
|
16491
16504
|
var init_plans = __esm(() => {
|
|
16492
|
-
|
|
16505
|
+
init_types();
|
|
16493
16506
|
init_event_emission_safety();
|
|
16494
16507
|
init_event_hooks();
|
|
16495
16508
|
init_database();
|
|
@@ -17176,7 +17189,7 @@ function deleteComment(id, db) {
|
|
|
17176
17189
|
return result.changes > 0;
|
|
17177
17190
|
}
|
|
17178
17191
|
var init_comments = __esm(() => {
|
|
17179
|
-
|
|
17192
|
+
init_types();
|
|
17180
17193
|
init_database();
|
|
17181
17194
|
init_tasks();
|
|
17182
17195
|
init_prewrite_secrets();
|
|
@@ -18055,7 +18068,7 @@ var init_task_runs = __esm(() => {
|
|
|
18055
18068
|
init_event_emission_safety();
|
|
18056
18069
|
init_event_hooks();
|
|
18057
18070
|
init_prewrite_secrets();
|
|
18058
|
-
|
|
18071
|
+
init_types();
|
|
18059
18072
|
init_comments();
|
|
18060
18073
|
init_database();
|
|
18061
18074
|
init_task_files();
|
|
@@ -18845,7 +18858,7 @@ async function cloudDetailRelations(cloud, id) {
|
|
|
18845
18858
|
if (status !== 404 && status !== 501) {
|
|
18846
18859
|
console.error(chalk2.dim(`Warning: could not load task dependencies: ${e instanceof Error ? e.message : String(e)}`));
|
|
18847
18860
|
}
|
|
18848
|
-
return { dependencies: [], blocked_by: [] };
|
|
18861
|
+
return { dependencies: [], blocked_by: [], blocks: [] };
|
|
18849
18862
|
}
|
|
18850
18863
|
}
|
|
18851
18864
|
function resolveProjectIdOrSlug(input) {
|
|
@@ -19422,6 +19435,7 @@ function registerTaskCommands(program2) {
|
|
|
19422
19435
|
tags: remote.tags ?? [],
|
|
19423
19436
|
dependencies: relations.dependencies,
|
|
19424
19437
|
blocked_by: relations.blocked_by,
|
|
19438
|
+
blocks: relations.blocks,
|
|
19425
19439
|
comments: commentPage.comments,
|
|
19426
19440
|
comments_page: {
|
|
19427
19441
|
count: commentPage.count,
|
|
@@ -19505,10 +19519,10 @@ function registerTaskCommands(program2) {
|
|
|
19505
19519
|
console.log(` ${formatTaskLine(dep)}`);
|
|
19506
19520
|
}
|
|
19507
19521
|
}
|
|
19508
|
-
if (task2.
|
|
19522
|
+
if (task2.blocks.length > 0) {
|
|
19509
19523
|
console.log(chalk2.bold(`
|
|
19510
|
-
Blocks (${task2.
|
|
19511
|
-
for (const b of task2.
|
|
19524
|
+
Blocks (${task2.blocks.length}):`));
|
|
19525
|
+
for (const b of task2.blocks) {
|
|
19512
19526
|
console.log(` ${formatTaskLine(b)}`);
|
|
19513
19527
|
}
|
|
19514
19528
|
}
|
|
@@ -19551,6 +19565,7 @@ function registerTaskCommands(program2) {
|
|
|
19551
19565
|
tags: remote.tags ?? [],
|
|
19552
19566
|
dependencies: relations.dependencies,
|
|
19553
19567
|
blocked_by: relations.blocked_by,
|
|
19568
|
+
blocks: relations.blocks,
|
|
19554
19569
|
comments: commentPage.comments,
|
|
19555
19570
|
comments_page: {
|
|
19556
19571
|
count: commentPage.count,
|
|
@@ -19632,10 +19647,10 @@ ${chalk2.cyan(sid)} ${statusColor(task2.status)} ${prioColor(task2.priority)} ${
|
|
|
19632
19647
|
console.log(chalk2.red(`
|
|
19633
19648
|
BLOCKED by ${unfinishedDeps.length} unfinished dep(s)`));
|
|
19634
19649
|
}
|
|
19635
|
-
if (task2.
|
|
19650
|
+
if (task2.blocks.length > 0) {
|
|
19636
19651
|
console.log(chalk2.bold(`
|
|
19637
|
-
Blocks (${task2.
|
|
19638
|
-
for (const b of task2.
|
|
19652
|
+
Blocks (${task2.blocks.length}):`));
|
|
19653
|
+
for (const b of task2.blocks)
|
|
19639
19654
|
console.log(` ${formatTaskLine(b)}`);
|
|
19640
19655
|
}
|
|
19641
19656
|
if (task2.subtasks.length > 0) {
|
|
@@ -20203,7 +20218,7 @@ var init_task_commands = __esm(() => {
|
|
|
20203
20218
|
init_cloud_router();
|
|
20204
20219
|
init_helpers();
|
|
20205
20220
|
init_output_redaction();
|
|
20206
|
-
|
|
20221
|
+
init_types();
|
|
20207
20222
|
});
|
|
20208
20223
|
|
|
20209
20224
|
// src/lib/plan-artifacts.ts
|
|
@@ -21724,13 +21739,14 @@ function detectCyclesFromEdges(edges) {
|
|
|
21724
21739
|
}
|
|
21725
21740
|
return cycles;
|
|
21726
21741
|
}
|
|
21727
|
-
function buildTaskDependencyEdges(task, dependencies,
|
|
21742
|
+
function buildTaskDependencyEdges(task, dependencies, blocks) {
|
|
21728
21743
|
return {
|
|
21729
21744
|
schema_version: TASK_DEPENDENCY_EDGES_SCHEMA,
|
|
21730
21745
|
task_id: task.id,
|
|
21731
21746
|
short_id: task.short_id,
|
|
21732
21747
|
dependencies: dependencies.map(toNode),
|
|
21733
|
-
blocked_by:
|
|
21748
|
+
blocked_by: dependencies.filter((dep) => isBlockingDependencyStatus(dep.status)).map(toNode),
|
|
21749
|
+
blocks: blocks.map(toNode)
|
|
21734
21750
|
};
|
|
21735
21751
|
}
|
|
21736
21752
|
function getTaskDependencyEdges(taskId, db) {
|
|
@@ -21739,8 +21755,8 @@ function getTaskDependencyEdges(taskId, db) {
|
|
|
21739
21755
|
if (!task)
|
|
21740
21756
|
return null;
|
|
21741
21757
|
const dependencies = getTaskDependencies(taskId, d).map((edge) => getTask(edge.depends_on, d)).filter((t) => Boolean(t));
|
|
21742
|
-
const
|
|
21743
|
-
return buildTaskDependencyEdges(task, dependencies,
|
|
21758
|
+
const blocks = getTaskDependents(taskId, d).map((edge) => getTask(edge.task_id, d)).filter((t) => Boolean(t));
|
|
21759
|
+
return buildTaskDependencyEdges(task, dependencies, blocks);
|
|
21744
21760
|
}
|
|
21745
21761
|
function buildProjectDependencyGraph(projectId, tasks, edges, generatedAt = new Date().toISOString()) {
|
|
21746
21762
|
const nodeIds = new Set(tasks.map((t) => t.id));
|
|
@@ -21766,6 +21782,8 @@ var init_dependency_graph = __esm(() => {
|
|
|
21766
21782
|
init_tasks();
|
|
21767
21783
|
init_task_graph();
|
|
21768
21784
|
init_task_lifecycle();
|
|
21785
|
+
init_types();
|
|
21786
|
+
init_types();
|
|
21769
21787
|
});
|
|
21770
21788
|
|
|
21771
21789
|
// src/lib/local-fields.ts
|
|
@@ -21860,7 +21878,7 @@ var LOCAL_FIELDS_KEY = "local_fields";
|
|
|
21860
21878
|
var init_local_fields = __esm(() => {
|
|
21861
21879
|
init_database();
|
|
21862
21880
|
init_tasks();
|
|
21863
|
-
|
|
21881
|
+
init_types();
|
|
21864
21882
|
init_redaction();
|
|
21865
21883
|
});
|
|
21866
21884
|
|
|
@@ -25241,7 +25259,7 @@ function registerProjectCommands(program2) {
|
|
|
25241
25259
|
}
|
|
25242
25260
|
if (globalOpts.json) {
|
|
25243
25261
|
const relations = await cloudGetTaskRelations(cloud, cloudId);
|
|
25244
|
-
output(buildTaskDependencyEdges({ id: cloudId, short_id: null }, relations.dependencies.filter(isResolvedTask), relations.
|
|
25262
|
+
output(buildTaskDependencyEdges({ id: cloudId, short_id: null }, relations.dependencies.filter(isResolvedTask), relations.blocks.filter(isResolvedTask)), true);
|
|
25245
25263
|
return;
|
|
25246
25264
|
}
|
|
25247
25265
|
const edges = await cloudGetDependencies(cloud, cloudId);
|
|
@@ -25250,12 +25268,12 @@ function registerProjectCommands(program2) {
|
|
|
25250
25268
|
for (const dep of edges.dependencies)
|
|
25251
25269
|
console.log(` ${chalk4.cyan(dep.depends_on)}`);
|
|
25252
25270
|
}
|
|
25253
|
-
if (edges.
|
|
25271
|
+
if (edges.blocks.length > 0) {
|
|
25254
25272
|
console.log(chalk4.bold("Blocks:"));
|
|
25255
|
-
for (const b of edges.
|
|
25273
|
+
for (const b of edges.blocks)
|
|
25256
25274
|
console.log(` ${chalk4.cyan(b.task_id)}`);
|
|
25257
25275
|
}
|
|
25258
|
-
if (edges.dependencies.length === 0 && edges.
|
|
25276
|
+
if (edges.dependencies.length === 0 && edges.blocks.length === 0) {
|
|
25259
25277
|
console.log(chalk4.dim("No dependencies."));
|
|
25260
25278
|
}
|
|
25261
25279
|
return;
|
|
@@ -25317,13 +25335,13 @@ function registerProjectCommands(program2) {
|
|
|
25317
25335
|
console.log(` ${formatTaskLine(dep)}`);
|
|
25318
25336
|
}
|
|
25319
25337
|
}
|
|
25320
|
-
if (task.
|
|
25338
|
+
if (task.blocks.length > 0) {
|
|
25321
25339
|
console.log(chalk4.bold("Blocks:"));
|
|
25322
|
-
for (const b of task.
|
|
25340
|
+
for (const b of task.blocks) {
|
|
25323
25341
|
console.log(` ${formatTaskLine(b)}`);
|
|
25324
25342
|
}
|
|
25325
25343
|
}
|
|
25326
|
-
if (task.dependencies.length === 0 && task.
|
|
25344
|
+
if (task.dependencies.length === 0 && task.blocks.length === 0) {
|
|
25327
25345
|
console.log(chalk4.dim("No dependencies."));
|
|
25328
25346
|
}
|
|
25329
25347
|
}
|
|
@@ -26500,7 +26518,7 @@ function getCapableAgents(capabilities, opts, db) {
|
|
|
26500
26518
|
return opts?.limit ? scored.slice(0, opts.limit) : scored;
|
|
26501
26519
|
}
|
|
26502
26520
|
var init_agents = __esm(() => {
|
|
26503
|
-
|
|
26521
|
+
init_types();
|
|
26504
26522
|
init_database();
|
|
26505
26523
|
init_identity_mapping();
|
|
26506
26524
|
init_storage_tombstones();
|
|
@@ -26948,6 +26966,44 @@ var init_agent_commands = __esm(() => {
|
|
|
26948
26966
|
init_cloud_router();
|
|
26949
26967
|
});
|
|
26950
26968
|
|
|
26969
|
+
// src/server/port.ts
|
|
26970
|
+
var exports_port = {};
|
|
26971
|
+
__export(exports_port, {
|
|
26972
|
+
refuseInvalidPort: () => refuseInvalidPort,
|
|
26973
|
+
findFreePort: () => findFreePort,
|
|
26974
|
+
coercePort: () => coercePort,
|
|
26975
|
+
DEFAULT_PORT: () => DEFAULT_PORT
|
|
26976
|
+
});
|
|
26977
|
+
function coercePort(raw) {
|
|
26978
|
+
if (raw === undefined)
|
|
26979
|
+
return;
|
|
26980
|
+
const trimmed = raw.trim();
|
|
26981
|
+
if (!/^\d+$/.test(trimmed))
|
|
26982
|
+
return;
|
|
26983
|
+
if (trimmed.length > 1 && trimmed.startsWith("0"))
|
|
26984
|
+
return;
|
|
26985
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
26986
|
+
if (!Number.isInteger(parsed) || parsed > 65535)
|
|
26987
|
+
return;
|
|
26988
|
+
return parsed;
|
|
26989
|
+
}
|
|
26990
|
+
function refuseInvalidPort(source, raw) {
|
|
26991
|
+
console.error(`Invalid ${source}: ${JSON.stringify(raw)} is not a port.
|
|
26992
|
+
` + `Use an integer from 0 to 65535, where 0 asks the kernel for a free port.`);
|
|
26993
|
+
process.exit(1);
|
|
26994
|
+
}
|
|
26995
|
+
async function findFreePort(start) {
|
|
26996
|
+
for (let port = start;port < start + 100; port++) {
|
|
26997
|
+
try {
|
|
26998
|
+
const server = Bun.serve({ port, fetch: () => new Response("") });
|
|
26999
|
+
server.stop(true);
|
|
27000
|
+
return port;
|
|
27001
|
+
} catch {}
|
|
27002
|
+
}
|
|
27003
|
+
return start;
|
|
27004
|
+
}
|
|
27005
|
+
var DEFAULT_PORT = 19427;
|
|
27006
|
+
|
|
26951
27007
|
// src/lib/db-backup.ts
|
|
26952
27008
|
import { existsSync as existsSync14, copyFileSync, mkdirSync as mkdirSync8, readFileSync as readFileSync8, renameSync, statSync as statSync6, writeFileSync as writeFileSync7, unlinkSync } from "fs";
|
|
26953
27009
|
import { dirname as dirname7, join as join12, resolve as resolve14 } from "path";
|
|
@@ -29519,7 +29575,7 @@ var init_approval_gates = __esm(() => {
|
|
|
29519
29575
|
init_database();
|
|
29520
29576
|
init_task_runs();
|
|
29521
29577
|
init_tasks();
|
|
29522
|
-
|
|
29578
|
+
init_types();
|
|
29523
29579
|
init_event_emission_safety();
|
|
29524
29580
|
init_event_hooks();
|
|
29525
29581
|
});
|
|
@@ -31227,9 +31283,11 @@ async function removeDependency2(taskId, dependsOn, store) {
|
|
|
31227
31283
|
}
|
|
31228
31284
|
async function listDependencies(taskId, store) {
|
|
31229
31285
|
const edges = await store.list("dependencies");
|
|
31286
|
+
const incoming = edges.filter((edge) => edge.depends_on === taskId).map((edge) => ({ task_id: edge.task_id, depends_on: edge.depends_on }));
|
|
31230
31287
|
return {
|
|
31231
31288
|
dependencies: edges.filter((edge) => edge.task_id === taskId).map((edge) => ({ task_id: edge.task_id, depends_on: edge.depends_on })),
|
|
31232
|
-
|
|
31289
|
+
blocks: incoming,
|
|
31290
|
+
blocked_by: incoming
|
|
31233
31291
|
};
|
|
31234
31292
|
}
|
|
31235
31293
|
async function addVerification(input, store, context) {
|
|
@@ -31773,7 +31831,7 @@ function postgresConstraintName(error) {
|
|
|
31773
31831
|
}
|
|
31774
31832
|
var CLOUD_LOCK_EXPIRY_MINUTES = 30, TASK_ORDER_TIEBREAK = "CASE payload->>'priority' WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END ASC, payload->>'created_at' ASC, payload->>'id' ASC", TASK_ORDER_BY;
|
|
31775
31833
|
var init_postgres_adapter = __esm(() => {
|
|
31776
|
-
|
|
31834
|
+
init_types();
|
|
31777
31835
|
init_postgres_sync();
|
|
31778
31836
|
init_redaction();
|
|
31779
31837
|
TASK_ORDER_BY = `ORDER BY ${TASK_ORDER_TIEBREAK}`;
|
|
@@ -32256,7 +32314,7 @@ class PostgresPrGroupLedgerPersistence {
|
|
|
32256
32314
|
}
|
|
32257
32315
|
}
|
|
32258
32316
|
var init_postgres = __esm(() => {
|
|
32259
|
-
|
|
32317
|
+
init_types2();
|
|
32260
32318
|
});
|
|
32261
32319
|
|
|
32262
32320
|
// src/storage/comment-redaction-backfill.ts
|
|
@@ -33974,7 +34032,7 @@ function handleStaticFiles(path, method, ctx, json2, serveStaticFile2) {
|
|
|
33974
34032
|
var init_routes = __esm(() => {
|
|
33975
34033
|
init_tasks();
|
|
33976
34034
|
init_database();
|
|
33977
|
-
|
|
34035
|
+
init_types();
|
|
33978
34036
|
init_projects();
|
|
33979
34037
|
init_agents();
|
|
33980
34038
|
init_plans();
|
|
@@ -36612,7 +36670,7 @@ async function handlePrGroupHttpRequest(req, url, ledger, basePath, principal) {
|
|
|
36612
36670
|
}
|
|
36613
36671
|
var JSON_HEADERS;
|
|
36614
36672
|
var init_pr_groups = __esm(() => {
|
|
36615
|
-
|
|
36673
|
+
init_types2();
|
|
36616
36674
|
JSON_HEADERS = { "Content-Type": "application/json" };
|
|
36617
36675
|
});
|
|
36618
36676
|
|
|
@@ -37731,7 +37789,7 @@ async function handleV1Request(req, url, dependencies = {}) {
|
|
|
37731
37789
|
}
|
|
37732
37790
|
var JSON_HEADERS2, DEFAULT_COMMENT_PAGE_SIZE = 100, MAX_COMMENT_PAGE_SIZE = 500, LEGACY_COMMENT_RESPONSE_LIMIT = 500;
|
|
37733
37791
|
var init_v1 = __esm(() => {
|
|
37734
|
-
|
|
37792
|
+
init_types();
|
|
37735
37793
|
init_cloud();
|
|
37736
37794
|
init_pr_groups();
|
|
37737
37795
|
init_redaction();
|
|
@@ -41816,7 +41874,7 @@ function getDueDispatches(db) {
|
|
|
41816
41874
|
}
|
|
41817
41875
|
var init_dispatches = __esm(() => {
|
|
41818
41876
|
init_database();
|
|
41819
|
-
|
|
41877
|
+
init_types();
|
|
41820
41878
|
init_prewrite_secrets();
|
|
41821
41879
|
});
|
|
41822
41880
|
|
|
@@ -42595,7 +42653,7 @@ ${task.description}` : null
|
|
|
42595
42653
|
var init_task_crud2 = __esm(() => {
|
|
42596
42654
|
init_zod();
|
|
42597
42655
|
init_tasks();
|
|
42598
|
-
|
|
42656
|
+
init_types();
|
|
42599
42657
|
init_token_utils();
|
|
42600
42658
|
init_cloud_router();
|
|
42601
42659
|
});
|
|
@@ -43993,7 +44051,7 @@ function renderWorkflowStatesMarkdown(states = listWorkflowStates()) {
|
|
|
43993
44051
|
var LOCAL_FIELDS_KEY2 = "local_fields", WORKFLOW_STATE_KEY = "workflow_state", DEFAULT_WORKFLOW_STATES;
|
|
43994
44052
|
var init_workflow_states = __esm(() => {
|
|
43995
44053
|
init_tasks();
|
|
43996
|
-
|
|
44054
|
+
init_types();
|
|
43997
44055
|
init_database();
|
|
43998
44056
|
init_config();
|
|
43999
44057
|
init_local_fields();
|
|
@@ -48237,7 +48295,7 @@ var init_task_project_tools = __esm(() => {
|
|
|
48237
48295
|
init_capacity_forecasts();
|
|
48238
48296
|
init_audit_ledger();
|
|
48239
48297
|
init_release_compatibility();
|
|
48240
|
-
|
|
48298
|
+
init_types();
|
|
48241
48299
|
});
|
|
48242
48300
|
|
|
48243
48301
|
// src/db/handoffs.ts
|
|
@@ -48914,7 +48972,7 @@ function registerTaskWorkflowTools(server, ctx) {
|
|
|
48914
48972
|
}
|
|
48915
48973
|
var init_task_workflow_tools = __esm(() => {
|
|
48916
48974
|
init_zod();
|
|
48917
|
-
|
|
48975
|
+
init_types();
|
|
48918
48976
|
init_token_utils();
|
|
48919
48977
|
init_cloud_router();
|
|
48920
48978
|
});
|
|
@@ -49879,7 +49937,7 @@ var init_context_packs = __esm(() => {
|
|
|
49879
49937
|
init_task_graph();
|
|
49880
49938
|
init_task_runs();
|
|
49881
49939
|
init_tasks();
|
|
49882
|
-
|
|
49940
|
+
init_types();
|
|
49883
49941
|
init_redaction();
|
|
49884
49942
|
DEFAULT_LIMITS = {
|
|
49885
49943
|
comment_limit: 8,
|
|
@@ -51274,7 +51332,7 @@ function resolveMissingTaskFindings(input, db) {
|
|
|
51274
51332
|
var TASK_FINDING_SCHEMA_VERSION = "todos.task_finding.v1", TASK_FINDING_UPSERT_SCHEMA_VERSION = "todos.task_finding_upsert.v1", TASK_FINDING_RESOLVE_MISSING_SCHEMA_VERSION = "todos.task_finding_resolve_missing.v1", SEVERITIES, STATUSES;
|
|
51275
51333
|
var init_findings = __esm(() => {
|
|
51276
51334
|
init_redaction();
|
|
51277
|
-
|
|
51335
|
+
init_types();
|
|
51278
51336
|
init_database();
|
|
51279
51337
|
init_tasks();
|
|
51280
51338
|
init_task_runs();
|
|
@@ -56372,7 +56430,7 @@ function forceUnlockFile(path, db) {
|
|
|
56372
56430
|
var FILE_LOCK_DEFAULT_TTL_SECONDS;
|
|
56373
56431
|
var init_file_locks = __esm(() => {
|
|
56374
56432
|
init_database();
|
|
56375
|
-
|
|
56433
|
+
init_types();
|
|
56376
56434
|
FILE_LOCK_DEFAULT_TTL_SECONDS = 30 * 60;
|
|
56377
56435
|
});
|
|
56378
56436
|
|
|
@@ -61520,7 +61578,7 @@ var agentFocusMap, isDirectRun;
|
|
|
61520
61578
|
var init_mcp2 = __esm(() => {
|
|
61521
61579
|
init_agents();
|
|
61522
61580
|
init_database();
|
|
61523
|
-
|
|
61581
|
+
init_types();
|
|
61524
61582
|
init_dispatch2();
|
|
61525
61583
|
init_task_crud2();
|
|
61526
61584
|
init_task_project_tools();
|
|
@@ -61874,7 +61932,7 @@ var init_pr_groups2 = __esm(() => {
|
|
|
61874
61932
|
init_database();
|
|
61875
61933
|
init_ledger();
|
|
61876
61934
|
init_sqlite();
|
|
61877
|
-
|
|
61935
|
+
init_types2();
|
|
61878
61936
|
init_ledger();
|
|
61879
61937
|
init_sqlite();
|
|
61880
61938
|
init_http_client();
|
|
@@ -62112,7 +62170,7 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
62112
62170
|
const path = url.pathname;
|
|
62113
62171
|
const method = req.method;
|
|
62114
62172
|
const reqOrigin = req.headers.get("origin") || undefined;
|
|
62115
|
-
const corsHeaders = reqOrigin &&
|
|
62173
|
+
const corsHeaders = reqOrigin && reqOrigin === `http://localhost:${ctx.port}` ? {
|
|
62116
62174
|
"Access-Control-Allow-Origin": reqOrigin,
|
|
62117
62175
|
"Access-Control-Allow-Methods": "GET, POST, PATCH, DELETE, OPTIONS",
|
|
62118
62176
|
"Access-Control-Allow-Headers": "Content-Type, X-API-Key, Authorization",
|
|
@@ -62400,7 +62458,9 @@ Dashboard not found at: ${dashboardDir}`);
|
|
|
62400
62458
|
};
|
|
62401
62459
|
process.on("SIGINT", shutdown);
|
|
62402
62460
|
process.on("SIGTERM", shutdown);
|
|
62403
|
-
const
|
|
62461
|
+
const boundPort = server.port ?? port;
|
|
62462
|
+
ctx.port = boundPort;
|
|
62463
|
+
const serverUrl = `http://localhost:${boundPort}`;
|
|
62404
62464
|
console.log(`Todos Dashboard running at ${serverUrl}`);
|
|
62405
62465
|
if (shouldOpen) {
|
|
62406
62466
|
try {
|
|
@@ -62882,7 +62942,7 @@ function TaskDetail({ task: task2 }) {
|
|
|
62882
62942
|
}, dep.id, true, undefined, this))
|
|
62883
62943
|
]
|
|
62884
62944
|
}, undefined, true, undefined, this),
|
|
62885
|
-
task2.
|
|
62945
|
+
task2.blocks.length > 0 && /* @__PURE__ */ jsxDEV3(Box3, {
|
|
62886
62946
|
flexDirection: "column",
|
|
62887
62947
|
marginBottom: 1,
|
|
62888
62948
|
children: [
|
|
@@ -62890,11 +62950,11 @@ function TaskDetail({ task: task2 }) {
|
|
|
62890
62950
|
bold: true,
|
|
62891
62951
|
children: [
|
|
62892
62952
|
"Blocks (",
|
|
62893
|
-
task2.
|
|
62953
|
+
task2.blocks.length,
|
|
62894
62954
|
"):"
|
|
62895
62955
|
]
|
|
62896
62956
|
}, undefined, true, undefined, this),
|
|
62897
|
-
task2.
|
|
62957
|
+
task2.blocks.map((b) => /* @__PURE__ */ jsxDEV3(Box3, {
|
|
62898
62958
|
marginLeft: 2,
|
|
62899
62959
|
children: [
|
|
62900
62960
|
/* @__PURE__ */ jsxDEV3(Text3, {
|
|
@@ -64878,18 +64938,11 @@ function registerConfigServeCommands(program2) {
|
|
|
64878
64938
|
console.log(renderTerminalNotification2(notification, rule?.format || "line"));
|
|
64879
64939
|
}
|
|
64880
64940
|
});
|
|
64881
|
-
program2.command("serve").description("Start the web dashboard").option("--port <port>", "Port number",
|
|
64941
|
+
program2.command("serve").description("Start the web dashboard").option("--port <port>", "Port number", String(DEFAULT_PORT)).option("--host <host>", "Host to bind (default: 127.0.0.1 localhost only, use 0.0.0.0 for all interfaces)").option("--api-key <key>", "Require this API key for /api/* requests").option("--allow-anonymous", "Local dev only: serve /api/* and /mcp without a credential (refused unless the bind host is loopback)").option("--no-open", "Don't open browser automatically").action(async (opts) => {
|
|
64882
64942
|
const { startServer: startServer2 } = await Promise.resolve().then(() => (init_serve(), exports_serve));
|
|
64883
|
-
const
|
|
64884
|
-
|
|
64885
|
-
|
|
64886
|
-
try {
|
|
64887
|
-
const s = Bun.serve({ port: p, fetch: () => new Response("") });
|
|
64888
|
-
s.stop(true);
|
|
64889
|
-
port = p;
|
|
64890
|
-
break;
|
|
64891
|
-
} catch {}
|
|
64892
|
-
}
|
|
64943
|
+
const { coercePort: coercePort2, findFreePort: findFreePort2, refuseInvalidPort: refuseInvalidPort2 } = await Promise.resolve().then(() => exports_port);
|
|
64944
|
+
const requestedPort = coercePort2(opts.port) ?? refuseInvalidPort2("--port", String(opts.port));
|
|
64945
|
+
const port = requestedPort === 0 ? requestedPort : await findFreePort2(requestedPort);
|
|
64893
64946
|
if (port !== requestedPort) {
|
|
64894
64947
|
console.log(`Port ${requestedPort} in use, using ${port}`);
|
|
64895
64948
|
}
|
|
@@ -69304,7 +69357,7 @@ var init_query_commands = __esm(() => {
|
|
|
69304
69357
|
init_local_reports();
|
|
69305
69358
|
init_helpers();
|
|
69306
69359
|
init_cloud_router();
|
|
69307
|
-
|
|
69360
|
+
init_types();
|
|
69308
69361
|
});
|
|
69309
69362
|
|
|
69310
69363
|
// src/cli/commands/mcp-hooks-commands.ts
|