Skip to content

Commit 219c6d3

Browse files
koki-developclaude
andcommitted
docs: archive task-due-date change and sync specs
Move the completed task-due-date change to archive/ and apply its deltas to the living specs: new task-dates capability spec, and mcp-server spec updated with the date field on list_tasks output and the create_task date input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1ac2d42 commit 219c6d3

8 files changed

Lines changed: 224 additions & 6 deletions

File tree

openspec/changes/task-due-date/.openspec.yaml renamed to openspec/changes/archive/2026-06-12-task-due-date/.openspec.yaml

File renamed without changes.
File renamed without changes.
File renamed without changes.

openspec/changes/task-due-date/specs/mcp-server/spec.md renamed to openspec/changes/archive/2026-06-12-task-due-date/specs/mcp-server/spec.md

File renamed without changes.

openspec/changes/task-due-date/specs/task-dates/spec.md renamed to openspec/changes/archive/2026-06-12-task-due-date/specs/task-dates/spec.md

File renamed without changes.

openspec/changes/task-due-date/tasks.md renamed to openspec/changes/archive/2026-06-12-task-due-date/tasks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@
5656
## 9. 検証
5757

5858
- [x] 9.1 `bunx tsc --noEmit` / `bun run lint` / `bun run fmt:check` が通ることを確認
59-
- [ ] 9.2 `bun run tauri dev` で手動スモーク: 作成ダイアログでのカレンダー選択・直接入力・クリア、詳細ダイアログでの auto-save、カードの各カテゴリ表示(today/tomorrow/soon/overdue/far/なし)、frontmatter のラウンドトリップ
59+
- [x] 9.2 `bun run tauri dev` で手動スモーク: 作成ダイアログでのカレンダー選択・直接入力・クリア、詳細ダイアログでの auto-save、カードの各カテゴリ表示(today/tomorrow/soon/overdue/far/なし)、frontmatter のラウンドトリップ

openspec/specs/mcp-server/spec.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,22 @@ Cork プロセス起動時、`tauri_plugin_store` の `settings.json` の `mcp`
8383

8484
### Requirement: MCP サーバは `list_tasks` ツールを公開する
8585

86-
サーバは MCP 仕様の `tools/list``list_tasks` ツール 1 件のみを返す。クライアントが `tools/call``list_tasks` を呼ぶと、現セッションの workspace ディレクトリを直接読み、`frontmatter``status` フィールドが設定されている `.md` ファイルだけを抽出し、オプショナルな `query` / `filters` 引数でフィルタリングした結果を `{ "tasks": [{ title, file_path, status, tags }] }` として返す
86+
サーバは MCP 仕様の `tools/list``list_tasks` ツール 1 件のみを返さなければならない (MUST)。クライアントが `tools/call``list_tasks` を呼ぶと、現セッションの workspace ディレクトリを直接読み、`frontmatter``status` フィールドが設定されている `.md` ファイルだけを抽出し、オプショナルな `query` / `filters` 引数でフィルタリングした結果を `{ "tasks": [{ title, file_path, status, tags, date }] }` として返さなければならない (MUST)
8787

8888
ツールは以下のオプショナル引数を受け付ける:
8989

9090
- `query`(任意、文字列): タイトルに対する fuzzy 検索。大文字小文字を区別せず、部分一致・非連続一致を許容する。空文字列または未指定の場合はフィルタリングなし。
9191
- `filters`(任意、配列): タグフィルターのリスト。各要素は `operator` で識別される discriminated union。複数指定時は AND 結合される。空配列または未指定の場合はフィルタリングなし。
9292

93-
MCP 仕様は `outputSchema` の root が `object` であることを要求するため、タスク配列は単一フィールド `tasks` を持つオブジェクトでラップする。`title` はファイル名 (拡張子なし)、`file_path` はファイルの絶対パス、`status``tags` は frontmatter の値。タスクが 1 件もない workspace に対しては `{ "tasks": [] }` を返す (エラーではない)。引数なしの呼び出しは従来通り全タスクを返す(後方互換性維持)。
93+
MCP 仕様は `outputSchema` の root が `object` であることを要求するため、タスク配列は単一フィールド `tasks` を持つオブジェクトでラップする。`title` はファイル名 (拡張子なし)、`file_path` はファイルの絶対パス、`status``tags` は frontmatter の値。各タスクは frontmatter の期日を表す `date` フィールドを含まなければならない (MUST) — 値は正準形 `YYYY-MM-DD` の文字列、未設定 / 不正値の場合は `null`タスクが 1 件もない workspace に対しては `{ "tasks": [] }` を返す (エラーではない)。引数なしの呼び出しは従来通り全タスクを返す(後方互換性維持)。
9494

