Skip to content

chore(speckit): vendor harness scripts under .specify/scripts/bash/#83

Merged
TortoiseWolfe merged 1 commit intomainfrom
feat/speckit-harness
May 6, 2026
Merged

chore(speckit): vendor harness scripts under .specify/scripts/bash/#83
TortoiseWolfe merged 1 commit intomainfrom
feat/speckit-harness

Conversation

@TortoiseWolfe
Copy link
Copy Markdown
Owner

Summary

  • Vendor 5 upstream github/spec-kit bash scripts under .specify/scripts/bash/ so every contributor gets working /speckit.* slash commands without per-developer setup.
  • Add 2 ScriptHammer-specific scripts: config.sh (declares SPEC_KIT_FEATURES_ROOT=features) and update-agent-context.sh (deliberate no-op since CLAUDE.md is hand-curated).
  • Patch common.sh and create-new-feature.sh to support ScriptHammer's nested features/<category>/<NNN-name>/ layout instead of upstream's flat specs/<NNN-name>/.
  • Drop the .specify/scripts/ and .specify/templates/ exclusions from .gitignore (templates were already tracked despite the rule; scripts now ship too).

Why

The /speckit.* slash commands in .claude/commands/ reference .specify/scripts/bash/*.sh files that didn't exist in this repo. Phase 0 PRs (#22, #73, #21, #82) all shipped by walking the cascade as discipline without actually invoking the slash commands. Constitution v1.0.2 Principle III formally requires the cascade — best practice for spec-driven dev is to commit the harness so the discipline is mechanizable, not just manual.

ScriptHammer adaptations

Two surgical patches to upstream:

  • common.sh:find_feature_dir_by_prefix() — recurses through ${SPEC_KIT_FEATURES_ROOT}/*/<prefix>-*/ to match the nested layout. Returns the absolute path including the <category> segment so downstream paths resolve correctly.
  • create-new-feature.shSPECS_DIR honors SPEC_KIT_FEATURES_ROOT (default features); new dirs land under ${SPEC_KIT_DEFAULT_CATEGORY} (default _uncategorized/); get_highest_from_specs() scans both flat and nested layouts.

All other files are upstream-verbatim. See .specify/scripts/bash/README.md for the upstream-sync recipe.

Test plan

  • pre-push hooks pass (lint, type-check, unit tests, build) — done as part of git push
  • SPECIFY_FEATURE=013-oauth-messaging-password .specify/scripts/bash/check-prerequisites.sh --json --paths-only resolves to features/auth-oauth/013-oauth-messaging-password/
  • setup-plan.sh --json copies plan-template.md to the feature dir and emits valid JSON
  • create-new-feature.sh --dry-run --json --short-name "smoke" "test" computes next-available number and lands under features/_uncategorized/
  • update-agent-context.sh claude no-ops cleanly with stderr message
  • check-prerequisites.sh --require-tasks errors out cleanly when tasks.md doesn't exist
  • Future test: invoke /speckit.specify against a fresh feature description and confirm full cascade runs (post-merge follow-up)

🤖 Generated with Claude Code

…/bash/

Pulls the upstream github/spec-kit bash scripts (check-prerequisites,
common, create-new-feature, setup-plan, setup-tasks) plus two
ScriptHammer-specific additions (config.sh, update-agent-context.sh).

Adapted to ScriptHammer's nested features/<category>/<NNN-name>/ layout:
common.sh now recurses through SPEC_KIT_FEATURES_ROOT subdirectories,
create-new-feature.sh lands new dirs under features/_uncategorized/.
The prior gitignore exclusion treated SpecKit as a per-developer install;
shipping the harness instead means every contributor gets working
/speckit.* commands without setup. See .specify/scripts/bash/README.md
for adaptation details and upstream-sync recipe.

