@fitlab-ai/agent-infra 0.3.2 → 0.4.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 +18 -33
- package/README.zh-CN.md +18 -33
- package/lib/defaults.json +3 -12
- package/lib/init.js +13 -24
- package/lib/paths.js +3 -42
- package/lib/update.js +98 -32
- package/package.json +2 -1
- package/templates/.agents/QUICKSTART.md +7 -7
- package/templates/.agents/QUICKSTART.zh-CN.md +7 -7
- package/templates/.agents/README.md +4 -4
- package/templates/.agents/README.zh-CN.md +4 -4
- package/templates/.agents/skills/analyze-task/SKILL.md +6 -6
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/block-task/SKILL.md +8 -8
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/check-task/SKILL.md +3 -3
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/commit/SKILL.md +1 -1
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/complete-task/SKILL.md +7 -7
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +7 -7
- package/templates/.agents/skills/create-issue/SKILL.md +2 -2
- package/templates/.agents/skills/create-issue/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/create-pr/SKILL.md +1 -1
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/create-task/SKILL.md +4 -4
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +4 -4
- package/templates/.agents/skills/implement-task/SKILL.md +8 -8
- package/templates/.agents/skills/implement-task/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/import-codescan/SKILL.md +1 -1
- package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-dependabot/SKILL.md +3 -3
- package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/import-issue/SKILL.md +5 -5
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/plan-task/SKILL.md +6 -6
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/refine-task/SKILL.md +3 -3
- package/templates/.agents/skills/refine-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/release/SKILL.md +55 -14
- package/templates/.agents/skills/release/SKILL.zh-CN.md +55 -14
- package/templates/.agents/skills/review-task/SKILL.md +9 -9
- package/templates/.agents/skills/review-task/SKILL.zh-CN.md +9 -9
- package/templates/.agents/skills/sync-issue/SKILL.md +8 -8
- package/templates/.agents/skills/sync-issue/SKILL.zh-CN.md +8 -8
- package/templates/.agents/skills/sync-pr/SKILL.md +3 -3
- package/templates/.agents/skills/sync-pr/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/update-agent-infra/SKILL.md +6 -6
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +6 -6
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +61 -116
- package/templates/.agents/templates/handoff.md +1 -1
- package/templates/.agents/templates/handoff.zh-CN.md +1 -1
- package/templates/.agents/workflows/bug-fix.yaml +71 -71
- package/templates/.agents/workflows/bug-fix.zh-CN.yaml +1 -1
- package/templates/.agents/workflows/feature-development.yaml +71 -71
- package/templates/.agents/workflows/feature-development.zh-CN.yaml +1 -1
- package/templates/.agents/workflows/refactoring.yaml +76 -76
- package/templates/.agents/workflows/refactoring.zh-CN.yaml +1 -1
- package/templates/{.agent-workspace → .agents/workspace}/README.md +1 -1
- package/templates/{.agent-workspace → .agents/workspace}/README.zh-CN.md +1 -1
- package/templates/.claude/CLAUDE.md +1 -1
- package/templates/.claude/CLAUDE.zh-CN.md +1 -1
- package/templates/.claude/hooks/check-version-format.sh +44 -0
- package/templates/.claude/settings.json +14 -0
- package/templates/.opencode/COMMAND_STYLE_GUIDE.md +6 -6
- package/templates/.opencode/COMMAND_STYLE_GUIDE.zh-CN.md +6 -6
- package/templates/AGENTS.md +1 -1
- package/templates/AGENTS.zh-CN.md +1 -1
- package/templates/.editorconfig +0 -15
- package/templates/.github/ISSUE_TEMPLATE/01_bug_report.yml +0 -149
- package/templates/.github/ISSUE_TEMPLATE/02_question.yml +0 -101
- package/templates/.github/ISSUE_TEMPLATE/03_feature_request.yml +0 -131
- package/templates/.github/ISSUE_TEMPLATE/04_documentation.yml +0 -165
- package/templates/.github/ISSUE_TEMPLATE/05_other.yml +0 -147
- package/templates/.github/ISSUE_TEMPLATE/config.yml +0 -11
- package/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -123
- package/templates/.github/dependabot.yml +0 -17
- package/templates/.github/hooks/check-utf8-encoding.sh +0 -25
- package/templates/.github/release.yml +0 -27
- package/templates/.github/workflows/pr-title-check.yml +0 -42
- package/templates/.mailmap +0 -4
- package/templates/CONTRIBUTING.md +0 -126
- package/templates/CONTRIBUTING.zh-CN.md +0 -124
- package/templates/SECURITY.md +0 -131
- package/templates/SECURITY.zh-CN.md +0 -131
package/README.md
CHANGED
|
@@ -144,7 +144,7 @@ ai init
|
|
|
144
144
|
# or: agent-infra init
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
The CLI collects project metadata, installs the `update-agent-infra` seed command for all supported AI TUIs, and generates `.airc.json`.
|
|
147
|
+
The CLI collects project metadata, installs the `update-agent-infra` seed command for all supported AI TUIs, and generates `.agents/.airc.json`.
|
|
148
148
|
|
|
149
149
|
> `ai` is a shorthand for `agent-infra`. Both commands are equivalent.
|
|
150
150
|
|
|
@@ -159,7 +159,7 @@ Open the project in any AI TUI and run `update-agent-infra`:
|
|
|
159
159
|
| Gemini CLI | `/{{project}}:update-agent-infra` |
|
|
160
160
|
| OpenCode | `/update-agent-infra` |
|
|
161
161
|
|
|
162
|
-
This
|
|
162
|
+
This detects the packaged template version and renders all managed files. The same command is used both for first-time setup and for future template upgrades.
|
|
163
163
|
|
|
164
164
|
<a id="architecture-overview"></a>
|
|
165
165
|
|
|
@@ -170,8 +170,8 @@ agent-infra is intentionally simple: a bootstrap CLI creates the seed configurat
|
|
|
170
170
|
### End-to-End Flow
|
|
171
171
|
|
|
172
172
|
1. **Install** — `npm install -g @fitlab-ai/agent-infra` (or use the shell script wrapper)
|
|
173
|
-
2. **Initialize** — `ai init` in the project root to generate `.airc.json` and install the seed command
|
|
174
|
-
3. **Render** — run `update-agent-infra` in any AI TUI to
|
|
173
|
+
2. **Initialize** — `ai init` in the project root to generate `.agents/.airc.json` and install the seed command
|
|
174
|
+
3. **Render** — run `update-agent-infra` in any AI TUI to detect the bundled template version and generate all managed files
|
|
175
175
|
4. **Develop** — use 28 built-in skills to drive the full lifecycle: `analysis → design → implementation → review → fix → commit`
|
|
176
176
|
5. **Update** — run `update-agent-infra` again whenever a new template version is available
|
|
177
177
|
|
|
@@ -197,7 +197,7 @@ block-beta
|
|
|
197
197
|
|
|
198
198
|
block:project:4
|
|
199
199
|
columns 4
|
|
200
|
-
agents[".agents/"] config[".airc.json"] workspace[".
|
|
200
|
+
agents[".agents/"] config[".agents/.airc.json"] workspace[".agents/workspace/"] governance["AGENTS.md"]
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
tui -- "slash commands" --> shared
|
|
@@ -215,19 +215,15 @@ After setup, your project gains a complete AI collaboration infrastructure:
|
|
|
215
215
|
```text
|
|
216
216
|
my-project/
|
|
217
217
|
├── .agents/ # Shared AI collaboration config
|
|
218
|
+
│ ├── .airc.json # Central configuration
|
|
219
|
+
│ ├── workspace/ # Task workspace (git-ignored)
|
|
218
220
|
│ ├── skills/ # 28 built-in AI skills
|
|
219
221
|
│ ├── workflows/ # 4 prebuilt workflows
|
|
220
222
|
│ └── templates/ # Task and artifact templates
|
|
221
|
-
├── .agent-workspace/ # Task workspace (git-ignored)
|
|
222
223
|
├── .claude/ # Claude Code config and commands
|
|
223
224
|
├── .gemini/ # Gemini CLI config and commands
|
|
224
225
|
├── .opencode/ # OpenCode config and commands
|
|
225
|
-
|
|
226
|
-
├── AGENTS.md # Universal AI agent instructions
|
|
227
|
-
├── CONTRIBUTING.md # Contribution guide
|
|
228
|
-
├── SECURITY.md # Security policy (English)
|
|
229
|
-
├── SECURITY.zh-CN.md # Security policy (Chinese)
|
|
230
|
-
└── .airc.json # Central configuration
|
|
226
|
+
└── AGENTS.md # Universal AI agent instructions
|
|
231
227
|
```
|
|
232
228
|
|
|
233
229
|
<a id="built-in-ai-skills"></a>
|
|
@@ -375,9 +371,9 @@ import-issue #42 Import task from GitHub Issue
|
|
|
375
371
|
|
|
376
372
|
## Configuration Reference
|
|
377
373
|
|
|
378
|
-
The generated `.airc.json` file is the central contract between the bootstrap CLI, templates, and future updates.
|
|
374
|
+
The generated `.agents/.airc.json` file is the central contract between the bootstrap CLI, templates, and future updates.
|
|
379
375
|
|
|
380
|
-
### Example `.airc.json`
|
|
376
|
+
### Example `.agents/.airc.json`
|
|
381
377
|
|
|
382
378
|
```json
|
|
383
379
|
{
|
|
@@ -385,10 +381,10 @@ The generated `.airc.json` file is the central contract between the bootstrap CL
|
|
|
385
381
|
"org": "my-org",
|
|
386
382
|
"language": "en",
|
|
387
383
|
"templateSource": "templates/",
|
|
388
|
-
"templateVersion": "v0.
|
|
389
|
-
"modules": ["ai", "github"],
|
|
384
|
+
"templateVersion": "v0.4.0",
|
|
390
385
|
"files": {
|
|
391
386
|
"managed": [
|
|
387
|
+
".agents/workspace/README.md",
|
|
392
388
|
".agents/skills/",
|
|
393
389
|
".agents/templates/",
|
|
394
390
|
".agents/workflows/",
|
|
@@ -399,9 +395,7 @@ The generated `.airc.json` file is the central contract between the bootstrap CL
|
|
|
399
395
|
"merged": [
|
|
400
396
|
".agents/README.md",
|
|
401
397
|
".gitignore",
|
|
402
|
-
"AGENTS.md"
|
|
403
|
-
"CONTRIBUTING.md",
|
|
404
|
-
"SECURITY.md"
|
|
398
|
+
"AGENTS.md"
|
|
405
399
|
],
|
|
406
400
|
"ejected": []
|
|
407
401
|
}
|
|
@@ -417,16 +411,8 @@ The generated `.airc.json` file is the central contract between the bootstrap CL
|
|
|
417
411
|
| `language` | Primary project language or locale used by rendered templates. |
|
|
418
412
|
| `templateSource` | Local template root used during rendering. |
|
|
419
413
|
| `templateVersion` | Installed template version for future upgrades and drift tracking. |
|
|
420
|
-
| `modules` | Enabled template bundles. Supported values are `ai` and `github`. |
|
|
421
414
|
| `files` | Per-path update strategy configuration for managed, merged, and ejected files. |
|
|
422
415
|
|
|
423
|
-
### Module reference
|
|
424
|
-
|
|
425
|
-
| Module | Includes |
|
|
426
|
-
|--------|----------|
|
|
427
|
-
| `ai` | `.agents/`, `.claude/`, `.gemini/`, `.opencode/`, `AGENTS.md`, and related collaboration assets |
|
|
428
|
-
| `github` | `.github/`, contribution templates, release config, and GitHub governance assets |
|
|
429
|
-
|
|
430
416
|
<a id="file-management-strategies"></a>
|
|
431
417
|
|
|
432
418
|
## File Management Strategies
|
|
@@ -446,15 +432,14 @@ Each generated path is assigned an update strategy. That strategy determines how
|
|
|
446
432
|
"files": {
|
|
447
433
|
"managed": [
|
|
448
434
|
".agents/skills/",
|
|
449
|
-
".
|
|
435
|
+
".agents/workspace/README.md"
|
|
450
436
|
],
|
|
451
437
|
"merged": [
|
|
452
438
|
".gitignore",
|
|
453
|
-
"AGENTS.md"
|
|
454
|
-
"CONTRIBUTING.md"
|
|
439
|
+
"AGENTS.md"
|
|
455
440
|
],
|
|
456
441
|
"ejected": [
|
|
457
|
-
"
|
|
442
|
+
"docs/architecture.md"
|
|
458
443
|
]
|
|
459
444
|
}
|
|
460
445
|
}
|
|
@@ -462,7 +447,7 @@ Each generated path is assigned an update strategy. That strategy determines how
|
|
|
462
447
|
|
|
463
448
|
### Moving a file from `managed` to `ejected`
|
|
464
449
|
|
|
465
|
-
1. Remove the path from the `managed` array in `.airc.json`.
|
|
450
|
+
1. Remove the path from the `managed` array in `.agents/.airc.json`.
|
|
466
451
|
2. Add the same path to the `ejected` array.
|
|
467
452
|
3. Run `update-agent-infra` again so future updates stop managing that file.
|
|
468
453
|
|
|
@@ -472,7 +457,7 @@ Use this when a file starts as template-owned but later becomes project-specific
|
|
|
472
457
|
|
|
473
458
|
## Version Management
|
|
474
459
|
|
|
475
|
-
agent-infra uses semantic versioning through Git tags and GitHub releases. The installed template version is recorded in `.airc.json` as `templateVersion`, which gives both humans and AI tools a stable reference point for upgrades.
|
|
460
|
+
agent-infra uses semantic versioning through Git tags and GitHub releases. The installed template version is recorded in `.agents/.airc.json` as `templateVersion`, which gives both humans and AI tools a stable reference point for upgrades.
|
|
476
461
|
|
|
477
462
|
<a id="contributing"></a>
|
|
478
463
|
|
package/README.zh-CN.md
CHANGED
|
@@ -144,7 +144,7 @@ ai init
|
|
|
144
144
|
# 或:agent-infra init
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
-
CLI 会收集项目元数据,向所有支持的 AI TUI 安装 `update-agent-infra` 种子命令,并生成 `.airc.json`。
|
|
147
|
+
CLI 会收集项目元数据,向所有支持的 AI TUI 安装 `update-agent-infra` 种子命令,并生成 `.agents/.airc.json`。
|
|
148
148
|
|
|
149
149
|
> `ai` 是 `agent-infra` 的简写命令,两者等价。
|
|
150
150
|
|
|
@@ -159,7 +159,7 @@ CLI 会收集项目元数据,向所有支持的 AI TUI 安装 `update-agent-in
|
|
|
159
159
|
| Gemini CLI | `/{{project}}:update-agent-infra` |
|
|
160
160
|
| OpenCode | `/update-agent-infra` |
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
该命令会检测当前打包模板版本并渲染所有受管理文件。首次安装和后续升级都使用同一条命令。
|
|
163
163
|
|
|
164
164
|
<a id="architecture-overview"></a>
|
|
165
165
|
|
|
@@ -170,8 +170,8 @@ agent-infra 的结构刻意保持简单:引导 CLI 负责生成种子配置,
|
|
|
170
170
|
### 端到端流程
|
|
171
171
|
|
|
172
172
|
1. **安装** — `npm install -g @fitlab-ai/agent-infra`(或使用 shell 脚本便捷封装)
|
|
173
|
-
2. **初始化** — 在项目根目录运行 `ai init`,生成 `.airc.json` 并安装种子命令
|
|
174
|
-
3. **渲染** — 在任意 AI TUI 中执行 `update-agent-infra
|
|
173
|
+
2. **初始化** — 在项目根目录运行 `ai init`,生成 `.agents/.airc.json` 并安装种子命令
|
|
174
|
+
3. **渲染** — 在任意 AI TUI 中执行 `update-agent-infra`,检测当前打包模板版本并生成所有受管理文件
|
|
175
175
|
4. **开发** — 使用 28 个内置 skill 驱动完整生命周期:`analysis → design → implementation → review → fix → commit`
|
|
176
176
|
5. **升级** — 有新模板版本时再次执行 `update-agent-infra` 即可
|
|
177
177
|
|
|
@@ -197,7 +197,7 @@ block-beta
|
|
|
197
197
|
|
|
198
198
|
block:project:4
|
|
199
199
|
columns 4
|
|
200
|
-
agents[".agents/"] config[".airc.json"] workspace[".
|
|
200
|
+
agents[".agents/"] config[".agents/.airc.json"] workspace[".agents/workspace/"] governance["AGENTS.md"]
|
|
201
201
|
end
|
|
202
202
|
|
|
203
203
|
tui -- "slash commands" --> shared
|
|
@@ -215,19 +215,15 @@ GitHub 原生支持 Mermaid 渲染。即使某些下游渲染器不支持,上
|
|
|
215
215
|
```text
|
|
216
216
|
my-project/
|
|
217
217
|
├── .agents/ # 共享 AI 协作配置
|
|
218
|
+
│ ├── .airc.json # 中央配置文件
|
|
219
|
+
│ ├── workspace/ # 任务工作区(git 忽略)
|
|
218
220
|
│ ├── skills/ # 28 个内置 AI skills
|
|
219
221
|
│ ├── workflows/ # 4 个预置工作流
|
|
220
222
|
│ └── templates/ # 任务与产物模板
|
|
221
|
-
├── .agent-workspace/ # 任务工作区(git 忽略)
|
|
222
223
|
├── .claude/ # Claude Code 配置与命令
|
|
223
224
|
├── .gemini/ # Gemini CLI 配置与命令
|
|
224
225
|
├── .opencode/ # OpenCode 配置与命令
|
|
225
|
-
|
|
226
|
-
├── AGENTS.md # 通用 AI agent 指令
|
|
227
|
-
├── CONTRIBUTING.md # 贡献指南
|
|
228
|
-
├── SECURITY.md # 安全策略(英文)
|
|
229
|
-
├── SECURITY.zh-CN.md # 安全策略(中文)
|
|
230
|
-
└── .airc.json # 中央配置文件
|
|
226
|
+
└── AGENTS.md # 通用 AI agent 指令
|
|
231
227
|
```
|
|
232
228
|
|
|
233
229
|
<a id="built-in-ai-skills"></a>
|
|
@@ -375,9 +371,9 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
375
371
|
|
|
376
372
|
## 配置参考
|
|
377
373
|
|
|
378
|
-
生成出的 `.airc.json` 是引导 CLI、模板系统和后续升级之间的中心契约。
|
|
374
|
+
生成出的 `.agents/.airc.json` 是引导 CLI、模板系统和后续升级之间的中心契约。
|
|
379
375
|
|
|
380
|
-
### `.airc.json` 示例
|
|
376
|
+
### `.agents/.airc.json` 示例
|
|
381
377
|
|
|
382
378
|
```json
|
|
383
379
|
{
|
|
@@ -385,10 +381,10 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
385
381
|
"org": "my-org",
|
|
386
382
|
"language": "en",
|
|
387
383
|
"templateSource": "templates/",
|
|
388
|
-
"templateVersion": "v0.
|
|
389
|
-
"modules": ["ai", "github"],
|
|
384
|
+
"templateVersion": "v0.4.0",
|
|
390
385
|
"files": {
|
|
391
386
|
"managed": [
|
|
387
|
+
".agents/workspace/README.md",
|
|
392
388
|
".agents/skills/",
|
|
393
389
|
".agents/templates/",
|
|
394
390
|
".agents/workflows/",
|
|
@@ -399,9 +395,7 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
399
395
|
"merged": [
|
|
400
396
|
".agents/README.md",
|
|
401
397
|
".gitignore",
|
|
402
|
-
"AGENTS.md"
|
|
403
|
-
"CONTRIBUTING.md",
|
|
404
|
-
"SECURITY.md"
|
|
398
|
+
"AGENTS.md"
|
|
405
399
|
],
|
|
406
400
|
"ejected": []
|
|
407
401
|
}
|
|
@@ -417,16 +411,8 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
417
411
|
| `language` | 渲染模板时采用的项目主语言或区域设置。 |
|
|
418
412
|
| `templateSource` | 本地模板根目录。 |
|
|
419
413
|
| `templateVersion` | 当前安装的模板版本,用于升级和差异追踪。 |
|
|
420
|
-
| `modules` | 启用的模板模块。可选值为 `ai` 和 `github`。 |
|
|
421
414
|
| `files` | 针对具体路径配置 `managed`、`merged`、`ejected` 三类更新策略。 |
|
|
422
415
|
|
|
423
|
-
### 模块说明
|
|
424
|
-
|
|
425
|
-
| 模块 | 包含内容 |
|
|
426
|
-
|------|----------|
|
|
427
|
-
| `ai` | `.agents/`、`.claude/`、`.gemini/`、`.opencode/`、`AGENTS.md` 及相关协作资产 |
|
|
428
|
-
| `github` | `.github/`、贡献模板、发布配置以及 GitHub 治理相关文件 |
|
|
429
|
-
|
|
430
416
|
<a id="file-management-strategies"></a>
|
|
431
417
|
|
|
432
418
|
## 文件管理策略
|
|
@@ -446,15 +432,14 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
446
432
|
"files": {
|
|
447
433
|
"managed": [
|
|
448
434
|
".agents/skills/",
|
|
449
|
-
".
|
|
435
|
+
".agents/workspace/README.md"
|
|
450
436
|
],
|
|
451
437
|
"merged": [
|
|
452
438
|
".gitignore",
|
|
453
|
-
"AGENTS.md"
|
|
454
|
-
"CONTRIBUTING.md"
|
|
439
|
+
"AGENTS.md"
|
|
455
440
|
],
|
|
456
441
|
"ejected": [
|
|
457
|
-
"
|
|
442
|
+
"docs/architecture.md"
|
|
458
443
|
]
|
|
459
444
|
}
|
|
460
445
|
}
|
|
@@ -462,7 +447,7 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
462
447
|
|
|
463
448
|
### 如何把文件从 `managed` 改为 `ejected`
|
|
464
449
|
|
|
465
|
-
1. 在 `.airc.json` 中把该路径从 `managed` 数组移除。
|
|
450
|
+
1. 在 `.agents/.airc.json` 中把该路径从 `managed` 数组移除。
|
|
466
451
|
2. 将同一路径加入 `ejected` 数组。
|
|
467
452
|
3. 再次执行 `update-agent-infra`,让后续升级不再管理这个文件。
|
|
468
453
|
|
|
@@ -472,7 +457,7 @@ import-issue #42 从 GitHub Issue 导入任务
|
|
|
472
457
|
|
|
473
458
|
## 版本管理
|
|
474
459
|
|
|
475
|
-
agent-infra 通过 Git tag 和 GitHub release 使用语义化版本号。当前安装的模板版本记录在 `.airc.json` 的 `templateVersion` 字段中,方便人和 AI 工具在升级时都能基于同一个版本基线工作。
|
|
460
|
+
agent-infra 通过 Git tag 和 GitHub release 使用语义化版本号。当前安装的模板版本记录在 `.agents/.airc.json` 的 `templateVersion` 字段中,方便人和 AI 工具在升级时都能基于同一个版本基线工作。
|
|
476
461
|
|
|
477
462
|
<a id="contributing"></a>
|
|
478
463
|
|
package/lib/defaults.json
CHANGED
|
@@ -4,15 +4,10 @@
|
|
|
4
4
|
".agents/skills/",
|
|
5
5
|
".agents/templates/",
|
|
6
6
|
".agents/workflows/",
|
|
7
|
-
".
|
|
7
|
+
".agents/workspace/README.md",
|
|
8
8
|
".claude/commands/",
|
|
9
|
-
".
|
|
9
|
+
".claude/hooks/",
|
|
10
10
|
".gemini/commands/",
|
|
11
|
-
".github/hooks/",
|
|
12
|
-
".github/ISSUE_TEMPLATE/",
|
|
13
|
-
".github/PULL_REQUEST_TEMPLATE.md",
|
|
14
|
-
".github/release.yml",
|
|
15
|
-
".github/workflows/pr-title-check.yml",
|
|
16
11
|
".opencode/commands/"
|
|
17
12
|
],
|
|
18
13
|
"merged": [
|
|
@@ -31,14 +26,10 @@
|
|
|
31
26
|
".claude/settings.json",
|
|
32
27
|
".codex/README.md",
|
|
33
28
|
".gemini/settings.json",
|
|
34
|
-
".github/dependabot.yml",
|
|
35
29
|
".gitignore",
|
|
36
|
-
".mailmap",
|
|
37
30
|
".opencode/COMMAND_STYLE_GUIDE.md",
|
|
38
31
|
".opencode/README.md",
|
|
39
|
-
"AGENTS.md"
|
|
40
|
-
"CONTRIBUTING.md",
|
|
41
|
-
"SECURITY.md"
|
|
32
|
+
"AGENTS.md"
|
|
42
33
|
],
|
|
43
34
|
"ejected": []
|
|
44
35
|
}
|
package/lib/init.js
CHANGED
|
@@ -3,7 +3,7 @@ import path from 'node:path';
|
|
|
3
3
|
import { execSync } from 'node:child_process';
|
|
4
4
|
import { info, ok, err } from './log.js';
|
|
5
5
|
import { prompt, closePrompt } from './prompt.js';
|
|
6
|
-
import { resolveTemplateDir
|
|
6
|
+
import { resolveTemplateDir } from './paths.js';
|
|
7
7
|
import { renderFile, copySkillDir } from './render.js';
|
|
8
8
|
import { VERSION } from './version.js';
|
|
9
9
|
|
|
@@ -50,28 +50,19 @@ async function cmdInit() {
|
|
|
50
50
|
if (!templateDir) {
|
|
51
51
|
err('Template directory not found.');
|
|
52
52
|
err('Install via npm: npm install -g @fitlab-ai/agent-infra');
|
|
53
|
-
err('Or via clone: curl -fsSL https://raw.githubusercontent.com/fitlab-ai/agent-infra/main/install.sh | sh');
|
|
54
53
|
process.exitCode = 1;
|
|
55
54
|
return;
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
if (isCloneInstall()) {
|
|
60
|
-
const installDir = resolveInstallDir();
|
|
61
|
-
if (fs.existsSync(path.join(installDir, '.git'))) {
|
|
62
|
-
info('Updating templates to latest version...');
|
|
63
|
-
try {
|
|
64
|
-
execSync('git pull --rebase --quiet', { cwd: installDir, stdio: 'pipe' });
|
|
65
|
-
ok('Templates updated.');
|
|
66
|
-
} catch {
|
|
67
|
-
err('Failed to update templates (network issue?). Using local version.');
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
57
|
+
const configPath = path.join('.agents', '.airc.json');
|
|
71
58
|
|
|
72
|
-
// check existing
|
|
73
|
-
if (
|
|
74
|
-
|
|
59
|
+
// check existing config
|
|
60
|
+
if (
|
|
61
|
+
fs.existsSync(configPath) ||
|
|
62
|
+
fs.existsSync('.airc.json') ||
|
|
63
|
+
fs.existsSync(path.join('.agent-infra', 'config.json'))
|
|
64
|
+
) {
|
|
65
|
+
err('This project already has agent-infra configuration.');
|
|
75
66
|
err('Use /update-agent-infra in your AI TUI to update.');
|
|
76
67
|
process.exitCode = 1;
|
|
77
68
|
return;
|
|
@@ -113,7 +104,6 @@ async function cmdInit() {
|
|
|
113
104
|
return;
|
|
114
105
|
}
|
|
115
106
|
|
|
116
|
-
const modules = 'ai,github';
|
|
117
107
|
const project = projectName;
|
|
118
108
|
const replacements = { project, org: orgName };
|
|
119
109
|
|
|
@@ -170,20 +160,19 @@ async function cmdInit() {
|
|
|
170
160
|
);
|
|
171
161
|
ok('Installed .opencode/commands/update-agent-infra.md');
|
|
172
162
|
|
|
173
|
-
// generate .airc.json
|
|
174
|
-
const modulesArray = modules.split(',');
|
|
163
|
+
// generate .agents/.airc.json
|
|
175
164
|
const config = {
|
|
176
165
|
project: projectName,
|
|
177
166
|
org: orgName,
|
|
178
167
|
language,
|
|
179
168
|
templateSource: 'templates/',
|
|
180
169
|
templateVersion: VERSION,
|
|
181
|
-
modules: modulesArray,
|
|
182
170
|
files: structuredClone(defaults.files)
|
|
183
171
|
};
|
|
184
172
|
|
|
185
|
-
fs.
|
|
186
|
-
|
|
173
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
174
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
175
|
+
ok(`Generated ${configPath}`);
|
|
187
176
|
|
|
188
177
|
// done
|
|
189
178
|
console.log('');
|
package/lib/paths.js
CHANGED
|
@@ -1,48 +1,9 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import fs from 'node:fs';
|
|
3
|
-
import os from 'node:os';
|
|
4
2
|
import { fileURLToPath } from 'node:url';
|
|
5
3
|
|
|
6
|
-
function resolveBundledTemplateDir() {
|
|
7
|
-
return fileURLToPath(new URL('../templates', import.meta.url));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function resolveCloneTemplateDir() {
|
|
11
|
-
return path.join(os.homedir(), '.agent-infra', 'templates');
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function normalizePath(targetPath) {
|
|
15
|
-
try {
|
|
16
|
-
return fs.realpathSync(targetPath);
|
|
17
|
-
} catch {
|
|
18
|
-
return path.resolve(targetPath);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
4
|
function resolveTemplateDir() {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if (fs.existsSync(npmPath)) {
|
|
26
|
-
return npmPath;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// clone install mode: ~/.agent-infra/templates
|
|
30
|
-
const clonePath = resolveCloneTemplateDir();
|
|
31
|
-
if (fs.existsSync(clonePath)) {
|
|
32
|
-
return clonePath;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function resolveInstallDir() {
|
|
39
|
-
return path.join(os.homedir(), '.agent-infra');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function isCloneInstall() {
|
|
43
|
-
const npmPath = resolveBundledTemplateDir();
|
|
44
|
-
const clonePath = resolveCloneTemplateDir();
|
|
45
|
-
return fs.existsSync(npmPath) && normalizePath(npmPath) === normalizePath(clonePath);
|
|
5
|
+
const bundledDir = fileURLToPath(new URL('../templates', import.meta.url));
|
|
6
|
+
return fs.existsSync(bundledDir) ? bundledDir : null;
|
|
46
7
|
}
|
|
47
8
|
|
|
48
|
-
export { resolveTemplateDir
|
|
9
|
+
export { resolveTemplateDir };
|
package/lib/update.js
CHANGED
|
@@ -1,15 +1,75 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { execSync } from 'node:child_process';
|
|
4
3
|
import { info, ok, err } from './log.js';
|
|
5
|
-
import { resolveTemplateDir
|
|
4
|
+
import { resolveTemplateDir } from './paths.js';
|
|
6
5
|
import { renderFile, copySkillDir } from './render.js';
|
|
7
6
|
|
|
8
7
|
const defaults = JSON.parse(
|
|
9
8
|
fs.readFileSync(new URL('./defaults.json', import.meta.url), 'utf8')
|
|
10
9
|
);
|
|
11
10
|
|
|
11
|
+
const CONFIG_DIR = '.agents';
|
|
12
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, '.airc.json');
|
|
13
|
+
const LEGACY_CONFIG_PATHS = ['.airc.json', path.join('.agent-infra', 'config.json')];
|
|
14
|
+
const WORKSPACE_PATH = path.join(CONFIG_DIR, 'workspace');
|
|
15
|
+
const LEGACY_WORKSPACE_PATHS = ['.agent-workspace', path.join('.agent-infra', 'workspace')];
|
|
16
|
+
|
|
17
|
+
function migrateLegacyPaths() {
|
|
18
|
+
let migratedConfig = false;
|
|
19
|
+
let migratedWorkspace = false;
|
|
20
|
+
let configFrom = null;
|
|
21
|
+
let workspaceFrom = null;
|
|
22
|
+
|
|
23
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
24
|
+
for (const legacyPath of LEGACY_CONFIG_PATHS) {
|
|
25
|
+
if (!fs.existsSync(legacyPath)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
29
|
+
fs.renameSync(legacyPath, CONFIG_PATH);
|
|
30
|
+
migratedConfig = true;
|
|
31
|
+
configFrom = legacyPath;
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (!fs.existsSync(WORKSPACE_PATH)) {
|
|
37
|
+
for (const legacyPath of LEGACY_WORKSPACE_PATHS) {
|
|
38
|
+
if (!fs.existsSync(legacyPath)) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
42
|
+
fs.renameSync(legacyPath, WORKSPACE_PATH);
|
|
43
|
+
migratedWorkspace = true;
|
|
44
|
+
workspaceFrom = legacyPath;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
if (fs.existsSync('.agent-infra') && fs.readdirSync('.agent-infra').length === 0) {
|
|
51
|
+
fs.rmdirSync('.agent-infra');
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
// Ignore cleanup failures for partially migrated directories.
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { migratedConfig, migratedWorkspace, configFrom, workspaceFrom };
|
|
58
|
+
}
|
|
59
|
+
|
|
12
60
|
function syncFileRegistry(config) {
|
|
61
|
+
config.files ||= {};
|
|
62
|
+
const before = JSON.stringify({
|
|
63
|
+
files: {
|
|
64
|
+
managed: config.files.managed || [],
|
|
65
|
+
merged: config.files.merged || [],
|
|
66
|
+
ejected: config.files.ejected || []
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
config.files.managed = config.files.managed || [];
|
|
70
|
+
config.files.merged = config.files.merged || [];
|
|
71
|
+
config.files.ejected = config.files.ejected || [];
|
|
72
|
+
|
|
13
73
|
const allExisting = [
|
|
14
74
|
...config.files.managed,
|
|
15
75
|
...config.files.merged,
|
|
@@ -30,7 +90,15 @@ function syncFileRegistry(config) {
|
|
|
30
90
|
}
|
|
31
91
|
}
|
|
32
92
|
|
|
33
|
-
|
|
93
|
+
const after = JSON.stringify({
|
|
94
|
+
files: {
|
|
95
|
+
managed: config.files.managed,
|
|
96
|
+
merged: config.files.merged,
|
|
97
|
+
ejected: config.files.ejected
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return { added, changed: before !== after };
|
|
34
102
|
}
|
|
35
103
|
|
|
36
104
|
async function cmdUpdate() {
|
|
@@ -39,9 +107,18 @@ async function cmdUpdate() {
|
|
|
39
107
|
console.log(' ==================================');
|
|
40
108
|
console.log('');
|
|
41
109
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
110
|
+
const { migratedConfig, migratedWorkspace, configFrom, workspaceFrom } = migrateLegacyPaths();
|
|
111
|
+
|
|
112
|
+
if (migratedConfig) {
|
|
113
|
+
ok(`Migrated ${configFrom} -> ${CONFIG_PATH}`);
|
|
114
|
+
}
|
|
115
|
+
if (migratedWorkspace) {
|
|
116
|
+
ok(`Migrated ${workspaceFrom} -> ${WORKSPACE_PATH}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// check config exists
|
|
120
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
121
|
+
err(`No ${CONFIG_PATH} found in current directory.`);
|
|
45
122
|
err('Run "ai init" first to initialize the project.');
|
|
46
123
|
process.exitCode = 1;
|
|
47
124
|
return;
|
|
@@ -52,27 +129,12 @@ async function cmdUpdate() {
|
|
|
52
129
|
if (!templateDir) {
|
|
53
130
|
err('Template directory not found.');
|
|
54
131
|
err('Install via npm: npm install -g @fitlab-ai/agent-infra');
|
|
55
|
-
err('Or via clone: curl -fsSL https://raw.githubusercontent.com/fitlab-ai/agent-infra/main/install.sh | sh');
|
|
56
132
|
process.exitCode = 1;
|
|
57
133
|
return;
|
|
58
134
|
}
|
|
59
135
|
|
|
60
|
-
// auto-update: only for clone installs
|
|
61
|
-
if (isCloneInstall()) {
|
|
62
|
-
const installDir = resolveInstallDir();
|
|
63
|
-
if (fs.existsSync(path.join(installDir, '.git'))) {
|
|
64
|
-
info('Updating templates to latest version...');
|
|
65
|
-
try {
|
|
66
|
-
execSync('git pull --rebase --quiet', { cwd: installDir, stdio: 'pipe' });
|
|
67
|
-
ok('Templates updated.');
|
|
68
|
-
} catch {
|
|
69
|
-
err('Failed to update templates (network issue?). Using local version.');
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
136
|
// read project config
|
|
75
|
-
const config = JSON.parse(fs.readFileSync(
|
|
137
|
+
const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8'));
|
|
76
138
|
const { project, org, language } = config;
|
|
77
139
|
const replacements = { project, org };
|
|
78
140
|
|
|
@@ -130,20 +192,24 @@ async function cmdUpdate() {
|
|
|
130
192
|
ok('Updated .opencode/commands/update-agent-infra.md');
|
|
131
193
|
|
|
132
194
|
// sync file registry
|
|
133
|
-
const added = syncFileRegistry(config);
|
|
195
|
+
const { added, changed } = syncFileRegistry(config);
|
|
134
196
|
const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
|
|
135
197
|
|
|
136
|
-
if (
|
|
198
|
+
if (changed) {
|
|
137
199
|
console.log('');
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
200
|
+
if (hasNewEntries) {
|
|
201
|
+
info(`New file entries synced to ${CONFIG_PATH}:`);
|
|
202
|
+
for (const entry of added.managed) {
|
|
203
|
+
ok(` managed: ${entry}`);
|
|
204
|
+
}
|
|
205
|
+
for (const entry of added.merged) {
|
|
206
|
+
ok(` merged: ${entry}`);
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
info(`File registry changed in ${CONFIG_PATH}.`);
|
|
144
210
|
}
|
|
145
|
-
fs.writeFileSync(
|
|
146
|
-
ok(
|
|
211
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
212
|
+
ok(`Updated ${CONFIG_PATH}`);
|
|
147
213
|
}
|
|
148
214
|
|
|
149
215
|
// done
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fitlab-ai/agent-infra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Gemini CLI, and OpenCode",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
],
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "node scripts/build-inline.js",
|
|
45
|
+
"prepare": "git config core.hooksPath .github/hooks || true",
|
|
45
46
|
"test": "node scripts/build-inline.js --check && node --test tests/*.test.js",
|
|
46
47
|
"prepublishOnly": "node scripts/build-inline.js --check && node --test tests/*.test.js"
|
|
47
48
|
}
|