aico-cli 0.2.2 → 0.2.5
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/dist/chunks/feature-checker.mjs +2 -2
- package/dist/chunks/simple-config.mjs +169 -174
- package/dist/cli.mjs +7 -13
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.mjs +2 -2
- package/dist/shared/{aico-cli.C9hv-Gol.mjs → aico-cli.CWSSz8Hk.mjs} +1 -1
- package/package.json +1 -1
- package/templates/CLAUDE.md +2 -71
- package/templates/agents/aico/requirement/PLATFORM_COMPATIBILITY.md +219 -0
- package/templates/agents/aico/requirement/crossplatform-utils.sh +307 -0
- package/templates/agents/aico/requirement/requirement-functions-crossplatform.sh +472 -0
- package/templates/agents/aico/requirement/requirement-identifier.md +286 -156
- package/templates/agents/aico/requirement/requirement-launcher.sh +146 -0
- package/templates/agents/aico/requirement/task-executor.md +100 -34
- package/templates/commands/aico/requirement.md +7 -1
- package/templates/personality.md +120 -235
- package/dist/chunks/workflow-installer.mjs +0 -213
- package/templates/base.md +0 -51
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { join, dirname } from 'pathe';
|
|
2
|
-
import { rm, mkdir, copyFile } from 'node:fs/promises';
|
|
3
|
-
import { existsSync } from 'node:fs';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import ansis from 'ansis';
|
|
6
|
-
import { I as messages, C as CLAUDE_DIR } from './simple-config.mjs';
|
|
7
|
-
import 'inquirer';
|
|
8
|
-
import 'tinyexec';
|
|
9
|
-
import 'node:os';
|
|
10
|
-
import 'node:child_process';
|
|
11
|
-
import 'node:util';
|
|
12
|
-
import 'child_process';
|
|
13
|
-
import 'util';
|
|
14
|
-
import 'ora';
|
|
15
|
-
import 'dayjs';
|
|
16
|
-
import 'node:path';
|
|
17
|
-
|
|
18
|
-
const WORKFLOW_CONFIGS = [
|
|
19
|
-
{
|
|
20
|
-
id: "sixStepsWorkflow",
|
|
21
|
-
nameKey: "workflowOption.sixStepsWorkflow",
|
|
22
|
-
descriptionKey: "workflowDescription.sixStepsWorkflow",
|
|
23
|
-
defaultSelected: true,
|
|
24
|
-
order: 1,
|
|
25
|
-
commands: ["workflow.md"],
|
|
26
|
-
agents: [],
|
|
27
|
-
autoInstallAgents: false,
|
|
28
|
-
category: "sixStep",
|
|
29
|
-
outputDir: "workflow"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: "featPlanUx",
|
|
33
|
-
nameKey: "workflowOption.featPlanUx",
|
|
34
|
-
descriptionKey: "workflowDescription.featPlanUx",
|
|
35
|
-
defaultSelected: true,
|
|
36
|
-
order: 2,
|
|
37
|
-
commands: ["feat.md"],
|
|
38
|
-
agents: [
|
|
39
|
-
{ id: "planner", filename: "planner.md", required: true },
|
|
40
|
-
{ id: "ui-ux-designer", filename: "ui-ux-designer.md", required: true }
|
|
41
|
-
],
|
|
42
|
-
autoInstallAgents: true,
|
|
43
|
-
category: "plan",
|
|
44
|
-
outputDir: "feat"
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
id: "bmadWorkflow",
|
|
48
|
-
nameKey: "workflowOption.bmadWorkflow",
|
|
49
|
-
descriptionKey: "workflowDescription.bmadWorkflow",
|
|
50
|
-
defaultSelected: false,
|
|
51
|
-
order: 3,
|
|
52
|
-
commands: ["bmad-init.md"],
|
|
53
|
-
agents: [],
|
|
54
|
-
autoInstallAgents: false,
|
|
55
|
-
category: "bmad",
|
|
56
|
-
outputDir: "bmad"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
id: "gitWorkflow",
|
|
60
|
-
nameKey: "workflowOption.gitWorkflow",
|
|
61
|
-
descriptionKey: "workflowDescription.gitWorkflow",
|
|
62
|
-
defaultSelected: false,
|
|
63
|
-
order: 4,
|
|
64
|
-
commands: ["git-commit.md", "git-rollback.md", "git-cleanBranches.md", "git-worktree.md"],
|
|
65
|
-
agents: [],
|
|
66
|
-
autoInstallAgents: false,
|
|
67
|
-
category: "git",
|
|
68
|
-
outputDir: "git"
|
|
69
|
-
}
|
|
70
|
-
];
|
|
71
|
-
function getWorkflowConfig(workflowId) {
|
|
72
|
-
return WORKFLOW_CONFIGS.find((config) => config.id === workflowId);
|
|
73
|
-
}
|
|
74
|
-
function getOrderedWorkflows() {
|
|
75
|
-
return [...WORKFLOW_CONFIGS].sort((a, b) => a.order - b.order);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function getRootDir() {
|
|
79
|
-
const currentFilePath = fileURLToPath(import.meta.url);
|
|
80
|
-
const distDir = dirname(dirname(currentFilePath));
|
|
81
|
-
return dirname(distDir);
|
|
82
|
-
}
|
|
83
|
-
async function selectAndInstallWorkflows(configLang, scriptLang, preselectedWorkflows) {
|
|
84
|
-
const workflows = getOrderedWorkflows();
|
|
85
|
-
workflows.map((workflow) => {
|
|
86
|
-
const nameKey = workflow.id;
|
|
87
|
-
const name = messages.workflow.selectWorkflowType[nameKey] || workflow.id;
|
|
88
|
-
return {
|
|
89
|
-
name,
|
|
90
|
-
value: workflow.id,
|
|
91
|
-
checked: workflow.defaultSelected
|
|
92
|
-
};
|
|
93
|
-
});
|
|
94
|
-
let selectedWorkflows;
|
|
95
|
-
if (preselectedWorkflows) {
|
|
96
|
-
selectedWorkflows = preselectedWorkflows;
|
|
97
|
-
} else {
|
|
98
|
-
selectedWorkflows = workflows.map((w) => w.id);
|
|
99
|
-
}
|
|
100
|
-
if (!selectedWorkflows || selectedWorkflows.length === 0) {
|
|
101
|
-
console.log(ansis.yellow(messages.common.cancelled));
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
await cleanupOldVersionFiles();
|
|
105
|
-
for (const workflowId of selectedWorkflows) {
|
|
106
|
-
const config = getWorkflowConfig(workflowId);
|
|
107
|
-
if (config) {
|
|
108
|
-
await installWorkflowWithDependencies(config, configLang);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async function installWorkflowWithDependencies(config, configLang, scriptLang) {
|
|
113
|
-
const rootDir = getRootDir();
|
|
114
|
-
const result = {
|
|
115
|
-
workflow: config.id,
|
|
116
|
-
success: true,
|
|
117
|
-
installedCommands: [],
|
|
118
|
-
installedAgents: [],
|
|
119
|
-
errors: []
|
|
120
|
-
};
|
|
121
|
-
const workflowName = messages.workflow.selectWorkflowType[config.id] || config.id;
|
|
122
|
-
console.log(ansis.cyan(`
|
|
123
|
-
\u{1F4E6} ${messages.workflow.installing}: ${workflowName}...`));
|
|
124
|
-
const commandsDir = join(CLAUDE_DIR, "commands", "aico");
|
|
125
|
-
if (!existsSync(commandsDir)) {
|
|
126
|
-
await mkdir(commandsDir, { recursive: true });
|
|
127
|
-
}
|
|
128
|
-
for (const commandFile of config.commands) {
|
|
129
|
-
const commandSource = join(rootDir, "templates", configLang, "workflow", config.category, "commands", commandFile);
|
|
130
|
-
const destFileName = commandFile;
|
|
131
|
-
const commandDest = join(commandsDir, destFileName);
|
|
132
|
-
if (existsSync(commandSource)) {
|
|
133
|
-
try {
|
|
134
|
-
await copyFile(commandSource, commandDest);
|
|
135
|
-
result.installedCommands.push(destFileName);
|
|
136
|
-
console.log(ansis.gray(` \u2714 ${messages.workflow.installedCommand}: aico/${destFileName}`));
|
|
137
|
-
} catch (error) {
|
|
138
|
-
const errorMsg = `${messages.workflow.failedToInstallCommand} ${commandFile}: ${error}`;
|
|
139
|
-
result.errors?.push(errorMsg);
|
|
140
|
-
console.error(ansis.red(` \u2717 ${errorMsg}`));
|
|
141
|
-
result.success = false;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (config.autoInstallAgents && config.agents.length > 0) {
|
|
146
|
-
const agentsCategoryDir = join(CLAUDE_DIR, "agents", "aico", config.category);
|
|
147
|
-
if (!existsSync(agentsCategoryDir)) {
|
|
148
|
-
await mkdir(agentsCategoryDir, { recursive: true });
|
|
149
|
-
}
|
|
150
|
-
for (const agent of config.agents) {
|
|
151
|
-
const agentSource = join(rootDir, "templates", configLang, "workflow", config.category, "agents", agent.filename);
|
|
152
|
-
const agentDest = join(agentsCategoryDir, agent.filename);
|
|
153
|
-
if (existsSync(agentSource)) {
|
|
154
|
-
try {
|
|
155
|
-
await copyFile(agentSource, agentDest);
|
|
156
|
-
result.installedAgents.push(agent.filename);
|
|
157
|
-
console.log(ansis.gray(` \u2714 ${messages.workflow.installedAgent}: aico/${config.category}/${agent.filename}`));
|
|
158
|
-
} catch (error) {
|
|
159
|
-
const errorMsg = `${messages.workflow.failedToInstallAgent} ${agent.filename}: ${error}`;
|
|
160
|
-
result.errors?.push(errorMsg);
|
|
161
|
-
console.error(ansis.red(` \u2717 ${errorMsg}`));
|
|
162
|
-
if (agent.required) {
|
|
163
|
-
result.success = false;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
if (result.success) {
|
|
170
|
-
console.log(ansis.green(`\u2714 ${workflowName} ${messages.workflow.installSuccess}`));
|
|
171
|
-
if (config.id === "bmadWorkflow") {
|
|
172
|
-
console.log(ansis.cyan(`
|
|
173
|
-
${messages.workflow.bmadInitPrompt}`));
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
console.log(ansis.red(`\u2717 ${workflowName} ${messages.workflow.installFailed}`));
|
|
177
|
-
}
|
|
178
|
-
return result;
|
|
179
|
-
}
|
|
180
|
-
async function cleanupOldVersionFiles(scriptLang) {
|
|
181
|
-
console.log(ansis.cyan(`
|
|
182
|
-
\u{1F9F9} ${messages.workflow.cleaningOldFiles || "Cleaning up old version files"}...`));
|
|
183
|
-
const oldCommandFiles = [
|
|
184
|
-
join(CLAUDE_DIR, "commands", "workflow.md"),
|
|
185
|
-
join(CLAUDE_DIR, "commands", "feat.md")
|
|
186
|
-
];
|
|
187
|
-
const oldAgentFiles = [
|
|
188
|
-
join(CLAUDE_DIR, "agents", "planner.md"),
|
|
189
|
-
join(CLAUDE_DIR, "agents", "ui-ux-designer.md")
|
|
190
|
-
];
|
|
191
|
-
for (const file of oldCommandFiles) {
|
|
192
|
-
if (existsSync(file)) {
|
|
193
|
-
try {
|
|
194
|
-
await rm(file, { force: true });
|
|
195
|
-
console.log(ansis.gray(` \u2714 ${messages.workflow.removedOldFile || "Removed old file"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.error(ansis.yellow(` \u26A0 ${messages.workflow.failedToRemoveFile || "Failed to remove"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
for (const file of oldAgentFiles) {
|
|
202
|
-
if (existsSync(file)) {
|
|
203
|
-
try {
|
|
204
|
-
await rm(file, { force: true });
|
|
205
|
-
console.log(ansis.gray(` \u2714 ${messages.workflow.removedOldFile || "Removed old file"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
206
|
-
} catch (error) {
|
|
207
|
-
console.error(ansis.yellow(` \u26A0 ${messages.workflow.failedToRemoveFile || "Failed to remove"}: ${file.replace(CLAUDE_DIR, "~/.claude")}`));
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export { selectAndInstallWorkflows };
|
package/templates/base.md
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
description: Ensure what you implement Always Works™ with comprehensive testing
|
|
2
|
-
---
|
|
3
|
-
|
|
4
|
-
# How to ensure Always Works™ implementation
|
|
5
|
-
|
|
6
|
-
Please ensure your implementation Always Works™ for: $ARGUMENTS.
|
|
7
|
-
|
|
8
|
-
Follow this systematic approach:
|
|
9
|
-
|
|
10
|
-
## Core Philosophy
|
|
11
|
-
|
|
12
|
-
- "Should work" ≠ "does work" - Pattern matching isn't enough
|
|
13
|
-
- I'm not paid to write code, I'm paid to solve problems
|
|
14
|
-
- Untested code is just a guess, not a solution
|
|
15
|
-
|
|
16
|
-
# The 30-Second Reality Check - Must answer YES to ALL:
|
|
17
|
-
|
|
18
|
-
- Did I run/build the code?
|
|
19
|
-
- Did I trigger the exact feature I changed?
|
|
20
|
-
- Did I see the expected result with my own observation (including GUI)?
|
|
21
|
-
- Did I check for error messages?
|
|
22
|
-
|
|
23
|
-
# Phrases to Avoid:
|
|
24
|
-
|
|
25
|
-
- "This should work now"
|
|
26
|
-
- "I've fixed the issue" (especially 2nd+ time)
|
|
27
|
-
- "Try it now" (without trying it myself)
|
|
28
|
-
- "The logic is correct so..."
|
|
29
|
-
|
|
30
|
-
# Specific Test Requirements:
|
|
31
|
-
|
|
32
|
-
- UI Changes: Actually click the button/link/form
|
|
33
|
-
- API Changes: Make the actual API call
|
|
34
|
-
- Data Changes: Query the database
|
|
35
|
-
- Logic Changes: Run the specific scenario
|
|
36
|
-
- Config Changes: Restart and verify it loads
|
|
37
|
-
|
|
38
|
-
# The Embarrassment Test:
|
|
39
|
-
|
|
40
|
-
"If the user records trying this and it fails, will I feel embarrassed to see his face?"
|
|
41
|
-
|
|
42
|
-
# Time Reality:
|
|
43
|
-
|
|
44
|
-
- Time saved skipping tests: 30 seconds
|
|
45
|
-
- Time wasted when it doesn't work: 30 minutes
|
|
46
|
-
- User trust lost: Immeasurable
|
|
47
|
-
|
|
48
|
-
A user describing a bug for the third time isn't thinking "this AI is trying hard" - they're thinking "why am I wasting time with this incompetent tool?"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|