Smoke-tested all 4 user-facing scripts against features/auth-oauth/013-
oauth-messaging-password/ — branch resolution, dry-run feature creation,
prerequisite checks, and stub agent-context all behave correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@TortoiseWolfe TortoiseWolfe merged commit cb6312c into main May 6, 2026
27 checks passed
@TortoiseWolfe TortoiseWolfe deleted the feat/speckit-harness branch May 6, 2026 22:26
TortoiseWolfe added a commit that referenced this pull request May 7, 2026
…polish (#84)

* docs(speckit): #28 Phase A+B — clear wireframe gate, encode clarifications

Phase A — wireframe gate:
- validate.py v5.4 returns 0 errors on both 01-oauth-password-setup.svg
  and 02-oauth-password-unlock.svg (annotation text now uses #1f2937 /
  #374151 instead of #6b7280 the 2026-01-16 review flagged).
- Refreshed both .issues.md files to "Status: PASSED" with history
  table showing the v5.0 fail → v5.4 pass transition.
- Added ## UI Mockup section to spec.md per Constitution v1.0.2
  Principle III, linking both wireframes with sign-off date.

Phase B — clarifications encoded:
- Updated the stale Implementation Status block (was "Not Started, no
  OAuth modal found"; now reflects the partial-ship reality:
  isOAuthUser/getOAuthProvider already shipped, /messages/setup
  already shows password+confirm, ReAuthModal already
  OAuth-aware on unlock).
- Added ## Clarifications / ### Session 2026-05-06 with 5 Q→A bullets
  per /speckit.clarify convention: setup-mode trigger, no persistence
  of messaging password, no recovery flow, provider badge UX, and
  modal-vs-page primary path.
- Added FR-018 through FR-022 encoding the clarification answers.

Unblocks /speckit.plan via the harness shipped in PR #83.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(speckit): #28 Phase C — checklist + tasks + analysis cascade

Continues the v1.0.2 cascade for OAuth Messaging Password (issue #28).

- checklists/implementation-readiness.md: "unit-tests-for-English"
  validation that plan.md and spec.md together carry enough info to
  drive /speckit.tasks and /speckit.implement without re-asking
  decisions. All 7 sections PASS.

- tasks.md: 19 tasks ordered T001..T019 across 6 phases. US-1 (T002-T008)
  ships modal setup mode + EncryptionKeyGate redirect-flip. US-2
  (T009-T012) layers in unlock-mode polish + provider badge. US-3
  (T013-T015) is regression-only. T016-T019 polish (Storybook stories,
  AAA re-verify, manual smoke + screenshots, wireframe re-validate).
  RED tests authored before GREEN per Constitution II.

- analysis.md: cross-artifact consistency check. FR-to-task traceability
  matrix shows every one of FR-001..022 has a task or already-shipped
  marker. User stories independently testable per their checkpoints.
  Plan-vs-tasks file paths align. Constitution v1.0.2 compliance
  verified across all 6 principles. Flags scripts/constitution-check.py
  layout bug as a separate one-liner.

Recommendation in analysis: proceed to /speckit.implement.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat(auth): #28 modal-based OAuth messaging password setup + unlock polish

Closes the gap where OAuth users (Google/GitHub) had no in-modal way to
create the messaging password used to derive ECDH keys for E2E messaging.
Today they were redirected to /messages/setup; per FR-021 they now see
the modal in setup mode inline. The setup page is preserved as a deep-
link fallback per FR-022.

Implementation per features/auth-oauth/013-oauth-messaging-password/plan.md:

- New helper: src/lib/messaging/welcome/send-welcome-message.ts.
  Extracted from app/messages/setup/page.tsx so both modal-setup and
  page-setup share one welcome-message dispatch (cleaner long-term per
  memory rule). setup/page.tsx now imports and calls the helper.

- ReAuthModal grows a 'mode' state ('unlock' | 'setup') decided at open
  time by inspecting hasKeys() when an OAuth user opens the modal:
    setup mode  → password + confirm fields, "Create a Messaging
                  Password" title, "Create Messaging Password" submit
                  button, lossless-recovery warning copy, calls
                  initializeKeys + dispatches welcome message
    unlock mode → existing single-password flow, calls deriveKeys
                  (unchanged behavior)
  Provider badge ("Signed in via Google" / "Signed in via GitHub")
  renders in both modes when isOAuthUser(user) is true (FR-020).
  Unlock-mode description for OAuth users now explicitly says "This is
  separate from your <Provider> login" per US-2 wireframe 02.

- EncryptionKeyGate.tsx flips the no-keys redirect: OAuth users get
  setNeedsReAuth(true) (modal opens in setup mode); email users still
  get the full-page redirect to /messages/setup so the browser's
  password manager can offer auto-fill on a real <form>.

- ReAuthModal stories updated with documentation describing both modes.
  Storybook stories rely on real AuthProvider; the per-mode behavioral
  differentiation is covered by the unit tests rather than per-story
  mocks.

7 new RED tests authored before implementation per Constitution II:
  - setup-mode title renders for OAuth user without keys
  - confirm-password field renders in setup mode
  - submit calls initializeKeys (not deriveKeys) in setup mode
  - mismatched passwords block submit + show alert
  - provider badge renders with provider name in setup mode
  - provider badge does NOT render for email users (FR-014)
  - existing OAuth-with-keys regex updated for new copy

Full unit suite: 3261/3261 passing. type-check + lint clean.
Manual browser smoke + Playwright E2E spec + post-implement screenshots
follow in a subsequent commit (T013/T015/T018/T019 in tasks.md).

Refs: #28
Spec: features/auth-oauth/013-oauth-messaging-password/spec.md
Plan: features/auth-oauth/013-oauth-messaging-password/plan.md
Tasks: features/auth-oauth/013-oauth-messaging-password/tasks.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(e2e): #28 add Playwright spec for OAuth Messaging Password modal

Three test slots in tests/e2e/messaging/oauth-setup-modal.spec.ts:

US-3 (runs in CI across chromium-msg, firefox-msg, webkit-msg, plus
mobile profiles) — email user lands on /messages with cleared
IndexedDB, ReAuthModal opens in unlock mode, asserts byte-identical
pre-feature copy: "Enter Your Messaging Password" title, "Password"
label (NOT "Messaging Password"), "Unlock Messages" submit button,
no provider badge. Pins FR-013/FR-014/FR-020 invariants for the email
flow.

US-1 + US-2 (.skip()'d) — OAuth user setup mode and unlock-with-badge
flows. Skipped because the repo does not yet have an OAuth test
fixture (no Google/GitHub test app credentials in CI). The unit tests
in src/components/auth/ReAuthModal/ReAuthModal.test.tsx carry the
behavioral coverage; manual smoke at T018 in tasks.md exercises the
real OAuth flow end-to-end. Spec body documents the future
implementation path (Supabase admin API to flip app_metadata.provider
+ teardown).

Refs: #28
Tasks: T003, T009, T013 (US-3 portion only — OAuth portions deferred)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: TurtleWolfe <TurtleWolfe@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants