clawpowers 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.
- package/.claude-plugin/manifest.json +19 -0
- package/.codex/INSTALL.md +36 -0
- package/.cursor-plugin/manifest.json +21 -0
- package/.opencode/INSTALL.md +52 -0
- package/ARCHITECTURE.md +69 -0
- package/README.md +381 -0
- package/bin/clawpowers.js +390 -0
- package/bin/clawpowers.sh +91 -0
- package/gemini-extension.json +32 -0
- package/hooks/session-start +205 -0
- package/hooks/session-start.cmd +43 -0
- package/hooks/session-start.js +163 -0
- package/package.json +54 -0
- package/runtime/feedback/analyze.js +621 -0
- package/runtime/feedback/analyze.sh +546 -0
- package/runtime/init.js +172 -0
- package/runtime/init.sh +145 -0
- package/runtime/metrics/collector.js +361 -0
- package/runtime/metrics/collector.sh +308 -0
- package/runtime/persistence/store.js +433 -0
- package/runtime/persistence/store.sh +303 -0
- package/skill.json +74 -0
- package/skills/agent-payments/SKILL.md +411 -0
- package/skills/brainstorming/SKILL.md +233 -0
- package/skills/content-pipeline/SKILL.md +282 -0
- package/skills/dispatching-parallel-agents/SKILL.md +305 -0
- package/skills/executing-plans/SKILL.md +255 -0
- package/skills/finishing-a-development-branch/SKILL.md +260 -0
- package/skills/learn-how-to-learn/SKILL.md +235 -0
- package/skills/market-intelligence/SKILL.md +288 -0
- package/skills/prospecting/SKILL.md +313 -0
- package/skills/receiving-code-review/SKILL.md +225 -0
- package/skills/requesting-code-review/SKILL.md +206 -0
- package/skills/security-audit/SKILL.md +308 -0
- package/skills/subagent-driven-development/SKILL.md +244 -0
- package/skills/systematic-debugging/SKILL.md +279 -0
- package/skills/test-driven-development/SKILL.md +299 -0
- package/skills/using-clawpowers/SKILL.md +137 -0
- package/skills/using-git-worktrees/SKILL.md +261 -0
- package/skills/verification-before-completion/SKILL.md +254 -0
- package/skills/writing-plans/SKILL.md +276 -0
- package/skills/writing-skills/SKILL.md +260 -0
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// bin/clawpowers.js — Cross-platform CLI entry point
|
|
3
|
+
//
|
|
4
|
+
// Commands: init, status, update, inject, metrics, analyze, store
|
|
5
|
+
// Works on Windows CMD, PowerShell, macOS, Linux.
|
|
6
|
+
// Zero npm dependencies — only Node.js built-ins.
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const fs = require('fs');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
const os = require('os');
|
|
12
|
+
const { execSync, spawnSync } = require('child_process');
|
|
13
|
+
|
|
14
|
+
// __dirname is the bin/ directory; repo root is one level up
|
|
15
|
+
const SCRIPT_DIR = __dirname;
|
|
16
|
+
const REPO_ROOT = path.resolve(SCRIPT_DIR, '..');
|
|
17
|
+
|
|
18
|
+
// Runtime data directory — override with CLAWPOWERS_DIR env var for testing
|
|
19
|
+
const CLAWPOWERS_DIR = process.env.CLAWPOWERS_DIR || path.join(os.homedir(), '.clawpowers');
|
|
20
|
+
|
|
21
|
+
// Absolute paths to each runtime module — resolved once at startup so
|
|
22
|
+
// error messages can include the full path if a module is missing
|
|
23
|
+
const INIT_JS = path.join(REPO_ROOT, 'runtime', 'init.js');
|
|
24
|
+
const ANALYZE_JS = path.join(REPO_ROOT, 'runtime', 'feedback', 'analyze.js');
|
|
25
|
+
const STORE_JS = path.join(REPO_ROOT, 'runtime', 'persistence', 'store.js');
|
|
26
|
+
const COLLECTOR_JS = path.join(REPO_ROOT, 'runtime', 'metrics', 'collector.js');
|
|
27
|
+
const SESSION_JS = path.join(REPO_ROOT, 'hooks', 'session-start.js');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Prints the top-level command usage to stdout.
|
|
31
|
+
* Called when no command is given or when 'help'/'-h'/'--help' is passed.
|
|
32
|
+
*/
|
|
33
|
+
function printUsage() {
|
|
34
|
+
console.log(`Usage: clawpowers <command> [args]
|
|
35
|
+
|
|
36
|
+
Commands:
|
|
37
|
+
init Initialize ClawPowers runtime in ~/.clawpowers/
|
|
38
|
+
status Show runtime health and skill metrics summary
|
|
39
|
+
update Pull latest skill definitions from repo
|
|
40
|
+
inject Inject using-clawpowers skill into current session context
|
|
41
|
+
metrics <cmd> Record or query skill execution metrics
|
|
42
|
+
analyze [opts] RSI feedback analysis of skill performance
|
|
43
|
+
store <cmd> Key-value state store operations
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
npx clawpowers init
|
|
47
|
+
npx clawpowers status
|
|
48
|
+
npx clawpowers metrics record --skill my-skill --outcome success
|
|
49
|
+
npx clawpowers metrics summary
|
|
50
|
+
npx clawpowers analyze --skill systematic-debugging
|
|
51
|
+
npx clawpowers store set "my:key" "my value"
|
|
52
|
+
npx clawpowers store get "my:key"
|
|
53
|
+
|
|
54
|
+
Run 'npx clawpowers <command> help' for command-specific help.`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Safely require() a runtime module, exiting with a helpful error if the
|
|
59
|
+
* file doesn't exist (i.e., user hasn't run `init` yet).
|
|
60
|
+
*
|
|
61
|
+
* @param {string} filepath - Absolute path to the module to load.
|
|
62
|
+
* @returns {object} The module's exports.
|
|
63
|
+
*/
|
|
64
|
+
function requireModule(filepath) {
|
|
65
|
+
if (!fs.existsSync(filepath)) {
|
|
66
|
+
process.stderr.write(`Error: runtime module not found: ${filepath}\n`);
|
|
67
|
+
process.stderr.write('Try running: npx clawpowers init\n');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
return require(filepath);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* `clawpowers init` — Set up ~/.clawpowers/ directory structure.
|
|
75
|
+
* Delegates to runtime/init.js which is idempotent (safe to run repeatedly).
|
|
76
|
+
*/
|
|
77
|
+
function cmdInit() {
|
|
78
|
+
console.log('Initializing ClawPowers runtime...');
|
|
79
|
+
const init = requireModule(INIT_JS);
|
|
80
|
+
init.main();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* `clawpowers status` — Show runtime health and full RSI analysis.
|
|
85
|
+
* Requires the runtime to be initialized; exits with an error if not.
|
|
86
|
+
*/
|
|
87
|
+
function cmdStatus() {
|
|
88
|
+
if (!fs.existsSync(CLAWPOWERS_DIR)) {
|
|
89
|
+
process.stderr.write('Runtime not initialized. Run: npx clawpowers init\n');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const analyze = requireModule(ANALYZE_JS);
|
|
93
|
+
analyze.cmdFullAnalysis();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* `clawpowers update` — Pull the latest skill definitions from the GitHub repo.
|
|
98
|
+
* Uses git fast-forward only to avoid overwriting local modifications.
|
|
99
|
+
* Falls back gracefully if git is not installed.
|
|
100
|
+
*/
|
|
101
|
+
function cmdUpdate() {
|
|
102
|
+
const repoUrl = 'https://github.com/up2itnow0822/clawpowers';
|
|
103
|
+
const result = spawnSync('git', ['-C', REPO_ROOT, 'pull', '--ff-only', 'origin', 'main'], {
|
|
104
|
+
stdio: 'inherit',
|
|
105
|
+
// On Windows, git must be launched through the shell so PATH is resolved
|
|
106
|
+
shell: os.platform() === 'win32',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (result.error) {
|
|
110
|
+
// git binary not found or OS-level spawn error
|
|
111
|
+
console.log(`git not found or failed. Visit ${repoUrl} to update manually.`);
|
|
112
|
+
} else if (result.status !== 0) {
|
|
113
|
+
console.log(`Warning: could not auto-update. Visit ${repoUrl} for latest.`);
|
|
114
|
+
} else {
|
|
115
|
+
console.log('Pulling latest skill definitions...');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* `clawpowers inject` — Run the session-start hook to inject the
|
|
121
|
+
* using-clawpowers skill into the current AI platform session.
|
|
122
|
+
* Spawns hooks/session-start.js as a child process so it inherits stdio.
|
|
123
|
+
*/
|
|
124
|
+
function cmdInject() {
|
|
125
|
+
const result = spawnSync(process.execPath, [SESSION_JS], {
|
|
126
|
+
stdio: 'inherit',
|
|
127
|
+
});
|
|
128
|
+
if (result.error) {
|
|
129
|
+
process.stderr.write(`Error running session-start.js: ${result.error.message}\n`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
process.exit(result.status || 0);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* `clawpowers metrics <subcmd> [args]` — Delegate to collector.js.
|
|
137
|
+
* Supported subcommands: record, show, summary.
|
|
138
|
+
*
|
|
139
|
+
* @param {string[]} args - Remaining argv after 'metrics'.
|
|
140
|
+
*/
|
|
141
|
+
function cmdMetrics(args) {
|
|
142
|
+
const collector = requireModule(COLLECTOR_JS);
|
|
143
|
+
const [subcmd, ...rest] = args;
|
|
144
|
+
|
|
145
|
+
// No subcommand or explicit help request: print metrics-specific usage
|
|
146
|
+
if (!subcmd || subcmd === 'help' || subcmd === '--help' || subcmd === '-h') {
|
|
147
|
+
printCollectorUsage();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const mod = requireModule(COLLECTOR_JS);
|
|
152
|
+
|
|
153
|
+
switch (subcmd) {
|
|
154
|
+
case 'record':
|
|
155
|
+
// cmdRecord expects the remaining args array (e.g. ['--skill', 'foo', '--outcome', 'success'])
|
|
156
|
+
mod.cmdRecord ? mod.cmdRecord(rest) : delegateToNode(COLLECTOR_JS, ['record', ...rest]);
|
|
157
|
+
break;
|
|
158
|
+
case 'show':
|
|
159
|
+
mod.cmdShow ? mod.cmdShow(rest) : delegateToNode(COLLECTOR_JS, ['show', ...rest]);
|
|
160
|
+
break;
|
|
161
|
+
case 'summary':
|
|
162
|
+
mod.cmdSummary ? mod.cmdSummary(rest) : delegateToNode(COLLECTOR_JS, ['summary', ...rest]);
|
|
163
|
+
break;
|
|
164
|
+
default:
|
|
165
|
+
process.stderr.write(`Unknown metrics subcommand: ${subcmd}\n`);
|
|
166
|
+
printCollectorUsage();
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Prints usage information for the `metrics` sub-command group.
|
|
173
|
+
*/
|
|
174
|
+
function printCollectorUsage() {
|
|
175
|
+
console.log(`Usage: clawpowers metrics <command> [options]
|
|
176
|
+
|
|
177
|
+
Commands:
|
|
178
|
+
record Record a skill execution outcome
|
|
179
|
+
show Show recent execution records
|
|
180
|
+
summary Show aggregated statistics
|
|
181
|
+
|
|
182
|
+
record options:
|
|
183
|
+
--skill <name> Skill name (required)
|
|
184
|
+
--outcome <result> success | failure | partial | skipped (required)
|
|
185
|
+
--duration <seconds> Execution time in seconds
|
|
186
|
+
--notes <text> Notes about this execution
|
|
187
|
+
--session-id <id> Session identifier`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* `clawpowers analyze [flag] [value]` — RSI feedback analysis.
|
|
192
|
+
* Dispatches to the appropriate analyze.js function based on the flag.
|
|
193
|
+
*
|
|
194
|
+
* @param {string[]} args - Remaining argv after 'analyze'.
|
|
195
|
+
*/
|
|
196
|
+
function cmdAnalyze(args) {
|
|
197
|
+
const analyze = requireModule(ANALYZE_JS);
|
|
198
|
+
const [flag, value] = args;
|
|
199
|
+
|
|
200
|
+
switch (flag) {
|
|
201
|
+
case '--skill': analyze.cmdSkillAnalysis(value); break;
|
|
202
|
+
case '--plan': analyze.cmdPlanAnalysis(value); break;
|
|
203
|
+
case '--worktrees': analyze.cmdWorktreeReport(); break;
|
|
204
|
+
case '--recommendations': analyze.cmdRecommendations(); break;
|
|
205
|
+
// --format accepts a format name but human-readable is the only current output
|
|
206
|
+
case '--format': analyze.cmdFullAnalysis(); break;
|
|
207
|
+
case 'help':
|
|
208
|
+
case '-h':
|
|
209
|
+
case '--help': printAnalyzeUsage(); break;
|
|
210
|
+
// No flag = full analysis of all skills
|
|
211
|
+
case undefined:
|
|
212
|
+
case '': analyze.cmdFullAnalysis(); break;
|
|
213
|
+
default:
|
|
214
|
+
process.stderr.write(`Unknown analyze option: ${flag}\n`);
|
|
215
|
+
printAnalyzeUsage();
|
|
216
|
+
process.exit(1);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Prints usage information for the `analyze` sub-command.
|
|
222
|
+
*/
|
|
223
|
+
function printAnalyzeUsage() {
|
|
224
|
+
console.log(`Usage: clawpowers analyze [options]
|
|
225
|
+
|
|
226
|
+
Options:
|
|
227
|
+
(no args) Full analysis of all skills
|
|
228
|
+
--skill <name> Analysis for one specific skill
|
|
229
|
+
--plan <name> Plan execution analysis
|
|
230
|
+
--worktrees Worktree lifecycle report
|
|
231
|
+
--recommendations Show improvement recommendations only
|
|
232
|
+
--format json JSON output (default: human-readable)`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* `clawpowers store <subcmd> [args]` — Key-value state store operations.
|
|
237
|
+
* Maps CLI subcommands to store.js exported functions.
|
|
238
|
+
*
|
|
239
|
+
* @param {string[]} args - Remaining argv after 'store'.
|
|
240
|
+
*/
|
|
241
|
+
function cmdStore(args) {
|
|
242
|
+
const store = requireModule(STORE_JS);
|
|
243
|
+
const [subcmd, ...rest] = args;
|
|
244
|
+
|
|
245
|
+
if (!subcmd || subcmd === 'help' || subcmd === '--help' || subcmd === '-h') {
|
|
246
|
+
printStoreUsage();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
switch (subcmd) {
|
|
252
|
+
case 'set':
|
|
253
|
+
// rest[1] may be undefined for empty-string value; default to ''
|
|
254
|
+
store.cmdSet(rest[0], rest[1] !== undefined ? rest[1] : '');
|
|
255
|
+
break;
|
|
256
|
+
|
|
257
|
+
case 'get': {
|
|
258
|
+
// Pass default value only when it was explicitly supplied (args.length >= 2)
|
|
259
|
+
let val;
|
|
260
|
+
try {
|
|
261
|
+
val = rest.length >= 2 ? store.cmdGet(rest[0], rest[1]) : store.cmdGet(rest[0]);
|
|
262
|
+
console.log(val);
|
|
263
|
+
} catch (err) {
|
|
264
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
265
|
+
process.exit(1);
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
case 'delete': {
|
|
271
|
+
const msg = store.cmdDelete(rest[0]);
|
|
272
|
+
// cmdDelete returns a "Key not found" prefix for missing keys — route to stderr
|
|
273
|
+
if (msg.startsWith('Key not found')) process.stderr.write(msg + '\n');
|
|
274
|
+
else console.log(msg);
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
case 'list': {
|
|
279
|
+
const keys = store.cmdList(rest[0] || '');
|
|
280
|
+
if (keys.length === 0 && rest[0]) {
|
|
281
|
+
process.stderr.write(`No keys found with prefix: ${rest[0]}\n`);
|
|
282
|
+
} else {
|
|
283
|
+
keys.forEach(k => console.log(k));
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
case 'list-values': {
|
|
289
|
+
const pairs = store.cmdListValues(rest[0] || '');
|
|
290
|
+
if (pairs.length === 0 && rest[0]) {
|
|
291
|
+
process.stderr.write(`No keys found with prefix: ${rest[0]}\n`);
|
|
292
|
+
} else {
|
|
293
|
+
pairs.forEach(p => console.log(p));
|
|
294
|
+
}
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
case 'exists': {
|
|
299
|
+
// Exit 0 if key exists, exit 1 if not — compatible with shell conditionals
|
|
300
|
+
const exists = store.cmdExists(rest[0]);
|
|
301
|
+
process.exit(exists ? 0 : 1);
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
case 'append':
|
|
306
|
+
store.cmdAppend(rest[0], rest[1] !== undefined ? rest[1] : '');
|
|
307
|
+
break;
|
|
308
|
+
|
|
309
|
+
case 'incr': {
|
|
310
|
+
// Parse increment amount as base-10 integer; defaults to 1 inside cmdIncr
|
|
311
|
+
const newVal = store.cmdIncr(rest[0], rest[1] !== undefined ? parseInt(rest[1], 10) : 1);
|
|
312
|
+
console.log(newVal);
|
|
313
|
+
break;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
default:
|
|
317
|
+
process.stderr.write(`Unknown store command: ${subcmd}\n`);
|
|
318
|
+
printStoreUsage();
|
|
319
|
+
process.exit(1);
|
|
320
|
+
}
|
|
321
|
+
} catch (err) {
|
|
322
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Prints usage information for the `store` sub-command group.
|
|
329
|
+
*/
|
|
330
|
+
function printStoreUsage() {
|
|
331
|
+
console.log(`Usage: clawpowers store <command> [args]
|
|
332
|
+
|
|
333
|
+
Commands:
|
|
334
|
+
set <key> <value> Set a key-value pair
|
|
335
|
+
get <key> [default] Get value (returns default or error if not found)
|
|
336
|
+
delete <key> Delete a key
|
|
337
|
+
list [prefix] List all keys matching prefix
|
|
338
|
+
list-values [prefix] List key=value pairs matching prefix
|
|
339
|
+
exists <key> Exit 0 if key exists, 1 if not
|
|
340
|
+
append <key> <value> Append value (newline-separated)
|
|
341
|
+
incr <key> [amount] Increment integer value by amount (default: 1)
|
|
342
|
+
|
|
343
|
+
Key format: namespace:entity:attribute`);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Fallback dispatcher: spawn `node <script> [...args]` as a child process.
|
|
348
|
+
* Used when a module function isn't directly exported but can be triggered
|
|
349
|
+
* via its CLI entry point.
|
|
350
|
+
*
|
|
351
|
+
* @param {string} script - Absolute path to the Node.js script to run.
|
|
352
|
+
* @param {string[]} args - Arguments to forward to the script.
|
|
353
|
+
*/
|
|
354
|
+
function delegateToNode(script, args) {
|
|
355
|
+
const result = spawnSync(process.execPath, [script, ...args], { stdio: 'inherit' });
|
|
356
|
+
process.exit(result.status || 0);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// ============================================================
|
|
360
|
+
// Main dispatch — parse the first positional argument as the command
|
|
361
|
+
// ============================================================
|
|
362
|
+
const [cmd, ...args] = process.argv.slice(2);
|
|
363
|
+
|
|
364
|
+
try {
|
|
365
|
+
switch (cmd) {
|
|
366
|
+
case 'init': cmdInit(); break;
|
|
367
|
+
case 'status': cmdStatus(); break;
|
|
368
|
+
case 'update': cmdUpdate(); break;
|
|
369
|
+
case 'inject': cmdInject(); break;
|
|
370
|
+
case 'metrics': cmdMetrics(args); break;
|
|
371
|
+
case 'analyze': cmdAnalyze(args); break;
|
|
372
|
+
case 'store': cmdStore(args); break;
|
|
373
|
+
case 'help':
|
|
374
|
+
case '-h':
|
|
375
|
+
case '--help': printUsage(); break;
|
|
376
|
+
// No command or empty string: show usage and exit 1 (non-zero for scripts)
|
|
377
|
+
case undefined:
|
|
378
|
+
case '':
|
|
379
|
+
printUsage();
|
|
380
|
+
process.exit(1);
|
|
381
|
+
break;
|
|
382
|
+
default:
|
|
383
|
+
process.stderr.write(`Unknown command: ${cmd}\n`);
|
|
384
|
+
printUsage();
|
|
385
|
+
process.exit(1);
|
|
386
|
+
}
|
|
387
|
+
} catch (err) {
|
|
388
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
389
|
+
process.exit(1);
|
|
390
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# bin/clawpowers.sh — Bash CLI entry point for ClawPowers
|
|
3
|
+
#
|
|
4
|
+
# Provides the same commands as clawpowers.js for Unix environments that
|
|
5
|
+
# prefer bash over Node.js. The JS version (clawpowers.js) is the primary
|
|
6
|
+
# cross-platform entry point; this script is a convenience wrapper.
|
|
7
|
+
#
|
|
8
|
+
# Commands: init, status, update, inject
|
|
9
|
+
# Requires: bash, git (optional, for update command)
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
# Runtime data directory — override with CLAWPOWERS_DIR env var for custom locations
|
|
13
|
+
CLAWPOWERS_DIR="${CLAWPOWERS_DIR:-$HOME/.clawpowers}"
|
|
14
|
+
|
|
15
|
+
# Resolve the repo root from this script's location (bin/ → repo root)
|
|
16
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
18
|
+
|
|
19
|
+
## === Usage ===
|
|
20
|
+
|
|
21
|
+
usage() {
|
|
22
|
+
cat <<EOF
|
|
23
|
+
Usage: clawpowers <command>
|
|
24
|
+
|
|
25
|
+
Commands:
|
|
26
|
+
init Initialize ClawPowers runtime in ~/.clawpowers/
|
|
27
|
+
status Show runtime health and skill metrics summary
|
|
28
|
+
update Pull latest skill definitions from repo
|
|
29
|
+
inject Inject using-clawpowers skill into current session context
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
npx clawpowers init
|
|
33
|
+
npx clawpowers status
|
|
34
|
+
EOF
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
## === Command Implementations ===
|
|
38
|
+
|
|
39
|
+
# init — Set up the runtime directory structure
|
|
40
|
+
# Delegates to runtime/init.sh which is idempotent (safe to run multiple times)
|
|
41
|
+
cmd_init() {
|
|
42
|
+
echo "Initializing ClawPowers runtime..."
|
|
43
|
+
bash "$REPO_ROOT/runtime/init.sh"
|
|
44
|
+
echo "Done. ClawPowers runtime ready at $CLAWPOWERS_DIR"
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# status — Show RSI feedback analysis and runtime health
|
|
48
|
+
# Requires the runtime to be initialized; exits 1 with a helpful message if not
|
|
49
|
+
cmd_status() {
|
|
50
|
+
if [[ ! -d "$CLAWPOWERS_DIR" ]]; then
|
|
51
|
+
echo "Runtime not initialized. Run: npx clawpowers init"
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
bash "$REPO_ROOT/runtime/feedback/analyze.sh"
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
# update — Pull the latest skill definitions from the GitHub repository
|
|
58
|
+
# Uses git fast-forward only (--ff-only) to avoid overwriting local modifications.
|
|
59
|
+
# Falls back gracefully when git is not installed.
|
|
60
|
+
cmd_update() {
|
|
61
|
+
local repo_url="https://github.com/up2itnow0822/clawpowers"
|
|
62
|
+
if command -v git >/dev/null 2>&1; then
|
|
63
|
+
echo "Pulling latest skill definitions..."
|
|
64
|
+
# Redirect stderr so git verbose output doesn't clutter the terminal
|
|
65
|
+
git -C "$REPO_ROOT" pull --ff-only origin main 2>/dev/null || \
|
|
66
|
+
echo "Warning: could not auto-update. Visit $repo_url for latest."
|
|
67
|
+
else
|
|
68
|
+
echo "git not found. Visit $repo_url to update manually."
|
|
69
|
+
fi
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
# inject — Run the session-start hook to push the using-clawpowers skill
|
|
73
|
+
# into the current AI platform's context window.
|
|
74
|
+
# Calls the bash hook (hooks/session-start) which auto-detects the platform.
|
|
75
|
+
cmd_inject() {
|
|
76
|
+
bash "$REPO_ROOT/hooks/session-start"
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
## === Main Dispatch ===
|
|
80
|
+
|
|
81
|
+
# Route the first positional argument to the appropriate command function.
|
|
82
|
+
# Unknown commands print usage and exit 1 so shell scripts can detect errors.
|
|
83
|
+
case "${1:-}" in
|
|
84
|
+
init) cmd_init ;;
|
|
85
|
+
status) cmd_status ;;
|
|
86
|
+
update) cmd_update ;;
|
|
87
|
+
inject) cmd_inject ;;
|
|
88
|
+
help|-h|--help) usage ;;
|
|
89
|
+
"") usage; exit 1 ;;
|
|
90
|
+
*) echo "Unknown command: $1"; usage; exit 1 ;;
|
|
91
|
+
esac
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "clawpowers",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Skills framework with runtime execution, persistent memory, self-improvement, and agent payments for Gemini CLI.",
|
|
5
|
+
"author": "AI Agent Economy",
|
|
6
|
+
"homepage": "https://github.com/up2itnow0822/clawpowers",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"type": "extension",
|
|
9
|
+
"hooks": {
|
|
10
|
+
"session_start": {
|
|
11
|
+
"command": "bash",
|
|
12
|
+
"args": ["hooks/session-start"],
|
|
13
|
+
"env": {
|
|
14
|
+
"GEMINI_CLI": "1"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"skills_directory": "skills/",
|
|
19
|
+
"runtime_directory": "runtime/",
|
|
20
|
+
"inject_on_start": true,
|
|
21
|
+
"inject_skill": "using-clawpowers",
|
|
22
|
+
"capabilities": [
|
|
23
|
+
"skill_injection",
|
|
24
|
+
"persistent_state",
|
|
25
|
+
"outcome_metrics",
|
|
26
|
+
"rsi_feedback"
|
|
27
|
+
],
|
|
28
|
+
"install": {
|
|
29
|
+
"command": "gemini extensions install https://github.com/up2itnow0822/clawpowers",
|
|
30
|
+
"post_install": "npx clawpowers init"
|
|
31
|
+
}
|
|
32
|
+
}
|