Skip to content
Open
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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@
/target/

!examples/src/bin/

# graphify (knowledge graph) — allowlist: commit only graph.json + GRAPH_REPORT.md,
# ignore everything else graphify-out/ produces (exports, caches, bookkeeping)
graphify-out/*
!graphify-out/graph.json
!graphify-out/GRAPH_REPORT.md
8 changes: 8 additions & 0 deletions .specify/init-options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"ai": "copilot",
"feature_numbering": "sequential",
"here": true,
"integration": "copilot",
"script": "sh",
"speckit_version": "0.12.18"
}
15 changes: 15 additions & 0 deletions .specify/integration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "0.12.18",
"integration_state_schema": 1,
"installed_integrations": [
"copilot"
],
"integration_settings": {
"copilot": {
"script": "sh",
"invoke_separator": "."
}
},
"integration": "copilot",
"default_integration": "copilot"
}
28 changes: 28 additions & 0 deletions .specify/integrations/copilot.manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"integration": "copilot",
"version": "0.12.18",
"installed_at": "2026-07-17T15:07:12.587971+00:00",
"files": {
".github/agents/speckit.analyze.agent.md": "07e1e9f997bce9e06d3823ecf1ed315bb62381b81e7d6a7aef19c5087c320e70",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The copilot manifest records content hashes for 21 files (.github/agents/.agent.md, .github/prompts/.prompt.md, .vscode/settings.json) that are not present in the repository. A hash-based integrity/compliance ledger that references files that never get committed cannot be verified on a fresh checkout, so the scaffold is not reproducible from this PR alone. Install the copilot integration's files (or whatever produces these) in the same change, or drop the manifest entries until the files exist.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/integrations/copilot.manifest.json, line 6:

<comment>The copilot manifest records content hashes for 21 files (.github/agents/*.agent.md, .github/prompts/*.prompt.md, .vscode/settings.json) that are not present in the repository. A hash-based integrity/compliance ledger that references files that never get committed cannot be verified on a fresh checkout, so the scaffold is not reproducible from this PR alone. Install the copilot integration's files (or whatever produces these) in the same change, or drop the manifest entries until the files exist.</comment>

<file context>
@@ -0,0 +1,28 @@
+  "version": "0.12.18",
+  "installed_at": "2026-07-17T15:07:12.587971+00:00",
+  "files": {
+    ".github/agents/speckit.analyze.agent.md": "07e1e9f997bce9e06d3823ecf1ed315bb62381b81e7d6a7aef19c5087c320e70",
+    ".github/agents/speckit.clarify.agent.md": "595ae8988179a91780ce10e258afcccaa313b0924a79e720c66226e31af7ec00",
+    ".github/agents/speckit.constitution.agent.md": "e0d1d7c237d4657914dcccb6ea0c3a3a10d8d1d9a36b198282e22b3d0b9a55e5",
</file context>

".github/agents/speckit.clarify.agent.md": "595ae8988179a91780ce10e258afcccaa313b0924a79e720c66226e31af7ec00",
".github/agents/speckit.constitution.agent.md": "e0d1d7c237d4657914dcccb6ea0c3a3a10d8d1d9a36b198282e22b3d0b9a55e5",
".github/agents/speckit.implement.agent.md": "6a5713a4db8d48dd7c93e38b9957c6e54b6b7dc899ebab66f9ccb3bce58fdfeb",
".github/agents/speckit.converge.agent.md": "e585bc94a3f01cb45eb4f4f6003268a7bc7e1f1685d343c25ad5dc3c484b4816",
".github/agents/speckit.plan.agent.md": "ff1809d5d72b399ec364414a150c1a20e782677972d11f0bdf8c65c73f898a71",
".github/agents/speckit.checklist.agent.md": "2124a817bddbff7f469fd47b08e43dd9a39b769499d367f6888a74e1e821412d",
".github/agents/speckit.specify.agent.md": "e24c01f27d269dab73c4178ce5bb1c31198dbfc36b9198cc6e407ef1122f4745",
".github/agents/speckit.tasks.agent.md": "e3569f2fbdb99704b81e3647ce9e52fb812764d6b2590fc497a2c2130b43ba72",
".github/agents/speckit.taskstoissues.agent.md": "0a436a42ceca2db309df88985d1939ee7f176c4a7a2d7c7a8d2253006cfe6870",
".github/prompts/speckit.analyze.prompt.md": "bb93dbbafa96d07b7cd07fc7061d8adb0c6b26cb772a52d0dce263b1ca2b9b77",
".github/prompts/speckit.clarify.prompt.md": "ce79b3437ca918d46ac858eb4b8b44d3b0a02c563660c60d94c922a7b5d8d4f4",
".github/prompts/speckit.constitution.prompt.md": "38f937279de14387601422ddfda48365debdbaf47b2d513527b8f6d8a27d499d",
".github/prompts/speckit.implement.prompt.md": "5053a17fb9238338c63b898ee9c80b2cb4ad1a90c6071fe3748de76864ac6a80",
".github/prompts/speckit.converge.prompt.md": "8e37fe6d8b6ce130fcc011b995edd3e412d825c0f46abd1a7706451f2049d571",
".github/prompts/speckit.plan.prompt.md": "2098dae6bd9277335f31cb150b78bfb1de539c0491798e5cfe382c89ab0bcd0e",
".github/prompts/speckit.checklist.prompt.md": "c3aea7526c5cbfd8665acc9508ad5a9a3f71e91a63c36be7bed13a834c3a683c",
".github/prompts/speckit.specify.prompt.md": "7b2cc4dc6462da1c96df46bac4f60e53baba3097f4b24ac3f9b684194458aa98",
".github/prompts/speckit.tasks.prompt.md": "88fc57c289f99d5e9d35c255f3e2683f73ecb0a5155dcb4d886f82f52b11841f",
".github/prompts/speckit.taskstoissues.prompt.md": "2f9636d4f312a1470f000747cb62677fec0655d8b4e2357fa4fbf238965fa66d",
".vscode/settings.json": "3db3a1d8417d38a56b405f60b600dce666b4fc47be7fe332a0b051c4bd1fd4b7"
}
}
17 changes: 17 additions & 0 deletions .specify/integrations/speckit.manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"integration": "speckit",
"version": "0.12.18",
"installed_at": "2026-07-17T15:07:12.597929+00:00",
"files": {
".specify/scripts/bash/common.sh": "6ff86bf39f6b4684b0f80927dc7a1dadec26b4671988a3fe4d6c2523cbd3aa22",
".specify/scripts/bash/setup-plan.sh": "4469b22960f43c07c33dca00de6dedb252145e9a9ce8fbb0e63be82e02b082ab",
".specify/scripts/bash/setup-tasks.sh": "1d4bcebe93f3e4e778964978cfe9bfb67ee94e7dc688f2ff3be224f647f61f1f",
".specify/scripts/bash/check-prerequisites.sh": "ac3e96258a05d029d048076393a03aadff5c7c3a55a26d0a9f5c17886a1c659d",
".specify/scripts/bash/create-new-feature.sh": "dd531f9ba47c9ce9975b597947377be9542b7236681d6dc033513c4e3cfc50f2",
".specify/templates/constitution-template.md": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3",
".specify/templates/checklist-template.md": "0ad704b60af2df817aee1c0a2ecc0e0304b271d2de34047df1c891735967033e",
".specify/templates/tasks-template.md": "c731575d8099b3f871861186fbd1a592b51b2ba57fb99e1a0dab439ff6d5608f",
".specify/templates/spec-template.md": "3945437fc35cd30a5b2bf7beea680337c3516826d3efa5a6b92c4a7eca1ba28e",
".specify/templates/plan-template.md": "5ef0e4c97b36e9f91372dc6eb8e5a7e515af8958cf1a9286e43a1ebd9bd48540"
}
}
4 changes: 4 additions & 0 deletions .specify/memory/.constitution-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"sha256": "ce7549540fa45543cca797a150201d868e64495fdff39dc38246fb17bd4024b3",
"source": "core"
}
104 changes: 104 additions & 0 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Iklo Constitution

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This scaffolded constitution is content from the wrong project. The doc is titled "Iklo Constitution" and governs Iklo (a language/shell/live-image runtime, with kebab-case identifiers, sigils, and grammar rules), but this repo is rsenna/guiltty, a Rust terminal-graphics library (per repo.toml and README.md). The rsenna/iklo/issues links and "Iklo"/grammar constraints don't apply here and will mislead every reader who follows this as the governing standard. Rewrite the document to describe this repo's actual project, or place it in a template that is instantiated per-repo with the correct project name.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/memory/constitution.md, line 1:

<comment>This scaffolded constitution is content from the wrong project. The doc is titled "Iklo Constitution" and governs Iklo (a language/shell/live-image runtime, with kebab-case identifiers, sigils, and grammar rules), but this repo is `rsenna/guiltty`, a Rust terminal-graphics library (per `repo.toml` and `README.md`). The `rsenna/iklo/issues` links and "Iklo"/grammar constraints don't apply here and will mislead every reader who follows this as the governing standard. Rewrite the document to describe this repo's actual project, or place it in a template that is instantiated per-repo with the correct project name.</comment>

<file context>
@@ -0,0 +1,104 @@
+# Iklo Constitution
+
+These are the principles that govern every spec, plan, and task in this repo.
</file context>


These are the principles that govern every spec, plan, and task in this repo.
They supersede convenience. Amendments require an ADR under
[`specs/decisions/`](../../specs/decisions/).

## Core Principles

### I. Test-First (Non-Negotiable)

Every behavioral change lands with a failing test first. Red → Green →
regression → commit. No feature is "done" until `make test` is green and the

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The constitution says a feature is not done "until make test is green", but this repo has no Makefile — the test command is cargo test --workspace (see AGENTS.md/README). Point readers at the real command so the gate is actionable.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/memory/constitution.md, line 12:

<comment>The constitution says a feature is not done "until `make test` is green", but this repo has no Makefile — the test command is `cargo test --workspace` (see AGENTS.md/README). Point readers at the real command so the gate is actionable.</comment>

<file context>
@@ -0,0 +1,104 @@
+### I. Test-First (Non-Negotiable)
+
+Every behavioral change lands with a failing test first. Red → Green →
+regression → commit. No feature is "done" until `make test` is green and the
+new behavior is covered by a test that fails against `main`.
+
</file context>

new behavior is covered by a test that fails against `main`.

### II. One Epic In Flight

At most one feature under `specs/` is active at a time. Concurrent epics
fracture attention, produce merge pain, and let half-formed specs contaminate
each other. When a new epic is activated, the previous one either ships or is
paused explicitly (its `specs/NNN-*/` directory stays put; nothing else moves
forward until it's back on the runway).

### III. Substrate Before Feature

Iklo is a language, a shell, and an in-process live-image runtime that must
share one grammar. When any load-bearing capability grows a second consumer
(a second backend, a second call site, a second scope), the *shape* of the
seam gets extracted to an interface **before** the second implementation is
built. We install boundaries early; we do not retrofit them under pressure.

### IV. Kebab-Case Iklo, Idiomatic Rust

Iklo-level identifiers (primitives, keywords, forms, sigils) are kebab-case
without exception, including subtraction-lookalikes: `x-1` is one identifier;
subtraction requires whitespace on both sides. Rust code follows idiomatic
Rust (`snake_case` items, `PascalCase` types) — the two style systems do not
bleed. See [`.github/instructions/rust.instructions.md`](../../.github/instructions/rust.instructions.md).

### V. Comments Justify Themselves

Code is documentation by default. Comments appear only where the *why* is
non-obvious. Do not narrate what the code does. Doc comments on public APIs;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The constitution links to instruction and ADR files that don't exist here: .github/instructions/rust.instructions.md, .github/instructions/self-explanatory-code-commenting.instructions.md, and specs/decisions/ADR-0001-substrate-boundary.md (.github/instructions is absent; specs/decisions is empty). Broken links in a compliance document make the referenced rules unverifiable. Either add these files in this PR or fix the links to existing references.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .specify/memory/constitution.md, line 42:

<comment>The constitution links to instruction and ADR files that don't exist here: `.github/instructions/rust.instructions.md`, `.github/instructions/self-explanatory-code-commenting.instructions.md`, and `specs/decisions/ADR-0001-substrate-boundary.md` (`.github/instructions` is absent; `specs/decisions` is empty). Broken links in a compliance document make the referenced rules unverifiable. Either add these files in this PR or fix the links to existing references.</comment>

<file context>
@@ -0,0 +1,104 @@
+### V. Comments Justify Themselves
+
+Code is documentation by default. Comments appear only where the *why* is
+non-obvious. Do not narrate what the code does. Doc comments on public APIs;
+usually nothing on internal helpers. See
+[`.github/instructions/self-explanatory-code-commenting.instructions.md`](../../.github/instructions/self-explanatory-code-commenting.instructions.md).
</file context>

usually nothing on internal helpers. See
[`.github/instructions/self-explanatory-code-commenting.instructions.md`](../../.github/instructions/self-explanatory-code-commenting.instructions.md).

### VI. Load-Bearing Decisions Become ADRs

Any decision that is expensive to reverse, that determines the shape of code
across multiple crates, or that gets questioned a second time becomes an ADR
under [`specs/decisions/`](../../specs/decisions/). ADRs are sequential
(`ADR-NNNN`), never deleted, and superseded rather than edited. Lightweight
inline `**Decision (date)**` notes are fine until they harden.

### VII. No Workarounds Left Standing

If a bug is directly caused by or tightly coupled to code being changed, it
gets fixed as part of that change. Failing tests are never skipped or removed
to make a build pass. Half-fixes and "for now" scaffolding either graduate
into real solutions in the same PR or become an issue on
[rsenna/iklo](https://github.com/rsenna/iklo/issues) with the code that
requires them.

## Development Constraints

- **Rust**, edition 2021, workspace `resolver = "2"`. Toolchain pinned via
[`mise.toml`](../../mise.toml).
- **Storage:** the runtime image lives behind a `Substrate` boundary (see
[ADR-0001](../../specs/decisions/ADR-0001-substrate-boundary.md)). Only
substrate implementations may hold binding state directly.
- **Dependencies:** adding a workspace dependency or a new crate is an
"ask first" change. Removing one usually isn't.
- **Grammar changes:** any change to sigils, keywords, or terminator rules
requires an ADR — the parser has many quiet consumers.

## Workflow

Spec-driven, four gates powered by GitHub Spec Kit v0.12+:

1. **`/speckit.specify`** — author a feature spec in `specs/NNN-<slug>/spec.md`.
Creates and switches to branch `NNN-<slug>`.
2. **`/speckit.plan`** — produce `specs/NNN-<slug>/plan.md` (technical approach,
structure decisions) from the spec.
3. **`/speckit.tasks`** — produce `specs/NNN-<slug>/tasks.md` (ordered,
TDD-shaped, one commit per task).
4. **`/speckit.implement`** — execute the tasks; each task ends with a commit.

Optional gates: `/speckit.clarify` (before `/speckit.plan`),
`/speckit.checklist` (after `/speckit.plan`), `/speckit.analyze` (after
`/speckit.tasks`), `/speckit.converge` (retro-fit remaining work into tasks).

**Bugs** are GitHub Issues on
[rsenna/iklo](https://github.com/rsenna/iklo/issues) — not files in this
repo. Promote an issue into a `specs/NNN-*/spec.md` when it grows into real
design work.

## Governance

- These principles supersede all other practices in the repo.
- Amendments require an ADR (context, alternatives rejected, consequences).
- Every PR/review verifies compliance; complexity must be justified in
`plan.md`'s Complexity Tracking section.
- Runtime development guidance lives in [`../../AGENTS.md`](../../AGENTS.md).

**Version**: 1.0.0 | **Ratified**: 2026-07-17 | **Last Amended**: 2026-07-17
195 changes: 195 additions & 0 deletions .specify/scripts/bash/check-prerequisites.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#!/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.
# In --paths-only mode this is pure resolution, so pass --no-persist to opt out
# of the feature.json write side effect (issue #3025).
if $PATHS_ONLY; then
_paths_output=$(get_feature_paths --no-persist) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
else
_paths_output=$(get_feature_paths) || { echo "ERROR: Failed to resolve feature paths" >&2; exit 1; }
fi
eval "$_paths_output"
unset _paths_output

# If paths-only mode, output paths and exit (no validation)
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