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
5 changes: 5 additions & 0 deletions .agents/LEARNINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

## Patterns That Work

- For any new project-grouping logic, mirror `summary-builder`'s key derivation: use `context.root ?? context.name ?? 'unknown'`, not just `context.root`, or app/non-root sessions will collapse incorrectly.
- For branch PR workflow, `gh pr list --head <branch>` quickly confirms whether a PR already exists before running `gh pr create --base main --head <branch> --fill`.
- Use `summarize_report_with_meta`; `summarize_day_with_meta` is legacy.
- Import `fmt_duration_ms` from `src/utils/format.ts` (avoid local copies with divergent behavior).
Expand Down Expand Up @@ -38,10 +39,13 @@
- When refreshing docs/tutorials, treat `src/wildcard.ts` and `ARCHITECTURE.md` as source of truth first; old `apps/*`, `packages/*`, and Screenpipe references can linger after architecture consolidation.
- During snake_case -> kebab-case migrations, sweep architecture/docs tables and diagrams for stale underscore filenames to keep docs executable.
- For report-style commands with human output on `stdout`, send progress/status lines to `stderr` to keep markdown/JSON pipe-safe.
- For table-like CLI output with variable project/branch labels, compute the label column width from the current rows instead of hard-coding `padEnd(...)`; fixed widths break quickly on long branch names.
- AI provider env var fallbacks should be provider-specific: only use `OPENAI_API_KEY` when provider is `openai`, not `ollama`.
- For architecture-probe workflows, prefer creating `scratch/` scripts that favor read-only real module imports and print resolved module/config boundaries before performing any writes.
- `ConfigStore` + `wildcard` CLI outputs show that command behavior is mostly orchestrator-based and storage-driven; this helps in architecture mapping.
- `SyncEngine.syncOnce()` behavior is visible with a temp local `/bulk-upload/v1` server, but empty app_usage streams can leave corresponding cursor keys unset until data arrives.
- For time-bucketing utilities, anchor bucket boundaries to the requested range start instead of epoch multiples so local day/week labels do not drift in non-UTC timezones.
- For prompt readability in summary/report flows, keep stable system instructions in feature-local markdown files (`src/summary/prompts/*.md`) and keep dynamic session/project payload assembly in code.

## Patterns That Don't Work

Expand Down Expand Up @@ -75,3 +79,4 @@
- 2026-02-23: Ignore pattern updates should be mirrored in both `src/config/config-store.ts` (default config ignores) and `src/capture/ignore-patterns.ts` (defensive fallback) to keep watch filtering consistent when config is unavailable.
- 2026-02-24: In `SKILL.md` report guidance, require a two-pass "timeline + project enrichment" workflow: run `show/report`, then inspect top projects' README/manifests and changed high-signal files to produce impact-oriented summaries with confidence and explicit unknowns.
- 2026-03-03: For `scratch/` architecture probes, combine source parsing with real `wildcard --help`/`status --json` execution; parser-only command-dispatch checks can miss multiline `.action(...)` wiring.
- 2026-03-20: When refreshing Wildcard docs, verify `README.md`, `docs/ARCHITECTURE.md`, and `SKILL.md` against `src/wildcard.ts`, `src/config/config-store.ts`, and `src/server/bulk-upload-server.ts`; command flags, config defaults, and ingest routes drift independently.
9 changes: 9 additions & 0 deletions .specify/init-options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ai": "claude",
"ai_commands_dir": null,
"ai_skills": false,
"here": true,
"preset": null,
"script": "sh",
"speckit_version": "0.3.1"
}
37 changes: 37 additions & 0 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Wildcard Constitution

## Core Principles

### I. Local-First, Minimal Permissions
Wildcard must stay local-first. Core capture, search, sessionization, and reporting flows must work without network dependencies, and new features must preserve the project's lightweight, minimal-permission posture by default.

### II. CLI-First, Pipe-Safe Interfaces
Every user-facing workflow must be operable from the CLI. Human-readable output goes to `stdout`, progress and diagnostics go to `stderr`, and machine-readable modes must remain stable enough for automation.

### III. Small, Typed Changes
Changes should follow the existing Bun + TypeScript patterns: strict typing, focused modules, 2-space indentation, single quotes, and small helpers over sprawling abstractions. Prefer extending current command/session/storage flows before introducing new layers.

### IV. Validation Before Commit
Behavior changes must be backed by the smallest validation that proves them safe: focused tests for new logic, full `bun test` and `bun run check` before marking cross-cutting work complete, and CLI smoke checks for user-facing commands.

### V. Honest Specs and Docs
Specs, task lists, README/tutorial content, and architecture docs must reflect the code that actually ships. Tasks may only be marked done after the corresponding implementation and validation have really happened.

## Additional Constraints

- Runtime stack is Bun + TypeScript with SQLite-backed local storage.
- Core features must not assume cloud connectivity or AI availability.
- Existing command semantics and config defaults should be preserved unless a change is explicitly intentional and documented.

## Development Workflow

- Start from a spec or a clear implementation goal, then keep commits atomic and independently reversible.
- Reuse existing modules and patterns before adding new files or abstractions.
- For user-facing changes, update the relevant docs in the same unit of work.
- Treat project-memory notes in `.agents/LEARNINGS.md` as helpful local context, not a substitute for repo docs or tests.

## Governance

This constitution governs new plans, reviews, and implementation work in this repository. Any exception must be called out explicitly in the relevant plan or commit, along with why the deviation is necessary.

**Version**: 1.0.0 | **Ratified**: 2026-03-20 | **Last Amended**: 2026-03-20
190 changes: 190 additions & 0 deletions .specify/scripts/bash/check-prerequisites.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
#!/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
_paths_output=$(get_feature_paths) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
eval "$_paths_output"
unset _paths_output
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)
if has_jq; then
jq -cn \
--arg repo_root "$REPO_ROOT" \
--arg branch "$CURRENT_BRANCH" \
--arg feature_dir "$FEATURE_DIR" \
--arg feature_spec "$FEATURE_SPEC" \
--arg impl_plan "$IMPL_PLAN" \
--arg tasks "$TASKS" \
'{REPO_ROOT:$repo_root,BRANCH:$branch,FEATURE_DIR:$feature_dir,FEATURE_SPEC:$feature_spec,IMPL_PLAN:$impl_plan,TASKS:$tasks}'
else
printf '{"REPO_ROOT":"%s","BRANCH":"%s","FEATURE_DIR":"%s","FEATURE_SPEC":"%s","IMPL_PLAN":"%s","TASKS":"%s"}\n' \
"$(json_escape "$REPO_ROOT")" "$(json_escape "$CURRENT_BRANCH")" "$(json_escape "$FEATURE_DIR")" "$(json_escape "$FEATURE_SPEC")" "$(json_escape "$IMPL_PLAN")" "$(json_escape "$TASKS")"
fi
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 has_jq; then
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(printf '%s\n' "${docs[@]}" | jq -R . | jq -s .)
fi
jq -cn \
--arg feature_dir "$FEATURE_DIR" \
--argjson docs "$json_docs" \
'{FEATURE_DIR:$feature_dir,AVAILABLE_DOCS:$docs}'
else
if [[ ${#docs[@]} -eq 0 ]]; then
json_docs="[]"
else
json_docs=$(for d in "${docs[@]}"; do printf '"%s",' "$(json_escape "$d")"; done)
json_docs="[${json_docs%,}]"
fi
printf '{"FEATURE_DIR":"%s","AVAILABLE_DOCS":%s}\n' "$(json_escape "$FEATURE_DIR")" "$json_docs"
fi
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
Loading