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.
Files changed (42) hide show
  1. package/.claude-plugin/manifest.json +19 -0
  2. package/.codex/INSTALL.md +36 -0
  3. package/.cursor-plugin/manifest.json +21 -0
  4. package/.opencode/INSTALL.md +52 -0
  5. package/ARCHITECTURE.md +69 -0
  6. package/README.md +381 -0
  7. package/bin/clawpowers.js +390 -0
  8. package/bin/clawpowers.sh +91 -0
  9. package/gemini-extension.json +32 -0
  10. package/hooks/session-start +205 -0
  11. package/hooks/session-start.cmd +43 -0
  12. package/hooks/session-start.js +163 -0
  13. package/package.json +54 -0
  14. package/runtime/feedback/analyze.js +621 -0
  15. package/runtime/feedback/analyze.sh +546 -0
  16. package/runtime/init.js +172 -0
  17. package/runtime/init.sh +145 -0
  18. package/runtime/metrics/collector.js +361 -0
  19. package/runtime/metrics/collector.sh +308 -0
  20. package/runtime/persistence/store.js +433 -0
  21. package/runtime/persistence/store.sh +303 -0
  22. package/skill.json +74 -0
  23. package/skills/agent-payments/SKILL.md +411 -0
  24. package/skills/brainstorming/SKILL.md +233 -0
  25. package/skills/content-pipeline/SKILL.md +282 -0
  26. package/skills/dispatching-parallel-agents/SKILL.md +305 -0
  27. package/skills/executing-plans/SKILL.md +255 -0
  28. package/skills/finishing-a-development-branch/SKILL.md +260 -0
  29. package/skills/learn-how-to-learn/SKILL.md +235 -0
  30. package/skills/market-intelligence/SKILL.md +288 -0
  31. package/skills/prospecting/SKILL.md +313 -0
  32. package/skills/receiving-code-review/SKILL.md +225 -0
  33. package/skills/requesting-code-review/SKILL.md +206 -0
  34. package/skills/security-audit/SKILL.md +308 -0
  35. package/skills/subagent-driven-development/SKILL.md +244 -0
  36. package/skills/systematic-debugging/SKILL.md +279 -0
  37. package/skills/test-driven-development/SKILL.md +299 -0
  38. package/skills/using-clawpowers/SKILL.md +137 -0
  39. package/skills/using-git-worktrees/SKILL.md +261 -0
  40. package/skills/verification-before-completion/SKILL.md +254 -0
  41. package/skills/writing-plans/SKILL.md +276 -0
  42. 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
+ }