diff --git a/.agents/skills/speckit-analyze/SKILL.md b/.agents/skills/speckit-analyze/SKILL.md index 62f1267..5109d8f 100644 --- a/.agents/skills/speckit-analyze/SKILL.md +++ b/.agents/skills/speckit-analyze/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before analysis)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_analyze` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -208,7 +208,7 @@ Ask the user: "Would you like me to suggest concrete remediation edits for the t After reporting, check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.after_analyze` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-checklist/SKILL.md b/.agents/skills/speckit-checklist/SKILL.md index fd9ca0e..b467ea8 100644 --- a/.agents/skills/speckit-checklist/SKILL.md +++ b/.agents/skills/speckit-checklist/SKILL.md @@ -51,7 +51,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before checklist generation)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_checklist` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -353,7 +353,7 @@ Sample items: **Check for extension hooks (after checklist generation)**: Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.after_checklist` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-clarify/SKILL.md b/.agents/skills/speckit-clarify/SKILL.md index 54fca40..020f41e 100644 --- a/.agents/skills/speckit-clarify/SKILL.md +++ b/.agents/skills/speckit-clarify/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before clarification)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_clarify` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -244,7 +244,7 @@ Context for prioritization: $ARGUMENTS Check if `.specify/extensions.yml` exists in the project root. - If it does not exist, or no hooks are registered under `hooks.after_clarify`, skip to the Completion Report. - If it exists, read it and look for entries under the `hooks.after_clarify` key. -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report. +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue to the Completion Report. - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-constitution/SKILL.md b/.agents/skills/speckit-constitution/SKILL.md index c96e486..30f2b45 100644 --- a/.agents/skills/speckit-constitution/SKILL.md +++ b/.agents/skills/speckit-constitution/SKILL.md @@ -40,7 +40,7 @@ and commands read the constitution at runtime and are not modified here. **Check for extension hooks (before constitution update)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_constitution` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -108,7 +108,9 @@ Follow this execution flow: - Ensure each Principle section: succinct name line, paragraph (or bullet list) capturing non‑negotiable rules, explicit rationale if not obvious. - Ensure Governance section lists amendment procedure, versioning policy, and compliance review expectations. -4. Produce a Sync Impact Report (prepend as an HTML comment at top of the constitution file after update): +4. Produce a Sync Impact Report as an HTML comment at the top of the constitution file after update. + This report is temporary scratch material for human review of the amendment, not governance + content; it is expected to be removed before the amended constitution file is committed. - Version change: old → new - List of modified principles (old title → new title if renamed) - Added sections @@ -147,7 +149,7 @@ Write only `.specify/memory/constitution.md`; do not create or modify template s **Check for extension hooks (after constitution update)**: Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.after_constitution` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-converge/SKILL.md b/.agents/skills/speckit-converge/SKILL.md index 20f172b..6fc3917 100644 --- a/.agents/skills/speckit-converge/SKILL.md +++ b/.agents/skills/speckit-converge/SKILL.md @@ -22,7 +22,7 @@ You **MUST** consider the user input before proceeding (if not empty). - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_converge` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -241,7 +241,7 @@ Append to the **end** of `tasks.md`, per the append contract: After producing the result, check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.after_converge` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-implement/SKILL.md b/.agents/skills/speckit-implement/SKILL.md index 0f7734d..f146d3c 100644 --- a/.agents/skills/speckit-implement/SKILL.md +++ b/.agents/skills/speckit-implement/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before implementation)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_implement` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -186,7 +186,7 @@ Note: This command assumes a complete task breakdown exists in tasks.md. If task Check if `.specify/extensions.yml` exists in the project root. - If it does not exist, or no hooks are registered under `hooks.after_implement`, skip to the Completion Report. - If it exists, read it and look for entries under the `hooks.after_implement` key. -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report. +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue to the Completion Report. - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-plan/SKILL.md b/.agents/skills/speckit-plan/SKILL.md index a44bbfd..9c0a09f 100644 --- a/.agents/skills/speckit-plan/SKILL.md +++ b/.agents/skills/speckit-plan/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before planning)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_plan` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -54,7 +54,7 @@ You **MUST** consider the user input before proceeding (if not empty). ## Outline -1. **Setup**: Run `.specify/scripts/bash/setup-plan.sh --json` from repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, SPECS_DIR, BRANCH. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot"). +1. **Setup**: Run `.specify/scripts/bash/setup-plan.sh --json` from repo root and parse JSON for FEATURE_SPEC, IMPL_PLAN, FEATURE_DIR, BRANCH. For single quotes in args like "I'm Groot", use escape syntax: e.g 'I'\''m Groot' (or double-quote if possible: "I'm Groot"). 2. **Load context**: Read FEATURE_SPEC and `.specify/memory/constitution.md`. Load IMPL_PLAN template (already copied). @@ -73,7 +73,7 @@ You **MUST** consider the user input before proceeding (if not empty). Check if `.specify/extensions.yml` exists in the project root. - If it does not exist, or no hooks are registered under `hooks.after_plan`, skip to the Completion Report. - If it exists, read it and look for entries under the `hooks.after_plan` key. -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report. +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue to the Completion Report. - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-specify/SKILL.md b/.agents/skills/speckit-specify/SKILL.md index 8fbbd13..95a1e01 100644 --- a/.agents/skills/speckit-specify/SKILL.md +++ b/.agents/skills/speckit-specify/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before specification)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_specify` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -239,7 +239,7 @@ Given that feature description, do this: Check if `.specify/extensions.yml` exists in the project root. - If it does not exist, or no hooks are registered under `hooks.after_specify`, skip to the Completion Report. - If it exists, read it and look for entries under the `hooks.after_specify` key. -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report. +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue to the Completion Report. - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.agents/skills/speckit-tasks/SKILL.md b/.agents/skills/speckit-tasks/SKILL.md index 548b1b9..71ee03e 100644 --- a/.agents/skills/speckit-tasks/SKILL.md +++ b/.agents/skills/speckit-tasks/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before tasks generation)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_tasks` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -93,7 +93,7 @@ You **MUST** consider the user input before proceeding (if not empty). Check if `.specify/extensions.yml` exists in the project root. - If it does not exist, or no hooks are registered under `hooks.after_tasks`, skip to the Completion Report. - If it exists, read it and look for entries under the `hooks.after_tasks` key. -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue to the Completion Report. +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue to the Completion Report. - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -192,6 +192,7 @@ Every task MUST strictly follow this format: - Map each entity to the user story(ies) that need it - If entity serves multiple stories: Put in earliest story or Setup phase - Relationships → service layer tasks in appropriate story phase + - For each field with constraints in data-model.md (max length, nullable/required, enum values, validation rules), quote the constraint verbatim in the task description so it is not left to implementation-time discretion 4. **From Setup/Infrastructure**: - Shared infrastructure → Setup phase (Phase 1) diff --git a/.agents/skills/speckit-taskstoissues/SKILL.md b/.agents/skills/speckit-taskstoissues/SKILL.md index 90e90bd..2bde7d3 100644 --- a/.agents/skills/speckit-taskstoissues/SKILL.md +++ b/.agents/skills/speckit-taskstoissues/SKILL.md @@ -21,7 +21,7 @@ You **MUST** consider the user input before proceeding (if not empty). **Check for extension hooks (before tasks-to-issues conversion)**: - Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.before_taskstoissues` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable @@ -79,7 +79,7 @@ git config --get remote.origin.url **Check for extension hooks (after tasks-to-issues conversion)**: Check if `.specify/extensions.yml` exists in the project root. - If it exists, read it and look for entries under the `hooks.after_taskstoissues` key -- If the YAML cannot be parsed or is invalid, skip hook checking silently and continue normally +- If the YAML cannot be parsed or is invalid, do not skip silently: tell the user that `.specify/extensions.yml` could not be read (include the parser error) and that no hooks were checked, including any mandatory (`optional: false`) hooks registered there, then continue normally - Filter out hooks where `enabled` is explicitly `false`. Treat hooks without an `enabled` field as enabled by default. - For each remaining hook, do **not** attempt to interpret or evaluate hook `condition` expressions: - If the hook has no `condition` field, or it is null/empty, treat the hook as executable diff --git a/.specify/init-options.json b/.specify/init-options.json index a32aaa6..fe644d9 100644 --- a/.specify/init-options.json +++ b/.specify/init-options.json @@ -5,5 +5,5 @@ "here": true, "integration": "codex", "script": "sh", - "speckit_version": "1.0.3" + "speckit_version": "1.0.6" } diff --git a/.specify/integration.json b/.specify/integration.json index 7c49ebd..41c5032 100644 --- a/.specify/integration.json +++ b/.specify/integration.json @@ -1,5 +1,5 @@ { - "version": "1.0.3", + "version": "1.0.6", "integration_state_schema": 1, "installed_integrations": [ "codex" diff --git a/.specify/integrations/codex.manifest.json b/.specify/integrations/codex.manifest.json index 0b601ac..3f9a1a3 100644 --- a/.specify/integrations/codex.manifest.json +++ b/.specify/integrations/codex.manifest.json @@ -1,17 +1,17 @@ { "integration": "codex", - "version": "1.0.3", - "installed_at": "2026-09-02T16:47:19.453154+00:00", + "version": "1.0.6", + "installed_at": "2026-09-15T13:24:35.128770+00:00", "files": { - ".agents/skills/speckit-analyze/SKILL.md": "f9828d73a545500680c4f6f1e1eb8b0f9124578430128045170a8d7e388a944b", - ".agents/skills/speckit-clarify/SKILL.md": "d3aa120d6b5d7718c4c6d792dd41bee66254bd4bb82f88f3067f1d1c4e9d2dc2", - ".agents/skills/speckit-constitution/SKILL.md": "01074220f2b4bb32a92b8ad23a688358bd5e3828e18871b21a32ff8db6753358", - ".agents/skills/speckit-implement/SKILL.md": "d113f4e09878a8a2e7f64b3852d698076a38394b8fc777b7426b1159c28e92fe", - ".agents/skills/speckit-converge/SKILL.md": "36bded5c2afe14cae77161ac2f1f42e6bedeb5fa2028e06dba541420b4b5508d", - ".agents/skills/speckit-plan/SKILL.md": "b3dca1c679a2452e8e3aa84c96b42fc5cee42e8b0cb3c30fa77a60ff83db6d4d", - ".agents/skills/speckit-checklist/SKILL.md": "6632a53c5ddbde330c7ca3a8d19459b4de866ea5296028c2178f7b4598243d78", - ".agents/skills/speckit-specify/SKILL.md": "88d7fab201de66297f16b6c271a418a0f2c198d714456dfd707e623348ec47c1", - ".agents/skills/speckit-tasks/SKILL.md": "1ae03ee3aac56f19cac4cba8d51c672e4f50692f5a179f8fb65a035752e71592", - ".agents/skills/speckit-taskstoissues/SKILL.md": "542bf370046ecc2dbea0a539522e0628bee7a425b47b8afb0bd67ae274c01720" + ".agents/skills/speckit-analyze/SKILL.md": "0b3261b13cc33537f24b3e1f6d5320694c348302c385d0046dc6b958cf2db6cb", + ".agents/skills/speckit-clarify/SKILL.md": "7a06609c7b2ac43ed89a55d22f4bc1b8d712d8bfa48ea30a82f17258f9408f44", + ".agents/skills/speckit-constitution/SKILL.md": "b2a6a979ef7511812b60cde4adb6f1c4a8b1b57314ea2f1861ebc3f4796bf377", + ".agents/skills/speckit-implement/SKILL.md": "848a5c9eff7b99e348927cbde6c35378de9fea3fd317941f58fa0b0b79301eec", + ".agents/skills/speckit-converge/SKILL.md": "ba0b853dba470f414cdf9eae53200b8468bd639ecd92549a6d4e533af3da7521", + ".agents/skills/speckit-plan/SKILL.md": "db2406adfa50103fc04ca8109ac934cd715086fba64365fb404630a88c62bda5", + ".agents/skills/speckit-checklist/SKILL.md": "7ac5cba31a27151a1a7b73f691bd478d42750ce2dd734701a07eb0e235ffbd94", + ".agents/skills/speckit-specify/SKILL.md": "a505028de7f6489878696d6656c7d057f3a66119ebb8c0cc82d69fabb7b344ff", + ".agents/skills/speckit-tasks/SKILL.md": "1086d7885df1188d00e7d5eb4715e678b4340b893e8f24ae748d823b13599a56", + ".agents/skills/speckit-taskstoissues/SKILL.md": "a349d410c180385215bf5180b13319bd8259199267af24917f4f4d0adcbb6ad2" } } diff --git a/.specify/integrations/speckit.manifest.json b/.specify/integrations/speckit.manifest.json index 9813630..fc90d0b 100644 --- a/.specify/integrations/speckit.manifest.json +++ b/.specify/integrations/speckit.manifest.json @@ -1,13 +1,13 @@ { "integration": "speckit", - "version": "1.0.3", + "version": "1.0.6", "installed_at": "2026-09-02T16:47:19.464853+00:00", "files": { - ".specify/scripts/bash/create-new-feature.sh": "fe99ea8da184380056ce8512ca5d37f67fb499ee4234835c15dcf7c4fb75451c", + ".specify/scripts/bash/create-new-feature.sh": "9f7a741d9766a6c1c5d5e44368f2c6bea6026b399ff6f0055870f760afdb8726", ".specify/scripts/bash/resolve-template.sh": "829e227096abc8bf0889889ec9f792f503ca5d395b7836a8a7eb739ee75214e7", ".specify/scripts/bash/check-prerequisites.sh": "13be175548848bd84e96a90cf9be87665c2e68603b2eaa3e19187e7ca8b4fcb0", - ".specify/scripts/bash/common.sh": "c552063e4c18818b6f6a924a0b638835a8bcb6bd166053b103cc1ef5096f6525", - ".specify/scripts/bash/setup-plan.sh": "f417e1b8de7a48fa9d5fea3aabea8fe62149fa11c4b41b3103de06efe73dec8d", + ".specify/scripts/bash/common.sh": "fdfebd1274594eb3fbfccdf7968d5dd1243aaf244daf262d7c9d0c012c5d21a6", + ".specify/scripts/bash/setup-plan.sh": "d0bd298c026446f3c63167130d65e49e4aa4485de6bef18bcdfd57b19aa0de96", ".specify/scripts/bash/setup-tasks.sh": "0350b2def158c4dc333cd888fc5a3b10785b3d5c2cf936f93e910242ea9d507d", ".specify/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3", ".specify/templates/plan-template.md": "a828ad6206526574ab3fc99be6d0154588cb1c9774c5919d71b81ab5b2dbffa0", diff --git a/.specify/scripts/bash/common.sh b/.specify/scripts/bash/common.sh index a49aa51..e8c3daa 100755 --- a/.specify/scripts/bash/common.sh +++ b/.specify/scripts/bash/common.sh @@ -902,12 +902,20 @@ except Exception as exc: *'{CORE_TEMPLATE}'*) ;; *) echo "Error: wrap strategy missing {CORE_TEMPLATE} placeholder" >&2; return 2 ;; esac - while [[ "$layer_content" == *'{CORE_TEMPLATE}'* ]]; do - local before="${layer_content%%\{CORE_TEMPLATE\}*}" - local after="${layer_content#*\{CORE_TEMPLATE\}}" - layer_content="${before}${content}${after}" + # Consume the wrapper left to right instead of rewriting it in + # place. Rewriting re-scanned the string just modified, so base + # content holding a literal {CORE_TEMPLATE} reintroduced the + # token every pass and the loop never terminated. Advancing over + # ``rest`` bounds the work by the tokens in the original wrapper + # and leaves inserted content untouched, matching the single-pass + # semantics of .Replace()/.replace() in the PowerShell and Python + # ports. + local wrapped="" rest="$layer_content" + while [[ "$rest" == *'{CORE_TEMPLATE}'* ]]; do + wrapped="${wrapped}${rest%%\{CORE_TEMPLATE\}*}${content}" + rest="${rest#*\{CORE_TEMPLATE\}}" done - content="$layer_content" + content="${wrapped}${rest}" ;; *) echo "Error: unknown strategy '$strat'" >&2; return 2 ;; esac diff --git a/.specify/scripts/bash/create-new-feature.sh b/.specify/scripts/bash/create-new-feature.sh index abdb219..06681d9 100755 --- a/.specify/scripts/bash/create-new-feature.sh +++ b/.specify/scripts/bash/create-new-feature.sh @@ -145,9 +145,18 @@ spec_prefix_exists() { } # Function to clean and format a branch name +# +# Three details keep this byte-identical to the Python and PowerShell twins: +# * LC_ALL=C -- in a UTF-8 locale glibc resolves the a-z *range* through +# collation, so [^a-z0-9] keeps accented lowercase letters that +# re.sub(r"[^a-z0-9]", ...) and .NET's -replace both strip. +# * `--*` instead of the GNU-only `\+`, which POSIX/BSD sed reads as a literal +# '+', leaving repeated separators uncollapsed on macOS. +# * printf instead of echo, so a name of "-n"/"-e"/"-E" is text, not options. clean_branch_name() { local name="$1" - echo "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/-\+/-/g' | sed 's/^-//' | sed 's/-$//' + local -x LC_ALL=C + printf '%s\n' "$name" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-//' | sed 's/-$//' } # Fit a feature prefix and suffix within GitHub's branch-name limit. @@ -200,7 +209,11 @@ generate_branch_name() { # Common stop words to filter out local stop_words="^(i|a|an|the|to|for|of|in|on|at|by|with|from|is|are|was|were|be|been|being|have|has|had|do|does|did|will|would|should|could|can|may|might|must|shall|this|that|these|those|my|your|our|their|want|need|add|get|set)$" - # Convert to lowercase and split into words + # Convert to lowercase and split into words. LC_ALL=C for the same + # collation reason documented on clean_branch_name, and so the `grep -qw` + # acronym probe below uses ASCII word boundaries like the Python twin's + # (?