@spotsccc/agents-framework 0.1.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.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # @spotsccc/agents-framework
2
+
3
+ `@spotsccc/agents-framework` is an npm package that installs the `agents-framework` CLI for bootstrapping backlog-driven working agreements for coding agents inside a repository.
4
+
5
+ ## What It Sets Up
6
+
7
+ The CLI turns agent workflow conventions into repository assets:
8
+
9
+ - detects existing `.agents`, `.claude`, `AGENTS.md`, and `CLAUDE.md` configuration
10
+ - installs backlog skills for research, planning, readiness review, and execution
11
+ - scaffolds a shared markdown backlog in `.agents/backlog`
12
+ - creates or updates managed blocks in `AGENTS.md` and `CLAUDE.md`
13
+
14
+ The result is a repository where agent work can be routed through durable backlog artifacts instead of chat-only context.
15
+
16
+ ## Requirements
17
+
18
+ - Node.js `>=22.12.0`
19
+
20
+ ## Usage
21
+
22
+ Run without installing globally:
23
+
24
+ ```bash
25
+ npx @spotsccc/agents-framework init
26
+ ```
27
+
28
+ Target a specific repository:
29
+
30
+ ```bash
31
+ npx @spotsccc/agents-framework init --cwd /path/to/project
32
+ ```
33
+
34
+ Install as a project dependency and use the local binary through `npm exec`:
35
+
36
+ ```bash
37
+ npm install -D @spotsccc/agents-framework
38
+ npm exec agents-framework -- init
39
+ ```
40
+
41
+ Overwrite managed files when you intentionally want to refresh generated content:
42
+
43
+ ```bash
44
+ npx @spotsccc/agents-framework init --force
45
+ ```
46
+
47
+ ## Current Scope
48
+
49
+ The current release focuses on the backlog bootstrap flow:
50
+
51
+ - `agents-framework init`
52
+ - backlog-only starter skills
53
+ - backlog templates and directory structure
54
+ - safe managed-block upserts for `AGENTS.md` and `CLAUDE.md`
55
+
56
+ ## Local Development
57
+
58
+ Run commands from `apps/agents-framework`:
59
+
60
+ ```bash
61
+ vp check
62
+ vp test
63
+ vp pack
64
+ ```
65
+
66
+ Build and execute the local CLI directly:
67
+
68
+ ```bash
69
+ vp pack
70
+ node dist/cli.mjs init --cwd /path/to/project
71
+ ```
@@ -0,0 +1,51 @@
1
+ # Backlog Execution
2
+
3
+ Use this skill when the agent is implementing a single backlog item that has already passed readiness review and is ready for execution.
4
+
5
+ ## Do Not Use When
6
+
7
+ - Do not use this skill when the request is still a loose idea or the work has not been turned into backlog task drafts yet. Use `backlog-research` or `backlog-planning` first.
8
+ - Do not use this skill when the task still needs readiness review or is blocked by missing context. Use `backlog-readiness` or keep the item in `blocked/`.
9
+
10
+ ## Goal
11
+
12
+ - Execute one ready backlog item with clear status tracking and repository-visible notes.
13
+ - Keep code changes, task updates, and validation aligned with the same task file from start to finish.
14
+
15
+ ## Inputs
16
+
17
+ - One ready backlog item, usually under `.agents/backlog/ready/`.
18
+ - Linked research, dependency notes, parent context, and nearby code or tests.
19
+ - `.agents/backlog/task-template.md` as the expected task shape when the repository uses the managed scaffold.
20
+
21
+ ## Workflow
22
+
23
+ 1. Read the backlog item, linked research, parent context, dependencies, and acceptance criteria.
24
+ 2. Move the task into `.agents/backlog/in-progress/` before making substantive code changes.
25
+ 3. Reconfirm the scoped deliverable and stop if new ambiguity makes the task no longer execution-ready.
26
+ 4. Implement only the work needed for the current item.
27
+ 5. Update `Implementation Notes`, `Verification`, and `Decision Log` in the same task file as decisions, blockers, and evidence appear.
28
+ 6. If new work is discovered outside scope, create or request a follow-up backlog item instead of widening the current one.
29
+ 7. Run the smallest useful validation that proves the change and record the exact outcome in the task file.
30
+ 8. Move the task into `.agents/backlog/done/` only when acceptance criteria, code, docs, and validation notes agree.
31
+
32
+ ## Output
33
+
34
+ Update the same backlog task markdown that is being executed; do not split execution state across extra side files.
35
+
36
+ - The task moves from `ready/` to `in-progress/`, and to `done/` only after execution is actually complete.
37
+ - `Implementation Notes` reflects meaningful implementation details, constraints, and touched systems.
38
+ - `Verification` records what was run, what passed or failed, and any manual checks or blockers.
39
+ - `Decision Log` captures scope decisions, tradeoffs, and follow-up items created during execution.
40
+
41
+ ## Verification
42
+
43
+ - Confirm the task file remains the single source of truth for execution notes and validation evidence.
44
+ - Confirm any newly discovered out-of-scope work is represented as a follow-up backlog item instead of being silently absorbed.
45
+ - Confirm the task directory matches reality: `in-progress/` while work is active, `done/` only after code, docs, and validation are aligned.
46
+
47
+ ## Constraints
48
+
49
+ - If the item turns out to be under-specified, stop and route it through `backlog-readiness` or `backlog-planning`.
50
+ - If validation cannot run, document the blocker and residual risk in the task file and keep the item out of `done`.
51
+ - Do not quietly expand scope inside the current task.
@@ -0,0 +1,60 @@
1
+ # Backlog Planning
2
+
3
+ Use this skill when research exists and the next step is to create backlog task drafts for implementation.
4
+
5
+ ## Do Not Use When
6
+
7
+ - Do not use this skill when the input is still a loose request or feature idea. Use `backlog-research` first.
8
+ - Do not use this skill when a single backlog task draft only needs readiness review before execution. Use `backlog-readiness`.
9
+ - Do not use this skill when a ready item is already being implemented. Use `backlog-execution`.
10
+
11
+ ## Goal
12
+
13
+ - Convert research into backlog task drafts that are ordered, linked, and executable by agents after readiness review.
14
+ - Remove hidden context from the plan so work can be picked up asynchronously.
15
+
16
+ ## Inputs
17
+
18
+ - A completed research artifact, usually under `.agents/backlog/research/`.
19
+ - Optional user clarifications when scope or sequencing is still unclear.
20
+ - `.agents/backlog/task-template.md` as the shape for each created task draft.
21
+
22
+ ## Workflow
23
+
24
+ 1. Read the research document and extract the concrete deliverables.
25
+ 2. Identify unresolved questions that block planning; ask the user only when the decision changes scope or sequencing.
26
+ 3. Split the work into one or more focused task drafts based on delivery boundaries.
27
+ 4. Create or update task drafts under `.agents/backlog/draft/` using `task-template.md`.
28
+ 5. Capture likely sequencing, dependencies, and affected systems inside each task draft.
29
+ 6. Link every task draft back to the relevant research.
30
+ 7. Keep items in draft until `backlog-readiness` confirms they are ready for execution.
31
+
32
+ ## Planning Rules
33
+
34
+ - Prefer small tasks with clear outcomes over large mixed-scope items.
35
+ - Split discovery work from implementation work when uncertainty is still high.
36
+ - Use separate task drafts and explicit dependency notes instead of burying sequencing inside prose.
37
+ - Each task should describe what changes, where it likely changes, and how success will be checked.
38
+ - The managed scaffold currently supports task-level backlog items; do not invent a separate hierarchy unless the repository already uses one.
39
+
40
+ ## Output
41
+
42
+ Each planning pass should produce one or more task drafts in `.agents/backlog/draft/`.
43
+
44
+ Each task draft should include:
45
+
46
+ - a stable human-readable file name and title;
47
+ - scope and acceptance criteria that describe the expected result;
48
+ - implementation notes with dependencies and likely affected files or systems;
49
+ - links back to the relevant research;
50
+ - a verification plan that another agent can execute.
51
+
52
+ ## Verification
53
+
54
+ - Confirm every meaningful deliverable from the research is represented by a task draft or an explicit follow-up item.
55
+ - Confirm each task draft is narrow enough that `backlog-readiness` could realistically mark it ready after review.
56
+ - Confirm sequencing, dependencies, and research links are visible in the repository rather than implied in chat.
57
+
58
+ ## Next Step
59
+
60
+ - Hand each task draft to `backlog-readiness` before moving it into `ready/`.
@@ -0,0 +1,65 @@
1
+ # Backlog Readiness
2
+
3
+ Use this skill when a backlog item must be evaluated before it is handed to an implementation agent.
4
+
5
+ ## Do Not Use When
6
+
7
+ - Do not use this skill when the input is still a loose request or idea. Use `backlog-research` first.
8
+ - Do not use this skill when research exists but the work has not been broken into backlog task drafts yet. Use `backlog-planning`.
9
+ - Do not use this skill when the item is already ready and active implementation has started. Use `backlog-execution`.
10
+
11
+ ## Goal
12
+
13
+ - Decide whether the item is ready, should remain draft until refined, or is blocked.
14
+ - Identify the missing information that would cause execution drift or rework.
15
+
16
+ ## Inputs
17
+
18
+ - One backlog item that may be close to implementation.
19
+ - Linked research, parent items, dependencies, or surrounding project context when they exist.
20
+
21
+ ## Workflow
22
+
23
+ 1. Read the backlog item, linked research, parent context, and dependency notes.
24
+ 2. Evaluate scope, acceptance criteria, dependencies, likely affected systems, and verification plan.
25
+ 3. Separate blocking gaps from non-blocking details that can be resolved during implementation.
26
+ 4. Record the readiness review in the task markdown, using `.agents/backlog/readiness-checklist.md` as the review format when it exists.
27
+ 5. Mark the item `ready` only when the remaining ambiguity is low enough for focused implementation.
28
+ 6. If the item is not ready, keep it in draft or blocked state and list the minimum follow-up needed.
29
+
30
+ ## Review Checklist
31
+
32
+ - Is the scope narrow enough to implement in one focused change?
33
+ - Are the acceptance criteria observable and specific?
34
+ - Are dependencies, blockers, and parent links explicit?
35
+ - Does the item point to the right research or surrounding context?
36
+ - Are the likely files, systems, or interfaces named?
37
+ - Is there a realistic verification plan?
38
+ - Are there unresolved decisions that should be answered before coding starts?
39
+
40
+ ## Output
41
+
42
+ Record a short readiness review in the backlog item itself, keeping the task file as the source of truth:
43
+
44
+ - `Verdict`: `ready`, `draft`, or `blocked`.
45
+ - `What is solid`: the parts of the item that are already implementation-safe.
46
+ - `Gaps`: the missing information or weak assumptions.
47
+ - `Required follow-up`: the minimum changes needed before execution.
48
+
49
+ ## Verification
50
+
51
+ - Confirm the review is based on the actual task file and any linked research, not on chat assumptions alone.
52
+ - Confirm the required follow-up is specific enough that another agent can make the item ready without guessing.
53
+ - Confirm the verdict matches the backlog workflow: only `ready` items should be handed to implementation.
54
+
55
+ ## Next Step
56
+
57
+ - Hand `ready` items to `backlog-execution`.
58
+ - Route `draft` items back through planning or clarification work.
59
+ - Keep `blocked` items out of execution until the blocker is resolved.
60
+
61
+ ## Rules
62
+
63
+ - Be strict about ambiguity that would create wasted coding effort.
64
+ - Do not ask for perfect detail when the missing information is non-blocking.
65
+ - Prefer concrete fixes to generic feedback.
@@ -0,0 +1,56 @@
1
+ # Backlog Research
2
+
3
+ Use this skill when the agent receives an idea for a feature or project that is not implementation-ready yet.
4
+
5
+ ## Do Not Use When
6
+
7
+ - Do not use this skill when research already exists and the next step is to create backlog items. Use `backlog-planning` instead.
8
+ - Do not use this skill when a single backlog item is already scoped well enough for readiness review or implementation.
9
+
10
+ ## Goal
11
+
12
+ - Turn a loose request into durable implementation context stored in the repository.
13
+ - Identify the parts of the codebase, tests, and systems that are likely to be touched.
14
+ - Surface risks, assumptions, and open questions before backlog planning begins.
15
+
16
+ ## Inputs
17
+
18
+ - A feature idea, product request, bug theme, or project initiative.
19
+ - Optional chat context, existing docs, or links to related code.
20
+
21
+ ## Workflow
22
+
23
+ 1. Restate the goal and identify any blocking ambiguities.
24
+ 2. Inspect the repository structure, relevant modules, and nearby tests.
25
+ 3. List the files, systems, and interfaces that are likely to change.
26
+ 4. Capture constraints, dependencies, migration concerns, and rollout risks.
27
+ 5. Propose one or more implementation directions with tradeoffs.
28
+ 6. Outline how the work should be verified, including affected existing tests.
29
+
30
+ ## Output
31
+
32
+ Store the result as a markdown document under `.agents/backlog/research/`, using `.agents/backlog/research-template.md` when it exists.
33
+
34
+ - `Goal`: what needs to change and why.
35
+ - `Relevant Areas`: files, modules, systems, and integration points.
36
+ - `Implementation Notes`: expected change shape and technical constraints.
37
+ - `Options and Tradeoffs`: viable implementation directions and why one may be preferred.
38
+ - `Test Impact`: existing tests that likely need updates or expansion.
39
+ - `Verification Plan`: automated and manual validation ideas.
40
+ - `Open Questions`: decisions that require user input or product clarification.
41
+
42
+ ## Verification
43
+
44
+ - Confirm the research names concrete files, modules, or systems whenever they can be identified.
45
+ - Confirm the output distinguishes known facts from assumptions and open questions.
46
+ - Confirm another agent could create backlog items from the document without rereading the whole codebase.
47
+
48
+ ## Next Step
49
+
50
+ - Hand the research artifact to `backlog-planning` so it can be converted into backlog task drafts.
51
+
52
+ ## Quality Bar
53
+
54
+ - Do not stop at a high-level summary; name the concrete files and code areas when they can be identified.
55
+ - Call out uncertainty explicitly instead of pretending the repository is clearer than it is.
56
+ - Leave enough detail that another agent can create backlog items without rereading the entire codebase.
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/cli.mjs ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import { n as initializeProject, t as formatInitializationReport } from "./src-C0-6U5Ro.mjs";
3
+ //#region src/cli.ts
4
+ const HELP_TEXT = `agents-framework
5
+
6
+ Usage:
7
+ agents-framework init [--cwd <path>] [--force]
8
+ agents-framework --help
9
+
10
+ Commands:
11
+ init Detect agent configs, install backlog skills, scaffold backlog structure, and update AGENTS.md/CLAUDE.md.
12
+
13
+ Options:
14
+ --cwd <path> Target project directory. Defaults to the current working directory.
15
+ --force Rewrite managed skill files when they already exist.
16
+ --help Show this message.
17
+ `;
18
+ async function main(argv) {
19
+ const parsedArgs = parseArgs(argv);
20
+ if (parsedArgs.command === "help") {
21
+ process.stdout.write(HELP_TEXT);
22
+ return;
23
+ }
24
+ const result = await initializeProject({
25
+ cwd: parsedArgs.cwd,
26
+ force: parsedArgs.force
27
+ });
28
+ process.stdout.write(formatInitializationReport(result));
29
+ }
30
+ function parseArgs(argv) {
31
+ if (argv.includes("--help") || argv.includes("-h")) return {
32
+ command: "help",
33
+ force: false
34
+ };
35
+ const args = [...argv];
36
+ let command = "init";
37
+ if (args[0] === "init" || args[0] === "help") command = args.shift();
38
+ if (command === "help") return {
39
+ command,
40
+ force: false
41
+ };
42
+ let cwd;
43
+ let force = false;
44
+ while (args.length > 0) {
45
+ const argument = args.shift();
46
+ if (!argument) continue;
47
+ if (!argument.startsWith("--")) throw new Error(`Unknown argument: ${argument}`);
48
+ if (argument === "--cwd") {
49
+ cwd = args.shift();
50
+ continue;
51
+ }
52
+ if (argument === "--force") {
53
+ force = true;
54
+ continue;
55
+ }
56
+ throw new Error(`Unknown argument: ${argument}`);
57
+ }
58
+ return {
59
+ command,
60
+ cwd,
61
+ force
62
+ };
63
+ }
64
+ main(process.argv.slice(2)).catch((error) => {
65
+ const message = error instanceof Error ? error.message : String(error);
66
+ process.stderr.write(`${message}\n`);
67
+ process.stderr.write("Run `agents-framework --help` for usage.\n");
68
+ process.exitCode = 1;
69
+ });
70
+ //#endregion
71
+ export {};
@@ -0,0 +1,45 @@
1
+ //#region src/constants.d.ts
2
+ declare const AI_FRAMEWORK_BLOCK_START = "<!-- AI_FRAMEWORK:START -->";
3
+ declare const AI_FRAMEWORK_BLOCK_END = "<!-- AI_FRAMEWORK:END -->";
4
+ declare const INSTALL_TARGETS: readonly ["agents", "claude"];
5
+ type InstallationTarget = (typeof INSTALL_TARGETS)[number];
6
+ interface SkillDefinition {
7
+ slug: string;
8
+ title: string;
9
+ summary: string;
10
+ }
11
+ declare const SKILL_DEFINITIONS: readonly SkillDefinition[];
12
+ //#endregion
13
+ //#region src/init.d.ts
14
+ interface InitializeProjectOptions {
15
+ cwd?: string;
16
+ force?: boolean;
17
+ }
18
+ interface DetectedConfigs {
19
+ agentsDir: boolean;
20
+ claudeDir: boolean;
21
+ agentsMd: boolean;
22
+ claudeMd: boolean;
23
+ }
24
+ type FileAction = "created" | "updated" | "skipped";
25
+ interface InstalledSkillResult {
26
+ path: string;
27
+ slug: string;
28
+ status: FileAction;
29
+ target: InstallationTarget;
30
+ }
31
+ interface InitializeProjectResult {
32
+ activeTargets: InstallationTarget[];
33
+ createdFiles: string[];
34
+ detectedConfigs: DetectedConfigs;
35
+ installedSkills: InstalledSkillResult[];
36
+ rootDir: string;
37
+ updatedFiles: string[];
38
+ skippedFiles: string[];
39
+ }
40
+ declare function initializeProject(options: InitializeProjectOptions): Promise<InitializeProjectResult>;
41
+ //#endregion
42
+ //#region src/report.d.ts
43
+ declare function formatInitializationReport(result: InitializeProjectResult): string;
44
+ //#endregion
45
+ export { AI_FRAMEWORK_BLOCK_END, AI_FRAMEWORK_BLOCK_START, type DetectedConfigs, type FileAction, INSTALL_TARGETS, type InitializeProjectOptions, type InitializeProjectResult, type InstallationTarget, type InstalledSkillResult, SKILL_DEFINITIONS, type SkillDefinition, formatInitializationReport, initializeProject };
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as INSTALL_TARGETS, i as AI_FRAMEWORK_BLOCK_START, n as initializeProject, o as SKILL_DEFINITIONS, r as AI_FRAMEWORK_BLOCK_END, t as formatInitializationReport } from "./src-C0-6U5Ro.mjs";
2
+ export { AI_FRAMEWORK_BLOCK_END, AI_FRAMEWORK_BLOCK_START, INSTALL_TARGETS, SKILL_DEFINITIONS, formatInitializationReport, initializeProject };
@@ -0,0 +1,486 @@
1
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, join, relative, resolve } from "node:path";
3
+ import { readFileSync } from "node:fs";
4
+ //#region src/constants.ts
5
+ const AI_FRAMEWORK_BLOCK_START = "<!-- AI_FRAMEWORK:START -->";
6
+ const AI_FRAMEWORK_BLOCK_END = "<!-- AI_FRAMEWORK:END -->";
7
+ const INSTALL_TARGETS = ["agents", "claude"];
8
+ const TARGET_SKILLS_DIRECTORY = {
9
+ agents: ".agents/skills",
10
+ claude: ".claude/skills"
11
+ };
12
+ const SKILL_DEFINITIONS = [
13
+ {
14
+ slug: "backlog-research",
15
+ title: "Backlog Research",
16
+ summary: "Turn feature or project ideas into concrete repository research and implementation context."
17
+ },
18
+ {
19
+ slug: "backlog-planning",
20
+ title: "Backlog Planning",
21
+ summary: "Convert research into ordered backlog items with dependencies and execution boundaries."
22
+ },
23
+ {
24
+ slug: "backlog-readiness",
25
+ title: "Backlog Readiness",
26
+ summary: "Evaluate whether a backlog item is ready for execution by an agent."
27
+ },
28
+ {
29
+ slug: "backlog-execution",
30
+ title: "Backlog Execution",
31
+ summary: "Execute ready backlog items while keeping status, notes, and validation synchronized."
32
+ }
33
+ ];
34
+ //#endregion
35
+ //#region src/templates/shared.ts
36
+ function toMarkdown(lines) {
37
+ return `${lines.join("\n")}\n`;
38
+ }
39
+ //#endregion
40
+ //#region src/templates/agents.ts
41
+ function createManagedInstructionsBlock(target) {
42
+ const title = target === "agents" ? "AGENTS.md" : "CLAUDE.md";
43
+ const skillsDirectory = TARGET_SKILLS_DIRECTORY[target];
44
+ const starterSkills = SKILL_DEFINITIONS.map((skill) => `- \`${skill.slug}\``);
45
+ return toMarkdown([
46
+ AI_FRAMEWORK_BLOCK_START,
47
+ "# AI Framework",
48
+ "",
49
+ "This repository uses `agents-framework` to keep agent work backlog-driven and repeatable.",
50
+ "",
51
+ `- Managed file: \`${title}\``,
52
+ `- Agent skills: \`${skillsDirectory}\``,
53
+ "- Shared backlog: `.agents/backlog`",
54
+ "",
55
+ "## Required Flow",
56
+ "",
57
+ "1. Read `.agents/backlog/README.md` before starting new work.",
58
+ "2. Pull the highest-priority task from `ready/` into `in-progress/`.",
59
+ "3. Keep implementation notes, decisions, and verification inside the task markdown.",
60
+ "4. Move completed work to `done/` only after code, tests, and docs are updated.",
61
+ "",
62
+ "## Backlog Routing",
63
+ "",
64
+ "- Use `backlog-research` when the request is still a loose idea, project request, or poorly scoped feature.",
65
+ "- Use `backlog-planning` when research exists and needs to be converted into backlog task drafts.",
66
+ "- Use `backlog-readiness` when a single backlog item must be reviewed before implementation starts.",
67
+ "- Use `backlog-execution` when a ready backlog item is being implemented.",
68
+ "",
69
+ "## Starter Skills",
70
+ "",
71
+ ...starterSkills,
72
+ AI_FRAMEWORK_BLOCK_END
73
+ ]);
74
+ }
75
+ function createInstructionFile(target) {
76
+ return toMarkdown([
77
+ `# ${target === "agents" ? "Agent Workspace" : "Claude Workspace"}`,
78
+ "",
79
+ "This file is partially managed by `agents-framework`.",
80
+ "",
81
+ createManagedInstructionsBlock(target).trimEnd()
82
+ ]);
83
+ }
84
+ //#endregion
85
+ //#region src/templates/backlog.ts
86
+ function createBacklogReadme() {
87
+ return toMarkdown([
88
+ "# Agent Backlog",
89
+ "",
90
+ "Use this backlog to turn project requests into auditable markdown tasks for the agent.",
91
+ "",
92
+ "## Directories",
93
+ "",
94
+ "- `research/`: durable research artifacts for ideas that are still being clarified before planning.",
95
+ "- `draft/`: task drafts created during planning before readiness review is complete.",
96
+ "- `blocked/`: task drafts or ready items that cannot move forward until an external blocker is resolved.",
97
+ "- `inbox/`: raw requests and notes that still need scope refinement.",
98
+ "- `ready/`: well-scoped tasks with acceptance criteria and known dependencies.",
99
+ "- `in-progress/`: the single task or small batch currently being executed.",
100
+ "- `done/`: completed tasks with verification notes and links to the delivered change.",
101
+ "",
102
+ "## Task Lifecycle",
103
+ "",
104
+ "1. Capture new requests in `inbox/` as soon as they appear.",
105
+ "2. Write a research artifact in `research/` using `research-template.md` when the request is still ambiguous or cross-cutting.",
106
+ "3. Rewrite the research or request into one or more task drafts in `draft/` using `task-template.md`.",
107
+ "4. Review each draft with `readiness-checklist.md` before moving it into `ready/`.",
108
+ "5. Keep under-specified work in `draft/` and move blocked work into `blocked/` until the blocker is resolved.",
109
+ "6. Move a ready task into `in-progress/` when work actually starts.",
110
+ "7. Record decisions, risks, links, and verification in the same task file while implementing.",
111
+ "8. Move the task into `done/` after code, tests, and documentation are in sync.",
112
+ "",
113
+ "## Shared Templates",
114
+ "",
115
+ "- `research-template.md`: shape a durable research artifact before planning.",
116
+ "- `task-template.md`: define backlog task drafts and ready-to-execute tasks.",
117
+ "- `readiness-checklist.md`: review whether a task is specific enough for implementation.",
118
+ "",
119
+ "## Naming",
120
+ "",
121
+ "Use stable file names such as `AF-001-initialize-cli.md` so backlog history stays easy to follow."
122
+ ]);
123
+ }
124
+ function createResearchTemplate() {
125
+ return toMarkdown([
126
+ "# AF-RSCH-000 Research Title",
127
+ "",
128
+ "## Goal",
129
+ "",
130
+ "- What needs to change?",
131
+ "- Why does this matter now?",
132
+ "",
133
+ "## Relevant Areas",
134
+ "",
135
+ "- Files, modules, systems, and integration points that likely need review or changes",
136
+ "",
137
+ "## Implementation Notes",
138
+ "",
139
+ "- Constraints:",
140
+ "- Dependencies:",
141
+ "- Risks:",
142
+ "",
143
+ "## Options and Tradeoffs",
144
+ "",
145
+ "- Option A:",
146
+ "- Option B:",
147
+ "",
148
+ "## Test Impact",
149
+ "",
150
+ "- Existing tests likely affected:",
151
+ "- New coverage likely needed:",
152
+ "",
153
+ "## Verification Plan",
154
+ "",
155
+ "- Automated checks:",
156
+ "- Manual checks:",
157
+ "",
158
+ "## Open Questions",
159
+ "",
160
+ "-"
161
+ ]);
162
+ }
163
+ function createReadinessChecklistTemplate() {
164
+ return toMarkdown([
165
+ "# Readiness Checklist",
166
+ "",
167
+ "Use this checklist when deciding whether a backlog item can move into `ready/` for implementation.",
168
+ "",
169
+ "## Verdict",
170
+ "",
171
+ "- `ready`",
172
+ "- `draft`",
173
+ "- `blocked`",
174
+ "",
175
+ "## What Is Solid",
176
+ "",
177
+ "-",
178
+ "",
179
+ "## Gaps",
180
+ "",
181
+ "-",
182
+ "",
183
+ "## Required Follow-up",
184
+ "",
185
+ "-",
186
+ "",
187
+ "## Checklist",
188
+ "",
189
+ "- [ ] Scope is narrow enough for one focused implementation pass",
190
+ "- [ ] Acceptance criteria are observable and specific",
191
+ "- [ ] Dependencies, blockers, and parent links are explicit",
192
+ "- [ ] Relevant files, systems, or interfaces are named",
193
+ "- [ ] Linked research or surrounding context is sufficient",
194
+ "- [ ] Verification plan is realistic for the change"
195
+ ]);
196
+ }
197
+ function createTaskTemplate() {
198
+ return toMarkdown([
199
+ "# AF-000 Task Title",
200
+ "",
201
+ "## Context",
202
+ "",
203
+ "- Why does this work matter now?",
204
+ "- What user or system problem does it solve?",
205
+ "",
206
+ "## Scope",
207
+ "",
208
+ "- In scope:",
209
+ "- Out of scope:",
210
+ "",
211
+ "## Acceptance Criteria",
212
+ "",
213
+ "- [ ]",
214
+ "- [ ]",
215
+ "",
216
+ "## Implementation Notes",
217
+ "",
218
+ "- Constraints:",
219
+ "- Dependencies:",
220
+ "- Relevant files or systems:",
221
+ "",
222
+ "## Verification",
223
+ "",
224
+ "- [ ] Tests updated or added",
225
+ "- [ ] Docs updated if behavior changed",
226
+ "- [ ] Manual validation recorded",
227
+ "",
228
+ "## Links",
229
+ "",
230
+ "- Research:",
231
+ "- Related tasks:",
232
+ "",
233
+ "## Decision Log",
234
+ "",
235
+ "-"
236
+ ]);
237
+ }
238
+ //#endregion
239
+ //#region src/templates/skills/index.ts
240
+ const skillTemplateFiles = {
241
+ "backlog-research": "backlog-research.md",
242
+ "backlog-planning": "backlog-planning.md",
243
+ "backlog-readiness": "backlog-readiness.md",
244
+ "backlog-execution": "backlog-execution.md"
245
+ };
246
+ const templateCache = /* @__PURE__ */ new Map();
247
+ function createSkillContent(slug) {
248
+ const fileName = skillTemplateFiles[slug];
249
+ if (!fileName) throw new Error(`Unknown skill slug: ${slug}`);
250
+ const cachedContent = templateCache.get(fileName);
251
+ if (cachedContent) return cachedContent;
252
+ const content = readFileSync(new URL(`./${fileName}`, import.meta.url), "utf8");
253
+ templateCache.set(fileName, content);
254
+ return content;
255
+ }
256
+ //#endregion
257
+ //#region src/init.ts
258
+ async function initializeProject(options) {
259
+ const rootDir = resolve(options.cwd ?? process.cwd());
260
+ const force = options.force ?? false;
261
+ const detectedConfigs = await detectConfigs(rootDir);
262
+ const activeTargets = determineActiveTargets(detectedConfigs);
263
+ const result = {
264
+ activeTargets,
265
+ detectedConfigs,
266
+ rootDir,
267
+ installedSkills: [],
268
+ createdFiles: [],
269
+ updatedFiles: [],
270
+ skippedFiles: []
271
+ };
272
+ const backlogRoot = join(rootDir, ".agents", "backlog");
273
+ const managedFiles = [
274
+ {
275
+ filePath: join(backlogRoot, "README.md"),
276
+ content: createBacklogReadme()
277
+ },
278
+ {
279
+ filePath: join(backlogRoot, "task-template.md"),
280
+ content: createTaskTemplate()
281
+ },
282
+ {
283
+ filePath: join(backlogRoot, "research-template.md"),
284
+ content: createResearchTemplate()
285
+ },
286
+ {
287
+ filePath: join(backlogRoot, "readiness-checklist.md"),
288
+ content: createReadinessChecklistTemplate()
289
+ },
290
+ {
291
+ filePath: join(backlogRoot, "research", ".gitkeep"),
292
+ content: ""
293
+ },
294
+ {
295
+ filePath: join(backlogRoot, "draft", ".gitkeep"),
296
+ content: ""
297
+ },
298
+ {
299
+ filePath: join(backlogRoot, "blocked", ".gitkeep"),
300
+ content: ""
301
+ },
302
+ {
303
+ filePath: join(backlogRoot, "inbox", ".gitkeep"),
304
+ content: ""
305
+ },
306
+ {
307
+ filePath: join(backlogRoot, "ready", ".gitkeep"),
308
+ content: ""
309
+ },
310
+ {
311
+ filePath: join(backlogRoot, "in-progress", ".gitkeep"),
312
+ content: ""
313
+ },
314
+ {
315
+ filePath: join(backlogRoot, "done", ".gitkeep"),
316
+ content: ""
317
+ }
318
+ ];
319
+ for (const file of managedFiles) await writeManagedFile(file.filePath, file.content, {
320
+ force,
321
+ result,
322
+ rootDir
323
+ });
324
+ for (const target of activeTargets) {
325
+ const skillsRoot = join(rootDir, TARGET_SKILLS_DIRECTORY[target]);
326
+ for (const skill of SKILL_DEFINITIONS) {
327
+ const skillPath = join(skillsRoot, skill.slug, "SKILL.md");
328
+ const status = await writeManagedFile(skillPath, createSkillContent(skill.slug), {
329
+ force,
330
+ result,
331
+ rootDir
332
+ });
333
+ result.installedSkills.push({
334
+ path: toRelativePath(rootDir, skillPath),
335
+ slug: skill.slug,
336
+ status,
337
+ target
338
+ });
339
+ }
340
+ await upsertInstructionFile(join(rootDir, target === "agents" ? "AGENTS.md" : "CLAUDE.md"), target, {
341
+ result,
342
+ rootDir
343
+ });
344
+ }
345
+ return result;
346
+ }
347
+ async function writeManagedFile(filePath, content, context) {
348
+ await mkdir(dirname(filePath), { recursive: true });
349
+ const normalizedContent = ensureTrailingNewline(content);
350
+ const relativePath = toRelativePath(context.rootDir, filePath);
351
+ if (!await fileExists(filePath)) {
352
+ await writeFile(filePath, normalizedContent, "utf8");
353
+ recordFileAction(context.result, "created", relativePath);
354
+ return "created";
355
+ }
356
+ const currentContent = await readFile(filePath, "utf8");
357
+ if (!context.force) {
358
+ recordFileAction(context.result, "skipped", relativePath);
359
+ return "skipped";
360
+ }
361
+ if (currentContent === normalizedContent) {
362
+ recordFileAction(context.result, "skipped", relativePath);
363
+ return "skipped";
364
+ }
365
+ await writeFile(filePath, normalizedContent, "utf8");
366
+ recordFileAction(context.result, "updated", relativePath);
367
+ return "updated";
368
+ }
369
+ async function upsertInstructionFile(filePath, target, context) {
370
+ await mkdir(dirname(filePath), { recursive: true });
371
+ const relativePath = toRelativePath(context.rootDir, filePath);
372
+ const nextBlock = createManagedInstructionsBlock(target).trim();
373
+ if (!await fileExists(filePath)) {
374
+ await writeFile(filePath, createInstructionFile(target), "utf8");
375
+ recordFileAction(context.result, "created", relativePath);
376
+ return;
377
+ }
378
+ const currentContent = await readFile(filePath, "utf8");
379
+ const nextContent = ensureTrailingNewline(upsertManagedBlock(currentContent, nextBlock));
380
+ if (nextContent === currentContent) {
381
+ recordFileAction(context.result, "skipped", relativePath);
382
+ return;
383
+ }
384
+ await writeFile(filePath, nextContent, "utf8");
385
+ recordFileAction(context.result, "updated", relativePath);
386
+ }
387
+ function upsertManagedBlock(currentContent, nextBlock) {
388
+ const blockPattern = new RegExp(`${escapeForRegExp(AI_FRAMEWORK_BLOCK_START)}[\\s\\S]*?${escapeForRegExp(AI_FRAMEWORK_BLOCK_END)}`, "m");
389
+ if (blockPattern.test(currentContent)) return currentContent.replace(blockPattern, nextBlock);
390
+ return `${currentContent.trimEnd()}\n\n${nextBlock}\n`;
391
+ }
392
+ function ensureTrailingNewline(content) {
393
+ return content.endsWith("\n") ? content : `${content}\n`;
394
+ }
395
+ function toRelativePath(rootDir, targetPath) {
396
+ return relative(rootDir, targetPath) || targetPath;
397
+ }
398
+ function escapeForRegExp(value) {
399
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
400
+ }
401
+ async function fileExists(filePath) {
402
+ try {
403
+ await access(filePath);
404
+ return true;
405
+ } catch {
406
+ return false;
407
+ }
408
+ }
409
+ async function detectConfigs(rootDir) {
410
+ const [agentsDir, claudeDir, agentsMd, claudeMd] = await Promise.all([
411
+ fileExists(join(rootDir, ".agents")),
412
+ fileExists(join(rootDir, ".claude")),
413
+ fileExists(join(rootDir, "AGENTS.md")),
414
+ fileExists(join(rootDir, "CLAUDE.md"))
415
+ ]);
416
+ return {
417
+ agentsDir,
418
+ claudeDir,
419
+ agentsMd,
420
+ claudeMd
421
+ };
422
+ }
423
+ function determineActiveTargets(detectedConfigs) {
424
+ const activeTargets = INSTALL_TARGETS.filter((target) => {
425
+ if (target === "agents") return detectedConfigs.agentsDir || detectedConfigs.agentsMd;
426
+ return detectedConfigs.claudeDir || detectedConfigs.claudeMd;
427
+ });
428
+ return activeTargets.length > 0 ? activeTargets : [...INSTALL_TARGETS];
429
+ }
430
+ function recordFileAction(result, action, relativePath) {
431
+ if (action === "created") {
432
+ result.createdFiles.push(relativePath);
433
+ return;
434
+ }
435
+ if (action === "updated") {
436
+ result.updatedFiles.push(relativePath);
437
+ return;
438
+ }
439
+ result.skippedFiles.push(relativePath);
440
+ }
441
+ //#endregion
442
+ //#region src/report.ts
443
+ function formatInitializationReport(result) {
444
+ return `${[
445
+ `Initialized agents-framework in ${result.rootDir}`,
446
+ "",
447
+ "Detected configs:",
448
+ ...formatDetectedConfigs(result.detectedConfigs),
449
+ "",
450
+ "Active targets:",
451
+ ...formatValues(result.activeTargets),
452
+ "",
453
+ "Installed backlog skills:",
454
+ ...formatInstalledSkills(result),
455
+ "",
456
+ "Created files:",
457
+ ...formatValues(result.createdFiles),
458
+ "",
459
+ "Updated files:",
460
+ ...formatValues(result.updatedFiles),
461
+ "",
462
+ "Skipped files:",
463
+ ...formatValues(result.skippedFiles)
464
+ ].join("\n")}\n`;
465
+ }
466
+ function formatDetectedConfigs(detectedConfigs) {
467
+ return [
468
+ `- .agents: ${formatPresence(detectedConfigs.agentsDir)}`,
469
+ `- .claude: ${formatPresence(detectedConfigs.claudeDir)}`,
470
+ `- AGENTS.md: ${formatPresence(detectedConfigs.agentsMd)}`,
471
+ `- CLAUDE.md: ${formatPresence(detectedConfigs.claudeMd)}`
472
+ ];
473
+ }
474
+ function formatInstalledSkills(result) {
475
+ if (result.installedSkills.length === 0) return ["- none"];
476
+ return result.installedSkills.map((skill) => `- ${skill.target}: ${skill.slug} (${skill.status}) -> ${skill.path}`);
477
+ }
478
+ function formatValues(values) {
479
+ if (values.length === 0) return ["- none"];
480
+ return values.map((value) => `- ${value}`);
481
+ }
482
+ function formatPresence(value) {
483
+ return value ? "found" : "missing";
484
+ }
485
+ //#endregion
486
+ export { INSTALL_TARGETS as a, AI_FRAMEWORK_BLOCK_START as i, initializeProject as n, SKILL_DEFINITIONS as o, AI_FRAMEWORK_BLOCK_END as r, formatInitializationReport as t };
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@spotsccc/agents-framework",
3
+ "version": "0.1.0",
4
+ "description": "CLI for scaffolding agent operating conventions, backlog workflow, and starter skills.",
5
+ "keywords": [
6
+ "agents",
7
+ "ai",
8
+ "backlog",
9
+ "claude-code",
10
+ "cli",
11
+ "codex",
12
+ "scaffolding"
13
+ ],
14
+ "homepage": "https://github.com/spotsccc/agents/tree/master/apps/agents-framework#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/spotsccc/agents/issues"
17
+ },
18
+ "license": "UNLICENSED",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/spotsccc/agents.git",
22
+ "directory": "apps/agents-framework"
23
+ },
24
+ "bin": {
25
+ "agents-framework": "./dist/cli.mjs"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "type": "module",
31
+ "types": "./dist/index.d.mts",
32
+ "exports": {
33
+ ".": "./dist/index.mjs",
34
+ "./cli": "./dist/cli.mjs",
35
+ "./package.json": "./package.json"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "scripts": {
41
+ "build": "vp pack",
42
+ "dev": "vp pack --watch",
43
+ "check": "vp check",
44
+ "test": "vp test",
45
+ "typecheck": "vp check --no-fmt --no-lint",
46
+ "prepublishOnly": "vp pack"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^25.3.5",
50
+ "@typescript/native-preview": "7.0.0-dev.20260309.1",
51
+ "bumpp": "^10.4.1",
52
+ "typescript": "^5.9.3",
53
+ "vite-plus": "catalog:",
54
+ "vitest": "catalog:"
55
+ },
56
+ "engines": {
57
+ "node": ">=22.12.0"
58
+ }
59
+ }