@fitlab-ai/agent-infra 0.5.9 → 0.6.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 +200 -8
- package/README.zh-CN.md +176 -8
- package/bin/{cli.js → cli.ts} +23 -19
- package/dist/bin/cli.js +116 -0
- package/dist/lib/defaults.json +61 -0
- package/dist/lib/init.js +238 -0
- package/dist/lib/log.js +18 -0
- package/dist/lib/merge.js +747 -0
- package/dist/lib/paths.js +18 -0
- package/dist/lib/prompt.js +85 -0
- package/dist/lib/render.js +139 -0
- package/dist/lib/sandbox/commands/create.js +1173 -0
- package/dist/lib/sandbox/commands/enter.js +98 -0
- package/dist/lib/sandbox/commands/ls.js +93 -0
- package/dist/lib/sandbox/commands/rebuild.js +101 -0
- package/dist/lib/sandbox/commands/refresh.js +85 -0
- package/dist/lib/sandbox/commands/rm.js +226 -0
- package/dist/lib/sandbox/commands/vm.js +144 -0
- package/dist/lib/sandbox/config.js +85 -0
- package/dist/lib/sandbox/constants.js +104 -0
- package/dist/lib/sandbox/credentials.js +437 -0
- package/dist/lib/sandbox/dockerfile.js +76 -0
- package/dist/lib/sandbox/dotfiles.js +170 -0
- package/dist/lib/sandbox/engine.js +155 -0
- package/dist/lib/sandbox/engines/colima.js +64 -0
- package/dist/lib/sandbox/engines/docker-desktop.js +27 -0
- package/dist/lib/sandbox/engines/index.js +25 -0
- package/dist/lib/sandbox/engines/native.js +96 -0
- package/dist/lib/sandbox/engines/orbstack.js +63 -0
- package/dist/lib/sandbox/engines/selinux.js +48 -0
- package/dist/lib/sandbox/engines/wsl2-paths.js +47 -0
- package/dist/lib/sandbox/engines/wsl2.js +57 -0
- package/dist/lib/sandbox/index.js +70 -0
- package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +39 -0
- package/dist/lib/sandbox/runtimes/base.dockerfile +178 -0
- package/dist/lib/sandbox/runtimes/java17.dockerfile +3 -0
- package/dist/lib/sandbox/runtimes/java21.dockerfile +3 -0
- package/dist/lib/sandbox/runtimes/node20.dockerfile +3 -0
- package/dist/lib/sandbox/runtimes/node22.dockerfile +3 -0
- package/dist/lib/sandbox/runtimes/python3.dockerfile +3 -0
- package/dist/lib/sandbox/shell.js +148 -0
- package/dist/lib/sandbox/task-resolver.js +35 -0
- package/dist/lib/sandbox/tools.js +115 -0
- package/dist/lib/update.js +186 -0
- package/dist/lib/version.js +5 -0
- package/dist/package.json +5 -0
- package/lib/{init.js → init.ts} +64 -20
- package/lib/{log.js → log.ts} +4 -4
- package/lib/{merge.js → merge.ts} +129 -63
- package/lib/paths.ts +18 -0
- package/lib/{prompt.js → prompt.ts} +12 -12
- package/lib/{render.js → render.ts} +30 -17
- package/lib/sandbox/commands/create.ts +1507 -0
- package/lib/sandbox/commands/enter.ts +115 -0
- package/lib/sandbox/commands/{ls.js → ls.ts} +41 -10
- package/lib/sandbox/commands/rebuild.ts +135 -0
- package/lib/sandbox/commands/refresh.ts +128 -0
- package/lib/sandbox/commands/{rm.js → rm.ts} +71 -21
- package/lib/sandbox/commands/{vm.js → vm.ts} +62 -15
- package/lib/sandbox/config.ts +133 -0
- package/lib/sandbox/{constants.js → constants.ts} +41 -17
- package/lib/sandbox/credentials.ts +634 -0
- package/lib/sandbox/{dockerfile.js → dockerfile.ts} +13 -6
- package/lib/sandbox/dotfiles.ts +236 -0
- package/lib/sandbox/engine.ts +231 -0
- package/lib/sandbox/engines/colima.ts +81 -0
- package/lib/sandbox/engines/docker-desktop.ts +36 -0
- package/lib/sandbox/engines/index.ts +74 -0
- package/lib/sandbox/engines/native.ts +131 -0
- package/lib/sandbox/engines/orbstack.ts +78 -0
- package/lib/sandbox/engines/selinux.ts +66 -0
- package/lib/sandbox/engines/wsl2-paths.ts +65 -0
- package/lib/sandbox/engines/wsl2.ts +74 -0
- package/lib/sandbox/{index.js → index.ts} +17 -8
- package/lib/sandbox/runtimes/ai-tools.dockerfile +14 -1
- package/lib/sandbox/runtimes/base.dockerfile +116 -1
- package/lib/sandbox/shell.ts +186 -0
- package/lib/sandbox/{task-resolver.js → task-resolver.ts} +6 -6
- package/lib/sandbox/{tools.js → tools.ts} +33 -29
- package/lib/{update.js → update.ts} +33 -10
- package/package.json +22 -12
- package/templates/.agents/rules/create-issue.github.en.md +2 -4
- package/templates/.agents/rules/create-issue.github.zh-CN.md +2 -4
- package/templates/.agents/rules/issue-pr-commands.github.en.md +29 -0
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +29 -0
- package/templates/.agents/scripts/{platform-adapters/find-existing-task.github.js → find-existing-task.js} +22 -79
- package/templates/.agents/scripts/platform-adapters/platform-sync.github.js +26 -41
- package/templates/.agents/skills/create-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +6 -8
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +6 -8
- package/lib/paths.js +0 -9
- package/lib/sandbox/commands/create.js +0 -1174
- package/lib/sandbox/commands/enter.js +0 -79
- package/lib/sandbox/commands/rebuild.js +0 -102
- package/lib/sandbox/config.js +0 -84
- package/lib/sandbox/engine.js +0 -256
- package/lib/sandbox/shell.js +0 -122
- package/templates/.agents/scripts/platform-adapters/find-existing-task.js +0 -5
- /package/lib/{version.js → version.ts} +0 -0
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
import { VERSION } from "../lib/version.js";
|
|
11
|
+
// Node.js version check
|
|
12
|
+
const [major = 0] = process.versions.node.split('.').map((part) => parseInt(part, 10));
|
|
13
|
+
if (major < 22) {
|
|
14
|
+
process.stderr.write(`agent-infra requires Node.js >= 22 (current: ${process.version})\n`);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const USAGE = `agent-infra - bootstrap AI collaboration infrastructure
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
agent-infra init Initialize a new project with update-agent-infra seed command
|
|
21
|
+
agent-infra merge Merge tasks from another workspace directory (active/blocked/completed/archive)
|
|
22
|
+
agent-infra update Update seed files and sync file registry for an existing project
|
|
23
|
+
agent-infra sandbox Manage Docker-based AI sandboxes
|
|
24
|
+
agent-infra version Show version
|
|
25
|
+
agent-infra help Show this help message
|
|
26
|
+
|
|
27
|
+
Shorthand: ai (e.g. ai init)
|
|
28
|
+
|
|
29
|
+
Install methods:
|
|
30
|
+
npm: npm install -g @fitlab-ai/agent-infra
|
|
31
|
+
npx: npx @fitlab-ai/agent-infra init
|
|
32
|
+
brew: brew install fitlab-ai/tap/agent-infra (macOS)
|
|
33
|
+
curl: curl -fsSL https://raw.githubusercontent.com/fitlab-ai/agent-infra/main/install.sh | sh (runs npm install -g internally)
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
cd my-project && agent-infra init
|
|
37
|
+
npx @fitlab-ai/agent-infra init
|
|
38
|
+
`;
|
|
39
|
+
const command = process.argv[2] || '';
|
|
40
|
+
function errorMessage(error) {
|
|
41
|
+
return error instanceof Error ? error.message : String(error);
|
|
42
|
+
}
|
|
43
|
+
async function importCommand(importPath) {
|
|
44
|
+
try {
|
|
45
|
+
return await import(__rewriteRelativeImportExtension(importPath));
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error && typeof error === 'object' && 'code' in error && error.code === 'ERR_MODULE_NOT_FOUND') {
|
|
49
|
+
process.stderr.write('Error: Missing npm dependency. Run npm install before using agent-infra from a development checkout.\n');
|
|
50
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
51
|
+
process.exitCode = 1;
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
switch (command) {
|
|
58
|
+
case 'init': {
|
|
59
|
+
const imported = await importCommand('../lib/init.ts');
|
|
60
|
+
if (!imported)
|
|
61
|
+
break;
|
|
62
|
+
const { cmdInit } = imported;
|
|
63
|
+
await cmdInit().catch((e) => {
|
|
64
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
65
|
+
process.exitCode = 1;
|
|
66
|
+
});
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
case 'update': {
|
|
70
|
+
const imported = await importCommand('../lib/update.ts');
|
|
71
|
+
if (!imported)
|
|
72
|
+
break;
|
|
73
|
+
const { cmdUpdate } = imported;
|
|
74
|
+
await cmdUpdate().catch((e) => {
|
|
75
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
76
|
+
process.exitCode = 1;
|
|
77
|
+
});
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case 'merge': {
|
|
81
|
+
const imported = await importCommand('../lib/merge.ts');
|
|
82
|
+
if (!imported)
|
|
83
|
+
break;
|
|
84
|
+
const { cmdMerge } = imported;
|
|
85
|
+
await cmdMerge(process.argv.slice(3)).catch((e) => {
|
|
86
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
87
|
+
process.exitCode = 1;
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'sandbox': {
|
|
92
|
+
const imported = await importCommand('../lib/sandbox/index.ts');
|
|
93
|
+
if (!imported)
|
|
94
|
+
break;
|
|
95
|
+
const { runSandbox } = imported;
|
|
96
|
+
await runSandbox(process.argv.slice(3)).catch((e) => {
|
|
97
|
+
process.stderr.write(`Error: ${errorMessage(e)}\n`);
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
});
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case 'version': {
|
|
103
|
+
console.log(`agent-infra ${VERSION}`);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case 'help':
|
|
107
|
+
case '':
|
|
108
|
+
process.stdout.write(USAGE);
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
process.stderr.write(`Unknown command: ${command}\n\n`);
|
|
112
|
+
process.stdout.write(USAGE);
|
|
113
|
+
process.exitCode = 1;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platform": {
|
|
3
|
+
"type": "github"
|
|
4
|
+
},
|
|
5
|
+
"sandbox": {
|
|
6
|
+
"engine": null,
|
|
7
|
+
"runtimes": [
|
|
8
|
+
"node20"
|
|
9
|
+
],
|
|
10
|
+
"tools": [
|
|
11
|
+
"claude-code",
|
|
12
|
+
"codex",
|
|
13
|
+
"opencode",
|
|
14
|
+
"gemini-cli"
|
|
15
|
+
],
|
|
16
|
+
"dockerfile": null,
|
|
17
|
+
"vm": {
|
|
18
|
+
"cpu": null,
|
|
19
|
+
"memory": null,
|
|
20
|
+
"disk": null
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"labels": {
|
|
24
|
+
"in": {}
|
|
25
|
+
},
|
|
26
|
+
"files": {
|
|
27
|
+
"managed": [
|
|
28
|
+
".agents/QUICKSTART.md",
|
|
29
|
+
".agents/README.md",
|
|
30
|
+
".agents/rules/",
|
|
31
|
+
".agents/scripts/",
|
|
32
|
+
".agents/skills/",
|
|
33
|
+
".agents/templates/",
|
|
34
|
+
".agents/workflows/",
|
|
35
|
+
".agents/workspace/README.md",
|
|
36
|
+
".claude/commands/",
|
|
37
|
+
".claude/hooks/",
|
|
38
|
+
".gemini/commands/",
|
|
39
|
+
".git-hooks/check-version-format.sh",
|
|
40
|
+
".github/scripts/",
|
|
41
|
+
".opencode/commands/"
|
|
42
|
+
],
|
|
43
|
+
"merged": [
|
|
44
|
+
"**/post-release.*",
|
|
45
|
+
"**/release.*",
|
|
46
|
+
"**/test-integration.*",
|
|
47
|
+
"**/test.*",
|
|
48
|
+
"**/upgrade-dependency.*",
|
|
49
|
+
".agents/skills/post-release/SKILL.*",
|
|
50
|
+
".agents/skills/release/SKILL.*",
|
|
51
|
+
".agents/skills/test-integration/SKILL.*",
|
|
52
|
+
".agents/skills/test/SKILL.*",
|
|
53
|
+
".agents/skills/upgrade-dependency/SKILL.*",
|
|
54
|
+
".claude/settings.json",
|
|
55
|
+
".gemini/settings.json",
|
|
56
|
+
".git-hooks/pre-commit",
|
|
57
|
+
".gitignore"
|
|
58
|
+
],
|
|
59
|
+
"ejected": []
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/lib/init.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { execSync } from 'node:child_process';
|
|
4
|
+
import { platform } from 'node:os';
|
|
5
|
+
import { info, ok, err } from "./log.js";
|
|
6
|
+
import { prompt, select, closePrompt } from "./prompt.js";
|
|
7
|
+
import { resolveTemplateDir } from "./paths.js";
|
|
8
|
+
import { renderFile, copySkillDir, KNOWN_PLATFORMS } from "./render.js";
|
|
9
|
+
import { enginesForPlatform } from "./sandbox/engines/index.js";
|
|
10
|
+
import { VERSION } from "./version.js";
|
|
11
|
+
const defaults = JSON.parse(fs.readFileSync(new URL('./defaults.json', import.meta.url), 'utf8'));
|
|
12
|
+
const PLATFORM_DEFAULT_ENGINES = Object.freeze({
|
|
13
|
+
linux: 'native',
|
|
14
|
+
darwin: 'colima',
|
|
15
|
+
win32: 'wsl2'
|
|
16
|
+
});
|
|
17
|
+
function isPathOwnedByOtherPlatform(relativePath, platformType) {
|
|
18
|
+
const top = String(relativePath || '').replace(/\\/g, '/').replace(/^\.\//, '').split('/')[0] ?? '';
|
|
19
|
+
if (!top.startsWith('.'))
|
|
20
|
+
return false;
|
|
21
|
+
const candidate = top.slice(1);
|
|
22
|
+
if (!KNOWN_PLATFORMS.has(candidate))
|
|
23
|
+
return false;
|
|
24
|
+
return candidate !== platformType;
|
|
25
|
+
}
|
|
26
|
+
function buildDefaultFiles(platformType) {
|
|
27
|
+
return {
|
|
28
|
+
managed: (defaults.files.managed || []).filter((entry) => !isPathOwnedByOtherPlatform(entry, platformType)),
|
|
29
|
+
merged: (defaults.files.merged || []).filter((entry) => !isPathOwnedByOtherPlatform(entry, platformType)),
|
|
30
|
+
ejected: structuredClone(defaults.files.ejected || [])
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function detectProjectName() {
|
|
34
|
+
try {
|
|
35
|
+
const url = execSync('git remote get-url origin', { stdio: ['pipe', 'pipe', 'pipe'] })
|
|
36
|
+
.toString().trim().replace(/\.git$/, '');
|
|
37
|
+
return path.basename(url);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return path.basename(process.cwd());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function detectOrgName() {
|
|
44
|
+
try {
|
|
45
|
+
const url = execSync('git remote get-url origin', { stdio: ['pipe', 'pipe', 'pipe'] })
|
|
46
|
+
.toString().trim().replace(/\.git$/, '');
|
|
47
|
+
// SSH: git@github.com:org/repo → org
|
|
48
|
+
// HTTPS: https://github.com/org/repo → org
|
|
49
|
+
const sshMatch = url.match(/:([^/]+)\//);
|
|
50
|
+
if (sshMatch?.[1])
|
|
51
|
+
return sshMatch[1];
|
|
52
|
+
const httpsMatch = url.match(/\/\/[^/]+\/([^/]+)\//);
|
|
53
|
+
if (httpsMatch?.[1])
|
|
54
|
+
return httpsMatch[1];
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// no remote
|
|
58
|
+
}
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
const VALID_NAME_RE = /^[a-zA-Z0-9_.@-]+$/;
|
|
62
|
+
function parseLocalSources(input) {
|
|
63
|
+
return input
|
|
64
|
+
.split(',')
|
|
65
|
+
.map((entry) => entry.trim())
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.map((entry) => ({ type: 'local', path: entry }));
|
|
68
|
+
}
|
|
69
|
+
async function cmdInit() {
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log(' agent-infra init');
|
|
72
|
+
console.log(' ================================');
|
|
73
|
+
console.log(' Optional template and skill sources can be added now or later in .agents/.airc.json.');
|
|
74
|
+
console.log('');
|
|
75
|
+
// resolve templates
|
|
76
|
+
const templateDir = resolveTemplateDir();
|
|
77
|
+
if (!templateDir) {
|
|
78
|
+
err('Template directory not found.');
|
|
79
|
+
err('Install via npm: npm install -g @fitlab-ai/agent-infra');
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const configPath = path.join('.agents', '.airc.json');
|
|
84
|
+
// check existing config
|
|
85
|
+
if (fs.existsSync(configPath)) {
|
|
86
|
+
err('This project already has agent-infra configuration.');
|
|
87
|
+
err('Use /update-agent-infra in your AI TUI to update.');
|
|
88
|
+
process.exitCode = 1;
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// collect project info
|
|
92
|
+
const defaultProject = detectProjectName();
|
|
93
|
+
const projectName = await prompt('Project name', defaultProject);
|
|
94
|
+
if (!projectName) {
|
|
95
|
+
err('Project name is required.');
|
|
96
|
+
closePrompt();
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (!VALID_NAME_RE.test(projectName)) {
|
|
101
|
+
err('Project name may only contain letters, digits, hyphens, underscores, dots, and @.');
|
|
102
|
+
err(`Got: ${projectName}`);
|
|
103
|
+
closePrompt();
|
|
104
|
+
process.exitCode = 1;
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const defaultOrg = detectOrgName();
|
|
108
|
+
const orgName = await prompt('Organization / owner (optional)', defaultOrg);
|
|
109
|
+
if (orgName && !VALID_NAME_RE.test(orgName)) {
|
|
110
|
+
err('Organization name may only contain letters, digits, hyphens, underscores, dots, and @.');
|
|
111
|
+
err(`Got: ${orgName}`);
|
|
112
|
+
closePrompt();
|
|
113
|
+
process.exitCode = 1;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
let language = await prompt('Language (en / zh)', 'zh');
|
|
117
|
+
if (language === 'zh')
|
|
118
|
+
language = 'zh-CN';
|
|
119
|
+
if (language !== 'en' && language !== 'zh-CN') {
|
|
120
|
+
closePrompt();
|
|
121
|
+
err(`Language must be 'en' or 'zh'. Got: ${language}`);
|
|
122
|
+
process.exitCode = 1;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const currentPlatform = platform();
|
|
126
|
+
const defaultEngine = PLATFORM_DEFAULT_ENGINES[currentPlatform];
|
|
127
|
+
const engineChoices = enginesForPlatform(currentPlatform).sort((left, right) => {
|
|
128
|
+
if (left === defaultEngine)
|
|
129
|
+
return -1;
|
|
130
|
+
if (right === defaultEngine)
|
|
131
|
+
return 1;
|
|
132
|
+
return 0;
|
|
133
|
+
});
|
|
134
|
+
let sandboxEngine = null;
|
|
135
|
+
if (engineChoices.length > 0) {
|
|
136
|
+
sandboxEngine = await select(`Sandbox engine (${currentPlatform})`, engineChoices, defaultEngine);
|
|
137
|
+
}
|
|
138
|
+
const platformChoices = [...KNOWN_PLATFORMS, 'other'];
|
|
139
|
+
let platformType = await select('Platform', platformChoices, 'github');
|
|
140
|
+
if (platformType === 'other') {
|
|
141
|
+
platformType = (await prompt('Custom platform type', '')).trim();
|
|
142
|
+
if (!platformType) {
|
|
143
|
+
closePrompt();
|
|
144
|
+
err('Custom platform type is required.');
|
|
145
|
+
process.exitCode = 1;
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!/^[a-z0-9][a-z0-9-]*$/.test(platformType)) {
|
|
150
|
+
closePrompt();
|
|
151
|
+
err(`Platform type must match /^[a-z0-9][a-z0-9-]*$/. Got: ${platformType}`);
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (!KNOWN_PLATFORMS.has(platformType)) {
|
|
156
|
+
info(`Custom platform '${platformType}' selected. Built-in templates are only complete for github;`
|
|
157
|
+
+ ` provide matching '.${platformType}.' or generic templates before running update-agent-infra.`);
|
|
158
|
+
}
|
|
159
|
+
const templateSources = parseLocalSources(await prompt('Template sources (optional, comma-separated local paths, e.g. ~/my-templates; Enter to skip)', ''));
|
|
160
|
+
const skillSources = parseLocalSources(await prompt('Skill sources (optional, comma-separated local paths, e.g. ~/my-skills; Enter to skip)', ''));
|
|
161
|
+
closePrompt();
|
|
162
|
+
const project = projectName;
|
|
163
|
+
const replacements = { project, org: orgName };
|
|
164
|
+
console.log('');
|
|
165
|
+
if (orgName) {
|
|
166
|
+
info(`Installing update-agent-infra seed command for: ${projectName} (${orgName})`);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
info(`Installing update-agent-infra seed command for: ${projectName}`);
|
|
170
|
+
}
|
|
171
|
+
console.log('');
|
|
172
|
+
// select language-specific template filenames
|
|
173
|
+
let claudeSrc, geminiSrc, opencodeSrc;
|
|
174
|
+
if (language === 'zh-CN') {
|
|
175
|
+
claudeSrc = 'update-agent-infra.zh-CN.md';
|
|
176
|
+
geminiSrc = 'update-agent-infra.zh-CN.toml';
|
|
177
|
+
opencodeSrc = 'update-agent-infra.zh-CN.md';
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
claudeSrc = 'update-agent-infra.en.md';
|
|
181
|
+
geminiSrc = 'update-agent-infra.en.toml';
|
|
182
|
+
opencodeSrc = 'update-agent-infra.en.md';
|
|
183
|
+
}
|
|
184
|
+
// install skill
|
|
185
|
+
copySkillDir(path.join(templateDir, '.agents', 'skills', 'update-agent-infra'), path.join('.agents', 'skills', 'update-agent-infra'), replacements, language, platformType);
|
|
186
|
+
ok('Installed .agents/skills/update-agent-infra/');
|
|
187
|
+
// install Claude command
|
|
188
|
+
renderFile(path.join(templateDir, '.claude', 'commands', claudeSrc), path.join('.claude', 'commands', 'update-agent-infra.md'), replacements);
|
|
189
|
+
ok('Installed .claude/commands/update-agent-infra.md');
|
|
190
|
+
// install Gemini command
|
|
191
|
+
renderFile(path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc), path.join('.gemini', 'commands', project, 'update-agent-infra.toml'), replacements);
|
|
192
|
+
ok(`Installed .gemini/commands/${project}/update-agent-infra.toml`);
|
|
193
|
+
// install OpenCode command
|
|
194
|
+
renderFile(path.join(templateDir, '.opencode', 'commands', opencodeSrc), path.join('.opencode', 'commands', 'update-agent-infra.md'), replacements);
|
|
195
|
+
ok('Installed .opencode/commands/update-agent-infra.md');
|
|
196
|
+
// generate .agents/.airc.json
|
|
197
|
+
const config = {
|
|
198
|
+
project: projectName,
|
|
199
|
+
org: orgName,
|
|
200
|
+
language,
|
|
201
|
+
platform: { type: platformType },
|
|
202
|
+
templateVersion: VERSION,
|
|
203
|
+
sandbox: structuredClone(defaults.sandbox),
|
|
204
|
+
labels: structuredClone(defaults.labels),
|
|
205
|
+
files: buildDefaultFiles(platformType)
|
|
206
|
+
};
|
|
207
|
+
if (sandboxEngine) {
|
|
208
|
+
config.sandbox.engine = sandboxEngine;
|
|
209
|
+
}
|
|
210
|
+
if (templateSources.length > 0) {
|
|
211
|
+
config.templates = {
|
|
212
|
+
sources: templateSources
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (skillSources.length > 0) {
|
|
216
|
+
config.skills = {
|
|
217
|
+
sources: skillSources
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
221
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
|
|
222
|
+
ok(`Generated ${configPath}`);
|
|
223
|
+
// done
|
|
224
|
+
console.log('');
|
|
225
|
+
ok('Project initialized successfully!');
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(' Next step: open this project in any AI TUI and run:');
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log(' Claude Code / OpenCode: /update-agent-infra');
|
|
230
|
+
console.log(` Gemini CLI: /${project}:update-agent-infra`);
|
|
231
|
+
console.log(' Codex CLI: $update-agent-infra');
|
|
232
|
+
console.log('');
|
|
233
|
+
console.log(' This will render all templates and set up the full');
|
|
234
|
+
console.log(' AI collaboration infrastructure.');
|
|
235
|
+
console.log('');
|
|
236
|
+
}
|
|
237
|
+
export { cmdInit };
|
|
238
|
+
//# sourceMappingURL=init.js.map
|
package/dist/lib/log.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
function info(...args) {
|
|
3
|
+
const msg = args.join(' ');
|
|
4
|
+
process.stdout.write(` ${pc.bold(pc.blue('>'))} ${msg}\n`);
|
|
5
|
+
}
|
|
6
|
+
function ok(...args) {
|
|
7
|
+
const msg = args.join(' ');
|
|
8
|
+
process.stdout.write(` ${pc.bold(pc.green('\u2713'))} ${msg}\n`);
|
|
9
|
+
}
|
|
10
|
+
function err(...args) {
|
|
11
|
+
const msg = args.join(' ');
|
|
12
|
+
process.stderr.write(` ${pc.bold(pc.red('\u2717'))} ${msg}\n`);
|
|
13
|
+
}
|
|
14
|
+
function ask(text) {
|
|
15
|
+
process.stdout.write(` ${pc.bold(pc.yellow('?'))} ${text}`);
|
|
16
|
+
}
|
|
17
|
+
export { info, ok, err, ask };
|
|
18
|
+
//# sourceMappingURL=log.js.map
|