diff --git a/.github/actions/setup-bun-deps/action.yml b/.github/actions/setup-bun-deps/action.yml index 0451211..29b825f 100644 --- a/.github/actions/setup-bun-deps/action.yml +++ b/.github/actions/setup-bun-deps/action.yml @@ -12,12 +12,13 @@ runs: - uses: oven-sh/setup-bun@v2 + # node_modules навмисно НЕ кешується: відновлене з restore-keys дерево від + # іншого bun.lock після bun install --frozen-lockfile лишається без вкладених + # копій пакетів (eslint/node_modules/ajv тощо) — недетерміновані падіння eslint - name: Cache Bun dependencies uses: actions/cache@v5 with: - path: | - ~/.bun/install/cache - node_modules + path: ~/.bun/install/cache key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }} restore-keys: | ${{ runner.os }}-bun- diff --git a/app/.changes/260712-0836.md b/app/.changes/260712-0836.md new file mode 100644 index 0000000..b3ba62d --- /dev/null +++ b/app/.changes/260712-0836.md @@ -0,0 +1,5 @@ +--- +bump: patch +section: Fixed +--- +eslint 10.7: виправлено порушення нових unicorn-правил (prefer-await, better-dom-traversing та ін.) diff --git a/app/bin/docs/task.md b/app/bin/docs/task.md index 6f75c16..5cf45c7 100644 --- a/app/bin/docs/task.md +++ b/app/bin/docs/task.md @@ -3,9 +3,8 @@ type: JS Module title: task.mjs resource: app/bin/task.mjs docgen: - crc: 86954155 + crc: c2c46484 model: omlx/gemma-4-e4b-it-OptiQ-4bit - tier: local-min score: 100 issues: judge:inaccurate:0.98 judgeModel: openai-codex/gpt-5.4-mini diff --git a/app/bin/task.mjs b/app/bin/task.mjs index 5991287..9ef1159 100644 --- a/app/bin/task.mjs +++ b/app/bin/task.mjs @@ -217,12 +217,11 @@ async function main() { return envelope.ok ? 0 : 2 } -main() - .then(code => { - // null = long-running mode (MCP server) — let the process live on its own handles. - if (code !== null) process.exit(code) - }) - .catch(error => { - process.stderr.write(`${String(error?.message ?? error)}\n`) - process.exit(1) - }) +try { + const code = await main() + // null = long-running mode (MCP server) — let the process live on its own handles. + if (code !== null) process.exit(code) +} catch (error) { + process.stderr.write(`${String(error?.message ?? error)}\n`) + process.exit(1) +} diff --git a/app/src/composables/docs/use-project-paths.md b/app/src/composables/docs/use-project-paths.md index 7fd14cd..6897acd 100644 --- a/app/src/composables/docs/use-project-paths.md +++ b/app/src/composables/docs/use-project-paths.md @@ -3,9 +3,8 @@ type: JS Module title: use-project-paths.js resource: app/src/composables/use-project-paths.js docgen: - crc: 99c09765 + crc: 02e55a8e model: omlx/gemma-4-e4b-it-OptiQ-4bit - tier: local-min score: 100 issues: best-of-2:retry-won,judge:inaccurate:0.98 judgeModel: openai-codex/gpt-5.4-mini diff --git a/app/src/composables/use-project-paths.js b/app/src/composables/use-project-paths.js index 60b1908..aec70f9 100644 --- a/app/src/composables/use-project-paths.js +++ b/app/src/composables/use-project-paths.js @@ -59,10 +59,12 @@ export function useProjectPaths() { /** * Persist the current paths to the Rust config (fire-and-forget). */ - function persist() { - invoke('set_project_paths', { paths: projectPaths.value }).catch(() => { + async function persist() { + try { + await invoke('set_project_paths', { paths: projectPaths.value }) + } catch { // best-effort; not under Tauri (tests) or transient FS error - }) + } } /** diff --git a/app/src/docs/format-ledger.md b/app/src/docs/format-ledger.md index b0fd25a..193e89f 100644 --- a/app/src/docs/format-ledger.md +++ b/app/src/docs/format-ledger.md @@ -3,9 +3,8 @@ type: JS Module title: format-ledger.js resource: app/src/format-ledger.js docgen: - crc: e5a514ea + crc: 81e5f952 model: omlx/gemma-4-e4b-it-OptiQ-4bit - tier: local-min score: 100 issues: judge:inaccurate:0.98 judgeModel: openai-codex/gpt-5.4-mini diff --git a/app/src/docs/task-create.md b/app/src/docs/task-create.md index f30ba5b..d2245ab 100644 --- a/app/src/docs/task-create.md +++ b/app/src/docs/task-create.md @@ -3,9 +3,8 @@ type: JS Module title: task-create.js resource: app/src/task-create.js docgen: - crc: b9f5c463 + crc: 419e7332 model: omlx/gemma-4-e4b-it-OptiQ-4bit - tier: local-min score: 100 issues: best-of-2:retry-won,judge:inaccurate:0.98 judgeModel: openai-codex/gpt-5.4-mini diff --git a/app/src/format-ledger.js b/app/src/format-ledger.js index e3fa54b..783feda 100644 --- a/app/src/format-ledger.js +++ b/app/src/format-ledger.js @@ -10,8 +10,8 @@ export function formatDuration(sec) { const s = Math.round(sec) const h = Math.floor(s / 3600) const m = Math.floor((s % 3600) / 60) - const r = s % 60 if (h > 0) return `${h}h ${m}m` + const r = s % 60 if (m > 0) return `${m}m ${r}s` return `${r}s` } diff --git a/app/src/task-create.js b/app/src/task-create.js index 72cb190..5f2049e 100644 --- a/app/src/task-create.js +++ b/app/src/task-create.js @@ -21,7 +21,7 @@ export function validateTaskName(name) { if (!name) return 'Вкажіть назву задачі' for (const segment of name.split('/')) { if (!segment) return 'Порожній сегмент — приберіть зайвий «/»' - if (![...segment].every(ch => isSegmentChar(ch))) return 'Лише a-z, 0-9, «-»; сегменти через «/»' + if ([...segment].some(ch => !isSegmentChar(ch))) return 'Лише a-z, 0-9, «-»; сегменти через «/»' } return null } diff --git a/app/src/tests/claims.test.js b/app/src/tests/claims.test.js index fb135a5..acbf6c9 100644 --- a/app/src/tests/claims.test.js +++ b/app/src/tests/claims.test.js @@ -13,6 +13,7 @@ const tree = () => [ } ] +/* eslint-disable unicorn/better-dom-traversing -- children тут — вузли task-дерева, не DOM */ describe('applyClaims', () => { it('активний claim → running, прострочений → stalled (рекурсивно)', () => { const nodes = applyClaims(tree(), [ diff --git a/app/src/tests/task-create.test.js b/app/src/tests/task-create.test.js index 9b80fa1..d8ab2a5 100644 --- a/app/src/tests/task-create.test.js +++ b/app/src/tests/task-create.test.js @@ -67,9 +67,9 @@ describe('buildCreateOpts', () => { }) it('drops empty optional fields so .mt.json defaults apply', () => { - expect(buildCreateOpts({ mode: 'agent', modelTier: '', budgetSec: '', hint: ' ', deps: [], skills: [] })).toEqual( - { mode: 'agent' } - ) + expect( + buildCreateOpts({ mode: 'agent', modelTier: '', budgetSec: '', hint: ' '.repeat(3), deps: [], skills: [] }) + ).toEqual({ mode: 'agent' }) }) it('omits agent-only fields for human mode', () => { diff --git a/app/src/tests/ui-open.test.js b/app/src/tests/ui-open.test.js index f31a8ec..a8177ef 100644 --- a/app/src/tests/ui-open.test.js +++ b/app/src/tests/ui-open.test.js @@ -4,7 +4,7 @@ import { mountQuasar } from '../test-utils/quasar.js' beforeEach(() => { const store = {} - globalThis.localStorage = { + vi.stubGlobal('localStorage', { getItem: key => (key in store ? store[key] : null), setItem: (key, value) => { store[key] = String(value) @@ -12,7 +12,7 @@ beforeEach(() => { removeItem: key => { delete store[key] } - } + }) }) vi.mock('@tauri-apps/api/core', () => ({ invoke: vi.fn(() => Promise.resolve([])) })) diff --git a/owner/.changes/260712-0840.md b/owner/.changes/260712-0840.md new file mode 100644 index 0000000..74045c5 --- /dev/null +++ b/owner/.changes/260712-0840.md @@ -0,0 +1,5 @@ +--- +bump: patch +section: Changed +--- +release: app@0.5.4, owner@0.2.1