@sabaiway/agent-workflow-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +21 -0
  3. package/README.md +216 -0
  4. package/SKILL.md +121 -0
  5. package/bin/install.mjs +139 -0
  6. package/launchers/README.md +33 -0
  7. package/launchers/install-launchers.sh +94 -0
  8. package/launchers/windsurf-workflow.md +30 -0
  9. package/migrations/README.md +41 -0
  10. package/package.json +46 -0
  11. package/references/planning.md +105 -0
  12. package/references/scripts/_expect-shim.mjs +41 -0
  13. package/references/scripts/archive-changelog.mjs +441 -0
  14. package/references/scripts/archive-changelog.test.mjs +212 -0
  15. package/references/scripts/archive-issues.mjs +179 -0
  16. package/references/scripts/archive-issues.test.mjs +95 -0
  17. package/references/scripts/check-docs-size.mjs +353 -0
  18. package/references/scripts/check-docs-size.test.mjs +180 -0
  19. package/references/scripts/install-git-hooks.mjs +83 -0
  20. package/references/templates/AGENTS.md +78 -0
  21. package/references/templates/active_plan.md +31 -0
  22. package/references/templates/agent_rules.md +85 -0
  23. package/references/templates/architecture.md +49 -0
  24. package/references/templates/changelog.md +24 -0
  25. package/references/templates/current_state.md +36 -0
  26. package/references/templates/decisions.md +44 -0
  27. package/references/templates/env_commands.md +41 -0
  28. package/references/templates/handover.md +37 -0
  29. package/references/templates/known_issues.md +33 -0
  30. package/references/templates/pages/PAGE_TEMPLATE.md +53 -0
  31. package/references/templates/pages/index.md +23 -0
  32. package/references/templates/pages/shared-patterns.md +30 -0
  33. package/references/templates/tech_reference.md +34 -0
  34. package/references/templates/technical_specification.md +37 -0
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env bash
2
+ # Install agent-workflow-kit launchers for whichever non-Claude agents you have.
3
+ # Claude Code needs no launcher — it reads the kit natively from ~/.claude/skills/.
4
+ #
5
+ # SAFE BY DEFAULT — additive only:
6
+ # - Writes only the kit's OWN namespaced slots:
7
+ # ~/.codex/skills/agent-workflow-kit (a symlink)
8
+ # ~/.codeium/.../global_workflows/agent-workflow-kit.md (a managed file)
9
+ # - NEVER touches your other Codex skills or Windsurf workflows.
10
+ # - If one of those exact slots already holds a file the kit did NOT write, it is
11
+ # left untouched and you are told. Re-run with --force to replace it; --force first
12
+ # backs the file up (.bak.<timestamp>) and prints the command to restore it.
13
+ #
14
+ # bash <KIT_DIR>/launchers/install-launchers.sh [--force]
15
+ set -euo pipefail
16
+
17
+ FORCE=0
18
+ for arg in "$@"; do
19
+ case "$arg" in
20
+ --force) FORCE=1 ;;
21
+ *) echo "[launchers] unknown arg: $arg" >&2; exit 2 ;;
22
+ esac
23
+ done
24
+
25
+ # Kit dir = parent of this script's directory (launchers/..).
26
+ KIT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
27
+ MARKER="agent-workflow-kit:managed"
28
+ TS="$(date +%Y%m%d-%H%M%S)"
29
+ echo "[launchers] kit: $KIT_DIR"
30
+
31
+ installed_any=0
32
+ skipped_any=0
33
+
34
+ backup_and_note() { # $1 = path to back up before we replace it
35
+ local path="$1"
36
+ local bak="${path}.bak.${TS}"
37
+ cp -a "$path" "$bak"
38
+ echo "[launchers] backed up existing → $bak"
39
+ echo "[launchers] restore with: rm -rf \"$path\" && mv \"$bak\" \"$path\""
40
+ }
41
+
42
+ # --- Codex: SKILL.md is a native cross-agent skill → symlink into a Codex skill scope.
43
+ if command -v codex >/dev/null 2>&1 || [ -d "$HOME/.codex" ]; then
44
+ mkdir -p "$HOME/.codex/skills"
45
+ LINK="$HOME/.codex/skills/agent-workflow-kit"
46
+ if [ -L "$LINK" ] || { [ ! -e "$LINK" ] && [ ! -L "$LINK" ]; }; then
47
+ # Our own symlink slot, or empty — a symlink is a pointer, not user data.
48
+ ln -sfn "$KIT_DIR" "$LINK"
49
+ echo "[launchers] Codex → linked $LINK -> $KIT_DIR"
50
+ installed_any=1
51
+ elif [ "$FORCE" -eq 1 ]; then
52
+ backup_and_note "$LINK"
53
+ rm -rf "$LINK"
54
+ ln -sfn "$KIT_DIR" "$LINK"
55
+ echo "[launchers] Codex → replaced (forced) $LINK -> $KIT_DIR"
56
+ installed_any=1
57
+ else
58
+ echo "[launchers] Codex ⚠ $LINK exists and was not created by the kit — left untouched."
59
+ echo "[launchers] re-run with --force to replace it (a backup is made first)."
60
+ skipped_any=1
61
+ fi
62
+ fi
63
+
64
+ # --- Windsurf: needs a workflow launcher (Cascade does not read SKILL.md).
65
+ if command -v windsurf >/dev/null 2>&1 || [ -d "$HOME/.codeium/windsurf" ]; then
66
+ WF_DIR="$HOME/.codeium/windsurf/global_workflows"
67
+ mkdir -p "$WF_DIR"
68
+ WF="$WF_DIR/agent-workflow-kit.md"
69
+ write_wf() { sed "s#<KIT_DIR>#$KIT_DIR#g" "$KIT_DIR/launchers/windsurf-workflow.md" > "$WF"; }
70
+ if [ ! -e "$WF" ]; then
71
+ write_wf
72
+ echo "[launchers] Windsurf → wrote $WF (/agent-workflow-kit in Cascade)"
73
+ installed_any=1
74
+ elif grep -q "$MARKER" "$WF" 2>/dev/null; then
75
+ write_wf
76
+ echo "[launchers] Windsurf → refreshed $WF (kit-managed)"
77
+ installed_any=1
78
+ elif [ "$FORCE" -eq 1 ]; then
79
+ backup_and_note "$WF"
80
+ write_wf
81
+ echo "[launchers] Windsurf → replaced (forced) $WF"
82
+ installed_any=1
83
+ else
84
+ echo "[launchers] Windsurf ⚠ $WF exists and was not written by the kit — left untouched."
85
+ echo "[launchers] re-run with --force to replace it (a backup is made first)."
86
+ skipped_any=1
87
+ fi
88
+ fi
89
+
90
+ if [ "$installed_any" -eq 0 ] && [ "$skipped_any" -eq 0 ]; then
91
+ echo "[launchers] No Codex/Windsurf install detected. Claude Code (if present) already has the kit natively."
92
+ fi
93
+ echo "[launchers] Uninstall later: delete the kit's own slot(s) above (the symlink / the agent-workflow-kit.md file)."
94
+ echo "[launchers] done."
@@ -0,0 +1,30 @@
1
+ ---
2
+ description: Bootstrap or upgrade the agent-workflow-kit AI memory & workflow system (docs/ai + AGENTS.md + enforcement) in this project.
3
+ ---
4
+
5
+ <!-- agent-workflow-kit:managed — generated by the kit installer. Safe to overwrite on
6
+ reinstall; delete this file to remove the Windsurf launcher. -->
7
+
8
+ # agent-workflow-kit
9
+
10
+ Thin launcher — the full algorithm, templates, and scripts live in the kit. Do **not**
11
+ reinvent any of it here; the kit's `SKILL.md` is the single source of truth.
12
+
13
+ `<KIT_DIR>` = the kit's directory on this machine (the installer substitutes the real path).
14
+
15
+ ## Steps
16
+
17
+ 1. Read the kit instructions in full: `<KIT_DIR>/SKILL.md`, plus the `references/` files it
18
+ points to. Wherever it says `${CLAUDE_SKILL_DIR}`, read that as `<KIT_DIR>`.
19
+ 2. Pick the mode:
20
+ - No `docs/ai/` in this project → **bootstrap**.
21
+ - `docs/ai/` already exists → ask the user whether to run **upgrade** instead.
22
+ 3. Execute every step from `SKILL.md` for THIS repository:
23
+ - Recon (read-only) → **ask the user: visible or hidden** (wait for the answer) →
24
+ create `AGENTS.md` (+ `CLAUDE.md` symlink) from `<KIT_DIR>/references/templates/` →
25
+ deploy `docs/ai/` → copy `<KIT_DIR>/references/scripts/*.mjs` (Node projects) →
26
+ wire/hide per visibility → install the pre-commit hook → stamp `docs/ai/.workflow-version`.
27
+ 4. Report what was filled with real data vs left as TODO, then **ask before committing** —
28
+ never auto-commit.
29
+
30
+ This workflow is manual-only; run it deliberately, like a deploy.
@@ -0,0 +1,41 @@
1
+ # Migrations
2
+
3
+ Each upgrade step is one file: `migrations/<version>-<slug>.md`, where `<version>` is the
4
+ skill release that introduced the change (matches a `CHANGELOG.md` heading) and `<slug>`
5
+ is a short kebab-case name. Empty until the first change that needs migrating — most
6
+ releases add files/templates, which `upgrade` reconciles without a migration.
7
+
8
+ ## How `upgrade` applies them
9
+
10
+ 1. Read the project's stamped version from `docs/ai/.workflow-version`.
11
+ 2. Select every migration whose `<version>` is **strictly newer** than the stamp.
12
+ 3. Apply them in **ascending semver order**.
13
+ 4. Re-stamp `docs/ai/.workflow-version` to the skill's current `version`.
14
+
15
+ ## Authoring rules
16
+
17
+ - **Idempotent** — safe to re-run; check before mutating (e.g. "if the file already has X, skip").
18
+ - **Non-destructive** — never clobber project-authored content (their `decisions.md`, `known_issues.md`, page specs). Add/rename/restructure only what the kernel owns.
19
+ - **Self-contained** — exact paths + commands, readable cold, like a mini-plan.
20
+ - **Mention rollback** — note how to undo if the step is risky.
21
+
22
+ ## Template
23
+
24
+ ```markdown
25
+ # Migration <version>-<slug>
26
+
27
+ **From:** versions < <version> **To:** <version>
28
+
29
+ ## Why
30
+ <what changed in the kernel and why a project needs to follow>
31
+
32
+ ## Steps
33
+ 1. <exact, idempotent action with paths/commands>
34
+ 2. ...
35
+
36
+ ## Verification
37
+ <how to confirm the project is now consistent — e.g. docs cap-validator green>
38
+
39
+ ## Rollback
40
+ <how to undo, or "n/a — additive only">
41
+ ```
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@sabaiway/agent-workflow-kit",
3
+ "version": "1.0.0",
4
+ "description": "A portable, cross-agent memory & workflow system for AI coding agents. One command deploys docs/ai + an entry-point AGENTS.md + cap/archive/index enforcement into any project.",
5
+ "keywords": [
6
+ "ai-agents",
7
+ "claude-code",
8
+ "codex",
9
+ "cursor",
10
+ "windsurf",
11
+ "agents-md",
12
+ "workflow",
13
+ "skill",
14
+ "memory",
15
+ "developer-tools"
16
+ ],
17
+ "homepage": "https://github.com/sabaiway/agent-workflow-kit#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/sabaiway/agent-workflow-kit/issues"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/sabaiway/agent-workflow-kit.git"
24
+ },
25
+ "license": "MIT",
26
+ "author": "sabaiway",
27
+ "type": "module",
28
+ "bin": {
29
+ "agent-workflow-kit": "bin/install.mjs"
30
+ },
31
+ "files": [
32
+ "bin/",
33
+ "SKILL.md",
34
+ "README.md",
35
+ "CHANGELOG.md",
36
+ "references/",
37
+ "launchers/",
38
+ "migrations/"
39
+ ],
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ }
46
+ }
@@ -0,0 +1,105 @@
1
+ # Planning Workflow
2
+
3
+ Source of truth for **how plans are written, stored, executed, and torn down**. Overrides the generic `writing-plans` skill — if both trigger, this one wins. Runtime series status (which plan is Current / Pending) lives in `docs/plans/queue.md`.
4
+
5
+ ---
6
+
7
+ ## 1. Plan vocabulary
8
+
9
+ Strict four-level hierarchy, used in plan files (`docs/plans/*.md`) and in verbal summaries:
10
+
11
+ - **Plan** — top-level container = the plan file itself. One file = one Plan. A series of related plans is not grouped under any wrapper noun; refer to them as "Plan 1 of N", "the next plan". Series order lives in `queue.md` (§3).
12
+ - **Phase** — a large block inside the Plan. Exactly one execution session. Ends with its own verification block. `## Phase 1: …`, `## Phase 2: …`.
13
+ - **Step** — an atomic change inside a Phase. Numbered `<phase>.<step>`: `### 1.1. …`. One Step → one logical commit.
14
+ - **Substep** — optional split of a complex Step. Lettered: `**1.2.a**`, `**1.2.b**`. Use only when a Step cannot be one command.
15
+
16
+ Reserve the word "task" for the todo list and `active_plan.md` — not for plan structure.
17
+
18
+ ## 2. Plan directory & lifecycle
19
+
20
+ Plan files are **ephemeral, machine-local scratch space**, gitignored (`.gitignore` contains `docs/plans/`).
21
+
22
+ **Lifecycle:** Creation (untracked file) → Execution (Phases 1..N-1) → mandatory **Phase N: Cleanup** (§4) → Post-deletion (only `changelog.md` + ADRs remain). Plans are **NEVER committed** — full stop. Even if a plan looks load-bearing (referenced by an ADR), inline the load-bearing content into a persistent doc and delete the plan file.
23
+
24
+ **Forbidden:** `git add` of any plan file; plan-file paths in committed docs; leaving plan files on disk after Cleanup. If the user says "commit the plan" — ask back: "the plan is ephemeral — what exactly should I inline into `decisions.md` / `changelog.md`?".
25
+
26
+ ## 3. Series & queue.md
27
+
28
+ A **series** = 2+ related plans that share a roadmap. The index lives at `docs/plans/queue.md` (gitignored, machine-local):
29
+
30
+ ```markdown
31
+ ## Series: <name>
32
+
33
+ ### Current
34
+ - **Plan N / M** — <slug> — <one-line description>
35
+
36
+ ### Pending
37
+ - **Plan N+1 / M** — <slug or TBD> — <description>
38
+
39
+ ### Done
40
+ - **Plan K / M** — <slug> — done YYYY-MM-DD. Outputs: <pointers>.
41
+ ```
42
+
43
+ `queue.md` is initialised when the **first** plan of a series is written, not during its Cleanup — without an upfront index the execution agent has no map of the series. Each plan's Cleanup then marks itself Done (with outputs) and promotes the next plan to Current. A single, unrelated plan does not need a series entry.
44
+
45
+ ## 4. Required Cleanup phase
46
+
47
+ Every Plan MUST end with a final **Phase N: Cleanup** — the last numbered Phase. Without it the Plan is not done.
48
+
49
+ Minimum content:
50
+
51
+ - **Migrate outputs** → `docs/ai/decisions.md` (AD-XXX), `changelog.md`, `known_issues.md` (Issue-XXX), `current_state.md`, `pages/<page>.md`.
52
+ - **Inline cross-references** — `grep -rn "<plan-slug>" docs/` must be empty. Every pointer is rewritten inline or removed.
53
+ - **Update `queue.md`** — if part of a series, mark Done + promote next.
54
+ - **Delete the plan file** — `rm docs/plans/<slug>.md`.
55
+ - **Verification** — `grep -rn "<slug>" .` empty; `ls docs/plans/<slug>.md` → No such file; docs cap-validator green.
56
+
57
+ If a Plan is aborted mid-flight, Cleanup still runs — partial outputs land in `known_issues.md`, then the file is deleted.
58
+
59
+ ## 5. All work in plans
60
+
61
+ Anything required for the task is a **Step inside the Plan**. Nothing "before the plan", "between plans", or "don't forget" — those evaporate at execution time because the execution agent reads only the plan file, not chat scrollback. Every dependency, check, and install is its own Step or Substep. The final "Next steps" section contains **only user-actionable** items.
62
+
63
+ ## 6. Plan-then-execute split
64
+
65
+ Default workflow for non-trivial features (multi-file change, new service + hook + UI, architectural choices): write a **self-contained Plan** and stop. Implementation runs in a fresh session via the `executing-plans` skill.
66
+
67
+ - Triggers: any feature, refactor, or change touching more than ~1 file, or non-obvious architectural choices.
68
+ - Does NOT apply to typos, one-line fixes, doc-only edits, or pure "where is X" research — those run inline.
69
+ - The Plan must be readable cold by a fresh agent: file paths, contracts, execution order, verification, gotchas — all inside the file.
70
+
71
+ This split is a token-efficiency strategy: exploration context stays out of the execution window.
72
+
73
+ ### Session-continuity heuristic (split vs continue)
74
+
75
+ The volume trigger above (files / LoC / tokens) is necessary but not sufficient. The deeper question is whether the planning context is the execution **payload** or **noise**:
76
+
77
+ - **Split** (fresh session) when planning exploration was *broad fan-out* — many files skimmed, sub-agent dumps, wide searches to *locate* things. That context is noise for execution; discard it.
78
+ - **Continue** in the current session when ALL hold: (1) exploration was *targeted-deep* — you read the exact files to be created/modified/copied, so execution would just re-read them; (2) no new heavy exploration is needed to execute; (3) the context budget is healthy (far from the window limit / Lost-in-the-Middle).
79
+ - When continuing, each Phase's Verification block is a natural checkpoint. If different Phases need different cold context, continue only through the warm Phases, then split.
80
+
81
+ ## 7. Plan-document structure
82
+
83
+ ```
84
+ # Plan: <human-readable title>
85
+
86
+ ## Context ← why this Plan exists, current state, why now (reads cold)
87
+ ## Approach ← chosen design + an explicit "What we are NOT doing"
88
+ ## Phase 1: <name>
89
+ ### 1.1. <step> ← exact paths + commands
90
+ ## Phase 2: <name>
91
+ ...
92
+ ## Phase N: Cleanup ← mandatory (§4)
93
+ ## Critical files ← table: file → change kind (new / modify / delete / move)
94
+ ## Reuse ← pointers to existing patterns/snippets to copy, not re-derive
95
+ ## Verification ← full check sequence (mechanical + behavioural)
96
+ ## Next steps ← user-actionable only (§5)
97
+ ```
98
+
99
+ ## 8. Self-review checklist (before finalizing a Plan)
100
+
101
+ - Every Step has exact file paths and exact commands.
102
+ - Every recommendation that used to live outside the Plan is now a Step (§5).
103
+ - Vocabulary is strict (§1); the Plan ends with **Phase N: Cleanup** (§4).
104
+ - If part of a series: `queue.md` is initialised / updated (§3).
105
+ - No `git add <plan>` and no "commit the plan" wording in the final report.
@@ -0,0 +1,41 @@
1
+ // Minimal dependency-free `expect` shim mapping the Vitest matchers used by the
2
+ // kernel's *.test.mjs onto node:assert, so the suite runs under `node --test` with
3
+ // zero dependencies. Supports only the matchers these tests use.
4
+ import assert from 'node:assert/strict';
5
+
6
+ const has = (actual, expected) => {
7
+ if (typeof actual === 'string') return actual.includes(expected);
8
+ if (Array.isArray(actual)) return actual.includes(expected);
9
+ return false;
10
+ };
11
+
12
+ const matchers = (actual, negate) => ({
13
+ toBe: (expected) =>
14
+ negate ? assert.notStrictEqual(actual, expected) : assert.strictEqual(actual, expected),
15
+ toEqual: (expected) =>
16
+ negate ? assert.notDeepStrictEqual(actual, expected) : assert.deepStrictEqual(actual, expected),
17
+ toContain: (expected) =>
18
+ assert.ok(
19
+ negate ? !has(actual, expected) : has(actual, expected),
20
+ `expected ${JSON.stringify(actual)} ${negate ? 'not ' : ''}to contain ${JSON.stringify(expected)}`,
21
+ ),
22
+ toMatch: (re) => (negate ? assert.doesNotMatch(actual, re) : assert.match(actual, re)),
23
+ toHaveLength: (n) =>
24
+ negate ? assert.notStrictEqual(actual.length, n) : assert.strictEqual(actual.length, n),
25
+ toBeNull: () => (negate ? assert.notStrictEqual(actual, null) : assert.strictEqual(actual, null)),
26
+ toBeInstanceOf: (Ctor) =>
27
+ assert.ok(
28
+ negate ? !(actual instanceof Ctor) : actual instanceof Ctor,
29
+ `expected value ${negate ? 'not ' : ''}to be instance of ${Ctor.name}`,
30
+ ),
31
+ toBeGreaterThan: (n) =>
32
+ assert.ok(negate ? !(actual > n) : actual > n, `expected ${actual} ${negate ? 'not ' : ''}> ${n}`),
33
+ toBeLessThan: (n) =>
34
+ assert.ok(negate ? !(actual < n) : actual < n, `expected ${actual} ${negate ? 'not ' : ''}< ${n}`),
35
+ });
36
+
37
+ export const expect = (actual) => {
38
+ const api = matchers(actual, false);
39
+ api.not = matchers(actual, true);
40
+ return api;
41
+ };