@fukuchang/taskchute-mcp 0.2.0 → 0.3.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/CHANGELOG.md +18 -0
- package/dist/index.js +16 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0 (2026-05-28) — 実績時刻の秒精度サポート
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `set_actual_times` の `start_time` / `end_time` が `HH:MM` に加え `HH:MM:SS`
|
|
8
|
+
も受け入れるようになった。秒は任意で、省略時は従来通り 0 として扱う。Web UI
|
|
9
|
+
でも実績時刻の入力 / 表示が秒精度で行えるようになり、Play ボタンを押した時刻
|
|
10
|
+
も秒単位で `actual_start_time` に記録される。
|
|
11
|
+
|
|
12
|
+
### Notes
|
|
13
|
+
|
|
14
|
+
- 後方互換あり: 既存の `HH:MM` 入力 / 保存データはそのまま動く。Supabase の
|
|
15
|
+
時刻カラムは TEXT のためマイグレーション不要
|
|
16
|
+
- `start_task` / 並列タスク / 割り込みタスクで記録される `actual_start_time`
|
|
17
|
+
は今後 `HH:MM:SS` 形式で返ることがある (従来は `HH:MM`)。文字列としての
|
|
18
|
+
扱いは変わらないが、下流ツールが正規表現で `HH:MM` のみを期待していた場合
|
|
19
|
+
は `HH:MM(:SS)?` にゆるめる必要がある
|
|
20
|
+
|
|
3
21
|
## 0.2.0 (2026-05-28) — Web パリティ完全達成 ✨
|
|
4
22
|
|
|
5
23
|
5 PR (PR1〜5) で MCP/CLI を Web 機能パリティまで拡張し、PR6 で SOLID 観点の
|
package/dist/index.js
CHANGED
|
@@ -1613,6 +1613,12 @@ function toTimeString(date) {
|
|
|
1613
1613
|
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
1614
1614
|
return `${hours}:${minutes}`;
|
|
1615
1615
|
}
|
|
1616
|
+
function toTimeStringWithSeconds(date) {
|
|
1617
|
+
const hours = String(date.getHours()).padStart(2, "0");
|
|
1618
|
+
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
1619
|
+
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
1620
|
+
return `${hours}:${minutes}:${seconds}`;
|
|
1621
|
+
}
|
|
1616
1622
|
|
|
1617
1623
|
// ../domain/src/task-utils.ts
|
|
1618
1624
|
function sessionDurationSeconds(session) {
|
|
@@ -1630,14 +1636,15 @@ function calculateActualSeconds(task, now = /* @__PURE__ */ new Date()) {
|
|
|
1630
1636
|
}
|
|
1631
1637
|
|
|
1632
1638
|
// ../domain/src/task-operations.ts
|
|
1633
|
-
var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)
|
|
1639
|
+
var TIME_RE = /^([01]\d|2[0-3]):([0-5]\d)(?::([0-5]\d))?$/;
|
|
1634
1640
|
function parseTimeOnDate(dateString, timeString) {
|
|
1635
1641
|
const m = TIME_RE.exec(timeString);
|
|
1636
1642
|
if (!m || !m[1] || !m[2]) {
|
|
1637
1643
|
throw new Error(`Invalid time string: ${timeString}`);
|
|
1638
1644
|
}
|
|
1639
1645
|
const base = fromDateString(dateString);
|
|
1640
|
-
|
|
1646
|
+
const seconds = m[3] ? Number(m[3]) : 0;
|
|
1647
|
+
base.setHours(Number(m[1]), Number(m[2]), seconds, 0);
|
|
1641
1648
|
return base;
|
|
1642
1649
|
}
|
|
1643
1650
|
async function startTask(repo, taskId) {
|
|
@@ -1650,7 +1657,7 @@ async function startTask(repo, taskId) {
|
|
|
1650
1657
|
currentSession: { startedAt: now }
|
|
1651
1658
|
};
|
|
1652
1659
|
if (!task.actualStartTime) {
|
|
1653
|
-
patch.actualStartTime =
|
|
1660
|
+
patch.actualStartTime = toTimeStringWithSeconds(now);
|
|
1654
1661
|
}
|
|
1655
1662
|
return repo.update(taskId, patch);
|
|
1656
1663
|
}
|
|
@@ -1737,7 +1744,7 @@ async function interruptTask(repo, params) {
|
|
|
1737
1744
|
currentSession: { startedAt: interruptionStartedAt },
|
|
1738
1745
|
status: "running",
|
|
1739
1746
|
orderIndex: target.orderIndex + 1,
|
|
1740
|
-
actualStartTime:
|
|
1747
|
+
actualStartTime: toTimeStringWithSeconds(interruptionStartedAt),
|
|
1741
1748
|
projectId: params.interruption.projectId,
|
|
1742
1749
|
contextId: params.interruption.contextId,
|
|
1743
1750
|
tagIds: params.interruption.tagIds ?? []
|
|
@@ -1778,7 +1785,7 @@ async function addParallelTask(repo, input) {
|
|
|
1778
1785
|
currentSession: startedAt ? { startedAt } : void 0,
|
|
1779
1786
|
status: startImmediately ? "running" : "planned",
|
|
1780
1787
|
orderIndex: maxOrder + 10,
|
|
1781
|
-
actualStartTime: startedAt ?
|
|
1788
|
+
actualStartTime: startedAt ? toTimeStringWithSeconds(startedAt) : void 0,
|
|
1782
1789
|
projectId: input.projectId,
|
|
1783
1790
|
contextId: input.contextId,
|
|
1784
1791
|
tagIds: input.tagIds ?? [],
|
|
@@ -3135,10 +3142,11 @@ async function reorderTaskHandler(ctx, input) {
|
|
|
3135
3142
|
const updated = await ctx.repos.task.update(input.id, patch);
|
|
3136
3143
|
return { task: taskSummaryFrom(updated) };
|
|
3137
3144
|
}
|
|
3145
|
+
var ACTUAL_TIME_RE = /^([01]\d|2[0-3]):[0-5]\d(?::[0-5]\d)?$/;
|
|
3138
3146
|
var setActualTimesInputSchema = z.object({
|
|
3139
3147
|
id: z.string().uuid(),
|
|
3140
|
-
start_time: z.union([z.string().regex(
|
|
3141
|
-
end_time: z.union([z.string().regex(
|
|
3148
|
+
start_time: z.union([z.string().regex(ACTUAL_TIME_RE, "must be HH:MM or HH:MM:SS"), z.null()]).describe("HH:MM \u307E\u305F\u306F HH:MM:SS\u3002null \u306A\u3089\u5B9F\u7E3E\u958B\u59CB\u306A\u3057\u3002end_time \u306E\u307F\u6307\u5B9A\u306F\u30A8\u30E9\u30FC"),
|
|
3149
|
+
end_time: z.union([z.string().regex(ACTUAL_TIME_RE, "must be HH:MM or HH:MM:SS"), z.null()]).describe("HH:MM \u307E\u305F\u306F HH:MM:SS\u3002null \u306A\u3089\u672A\u5B8C\u4E86 (running \u6271\u3044)")
|
|
3142
3150
|
});
|
|
3143
3151
|
async function setActualTimesHandler(ctx, input) {
|
|
3144
3152
|
const existing = await ctx.repos.task.findById(input.id);
|
|
@@ -3892,7 +3900,7 @@ function createMcpServer(opts) {
|
|
|
3892
3900
|
|
|
3893
3901
|
// src/index.ts
|
|
3894
3902
|
async function main() {
|
|
3895
|
-
const version = "0.
|
|
3903
|
+
const version = "0.3.0" ;
|
|
3896
3904
|
const server = createMcpServer({ version });
|
|
3897
3905
|
const transport = new StdioServerTransport();
|
|
3898
3906
|
await server.connect(transport);
|
package/package.json
CHANGED