aios-lite 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/CHANGELOG.md +17 -0
- package/CODE_OF_CONDUCT.md +12 -0
- package/CONTRIBUTING.md +13 -0
- package/LICENSE +21 -0
- package/README.md +47 -0
- package/bin/aios-lite.js +4 -0
- package/docs/en/i18n.md +23 -0
- package/docs/en/release-flow.md +23 -0
- package/docs/en/release-notes-template.md +41 -0
- package/docs/en/release.md +32 -0
- package/package.json +42 -0
- package/src/cli.js +74 -0
- package/src/commands/doctor.js +29 -0
- package/src/commands/i18n-add.js +53 -0
- package/src/commands/info.js +33 -0
- package/src/commands/init.js +54 -0
- package/src/commands/install.js +38 -0
- package/src/commands/update.js +30 -0
- package/src/constants.js +50 -0
- package/src/detector.js +136 -0
- package/src/doctor.js +55 -0
- package/src/i18n/index.js +96 -0
- package/src/i18n/messages/en.js +74 -0
- package/src/i18n/scaffold.js +64 -0
- package/src/installer.js +152 -0
- package/src/parser.js +52 -0
- package/src/updater.js +32 -0
- package/src/utils.js +46 -0
- package/template/.aios-lite/agents/analyst.md +25 -0
- package/template/.aios-lite/agents/architect.md +21 -0
- package/template/.aios-lite/agents/dev.md +17 -0
- package/template/.aios-lite/agents/orchestrator.md +14 -0
- package/template/.aios-lite/agents/pm.md +18 -0
- package/template/.aios-lite/agents/qa.md +19 -0
- package/template/.aios-lite/agents/setup.md +50 -0
- package/template/.aios-lite/config.md +32 -0
- package/template/.aios-lite/context/.gitkeep +0 -0
- package/template/.aios-lite/context/parallel/.gitkeep +0 -0
- package/template/.aios-lite/mcp/servers.md +10 -0
- package/template/.aios-lite/skills/dynamic/flux-ui-docs.md +3 -0
- package/template/.aios-lite/skills/dynamic/laravel-docs.md +3 -0
- package/template/.aios-lite/skills/dynamic/npm-packages.md +3 -0
- package/template/.aios-lite/skills/static/filament-patterns.md +5 -0
- package/template/.aios-lite/skills/static/flux-ui-components.md +5 -0
- package/template/.aios-lite/skills/static/git-conventions.md +6 -0
- package/template/.aios-lite/skills/static/jetstream-setup.md +5 -0
- package/template/.aios-lite/skills/static/laravel-conventions.md +7 -0
- package/template/.aios-lite/skills/static/nextjs-patterns.md +6 -0
- package/template/.aios-lite/skills/static/node-express-patterns.md +6 -0
- package/template/.aios-lite/skills/static/rails-conventions.md +6 -0
- package/template/.aios-lite/skills/static/tall-stack-patterns.md +6 -0
- package/template/.aios-lite/skills/static/ui-ux-modern.md +6 -0
- package/template/.gemini/GEMINI.md +9 -0
- package/template/.gemini/commands/aios-analyst.toml +4 -0
- package/template/.gemini/commands/aios-architect.toml +7 -0
- package/template/.gemini/commands/aios-dev.toml +8 -0
- package/template/.gemini/commands/aios-orchestrator.toml +8 -0
- package/template/.gemini/commands/aios-pm.toml +8 -0
- package/template/.gemini/commands/aios-qa.toml +6 -0
- package/template/.gemini/commands/aios-setup.toml +3 -0
- package/template/AGENTS.md +17 -0
- package/template/CLAUDE.md +21 -0
- package/template/OPENCODE.md +18 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [0.1.0] - 2026-03-01
|
|
6
|
+
### Added
|
|
7
|
+
- Initial CLI commands: init, install, update, info, doctor
|
|
8
|
+
- Multi-IDE template gateways (Claude, Codex, Gemini, OpenCode)
|
|
9
|
+
- Framework detector and installer/updater core
|
|
10
|
+
- i18n message system with English default
|
|
11
|
+
- Automated tests for detector, installer, doctor, i18n
|
|
12
|
+
- `i18n:add <locale>` command to scaffold new locale dictionaries
|
|
13
|
+
- GitHub Actions CI and tag-based npm release workflows
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Project-facing content standardized to English
|
|
17
|
+
- CLI i18n upgraded with dynamic locale loading and fallback behavior
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
Be respectful, inclusive, and constructive.
|
|
4
|
+
|
|
5
|
+
## Expected behavior
|
|
6
|
+
- Use welcoming and professional language.
|
|
7
|
+
- Focus on technical feedback and collaborative problem solving.
|
|
8
|
+
- Assume good intent.
|
|
9
|
+
|
|
10
|
+
## Unacceptable behavior
|
|
11
|
+
- Harassment, insults, discrimination, or intimidation.
|
|
12
|
+
- Personal attacks or hostile communication.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Development
|
|
4
|
+
1. Fork the repository.
|
|
5
|
+
2. Create a branch from main.
|
|
6
|
+
3. Run tests: `npm test`.
|
|
7
|
+
4. Run lint checks: `npm run lint`.
|
|
8
|
+
5. Open a pull request with a clear description.
|
|
9
|
+
|
|
10
|
+
## Commit style
|
|
11
|
+
Use Conventional Commits, for example:
|
|
12
|
+
- `feat(cli): add doctor command output hints`
|
|
13
|
+
- `fix(detector): avoid false positives for Node projects`
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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,47 @@
|
|
|
1
|
+
# AIOS Lite
|
|
2
|
+
|
|
3
|
+
Lightweight AI agent framework for software projects.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx aios-lite init my-project
|
|
9
|
+
# or
|
|
10
|
+
npx aios-lite install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
- `aios-lite init <project-name>`
|
|
15
|
+
- `aios-lite install [path]`
|
|
16
|
+
- `aios-lite update [path]`
|
|
17
|
+
- `aios-lite info [path]`
|
|
18
|
+
- `aios-lite doctor [path]`
|
|
19
|
+
- `aios-lite i18n:add <locale>`
|
|
20
|
+
|
|
21
|
+
## i18n
|
|
22
|
+
CLI localization is supported with:
|
|
23
|
+
- `--locale=<code>`
|
|
24
|
+
- `AIOS_LITE_LOCALE=<code>`
|
|
25
|
+
|
|
26
|
+
Default locale is `en`.
|
|
27
|
+
|
|
28
|
+
Generate a new locale scaffold:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
aios-lite i18n:add fr
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Multi-IDE support
|
|
35
|
+
- Claude Code (`CLAUDE.md`)
|
|
36
|
+
- Codex CLI (`AGENTS.md`)
|
|
37
|
+
- Gemini CLI (`.gemini/GEMINI.md`)
|
|
38
|
+
- OpenCode (`OPENCODE.md`)
|
|
39
|
+
|
|
40
|
+
## Docs
|
|
41
|
+
- i18n guide: `docs/en/i18n.md`
|
|
42
|
+
- release guide: `docs/en/release.md`
|
|
43
|
+
- release flow: `docs/en/release-flow.md`
|
|
44
|
+
- release notes template: `docs/en/release-notes-template.md`
|
|
45
|
+
|
|
46
|
+
## License
|
|
47
|
+
MIT
|
package/bin/aios-lite.js
ADDED
package/docs/en/i18n.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# i18n Guide
|
|
2
|
+
|
|
3
|
+
AIOS Lite CLI supports localization through message dictionaries.
|
|
4
|
+
|
|
5
|
+
## How it works
|
|
6
|
+
- Dictionaries are stored in `src/i18n/messages/`.
|
|
7
|
+
- `src/i18n/index.js` resolves locale and fallback behavior.
|
|
8
|
+
- Commands use translation keys instead of hardcoded strings.
|
|
9
|
+
|
|
10
|
+
## Runtime selection
|
|
11
|
+
- CLI option: `--locale=en`
|
|
12
|
+
- Env var: `AIOS_LITE_LOCALE=en`
|
|
13
|
+
- Default: `en`
|
|
14
|
+
|
|
15
|
+
## Create a locale scaffold
|
|
16
|
+
```bash
|
|
17
|
+
aios-lite i18n:add fr
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Add a new locale
|
|
21
|
+
1. Run `aios-lite i18n:add <locale>`.
|
|
22
|
+
2. Replace English strings in `src/i18n/messages/<locale>.js`.
|
|
23
|
+
3. Add tests for locale resolution and fallback behavior.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Release Tag Flow
|
|
2
|
+
|
|
3
|
+
## Preconditions
|
|
4
|
+
- Git repository initialized and connected to GitHub.
|
|
5
|
+
- `NPM_TOKEN` configured in repository secrets.
|
|
6
|
+
- `main` branch green in CI.
|
|
7
|
+
|
|
8
|
+
## Steps
|
|
9
|
+
1. Update `CHANGELOG.md` and `package.json` version.
|
|
10
|
+
2. Run local validation:
|
|
11
|
+
- `npm run ci`
|
|
12
|
+
3. Commit release changes.
|
|
13
|
+
4. Create tag:
|
|
14
|
+
- `git tag vX.Y.Z`
|
|
15
|
+
5. Push branch and tag:
|
|
16
|
+
- `git push origin main --tags`
|
|
17
|
+
6. Watch `Release` workflow in GitHub Actions.
|
|
18
|
+
7. Publish GitHub release using `.github/release-notes-template.md`.
|
|
19
|
+
|
|
20
|
+
## Verify publication
|
|
21
|
+
- `npm view aios-lite version`
|
|
22
|
+
- `npx aios-lite@latest info`
|
|
23
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Release Notes Template
|
|
2
|
+
|
|
3
|
+
## AIOS Lite vX.Y.Z
|
|
4
|
+
|
|
5
|
+
### Highlights
|
|
6
|
+
- [short summary 1]
|
|
7
|
+
- [short summary 2]
|
|
8
|
+
- [short summary 3]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- [feature]
|
|
12
|
+
- [feature]
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- [change]
|
|
16
|
+
- [change]
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- [bug fix]
|
|
20
|
+
- [bug fix]
|
|
21
|
+
|
|
22
|
+
### CLI
|
|
23
|
+
- Commands impacted: `[list]`
|
|
24
|
+
- Breaking changes: `yes/no` (if yes, describe migration)
|
|
25
|
+
|
|
26
|
+
### i18n
|
|
27
|
+
- New locale scaffolds or translation keys:
|
|
28
|
+
- [item]
|
|
29
|
+
|
|
30
|
+
### Upgrade notes
|
|
31
|
+
1. Update package:
|
|
32
|
+
- `npx aios-lite@latest update`
|
|
33
|
+
2. Run health check:
|
|
34
|
+
- `aios-lite doctor`
|
|
35
|
+
3. Verify local customizations in `.aios-lite/backups/` if applicable.
|
|
36
|
+
|
|
37
|
+
### Checks
|
|
38
|
+
- [ ] Lint passed
|
|
39
|
+
- [ ] Tests passed
|
|
40
|
+
- [ ] Smoke test passed
|
|
41
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Release Guide
|
|
2
|
+
|
|
3
|
+
## CI
|
|
4
|
+
- Workflow: `.github/workflows/ci.yml`
|
|
5
|
+
- Triggers: push to `main`, pull requests
|
|
6
|
+
- Steps: install, lint, test, `npm pack --dry-run`
|
|
7
|
+
|
|
8
|
+
## npm publish
|
|
9
|
+
- Workflow: `.github/workflows/release.yml`
|
|
10
|
+
- Triggers: `v*` git tags or manual dispatch
|
|
11
|
+
- Required secret: `NPM_TOKEN`
|
|
12
|
+
|
|
13
|
+
## Name availability snapshot (2026-03-01)
|
|
14
|
+
The following names returned `404 Not Found` from npm registry lookup and were therefore available at the time of check:
|
|
15
|
+
- `aios-lite`
|
|
16
|
+
- `aios-lite-cli`
|
|
17
|
+
- `create-aios-lite`
|
|
18
|
+
- `@aios-lite/create`
|
|
19
|
+
- `@synkra-ai/aios-lite`
|
|
20
|
+
- `@synkra-ai/create-aios-lite`
|
|
21
|
+
|
|
22
|
+
## Recommended release flow
|
|
23
|
+
1. Update `CHANGELOG.md`.
|
|
24
|
+
2. Bump version in `package.json`.
|
|
25
|
+
3. Commit and push to `main`.
|
|
26
|
+
4. Create and push a tag like `v0.1.1`.
|
|
27
|
+
5. Verify publish logs in GitHub Actions.
|
|
28
|
+
|
|
29
|
+
## Templates
|
|
30
|
+
- Release notes template: `.github/release-notes-template.md`
|
|
31
|
+
- Extended release notes guide: `docs/en/release-notes-template.md`
|
|
32
|
+
- Tag flow checklist: `docs/en/release-flow.md`
|
package/package.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aios-lite",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight AI agent framework for software projects.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ai",
|
|
7
|
+
"agents",
|
|
8
|
+
"claude",
|
|
9
|
+
"codex",
|
|
10
|
+
"gemini",
|
|
11
|
+
"opencode",
|
|
12
|
+
"cli",
|
|
13
|
+
"framework"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"main": "src/cli.js",
|
|
17
|
+
"bin": {
|
|
18
|
+
"aios-lite": "bin/aios-lite.js"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"bin/",
|
|
25
|
+
"src/",
|
|
26
|
+
"template/",
|
|
27
|
+
"docs/",
|
|
28
|
+
"README.md",
|
|
29
|
+
"CHANGELOG.md",
|
|
30
|
+
"CONTRIBUTING.md",
|
|
31
|
+
"CODE_OF_CONDUCT.md",
|
|
32
|
+
"LICENSE"
|
|
33
|
+
],
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18.0.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"test": "node --test",
|
|
39
|
+
"lint": "node --check src/*.js src/commands/*.js src/i18n/*.js src/i18n/messages/*.js bin/*.js",
|
|
40
|
+
"ci": "npm run lint && npm test"
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { parseArgv } = require('./parser');
|
|
4
|
+
const { createTranslator, normalizeLocale } = require('./i18n');
|
|
5
|
+
const { runInit } = require('./commands/init');
|
|
6
|
+
const { runInstall } = require('./commands/install');
|
|
7
|
+
const { runUpdate } = require('./commands/update');
|
|
8
|
+
const { runInfo } = require('./commands/info');
|
|
9
|
+
const { runDoctorCommand } = require('./commands/doctor');
|
|
10
|
+
const { runI18nAdd } = require('./commands/i18n-add');
|
|
11
|
+
|
|
12
|
+
function printHelp(t) {
|
|
13
|
+
console.log(`${t('cli.title')}\n`);
|
|
14
|
+
console.log(t('cli.usage'));
|
|
15
|
+
console.log(` ${t('cli.help_init')}`);
|
|
16
|
+
console.log(` ${t('cli.help_install')}`);
|
|
17
|
+
console.log(` ${t('cli.help_update')}`);
|
|
18
|
+
console.log(` ${t('cli.help_info')}`);
|
|
19
|
+
console.log(` ${t('cli.help_doctor')}`);
|
|
20
|
+
console.log(` ${t('cli.help_i18n_add')}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function main() {
|
|
24
|
+
const { command, args, options } = parseArgv(process.argv);
|
|
25
|
+
const locale = normalizeLocale(options.locale || process.env.AIOS_LITE_LOCALE || 'en');
|
|
26
|
+
const { t } = createTranslator(locale);
|
|
27
|
+
const logger = console;
|
|
28
|
+
|
|
29
|
+
if (command === 'help' || options.help || command === '--help' || command === '-h') {
|
|
30
|
+
printHelp(t);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (command === '--version' || command === '-v' || command === 'version' || options.version) {
|
|
35
|
+
await runInfo({ args: ['.'], options: {}, logger, t });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
if (command === 'init') {
|
|
41
|
+
await runInit({ args, options, logger, t });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (command === 'install') {
|
|
45
|
+
await runInstall({ args, options, logger, t });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (command === 'update') {
|
|
49
|
+
await runUpdate({ args, options, logger, t });
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (command === 'info') {
|
|
53
|
+
await runInfo({ args, options, logger, t });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (command === 'doctor') {
|
|
57
|
+
await runDoctorCommand({ args, options, logger, t });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (command === 'i18n:add' || command === 'i18n-add') {
|
|
61
|
+
await runI18nAdd({ args, options, logger, t });
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
logger.error(`${t('cli.unknown_command', { command })}\n`);
|
|
66
|
+
printHelp(t);
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
} catch (error) {
|
|
69
|
+
logger.error(t('cli.error_prefix', { message: error.message }));
|
|
70
|
+
process.exitCode = 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
main();
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { runDoctor } = require('../doctor');
|
|
5
|
+
|
|
6
|
+
async function runDoctorCommand({ args, logger, t }) {
|
|
7
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
8
|
+
const report = await runDoctor(targetDir);
|
|
9
|
+
|
|
10
|
+
for (const check of report.checks) {
|
|
11
|
+
const icon = check.ok ? t('doctor.ok') : t('doctor.fail');
|
|
12
|
+
logger.log(`[${icon}] ${t(check.key, check.params)}`);
|
|
13
|
+
if (!check.ok && check.hintKey) {
|
|
14
|
+
logger.log(` ${t('doctor.hint_prefix', { hint: t(check.hintKey) })}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!report.ok) {
|
|
19
|
+
logger.log(`\n${t('doctor.diagnosis_fail', { count: report.failedCount })}`);
|
|
20
|
+
} else {
|
|
21
|
+
logger.log(`\n${t('doctor.diagnosis_ok')}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return report;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = {
|
|
28
|
+
runDoctorCommand
|
|
29
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createLocaleScaffold } = require('../i18n/scaffold');
|
|
4
|
+
|
|
5
|
+
async function runI18nAdd({ args, options, logger, t }) {
|
|
6
|
+
const requestedLocale = args[0];
|
|
7
|
+
if (!requestedLocale) {
|
|
8
|
+
throw new Error(t('i18n_add.usage_error'));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const force = Boolean(options.force);
|
|
12
|
+
const dryRun = Boolean(options['dry-run']);
|
|
13
|
+
|
|
14
|
+
let result;
|
|
15
|
+
try {
|
|
16
|
+
result = await createLocaleScaffold(requestedLocale, { force, dryRun });
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error.code === 'INVALID_LOCALE') {
|
|
19
|
+
throw new Error(t('i18n_add.invalid_locale', { locale: requestedLocale }));
|
|
20
|
+
}
|
|
21
|
+
if (error.code === 'BASE_LOCALE') {
|
|
22
|
+
throw new Error(t('i18n_add.base_locale'));
|
|
23
|
+
}
|
|
24
|
+
if (error.code === 'LOCALE_EXISTS') {
|
|
25
|
+
throw new Error(t('i18n_add.locale_exists', { path: error.path }));
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (result.dryRun) {
|
|
31
|
+
logger.log(
|
|
32
|
+
result.overwritten
|
|
33
|
+
? t('i18n_add.dry_run_overwritten', { locale: result.locale })
|
|
34
|
+
: t('i18n_add.dry_run_created', { locale: result.locale })
|
|
35
|
+
);
|
|
36
|
+
} else {
|
|
37
|
+
logger.log(
|
|
38
|
+
result.overwritten
|
|
39
|
+
? t('i18n_add.overwritten', { locale: result.locale })
|
|
40
|
+
: t('i18n_add.created', { locale: result.locale })
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
logger.log(t('i18n_add.file_path', { path: result.filePath }));
|
|
44
|
+
logger.log(t('i18n_add.next_steps'));
|
|
45
|
+
logger.log(t('i18n_add.step_translate'));
|
|
46
|
+
logger.log(t('i18n_add.step_try', { locale: result.locale }));
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
runI18nAdd
|
|
53
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { detectFramework } = require('../detector');
|
|
6
|
+
const { detectExistingInstall } = require('../installer');
|
|
7
|
+
|
|
8
|
+
async function runInfo({ args, logger, t }) {
|
|
9
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
10
|
+
const pkgPath = path.join(__dirname, '../../package.json');
|
|
11
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'));
|
|
12
|
+
|
|
13
|
+
const installed = await detectExistingInstall(targetDir);
|
|
14
|
+
const detection = await detectFramework(targetDir);
|
|
15
|
+
|
|
16
|
+
logger.log(t('info.cli_version', { version: pkg.version }));
|
|
17
|
+
logger.log(t('info.directory', { targetDir }));
|
|
18
|
+
logger.log(t('info.installed_here', { value: installed ? t('info.yes') : t('info.no') }));
|
|
19
|
+
logger.log(t('info.framework_detected', { framework: detection.framework || t('info.none') }));
|
|
20
|
+
if (detection.evidence) {
|
|
21
|
+
logger.log(t('info.evidence', { evidence: detection.evidence }));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
version: pkg.version,
|
|
26
|
+
installed,
|
|
27
|
+
detection
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
runInfo
|
|
33
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('node:fs/promises');
|
|
4
|
+
const path = require('node:path');
|
|
5
|
+
const { installTemplate } = require('../installer');
|
|
6
|
+
|
|
7
|
+
async function directoryIsEmpty(dirPath) {
|
|
8
|
+
try {
|
|
9
|
+
const entries = await fs.readdir(dirPath);
|
|
10
|
+
return entries.length === 0;
|
|
11
|
+
} catch (error) {
|
|
12
|
+
if (error && error.code === 'ENOENT') return true;
|
|
13
|
+
throw error;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function runInit({ args, options, logger, t }) {
|
|
18
|
+
const projectName = args[0];
|
|
19
|
+
if (!projectName) {
|
|
20
|
+
throw new Error(t('init.usage_error'));
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
24
|
+
const force = Boolean(options.force);
|
|
25
|
+
const dryRun = Boolean(options['dry-run']);
|
|
26
|
+
|
|
27
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
28
|
+
|
|
29
|
+
if (!(await directoryIsEmpty(targetDir)) && !force) {
|
|
30
|
+
throw new Error(t('init.non_empty_dir', { targetDir }));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await installTemplate(targetDir, {
|
|
34
|
+
overwrite: true,
|
|
35
|
+
dryRun,
|
|
36
|
+
mode: 'init'
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
logger.log(t('init.created_at', { targetDir }));
|
|
40
|
+
logger.log(t('init.files_copied', { count: result.copied.length }));
|
|
41
|
+
if (result.skipped.length > 0) {
|
|
42
|
+
logger.log(t('init.files_skipped', { count: result.skipped.length }));
|
|
43
|
+
}
|
|
44
|
+
logger.log(t('init.next_steps'));
|
|
45
|
+
logger.log(t('init.step_cd', { projectName }));
|
|
46
|
+
logger.log(t('init.step_setup'));
|
|
47
|
+
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
runInit,
|
|
53
|
+
directoryIsEmpty
|
|
54
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { detectFramework } = require('../detector');
|
|
5
|
+
const { installTemplate } = require('../installer');
|
|
6
|
+
|
|
7
|
+
async function runInstall({ args, options, logger, t }) {
|
|
8
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
9
|
+
const force = Boolean(options.force);
|
|
10
|
+
const dryRun = Boolean(options['dry-run']);
|
|
11
|
+
|
|
12
|
+
const detection = await detectFramework(targetDir);
|
|
13
|
+
if (detection.installed) {
|
|
14
|
+
logger.log(t('install.framework_detected', {
|
|
15
|
+
framework: detection.framework,
|
|
16
|
+
evidence: detection.evidence
|
|
17
|
+
}));
|
|
18
|
+
} else {
|
|
19
|
+
logger.log(t('install.framework_not_detected'));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const result = await installTemplate(targetDir, {
|
|
23
|
+
overwrite: force,
|
|
24
|
+
dryRun,
|
|
25
|
+
mode: 'install',
|
|
26
|
+
frameworkDetection: detection.framework
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
logger.log(t('install.done_at', { targetDir }));
|
|
30
|
+
logger.log(t('install.files_copied', { count: result.copied.length }));
|
|
31
|
+
logger.log(t('install.files_skipped', { count: result.skipped.length }));
|
|
32
|
+
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = {
|
|
37
|
+
runInstall
|
|
38
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
const { detectFramework } = require('../detector');
|
|
5
|
+
const { updateInstallation } = require('../updater');
|
|
6
|
+
|
|
7
|
+
async function runUpdate({ args, options, logger, t }) {
|
|
8
|
+
const targetDir = path.resolve(process.cwd(), args[0] || '.');
|
|
9
|
+
const dryRun = Boolean(options['dry-run']);
|
|
10
|
+
|
|
11
|
+
const detection = await detectFramework(targetDir);
|
|
12
|
+
const result = await updateInstallation(targetDir, {
|
|
13
|
+
dryRun,
|
|
14
|
+
frameworkDetection: detection.framework
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (!result.ok) {
|
|
18
|
+
throw new Error(t('update.not_installed', { targetDir }));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
logger.log(t('update.done_at', { targetDir }));
|
|
22
|
+
logger.log(t('update.files_updated', { count: result.copied.length }));
|
|
23
|
+
logger.log(t('update.backups_created', { count: result.backedUp.length }));
|
|
24
|
+
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = {
|
|
29
|
+
runUpdate
|
|
30
|
+
};
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const MANAGED_FILES = [
|
|
4
|
+
'CLAUDE.md',
|
|
5
|
+
'AGENTS.md',
|
|
6
|
+
'OPENCODE.md',
|
|
7
|
+
'.gemini/GEMINI.md',
|
|
8
|
+
'.gemini/commands/aios-setup.toml',
|
|
9
|
+
'.gemini/commands/aios-analyst.toml',
|
|
10
|
+
'.gemini/commands/aios-architect.toml',
|
|
11
|
+
'.gemini/commands/aios-pm.toml',
|
|
12
|
+
'.gemini/commands/aios-dev.toml',
|
|
13
|
+
'.gemini/commands/aios-qa.toml',
|
|
14
|
+
'.gemini/commands/aios-orchestrator.toml',
|
|
15
|
+
'.aios-lite/config.md',
|
|
16
|
+
'.aios-lite/agents/setup.md',
|
|
17
|
+
'.aios-lite/agents/analyst.md',
|
|
18
|
+
'.aios-lite/agents/architect.md',
|
|
19
|
+
'.aios-lite/agents/pm.md',
|
|
20
|
+
'.aios-lite/agents/dev.md',
|
|
21
|
+
'.aios-lite/agents/qa.md',
|
|
22
|
+
'.aios-lite/agents/orchestrator.md',
|
|
23
|
+
'.aios-lite/skills/static/laravel-conventions.md',
|
|
24
|
+
'.aios-lite/skills/static/tall-stack-patterns.md',
|
|
25
|
+
'.aios-lite/skills/static/jetstream-setup.md',
|
|
26
|
+
'.aios-lite/skills/static/rails-conventions.md',
|
|
27
|
+
'.aios-lite/skills/static/node-express-patterns.md',
|
|
28
|
+
'.aios-lite/skills/static/nextjs-patterns.md',
|
|
29
|
+
'.aios-lite/skills/static/ui-ux-modern.md',
|
|
30
|
+
'.aios-lite/skills/static/git-conventions.md',
|
|
31
|
+
'.aios-lite/skills/dynamic/laravel-docs.md',
|
|
32
|
+
'.aios-lite/skills/dynamic/flux-ui-docs.md',
|
|
33
|
+
'.aios-lite/skills/dynamic/npm-packages.md',
|
|
34
|
+
'.aios-lite/mcp/servers.md'
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
const REQUIRED_FILES = [
|
|
38
|
+
'CLAUDE.md',
|
|
39
|
+
'AGENTS.md',
|
|
40
|
+
'.aios-lite/config.md',
|
|
41
|
+
'.aios-lite/agents/setup.md',
|
|
42
|
+
'.aios-lite/agents/analyst.md',
|
|
43
|
+
'.aios-lite/agents/dev.md',
|
|
44
|
+
'.aios-lite/context/.gitkeep'
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
module.exports = {
|
|
48
|
+
MANAGED_FILES,
|
|
49
|
+
REQUIRED_FILES
|
|
50
|
+
};
|