agentcraft 0.0.1 → 0.0.2

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentcraft",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "description": "Assign sounds to AI coding agent lifecycle events. Works with Claude Code and OpenCode.",
5
5
  "author": { "name": "rohenaz" },
6
6
  "keywords": ["sounds", "hooks", "audio", "productivity", "opencode", "claude-code"]
package/README.md CHANGED
@@ -18,7 +18,7 @@ From any Claude Code session:
18
18
 
19
19
  **2. Sounds download automatically**
20
20
 
21
- On first launch, AgentCraft clones the [agentcraft-sounds](https://github.com/rohenaz/agentcraft-sounds) library to `~/.agentcraft/sounds/`. No manual setup required.
21
+ On first launch, AgentCraft installs the [agentcraft-sounds](https://github.com/rohenaz/agentcraft-sounds) pack to `~/.agentcraft/packs/rohenaz/agentcraft-sounds/`. No manual setup required.
22
22
 
23
23
  **3. The dashboard opens at `http://localhost:4040`**
24
24
 
@@ -38,11 +38,48 @@ From then on, Claude Code plays your sounds automatically as it works — no das
38
38
  claude plugin install agentcraft@rohenaz
39
39
  ```
40
40
 
41
+ ## CLI
42
+
43
+ The `agentcraft` CLI manages sound packs:
44
+
45
+ ```bash
46
+ npm install -g agentcraft
47
+ # or
48
+ bun install -g agentcraft
49
+ ```
50
+
51
+ ```bash
52
+ agentcraft pack install rohenaz/agentcraft-sounds # install a pack from GitHub
53
+ agentcraft pack list # list installed packs
54
+ agentcraft pack update rohenaz/agentcraft-sounds # update a pack (git pull)
55
+ agentcraft pack update --all # update all packs
56
+ agentcraft pack remove rohenaz/agentcraft-sounds # remove a pack
57
+ ```
58
+
59
+ ## Sound Packs
60
+
61
+ Packs live at `~/.agentcraft/packs/<publisher>/<name>/`. Each pack is a plain git repo — installing is just a clone, updating is just a pull.
62
+
63
+ ```
64
+ ~/.agentcraft/packs/
65
+ rohenaz/
66
+ agentcraft-sounds/ ← official pack
67
+ you/
68
+ custom-pack/ ← any git repo cloned here works automatically
69
+ ```
70
+
71
+ **Manual install** works identically to the CLI:
72
+ ```bash
73
+ git clone https://github.com/publisher/name ~/.agentcraft/packs/publisher/name
74
+ ```
75
+
76
+ To create your own pack: make a GitHub repo with sound files, share the `publisher/name` slug. That's it — no registry, no manifest required.
77
+
41
78
  ## Prerequisites
42
79
 
43
80
  - [Bun](https://bun.sh) — runs the web UI
44
81
  - [jq](https://jqlang.github.io/jq/) — JSON parsing in the hook script
45
- - [git](https://git-scm.com) — downloads the sound library on first run
82
+ - [git](https://git-scm.com) — downloads packs on install
46
83
  - macOS: `afplay` (built in) · Linux: `paplay` or `aplay`
47
84
 
48
85
  ## Hooks
@@ -72,20 +109,12 @@ The **UI SFX** dropdown in the header controls ambient sounds that play as you u
72
109
  | FF9 | Final Fantasy IX — soft, minimal |
73
110
  | OFF | No UI sounds |
74
111
 
75
- ## Sound Library
76
-
77
- Sounds live at `~/.agentcraft/sounds/`. Any `.mp3`, `.wav`, `.ogg`, or `.m4a` file you drop there appears in the browser automatically. To update the library:
78
-
79
- ```bash
80
- git -C ~/.agentcraft/sounds pull
81
- ```
82
-
83
112
  ## Storage
84
113
 
85
114
  | Path | Contents |
86
115
  |------|----------|
87
116
  | `~/.agentcraft/assignments.json` | Your sound assignments |
88
- | `~/.agentcraft/sounds/` | Sound library |
117
+ | `~/.agentcraft/packs/` | Installed sound packs |
89
118
 
90
119
  ## Managing the Plugin
91
120
 
package/bin/agentcraft.js CHANGED
@@ -1,12 +1,156 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
- // AgentCraft CLI https://github.com/rohenaz/agentcraft
5
- // Full implementation coming in a future release.
6
- // Install the Claude Code plugin: claude plugin install agentcraft@rohenaz
4
+ const { execSync, spawnSync } = require('child_process');
5
+ const { existsSync, readdirSync, rmSync, statSync, mkdirSync } = require('fs');
6
+ const { join } = require('path');
7
+ const { homedir } = require('os');
7
8
 
8
- const [,, cmd, ...args] = process.argv;
9
+ const PACKS_DIR = join(homedir(), '.agentcraft', 'packs');
10
+ const [,, cmd, sub, ...rest] = process.argv;
9
11
 
10
- console.log('AgentCraft CLI v0.0.1');
11
- console.log('Full CLI coming soon. Install the Claude Code plugin:');
12
- console.log(' claude plugin install agentcraft@rohenaz');
12
+ function ensureDir(p) {
13
+ mkdirSync(p, { recursive: true });
14
+ }
15
+
16
+ function parsePackId(arg) {
17
+ if (!arg || !arg.includes('/')) {
18
+ console.error(`Error: pack must be "publisher/name", got: ${arg ?? '(nothing)'}`);
19
+ process.exit(1);
20
+ }
21
+ const slash = arg.indexOf('/');
22
+ const publisher = arg.slice(0, slash);
23
+ const name = arg.slice(slash + 1);
24
+ return { publisher, name, id: arg, url: `https://github.com/${publisher}/${name}` };
25
+ }
26
+
27
+ function getInstalledPacks() {
28
+ if (!existsSync(PACKS_DIR)) return [];
29
+ const packs = [];
30
+ for (const publisher of readdirSync(PACKS_DIR)) {
31
+ const ppath = join(PACKS_DIR, publisher);
32
+ try {
33
+ if (!statSync(ppath).isDirectory()) continue;
34
+ } catch { continue; }
35
+ for (const name of readdirSync(ppath)) {
36
+ try {
37
+ if (statSync(join(ppath, name)).isDirectory()) packs.push(`${publisher}/${name}`);
38
+ } catch { continue; }
39
+ }
40
+ }
41
+ return packs;
42
+ }
43
+
44
+ function packInstall(packArg) {
45
+ const { publisher, name, url } = parsePackId(packArg);
46
+ const dest = join(PACKS_DIR, publisher, name);
47
+ if (existsSync(dest)) {
48
+ console.log(`Already installed: ${publisher}/${name}`);
49
+ process.exit(0);
50
+ }
51
+ ensureDir(join(PACKS_DIR, publisher));
52
+ console.log(`Installing ${publisher}/${name} from ${url} ...`);
53
+ const r = spawnSync('git', ['clone', url, dest], { stdio: 'inherit' });
54
+ if (r.status !== 0) {
55
+ console.error(`Failed to install ${publisher}/${name}`);
56
+ process.exit(1);
57
+ }
58
+ console.log(`\nInstalled: ${publisher}/${name}`);
59
+ }
60
+
61
+ function packRemove(packArg) {
62
+ const { publisher, name } = parsePackId(packArg);
63
+ const dest = join(PACKS_DIR, publisher, name);
64
+ if (!existsSync(dest)) {
65
+ console.error(`Not installed: ${publisher}/${name}`);
66
+ process.exit(1);
67
+ }
68
+ rmSync(dest, { recursive: true, force: true });
69
+ console.log(`Removed: ${publisher}/${name}`);
70
+ }
71
+
72
+ function packUpdate(packArg) {
73
+ const { publisher, name } = parsePackId(packArg);
74
+ const dest = join(PACKS_DIR, publisher, name);
75
+ if (!existsSync(dest)) {
76
+ console.error(`Not installed: ${publisher}/${name}. Run: agentcraft pack install ${publisher}/${name}`);
77
+ process.exit(1);
78
+ }
79
+ console.log(`Updating ${publisher}/${name} ...`);
80
+ spawnSync('git', ['-C', dest, 'pull'], { stdio: 'inherit' });
81
+ }
82
+
83
+ function packList() {
84
+ const packs = getInstalledPacks();
85
+ if (!packs.length) {
86
+ console.log('No packs installed.');
87
+ console.log('\nInstall the official pack:');
88
+ console.log(' agentcraft pack install rohenaz/agentcraft-sounds');
89
+ } else {
90
+ console.log('Installed packs:');
91
+ for (const p of packs) console.log(` ${p}`);
92
+ }
93
+ }
94
+
95
+ function showHelp() {
96
+ console.log(`
97
+ AgentCraft CLI — assign sounds to AI agent lifecycle events
98
+
99
+ Usage:
100
+ agentcraft pack install <publisher/name> Install a sound pack from GitHub
101
+ agentcraft pack remove <publisher/name> Remove an installed pack
102
+ agentcraft pack update <publisher/name> Update a pack (git pull)
103
+ agentcraft pack update --all Update all installed packs
104
+ agentcraft pack list List installed packs
105
+ agentcraft start Launch the dashboard (port 4040)
106
+
107
+ Examples:
108
+ agentcraft pack install rohenaz/agentcraft-sounds
109
+ agentcraft pack update --all
110
+ agentcraft pack list
111
+
112
+ Packs are stored at: ~/.agentcraft/packs/<publisher>/<name>/
113
+ Any git repo cloned there is automatically discovered by the dashboard.
114
+
115
+ Install the Claude Code plugin:
116
+ claude plugin install agentcraft@rohenaz
117
+ `);
118
+ }
119
+
120
+ if (cmd === 'pack') {
121
+ if (sub === 'install') {
122
+ if (!rest[0]) { console.error('Usage: agentcraft pack install <publisher/name>'); process.exit(1); }
123
+ packInstall(rest[0]);
124
+ } else if (sub === 'remove') {
125
+ if (!rest[0]) { console.error('Usage: agentcraft pack remove <publisher/name>'); process.exit(1); }
126
+ packRemove(rest[0]);
127
+ } else if (sub === 'update') {
128
+ if (rest[0] === '--all') {
129
+ const packs = getInstalledPacks();
130
+ if (!packs.length) { console.log('No packs installed.'); process.exit(0); }
131
+ for (const p of packs) packUpdate(p);
132
+ } else {
133
+ if (!rest[0]) { console.error('Usage: agentcraft pack update <publisher/name> | --all'); process.exit(1); }
134
+ packUpdate(rest[0]);
135
+ }
136
+ } else if (sub === 'list') {
137
+ packList();
138
+ } else {
139
+ console.error(`Unknown pack subcommand: ${sub ?? '(none)'}`);
140
+ console.error('Usage: agentcraft pack <install|remove|update|list>');
141
+ process.exit(1);
142
+ }
143
+ } else if (cmd === 'start') {
144
+ const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT;
145
+ if (!pluginRoot) {
146
+ console.error('CLAUDE_PLUGIN_ROOT not set. This command is intended to run from the Claude Code plugin context.');
147
+ process.exit(1);
148
+ }
149
+ execSync(`cd "${pluginRoot}/web" && bun dev --port 4040`, { stdio: 'inherit' });
150
+ } else if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
151
+ showHelp();
152
+ } else {
153
+ console.error(`Unknown command: ${cmd}`);
154
+ showHelp();
155
+ process.exit(1);
156
+ }
@@ -1,5 +1,5 @@
1
1
  ---
