@hugo.bastidas/agent-foundation 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,53 @@
1
+ # agent-foundation
2
+
3
+ CLI que instala convenciones personales de trabajo para agentes de IA
4
+ (`AGENT_FOUNDATION.md`) en las instrucciones globales de Claude Code, Codex y
5
+ OpenCode. Una sola fuente de verdad para convenciones de código, commits,
6
+ estructura de proyectos y documentación — aplicada de forma idempotente en
7
+ todos los hosts.
8
+
9
+ ## Uso
10
+
11
+ ```bash
12
+ # instalar en todos los hosts
13
+ npx -y @hugo.bastidas/agent-foundation install
14
+
15
+ # instalar solo en hosts específicos
16
+ npx -y @hugo.bastidas/agent-foundation install --host claude,codex
17
+
18
+ # ver estado
19
+ npx -y @hugo.bastidas/agent-foundation status
20
+
21
+ # desinstalar
22
+ npx -y @hugo.bastidas/agent-foundation remove
23
+ ```
24
+
25
+ ## Qué hace
26
+
27
+ Por cada host seleccionado:
28
+
29
+ 1. Escribe `AGENT_FOUNDATION.md` (las convenciones) junto al archivo de
30
+ instrucciones globales del host.
31
+ 2. Inyecta un bloque gestionado con una `@referencia` al inicio de las
32
+ instrucciones globales, preservando el contenido existente.
33
+
34
+ | Host | Instrucciones globales |
35
+ |---|---|
36
+ | Claude Code | `~/.claude/CLAUDE.md` |
37
+ | Codex | `~/.codex/AGENTS.md` |
38
+ | OpenCode | `~/.config/opencode/AGENTS.md` |
39
+
40
+ La operación es idempotente: re-ejecutar `install` actualiza el bloque sin
41
+ duplicarlo. `remove` elimina el bloque y el sidecar dejando intacto el resto
42
+ del archivo.
43
+
44
+ ## Desarrollo
45
+
46
+ ```bash
47
+ npm install
48
+ npm run build
49
+ npm test
50
+ ```
51
+
52
+ Las convenciones viven en `AGENT_FOUNDATION_INSTRUCTIONS` en
53
+ `src/foundation.ts` — edita ahí y re-ejecuta `install` para propagar.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from 'node:fs';
3
+ import { writeAgentFoundation, removeAgentFoundation, agentFoundationPath } from './foundation.js';
4
+ import { HOSTS, ALL_HOSTS, parseHosts } from './hosts.js';
5
+ const USAGE = `agent-foundation — install personal agent conventions across AI coding hosts
6
+
7
+ Usage:
8
+ agent-foundation install [--host <claude|codex|opencode|all>]
9
+ agent-foundation remove [--host <claude|codex|opencode|all>]
10
+ agent-foundation status
11
+ agent-foundation --help
12
+
13
+ Writes AGENT_FOUNDATION.md next to each host's global instructions file and
14
+ injects a managed @reference block. "remove" deletes both. Default host: all.
15
+ Hosts accept a comma-separated list (e.g. --host claude,codex).`;
16
+ function getHostFlag(args) {
17
+ const index = args.indexOf('--host');
18
+ if (index === -1)
19
+ return undefined;
20
+ const value = args[index + 1];
21
+ if (!value || value.startsWith('--'))
22
+ throw new Error('--host requires a value');
23
+ return value;
24
+ }
25
+ async function install(hosts) {
26
+ for (const host of hosts) {
27
+ await writeAgentFoundation(HOSTS[host].instructions);
28
+ console.log(`Installed Agent Foundation reference in ${HOSTS[host].instructions}`);
29
+ }
30
+ }
31
+ async function remove(hosts) {
32
+ for (const host of hosts) {
33
+ await removeAgentFoundation(HOSTS[host].instructions);
34
+ console.log(`Removed Agent Foundation reference from ${HOSTS[host].instructions}`);
35
+ }
36
+ }
37
+ function status() {
38
+ console.table(ALL_HOSTS.map((host) => ({
39
+ Host: HOSTS[host].label,
40
+ Instructions: existsSync(HOSTS[host].instructions) ? 'yes' : 'no',
41
+ Foundation: existsSync(agentFoundationPath(HOSTS[host].instructions)) ? 'installed' : 'missing',
42
+ })));
43
+ }
44
+ async function main() {
45
+ const [command, ...args] = process.argv.slice(2);
46
+ if (!command || command === '--help' || command === '-h' || command === 'help') {
47
+ console.log(USAGE);
48
+ return;
49
+ }
50
+ switch (command) {
51
+ case 'install':
52
+ await install(parseHosts(getHostFlag(args)));
53
+ break;
54
+ case 'remove':
55
+ await remove(parseHosts(getHostFlag(args)));
56
+ break;
57
+ case 'status':
58
+ status();
59
+ break;
60
+ default:
61
+ console.error(`Unknown command: ${command}\n`);
62
+ console.log(USAGE);
63
+ process.exit(1);
64
+ }
65
+ }
66
+ main().catch((err) => {
67
+ console.error(err instanceof Error ? err.message : err);
68
+ process.exit(1);
69
+ });
70
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const AGENT_FOUNDATION_START = "<!-- >>> agent-foundation >>> -->";
2
+ export declare const AGENT_FOUNDATION_END = "<!-- <<< agent-foundation <<< -->";
3
+ export declare const AGENT_FOUNDATION_FILE = "AGENT_FOUNDATION.md";
4
+ export declare const AGENT_FOUNDATION_INSTRUCTIONS: string;
5
+ export declare function agentFoundationPath(globalInstructionsPath: string): string;
6
+ export declare function writeAgentFoundation(filePath: string): Promise<void>;
7
+ export declare function removeAgentFoundation(filePath: string): Promise<void>;
8
+ //# sourceMappingURL=foundation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.d.ts","sourceRoot":"","sources":["../src/foundation.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,sBAAsB,sCAAsC,CAAC;AAC1E,eAAO,MAAM,oBAAoB,sCAAsC,CAAC;AACxE,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D,eAAO,MAAM,6BAA6B,QA2J9B,CAAC;AA8Cb,wBAAgB,mBAAmB,CAAC,sBAAsB,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW1E;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS3E"}
@@ -0,0 +1,227 @@
1
+ import { readFile, writeFile, mkdir, rm } from 'node:fs/promises';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ export const AGENT_FOUNDATION_START = '<!-- >>> agent-foundation >>> -->';
4
+ export const AGENT_FOUNDATION_END = '<!-- <<< agent-foundation <<< -->';
5
+ export const AGENT_FOUNDATION_FILE = 'AGENT_FOUNDATION.md';
6
+ export const AGENT_FOUNDATION_INSTRUCTIONS = [
7
+ '## Agent Foundation',
8
+ '',
9
+ '### Code conventions',
10
+ '',
11
+ '| Element | Language |',
12
+ '|---|---|',
13
+ '| Variables, functions, constants | English |',
14
+ '| Classes and types | English |',
15
+ '| File names | English |',
16
+ '| Inline/block comments | Spanish |',
17
+ '| User-facing UI text | Spanish unless the project targets a specific locale |',
18
+ '',
19
+ 'These conventions apply across TypeScript, JavaScript, Python, Astro, CSS, and other stacks.',
20
+ '',
21
+ '### Code quality and security',
22
+ '',
23
+ '- Write optimal code: avoid redundant logic, unnecessary loops, avoidable re-renders, N+1 queries, and preventable inefficiencies.',
24
+ '- Write secure code: prevent OWASP Top 10 issues, never hardcode secrets, and validate inputs at system boundaries.',
25
+ '- Boundary input validation and secret/security controls are required even when the user did not explicitly request them.',
26
+ '- Prefer simple, direct solutions over premature abstractions.',
27
+ '- Do not add error handling, validations, or features that were not explicitly requested unless they are necessary for boundary security, data integrity, or safe failure of the requested behavior.',
28
+ '',
29
+ '### Documentation lookups',
30
+ '',
31
+ '- When current library, framework, SDK, API, CLI, or cloud-service documentation is needed, use the available Context7 MCP/tooling first.',
32
+ '- If Context7 is unavailable or does not cover the requested technology, use the best available official documentation source.',
33
+ '- Do not rely on memory alone for version-sensitive syntax, setup, migration, or API behavior.',
34
+ '',
35
+ '### Required project structure',
36
+ '',
37
+ 'Every new or existing project should have:',
38
+ '',
39
+ '1. `.env` — real environment variables, never committed.',
40
+ '2. `.env.example` — same keys without sensitive values, committed.',
41
+ '3. `.gitignore` — adjusted to the project stack.',
42
+ '4. Lock file — commit it (`package-lock.json`, `uv.lock`, `go.sum`, etc.). Never add lock files to `.gitignore`.',
43
+ '',
44
+ 'The `.gitignore` should include at minimum:',
45
+ '',
46
+ '- Node/JS/TS: `node_modules/`, `dist/`, `.env`, `.env.local`, `*.log`',
47
+ '- Python: `__pycache__/`, `*.pyc`, `.venv/`, `.env`, `dist/`, `*.egg-info/`',
48
+ '- Astro: Node entries plus `.astro/`',
49
+ '- General: `.DS_Store`, `Thumbs.db`, `.idea/`, `.vscode/` unless team settings are intentionally shared.',
50
+ '- AI tool artifacts: `.minimax/runs/`, `.minimax/cli-tests/`, `.minimax/multimodal-tests/`',
51
+ '',
52
+ 'If these files are missing, tell the user and offer to create them.',
53
+ '',
54
+ '### Node.js workflow',
55
+ '',
56
+ 'Use `npm` by default. Do not switch to yarn, pnpm, or bun unless the project already uses one of them (check for `yarn.lock`, `pnpm-lock.yaml`, or `bun.lockb`). Commit `package-lock.json` — never gitignore it.',
57
+ '',
58
+ 'Do not install a package to do something the runtime or an already-present dependency already handles.',
59
+ '',
60
+ '### Python workflow',
61
+ '',
62
+ 'Always use `uv` for Python projects. Use `pyproject.toml` plus `uv.lock` as the default dependency contract, create/update dependencies with `uv add` or `uv remove`, install reproducibly with `uv sync --locked` (or `uv sync --frozen` when the project already standardizes on that flag), and run tools through `uv run` (for example `uv run pytest`, `uv run ruff check .`, `uv run mypy src`, or `uv run python -m package`). Do not introduce raw `pip`, manual `venv` setup, Poetry, Pipenv, or requirements-only workflows unless the user explicitly asks for compatibility with an existing project that already depends on them.',
63
+ '',
64
+ '### Testing',
65
+ '',
66
+ 'Write tests only when explicitly requested or when the project already has a test suite and new code clearly belongs in it. Do not create a test suite from scratch unless asked.',
67
+ '',
68
+ 'When writing tests:',
69
+ '- Test observable behavior, not implementation details.',
70
+ '- Follow the naming and placement convention already used in the project (e.g., `foo.test.ts` next to source, or a `/tests` directory at the project root).',
71
+ '- Prefer integration-level assertions over mocking internals.',
72
+ '',
73
+ '### Git repository initialization',
74
+ '',
75
+ 'When starting or scaffolding any new project:',
76
+ '',
77
+ '1. Verify the directory is a git repository (`git status`). If not, run `git init` immediately before creating any project files.',
78
+ '2. Verify `.gitignore` exists and covers the project stack (see above). Create or update it before making any commit.',
79
+ '3. Make the initial commit only after `.gitignore`, `.env.example`, and the main documentation file (`AGENTS.md` or `README.md`) are in place.',
80
+ '',
81
+ 'If any of these are missing when starting work on a new project, tell the user and offer to create them.',
82
+ '',
83
+ '### Git commit conventions',
84
+ '',
85
+ 'When making commits in any project:',
86
+ '',
87
+ '- Use the Conventional Commits format: `type(scope): short description`',
88
+ '- Write commit title and body bullets in Spanish.',
89
+ '- Allowed types: `feat`, `fix`, `refactor`, `style`, `chore`, `docs`, `test`, `perf`, `ci`, `build`',
90
+ '- Keep the title concise (under 72 characters), lowercase, no trailing period.',
91
+ '- Add a body with bullet points when 3+ files change or changes clearly span different areas.',
92
+ '- Never include secrets, tokens, keys, or env variable values in commit messages.',
93
+ '- Always show the proposed message to the user and ask for confirmation before running `git commit`.',
94
+ '- After committing, ask the user whether to also run `git push`.',
95
+ '',
96
+ 'Examples:',
97
+ '',
98
+ '```',
99
+ 'fix(auth): corregir validación de token expirado',
100
+ '```',
101
+ '',
102
+ '```',
103
+ 'feat(install): agregar componente de alias de shell y selección de hosts',
104
+ '',
105
+ '- agregar shell-alias.ts para generar alias mmx en bash/zsh',
106
+ '- ampliar el instalador con selección múltiple de hosts Claude',
107
+ '- expandir estadísticas de uso con desglose por herramienta',
108
+ '```',
109
+ '',
110
+ '### Required project documentation',
111
+ '',
112
+ 'All local project documentation files (AGENTS.md, README.md, ARCHITECTURE.md, DESIGN.md) must be written in Spanish. Global sidecars (AGENT_FOUNDATION.md and any other host-level references you have installed) remain in English.',
113
+ '',
114
+ 'Every new project must include these files at the repository root:',
115
+ '',
116
+ '1. `CLAUDE.md` — keep it free of project content; it only points the agent to `AGENTS.md`. Use a single line such as: "Always read and follow `AGENTS.md` for all project context and instructions."',
117
+ '2. `AGENTS.md` — the canonical project brief. It holds the most relevant information: project purpose, stack, run/build/test commands, project-specific constraints, and agent guidance. This is where the real instructions live.',
118
+ '3. `ARCHITECTURE.md` — a short, high-level map of the system (see below). Create it once the project has more than a couple of modules.',
119
+ '4. `DESIGN.md` — the design-system contract for the UI (see below). **Frontend projects only.**',
120
+ '',
121
+ 'A project-local `AGENTS.md` must contain ONLY what is unique to that project. Never copy, paraphrase, or summarize sections already provided by global sidecars (`AGENT_FOUNDATION.md` or any other host-level references you have installed).',
122
+ '',
123
+ '**Never include in a local AGENTS.md:**',
124
+ '- Code conventions (variables, comments, file names, UI text language)',
125
+ '- Code quality or security rules',
126
+ '- Documentation lookup instructions (Context7, etc.)',
127
+ '- Required project structure (.env, .gitignore, lock file rules)',
128
+ '- Node.js or Python workflow rules',
129
+ '- Git repository initialization steps',
130
+ '- Git commit conventions or examples',
131
+ '- Any tool-specific routing or delegation policy (belongs in that tool\'s own sidecar)',
132
+ '- Any section that would be identical or near-identical across projects',
133
+ '',
134
+ '**A correct local AGENTS.md contains only:**',
135
+ '- What this project does (1–3 sentences)',
136
+ '- Stack and key dependencies',
137
+ '- How to build, test, and run the project',
138
+ '- Project-specific constraints or domain rules not covered globally',
139
+ '',
140
+ 'When in doubt, omit the section. The global sidecars are always active — repeating them wastes tokens and creates drift when the global rule changes.',
141
+ '',
142
+ '#### ARCHITECTURE.md (keep it to ~1 page; point to code, do not duplicate it)',
143
+ '',
144
+ '- Overview: a few sentences on what the system does and its bird\'s-eye shape.',
145
+ '- Codemap: name the important modules, files, and types and what each is responsible for. Refer to them by name so symbol search can find them; avoid links that go stale.',
146
+ '- Invariants: rules that must always hold, especially "absence" rules (e.g. the model layer never imports the view layer).',
147
+ '- Boundaries: the seams between layers/systems and what each side may assume about the other.',
148
+ '- Cross-cutting concerns: logging, auth, error handling, configuration — anything that spans modules.',
149
+ '- Update it when the coarse structure changes, not on every edit.',
150
+ '',
151
+ '#### DESIGN.md (frontend only)',
152
+ '',
153
+ 'A machine- and human-readable design-system spec so the UI stays consistent (format: github.com/google-labs-code/design.md):',
154
+ '',
155
+ '- YAML front matter with design tokens: colors (hex), typography (family, size, weight, line height), spacing scale, radius scale, and components that reference those tokens.',
156
+ '- Markdown body with the rationale: design philosophy and how/when to apply each token.',
157
+ '- Recommended sections, in order: Overview, Colors, Typography, Layout, Elevation & Depth, Shapes, Components, Do\'s and Don\'ts.',
158
+ '- Treat it as the source of truth for styling; generate framework tokens (e.g. Tailwind) from it instead of hardcoding values.',
159
+ '',
160
+ 'If any required documentation file is missing when starting or scaffolding a project, tell the user and offer to create it.',
161
+ ].join('\n');
162
+ const LEGACY_CLAUDE_SECTION_PATTERNS = [
163
+ /## Ruta del usuario\n[\s\S]*?(?=\n## Convenciones de código|\n## Calidad y seguridad del código|\n## Estructura obligatoria de proyectos|\n@RTK\.md|\n<!-- >>> minimax-plugin >>>|$)/g,
164
+ /## Convenciones de código \(aplican a todos los proyectos\)\n[\s\S]*?(?=\n## Calidad y seguridad del código|\n## Estructura obligatoria de proyectos|\n@RTK\.md|\n<!-- >>> minimax-plugin >>>|$)/g,
165
+ /## Calidad y seguridad del código\n[\s\S]*?(?=\n## Estructura obligatoria de proyectos|\n@RTK\.md|\n<!-- >>> minimax-plugin >>>|$)/g,
166
+ /## Estructura obligatoria de proyectos\n[\s\S]*?(?=\n@RTK\.md|\n<!-- >>> minimax-plugin >>>|$)/g,
167
+ ];
168
+ function escapeRegExp(str) {
169
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
170
+ }
171
+ // Normalizar CRLF a LF para que los regex funcionen igual en Windows/Mac/Linux.
172
+ function normalizeLf(content) {
173
+ return content.replace(/\r\n/g, '\n');
174
+ }
175
+ function stripManagedAgentFoundation(content) {
176
+ return normalizeLf(content)
177
+ .replace(new RegExp(`${escapeRegExp(AGENT_FOUNDATION_START)}[\\s\\S]*?${escapeRegExp(AGENT_FOUNDATION_END)}`, 'g'), '')
178
+ .trim();
179
+ }
180
+ function stripLegacyClaudeSections(content) {
181
+ return LEGACY_CLAUDE_SECTION_PATTERNS.reduce((current, pattern) => current.replace(pattern, ''), normalizeLf(content))
182
+ .replace(/\n{3,}/g, '\n\n')
183
+ .trim();
184
+ }
185
+ function instructionReference(filePath) {
186
+ // Normalizar a forward slashes para que el @ reference funcione igual en Windows/Mac/Linux.
187
+ return `@${resolve(filePath).replace(/\\/g, '/')}`;
188
+ }
189
+ function managedReferenceBlock(targetPath) {
190
+ return [
191
+ AGENT_FOUNDATION_START,
192
+ instructionReference(targetPath),
193
+ AGENT_FOUNDATION_END,
194
+ ].join('\n');
195
+ }
196
+ export function agentFoundationPath(globalInstructionsPath) {
197
+ return join(dirname(globalInstructionsPath), AGENT_FOUNDATION_FILE);
198
+ }
199
+ export async function writeAgentFoundation(filePath) {
200
+ const targetPath = agentFoundationPath(filePath);
201
+ let existing = '';
202
+ try {
203
+ existing = await readFile(filePath, 'utf8');
204
+ }
205
+ catch { /* new file */ }
206
+ const stripped = stripLegacyClaudeSections(stripManagedAgentFoundation(existing));
207
+ const block = managedReferenceBlock(targetPath);
208
+ const updated = stripped ? `${block}\n\n${stripped}\n` : `${block}\n`;
209
+ await mkdir(dirname(filePath), { recursive: true });
210
+ await mkdir(dirname(targetPath), { recursive: true });
211
+ await writeFile(targetPath, `${AGENT_FOUNDATION_INSTRUCTIONS}\n`, 'utf8');
212
+ await writeFile(filePath, updated, 'utf8');
213
+ }
214
+ export async function removeAgentFoundation(filePath) {
215
+ let existing = '';
216
+ try {
217
+ existing = await readFile(filePath, 'utf8');
218
+ }
219
+ catch {
220
+ await rm(agentFoundationPath(filePath), { force: true });
221
+ return;
222
+ }
223
+ const stripped = stripManagedAgentFoundation(existing);
224
+ await writeFile(filePath, stripped ? `${stripped}\n` : '', 'utf8');
225
+ await rm(agentFoundationPath(filePath), { force: true });
226
+ }
227
+ //# sourceMappingURL=foundation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"foundation.js","sourceRoot":"","sources":["../src/foundation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type HostId = 'claude' | 'codex' | 'opencode';
2
+ export interface HostInfo {
3
+ label: string;
4
+ instructions: string;
5
+ }
6
+ export declare const HOSTS: Record<HostId, HostInfo>;
7
+ export declare const ALL_HOSTS: HostId[];
8
+ export declare function parseHosts(value: string | undefined): HostId[];
9
+ //# sourceMappingURL=hosts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.d.ts","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAErD,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IAEd,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAI1C,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,MAAM,EAAoC,CAAC;AAEnE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAQ9D"}
package/dist/hosts.js ADDED
@@ -0,0 +1,19 @@
1
+ import { homedir } from 'node:os';
2
+ import { join } from 'node:path';
3
+ export const HOSTS = {
4
+ claude: { label: 'Claude Code', instructions: join(homedir(), '.claude', 'CLAUDE.md') },
5
+ codex: { label: 'Codex', instructions: join(homedir(), '.codex', 'AGENTS.md') },
6
+ opencode: { label: 'OpenCode', instructions: join(homedir(), '.config', 'opencode', 'AGENTS.md') },
7
+ };
8
+ export const ALL_HOSTS = ['claude', 'codex', 'opencode'];
9
+ export function parseHosts(value) {
10
+ if (!value || value === 'all')
11
+ return ALL_HOSTS;
12
+ const requested = value.split(',').map((host) => host.trim().toLowerCase());
13
+ const invalid = requested.filter((host) => !(host in HOSTS));
14
+ if (invalid.length) {
15
+ throw new Error(`Unknown host(s): ${invalid.join(', ')}. Valid hosts: ${ALL_HOSTS.join(', ')}, all`);
16
+ }
17
+ return [...new Set(requested)];
18
+ }
19
+ //# sourceMappingURL=hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosts.js","sourceRoot":"","sources":["../src/hosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAUjC,MAAM,CAAC,MAAM,KAAK,GAA6B;IAC7C,MAAM,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE;IACvF,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,EAAE;IAC/E,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE;CACnG,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;AAEnE,MAAM,UAAU,UAAU,CAAC,KAAyB;IAClD,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvG,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAa,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { writeAgentFoundation, removeAgentFoundation, agentFoundationPath, AGENT_FOUNDATION_FILE, AGENT_FOUNDATION_START, AGENT_FOUNDATION_END, AGENT_FOUNDATION_INSTRUCTIONS, } from './foundation.js';
2
+ export { HOSTS, ALL_HOSTS, parseHosts } from './hosts.js';
3
+ export type { HostId, HostInfo } from './hosts.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { writeAgentFoundation, removeAgentFoundation, agentFoundationPath, AGENT_FOUNDATION_FILE, AGENT_FOUNDATION_START, AGENT_FOUNDATION_END, AGENT_FOUNDATION_INSTRUCTIONS, } from './foundation.js';
2
+ export { HOSTS, ALL_HOSTS, parseHosts } from './hosts.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@hugo.bastidas/agent-foundation",
3
+ "version": "0.1.0",
4
+ "description": "CLI to install personal agent conventions (AGENT_FOUNDATION.md) into Claude Code, Codex, and OpenCode global instructions",
5
+ "type": "module",
6
+ "bin": {
7
+ "agent-foundation": "./dist/cli.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest",
15
+ "typecheck": "tsc --noEmit",
16
+ "prepublishOnly": "npm run build && npm test"
17
+ },
18
+ "keywords": [
19
+ "agent",
20
+ "claude-code",
21
+ "codex",
22
+ "opencode",
23
+ "conventions",
24
+ "dotfiles"
25
+ ],
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://gitlab.com/tools5290918/agent-foundations.git"
29
+ },
30
+ "homepage": "https://gitlab.com/tools5290918/agent-foundations",
31
+ "bugs": "https://gitlab.com/tools5290918/agent-foundations/-/issues",
32
+ "license": "MIT",
33
+ "devDependencies": {
34
+ "@types/node": "^20.14.0",
35
+ "typescript": "^5.5.0",
36
+ "vitest": "^2.0.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=20.0.0"
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public"
47
+ }
48
+ }