@hasna/todos 0.15.4 → 0.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/delegate.d.ts +51 -0
- package/dist/cli/commands/delegate.d.ts.map +1 -0
- package/dist/cli/index.js +628 -202
- package/dist/cli/stage-a.d.ts.map +1 -1
- package/dist/contracts.js +13 -1
- package/dist/db/task-crud.d.ts.map +1 -1
- package/dist/index.js +13 -1
- package/dist/lib/delegation-brief.d.ts +31 -0
- package/dist/lib/delegation-brief.d.ts.map +1 -0
- package/dist/lib/delegation-policy.d.ts +32 -0
- package/dist/lib/delegation-policy.d.ts.map +1 -0
- package/dist/lib/delegation-record.d.ts +50 -0
- package/dist/lib/delegation-record.d.ts.map +1 -0
- package/dist/lib/delegation-verify.d.ts +57 -0
- package/dist/lib/delegation-verify.d.ts.map +1 -0
- package/dist/mcp/index.js +13 -1
- package/dist/mcp.js +1 -1
- package/dist/registry.js +13 -1
- package/dist/release-provenance.json +5 -5
- package/dist/server/index.js +13 -1
- package/dist/storage.js +12 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
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.15.
|
|
2126
|
+
version: "0.15.5",
|
|
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",
|
|
@@ -6646,6 +6646,7 @@ var init_stage_a = __esm(() => {
|
|
|
6646
6646
|
"count",
|
|
6647
6647
|
"dashboard",
|
|
6648
6648
|
"dedupe",
|
|
6649
|
+
"delegate",
|
|
6649
6650
|
"delete",
|
|
6650
6651
|
"deps",
|
|
6651
6652
|
"dispatch",
|
|
@@ -6832,6 +6833,7 @@ var init_stage_a = __esm(() => {
|
|
|
6832
6833
|
"claim",
|
|
6833
6834
|
"comment",
|
|
6834
6835
|
"count",
|
|
6836
|
+
"delegate",
|
|
6835
6837
|
"delete",
|
|
6836
6838
|
"deps",
|
|
6837
6839
|
"doctor",
|
|
@@ -16243,6 +16245,18 @@ function updateTask(id, input, db) {
|
|
|
16243
16245
|
sets.push("assigned_to = ?");
|
|
16244
16246
|
params.push(input.assigned_to);
|
|
16245
16247
|
}
|
|
16248
|
+
if (input.assigned_by !== undefined) {
|
|
16249
|
+
sets.push("assigned_by = ?");
|
|
16250
|
+
params.push(input.assigned_by);
|
|
16251
|
+
}
|
|
16252
|
+
if (input.delegated_from !== undefined) {
|
|
16253
|
+
sets.push("delegated_from = ?");
|
|
16254
|
+
params.push(input.delegated_from);
|
|
16255
|
+
}
|
|
16256
|
+
if (input.delegation_depth !== undefined) {
|
|
16257
|
+
sets.push("delegation_depth = ?");
|
|
16258
|
+
params.push(input.delegation_depth);
|
|
16259
|
+
}
|
|
16246
16260
|
if (input.working_dir !== undefined) {
|
|
16247
16261
|
sets.push("working_dir = ?");
|
|
16248
16262
|
params.push(input.working_dir);
|
|
@@ -72729,16 +72743,425 @@ var init_dispatch3 = __esm(() => {
|
|
|
72729
72743
|
init_helpers();
|
|
72730
72744
|
});
|
|
72731
72745
|
|
|
72746
|
+
// src/lib/delegation-brief.ts
|
|
72747
|
+
import { createHash as createHash17 } from "crypto";
|
|
72748
|
+
function resolveDelegationBrief(input, sources) {
|
|
72749
|
+
const hasPath = typeof input.briefPath === "string" && input.briefPath.length > 0;
|
|
72750
|
+
const hasText = typeof input.briefText === "string" && input.briefText.length > 0;
|
|
72751
|
+
if (hasPath && hasText) {
|
|
72752
|
+
return {
|
|
72753
|
+
ok: false,
|
|
72754
|
+
reason: "conflict",
|
|
72755
|
+
message: "Pass either --brief <path> or --brief-text <text>, not both. " + "Two briefs means the worker is told two things and the [DISPATCH] record can only name one."
|
|
72756
|
+
};
|
|
72757
|
+
}
|
|
72758
|
+
if (!hasPath && !hasText) {
|
|
72759
|
+
return {
|
|
72760
|
+
ok: false,
|
|
72761
|
+
reason: "missing",
|
|
72762
|
+
message: "A delegation needs a brief: pass --brief <path> (or --brief - to read stdin), or --brief-text <text>. " + "A dispatched worker sees no announcement, no channel and no rule published after it starts, " + "so anything it is not told in the brief it will never learn."
|
|
72763
|
+
};
|
|
72764
|
+
}
|
|
72765
|
+
let text2;
|
|
72766
|
+
let source3;
|
|
72767
|
+
if (hasPath) {
|
|
72768
|
+
const path = input.briefPath;
|
|
72769
|
+
if (path === STDIN_SENTINEL) {
|
|
72770
|
+
try {
|
|
72771
|
+
text2 = sources.readStdin();
|
|
72772
|
+
} catch (error2) {
|
|
72773
|
+
return {
|
|
72774
|
+
ok: false,
|
|
72775
|
+
reason: "unreadable",
|
|
72776
|
+
message: `Could not read the brief from stdin: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
72777
|
+
};
|
|
72778
|
+
}
|
|
72779
|
+
source3 = "(stdin)";
|
|
72780
|
+
} else {
|
|
72781
|
+
try {
|
|
72782
|
+
text2 = sources.readFile(path);
|
|
72783
|
+
} catch (error2) {
|
|
72784
|
+
return {
|
|
72785
|
+
ok: false,
|
|
72786
|
+
reason: "unreadable",
|
|
72787
|
+
message: `Could not read the brief at ${path}: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
72788
|
+
};
|
|
72789
|
+
}
|
|
72790
|
+
source3 = path;
|
|
72791
|
+
}
|
|
72792
|
+
} else {
|
|
72793
|
+
text2 = input.briefText;
|
|
72794
|
+
source3 = "(--brief-text)";
|
|
72795
|
+
}
|
|
72796
|
+
if (text2.trim().length === 0) {
|
|
72797
|
+
return {
|
|
72798
|
+
ok: false,
|
|
72799
|
+
reason: "empty",
|
|
72800
|
+
message: `The brief at ${source3} is empty (it contains only whitespace). ` + "An empty brief is worse than no brief, because the dispatch record would claim the worker was briefed."
|
|
72801
|
+
};
|
|
72802
|
+
}
|
|
72803
|
+
return {
|
|
72804
|
+
ok: true,
|
|
72805
|
+
text: text2,
|
|
72806
|
+
source: source3,
|
|
72807
|
+
sha256: createHash17("sha256").update(text2, "utf8").digest("hex"),
|
|
72808
|
+
bytes: Buffer.byteLength(text2, "utf8")
|
|
72809
|
+
};
|
|
72810
|
+
}
|
|
72811
|
+
var STDIN_SENTINEL = "-";
|
|
72812
|
+
var init_delegation_brief = () => {};
|
|
72813
|
+
|
|
72814
|
+
// src/lib/delegation-policy.ts
|
|
72815
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
72816
|
+
import { homedir as homedir4 } from "os";
|
|
72817
|
+
import { join as join28 } from "path";
|
|
72818
|
+
function defaultDelegationEmbargoPath() {
|
|
72819
|
+
return process.env["TODOS_DELEGATION_EMBARGO_PATH"] || join28(homedir4(), ".hasna", "identities", "delegation-embargo.json");
|
|
72820
|
+
}
|
|
72821
|
+
function loadDelegationEmbargo(path = defaultDelegationEmbargoPath()) {
|
|
72822
|
+
try {
|
|
72823
|
+
const parsed = JSON.parse(readFileSync20(path, "utf8"));
|
|
72824
|
+
const entries = Array.isArray(parsed) ? parsed : Array.isArray(parsed?.embargoed) ? parsed.embargoed : [];
|
|
72825
|
+
const names = new Set;
|
|
72826
|
+
for (const entry2 of entries) {
|
|
72827
|
+
const raw = typeof entry2 === "string" ? entry2 : entry2?.slug;
|
|
72828
|
+
if (typeof raw === "string" && raw.trim())
|
|
72829
|
+
names.add(normalizeAgentNameInput(raw));
|
|
72830
|
+
}
|
|
72831
|
+
return names;
|
|
72832
|
+
} catch {
|
|
72833
|
+
return new Set;
|
|
72834
|
+
}
|
|
72835
|
+
}
|
|
72836
|
+
function resolveDelegationDepthThreshold(flagValue) {
|
|
72837
|
+
const fromFlag = coerceThreshold(flagValue);
|
|
72838
|
+
if (fromFlag !== null)
|
|
72839
|
+
return { value: fromFlag, source: "flag" };
|
|
72840
|
+
const fromEnv = coerceThreshold(process.env["TODOS_DELEGATION_DEPTH_THRESHOLD"]);
|
|
72841
|
+
if (fromEnv !== null)
|
|
72842
|
+
return { value: fromEnv, source: "env" };
|
|
72843
|
+
return { value: null, source: "unset" };
|
|
72844
|
+
}
|
|
72845
|
+
function coerceThreshold(value) {
|
|
72846
|
+
if (value === undefined || value === null || value === "")
|
|
72847
|
+
return null;
|
|
72848
|
+
const parsed = typeof value === "number" ? value : Number.parseInt(String(value).trim(), 10);
|
|
72849
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0)
|
|
72850
|
+
return null;
|
|
72851
|
+
return parsed;
|
|
72852
|
+
}
|
|
72853
|
+
var DEFAULT_CLAIM_WINDOW_MINUTES = 30;
|
|
72854
|
+
var init_delegation_policy = () => {};
|
|
72855
|
+
|
|
72856
|
+
// src/lib/delegation-record.ts
|
|
72857
|
+
function formatDispatchComment(input) {
|
|
72858
|
+
const lines = [];
|
|
72859
|
+
lines.push(`${DISPATCH_COMMENT_MARKER} ${input.worker} <- ${input.dispatcher} @ ${input.dispatchedAt}`);
|
|
72860
|
+
lines.push(`runtime: ${input.runtime ?? "unspecified"}`);
|
|
72861
|
+
lines.push(`brief: ${input.briefSource} (${input.briefBytes} bytes, sha256 ${input.briefSha256})`);
|
|
72862
|
+
lines.push(`lineage: delegated_from=${input.dispatcher} delegation_depth=${input.depth} reports_to=${input.reportsTo}`);
|
|
72863
|
+
lines.push(`identity: ${input.identityOutcome}`);
|
|
72864
|
+
lines.push(`seat ${input.seatSlug}: ${input.seatOpenTasks} open, threshold ${input.depthThreshold === null ? "unset" : input.depthThreshold}${input.override ? `, OVERRIDE ${input.override}` : ""}`);
|
|
72865
|
+
lines.push(`claim deadline: ${input.claimDeadline}`);
|
|
72866
|
+
lines.push("started_at is deliberately NOT set: the worker claims with `todos start`.");
|
|
72867
|
+
return lines.join(`
|
|
72868
|
+
`);
|
|
72869
|
+
}
|
|
72870
|
+
function formatDispatchNotice(input) {
|
|
72871
|
+
const shortId = input.taskId.slice(0, 8);
|
|
72872
|
+
const override = input.override ? ` [${input.override}]` : "";
|
|
72873
|
+
return `${DISPATCH_COMMENT_MARKER} ${shortId} -> ${input.worker} ` + `(by ${input.dispatcher}, depth ${input.depth}, claim by ${input.claimDeadline})${override}`;
|
|
72874
|
+
}
|
|
72875
|
+
function claimDeadlineFrom(dispatchedAt, windowMinutes) {
|
|
72876
|
+
return new Date(dispatchedAt.getTime() + windowMinutes * 60000).toISOString();
|
|
72877
|
+
}
|
|
72878
|
+
var DISPATCH_COMMENT_MARKER = "[DISPATCH]";
|
|
72879
|
+
|
|
72880
|
+
// src/lib/delegation-verify.ts
|
|
72881
|
+
function missingDelegationLineage(persisted, expected) {
|
|
72882
|
+
const missing = [];
|
|
72883
|
+
if (!sameName(persisted.assigned_to, expected.assignedTo))
|
|
72884
|
+
missing.push("assigned_to");
|
|
72885
|
+
if (!sameName(persisted.assigned_by, expected.assignedBy))
|
|
72886
|
+
missing.push("assigned_by");
|
|
72887
|
+
if (!sameName(persisted.delegated_from, expected.delegatedFrom))
|
|
72888
|
+
missing.push("delegated_from");
|
|
72889
|
+
if (persisted.delegation_depth !== expected.depth)
|
|
72890
|
+
missing.push("delegation_depth");
|
|
72891
|
+
return missing;
|
|
72892
|
+
}
|
|
72893
|
+
function sameName(actual, wanted) {
|
|
72894
|
+
return typeof actual === "string" && actual.trim().toLowerCase() === wanted.trim().toLowerCase();
|
|
72895
|
+
}
|
|
72896
|
+
function partialDelegationMessage(missing, taskId) {
|
|
72897
|
+
return `The delegation was only PARTIALLY recorded on task ${taskId}: the authority accepted the update but did not ` + `persist ${missing.join(", ")}. ` + "The row may now be assigned without its handover lineage, so it is NOT safe to treat this as delegated. " + "This is an authority-version problem, not a connectivity, credential or storage-mode problem: the /v1 server " + "must be running a build that writes assigned_by, delegated_from and delegation_depth. " + "Re-run this exact command once it is, and the row will be completed in place.";
|
|
72898
|
+
}
|
|
72899
|
+
|
|
72900
|
+
// src/cli/commands/delegate.ts
|
|
72901
|
+
var exports_delegate = {};
|
|
72902
|
+
__export(exports_delegate, {
|
|
72903
|
+
registerDelegateCommands: () => registerDelegateCommands
|
|
72904
|
+
});
|
|
72905
|
+
import chalk12 from "chalk";
|
|
72906
|
+
import { readFileSync as readFileSync21 } from "fs";
|
|
72907
|
+
function registerDelegateCommands(program2) {
|
|
72908
|
+
program2.command("delegate <task> <worker>").description("Hand a filed task to a worker in one call: brief, depth, lineage, assignment, record and notice").option("--brief <path>", "Path to the self-sufficient brief; `-` reads stdin").option("--brief-text <text>", "Inline brief, as an alternative to --brief").option("--depth-threshold <n>", "Open-task count above which this delegation parks").option("--despite-depth", "Proceed past an armed depth threshold; recorded in the [DISPATCH] comment").option("--owner-directive", "Mark as an owner-directive dispatch: depth warns and never parks").option("--seat <slug>", "Seat whose open count is read (default: the lineage parent)").option("--runtime <name>", "Worker runtime label recorded in the comment (e.g. claude-code-subagent)").option("--reports-to <agent>", "Lineage parent for the worker identity (default: the dispatcher)").option("--reuse-identity", "Skip registration and reuse an existing worker identity").option("--depth <n>", "Explicit delegation_depth (default: the task's current depth + 1)").option("--channel <name>", "Channel for the one-line notice (default: $TODOS_DELEGATE_NOTICE_CHANNEL)").option("--no-post", "Skip the channel notice").option("--claim-window <minutes>", `Minutes before the claim deadline (default: ${DEFAULT_CLAIM_WINDOW_MINUTES})`).option("--assign-seat", "Allow <worker> to name a durable seat (a seat queue has no session watching it)").option("--dry-run", "Report all seven effects and perform none").option("-j, --json", "Output as JSON").action(async (taskRef, workerInput, opts) => {
|
|
72909
|
+
const globalOpts = program2.opts();
|
|
72910
|
+
const useJson = Boolean(opts.json || globalOpts.json);
|
|
72911
|
+
try {
|
|
72912
|
+
const brief = resolveDelegationBrief({ briefPath: opts.brief, briefText: opts.briefText }, {
|
|
72913
|
+
readFile: (path) => readFileSync21(path, "utf8"),
|
|
72914
|
+
readStdin: () => readFileSync21(0, "utf8")
|
|
72915
|
+
});
|
|
72916
|
+
if (!brief.ok)
|
|
72917
|
+
handleError(new Error(brief.message));
|
|
72918
|
+
const dispatcherIdentity = resolveWritableIdentity(globalOpts.agent);
|
|
72919
|
+
if (!dispatcherIdentity.agent_id) {
|
|
72920
|
+
handleError(new Error("Cannot delegate without a dispatcher identity: this verb records WHO handed the row over, " + "and a handover from nobody is not a handover. " + "Set TODOS_AGENT_ID=<name> for this session, or pass --agent <name>. " + "An identity persisted by `todos init` is deliberately not used \u2014 it is keyed on $HOME and names the station, not this session."));
|
|
72921
|
+
}
|
|
72922
|
+
const dispatcher = dispatcherIdentity.agent_id;
|
|
72923
|
+
const worker = await resolveValidatedAssignee(workerInput, Boolean(opts.assignSeat), (v) => `${taskRef} ${v} --assign-seat`);
|
|
72924
|
+
const embargo = loadDelegationEmbargo();
|
|
72925
|
+
const embargoedForm = [workerInput, worker].find((candidate) => embargo.has(normalizeAgentNameInput(candidate)));
|
|
72926
|
+
if (embargoedForm !== undefined) {
|
|
72927
|
+
handleError(new Error(`'${embargoedForm}' is under a delegation embargo and must not receive dispatched work. ` + "The embargo list is a file, not a constant \u2014 see TODOS_DELEGATION_EMBARGO_PATH."));
|
|
72928
|
+
}
|
|
72929
|
+
try {
|
|
72930
|
+
validateAgentName(worker);
|
|
72931
|
+
} catch (error2) {
|
|
72932
|
+
handleError(new Error(`Cannot delegate to '${worker}': ${error2 instanceof Error ? error2.message : String(error2)} ` + "Nothing was written \u2014 the task is unchanged and still unassigned."));
|
|
72933
|
+
}
|
|
72934
|
+
const reportsTo = (opts.reportsTo ?? dispatcher).trim();
|
|
72935
|
+
const seatSlug = (opts.seat ?? reportsTo).trim();
|
|
72936
|
+
const cloud = getTodosCloudClient();
|
|
72937
|
+
const taskId = await resolveTaskIdForCommand(taskRef, cloud);
|
|
72938
|
+
const db = cloud ? null : getDatabase();
|
|
72939
|
+
const task2 = cloud ? await cloudGetTask(cloud, taskId) : getTask(taskId, db);
|
|
72940
|
+
if (!task2)
|
|
72941
|
+
handleError(new Error(`Task not found: ${taskRef}`));
|
|
72942
|
+
const threshold = resolveDelegationDepthThreshold(opts.depthThreshold);
|
|
72943
|
+
const seatOpenTasks = cloud ? await cloudCountTasks(cloud, { assigned_to: seatSlug, status: "pending" }) : countTasks({ assigned_to: seatSlug, status: "pending" }, db);
|
|
72944
|
+
const override = opts.ownerDirective ? "owner-directive" : opts.despiteDepth ? "despite-depth" : null;
|
|
72945
|
+
const overThreshold = threshold.value !== null && seatOpenTasks > threshold.value;
|
|
72946
|
+
const parked = overThreshold && override === null;
|
|
72947
|
+
if (overThreshold && override === "owner-directive") {
|
|
72948
|
+
console.error(chalk12.yellow(`Warning: seat ${seatSlug} carries ${seatOpenTasks} open tasks (threshold ${threshold.value}); ` + "proceeding because this is an owner-directive dispatch."));
|
|
72949
|
+
}
|
|
72950
|
+
if (parked) {
|
|
72951
|
+
handleError(new Error(`Seat ${seatSlug} carries ${seatOpenTasks} open tasks, above the armed threshold of ${threshold.value} ` + `(from ${threshold.source}). Re-run with --despite-depth to proceed and have the override recorded, ` + "or --owner-directive if this row is an owner directive."));
|
|
72952
|
+
}
|
|
72953
|
+
const currentDepth = typeof task2.delegation_depth === "number" ? task2.delegation_depth : 0;
|
|
72954
|
+
const depth = opts.depth !== undefined ? Number.parseInt(opts.depth, 10) : currentDepth + 1;
|
|
72955
|
+
if (!Number.isSafeInteger(depth) || depth < 0) {
|
|
72956
|
+
handleError(new Error(`--depth must be a non-negative integer; got ${JSON.stringify(opts.depth)}`));
|
|
72957
|
+
}
|
|
72958
|
+
const dispatchedAtDate = new Date;
|
|
72959
|
+
const dispatchedAt = dispatchedAtDate.toISOString();
|
|
72960
|
+
const claimWindowMinutes = opts.claimWindow !== undefined ? Number.parseInt(opts.claimWindow, 10) : DEFAULT_CLAIM_WINDOW_MINUTES;
|
|
72961
|
+
if (!Number.isSafeInteger(claimWindowMinutes) || claimWindowMinutes <= 0) {
|
|
72962
|
+
handleError(new Error(`--claim-window must be a positive integer; got ${JSON.stringify(opts.claimWindow)}`));
|
|
72963
|
+
}
|
|
72964
|
+
const claimDeadline = claimDeadlineFrom(dispatchedAtDate, claimWindowMinutes);
|
|
72965
|
+
const record = {
|
|
72966
|
+
taskId: task2.id,
|
|
72967
|
+
worker,
|
|
72968
|
+
dispatcher,
|
|
72969
|
+
runtime: opts.runtime ?? null,
|
|
72970
|
+
briefSource: brief.source,
|
|
72971
|
+
briefSha256: brief.sha256,
|
|
72972
|
+
briefBytes: brief.bytes,
|
|
72973
|
+
depth,
|
|
72974
|
+
reportsTo,
|
|
72975
|
+
seatSlug,
|
|
72976
|
+
seatOpenTasks,
|
|
72977
|
+
depthThreshold: threshold.value,
|
|
72978
|
+
override,
|
|
72979
|
+
identityOutcome: opts.reuseIdentity ? "skipped" : "created",
|
|
72980
|
+
dispatchedAt,
|
|
72981
|
+
claimDeadline
|
|
72982
|
+
};
|
|
72983
|
+
if (opts.dryRun) {
|
|
72984
|
+
const previewChannel = opts.channel ?? process.env["TODOS_DELEGATE_NOTICE_CHANNEL"] ?? null;
|
|
72985
|
+
const preview = {
|
|
72986
|
+
dry_run: true,
|
|
72987
|
+
task: { id: task2.id, short_id: task2.short_id, title: task2.title },
|
|
72988
|
+
delegation: summarize4(record, {
|
|
72989
|
+
identityOutcome: opts.reuseIdentity ? "skipped" : "created",
|
|
72990
|
+
commentId: null,
|
|
72991
|
+
notice: { posted: false, channel: previewChannel, error: null }
|
|
72992
|
+
}),
|
|
72993
|
+
would: [
|
|
72994
|
+
"1. brief accepted (already validated)",
|
|
72995
|
+
`2. seat ${seatSlug}: ${seatOpenTasks} open, threshold ${threshold.value ?? "unset"}`,
|
|
72996
|
+
opts.reuseIdentity ? `3. registration SKIPPED (--reuse-identity); reusing ${worker}` : `3. register ${worker} with reports_to=${reportsTo}`,
|
|
72997
|
+
`4. assign to ${worker}; assigned_by=${dispatcher}, delegated_from=${dispatcher}, delegation_depth=${depth}`,
|
|
72998
|
+
"5. append the [DISPATCH] comment",
|
|
72999
|
+
opts.post === false ? "6. channel notice SKIPPED (--no-post)" : `6. post one notice to ${previewChannel ?? "(no channel resolved \u2014 set --channel or TODOS_DELEGATE_NOTICE_CHANNEL)"}`,
|
|
73000
|
+
`7. claim deadline ${claimDeadline}`
|
|
73001
|
+
]
|
|
73002
|
+
};
|
|
73003
|
+
if (useJson) {
|
|
73004
|
+
output(preview, true);
|
|
73005
|
+
return;
|
|
73006
|
+
}
|
|
73007
|
+
console.log(chalk12.dim("[dry-run] no writes performed"));
|
|
73008
|
+
for (const line of preview.would)
|
|
73009
|
+
console.log(` ${line}`);
|
|
73010
|
+
return;
|
|
73011
|
+
}
|
|
73012
|
+
let identityOutcome = "skipped";
|
|
73013
|
+
if (!opts.reuseIdentity) {
|
|
73014
|
+
identityOutcome = await registerWorkerIdentity(worker, reportsTo, cloud, db);
|
|
73015
|
+
}
|
|
73016
|
+
record.identityOutcome = identityOutcome;
|
|
73017
|
+
const mergedMetadata = {
|
|
73018
|
+
...task2.metadata && typeof task2.metadata === "object" ? task2.metadata : {},
|
|
73019
|
+
delegation: {
|
|
73020
|
+
worker,
|
|
73021
|
+
dispatcher,
|
|
73022
|
+
runtime: opts.runtime ?? null,
|
|
73023
|
+
brief_source: brief.source,
|
|
73024
|
+
brief_sha256: brief.sha256,
|
|
73025
|
+
dispatched_at: dispatchedAt,
|
|
73026
|
+
claim_deadline: claimDeadline,
|
|
73027
|
+
claim_window_minutes: claimWindowMinutes,
|
|
73028
|
+
depth,
|
|
73029
|
+
override
|
|
73030
|
+
}
|
|
73031
|
+
};
|
|
73032
|
+
const patch = {
|
|
73033
|
+
assigned_to: worker,
|
|
73034
|
+
assigned_by: dispatcher,
|
|
73035
|
+
delegated_from: dispatcher,
|
|
73036
|
+
delegation_depth: depth,
|
|
73037
|
+
metadata: mergedMetadata
|
|
73038
|
+
};
|
|
73039
|
+
const updated = cloud ? await cloudUpdateTask(cloud, task2.id, patch) : updateTask(task2.id, { ...patch, version: task2.version }, db);
|
|
73040
|
+
const missing = missingDelegationLineage(updated, {
|
|
73041
|
+
assignedTo: worker,
|
|
73042
|
+
assignedBy: dispatcher,
|
|
73043
|
+
delegatedFrom: dispatcher,
|
|
73044
|
+
depth
|
|
73045
|
+
});
|
|
73046
|
+
if (missing.length > 0) {
|
|
73047
|
+
handleError(new Error(partialDelegationMessage(missing, task2.id)));
|
|
73048
|
+
}
|
|
73049
|
+
const commentBody = formatDispatchComment(record);
|
|
73050
|
+
const comment = cloud ? await cloudAddComment(cloud, task2.id, { content: commentBody, agent_id: dispatcher }) : addComment({ task_id: task2.id, agent_id: dispatcher, content: commentBody }, db);
|
|
73051
|
+
const notice = opts.post === false ? { posted: false, channel: opts.channel ?? null, error: null } : postNotice(formatDispatchNotice(record), opts.channel ?? null);
|
|
73052
|
+
const payload = {
|
|
73053
|
+
task: updated,
|
|
73054
|
+
delegation: summarize4(record, {
|
|
73055
|
+
identityOutcome,
|
|
73056
|
+
commentId: comment.id,
|
|
73057
|
+
notice
|
|
73058
|
+
})
|
|
73059
|
+
};
|
|
73060
|
+
if (useJson) {
|
|
73061
|
+
output(payload, true);
|
|
73062
|
+
return;
|
|
73063
|
+
}
|
|
73064
|
+
console.log(chalk12.green(`Delegated ${updated.short_id ?? updated.id.slice(0, 8)} to ${worker}`));
|
|
73065
|
+
console.log(chalk12.dim(` by ${dispatcher}, depth ${depth}, seat ${seatSlug} has ${seatOpenTasks} open`));
|
|
73066
|
+
console.log(chalk12.dim(` brief ${brief.source} (sha256 ${brief.sha256.slice(0, 12)}\u2026)`));
|
|
73067
|
+
console.log(chalk12.dim(` claim by ${claimDeadline}; the worker claims with \`todos start\``));
|
|
73068
|
+
if (!notice.posted && opts.post !== false) {
|
|
73069
|
+
console.error(chalk12.yellow(`Warning: the channel notice was not posted: ${notice.error ?? "unknown reason"}`));
|
|
73070
|
+
}
|
|
73071
|
+
} catch (e) {
|
|
73072
|
+
handleError(e);
|
|
73073
|
+
}
|
|
73074
|
+
});
|
|
73075
|
+
}
|
|
73076
|
+
function summarize4(record, extra) {
|
|
73077
|
+
return {
|
|
73078
|
+
worker: record.worker,
|
|
73079
|
+
dispatcher: record.dispatcher,
|
|
73080
|
+
runtime: record.runtime,
|
|
73081
|
+
depth: record.depth,
|
|
73082
|
+
reports_to: record.reportsTo,
|
|
73083
|
+
brief: { source: record.briefSource, sha256: record.briefSha256, bytes: record.briefBytes },
|
|
73084
|
+
seat: {
|
|
73085
|
+
slug: record.seatSlug,
|
|
73086
|
+
open_tasks: record.seatOpenTasks,
|
|
73087
|
+
threshold: record.depthThreshold,
|
|
73088
|
+
parked: false,
|
|
73089
|
+
override: record.override
|
|
73090
|
+
},
|
|
73091
|
+
identity: { name: record.worker, reports_to: record.reportsTo, outcome: extra.identityOutcome },
|
|
73092
|
+
comment_id: extra.commentId,
|
|
73093
|
+
dispatched_at: record.dispatchedAt,
|
|
73094
|
+
claim_deadline: record.claimDeadline,
|
|
73095
|
+
notice: extra.notice,
|
|
73096
|
+
started_at_written: false
|
|
73097
|
+
};
|
|
73098
|
+
}
|
|
73099
|
+
async function registerWorkerIdentity(worker, reportsTo, cloud, db) {
|
|
73100
|
+
if (cloud) {
|
|
73101
|
+
const existing = (await cloudListAgents(cloud)).find((a) => normalizeAgentNameInput(a.name) === normalizeAgentNameInput(worker));
|
|
73102
|
+
if (existing)
|
|
73103
|
+
return "reused";
|
|
73104
|
+
try {
|
|
73105
|
+
await cloudRegisterAgent(cloud, { name: worker, reports_to: reportsTo });
|
|
73106
|
+
return "created";
|
|
73107
|
+
} catch (error2) {
|
|
73108
|
+
const status = error2 && typeof error2 === "object" ? error2.status : undefined;
|
|
73109
|
+
if (status === 409)
|
|
73110
|
+
return "reused";
|
|
73111
|
+
throw error2;
|
|
73112
|
+
}
|
|
73113
|
+
}
|
|
73114
|
+
if (getAgentByName(worker, db))
|
|
73115
|
+
return "reused";
|
|
73116
|
+
const result = registerAgent({ name: worker, reports_to: reportsTo }, db);
|
|
73117
|
+
return isAgentConflict(result) ? "reused" : "created";
|
|
73118
|
+
}
|
|
73119
|
+
function postNotice(line, channel) {
|
|
73120
|
+
const resolved = channel || process.env["TODOS_DELEGATE_NOTICE_CHANNEL"] || null;
|
|
73121
|
+
if (!resolved) {
|
|
73122
|
+
return {
|
|
73123
|
+
posted: false,
|
|
73124
|
+
channel: null,
|
|
73125
|
+
error: "no channel resolved: pass --channel <name>, set TODOS_DELEGATE_NOTICE_CHANNEL, " + "or pass --no-post to skip the notice deliberately"
|
|
73126
|
+
};
|
|
73127
|
+
}
|
|
73128
|
+
channel = resolved;
|
|
73129
|
+
const bin = process.env["TODOS_DELEGATE_NOTIFY_BIN"] || "conversations";
|
|
73130
|
+
try {
|
|
73131
|
+
const proc = Bun.spawnSync([bin, "send", "--channel", channel, line], { stdout: "pipe", stderr: "pipe" });
|
|
73132
|
+
if (proc.exitCode !== 0) {
|
|
73133
|
+
const stderr = new TextDecoder().decode(proc.stderr).trim();
|
|
73134
|
+
return { posted: false, channel, error: stderr || `${bin} exited ${proc.exitCode}` };
|
|
73135
|
+
}
|
|
73136
|
+
return { posted: true, channel, error: null };
|
|
73137
|
+
} catch (error2) {
|
|
73138
|
+
return { posted: false, channel, error: error2 instanceof Error ? error2.message : String(error2) };
|
|
73139
|
+
}
|
|
73140
|
+
}
|
|
73141
|
+
var init_delegate = __esm(() => {
|
|
73142
|
+
init_cloud_router();
|
|
73143
|
+
init_database();
|
|
73144
|
+
init_tasks();
|
|
73145
|
+
init_comments();
|
|
73146
|
+
init_agents();
|
|
73147
|
+
init_agent_names();
|
|
73148
|
+
init_creator_identity();
|
|
73149
|
+
init_delegation_brief();
|
|
73150
|
+
init_delegation_policy();
|
|
73151
|
+
init_assignee_guard();
|
|
73152
|
+
init_helpers();
|
|
73153
|
+
});
|
|
73154
|
+
|
|
72732
73155
|
// src/cli/commands/machines.tsx
|
|
72733
73156
|
var exports_machines = {};
|
|
72734
73157
|
__export(exports_machines, {
|
|
72735
73158
|
registerMachineCommands: () => registerMachineCommands
|
|
72736
73159
|
});
|
|
72737
|
-
import
|
|
73160
|
+
import chalk13 from "chalk";
|
|
72738
73161
|
import { execSync as execSync4 } from "child_process";
|
|
72739
|
-
import { readFileSync as
|
|
73162
|
+
import { readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync14 } from "fs";
|
|
72740
73163
|
import { tmpdir as tmpdir5 } from "os";
|
|
72741
|
-
import { join as
|
|
73164
|
+
import { join as join29 } from "path";
|
|
72742
73165
|
function getOrCreateLocalMachineName() {
|
|
72743
73166
|
return process.env["TODOS_MACHINE_NAME"] || __require("os").hostname() || "unknown";
|
|
72744
73167
|
}
|
|
@@ -72776,11 +73199,11 @@ function remoteTempPath(sshAddress) {
|
|
|
72776
73199
|
}
|
|
72777
73200
|
function readRemoteBridgeBundle(sshAddress) {
|
|
72778
73201
|
const remotePath = remoteTempPath(sshAddress);
|
|
72779
|
-
const localPath =
|
|
73202
|
+
const localPath = join29(tmpdir5(), `todos-bridge-pull-${uuid()}.json`);
|
|
72780
73203
|
try {
|
|
72781
73204
|
runSsh(sshAddress, `todos export --format bridge --allow-plaintext-sensitive --output ${shellQuote(remotePath)}`, 120000);
|
|
72782
73205
|
scpFromRemote(sshAddress, remotePath, localPath);
|
|
72783
|
-
return JSON.parse(
|
|
73206
|
+
return JSON.parse(readFileSync22(localPath, "utf-8"));
|
|
72784
73207
|
} finally {
|
|
72785
73208
|
try {
|
|
72786
73209
|
runSsh(sshAddress, `rm -f ${shellQuote(remotePath)}`, 1e4);
|
|
@@ -72791,7 +73214,7 @@ function readRemoteBridgeBundle(sshAddress) {
|
|
|
72791
73214
|
}
|
|
72792
73215
|
}
|
|
72793
73216
|
function writeLocalBridgeBundle() {
|
|
72794
|
-
const localPath =
|
|
73217
|
+
const localPath = join29(tmpdir5(), `todos-bridge-push-${uuid()}.json`);
|
|
72795
73218
|
writeFileSync14(localPath, JSON.stringify(createLocalBridgeBundle(), null, 2));
|
|
72796
73219
|
return localPath;
|
|
72797
73220
|
}
|
|
@@ -72828,17 +73251,17 @@ function registerMachineCommands(program2) {
|
|
|
72828
73251
|
const db = getDatabase();
|
|
72829
73252
|
const machines = listMachines(db, opts.all);
|
|
72830
73253
|
if (machines.length === 0) {
|
|
72831
|
-
console.log(
|
|
72832
|
-
console.log(
|
|
73254
|
+
console.log(chalk13.yellow("No machines registered."));
|
|
73255
|
+
console.log(chalk13.dim("Use `todos machines register` to add one."));
|
|
72833
73256
|
return;
|
|
72834
73257
|
}
|
|
72835
73258
|
for (const m of machines) {
|
|
72836
|
-
const primaryTag = m.is_primary ?
|
|
72837
|
-
const archivedTag = m.archived_at ?
|
|
72838
|
-
console.log(`${
|
|
72839
|
-
console.log(
|
|
72840
|
-
console.log(
|
|
72841
|
-
console.log(
|
|
73259
|
+
const primaryTag = m.is_primary ? chalk13.bold(" [PRIMARY]") : "";
|
|
73260
|
+
const archivedTag = m.archived_at ? chalk13.dim(" [ARCHIVED]") : "";
|
|
73261
|
+
console.log(`${chalk13.cyan(m.name)} (${m.id.slice(0, 8)})${primaryTag}${archivedTag}`);
|
|
73262
|
+
console.log(chalk13.dim(` Host: ${m.hostname ?? "unknown"} | Platform: ${m.platform ?? "unknown"}`));
|
|
73263
|
+
console.log(chalk13.dim(` SSH: ${m.ssh_address ?? "(not set)"}`));
|
|
73264
|
+
console.log(chalk13.dim(` Last seen: ${m.last_seen_at}`));
|
|
72842
73265
|
}
|
|
72843
73266
|
});
|
|
72844
73267
|
machinesCmd.command("register").description("Register a machine").argument("<name>", "Machine name").option("--hostname <host>", "OS hostname").option("--platform <platform>", "OS platform").option("--ssh <address>", "SSH address (e.g. user@host)").option("--arch <arch>", "Architecture (e.g. linux-arm64)").option("--tailscale-name <name>", "User-provided Tailscale/MagicDNS name").option("--tailscale-ip <ip>", "User-provided Tailscale IP").option("--lan-address <address>", "User-provided LAN address").option("--workspace <path>", "Local workspace path for this machine").option("--git-root <path>", "Local git root for this machine").option("--primary", "Set as primary machine").option("-j, --json", "Output as JSON").action((name, opts) => {
|
|
@@ -72860,17 +73283,17 @@ function registerMachineCommands(program2) {
|
|
|
72860
73283
|
console.log(JSON.stringify(machine));
|
|
72861
73284
|
return;
|
|
72862
73285
|
}
|
|
72863
|
-
console.log(
|
|
72864
|
-
console.log(
|
|
72865
|
-
console.log(
|
|
73286
|
+
console.log(chalk13.green(`Machine registered: ${machine.name} (${machine.id.slice(0, 8)})`));
|
|
73287
|
+
console.log(chalk13.dim(` Host: ${machine.hostname} | Platform: ${machine.platform}`));
|
|
73288
|
+
console.log(chalk13.dim(` Primary: ${machine.is_primary}`));
|
|
72866
73289
|
if (machine.ssh_address)
|
|
72867
|
-
console.log(
|
|
73290
|
+
console.log(chalk13.dim(` SSH: ${machine.ssh_address}`));
|
|
72868
73291
|
if (machine.metadata["tailscale_name"])
|
|
72869
|
-
console.log(
|
|
73292
|
+
console.log(chalk13.dim(` Tailscale: ${machine.metadata["tailscale_name"]}`));
|
|
72870
73293
|
if (machine.metadata["lan_address"])
|
|
72871
|
-
console.log(
|
|
73294
|
+
console.log(chalk13.dim(` LAN: ${machine.metadata["lan_address"]}`));
|
|
72872
73295
|
} catch (err) {
|
|
72873
|
-
console.error(
|
|
73296
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72874
73297
|
process.exit(1);
|
|
72875
73298
|
}
|
|
72876
73299
|
});
|
|
@@ -72892,10 +73315,10 @@ function registerMachineCommands(program2) {
|
|
|
72892
73315
|
console.log(JSON.stringify(machine));
|
|
72893
73316
|
return;
|
|
72894
73317
|
}
|
|
72895
|
-
console.log(
|
|
72896
|
-
console.log(
|
|
73318
|
+
console.log(chalk13.green(`Heartbeat recorded: ${machine.name} (${machine.id.slice(0, 8)})`));
|
|
73319
|
+
console.log(chalk13.dim(` Last seen: ${machine.last_seen_at}`));
|
|
72897
73320
|
} catch (err) {
|
|
72898
|
-
console.error(
|
|
73321
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72899
73322
|
process.exit(1);
|
|
72900
73323
|
}
|
|
72901
73324
|
});
|
|
@@ -72903,9 +73326,9 @@ function registerMachineCommands(program2) {
|
|
|
72903
73326
|
try {
|
|
72904
73327
|
const db = getDatabase();
|
|
72905
73328
|
const machine = setPrimaryMachine(name, db);
|
|
72906
|
-
console.log(
|
|
73329
|
+
console.log(chalk13.green(`Primary machine set to: ${machine.name} (${machine.id.slice(0, 8)})`));
|
|
72907
73330
|
} catch (err) {
|
|
72908
|
-
console.error(
|
|
73331
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72909
73332
|
process.exit(1);
|
|
72910
73333
|
}
|
|
72911
73334
|
});
|
|
@@ -72914,13 +73337,13 @@ function registerMachineCommands(program2) {
|
|
|
72914
73337
|
const db = getDatabase();
|
|
72915
73338
|
const machine = getMachineByName(name, db);
|
|
72916
73339
|
if (!machine) {
|
|
72917
|
-
console.error(
|
|
73340
|
+
console.error(chalk13.red(`Machine '${name}' not found`));
|
|
72918
73341
|
process.exit(1);
|
|
72919
73342
|
}
|
|
72920
73343
|
archiveMachine(machine.id, db);
|
|
72921
|
-
console.log(
|
|
73344
|
+
console.log(chalk13.green(`Machine '${name}' archived`));
|
|
72922
73345
|
} catch (err) {
|
|
72923
|
-
console.error(
|
|
73346
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72924
73347
|
process.exit(1);
|
|
72925
73348
|
}
|
|
72926
73349
|
});
|
|
@@ -72929,13 +73352,13 @@ function registerMachineCommands(program2) {
|
|
|
72929
73352
|
const db = getDatabase();
|
|
72930
73353
|
const machine = getMachineByName(name, db);
|
|
72931
73354
|
if (!machine) {
|
|
72932
|
-
console.error(
|
|
73355
|
+
console.error(chalk13.red(`Machine '${name}' not found`));
|
|
72933
73356
|
process.exit(1);
|
|
72934
73357
|
}
|
|
72935
73358
|
unarchiveMachine(machine.id, db);
|
|
72936
|
-
console.log(
|
|
73359
|
+
console.log(chalk13.green(`Machine '${name}' unarchived`));
|
|
72937
73360
|
} catch (err) {
|
|
72938
|
-
console.error(
|
|
73361
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72939
73362
|
process.exit(1);
|
|
72940
73363
|
}
|
|
72941
73364
|
});
|
|
@@ -72944,13 +73367,13 @@ function registerMachineCommands(program2) {
|
|
|
72944
73367
|
const db = getDatabase();
|
|
72945
73368
|
const machine = getMachineByName(name, db);
|
|
72946
73369
|
if (!machine) {
|
|
72947
|
-
console.error(
|
|
73370
|
+
console.error(chalk13.red(`Machine '${name}' not found`));
|
|
72948
73371
|
process.exit(1);
|
|
72949
73372
|
}
|
|
72950
73373
|
deleteMachine(machine.id, db);
|
|
72951
|
-
console.log(
|
|
73374
|
+
console.log(chalk13.green(`Machine '${name}' deleted`));
|
|
72952
73375
|
} catch (err) {
|
|
72953
|
-
console.error(
|
|
73376
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
72954
73377
|
process.exit(1);
|
|
72955
73378
|
}
|
|
72956
73379
|
});
|
|
@@ -72959,39 +73382,39 @@ function registerMachineCommands(program2) {
|
|
|
72959
73382
|
const machines = listMachines(db);
|
|
72960
73383
|
const primary = getPrimaryMachine(db);
|
|
72961
73384
|
if (machines.length === 0) {
|
|
72962
|
-
console.log(
|
|
73385
|
+
console.log(chalk13.yellow("No machines registered."));
|
|
72963
73386
|
return;
|
|
72964
73387
|
}
|
|
72965
|
-
console.log(
|
|
73388
|
+
console.log(chalk13.bold(`
|
|
72966
73389
|
Machine Health`));
|
|
72967
|
-
console.log(
|
|
73390
|
+
console.log(chalk13.dim("\u2500".repeat(60)));
|
|
72968
73391
|
for (const m of machines) {
|
|
72969
|
-
const primaryTag = m.is_primary ?
|
|
73392
|
+
const primaryTag = m.is_primary ? chalk13.bold(" [PRIMARY]") : "";
|
|
72970
73393
|
const lastSeen = new Date(m.last_seen_at);
|
|
72971
73394
|
const nowDate = new Date;
|
|
72972
73395
|
const diffMs = nowDate.getTime() - lastSeen.getTime();
|
|
72973
73396
|
const diffMin = Math.round(diffMs / 60000);
|
|
72974
73397
|
let status;
|
|
72975
73398
|
if (diffMin < 5) {
|
|
72976
|
-
status =
|
|
73399
|
+
status = chalk13.green("online");
|
|
72977
73400
|
} else if (diffMin < 60) {
|
|
72978
|
-
status =
|
|
73401
|
+
status = chalk13.yellow("stale");
|
|
72979
73402
|
} else {
|
|
72980
|
-
status =
|
|
73403
|
+
status = chalk13.red("offline");
|
|
72981
73404
|
}
|
|
72982
|
-
console.log(`${
|
|
73405
|
+
console.log(`${chalk13.cyan(m.name)}${primaryTag} ${status} last: ${diffMin}m ago`);
|
|
72983
73406
|
}
|
|
72984
73407
|
if (!primary) {
|
|
72985
|
-
console.log(
|
|
73408
|
+
console.log(chalk13.yellow(`
|
|
72986
73409
|
Warning: No primary machine set.`));
|
|
72987
|
-
console.log(
|
|
73410
|
+
console.log(chalk13.dim("Use `todos machines set-primary <name>` to set one."));
|
|
72988
73411
|
}
|
|
72989
73412
|
});
|
|
72990
73413
|
machinesCmd.command("topology").description("Show local machine topology diagnostics").option("--stale-minutes <n>", "Minutes before a machine is considered stale", "30").option("--include-archived", "Include archived machines").option("-j, --json", "Output as JSON").action((opts) => {
|
|
72991
73414
|
try {
|
|
72992
73415
|
const staleMinutes = Number.parseInt(opts.staleMinutes, 10);
|
|
72993
73416
|
if (!Number.isFinite(staleMinutes) || staleMinutes < 1) {
|
|
72994
|
-
console.error(
|
|
73417
|
+
console.error(chalk13.red("Invalid --stale-minutes value. Must be a positive integer."));
|
|
72995
73418
|
process.exit(1);
|
|
72996
73419
|
}
|
|
72997
73420
|
const diagnostics = getMachineTopologyDiagnostics({
|
|
@@ -73002,26 +73425,26 @@ Warning: No primary machine set.`));
|
|
|
73002
73425
|
console.log(JSON.stringify(diagnostics));
|
|
73003
73426
|
return;
|
|
73004
73427
|
}
|
|
73005
|
-
console.log(
|
|
73428
|
+
console.log(chalk13.bold(`
|
|
73006
73429
|
Machine Topology`));
|
|
73007
|
-
console.log(
|
|
73430
|
+
console.log(chalk13.dim("\u2500".repeat(60)));
|
|
73008
73431
|
for (const machine of diagnostics.machines) {
|
|
73009
|
-
const stale = machine.stale ?
|
|
73432
|
+
const stale = machine.stale ? chalk13.red(` stale ${machine.stale_minutes}m`) : chalk13.green(" fresh");
|
|
73010
73433
|
const ts = machine.topology.tailscale_ip ? ` ts:${machine.topology.tailscale_ip}` : "";
|
|
73011
73434
|
const lan = machine.topology.lan_address ? ` lan:${machine.topology.lan_address}` : "";
|
|
73012
73435
|
const workspace = machine.topology.workspace_path ? `
|
|
73013
73436
|
workspace: ${machine.topology.workspace_path}` : "";
|
|
73014
|
-
console.log(`${
|
|
73437
|
+
console.log(`${chalk13.cyan(machine.name)}${stale}${chalk13.dim(ts + lan)}${chalk13.dim(workspace)}`);
|
|
73015
73438
|
}
|
|
73016
73439
|
if (diagnostics.path_issues.length > 0) {
|
|
73017
|
-
console.log(
|
|
73440
|
+
console.log(chalk13.yellow(`
|
|
73018
73441
|
Path diagnostics (${diagnostics.path_issues.length})`));
|
|
73019
73442
|
for (const issue of diagnostics.path_issues) {
|
|
73020
|
-
console.log(
|
|
73443
|
+
console.log(chalk13.yellow(` ${issue.type}: ${issue.message}`));
|
|
73021
73444
|
}
|
|
73022
73445
|
}
|
|
73023
73446
|
} catch (err) {
|
|
73024
|
-
console.error(
|
|
73447
|
+
console.error(chalk13.red(err instanceof Error ? err.message : String(err)));
|
|
73025
73448
|
process.exit(1);
|
|
73026
73449
|
}
|
|
73027
73450
|
});
|
|
@@ -73049,7 +73472,7 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
73049
73472
|
}, null, 2));
|
|
73050
73473
|
return;
|
|
73051
73474
|
}
|
|
73052
|
-
console.log(
|
|
73475
|
+
console.log(chalk13.dim(opts.machine ? `No remote SSH target found for machine '${opts.machine}'.` : "No remote machines with SSH addresses to sync."));
|
|
73053
73476
|
return;
|
|
73054
73477
|
}
|
|
73055
73478
|
const results = [];
|
|
@@ -73064,14 +73487,14 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
73064
73487
|
const record = { machine: target.name, pull };
|
|
73065
73488
|
if (!wantsJson(program2, opts)) {
|
|
73066
73489
|
const mode = opts.dryRun ? "would pull" : "pulled";
|
|
73067
|
-
console.log(
|
|
73490
|
+
console.log(chalk13.green(` ${target.name}: ${mode} ${formatBridgeImportSummary(pull)}`));
|
|
73068
73491
|
}
|
|
73069
73492
|
if (opts.push) {
|
|
73070
73493
|
const push = pushLocalBridgeBundle(ssh, Boolean(opts.dryRun));
|
|
73071
73494
|
record.push = push;
|
|
73072
73495
|
if (!wantsJson(program2, opts)) {
|
|
73073
73496
|
const mode = opts.dryRun ? "would push" : "pushed";
|
|
73074
|
-
console.log(
|
|
73497
|
+
console.log(chalk13.green(` ${target.name}: ${mode} ${formatBridgeImportSummary(push)}`));
|
|
73075
73498
|
}
|
|
73076
73499
|
}
|
|
73077
73500
|
results.push(record);
|
|
@@ -73079,7 +73502,7 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
73079
73502
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
73080
73503
|
results.push({ machine: target.name, error: message });
|
|
73081
73504
|
if (!wantsJson(program2, opts))
|
|
73082
|
-
console.log(
|
|
73505
|
+
console.log(chalk13.yellow(` ${target.name}: sync failed: ${message}`));
|
|
73083
73506
|
}
|
|
73084
73507
|
}
|
|
73085
73508
|
if (wantsJson(program2, opts)) {
|
|
@@ -73090,19 +73513,19 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
73090
73513
|
}, null, 2));
|
|
73091
73514
|
return;
|
|
73092
73515
|
}
|
|
73093
|
-
console.log(
|
|
73516
|
+
console.log(chalk13.bold(`
|
|
73094
73517
|
Sync ${opts.dryRun ? "dry-run" : "complete"}: ${results.length} machine(s) checked.`));
|
|
73095
73518
|
});
|
|
73096
73519
|
machinesCmd.command("tasks").description("List tasks from a remote machine via SSH").argument("<machine-name>", "Machine name (must have SSH address)").option("--status <status>", "Filter by status").action((machineName, opts) => {
|
|
73097
73520
|
const db = getDatabase();
|
|
73098
73521
|
const machine = getMachineByName(machineName, db);
|
|
73099
73522
|
if (!machine) {
|
|
73100
|
-
console.error(
|
|
73523
|
+
console.error(chalk13.red(`Machine '${machineName}' not found`));
|
|
73101
73524
|
process.exit(1);
|
|
73102
73525
|
}
|
|
73103
73526
|
const sshAddress = resolveMachineSshAddress(machine, getOrCreateLocalMachineName());
|
|
73104
73527
|
if (!sshAddress) {
|
|
73105
|
-
console.error(
|
|
73528
|
+
console.error(chalk13.red(`Machine '${machineName}' has no SSH address`));
|
|
73106
73529
|
process.exit(1);
|
|
73107
73530
|
}
|
|
73108
73531
|
try {
|
|
@@ -73110,19 +73533,19 @@ Sync ${opts.dryRun ? "dry-run" : "complete"}: ${results.length} machine(s) check
|
|
|
73110
73533
|
const tasks = bundle.data.tasks;
|
|
73111
73534
|
const filtered = opts.status ? tasks.filter((t) => t.status === opts.status) : tasks;
|
|
73112
73535
|
if (filtered.length === 0) {
|
|
73113
|
-
console.log(
|
|
73536
|
+
console.log(chalk13.dim(`No tasks on ${machineName}`));
|
|
73114
73537
|
return;
|
|
73115
73538
|
}
|
|
73116
|
-
console.log(
|
|
73539
|
+
console.log(chalk13.bold(`${filtered.length} task(s) on ${machineName}:
|
|
73117
73540
|
`));
|
|
73118
73541
|
for (const t of filtered) {
|
|
73119
73542
|
const check = t.status === "completed" ? "x" : " ";
|
|
73120
|
-
const prio = t.priority ?
|
|
73543
|
+
const prio = t.priority ? chalk13.yellow(`[${t.priority}]`) : "";
|
|
73121
73544
|
console.log(` [${check}] ${t.short_id || t.id.slice(0, 8)} ${prio} ${t.title}`);
|
|
73122
73545
|
}
|
|
73123
73546
|
} catch (error2) {
|
|
73124
73547
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
73125
|
-
console.error(
|
|
73548
|
+
console.error(chalk13.red(`Could not read tasks from ${sshAddress}: ${message}`));
|
|
73126
73549
|
process.exit(1);
|
|
73127
73550
|
}
|
|
73128
73551
|
});
|
|
@@ -73138,7 +73561,7 @@ var exports_api_key_commands = {};
|
|
|
73138
73561
|
__export(exports_api_key_commands, {
|
|
73139
73562
|
registerApiKeyCommands: () => registerApiKeyCommands
|
|
73140
73563
|
});
|
|
73141
|
-
import
|
|
73564
|
+
import chalk14 from "chalk";
|
|
73142
73565
|
function registerApiKeyCommands(program2) {
|
|
73143
73566
|
const apiKeys = program2.command("api-keys").alias("api-key").description("Generate, list, and revoke API keys for secured app/API access");
|
|
73144
73567
|
apiKeys.command("create <name>").alias("generate").description("Generate a new API key. The plaintext key is shown once.").option("--expires-at <iso>", "Optional ISO timestamp when this key expires").option("--permissions <list>", "Comma-separated permissions (default: *)").action((name, opts) => {
|
|
@@ -73150,12 +73573,12 @@ function registerApiKeyCommands(program2) {
|
|
|
73150
73573
|
output(created, true);
|
|
73151
73574
|
return;
|
|
73152
73575
|
}
|
|
73153
|
-
console.log(
|
|
73154
|
-
console.log(` ${
|
|
73155
|
-
console.log(` ${
|
|
73156
|
-
console.log(` ${
|
|
73576
|
+
console.log(chalk14.green("API key generated:"));
|
|
73577
|
+
console.log(` ${chalk14.dim("ID:")} ${created.record.id}`);
|
|
73578
|
+
console.log(` ${chalk14.dim("Name:")} ${created.record.name}`);
|
|
73579
|
+
console.log(` ${chalk14.dim("Prefix:")} ${created.record.prefix}`);
|
|
73157
73580
|
console.log();
|
|
73158
|
-
console.log(
|
|
73581
|
+
console.log(chalk14.yellow("Copy this key now. It will not be shown again:"));
|
|
73159
73582
|
console.log(created.key);
|
|
73160
73583
|
} catch (e) {
|
|
73161
73584
|
handleError(e);
|
|
@@ -73170,16 +73593,16 @@ function registerApiKeyCommands(program2) {
|
|
|
73170
73593
|
return;
|
|
73171
73594
|
}
|
|
73172
73595
|
if (keys.length === 0) {
|
|
73173
|
-
console.log(
|
|
73596
|
+
console.log(chalk14.dim("No API keys found."));
|
|
73174
73597
|
return;
|
|
73175
73598
|
}
|
|
73176
73599
|
for (const key of keys) {
|
|
73177
|
-
const state = key.revoked_at ?
|
|
73178
|
-
console.log(`${
|
|
73600
|
+
const state = key.revoked_at ? chalk14.red("revoked") : key.expires_at && key.expires_at < new Date().toISOString() ? chalk14.yellow("expired") : chalk14.green("active");
|
|
73601
|
+
console.log(`${chalk14.cyan(key.id)} ${chalk14.bold(key.name)} ${chalk14.dim(key.prefix)} ${state}`);
|
|
73179
73602
|
if (key.last_used_at)
|
|
73180
|
-
console.log(
|
|
73603
|
+
console.log(chalk14.dim(` last used: ${key.last_used_at}`));
|
|
73181
73604
|
if (key.expires_at)
|
|
73182
|
-
console.log(
|
|
73605
|
+
console.log(chalk14.dim(` expires: ${key.expires_at}`));
|
|
73183
73606
|
}
|
|
73184
73607
|
} catch (e) {
|
|
73185
73608
|
handleError(e);
|
|
@@ -73196,7 +73619,7 @@ function registerApiKeyCommands(program2) {
|
|
|
73196
73619
|
output(revoked, true);
|
|
73197
73620
|
return;
|
|
73198
73621
|
}
|
|
73199
|
-
console.log(
|
|
73622
|
+
console.log(chalk14.green(`Revoked API key: ${revoked.name} (${revoked.prefix})`));
|
|
73200
73623
|
} catch (e) {
|
|
73201
73624
|
handleError(e);
|
|
73202
73625
|
}
|
|
@@ -73212,7 +73635,7 @@ function registerApiKeyCommands(program2) {
|
|
|
73212
73635
|
if (!record) {
|
|
73213
73636
|
handleError(new Error("API key is invalid, revoked, or expired."));
|
|
73214
73637
|
}
|
|
73215
|
-
console.log(
|
|
73638
|
+
console.log(chalk14.green(`API key valid: ${record.name} (${record.prefix})`));
|
|
73216
73639
|
} catch (e) {
|
|
73217
73640
|
handleError(e);
|
|
73218
73641
|
}
|
|
@@ -73228,7 +73651,7 @@ var exports_environment_snapshots2 = {};
|
|
|
73228
73651
|
__export(exports_environment_snapshots2, {
|
|
73229
73652
|
registerEnvironmentSnapshotCommands: () => registerEnvironmentSnapshotCommands
|
|
73230
73653
|
});
|
|
73231
|
-
import
|
|
73654
|
+
import chalk15 from "chalk";
|
|
73232
73655
|
function printJson2(value) {
|
|
73233
73656
|
console.log(JSON.stringify(value, null, 2));
|
|
73234
73657
|
}
|
|
@@ -73250,7 +73673,7 @@ function registerEnvironmentSnapshotCommands(program2) {
|
|
|
73250
73673
|
printJson2(result);
|
|
73251
73674
|
return;
|
|
73252
73675
|
}
|
|
73253
|
-
console.log(
|
|
73676
|
+
console.log(chalk15.green("Captured") + ` ${result.snapshot.id}`);
|
|
73254
73677
|
console.log(`path: ${result.output_path}`);
|
|
73255
73678
|
console.log(`root: ${result.snapshot.root}`);
|
|
73256
73679
|
console.log(`git: ${result.snapshot.git.commit || "none"}${result.snapshot.git.is_dirty ? " dirty" : ""}`);
|
|
@@ -73260,13 +73683,13 @@ function registerEnvironmentSnapshotCommands(program2) {
|
|
|
73260
73683
|
if (result.task_verification_id)
|
|
73261
73684
|
console.log(`task verification: ${result.task_verification_id}`);
|
|
73262
73685
|
for (const warning of result.snapshot.warnings)
|
|
73263
|
-
console.log(
|
|
73686
|
+
console.log(chalk15.yellow(`warning: ${warning}`));
|
|
73264
73687
|
} catch (error2) {
|
|
73265
73688
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
73266
73689
|
if (globalOpts.json)
|
|
73267
73690
|
printJson2({ error: message });
|
|
73268
73691
|
else
|
|
73269
|
-
console.error(
|
|
73692
|
+
console.error(chalk15.red(`Error: ${message}`));
|
|
73270
73693
|
process.exit(1);
|
|
73271
73694
|
}
|
|
73272
73695
|
});
|
|
@@ -73292,7 +73715,7 @@ function registerEnvironmentSnapshotCommands(program2) {
|
|
|
73292
73715
|
if (globalOpts.json)
|
|
73293
73716
|
printJson2({ error: message });
|
|
73294
73717
|
else
|
|
73295
|
-
console.error(
|
|
73718
|
+
console.error(chalk15.red(`Error: ${message}`));
|
|
73296
73719
|
process.exit(1);
|
|
73297
73720
|
}
|
|
73298
73721
|
});
|
|
@@ -73306,7 +73729,7 @@ var exports_knowledge_commands = {};
|
|
|
73306
73729
|
__export(exports_knowledge_commands, {
|
|
73307
73730
|
registerKnowledgeCommands: () => registerKnowledgeCommands
|
|
73308
73731
|
});
|
|
73309
|
-
import
|
|
73732
|
+
import chalk16 from "chalk";
|
|
73310
73733
|
function parseRecordType(value) {
|
|
73311
73734
|
if (RECORD_TYPES.includes(value))
|
|
73312
73735
|
return value;
|
|
@@ -73342,13 +73765,13 @@ function commonFilters(opts) {
|
|
|
73342
73765
|
};
|
|
73343
73766
|
}
|
|
73344
73767
|
function printRecord(record) {
|
|
73345
|
-
console.log(`${
|
|
73768
|
+
console.log(`${chalk16.cyan(record.id.slice(0, 8))} ${chalk16.yellow(record.record_type)} ${record.title}`);
|
|
73346
73769
|
if (record.task_id)
|
|
73347
|
-
console.log(
|
|
73770
|
+
console.log(chalk16.dim(` task: ${record.task_id}`));
|
|
73348
73771
|
if (record.project_id)
|
|
73349
|
-
console.log(
|
|
73772
|
+
console.log(chalk16.dim(` project: ${record.project_id}`));
|
|
73350
73773
|
if (record.tags.length > 0)
|
|
73351
|
-
console.log(
|
|
73774
|
+
console.log(chalk16.dim(` tags: ${record.tags.join(", ")}`));
|
|
73352
73775
|
if (record.decision)
|
|
73353
73776
|
console.log(` decision: ${record.decision}`);
|
|
73354
73777
|
else if (record.content)
|
|
@@ -73401,7 +73824,7 @@ function registerKnowledgeCommands(program2) {
|
|
|
73401
73824
|
if (opts.json || globalOpts.json)
|
|
73402
73825
|
output(result, true);
|
|
73403
73826
|
else {
|
|
73404
|
-
console.log(
|
|
73827
|
+
console.log(chalk16.green(`Snapshot ${result.snapshot_id.slice(0, 8)} saved.`));
|
|
73405
73828
|
printRecord(result.record);
|
|
73406
73829
|
}
|
|
73407
73830
|
} catch (error2) {
|
|
@@ -73475,7 +73898,7 @@ var exports_risk_commands = {};
|
|
|
73475
73898
|
__export(exports_risk_commands, {
|
|
73476
73899
|
registerRiskCommands: () => registerRiskCommands
|
|
73477
73900
|
});
|
|
73478
|
-
import
|
|
73901
|
+
import chalk17 from "chalk";
|
|
73479
73902
|
function parseChoice(value, choices, label) {
|
|
73480
73903
|
if (choices.includes(value))
|
|
73481
73904
|
return value;
|
|
@@ -73514,16 +73937,16 @@ function commonFilters2(opts) {
|
|
|
73514
73937
|
};
|
|
73515
73938
|
}
|
|
73516
73939
|
function printRisk(risk) {
|
|
73517
|
-
const color = risk.severity === "critical" ?
|
|
73518
|
-
console.log(`${
|
|
73940
|
+
const color = risk.severity === "critical" ? chalk17.red : risk.severity === "high" ? chalk17.yellow : chalk17.white;
|
|
73941
|
+
console.log(`${chalk17.cyan(risk.id.slice(0, 8))} ${color(risk.severity)} ${chalk17.bold(risk.status)} ${risk.title}`);
|
|
73519
73942
|
if (risk.owner)
|
|
73520
|
-
console.log(
|
|
73943
|
+
console.log(chalk17.dim(` owner: ${risk.owner}`));
|
|
73521
73944
|
if (risk.due_at)
|
|
73522
|
-
console.log(
|
|
73945
|
+
console.log(chalk17.dim(` due: ${risk.due_at}`));
|
|
73523
73946
|
if (risk.plan_id)
|
|
73524
|
-
console.log(
|
|
73947
|
+
console.log(chalk17.dim(` plan: ${risk.plan_id}`));
|
|
73525
73948
|
if (risk.project_id)
|
|
73526
|
-
console.log(
|
|
73949
|
+
console.log(chalk17.dim(` project: ${risk.project_id}`));
|
|
73527
73950
|
if (risk.mitigation)
|
|
73528
73951
|
console.log(` mitigation: ${risk.mitigation}`);
|
|
73529
73952
|
}
|
|
@@ -73631,8 +74054,8 @@ function registerRiskCommands(program2) {
|
|
|
73631
74054
|
if (opts.json || globalOpts.json)
|
|
73632
74055
|
output(report, true);
|
|
73633
74056
|
else {
|
|
73634
|
-
console.log(`${
|
|
73635
|
-
console.log(
|
|
74057
|
+
console.log(`${chalk17.bold("Health")} ${report.status} (${report.score}/100)`);
|
|
74058
|
+
console.log(chalk17.dim(`${report.components.total_tasks} tasks \xB7 ${report.components.blocked_tasks} blocked \xB7 ${report.components.overdue_tasks} overdue \xB7 ${report.components.open_risks} open risks`));
|
|
73636
74059
|
for (const recommendation of report.recommendations)
|
|
73637
74060
|
console.log(`- ${recommendation}`);
|
|
73638
74061
|
}
|
|
@@ -73670,7 +74093,7 @@ var exports_retrospective_commands = {};
|
|
|
73670
74093
|
__export(exports_retrospective_commands, {
|
|
73671
74094
|
registerRetrospectiveCommands: () => registerRetrospectiveCommands
|
|
73672
74095
|
});
|
|
73673
|
-
import
|
|
74096
|
+
import chalk18 from "chalk";
|
|
73674
74097
|
function commonFilters3(opts) {
|
|
73675
74098
|
return {
|
|
73676
74099
|
project_id: opts.project,
|
|
@@ -73681,8 +74104,8 @@ function commonFilters3(opts) {
|
|
|
73681
74104
|
}
|
|
73682
74105
|
function printRetrospective(record) {
|
|
73683
74106
|
const report = record.report;
|
|
73684
|
-
console.log(`${
|
|
73685
|
-
console.log(
|
|
74107
|
+
console.log(`${chalk18.cyan(record.id.slice(0, 8))} ${chalk18.bold(record.title)} ${chalk18.dim(`${record.scope}:${report.scope_id.slice(0, 8)}`)}`);
|
|
74108
|
+
console.log(chalk18.dim(` tasks: ${report.summary.completed_tasks}/${report.summary.total_tasks} completed \xB7 missed: ${report.summary.missed_estimates} \xB7 blockers: ${report.summary.recurring_blockers} \xB7 failed checks: ${report.summary.failed_verifications}`));
|
|
73686
74109
|
for (const lesson of report.lessons.slice(0, 3))
|
|
73687
74110
|
console.log(` - ${lesson}`);
|
|
73688
74111
|
}
|
|
@@ -73760,7 +74183,7 @@ var exports_agent_reliability_commands = {};
|
|
|
73760
74183
|
__export(exports_agent_reliability_commands, {
|
|
73761
74184
|
registerAgentReliabilityCommands: () => registerAgentReliabilityCommands
|
|
73762
74185
|
});
|
|
73763
|
-
import
|
|
74186
|
+
import chalk19 from "chalk";
|
|
73764
74187
|
function parseNumber(value, fallback) {
|
|
73765
74188
|
if (!value)
|
|
73766
74189
|
return fallback;
|
|
@@ -73775,9 +74198,9 @@ function commonOptions(opts) {
|
|
|
73775
74198
|
};
|
|
73776
74199
|
}
|
|
73777
74200
|
function printScorecard(scorecard) {
|
|
73778
|
-
const color = scorecard.grade === "at_risk" ?
|
|
73779
|
-
console.log(`${
|
|
73780
|
-
console.log(
|
|
74201
|
+
const color = scorecard.grade === "at_risk" ? chalk19.red : scorecard.grade === "watch" ? chalk19.yellow : scorecard.grade === "excellent" ? chalk19.green : chalk19.white;
|
|
74202
|
+
console.log(`${chalk19.cyan(scorecard.agent_id.slice(0, 8))} ${color(`${scorecard.score}/100`)} ${chalk19.bold(scorecard.agent_name)} ${chalk19.dim(scorecard.grade)}`);
|
|
74203
|
+
console.log(chalk19.dim(` completed: ${scorecard.signals.tasks_completed} \xB7 failed: ${scorecard.signals.tasks_failed} \xB7 failed checks: ${scorecard.signals.failed_verifications} \xB7 failed runs: ${scorecard.signals.runs_failed} \xB7 stale locks: ${scorecard.signals.stale_task_locks + scorecard.signals.stale_resource_locks}`));
|
|
73781
74204
|
for (const recommendation of scorecard.recommendations.slice(0, 3))
|
|
73782
74205
|
console.log(` - ${recommendation}`);
|
|
73783
74206
|
}
|
|
@@ -73849,7 +74272,7 @@ var exports_onboarding_commands = {};
|
|
|
73849
74272
|
__export(exports_onboarding_commands, {
|
|
73850
74273
|
registerOnboardingCommands: () => registerOnboardingCommands
|
|
73851
74274
|
});
|
|
73852
|
-
import
|
|
74275
|
+
import chalk20 from "chalk";
|
|
73853
74276
|
import { resolve as resolve23 } from "path";
|
|
73854
74277
|
function registerOnboardingCommands(program2) {
|
|
73855
74278
|
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) => {
|
|
@@ -73871,9 +74294,9 @@ function registerOnboardingCommands(program2) {
|
|
|
73871
74294
|
output(result, true);
|
|
73872
74295
|
return;
|
|
73873
74296
|
}
|
|
73874
|
-
console.log(
|
|
74297
|
+
console.log(chalk20.green(`Wrote ${result.written} onboarding fixture file(s) to ${result.directory}`));
|
|
73875
74298
|
for (const file of result.files)
|
|
73876
|
-
console.log(
|
|
74299
|
+
console.log(chalk20.dim(` ${file}`));
|
|
73877
74300
|
return;
|
|
73878
74301
|
}
|
|
73879
74302
|
if (opts.import) {
|
|
@@ -73887,7 +74310,7 @@ function registerOnboardingCommands(program2) {
|
|
|
73887
74310
|
return;
|
|
73888
74311
|
}
|
|
73889
74312
|
const mode = result.dry_run ? "Dry-run" : "Import";
|
|
73890
|
-
console.log(
|
|
74313
|
+
console.log(chalk20.bold(`${mode} ${result.ok ? "ready" : "has issues"}`));
|
|
73891
74314
|
for (const [key, count2] of Object.entries(result.inserted)) {
|
|
73892
74315
|
if (count2 > 0)
|
|
73893
74316
|
console.log(` ${key}: ${count2}`);
|
|
@@ -73897,9 +74320,9 @@ function registerOnboardingCommands(program2) {
|
|
|
73897
74320
|
console.log(` ${key} merged: ${count2}`);
|
|
73898
74321
|
}
|
|
73899
74322
|
if (result.conflicts.length > 0)
|
|
73900
|
-
console.log(
|
|
74323
|
+
console.log(chalk20.yellow(` conflicts: ${result.conflicts.length}`));
|
|
73901
74324
|
for (const issue of result.issues)
|
|
73902
|
-
console.error(
|
|
74325
|
+
console.error(chalk20.red(` ${issue}`));
|
|
73903
74326
|
return;
|
|
73904
74327
|
}
|
|
73905
74328
|
const fixtures = listOnboardingFixtures2();
|
|
@@ -73907,11 +74330,11 @@ function registerOnboardingCommands(program2) {
|
|
|
73907
74330
|
output(fixtures, true);
|
|
73908
74331
|
return;
|
|
73909
74332
|
}
|
|
73910
|
-
console.log(
|
|
74333
|
+
console.log(chalk20.bold(`${fixtures.length} bundled onboarding fixture(s):
|
|
73911
74334
|
`));
|
|
73912
74335
|
for (const fixture of fixtures) {
|
|
73913
|
-
console.log(` ${
|
|
73914
|
-
console.log(
|
|
74336
|
+
console.log(` ${chalk20.bold(fixture.name)} ${chalk20.dim(`[${fixture.version}]`)} ${chalk20.yellow(`${fixture.stats.tasks} tasks`)}`);
|
|
74337
|
+
console.log(chalk20.dim(` ${fixture.description}`));
|
|
73915
74338
|
}
|
|
73916
74339
|
} catch (e) {
|
|
73917
74340
|
handleError(e);
|
|
@@ -73927,7 +74350,7 @@ var exports_local_snapshot_commands = {};
|
|
|
73927
74350
|
__export(exports_local_snapshot_commands, {
|
|
73928
74351
|
registerLocalSnapshotCommands: () => registerLocalSnapshotCommands
|
|
73929
74352
|
});
|
|
73930
|
-
import
|
|
74353
|
+
import chalk21 from "chalk";
|
|
73931
74354
|
function splitTypes(value) {
|
|
73932
74355
|
if (!value)
|
|
73933
74356
|
return;
|
|
@@ -73961,9 +74384,9 @@ function registerLocalSnapshotCommands(program2) {
|
|
|
73961
74384
|
output(result, true);
|
|
73962
74385
|
return;
|
|
73963
74386
|
}
|
|
73964
|
-
console.log(
|
|
74387
|
+
console.log(chalk21.bold(`Changed snapshots: ${result.snapshots.length}`));
|
|
73965
74388
|
for (const snapshot of result.snapshots) {
|
|
73966
|
-
console.log(` ${snapshot.type} ${
|
|
74389
|
+
console.log(` ${snapshot.type} ${chalk21.dim(snapshot.cursor)} ${snapshot.fingerprint.slice(0, 12)}`);
|
|
73967
74390
|
}
|
|
73968
74391
|
return;
|
|
73969
74392
|
}
|
|
@@ -73982,7 +74405,7 @@ function registerLocalSnapshotCommands(program2) {
|
|
|
73982
74405
|
output(snapshot, true);
|
|
73983
74406
|
return;
|
|
73984
74407
|
}
|
|
73985
|
-
console.log(
|
|
74408
|
+
console.log(chalk21.bold(`${snapshot.type} snapshot`));
|
|
73986
74409
|
console.log(` count: ${snapshot.count}`);
|
|
73987
74410
|
console.log(` cursor: ${snapshot.cursor}`);
|
|
73988
74411
|
console.log(` fingerprint: ${snapshot.fingerprint}`);
|
|
@@ -73993,11 +74416,11 @@ function registerLocalSnapshotCommands(program2) {
|
|
|
73993
74416
|
output(resources, true);
|
|
73994
74417
|
return;
|
|
73995
74418
|
}
|
|
73996
|
-
console.log(
|
|
74419
|
+
console.log(chalk21.bold(`${resources.length} local snapshot resources:
|
|
73997
74420
|
`));
|
|
73998
74421
|
for (const resource of resources) {
|
|
73999
|
-
console.log(` ${
|
|
74000
|
-
console.log(
|
|
74422
|
+
console.log(` ${chalk21.bold(resource.type)} ${chalk21.dim(resource.uri)}`);
|
|
74423
|
+
console.log(chalk21.dim(` ${resource.description}`));
|
|
74001
74424
|
}
|
|
74002
74425
|
} catch (e) {
|
|
74003
74426
|
handleError(e);
|
|
@@ -77366,7 +77789,7 @@ __export(exports_sdk_integration_fixtures, {
|
|
|
77366
77789
|
TODOS_SDK_INTEGRATION_FIXTURE_GENERATED_AT: () => TODOS_SDK_INTEGRATION_FIXTURE_GENERATED_AT
|
|
77367
77790
|
});
|
|
77368
77791
|
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync15 } from "fs";
|
|
77369
|
-
import { join as
|
|
77792
|
+
import { join as join30 } from "path";
|
|
77370
77793
|
function source5(version) {
|
|
77371
77794
|
return {
|
|
77372
77795
|
packageName: "@hasna/todos",
|
|
@@ -77473,7 +77896,7 @@ function writeSdkIntegrationFixtures(directory, options = {}) {
|
|
|
77473
77896
|
];
|
|
77474
77897
|
const written = [];
|
|
77475
77898
|
for (const [name, payload] of files) {
|
|
77476
|
-
const file =
|
|
77899
|
+
const file = join30(directory, name);
|
|
77477
77900
|
writeFileSync15(file, `${JSON.stringify(payload, null, 2)}
|
|
77478
77901
|
`, "utf-8");
|
|
77479
77902
|
written.push(file);
|
|
@@ -77496,7 +77919,7 @@ var exports_sdk_fixture_commands = {};
|
|
|
77496
77919
|
__export(exports_sdk_fixture_commands, {
|
|
77497
77920
|
registerSdkFixtureCommands: () => registerSdkFixtureCommands
|
|
77498
77921
|
});
|
|
77499
|
-
import
|
|
77922
|
+
import chalk22 from "chalk";
|
|
77500
77923
|
import { resolve as resolve24 } from "path";
|
|
77501
77924
|
function registerSdkFixtureCommands(program2) {
|
|
77502
77925
|
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) => {
|
|
@@ -77513,9 +77936,9 @@ function registerSdkFixtureCommands(program2) {
|
|
|
77513
77936
|
console.log(JSON.stringify(result));
|
|
77514
77937
|
return;
|
|
77515
77938
|
}
|
|
77516
|
-
console.log(
|
|
77939
|
+
console.log(chalk22.green(`Wrote ${result.files.length} SDK integration fixture file(s) to ${result.directory}`));
|
|
77517
77940
|
for (const file of result.files)
|
|
77518
|
-
console.log(
|
|
77941
|
+
console.log(chalk22.dim(` ${file}`));
|
|
77519
77942
|
return;
|
|
77520
77943
|
}
|
|
77521
77944
|
if (opts.show) {
|
|
@@ -77527,11 +77950,11 @@ function registerSdkFixtureCommands(program2) {
|
|
|
77527
77950
|
output(examples, true);
|
|
77528
77951
|
return;
|
|
77529
77952
|
}
|
|
77530
|
-
console.log(
|
|
77953
|
+
console.log(chalk22.bold(`${examples.length} local SDK integration example(s):
|
|
77531
77954
|
`));
|
|
77532
77955
|
for (const example of examples) {
|
|
77533
|
-
console.log(` ${
|
|
77534
|
-
console.log(
|
|
77956
|
+
console.log(` ${chalk22.bold(example.id)} ${chalk22.dim(`[${example.surface}]`)}`);
|
|
77957
|
+
console.log(chalk22.dim(` ${example.command}`));
|
|
77535
77958
|
}
|
|
77536
77959
|
} catch (e) {
|
|
77537
77960
|
handleError(e);
|
|
@@ -77547,7 +77970,7 @@ var exports_review_queue_commands = {};
|
|
|
77547
77970
|
__export(exports_review_queue_commands, {
|
|
77548
77971
|
registerReviewQueueCommands: () => registerReviewQueueCommands
|
|
77549
77972
|
});
|
|
77550
|
-
import
|
|
77973
|
+
import chalk23 from "chalk";
|
|
77551
77974
|
function splitList2(value) {
|
|
77552
77975
|
return value?.split(";").flatMap((part) => part.split(",")).map((item) => item.trim()).filter(Boolean);
|
|
77553
77976
|
}
|
|
@@ -77578,12 +78001,12 @@ function registerReviewQueueCommands(program2) {
|
|
|
77578
78001
|
return;
|
|
77579
78002
|
}
|
|
77580
78003
|
if (items.length === 0) {
|
|
77581
|
-
console.log(
|
|
78004
|
+
console.log(chalk23.dim("Review queue is empty."));
|
|
77582
78005
|
return;
|
|
77583
78006
|
}
|
|
77584
78007
|
for (const item of items) {
|
|
77585
78008
|
const assignee = item.claimed_by || item.reviewer || "(unclaimed)";
|
|
77586
|
-
console.log(`${
|
|
78009
|
+
console.log(`${chalk23.dim(item.task_id.slice(0, 8))} ${item.state.padEnd(17)} ${item.queue.padEnd(12)} ${assignee.padEnd(12)} ${item.title}`);
|
|
77587
78010
|
}
|
|
77588
78011
|
} catch (e) {
|
|
77589
78012
|
handleError(e);
|
|
@@ -77605,7 +78028,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77605
78028
|
output(item, true);
|
|
77606
78029
|
return;
|
|
77607
78030
|
}
|
|
77608
|
-
console.log(
|
|
78031
|
+
console.log(chalk23.green(`Review requested: ${item.task_id.slice(0, 8)} -> ${item.queue}`));
|
|
77609
78032
|
} catch (e) {
|
|
77610
78033
|
handleError(e);
|
|
77611
78034
|
}
|
|
@@ -77619,7 +78042,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77619
78042
|
output(item, true);
|
|
77620
78043
|
return;
|
|
77621
78044
|
}
|
|
77622
|
-
console.log(
|
|
78045
|
+
console.log(chalk23.green(`Review claimed: ${item.task_id.slice(0, 8)} by ${item.claimed_by}`));
|
|
77623
78046
|
} catch (e) {
|
|
77624
78047
|
handleError(e);
|
|
77625
78048
|
}
|
|
@@ -77633,7 +78056,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77633
78056
|
output(item, true);
|
|
77634
78057
|
return;
|
|
77635
78058
|
}
|
|
77636
|
-
console.log(
|
|
78059
|
+
console.log(chalk23.green(`Review approved: ${item.task_id.slice(0, 8)} by ${item.reviewer}`));
|
|
77637
78060
|
} catch (e) {
|
|
77638
78061
|
handleError(e);
|
|
77639
78062
|
}
|
|
@@ -77652,7 +78075,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77652
78075
|
output(item, true);
|
|
77653
78076
|
return;
|
|
77654
78077
|
}
|
|
77655
|
-
console.log(
|
|
78078
|
+
console.log(chalk23.yellow(`Review returned: ${item.task_id.slice(0, 8)} with ${item.changes_requested.length} requested change(s)`));
|
|
77656
78079
|
} catch (e) {
|
|
77657
78080
|
handleError(e);
|
|
77658
78081
|
}
|
|
@@ -77666,7 +78089,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77666
78089
|
output(item, true);
|
|
77667
78090
|
return;
|
|
77668
78091
|
}
|
|
77669
|
-
console.log(
|
|
78092
|
+
console.log(chalk23.yellow(`Review reopened: ${item.task_id.slice(0, 8)}`));
|
|
77670
78093
|
} catch (e) {
|
|
77671
78094
|
handleError(e);
|
|
77672
78095
|
}
|
|
@@ -77682,11 +78105,11 @@ function registerReviewQueueCommands(program2) {
|
|
|
77682
78105
|
return;
|
|
77683
78106
|
}
|
|
77684
78107
|
if (items.length === 0) {
|
|
77685
|
-
console.log(
|
|
78108
|
+
console.log(chalk23.dim("No review routing rules configured."));
|
|
77686
78109
|
return;
|
|
77687
78110
|
}
|
|
77688
78111
|
for (const rule of items) {
|
|
77689
|
-
console.log(`${rule.enabled ?
|
|
78112
|
+
console.log(`${rule.enabled ? chalk23.green("on ") : chalk23.gray("off")} ${rule.name.padEnd(16)} ${rule.queue.padEnd(12)} ${rule.reviewers.join(",") || "(no reviewers)"}`);
|
|
77690
78113
|
}
|
|
77691
78114
|
} catch (e) {
|
|
77692
78115
|
handleError(e);
|
|
@@ -77709,7 +78132,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77709
78132
|
output(rule, true);
|
|
77710
78133
|
return;
|
|
77711
78134
|
}
|
|
77712
|
-
console.log(
|
|
78135
|
+
console.log(chalk23.green(`Review routing rule saved: ${rule.name}`));
|
|
77713
78136
|
} catch (e) {
|
|
77714
78137
|
handleError(e);
|
|
77715
78138
|
}
|
|
@@ -77723,7 +78146,7 @@ function registerReviewQueueCommands(program2) {
|
|
|
77723
78146
|
output({ removed }, true);
|
|
77724
78147
|
return;
|
|
77725
78148
|
}
|
|
77726
|
-
console.log(removed ?
|
|
78149
|
+
console.log(removed ? chalk23.green("Review routing rule removed.") : chalk23.dim("No review routing rule matched."));
|
|
77727
78150
|
} catch (e) {
|
|
77728
78151
|
handleError(e);
|
|
77729
78152
|
}
|
|
@@ -77738,8 +78161,8 @@ var exports_roadmap_commands = {};
|
|
|
77738
78161
|
__export(exports_roadmap_commands, {
|
|
77739
78162
|
registerRoadmapCommands: () => registerRoadmapCommands
|
|
77740
78163
|
});
|
|
77741
|
-
import { readFileSync as
|
|
77742
|
-
import
|
|
78164
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "fs";
|
|
78165
|
+
import chalk24 from "chalk";
|
|
77743
78166
|
function splitList3(value) {
|
|
77744
78167
|
return value?.split(";").flatMap((part) => part.split(",")).map((item) => item.trim()).filter(Boolean);
|
|
77745
78168
|
}
|
|
@@ -77786,7 +78209,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77786
78209
|
output(roadmap, true);
|
|
77787
78210
|
return;
|
|
77788
78211
|
}
|
|
77789
|
-
console.log(
|
|
78212
|
+
console.log(chalk24.green(`Roadmap created: ${roadmap.id.slice(0, 8)} ${roadmap.name}`));
|
|
77790
78213
|
} catch (e) {
|
|
77791
78214
|
handleError(e);
|
|
77792
78215
|
}
|
|
@@ -77801,11 +78224,11 @@ function registerRoadmapCommands(program2) {
|
|
|
77801
78224
|
return;
|
|
77802
78225
|
}
|
|
77803
78226
|
if (items.length === 0) {
|
|
77804
|
-
console.log(
|
|
78227
|
+
console.log(chalk24.dim("No roadmaps configured."));
|
|
77805
78228
|
return;
|
|
77806
78229
|
}
|
|
77807
78230
|
for (const item of items)
|
|
77808
|
-
console.log(`${
|
|
78231
|
+
console.log(`${chalk24.dim(item.id.slice(0, 8))} ${item.status.padEnd(9)} ${item.name}`);
|
|
77809
78232
|
} catch (e) {
|
|
77810
78233
|
handleError(e);
|
|
77811
78234
|
}
|
|
@@ -77845,7 +78268,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77845
78268
|
output(updated, true);
|
|
77846
78269
|
return;
|
|
77847
78270
|
}
|
|
77848
|
-
console.log(
|
|
78271
|
+
console.log(chalk24.green(`Roadmap updated: ${updated.id.slice(0, 8)} ${updated.name}`));
|
|
77849
78272
|
} catch (e) {
|
|
77850
78273
|
handleError(e);
|
|
77851
78274
|
}
|
|
@@ -77859,7 +78282,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77859
78282
|
output({ deleted }, true);
|
|
77860
78283
|
return;
|
|
77861
78284
|
}
|
|
77862
|
-
console.log(deleted ?
|
|
78285
|
+
console.log(deleted ? chalk24.green("Roadmap deleted.") : chalk24.dim("No roadmap matched."));
|
|
77863
78286
|
} catch (e) {
|
|
77864
78287
|
handleError(e);
|
|
77865
78288
|
}
|
|
@@ -77887,7 +78310,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77887
78310
|
output(milestone, true);
|
|
77888
78311
|
return;
|
|
77889
78312
|
}
|
|
77890
|
-
console.log(
|
|
78313
|
+
console.log(chalk24.green(`Milestone added: ${milestone.id.slice(0, 8)} ${milestone.title}`));
|
|
77891
78314
|
} catch (e) {
|
|
77892
78315
|
handleError(e);
|
|
77893
78316
|
}
|
|
@@ -77913,7 +78336,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77913
78336
|
output(updated, true);
|
|
77914
78337
|
return;
|
|
77915
78338
|
}
|
|
77916
|
-
console.log(
|
|
78339
|
+
console.log(chalk24.green(`Milestone updated: ${updated.id.slice(0, 8)} ${updated.title}`));
|
|
77917
78340
|
} catch (e) {
|
|
77918
78341
|
handleError(e);
|
|
77919
78342
|
}
|
|
@@ -77938,7 +78361,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77938
78361
|
output(release, true);
|
|
77939
78362
|
return;
|
|
77940
78363
|
}
|
|
77941
|
-
console.log(
|
|
78364
|
+
console.log(chalk24.green(`Release group saved: ${release.name}`));
|
|
77942
78365
|
} catch (e) {
|
|
77943
78366
|
handleError(e);
|
|
77944
78367
|
}
|
|
@@ -77951,7 +78374,7 @@ function registerRoadmapCommands(program2) {
|
|
|
77951
78374
|
if (opts.out) {
|
|
77952
78375
|
writeFileSync16(opts.out, content);
|
|
77953
78376
|
if (!globalOpts.json)
|
|
77954
|
-
console.log(
|
|
78377
|
+
console.log(chalk24.green(`Wrote roadmap export to ${opts.out}`));
|
|
77955
78378
|
}
|
|
77956
78379
|
if (globalOpts.json) {
|
|
77957
78380
|
output(opts.format === "markdown" ? { content } : JSON.parse(content), true);
|
|
@@ -77967,13 +78390,13 @@ function registerRoadmapCommands(program2) {
|
|
|
77967
78390
|
const globalOpts = globalOptions(program2);
|
|
77968
78391
|
try {
|
|
77969
78392
|
const { importRoadmapBundle: importRoadmapBundle2 } = await Promise.resolve().then(() => (init_roadmaps(), exports_roadmaps));
|
|
77970
|
-
const bundle = JSON.parse(
|
|
78393
|
+
const bundle = JSON.parse(readFileSync23(path, "utf8"));
|
|
77971
78394
|
const result = importRoadmapBundle2(bundle, { apply: Boolean(opts.apply) });
|
|
77972
78395
|
if (globalOpts.json) {
|
|
77973
78396
|
output(result, true);
|
|
77974
78397
|
return;
|
|
77975
78398
|
}
|
|
77976
|
-
console.log(result.applied ?
|
|
78399
|
+
console.log(result.applied ? chalk24.green(`Imported roadmap ${result.roadmap_id}`) : chalk24.dim(`Preview: ${result.milestones} milestones, ${result.releases} releases`));
|
|
77977
78400
|
} catch (e) {
|
|
77978
78401
|
handleError(e);
|
|
77979
78402
|
}
|
|
@@ -77989,7 +78412,7 @@ var exports_capacity_commands = {};
|
|
|
77989
78412
|
__export(exports_capacity_commands, {
|
|
77990
78413
|
registerCapacityCommands: () => registerCapacityCommands
|
|
77991
78414
|
});
|
|
77992
|
-
import
|
|
78415
|
+
import chalk25 from "chalk";
|
|
77993
78416
|
function splitDays(value) {
|
|
77994
78417
|
return value?.split(",").map((item) => Number(item.trim())).filter((item) => Number.isFinite(item));
|
|
77995
78418
|
}
|
|
@@ -78022,7 +78445,7 @@ function registerCapacityCommands(program2) {
|
|
|
78022
78445
|
output(profile, true);
|
|
78023
78446
|
return;
|
|
78024
78447
|
}
|
|
78025
|
-
console.log(
|
|
78448
|
+
console.log(chalk25.green(`Capacity saved: ${profile.agent_id} ${profile.minutes_per_day}m/day`));
|
|
78026
78449
|
} catch (e) {
|
|
78027
78450
|
handleError(e);
|
|
78028
78451
|
}
|
|
@@ -78040,7 +78463,7 @@ function registerCapacityCommands(program2) {
|
|
|
78040
78463
|
return;
|
|
78041
78464
|
}
|
|
78042
78465
|
if (profiles.length === 0) {
|
|
78043
|
-
console.log(
|
|
78466
|
+
console.log(chalk25.dim("No capacity profiles."));
|
|
78044
78467
|
return;
|
|
78045
78468
|
}
|
|
78046
78469
|
for (const profile of profiles) {
|
|
@@ -78059,7 +78482,7 @@ function registerCapacityCommands(program2) {
|
|
|
78059
78482
|
output({ removed }, true);
|
|
78060
78483
|
return;
|
|
78061
78484
|
}
|
|
78062
|
-
console.log(removed ?
|
|
78485
|
+
console.log(removed ? chalk25.green("Capacity profile removed.") : chalk25.dim("No capacity profile matched."));
|
|
78063
78486
|
} catch (e) {
|
|
78064
78487
|
handleError(e);
|
|
78065
78488
|
}
|
|
@@ -78098,7 +78521,7 @@ var exports_audit_ledger_commands = {};
|
|
|
78098
78521
|
__export(exports_audit_ledger_commands, {
|
|
78099
78522
|
registerAuditLedgerCommands: () => registerAuditLedgerCommands
|
|
78100
78523
|
});
|
|
78101
|
-
import
|
|
78524
|
+
import chalk26 from "chalk";
|
|
78102
78525
|
function globalOptions3(program2) {
|
|
78103
78526
|
const command = program2;
|
|
78104
78527
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
@@ -78154,7 +78577,7 @@ function registerAuditLedgerCommands(program2) {
|
|
|
78154
78577
|
output(checkpoint, true);
|
|
78155
78578
|
return;
|
|
78156
78579
|
}
|
|
78157
|
-
console.log(
|
|
78580
|
+
console.log(chalk26.green(`Audit checkpoint sealed: ${checkpoint.name} ${checkpoint.root_hash}`));
|
|
78158
78581
|
} catch (e) {
|
|
78159
78582
|
handleError(e);
|
|
78160
78583
|
}
|
|
@@ -78169,7 +78592,7 @@ function registerAuditLedgerCommands(program2) {
|
|
|
78169
78592
|
return;
|
|
78170
78593
|
}
|
|
78171
78594
|
if (checkpoints.length === 0) {
|
|
78172
|
-
console.log(
|
|
78595
|
+
console.log(chalk26.dim("No audit ledger checkpoints."));
|
|
78173
78596
|
return;
|
|
78174
78597
|
}
|
|
78175
78598
|
for (const checkpoint of checkpoints) {
|
|
@@ -78192,7 +78615,7 @@ function registerAuditLedgerCommands(program2) {
|
|
|
78192
78615
|
output(result, true);
|
|
78193
78616
|
return;
|
|
78194
78617
|
}
|
|
78195
|
-
console.log(result.ok ?
|
|
78618
|
+
console.log(result.ok ? chalk26.green("Audit ledger verified.") : chalk26.red(`Audit ledger failed: ${result.issues.join("; ")}`));
|
|
78196
78619
|
if (!result.ok)
|
|
78197
78620
|
process.exitCode = 1;
|
|
78198
78621
|
} catch (e) {
|
|
@@ -78211,7 +78634,7 @@ var exports_release_compatibility_commands = {};
|
|
|
78211
78634
|
__export(exports_release_compatibility_commands, {
|
|
78212
78635
|
registerReleaseCompatibilityCommands: () => registerReleaseCompatibilityCommands
|
|
78213
78636
|
});
|
|
78214
|
-
import
|
|
78637
|
+
import chalk27 from "chalk";
|
|
78215
78638
|
function globalOptions4(program2) {
|
|
78216
78639
|
const command = program2;
|
|
78217
78640
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
@@ -78243,7 +78666,7 @@ function registerReleaseCompatibilityCommands(program2) {
|
|
|
78243
78666
|
process.exitCode = 1;
|
|
78244
78667
|
return;
|
|
78245
78668
|
}
|
|
78246
|
-
console.log(report.ok ?
|
|
78669
|
+
console.log(report.ok ? chalk27.green("Release compatibility passed.") : chalk27.red("Release compatibility failed."));
|
|
78247
78670
|
if (!report.ok)
|
|
78248
78671
|
process.exitCode = 1;
|
|
78249
78672
|
} catch (error2) {
|
|
@@ -78326,14 +78749,14 @@ var exports_local_backup_commands = {};
|
|
|
78326
78749
|
__export(exports_local_backup_commands, {
|
|
78327
78750
|
registerLocalBackupCommands: () => registerLocalBackupCommands
|
|
78328
78751
|
});
|
|
78329
|
-
import
|
|
78752
|
+
import chalk28 from "chalk";
|
|
78330
78753
|
import { resolve as resolve25 } from "path";
|
|
78331
78754
|
function globalOptions6(program2) {
|
|
78332
78755
|
const command = program2;
|
|
78333
78756
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
78334
78757
|
}
|
|
78335
78758
|
function printCreateSummary(result) {
|
|
78336
|
-
console.log(
|
|
78759
|
+
console.log(chalk28.bold("todos local backup"));
|
|
78337
78760
|
if (result.output_path)
|
|
78338
78761
|
console.log(`File: ${result.output_path}`);
|
|
78339
78762
|
console.log(`Checksum: ${result.backup.checksum}`);
|
|
@@ -78373,13 +78796,13 @@ function registerLocalBackupCommands(program2) {
|
|
|
78373
78796
|
output(verification, true);
|
|
78374
78797
|
return;
|
|
78375
78798
|
}
|
|
78376
|
-
console.log(
|
|
78799
|
+
console.log(chalk28.bold(`Backup ${verification.ok ? "verified" : "has issues"}`));
|
|
78377
78800
|
console.log(`Checksum: ${verification.checksum.ok ? "ok" : "mismatch"}`);
|
|
78378
78801
|
console.log(`Bridge: ${verification.bridge_checksum.ok ? "ok" : "mismatch"}`);
|
|
78379
78802
|
for (const issue of verification.issues)
|
|
78380
|
-
console.error(
|
|
78803
|
+
console.error(chalk28.red(` ${issue}`));
|
|
78381
78804
|
for (const warning of verification.warnings)
|
|
78382
|
-
console.error(
|
|
78805
|
+
console.error(chalk28.yellow(` ${warning}`));
|
|
78383
78806
|
} catch (error2) {
|
|
78384
78807
|
handleError(error2);
|
|
78385
78808
|
}
|
|
@@ -78396,18 +78819,18 @@ function registerLocalBackupCommands(program2) {
|
|
|
78396
78819
|
output(result, true);
|
|
78397
78820
|
return;
|
|
78398
78821
|
}
|
|
78399
|
-
console.log(
|
|
78822
|
+
console.log(chalk28.bold(`${result.dry_run ? "Restore dry-run" : "Restore"} ${result.ok ? "ready" : "has issues"}`));
|
|
78400
78823
|
if (result.import_result) {
|
|
78401
78824
|
for (const [key, count2] of Object.entries(result.import_result.inserted)) {
|
|
78402
78825
|
if (count2 > 0)
|
|
78403
78826
|
console.log(` ${key}: ${count2}`);
|
|
78404
78827
|
}
|
|
78405
78828
|
if (result.import_result.conflicts.length > 0) {
|
|
78406
|
-
console.log(
|
|
78829
|
+
console.log(chalk28.yellow(` conflicts: ${result.import_result.conflicts.length}`));
|
|
78407
78830
|
}
|
|
78408
78831
|
}
|
|
78409
78832
|
for (const issue of result.issues)
|
|
78410
|
-
console.error(
|
|
78833
|
+
console.error(chalk28.red(` ${issue}`));
|
|
78411
78834
|
} catch (error2) {
|
|
78412
78835
|
handleError(error2);
|
|
78413
78836
|
}
|
|
@@ -78423,14 +78846,14 @@ function registerLocalBackupCommands(program2) {
|
|
|
78423
78846
|
output(report, true);
|
|
78424
78847
|
return;
|
|
78425
78848
|
}
|
|
78426
|
-
console.log(
|
|
78849
|
+
console.log(chalk28.bold(`Local integrity ${report.ok ? "ok" : "needs attention"}`));
|
|
78427
78850
|
console.log(`Quick check: ${report.sqlite.quick_check}`);
|
|
78428
78851
|
console.log(`Foreign key violations: ${report.sqlite.foreign_key_violations}`);
|
|
78429
78852
|
console.log(`Tasks: ${report.counts.tasks}`);
|
|
78430
78853
|
for (const issue of report.issues)
|
|
78431
|
-
console.error(
|
|
78854
|
+
console.error(chalk28.red(` ${issue}`));
|
|
78432
78855
|
for (const warning of report.warnings)
|
|
78433
|
-
console.error(
|
|
78856
|
+
console.error(chalk28.yellow(` ${warning}`));
|
|
78434
78857
|
} catch (error2) {
|
|
78435
78858
|
handleError(error2);
|
|
78436
78859
|
}
|
|
@@ -78924,7 +79347,7 @@ var init_hybrid = __esm(() => {
|
|
|
78924
79347
|
});
|
|
78925
79348
|
|
|
78926
79349
|
// src/storage/s3-artifacts.ts
|
|
78927
|
-
import { createHash as
|
|
79350
|
+
import { createHash as createHash18, createHmac as createHmac2 } from "crypto";
|
|
78928
79351
|
function createTodosS3ArtifactStore(options) {
|
|
78929
79352
|
const requestFetch = options.fetch ?? fetch;
|
|
78930
79353
|
const now4 = options.now ?? (() => new Date);
|
|
@@ -79096,7 +79519,7 @@ function toAmzDate(date) {
|
|
|
79096
79519
|
return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
79097
79520
|
}
|
|
79098
79521
|
function sha256Hex(value) {
|
|
79099
|
-
return
|
|
79522
|
+
return createHash18("sha256").update(value).digest("hex");
|
|
79100
79523
|
}
|
|
79101
79524
|
function hmac(key, value) {
|
|
79102
79525
|
return createHmac2("sha256", key).update(value).digest();
|
|
@@ -79703,13 +80126,13 @@ __export(exports_storage_commands, {
|
|
|
79703
80126
|
s3CredentialsFromEnv: () => s3CredentialsFromEnv,
|
|
79704
80127
|
registerStorageCommands: () => registerStorageCommands
|
|
79705
80128
|
});
|
|
79706
|
-
import
|
|
80129
|
+
import chalk29 from "chalk";
|
|
79707
80130
|
function globalOptions7(program2) {
|
|
79708
80131
|
const command = program2;
|
|
79709
80132
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
79710
80133
|
}
|
|
79711
80134
|
function printStatus(status) {
|
|
79712
|
-
console.log(
|
|
80135
|
+
console.log(chalk29.bold("todos storage"));
|
|
79713
80136
|
console.log(`Mode: ${status.mode}`);
|
|
79714
80137
|
console.log(`Remote: ${status.remote_enabled ? "enabled" : "disabled"}`);
|
|
79715
80138
|
console.log(`Canonical RDS: ${status.canonical.cluster}/${status.canonical.database}`);
|
|
@@ -79720,12 +80143,12 @@ function printStatus(status) {
|
|
|
79720
80143
|
console.log(`Sync batch: ${status.sync.batch_size}`);
|
|
79721
80144
|
console.log(`Network: not used`);
|
|
79722
80145
|
for (const issue of status.issues)
|
|
79723
|
-
console.error(
|
|
80146
|
+
console.error(chalk29.red(` ${issue}`));
|
|
79724
80147
|
for (const warning of status.warnings)
|
|
79725
|
-
console.error(
|
|
80148
|
+
console.error(chalk29.yellow(` ${warning}`));
|
|
79726
80149
|
}
|
|
79727
80150
|
function printSyncPlan(plan) {
|
|
79728
|
-
console.log(
|
|
80151
|
+
console.log(chalk29.bold("todos storage sync-plan"));
|
|
79729
80152
|
console.log(`Mode: ${plan.status.mode}`);
|
|
79730
80153
|
console.log(`Dry run: yes`);
|
|
79731
80154
|
console.log(`Database: ${plan.postgres.configured ? "configured" : "not configured"}`);
|
|
@@ -79739,17 +80162,17 @@ function printSyncPlan(plan) {
|
|
|
79739
80162
|
console.log(statement);
|
|
79740
80163
|
}
|
|
79741
80164
|
for (const issue of plan.status.issues)
|
|
79742
|
-
console.error(
|
|
80165
|
+
console.error(chalk29.red(` ${issue}`));
|
|
79743
80166
|
for (const warning of plan.status.warnings)
|
|
79744
|
-
console.error(
|
|
80167
|
+
console.error(chalk29.yellow(` ${warning}`));
|
|
79745
80168
|
}
|
|
79746
80169
|
function printShadowStatus(report, enabled, shadowEnv) {
|
|
79747
|
-
console.log(
|
|
80170
|
+
console.log(chalk29.bold("todos storage shadow-status"));
|
|
79748
80171
|
console.log(`Shadow mirror: ${enabled ? "enabled" : "disabled"} (${shadowEnv})`);
|
|
79749
80172
|
console.log(`Service: ${report.service}`);
|
|
79750
80173
|
console.log(`Cloud reachable: ${report.cloud_reachable ? "yes" : "no"}`);
|
|
79751
80174
|
if (report.error) {
|
|
79752
|
-
console.error(
|
|
80175
|
+
console.error(chalk29.red(` ${report.error}`));
|
|
79753
80176
|
return;
|
|
79754
80177
|
}
|
|
79755
80178
|
console.log(`In sync: ${report.in_sync ? "yes" : "no"}`);
|
|
@@ -79757,7 +80180,7 @@ function printShadowStatus(report, enabled, shadowEnv) {
|
|
|
79757
80180
|
console.log(`Last mirror lag: ${report.last_mirror_lag_ms === null ? "n/a" : `${report.last_mirror_lag_ms}ms`}`);
|
|
79758
80181
|
console.log("Rows (local -> cloud):");
|
|
79759
80182
|
for (const entry2 of report.objects) {
|
|
79760
|
-
const flag = entry2.diff === 0 ? "" :
|
|
80183
|
+
const flag = entry2.diff === 0 ? "" : chalk29.yellow(` (diff ${entry2.diff > 0 ? "+" : ""}${entry2.diff})`);
|
|
79761
80184
|
console.log(` ${entry2.object_type.padEnd(14)} local=${String(entry2.local).padStart(6)} cloud=${String(entry2.cloud).padStart(6)} tombstones=${entry2.cloud_tombstones}${flag}`);
|
|
79762
80185
|
}
|
|
79763
80186
|
console.log(` ${"TOTAL".padEnd(14)} local=${String(report.totals.local).padStart(6)} cloud=${String(report.totals.cloud).padStart(6)} diff=${report.totals.diff}`);
|
|
@@ -79777,7 +80200,7 @@ function readOutboxDepth() {
|
|
|
79777
80200
|
}
|
|
79778
80201
|
}
|
|
79779
80202
|
function printArtifactPlan(plan) {
|
|
79780
|
-
console.log(
|
|
80203
|
+
console.log(chalk29.bold(`todos storage artifacts ${plan.direction}`));
|
|
79781
80204
|
console.log("Dry run: yes");
|
|
79782
80205
|
console.log("Network: not used");
|
|
79783
80206
|
console.log(`Total: ${plan.total}`);
|
|
@@ -79788,10 +80211,10 @@ function printArtifactPlan(plan) {
|
|
|
79788
80211
|
console.log(` ${artifact.status.padEnd(18)} ${artifact.id.slice(0, 8)} ${artifact.sha256?.slice(0, 12) ?? "no-sha"}`);
|
|
79789
80212
|
}
|
|
79790
80213
|
for (const error2 of plan.errors)
|
|
79791
|
-
console.error(
|
|
80214
|
+
console.error(chalk29.red(` ${error2}`));
|
|
79792
80215
|
}
|
|
79793
80216
|
function printArtifactResult(direction, result) {
|
|
79794
|
-
console.log(
|
|
80217
|
+
console.log(chalk29.bold(`todos storage artifacts ${direction}`));
|
|
79795
80218
|
console.log(`Uploaded: ${result.uploaded}`);
|
|
79796
80219
|
console.log(`Downloaded: ${result.downloaded}`);
|
|
79797
80220
|
console.log(`Skipped: ${result.skipped}`);
|
|
@@ -79799,7 +80222,7 @@ function printArtifactResult(direction, result) {
|
|
|
79799
80222
|
console.log(` ${artifact.id.slice(0, 8)} ${artifact.key}`);
|
|
79800
80223
|
}
|
|
79801
80224
|
for (const error2 of result.errors)
|
|
79802
|
-
console.error(
|
|
80225
|
+
console.error(chalk29.red(` ${error2}`));
|
|
79803
80226
|
}
|
|
79804
80227
|
function artifactFilter(opts) {
|
|
79805
80228
|
const limit = opts.limit ? Number.parseInt(opts.limit, 10) : undefined;
|
|
@@ -79878,7 +80301,7 @@ function registerStorageCommands(program2) {
|
|
|
79878
80301
|
return;
|
|
79879
80302
|
}
|
|
79880
80303
|
if (remoteAuthority.selected) {
|
|
79881
|
-
console.log(
|
|
80304
|
+
console.log(chalk29.bold("todos storage"));
|
|
79882
80305
|
console.log("Mode: http");
|
|
79883
80306
|
console.log("Transport: authenticated HTTP /v1");
|
|
79884
80307
|
console.log(`Authority: ${remoteAuthority.v1_base_url ?? "not configured"}`);
|
|
@@ -79886,7 +80309,7 @@ function registerStorageCommands(program2) {
|
|
|
79886
80309
|
console.log("Local fallback: disabled");
|
|
79887
80310
|
console.log("Network: not used (configuration diagnostic only)");
|
|
79888
80311
|
for (const issue of remoteAuthority.issues)
|
|
79889
|
-
console.error(
|
|
80312
|
+
console.error(chalk29.red(` ${issue}`));
|
|
79890
80313
|
if (!status.ok)
|
|
79891
80314
|
process.exitCode = 1;
|
|
79892
80315
|
return;
|
|
@@ -79931,7 +80354,7 @@ function registerStorageCommands(program2) {
|
|
|
79931
80354
|
output({ configured: false, message }, true);
|
|
79932
80355
|
return;
|
|
79933
80356
|
}
|
|
79934
|
-
console.log(
|
|
80357
|
+
console.log(chalk29.yellow(message));
|
|
79935
80358
|
return;
|
|
79936
80359
|
}
|
|
79937
80360
|
cloud = client;
|
|
@@ -79969,7 +80392,7 @@ function registerStorageCommands(program2) {
|
|
|
79969
80392
|
output({ shadow_enabled: false, message }, true);
|
|
79970
80393
|
return;
|
|
79971
80394
|
}
|
|
79972
|
-
console.log(
|
|
80395
|
+
console.log(chalk29.yellow(message));
|
|
79973
80396
|
return;
|
|
79974
80397
|
}
|
|
79975
80398
|
const { getDatabase: getDatabase2 } = await Promise.resolve().then(() => (init_database(), exports_database));
|
|
@@ -79981,7 +80404,7 @@ function registerStorageCommands(program2) {
|
|
|
79981
80404
|
output({ shadow_enabled: true, ...stats2 }, true);
|
|
79982
80405
|
return;
|
|
79983
80406
|
}
|
|
79984
|
-
console.log(
|
|
80407
|
+
console.log(chalk29.bold("todos storage shadow-drain"));
|
|
79985
80408
|
console.log(`Mirrored: ${stats2.mirrored}`);
|
|
79986
80409
|
console.log(`Retries: ${stats2.retries}`);
|
|
79987
80410
|
console.log(`Pending: ${stats2.pending}`);
|
|
@@ -79989,7 +80412,7 @@ function registerStorageCommands(program2) {
|
|
|
79989
80412
|
console.log(`Outbox depth: ${stats2.depth}`);
|
|
79990
80413
|
console.log(`Last mirror: ${stats2.lastMirrorAt ?? "never"}`);
|
|
79991
80414
|
if (stats2.lastError)
|
|
79992
|
-
console.error(
|
|
80415
|
+
console.error(chalk29.yellow(`Last error: ${stats2.lastError}`));
|
|
79993
80416
|
} catch (error2) {
|
|
79994
80417
|
handleError(error2);
|
|
79995
80418
|
}
|
|
@@ -80287,7 +80710,7 @@ var exports_scale_hardening_commands = {};
|
|
|
80287
80710
|
__export(exports_scale_hardening_commands, {
|
|
80288
80711
|
registerScaleHardeningCommands: () => registerScaleHardeningCommands
|
|
80289
80712
|
});
|
|
80290
|
-
import
|
|
80713
|
+
import chalk30 from "chalk";
|
|
80291
80714
|
function globalOptions8(program2) {
|
|
80292
80715
|
const command = program2;
|
|
80293
80716
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
@@ -80334,7 +80757,7 @@ function registerScaleHardeningCommands(program2) {
|
|
|
80334
80757
|
}
|
|
80335
80758
|
if (format !== "markdown")
|
|
80336
80759
|
throw new Error("--format must be json or markdown");
|
|
80337
|
-
console.log(
|
|
80760
|
+
console.log(chalk30.bold(`todos scale compaction
|
|
80338
80761
|
`));
|
|
80339
80762
|
console.log(`Mode: ${result.dry_run ? "dry run" : "applied"}`);
|
|
80340
80763
|
console.log(`Before: ${result.before.page_count} pages, ${result.before.freelist_count} free`);
|
|
@@ -80354,7 +80777,7 @@ var exports_pr_group_commands = {};
|
|
|
80354
80777
|
__export(exports_pr_group_commands, {
|
|
80355
80778
|
registerPrGroupCommands: () => registerPrGroupCommands
|
|
80356
80779
|
});
|
|
80357
|
-
import
|
|
80780
|
+
import chalk31 from "chalk";
|
|
80358
80781
|
function globalOptions9(program2) {
|
|
80359
80782
|
const command = program2;
|
|
80360
80783
|
return command.optsWithGlobals?.() ?? program2.opts();
|
|
@@ -80381,7 +80804,7 @@ function registerPrGroupCommands(program2) {
|
|
|
80381
80804
|
output(view, true);
|
|
80382
80805
|
return;
|
|
80383
80806
|
}
|
|
80384
|
-
console.log(`${
|
|
80807
|
+
console.log(`${chalk31.bold(view.group.id)} ${view.group.state} revision=${view.group.revision}`);
|
|
80385
80808
|
console.log(`authority=${view.authority} attempts=${view.attempts.length} events=${view.diagnostics.event_count}`);
|
|
80386
80809
|
} catch (error2) {
|
|
80387
80810
|
handleError(error2);
|
|
@@ -80399,7 +80822,7 @@ function registerPrGroupCommands(program2) {
|
|
|
80399
80822
|
output(history, true);
|
|
80400
80823
|
return;
|
|
80401
80824
|
}
|
|
80402
|
-
console.log(`${
|
|
80825
|
+
console.log(`${chalk31.bold(history.group_id)} events=${history.count} authority=${history.authority}`);
|
|
80403
80826
|
for (const event of history.events) {
|
|
80404
80827
|
console.log(`${String(event.sequence).padStart(4)} ${event.event_type} ${event.state}`);
|
|
80405
80828
|
}
|
|
@@ -80796,6 +81219,7 @@ var [
|
|
|
80796
81219
|
{ registerQueryCommands: registerQueryCommands2 },
|
|
80797
81220
|
{ registerMcpHooksCommands: registerMcpHooksCommands2 },
|
|
80798
81221
|
{ registerDispatchCommands: registerDispatchCommands2 },
|
|
81222
|
+
{ registerDelegateCommands: registerDelegateCommands2 },
|
|
80799
81223
|
{ registerMachineCommands: registerMachineCommands2 },
|
|
80800
81224
|
{ registerApiKeyCommands: registerApiKeyCommands2 },
|
|
80801
81225
|
{ registerEnvironmentSnapshotCommands: registerEnvironmentSnapshotCommands2 },
|
|
@@ -80827,6 +81251,7 @@ var [
|
|
|
80827
81251
|
Promise.resolve().then(() => (init_query_commands(), exports_query_commands)),
|
|
80828
81252
|
Promise.resolve().then(() => (init_mcp_hooks_commands(), exports_mcp_hooks_commands)),
|
|
80829
81253
|
Promise.resolve().then(() => (init_dispatch3(), exports_dispatch2)),
|
|
81254
|
+
Promise.resolve().then(() => (init_delegate(), exports_delegate)),
|
|
80830
81255
|
Promise.resolve().then(() => (init_machines3(), exports_machines)),
|
|
80831
81256
|
Promise.resolve().then(() => (init_api_key_commands(), exports_api_key_commands)),
|
|
80832
81257
|
Promise.resolve().then(() => (init_environment_snapshots3(), exports_environment_snapshots2)),
|
|
@@ -80857,6 +81282,7 @@ registerConfigServeCommands2(program2);
|
|
|
80857
81282
|
registerQueryCommands2(program2);
|
|
80858
81283
|
registerMcpHooksCommands2(program2);
|
|
80859
81284
|
registerDispatchCommands2(program2);
|
|
81285
|
+
registerDelegateCommands2(program2);
|
|
80860
81286
|
registerMachineCommands2(program2);
|
|
80861
81287
|
registerApiKeyCommands2(program2);
|
|
80862
81288
|
registerEnvironmentSnapshotCommands2(program2);
|