Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Commit Message Instructions

When generating commit messages or summaries, adhere to the following strict guidelines:

1. **Conventional Commits Standard**:
- Use the format: `<type>(<scope>): <description>`
- Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`.

2. **Style & Tone**:
- **Imperative Mood**: Use "add", "fix", "change" (not "added", "fixes", "changing").
- **Concise**: Keep the subject line under 50 characters.
- **Factual**: Describe WHAT changed. Avoid opinionated adjectives.

3. **No Filler**:
- **FORBIDDEN**: "This commit...", "Updates the file...", "Refactors code to...", "Various changes..."
- **REQUIRED**: Direct statements like "update constitution", "fix NPE in usage", "bump kotlin version".

4. **Formatting**:
- No period at the end of the subject line.
- Use strict markdown lists for the body if explaining multiple changes.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,6 @@ local.properties
.idea/modules
*.iml
*.ipr

# Agent
.agent
54 changes: 54 additions & 0 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# WorldTides Constitution

## Core Principles

### I. Kotlin-First, Java-Compatible
This library is developed in Kotlin to leverage modern language features, safety, and conciseness. However, **Java interoperability is a first-class citizen**.
- All public APIs must be consumable from Java without awkward syntax (e.g., use `@JvmOverloads`, `@JvmStatic` where appropriate).
- Asynchronous operations must provide both Suspend functions (for Kotlin) and Callback interfaces (for Java).
- Avoid exposing Kotlin-specific types (like `inline` classes) in the public API if they degrade the Java experience.

### II. Strict API Fidelity
The library serves as a strongly-typed proxy for the [WorldTides API](https://www.worldtides.info/apidocs).
- **Naming**: Library models and methods should mirror the API's terminology unless it conflicts with standard Java/Kotlin naming conventions.
- **Completeness**: Aim to support all parameters and response fields available in the API version we target.
- **Updates**: Changes in the WorldTides API (v2, v3, etc.) should be reflected in the library with appropriate versioning.

### III. Type Safety & Null Safety
Users of this library should never have to parse raw JSON.
- All API responses must be mapped to strongly-typed data classes.
- Nullability must be strictly modeled: if a field can be missing in the API response, it must be nullable in the model.
- `Result<T>` or similar wrappers should be used to handle success/failure states explicitly.

## Architecture Standards

### Networking Layer
- **Retrofit & Moshi**: The library uses Retrofit for networking and Moshi for JSON parsing.
- **Encapsulation**: The internal networking stack (OkHttp client) is encapsulated to provide a simple "one-line" initialization experience.
- *Future Consideration*: Allow dependency injection for `OkHttpClient` to enable advanced configuration (caching, interceptors) by the consumer.

### Data Models
- **Immutability**: All data models (`TideExtremes`, `Extreme`, etc.) are immutable `data class` structures.
- **Serialization**: Use annotations (e.g., `@Json`) to map API JSON keys to clean Kotlin property names.

## Development Workflow

### Versioning
- **Semantic Versioning**: Follow [SemVer](https://semver.org/) (MAJOR.MINOR.PATCH).
- MAJOR: Breaking API changes.
- MINOR: New features (e.g., new API endpoints supported) in a backward-compatible manner.
- PATCH: Bug fixes.

### Documentation
- **KDoc & Javadoc**: All public classes and methods must be documented.
- **Samples**: Code samples in README must include both Kotlin and Java examples side-by-side.

## Governance

### QA & Testing
- **Mandatory Testing**: 100% of the codebase must be covered by tests.
- **Unit Tests**: Required for all logic, data transformations, and utility functions.
- **Integration Tests**: Verification of API mapping and inter-component communication is critical.
- **Public API Review**: Any change to the public API requires a review focusing on "How does this look in Java?" and "How does this look in Kotlin?".

**Version**: 1.0.0 | **Ratified**: 2026-01-09
166 changes: 166 additions & 0 deletions .specify/scripts/bash/check-prerequisites.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env bash

# Consolidated prerequisite checking script
#
# This script provides unified prerequisite checking for Spec-Driven Development workflow.
# It replaces the functionality previously spread across multiple scripts.
#
# Usage: ./check-prerequisites.sh [OPTIONS]
#
# OPTIONS:
# --json Output in JSON format
# --require-tasks Require tasks.md to exist (for implementation phase)
# --include-tasks Include tasks.md in AVAILABLE_DOCS list
# --paths-only Only output path variables (no validation)
# --help, -h Show help message
#
# OUTPUTS:
# JSON mode: {"FEATURE_DIR":"...", "AVAILABLE_DOCS":["..."]}
# Text mode: FEATURE_DIR:... \n AVAILABLE_DOCS: \n ✓/✗ file.md
# Paths only: REPO_ROOT: ... \n BRANCH: ... \n FEATURE_DIR: ... etc.

set -e

# Parse command line arguments
JSON_MODE=false
REQUIRE_TASKS=false
INCLUDE_TASKS=false
PATHS_ONLY=false

for arg in "$@"; do
case "$arg" in
--json)
JSON_MODE=true
;;
--require-tasks)
REQUIRE_TASKS=true
;;
--include-tasks)
INCLUDE_TASKS=true
;;
--paths-only)
PATHS_ONLY=true
;;
--help|-h)
cat << 'EOF'
Usage: check-prerequisites.sh [OPTIONS]
Consolidated prerequisite checking for Spec-Driven Development workflow.
OPTIONS:
--json Output in JSON format
--require-tasks Require tasks.md to exist (for implementation phase)
--include-tasks Include tasks.md in AVAILABLE_DOCS list
--paths-only Only output path variables (no prerequisite validation)
--help, -h Show this help message
EXAMPLES:
# Check task prerequisites (plan.md required)
./check-prerequisites.sh --json
# Check implementation prerequisites (plan.md + tasks.md required)
./check-prerequisites.sh --json --require-tasks --include-tasks
# Get feature paths only (no validation)
./check-prerequisites.sh --paths-only
EOF
exit 0
;;
*)
echo "ERROR: Unknown option '$arg'. Use --help for usage information." >&2
exit 1
;;
esac
done

# Source common functions
SCRIPT_DIR="$(CDPATH="" cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/common.sh"

# Get feature paths and validate branch
eval $(get_feature_paths)
check_feature_branch "$CURRENT_BRANCH" "$HAS_GIT" || exit 1

# If paths-only mode, output paths and exit (support JSON + paths-only combined)
if $PATHS_ONLY; then
if $JSON_MODE; then
# Minimal JSON paths payload (no validation performed)
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
"$REPO_ROOT" "$CURRENT_BRANCH" "$FEATURE_DIR" "$FEATURE_SPEC" "$IMPL_PLAN" "$TASKS"
else
echo "REPO_ROOT: $REPO_ROOT"
echo "BRANCH: $CURRENT_BRANCH"
echo "FEATURE_DIR: $FEATURE_DIR"
echo "FEATURE_SPEC: $FEATURE_SPEC"
echo "IMPL_PLAN: $IMPL_PLAN"
echo "TASKS: $TASKS"
fi
exit 0
fi

# Validate required directories and files
if [[ ! -d "$FEATURE_DIR" ]]; then
echo "ERROR: Feature directory not found: $FEATURE_DIR" >&2
echo "Run /speckit.specify first to create the feature structure." >&2
exit 1
fi

if [[ ! -f "$IMPL_PLAN" ]]; then
echo "ERROR: plan.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.plan first to create the implementation plan." >&2
exit 1
fi

# Check for tasks.md if required
if $REQUIRE_TASKS && [[ ! -f "$TASKS" ]]; then
echo "ERROR: tasks.md not found in $FEATURE_DIR" >&2
echo "Run /speckit.tasks first to create the task list." >&2
exit 1
fi

# Build list of available documents
docs=()

# Always check these optional docs
[[ -f "$RESEARCH" ]] && docs+=("research.md")
[[ -f "$DATA_MODEL" ]] && docs+=("data-model.md")

# Check contracts directory (only if it exists and has files)
if [[ -d "$CONTRACTS_DIR" ]] && [[ -n "$(ls -A "$CONTRACTS_DIR" 2>/dev/null)" ]]; then
docs+=("contracts/")
fi

[[ -f "$QUICKSTART" ]] && docs+=("quickstart.md")

# Include tasks.md if requested and it exists
if $INCLUDE_TASKS && [[ -f "$TASKS" ]]; then
docs+=("tasks.md")
fi

# Output results
if $JSON_MODE; then
# Build JSON array of documents
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(printf '"%s",' "${docs[@]}")
json_docs="[${json_docs%,}]"
fi

printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$FEATURE_DIR" "$json_docs"
else
# Text output
echo "FEATURE_DIR:$FEATURE_DIR"
echo "AVAILABLE_DOCS:"

# Show status of each potential document
check_file "$RESEARCH" "research.md"
check_file "$DATA_MODEL" "data-model.md"
check_dir "$CONTRACTS_DIR" "contracts/"
check_file "$QUICKSTART" "quickstart.md"

if $INCLUDE_TASKS; then
check_file "$TASKS" "tasks.md"
fi
fi
Loading