apero-kit-cli 1.7.1 → 2.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/bin/ak.js +1 -90
- package/dist/index.js +2480 -0
- package/dist/index.js.map +1 -0
- package/package.json +20 -10
- package/src/commands/add.js +0 -126
- package/src/commands/doctor.js +0 -129
- package/src/commands/help.js +0 -1412
- package/src/commands/init.js +0 -263
- package/src/commands/list.js +0 -190
- package/src/commands/status.js +0 -113
- package/src/commands/update.js +0 -183
- package/src/index.js +0 -8
- package/src/kits/index.js +0 -122
- package/src/utils/copy.js +0 -214
- package/src/utils/hash.js +0 -74
- package/src/utils/paths.js +0 -255
- package/src/utils/prompts.js +0 -254
- package/src/utils/state.js +0 -136
package/src/commands/init.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import { join, resolve } from 'path';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
import ora from 'ora';
|
|
5
|
-
import { KITS, getKit } from '../kits/index.js';
|
|
6
|
-
import { resolveSource, getTargetDir, TARGETS } from '../utils/paths.js';
|
|
7
|
-
import { copyItems, copyAllOfType, copyRouter, copyHooks, copyBaseFiles, copyAgentsMd } from '../utils/copy.js';
|
|
8
|
-
import { createInitialState } from '../utils/state.js';
|
|
9
|
-
import {
|
|
10
|
-
promptProjectName,
|
|
11
|
-
promptKit,
|
|
12
|
-
promptTarget,
|
|
13
|
-
promptAgents,
|
|
14
|
-
promptSkills,
|
|
15
|
-
promptCommands,
|
|
16
|
-
promptIncludeRouter,
|
|
17
|
-
promptIncludeHooks,
|
|
18
|
-
promptConfirm,
|
|
19
|
-
promptExistingTarget
|
|
20
|
-
} from '../utils/prompts.js';
|
|
21
|
-
|
|
22
|
-
export async function initCommand(projectName, options) {
|
|
23
|
-
console.log('');
|
|
24
|
-
|
|
25
|
-
// 1. Get project name (support current directory with "." or empty)
|
|
26
|
-
let projectDir;
|
|
27
|
-
let isCurrentDir = false;
|
|
28
|
-
|
|
29
|
-
if (!projectName || projectName === '.') {
|
|
30
|
-
// Use current directory
|
|
31
|
-
projectDir = process.cwd();
|
|
32
|
-
projectName = '.';
|
|
33
|
-
isCurrentDir = true;
|
|
34
|
-
console.log(chalk.gray(`Initializing in current directory: ${projectDir}`));
|
|
35
|
-
} else {
|
|
36
|
-
projectDir = resolve(process.cwd(), projectName);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// 2. Get target early to check existing
|
|
40
|
-
let target = options.target || 'claude';
|
|
41
|
-
if (!TARGETS[target]) {
|
|
42
|
-
console.log(chalk.yellow(`Unknown target "${target}", using "claude"`));
|
|
43
|
-
target = 'claude';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const targetDir = getTargetDir(projectDir, target);
|
|
47
|
-
let existingAction = null;
|
|
48
|
-
|
|
49
|
-
// Check if target directory (.claude, .opencode, etc.) already exists
|
|
50
|
-
if (fs.existsSync(targetDir) && !options.force) {
|
|
51
|
-
if (!process.stdin.isTTY) {
|
|
52
|
-
// Non-interactive mode - skip
|
|
53
|
-
console.log(chalk.yellow(`${TARGETS[target]} already exists. Use --force to override.`));
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
existingAction = await promptExistingTarget(TARGETS[target]);
|
|
58
|
-
|
|
59
|
-
if (existingAction === 'skip') {
|
|
60
|
-
console.log(chalk.yellow('Skipped. No changes made.'));
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// For new project directory, check if it exists
|
|
66
|
-
if (!isCurrentDir && fs.existsSync(projectDir) && !options.force) {
|
|
67
|
-
const files = fs.readdirSync(projectDir);
|
|
68
|
-
if (files.length > 0 && !existingAction) {
|
|
69
|
-
console.log(chalk.red(`Directory "${projectName}" already exists and is not empty.`));
|
|
70
|
-
console.log(chalk.gray('Use --force to overwrite.'));
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 3. Resolve source
|
|
76
|
-
const source = resolveSource(options.source);
|
|
77
|
-
if (source.error) {
|
|
78
|
-
console.log(chalk.red(`Error: ${source.error}`));
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log(chalk.gray(`Source: ${source.path}`));
|
|
83
|
-
|
|
84
|
-
// 4. Get kit
|
|
85
|
-
let kitName = options.kit;
|
|
86
|
-
if (!kitName && !options.force) {
|
|
87
|
-
kitName = await promptKit();
|
|
88
|
-
} else if (!kitName) {
|
|
89
|
-
kitName = 'engineer'; // Default kit for --force mode
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// 5. Set merge mode based on existing action
|
|
93
|
-
const mergeMode = existingAction === 'merge';
|
|
94
|
-
|
|
95
|
-
// 6. Prepare what to install
|
|
96
|
-
let toInstall = {
|
|
97
|
-
agents: [],
|
|
98
|
-
commands: [],
|
|
99
|
-
skills: [],
|
|
100
|
-
workflows: [],
|
|
101
|
-
includeRouter: false,
|
|
102
|
-
includeHooks: false
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
if (kitName === 'custom') {
|
|
106
|
-
// Custom mode - prompt for everything
|
|
107
|
-
console.log(chalk.cyan('\nCustom kit configuration:'));
|
|
108
|
-
toInstall.agents = await promptAgents(source.claudeDir);
|
|
109
|
-
toInstall.skills = await promptSkills(source.claudeDir);
|
|
110
|
-
toInstall.commands = await promptCommands(source.claudeDir);
|
|
111
|
-
toInstall.includeRouter = await promptIncludeRouter();
|
|
112
|
-
toInstall.includeHooks = await promptIncludeHooks();
|
|
113
|
-
} else {
|
|
114
|
-
const kit = getKit(kitName);
|
|
115
|
-
if (!kit) {
|
|
116
|
-
console.log(chalk.red(`Unknown kit: ${kitName}`));
|
|
117
|
-
console.log(chalk.gray(`Available kits: ${Object.keys(KITS).join(', ')}`));
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
toInstall = {
|
|
122
|
-
agents: kit.agents,
|
|
123
|
-
commands: kit.commands,
|
|
124
|
-
skills: kit.skills,
|
|
125
|
-
workflows: kit.workflows || [],
|
|
126
|
-
includeRouter: kit.includeRouter,
|
|
127
|
-
includeHooks: kit.includeHooks
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// 6. Confirm
|
|
132
|
-
console.log(chalk.cyan('\nWill create:'));
|
|
133
|
-
console.log(chalk.white(` Project: ${projectName}/`));
|
|
134
|
-
console.log(chalk.white(` Target: ${TARGETS[target]}/`));
|
|
135
|
-
console.log(chalk.white(` Kit: ${kitName}`));
|
|
136
|
-
|
|
137
|
-
if (Array.isArray(toInstall.agents)) {
|
|
138
|
-
console.log(chalk.gray(` Agents: ${toInstall.agents.length}`));
|
|
139
|
-
}
|
|
140
|
-
if (Array.isArray(toInstall.skills)) {
|
|
141
|
-
console.log(chalk.gray(` Skills: ${toInstall.skills.length}`));
|
|
142
|
-
}
|
|
143
|
-
if (Array.isArray(toInstall.commands)) {
|
|
144
|
-
console.log(chalk.gray(` Commands: ${toInstall.commands.length}`));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
console.log('');
|
|
148
|
-
|
|
149
|
-
// Skip confirmation if --force is set
|
|
150
|
-
if (!options.force) {
|
|
151
|
-
if (!await promptConfirm('Proceed?')) {
|
|
152
|
-
console.log(chalk.yellow('Cancelled.'));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// 7. Create project
|
|
158
|
-
const spinner = ora('Creating project...').start();
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
// Create project directory
|
|
162
|
-
await fs.ensureDir(projectDir);
|
|
163
|
-
|
|
164
|
-
// Create target directory
|
|
165
|
-
const targetDir = getTargetDir(projectDir, target);
|
|
166
|
-
await fs.ensureDir(targetDir);
|
|
167
|
-
|
|
168
|
-
// Copy agents
|
|
169
|
-
spinner.text = mergeMode ? 'Merging agents...' : 'Copying agents...';
|
|
170
|
-
if (toInstall.agents === 'all') {
|
|
171
|
-
await copyAllOfType('agents', source.claudeDir, targetDir, mergeMode);
|
|
172
|
-
} else if (toInstall.agents.length > 0) {
|
|
173
|
-
await copyItems(toInstall.agents, 'agents', source.claudeDir, targetDir, mergeMode);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Copy skills
|
|
177
|
-
spinner.text = mergeMode ? 'Merging skills...' : 'Copying skills...';
|
|
178
|
-
if (toInstall.skills === 'all') {
|
|
179
|
-
await copyAllOfType('skills', source.claudeDir, targetDir, mergeMode);
|
|
180
|
-
} else if (toInstall.skills.length > 0) {
|
|
181
|
-
await copyItems(toInstall.skills, 'skills', source.claudeDir, targetDir, mergeMode);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Copy commands
|
|
185
|
-
spinner.text = mergeMode ? 'Merging commands...' : 'Copying commands...';
|
|
186
|
-
if (toInstall.commands === 'all') {
|
|
187
|
-
await copyAllOfType('commands', source.claudeDir, targetDir, mergeMode);
|
|
188
|
-
} else if (toInstall.commands.length > 0) {
|
|
189
|
-
await copyItems(toInstall.commands, 'commands', source.claudeDir, targetDir, mergeMode);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Copy workflows
|
|
193
|
-
spinner.text = mergeMode ? 'Merging workflows...' : 'Copying workflows...';
|
|
194
|
-
if (toInstall.workflows === 'all') {
|
|
195
|
-
await copyAllOfType('workflows', source.claudeDir, targetDir, mergeMode);
|
|
196
|
-
} else if (toInstall.workflows && toInstall.workflows.length > 0) {
|
|
197
|
-
await copyItems(toInstall.workflows, 'workflows', source.claudeDir, targetDir, mergeMode);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Copy router
|
|
201
|
-
if (toInstall.includeRouter) {
|
|
202
|
-
spinner.text = mergeMode ? 'Merging router...' : 'Copying router...';
|
|
203
|
-
await copyRouter(source.claudeDir, targetDir, mergeMode);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Copy hooks
|
|
207
|
-
if (toInstall.includeHooks) {
|
|
208
|
-
spinner.text = mergeMode ? 'Merging hooks...' : 'Copying hooks...';
|
|
209
|
-
await copyHooks(source.claudeDir, targetDir, mergeMode);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Copy base files
|
|
213
|
-
spinner.text = mergeMode ? 'Merging base files...' : 'Copying base files...';
|
|
214
|
-
await copyBaseFiles(source.claudeDir, targetDir, mergeMode);
|
|
215
|
-
|
|
216
|
-
// Copy AGENTS.md
|
|
217
|
-
if (source.agentsMd) {
|
|
218
|
-
await copyAgentsMd(source.agentsMd, projectDir, mergeMode);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Create state file
|
|
222
|
-
spinner.text = 'Saving state...';
|
|
223
|
-
await createInitialState(projectDir, {
|
|
224
|
-
kit: kitName,
|
|
225
|
-
source: source.path,
|
|
226
|
-
target: TARGETS[target],
|
|
227
|
-
installed: {
|
|
228
|
-
agents: toInstall.agents === 'all' ? ['all'] : toInstall.agents,
|
|
229
|
-
skills: toInstall.skills === 'all' ? ['all'] : toInstall.skills,
|
|
230
|
-
commands: toInstall.commands === 'all' ? ['all'] : toInstall.commands,
|
|
231
|
-
workflows: toInstall.workflows === 'all' ? ['all'] : (toInstall.workflows || []),
|
|
232
|
-
router: toInstall.includeRouter,
|
|
233
|
-
hooks: toInstall.includeHooks
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
const actionWord = mergeMode ? 'merged' : (existingAction === 'override' ? 'overridden' : 'created');
|
|
238
|
-
spinner.succeed(chalk.green(`Project ${actionWord} successfully!`));
|
|
239
|
-
|
|
240
|
-
// Print next steps
|
|
241
|
-
console.log('');
|
|
242
|
-
if (!isCurrentDir) {
|
|
243
|
-
console.log(chalk.cyan('Next steps:'));
|
|
244
|
-
console.log(chalk.white(` cd ${projectName}`));
|
|
245
|
-
console.log(chalk.white(' # Start coding with Claude Code'));
|
|
246
|
-
} else {
|
|
247
|
-
console.log(chalk.cyan('Ready to code with Claude Code!'));
|
|
248
|
-
}
|
|
249
|
-
console.log('');
|
|
250
|
-
console.log(chalk.gray('Useful commands:'));
|
|
251
|
-
console.log(chalk.gray(' ak status - Check file status'));
|
|
252
|
-
console.log(chalk.gray(' ak add <item> - Add more agents/skills'));
|
|
253
|
-
console.log(chalk.gray(' ak update - Sync from source'));
|
|
254
|
-
console.log('');
|
|
255
|
-
|
|
256
|
-
} catch (error) {
|
|
257
|
-
spinner.fail(chalk.red('Failed to create project'));
|
|
258
|
-
console.error(chalk.red(error.message));
|
|
259
|
-
if (process.env.DEBUG) {
|
|
260
|
-
console.error(error.stack);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
package/src/commands/list.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { KITS, getKitList } from '../kits/index.js';
|
|
3
|
-
import { resolveSource } from '../utils/paths.js';
|
|
4
|
-
import { listAvailable } from '../utils/copy.js';
|
|
5
|
-
|
|
6
|
-
export async function listCommand(type, options = {}) {
|
|
7
|
-
const validTypes = ['kits', 'agents', 'skills', 'commands', 'workflows'];
|
|
8
|
-
|
|
9
|
-
// If no type specified, show help
|
|
10
|
-
if (!type) {
|
|
11
|
-
console.log(chalk.cyan('\nAvailable list commands:'));
|
|
12
|
-
console.log(chalk.white(' ak list kits - List available kits'));
|
|
13
|
-
console.log(chalk.white(' ak list agents - List available agents'));
|
|
14
|
-
console.log(chalk.white(' ak list skills - List available skills'));
|
|
15
|
-
console.log(chalk.white(' ak list commands - List available commands'));
|
|
16
|
-
console.log(chalk.white(' ak list workflows - List available workflows'));
|
|
17
|
-
console.log('');
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Normalize type
|
|
22
|
-
type = type.toLowerCase();
|
|
23
|
-
if (!validTypes.includes(type)) {
|
|
24
|
-
console.log(chalk.red(`Unknown type: ${type}`));
|
|
25
|
-
console.log(chalk.gray(`Valid types: ${validTypes.join(', ')}`));
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// List kits (doesn't need source)
|
|
30
|
-
if (type === 'kits') {
|
|
31
|
-
listKits();
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// For other types, need source
|
|
36
|
-
const source = resolveSource(options.source);
|
|
37
|
-
if (source.error) {
|
|
38
|
-
console.log(chalk.red(`Error: ${source.error}`));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
console.log(chalk.gray(`Source: ${source.path}\n`));
|
|
43
|
-
|
|
44
|
-
switch (type) {
|
|
45
|
-
case 'agents':
|
|
46
|
-
listAgents(source.claudeDir);
|
|
47
|
-
break;
|
|
48
|
-
case 'skills':
|
|
49
|
-
listSkills(source.claudeDir);
|
|
50
|
-
break;
|
|
51
|
-
case 'commands':
|
|
52
|
-
listCommands(source.claudeDir);
|
|
53
|
-
break;
|
|
54
|
-
case 'workflows':
|
|
55
|
-
listWorkflows(source.claudeDir);
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function listKits() {
|
|
61
|
-
const kits = getKitList();
|
|
62
|
-
|
|
63
|
-
console.log(chalk.cyan.bold('\nAvailable Kits:\n'));
|
|
64
|
-
|
|
65
|
-
for (const kit of kits) {
|
|
66
|
-
const colorFn = chalk[kit.color] || chalk.white;
|
|
67
|
-
console.log(` ${kit.emoji} ${colorFn.bold(kit.name.padEnd(12))} - ${kit.description}`);
|
|
68
|
-
|
|
69
|
-
// Show details
|
|
70
|
-
if (Array.isArray(kit.agents)) {
|
|
71
|
-
console.log(chalk.gray(` Agents: ${kit.agents.length} | Skills: ${kit.skills.length} | Commands: ${kit.commands.length}`));
|
|
72
|
-
} else {
|
|
73
|
-
console.log(chalk.gray(' Includes: ALL agents, skills, commands'));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log(`\n 🔧 ${chalk.bold('custom'.padEnd(12))} - Pick your own agents, skills, and commands`);
|
|
78
|
-
console.log('');
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function listAgents(sourceDir) {
|
|
82
|
-
const agents = listAvailable('agents', sourceDir);
|
|
83
|
-
|
|
84
|
-
console.log(chalk.cyan.bold(`Available Agents (${agents.length}):\n`));
|
|
85
|
-
|
|
86
|
-
if (agents.length === 0) {
|
|
87
|
-
console.log(chalk.gray(' No agents found'));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Group into columns
|
|
92
|
-
const cols = 3;
|
|
93
|
-
const rows = Math.ceil(agents.length / cols);
|
|
94
|
-
|
|
95
|
-
for (let i = 0; i < rows; i++) {
|
|
96
|
-
let line = ' ';
|
|
97
|
-
for (let j = 0; j < cols; j++) {
|
|
98
|
-
const idx = i + j * rows;
|
|
99
|
-
if (idx < agents.length) {
|
|
100
|
-
line += chalk.white(agents[idx].name.padEnd(25));
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
console.log(line);
|
|
104
|
-
}
|
|
105
|
-
console.log('');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function listSkills(sourceDir) {
|
|
109
|
-
const skills = listAvailable('skills', sourceDir).filter(s => s.isDir);
|
|
110
|
-
|
|
111
|
-
console.log(chalk.cyan.bold(`Available Skills (${skills.length}):\n`));
|
|
112
|
-
|
|
113
|
-
if (skills.length === 0) {
|
|
114
|
-
console.log(chalk.gray(' No skills found'));
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Group into columns
|
|
119
|
-
const cols = 2;
|
|
120
|
-
const rows = Math.ceil(skills.length / cols);
|
|
121
|
-
|
|
122
|
-
for (let i = 0; i < rows; i++) {
|
|
123
|
-
let line = ' ';
|
|
124
|
-
for (let j = 0; j < cols; j++) {
|
|
125
|
-
const idx = i + j * rows;
|
|
126
|
-
if (idx < skills.length) {
|
|
127
|
-
line += chalk.white(skills[idx].name.padEnd(35));
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
console.log(line);
|
|
131
|
-
}
|
|
132
|
-
console.log('');
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function listCommands(sourceDir) {
|
|
136
|
-
const commands = listAvailable('commands', sourceDir);
|
|
137
|
-
|
|
138
|
-
console.log(chalk.cyan.bold(`Available Commands (${commands.length}):\n`));
|
|
139
|
-
|
|
140
|
-
if (commands.length === 0) {
|
|
141
|
-
console.log(chalk.gray(' No commands found'));
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Separate files and directories
|
|
146
|
-
const files = commands.filter(c => !c.isDir);
|
|
147
|
-
const dirs = commands.filter(c => c.isDir);
|
|
148
|
-
|
|
149
|
-
// Print main commands (files)
|
|
150
|
-
console.log(chalk.gray(' Main commands:'));
|
|
151
|
-
const cols = 4;
|
|
152
|
-
let rows = Math.ceil(files.length / cols);
|
|
153
|
-
|
|
154
|
-
for (let i = 0; i < rows; i++) {
|
|
155
|
-
let line = ' ';
|
|
156
|
-
for (let j = 0; j < cols; j++) {
|
|
157
|
-
const idx = i + j * rows;
|
|
158
|
-
if (idx < files.length) {
|
|
159
|
-
line += chalk.white(('/' + files[idx].name).padEnd(18));
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
console.log(line);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Print command groups (directories)
|
|
166
|
-
if (dirs.length > 0) {
|
|
167
|
-
console.log(chalk.gray('\n Command groups:'));
|
|
168
|
-
for (const dir of dirs) {
|
|
169
|
-
console.log(chalk.yellow(` /${dir.name}/`));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
console.log('');
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function listWorkflows(sourceDir) {
|
|
177
|
-
const workflows = listAvailable('workflows', sourceDir);
|
|
178
|
-
|
|
179
|
-
console.log(chalk.cyan.bold(`Available Workflows (${workflows.length}):\n`));
|
|
180
|
-
|
|
181
|
-
if (workflows.length === 0) {
|
|
182
|
-
console.log(chalk.gray(' No workflows found'));
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
for (const wf of workflows) {
|
|
187
|
-
console.log(chalk.white(` • ${wf.name}`));
|
|
188
|
-
}
|
|
189
|
-
console.log('');
|
|
190
|
-
}
|
package/src/commands/status.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { isAkProject } from '../utils/paths.js';
|
|
3
|
-
import { loadState, getFileStatuses } from '../utils/state.js';
|
|
4
|
-
import fs from 'fs-extra';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
|
|
7
|
-
export async function statusCommand(options = {}) {
|
|
8
|
-
const projectDir = process.cwd();
|
|
9
|
-
|
|
10
|
-
// Check if in ak project
|
|
11
|
-
if (!isAkProject(projectDir)) {
|
|
12
|
-
console.log(chalk.red('Not in an ak project.'));
|
|
13
|
-
console.log(chalk.gray('Run "ak init" first.'));
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Load state
|
|
18
|
-
const state = await loadState(projectDir);
|
|
19
|
-
if (!state) {
|
|
20
|
-
console.log(chalk.yellow('No state file found.'));
|
|
21
|
-
console.log(chalk.gray('This project may have been created without ak.'));
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Print project info
|
|
26
|
-
console.log(chalk.cyan.bold('\nProject Status\n'));
|
|
27
|
-
console.log(chalk.white(` Kit: ${state.kit}`));
|
|
28
|
-
console.log(chalk.white(` Target: ${state.target}`));
|
|
29
|
-
console.log(chalk.white(` Source: ${state.source}`));
|
|
30
|
-
console.log(chalk.gray(` Created: ${new Date(state.createdAt).toLocaleDateString()}`));
|
|
31
|
-
console.log(chalk.gray(` Updated: ${new Date(state.lastUpdate).toLocaleDateString()}`));
|
|
32
|
-
console.log('');
|
|
33
|
-
|
|
34
|
-
// Get file statuses
|
|
35
|
-
const result = await getFileStatuses(projectDir);
|
|
36
|
-
|
|
37
|
-
if (result.error) {
|
|
38
|
-
console.log(chalk.red(`Error: ${result.error}`));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const { statuses } = result;
|
|
43
|
-
|
|
44
|
-
// Summary
|
|
45
|
-
const total = statuses.unchanged.length + statuses.modified.length + statuses.added.length;
|
|
46
|
-
console.log(chalk.cyan('File Status:'));
|
|
47
|
-
console.log(chalk.green(` ✓ ${statuses.unchanged.length} unchanged`));
|
|
48
|
-
if (statuses.modified.length > 0) {
|
|
49
|
-
console.log(chalk.yellow(` ~ ${statuses.modified.length} modified`));
|
|
50
|
-
}
|
|
51
|
-
if (statuses.added.length > 0) {
|
|
52
|
-
console.log(chalk.blue(` + ${statuses.added.length} added locally`));
|
|
53
|
-
}
|
|
54
|
-
if (statuses.deleted.length > 0) {
|
|
55
|
-
console.log(chalk.red(` - ${statuses.deleted.length} deleted`));
|
|
56
|
-
}
|
|
57
|
-
console.log(chalk.gray(` Total: ${total} files tracked`));
|
|
58
|
-
console.log('');
|
|
59
|
-
|
|
60
|
-
// Show modified files
|
|
61
|
-
if (statuses.modified.length > 0 && (options.verbose || statuses.modified.length <= 10)) {
|
|
62
|
-
console.log(chalk.yellow('Modified files:'));
|
|
63
|
-
for (const file of statuses.modified) {
|
|
64
|
-
console.log(chalk.yellow(` ~ ${file}`));
|
|
65
|
-
}
|
|
66
|
-
console.log('');
|
|
67
|
-
} else if (statuses.modified.length > 10) {
|
|
68
|
-
console.log(chalk.yellow(`Modified files: (showing first 10, use --verbose for all)`));
|
|
69
|
-
for (const file of statuses.modified.slice(0, 10)) {
|
|
70
|
-
console.log(chalk.yellow(` ~ ${file}`));
|
|
71
|
-
}
|
|
72
|
-
console.log(chalk.gray(` ... and ${statuses.modified.length - 10} more`));
|
|
73
|
-
console.log('');
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Show added files
|
|
77
|
-
if (statuses.added.length > 0 && (options.verbose || statuses.added.length <= 5)) {
|
|
78
|
-
console.log(chalk.blue('Added locally:'));
|
|
79
|
-
for (const file of statuses.added) {
|
|
80
|
-
console.log(chalk.blue(` + ${file}`));
|
|
81
|
-
}
|
|
82
|
-
console.log('');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Installed components
|
|
86
|
-
if (state.installed) {
|
|
87
|
-
console.log(chalk.cyan('Installed Components:'));
|
|
88
|
-
const { agents, skills, commands, workflows, router, hooks } = state.installed;
|
|
89
|
-
|
|
90
|
-
if (agents && agents.length > 0) {
|
|
91
|
-
console.log(chalk.gray(` Agents: ${agents.includes('all') ? 'ALL' : agents.length}`));
|
|
92
|
-
}
|
|
93
|
-
if (skills && skills.length > 0) {
|
|
94
|
-
console.log(chalk.gray(` Skills: ${skills.includes('all') ? 'ALL' : skills.length}`));
|
|
95
|
-
}
|
|
96
|
-
if (commands && commands.length > 0) {
|
|
97
|
-
console.log(chalk.gray(` Commands: ${commands.includes('all') ? 'ALL' : commands.length}`));
|
|
98
|
-
}
|
|
99
|
-
if (workflows && workflows.length > 0) {
|
|
100
|
-
console.log(chalk.gray(` Workflows: ${workflows.includes('all') ? 'ALL' : workflows.length}`));
|
|
101
|
-
}
|
|
102
|
-
if (router) console.log(chalk.gray(' Router: ✓'));
|
|
103
|
-
if (hooks) console.log(chalk.gray(' Hooks: ✓'));
|
|
104
|
-
console.log('');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Check source availability
|
|
108
|
-
if (state.source && !fs.existsSync(state.source)) {
|
|
109
|
-
console.log(chalk.yellow('⚠ Source directory not found. Update may not work.'));
|
|
110
|
-
console.log(chalk.gray(` Expected: ${state.source}`));
|
|
111
|
-
console.log('');
|
|
112
|
-
}
|
|
113
|
-
}
|