yatt-md 0.1.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 +172 -0
- package/SPEC.md +368 -0
- package/dist/cli/serve.js +3187 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +21 -0
- package/dist/lexer.d.ts +12 -0
- package/dist/lexer.js +100 -0
- package/dist/parser.d.ts +5 -0
- package/dist/parser.js +473 -0
- package/dist/renderer/gantt-svg.d.ts +10 -0
- package/dist/renderer/gantt-svg.js +489 -0
- package/dist/renderer/list-html.d.ts +7 -0
- package/dist/renderer/list-html.js +204 -0
- package/dist/scheduler.d.ts +2 -0
- package/dist/scheduler.js +284 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.js +1 -0
- package/dist/validator.d.ts +2 -0
- package/dist/validator.js +121 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# YATT — Yet Another Task Tracker
|
|
2
|
+
|
|
3
|
+
**Markdown is the database. Git is the history. YATT is the UI.**
|
|
4
|
+
|
|
5
|
+
YATT is a plain-text task tracker that lives inside your Markdown files. Tasks are written in a simple one-line format — status, name, duration, assignee, tags — and YATT renders them as a Gantt timeline, Kanban board, or people view. Because everything is text, your whole team can edit tasks in any editor, review changes in pull requests, and get a full audit trail from git for free.
|
|
6
|
+
|
|
7
|
+
 
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Why YATT?
|
|
12
|
+
|
|
13
|
+
Most task trackers store data in a database you can't read or diff. YATT flips this: **the `.md` file is the source of truth.** This means:
|
|
14
|
+
|
|
15
|
+
- **Git-native** — every task change is a commit. Branch for experiments, merge to ship, revert mistakes.
|
|
16
|
+
- **No lock-in** — your tasks are plain text. Open them in Vim, VS Code, Obsidian, or cat them in a terminal.
|
|
17
|
+
- **Team-friendly** — pull requests *are* planning reviews. Comment on task lines, suggest changes, approve.
|
|
18
|
+
- **Offline-first** — nothing to sync. The file is always up to date.
|
|
19
|
+
- **Lightweight server** — run `yatt serve` to get a live Gantt, Kanban, and People view. Commit and push without leaving the browser.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## What it looks like
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
> *3 slides: write plain text → timeline view → kanban board. Cycles automatically.*
|
|
28
|
+
|
|
29
|
+
```yatt
|
|
30
|
+
title: Product v2 Launch
|
|
31
|
+
start: 2026-01-05
|
|
32
|
+
|
|
33
|
+
[x] Discovery & planning | id:phase1 | 5d | @alice | delayed 3d
|
|
34
|
+
// Research took longer than expected — scope was broader than estimated.
|
|
35
|
+
>> Kickoff complete | after:phase1
|
|
36
|
+
|
|
37
|
+
parallel: design | after:phase1
|
|
38
|
+
[done] UX wireframes | 4d | @carol | %100
|
|
39
|
+
[~] Visual design | 3d | @carol | %80 | delayed 2d
|
|
40
|
+
end: design
|
|
41
|
+
|
|
42
|
+
parallel: engineering | after:phase1
|
|
43
|
+
[x] API scaffold | id:api | 3d | @bob | blocked 1w | delayed 2d
|
|
44
|
+
[ ] Auth service | 4d | @bob | after:api | %45
|
|
45
|
+
[ ] Core features | 1w | @alice | after:api
|
|
46
|
+
end: engineering
|
|
47
|
+
|
|
48
|
+
[ ] Integration & QA | id:qa | 5d | @alice @bob | after:design,engineering
|
|
49
|
+
>> v2.0 Release | after:qa | +deadline
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Tasks render as a minimal **line + circle** timeline — a filled dot at start, hollow ring at end, bright leading segment for progress. Milestones are bullseye circles. Hover any row for a details card.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Quick start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Serve a folder of Markdown files
|
|
60
|
+
npx yatt serve ./docs
|
|
61
|
+
|
|
62
|
+
# Or install globally
|
|
63
|
+
npm install -g yatt
|
|
64
|
+
yatt serve .
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Open `http://localhost:3000`. Pick any `.md` file from the sidebar. YATT finds all ` ```yatt ` blocks in the file and renders them.
|
|
68
|
+
|
|
69
|
+
The **Edit** tab lets you write raw YATT syntax. Changes save automatically and the view updates live.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Task syntax
|
|
74
|
+
|
|
75
|
+
One task per line:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
[status] Task name | duration | @assignee | #tag | %progress | id:slug | after:dep
|
|
79
|
+
// Optional description — attach one or more comment lines immediately after a task
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Status sigils:**
|
|
83
|
+
|
|
84
|
+
| Sigil | Word | Meaning |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `[ ]` | `[new]` | Not started |
|
|
87
|
+
| `[~]` | `[active]` | In progress |
|
|
88
|
+
| `[=]` | `[review]` | In review |
|
|
89
|
+
| `[!]` | `[blocked]` | Blocked |
|
|
90
|
+
| `[o]` | `[paused]` | Paused |
|
|
91
|
+
| `[x]` | `[done]` | Complete |
|
|
92
|
+
| `[_]` | `[cancelled]` | Cancelled |
|
|
93
|
+
|
|
94
|
+
**Other syntax:**
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
>> Milestone name | after:id | +deadline ← milestone; +deadline draws a full-height line
|
|
98
|
+
parallel: name ← parallel block start
|
|
99
|
+
end: name ← parallel block end
|
|
100
|
+
[ ] Task | blocked 2w ← externally blocked for 2 weeks (red ghost)
|
|
101
|
+
[ ] Task | delayed 3d ← running 3 days late (orange overrun)
|
|
102
|
+
[ ] Task | 5bd ← 5 business days
|
|
103
|
+
[ ] Task | 2026-04-01 ← fixed start date
|
|
104
|
+
[ ] Task | !high ← priority: low / normal / high / critical
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## The server
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
yatt serve [folder] [--port 3000]
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Four views, switchable by tab:
|
|
116
|
+
|
|
117
|
+
| View | What you see |
|
|
118
|
+
|---|---|
|
|
119
|
+
| **Timeline** | Minimal Gantt — lines and circles, hover for details |
|
|
120
|
+
| **Kanban** | Columns by status; drag to reassign; empty columns collapse to slim strips |
|
|
121
|
+
| **People** | Tasks grouped by assignee |
|
|
122
|
+
| **Edit** | Raw YATT source with live save |
|
|
123
|
+
|
|
124
|
+
Click any task in any view to open the **edit modal** — change status, assignees, dates, priority, delayed/blocked duration, and description.
|
|
125
|
+
|
|
126
|
+
### Git integration
|
|
127
|
+
|
|
128
|
+
The top bar shows your current branch and sync state. No terminal needed for day-to-day use:
|
|
129
|
+
|
|
130
|
+
- **Pull** — fetch and merge the latest from remote
|
|
131
|
+
- **Commit** — stages everything (`git add -A`) and commits with your message
|
|
132
|
+
- **Push** — pushes to remote
|
|
133
|
+
|
|
134
|
+
Merge conflicts and auth are left to the CLI — YATT surfaces the error and tells you to resolve from the terminal.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Key features
|
|
139
|
+
|
|
140
|
+
- **Descriptions** — `//` comment lines immediately after a task become its description (shown in hover card and list view)
|
|
141
|
+
- **Dependencies** — `after:a,b` (AND), `after:a|b` (OR), cross-block by ID
|
|
142
|
+
- **Parallel workstreams** — `parallel: name` … `end: name`
|
|
143
|
+
- **Subtasks** — leading `.` or `..` (sequential within parent)
|
|
144
|
+
- **Progress** — `%60` renders as a bright leading segment on the timeline bar
|
|
145
|
+
- **Delayed / blocked** — `delayed 3d` extends the end; `blocked 2w` shifts the start; both show ghost indicators
|
|
146
|
+
- **Business days** — `5bd` or header `schedule: business-days`
|
|
147
|
+
- **Milestones** — `>> name | +deadline`
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Examples
|
|
152
|
+
|
|
153
|
+
| File | Description |
|
|
154
|
+
|---|---|
|
|
155
|
+
| [01-hello-world.md](./examples/01-hello-world.md) | Simplest chart — sequential tasks with descriptions |
|
|
156
|
+
| [02-team-sprint.md](./examples/02-team-sprint.md) | Sprint with statuses, assignees, priorities, dependencies |
|
|
157
|
+
| [03-product-launch.md](./examples/03-product-launch.md) | Phased launch with milestones, subtasks, cross-phase deps |
|
|
158
|
+
| [04-parallel-workstreams.md](./examples/04-parallel-workstreams.md) | Multiple workstreams converging on shared milestones |
|
|
159
|
+
| [05-enterprise-program.md](./examples/05-enterprise-program.md) | Full-scale program — all features combined |
|
|
160
|
+
| [06-delays-and-blocks.md](./examples/06-delays-and-blocks.md) | `delayed X` and `blocked X` with ghost indicators |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Documentation
|
|
165
|
+
|
|
166
|
+
- [SPEC.md](./SPEC.md) — Full language reference
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
MIT
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# YATT Language Specification
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Syntax Cheatsheet
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
title: My Project
|
|
9
|
+
start: 2026-04-01
|
|
10
|
+
schedule: business-days
|
|
11
|
+
|
|
12
|
+
# Section name
|
|
13
|
+
|
|
14
|
+
[ ] Task name | 3d | @alice | #tag | !high | %40 | id:slug | after:other | <2026-05-01
|
|
15
|
+
// Optional description line (immediately follows the task)
|
|
16
|
+
// More description — shown as tooltip or annotation.
|
|
17
|
+
|
|
18
|
+
[~] Active task | 2bd | @bob | delayed 2d
|
|
19
|
+
[x] Done task | 1w | @carol | %100
|
|
20
|
+
[~] Blocked | 4d | @dave | blocked 1w
|
|
21
|
+
[=] In review | 2d
|
|
22
|
+
[?] At risk | 3d | !high
|
|
23
|
+
[>] Deferred | 2d
|
|
24
|
+
[_] Cancelled | 1d
|
|
25
|
+
|
|
26
|
+
>> Milestone name | >2026-05-15 | +deadline | id:ms
|
|
27
|
+
|
|
28
|
+
parallel: workstream-name | after:slug
|
|
29
|
+
[ ] Task A | 3d
|
|
30
|
+
[ ] Task B | 2d
|
|
31
|
+
end: workstream-name
|
|
32
|
+
|
|
33
|
+
[~] Parent task | 5d | id:parent
|
|
34
|
+
. [x] Sub one | 2d
|
|
35
|
+
. [ ] Sub two | 3d
|
|
36
|
+
.. [ ] Nested | 1d
|
|
37
|
+
|
|
38
|
+
*daily Standup | 15m | @team
|
|
39
|
+
*weekly Review | 1h
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Header Block
|
|
45
|
+
|
|
46
|
+
`key: value` lines at the top of the file, before any task lines. All fields are optional.
|
|
47
|
+
|
|
48
|
+
| Field | Type | Default | Description |
|
|
49
|
+
|---|---|---|---|
|
|
50
|
+
| `title` | string | `"Untitled"` | Display name |
|
|
51
|
+
| `start` | `YYYY-MM-DD` | today | Absolute schedule start date |
|
|
52
|
+
| `end` | `YYYY-MM-DD` | derived | Optional hard end date |
|
|
53
|
+
| `schedule` | `calendar-days` \| `business-days` | `calendar-days` | Default duration semantics |
|
|
54
|
+
| `timezone` | IANA timezone | `UTC` | For date calculations |
|
|
55
|
+
| `locale` | BCP 47 tag | `en` | Date formatting in output |
|
|
56
|
+
| `owner` | string | — | Default assignee for tasks without `@` |
|
|
57
|
+
| `week-start` | `mon` \| `sun` | `mon` | First day of week |
|
|
58
|
+
| `version` | string | — | Free-form version label |
|
|
59
|
+
|
|
60
|
+
Header parsing ends at the first non-header, non-blank, non-comment line.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Line Classification
|
|
65
|
+
|
|
66
|
+
Lines are classified in this order (first match wins):
|
|
67
|
+
|
|
68
|
+
| Pattern | Classification |
|
|
69
|
+
|---|---|
|
|
70
|
+
| Starts with `//` | Comment / task description |
|
|
71
|
+
| `key: value` in header zone | Header field |
|
|
72
|
+
| Starts with `#` + space | Section header |
|
|
73
|
+
| Starts with `>>` | Milestone |
|
|
74
|
+
| Starts with `parallel:` | Parallel block open |
|
|
75
|
+
| Starts with `end:` | Parallel block close |
|
|
76
|
+
| Starts with `*` | Recurring task |
|
|
77
|
+
| Starts with `.`+ space + `[` | Subtask |
|
|
78
|
+
| Starts with `[` | Task |
|
|
79
|
+
| Blank line | Ignored |
|
|
80
|
+
| Anything else | Parse warning; line skipped |
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Task Syntax
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
[status] Task name | field | field | field ...
|
|
88
|
+
// Optional description line
|
|
89
|
+
// Another description line
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The status token uses either sigil or word form. The task name is everything after `]` up to the first `|`, trimmed. Fields are pipe-separated and order-independent.
|
|
93
|
+
|
|
94
|
+
**Task descriptions:** `//` lines immediately following a task (with no blank line in between) are that task's description. They are displayed as a tooltip or annotation in rendered output. Standalone `//` lines not immediately following a task are ignored by the parser.
|
|
95
|
+
|
|
96
|
+
### Status Vocabulary
|
|
97
|
+
|
|
98
|
+
| Sigil | Word | Colour | Scheduling |
|
|
99
|
+
|---|---|---|---|
|
|
100
|
+
| `[ ]` | `new` | steel blue | Normal |
|
|
101
|
+
| `[~]` | `active` | blue | Normal |
|
|
102
|
+
| `[x]` | `done` | green | Normal (historical) |
|
|
103
|
+
| `[!]` | `blocked` | red + stripes | Normal (chain continues unless `+hard-block`) |
|
|
104
|
+
| `[?]` | `at-risk` | amber | Normal |
|
|
105
|
+
| `[>]` | `deferred` | purple | Skipped in chain (zero-duration for deps) |
|
|
106
|
+
| `[_]` | `cancelled` | grey + strikethrough | Fully excluded |
|
|
107
|
+
| `[=]` | `review` | violet | Normal |
|
|
108
|
+
| `[o]` | `paused` | slate-dark | Normal |
|
|
109
|
+
|
|
110
|
+
`deferred` — the following task starts where the deferred task would have started.
|
|
111
|
+
`cancelled` — fully excluded; downstream `after:` references resolve to its start date.
|
|
112
|
+
|
|
113
|
+
### Field Reference
|
|
114
|
+
|
|
115
|
+
| Sigil | Name | Example | Notes |
|
|
116
|
+
|---|---|---|---|
|
|
117
|
+
| (no sigil) | duration | `3d`, `2bd`, `1w` | Defaults to `1d` if absent |
|
|
118
|
+
| `@` | assignee | `@alice`, `@alice @bob` | Multiple: space-separated or repeat `@` fields |
|
|
119
|
+
| `#` | tag | `#backend` | Multiple allowed |
|
|
120
|
+
| `!` | priority | `!high` | `critical` / `high` / `medium` / `low` |
|
|
121
|
+
| `%` | progress | `%40` | Integer 0–100; fills bar |
|
|
122
|
+
| `id:` | task ID | `id:auth-refactor` | Slug; unique per document |
|
|
123
|
+
| `after:` | dependency | `after:a,b` / `after:a\|b` | AND (comma) or OR (pipe) |
|
|
124
|
+
| `+` | modifier | `+deadline`, `+fixed` | See Modifiers section |
|
|
125
|
+
| (space-separated) | time-shift | `delayed 3d`, `blocked 2w` | See Time-shift Modifiers |
|
|
126
|
+
| `>` | start floor | `>2026-03-01` | Task can't start before this date |
|
|
127
|
+
| `<` | soft due date | `<2026-03-31` | Flags overrun visually |
|
|
128
|
+
| `$` | ticket ref | `$JIRA-42` | Opaque; rendered as link if URL template configured |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Duration Grammar
|
|
133
|
+
|
|
134
|
+
A duration is a positive number (integer or decimal) followed immediately by a unit suffix, no spaces.
|
|
135
|
+
|
|
136
|
+
| Suffix | Meaning | Respects `schedule` setting? |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| `h` | Hours | No — always calendar hours |
|
|
139
|
+
| `d` | Calendar or business days | Yes |
|
|
140
|
+
| `bd` | Business days | Always business days |
|
|
141
|
+
| `w` | Weeks (7 calendar days) | No |
|
|
142
|
+
| `m` | Calendar months | No |
|
|
143
|
+
| `q` | Quarters (3 months) | No |
|
|
144
|
+
|
|
145
|
+
Examples: `3d`, `5bd`, `2w`, `1.5h`, `0.5m`, `1q`. Decimal durations are valid. Compound durations (`2w3d`) are not supported.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Scheduling Model
|
|
150
|
+
|
|
151
|
+
Tasks are scheduled sequentially by default — Task N starts the day after Task N−1 ends. The first task starts on the document `start` date.
|
|
152
|
+
|
|
153
|
+
**Start date resolution (in order of precedence):**
|
|
154
|
+
|
|
155
|
+
1. `after:` dependencies — start is the maximum end date of all resolved deps (AND) or minimum (OR).
|
|
156
|
+
2. `>start-date` field — task cannot start before this date; whichever is later wins.
|
|
157
|
+
3. Sequential position — starts immediately after the preceding task ends.
|
|
158
|
+
|
|
159
|
+
`deferred` and `cancelled` tasks are skipped in the sequential chain. `done` tasks occupy their slot normally (start + duration); they are historical.
|
|
160
|
+
|
|
161
|
+
`+fixed` combined with `>date` pins the task absolutely — no upstream dependency can push it later.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Parallel Blocks
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
parallel: blockname | after:other | >start-date
|
|
169
|
+
[ ] Task A | 3d | @alice
|
|
170
|
+
[ ] Task B | 2d | @bob
|
|
171
|
+
end: blockname
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Tasks within a block are scheduled sequentially among themselves, starting at the block's anchor point. Multiple parallel blocks opening at the same document position run concurrently — they do not advance the outer sequential chain. The block name is its implicit ID for `after:` references.
|
|
175
|
+
|
|
176
|
+
**Block completion:** `after:blockname` resolves to the end date of the last task in that block (the latest end across all members). To sequence the outer chain after parallel blocks, use explicit `after:` references:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
parallel: phase-a
|
|
180
|
+
[ ] Work A | 3d
|
|
181
|
+
end: phase-a
|
|
182
|
+
|
|
183
|
+
parallel: phase-b
|
|
184
|
+
[ ] Work B | 2d
|
|
185
|
+
end: phase-b
|
|
186
|
+
|
|
187
|
+
[ ] Integration | 2d | after:phase-a,phase-b
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Block names and task IDs share the same namespace. Nested parallel blocks are not supported.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Task IDs and Dependencies
|
|
195
|
+
|
|
196
|
+
**IDs** (`id:slug`) are slugs (lowercase letters, digits, hyphens), unique within the document. Tasks without an `id:` cannot be referenced by `after:`. Subtask IDs are in the same global namespace as top-level IDs.
|
|
197
|
+
|
|
198
|
+
**AND dependency** (`after:a,b`) — starts after all listed deps have ended.
|
|
199
|
+
**OR dependency** (`after:a|b`) — starts after any one dep has ended.
|
|
200
|
+
AND and OR cannot be mixed on the same `after:` field.
|
|
201
|
+
|
|
202
|
+
The parser performs cycle detection after resolving all `after:` references. A circular dependency is a parse error.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Subtasks
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
[~] Parent task | 5d | @alice | id:parent
|
|
210
|
+
. [x] Research | 1d
|
|
211
|
+
. [~] Implement | 3d | id:impl
|
|
212
|
+
.. [ ] Unit tests | 1d
|
|
213
|
+
.. [ ] Integration| 1d | after:impl
|
|
214
|
+
. [ ] Review | 1d
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Leading dots indicate depth: `.` = level 1, `..` = level 2, `...` = level 3. Subtasks are scheduled sequentially within the parent, starting at the parent's start date.
|
|
218
|
+
|
|
219
|
+
If the parent has no explicit duration, it is computed as the sum of its subtasks' durations. If the parent has no explicit `%progress`, it is the weighted average of subtask progress (by duration).
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Milestones
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
>> Milestone name | >2026-03-15 | +deadline | id:go-live | after:phase1
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Milestones have zero duration and appear as a point (diamond ◆) on the timeline. If a `>date` field is present, the milestone is pinned to that date; otherwise its date is the end of the preceding sequential element. Milestones accept `id:`, `after:`, `>`, `+modifier`, `@`, and `#` fields. They participate in the sequential chain (zero duration — start and end are the same day).
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Modifiers
|
|
234
|
+
|
|
235
|
+
Modifiers are `+keyword` fields that attach flags to tasks or milestones.
|
|
236
|
+
|
|
237
|
+
| Modifier | Scheduling Effect | Rendering Effect |
|
|
238
|
+
|---|---|---|
|
|
239
|
+
| `+deadline` | Emits overrun warning if computed end > `<due-date` | Red flag/diamond at due date |
|
|
240
|
+
| `+fixed` | Pins task to `>start-date`; deps cannot push it later | Lock icon or hatched bar |
|
|
241
|
+
| `delayed X` | Shifts start+end forward by X; stores original as `plannedStart`/`plannedEnd` | Orange ghost bar at original position |
|
|
242
|
+
| `blocked X` | Same time-shift; semantically: held up externally | Red ghost bar at original position |
|
|
243
|
+
| `+hard-block` | Stops sequential chain at this blocked task | — |
|
|
244
|
+
| `+external` | None | Different bar colour (third-party/vendor work) |
|
|
245
|
+
| `+critical` | None | Bold/bright bar (critical path) |
|
|
246
|
+
| `+tentative` | None | Dashed bar or diamond outline |
|
|
247
|
+
| `+at-risk` | None | Yellow warning icon |
|
|
248
|
+
| `+waiting` | None | Clock icon |
|
|
249
|
+
|
|
250
|
+
### Time-Shift Modifiers
|
|
251
|
+
|
|
252
|
+
`delayed X` and `blocked X` accept a duration value (`3d`, `2w`, `1bd`, etc.) and push the task's computed start and end forward by that amount. The original (unshifted) dates are preserved and rendered as a ghost bar:
|
|
253
|
+
|
|
254
|
+
- **`delayed X`** — internal slip (team-side). Ghost bar is **orange**.
|
|
255
|
+
- **`blocked X`** — held up by an external factor for a known duration. Ghost bar is **red**.
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
[~] API integration | 5d | @alice | delayed 3d
|
|
259
|
+
// Was planned for Mon; environment issues pushed start to Thu.
|
|
260
|
+
|
|
261
|
+
[~] SWIFT certification | 8d | @carol | blocked 2w
|
|
262
|
+
// Waiting on SWIFT sandbox credentials — estimated 2-week hold.
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Both can be applied to the same task; shifts are applied sequentially.
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Recurring Tasks
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
*daily Standup | 15m | @team
|
|
273
|
+
*weekday Async update | 5m | @team
|
|
274
|
+
*weekly Sprint planning | 2h | @team
|
|
275
|
+
*biweekly Architecture sync | 1h | @leads
|
|
276
|
+
*monthly Stakeholder review | 2h | @pm
|
|
277
|
+
*quarterly Business review | 3h | @exec
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Recurring tasks do not participate in the sequential scheduling chain and do not affect other tasks' start dates. They are rendered as repeating blocks across the document's date range.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Sections and Comments
|
|
285
|
+
|
|
286
|
+
**Sections** (`#` or `##` + space + name) group tasks visually. They have no effect on scheduling. A renderer may draw a divider row with the section label.
|
|
287
|
+
|
|
288
|
+
**Standalone comments** (`//` lines not immediately following a task) are ignored by the parser. A `//` sequence within a task name or field value is treated as literal characters.
|
|
289
|
+
|
|
290
|
+
**Task descriptions** (`//` lines immediately following a task, with no blank line) are attached to that task as its description. See Task Syntax above.
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Formal Grammar
|
|
295
|
+
|
|
296
|
+
PEG-style sketch (informative, not normative):
|
|
297
|
+
|
|
298
|
+
```peg
|
|
299
|
+
Document <- Header? Body
|
|
300
|
+
Header <- HeaderLine+
|
|
301
|
+
HeaderLine <- Key ":" SP Value NL
|
|
302
|
+
Key <- [a-z] [a-z0-9-]*
|
|
303
|
+
Value <- (!NL .)+
|
|
304
|
+
|
|
305
|
+
Body <- BodyLine*
|
|
306
|
+
BodyLine <- Comment / Section / Milestone / ParallelOpen
|
|
307
|
+
/ ParallelClose / RecurringTask / Subtask / Task
|
|
308
|
+
/ BlankLine
|
|
309
|
+
|
|
310
|
+
Comment <- "//" (!NL .)* NL
|
|
311
|
+
Section <- "#"+ SP Name NL
|
|
312
|
+
Name <- (!NL .)+
|
|
313
|
+
|
|
314
|
+
Milestone <- ">>" SP Name PipeFields? NL
|
|
315
|
+
|
|
316
|
+
ParallelOpen <- "parallel:" SP BlockName PipeFields? NL
|
|
317
|
+
ParallelClose <- "end:" (SP BlockName)? NL
|
|
318
|
+
BlockName <- [a-zA-Z0-9_-]+
|
|
319
|
+
|
|
320
|
+
RecurringTask <- "*" RecurToken SP Name PipeFields? NL
|
|
321
|
+
RecurToken <- "daily" / "weekday" / "weekly" / "biweekly"
|
|
322
|
+
/ "monthly" / "quarterly"
|
|
323
|
+
|
|
324
|
+
Subtask <- Dots SP "[" Status "]" SP Name PipeFields? NL
|
|
325
|
+
Dots <- "." / ".." / "..."
|
|
326
|
+
|
|
327
|
+
Task <- "[" Status "]" SP Name PipeFields? NL
|
|
328
|
+
|
|
329
|
+
Status <- " " / "~" / "x" / "!" / "?" / ">" / "_" / "=" / "o"
|
|
330
|
+
/ "new" / "active" / "done" / "blocked" / "at-risk"
|
|
331
|
+
/ "deferred" / "cancelled" / "review" / "paused"
|
|
332
|
+
|
|
333
|
+
PipeFields <- (SP? "|" SP? Field)+
|
|
334
|
+
Field <- DurationField / AssigneeField / TagField / PriorityField
|
|
335
|
+
/ ProgressField / IdField / AfterField / ModifierField / ShiftField
|
|
336
|
+
/ StartDateField / DueDateField / TicketField
|
|
337
|
+
|
|
338
|
+
DurationField <- NUMBER ("h" / "bd" / "d" / "w" / "m" / "q")
|
|
339
|
+
AssigneeField <- "@" [a-zA-Z0-9_-]+ (SP "@" [a-zA-Z0-9_-]+)*
|
|
340
|
+
TagField <- "#" [a-zA-Z0-9_-]+
|
|
341
|
+
PriorityField <- "!" ("critical" / "high" / "medium" / "low")
|
|
342
|
+
ProgressField <- "%" [0-9]+ ("%"?)
|
|
343
|
+
IdField <- "id:" Slug
|
|
344
|
+
AfterField <- "after:" Slug ("," Slug)* / "after:" Slug ("|" Slug)*
|
|
345
|
+
ModifierField <- "+" ModifierWord
|
|
346
|
+
ShiftField <- ("delayed" / "blocked") SP DurationField
|
|
347
|
+
StartDateField <- ">" ISODate
|
|
348
|
+
DueDateField <- "<" ISODate
|
|
349
|
+
TicketField <- "$" [A-Z0-9_-]+
|
|
350
|
+
|
|
351
|
+
Slug <- [a-z0-9-]+
|
|
352
|
+
ISODate <- [0-9]{4} "-" [0-9]{2} "-" [0-9]{2}
|
|
353
|
+
NUMBER <- [0-9]+ ("." [0-9]+)?
|
|
354
|
+
SP <- " "+
|
|
355
|
+
NL <- "\n" / "\r\n"
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Rendering Model
|
|
361
|
+
|
|
362
|
+
A rendered YATT document is a horizontal Gantt chart with one row per task, subtask, and milestone; section headers as divider rows; and a date axis scaled to the full document range.
|
|
363
|
+
|
|
364
|
+
**Bar colours by status:** `new` → steel blue · `active` → blue · `done` → green · `blocked` → red stripes · `at-risk` → amber · `deferred` → grey · `cancelled` → light grey + strikethrough · `review` → violet · `paused` → slate-dark.
|
|
365
|
+
|
|
366
|
+
**Progress fill:** `%progress` splits the bar — filled portion uses the status colour; remainder uses a lighter tint. `%100` renders identically to `done`.
|
|
367
|
+
|
|
368
|
+
**Standard annotations:** today line (vertical dashed), overrun highlight (if computed end > `<due-date`), assignee initials on bars, optional dependency arrows, hover tooltips on interactive renderers.
|