9595
#### Scenario: タスクが複数ある workspace
9696

97-
- **WHEN** workspace に `Todo.md` (frontmatter `status: Todo`, `tags: [a, b]`) と `Doing.md` (frontmatter `status: Doing`) と `NoStatus.md` (frontmatter 無し) が含まれる状態で `list_tasks` を呼ぶ
97+
- **WHEN** workspace に `Todo.md` (frontmatter `status: Todo`, `tags: [a, b]`, `date: 2026-06-15`) と `Doing.md` (frontmatter `status: Doing`) と `NoStatus.md` (frontmatter 無し) が含まれる状態で `list_tasks` を呼ぶ
9898
- **THEN** レスポンスの `tasks` 配列には 2 件のタスク (`Todo.md``Doing.md`) のみが含まれる
9999
- **AND** `NoStatus.md` は含まれない
100-
- **AND** 各タスクは `title`, `file_path`, `status`, `tags` の 4 フィールドのみを持ち、`body``order` は含まれない
100+
- **AND** 各タスクは `title`, `file_path`, `status`, `tags`, `date` の 5 フィールドのみを持ち、`body``order` は含まれない
101+
- **AND** `Todo.md``date``"2026-06-15"``Doing.md``date``null` である
101102

102103
#### Scenario: タスクが 0 件の workspace
103104

@@ -109,7 +110,7 @@ MCP 仕様は `outputSchema` の root が `object` であることを要求す
109110
- **WHEN** クライアントが `tools/list` リクエストを送る
110111
- **THEN** レスポンスには `list_tasks` ツール 1 件のみが含まれる
111112
- **AND** ツールスキーマには `query`(任意、文字列)と `filters`(任意、配列)の入力パラメータが含まれる
112-
- **AND** 出力スキーマは root が `object``tasks` プロパティ (要素が `title`, `file_path`, `status`, `tags` の 4 フィールドを持つ array) のみを含む
113+
- **AND** 出力スキーマは root が `object``tasks` プロパティ (要素が `title`, `file_path`, `status`, `tags`, `date` の 5 フィールドを持つ array) のみを含む
113114

114115
#### Scenario: query によるタイトル検索
115116

@@ -144,6 +145,27 @@ MCP 仕様は `outputSchema` の root が `object` であることを要求す
144145
- **WHEN** `filters: []` を指定する
145146
- **THEN** フィルタリングは行われず、全タスクが返される
146147

148+
### Requirement: MCP `create_task` ツールはオプショナルな期日を受け付ける
149+
150+
MCP の `create_task` ツールは、オプショナルな入力パラメータ `date`(任意、文字列)を受け付けなければならない (MUST)。正準形 `YYYY-MM-DD` が渡された場合、作成されるタスクの frontmatter に `date` を書き出さなければならない (MUST)。未指定の場合は frontmatter に `date` キーを出力してはならない (MUST NOT)。正準形でない値が渡された場合はエラーを返さなければならない (MUST)。ツールが返す `task` オブジェクトは、`list_tasks` と同じ `McpTask` 形状(`title`, `file_path`, `status`, `tags`, `date`)を持つ。
151+
152+
#### Scenario: 期日付きでタスクを作成する
153+
154+
- **WHEN** `create_task``title="Ship release"`, `status="Doing"`, `date="2026-06-20"` で呼ばれる
155+
- **THEN** 新規 `.md` ファイルが作成され、その frontmatter に `date: 2026-06-20` が含まれる
156+
- **AND** レスポンスの `task.date``"2026-06-20"` である
157+
158+
#### Scenario: 期日未指定でタスクを作成する
159+
160+
- **WHEN** `create_task``date` 未指定で呼ばれる
161+
- **THEN** 新規ファイルの frontmatter に `date:` キーは含まれない
162+
- **AND** レスポンスの `task.date``null` である
163+
164+
#### Scenario: 不正な期日値はエラーになる
165+
166+
- **WHEN** `create_task``date="2026/6/5"`(非正準形)で呼ばれる
167+
- **THEN** ツールはエラーを返し、タスクは作成されない
168+
147169
### Requirement: MCP 設定はグローバルに永続化される
148170

