iriai-build 0.1.2 → 0.1.4
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 +49 -0
- package/cli/commands/setup.js +28 -19
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# iriai-build
|
|
2
|
+
|
|
3
|
+
AI agent orchestration CLI for planning, implementing, and shipping features. Drives multi-agent workflows from the terminal or via Slack, using the `claude` CLI as the underlying execution engine.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js >= 18
|
|
8
|
+
- `claude` CLI installed and available on PATH (or configured via `CLAUDE_BIN`)
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
npm install -g iriai-build
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
Run `iriai-build` with no arguments for an interactive menu, or use a subcommand directly.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
iriai-build [command]
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Commands
|
|
25
|
+
|
|
26
|
+
| Command | Alias | Description |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| `launch [description]` | | Full flow: planning, implementation, and completion. Without an argument, select from active features or start a new one. |
|
|
29
|
+
| `plan [description]` | | Run the planning pipeline. After plan approval, prompts to continue to implementation. |
|
|
30
|
+
| `implementation` | `impl` | Select from planned or in-progress features and run implementation. |
|
|
31
|
+
| `slack` | | Launch the Slack bridge for receiving decisions and updates via Slack. |
|
|
32
|
+
| `transfer-to-slack` | | Sync all CLI-created features to Slack channels and start the Slack bridge. |
|
|
33
|
+
| `setup` | | Interactive configuration for Slack tokens, tool paths, and preferences. |
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
Run `iriai-build setup` to configure the tool interactively. Values are saved to `~/.iriai/config.json`.
|
|
38
|
+
|
|
39
|
+
### Settings
|
|
40
|
+
|
|
41
|
+
| Setting | Config key | Env var override | Default |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| Claude CLI path | `claude_bin` | `CLAUDE_BIN` | `claude` |
|
|
44
|
+
| QA feedback CLI path | `qa_feedback_bin` | `QA_FEEDBACK_BIN` | `iriai-feedback` |
|
|
45
|
+
| Slack App Token | `slack_app_token` | `SLACK_APP_TOKEN` | -- |
|
|
46
|
+
| Slack Bot Token | `slack_bot_token` | `SLACK_BOT_TOKEN` | -- |
|
|
47
|
+
| Slack Channel ID | `slack_channel_id` | `SLACK_CHANNEL_ID` | -- |
|
|
48
|
+
|
|
49
|
+
Environment variables always take precedence over config file values. Slack tokens are required only for `slack` and `transfer-to-slack` commands.
|
package/cli/commands/setup.js
CHANGED
|
@@ -5,6 +5,16 @@ import { input, confirm } from "@inquirer/prompts";
|
|
|
5
5
|
import * as config from "../config.js";
|
|
6
6
|
import { banner, systemMsg, successMsg, errorMsg } from "../display.js";
|
|
7
7
|
|
|
8
|
+
function mask(value) {
|
|
9
|
+
if (!value) return null;
|
|
10
|
+
if (value.length <= 8) return value;
|
|
11
|
+
return value.slice(0, 4) + "..." + value.slice(-4);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hint(current) {
|
|
15
|
+
return current ? ` \x1b[2m(current: ${mask(current)}, Enter to keep)\x1b[0m` : "";
|
|
16
|
+
}
|
|
17
|
+
|
|
8
18
|
export async function setupCommand() {
|
|
9
19
|
banner();
|
|
10
20
|
systemMsg("Configure iriai-build. Values are saved to " + config.configPath());
|
|
@@ -18,49 +28,48 @@ export async function setupCommand() {
|
|
|
18
28
|
console.log("\x1b[2mEnv vars (SLACK_APP_TOKEN, etc.) always override these values.\x1b[0m\n");
|
|
19
29
|
|
|
20
30
|
const appToken = await input({
|
|
21
|
-
message:
|
|
22
|
-
default: current.slack_app_token || "",
|
|
31
|
+
message: `Slack App Token (xapp-...):${hint(current.slack_app_token)}`,
|
|
23
32
|
});
|
|
24
33
|
|
|
25
34
|
const botToken = await input({
|
|
26
|
-
message:
|
|
27
|
-
default: current.slack_bot_token || "",
|
|
35
|
+
message: `Slack Bot Token (xoxb-...):${hint(current.slack_bot_token)}`,
|
|
28
36
|
});
|
|
29
37
|
|
|
30
38
|
const channelId = await input({
|
|
31
|
-
message:
|
|
32
|
-
default: current.slack_channel_id || "",
|
|
39
|
+
message: `Slack Planning Channel ID (C...):${hint(current.slack_channel_id)}`,
|
|
33
40
|
});
|
|
34
41
|
|
|
35
|
-
//
|
|
42
|
+
// Tool paths
|
|
36
43
|
console.log("\n\x1b[1mTool Paths\x1b[0m");
|
|
37
|
-
console.log("\x1b[2mOptional —
|
|
44
|
+
console.log("\x1b[2mOptional — Enter to keep defaults.\x1b[0m\n");
|
|
38
45
|
|
|
39
46
|
const claudeBin = await input({
|
|
40
|
-
message:
|
|
41
|
-
default: current.claude_bin || "claude",
|
|
47
|
+
message: `claude CLI path:${hint(current.claude_bin || "claude")}`,
|
|
42
48
|
});
|
|
43
49
|
|
|
44
50
|
const qaFeedbackBin = await input({
|
|
45
|
-
message:
|
|
46
|
-
default: current.qa_feedback_bin || "iriai-feedback",
|
|
51
|
+
message: `iriai-feedback CLI path:${hint(current.qa_feedback_bin || "iriai-feedback")}`,
|
|
47
52
|
});
|
|
48
53
|
|
|
49
|
-
// Save
|
|
50
|
-
const updates = {};
|
|
54
|
+
// Save — only update fields that were actually changed
|
|
55
|
+
const updates = { ...current };
|
|
51
56
|
if (appToken) updates.slack_app_token = appToken;
|
|
52
57
|
if (botToken) updates.slack_bot_token = botToken;
|
|
53
58
|
if (channelId) updates.slack_channel_id = channelId;
|
|
54
|
-
if (claudeBin
|
|
55
|
-
if (qaFeedbackBin
|
|
59
|
+
if (claudeBin) updates.claude_bin = claudeBin;
|
|
60
|
+
if (qaFeedbackBin) updates.qa_feedback_bin = qaFeedbackBin;
|
|
56
61
|
|
|
57
|
-
config.
|
|
62
|
+
config.save(updates);
|
|
58
63
|
|
|
59
64
|
console.log("");
|
|
60
65
|
successMsg(`Config saved to ${config.configPath()}`);
|
|
61
66
|
|
|
62
67
|
// Validate
|
|
63
|
-
|
|
68
|
+
const finalAppToken = updates.slack_app_token;
|
|
69
|
+
const finalBotToken = updates.slack_bot_token;
|
|
70
|
+
const finalChannelId = updates.slack_channel_id;
|
|
71
|
+
|
|
72
|
+
if (finalAppToken && finalBotToken && finalChannelId) {
|
|
64
73
|
const shouldTest = await confirm({
|
|
65
74
|
message: "Test Slack connection?",
|
|
66
75
|
default: true,
|
|
@@ -69,7 +78,7 @@ export async function setupCommand() {
|
|
|
69
78
|
if (shouldTest) {
|
|
70
79
|
try {
|
|
71
80
|
const { WebClient } = await import("@slack/web-api");
|
|
72
|
-
const web = new WebClient(
|
|
81
|
+
const web = new WebClient(finalBotToken);
|
|
73
82
|
const auth = await web.auth.test();
|
|
74
83
|
successMsg(`Connected as ${auth.user} (${auth.user_id}) in workspace ${auth.team}`);
|
|
75
84
|
} catch (err) {
|