@dtlabs/ai-toolkit 0.22.0 → 0.22.1
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
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
## 0.1.4 (2026-07-21)
|
|
2
|
+
## [0.22.1](https://github.com/dtlab-tech/ai-toolkit/compare/v0.22.0...v0.22.1) (2026-10-21)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
* **task-executor:** deterministic split-wbs/ render for planDigest stability ([0afbcba](https://github.com/dtlab-tech/ai-toolkit/commit/0afbcba0b0a6d2e09251acd97f6b22b6cc288ce3))
|
|
8
|
+
* **task-executor:** make split-wbs/ in-memory render deterministic for planDigest ([0f500fe](https://github.com/dtlab-tech/ai-toolkit/commit/0f500fe85bff37199601dae2e689f2426a656d6b))
|
|
9
|
+
|
|
2
10
|
## [0.22.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.21.2...v0.22.0) (2026-10-21)
|
|
3
11
|
|
|
4
12
|
|
|
@@ -3834,7 +3834,15 @@ function _loadPlanDocs(featureDir, prefix, errorCode, callerLabel) {
|
|
|
3834
3834
|
throw _err(code, label + ': failed to load split Work Breakdown "' + wbsDir + '": ' + err.message);
|
|
3835
3835
|
}
|
|
3836
3836
|
const phaseDepsMap = computePhaseDependsOn(wb);
|
|
3837
|
-
|
|
3837
|
+
// A stable (not wall-clock) "Generated" value: this in-memory render runs fresh on EVERY
|
|
3838
|
+
// call (unlike the legacy path's render-once-to-disk), so planDigest must be a pure function
|
|
3839
|
+
// of this call's inputs, not of when it happened to run — see renderMarkdown's own doc
|
|
3840
|
+
// comment for the real replan()/execute() digest-mismatch bug this fixes.
|
|
3841
|
+
const generatedAt = fs.statSync(indexPath).mtime.toISOString();
|
|
3842
|
+
return {
|
|
3843
|
+
md: renderMarkdown(wb, prefix, phaseDepsMap, generatedAt),
|
|
3844
|
+
csv: renderCsv(wb, prefix, phaseDepsMap),
|
|
3845
|
+
};
|
|
3838
3846
|
}
|
|
3839
3847
|
}
|
|
3840
3848
|
|
package/package.json
CHANGED
|
@@ -92,7 +92,17 @@ function buildCommitSubject(task) {
|
|
|
92
92
|
|
|
93
93
|
// ── Render stubs (implemented in T03–T05) ─────────────────────────────────────
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
// generatedAt: optional override for the "Generated" line below, defaulting to the current
|
|
96
|
+
// wall-clock time (unchanged behavior for the CLI entry point's one-shot render-to-disk use).
|
|
97
|
+
// lib/task-executor/index.js's _loadPlanDocs() passes an explicit, stable value (wbs/index.json's
|
|
98
|
+
// own mtime) instead — it re-renders a split wbs/ directory in memory on EVERY execute()/replan()
|
|
99
|
+
// call (the legacy .md/.csv path renders to disk once and is read back unchanged thereafter), and
|
|
100
|
+
// a live timestamp there made planDigest non-deterministic between two calls against the exact
|
|
101
|
+
// same unchanged plan, spuriously tripping REPLAN_PLAN_DIGEST_MISMATCH on a real replan() ->
|
|
102
|
+
// execute() --from-replan-run-id sequence (reported against a real Fincantieri.ISDM.JobScheduler
|
|
103
|
+
// run). mtime still correctly changes the digest if the plan is genuinely edited between calls —
|
|
104
|
+
// exactly the drift planDigest exists to catch.
|
|
105
|
+
function renderMarkdown(wb, prefix, phaseDepsMap, generatedAt) {
|
|
96
106
|
const DOMAINS = ['BE', 'FE', 'DB', 'DevOps', 'INFRA', 'TEST']
|
|
97
107
|
|
|
98
108
|
function getAgentMinutes(task) {
|
|
@@ -176,7 +186,7 @@ function renderMarkdown(wb, prefix, phaseDepsMap) {
|
|
|
176
186
|
}
|
|
177
187
|
|
|
178
188
|
const title = wb.title ?? wb.feature ?? prefix
|
|
179
|
-
const generated = new Date().toISOString()
|
|
189
|
+
const generated = generatedAt == null ? new Date().toISOString() : generatedAt
|
|
180
190
|
const L = []
|
|
181
191
|
|
|
182
192
|
// ── Title ──
|