149171
MCP 設定 (`enabled`, `token`) は `tauri_plugin_store` の既存ストア `settings.json` の新規トップレベルキー `mcp` 配下にネスト保存される。これらの設定はプロセス全体に対して 1 セット (window 単位や workspace 単位ではない)。`workspace_history` / `workspaces` (per-workspace filters) など `settings.json` の既存キーには干渉しない。ポートは UI から変更できず、コード内の `DEFAULT_PORT = 8569` 定数が単一の真実の源 (Single Source of Truth)。

openspec/specs/task-dates/spec.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# task-dates Specification
2+
3+
## Purpose
4+
5+
TBD - created by archiving change task-due-date. Update Purpose after archive.
6+
7+
## Requirements
8+
9+
### Requirement: タスクは frontmatter `date` で単一の期日を保持できる
10+
11+
タスクの Markdown ファイルは YAML frontmatter キー `date``YYYY-MM-DD` 形式(時刻なし、ゼロ埋めの月日)の文字列で単一の期日を保持できる (SHALL)。`date` が未定義 / `null` / 空文字 / 正準形 `YYYY-MM-DD` 以外の値の場合、システムは当該タスクを「期日なし」状態として扱わなければならない (MUST)。
12+
13+
#### Scenario: 正準形の日付をパースして読み出せる
14+
15+
- **GIVEN** ワークスペース直下の `task-a.md` の frontmatter に `date: 2026-06-15` が記述されている
16+
- **WHEN** フロントエンドが `list_tasks` または `get_task` を invoke する
17+
- **THEN** 当該タスクの `Task.date` は文字列 `"2026-06-15"` で返る
18+
19+
#### Scenario: `date` キー欠落は期日なしとして扱われる
20+
21+
- **GIVEN** タスクの frontmatter に `date` キーが存在しない
22+
- **WHEN** `list_tasks` または `get_task` が当該タスクを返す
23+
- **THEN** `Task.date``null` として返る
24+
- **AND** フロントエンドは「期日なしタスク」として扱う(カードの期日バッジが非表示になる)
25+
26+
#### Scenario: `date: null` は期日なしとして扱われる
27+
28+
- **GIVEN** タスクの frontmatter に `date: null` が記述されている
29+
- **WHEN** `list_tasks` または `get_task` が当該タスクを返す
30+
- **THEN** `Task.date``null` として返る
31+
- **AND** ファイル読み取りは失敗しない
32+
33+
#### Scenario: 正準形でない日付値は期日なしにフォールバックする
34+
35+
- **GIVEN** タスクの frontmatter に `date: 2026/6/5`(スラッシュ区切り・非ゼロ埋め)が記述されている
36+
- **WHEN** `list_tasks` または `get_task` が当該タスクを返す
37+
- **THEN** 当該タスクの `Task.date``null` として返る
38+
- **AND** タスク自体は無視されず、他フィールド(title / status / body / tags)は通常通り読み出される
39+
40+
#### Scenario: 日付の serialize / parse がラウンドトリップする
41+
42+
- **GIVEN** アプリ経由で `date``"2026-06-15"` が書き込まれる
43+
- **WHEN** 当該ファイルを再度パースする
44+
- **THEN** `Task.date` は文字列 `"2026-06-15"` に戻る
45+
- **AND** YAML の date 型や数値ではなく、文字列として安定的に往復する
46+
47+
### Requirement: `create_task` コマンドは期日を受け取って frontmatter に書き出す
48+
49+
`create_task` Tauri コマンドは、オプションパラメータ `date: Option<String>` を受け付けなければならない (MUST)。`Some(_)` で正準形 `YYYY-MM-DD` が渡された場合、frontmatter キー `date` に書き出さなければならない (MUST)。`None` または空文字の場合、frontmatter に `date` キーを出力してはならない (MUST NOT)。
50+
51+
#### Scenario: 期日付きでタスクを作成する
52+
53+
- **WHEN** `create_task``title="Ship release"`, `status="Doing"`, `date=Some("2026-06-20")` で呼ばれる
54+
- **THEN** 新規 `.md` ファイルが作成され、その frontmatter に `date: 2026-06-20` が含まれる
55+
- **AND** 戻り値の `Task.date``"2026-06-20"` である
56+
57+
#### Scenario: 期日未指定でタスクを作成する
58+
59+
- **WHEN** `create_task``date=None` で呼ばれる
60+
- **THEN** 新規ファイルの frontmatter に `date:` キーは含まれない
61+
- **AND** 戻り値の `Task.date``null` である
62+
63+
### Requirement: `update_task` コマンドは期日を Keep / Set / Clear の 3 状態で更新する
64+
65+
`update_task` Tauri コマンドは、オプションパラメータ `date: Option<String>` を受け付けなければならない (MUST)。値は `tags` と同一のセマンティクスで解釈される:
66+
67+
- `None`(未指定): 既存の `date` を維持する (Keep)。
68+
- `Some("")`(空文字): frontmatter の `date` キーを物理削除する (Clear)。
69+
- `Some(canonical)`(正準形 `YYYY-MM-DD`): frontmatter の `date` を当該値に設定する (Set)。
70+
71+
frontmatter の他フィールド(status / order / tags / body)および body は、`date` の更新によって変化してはならない (MUST NOT)。
72+
73+
#### Scenario: 期日を新規設定する
74+
75+
- **GIVEN** `date` キーを持たないタスク
76+
- **WHEN** `update_task``date=Some("2026-07-01")` で呼ばれる
77+
- **THEN** frontmatter に `date: 2026-07-01` が追加される
78+
- **AND** 戻り値の `Task.date``"2026-07-01"`
79+
80+
#### Scenario: 期日を別の日付に変更する
81+
82+
- **GIVEN** `date: 2026-06-15` を持つタスク
83+
- **WHEN** `update_task``date=Some("2026-06-20")` で呼ばれる
84+
- **THEN** frontmatter の `date``2026-06-20` に更新される
85+
86+
#### Scenario: 期日をクリアする
87+
88+
- **GIVEN** `date: 2026-06-15` を持つタスク
89+
- **WHEN** `update_task``date=Some("")` で呼ばれる
90+
- **THEN** frontmatter から `date` キーが削除される
91+
- **AND** 戻り値の `Task.date``null`
92+
- **AND** status / tags / order / body は変化しない
93+
94+
#### Scenario: 期日を維持する(未指定)
95+
96+
- **GIVEN** `date: 2026-06-15` を持つタスク
97+
- **WHEN** `update_task``date=None`(他フィールドのみ変更)で呼ばれる
98+
- **THEN** frontmatter の `date``2026-06-15` のまま維持される
99+
100+
### Requirement: ダイアログは期日入力欄とカレンダーポップオーバーを提供する
101+
102+
タスク作成ダイアログおよびタスク詳細ダイアログは、サイドバーに「Date」フィールドを持たなければならない (MUST)。当該フィールドはテキスト入力欄を持ち、フォーカス時にカレンダーをポップオーバーとして表示する (SHALL)。ユーザーはカレンダーからの日付選択、`YYYY-MM-DD` の直接入力、設定済み期日のクリアのいずれも行える (SHALL)。
103+
104+
#### Scenario: 入力欄フォーカスでカレンダーが開く
105+
106+
- **WHEN** ユーザーが「Date」フィールドの入力欄にフォーカスする
107+
- **THEN** カレンダーがポップオーバーとして表示される
108+
- **AND** ポップオーバーはモーダルダイアログの背景より前面に表示される
109+
110+
#### Scenario: カレンダーから日付を選択する
111+
112+
- **WHEN** ユーザーがカレンダー上の日をクリックする
113+
- **THEN** 入力欄に選択日が `YYYY-MM-DD` 形式で反映される
114+
- **AND** ポップオーバーが閉じる
115+
116+
#### Scenario: 期日を直接入力する
117+
118+
- **WHEN** ユーザーが入力欄に `2026-06-20` と直接入力して確定する
119+
- **THEN** 当該日付が期日として受理される
120+
- **AND** カレンダーの選択状態も同じ日付を示す
121+
122+
#### Scenario: 不正な入力は受理されない
123+
124+
- **WHEN** ユーザーが入力欄に `2026-13-40``abc` のような不正値を入力して確定する
125+
- **THEN** 当該値は期日として受理されない
126+
- **AND** フィールドは直前の有効値(または未設定)に戻る
127+
128+
#### Scenario: 期日をクリアする
129+
130+
- **GIVEN** 期日が設定済みのフィールド
131+
- **WHEN** ユーザーがクリア操作(× ボタン等)を行う
132+
- **THEN** 期日が未設定になる
133+
- **AND** 詳細ダイアログでは `update_task``date=""`(Clear)で auto-save される
134+
135+
#### Scenario: 詳細ダイアログでの期日変更が auto-save される
136+
137+
- **GIVEN** タスク詳細ダイアログが開いている
138+
- **WHEN** ユーザーが期日を変更する
139+
- **THEN** `tags` / `status` と同様に変更が即座に `update_task` で保存される
140+
141+
### Requirement: Kanban カードは期日を相対表示する
142+
143+
Kanban ボードのカードは、期日が設定されたタスクに対して、今日からの相対距離に応じたラベルと色で期日バッジを表示しなければならない (MUST)。期日が未設定のタスクには期日バッジを表示してはならない (MUST NOT)。相対距離 `diff`(= 期日 − 今日、ローカルカレンダー日単位)に基づくカテゴリ・ラベル・色は以下に従う:
144+
145+
| カテゴリ | 条件 | ラベル ||
146+
| -------- | ---------------- | --------------------- | --------------- |
147+
| overdue | `diff < 0` | 実日付(例 `Jun 5`| danger 赤 |
148+
| today | `diff == 0` | `Today` ||
149+
| tomorrow | `diff == 1` | `Tomorrow` | オレンジ |
150+
| soon | `2 <= diff <= 6` | 曜日名(例 `Monday`| 紫(accent 系) |
151+
| far | `diff >= 7` | 実日付(例 `Jun 20`| muted |
152+
153+
曜日名表示は `diff <= 6` までに限定する。`diff == 7` 以降は今日と同じ曜日名になり曖昧なため far として実日付を表示する。
154+
155+
#### Scenario: 今日が期日のカード
156+
157+
- **GIVEN** 期日が今日のタスク
158+
- **WHEN** カードが描画される
159+
- **THEN** バッジに `Today` が緑で表示される
160+
161+
#### Scenario: 明日が期日のカード
162+
163+
- **GIVEN** 期日が明日のタスク
164+
- **WHEN** カードが描画される
165+
- **THEN** バッジに `Tomorrow` がオレンジで表示される
166+
167+
#### Scenario: 数日以内の期日のカード
168+
169+
- **GIVEN** 期日が今日から 3 日後(例: 月曜)のタスク
170+
- **WHEN** カードが描画される
171+
- **THEN** バッジに曜日名(例 `Monday`)が紫系で表示される
172+
173+
#### Scenario: 期日超過のカード
174+
175+
- **GIVEN** 期日が過去のタスク
176+
- **WHEN** カードが描画される
177+
- **THEN** バッジに実日付が danger 赤で表示される
178+
179+
#### Scenario: 遠い未来の期日のカード
180+
181+
- **GIVEN** 期日が今日から 7 日以上後のタスク
182+
- **WHEN** カードが描画される
183+
- **THEN** バッジに実日付(例 `Jun 20`)が muted で表示される
184+
185+
#### Scenario: 別の暦年の期日は年も表示する
186+
187+
- **GIVEN** 期日が今日と異なる暦年(過去・未来いずれも)のタスク
188+
- **WHEN** カードが描画される
189+
- **THEN** バッジの実日付に年が付与される(例 今日が 2026 年で期日 2027-01-05 → `Jan 5, 2027`
190+
- **AND** 今日と同じ暦年の実日付には年が付かない(例 `Jun 20`
191+
192+
#### Scenario: 期日なしのカード
193+
194+
- **GIVEN** 期日が未設定のタスク
195+
- **WHEN** カードが描画される
196+
- **THEN** 期日バッジは表示されない

0 commit comments

Comments
 (0)