@fukuchang/taskchute-cli 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +44 -10
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -217,14 +217,14 @@ async function deriveKEK(password4, salt, params = DEFAULT_ARGON2ID_PARAMS) {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
// ../crypto/src/wrap.ts
|
|
220
|
-
async function unwrapMasterKey(wrapped, iv, kek) {
|
|
220
|
+
async function unwrapMasterKey(wrapped, iv, kek, options = {}) {
|
|
221
221
|
return crypto.subtle.unwrapKey(
|
|
222
222
|
"raw",
|
|
223
223
|
wrapped,
|
|
224
224
|
kek,
|
|
225
225
|
{ name: "AES-GCM", iv },
|
|
226
226
|
{ name: "AES-GCM", length: 256 },
|
|
227
|
-
false,
|
|
227
|
+
options.extractable ?? false,
|
|
228
228
|
["encrypt", "decrypt"]
|
|
229
229
|
);
|
|
230
230
|
}
|
|
@@ -510,6 +510,7 @@ async function rowToContext(row, cryptoSession) {
|
|
|
510
510
|
id: row.id,
|
|
511
511
|
name,
|
|
512
512
|
status: row.status,
|
|
513
|
+
notifyAtScheduledStart: row.notify_at_scheduled_start,
|
|
513
514
|
createdAt: new Date(row.created_at),
|
|
514
515
|
updatedAt: new Date(row.updated_at)
|
|
515
516
|
};
|
|
@@ -523,6 +524,9 @@ function nonEncryptedFieldsToRow(input2) {
|
|
|
523
524
|
if ("icon" in input2) row.icon = input2.icon ?? null;
|
|
524
525
|
if ("color" in input2) row.color = input2.color ?? null;
|
|
525
526
|
if ("status" in input2 && input2.status !== void 0) row.status = input2.status;
|
|
527
|
+
if ("notifyAtScheduledStart" in input2 && input2.notifyAtScheduledStart !== void 0) {
|
|
528
|
+
row.notify_at_scheduled_start = input2.notifyAtScheduledStart;
|
|
529
|
+
}
|
|
526
530
|
return row;
|
|
527
531
|
}
|
|
528
532
|
async function encryptContextFieldsInto(row, entityId, patch, cryptoSession) {
|
|
@@ -2209,6 +2213,14 @@ function pickPropagationTargets(routine, tasks, today) {
|
|
|
2209
2213
|
);
|
|
2210
2214
|
}
|
|
2211
2215
|
|
|
2216
|
+
// ../domain/src/context-task-inheritance.ts
|
|
2217
|
+
function applyContextNotificationInheritance(input2, context) {
|
|
2218
|
+
if (context?.notifyAtScheduledStart !== true) return input2;
|
|
2219
|
+
const current = input2.notifyAtScheduledStart;
|
|
2220
|
+
if (current !== void 0) return input2;
|
|
2221
|
+
return { ...input2, notifyAtScheduledStart: true };
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2212
2224
|
// ../infra-supabase/src/audit-task-repository.ts
|
|
2213
2225
|
var AuditingTaskRepository = class {
|
|
2214
2226
|
// `erasableSyntaxOnly` 配下では parameter property が使えないので、明示的に
|
|
@@ -2460,12 +2472,16 @@ function contextsArchiveCommand() {
|
|
|
2460
2472
|
});
|
|
2461
2473
|
}
|
|
2462
2474
|
function contextsCreateCommand() {
|
|
2463
|
-
return new Command("create").description("\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B").argument("<name>", "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u540D").option("--description <text>", "\u8A73\u7D30\u8AAC\u660E").option("--icon <icon>", "\u7D75\u6587\u5B57\u307E\u305F\u306F\u30A2\u30A4\u30B3\u30F3\u540D (\u4F8B: \u{1F3E0})").option("--color <color>", "UI \u8272").
|
|
2475
|
+
return new Command("create").description("\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u65B0\u898F\u4F5C\u6210\u3059\u308B").argument("<name>", "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u540D").option("--description <text>", "\u8A73\u7D30\u8AAC\u660E").option("--icon <icon>", "\u7D75\u6587\u5B57\u307E\u305F\u306F\u30A2\u30A4\u30B3\u30F3\u540D (\u4F8B: \u{1F3E0})").option("--color <color>", "UI \u8272").option(
|
|
2476
|
+
"--notify-at-start",
|
|
2477
|
+
"\u3053\u306E\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u4ED8\u3051\u308B\u65B0\u898F/\u66F4\u65B0\u30BF\u30B9\u30AF\u306E\u901A\u77E5\u3092 ON \u306B\u81EA\u52D5\u7D99\u627F\u3059\u308B"
|
|
2478
|
+
).action(async (name, opts) => {
|
|
2464
2479
|
const ctx = await createAppContext();
|
|
2465
2480
|
const input2 = { name, status: "active" };
|
|
2466
2481
|
if (opts.description !== void 0) input2.description = opts.description;
|
|
2467
2482
|
if (opts.icon !== void 0) input2.icon = opts.icon;
|
|
2468
2483
|
if (opts.color !== void 0) input2.color = opts.color;
|
|
2484
|
+
if (opts.notifyAtStart !== void 0) input2.notifyAtScheduledStart = opts.notifyAtStart;
|
|
2469
2485
|
const context = await ctx.repos.context.create(input2);
|
|
2470
2486
|
console.log(`\u2713 Created context: ${shortenId(context.id)} ${context.name}`);
|
|
2471
2487
|
});
|
|
@@ -2488,7 +2504,8 @@ function formatContextRow(context) {
|
|
|
2488
2504
|
name: context.name,
|
|
2489
2505
|
status: context.status,
|
|
2490
2506
|
icon: context.icon ?? "-",
|
|
2491
|
-
color: context.color ?? "-"
|
|
2507
|
+
color: context.color ?? "-",
|
|
2508
|
+
notify_at_start: context.notifyAtScheduledStart ? "\u2713" : "-"
|
|
2492
2509
|
};
|
|
2493
2510
|
}
|
|
2494
2511
|
|
|
@@ -2506,7 +2523,10 @@ function contextsListCommand() {
|
|
|
2506
2523
|
});
|
|
2507
2524
|
}
|
|
2508
2525
|
function contextsUpdateCommand() {
|
|
2509
|
-
return new Command("update").description("\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u90E8\u5206\u66F4\u65B0\u3059\u308B").argument("<id-prefix>", "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8 id \u306E\u5148\u982D 4 \u6587\u5B57\u4EE5\u4E0A").option("--name <text>", "\u540D\u524D\u5909\u66F4").option("--description <text>", "\u8A73\u7D30\u8AAC\u660E").option("--clear-description", "\u8A73\u7D30\u8AAC\u660E\u3092\u7A7A\u306B\u3059\u308B").option("--icon <icon>", "\u7D75\u6587\u5B57\u307E\u305F\u306F\u30A2\u30A4\u30B3\u30F3\u540D").option("--clear-icon", "\u30A2\u30A4\u30B3\u30F3\u3092\u5916\u3059").option("--color <color>", "UI \u8272").option("--clear-color", "\u8272\u3092\u5916\u3059").
|
|
2526
|
+
return new Command("update").description("\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u90E8\u5206\u66F4\u65B0\u3059\u308B").argument("<id-prefix>", "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8 id \u306E\u5148\u982D 4 \u6587\u5B57\u4EE5\u4E0A").option("--name <text>", "\u540D\u524D\u5909\u66F4").option("--description <text>", "\u8A73\u7D30\u8AAC\u660E").option("--clear-description", "\u8A73\u7D30\u8AAC\u660E\u3092\u7A7A\u306B\u3059\u308B").option("--icon <icon>", "\u7D75\u6587\u5B57\u307E\u305F\u306F\u30A2\u30A4\u30B3\u30F3\u540D").option("--clear-icon", "\u30A2\u30A4\u30B3\u30F3\u3092\u5916\u3059").option("--color <color>", "UI \u8272").option("--clear-color", "\u8272\u3092\u5916\u3059").option(
|
|
2527
|
+
"--notify-at-start",
|
|
2528
|
+
"\u3053\u306E\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u3092\u4ED8\u3051\u308B\u65B0\u898F/\u66F4\u65B0\u30BF\u30B9\u30AF\u306E\u901A\u77E5\u3092 ON \u7D99\u627F\u3059\u308B"
|
|
2529
|
+
).option("--no-notify-at-start", "\u30B3\u30F3\u30C6\u30AD\u30B9\u30C8\u306E\u901A\u77E5\u7D99\u627F\u3092 OFF \u306B\u3059\u308B").action(async (prefix, opts) => {
|
|
2510
2530
|
const ctx = await createAppContext();
|
|
2511
2531
|
const all = await ctx.repos.context.findAll();
|
|
2512
2532
|
const id = resolveResourceIdByPrefix(all, prefix, "context");
|
|
@@ -2518,9 +2538,12 @@ function contextsUpdateCommand() {
|
|
|
2518
2538
|
else if (opts.icon !== void 0) patch.icon = opts.icon;
|
|
2519
2539
|
if (opts.clearColor) patch.color = void 0;
|
|
2520
2540
|
else if (opts.color !== void 0) patch.color = opts.color;
|
|
2541
|
+
if (opts.notifyAtStart !== void 0) {
|
|
2542
|
+
patch.notifyAtScheduledStart = opts.notifyAtStart;
|
|
2543
|
+
}
|
|
2521
2544
|
if (Object.keys(patch).length === 0) {
|
|
2522
2545
|
throw new CliError(
|
|
2523
|
-
"No field to update. Specify at least one of --name / --description / --icon / --color / --clear-*."
|
|
2546
|
+
"No field to update. Specify at least one of --name / --description / --icon / --color / --notify-at-start / --clear-*."
|
|
2524
2547
|
);
|
|
2525
2548
|
}
|
|
2526
2549
|
const updated = await ctx.repos.context.update(id, patch);
|
|
@@ -2951,9 +2974,11 @@ function routinesUpdateCommand() {
|
|
|
2951
2974
|
);
|
|
2952
2975
|
}
|
|
2953
2976
|
const taskPatch = buildRoutineTaskPatch(updated);
|
|
2977
|
+
const routineContext = updated.contextId ? await ctx.repos.context.findById(updated.contextId) : null;
|
|
2978
|
+
const propagatedPatch = applyContextNotificationInheritance(taskPatch, routineContext);
|
|
2954
2979
|
await Promise.all(
|
|
2955
2980
|
targets.map(
|
|
2956
|
-
(task) => auditingTask.updateWithCause(task.id,
|
|
2981
|
+
(task) => auditingTask.updateWithCause(task.id, propagatedPatch, "routine-propagation")
|
|
2957
2982
|
)
|
|
2958
2983
|
);
|
|
2959
2984
|
propagated = targets.length;
|
|
@@ -3060,9 +3085,11 @@ function tasksAddCommand() {
|
|
|
3060
3085
|
projectId = resolveResourceIdByPrefix(all, opts.project, "project");
|
|
3061
3086
|
}
|
|
3062
3087
|
let contextId;
|
|
3088
|
+
let context = null;
|
|
3063
3089
|
if (opts.context !== void 0) {
|
|
3064
3090
|
const all = await ctx.repos.context.findAll();
|
|
3065
3091
|
contextId = resolveResourceIdByPrefix(all, opts.context, "context");
|
|
3092
|
+
context = all.find((c) => c.id === contextId) ?? null;
|
|
3066
3093
|
}
|
|
3067
3094
|
const tagIds = [];
|
|
3068
3095
|
if (opts.tag !== void 0 && opts.tag.length > 0) {
|
|
@@ -3076,7 +3103,7 @@ function tasksAddCommand() {
|
|
|
3076
3103
|
}
|
|
3077
3104
|
const existing = await ctx.repos.task.findByDate(date);
|
|
3078
3105
|
const orderIndex = computeNextOrderIndex(existing);
|
|
3079
|
-
const
|
|
3106
|
+
const createInput = {
|
|
3080
3107
|
date,
|
|
3081
3108
|
title,
|
|
3082
3109
|
description: opts.description,
|
|
@@ -3090,7 +3117,10 @@ function tasksAddCommand() {
|
|
|
3090
3117
|
scheduledStartTime: opts.scheduled,
|
|
3091
3118
|
notifyAtScheduledStart: opts.notify,
|
|
3092
3119
|
isBackground: opts.background
|
|
3093
|
-
}
|
|
3120
|
+
};
|
|
3121
|
+
const task = await ctx.repos.task.create(
|
|
3122
|
+
applyContextNotificationInheritance(createInput, context)
|
|
3123
|
+
);
|
|
3094
3124
|
console.log(`\u2713 Created: ${shortenId(task.id)} ${task.title}`);
|
|
3095
3125
|
});
|
|
3096
3126
|
}
|
|
@@ -3437,6 +3467,10 @@ function tasksUpdateCommand() {
|
|
|
3437
3467
|
const tasks = await ctx.repos.task.findByDate(date);
|
|
3438
3468
|
const taskId = resolveTaskIdByPrefix(tasks, prefix);
|
|
3439
3469
|
const patch = await buildPatch(ctx, opts);
|
|
3470
|
+
if (patch.contextId) {
|
|
3471
|
+
const newContext = await ctx.repos.context.findById(patch.contextId);
|
|
3472
|
+
Object.assign(patch, applyContextNotificationInheritance(patch, newContext));
|
|
3473
|
+
}
|
|
3440
3474
|
const updated = await ctx.repos.task.update(taskId, patch);
|
|
3441
3475
|
console.log(`\u270E Updated: ${shortenId(updated.id)} ${updated.title}`);
|
|
3442
3476
|
});
|
|
@@ -3690,7 +3724,7 @@ function whoamiCommand() {
|
|
|
3690
3724
|
|
|
3691
3725
|
// src/index.ts
|
|
3692
3726
|
var program = new Command();
|
|
3693
|
-
program.name("taskchute").description("TaskChute CLI \u2014 CLI/MCP \u304B\u3089 TaskChute \u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u305F\u3081\u306E\u30A8\u30F3\u30C8\u30EA\u30DD\u30A4\u30F3\u30C8").version("0.
|
|
3727
|
+
program.name("taskchute").description("TaskChute CLI \u2014 CLI/MCP \u304B\u3089 TaskChute \u306B\u30A2\u30AF\u30BB\u30B9\u3059\u308B\u305F\u3081\u306E\u30A8\u30F3\u30C8\u30EA\u30DD\u30A4\u30F3\u30C8").version("0.4.0" );
|
|
3694
3728
|
program.addCommand(loginCommand());
|
|
3695
3729
|
program.addCommand(whoamiCommand());
|
|
3696
3730
|
program.addCommand(logoutCommand());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fukuchang/taskchute-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "TaskChute CLI — E2EE 暗号化された TaskChute タスクをターミナルから操作するための CLI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "fukuchang",
|
|
@@ -50,9 +50,9 @@
|
|
|
50
50
|
"tsup": "^8.5.1",
|
|
51
51
|
"tsx": "^4.20.0",
|
|
52
52
|
"typescript": "~6.0.2",
|
|
53
|
-
"@taskchute/crypto": "0.0.0",
|
|
54
53
|
"@taskchute/domain": "0.0.0",
|
|
55
54
|
"@taskchute/infra-supabase": "0.0.0",
|
|
55
|
+
"@taskchute/crypto": "0.0.0",
|
|
56
56
|
"@taskchute/node-shared": "0.0.0"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|