2
- allowed-tools: Bash(lsof:*), Bash(open:*), Bash(bun:*), Bash(curl:*), Bash(git:*), Bash(ls:*), Bash(mkdir:*)
2
+ allowed-tools: Bash(lsof:*), Bash(open:*), Bash(bun:*), Bash(curl:*), Bash(git:*), Bash(ls:*), Bash(mkdir:*), Bash(agentcraft:*)
3
3
  description: Open the AgentCraft sound assignment dashboard. Launches web UI on port 4040.
4
4
  argument-hint: "[--stop] Stop the AgentCraft server"
5
5
  ---
@@ -12,14 +12,15 @@ kill $(lsof -ti:4040) 2>/dev/null
12
12
  echo "AgentCraft server stopped."
13
13
  ```
14
14
 
15
- Otherwise, ensure the sound library is present. Check if ~/.agentcraft/sounds exists and has files:
15
+ Check if the official sound pack is installed:
16
16
  ```bash
17
- ls ~/.agentcraft/sounds 2>/dev/null | head -1
17
+ ls ~/.agentcraft/packs/rohenaz/agentcraft-sounds 2>/dev/null | head -1
18
18
  ```
19
19
 
20
- If that returned nothing (empty or missing), clone the sound library:
20
+ If that returned nothing (empty or missing), install it:
21
21
  ```bash
22
- git clone https://github.com/rohenaz/agentcraft-sounds ~/.agentcraft/sounds
22
+ agentcraft pack install rohenaz/agentcraft-sounds 2>/dev/null || \
23
+ git clone https://github.com/rohenaz/agentcraft-sounds ~/.agentcraft/packs/rohenaz/agentcraft-sounds
23
24
  ```
24
25
 
25
26
  Check if server is already running: