helloagents 1.0.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.
Files changed (36) hide show
  1. package/Claude/Skills/CN/CLAUDE.md +998 -0
  2. package/Claude/Skills/CN/skills/helloagents/analyze/SKILL.md +187 -0
  3. package/Claude/Skills/CN/skills/helloagents/design/SKILL.md +261 -0
  4. package/Claude/Skills/CN/skills/helloagents/develop/SKILL.md +352 -0
  5. package/Claude/Skills/CN/skills/helloagents/kb/SKILL.md +249 -0
  6. package/Claude/Skills/CN/skills/helloagents/templates/SKILL.md +451 -0
  7. package/Claude/Skills/EN/CLAUDE.md +998 -0
  8. package/Claude/Skills/EN/skills/helloagents/analyze/SKILL.md +187 -0
  9. package/Claude/Skills/EN/skills/helloagents/design/SKILL.md +261 -0
  10. package/Claude/Skills/EN/skills/helloagents/develop/SKILL.md +352 -0
  11. package/Claude/Skills/EN/skills/helloagents/kb/SKILL.md +249 -0
  12. package/Claude/Skills/EN/skills/helloagents/templates/SKILL.md +451 -0
  13. package/Codex/Skills/CN/AGENTS.md +998 -0
  14. package/Codex/Skills/CN/skills/helloagents/analyze/SKILL.md +187 -0
  15. package/Codex/Skills/CN/skills/helloagents/design/SKILL.md +261 -0
  16. package/Codex/Skills/CN/skills/helloagents/develop/SKILL.md +352 -0
  17. package/Codex/Skills/CN/skills/helloagents/kb/SKILL.md +249 -0
  18. package/Codex/Skills/CN/skills/helloagents/templates/SKILL.md +451 -0
  19. package/Codex/Skills/EN/AGENTS.md +998 -0
  20. package/Codex/Skills/EN/skills/helloagents/analyze/SKILL.md +187 -0
  21. package/Codex/Skills/EN/skills/helloagents/design/SKILL.md +261 -0
  22. package/Codex/Skills/EN/skills/helloagents/develop/SKILL.md +352 -0
  23. package/Codex/Skills/EN/skills/helloagents/kb/SKILL.md +249 -0
  24. package/Codex/Skills/EN/skills/helloagents/templates/SKILL.md +451 -0
  25. package/README.md +840 -0
  26. package/bin/cli.js +85 -0
  27. package/lib/args.js +106 -0
  28. package/lib/backup.js +81 -0
  29. package/lib/conflict.js +118 -0
  30. package/lib/copy.js +125 -0
  31. package/lib/defaults.js +47 -0
  32. package/lib/index.js +297 -0
  33. package/lib/output.js +220 -0
  34. package/lib/prompts.js +173 -0
  35. package/lib/utils.js +225 -0
  36. package/package.json +38 -0
