@lean-agent/core 0.0.1
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/LICENSE +21 -0
- package/README.md +44 -0
- package/dist/adapters/claude.d.ts +11 -0
- package/dist/adapters/claude.js +70 -0
- package/dist/adapters/claude.js.map +1 -0
- package/dist/adapters/cursor.d.ts +17 -0
- package/dist/adapters/cursor.js +49 -0
- package/dist/adapters/cursor.js.map +1 -0
- package/dist/adapters/index.d.ts +3 -0
- package/dist/adapters/index.js +18 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/types.d.ts +22 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/vscode.d.ts +17 -0
- package/dist/adapters/vscode.js +48 -0
- package/dist/adapters/vscode.js.map +1 -0
- package/dist/adapters/windsurf.d.ts +20 -0
- package/dist/adapters/windsurf.js +52 -0
- package/dist/adapters/windsurf.js.map +1 -0
- package/dist/adapters/yaml.d.ts +9 -0
- package/dist/adapters/yaml.js +15 -0
- package/dist/adapters/yaml.js.map +1 -0
- package/dist/banner.d.ts +1 -0
- package/dist/banner.js +19 -0
- package/dist/banner.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +7 -0
- package/dist/commands/add.js +63 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.js +37 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.js +44 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/remove.d.ts +7 -0
- package/dist/commands/remove.js +31 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +55 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/skill.d.ts +14 -0
- package/dist/skill.js +54 -0
- package/dist/skill.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter Rupp
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# @lean-agent/core
|
|
2
|
+
|
|
3
|
+
> CLI and SDK for [lean-agent](https://github.com/disRupptive/lean-agent) — the lean framework for agentic software development.
|
|
4
|
+
|
|
5
|
+
Install portable skills, workflows, and commands into any AI coding tool with a single command.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx lean-agent add challenger --tool=claude
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or install globally:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g @lean-agent/core @lean-agent/skills
|
|
17
|
+
lean-agent add challenger
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Commands
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
lean-agent init Set up the project (or --global)
|
|
24
|
+
lean-agent add <skill> [--tool=NAME] Install a primitive
|
|
25
|
+
lean-agent remove <skill> [--tool=NAME] Uninstall a primitive
|
|
26
|
+
lean-agent list Show what's available and installed
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Short alias: `la`. Flags: `--tool=claude|cursor|windsurf|vscode`, `--global`.
|
|
30
|
+
|
|
31
|
+
## Supported tools
|
|
32
|
+
|
|
33
|
+
| Tool | Where it lives |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| Claude Code | `.claude/skills/<name>/SKILL.md` (symlink) |
|
|
36
|
+
| Cursor | `.cursor/rules/<name>.mdc` |
|
|
37
|
+
| Windsurf | `.windsurf/rules/<name>.md` |
|
|
38
|
+
| VS Code (GitHub Copilot) | `.github/prompts/<name>.prompt.md` |
|
|
39
|
+
|
|
40
|
+
See the [main repository](https://github.com/disRupptive/lean-agent) for the full vision, roadmap, and skill catalog.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Adapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Claude Code adapter.
|
|
4
|
+
*
|
|
5
|
+
* Project scope installs into `<targetRoot>/.claude/skills/<name>`.
|
|
6
|
+
* Global scope installs into `<targetRoot>/.claude/skills/<name>` where targetRoot is the homedir.
|
|
7
|
+
*
|
|
8
|
+
* Uses directory symlinks by default; falls back to a recursive copy on platforms
|
|
9
|
+
* (or permission modes) where symlinks can't be created — e.g. Windows without Developer Mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare const claudeAdapter: Adapter;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Claude Code adapter.
|
|
5
|
+
*
|
|
6
|
+
* Project scope installs into `<targetRoot>/.claude/skills/<name>`.
|
|
7
|
+
* Global scope installs into `<targetRoot>/.claude/skills/<name>` where targetRoot is the homedir.
|
|
8
|
+
*
|
|
9
|
+
* Uses directory symlinks by default; falls back to a recursive copy on platforms
|
|
10
|
+
* (or permission modes) where symlinks can't be created — e.g. Windows without Developer Mode.
|
|
11
|
+
*/
|
|
12
|
+
export const claudeAdapter = {
|
|
13
|
+
tool: 'claude',
|
|
14
|
+
async install(ctx) {
|
|
15
|
+
const skillsDir = path.join(ctx.targetRoot, '.claude', 'skills');
|
|
16
|
+
fs.mkdirSync(skillsDir, { recursive: true });
|
|
17
|
+
const linkPath = path.join(skillsDir, ctx.skill.name);
|
|
18
|
+
// Clear any existing entry (symlink or directory) so we can re-install cleanly.
|
|
19
|
+
clearPath(linkPath);
|
|
20
|
+
try {
|
|
21
|
+
fs.symlinkSync(ctx.skill.sourcePath, linkPath, 'dir');
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const code = err.code;
|
|
25
|
+
if (code === 'EPERM' || code === 'EACCES' || code === 'ENOSYS') {
|
|
26
|
+
// Windows without dev mode, or filesystem that doesn't support symlinks.
|
|
27
|
+
copyDir(ctx.skill.sourcePath, linkPath);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return linkPath;
|
|
34
|
+
},
|
|
35
|
+
async remove(ctx) {
|
|
36
|
+
const skillPath = path.join(ctx.targetRoot, '.claude', 'skills', ctx.skillName);
|
|
37
|
+
clearPath(skillPath);
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
function clearPath(p) {
|
|
41
|
+
try {
|
|
42
|
+
// lstat so we see symlinks themselves, not their targets.
|
|
43
|
+
const stat = fs.lstatSync(p);
|
|
44
|
+
if (stat.isSymbolicLink() || stat.isFile()) {
|
|
45
|
+
fs.unlinkSync(p);
|
|
46
|
+
}
|
|
47
|
+
else if (stat.isDirectory()) {
|
|
48
|
+
fs.rmSync(p, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (err.code !== 'ENOENT') {
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function copyDir(src, dest) {
|
|
58
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
59
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
60
|
+
const srcPath = path.join(src, entry.name);
|
|
61
|
+
const destPath = path.join(dest, entry.name);
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
copyDir(srcPath, destPath);
|
|
64
|
+
}
|
|
65
|
+
else if (entry.isFile()) {
|
|
66
|
+
fs.copyFileSync(srcPath, destPath);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Adapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Cursor adapter.
|
|
4
|
+
*
|
|
5
|
+
* Cursor reads project rules from `.cursor/rules/*.mdc` — a file format with
|
|
6
|
+
* YAML frontmatter plus a markdown body. (Global scope uses `~/.cursor/rules/`.)
|
|
7
|
+
*
|
|
8
|
+
* Unlike Claude Code, Cursor has no native SKILL.md support, so we transpile
|
|
9
|
+
* the skill into a rules file. Because this is a DERIVED file (not a symlink),
|
|
10
|
+
* it will NOT auto-update when `@lean-agent/skills` changes — re-run
|
|
11
|
+
* `lean-agent add <skill>` to refresh it.
|
|
12
|
+
*
|
|
13
|
+
* `alwaysApply: false` makes the rule "agent-requested": Cursor's AI decides
|
|
14
|
+
* whether to attach it based on the `description` field, which is the closest
|
|
15
|
+
* analogue to Claude Code's description-triggered auto-invocation.
|
|
16
|
+
*/
|
|
17
|
+
export declare const cursorAdapter: Adapter;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { yamlString } from './yaml.js';
|
|
4
|
+
/**
|
|
5
|
+
* Cursor adapter.
|
|
6
|
+
*
|
|
7
|
+
* Cursor reads project rules from `.cursor/rules/*.mdc` — a file format with
|
|
8
|
+
* YAML frontmatter plus a markdown body. (Global scope uses `~/.cursor/rules/`.)
|
|
9
|
+
*
|
|
10
|
+
* Unlike Claude Code, Cursor has no native SKILL.md support, so we transpile
|
|
11
|
+
* the skill into a rules file. Because this is a DERIVED file (not a symlink),
|
|
12
|
+
* it will NOT auto-update when `@lean-agent/skills` changes — re-run
|
|
13
|
+
* `lean-agent add <skill>` to refresh it.
|
|
14
|
+
*
|
|
15
|
+
* `alwaysApply: false` makes the rule "agent-requested": Cursor's AI decides
|
|
16
|
+
* whether to attach it based on the `description` field, which is the closest
|
|
17
|
+
* analogue to Claude Code's description-triggered auto-invocation.
|
|
18
|
+
*/
|
|
19
|
+
export const cursorAdapter = {
|
|
20
|
+
tool: 'cursor',
|
|
21
|
+
async install(ctx) {
|
|
22
|
+
const rulesDir = path.join(ctx.targetRoot, '.cursor', 'rules');
|
|
23
|
+
fs.mkdirSync(rulesDir, { recursive: true });
|
|
24
|
+
const filePath = path.join(rulesDir, `${ctx.skill.name}.mdc`);
|
|
25
|
+
const content = renderMdc(ctx.skill.metadata.description, ctx.skill.body);
|
|
26
|
+
fs.writeFileSync(filePath, content);
|
|
27
|
+
return filePath;
|
|
28
|
+
},
|
|
29
|
+
async remove(ctx) {
|
|
30
|
+
const filePath = path.join(ctx.targetRoot, '.cursor', 'rules', `${ctx.skillName}.mdc`);
|
|
31
|
+
try {
|
|
32
|
+
fs.unlinkSync(filePath);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err.code !== 'ENOENT')
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
function renderMdc(description, body) {
|
|
41
|
+
return `---
|
|
42
|
+
description: ${yamlString(description)}
|
|
43
|
+
alwaysApply: false
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
${body.trim()}
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=cursor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,aAAa,GAAY;IACpC,IAAI,EAAE,QAAQ;IAEd,KAAK,CAAC,OAAO,CAAC,GAAmB;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC/D,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC;QAC9D,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1E,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,GAAG,CAAC,UAAU,EACd,SAAS,EACT,OAAO,EACP,GAAG,GAAG,CAAC,SAAS,MAAM,CACvB,CAAC;QACF,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;IACH,CAAC;CACF,CAAC;AAEF,SAAS,SAAS,CAAC,WAAmB,EAAE,IAAY;IAClD,OAAO;eACM,UAAU,CAAC,WAAW,CAAC;;;;EAIpC,IAAI,CAAC,IAAI,EAAE;CACZ,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { claudeAdapter } from './claude.js';
|
|
2
|
+
import { cursorAdapter } from './cursor.js';
|
|
3
|
+
import { windsurfAdapter } from './windsurf.js';
|
|
4
|
+
import { vscodeAdapter } from './vscode.js';
|
|
5
|
+
export const ADAPTERS = {
|
|
6
|
+
claude: claudeAdapter,
|
|
7
|
+
cursor: cursorAdapter,
|
|
8
|
+
windsurf: windsurfAdapter,
|
|
9
|
+
vscode: vscodeAdapter,
|
|
10
|
+
};
|
|
11
|
+
export function getAdapter(tool) {
|
|
12
|
+
const adapter = ADAPTERS[tool];
|
|
13
|
+
if (!adapter) {
|
|
14
|
+
throw new Error(`Unknown tool: ${tool}`);
|
|
15
|
+
}
|
|
16
|
+
return adapter;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,MAAM,CAAC,MAAM,QAAQ,GAA0B;IAC7C,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,aAAa;IACrB,QAAQ,EAAE,eAAe;IACzB,MAAM,EAAE,aAAa;CACtB,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,IAAU;IACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Skill } from '../skill.js';
|
|
2
|
+
import type { Scope } from '../config.js';
|
|
3
|
+
export type Tool = 'claude' | 'cursor' | 'windsurf' | 'vscode';
|
|
4
|
+
export declare const ALL_TOOLS: Tool[];
|
|
5
|
+
export interface InstallContext {
|
|
6
|
+
skill: Skill;
|
|
7
|
+
scope: Scope;
|
|
8
|
+
/** The filesystem root to install under (cwd for project, homedir for global). */
|
|
9
|
+
targetRoot: string;
|
|
10
|
+
}
|
|
11
|
+
export interface RemoveContext {
|
|
12
|
+
skillName: string;
|
|
13
|
+
scope: Scope;
|
|
14
|
+
targetRoot: string;
|
|
15
|
+
}
|
|
16
|
+
export interface Adapter {
|
|
17
|
+
tool: Tool;
|
|
18
|
+
/** Install a skill. Returns the path the skill was installed at. */
|
|
19
|
+
install(ctx: InstallContext): Promise<string>;
|
|
20
|
+
/** Remove a previously installed skill. Idempotent. */
|
|
21
|
+
remove(ctx: RemoveContext): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,SAAS,GAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Adapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* VS Code / GitHub Copilot adapter.
|
|
4
|
+
*
|
|
5
|
+
* GitHub Copilot in VS Code supports three customization file types:
|
|
6
|
+
* - `.github/copilot-instructions.md` — always-on, repo-wide
|
|
7
|
+
* - `.github/instructions/*.instructions.md` — file-scoped via `applyTo` globs
|
|
8
|
+
* - `.github/prompts/*.prompt.md` — user-invoked reusable prompts
|
|
9
|
+
*
|
|
10
|
+
* Skills are user-triggered by design ("grill me on X", "code review me"),
|
|
11
|
+
* which maps cleanly onto prompt files — the user invokes them from chat
|
|
12
|
+
* by name rather than having them injected into every request.
|
|
13
|
+
*
|
|
14
|
+
* Derived file (not a symlink): re-run `lean-agent add <skill>` after
|
|
15
|
+
* updating `@lean-agent/skills` to refresh the transpiled prompt.
|
|
16
|
+
*/
|
|
17
|
+
export declare const vscodeAdapter: Adapter;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { yamlString } from './yaml.js';
|
|
4
|
+
/**
|
|
5
|
+
* VS Code / GitHub Copilot adapter.
|
|
6
|
+
*
|
|
7
|
+
* GitHub Copilot in VS Code supports three customization file types:
|
|
8
|
+
* - `.github/copilot-instructions.md` — always-on, repo-wide
|
|
9
|
+
* - `.github/instructions/*.instructions.md` — file-scoped via `applyTo` globs
|
|
10
|
+
* - `.github/prompts/*.prompt.md` — user-invoked reusable prompts
|
|
11
|
+
*
|
|
12
|
+
* Skills are user-triggered by design ("grill me on X", "code review me"),
|
|
13
|
+
* which maps cleanly onto prompt files — the user invokes them from chat
|
|
14
|
+
* by name rather than having them injected into every request.
|
|
15
|
+
*
|
|
16
|
+
* Derived file (not a symlink): re-run `lean-agent add <skill>` after
|
|
17
|
+
* updating `@lean-agent/skills` to refresh the transpiled prompt.
|
|
18
|
+
*/
|
|
19
|
+
export const vscodeAdapter = {
|
|
20
|
+
tool: 'vscode',
|
|
21
|
+
async install(ctx) {
|
|
22
|
+
const promptsDir = path.join(ctx.targetRoot, '.github', 'prompts');
|
|
23
|
+
fs.mkdirSync(promptsDir, { recursive: true });
|
|
24
|
+
const filePath = path.join(promptsDir, `${ctx.skill.name}.prompt.md`);
|
|
25
|
+
const content = renderPrompt(ctx.skill.metadata.description, ctx.skill.body);
|
|
26
|
+
fs.writeFileSync(filePath, content);
|
|
27
|
+
return filePath;
|
|
28
|
+
},
|
|
29
|
+
async remove(ctx) {
|
|
30
|
+
const filePath = path.join(ctx.targetRoot, '.github', 'prompts', `${ctx.skillName}.prompt.md`);
|
|
31
|
+
try {
|
|
32
|
+
fs.unlinkSync(filePath);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err.code !== 'ENOENT')
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
function renderPrompt(description, body) {
|
|
41
|
+
return `---
|
|
42
|
+
description: ${yamlString(description)}
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
${body.trim()}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=vscode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vscode.js","sourceRoot":"","sources":["../../src/adapters/vscode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,aAAa,GAAY;IACpC,IAAI,EAAE,QAAQ;IAEd,KAAK,CAAC,OAAO,CAAC,GAAmB;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACnE,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,YAAY,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7E,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,GAAG,CAAC,UAAU,EACd,SAAS,EACT,SAAS,EACT,GAAG,GAAG,CAAC,SAAS,YAAY,CAC7B,CAAC;QACF,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;IACH,CAAC;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,WAAmB,EAAE,IAAY;IACrD,OAAO;eACM,UAAU,CAAC,WAAW,CAAC;;;EAGpC,IAAI,CAAC,IAAI,EAAE;CACZ,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Adapter } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Windsurf adapter.
|
|
4
|
+
*
|
|
5
|
+
* Windsurf reads workspace rules from `.windsurf/rules/*.md` — markdown files
|
|
6
|
+
* with YAML frontmatter. The `trigger` field controls activation:
|
|
7
|
+
* - always_on: always injected into every request
|
|
8
|
+
* - model_decision: AI decides based on `description`
|
|
9
|
+
* - glob: activated when files matching `globs` are in context
|
|
10
|
+
* - manual: only when user explicitly references the rule
|
|
11
|
+
*
|
|
12
|
+
* For skills like challenger that should activate when the user expresses an
|
|
13
|
+
* intent (not for specific file types, not always-on), `trigger: model_decision`
|
|
14
|
+
* with a rich description is the right mapping — it mirrors Claude Code's
|
|
15
|
+
* description-triggered invocation model.
|
|
16
|
+
*
|
|
17
|
+
* Derived file (not a symlink): re-run `lean-agent add <skill>` after
|
|
18
|
+
* updating `@lean-agent/skills` to refresh the transpiled rule.
|
|
19
|
+
*/
|
|
20
|
+
export declare const windsurfAdapter: Adapter;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { yamlString } from './yaml.js';
|
|
4
|
+
/**
|
|
5
|
+
* Windsurf adapter.
|
|
6
|
+
*
|
|
7
|
+
* Windsurf reads workspace rules from `.windsurf/rules/*.md` — markdown files
|
|
8
|
+
* with YAML frontmatter. The `trigger` field controls activation:
|
|
9
|
+
* - always_on: always injected into every request
|
|
10
|
+
* - model_decision: AI decides based on `description`
|
|
11
|
+
* - glob: activated when files matching `globs` are in context
|
|
12
|
+
* - manual: only when user explicitly references the rule
|
|
13
|
+
*
|
|
14
|
+
* For skills like challenger that should activate when the user expresses an
|
|
15
|
+
* intent (not for specific file types, not always-on), `trigger: model_decision`
|
|
16
|
+
* with a rich description is the right mapping — it mirrors Claude Code's
|
|
17
|
+
* description-triggered invocation model.
|
|
18
|
+
*
|
|
19
|
+
* Derived file (not a symlink): re-run `lean-agent add <skill>` after
|
|
20
|
+
* updating `@lean-agent/skills` to refresh the transpiled rule.
|
|
21
|
+
*/
|
|
22
|
+
export const windsurfAdapter = {
|
|
23
|
+
tool: 'windsurf',
|
|
24
|
+
async install(ctx) {
|
|
25
|
+
const rulesDir = path.join(ctx.targetRoot, '.windsurf', 'rules');
|
|
26
|
+
fs.mkdirSync(rulesDir, { recursive: true });
|
|
27
|
+
const filePath = path.join(rulesDir, `${ctx.skill.name}.md`);
|
|
28
|
+
const content = renderRule(ctx.skill.metadata.description, ctx.skill.body);
|
|
29
|
+
fs.writeFileSync(filePath, content);
|
|
30
|
+
return filePath;
|
|
31
|
+
},
|
|
32
|
+
async remove(ctx) {
|
|
33
|
+
const filePath = path.join(ctx.targetRoot, '.windsurf', 'rules', `${ctx.skillName}.md`);
|
|
34
|
+
try {
|
|
35
|
+
fs.unlinkSync(filePath);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err.code !== 'ENOENT')
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
function renderRule(description, body) {
|
|
44
|
+
return `---
|
|
45
|
+
trigger: model_decision
|
|
46
|
+
description: ${yamlString(description)}
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
${body.trim()}
|
|
50
|
+
`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=windsurf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"windsurf.js","sourceRoot":"","sources":["../../src/adapters/windsurf.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,eAAe,GAAY;IACtC,IAAI,EAAE,UAAU;IAEhB,KAAK,CAAC,OAAO,CAAC,GAAmB;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QACjE,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3E,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAkB;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CACxB,GAAG,CAAC,UAAU,EACd,WAAW,EACX,OAAO,EACP,GAAG,GAAG,CAAC,SAAS,KAAK,CACtB,CAAC;QACF,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,GAAG,CAAC;QAClE,CAAC;IACH,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,WAAmB,EAAE,IAAY;IACnD,OAAO;;eAEM,UAAU,CAAC,WAAW,CAAC;;;EAGpC,IAAI,CAAC,IAAI,EAAE;CACZ,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a string as a YAML scalar safely.
|
|
3
|
+
*
|
|
4
|
+
* Uses the flow-style double-quoted form when the input contains any
|
|
5
|
+
* YAML-significant character, which lets us pass through descriptions
|
|
6
|
+
* containing colons, quotes, or other punctuation without worrying about
|
|
7
|
+
* the full YAML escape machinery.
|
|
8
|
+
*/
|
|
9
|
+
export declare function yamlString(s: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a string as a YAML scalar safely.
|
|
3
|
+
*
|
|
4
|
+
* Uses the flow-style double-quoted form when the input contains any
|
|
5
|
+
* YAML-significant character, which lets us pass through descriptions
|
|
6
|
+
* containing colons, quotes, or other punctuation without worrying about
|
|
7
|
+
* the full YAML escape machinery.
|
|
8
|
+
*/
|
|
9
|
+
export function yamlString(s) {
|
|
10
|
+
if (/[:#&*!|>'"%@`\n]/.test(s)) {
|
|
11
|
+
return '"' + s.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
|
|
12
|
+
}
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=yaml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.js","sourceRoot":"","sources":["../../src/adapters/yaml.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,UAAU,CAAC,CAAS;IAClC,IAAI,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/B,OAAO,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC;IACnE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/banner.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function banner(): string;
|
package/dist/banner.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
const LOGO = String.raw `
|
|
3
|
+
_ _ ___ _
|
|
4
|
+
/ \ / | / _ \ / \
|
|
5
|
+
/ _ \ | || | | | / _ \
|
|
6
|
+
/ ___ \| || |_| |/ ___ \
|
|
7
|
+
/_/ \_\_| \___//_/ \_\
|
|
8
|
+
`;
|
|
9
|
+
export function banner() {
|
|
10
|
+
return (pc.cyan(pc.bold(LOGO)) +
|
|
11
|
+
'\n' +
|
|
12
|
+
pc.bold(' agentic-agile') +
|
|
13
|
+
pc.dim(' (a10a)') +
|
|
14
|
+
pc.dim(' v0.0.1') +
|
|
15
|
+
'\n' +
|
|
16
|
+
pc.dim(' The lean framework for agentic software development.') +
|
|
17
|
+
'\n');
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../src/banner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;CAMtB,CAAC;AAEF,MAAM,UAAU,MAAM;IACpB,OAAO,CACL,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI;QACJ,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAC1B,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;QACjB,EAAE,CAAC,GAAG,CAAC,SAAS,CAAC;QACjB,IAAI;QACJ,EAAE,CAAC,GAAG,CAAC,wDAAwD,CAAC;QAChE,IAAI,CACL,CAAC;AACJ,CAAC"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { initCommand } from './commands/init.js';
|
|
4
|
+
import { addCommand } from './commands/add.js';
|
|
5
|
+
import { removeCommand } from './commands/remove.js';
|
|
6
|
+
import { listCommand } from './commands/list.js';
|
|
7
|
+
const program = new Command();
|
|
8
|
+
program
|
|
9
|
+
.name('lean-agent')
|
|
10
|
+
.description('The lean framework for agentic software development.')
|
|
11
|
+
.version('0.0.1');
|
|
12
|
+
program
|
|
13
|
+
.command('init')
|
|
14
|
+
.description('Set up lean-agent in the current project (or --global).')
|
|
15
|
+
.option('--global', 'Write global config to ~/.lean-agent.json')
|
|
16
|
+
.action(initCommand);
|
|
17
|
+
program
|
|
18
|
+
.command('add <skill>')
|
|
19
|
+
.description('Install a skill from the catalog.')
|
|
20
|
+
.option('--tool <name>', 'Tool to install for (claude, cursor, windsurf, vscode)')
|
|
21
|
+
.option('--global', 'Install into the user-global scope instead of this project')
|
|
22
|
+
.action(addCommand);
|
|
23
|
+
program
|
|
24
|
+
.command('remove <skill>')
|
|
25
|
+
.description('Uninstall a skill.')
|
|
26
|
+
.option('--tool <name>', 'Tool to remove from')
|
|
27
|
+
.option('--global', 'Remove from the user-global scope')
|
|
28
|
+
.action(removeCommand);
|
|
29
|
+
program
|
|
30
|
+
.command('list')
|
|
31
|
+
.description('List installed skills and the catalog of available skills.')
|
|
32
|
+
.option('--global', 'List against the user-global scope')
|
|
33
|
+
.action(listCommand);
|
|
34
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
35
|
+
console.error(err);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,sDAAsD,CAAC;KACnE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,yDAAyD,CAAC;KACtE,MAAM,CAAC,UAAU,EAAE,2CAA2C,CAAC;KAC/D,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,eAAe,EAAE,wDAAwD,CAAC;KACjF,MAAM,CAAC,UAAU,EAAE,4DAA4D,CAAC;KAChF,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;KAC9C,MAAM,CAAC,UAAU,EAAE,mCAAmC,CAAC;KACvD,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,UAAU,EAAE,oCAAoC,CAAC;KACxD,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { readConfig, writeConfig, markInstalled, } from '../config.js';
|
|
4
|
+
import { resolveSkillPath, loadSkill, listAvailableSkills } from '../skill.js';
|
|
5
|
+
import { getAdapter } from '../adapters/index.js';
|
|
6
|
+
import { pickTool } from './init.js';
|
|
7
|
+
export async function addCommand(skillName, options) {
|
|
8
|
+
const scope = options.global ? 'global' : 'project';
|
|
9
|
+
// 1. Resolve the skill in the catalog.
|
|
10
|
+
const skillDir = resolveSkillPath(skillName);
|
|
11
|
+
if (!skillDir) {
|
|
12
|
+
const available = listAvailableSkills();
|
|
13
|
+
console.error(pc.red(`skill "${skillName}" not found in @lean-agent/skills.`));
|
|
14
|
+
if (available.length > 0) {
|
|
15
|
+
console.error(pc.dim(`available: ${available.join(', ')}`));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.error(pc.dim('no skills available — is @lean-agent/skills installed?'));
|
|
19
|
+
}
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
const skill = loadSkill(skillDir);
|
|
23
|
+
// 2. Load or bootstrap config (auto-init on first use).
|
|
24
|
+
let config = readConfig(scope);
|
|
25
|
+
let tool = options.tool;
|
|
26
|
+
if (!tool) {
|
|
27
|
+
tool = config?.tools?.[0] ?? undefined;
|
|
28
|
+
}
|
|
29
|
+
if (!tool) {
|
|
30
|
+
const picked = await pickTool();
|
|
31
|
+
if (!picked) {
|
|
32
|
+
console.error(pc.red('aborted: no tool selected.'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
tool = picked;
|
|
36
|
+
}
|
|
37
|
+
if (!config) {
|
|
38
|
+
config = { tools: [tool], installed: {} };
|
|
39
|
+
}
|
|
40
|
+
if (!config.tools.includes(tool)) {
|
|
41
|
+
config.tools.push(tool);
|
|
42
|
+
}
|
|
43
|
+
// 3. Install via the adapter.
|
|
44
|
+
const adapter = getAdapter(tool);
|
|
45
|
+
const targetRoot = scope === 'global' ? os.homedir() : process.cwd();
|
|
46
|
+
try {
|
|
47
|
+
const installedAt = await adapter.install({ skill, scope, targetRoot });
|
|
48
|
+
markInstalled(config, skillName, tool);
|
|
49
|
+
writeConfig(scope, config);
|
|
50
|
+
console.log(pc.green('installed') +
|
|
51
|
+
` ${pc.bold(skill.name)} ` +
|
|
52
|
+
pc.dim('→ ') +
|
|
53
|
+
pc.cyan(tool) +
|
|
54
|
+
pc.dim(' (' + installedAt + ')'));
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
58
|
+
console.error(pc.red(`failed to install ${skillName}:`));
|
|
59
|
+
console.error(pc.red(' ' + msg));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { readConfig, writeConfig } from '../config.js';
|
|
4
|
+
export async function initCommand(options) {
|
|
5
|
+
const scope = options.global ? 'global' : 'project';
|
|
6
|
+
const existing = readConfig(scope);
|
|
7
|
+
if (existing && existing.tools.length > 0) {
|
|
8
|
+
console.log(pc.yellow(`lean-agent is already initialized in this ${scope} scope.`) +
|
|
9
|
+
` tools: ${pc.cyan(existing.tools.join(', '))}`);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const tool = await pickTool();
|
|
13
|
+
if (!tool) {
|
|
14
|
+
console.error(pc.red('aborted: no tool selected.'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
writeConfig(scope, { tools: [tool], installed: {} });
|
|
18
|
+
console.log(pc.green('initialized') +
|
|
19
|
+
` lean-agent for ${pc.cyan(tool)} (${scope} scope).`);
|
|
20
|
+
console.log(pc.dim('next: lean-agent add challenger'));
|
|
21
|
+
}
|
|
22
|
+
export async function pickTool() {
|
|
23
|
+
const response = await prompts({
|
|
24
|
+
type: 'select',
|
|
25
|
+
name: 'tool',
|
|
26
|
+
message: 'Which AI coding tool are you using?',
|
|
27
|
+
choices: [
|
|
28
|
+
{ title: 'Claude Code', value: 'claude' },
|
|
29
|
+
{ title: 'Cursor', value: 'cursor' },
|
|
30
|
+
{ title: 'Windsurf', value: 'windsurf' },
|
|
31
|
+
{ title: 'VS Code (GitHub Copilot)', value: 'vscode' },
|
|
32
|
+
],
|
|
33
|
+
initial: 0,
|
|
34
|
+
});
|
|
35
|
+
return response.tool ?? null;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEnC,IAAI,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,MAAM,CAAC,6CAA6C,KAAK,SAAS,CAAC;YACpE,WAAW,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAClD,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,WAAW,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CACT,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC;QACrB,mBAAmB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,UAAU,CACvD,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC;QAC7B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,qCAAqC;QAC9C,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,QAAQ,EAAE;YACzC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;YACpC,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;YACxC,EAAE,KAAK,EAAE,0BAA0B,EAAE,KAAK,EAAE,QAAQ,EAAE;SACvD;QACD,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;IACH,OAAQ,QAAQ,CAAC,IAAa,IAAI,IAAI,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
import { readConfig } from '../config.js';
|
|
3
|
+
import { listAvailableSkills, resolveSkillPath, loadSkill } from '../skill.js';
|
|
4
|
+
export async function listCommand(options) {
|
|
5
|
+
const scope = options.global ? 'global' : 'project';
|
|
6
|
+
console.log(pc.bold('catalog (@lean-agent/skills):'));
|
|
7
|
+
const available = listAvailableSkills();
|
|
8
|
+
if (available.length === 0) {
|
|
9
|
+
console.log(pc.dim(' (empty — is @lean-agent/skills installed?)'));
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
for (const name of available) {
|
|
13
|
+
const dir = resolveSkillPath(name);
|
|
14
|
+
if (!dir) {
|
|
15
|
+
console.log(' ' + pc.bold(name));
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const skill = loadSkill(dir);
|
|
20
|
+
const summary = skill.metadata.description.split(/\.\s/)[0];
|
|
21
|
+
console.log(' ' + pc.bold(name) + pc.dim(' — ' + summary));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
console.log(' ' + pc.bold(name));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log(pc.bold(`installed (${scope} scope):`));
|
|
30
|
+
const config = readConfig(scope);
|
|
31
|
+
if (!config) {
|
|
32
|
+
console.log(pc.dim(' (no config — run `lean-agent init`)'));
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const entries = Object.entries(config.installed);
|
|
36
|
+
if (entries.length === 0) {
|
|
37
|
+
console.log(pc.dim(' (none yet — run `lean-agent add <skill>`)'));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
for (const [name, tools] of entries) {
|
|
41
|
+
console.log(' ' + pc.bold(name) + pc.dim(' → ') + pc.cyan(tools.join(', ')));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAM/E,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAoB;IACpD,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;IACxC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;IACtE,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBAClC,SAAS;YACX,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;gBAC7B,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;YAC9D,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,KAAK,UAAU,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACnE,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAChF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { readConfig, writeConfig, markRemoved } from '../config.js';
|
|
4
|
+
import { getAdapter } from '../adapters/index.js';
|
|
5
|
+
export async function removeCommand(skillName, options) {
|
|
6
|
+
const scope = options.global ? 'global' : 'project';
|
|
7
|
+
const config = readConfig(scope);
|
|
8
|
+
if (!config) {
|
|
9
|
+
console.error(pc.red(`no lean-agent config in this ${scope} scope — nothing to remove.`));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const tool = options.tool ?? config.tools[0];
|
|
13
|
+
if (!tool) {
|
|
14
|
+
console.error(pc.red('no tool configured. pass --tool=<name>.'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const adapter = getAdapter(tool);
|
|
18
|
+
const targetRoot = scope === 'global' ? os.homedir() : process.cwd();
|
|
19
|
+
try {
|
|
20
|
+
await adapter.remove({ skillName, scope, targetRoot });
|
|
21
|
+
}
|
|
22
|
+
catch (err) {
|
|
23
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
24
|
+
console.error(pc.red(`failed to remove ${skillName}: ${msg}`));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
markRemoved(config, skillName, tool);
|
|
28
|
+
writeConfig(scope, config);
|
|
29
|
+
console.log(pc.green('removed') + ` ${pc.bold(skillName)} from ${pc.cyan(tool)}`);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAQlD,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,OAAsB;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAEjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,EAAE,CAAC,GAAG,CAAC,gCAAgC,KAAK,6BAA6B,CAAC,CAC3E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAqB,OAAO,CAAC,IAAI,IAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAsB,CAAC;IACrF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,UAAU,GAAG,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,oBAAoB,SAAS,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IACrC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpF,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type Scope = 'project' | 'global';
|
|
2
|
+
/**
|
|
3
|
+
* Sticky config for an lean-agent scope.
|
|
4
|
+
*
|
|
5
|
+
* - `tools`: the set of tools this project/user is configured to use.
|
|
6
|
+
* First entry is the default target when `--tool` is omitted.
|
|
7
|
+
* - `installed`: map from skill name → list of tools it is currently installed for.
|
|
8
|
+
* Tracking per-tool lets us remove a skill from one tool without forgetting
|
|
9
|
+
* that it's still installed on another.
|
|
10
|
+
*/
|
|
11
|
+
export interface LeanAgentConfig {
|
|
12
|
+
tools: string[];
|
|
13
|
+
installed: Record<string, string[]>;
|
|
14
|
+
}
|
|
15
|
+
export declare function getConfigPath(scope: Scope): string;
|
|
16
|
+
export declare function readConfig(scope: Scope): LeanAgentConfig | null;
|
|
17
|
+
export declare function writeConfig(scope: Scope, config: LeanAgentConfig): void;
|
|
18
|
+
/** Record that `skill` has been installed for `tool` in the given config. */
|
|
19
|
+
export declare function markInstalled(config: LeanAgentConfig, skill: string, tool: string): void;
|
|
20
|
+
/** Remove the record that `skill` is installed for `tool`. Drops the entry
|
|
21
|
+
* entirely if no tools remain. */
|
|
22
|
+
export declare function markRemoved(config: LeanAgentConfig, skill: string, tool: string): void;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
const CONFIG_NAME = '.lean-agent.json';
|
|
5
|
+
export function getConfigPath(scope) {
|
|
6
|
+
if (scope === 'global') {
|
|
7
|
+
return path.join(os.homedir(), CONFIG_NAME);
|
|
8
|
+
}
|
|
9
|
+
return path.join(process.cwd(), CONFIG_NAME);
|
|
10
|
+
}
|
|
11
|
+
export function readConfig(scope) {
|
|
12
|
+
const p = getConfigPath(scope);
|
|
13
|
+
if (!fs.existsSync(p))
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
const raw = fs.readFileSync(p, 'utf8');
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
return {
|
|
19
|
+
tools: Array.isArray(parsed.tools) ? parsed.tools : [],
|
|
20
|
+
installed: parsed.installed && typeof parsed.installed === 'object'
|
|
21
|
+
? parsed.installed
|
|
22
|
+
: {},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function writeConfig(scope, config) {
|
|
30
|
+
const p = getConfigPath(scope);
|
|
31
|
+
fs.writeFileSync(p, JSON.stringify(config, null, 2) + '\n');
|
|
32
|
+
}
|
|
33
|
+
/** Record that `skill` has been installed for `tool` in the given config. */
|
|
34
|
+
export function markInstalled(config, skill, tool) {
|
|
35
|
+
const current = config.installed[skill] ?? [];
|
|
36
|
+
if (!current.includes(tool)) {
|
|
37
|
+
current.push(tool);
|
|
38
|
+
}
|
|
39
|
+
config.installed[skill] = current;
|
|
40
|
+
}
|
|
41
|
+
/** Remove the record that `skill` is installed for `tool`. Drops the entry
|
|
42
|
+
* entirely if no tools remain. */
|
|
43
|
+
export function markRemoved(config, skill, tool) {
|
|
44
|
+
const current = config.installed[skill];
|
|
45
|
+
if (!current)
|
|
46
|
+
return;
|
|
47
|
+
const next = current.filter((t) => t !== tool);
|
|
48
|
+
if (next.length === 0) {
|
|
49
|
+
delete config.installed[skill];
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
config.installed[skill] = next;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AAkBzB,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAEvC,MAAM,UAAU,aAAa,CAAC,KAAY;IACxC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAY;IACrC,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;YACtD,SAAS,EACP,MAAM,CAAC,SAAS,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;gBACtD,CAAC,CAAC,MAAM,CAAC,SAAS;gBAClB,CAAC,CAAC,EAAE;SACT,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,MAAuB;IAC/D,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IAC/B,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC9D,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAC3B,MAAuB,EACvB,KAAa,EACb,IAAY;IAEZ,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrB,CAAC;IACD,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;AACpC,CAAC;AAED;mCACmC;AACnC,MAAM,UAAU,WAAW,CACzB,MAAuB,EACvB,KAAa,EACb,IAAY;IAEZ,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACjC,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { loadSkill, resolveSkillPath, listAvailableSkills } from './skill.js';
|
|
2
|
+
export type { Skill, SkillMetadata } from './skill.js';
|
|
3
|
+
export { readConfig, writeConfig, getConfigPath } from './config.js';
|
|
4
|
+
export type { LeanAgentConfig, Scope } from './config.js';
|
|
5
|
+
export { ADAPTERS, getAdapter } from './adapters/index.js';
|
|
6
|
+
export type { Adapter, Tool, InstallContext, RemoveContext } from './adapters/types.js';
|
|
7
|
+
export { ALL_TOOLS } from './adapters/types.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Public SDK surface. Consumers that want to build on top of lean-agent
|
|
2
|
+
// (e.g. authoring their own skill packages or custom adapters) import from here.
|
|
3
|
+
export { loadSkill, resolveSkillPath, listAvailableSkills } from './skill.js';
|
|
4
|
+
export { readConfig, writeConfig, getConfigPath } from './config.js';
|
|
5
|
+
export { ADAPTERS, getAdapter } from './adapters/index.js';
|
|
6
|
+
export { ALL_TOOLS } from './adapters/types.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,iFAAiF;AACjF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/skill.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SkillMetadata {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
[key: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface Skill {
|
|
7
|
+
name: string;
|
|
8
|
+
metadata: SkillMetadata;
|
|
9
|
+
body: string;
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveSkillPath(skillName: string): string | null;
|
|
13
|
+
export declare function loadSkill(skillDir: string): Skill;
|
|
14
|
+
export declare function listAvailableSkills(): string[];
|
package/dist/skill.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import matter from 'gray-matter';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the on-disk root of @lean-agent/skills via Node's resolver.
|
|
8
|
+
* Works with npm workspaces (symlink into node_modules) and published installs.
|
|
9
|
+
*/
|
|
10
|
+
function resolveSkillsPackageRoot() {
|
|
11
|
+
try {
|
|
12
|
+
const pkgJson = require.resolve('@lean-agent/skills/package.json');
|
|
13
|
+
return path.dirname(pkgJson);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function resolveSkillPath(skillName) {
|
|
20
|
+
const root = resolveSkillsPackageRoot();
|
|
21
|
+
if (!root)
|
|
22
|
+
return null;
|
|
23
|
+
const skillDir = path.join(root, 'skills', skillName);
|
|
24
|
+
if (!fs.existsSync(path.join(skillDir, 'SKILL.md')))
|
|
25
|
+
return null;
|
|
26
|
+
return skillDir;
|
|
27
|
+
}
|
|
28
|
+
export function loadSkill(skillDir) {
|
|
29
|
+
const skillMdPath = path.join(skillDir, 'SKILL.md');
|
|
30
|
+
const raw = fs.readFileSync(skillMdPath, 'utf8');
|
|
31
|
+
const parsed = matter(raw);
|
|
32
|
+
const metadata = parsed.data;
|
|
33
|
+
if (!metadata.name || !metadata.description) {
|
|
34
|
+
throw new Error(`Skill at ${skillDir} is missing required frontmatter fields (name, description).`);
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
name: metadata.name,
|
|
38
|
+
metadata,
|
|
39
|
+
body: parsed.content.trim(),
|
|
40
|
+
sourcePath: skillDir,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function listAvailableSkills() {
|
|
44
|
+
const root = resolveSkillsPackageRoot();
|
|
45
|
+
if (!root)
|
|
46
|
+
return [];
|
|
47
|
+
const skillsDir = path.join(root, 'skills');
|
|
48
|
+
if (!fs.existsSync(skillsDir))
|
|
49
|
+
return [];
|
|
50
|
+
return fs
|
|
51
|
+
.readdirSync(skillsDir)
|
|
52
|
+
.filter((name) => fs.existsSync(path.join(skillsDir, name, 'SKILL.md')));
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAe/C;;;GAGG;AACH,SAAS,wBAAwB;IAC/B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,IAAI,GAAG,wBAAwB,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACjE,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB;IACxC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAqB,CAAC;IAC9C,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CACb,YAAY,QAAQ,8DAA8D,CACnF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,QAAQ;QACR,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QAC3B,UAAU,EAAE,QAAQ;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,IAAI,GAAG,wBAAwB,EAAE,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,EAAE;SACN,WAAW,CAAC,SAAS,CAAC;SACtB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AAC7E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lean-agent/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "CLI and SDK for lean-agent — the lean framework for agentic software development across every AI coding tool.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"lean-agent": "./dist/cli.js",
|
|
8
|
+
"la": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/**/*",
|
|
14
|
+
"README.md",
|
|
15
|
+
"LICENSE"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsx src/cli.ts",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"prepublishOnly": "npm run build && npm run test"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@lean-agent/skills": "^0.0.1",
|
|
25
|
+
"commander": "^12.1.0",
|
|
26
|
+
"gray-matter": "^4.0.3",
|
|
27
|
+
"picocolors": "^1.1.0",
|
|
28
|
+
"prompts": "^2.4.2"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^20.14.0",
|
|
32
|
+
"@types/prompts": "^2.4.9",
|
|
33
|
+
"tsx": "^4.19.0",
|
|
34
|
+
"typescript": "^5.5.0",
|
|
35
|
+
"vitest": "^2.0.0"
|
|
36
|
+
},
|
|
37
|
+
"author": "Peter Rupp",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/disRupptive/lean-agent.git",
|
|
42
|
+
"directory": "packages/core"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/disRupptive/lean-agent/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/disRupptive/lean-agent/tree/main/packages/core#readme",
|
|
48
|
+
"keywords": [
|
|
49
|
+
"lean-agent",
|
|
50
|
+
"ai",
|
|
51
|
+
"cli",
|
|
52
|
+
"skills",
|
|
53
|
+
"claude",
|
|
54
|
+
"cursor",
|
|
55
|
+
"windsurf",
|
|
56
|
+
"copilot"
|
|
57
|
+
],
|
|
58
|
+
"engines": {
|
|
59
|
+
"node": ">=18"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public"
|
|
63
|
+
}
|
|
64
|
+
}
|