@everydaydevopsio/ballast 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/agents/cicd/content.md +17 -0
- package/agents/cicd/templates/claude-header.md +5 -0
- package/agents/cicd/templates/cursor-frontmatter.yaml +9 -0
- package/agents/cicd/templates/opencode-frontmatter.yaml +21 -0
- package/agents/linting/content.md +121 -0
- package/agents/linting/templates/claude-header.md +5 -0
- package/agents/linting/templates/cursor-frontmatter.yaml +12 -0
- package/agents/linting/templates/opencode-frontmatter.yaml +21 -0
- package/agents/local-dev/content.md +17 -0
- package/agents/local-dev/templates/claude-header.md +5 -0
- package/agents/local-dev/templates/cursor-frontmatter.yaml +10 -0
- package/agents/local-dev/templates/opencode-frontmatter.yaml +21 -0
- package/agents/observability/content.md +17 -0
- package/agents/observability/templates/claude-header.md +5 -0
- package/agents/observability/templates/cursor-frontmatter.yaml +9 -0
- package/agents/observability/templates/opencode-frontmatter.yaml +21 -0
- package/bin/ballast.js +3 -0
- package/dist/agents.d.ts +21 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +52 -0
- package/dist/agents.js.map +1 -0
- package/dist/build.d.ts +37 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/build.js +110 -0
- package/dist/build.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +118 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +73 -0
- package/dist/config.js.map +1 -0
- package/dist/install.d.ts +47 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +168 -0
- package/dist/install.js.map +1 -0
- package/package.json +66 -0
package/dist/build.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getContent = getContent;
|
|
7
|
+
exports.getTemplate = getTemplate;
|
|
8
|
+
exports.buildCursorFormat = buildCursorFormat;
|
|
9
|
+
exports.buildClaudeFormat = buildClaudeFormat;
|
|
10
|
+
exports.buildOpenCodeFormat = buildOpenCodeFormat;
|
|
11
|
+
exports.buildContent = buildContent;
|
|
12
|
+
exports.getDestination = getDestination;
|
|
13
|
+
exports.listTargets = listTargets;
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const agents_1 = require("./agents");
|
|
17
|
+
const TARGETS = ['cursor', 'claude', 'opencode'];
|
|
18
|
+
/**
|
|
19
|
+
* Read agent content.md
|
|
20
|
+
*/
|
|
21
|
+
function getContent(agentId) {
|
|
22
|
+
const dir = (0, agents_1.getAgentDir)(agentId);
|
|
23
|
+
const file = path_1.default.join(dir, 'content.md');
|
|
24
|
+
if (!fs_1.default.existsSync(file)) {
|
|
25
|
+
throw new Error(`Agent "${agentId}" has no content.md`);
|
|
26
|
+
}
|
|
27
|
+
return fs_1.default.readFileSync(file, 'utf8');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read agent template file
|
|
31
|
+
*/
|
|
32
|
+
function getTemplate(agentId, filename) {
|
|
33
|
+
const dir = (0, agents_1.getAgentDir)(agentId);
|
|
34
|
+
const file = path_1.default.join(dir, 'templates', filename);
|
|
35
|
+
if (!fs_1.default.existsSync(file)) {
|
|
36
|
+
throw new Error(`Agent "${agentId}" missing template: ${filename}`);
|
|
37
|
+
}
|
|
38
|
+
return fs_1.default.readFileSync(file, 'utf8');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build content for Cursor (.mdc = frontmatter + content)
|
|
42
|
+
*/
|
|
43
|
+
function buildCursorFormat(agentId) {
|
|
44
|
+
const frontmatter = getTemplate(agentId, 'cursor-frontmatter.yaml');
|
|
45
|
+
const content = getContent(agentId);
|
|
46
|
+
return frontmatter + '\n' + content;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Build content for Claude (header + content)
|
|
50
|
+
*/
|
|
51
|
+
function buildClaudeFormat(agentId) {
|
|
52
|
+
const header = getTemplate(agentId, 'claude-header.md');
|
|
53
|
+
const content = getContent(agentId);
|
|
54
|
+
return header + content;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build content for OpenCode (YAML frontmatter + content)
|
|
58
|
+
*/
|
|
59
|
+
function buildOpenCodeFormat(agentId) {
|
|
60
|
+
const frontmatter = getTemplate(agentId, 'opencode-frontmatter.yaml');
|
|
61
|
+
const content = getContent(agentId);
|
|
62
|
+
return frontmatter + '\n' + content;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Build content for the given agent and target
|
|
66
|
+
*/
|
|
67
|
+
function buildContent(agentId, target) {
|
|
68
|
+
switch (target) {
|
|
69
|
+
case 'cursor':
|
|
70
|
+
return buildCursorFormat(agentId);
|
|
71
|
+
case 'claude':
|
|
72
|
+
return buildClaudeFormat(agentId);
|
|
73
|
+
case 'opencode':
|
|
74
|
+
return buildOpenCodeFormat(agentId);
|
|
75
|
+
default:
|
|
76
|
+
throw new Error(`Unknown target: ${target}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get destination path for installed agent file
|
|
81
|
+
*/
|
|
82
|
+
function getDestination(agentId, target, projectRoot) {
|
|
83
|
+
const root = path_1.default.resolve(projectRoot);
|
|
84
|
+
switch (target) {
|
|
85
|
+
case 'cursor': {
|
|
86
|
+
const dir = path_1.default.join(root, '.cursor', 'rules');
|
|
87
|
+
const file = path_1.default.join(dir, `${agentId}.mdc`);
|
|
88
|
+
return { dir, file };
|
|
89
|
+
}
|
|
90
|
+
case 'claude': {
|
|
91
|
+
const dir = path_1.default.join(root, '.claude', 'rules');
|
|
92
|
+
const file = path_1.default.join(dir, `${agentId}.md`);
|
|
93
|
+
return { dir, file };
|
|
94
|
+
}
|
|
95
|
+
case 'opencode': {
|
|
96
|
+
const dir = path_1.default.join(root, '.opencode');
|
|
97
|
+
const file = path_1.default.join(dir, `${agentId}.md`);
|
|
98
|
+
return { dir, file };
|
|
99
|
+
}
|
|
100
|
+
default:
|
|
101
|
+
throw new Error(`Unknown target: ${target}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* List supported targets
|
|
106
|
+
*/
|
|
107
|
+
function listTargets() {
|
|
108
|
+
return TARGETS.slice();
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface CliOptions {
|
|
3
|
+
target?: string;
|
|
4
|
+
agents: string[];
|
|
5
|
+
all: boolean;
|
|
6
|
+
force: boolean;
|
|
7
|
+
yes: boolean;
|
|
8
|
+
}
|
|
9
|
+
export type ParseArgsResult = CliOptions | {
|
|
10
|
+
help: true;
|
|
11
|
+
} | {
|
|
12
|
+
version: true;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAIA,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const install_1 = require("./install");
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
const args = argv.slice(2);
|
|
7
|
+
const options = {
|
|
8
|
+
target: undefined,
|
|
9
|
+
agents: [],
|
|
10
|
+
all: false,
|
|
11
|
+
force: false,
|
|
12
|
+
yes: false
|
|
13
|
+
};
|
|
14
|
+
let i = 0;
|
|
15
|
+
while (i < args.length) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
if (arg === '--target' || arg === '-t') {
|
|
18
|
+
options.target = args[++i];
|
|
19
|
+
i++;
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (arg === '--agent' || arg === '-a') {
|
|
23
|
+
const value = args[++i];
|
|
24
|
+
if (value) {
|
|
25
|
+
options.agents = options.agents.concat(value.split(',').map((s) => s.trim()));
|
|
26
|
+
}
|
|
27
|
+
i++;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (arg === '--all') {
|
|
31
|
+
options.all = true;
|
|
32
|
+
i++;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (arg === '--force' || arg === '-f') {
|
|
36
|
+
options.force = true;
|
|
37
|
+
i++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (arg === '--yes' || arg === '-y') {
|
|
41
|
+
options.yes = true;
|
|
42
|
+
i++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (arg === '--help' || arg === '-h') {
|
|
46
|
+
return { help: true };
|
|
47
|
+
}
|
|
48
|
+
if (arg === '--version' || arg === '-v') {
|
|
49
|
+
return { version: true };
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
}
|
|
53
|
+
return options;
|
|
54
|
+
}
|
|
55
|
+
function printHelp() {
|
|
56
|
+
const pkg = require('../package.json');
|
|
57
|
+
console.log(`
|
|
58
|
+
${pkg.name} v${pkg.version}
|
|
59
|
+
|
|
60
|
+
Usage: ballast install [options]
|
|
61
|
+
|
|
62
|
+
Commands:
|
|
63
|
+
install Install agent rules for the chosen AI platform (default)
|
|
64
|
+
|
|
65
|
+
Options:
|
|
66
|
+
--target, -t <platform> AI platform: cursor, claude, opencode
|
|
67
|
+
--agent, -a <agents> Agent(s): linting, local-dev, cicd, observability (comma-separated)
|
|
68
|
+
--all Install all agents
|
|
69
|
+
--force, -f Overwrite existing rule files
|
|
70
|
+
--yes, -y Non-interactive; require --target and --agent/--all if no .rulesrc.json
|
|
71
|
+
--help, -h Show this help
|
|
72
|
+
--version, -v Show version
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
ballast install
|
|
76
|
+
ballast install --target cursor --agent linting
|
|
77
|
+
ballast install --target claude --all --force
|
|
78
|
+
ballast install --yes --target cursor --all
|
|
79
|
+
`);
|
|
80
|
+
}
|
|
81
|
+
function printVersion() {
|
|
82
|
+
const pkg = require('../package.json');
|
|
83
|
+
console.log(pkg.version);
|
|
84
|
+
}
|
|
85
|
+
async function main() {
|
|
86
|
+
const argv = process.argv;
|
|
87
|
+
const command = argv[2];
|
|
88
|
+
const isInstall = !command || command === 'install';
|
|
89
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
90
|
+
printHelp();
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
if (argv.includes('--version') || argv.includes('-v')) {
|
|
94
|
+
printVersion();
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
if (!isInstall) {
|
|
98
|
+
console.error(`Unknown command: ${command}`);
|
|
99
|
+
console.error('Run ballast --help for usage.');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
const options = parseArgs(argv);
|
|
103
|
+
if ('help' in options && options.help) {
|
|
104
|
+
printHelp();
|
|
105
|
+
process.exit(0);
|
|
106
|
+
}
|
|
107
|
+
if ('version' in options && options.version) {
|
|
108
|
+
printVersion();
|
|
109
|
+
process.exit(0);
|
|
110
|
+
}
|
|
111
|
+
const exitCode = await (0, install_1.runInstall)(options);
|
|
112
|
+
process.exit(exitCode);
|
|
113
|
+
}
|
|
114
|
+
main().catch((err) => {
|
|
115
|
+
console.error(err);
|
|
116
|
+
process.exit(1);
|
|
117
|
+
});
|
|
118
|
+
//# 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":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const RULESRC_FILENAME = ".rulesrc.json";
|
|
2
|
+
export type Target = 'cursor' | 'claude' | 'opencode';
|
|
3
|
+
export interface RulesConfig {
|
|
4
|
+
target: Target;
|
|
5
|
+
agents: string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Find project root (directory containing .rulesrc.json or package.json)
|
|
9
|
+
*/
|
|
10
|
+
export declare function findProjectRoot(cwd?: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Load .rulesrc.json from project root
|
|
13
|
+
*/
|
|
14
|
+
export declare function loadConfig(projectRoot?: string): RulesConfig | null;
|
|
15
|
+
/**
|
|
16
|
+
* Save .rulesrc.json to project root
|
|
17
|
+
*/
|
|
18
|
+
export declare function saveConfig(config: RulesConfig, projectRoot?: string): void;
|
|
19
|
+
/**
|
|
20
|
+
* Detect if running in CI (non-interactive) mode
|
|
21
|
+
*/
|
|
22
|
+
export declare function isCiMode(): boolean;
|
|
23
|
+
export { RULESRC_FILENAME };
|
|
24
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,gBAAgB,kBAAkB,CAAC;AAEzC,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,MAAM,CAanE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAqBnE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAQ1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,OAAO,CAQlC;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RULESRC_FILENAME = void 0;
|
|
7
|
+
exports.findProjectRoot = findProjectRoot;
|
|
8
|
+
exports.loadConfig = loadConfig;
|
|
9
|
+
exports.saveConfig = saveConfig;
|
|
10
|
+
exports.isCiMode = isCiMode;
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const RULESRC_FILENAME = '.rulesrc.json';
|
|
14
|
+
exports.RULESRC_FILENAME = RULESRC_FILENAME;
|
|
15
|
+
/**
|
|
16
|
+
* Find project root (directory containing .rulesrc.json or package.json)
|
|
17
|
+
*/
|
|
18
|
+
function findProjectRoot(cwd = process.cwd()) {
|
|
19
|
+
let dir = path_1.default.resolve(cwd);
|
|
20
|
+
const root = path_1.default.parse(dir).root;
|
|
21
|
+
while (dir !== root) {
|
|
22
|
+
if (fs_1.default.existsSync(path_1.default.join(dir, RULESRC_FILENAME)) ||
|
|
23
|
+
fs_1.default.existsSync(path_1.default.join(dir, 'package.json'))) {
|
|
24
|
+
return dir;
|
|
25
|
+
}
|
|
26
|
+
dir = path_1.default.dirname(dir);
|
|
27
|
+
}
|
|
28
|
+
return cwd;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load .rulesrc.json from project root
|
|
32
|
+
*/
|
|
33
|
+
function loadConfig(projectRoot) {
|
|
34
|
+
const root = projectRoot ?? findProjectRoot();
|
|
35
|
+
const filePath = path_1.default.join(root, RULESRC_FILENAME);
|
|
36
|
+
if (!fs_1.default.existsSync(filePath))
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
40
|
+
const data = JSON.parse(raw);
|
|
41
|
+
if (!data ||
|
|
42
|
+
typeof data !== 'object' ||
|
|
43
|
+
!('target' in data) ||
|
|
44
|
+
!Array.isArray(data.agents))
|
|
45
|
+
return null;
|
|
46
|
+
return {
|
|
47
|
+
target: data.target,
|
|
48
|
+
agents: data.agents
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Save .rulesrc.json to project root
|
|
57
|
+
*/
|
|
58
|
+
function saveConfig(config, projectRoot) {
|
|
59
|
+
const root = projectRoot ?? findProjectRoot();
|
|
60
|
+
const filePath = path_1.default.join(root, RULESRC_FILENAME);
|
|
61
|
+
fs_1.default.writeFileSync(filePath, JSON.stringify({ target: config.target, agents: config.agents }, null, 2), 'utf8');
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Detect if running in CI (non-interactive) mode
|
|
65
|
+
*/
|
|
66
|
+
function isCiMode() {
|
|
67
|
+
return (process.env.CI === 'true' ||
|
|
68
|
+
process.env.CI === '1' ||
|
|
69
|
+
process.env.TF_BUILD === 'true' ||
|
|
70
|
+
process.env.GITHUB_ACTIONS === 'true' ||
|
|
71
|
+
process.env.GITLAB_CI === 'true');
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;;;;AAeA,0CAaC;AAKD,gCAqBC;AAKD,gCAQC;AAKD,4BAQC;AAhFD,4CAAoB;AACpB,gDAAwB;AAExB,MAAM,gBAAgB,GAAG,eAAe,CAAC;AA+EhC,4CAAgB;AAtEzB;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACzD,IAAI,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5B,MAAM,IAAI,GAAG,cAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAClC,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC;QACpB,IACE,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;YAC/C,YAAE,CAAC,UAAU,CAAC,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAC7C,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,WAAoB;IAC7C,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACnD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACxC,IACE,CAAC,IAAI;YACL,OAAO,IAAI,KAAK,QAAQ;YACxB,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC;YACnB,CAAC,KAAK,CAAC,OAAO,CAAE,IAAoB,CAAC,MAAM,CAAC;YAE5C,OAAO,IAAI,CAAC;QACd,OAAO;YACL,MAAM,EAAG,IAAoB,CAAC,MAAM;YACpC,MAAM,EAAG,IAAoB,CAAC,MAAM;SACrC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,MAAmB,EAAE,WAAoB;IAClE,MAAM,IAAI,GAAG,WAAW,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IACnD,YAAE,CAAC,aAAa,CACd,QAAQ,EACR,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EACzE,MAAM,CACP,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,QAAQ;IACtB,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,MAAM;QACzB,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,GAAG;QACtB,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;QAC/B,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM;QACrC,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,MAAM,CACjC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Target } from './config';
|
|
2
|
+
export interface ResolveTargetAndAgentsOptions {
|
|
3
|
+
projectRoot?: string;
|
|
4
|
+
target?: string;
|
|
5
|
+
agents?: string | string[];
|
|
6
|
+
yes?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Resolve target and agents from config + flags; in CI with no config, return null and caller should exit with error
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveTargetAndAgents(options?: ResolveTargetAndAgentsOptions): Promise<{
|
|
12
|
+
target: Target;
|
|
13
|
+
agents: string[];
|
|
14
|
+
} | null>;
|
|
15
|
+
export interface InstallOptions {
|
|
16
|
+
projectRoot: string;
|
|
17
|
+
target: Target;
|
|
18
|
+
agents: string[];
|
|
19
|
+
force?: boolean;
|
|
20
|
+
saveConfig?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface InstallResult {
|
|
23
|
+
installed: string[];
|
|
24
|
+
skipped: string[];
|
|
25
|
+
errors: Array<{
|
|
26
|
+
agent: string;
|
|
27
|
+
error: string;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Install agents for the given target into projectRoot. Single policy: do not overwrite unless force.
|
|
32
|
+
*/
|
|
33
|
+
export declare function install(options: InstallOptions): InstallResult;
|
|
34
|
+
export interface RunInstallOptions {
|
|
35
|
+
projectRoot?: string;
|
|
36
|
+
target?: string;
|
|
37
|
+
agents?: string[];
|
|
38
|
+
all?: boolean;
|
|
39
|
+
force?: boolean;
|
|
40
|
+
yes?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run install flow: resolve target/agents (interactive or from config/flags), then install.
|
|
44
|
+
* In CI mode with no .rulesrc.json, --target and (--agent X or --all) are required.
|
|
45
|
+
*/
|
|
46
|
+
export declare function runInstall(options?: RunInstallOptions): Promise<number>;
|
|
47
|
+
//# sourceMappingURL=install.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAkDvC,MAAM,WAAW,6BAA6B;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CA2BtD;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,aAAa,CA0C9D;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CA0DjB"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveTargetAndAgents = resolveTargetAndAgents;
|
|
7
|
+
exports.install = install;
|
|
8
|
+
exports.runInstall = runInstall;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const readline_1 = __importDefault(require("readline"));
|
|
11
|
+
const build_1 = require("./build");
|
|
12
|
+
const agents_1 = require("./agents");
|
|
13
|
+
const config_1 = require("./config");
|
|
14
|
+
function prompt(question) {
|
|
15
|
+
const rl = readline_1.default.createInterface({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout
|
|
18
|
+
});
|
|
19
|
+
return new Promise((resolve) => {
|
|
20
|
+
rl.question(question, (answer) => {
|
|
21
|
+
rl.close();
|
|
22
|
+
resolve((answer || '').trim());
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Interactive: ask for target (cursor | claude | opencode)
|
|
28
|
+
*/
|
|
29
|
+
async function promptTarget() {
|
|
30
|
+
const targets = (0, build_1.listTargets)();
|
|
31
|
+
const line = await prompt(`AI platform (${targets.join(', ')}): `);
|
|
32
|
+
const t = line.toLowerCase();
|
|
33
|
+
if (targets.includes(t))
|
|
34
|
+
return t;
|
|
35
|
+
console.error(`Invalid target. Choose one of: ${targets.join(', ')}`);
|
|
36
|
+
return promptTarget();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Interactive: ask for agents (comma-separated or "all")
|
|
40
|
+
*/
|
|
41
|
+
async function promptAgents() {
|
|
42
|
+
const agents = (0, agents_1.listAgents)();
|
|
43
|
+
const line = await prompt(`Agents (comma-separated or "all") [${agents.join(', ')}]: `);
|
|
44
|
+
if (!line)
|
|
45
|
+
return agents;
|
|
46
|
+
const list = line.toLowerCase() === 'all'
|
|
47
|
+
? ['all']
|
|
48
|
+
: line.split(',').map((s) => s.trim());
|
|
49
|
+
const resolved = (0, agents_1.resolveAgents)(list);
|
|
50
|
+
if (resolved.length === 0) {
|
|
51
|
+
console.error(`Invalid agents. Use "all" or comma-separated: ${agents.join(', ')}`);
|
|
52
|
+
return promptAgents();
|
|
53
|
+
}
|
|
54
|
+
return resolved;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve target and agents from config + flags; in CI with no config, return null and caller should exit with error
|
|
58
|
+
*/
|
|
59
|
+
async function resolveTargetAndAgents(options = {}) {
|
|
60
|
+
const projectRoot = options.projectRoot ?? (0, config_1.findProjectRoot)();
|
|
61
|
+
const config = (0, config_1.loadConfig)(projectRoot);
|
|
62
|
+
const ci = (0, config_1.isCiMode)() || options.yes;
|
|
63
|
+
const targetFromFlag = options.target;
|
|
64
|
+
const agentsFromFlag = options.agents;
|
|
65
|
+
if (config && !targetFromFlag && agentsFromFlag === undefined) {
|
|
66
|
+
return { target: config.target, agents: config.agents };
|
|
67
|
+
}
|
|
68
|
+
const target = targetFromFlag ?? config?.target;
|
|
69
|
+
const agents = agentsFromFlag != null ? (0, agents_1.resolveAgents)(agentsFromFlag) : config?.agents;
|
|
70
|
+
if (target && agents && agents.length > 0) {
|
|
71
|
+
return { target: target, agents };
|
|
72
|
+
}
|
|
73
|
+
if (ci) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const resolvedTarget = (target ?? (await promptTarget()));
|
|
77
|
+
const resolvedAgents = agents?.length ? agents : await promptAgents();
|
|
78
|
+
return { target: resolvedTarget, agents: resolvedAgents };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Install agents for the given target into projectRoot. Single policy: do not overwrite unless force.
|
|
82
|
+
*/
|
|
83
|
+
function install(options) {
|
|
84
|
+
const { projectRoot, target, agents, force = false, saveConfig: persist } = options;
|
|
85
|
+
const installed = [];
|
|
86
|
+
const skipped = [];
|
|
87
|
+
const errors = [];
|
|
88
|
+
if (persist) {
|
|
89
|
+
(0, config_1.saveConfig)({ target, agents }, projectRoot);
|
|
90
|
+
}
|
|
91
|
+
for (const agentId of agents) {
|
|
92
|
+
if (!(0, agents_1.isValidAgent)(agentId)) {
|
|
93
|
+
errors.push({ agent: agentId, error: 'Unknown agent' });
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const { dir, file } = (0, build_1.getDestination)(agentId, target, projectRoot);
|
|
98
|
+
if (fs_1.default.existsSync(file) && !force) {
|
|
99
|
+
skipped.push(agentId);
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (!fs_1.default.existsSync(dir)) {
|
|
103
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
const content = (0, build_1.buildContent)(agentId, target);
|
|
106
|
+
fs_1.default.writeFileSync(file, content, 'utf8');
|
|
107
|
+
installed.push(agentId);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
errors.push({
|
|
111
|
+
agent: agentId,
|
|
112
|
+
error: err instanceof Error ? err.message : String(err)
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return { installed, skipped, errors };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Run install flow: resolve target/agents (interactive or from config/flags), then install.
|
|
120
|
+
* In CI mode with no .rulesrc.json, --target and (--agent X or --all) are required.
|
|
121
|
+
*/
|
|
122
|
+
async function runInstall(options = {}) {
|
|
123
|
+
const projectRoot = options.projectRoot ?? (0, config_1.findProjectRoot)();
|
|
124
|
+
const agentsFromFlag = options.all ? 'all' : options.agents;
|
|
125
|
+
const resolved = await resolveTargetAndAgents({
|
|
126
|
+
projectRoot,
|
|
127
|
+
target: options.target,
|
|
128
|
+
agents: agentsFromFlag,
|
|
129
|
+
yes: options.yes
|
|
130
|
+
});
|
|
131
|
+
if (!resolved) {
|
|
132
|
+
console.error('In CI/non-interactive mode (--yes or CI env), --target and --agent (or --all) are required when .rulesrc.json is missing.');
|
|
133
|
+
console.error('Example: ballast install --yes --target cursor --agent linting');
|
|
134
|
+
return 1;
|
|
135
|
+
}
|
|
136
|
+
const { target, agents } = resolved;
|
|
137
|
+
const persist = !options.target && !options.agents && !options.all;
|
|
138
|
+
const result = install({
|
|
139
|
+
projectRoot,
|
|
140
|
+
target,
|
|
141
|
+
agents,
|
|
142
|
+
force: options.force ?? false,
|
|
143
|
+
saveConfig: persist
|
|
144
|
+
});
|
|
145
|
+
if (result.errors.length > 0) {
|
|
146
|
+
result.errors.forEach(({ agent, error }) => {
|
|
147
|
+
console.error(`Error installing ${agent}: ${error}`);
|
|
148
|
+
});
|
|
149
|
+
return 1;
|
|
150
|
+
}
|
|
151
|
+
if (result.installed.length > 0) {
|
|
152
|
+
console.log(`Installed for ${target}: ${result.installed.join(', ')}`);
|
|
153
|
+
result.installed.forEach((agentId) => {
|
|
154
|
+
const { file } = (0, build_1.getDestination)(agentId, target, projectRoot);
|
|
155
|
+
console.log(` ${agentId} -> ${file}`);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
if (result.skipped.length > 0) {
|
|
159
|
+
console.log(`Skipped (already present; use --force to overwrite): ${result.skipped.join(', ')}`);
|
|
160
|
+
}
|
|
161
|
+
if (result.installed.length === 0 &&
|
|
162
|
+
result.skipped.length === 0 &&
|
|
163
|
+
result.errors.length === 0) {
|
|
164
|
+
console.log('Nothing to install.');
|
|
165
|
+
}
|
|
166
|
+
return 0;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@everydaydevopsio/ballast",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "CLI to install TypeScript AI agent rules (linting, local-dev, CI/CD, observability) for Cursor, Claude Code, and OpenCode",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ballast": "./bin/ballast.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist",
|
|
12
|
+
"agents"
|
|
13
|
+
],
|
|
14
|
+
"author": "Mark C Allen <mark@markcallen.com>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/everydaydevopsio/typescript-linting-agent.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/everydaydevopsio/typescript-linting-agent#readme",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/everydaydevopsio/typescript-linting-agent/issues"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@eslint/js": "^9.39.2",
|
|
26
|
+
"@types/jest": "^29.5.14",
|
|
27
|
+
"@types/node": "^22.10.1",
|
|
28
|
+
"@typescript-eslint/eslint-plugin": "^8.50.1",
|
|
29
|
+
"@typescript-eslint/parser": "^8.50.1",
|
|
30
|
+
"eslint": "^9.39.2",
|
|
31
|
+
"eslint-config-prettier": "^10.1.8",
|
|
32
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
33
|
+
"globals": "^16.5.0",
|
|
34
|
+
"husky": "^9.1.7",
|
|
35
|
+
"jest": "^29.7.0",
|
|
36
|
+
"lint-staged": "^16.2.7",
|
|
37
|
+
"prettier": "^3.7.4",
|
|
38
|
+
"ts-jest": "^29.2.5",
|
|
39
|
+
"tsc-files": "^1.1.4",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"typescript-eslint": "^8.53.1"
|
|
42
|
+
},
|
|
43
|
+
"lint-staged": {
|
|
44
|
+
"**/*.js": [
|
|
45
|
+
"prettier --write",
|
|
46
|
+
"eslint --fix"
|
|
47
|
+
],
|
|
48
|
+
"**/*.ts": [
|
|
49
|
+
"tsc-files --noEmit",
|
|
50
|
+
"prettier --write",
|
|
51
|
+
"eslint --fix"
|
|
52
|
+
],
|
|
53
|
+
"**/*.{json,md,yaml,yml}": [
|
|
54
|
+
"prettier --write"
|
|
55
|
+
]
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc",
|
|
59
|
+
"test": "jest",
|
|
60
|
+
"test:coverage": "jest --coverage",
|
|
61
|
+
"lint": "eslint .",
|
|
62
|
+
"lint:fix": "eslint . --fix",
|
|
63
|
+
"prettier": "prettier . --check",
|
|
64
|
+
"prettier:fix": "prettier . --write"
|
|
65
|
+
}
|
|
66
|
+
}
|