yadflow 3.9.1 → 3.9.2
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 +2 -2
- package/bin/yad.mjs +1 -1
- package/cli/commit.mjs +10 -1
- package/cli/manifest.mjs +4 -0
- package/package.json +1 -1
- package/skills/yad-commit/SKILL.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
## [3.9.
|
|
1
|
+
## [3.9.2](https://github.com/abdelrahmannasr/yadflow/compare/v3.9.1...v3.9.2) (2026-07-06)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* validate explicit --task id format in yad commit ([e3b0527](https://github.com/abdelrahmannasr/yadflow/commit/e3b05276b951dbeab6ce6bcb135e8228f73ede9d))
|
|
7
7
|
|
|
8
8
|
# [2.2.0](https://github.com/abdelrahmannasr/yadflow/compare/v2.1.0...v2.2.0) (2026-06-14)
|
|
9
9
|
|
package/bin/yad.mjs
CHANGED
|
@@ -124,7 +124,7 @@ ${c.bold('Options')}
|
|
|
124
124
|
--dir <path> Target project root (default: cwd)
|
|
125
125
|
--type <t> commit: feat|fix|docs|refactor|test|perf|build|ci|chore|revert
|
|
126
126
|
-m, --message <s> commit: subject / PR title
|
|
127
|
-
--task <id> commit: Task trailer (else derived from the branch)
|
|
127
|
+
--task <id> commit: Task trailer, a <story>-T<NN> id (else derived from the branch)
|
|
128
128
|
--ai <id> commit: co-author — claude|copilot|cursor|coderabbit|none (default none)
|
|
129
129
|
--contract-change commit/open-pr: mark the contract surface touched
|
|
130
130
|
--risk <level> open-pr: low|medium|high (default low)
|
package/cli/commit.mjs
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
// Subject is Conventional Commits; trailers are emitted in the fixed order
|
|
3
3
|
// Task -> Contract-Change -> Co-Authored-By. The human git author OWNS the commit; the AI is only a
|
|
4
4
|
// co-author (flagged with --ai, or `none` for human-only). An atomic-commit guard keeps diffs small.
|
|
5
|
+
// An explicit --task id is validated against the spec-link gate contract (<story>-T<NN>) so a
|
|
6
|
+
// malformed trailer fails locally rather than after a push.
|
|
5
7
|
import path from 'node:path';
|
|
6
8
|
import fs from 'node:fs';
|
|
7
9
|
import { c, log, ok, info, warn, fail, run, exists } from './lib.mjs';
|
|
8
10
|
import {
|
|
9
11
|
COMMIT_TYPES, AI_COAUTHORS, ATOMIC_FILE_LIMIT,
|
|
10
|
-
TASK_TRAILER, CONTRACT_CHANGE_TRAILER, COAUTHOR_TRAILER, PROJECT_FILES,
|
|
12
|
+
TASK_TRAILER, CONTRACT_CHANGE_TRAILER, COAUTHOR_TRAILER, PROJECT_FILES, TASK_ID_RE,
|
|
11
13
|
} from './manifest.mjs';
|
|
12
14
|
|
|
13
15
|
// PURE — unit tested directly. Build the full commit message text.
|
|
@@ -16,6 +18,13 @@ export function buildCommitMessage({ type, subject, task, contractChange = false
|
|
|
16
18
|
if (!subject || !subject.trim()) throw new Error('commit subject is required');
|
|
17
19
|
if (!(ai in AI_COAUTHORS)) throw new Error(`unknown --ai "${ai}" (one of: ${Object.keys(AI_COAUTHORS).join(', ')})`);
|
|
18
20
|
if (/\.$/.test(subject.trim())) throw new Error('subject must not end with a period');
|
|
21
|
+
// A malformed task id (e.g. a bare story `EP-x-S01` with no -T<NN>) commits fine locally but
|
|
22
|
+
// then fails the spec-link CI gate — forcing a history rewrite + force-push. Reject it here so
|
|
23
|
+
// it never enters a trailer. Well-formed branch-derived ids (taskFromBranch) are stricter and pass;
|
|
24
|
+
// a lowercase-suffix branch is caught here, matching the case-sensitive spec-link grep.
|
|
25
|
+
if (task && !TASK_ID_RE.test(task)) {
|
|
26
|
+
throw new Error(`invalid --task "${task}" (expected <story>-T<NN>, e.g. EP-x-S01-T02) — the spec-link CI gate would reject it`);
|
|
27
|
+
}
|
|
19
28
|
|
|
20
29
|
const trailers = [];
|
|
21
30
|
if (task) trailers.push(`${TASK_TRAILER}: ${task}`);
|
package/cli/manifest.mjs
CHANGED
|
@@ -170,6 +170,10 @@ export const ATOMIC_FILE_LIMIT = 3;
|
|
|
170
170
|
export const TASK_TRAILER = 'Task';
|
|
171
171
|
export const CONTRACT_CHANGE_TRAILER = 'Contract-Change';
|
|
172
172
|
export const COAUTHOR_TRAILER = 'Co-Authored-By';
|
|
173
|
+
// A Task trailer id must be a real <story>-T<NN>. Mirrors the spec-link gate contract
|
|
174
|
+
// (checks/spec-link.sh: `.+-T[0-9]+$`) so an explicit --task that would fail CI is
|
|
175
|
+
// rejected locally at commit time instead of after a push + history rewrite.
|
|
176
|
+
export const TASK_ID_RE = /.+-T\d+$/;
|
|
173
177
|
|
|
174
178
|
// Per-epic ledger files under epics/<epic>/.sdlc/ (the file source of truth the gate reads/writes).
|
|
175
179
|
export const epicFiles = (epicRoot) => ({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yadflow",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.2",
|
|
4
4
|
"description": "Yadflow — the gated, team, multi-repo SDLC: author → review → build with a PR-driven review gate and a zero-dependency `yad` CLI (setup, gate, commit, open-pr, ship, repo, thread, reconcile). A BMAD module + 38 yad-* skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "AbdelRahman Nasr",
|
|
@@ -20,7 +20,9 @@ and `yad-ship` use. It **never auto-advances**; it just commits.
|
|
|
20
20
|
- **Subject** — `<type>: <lowercase imperative description, no trailing period>`; types are
|
|
21
21
|
`feat|fix|docs|refactor|test|perf|build|ci|chore|revert`; proper nouns/acronyms keep their case.
|
|
22
22
|
- **Task trailer** — required on a code repo (anchors the `spec-link` + `commit-message` gates). Given
|
|
23
|
-
with `--task
|
|
23
|
+
with `--task` (a `<story>-T<NN>` id — an explicit value is validated against the `spec-link`
|
|
24
|
+
contract, so a malformed id like a bare `EP-x-S01` fails locally instead of after a push), else
|
|
25
|
+
derived from the branch (`feat/<story>-<task>-…`). Hub commits are not
|
|
24
26
|
task-scoped, so the trailer is optional there — a missing-Task warning is informational on the hub
|
|
25
27
|
(`spec-link` is a code-repo gate) and only flags a real gate failure in a code repo.
|
|
26
28
|
- **Contract-Change trailer** — `--contract-change` only when the diff touches the locked contract
|