@accio-ai/cli 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 +3 -0
- package/assets/workctl-darwin-amd64.tar.gz +0 -0
- package/assets/workctl-darwin-arm64.tar.gz +0 -0
- package/assets/workctl-linux-amd64.tar.gz +0 -0
- package/assets/workctl-linux-arm64.tar.gz +0 -0
- package/assets/workctl-skills.zip +0 -0
- package/assets/workctl-windows-amd64.zip +0 -0
- package/assets/workctl-windows-arm64.zip +0 -0
- package/bin/workctl.js +26 -0
- package/install.js +167 -0
- package/package.json +32 -0
package/README.md
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/bin/workctl.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const childProcess = require("child_process");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
|
|
9
|
+
const binaryPath = path.join(__dirname, "..", "vendor", process.platform === "win32" ? "workctl.exe" : "workctl");
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(binaryPath)) {
|
|
12
|
+
console.error(`workctl binary not found at ${binaryPath}. Reinstall the package.`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const env = { ...process.env };
|
|
17
|
+
delete env.WORKCTL_MCP_URL;
|
|
18
|
+
delete env.WORKCTL_CATALOG_FIXTURE;
|
|
19
|
+
delete env.WORKCTL_RUNTIME_CONFIG;
|
|
20
|
+
|
|
21
|
+
const result = childProcess.spawnSync(binaryPath, process.argv.slice(2), {
|
|
22
|
+
env,
|
|
23
|
+
stdio: "inherit",
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const childProcess = require("child_process");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const os = require("os");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
|
|
10
|
+
const AGENT_DIRS = [
|
|
11
|
+
".agents/skills",
|
|
12
|
+
".claude/skills",
|
|
13
|
+
".cursor/skills",
|
|
14
|
+
".codex/skills",
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const PLATFORM_MAP = {
|
|
18
|
+
"darwin-x64": "workctl-darwin-amd64.tar.gz",
|
|
19
|
+
"darwin-arm64": "workctl-darwin-arm64.tar.gz",
|
|
20
|
+
"linux-x64": "workctl-linux-amd64.tar.gz",
|
|
21
|
+
"linux-arm64": "workctl-linux-arm64.tar.gz",
|
|
22
|
+
"win32-x64": "workctl-windows-amd64.zip",
|
|
23
|
+
"win32-arm64": "workctl-windows-arm64.zip",
|
|
24
|
+
};
|
|
25
|
+
function ensureDir(dir) {
|
|
26
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function run(command, args) {
|
|
30
|
+
childProcess.execFileSync(command, args, { stdio: "inherit" });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function ensureCleanDir(dir) {
|
|
34
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
35
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function copyChildren(srcDir, destDir) {
|
|
39
|
+
ensureDir(destDir);
|
|
40
|
+
for (const entry of fs.readdirSync(srcDir)) {
|
|
41
|
+
fs.cpSync(path.join(srcDir, entry), path.join(destDir, entry), { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function findBinary(root, names) {
|
|
46
|
+
const entries = fs.readdirSync(root, { withFileTypes: true });
|
|
47
|
+
for (const entry of entries) {
|
|
48
|
+
const entryPath = path.join(root, entry.name);
|
|
49
|
+
if (entry.isDirectory()) {
|
|
50
|
+
const nested = findBinary(entryPath, names);
|
|
51
|
+
if (nested) {
|
|
52
|
+
return nested;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (names.includes(entry.name)) {
|
|
57
|
+
return entryPath;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return "";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function extractArchiveBinary(archivePath, names, destPath, cleanDestDir) {
|
|
64
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "workctl-npm-bin-"));
|
|
65
|
+
try {
|
|
66
|
+
if (archivePath.endsWith(".tar.gz")) {
|
|
67
|
+
run("tar", ["-xzf", archivePath, "-C", tmpDir]);
|
|
68
|
+
} else if (process.platform === "win32") {
|
|
69
|
+
run("powershell.exe", [
|
|
70
|
+
"-NoLogo",
|
|
71
|
+
"-NoProfile",
|
|
72
|
+
"-Command",
|
|
73
|
+
`Expand-Archive -Path '${archivePath.replace(/'/g, "''")}' -DestinationPath '${tmpDir.replace(/'/g, "''")}' -Force`,
|
|
74
|
+
]);
|
|
75
|
+
} else {
|
|
76
|
+
run("unzip", ["-q", archivePath, "-d", tmpDir]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const binaryPath = findBinary(tmpDir, names);
|
|
80
|
+
if (!binaryPath) {
|
|
81
|
+
throw new Error(`expected binary not found in archive ${archivePath}`);
|
|
82
|
+
}
|
|
83
|
+
copyExecutable(binaryPath, destPath, cleanDestDir);
|
|
84
|
+
} finally {
|
|
85
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function copyExecutable(srcPath, destPath, cleanDestDir) {
|
|
90
|
+
if (cleanDestDir) {
|
|
91
|
+
ensureCleanDir(path.dirname(destPath));
|
|
92
|
+
} else {
|
|
93
|
+
ensureDir(path.dirname(destPath));
|
|
94
|
+
}
|
|
95
|
+
fs.copyFileSync(srcPath, destPath);
|
|
96
|
+
if (process.platform !== "win32") {
|
|
97
|
+
fs.chmodSync(destPath, 0o755);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function extractSkills(zipPath, destDir) {
|
|
102
|
+
ensureCleanDir(destDir);
|
|
103
|
+
if (process.platform === "win32") {
|
|
104
|
+
run("powershell.exe", [
|
|
105
|
+
"-NoLogo",
|
|
106
|
+
"-NoProfile",
|
|
107
|
+
"-Command",
|
|
108
|
+
`Expand-Archive -Path '${zipPath.replace(/'/g, "''")}' -DestinationPath '${destDir.replace(/'/g, "''")}' -Force`,
|
|
109
|
+
]);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
run("unzip", ["-q", zipPath, "-d", destDir]);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function installSkillsToHomes(skillRoot) {
|
|
116
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
117
|
+
if (!homeDir) return;
|
|
118
|
+
|
|
119
|
+
AGENT_DIRS.forEach((agentDir) => {
|
|
120
|
+
copyChildren(skillRoot, path.join(homeDir, agentDir, "workctl"));
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function main() {
|
|
125
|
+
const packageRoot = __dirname;
|
|
126
|
+
const assetsDir = path.join(packageRoot, "assets");
|
|
127
|
+
const vendorDir = path.join(packageRoot, "vendor");
|
|
128
|
+
const skillDir = path.join(packageRoot, "share", "skills", "workctl");
|
|
129
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
130
|
+
const configDir = process.env.WORKCTL_CONFIG_DIR || path.join(homeDir, ".workctl");
|
|
131
|
+
const assetName = PLATFORM_MAP[`${process.platform}-${process.arch}`];
|
|
132
|
+
if (!assetName) {
|
|
133
|
+
throw new Error(`unsupported platform: ${process.platform}/${process.arch}`);
|
|
134
|
+
}
|
|
135
|
+
if (!homeDir) {
|
|
136
|
+
throw new Error("home directory not available for installation");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const archivePath = path.join(assetsDir, assetName);
|
|
140
|
+
const skillsPath = path.join(assetsDir, "workctl-skills.zip");
|
|
141
|
+
if (!fs.existsSync(archivePath)) {
|
|
142
|
+
throw new Error(`missing platform archive: ${archivePath}`);
|
|
143
|
+
}
|
|
144
|
+
if (!fs.existsSync(skillsPath)) {
|
|
145
|
+
throw new Error(`missing skills archive: ${skillsPath}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
extractArchiveBinary(archivePath, ["workctl", "workctl.exe"], path.join(vendorDir, process.platform === "win32" ? "workctl.exe" : "workctl"), true);
|
|
149
|
+
extractSkills(skillsPath, skillDir);
|
|
150
|
+
installSkillsToHomes(skillDir);
|
|
151
|
+
|
|
152
|
+
// 清除缓存,确保用户立即看到最新命令
|
|
153
|
+
clearWorkctlCache(configDir);
|
|
154
|
+
|
|
155
|
+
console.log("\n✓ Installation complete!");
|
|
156
|
+
console.log(" Run 'workctl --help' to get started");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function clearWorkctlCache(configDir) {
|
|
160
|
+
const cacheDir = path.join(configDir, "cache");
|
|
161
|
+
if (fs.existsSync(cacheDir)) {
|
|
162
|
+
fs.rmSync(cacheDir, { recursive: true, force: true });
|
|
163
|
+
console.log("✓ Cleared cache for fresh command discovery");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
main();
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@accio-ai/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Work Agent CLI - AI-native command line interface",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://www.npmjs.com/package/@accio-ai/cli"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://www.npmjs.com/package/@accio-ai/cli",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://www.npmjs.com/package/@accio-ai/cli"
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"workctl": "./bin/workctl.js"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"postinstall": "node install.js"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"registry": "https://registry.npmjs.org"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"assets",
|
|
25
|
+
"bin",
|
|
26
|
+
"install.js",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=16"
|
|
31
|
+
}
|
|
32
|
+
}
|