package/lib/utils.js ADDED
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Utils - Utility functions with dependency injection support
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const fs = require('fs');
8
+ const fsPromises = require('fs').promises;
9
+ const path = require('path');
10
+ const os = require('os');
11
+
12
+ /**
13
+ * Get home directory (injectable for testing)
14
+ * @param {Object} deps - Dependencies
15
+ * @returns {string} Home directory path
16
+ */
17
+ function getHomeDir(deps = {}) {
18
+ if (deps.homeDir) {
19
+ return deps.homeDir;
20
+ }
21
+ return os.homedir();
22
+ }
23
+
24
+ /**
25
+ * Get timestamp string (injectable for testing)
26
+ * @param {Object} deps - Dependencies
27
+ * @returns {string} Timestamp in YYYYMMDD-HHmmss format
28
+ */
29
+ function getTimestamp(deps = {}) {
30
+ const now = deps.now ? deps.now() : new Date();
31
+ const year = now.getFullYear();
32
+ const month = String(now.getMonth() + 1).padStart(2, '0');
33
+ const day = String(now.getDate()).padStart(2, '0');
34
+ const hours = String(now.getHours()).padStart(2, '0');
35
+ const minutes = String(now.getMinutes()).padStart(2, '0');
36
+ const seconds = String(now.getSeconds()).padStart(2, '0');
37
+ return `${year}${month}${day}-${hours}${minutes}${seconds}`;
38
+ }
39
+
40
+ /**
41
+ * Generate random suffix (injectable for testing)
42
+ * @param {Object} deps - Dependencies
43
+ * @returns {string} Random 6-character string
44
+ */
45
+ function randomSuffix(deps = {}) {
46
+ if (deps.randomSuffix) {
47
+ return deps.randomSuffix();
48
+ }
49
+ return Math.random().toString(36).slice(2, 8);
50
+ }
51
+
52
+ /**
53
+ * Check if file exists
54
+ * @param {string} filePath - Path to check
55
+ * @param {Object} deps - Dependencies
56
+ * @returns {Promise<boolean>}
57
+ */
58
+ async function fileExists(filePath, deps = {}) {
59
+ const fsModule = deps.fs || fsPromises;
60
+ try {
61
+ const stat = await fsModule.stat(filePath);
62
+ return stat.isFile();
63
+ } catch (err) {
64
+ if (err.code === 'ENOENT') {
65
+ return false;
66
+ }
67
+ throw err;
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Check if directory exists
73
+ * @param {string} dirPath - Path to check
74
+ * @param {Object} deps - Dependencies
75
+ * @returns {Promise<boolean>}
76
+ */
77
+ async function dirExists(dirPath, deps = {}) {
78
+ const fsModule = deps.fs || fsPromises;
79
+ try {
80
+ const stat = await fsModule.stat(dirPath);
81
+ return stat.isDirectory();
82
+ } catch (err) {
83
+ if (err.code === 'ENOENT') {
84
+ return false;
85
+ }
86
+ throw err;
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Read file content
92
+ * @param {string} filePath - Path to read
93
+ * @param {Object} deps - Dependencies
94
+ * @returns {Promise<string>}
95
+ */
96
+ async function readFileContent(filePath, deps = {}) {
97
+ const fsModule = deps.fs || fsPromises;
98
+ return fsModule.readFile(filePath, 'utf8');
99
+ }
100
+
101
+ /**
102
+ * Recursive delete (compatible with Node 14)
103
+ * @param {string} targetPath - Path to delete
104
+ * @param {Object} deps - Dependencies
105
+ * @returns {Promise<void>}
106
+ */
107
+ async function rmrf(targetPath, deps = {}) {
108
+ const fsModule = deps.fs || fsPromises;
109
+
110
+ // Check if path exists
111
+ try {
112
+ await fsModule.stat(targetPath);
113
+ } catch (err) {
114
+ if (err.code === 'ENOENT') {
115
+ return; // Already doesn't exist
116
+ }
117
+ throw err;
118
+ }
119
+
120
+ // Try fs.rm first (Node 14.14+)
121
+ if (fsModule.rm) {
122
+ try {
123
+ await fsModule.rm(targetPath, { recursive: true, force: true });
124
+ return;
125
+ } catch (err) {
126
+ // Fall through to rmdir
127
+ }
128
+ }
129
+
130
+ // Fallback to fs.rmdir with recursive (Node 14.0+)
131
+ if (fsModule.rmdir) {
132
+ await fsModule.rmdir(targetPath, { recursive: true });
133
+ return;
134
+ }
135
+
136
+ // Manual recursive delete as last resort
137
+ const stat = await fsModule.stat(targetPath);
138
+ if (stat.isDirectory()) {
139
+ const entries = await fsModule.readdir(targetPath);
140
+ for (const entry of entries) {
141
+ await rmrf(path.join(targetPath, entry), deps);
142
+ }
143
+ await fsModule.rmdir(targetPath);
144
+ } else {
145
+ await fsModule.unlink(targetPath);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Ensure directory exists (create if not)
151
+ * @param {string} dirPath - Directory path
152
+ * @param {Object} deps - Dependencies
153
+ * @returns {Promise<void>}
154
+ */
155
+ async function ensureDir(dirPath, deps = {}) {
156
+ const fsModule = deps.fs || fsPromises;
157
+ try {
158
+ await fsModule.mkdir(dirPath, { recursive: true });
159
+ } catch (err) {
160
+ if (err.code !== 'EEXIST') {
161
+ throw err;
162
+ }
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Get package root directory (where package.json is)
168
+ * @returns {string}
169
+ */
170
+ function getPackageRoot() {
171
+ return path.resolve(__dirname, '..');
172
+ }
173
+
174
+ /**
175
+ * Get source path for platform and language
176
+ * @param {string} platform - 'claude' or 'codex'
177
+ * @param {string} lang - 'cn' or 'en'
178
+ * @returns {Object} { configFile, skillsDir }
179
+ */
180
+ function getSourcePaths(platform, lang) {
181
+ const root = getPackageRoot();
182
+ const platformDir = platform === 'claude' ? 'Claude' : 'Codex';
183
+ const langDir = lang === 'cn' ? 'CN' : 'EN';
184
+ const configFileName = platform === 'claude' ? 'CLAUDE.md' : 'AGENTS.md';
185
+
186
+ return {
187
+ configFile: path.join(root, platformDir, 'Skills', langDir, configFileName),
188
+ skillsDir: path.join(root, platformDir, 'Skills', langDir, 'skills', 'helloagents'),
189
+ };
190
+ }
191
+
192
+ /**
193
+ * Get target path for platform
194
+ * @param {string} platform - 'claude' or 'codex'
195
+ * @param {Object} deps - Dependencies
196
+ * @returns {Object} { targetDir, configFile, skillsDir, newFile }
197
+ */
198
+ function getTargetPaths(platform, deps = {}) {
199
+ const homeDir = getHomeDir(deps);
200
+ const targetDir = platform === 'claude'
201
+ ? path.join(homeDir, '.claude')
202
+ : path.join(homeDir, '.codex');
203
+ const configFileName = platform === 'claude' ? 'CLAUDE.md' : 'AGENTS.md';
204
+
205
+ return {
206
+ targetDir,
207
+ configFile: path.join(targetDir, configFileName),
208
+ skillsDir: path.join(targetDir, 'skills', 'helloagents'),
209
+ newFile: path.join(targetDir, '.helloagents.new'),
210
+ };
211
+ }
212
+
213
+ module.exports = {
214
+ getHomeDir,
215
+ getTimestamp,
216
+ randomSuffix,
217
+ fileExists,
218
+ dirExists,
219
+ readFileContent,
220
+ rmrf,
221
+ ensureDir,
222
+ getPackageRoot,
223
+ getSourcePaths,
224
+ getTargetPaths,
225
+ };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "helloagents",
3
+ "version": "1.0.0",
4
+ "description": "CLI tool to configure HelloAGENTS for Claude Code and Codex",
5
+ "bin": {
6
+ "helloagents": "bin/cli.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "lib/",
11
+ "Claude/",
12
+ "Codex/"
13
+ ],
14
+ "scripts": {
15
+ "test": "node test/run.js"
16
+ },
17
+ "engines": {
18
+ "node": ">=14.0.0"
19
+ },
20
+ "keywords": [
21
+ "cli",
22
+ "claude",
23
+ "codex",
24
+ "ai",
25
+ "agents",
26
+ "helloagents"
27
+ ],
28
+ "author": "",
29
+ "license": "Apache-2.0",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/hellowind777/helloagents.git"
33
+ },
34
+ "homepage": "https://github.com/hellowind777/helloagents#readme",
35
+ "bugs": {
36
+ "url": "https://github.com/hellowind777/helloagents/issues"
37
+ }
38
+ }