ruby_reactor 0.5.4 → 0.6.0
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.
- checksums.yaml +4 -4
- data/.claude/skills/speckit-agent-context-update/SKILL.md +32 -0
- data/.claude/skills/speckit-analyze/SKILL.md +262 -0
- data/.claude/skills/speckit-checklist/SKILL.md +374 -0
- data/.claude/skills/speckit-clarify/SKILL.md +286 -0
- data/.claude/skills/speckit-constitution/SKILL.md +157 -0
- data/.claude/skills/speckit-converge/SKILL.md +277 -0
- data/.claude/skills/speckit-implement/SKILL.md +224 -0
- data/.claude/skills/speckit-plan/SKILL.md +171 -0
- data/.claude/skills/speckit-specify/SKILL.md +346 -0
- data/.claude/skills/speckit-tasks/SKILL.md +215 -0
- data/.claude/skills/speckit-taskstoissues/SKILL.md +110 -0
- data/.release-please-manifest.json +1 -1
- data/.specify/extensions/.registry +19 -0
- data/.specify/extensions/agent-context/README.md +66 -0
- data/.specify/extensions/agent-context/agent-context-config.yml +5 -0
- data/.specify/extensions/agent-context/commands/speckit.agent-context.update.md +27 -0
- data/.specify/extensions/agent-context/extension.yml +34 -0
- data/.specify/extensions/agent-context/scripts/bash/update-agent-context.sh +282 -0
- data/.specify/extensions/agent-context/scripts/powershell/update-agent-context.ps1 +353 -0
- data/.specify/extensions.yml +23 -0
- data/.specify/feature.json +3 -0
- data/.specify/init-options.json +9 -0
- data/.specify/integration.json +15 -0
- data/.specify/integrations/claude.manifest.json +17 -0
- data/.specify/integrations/speckit.manifest.json +17 -0
- data/.specify/memory/constitution.md +134 -0
- data/.specify/scripts/bash/check-prerequisites.sh +189 -0
- data/.specify/scripts/bash/common.sh +619 -0
- data/.specify/scripts/bash/create-new-feature.sh +299 -0
- data/.specify/scripts/bash/setup-plan.sh +84 -0
- data/.specify/scripts/bash/setup-tasks.sh +91 -0
- data/.specify/templates/checklist-template.md +40 -0
- data/.specify/templates/constitution-template.md +50 -0
- data/.specify/templates/plan-template.md +113 -0
- data/.specify/templates/spec-template.md +131 -0
- data/.specify/templates/tasks-template.md +252 -0
- data/.specify/workflows/speckit/workflow.yml +77 -0
- data/.specify/workflows/workflow-registry.json +13 -0
- data/CHANGELOG.md +7 -0
- data/README.md +51 -24
- data/lib/ruby_reactor/adapters/active_job/compat.rb +24 -0
- data/lib/ruby_reactor/adapters/active_job/map_collector_worker.rb +19 -0
- data/lib/ruby_reactor/adapters/active_job/map_element_worker.rb +19 -0
- data/lib/ruby_reactor/adapters/active_job/router.rb +91 -0
- data/lib/ruby_reactor/adapters/active_job/sweeper_worker.rb +16 -0
- data/lib/ruby_reactor/adapters/active_job/worker.rb +24 -0
- data/lib/ruby_reactor/adapters/sidekiq/map_collector_worker.rb +15 -0
- data/lib/ruby_reactor/adapters/sidekiq/map_element_worker.rb +15 -0
- data/lib/ruby_reactor/adapters/sidekiq/router.rb +91 -0
- data/lib/ruby_reactor/adapters/sidekiq/sweeper_worker.rb +19 -0
- data/lib/ruby_reactor/adapters/sidekiq/worker.rb +25 -0
- data/lib/ruby_reactor/configuration.rb +24 -4
- data/lib/ruby_reactor/map/element_executor.rb +1 -1
- data/lib/ruby_reactor/rspec/active_job_helpers.rb +52 -0
- data/lib/ruby_reactor/rspec/async_test_helpers.rb +41 -0
- data/lib/ruby_reactor/rspec/sidekiq_helpers.rb +3 -3
- data/lib/ruby_reactor/rspec/test_subject.rb +11 -7
- data/lib/ruby_reactor/rspec.rb +4 -0
- data/lib/ruby_reactor/sweeper_job.rb +70 -0
- data/lib/ruby_reactor/version.rb +1 -1
- data/lib/ruby_reactor/worker.rb +226 -0
- data/lib/ruby_reactor.rb +40 -1
- data/specs/active_job.md +259 -0
- metadata +54 -6
- data/lib/ruby_reactor/sidekiq_adapter.rb +0 -87
- data/lib/ruby_reactor/sidekiq_workers/map_collector_worker.rb +0 -13
- data/lib/ruby_reactor/sidekiq_workers/map_element_worker.rb +0 -13
- data/lib/ruby_reactor/sidekiq_workers/sweeper_worker.rb +0 -73
- data/lib/ruby_reactor/sidekiq_workers/worker.rb +0 -222
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"integration": "claude",
|
|
3
|
+
"version": "0.11.6",
|
|
4
|
+
"installed_at": "2026-06-23T23:29:12.149990+00:00",
|
|
5
|
+
"files": {
|
|
6
|
+
".claude/skills/speckit-analyze/SKILL.md": "0c6d0525b97b523851a3ea8fc0efdcf477dfa65bef8c4d976b6da2f220f32c86",
|
|
7
|
+
".claude/skills/speckit-clarify/SKILL.md": "eb8907c57e9af2c54952370a45e3fb66cb21a64dc7b3d361615bab914c13becf",
|
|
8
|
+
".claude/skills/speckit-constitution/SKILL.md": "c1a044aba243ca6aff627fb5e4404feb6f1108d4f7dd174631bee3ae477d6c15",
|
|
9
|
+
".claude/skills/speckit-implement/SKILL.md": "042a0415ce60a5b66adf039da431d9a98cb4897ff330635e0bab0becbbaf3cd2",
|
|
10
|
+
".claude/skills/speckit-converge/SKILL.md": "a6acccbb6630f04fa716967c68f3be9da96762805ddd2bf284fad36324c5c876",
|
|
11
|
+
".claude/skills/speckit-plan/SKILL.md": "fd0e312109109d09d6b691d232925b54df11681e79e1dc333ad49b210d5efb00",
|
|
12
|
+
".claude/skills/speckit-checklist/SKILL.md": "b05086a11d4b98dcb85822e8a468ef30b8353f132b6dac1359080b93833c4666",
|
|
13
|
+
".claude/skills/speckit-specify/SKILL.md": "ebe19db388407058a6b078b3a66ea7198cb89795dc75680ba3c457f11bc8bf7a",
|
|
14
|
+
".claude/skills/speckit-tasks/SKILL.md": "023b1c75a62dc6fd8bff67855ebb82ec54a8104e727571aa72200c8afcc3f99b",
|
|
15
|
+
".claude/skills/speckit-taskstoissues/SKILL.md": "aa1151798a551fb52c439ca75c02d4f2e7b40c6c7d11fc025265cf1230c67cb1"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"integration": "speckit",
|
|
3
|
+
"version": "0.11.6",
|
|
4
|
+
"installed_at": "2026-06-23T23:29:12.163635+00:00",
|
|
5
|
+
"files": {
|
|
6
|
+
".specify/scripts/bash/common.sh": "af8a16f87b4f9084759c42ff9abf35c0b2a2025dffe58c298758ff86de2923b2",
|
|
7
|
+
".specify/scripts/bash/setup-plan.sh": "4eb12c5b00f5c66a7d01b56c90898d320dcef4425d9b96652d57156c84948eda",
|
|
8
|
+
".specify/scripts/bash/setup-tasks.sh": "cf21ba2212b4dd5b435c5ea8527500cfd27768b86c0bbc7ebc3207759f118d27",
|
|
9
|
+
".specify/scripts/bash/check-prerequisites.sh": "afce0aa8db177320d83aa0b8e3619c06b865fd810781894e4a7a3f81664941ce",
|
|
10
|
+
".specify/scripts/bash/create-new-feature.sh": "9ba116b64f0328eb69bc1a195d209074ea38823a73a554160d69df34a74daa65",
|
|
11
|
+
".specify/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3",
|
|
12
|
+
".specify/templates/checklist-template.md": "c37695297e5d3153d64f82c21223509940b13932046c7961c42d1d669516130c",
|
|
13
|
+
".specify/templates/tasks-template.md": "fc29a233f6f5a27ca31f1aa46b596af6500c627441c6e62b2bc4a1d721525842",
|
|
14
|
+
".specify/templates/spec-template.md": "3945437fc35cd30a5b2bf7beea680337c3516826d3efa5a6b92c4a7eca1ba28e",
|
|
15
|
+
".specify/templates/plan-template.md": "cc7f7979cf8d8836ec26492785affd80791d3422a2b745062ec695be8c985ef7"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
SYNC IMPACT REPORT
|
|
3
|
+
==================
|
|
4
|
+
Version change: [unset] → 1.0.0 (MINOR: initial constitution, all principles defined from scratch)
|
|
5
|
+
|
|
6
|
+
Modified principles: N/A (first ratification)
|
|
7
|
+
|
|
8
|
+
Added sections:
|
|
9
|
+
- Core Principles (5 principles)
|
|
10
|
+
- Technical Constraints
|
|
11
|
+
- Development Workflow
|
|
12
|
+
- Governance
|
|
13
|
+
|
|
14
|
+
Templates checked:
|
|
15
|
+
- .specify/templates/plan-template.md ✅ Constitution Check gate present, no update needed
|
|
16
|
+
- .specify/templates/spec-template.md ✅ Aligned with Saga/library constraints
|
|
17
|
+
- .specify/templates/tasks-template.md ✅ Task phases align with Red-Green workflow
|
|
18
|
+
|
|
19
|
+
Deferred TODOs: none
|
|
20
|
+
-->
|
|
21
|
+
|
|
22
|
+
# RubyReactor Constitution
|
|
23
|
+
|
|
24
|
+
## Core Principles
|
|
25
|
+
|
|
26
|
+
### I. Gem-First Design
|
|
27
|
+
|
|
28
|
+
RubyReactor is a Ruby gem published to RubyGems. Every feature MUST be designed
|
|
29
|
+
as part of the gem's public API — self-contained, independently loadable, and
|
|
30
|
+
free of host-application coupling. New capabilities MUST ship via `lib/` and be
|
|
31
|
+
reachable through `require "ruby_reactor"` without requiring application-level
|
|
32
|
+
monkey-patching. Optional integrations (Sidekiq, OpenTelemetry) MUST be isolated
|
|
33
|
+
behind adapter modules so the gem remains usable in sync-only or minimal
|
|
34
|
+
environments.
|
|
35
|
+
|
|
36
|
+
**Rationale**: A gem that cannot be required cleanly, or that bleeds host
|
|
37
|
+
concerns into its core, is not a gem — it is a Rails engine in disguise.
|
|
38
|
+
Keeping gem boundaries honest protects downstream consumers.
|
|
39
|
+
|
|
40
|
+
### II. Saga Pattern Integrity (NON-NEGOTIABLE)
|
|
41
|
+
|
|
42
|
+
Every workflow defined with RubyReactor MUST support compensation. Steps MUST
|
|
43
|
+
declare rollback logic where side effects are produced. DAG-based dependency
|
|
44
|
+
resolution governs execution order — no step may run before its declared
|
|
45
|
+
dependencies complete. Interrupts (pause/resume) MUST be first-class, not
|
|
46
|
+
bolted on. Partial execution without a recovery path (durability or compensation)
|
|
47
|
+
is forbidden.
|
|
48
|
+
|
|
49
|
+
**Rationale**: The Saga pattern's value is atomicity-like guarantees without
|
|
50
|
+
distributed transactions. Violating it — e.g., skipping compensation or allowing
|
|
51
|
+
orphaned steps — destroys the core promise and corrupts application state.
|
|
52
|
+
|
|
53
|
+
### III. Test-First with Real Infrastructure
|
|
54
|
+
|
|
55
|
+
RSpec is the mandatory test framework. Tests MUST be written and confirmed
|
|
56
|
+
failing before implementation begins (Red-Green-Refactor). Redis MUST be
|
|
57
|
+
reachable for the test suite — mocking Redis or Sidekiq state is forbidden
|
|
58
|
+
for integration and contract tests. The in-memory Sidekiq testing mode
|
|
59
|
+
(`Sidekiq::Testing.inline!`) is acceptable only for unit-level step logic,
|
|
60
|
+
never for async orchestration paths.
|
|
61
|
+
|
|
62
|
+
**Rationale**: We were burned by mock/real divergence in async and locking
|
|
63
|
+
paths. Real Redis surfaces timing, serialization, and TTL bugs that mocks
|
|
64
|
+
hide. The spec_helper enforces Redis availability at suite start for this
|
|
65
|
+
reason.
|
|
66
|
+
|
|
67
|
+
### IV. Observability by Default
|
|
68
|
+
|
|
69
|
+
Every failure MUST carry: reactor name, step name, redacted inputs, and
|
|
70
|
+
failure reason. OpenTelemetry instrumentation MUST be available via middleware
|
|
71
|
+
without requiring it as a hard dependency. The web dashboard MUST remain
|
|
72
|
+
current with the reactor state model. Structured logging is required for all
|
|
73
|
+
async execution paths — log lines MUST be machine-parseable (key=value or JSON).
|
|
74
|
+
|
|
75
|
+
**Rationale**: Async distributed workflows are black boxes without
|
|
76
|
+
observability. Operators need to reconstruct what happened and why from logs
|
|
77
|
+
and dashboards alone, especially after crash recovery.
|
|
78
|
+
|
|
79
|
+
### V. Simplicity and Semantic Versioning
|
|
80
|
+
|
|
81
|
+
YAGNI governs design: add the abstraction when a second real use case exists,
|
|
82
|
+
not before. Complexity MUST be justified in the PR. SemVer is strictly
|
|
83
|
+
enforced: MAJOR for any breaking public API change, MINOR for backward-compatible
|
|
84
|
+
additions, PATCH for fixes and clarifications. Breaking changes MUST include a
|
|
85
|
+
migration note in CHANGELOG.md.
|
|
86
|
+
|
|
87
|
+
**Rationale**: RubyReactor is a library used in production applications. A
|
|
88
|
+
surprise breaking change in a MINOR bump costs downstream teams debugging time
|
|
89
|
+
they did not budget for. Simplicity keeps the library auditable and the
|
|
90
|
+
upgrade path predictable.
|
|
91
|
+
|
|
92
|
+
## Technical Constraints
|
|
93
|
+
|
|
94
|
+
- **Ruby**: >= 3.0.0 required. No polyfills for older Rubies.
|
|
95
|
+
- **Sidekiq**: Core async dependency. Workers live in `lib/ruby_reactor/sidekiq_workers/`.
|
|
96
|
+
- **Redis**: Required for state persistence, locks, semaphores, rate limits, and
|
|
97
|
+
periods. The gem does NOT manage Redis connections — callers provide them.
|
|
98
|
+
- **dry-validation**: Input validation DSL. Schema definitions stay inside the
|
|
99
|
+
reactor/step DSL, not scattered across application code.
|
|
100
|
+
- **OpenTelemetry**: Optional instrumentation via the middleware stack
|
|
101
|
+
(`lib/ruby_reactor/open_telemetry.rb`). MUST NOT be a hard dependency.
|
|
102
|
+
- **RuboCop**: Style enforced via `rubocop-rspec` and `rubocop-rake`. All
|
|
103
|
+
commits MUST pass `bundle exec rubocop` without `--disable-pending-cops`.
|
|
104
|
+
|
|
105
|
+
## Development Workflow
|
|
106
|
+
|
|
107
|
+
- Feature branches target `main`. PRs MUST pass CI (RSpec + RuboCop) before merge.
|
|
108
|
+
- Releases are managed by release-please. Version bump lives in
|
|
109
|
+
`lib/ruby_reactor/version.rb`. Do not manually edit the version in gemspec.
|
|
110
|
+
- New features MUST update `README.md` documentation and add entries to
|
|
111
|
+
`CHANGELOG.md` under the correct semantic heading (`Features`, `Bug Fixes`,
|
|
112
|
+
`documentation`).
|
|
113
|
+
- Class-based step definitions are the preferred authoring style (not inline
|
|
114
|
+
lambdas). Documentation and examples MUST reflect this.
|
|
115
|
+
- The `demo_app/` directory serves as a living integration example. Changes to
|
|
116
|
+
public API surface MUST be reflected there.
|
|
117
|
+
|
|
118
|
+
## Governance
|
|
119
|
+
|
|
120
|
+
This constitution supersedes all other informal practices. Amendments require:
|
|
121
|
+
|
|
122
|
+
1. A PR updating this file with rationale.
|
|
123
|
+
2. Version bump per the SemVer policy in Principle V.
|
|
124
|
+
3. Consistency propagation: update all `.specify/templates/` files that reference
|
|
125
|
+
amended principles before the PR merges.
|
|
126
|
+
|
|
127
|
+
All PR reviews MUST include a Constitution Check verifying the change does not
|
|
128
|
+
violate any principle. Complexity that appears to violate a principle MUST be
|
|
129
|
+
justified in the `Complexity Tracking` table of the plan.
|
|
130
|
+
|
|
131
|
+
Compliance review: at each MINOR or MAJOR gem release, confirm this constitution
|
|
132
|
+
still accurately reflects the codebase and update as needed.
|
|
133
|
+
|
|
134
|
+
**Version**: 1.0.0 | **Ratified**: 2025-10-02 | **Last Amended**: 2026-06-24
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Consolidated prerequisite checking script
|
|
4
|
+
#
|
|
5
|
+
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
|
|
6
|
+
# It replaces the functionality previously spread across multiple scripts.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./check-prerequisites.sh [OPTIONS]
|
|
9
|
+
#
|
|
10
|
+
# OPTIONS:
|
|
11
|
+
# --json Output in JSON format
|
|
12
|
+
# --require-tasks Require tasks.md to exist (for implementation phase)
|
|
13
|
+
# --include-tasks Include tasks.md in AVAILABLE_DOCS list
|
|
14
|
+
# --paths-only Only output path variables (no validation)
|
|
15
|
+
# --help, -h Show help message
|
|
16
|
+
#
|
|
17
|
+
# OUTPUTS:
|
|
18
|
+
# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
|
|
19
|
+
# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
|
|
20
|
+
# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.
|
|
21
|
+
|
|
22
|
+
set -e
|
|
23
|
+
|
|
24
|
+
# Parse command line arguments
|
|
25
|
+
JSON_MODE=false
|
|
26
|
+
REQUIRE_TASKS=false
|
|
27
|
+
INCLUDE_TASKS=false
|
|
28
|
+
PATHS_ONLY=false
|
|
29
|
+
|
|
30
|
+
for arg in "$@"; do
|
|
31
|
+
case "$arg" in
|
|
32
|
+
--json)
|
|
33
|
+
JSON_MODE=true
|
|
34
|
+
;;
|
|
35
|
+
--require-tasks)
|
|
36
|
+
REQUIRE_TASKS=true
|
|
37
|
+
;;
|
|
38
|
+
--include-tasks)
|
|
39
|
+
INCLUDE_TASKS=true
|
|
40
|
+
;;
|
|
41
|
+
--paths-only)
|
|
42
|
+
PATHS_ONLY=true
|
|
43
|
+
;;
|
|
44
|
+
--help|-h)
|
|
45
|
+
cat << 'EOF'
|
|
46
|
+
Usage: check-prerequisites.sh [OPTIONS]
|
|
47
|
+
|
|
48
|
+
Consolidated prerequisite checking for Spec-Driven Development workflow.
|
|
49
|
+
|
|
50
|
+
OPTIONS:
|
|
51
|
+
--json Output in JSON format
|
|
52
|
+
--require-tasks Require tasks.md to exist (for implementation phase)
|
|
53
|
+
--include-tasks Include tasks.md in AVAILABLE_DOCS list
|
|
54
|
+
--paths-only Only output path variables (no prerequisite validation)
|
|
55
|
+
--help, -h Show this help message
|
|
56
|
+
|
|
57
|
+
EXAMPLES:
|
|
58
|
+
# Check task prerequisites (plan.md required)
|
|
59
|
+
./check-prerequisites.sh --json
|
|
60
|
+
|
|
61
|
+
# Check implementation prerequisites (plan.md + tasks.md required)
|
|
62
|
+
./check-prerequisites.sh --json --require-tasks --include-tasks
|
|
63
|
+
|
|
64
|
+
# Get feature paths only (no validation)
|
|
65
|
+
./check-prerequisites.sh --paths-only
|
|
66
|
+
|
|
67
|
+
EOF
|
|
68
|
+
exit 0
|
|
69
|
+
;;
|
|
70
|
+
*)
|
|
71
|
+
echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
|
|
72
|
+
exit 1
|
|
73
|
+
;;
|
|
74
|
+
esac
|
|
75
|
+
done
|
|
76
|
+
|
|
77
|
+
# Source common functions
|
|
78
|
+
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
79
|
+
source "$SCRIPT_DIR/common.sh"
|
|
80
|
+
|
|
81
|
+
# Get feature paths
|
|
82
|
+
_paths_output=$(get_feature_paths) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
|
|
83
|
+
eval "$_paths_output"
|
|
84
|
+
unset _paths_output
|
|
85
|
+
|
|
86
|
+
# If paths-only mode, output paths and exit (no validation)
|
|
87
|
+
if $PATHS_ONLY; then
|
|
88
|
+
if $JSON_MODE; then
|
|
89
|
+
# Minimal JSON paths payload (no validation performed)
|
|
90
|
+
if has_jq; then
|
|
91
|
+
jq -cn \
|
|
92
|
+
--arg repo_root "$REPO_ROOT" \
|
|
93
|
+
--arg branch "$CURRENT_BRANCH" \
|
|
94
|
+
--arg feature_dir "$FEATURE_DIR" \
|
|
95
|
+
--arg feature_spec "$FEATURE_SPEC" \
|
|
96
|
+
--arg impl_plan "$IMPL_PLAN" \
|
|
97
|
+
--arg tasks "$TASKS" \
|
|
98
|
+
'{REPO_ROOT:$repo_root,BRANCH:$branch,FEATURE_DIR:$feature_dir,FEATURE_SPEC:$feature_spec,IMPL_PLAN:$impl_plan,TASKS:$tasks}'
|
|
99
|
+
else
|
|
100
|
+
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
|
|
101
|
+
"$(json_escape "$REPO_ROOT")" "$(json_escape "$CURRENT_BRANCH")" "$(json_escape "$FEATURE_DIR")" "$(json_escape "$FEATURE_SPEC")" "$(json_escape "$IMPL_PLAN")" "$(json_escape "$TASKS")"
|
|
102
|
+
fi
|
|
103
|
+
else
|
|
104
|
+
echo "REPO_ROOT: $REPO_ROOT"
|
|
105
|
+
echo "BRANCH: $CURRENT_BRANCH"
|
|
106
|
+
echo "FEATURE_DIR: $FEATURE_DIR"
|
|
107
|
+
echo "FEATURE_SPEC: $FEATURE_SPEC"
|
|
108
|
+
echo "IMPL_PLAN: $IMPL_PLAN"
|
|
109
|
+
echo "TASKS: $TASKS"
|
|
110
|
+
fi
|
|
111
|
+
exit 0
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Validate required directories and files
|
|
115
|
+
if [[ ! -d "$FEATURE_DIR" ]]; then
|
|
116
|
+
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
|
|
117
|
+
echo "Run /speckit-specify first to create the feature structure." >&2
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
if [[ ! -f "$IMPL_PLAN" ]]; then
|
|
122
|
+
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
|
|
123
|
+
echo "Run /speckit-plan first to create the implementation plan." >&2
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Check for tasks.md if required
|
|
128
|
+
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
|
|
129
|
+
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
|
|
130
|
+
echo "Run /speckit-tasks first to create the task list." >&2
|
|
131
|
+
exit 1
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
# Build list of available documents
|
|
135
|
+
docs=()
|
|
136
|
+
|
|
137
|
+
# Always check these optional docs
|
|
138
|
+
[[ -f "$RESEARCH" ]] && docs+=("research.md")
|
|
139
|
+
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")
|
|
140
|
+
|
|
141
|
+
# Check contracts directory (only if it exists and has files)
|
|
142
|
+
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
|
|
143
|
+
docs+=("contracts/")
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")
|
|
147
|
+
|
|
148
|
+
# Include tasks.md if requested and it exists
|
|
149
|
+
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
|
|
150
|
+
docs+=("tasks.md")
|
|
151
|
+
fi
|
|
152
|
+
|
|
153
|
+
# Output results
|
|
154
|
+
if $JSON_MODE; then
|
|
155
|
+
# Build JSON array of documents
|
|
156
|
+
if has_jq; then
|
|
157
|
+
if [[ ${#docs[@]} -eq 0 ]]; then
|
|
158
|
+
json_docs="[]"
|
|
159
|
+
else
|
|
160
|
+
json_docs=$(printf '%s\n' "${docs[@]}" | jq -R . | jq -s .)
|
|
161
|
+
fi
|
|
162
|
+
jq -cn \
|
|
163
|
+
--arg feature_dir "$FEATURE_DIR" \
|
|
164
|
+
--argjson docs "$json_docs" \
|
|
165
|
+
'{FEATURE_DIR:$feature_dir,AVAILABLE_DOCS:$docs}'
|
|
166
|
+
else
|
|
167
|
+
if [[ ${#docs[@]} -eq 0 ]]; then
|
|
168
|
+
json_docs="[]"
|
|
169
|
+
else
|
|
170
|
+
json_docs=$(for d in "${docs[@]}"; do printf '"%s",' "$(json_escape "$d")"; done)
|
|
171
|
+
json_docs="[${json_docs%,}]"
|
|
172
|
+
fi
|
|
173
|
+
printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$(json_escape "$FEATURE_DIR")" "$json_docs"
|
|
174
|
+
fi
|
|
175
|
+
else
|
|
176
|
+
# Text output
|
|
177
|
+
echo "FEATURE_DIR:$FEATURE_DIR"
|
|
178
|
+
echo "AVAILABLE_DOCS:"
|
|
179
|
+
|
|
180
|
+
# Show status of each potential document
|
|
181
|
+
check_file "$RESEARCH" "research.md"
|
|
182
|
+
check_file "$DATA_MODEL" "data-model.md"
|
|
183
|
+
check_dir "$CONTRACTS_DIR" "contracts/"
|
|
184
|
+
check_file "$QUICKSTART" "quickstart.md"
|
|
185
|
+
|
|
186
|
+
if $INCLUDE_TASKS; then
|
|
187
|
+
check_file "$TASKS" "tasks.md"
|
|
188
|
+
fi
|
|
189
|
+
fi
|