tick-md 1.0.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/README.md +228 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +282 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +15 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +95 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/agent.d.ts +20 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +125 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/claim.d.ts +9 -0
- package/dist/commands/claim.d.ts.map +1 -0
- package/dist/commands/claim.js +161 -0
- package/dist/commands/claim.js.map +1 -0
- package/dist/commands/done.d.ts +9 -0
- package/dist/commands/done.d.ts.map +1 -0
- package/dist/commands/done.js +152 -0
- package/dist/commands/done.js.map +1 -0
- package/dist/commands/graph.d.ts +9 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/graph.js +143 -0
- package/dist/commands/graph.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +78 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +15 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +104 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +137 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts +13 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +141 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/validate.d.ts +8 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +103 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch.d.ts +10 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +136 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/parse.d.ts +6 -0
- package/dist/parser/parse.d.ts.map +1 -0
- package/dist/parser/parse.js +178 -0
- package/dist/parser/parse.js.map +1 -0
- package/dist/parser/serialize.d.ts +10 -0
- package/dist/parser/serialize.d.ts.map +1 -0
- package/dist/parser/serialize.js +122 -0
- package/dist/parser/serialize.js.map +1 -0
- package/dist/types.d.ts +59 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/git.d.ts +54 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +192 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/lock.d.ts +47 -0
- package/dist/utils/lock.d.ts.map +1 -0
- package/dist/utils/lock.js +128 -0
- package/dist/utils/lock.js.map +1 -0
- package/dist/utils/validator.d.ts +17 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +188 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { parseTickFile } from "../parser/parse.js";
|
|
4
|
+
import { validateTickFile } from "../utils/validator.js";
|
|
5
|
+
/**
|
|
6
|
+
* Validate the current TICK.md file
|
|
7
|
+
*/
|
|
8
|
+
export async function validateCommand(options = {}) {
|
|
9
|
+
const tickPath = "TICK.md";
|
|
10
|
+
if (!fs.existsSync(tickPath)) {
|
|
11
|
+
console.error(chalk.red("✗ TICK.md not found"));
|
|
12
|
+
console.log(chalk.gray("Run 'tick init' to initialize a project"));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
console.log(chalk.cyan("🔍 Validating TICK.md..."));
|
|
16
|
+
console.log();
|
|
17
|
+
try {
|
|
18
|
+
const content = fs.readFileSync(tickPath, "utf-8");
|
|
19
|
+
const tickFile = parseTickFile(content);
|
|
20
|
+
const result = validateTickFile(tickFile);
|
|
21
|
+
// Display errors
|
|
22
|
+
if (result.errors.length > 0) {
|
|
23
|
+
console.log(chalk.red.bold(`✗ ${result.errors.length} error(s) found:`));
|
|
24
|
+
console.log();
|
|
25
|
+
for (const error of result.errors) {
|
|
26
|
+
console.log(chalk.red(" ✗"), chalk.white.bold(error.message));
|
|
27
|
+
if (error.location) {
|
|
28
|
+
console.log(chalk.gray(` Location: ${error.location}`));
|
|
29
|
+
}
|
|
30
|
+
if (error.fix) {
|
|
31
|
+
console.log(chalk.cyan(` Fix: ${error.fix}`));
|
|
32
|
+
}
|
|
33
|
+
console.log();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Display warnings
|
|
37
|
+
if (result.warnings.length > 0) {
|
|
38
|
+
console.log(chalk.yellow.bold(`⚠ ${result.warnings.length} warning(s) found:`));
|
|
39
|
+
console.log();
|
|
40
|
+
for (const warning of result.warnings) {
|
|
41
|
+
console.log(chalk.yellow(" ⚠"), chalk.white(warning.message));
|
|
42
|
+
if (warning.location) {
|
|
43
|
+
console.log(chalk.gray(` Location: ${warning.location}`));
|
|
44
|
+
}
|
|
45
|
+
if (warning.fix) {
|
|
46
|
+
console.log(chalk.cyan(` Fix: ${warning.fix}`));
|
|
47
|
+
}
|
|
48
|
+
console.log();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Display summary
|
|
52
|
+
console.log(chalk.gray("─".repeat(60)));
|
|
53
|
+
if (result.valid && result.warnings.length === 0) {
|
|
54
|
+
console.log(chalk.green.bold("✓ TICK.md is valid!"));
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(chalk.gray(` ${tickFile.tasks.length} tasks validated`));
|
|
57
|
+
console.log(chalk.gray(` ${tickFile.agents.length} agents registered`));
|
|
58
|
+
}
|
|
59
|
+
else if (result.valid) {
|
|
60
|
+
console.log(chalk.yellow.bold("✓ TICK.md is valid (with warnings)"));
|
|
61
|
+
console.log();
|
|
62
|
+
console.log(chalk.gray(` ${tickFile.tasks.length} tasks validated`));
|
|
63
|
+
console.log(chalk.gray(` ${tickFile.agents.length} agents registered`));
|
|
64
|
+
console.log(chalk.yellow(` ${result.warnings.length} warnings to address`));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log(chalk.red.bold("✗ TICK.md has errors"));
|
|
68
|
+
console.log();
|
|
69
|
+
console.log(chalk.red(` ${result.errors.length} errors to fix`));
|
|
70
|
+
console.log(chalk.yellow(` ${result.warnings.length} warnings to address`));
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
// Verbose stats
|
|
74
|
+
if (options.verbose) {
|
|
75
|
+
console.log();
|
|
76
|
+
console.log(chalk.cyan.bold("Detailed Stats:"));
|
|
77
|
+
console.log();
|
|
78
|
+
const statuses = tickFile.tasks.reduce((acc, task) => {
|
|
79
|
+
acc[task.status] = (acc[task.status] || 0) + 1;
|
|
80
|
+
return acc;
|
|
81
|
+
}, {});
|
|
82
|
+
for (const [status, count] of Object.entries(statuses)) {
|
|
83
|
+
console.log(chalk.gray(` ${status}: ${count}`));
|
|
84
|
+
}
|
|
85
|
+
const blockedTasks = tickFile.tasks.filter((t) => t.status === "blocked");
|
|
86
|
+
if (blockedTasks.length > 0) {
|
|
87
|
+
console.log();
|
|
88
|
+
console.log(chalk.yellow(` ${blockedTasks.length} blocked tasks`));
|
|
89
|
+
}
|
|
90
|
+
const unassigned = tickFile.tasks.filter((t) => !t.assigned_to && t.status !== "done").length;
|
|
91
|
+
if (unassigned > 0) {
|
|
92
|
+
console.log(chalk.gray(` ${unassigned} unassigned tasks`));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
console.log();
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.error(chalk.red("✗ Failed to parse TICK.md"));
|
|
99
|
+
console.error(chalk.gray(error.message));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TaskStatus } from "../types.js";
|
|
2
|
+
export interface WatchOptions {
|
|
3
|
+
interval?: number;
|
|
4
|
+
filter?: TaskStatus;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Watch TICK.md for changes and display updates in real-time
|
|
8
|
+
*/
|
|
9
|
+
export declare function watchCommand(options?: WatchOptions): Promise<void>;
|
|
10
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAQ,UAAU,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmG5E"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { parseTickFile } from "../parser/parse.js";
|
|
4
|
+
/**
|
|
5
|
+
* Watch TICK.md for changes and display updates in real-time
|
|
6
|
+
*/
|
|
7
|
+
export async function watchCommand(options = {}) {
|
|
8
|
+
const tickPath = "TICK.md";
|
|
9
|
+
if (!fs.existsSync(tickPath)) {
|
|
10
|
+
console.error(chalk.red("✗ TICK.md not found"));
|
|
11
|
+
console.log(chalk.gray("Run 'tick init' to initialize a project"));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const interval = (options.interval || 5) * 1000; // Convert to ms
|
|
15
|
+
let lastContent = "";
|
|
16
|
+
let lastTasks = [];
|
|
17
|
+
console.log(chalk.cyan.bold("👀 Watching TICK.md for changes..."));
|
|
18
|
+
console.log(chalk.gray(`Polling every ${options.interval || 5}s · Press Ctrl+C to stop`));
|
|
19
|
+
console.log();
|
|
20
|
+
// Initial load
|
|
21
|
+
try {
|
|
22
|
+
lastContent = fs.readFileSync(tickPath, "utf-8");
|
|
23
|
+
const tickFile = parseTickFile(lastContent);
|
|
24
|
+
lastTasks = tickFile.tasks;
|
|
25
|
+
displaySummary(lastTasks, options.filter);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error(chalk.red("✗ Failed to parse TICK.md"));
|
|
29
|
+
console.error(chalk.gray(error.message));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Watch for changes
|
|
33
|
+
const watchInterval = setInterval(() => {
|
|
34
|
+
try {
|
|
35
|
+
const currentContent = fs.readFileSync(tickPath, "utf-8");
|
|
36
|
+
// Check if content changed
|
|
37
|
+
if (currentContent === lastContent) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
lastContent = currentContent;
|
|
41
|
+
const tickFile = parseTickFile(currentContent);
|
|
42
|
+
const currentTasks = tickFile.tasks;
|
|
43
|
+
// Detect changes
|
|
44
|
+
const changes = detectChanges(lastTasks, currentTasks);
|
|
45
|
+
if (changes.length > 0) {
|
|
46
|
+
console.log(chalk.gray(`[${new Date().toLocaleTimeString()}]`));
|
|
47
|
+
for (const change of changes) {
|
|
48
|
+
switch (change.type) {
|
|
49
|
+
case "added":
|
|
50
|
+
console.log(chalk.green(` ✓ Added: ${change.task.id} - ${change.task.title}`));
|
|
51
|
+
break;
|
|
52
|
+
case "removed":
|
|
53
|
+
console.log(chalk.red(` ✗ Removed: ${change.task.id}`));
|
|
54
|
+
break;
|
|
55
|
+
case "status":
|
|
56
|
+
console.log(chalk.blue(` ⟳ ${change.task.id}: ${change.oldValue} → ${change.task.status}`));
|
|
57
|
+
break;
|
|
58
|
+
case "claimed":
|
|
59
|
+
console.log(chalk.yellow(` 🔒 ${change.task.id} claimed by ${change.task.claimed_by}`));
|
|
60
|
+
break;
|
|
61
|
+
case "released":
|
|
62
|
+
console.log(chalk.gray(` 🔓 ${change.task.id} released`));
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
console.log();
|
|
67
|
+
displaySummary(currentTasks, options.filter);
|
|
68
|
+
}
|
|
69
|
+
lastTasks = currentTasks;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error(chalk.red(`✗ Error reading TICK.md: ${error.message}`));
|
|
73
|
+
}
|
|
74
|
+
}, interval);
|
|
75
|
+
// Handle graceful shutdown
|
|
76
|
+
process.on("SIGINT", () => {
|
|
77
|
+
clearInterval(watchInterval);
|
|
78
|
+
console.log();
|
|
79
|
+
console.log(chalk.gray("Stopped watching"));
|
|
80
|
+
process.exit(0);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Detect changes between task lists
|
|
85
|
+
*/
|
|
86
|
+
function detectChanges(oldTasks, newTasks) {
|
|
87
|
+
const changes = [];
|
|
88
|
+
const oldMap = new Map(oldTasks.map((t) => [t.id, t]));
|
|
89
|
+
const newMap = new Map(newTasks.map((t) => [t.id, t]));
|
|
90
|
+
// Check for added and modified tasks
|
|
91
|
+
for (const [id, newTask] of newMap) {
|
|
92
|
+
const oldTask = oldMap.get(id);
|
|
93
|
+
if (!oldTask) {
|
|
94
|
+
changes.push({ type: "added", task: newTask });
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Check for status change
|
|
98
|
+
if (oldTask.status !== newTask.status) {
|
|
99
|
+
changes.push({ type: "status", task: newTask, oldValue: oldTask.status });
|
|
100
|
+
}
|
|
101
|
+
// Check for claim change
|
|
102
|
+
if (!oldTask.claimed_by && newTask.claimed_by) {
|
|
103
|
+
changes.push({ type: "claimed", task: newTask });
|
|
104
|
+
}
|
|
105
|
+
else if (oldTask.claimed_by && !newTask.claimed_by) {
|
|
106
|
+
changes.push({ type: "released", task: newTask });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Check for removed tasks
|
|
111
|
+
for (const [id, oldTask] of oldMap) {
|
|
112
|
+
if (!newMap.has(id)) {
|
|
113
|
+
changes.push({ type: "removed", task: oldTask });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return changes;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Display task summary
|
|
120
|
+
*/
|
|
121
|
+
function displaySummary(tasks, filter) {
|
|
122
|
+
const filteredTasks = filter ? tasks.filter((t) => t.status === filter) : tasks;
|
|
123
|
+
const byStatus = filteredTasks.reduce((acc, task) => {
|
|
124
|
+
acc[task.status] = (acc[task.status] || 0) + 1;
|
|
125
|
+
return acc;
|
|
126
|
+
}, {});
|
|
127
|
+
const parts = [
|
|
128
|
+
byStatus.todo ? chalk.white(`${byStatus.todo} todo`) : null,
|
|
129
|
+
byStatus.in_progress ? chalk.blue(`${byStatus.in_progress} in progress`) : null,
|
|
130
|
+
byStatus.blocked ? chalk.red(`${byStatus.blocked} blocked`) : null,
|
|
131
|
+
byStatus.done ? chalk.green(`${byStatus.done} done`) : null,
|
|
132
|
+
].filter(Boolean);
|
|
133
|
+
console.log(chalk.gray(` Status: ${parts.join(" · ")}`));
|
|
134
|
+
console.log();
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parser/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/parser/parse.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAUT,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAkCvD"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import matter from "gray-matter";
|
|
2
|
+
import YAML from "yaml";
|
|
3
|
+
/**
|
|
4
|
+
* Parse a TICK.md file into structured data
|
|
5
|
+
*/
|
|
6
|
+
export function parseTickFile(content) {
|
|
7
|
+
// Parse YAML frontmatter using gray-matter
|
|
8
|
+
const { data: frontmatter, content: body } = matter(content);
|
|
9
|
+
// Extract project metadata from frontmatter
|
|
10
|
+
const meta = {
|
|
11
|
+
project: frontmatter.project || "untitled",
|
|
12
|
+
title: frontmatter.title,
|
|
13
|
+
schema_version: frontmatter.schema_version || "1.0",
|
|
14
|
+
created: frontmatter.created || new Date().toISOString(),
|
|
15
|
+
updated: frontmatter.updated || new Date().toISOString(),
|
|
16
|
+
default_workflow: frontmatter.default_workflow || [
|
|
17
|
+
"backlog",
|
|
18
|
+
"todo",
|
|
19
|
+
"in_progress",
|
|
20
|
+
"review",
|
|
21
|
+
"done",
|
|
22
|
+
],
|
|
23
|
+
id_prefix: frontmatter.id_prefix || "TASK",
|
|
24
|
+
next_id: frontmatter.next_id || 1,
|
|
25
|
+
};
|
|
26
|
+
// Parse agents table
|
|
27
|
+
const agents = parseAgentsTable(body);
|
|
28
|
+
// Parse task blocks
|
|
29
|
+
const tasks = parseTaskBlocks(body);
|
|
30
|
+
return {
|
|
31
|
+
meta,
|
|
32
|
+
agents,
|
|
33
|
+
tasks,
|
|
34
|
+
raw_content: content,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parse the agents table from Markdown
|
|
39
|
+
* Format: | Agent | Type | Role | Status | Working On | Last Active | Trust Level |
|
|
40
|
+
*/
|
|
41
|
+
function parseAgentsTable(content) {
|
|
42
|
+
const agents = [];
|
|
43
|
+
// Find the agents section (starts with ## Agents)
|
|
44
|
+
const agentsMatch = content.match(/##\s+Agents\s*\n\n([\s\S]*?)(?=\n##|\n---|\n###|$)/i);
|
|
45
|
+
if (!agentsMatch)
|
|
46
|
+
return agents;
|
|
47
|
+
const agentsSection = agentsMatch[1];
|
|
48
|
+
// Split into lines and find table rows
|
|
49
|
+
const lines = agentsSection.split("\n");
|
|
50
|
+
let inTable = false;
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const trimmed = line.trim();
|
|
53
|
+
// Skip empty lines and header separator
|
|
54
|
+
if (!trimmed || trimmed.startsWith("|---") || trimmed.startsWith("| ---")) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
// Check if this is a table row
|
|
58
|
+
if (trimmed.startsWith("|")) {
|
|
59
|
+
const cells = trimmed
|
|
60
|
+
.split("|")
|
|
61
|
+
.map((c) => c.trim())
|
|
62
|
+
.filter((c) => c);
|
|
63
|
+
// Skip header row (contains "Agent" or "Type")
|
|
64
|
+
if (cells.some((c) => c === "Agent" ||
|
|
65
|
+
c === "Type" ||
|
|
66
|
+
c === "Role" ||
|
|
67
|
+
c === "Status" ||
|
|
68
|
+
c === "Working On")) {
|
|
69
|
+
inTable = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (inTable && cells.length >= 6) {
|
|
73
|
+
const [name, type, roleStr, status, workingOn, lastActive, trustLevel] = cells;
|
|
74
|
+
// Parse roles (can be comma-separated)
|
|
75
|
+
const roles = roleStr.split(",").map((r) => r.trim());
|
|
76
|
+
agents.push({
|
|
77
|
+
name: name.trim(),
|
|
78
|
+
type: type.toLowerCase() || "bot",
|
|
79
|
+
roles,
|
|
80
|
+
status: status.toLowerCase() || "offline",
|
|
81
|
+
working_on: workingOn === "-" ? null : workingOn.trim(),
|
|
82
|
+
last_active: lastActive.trim(),
|
|
83
|
+
trust_level: trustLevel.toLowerCase() || "restricted",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return agents;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Parse task blocks from Markdown
|
|
92
|
+
* Format:
|
|
93
|
+
* ### TASK-001 · Task Title
|
|
94
|
+
* ```yaml
|
|
95
|
+
* id: TASK-001
|
|
96
|
+
* status: done
|
|
97
|
+
* ...
|
|
98
|
+
* ```
|
|
99
|
+
* > Task description
|
|
100
|
+
*/
|
|
101
|
+
function parseTaskBlocks(content) {
|
|
102
|
+
const tasks = [];
|
|
103
|
+
// Find all task headers (### TASK-XXX · Title)
|
|
104
|
+
const taskHeaderRegex = /###\s+([A-Z]+-\d+)\s*·\s*(.+?)$/gm;
|
|
105
|
+
const matches = [...content.matchAll(taskHeaderRegex)];
|
|
106
|
+
for (let i = 0; i < matches.length; i++) {
|
|
107
|
+
const match = matches[i];
|
|
108
|
+
const taskId = match[1];
|
|
109
|
+
const taskTitle = match[2].trim();
|
|
110
|
+
const startIndex = match.index;
|
|
111
|
+
// Find the end of this task block (next task header or end of file)
|
|
112
|
+
const nextMatch = matches[i + 1];
|
|
113
|
+
const endIndex = nextMatch ? nextMatch.index : content.length;
|
|
114
|
+
const taskBlock = content.slice(startIndex, endIndex);
|
|
115
|
+
// Extract YAML metadata from code block
|
|
116
|
+
const yamlMatch = taskBlock.match(/```yaml\s*\n([\s\S]*?)\n```/);
|
|
117
|
+
if (!yamlMatch)
|
|
118
|
+
continue;
|
|
119
|
+
const yamlContent = yamlMatch[1];
|
|
120
|
+
let metadata;
|
|
121
|
+
try {
|
|
122
|
+
metadata = YAML.parse(yamlContent);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.warn(`Failed to parse YAML for ${taskId}:`, error);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// Extract description (text after ```, usually in blockquote)
|
|
129
|
+
const afterYaml = taskBlock.slice(taskBlock.indexOf("```", yamlMatch.index + 3) + 3);
|
|
130
|
+
const descMatch = afterYaml.match(/>\s*(.+?)(?=\n###|\n---|\n##|$)/s);
|
|
131
|
+
const description = descMatch
|
|
132
|
+
? descMatch[1]
|
|
133
|
+
.split("\n")
|
|
134
|
+
.map((line) => line.replace(/^>\s*/, "").trim())
|
|
135
|
+
.filter((line) => line)
|
|
136
|
+
.join("\n")
|
|
137
|
+
: "";
|
|
138
|
+
// Build task object
|
|
139
|
+
const task = {
|
|
140
|
+
id: metadata.id || taskId,
|
|
141
|
+
title: taskTitle,
|
|
142
|
+
status: metadata.status || "backlog",
|
|
143
|
+
priority: metadata.priority || "medium",
|
|
144
|
+
assigned_to: metadata.assigned_to || null,
|
|
145
|
+
claimed_by: metadata.claimed_by || null,
|
|
146
|
+
created_by: metadata.created_by || "",
|
|
147
|
+
created_at: metadata.created_at || new Date().toISOString(),
|
|
148
|
+
updated_at: metadata.updated_at || new Date().toISOString(),
|
|
149
|
+
due_date: metadata.due_date,
|
|
150
|
+
tags: Array.isArray(metadata.tags) ? metadata.tags : [],
|
|
151
|
+
depends_on: Array.isArray(metadata.depends_on) ? metadata.depends_on : [],
|
|
152
|
+
blocks: Array.isArray(metadata.blocks) ? metadata.blocks : [],
|
|
153
|
+
estimated_hours: metadata.estimated_hours,
|
|
154
|
+
actual_hours: metadata.actual_hours,
|
|
155
|
+
detail_file: metadata.detail_file,
|
|
156
|
+
description: description.trim(),
|
|
157
|
+
history: parseHistory(metadata.history || []),
|
|
158
|
+
};
|
|
159
|
+
tasks.push(task);
|
|
160
|
+
}
|
|
161
|
+
return tasks;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Parse history entries from YAML array
|
|
165
|
+
*/
|
|
166
|
+
function parseHistory(history) {
|
|
167
|
+
if (!Array.isArray(history))
|
|
168
|
+
return [];
|
|
169
|
+
return history.map((entry) => ({
|
|
170
|
+
ts: entry.ts || "",
|
|
171
|
+
who: entry.who || "",
|
|
172
|
+
action: entry.action || "",
|
|
173
|
+
note: entry.note,
|
|
174
|
+
from: entry.from,
|
|
175
|
+
to: entry.to,
|
|
176
|
+
}));
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../src/parser/parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TickFile } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Serialize a TickFile back to TICK.md format
|
|
4
|
+
*/
|
|
5
|
+
export declare function serializeTickFile(tickFile: TickFile): string;
|
|
6
|
+
/**
|
|
7
|
+
* Generate a default TICK.md template for a new project
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateDefaultTickFile(projectName: string): string;
|
|
10
|
+
//# sourceMappingURL=serialize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/parser/serialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAA6B,MAAM,aAAa,CAAC;AAEvE;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAyG5D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAkBnE"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import YAML from "yaml";
|
|
2
|
+
/**
|
|
3
|
+
* Serialize a TickFile back to TICK.md format
|
|
4
|
+
*/
|
|
5
|
+
export function serializeTickFile(tickFile) {
|
|
6
|
+
const parts = [];
|
|
7
|
+
// 1. Frontmatter
|
|
8
|
+
parts.push("---");
|
|
9
|
+
parts.push(`project: ${tickFile.meta.project}`);
|
|
10
|
+
if (tickFile.meta.title) {
|
|
11
|
+
parts.push(`title: ${tickFile.meta.title}`);
|
|
12
|
+
}
|
|
13
|
+
parts.push(`schema_version: "${tickFile.meta.schema_version}"`);
|
|
14
|
+
parts.push(`created: ${tickFile.meta.created}`);
|
|
15
|
+
parts.push(`updated: ${tickFile.meta.updated}`);
|
|
16
|
+
parts.push(`default_workflow: [${tickFile.meta.default_workflow.join(", ")}]`);
|
|
17
|
+
parts.push(`id_prefix: ${tickFile.meta.id_prefix}`);
|
|
18
|
+
parts.push(`next_id: ${tickFile.meta.next_id}`);
|
|
19
|
+
parts.push("---");
|
|
20
|
+
parts.push("");
|
|
21
|
+
// 2. Agents table
|
|
22
|
+
if (tickFile.agents.length > 0) {
|
|
23
|
+
parts.push("## Agents");
|
|
24
|
+
parts.push("");
|
|
25
|
+
parts.push("| Agent | Type | Role | Status | Working On | Last Active | Trust Level |");
|
|
26
|
+
parts.push("|-------|------|------|--------|------------|-------------|-------------|");
|
|
27
|
+
for (const agent of tickFile.agents) {
|
|
28
|
+
const roles = agent.roles.join(", ");
|
|
29
|
+
const workingOn = agent.working_on || "-";
|
|
30
|
+
parts.push(`| ${agent.name} | ${agent.type} | ${roles} | ${agent.status} | ${workingOn} | ${agent.last_active} | ${agent.trust_level} |`);
|
|
31
|
+
}
|
|
32
|
+
parts.push("");
|
|
33
|
+
parts.push("---");
|
|
34
|
+
parts.push("");
|
|
35
|
+
}
|
|
36
|
+
// 3. Tasks
|
|
37
|
+
if (tickFile.tasks.length > 0) {
|
|
38
|
+
parts.push("## Tasks");
|
|
39
|
+
parts.push("");
|
|
40
|
+
for (const task of tickFile.tasks) {
|
|
41
|
+
parts.push(`### ${task.id} · ${task.title}`);
|
|
42
|
+
parts.push("");
|
|
43
|
+
// Task YAML metadata
|
|
44
|
+
const metadata = {
|
|
45
|
+
id: task.id,
|
|
46
|
+
status: task.status,
|
|
47
|
+
priority: task.priority,
|
|
48
|
+
assigned_to: task.assigned_to,
|
|
49
|
+
claimed_by: task.claimed_by,
|
|
50
|
+
created_by: task.created_by,
|
|
51
|
+
created_at: task.created_at,
|
|
52
|
+
updated_at: task.updated_at,
|
|
53
|
+
};
|
|
54
|
+
if (task.due_date)
|
|
55
|
+
metadata.due_date = task.due_date;
|
|
56
|
+
if (task.tags.length > 0)
|
|
57
|
+
metadata.tags = task.tags;
|
|
58
|
+
if (task.depends_on.length > 0)
|
|
59
|
+
metadata.depends_on = task.depends_on;
|
|
60
|
+
if (task.blocks.length > 0)
|
|
61
|
+
metadata.blocks = task.blocks;
|
|
62
|
+
if (task.estimated_hours)
|
|
63
|
+
metadata.estimated_hours = task.estimated_hours;
|
|
64
|
+
if (task.actual_hours)
|
|
65
|
+
metadata.actual_hours = task.actual_hours;
|
|
66
|
+
if (task.detail_file)
|
|
67
|
+
metadata.detail_file = task.detail_file;
|
|
68
|
+
// Format history for better readability
|
|
69
|
+
if (task.history.length > 0) {
|
|
70
|
+
metadata.history = task.history.map((h) => {
|
|
71
|
+
const entry = {
|
|
72
|
+
ts: h.ts,
|
|
73
|
+
who: h.who,
|
|
74
|
+
action: h.action,
|
|
75
|
+
};
|
|
76
|
+
if (h.note)
|
|
77
|
+
entry.note = h.note;
|
|
78
|
+
if (h.from)
|
|
79
|
+
entry.from = h.from;
|
|
80
|
+
if (h.to)
|
|
81
|
+
entry.to = h.to;
|
|
82
|
+
return entry;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
parts.push("```yaml");
|
|
86
|
+
parts.push(YAML.stringify(metadata).trim());
|
|
87
|
+
parts.push("```");
|
|
88
|
+
parts.push("");
|
|
89
|
+
// Task description
|
|
90
|
+
if (task.description) {
|
|
91
|
+
const descLines = task.description
|
|
92
|
+
.split("\n")
|
|
93
|
+
.map((line) => `> ${line}`)
|
|
94
|
+
.join("\n");
|
|
95
|
+
parts.push(descLines);
|
|
96
|
+
parts.push("");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return parts.join("\n");
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Generate a default TICK.md template for a new project
|
|
104
|
+
*/
|
|
105
|
+
export function generateDefaultTickFile(projectName) {
|
|
106
|
+
const now = new Date().toISOString();
|
|
107
|
+
const defaultFile = {
|
|
108
|
+
meta: {
|
|
109
|
+
project: projectName,
|
|
110
|
+
schema_version: "1.0",
|
|
111
|
+
created: now,
|
|
112
|
+
updated: now,
|
|
113
|
+
default_workflow: ["backlog", "todo", "in_progress", "review", "done"],
|
|
114
|
+
id_prefix: "TASK",
|
|
115
|
+
next_id: 1,
|
|
116
|
+
},
|
|
117
|
+
agents: [],
|
|
118
|
+
tasks: [],
|
|
119
|
+
};
|
|
120
|
+
return serializeTickFile(defaultFile);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=serialize.js.map
|