diff --git a/.agents/memory/ACTIVE/PLAN.md b/.agents/memory/ACTIVE/PLAN.md new file mode 100644 index 0000000..e0a3f3f --- /dev/null +++ b/.agents/memory/ACTIVE/PLAN.md @@ -0,0 +1,28 @@ +# Plan: + +## Outcome + +What "done" looks like in one sentence. + +## Motivation + +What problem this solves and why it matters, with user scenarios, project context, and background in the problem space. + +## Constraints + +- Runtime and compatibility constraints +- Public API surface constraints +- `deno lint` compliance required throughout +- `deno doc --lint` compliance required throughout + +## Non-goals + +What is explicitly out of scope. + +## Approach + +A short narrative of the design at a high level. + +## Key decisions + +Link to ADRs in `../DECISIONS/` when needed. diff --git a/.agents/memory/ACTIVE/PROGRESS.md b/.agents/memory/ACTIVE/PROGRESS.md new file mode 100644 index 0000000..420e2f9 --- /dev/null +++ b/.agents/memory/ACTIVE/PROGRESS.md @@ -0,0 +1,21 @@ +# Progress + +## Current status + +- Today's focus: +- Next task: T0X +- Blockers: + +## Completed + +- [x] T01: (commit: <sha or PR link if known>) + +## Notes for the next agent + +- Assumptions made: + - <assumption> +- Files touched: + - <path> +- Verification to run: + - `deno task test` + - `deno doc --lint mod.ts` diff --git a/.agents/memory/ACTIVE/RISKS.md b/.agents/memory/ACTIVE/RISKS.md new file mode 100644 index 0000000..04f03ad --- /dev/null +++ b/.agents/memory/ACTIVE/RISKS.md @@ -0,0 +1,13 @@ +# Risks + +## Known risks + +- <risk and why it matters> + +## Mitigations + +- <how to validate or reduce the risk> + +## Follow-ups + +- <future check or improvement> diff --git a/.agents/memory/ACTIVE/TASKS.md b/.agents/memory/ACTIVE/TASKS.md new file mode 100644 index 0000000..62ad99b --- /dev/null +++ b/.agents/memory/ACTIVE/TASKS.md @@ -0,0 +1,18 @@ +# Tasks + +Rules: +- Each task is small enough to complete in one iteration. +- Each task has clear, verifiable acceptance checks. + +## Queue + +- [ ] T01: <task title> + - Why: <one sentence> + - Done when: + - [ ] `deno task test` passes + - [ ] `deno doc --lint mod.ts` passes + - [ ] <additional verifiable condition> + +## Parking lot + +- [ ] P01: <deferred idea> diff --git a/.agents/memory/CHECKLISTS/pr-checklist.md b/.agents/memory/CHECKLISTS/pr-checklist.md new file mode 100644 index 0000000..ac7c361 --- /dev/null +++ b/.agents/memory/CHECKLISTS/pr-checklist.md @@ -0,0 +1,26 @@ +# PR Checklist + +## Intent + +- [ ] The PR title and description explain outcome, problem, and motivation. +- [ ] The title follows Conventional Commit format (see + `pull-requests.instructions.md`). + +## Changes + +- [ ] Changes are scoped to the stated intent. +- [ ] Risky or breaking behavior changes are called out explicitly. + +## Verification + +- [ ] `deno task test` passes. +- [ ] `deno task bench` passes. +- [ ] `deno doc --lint mod.ts` passes with no errors. +- [ ] Failure modes and error paths were considered. + +## Documentation + +- [ ] TSDoc is updated for any changed public API. +- [ ] `readme.md` updated if user-facing behavior changed. +- [ ] `changelog.md` entry added (or will be generated by forge). +- [ ] Decisions that affect contracts are captured in an ADR. diff --git a/.agents/memory/CHECKLISTS/release-checklist.md b/.agents/memory/CHECKLISTS/release-checklist.md new file mode 100644 index 0000000..1a18cf9 --- /dev/null +++ b/.agents/memory/CHECKLISTS/release-checklist.md @@ -0,0 +1,25 @@ +# Release Checklist + +## Scope + +- [ ] Release intent is documented in `changelog.md`. +- [ ] Backwards compatibility risks are identified and called out. + +## Artifacts + +- [ ] Version bumped via `deno task forge bump`. +- [ ] Changelog entries are accurate and human-readable. +- [ ] Breaking changes are prominently marked with migration paths. + +## Validation + +- [ ] `deno task test` passes on the release commit. +- [ ] `deno task bench` passes on the release commit. +- [ ] `deno doc --lint mod.ts` passes with no errors. +- [ ] JSR publish dry-run: `deno publish --dry-run`. +- [ ] npm build succeeds: `deno task build:npm`. + +## Rollback + +- [ ] Rollback plan is clear if a regression is found post-publish. +- [ ] Yanked releases are marked in `changelog.md` with a note. diff --git a/.agents/memory/CHECKLISTS/review-checklist.md b/.agents/memory/CHECKLISTS/review-checklist.md new file mode 100644 index 0000000..1a17913 --- /dev/null +++ b/.agents/memory/CHECKLISTS/review-checklist.md @@ -0,0 +1,24 @@ +# Review Checklist + +## Correctness + +- [ ] Behavior matches the stated intent. +- [ ] Edge cases and error paths are handled explicitly (empty string, single + line, all whitespace, mixed line endings). + +## Safety + +- [ ] No unsafe patterns (eval, silent fallbacks, implicit coercions). +- [ ] Trust boundaries are clear. + +## Maintainability + +- [ ] Naming is clear, intent-revealing, and consistent with the existing API. +- [ ] Complex logic is explained with comments or ASCII diagrams. +- [ ] `deno doc --lint mod.ts` still passes — no `private-type-ref` errors. + +## Verification + +- [ ] `deno task test` passes. +- [ ] `deno doc --lint mod.ts` passes. +- [ ] Verification steps are adequate for the stated change. diff --git a/.agents/memory/CONVENTIONS.md b/.agents/memory/CONVENTIONS.md new file mode 100644 index 0000000..7944083 --- /dev/null +++ b/.agents/memory/CONVENTIONS.md @@ -0,0 +1,30 @@ +# Conventions + +## Intent + +Capture conventions that agents should follow when working in this repo. + +## Context + +This repo values small, verifiable changes and file-based progress that +survives context resets. + +## Constraints + +- Keep notes brief and actionable. +- Do not store secrets or customer data. +- Prefer explicit configuration and clear error handling. + +## Approach + +- Read `ACTIVE/PLAN.md` and `ACTIVE/TASKS.md` before starting multi-step work. +- Update `ACTIVE/PROGRESS.md` after meaningful progress. +- Mark tasks done only when acceptance checks pass. +- Promote architectural decisions to ADRs in `DECISIONS/`. +- Run `deno task test`, `deno task bench`, `deno lint` and `deno doc --lint mod.ts` before marking any + API-touching task complete. + +## Edge cases + +If work spans multiple iterations, capture risks in `ACTIVE/RISKS.md` to avoid +context loss. diff --git a/.agents/memory/DECISIONS/ADR-0001-template.md b/.agents/memory/DECISIONS/ADR-0001-template.md new file mode 100644 index 0000000..558c8bb --- /dev/null +++ b/.agents/memory/DECISIONS/ADR-0001-template.md @@ -0,0 +1,21 @@ +# ADR-0001: <decision title> + +## Context + +What prompted the decision. + +## Decision + +What we chose. + +## Rationale + +Why this choice over alternatives. + +## Consequences + +Trade-offs, risks, follow-ups. + +## Alternatives considered + +What we did not pick and why. diff --git a/.agents/memory/GLOSSARY.md b/.agents/memory/GLOSSARY.md new file mode 100644 index 0000000..29b6002 --- /dev/null +++ b/.agents/memory/GLOSSARY.md @@ -0,0 +1,15 @@ +# Glossary + +- **TSA** — Template Strings Array. The frozen array of string literals passed + as the first argument to a tagged template function. +- **Dedent / undent / outdent** — the operation of removing the common leading + whitespace from every line of an indented string. +- **Column offset** — the number of leading whitespace characters before the + first non-whitespace character on a line. +- **LICM** — Loop Invariant Code Motion. A JIT optimization that hoists + loop-invariant computations out of the loop. Relevant to benchmark validity. +- **TSDoc** — TypeScript documentation comment format (`/** ... */`) used by + `deno doc`. +- **JSR** — Jsr.io, the TypeScript-native package registry for Deno. +- **ADR** — Architecture Decision Record. A short document capturing a + significant design choice, its context, and the rationale. diff --git a/.agents/memory/INDEX.md b/.agents/memory/INDEX.md new file mode 100644 index 0000000..664493c --- /dev/null +++ b/.agents/memory/INDEX.md @@ -0,0 +1,19 @@ +# Memory Index + +## Core references + +- [PROJECT](PROJECT.md) +- [CONVENTIONS](CONVENTIONS.md) +- [GLOSSARY](GLOSSARY.md) + +## Active work + +- [PLAN](ACTIVE/PLAN.md) +- [TASKS](ACTIVE/TASKS.md) +- [PROGRESS](ACTIVE/PROGRESS.md) +- [RISKS](ACTIVE/RISKS.md) + +## Decisions and checklists + +- [DECISIONS](DECISIONS/) +- [CHECKLISTS](CHECKLISTS/) diff --git a/.agents/memory/PROJECT.md b/.agents/memory/PROJECT.md new file mode 100644 index 0000000..81170fe --- /dev/null +++ b/.agents/memory/PROJECT.md @@ -0,0 +1,30 @@ +# Project Summary + +## Outcome + +`@okikio/undent` is a single-module Deno library that strips source-code +indentation from template literals and plain strings. + +## Context + +- Runtime: Deno v2, TypeScript (strict), ESM +- Published to: JSR and npm +- Entire public API lives in `mod.ts` — no separate build step + +## Key exports + +- **Tag functions** — `undent`, `dedent`, `outdent`, `createUndent` +- **Value helpers** — `align`, `embed`, `isAligned` +- **String/text utilities** — `dedentString`, `alignText`, `splitLines`, + `rejoinLines`, `columnOffset`, `newlineLengthAt`, `resolveOptions`, `DEFAULTS` + +## Constraints + +- All public API types must be exported (enforced by `deno doc --lint`). +- No hidden global state; no top-level side effects. +- Keep the module tree-shakeable. + +## Non-goals + +This file is not a full API spec or changelog. See `mod.ts` TSDoc and +`readme.md` for those. diff --git a/.agents/memory/README.md b/.agents/memory/README.md new file mode 100644 index 0000000..a79799b --- /dev/null +++ b/.agents/memory/README.md @@ -0,0 +1,22 @@ +# Agent Memory + +This directory stores file-based state for agent work so progress survives +context resets. Durable notes that teammates can rely on live in the top-level +files and the `ACTIVE`, `DECISIONS`, and `CHECKLISTS` folders. Scratch notes +live under `SESSIONS` and are gitignored. + +## Constraints + +- Do not store secrets, tokens, private URLs, or customer data. +- Keep `ACTIVE` short and current; archive completed work. +- Prefer small, verifiable tasks that can be completed in one iteration. + +## Approach + +Use `ACTIVE` as the control panel for ongoing work, `DECISIONS` for long-lived +architectural choices, and `CHECKLISTS` for repeatable quality gates. + +## Edge cases + +If `TASKS` grows too large, split into multiple files or an epic folder. If a +decision affects the public API or documented behavior, promote it to an ADR. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 0b420ba..21ef250 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -146,3 +146,5 @@ Targeted rules live under `.github/instructions/`: | `testing.instructions.md` | `**/*_test.ts`, `**/*.test.ts` | | `benchmarking.instructions.md` | `**/*_bench.ts`, `**/*bench*.ts` | | `changelog-commits.instructions.md` | `**` (all files) | +| `pull-requests.instructions.md` | `**` (all files) | +| `code-review.instructions.md` | `**` (all files) | diff --git a/.github/instructions/code-review.instructions.md b/.github/instructions/code-review.instructions.md new file mode 100644 index 0000000..7cd14d2 --- /dev/null +++ b/.github/instructions/code-review.instructions.md @@ -0,0 +1,53 @@ +--- +description: Code review standards for this repo +applyTo: "**" +--- + +# Code Review + +Prioritize correctness, clarity, maintainability, and standards alignment. +Avoid noise: fewer, higher-signal comments. + +## Review rubric (in order) + +### 1. Correctness & contracts + +- Does the code do what it claims? +- Are edge cases handled (empty string, single line, mixed line endings, all + whitespace, no indentation)? +- Are public API contracts consistent across call site and implementation? + +### 2. Failure modes & safety + +- Are errors explicit? No silent fallbacks or implicit coercions. +- Any unsafe patterns (eval, unvalidated inputs, string-built operations)? +- Does the change affect `deno doc --lint` compliance? + +### 3. Types & narrowing + +- Avoid `any`. Prefer generics, unions, discriminated unions, and narrowing. +- Every type referenced in a public signature must itself be exported — + `deno doc --lint` will catch `private-type-ref` errors. +- Return types at module boundaries should be explicit and narrow. + +### 4. Readability & educational clarity + +- Naming should be approachable and intent-revealing. See naming rules in + `copilot-instructions.md`. +- Comments should explain _why_. For non-obvious logic (regex, bitwise, tricky + boolean), also explain _what/how_ in plain English. +- If the change's intent isn't obvious from the diff, suggest improving: + - naming and/or docstrings + - OR the PR description to clearly state motivation and impact + +### 5. Consistency & style + +Match repo formatting and import conventions. See `typescript.instructions.md`. + +## Output format + +Use tags: `[BLOCKER]`, `[IMPORTANT]`, `[SUGGESTION]`, `[NIT]` + +- Provide a concrete fix suggestion for every `[BLOCKER]` and `[IMPORTANT]`. +- Avoid generic feedback like "improve quality" — tie every comment to a + specific behavior, risk, or readability issue. diff --git a/.github/instructions/pull-requests.instructions.md b/.github/instructions/pull-requests.instructions.md new file mode 100644 index 0000000..2452e88 --- /dev/null +++ b/.github/instructions/pull-requests.instructions.md @@ -0,0 +1,65 @@ +--- +description: PR title, description, and design doc standards for this repo +applyTo: "**" +--- + +# Pull Requests + +## Title + +Use Conventional Commit style: `type(scope optional): outcome` + +- Prefer outcome-focused summaries ("prevent double-stripping on nested undent + calls") +- Avoid vague titles ("update mod.ts", "misc fixes") +- The title must describe an observable outcome (behavior, contract, or + workflow), not "add guidelines / improve quality" +- See `changelog-commits.instructions.md` for type/scope/breaking-change rules + +## Description + +Write for reviewers and future archaeology. Be concrete. + +**Summary** — 1–3 bullets: what changed and in which module/function. +No generic goals like "improve quality" unless tied to a specific behavior +change. + +**Problem / Motivation** — the real issue. Anchor it: "Before, X happened…" / +"Callers couldn't…" / "The output was wrong when…" + +**Solution** — what changed at a high level and where (files/functions). + +**Behavior changes** — if anything observable changes, list it plainly: + +- output shape changes +- edge case handling changes +- breaking API changes (see `changelog-commits.instructions.md`) +- performance / allocation changes + +**Verification** — list `deno task test` and `deno doc --lint mod.ts`, plus any +manual checks. If not verified, say "Should verify by…" — don't claim you ran +them. + +**Risk & rollout** (when relevant) — what could break, edge cases, mitigations. + +## Writing constraints + +- Short bullets and concrete nouns. +- Avoid memo-speak ("enhance process", "ensure quality", "various aspects"). +- Do not invent issue numbers, links, or test results. + +## Design docs and specs + +When a PR introduces a non-trivial behavioral change or a new public API, +include a design note using RFC structure: + +1. **Problem** — what is broken or missing +2. **Goals / Non-goals** — scope and explicit exclusions +3. **Constraints** — runtime, compatibility, performance, security +4. **Proposal** — the approach, with ASCII diagrams if helpful +5. **Alternatives considered** — why not the other options +6. **Edge cases & failure modes** +7. **Open questions** + +Prefer concrete examples over abstract statements. Call out trade-offs +explicitly. Keep decision points obvious so reviewers can challenge them.