@nitra/cursor 3.6.0 → 3.6.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,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.6.1] - 2026-06-01
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- flow: resolveArtifact обирає артефакт за mtime + пріоритетом slug гілки замість лексикографічного (spec/plan фіксували не той doc при кількох на одну дату)
|
|
8
|
+
|
|
3
9
|
## [3.6.0] - 2026-06-01
|
|
4
10
|
|
|
5
11
|
### Added
|
package/package.json
CHANGED
|
@@ -6,24 +6,36 @@
|
|
|
6
6
|
* Лінки front-matter (`spec.plan`/`plan.spec`/`plan.flow`) пише сам агент за
|
|
7
7
|
* контрактом `flow.mdc` — тут лише ВЕРИФІКАЦІЯ (мутатора `trace link` нема).
|
|
8
8
|
*/
|
|
9
|
-
import { existsSync, readdirSync } from 'node:fs'
|
|
9
|
+
import { existsSync, readdirSync, statSync } from 'node:fs'
|
|
10
10
|
import { join } from 'node:path'
|
|
11
11
|
|
|
12
12
|
import { runTraceCli } from '../trace.mjs'
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Резолвить артефакт у `docs/<kind>/`. Пріоритет: файли, чия назва містить
|
|
16
|
+
* хвіст гілки (slug, напр. `flow-gate` з `claude/flow-gate`); серед них (або
|
|
17
|
+
* серед усіх, якщо збігу нема) — **найсвіжіший за mtime**. Лексикографічний
|
|
18
|
+
* вибір був хибним при кількох артефактах на одну дату (виявлено dogfood'ом).
|
|
16
19
|
* @param {string} cwd корінь worktree
|
|
17
20
|
* @param {'specs' | 'plans'} kind підкаталог `docs`
|
|
21
|
+
* @param {string} [branch] гілка задачі — для пріоритету за slug
|
|
18
22
|
* @returns {string | null} абсолютний шлях або null, якщо каталог/файли відсутні
|
|
19
23
|
*/
|
|
20
|
-
export function resolveArtifact(cwd, kind) {
|
|
24
|
+
export function resolveArtifact(cwd, kind, branch) {
|
|
21
25
|
const dir = join(cwd, 'docs', kind)
|
|
22
26
|
if (!existsSync(dir)) return null
|
|
23
|
-
const md = readdirSync(dir)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
const md = readdirSync(dir).filter(f => f.endsWith('.md'))
|
|
28
|
+
if (md.length === 0) return null
|
|
29
|
+
|
|
30
|
+
const slug = branch ? branch.split('/').pop() : null
|
|
31
|
+
const matched = slug ? md.filter(f => f.includes(slug)) : []
|
|
32
|
+
const pool = matched.length > 0 ? matched : md
|
|
33
|
+
|
|
34
|
+
const best = pool
|
|
35
|
+
.map(f => ({ f, mtime: statSync(join(dir, f)).mtimeMs }))
|
|
36
|
+
.toSorted((a, b) => a.mtime - b.mtime || (a.f < b.f ? -1 : 1))
|
|
37
|
+
.at(-1)
|
|
38
|
+
return join(dir, best.f)
|
|
27
39
|
}
|
|
28
40
|
|
|
29
41
|
/** Маркер критерію приймання в рядку кроку (порівняння — case-insensitive). */
|
|
@@ -35,7 +35,7 @@ export async function plan(rest, deps = {}) {
|
|
|
35
35
|
log('plan: дизайн ще не зафіксовано — рекомендовано спершу `flow spec` (не блокує)')
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const doc = rest.find(a => a.endsWith('.md')) ?? resolveArtifact(cwd, 'plans')
|
|
38
|
+
const doc = rest.find(a => a.endsWith('.md')) ?? resolveArtifact(cwd, 'plans', state.branch)
|
|
39
39
|
let steps
|
|
40
40
|
if (rest.includes('--panel')) {
|
|
41
41
|
let runner = deps.runner
|
|
@@ -48,7 +48,7 @@ export async function spec(rest, deps = {}) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
const doc = rest.find(a => a.endsWith('.md')) ?? resolveArtifact(cwd, 'specs')
|
|
51
|
+
const doc = rest.find(a => a.endsWith('.md')) ?? resolveArtifact(cwd, 'specs', state.branch)
|
|
52
52
|
if (!doc || !existsSync(doc)) {
|
|
53
53
|
log('spec: нема docs/specs/<date>-<slug>.md — спершу пройди brainstorm (див. flow.mdc)')
|
|
54
54
|
return 1
|