@vibetasks/cli 0.4.6 → 0.5.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/bin/vibetasks.js +615 -21
- package/package.json +3 -3
package/dist/bin/vibetasks.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
} from "../chunk-2KRLRG4G.js";
|
|
12
12
|
|
|
13
13
|
// bin/vibetasks.ts
|
|
14
|
-
import { Command as
|
|
14
|
+
import { Command as Command18 } from "commander";
|
|
15
15
|
import { createRequire } from "module";
|
|
16
16
|
|
|
17
17
|
// src/commands/login.ts
|
|
@@ -48,8 +48,17 @@ ${url}
|
|
|
48
48
|
`));
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
+
function getAuthBaseUrl() {
|
|
52
|
+
if (process.env.VIBETASKS_AUTH_URL) {
|
|
53
|
+
return process.env.VIBETASKS_AUTH_URL;
|
|
54
|
+
}
|
|
55
|
+
if (process.env.TASKFLOW_WEB_PORT) {
|
|
56
|
+
return `http://localhost:${process.env.TASKFLOW_WEB_PORT}`;
|
|
57
|
+
}
|
|
58
|
+
return "https://vibetasks.dev";
|
|
59
|
+
}
|
|
51
60
|
async function loginWithBrowser() {
|
|
52
|
-
console.log(chalk.blue.bold("\n\u{1F510}
|
|
61
|
+
console.log(chalk.blue.bold("\n\u{1F510} VibeTasks Browser Login\n"));
|
|
53
62
|
const spinner = ora("Starting local server...").start();
|
|
54
63
|
const port = await getAvailablePort();
|
|
55
64
|
return new Promise((resolve, reject) => {
|
|
@@ -247,12 +256,12 @@ async function loginWithBrowser() {
|
|
|
247
256
|
<h1>Authentication Successful!</h1>
|
|
248
257
|
<p class="email">${email}</p>
|
|
249
258
|
<p class="message">
|
|
250
|
-
Your
|
|
259
|
+
Your VibeTasks CLI is now connected to your account.<br>
|
|
251
260
|
You can close this window and return to your terminal.
|
|
252
261
|
</p>
|
|
253
262
|
<div class="success-badge">Ready to use</div>
|
|
254
263
|
<div class="button-group">
|
|
255
|
-
<a href="
|
|
264
|
+
<a href="https://vibetasks.dev/dashboard" class="button button-primary">Go to Dashboard</a>
|
|
256
265
|
<button onclick="window.close()" class="button button-secondary">Close Window</button>
|
|
257
266
|
</div>
|
|
258
267
|
</div>
|
|
@@ -263,7 +272,7 @@ async function loginWithBrowser() {
|
|
|
263
272
|
console.log(chalk.gray(`
|
|
264
273
|
Logged in as: ${email}`));
|
|
265
274
|
console.log(chalk.gray(`Tokens stored in: ${storageLocation}`));
|
|
266
|
-
console.log(chalk.blue.bold("\n\u2728 You can now use
|
|
275
|
+
console.log(chalk.blue.bold("\n\u2728 You can now use VibeTasks CLI commands\n"));
|
|
267
276
|
if (timeoutId) clearTimeout(timeoutId);
|
|
268
277
|
resolve();
|
|
269
278
|
server.close(() => {
|
|
@@ -308,11 +317,13 @@ Error: ${error.message}`));
|
|
|
308
317
|
});
|
|
309
318
|
server.listen(port, async () => {
|
|
310
319
|
spinner.text = "Opening browser...";
|
|
311
|
-
const
|
|
312
|
-
const authUrl =
|
|
320
|
+
const baseUrl = getAuthBaseUrl();
|
|
321
|
+
const authUrl = `${baseUrl}/cli-auth?port=${port}`;
|
|
313
322
|
spinner.text = "Waiting for authentication in browser...";
|
|
314
323
|
console.log(chalk.gray(`
|
|
315
|
-
|
|
324
|
+
Opening: ${authUrl}`));
|
|
325
|
+
console.log(chalk.gray(`
|
|
326
|
+
If browser doesn't open, visit the URL above.
|
|
316
327
|
`));
|
|
317
328
|
await openBrowser(authUrl);
|
|
318
329
|
});
|
|
@@ -474,7 +485,227 @@ function parseDate(dateStr) {
|
|
|
474
485
|
|
|
475
486
|
// src/commands/add.ts
|
|
476
487
|
import { detectProject } from "@vibetasks/shared/utils/project-detector";
|
|
477
|
-
|
|
488
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
489
|
+
|
|
490
|
+
// src/utils/session-manager.ts
|
|
491
|
+
import { writeFile, readFile, mkdir } from "fs/promises";
|
|
492
|
+
import { join } from "path";
|
|
493
|
+
import { homedir } from "os";
|
|
494
|
+
import { randomUUID } from "crypto";
|
|
495
|
+
var ADJECTIVES = [
|
|
496
|
+
"swift",
|
|
497
|
+
"calm",
|
|
498
|
+
"bold",
|
|
499
|
+
"warm",
|
|
500
|
+
"cool",
|
|
501
|
+
"bright",
|
|
502
|
+
"dark",
|
|
503
|
+
"quick",
|
|
504
|
+
"slow",
|
|
505
|
+
"wise",
|
|
506
|
+
"keen",
|
|
507
|
+
"soft",
|
|
508
|
+
"loud",
|
|
509
|
+
"deep",
|
|
510
|
+
"high",
|
|
511
|
+
"low"
|
|
512
|
+
];
|
|
513
|
+
var NOUNS = [
|
|
514
|
+
"fox",
|
|
515
|
+
"owl",
|
|
516
|
+
"bear",
|
|
517
|
+
"wolf",
|
|
518
|
+
"hawk",
|
|
519
|
+
"moon",
|
|
520
|
+
"star",
|
|
521
|
+
"sun",
|
|
522
|
+
"tree",
|
|
523
|
+
"wave",
|
|
524
|
+
"wind",
|
|
525
|
+
"fire",
|
|
526
|
+
"snow",
|
|
527
|
+
"rain",
|
|
528
|
+
"leaf",
|
|
529
|
+
"stone"
|
|
530
|
+
];
|
|
531
|
+
var SessionManager = class {
|
|
532
|
+
storePath;
|
|
533
|
+
store = null;
|
|
534
|
+
constructor() {
|
|
535
|
+
this.storePath = join(homedir(), ".vibetasks", "sessions.json");
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Generate a memorable session ID like "swift-fox-42"
|
|
539
|
+
*/
|
|
540
|
+
generateSessionId() {
|
|
541
|
+
const adj = ADJECTIVES[Math.floor(Math.random() * ADJECTIVES.length)];
|
|
542
|
+
const noun = NOUNS[Math.floor(Math.random() * NOUNS.length)];
|
|
543
|
+
const num = Math.floor(Math.random() * 100);
|
|
544
|
+
return `${adj}-${noun}-${num}`;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Load sessions from disk
|
|
548
|
+
*/
|
|
549
|
+
async load() {
|
|
550
|
+
if (this.store) return this.store;
|
|
551
|
+
try {
|
|
552
|
+
const data = await readFile(this.storePath, "utf-8");
|
|
553
|
+
this.store = JSON.parse(data);
|
|
554
|
+
return this.store;
|
|
555
|
+
} catch {
|
|
556
|
+
this.store = { sessions: [] };
|
|
557
|
+
return this.store;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Save sessions to disk
|
|
562
|
+
*/
|
|
563
|
+
async save() {
|
|
564
|
+
const dir = join(homedir(), ".vibetasks");
|
|
565
|
+
await mkdir(dir, { recursive: true });
|
|
566
|
+
await writeFile(this.storePath, JSON.stringify(this.store, null, 2));
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Start a new session
|
|
570
|
+
*/
|
|
571
|
+
async startSession(project) {
|
|
572
|
+
const store = await this.load();
|
|
573
|
+
if (store.currentSession) {
|
|
574
|
+
await this.endSession();
|
|
575
|
+
}
|
|
576
|
+
const session = {
|
|
577
|
+
id: this.generateSessionId(),
|
|
578
|
+
fullId: randomUUID(),
|
|
579
|
+
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
580
|
+
project,
|
|
581
|
+
actions: []
|
|
582
|
+
};
|
|
583
|
+
store.sessions.push(session);
|
|
584
|
+
store.currentSession = session.id;
|
|
585
|
+
await this.save();
|
|
586
|
+
return session;
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Get current session (or start one if none exists)
|
|
590
|
+
*/
|
|
591
|
+
async getCurrentSession() {
|
|
592
|
+
const store = await this.load();
|
|
593
|
+
if (!store.currentSession) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
return store.sessions.find((s) => s.id === store.currentSession) || null;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Get or create current session
|
|
600
|
+
*/
|
|
601
|
+
async getOrCreateSession(project) {
|
|
602
|
+
const current = await this.getCurrentSession();
|
|
603
|
+
if (current) return current;
|
|
604
|
+
return this.startSession(project);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Log an action in the current session
|
|
608
|
+
*/
|
|
609
|
+
async logAction(action) {
|
|
610
|
+
const store = await this.load();
|
|
611
|
+
const session = store.sessions.find((s) => s.id === store.currentSession);
|
|
612
|
+
if (!session) {
|
|
613
|
+
const newSession = await this.startSession();
|
|
614
|
+
newSession.actions.push({
|
|
615
|
+
...action,
|
|
616
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
617
|
+
});
|
|
618
|
+
} else {
|
|
619
|
+
session.actions.push({
|
|
620
|
+
...action,
|
|
621
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
await this.save();
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* End the current session
|
|
628
|
+
*/
|
|
629
|
+
async endSession(summary) {
|
|
630
|
+
const store = await this.load();
|
|
631
|
+
const session = store.sessions.find((s) => s.id === store.currentSession);
|
|
632
|
+
if (session) {
|
|
633
|
+
session.endedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
634
|
+
session.summary = summary;
|
|
635
|
+
store.currentSession = void 0;
|
|
636
|
+
await this.save();
|
|
637
|
+
}
|
|
638
|
+
return session || null;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Get a session by ID (partial match supported)
|
|
642
|
+
*/
|
|
643
|
+
async getSession(id) {
|
|
644
|
+
const store = await this.load();
|
|
645
|
+
let session = store.sessions.find((s) => s.id === id);
|
|
646
|
+
if (session) return session;
|
|
647
|
+
session = store.sessions.find((s) => s.id.includes(id) || s.fullId.startsWith(id));
|
|
648
|
+
return session || null;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Get recent sessions
|
|
652
|
+
*/
|
|
653
|
+
async getRecentSessions(limit = 10) {
|
|
654
|
+
const store = await this.load();
|
|
655
|
+
return store.sessions.slice(-limit).reverse();
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Get session summary for handoff to next AI
|
|
659
|
+
*/
|
|
660
|
+
async getSessionHandoff(sessionId) {
|
|
661
|
+
const session = await this.getSession(sessionId);
|
|
662
|
+
if (!session) {
|
|
663
|
+
return `Session "${sessionId}" not found.`;
|
|
664
|
+
}
|
|
665
|
+
const lines = [
|
|
666
|
+
`## Session: ${session.id}`,
|
|
667
|
+
`Started: ${session.startedAt}`,
|
|
668
|
+
session.endedAt ? `Ended: ${session.endedAt}` : `Status: ACTIVE`,
|
|
669
|
+
session.project ? `Project: ${session.project}` : "",
|
|
670
|
+
"",
|
|
671
|
+
`### Actions (${session.actions.length}):`
|
|
672
|
+
];
|
|
673
|
+
for (const action of session.actions) {
|
|
674
|
+
const time = new Date(action.timestamp).toLocaleTimeString();
|
|
675
|
+
switch (action.type) {
|
|
676
|
+
case "task_created":
|
|
677
|
+
lines.push(`- [${time}] Created task: "${action.taskTitle}" (${action.taskId})`);
|
|
678
|
+
break;
|
|
679
|
+
case "task_completed":
|
|
680
|
+
lines.push(`- [${time}] Completed: "${action.taskTitle}"`);
|
|
681
|
+
break;
|
|
682
|
+
case "task_updated":
|
|
683
|
+
lines.push(`- [${time}] Updated: "${action.taskTitle}"`);
|
|
684
|
+
break;
|
|
685
|
+
case "file_modified":
|
|
686
|
+
lines.push(`- [${time}] Modified: ${action.filePath}`);
|
|
687
|
+
break;
|
|
688
|
+
case "note":
|
|
689
|
+
lines.push(`- [${time}] Note: ${action.description}`);
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (session.summary) {
|
|
694
|
+
lines.push("", "### Summary:", session.summary);
|
|
695
|
+
}
|
|
696
|
+
return lines.filter(Boolean).join("\n");
|
|
697
|
+
}
|
|
698
|
+
};
|
|
699
|
+
var sessionManager = null;
|
|
700
|
+
function getSessionManager() {
|
|
701
|
+
if (!sessionManager) {
|
|
702
|
+
sessionManager = new SessionManager();
|
|
703
|
+
}
|
|
704
|
+
return sessionManager;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
// src/commands/add.ts
|
|
708
|
+
var addCommand = new Command2("add").description("Add a new task").argument("<title>", "Task title").option("-n, --notes <notes>", "Task notes (markdown supported)").option("-d, --due <date>", 'Due date (YYYY-MM-DD, "today", "tomorrow", "+3d")').option("-p, --priority <level>", "Priority: low, medium, high", "none").option("-t, --tags <tags...>", "Tags (space-separated)").option("-s, --subtasks <subtasks...>", "Subtasks (space-separated, use quotes for multi-word)").option("--project <name>", "Override auto-detected project").option("-e, --energy <level>", "Energy required: low, medium, high").action(async (title, options) => {
|
|
478
709
|
const spinner = ora3("Creating task...").start();
|
|
479
710
|
try {
|
|
480
711
|
const authManager = new AuthManager3();
|
|
@@ -512,6 +743,11 @@ var addCommand = new Command2("add").description("Add a new task").argument("<ti
|
|
|
512
743
|
throw new Error(`Invalid energy level. Must be one of: ${validEnergy.join(", ")}`);
|
|
513
744
|
}
|
|
514
745
|
}
|
|
746
|
+
const subtasksJson = options.subtasks?.map((subtaskTitle) => ({
|
|
747
|
+
id: randomUUID2(),
|
|
748
|
+
title: subtaskTitle,
|
|
749
|
+
done: false
|
|
750
|
+
})) || [];
|
|
515
751
|
const task = await taskOps.createTask({
|
|
516
752
|
title,
|
|
517
753
|
notes: options.notes,
|
|
@@ -524,7 +760,8 @@ var addCommand = new Command2("add").description("Add a new task").argument("<ti
|
|
|
524
760
|
// ai or human
|
|
525
761
|
status: createdBy === "ai" ? "vibing" : "todo",
|
|
526
762
|
// AI tasks start vibing
|
|
527
|
-
energy_required: options.energy
|
|
763
|
+
energy_required: options.energy,
|
|
764
|
+
subtasks_json: subtasksJson
|
|
528
765
|
});
|
|
529
766
|
if (options.tags && options.tags.length > 0) {
|
|
530
767
|
const tagIds = [];
|
|
@@ -535,6 +772,15 @@ var addCommand = new Command2("add").description("Add a new task").argument("<ti
|
|
|
535
772
|
await taskOps.linkTaskTags(task.id, tagIds);
|
|
536
773
|
}
|
|
537
774
|
spinner.succeed(chalk3.green("Task created!"));
|
|
775
|
+
if (createdBy === "ai") {
|
|
776
|
+
const sessionManager2 = getSessionManager();
|
|
777
|
+
await sessionManager2.logAction({
|
|
778
|
+
type: "task_created",
|
|
779
|
+
description: `Created task: "${title}"`,
|
|
780
|
+
taskId: task.id,
|
|
781
|
+
taskTitle: title
|
|
782
|
+
});
|
|
783
|
+
}
|
|
538
784
|
console.log();
|
|
539
785
|
if (projectTag) {
|
|
540
786
|
console.log(chalk3.gray(`\u{1F4C1} Project: ${chalk3.white(projectTag)}`));
|
|
@@ -566,6 +812,12 @@ var addCommand = new Command2("add").description("Add a new task").argument("<ti
|
|
|
566
812
|
if (options.tags && options.tags.length > 0) {
|
|
567
813
|
console.log(chalk3.magenta(`Tags: ${options.tags.join(", ")}`));
|
|
568
814
|
}
|
|
815
|
+
if (subtasksJson.length > 0) {
|
|
816
|
+
console.log(chalk3.cyan(`Subtasks: ${subtasksJson.length}`));
|
|
817
|
+
subtasksJson.forEach((st, i) => {
|
|
818
|
+
console.log(chalk3.gray(` ${i + 1}. ${st.title}`));
|
|
819
|
+
});
|
|
820
|
+
}
|
|
569
821
|
console.log();
|
|
570
822
|
process.exit(0);
|
|
571
823
|
} catch (error) {
|
|
@@ -590,7 +842,81 @@ import { Command as Command3 } from "commander";
|
|
|
590
842
|
import chalk4 from "chalk";
|
|
591
843
|
import Table from "cli-table3";
|
|
592
844
|
import { AuthManager as AuthManager4, TaskOperations as TaskOperations2 } from "@vibetasks/core";
|
|
593
|
-
|
|
845
|
+
|
|
846
|
+
// src/utils/short-ids.ts
|
|
847
|
+
import { writeFile as writeFile2, readFile as readFile2, mkdir as mkdir2 } from "fs/promises";
|
|
848
|
+
import { join as join2 } from "path";
|
|
849
|
+
import { homedir as homedir2 } from "os";
|
|
850
|
+
var ShortIdManager = class {
|
|
851
|
+
storePath;
|
|
852
|
+
maxIds = 99;
|
|
853
|
+
constructor() {
|
|
854
|
+
this.storePath = join2(homedir2(), ".vibetasks", "short-ids.json");
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Save mappings from a list of task IDs
|
|
858
|
+
* Short IDs are assigned 1, 2, 3... based on array order
|
|
859
|
+
*/
|
|
860
|
+
async saveMappings(taskIds) {
|
|
861
|
+
const mappings = taskIds.slice(0, this.maxIds).map((fullId, index) => ({
|
|
862
|
+
shortId: index + 1,
|
|
863
|
+
fullId,
|
|
864
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
865
|
+
}));
|
|
866
|
+
const store = {
|
|
867
|
+
mappings,
|
|
868
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
869
|
+
};
|
|
870
|
+
const dir = join2(homedir2(), ".vibetasks");
|
|
871
|
+
await mkdir2(dir, { recursive: true });
|
|
872
|
+
await writeFile2(this.storePath, JSON.stringify(store, null, 2));
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Get the full UUID for a short ID
|
|
876
|
+
*/
|
|
877
|
+
async getFullId(shortId) {
|
|
878
|
+
try {
|
|
879
|
+
const content = await readFile2(this.storePath, "utf-8");
|
|
880
|
+
const store = JSON.parse(content);
|
|
881
|
+
const mapping = store.mappings.find((m) => m.shortId === shortId);
|
|
882
|
+
return mapping?.fullId || null;
|
|
883
|
+
} catch {
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
/**
|
|
888
|
+
* Get the short ID for a full UUID (if it exists in current mappings)
|
|
889
|
+
*/
|
|
890
|
+
async getShortId(fullId) {
|
|
891
|
+
try {
|
|
892
|
+
const content = await readFile2(this.storePath, "utf-8");
|
|
893
|
+
const store = JSON.parse(content);
|
|
894
|
+
const mapping = store.mappings.find((m) => m.fullId === fullId);
|
|
895
|
+
return mapping?.shortId || null;
|
|
896
|
+
} catch {
|
|
897
|
+
return null;
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Resolve an ID that could be either short (1-99) or full UUID
|
|
902
|
+
*/
|
|
903
|
+
async resolveId(idOrShortId) {
|
|
904
|
+
const shortId = parseInt(idOrShortId, 10);
|
|
905
|
+
if (!isNaN(shortId) && shortId >= 1 && shortId <= this.maxIds) {
|
|
906
|
+
const fullId = await this.getFullId(shortId);
|
|
907
|
+
if (fullId) {
|
|
908
|
+
return fullId;
|
|
909
|
+
}
|
|
910
|
+
throw new Error(
|
|
911
|
+
`Short ID #${shortId} not found. Run 'vibetasks list --short-ids' first to generate mappings.`
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
return idOrShortId;
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
// src/commands/list.ts
|
|
919
|
+
var listCommand = new Command3("list").description("List tasks").argument("[filter]", "Filter: all, today, upcoming, completed", "all").option("-l, --limit <number>", "Maximum number of tasks to show", "50").option("--project <name>", "Filter by project tag").option("--created-by <source>", "Filter by creator: ai or human").option("--status <status>", "Filter by status: todo, vibing, done").option("--short-ids", "Show short numeric IDs (1-99) for easy reference").action(async (filter, options) => {
|
|
594
920
|
try {
|
|
595
921
|
const validFilters = ["all", "today", "upcoming", "completed"];
|
|
596
922
|
if (!validFilters.includes(filter)) {
|
|
@@ -634,8 +960,18 @@ ${filterMessages[filter] || "No tasks found"}.
|
|
|
634
960
|
}
|
|
635
961
|
const limit = parseInt(options.limit, 10);
|
|
636
962
|
const displayTasks = tasks.slice(0, limit);
|
|
963
|
+
const shortIdManager = new ShortIdManager();
|
|
964
|
+
if (options.shortIds) {
|
|
965
|
+
await shortIdManager.saveMappings(displayTasks.map((t) => t.id));
|
|
966
|
+
}
|
|
637
967
|
const table = new Table({
|
|
638
|
-
head: [
|
|
968
|
+
head: options.shortIds ? [
|
|
969
|
+
chalk4.cyan("#"),
|
|
970
|
+
chalk4.cyan("Status"),
|
|
971
|
+
chalk4.cyan("Title"),
|
|
972
|
+
chalk4.cyan("Progress"),
|
|
973
|
+
chalk4.cyan("Due")
|
|
974
|
+
] : [
|
|
639
975
|
chalk4.cyan("ID"),
|
|
640
976
|
chalk4.cyan("Status"),
|
|
641
977
|
chalk4.cyan("Title"),
|
|
@@ -643,10 +979,10 @@ ${filterMessages[filter] || "No tasks found"}.
|
|
|
643
979
|
chalk4.cyan("Priority"),
|
|
644
980
|
chalk4.cyan("Due")
|
|
645
981
|
],
|
|
646
|
-
colWidths: [10, 10, 35, 15, 10, 12],
|
|
982
|
+
colWidths: options.shortIds ? [5, 10, 40, 12, 12] : [10, 10, 35, 15, 10, 12],
|
|
647
983
|
wordWrap: true
|
|
648
984
|
});
|
|
649
|
-
displayTasks.forEach((task) => {
|
|
985
|
+
displayTasks.forEach((task, index) => {
|
|
650
986
|
const priorityColors = {
|
|
651
987
|
high: chalk4.red,
|
|
652
988
|
medium: chalk4.yellow,
|
|
@@ -665,6 +1001,7 @@ ${filterMessages[filter] || "No tasks found"}.
|
|
|
665
1001
|
};
|
|
666
1002
|
const priorityColor = priorityColors[task.priority || "none"];
|
|
667
1003
|
const statusColor = statusColors[task.status || "todo"];
|
|
1004
|
+
const shortId = chalk4.yellow.bold(`${index + 1}`);
|
|
668
1005
|
const id = task.id.substring(0, 8);
|
|
669
1006
|
const status = statusColor(`${statusEmojis[task.status || "todo"]} ${task.status || "todo"}`);
|
|
670
1007
|
const title = task.status === "done" ? chalk4.strikethrough(task.title) : task.title;
|
|
@@ -672,7 +1009,15 @@ ${filterMessages[filter] || "No tasks found"}.
|
|
|
672
1009
|
const project = task.project_tag ? chalk4.blue(task.project_tag) : chalk4.gray("-");
|
|
673
1010
|
const priority = priorityColor(task.priority || "none");
|
|
674
1011
|
const dueDate = task.due_date ? task.due_date.split("T")[0] : chalk4.gray("-");
|
|
675
|
-
|
|
1012
|
+
const subtasks = task.subtasks_json || task.subtasks || [];
|
|
1013
|
+
const doneCount = subtasks.filter((s) => s.done).length;
|
|
1014
|
+
const totalCount = subtasks.length;
|
|
1015
|
+
const progress = totalCount > 0 ? chalk4.cyan(`${doneCount}/${totalCount}`) : chalk4.gray("-");
|
|
1016
|
+
if (options.shortIds) {
|
|
1017
|
+
table.push([shortId, status, titleWithAI, progress, dueDate]);
|
|
1018
|
+
} else {
|
|
1019
|
+
table.push([id, status, titleWithAI, project, priority, dueDate]);
|
|
1020
|
+
}
|
|
676
1021
|
});
|
|
677
1022
|
console.log("\n" + table.toString());
|
|
678
1023
|
const filterLabels = {
|
|
@@ -686,6 +1031,10 @@ Total: ${tasks.length} ${filterLabels[filter]} task${tasks.length === 1 ? "" : "
|
|
|
686
1031
|
if (tasks.length > limit) {
|
|
687
1032
|
console.log(chalk4.yellow(`Showing ${limit} of ${tasks.length} tasks. Use --limit to show more.`));
|
|
688
1033
|
}
|
|
1034
|
+
if (options.shortIds) {
|
|
1035
|
+
console.log(chalk4.gray(`
|
|
1036
|
+
Use: vibetasks vibing <#> to start working on a task`));
|
|
1037
|
+
}
|
|
689
1038
|
console.log();
|
|
690
1039
|
process.exit(0);
|
|
691
1040
|
} catch (error) {
|
|
@@ -706,15 +1055,16 @@ import { Command as Command4 } from "commander";
|
|
|
706
1055
|
import ora4 from "ora";
|
|
707
1056
|
import chalk5 from "chalk";
|
|
708
1057
|
import { AuthManager as AuthManager5, TaskOperations as TaskOperations3 } from "@vibetasks/core";
|
|
709
|
-
var doneCommand = new Command4("done").description("Mark a task as complete").argument("<id>", "Task ID (
|
|
1058
|
+
var doneCommand = new Command4("done").description("Mark a task as complete").argument("<id>", "Task ID, short # (1-99), or first 8 characters").action(async (id) => {
|
|
710
1059
|
const spinner = ora4("Completing task...").start();
|
|
711
1060
|
try {
|
|
712
1061
|
const authManager = new AuthManager5();
|
|
713
1062
|
const taskOps = await TaskOperations3.fromAuthManager(authManager);
|
|
714
|
-
|
|
715
|
-
|
|
1063
|
+
const shortIdManager = new ShortIdManager();
|
|
1064
|
+
let taskId = await shortIdManager.resolveId(id);
|
|
1065
|
+
if (taskId.length < 32) {
|
|
716
1066
|
const allTasks = await taskOps.getTasks("all");
|
|
717
|
-
const matchingTask = allTasks.find((t) => t.id.startsWith(
|
|
1067
|
+
const matchingTask = allTasks.find((t) => t.id.startsWith(taskId));
|
|
718
1068
|
if (!matchingTask) {
|
|
719
1069
|
spinner.fail(chalk5.red("Task not found"));
|
|
720
1070
|
console.error(chalk5.gray(`
|
|
@@ -725,6 +1075,13 @@ No task found with ID starting with: ${id}
|
|
|
725
1075
|
taskId = matchingTask.id;
|
|
726
1076
|
}
|
|
727
1077
|
const task = await taskOps.completeTask(taskId);
|
|
1078
|
+
const sessionManager2 = getSessionManager();
|
|
1079
|
+
await sessionManager2.logAction({
|
|
1080
|
+
type: "task_completed",
|
|
1081
|
+
description: `Completed: "${task.title}"`,
|
|
1082
|
+
taskId: task.id,
|
|
1083
|
+
taskTitle: task.title
|
|
1084
|
+
});
|
|
728
1085
|
spinner.succeed(chalk5.green("Task completed!"));
|
|
729
1086
|
console.log(chalk5.gray(`
|
|
730
1087
|
\u2713 ${task.title}`));
|
|
@@ -752,11 +1109,16 @@ import ora5 from "ora";
|
|
|
752
1109
|
import inquirer2 from "inquirer";
|
|
753
1110
|
import { AuthManager as AuthManager6, TaskOperations as TaskOperations4 } from "@vibetasks/core";
|
|
754
1111
|
var WIP_LIMIT = 3;
|
|
755
|
-
var vibingCommand = new Command5("vibing").alias("start").alias("v").description("Start working on a task (move to vibing status)").argument("[task-id]", "Task ID to start vibing on").option("-p, --pick", "Pick from todo tasks interactively").action(async (
|
|
1112
|
+
var vibingCommand = new Command5("vibing").alias("start").alias("v").description("Start working on a task (move to vibing status)").argument("[task-id]", "Task ID or short # (1-99) to start vibing on").option("-p, --pick", "Pick from todo tasks interactively").action(async (taskIdInput, options) => {
|
|
756
1113
|
const spinner = ora5();
|
|
757
1114
|
try {
|
|
758
1115
|
const authManager = new AuthManager6();
|
|
759
1116
|
const taskOps = await TaskOperations4.fromAuthManager(authManager);
|
|
1117
|
+
const shortIdManager = new ShortIdManager();
|
|
1118
|
+
let taskId;
|
|
1119
|
+
if (taskIdInput) {
|
|
1120
|
+
taskId = await shortIdManager.resolveId(taskIdInput);
|
|
1121
|
+
}
|
|
760
1122
|
const allTasks = await taskOps.getTasks("all");
|
|
761
1123
|
const vibingTasks = allTasks.filter((t) => t.status === "vibing" && !t.completed);
|
|
762
1124
|
if (vibingTasks.length >= WIP_LIMIT) {
|
|
@@ -2721,10 +3083,240 @@ function getTagColor2(category) {
|
|
|
2721
3083
|
return colors[category] || "#FF6B6B";
|
|
2722
3084
|
}
|
|
2723
3085
|
|
|
3086
|
+
// src/commands/next.ts
|
|
3087
|
+
import { Command as Command16 } from "commander";
|
|
3088
|
+
import chalk17 from "chalk";
|
|
3089
|
+
import { AuthManager as AuthManager16, TaskOperations as TaskOperations12 } from "@vibetasks/core";
|
|
3090
|
+
var PRIORITY_ORDER = { high: 0, medium: 1, low: 2, none: 3 };
|
|
3091
|
+
var nextCommand = new Command16("next").description("Show and optionally start the highest priority task").option("-s, --start", "Start vibing on the task immediately").option("--project <name>", "Filter by project tag").action(async (options) => {
|
|
3092
|
+
try {
|
|
3093
|
+
const authManager = new AuthManager16();
|
|
3094
|
+
const taskOps = await TaskOperations12.fromAuthManager(authManager);
|
|
3095
|
+
let tasks = await taskOps.getTasks("all");
|
|
3096
|
+
tasks = tasks.filter((t) => t.status !== "done" && t.status !== "archived" && !t.completed);
|
|
3097
|
+
if (options.project) {
|
|
3098
|
+
tasks = tasks.filter((t) => t.project_tag === options.project);
|
|
3099
|
+
}
|
|
3100
|
+
tasks.sort((a, b) => {
|
|
3101
|
+
const priorityDiff = (PRIORITY_ORDER[a.priority || "none"] || 3) - (PRIORITY_ORDER[b.priority || "none"] || 3);
|
|
3102
|
+
if (priorityDiff !== 0) return priorityDiff;
|
|
3103
|
+
if (a.status === "vibing" && b.status !== "vibing") return -1;
|
|
3104
|
+
if (b.status === "vibing" && a.status !== "vibing") return 1;
|
|
3105
|
+
return (a.position || 0) - (b.position || 0);
|
|
3106
|
+
});
|
|
3107
|
+
if (tasks.length === 0) {
|
|
3108
|
+
console.log(chalk17.gray("\n\u{1F389} No tasks in queue! You're all caught up.\n"));
|
|
3109
|
+
process.exit(0);
|
|
3110
|
+
}
|
|
3111
|
+
const nextTask = tasks[0];
|
|
3112
|
+
if (options.start && nextTask.status !== "vibing") {
|
|
3113
|
+
await taskOps.updateTaskStatus(nextTask.id, "vibing");
|
|
3114
|
+
console.log(chalk17.green(`
|
|
3115
|
+
\u26A1 Started vibing on task!
|
|
3116
|
+
`));
|
|
3117
|
+
}
|
|
3118
|
+
const priorityColors = {
|
|
3119
|
+
high: chalk17.red,
|
|
3120
|
+
medium: chalk17.yellow,
|
|
3121
|
+
low: chalk17.blue,
|
|
3122
|
+
none: chalk17.gray
|
|
3123
|
+
};
|
|
3124
|
+
const priorityEmojis = {
|
|
3125
|
+
high: "\u{1F534}",
|
|
3126
|
+
medium: "\u{1F7E1}",
|
|
3127
|
+
low: "\u{1F535}",
|
|
3128
|
+
none: "\u26AA"
|
|
3129
|
+
};
|
|
3130
|
+
const statusColors = {
|
|
3131
|
+
todo: chalk17.gray,
|
|
3132
|
+
vibing: chalk17.magenta,
|
|
3133
|
+
done: chalk17.green
|
|
3134
|
+
};
|
|
3135
|
+
const priority = nextTask.priority || "none";
|
|
3136
|
+
const priorityColor = priorityColors[priority];
|
|
3137
|
+
const priorityEmoji = priorityEmojis[priority];
|
|
3138
|
+
const statusColor = statusColors[nextTask.status || "todo"];
|
|
3139
|
+
const shortIdManager = new ShortIdManager();
|
|
3140
|
+
await shortIdManager.saveMappings([nextTask.id]);
|
|
3141
|
+
console.log("\n" + chalk17.bold("\u2501".repeat(50)));
|
|
3142
|
+
console.log(chalk17.bold.cyan("\n\u{1F4CD} NEXT UP:\n"));
|
|
3143
|
+
console.log(chalk17.bold.white(` ${nextTask.title}`));
|
|
3144
|
+
console.log();
|
|
3145
|
+
console.log(` ${priorityEmoji} Priority: ${priorityColor(priority.charAt(0).toUpperCase() + priority.slice(1))}`);
|
|
3146
|
+
console.log(` \u{1F4CA} Status: ${statusColor(nextTask.status || "todo")}`);
|
|
3147
|
+
if (nextTask.project_tag) {
|
|
3148
|
+
console.log(` \u{1F4C1} Project: ${chalk17.blue(nextTask.project_tag)}`);
|
|
3149
|
+
}
|
|
3150
|
+
if (nextTask.due_date) {
|
|
3151
|
+
const dueDate = new Date(nextTask.due_date);
|
|
3152
|
+
const today = /* @__PURE__ */ new Date();
|
|
3153
|
+
const isOverdue = dueDate < today;
|
|
3154
|
+
const dateStr = nextTask.due_date.split("T")[0];
|
|
3155
|
+
console.log(` \u{1F4C5} Due: ${isOverdue ? chalk17.red(dateStr + " (OVERDUE)") : chalk17.gray(dateStr)}`);
|
|
3156
|
+
}
|
|
3157
|
+
if (nextTask.context_notes) {
|
|
3158
|
+
console.log(`
|
|
3159
|
+
${chalk17.blue("\u{1F4AC} Context:")}`);
|
|
3160
|
+
console.log(chalk17.gray(` ${nextTask.context_notes}`));
|
|
3161
|
+
}
|
|
3162
|
+
const subtasks = nextTask.subtasks_json || nextTask.subtasks || [];
|
|
3163
|
+
if (subtasks.length > 0) {
|
|
3164
|
+
const doneCount = subtasks.filter((s) => s.done).length;
|
|
3165
|
+
console.log(`
|
|
3166
|
+
${chalk17.cyan("\u2713 Subtasks:")} ${doneCount}/${subtasks.length} done`);
|
|
3167
|
+
subtasks.slice(0, 5).forEach((s) => {
|
|
3168
|
+
const icon = s.done ? chalk17.green("\u2713") : chalk17.gray("\u25CB");
|
|
3169
|
+
const text = s.done ? chalk17.strikethrough.gray(s.title) : s.title;
|
|
3170
|
+
console.log(` ${icon} ${text}`);
|
|
3171
|
+
});
|
|
3172
|
+
if (subtasks.length > 5) {
|
|
3173
|
+
console.log(chalk17.gray(` ... and ${subtasks.length - 5} more`));
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3176
|
+
console.log("\n" + chalk17.bold("\u2501".repeat(50)));
|
|
3177
|
+
console.log(chalk17.gray("\n Quick actions:"));
|
|
3178
|
+
if (nextTask.status !== "vibing") {
|
|
3179
|
+
console.log(chalk17.gray(` \u2022 ${chalk17.cyan("vibetasks next --start")} - Start vibing on this task`));
|
|
3180
|
+
}
|
|
3181
|
+
console.log(chalk17.gray(` \u2022 ${chalk17.cyan("vibetasks vibing 1")} - Start working (short ID #1)`));
|
|
3182
|
+
console.log(chalk17.gray(` \u2022 ${chalk17.cyan("vibetasks done 1")} - Mark as done`));
|
|
3183
|
+
console.log();
|
|
3184
|
+
process.exit(0);
|
|
3185
|
+
} catch (error) {
|
|
3186
|
+
if (error.message.includes("Not authenticated")) {
|
|
3187
|
+
console.error(chalk17.yellow("\n\u26A0\uFE0F You need to login first"));
|
|
3188
|
+
console.error(chalk17.gray("Run: vibetasks login\n"));
|
|
3189
|
+
} else {
|
|
3190
|
+
console.error(chalk17.red(`
|
|
3191
|
+
Error: ${error.message}
|
|
3192
|
+
`));
|
|
3193
|
+
}
|
|
3194
|
+
process.exit(1);
|
|
3195
|
+
}
|
|
3196
|
+
});
|
|
3197
|
+
|
|
3198
|
+
// src/commands/session.ts
|
|
3199
|
+
import { Command as Command17 } from "commander";
|
|
3200
|
+
import chalk18 from "chalk";
|
|
3201
|
+
import { detectProject as detectProject5 } from "@vibetasks/shared/utils/project-detector";
|
|
3202
|
+
var sessionCommand = new Command17("session").description("Manage AI sessions for crash recovery and handoffs").addCommand(
|
|
3203
|
+
new Command17("start").description("Start a new session").action(async () => {
|
|
3204
|
+
const sessionManager2 = getSessionManager();
|
|
3205
|
+
const project = await detectProject5();
|
|
3206
|
+
const session = await sessionManager2.startSession(project?.name);
|
|
3207
|
+
console.log(chalk18.green("\u2713 Session started"));
|
|
3208
|
+
console.log();
|
|
3209
|
+
console.log(chalk18.cyan("Session ID:"), chalk18.bold(session.id));
|
|
3210
|
+
console.log(chalk18.gray("Full ID:"), session.fullId.slice(0, 8));
|
|
3211
|
+
if (session.project) {
|
|
3212
|
+
console.log(chalk18.gray("Project:"), session.project);
|
|
3213
|
+
}
|
|
3214
|
+
console.log();
|
|
3215
|
+
console.log(chalk18.yellow("Tip:"), "If the AI crashes, tell the next one:");
|
|
3216
|
+
console.log(chalk18.white(` "Continue from session ${session.id}"`));
|
|
3217
|
+
})
|
|
3218
|
+
).addCommand(
|
|
3219
|
+
new Command17("current").alias("status").description("Show current session status").action(async () => {
|
|
3220
|
+
const sessionManager2 = getSessionManager();
|
|
3221
|
+
const session = await sessionManager2.getCurrentSession();
|
|
3222
|
+
if (!session) {
|
|
3223
|
+
console.log(chalk18.yellow("No active session"));
|
|
3224
|
+
console.log(chalk18.gray("Start one with: vibetasks session start"));
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
console.log(chalk18.cyan("Current Session:"), chalk18.bold(session.id));
|
|
3228
|
+
console.log(chalk18.gray("Started:"), new Date(session.startedAt).toLocaleString());
|
|
3229
|
+
if (session.project) {
|
|
3230
|
+
console.log(chalk18.gray("Project:"), session.project);
|
|
3231
|
+
}
|
|
3232
|
+
console.log(chalk18.gray("Actions:"), session.actions.length);
|
|
3233
|
+
console.log();
|
|
3234
|
+
if (session.actions.length > 0) {
|
|
3235
|
+
console.log(chalk18.cyan("Recent actions:"));
|
|
3236
|
+
const recent = session.actions.slice(-5);
|
|
3237
|
+
for (const action of recent) {
|
|
3238
|
+
const time = new Date(action.timestamp).toLocaleTimeString();
|
|
3239
|
+
const icon = {
|
|
3240
|
+
task_created: "\u2795",
|
|
3241
|
+
task_completed: "\u2713",
|
|
3242
|
+
task_updated: "\u{1F4DD}",
|
|
3243
|
+
file_modified: "\u{1F4C4}",
|
|
3244
|
+
note: "\u{1F4AC}"
|
|
3245
|
+
}[action.type];
|
|
3246
|
+
console.log(chalk18.gray(` ${icon} [${time}]`), action.description);
|
|
3247
|
+
}
|
|
3248
|
+
if (session.actions.length > 5) {
|
|
3249
|
+
console.log(chalk18.gray(` ... and ${session.actions.length - 5} more`));
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
})
|
|
3253
|
+
).addCommand(
|
|
3254
|
+
new Command17("end").description("End the current session").option("-s, --summary <text>", "Add a summary of what was done").action(async (options) => {
|
|
3255
|
+
const sessionManager2 = getSessionManager();
|
|
3256
|
+
const session = await sessionManager2.endSession(options.summary);
|
|
3257
|
+
if (!session) {
|
|
3258
|
+
console.log(chalk18.yellow("No active session to end"));
|
|
3259
|
+
return;
|
|
3260
|
+
}
|
|
3261
|
+
console.log(chalk18.green("\u2713 Session ended:"), chalk18.bold(session.id));
|
|
3262
|
+
console.log(chalk18.gray("Duration:"), formatDuration(session.startedAt, session.endedAt));
|
|
3263
|
+
console.log(chalk18.gray("Actions:"), session.actions.length);
|
|
3264
|
+
if (options.summary) {
|
|
3265
|
+
console.log(chalk18.gray("Summary:"), options.summary);
|
|
3266
|
+
}
|
|
3267
|
+
})
|
|
3268
|
+
).addCommand(
|
|
3269
|
+
new Command17("list").description("List recent sessions").option("-n, --limit <number>", "Number of sessions to show", "10").action(async (options) => {
|
|
3270
|
+
const sessionManager2 = getSessionManager();
|
|
3271
|
+
const sessions = await sessionManager2.getRecentSessions(parseInt(options.limit));
|
|
3272
|
+
if (sessions.length === 0) {
|
|
3273
|
+
console.log(chalk18.yellow("No sessions found"));
|
|
3274
|
+
return;
|
|
3275
|
+
}
|
|
3276
|
+
console.log(chalk18.cyan("Recent Sessions:"));
|
|
3277
|
+
console.log();
|
|
3278
|
+
for (const session of sessions) {
|
|
3279
|
+
const status = session.endedAt ? chalk18.gray("ended") : chalk18.green("active");
|
|
3280
|
+
const date = new Date(session.startedAt).toLocaleDateString();
|
|
3281
|
+
const actions = session.actions.length;
|
|
3282
|
+
console.log(
|
|
3283
|
+
chalk18.bold(session.id),
|
|
3284
|
+
status,
|
|
3285
|
+
chalk18.gray(`| ${date} | ${actions} actions`),
|
|
3286
|
+
session.project ? chalk18.blue(`[${session.project}]`) : ""
|
|
3287
|
+
);
|
|
3288
|
+
}
|
|
3289
|
+
})
|
|
3290
|
+
).addCommand(
|
|
3291
|
+
new Command17("show").alias("handoff").description("Show session details for handoff to next AI").argument("<session-id>", "Session ID (partial match supported)").action(async (sessionId) => {
|
|
3292
|
+
const sessionManager2 = getSessionManager();
|
|
3293
|
+
const handoff = await sessionManager2.getSessionHandoff(sessionId);
|
|
3294
|
+
console.log(handoff);
|
|
3295
|
+
})
|
|
3296
|
+
).addCommand(
|
|
3297
|
+
new Command17("log").description("Log an action or note to the current session").argument("<message>", "Note to log").action(async (message) => {
|
|
3298
|
+
const sessionManager2 = getSessionManager();
|
|
3299
|
+
await sessionManager2.logAction({
|
|
3300
|
+
type: "note",
|
|
3301
|
+
description: message
|
|
3302
|
+
});
|
|
3303
|
+
console.log(chalk18.green("\u2713 Logged to session"));
|
|
3304
|
+
})
|
|
3305
|
+
);
|
|
3306
|
+
function formatDuration(start, end) {
|
|
3307
|
+
const ms = new Date(end).getTime() - new Date(start).getTime();
|
|
3308
|
+
const minutes = Math.floor(ms / 6e4);
|
|
3309
|
+
const hours = Math.floor(minutes / 60);
|
|
3310
|
+
if (hours > 0) {
|
|
3311
|
+
return `${hours}h ${minutes % 60}m`;
|
|
3312
|
+
}
|
|
3313
|
+
return `${minutes}m`;
|
|
3314
|
+
}
|
|
3315
|
+
|
|
2724
3316
|
// bin/vibetasks.ts
|
|
2725
3317
|
var require2 = createRequire(import.meta.url);
|
|
2726
3318
|
var pkg = require2("../../package.json");
|
|
2727
|
-
var program = new
|
|
3319
|
+
var program = new Command18();
|
|
2728
3320
|
program.name("vibetasks").description("VibeTasks CLI - Fast task management for vibers").version(pkg.version);
|
|
2729
3321
|
program.addCommand(setupCommand);
|
|
2730
3322
|
program.addCommand(loginCommand);
|
|
@@ -2742,4 +3334,6 @@ program.addCommand(watchCommand);
|
|
|
2742
3334
|
program.addCommand(checkCommand);
|
|
2743
3335
|
program.addCommand(archiveCommand);
|
|
2744
3336
|
program.addCommand(daemonCommand);
|
|
3337
|
+
program.addCommand(nextCommand);
|
|
3338
|
+
program.addCommand(sessionCommand);
|
|
2745
3339
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibetasks/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "VibeTasks CLI - Lightning-fast task management from your terminal. Works with Claude Code, Cursor, and all AI coding tools.",
|
|
5
5
|
"author": "Vyas",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"typecheck": "tsc --noEmit"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@vibetasks/core": "^0.
|
|
49
|
-
"@vibetasks/shared": "^1.
|
|
48
|
+
"@vibetasks/core": "^0.5.0",
|
|
49
|
+
"@vibetasks/shared": "^1.2.0",
|
|
50
50
|
"commander": "^11.1.0",
|
|
51
51
|
"chalk": "^5.3.0",
|
|
52
52
|
"ora": "^8.0.1",
|