@hasna/todos 0.11.54 → 0.11.55
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/index.js +30 -24
- package/dist/release-provenance.json +3 -3
- package/package.json +2 -2
package/dist/cli/index.js
CHANGED
|
@@ -50336,7 +50336,7 @@ import { join as join21 } from "path";
|
|
|
50336
50336
|
function getOrCreateLocalMachineName() {
|
|
50337
50337
|
return process.env["TODOS_MACHINE_NAME"] || __require("os").hostname() || "unknown";
|
|
50338
50338
|
}
|
|
50339
|
-
function
|
|
50339
|
+
function wantsJson2(program2, opts) {
|
|
50340
50340
|
return Boolean(opts["json"] || program2.opts().json);
|
|
50341
50341
|
}
|
|
50342
50342
|
function metadataString(machine, key) {
|
|
@@ -50450,7 +50450,7 @@ function registerMachineCommands(program2) {
|
|
|
50450
50450
|
git_root: opts.gitRoot,
|
|
50451
50451
|
primary: opts.primary
|
|
50452
50452
|
}, db);
|
|
50453
|
-
if (
|
|
50453
|
+
if (wantsJson2(program2, opts)) {
|
|
50454
50454
|
console.log(JSON.stringify(machine));
|
|
50455
50455
|
return;
|
|
50456
50456
|
}
|
|
@@ -50482,7 +50482,7 @@ function registerMachineCommands(program2) {
|
|
|
50482
50482
|
workspace_path: opts.workspace,
|
|
50483
50483
|
git_root: opts.gitRoot
|
|
50484
50484
|
}, db);
|
|
50485
|
-
if (
|
|
50485
|
+
if (wantsJson2(program2, opts)) {
|
|
50486
50486
|
console.log(JSON.stringify(machine));
|
|
50487
50487
|
return;
|
|
50488
50488
|
}
|
|
@@ -50592,7 +50592,7 @@ Warning: No primary machine set.`));
|
|
|
50592
50592
|
stale_minutes: staleMinutes,
|
|
50593
50593
|
include_archived: opts.includeArchived
|
|
50594
50594
|
}, getDatabase());
|
|
50595
|
-
if (
|
|
50595
|
+
if (wantsJson2(program2, opts)) {
|
|
50596
50596
|
console.log(JSON.stringify(diagnostics));
|
|
50597
50597
|
return;
|
|
50598
50598
|
}
|
|
@@ -50635,7 +50635,7 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
50635
50635
|
}
|
|
50636
50636
|
}
|
|
50637
50637
|
if (targets.length === 0) {
|
|
50638
|
-
if (
|
|
50638
|
+
if (wantsJson2(program2, opts)) {
|
|
50639
50639
|
console.log(JSON.stringify({
|
|
50640
50640
|
dry_run: Boolean(opts.dryRun),
|
|
50641
50641
|
pushed: Boolean(opts.push),
|
|
@@ -50656,14 +50656,14 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
50656
50656
|
conflictStrategy: "safe_merge"
|
|
50657
50657
|
}, db);
|
|
50658
50658
|
const record = { machine: target.name, pull };
|
|
50659
|
-
if (!
|
|
50659
|
+
if (!wantsJson2(program2, opts)) {
|
|
50660
50660
|
const mode = opts.dryRun ? "would pull" : "pulled";
|
|
50661
50661
|
console.log(chalk10.green(` ${target.name}: ${mode} ${formatBridgeImportSummary(pull)}`));
|
|
50662
50662
|
}
|
|
50663
50663
|
if (opts.push) {
|
|
50664
50664
|
const push = pushLocalBridgeBundle(ssh, Boolean(opts.dryRun));
|
|
50665
50665
|
record.push = push;
|
|
50666
|
-
if (!
|
|
50666
|
+
if (!wantsJson2(program2, opts)) {
|
|
50667
50667
|
const mode = opts.dryRun ? "would push" : "pushed";
|
|
50668
50668
|
console.log(chalk10.green(` ${target.name}: ${mode} ${formatBridgeImportSummary(push)}`));
|
|
50669
50669
|
}
|
|
@@ -50672,11 +50672,11 @@ Path diagnostics (${diagnostics.path_issues.length})`));
|
|
|
50672
50672
|
} catch (error) {
|
|
50673
50673
|
const message = error instanceof Error ? error.message : String(error);
|
|
50674
50674
|
results.push({ machine: target.name, error: message });
|
|
50675
|
-
if (!
|
|
50675
|
+
if (!wantsJson2(program2, opts))
|
|
50676
50676
|
console.log(chalk10.yellow(` ${target.name}: sync failed: ${message}`));
|
|
50677
50677
|
}
|
|
50678
50678
|
}
|
|
50679
|
-
if (
|
|
50679
|
+
if (wantsJson2(program2, opts)) {
|
|
50680
50680
|
console.log(JSON.stringify({
|
|
50681
50681
|
dry_run: Boolean(opts.dryRun),
|
|
50682
50682
|
pushed: Boolean(opts.push),
|
|
@@ -58676,7 +58676,7 @@ var init_help_commands = __esm(() => {
|
|
|
58676
58676
|
// src/cli/index.tsx
|
|
58677
58677
|
init_esm();
|
|
58678
58678
|
|
|
58679
|
-
// node_modules/.bun/@hasna+events@0.1.
|
|
58679
|
+
// node_modules/.bun/@hasna+events@0.1.7/node_modules/@hasna/events/dist/commander.js
|
|
58680
58680
|
import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
58681
58681
|
import { existsSync } from "fs";
|
|
58682
58682
|
import { homedir } from "os";
|
|
@@ -59239,9 +59239,15 @@ function print(value, json, text) {
|
|
|
59239
59239
|
else
|
|
59240
59240
|
console.log(text);
|
|
59241
59241
|
}
|
|
59242
|
+
function hasJsonOption(options) {
|
|
59243
|
+
return Boolean(options?.json || options?.opts?.().json || options?.optsWithGlobals?.().json || options?.parent?.opts?.().json || options?.parent?.optsWithGlobals?.().json);
|
|
59244
|
+
}
|
|
59245
|
+
function wantsJson(actionOptions, command) {
|
|
59246
|
+
return hasJsonOption(actionOptions) || hasJsonOption(command);
|
|
59247
|
+
}
|
|
59242
59248
|
function registerWebhookCommands(program2, options) {
|
|
59243
59249
|
const webhooks = program2.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
|
|
59244
|
-
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions) => {
|
|
59250
|
+
webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
|
|
59245
59251
|
const timestamp = new Date().toISOString();
|
|
59246
59252
|
const channel = {
|
|
59247
59253
|
id: actionOptions.id,
|
|
@@ -59262,11 +59268,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
59262
59268
|
throw new Error(`Transport ${actionOptions.transport} is reserved for future use and cannot be added yet`);
|
|
59263
59269
|
}
|
|
59264
59270
|
const saved = await createClient(options).addChannel(channel);
|
|
59265
|
-
print(sanitizeChannelForOutput(saved),
|
|
59271
|
+
print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
|
|
59266
59272
|
});
|
|
59267
|
-
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
59273
|
+
webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
59268
59274
|
const channels = await createClient(options).listChannels();
|
|
59269
|
-
if (actionOptions
|
|
59275
|
+
if (wantsJson(actionOptions, command)) {
|
|
59270
59276
|
console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
|
|
59271
59277
|
return;
|
|
59272
59278
|
}
|
|
@@ -59278,11 +59284,11 @@ function registerWebhookCommands(program2, options) {
|
|
|
59278
59284
|
console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
|
|
59279
59285
|
}
|
|
59280
59286
|
});
|
|
59281
|
-
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
59287
|
+
webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
59282
59288
|
const removed = await createClient(options).removeChannel(id);
|
|
59283
|
-
print({ removed },
|
|
59289
|
+
print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
|
|
59284
59290
|
});
|
|
59285
|
-
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions) => {
|
|
59291
|
+
webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
|
|
59286
59292
|
const result = await createClient(options).testChannel(id, {
|
|
59287
59293
|
source: options.source,
|
|
59288
59294
|
type: actionOptions.type,
|
|
@@ -59290,13 +59296,13 @@ function registerWebhookCommands(program2, options) {
|
|
|
59290
59296
|
message: actionOptions.message,
|
|
59291
59297
|
data: parseJsonObject(actionOptions.data, { test: true })
|
|
59292
59298
|
});
|
|
59293
|
-
print(result,
|
|
59299
|
+
print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
|
|
59294
59300
|
});
|
|
59295
59301
|
return webhooks;
|
|
59296
59302
|
}
|
|
59297
59303
|
function registerEventCommands(program2, options) {
|
|
59298
59304
|
const events = program2.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
|
|
59299
|
-
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions) => {
|
|
59305
|
+
events.command("emit").description("Emit an event from this app").argument("<type>", "Event type").option("--source <source>", "Event source override").option("--subject <subject>", "Event subject").option("--severity <severity>", "Event severity", "info").option("--message <message>", "Event message").option("--dedupe-key <key>", "Dedupe key").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--no-deliver", "Record without delivering").option("--no-dedupe", "Allow duplicate id/dedupeKey events").option("-j, --json", "Print JSON output", false).action(async (type, actionOptions, command) => {
|
|
59300
59306
|
const result = await createClient(options).emit({
|
|
59301
59307
|
source: actionOptions.source ?? options.source,
|
|
59302
59308
|
type,
|
|
@@ -59307,9 +59313,9 @@ function registerEventCommands(program2, options) {
|
|
|
59307
59313
|
data: parseJsonObject(actionOptions.data, {}),
|
|
59308
59314
|
metadata: parseJsonObject(actionOptions.metadata, {})
|
|
59309
59315
|
}, { deliver: actionOptions.deliver, dedupe: actionOptions.dedupe });
|
|
59310
|
-
print(result,
|
|
59316
|
+
print(result, wantsJson(actionOptions, command), `${result.deduped ? "Deduped" : "Emitted"} ${result.event.id} to ${result.deliveries.length} channel(s)`);
|
|
59311
59317
|
});
|
|
59312
|
-
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
59318
|
+
events.command("list").description("List recorded events").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--limit <n>", "Limit results", parseNumber).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
59313
59319
|
let rows = await createClient(options).listEvents();
|
|
59314
59320
|
if (actionOptions.source)
|
|
59315
59321
|
rows = rows.filter((event) => event.source === actionOptions.source);
|
|
@@ -59317,7 +59323,7 @@ function registerEventCommands(program2, options) {
|
|
|
59317
59323
|
rows = rows.filter((event) => event.type === actionOptions.type);
|
|
59318
59324
|
if (actionOptions.limit)
|
|
59319
59325
|
rows = rows.slice(-actionOptions.limit);
|
|
59320
|
-
if (actionOptions
|
|
59326
|
+
if (wantsJson(actionOptions, command)) {
|
|
59321
59327
|
console.log(JSON.stringify(rows, null, 2));
|
|
59322
59328
|
return;
|
|
59323
59329
|
}
|
|
@@ -59328,14 +59334,14 @@ function registerEventCommands(program2, options) {
|
|
|
59328
59334
|
for (const event of rows)
|
|
59329
59335
|
console.log(`${event.time} ${event.id} ${event.source} ${event.type} ${event.severity}`);
|
|
59330
59336
|
});
|
|
59331
|
-
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions) => {
|
|
59337
|
+
events.command("replay").description("Replay recorded events").option("--id <id>", "Replay one event id").option("--source <source>", "Filter by source").option("--type <type>", "Filter by type").option("--dry-run", "Preview without delivery", false).option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
|
|
59332
59338
|
const result = await createClient(options).replay({
|
|
59333
59339
|
eventId: actionOptions.id,
|
|
59334
59340
|
source: actionOptions.source,
|
|
59335
59341
|
type: actionOptions.type,
|
|
59336
59342
|
dryRun: actionOptions.dryRun
|
|
59337
59343
|
});
|
|
59338
|
-
print(result,
|
|
59344
|
+
print(result, wantsJson(actionOptions, command), `Replayed ${result.events.length} event(s), ${result.deliveries.length} delivery result(s)`);
|
|
59339
59345
|
});
|
|
59340
59346
|
return events;
|
|
59341
59347
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"packageName": "@hasna/todos",
|
|
3
|
-
"packageVersion": "0.11.
|
|
3
|
+
"packageVersion": "0.11.55",
|
|
4
4
|
"repository": "https://github.com/hasna/todos.git",
|
|
5
|
-
"gitCommit": "
|
|
6
|
-
"generatedAt": "2026-06-
|
|
5
|
+
"gitCommit": "00b566276db208cd222e9232ce2ff9fa20f9cba2",
|
|
6
|
+
"generatedAt": "2026-06-16T11:14:19.914Z"
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/todos",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.55",
|
|
4
4
|
"description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"author": "Andrei Hasna <andrei@hasna.com>",
|
|
90
90
|
"license": "Apache-2.0",
|
|
91
91
|
"dependencies": {
|
|
92
|
-
"@hasna/events": "^0.1.
|
|
92
|
+
"@hasna/events": "^0.1.7",
|
|
93
93
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
94
94
|
"chalk": "^5.4.1",
|
|
95
95
|
"commander": "^13.1.0",
|