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,303 @@
1
+ #!/usr/bin/env bash
2
+ # runtime/persistence/store.sh — File-based key-value persistence
3
+ #
4
+ # Stores skill state in ~/.clawpowers/state/ using flat files.
5
+ # Each key maps to a file. Safe for concurrent reads; writes are atomic via temp file.
6
+ #
7
+ # Usage:
8
+ # store.sh set <key> <value> Set a key-value pair
9
+ # store.sh get <key> Get value for key (exits 1 if not found)
10
+ # store.sh get <key> <default> Get value, return default if not found
11
+ # store.sh delete <key> Delete a key
12
+ # store.sh list [prefix] List all keys (optionally filtered by prefix)
13
+ # store.sh list-values [prefix] List key=value pairs
14
+ # store.sh exists <key> Exit 0 if key exists, 1 if not
15
+ # store.sh append <key> <value> Append value to existing (newline-separated)
16
+ # store.sh incr <key> Increment a numeric value by 1
17
+ # store.sh incr <key> <n> Increment by n
18
+ #
19
+ # Key naming convention:
20
+ # namespace:entity:attribute
21
+ # Example: "execution:auth-plan:task_3:status"
22
+ #
23
+ # Keys may contain: [a-zA-Z0-9:_.-]
24
+ # Values may contain any printable characters
25
+ # Keys with '/' are rejected (no path traversal)
26
+ set -euo pipefail
27
+
28
+ ## === Configuration ===
29
+
30
+ # State directory — override parent with CLAWPOWERS_DIR env var for testing
31
+ STATE_DIR="${CLAWPOWERS_DIR:-$HOME/.clawpowers}/state"
32
+
33
+ ## === Internal Utilities ===
34
+
35
+ # Creates the state directory if it doesn't already exist.
36
+ # Mode 700 ensures the directory is accessible only to the current user.
37
+ ensure_dir() {
38
+ if [[ ! -d "$STATE_DIR" ]]; then
39
+ mkdir -p "$STATE_DIR"
40
+ chmod 700 "$STATE_DIR"
41
+ fi
42
+ }
43
+
44
+ # Validates a key before use. Rejects empty keys, path separators, and '..'
45
+ # to prevent directory traversal attacks when constructing filenames.
46
+ validate_key() {
47
+ local key="$1"
48
+ if [[ -z "$key" ]]; then
49
+ echo "Error: key cannot be empty" >&2
50
+ exit 1
51
+ fi
52
+ # Reject '/' and '\' — they would allow writing outside STATE_DIR
53
+ if [[ "$key" =~ [/\\] ]]; then
54
+ echo "Error: key cannot contain '/' or '\\': $key" >&2
55
+ exit 1
56
+ fi
57
+ # Reject '..' segments to prevent directory traversal
58
+ if [[ "$key" =~ \.\. ]]; then
59
+ echo "Error: key cannot contain '..': $key" >&2
60
+ exit 1
61
+ fi
62
+ }
63
+
64
+ # Converts a colon-separated key to a safe filesystem filename.
65
+ # Colons are replaced with double underscores because ':' is not valid in
66
+ # Windows filenames and can be ambiguous on some filesystems.
67
+ #
68
+ # Example: "execution:my-plan:task_1" → "$STATE_DIR/execution__my-plan__task_1"
69
+ key_to_file() {
70
+ local key="$1"
71
+ echo "$STATE_DIR/${key//:/__}"
72
+ }
73
+
74
+ # Atomically writes a value to a file using temp-file-then-mv.
75
+ # This prevents partial writes — readers see either the old value or the new
76
+ # value, never an intermediate truncated state.
77
+ atomic_write() {
78
+ local file="$1"
79
+ local value="$2"
80
+ # Use PID in temp filename to avoid collisions with concurrent writes
81
+ local tmpfile="${file}.tmp.$$"
82
+
83
+ echo "$value" > "$tmpfile"
84
+ chmod 600 "$tmpfile"
85
+ # mv is atomic on POSIX filesystems when source and dest are on the same mount
86
+ mv "$tmpfile" "$file"
87
+ }
88
+
89
+ ## === Command Implementations ===
90
+
91
+ # set — Write a value to a key, overwriting any existing value.
92
+ cmd_set() {
93
+ local key="$1"
94
+ local value="${2:-}" # Default to empty string if no value provided
95
+ validate_key "$key"
96
+ ensure_dir
97
+
98
+ local file
99
+ file=$(key_to_file "$key")
100
+ atomic_write "$file" "$value"
101
+ }
102
+
103
+ # get — Read the value for a key.
104
+ # If the key doesn't exist and a default is provided, print the default.
105
+ # If the key doesn't exist and no default is provided, print an error and exit 1.
106
+ # The sentinel "__NOTSET__" distinguishes "no default provided" from "empty default".
107
+ cmd_get() {
108
+ local key="$1"
109
+ local default_val="${2:-__NOTSET__}"
110
+ validate_key "$key"
111
+ ensure_dir
112
+
113
+ local file
114
+ file=$(key_to_file "$key")
115
+
116
+ if [[ -f "$file" ]]; then
117
+ cat "$file"
118
+ elif [[ "$default_val" != "__NOTSET__" ]]; then
119
+ echo "$default_val"
120
+ else
121
+ echo "Error: key not found: $key" >&2
122
+ exit 1
123
+ fi
124
+ }
125
+
126
+ # delete — Remove a key and its file.
127
+ # Prints a confirmation on success, or a "not found" message to stderr.
128
+ cmd_delete() {
129
+ local key="$1"
130
+ validate_key "$key"
131
+
132
+ local file
133
+ file=$(key_to_file "$key")
134
+ if [[ -f "$file" ]]; then
135
+ rm -f "$file"
136
+ echo "Deleted: $key"
137
+ else
138
+ # Route "not found" to stderr so shell scripts can distinguish from success output
139
+ echo "Key not found (nothing deleted): $key" >&2
140
+ fi
141
+ }
142
+
143
+ # list — Print all keys matching an optional prefix (one key per line).
144
+ # The prefix uses colon notation (e.g. "execution:my-plan:") which is converted
145
+ # to filename notation before globbing.
146
+ cmd_list() {
147
+ local prefix="${1:-}"
148
+ ensure_dir
149
+
150
+ # Convert prefix from key format (colons) to filename format (double underscores)
151
+ local file_prefix="${prefix//:/__}"
152
+
153
+ local found=0
154
+ for f in "$STATE_DIR"/${file_prefix}*; do
155
+ if [[ -f "$f" ]]; then
156
+ # Convert filename back to colon-separated key format for output
157
+ local basename
158
+ basename=$(basename "$f")
159
+ local key="${basename//__/:}"
160
+ echo "$key"
161
+ ((found++)) || true
162
+ fi
163
+ done
164
+
165
+ if [[ $found -eq 0 && -n "$prefix" ]]; then
166
+ echo "No keys found with prefix: $prefix" >&2
167
+ fi
168
+ }
169
+
170
+ # list-values — Print all key=value pairs matching an optional prefix.
171
+ # Output format: "key=value" (one pair per line), suitable for shell parsing.
172
+ cmd_list_values() {
173
+ local prefix="${1:-}"
174
+ ensure_dir
175
+
176
+ local file_prefix="${prefix//:/__}"
177
+
178
+ local found=0
179
+ for f in "$STATE_DIR"/${file_prefix}*; do
180
+ if [[ -f "$f" ]]; then
181
+ local basename
182
+ basename=$(basename "$f")
183
+ local key="${basename//__/:}"
184
+ local value
185
+ value=$(cat "$f")
186
+ echo "${key}=${value}"
187
+ ((found++)) || true
188
+ fi
189
+ done
190
+
191
+ if [[ $found -eq 0 && -n "$prefix" ]]; then
192
+ echo "No keys found with prefix: $prefix" >&2
193
+ fi
194
+ }
195
+
196
+ # exists — Exit 0 if the key exists, exit 1 if not.
197
+ # Designed for use in shell conditionals: `store.sh exists my:key && echo "found"`
198
+ cmd_exists() {
199
+ local key="$1"
200
+ validate_key "$key"
201
+
202
+ local file
203
+ file=$(key_to_file "$key")
204
+ # The [[ -f "$file" ]] test returns 0/1 directly — no explicit exit needed
205
+ [[ -f "$file" ]]
206
+ }
207
+
208
+ # append — Add a value to an existing key, separated by a newline.
209
+ # Creates the key if it doesn't exist (same behavior as set on first call).
210
+ # Useful for maintaining lists, logs, or multi-line notes in a single key.
211
+ cmd_append() {
212
+ local key="$1"
213
+ local value="${2:-}"
214
+ validate_key "$key"
215
+ ensure_dir
216
+
217
+ local file
218
+ file=$(key_to_file "$key")
219
+
220
+ if [[ -f "$file" ]]; then
221
+ # Append to existing content — echo adds the trailing newline separator
222
+ echo "$value" >> "$file"
223
+ else
224
+ # First write: use atomic write to properly create the file with permissions
225
+ atomic_write "$file" "$value"
226
+ fi
227
+ }
228
+
229
+ # incr — Increment the integer value stored at a key.
230
+ # Creates the key with value equal to `amount` if it doesn't exist (treating missing as 0).
231
+ # Rejects non-integer values with an error.
232
+ cmd_incr() {
233
+ local key="$1"
234
+ local amount="${2:-1}" # Default increment is 1
235
+ validate_key "$key"
236
+ ensure_dir
237
+
238
+ local file
239
+ file=$(key_to_file "$key")
240
+
241
+ # Read the current value; default to 0 if the key doesn't exist
242
+ local current=0
243
+ if [[ -f "$file" ]]; then
244
+ # tr removes all whitespace including the trailing newline written by atomic_write
245
+ current=$(cat "$file" | tr -d '[:space:]')
246
+ # Validate that the stored value is a plain integer (no decimals, no whitespace)
247
+ if ! [[ "$current" =~ ^-?[0-9]+$ ]]; then
248
+ echo "Error: value is not an integer: $current" >&2
249
+ exit 1
250
+ fi
251
+ fi
252
+
253
+ local new_val=$((current + amount))
254
+ atomic_write "$file" "$new_val"
255
+ echo "$new_val"
256
+ }
257
+
258
+ ## === Usage ===
259
+
260
+ cmd_usage() {
261
+ cat << 'EOF'
262
+ Usage: store.sh <command> [args]
263
+
264
+ Commands:
265
+ set <key> <value> Set a key-value pair
266
+ get <key> [default] Get value (returns default or error if not found)
267
+ delete <key> Delete a key
268
+ list [prefix] List all keys matching prefix
269
+ list-values [prefix] List key=value pairs matching prefix
270
+ exists <key> Exit 0 if key exists, 1 if not
271
+ append <key> <value> Append value (newline-separated)
272
+ incr <key> [amount] Increment integer value by amount (default: 1)
273
+
274
+ Key format: namespace:entity:attribute (e.g., "execution:auth-plan:task_3:status")
275
+ State stored in: ~/.clawpowers/state/
276
+
277
+ Examples:
278
+ store.sh set "execution:my-plan:task_1:status" "complete"
279
+ store.sh get "execution:my-plan:task_1:status"
280
+ store.sh get "missing-key" "default-value"
281
+ store.sh list "execution:my-plan:"
282
+ store.sh incr "metrics:session:payment_count"
283
+ store.sh exists "execution:my-plan:task_1:status" && echo "exists"
284
+ EOF
285
+ }
286
+
287
+ ## === Main Dispatch ===
288
+
289
+ # Route the first positional argument to the appropriate command function.
290
+ # Arguments after the command name are forwarded directly to each function.
291
+ case "${1:-}" in
292
+ set) cmd_set "${2:-}" "${3:-}" ;;
293
+ get) cmd_get "${2:-}" "${3:-__NOTSET__}" ;;
294
+ delete) cmd_delete "${2:-}" ;;
295
+ list) cmd_list "${2:-}" ;;
296
+ list-values) cmd_list_values "${2:-}" ;;
297
+ exists) cmd_exists "${2:-}" ;;
298
+ append) cmd_append "${2:-}" "${3:-}" ;;
299
+ incr) cmd_incr "${2:-}" "${3:-1}" ;;
300
+ help|-h|--help) cmd_usage ;;
301
+ "") cmd_usage; exit 1 ;;
302
+ *) echo "Unknown command: $1"; cmd_usage; exit 1 ;;
303
+ esac
package/skill.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "clawpowers",
3
+ "version": "1.0.0",
4
+ "description": "Runtime-powered skills framework — 20 skills with persistent memory, self-improvement (RSI), outcome tracking, and autonomous agent payments (x402). Works on Claude Code, Cursor, Codex, OpenCode, Gemini CLI.",
5
+ "author": {
6
+ "name": "AI Agent Economy",
7
+ "url": "https://github.com/up2itnow0822"
8
+ },
9
+ "repository": "https://github.com/up2itnow0822/clawpowers",
10
+ "keywords": [
11
+ "skills",
12
+ "agent",
13
+ "runtime",
14
+ "rsi",
15
+ "self-improvement",
16
+ "persistence",
17
+ "payments",
18
+ "x402",
19
+ "tdd",
20
+ "debugging",
21
+ "code-review",
22
+ "security-audit",
23
+ "content-pipeline",
24
+ "market-intelligence",
25
+ "prospecting",
26
+ "subagent"
27
+ ],
28
+ "config": {},
29
+ "triggers": [
30
+ "plan this feature",
31
+ "debug this",
32
+ "write tests",
33
+ "code review",
34
+ "brainstorm",
35
+ "security audit",
36
+ "pay for this API",
37
+ "find leads",
38
+ "market research",
39
+ "analyze performance"
40
+ ],
41
+ "platforms": ["macos", "linux", "windows"],
42
+ "category": "development",
43
+ "runtime": {
44
+ "init": "node bin/clawpowers.js init",
45
+ "status": "node bin/clawpowers.js status",
46
+ "stateDir": "~/.clawpowers"
47
+ },
48
+ "skills": {
49
+ "core": [
50
+ "subagent-driven-development",
51
+ "test-driven-development",
52
+ "writing-plans",
53
+ "executing-plans",
54
+ "brainstorming",
55
+ "systematic-debugging",
56
+ "verification-before-completion",
57
+ "finishing-a-development-branch",
58
+ "requesting-code-review",
59
+ "receiving-code-review",
60
+ "using-git-worktrees",
61
+ "using-clawpowers",
62
+ "writing-skills",
63
+ "dispatching-parallel-agents"
64
+ ],
65
+ "extended": [
66
+ "agent-payments",
67
+ "security-audit",
68
+ "content-pipeline",
69
+ "learn-how-to-learn",
70
+ "market-intelligence",
71
+ "prospecting"
72
+ ]
73
+ }
74
+ }