From 2717212bdb1926534580b8bff8914fd377f759a9 Mon Sep 17 00:00:00 2001 From: "m.kindritskiy" Date: Sun, 14 Jun 2026 15:38:34 +0300 Subject: [PATCH] Init skills --- AGENTS.md | 14 +++++ CONTEXT.md | 101 +++++++++++++++++++++++++++++++++++ UBIQUITOUS_LANGUAGE.md | 76 ++++++++++++++++++++++++++ docs/agents/domain.md | 44 +++++++++++++++ docs/agents/issue-tracker.md | 22 ++++++++ docs/agents/triage-labels.md | 13 +++++ go.mod | 7 ++- go.sum | 10 ++++ 8 files changed, 285 insertions(+), 2 deletions(-) create mode 100644 CONTEXT.md create mode 100644 UBIQUITOUS_LANGUAGE.md create mode 100644 docs/agents/domain.md create mode 100644 docs/agents/issue-tracker.md create mode 100644 docs/agents/triage-labels.md diff --git a/AGENTS.md b/AGENTS.md index 9d97c7ab..befa397d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,6 +21,20 @@ lets publish-docs # deploy docs site `lets test-unit`, `lets test-bats`, and `lets lint` require Docker. Use `go test ./...` locally for quick iteration without Docker. +## Agent skills + +### Issue tracker + +The Issue tracker for this repo is GitHub; work items live as GitHub Issues in `lets-cli/lets`. See `docs/agents/issue-tracker.md`. + +### Triage labels + +Triage uses the default Triage label names: `needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, and `wontfix`. See `docs/agents/triage-labels.md`. + +### Domain docs + +This is a Single-context repo; skills should read the root Context and root ADRs. See `docs/agents/domain.md`. + ## Agent Behavior - **Proactive execution** — Don't ask "Can I proceed?" for implementation. DO ask before changing success criteria, test thresholds, or what "working" means. diff --git a/CONTEXT.md b/CONTEXT.md new file mode 100644 index 00000000..0405d751 --- /dev/null +++ b/CONTEXT.md @@ -0,0 +1,101 @@ +# Context + +This is a single-context repo. + +## Purpose + +`lets` is a YAML-based CLI task runner. A repository defines project workflow in `lets.yaml`, and `lets` turns that declaration into runnable **Project commands**, built-in **Self commands**, help output, shell completion, and editor tooling. In marketing copy "task runner" is fine; in precise product language prefer **Project command** to "task". + +## Language choices + +- Use **Settings** for `~/.config/lets/config.yaml`. +- Use **Project config** for `lets.yaml`. +- Use **Project command** for a user-defined runnable unit. +- Use **Self command** for `lets self ...` functionality. +- Use **Theme** for user-facing output styling; reserve "color scheme" for implementation details. + +## Configuration model + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Project config** | The repository-level declaration in `lets.yaml` that defines commands and shared execution rules. | Settings, user config | +| **Settings** | Per-user lets behavior stored in `~/.config/lets/config.yaml`. | Project config | +| **Mixin** | An additional config file merged additively into a Project config. | Override, patch | +| **Global env** | Top-level environment entries shared by all Project commands. | Process env | +| **Env file** | A dotenv-style file loaded into command execution at global or command scope. | Settings file, config file | +| **Theme** | A named style for lets help and styled error output. | Color scheme, palette | + +## Command model + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Project command** | A named runnable unit declared under `commands` in Project config. | Task, job | +| **Self command** | A built-in `lets self ...` command used to manage lets itself. | Project command | +| **Option** | A docopt-declared CLI input for a Project command. | Cobra flag, raw env var | +| **Dependency chain** | The ordered graph of Project commands reached through `depends`. | Pipeline, hook | +| **Reference command** | A Project command that reuses another command via `ref` and optional `args`. | Alias | +| **Command group** | A help-only label used to organize Project commands in rendered help. | Execution stage | +| **Environment** | The fully resolved environment passed to Project command execution. | Process env | +| **Checksum** | A SHA1 digest derived from configured files and exposed as environment variables. | Cache key | +| **Persisted checksum** | Stored checksum state used to detect change between invocations. | Build cache | + +## Execution model + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Init script** | A top-level script run once per lets invocation before the first Project command executes. | Before script | +| **Before script** | A top-level script prepended to each Project command invocation, including dependencies. | Init script | +| **After script** | A command-scoped script run after a Project command execution attempt. | Cleanup hook | +| **Work dir** | The directory where a Project command runs after config and command resolution. | Repo root | +| **Help surface** | The rendered CLI help for root and Project commands. | Docs page | +| **LSP surface** | The editor-facing language-server features exposed by `lets self lsp`. | CLI help | + +## Relationships + +- One **Project config** defines zero or more **Project commands**. +- A **Project command** inherits shell and shared execution rules from **Project config** unless it overrides them. +- A **Dependency chain** contains only **Project commands**; **Self commands** are outside that graph. +- A **Reference command** points to exactly one target **Project command**. +- An **Option** parsed for a **Project command** is exposed as `LETSOPT_*` and `LETSCLI_*` variables in the command **Environment**. +- A **Checksum** belongs to one **Project command** and may expose one aggregate digest plus named digests. +- **Settings** affect lets itself, while **Project config** affects repository workflow. +- **Mixins** add commands, env, before scripts, and env files; conflicting names are errors rather than implicit overrides. +- A **Command group** changes help organization only; it does not change execution behavior. + +## Execution flow + +1. Discover **Project config** from `--config`, `LETS_CONFIG`, or upward search for `lets.yaml`. +2. Load **Mixins** and merge them into one effective **Project config**. +3. Validate config structure, supported keywords, version requirements, references, and dependency graph. +4. Build CLI surfaces from **Project commands** plus built-in **Self commands**. +5. Parse **Option** values with docopt and expose them to the command **Environment**. +6. Resolve **Environment** from built-in lets vars, config env, env files, parsed options, explicit overrides, and checksum vars. +7. Run the **Init script** once per invocation. +8. Execute the **Dependency chain** before the requested **Project command**. +9. Run Project command scripts in the selected shell and **Work dir**. +10. Run the **After script** after the execution attempt; its own failure does not replace the main command result. +11. Persist **Persisted checksum** state only after successful execution. + +## Precedence and boundaries + +- **Settings** precedence is: environment variables > settings file > built-in defaults. +- **Environment** precedence at command runtime is: process env < built-in lets vars < global `env` < global `env_file` < command `env` < command `env_file` < parsed options / explicit env overrides / checksum vars. +- `NO_COLOR` disables color even if **Settings** choose a **Theme**. +- A **Theme** affects lets output itself, not the child processes launched by **Project commands**. +- **Project config** must declare `shell`; **Mixins** do not. +- `persist_checksum` is valid only when `checksum` is declared. +- Unknown top-level keywords fail config loading unless they use the `x-` prefix for custom extensions. +- **Agent skills** are installed and managed with `lets self skills`; they are not configured in **Project config**. + +## Non-goals + +- `lets` orchestrates shell commands; it does not replace the shell itself. +- `lets` is not a package manager. +- **Settings** are not a place to share repository workflow. +- **Self commands** are not part of a repository's **Project command** namespace. +- **Mixins** are additive composition, not implicit override layers. + +## Related docs + +- `UBIQUITOUS_LANGUAGE.md` is the working glossary and ambiguity log. +- Promote stable terminology from `UBIQUITOUS_LANGUAGE.md` into this file when it becomes durable project language. diff --git a/UBIQUITOUS_LANGUAGE.md b/UBIQUITOUS_LANGUAGE.md new file mode 100644 index 00000000..94e77747 --- /dev/null +++ b/UBIQUITOUS_LANGUAGE.md @@ -0,0 +1,76 @@ +# Ubiquitous Language + +## Lets configuration + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Settings** | Per-user lets behavior stored in `~/.config/lets/config.yaml`. | Config, `lets.yaml`, project config | +| **Project config** | Repository command and runtime configuration stored in `lets.yaml`. | Settings, user config | +| **Theme** | A named visual style for lets help and styled error output. | Color scheme, palette | +| **Default theme** | The standard lets theme. | Normal theme, builtin colors | +| **ANSI theme** | A theme limited to broadly supported ANSI terminal colors. | Plain theme, basic colors | +| **Synthwave theme** | A high-contrast neon lets theme. | Vaporwave, purple theme | + +## Issue workflow + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Issue tracker** | The system of record where this repo's work items live. | Tickets, task board | +| **GitHub Issue** | A work item stored in `lets-cli/lets` on GitHub. | Local issue, scratch note | +| **Triage label** | A label string that marks an issue's triage state. | Tag, status | +| **Needs triage** | The triage state meaning a maintainer still needs to evaluate the issue. | Unreviewed, backlog | +| **Needs info** | The triage state meaning the issue is waiting on the reporter. | Blocked, pending | +| **Ready for agent** | The triage state meaning an AFK agent can execute the work without more human context. | AFK-ready, bot-ready | +| **Ready for human** | The triage state meaning the work requires human implementation. | Human-ready | +| **Won't fix** | The triage state meaning the work will not be actioned. | Rejected, closed-no-action | + +## Documentation layout + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Domain docs** | The files that define project language and durable architectural decisions. | Repo docs, notes | +| **Context** | A `CONTEXT.md` file that defines the project's domain vocabulary for a scope. | Readme, design doc | +| **ADR** | An architecture decision record that captures a lasting technical decision. | Spec, random note | +| **Single-context repo** | A repo with one root `CONTEXT.md` and one root `docs/adr/`. | Monorepo, multi-context | +| **Multi-context repo** | A repo with a root `CONTEXT-MAP.md` and multiple per-context `CONTEXT.md` files. | Single-context | +| **Context map** | A root index file that points to per-context language docs. | Sitemap, overview | +| **Agent skill** | A reusable prompt-driven workflow that reads and writes repo-specific context. | Macro, script | + +## People + +| Term | Definition | Aliases to avoid | +| ---- | ---------- | ---------------- | +| **Maintainer** | A person who evaluates issues and applies triage labels. | Owner, reviewer | +| **Reporter** | A person who opens an issue or supplies follow-up information for it. | Submitter, user | +| **AFK agent** | An autonomous agent that can complete work without additional human context. | Bot, automation | +| **Human implementer** | A person needed when work cannot be delegated to an AFK agent. | Developer, coder | + +## Relationships + +- **Settings** apply to lets across all repositories, while **Project config** applies to one repository. +- A **Theme** belongs to **Settings** and is one of **Default theme**, **ANSI theme**, or **Synthwave theme**. +- A **GitHub Issue** lives in the **Issue tracker** and may have zero or more **Triage labels**. +- An issue should be **Ready for agent** only when a **Maintainer** has made it fully specified for an **AFK agent**. +- A **Single-context repo** has exactly one root **Context** and one shared root **ADR** directory. +- A **Multi-context repo** uses a **Context map** to point skills to the relevant **Context** files. + +## Example dialogue + +> **Dev:** "Should the new `theme` option live in **Settings** or the **Project config**?" +> +> **Domain expert:** "Put it in **Settings** — it changes lets itself, while the **Project config** in `lets.yaml` describes repo commands." +> +> **Dev:** "For this repo, does the **Issue tracker** mean **GitHub Issues** with **Triage labels**?" +> +> **Domain expert:** "Yes. A **Maintainer** evaluates each **GitHub Issue** and applies labels like **Needs triage** or **Ready for agent**." +> +> **Dev:** "And the repo is **Single-context**, so skills read one root **Context** and the root **ADR** directory?" +> +> **Domain expert:** "Exactly — no **Context map** is needed unless the repo grows into a **Multi-context repo**." + +## Flagged ambiguities + +- "settings" and "config" were used close together — use **Settings** for `~/.config/lets/config.yaml` and **Project config** for `lets.yaml`. +- "theme" and "color scheme" refer to the same user-facing concept here — use **Theme** in docs and CLI-facing language, and reserve "color scheme" for internal implementation details. +- "issue tracker" was used both abstractly and concretely — use **Issue tracker** for the system and **GitHub Issue** for an individual work item in this repo. +- "domain docs" was used for both the source-of-truth documents and the agent-facing instructions file — use **Domain docs** for `CONTEXT.md` and `docs/adr/`, and say "agent docs" when referring to `docs/agents/*`. diff --git a/docs/agents/domain.md b/docs/agents/domain.md new file mode 100644 index 00000000..1c24ca61 --- /dev/null +++ b/docs/agents/domain.md @@ -0,0 +1,44 @@ +# Domain Docs + +This repo is a **Single-context repo**. + +For this repo, the **Domain docs** are: + +- the root **Context** at `CONTEXT.md` +- the root **ADR** directory at `docs/adr/` + +`docs/agents/*` are agent docs. They describe workflow conventions for **Agent skills**, but they are not Domain docs. + +## Before exploring, read these + +- **`CONTEXT.md`** at the repo root +- **`docs/adr/`** at the repo root — read ADRs that touch the area you're about to work in + +If these files don't exist, **proceed silently**. Don't flag their absence; don't suggest creating them upfront. The producer skill (`/grill-with-docs`) creates them lazily when terms or decisions actually get resolved. + +## File structure + +Single-context repo layout: + +``` +/ +├── CONTEXT.md +├── docs/adr/ +│ ├── 0001-some-decision.md +│ └── 0002-another-decision.md +└── src/ +``` + +Do not expect a `CONTEXT-MAP.md` unless this repo grows into a **Multi-context repo**. + +## Use the Context vocabulary + +When your output names a domain concept (in an issue title, a refactor proposal, a hypothesis, or a test name), use the term as defined in the root **Context**. Don't drift to synonyms the glossary explicitly avoids. + +If the concept you need isn't in the glossary yet, that's a signal — either you're inventing language the project doesn't use (reconsider) or there's a real gap (note it for `/grill-with-docs`). + +## Flag ADR conflicts + +If your output contradicts an existing **ADR**, surface it explicitly rather than silently overriding: + +> _Contradicts ADR-0007 — but worth reopening because…_ diff --git a/docs/agents/issue-tracker.md b/docs/agents/issue-tracker.md new file mode 100644 index 00000000..31fab77a --- /dev/null +++ b/docs/agents/issue-tracker.md @@ -0,0 +1,22 @@ +# Issue tracker: GitHub + +The **Issue tracker** for this repo is GitHub. Work items and PRDs live as **GitHub Issues** in `lets-cli/lets`. Use the `gh` CLI for all operations. + +## Conventions + +- **Create a GitHub Issue**: `gh issue create --title "..." --body "..."`. Use a heredoc for multi-line bodies. +- **Read a GitHub Issue**: `gh issue view --comments`, and fetch labels when they matter to the workflow. +- **List GitHub Issues**: `gh issue list --state open --json number,title,body,labels,comments --jq '[.[] | {number, title, body, labels: [.labels[].name], comments: [.comments[].body]}]'` with appropriate `--label` and `--state` filters. +- **Comment on a GitHub Issue**: `gh issue comment --body "..."` +- **Apply / remove Triage labels**: `gh issue edit --add-label "..."` / `--remove-label "..."` +- **Close a GitHub Issue**: `gh issue close --comment "..."` + +Infer the repo from `git remote -v` — `gh` does this automatically when run inside a clone. + +## When a skill says "publish to the issue tracker" + +Create a **GitHub Issue**. + +## When a skill says "fetch the relevant ticket" + +Fetch the relevant **GitHub Issue** with `gh issue view --comments`. diff --git a/docs/agents/triage-labels.md b/docs/agents/triage-labels.md new file mode 100644 index 00000000..631c3b37 --- /dev/null +++ b/docs/agents/triage-labels.md @@ -0,0 +1,13 @@ +# Triage Labels + +This repo uses the default **Triage label** strings. The table below maps each canonical triage role to the exact GitHub label name to apply in this repo's **Issue tracker**. + +| Canonical triage role | Triage label in this repo | Meaning | +| --------------------- | ------------------------- | ------- | +| `needs-triage` (**Needs triage**) | `needs-triage` | A **Maintainer** still needs to evaluate the **GitHub Issue**. | +| `needs-info` (**Needs info**) | `needs-info` | The **GitHub Issue** is waiting on the **Reporter** for more information. | +| `ready-for-agent` (**Ready for agent**) | `ready-for-agent` | The **GitHub Issue** is fully specified and ready for an **AFK agent**. | +| `ready-for-human` (**Ready for human**) | `ready-for-human` | The **GitHub Issue** requires a **Human implementer**. | +| `wontfix` (**Won't fix**) | `wontfix` | The **GitHub Issue** will not be actioned. | + +When a skill mentions a canonical triage role, apply the matching label string from the second column. diff --git a/go.mod b/go.mod index 0a79fde2..97657a1c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.26 toolchain go1.26.0 require ( - charm.land/lipgloss/v2 v2.0.1 + charm.land/lipgloss/v2 v2.0.2 github.com/charmbracelet/colorprofile v0.4.2 github.com/charmbracelet/x/ansi v0.11.6 github.com/charmbracelet/x/exp/charmtone v0.0.0-20250603201427-c31516f43444 @@ -27,8 +27,11 @@ require ( ) require ( + charm.land/bubbles/v2 v2.1.0 // indirect + charm.land/bubbletea/v2 v2.0.2 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-udiff v0.4.1 // indirect + github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect @@ -38,7 +41,7 @@ require ( github.com/iancoleman/strcase v0.3.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-runewidth v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.21 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/mango v0.1.0 // indirect github.com/muesli/mango-cobra v1.2.0 // indirect diff --git a/go.sum b/go.sum index ab503bb7..1901af7d 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,19 @@ +charm.land/bubbles/v2 v2.1.0 h1:YSnNh5cPYlYjPxRrzs5VEn3vwhtEn3jVGRBT3M7/I0g= +charm.land/bubbles/v2 v2.1.0/go.mod h1:l97h4hym2hvWBVfmJDtrEHHCtkIKeTEb3TTJ4ZOB3wY= +charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0= +charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ= charm.land/lipgloss/v2 v2.0.1 h1:6Xzrn49+Py1Um5q/wZG1gWgER2+7dUyZ9XMEufqPSys= charm.land/lipgloss/v2 v2.0.1/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM= +charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs= +charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-udiff v0.4.1 h1:OEIrQ8maEeDBXQDoGCbbTTXYJMYRCRO1fnodZ12Gv5o= github.com/aymanbagabas/go-udiff v0.4.1/go.mod h1:0L9PGwj20lrtmEMeyw4WKJ/TMyDtvAoK9bf2u/mNo3w= github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= +github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= +github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA= github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= @@ -100,6 +108,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= +github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/mango v0.1.0 h1:DZQK45d2gGbql1arsYA4vfg4d7I9Hfx5rX/GCmzsAvI=