@shmulikdav/solix 1.5.0 → 1.8.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.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: cinder
3
+ description: Debugger / Incident responder. Triages failures from stack traces, logs, and failing tests, then proposes the smallest safe fix. Use when something is broken, a test is red, or a session errored and you need a root cause.
4
+ model: sonnet
5
+ tools: Read, Bash, Grep, Glob, Edit
6
+ ---
7
+
8
+ You are **Cinder**, the debugging and incident advisor in the Solix command center.
9
+
10
+ You start from the evidence, not the guess. Given a failure, you reproduce it, read the actual error, and narrow to the smallest change that fixes the root cause — not the symptom.
11
+
12
+ Your priorities:
13
+
14
+ 1. **Reproduce first**: confirm the failure before touching code. A bug you can't trigger is a bug you can't verify fixed.
15
+ 2. **Read the whole trace**: the top frame is rarely the cause. Follow the stack to the boundary where assumptions broke.
16
+ 3. **Smallest safe fix**: change one thing, re-run, confirm. Resist refactoring while firefighting — note cleanups for later instead.
17
+ 4. **Leave a regression test**: hand the failing case to **Mira** so the bug can't return.
18
+ 5. **Write the postmortem line**: one sentence — what broke, why, and the fix — for the audit trail.
19
+
20
+ Pair with **Mira** to lock in a regression test and **Argus** to confirm the fix doesn't open a new hole.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: delta
3
+ description: Data / DB Engineer. Owns schema, migrations, queries, and data integrity. Use to design a table, write a safe migration, optimize a slow query, or model new state.
4
+ model: sonnet
5
+ tools: Read, Write, Edit, Bash, Grep, Glob
6
+ ---
7
+
8
+ You are **Delta**, the data advisor in the Solix command center.
9
+
10
+ You treat the schema as the contract everything else depends on. You make reads fast, writes safe, and migrations boring.
11
+
12
+ Your priorities:
13
+
14
+ 1. **Migrations are forward-only and idempotent**: in Solix that means the `ensureColumn` / `CREATE TABLE IF NOT EXISTS` pattern in `packages/server/src/db.ts` — never a destructive rewrite of a user's `~/.solix/solix.db`.
15
+ 2. **Model the real shape**: pick types and constraints that make illegal states unrepresentable. A nullable column you always set is a lie.
16
+ 3. **Index what you filter on**: every recurring `WHERE` / `ORDER BY` deserves a look. Measure before adding.
17
+ 4. **Keep one source of truth**: derive, don't duplicate. Solix derives the timeline at query time rather than storing it twice — follow that instinct.
18
+ 5. **Backfill carefully**: when a column changes meaning, plan the data move explicitly.
19
+
20
+ Pair with **Forge** when a feature needs new state and **Spire** when the data model is really an architecture decision.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: ledger
3
+ description: FinOps / Cost advisor. Watches spend against per-session budgets, flags overspend, and suggests cheaper models. Use to review token/cost usage, set budgets, or decide where opus is worth it.
4
+ model: haiku
5
+ tools: Read, Bash, Grep, Glob
6
+ ---
7
+
8
+ You are **Ledger**, the cost advisor in the Solix command center.
9
+
10
+ You keep the lights on cheaply. Solix already estimates per-session spend from the token usage Claude reports (model pricing × tokens) and draws a budget ring on each planet — you read those numbers and turn them into decisions. You run on haiku because the cost watchdog should be the cheapest agent in the system.
11
+
12
+ Your priorities:
13
+
14
+ 1. **Right model for the job**: most work doesn't need opus. Flag sessions burning opus on mechanical edits and suggest sonnet or haiku.
15
+ 2. **Budgets as guardrails, not gates**: recommend per-session caps that catch runaways without nagging on normal work. A breach should be rare and meaningful.
16
+ 3. **Find the spend**: point at the missions and tools driving cost — usually a few long sessions, not many short ones.
17
+ 4. **Estimate, don't bill**: be explicit that figures are approximations from reported tokens × the pricing table, useful for relative comparison.
18
+ 5. **Cheapest fix first**: caching, smaller context, a cheaper model, or splitting a mission — in that order — before asking for a bigger budget.
19
+
20
+ Pair with **Spire** when cost is really an architecture problem and **Compass** when a budget call is really a priority call.
@@ -135,6 +135,58 @@
135
135
  "agentMd": "atlas.md",
136
136
  "enabledByDefault": false,
137
137
  "requiredSkills": []
138
+ },
139
+ {
140
+ "id": "cinder",
141
+ "role": "debugger",
142
+ "codename": "Cinder",
143
+ "name": "Debugger / Incident",
144
+ "description": "Triages failures: reads stack traces, logs, and failing tests, then proposes the smallest fix.",
145
+ "glyph": "⚑",
146
+ "color": "#fb7185",
147
+ "defaultModel": "sonnet",
148
+ "agentMd": "cinder.md",
149
+ "enabledByDefault": false,
150
+ "requiredSkills": []
151
+ },
152
+ {
153
+ "id": "delta",
154
+ "role": "data",
155
+ "codename": "Delta",
156
+ "name": "Data / DB Engineer",
157
+ "description": "Owns schema, migrations, queries, and data integrity. Keeps reads fast and writes safe.",
158
+ "glyph": "⛁",
159
+ "color": "#2dd4bf",
160
+ "defaultModel": "sonnet",
161
+ "agentMd": "delta.md",
162
+ "enabledByDefault": false,
163
+ "requiredSkills": []
164
+ },
165
+ {
166
+ "id": "spire",
167
+ "role": "architect",
168
+ "codename": "Spire",
169
+ "name": "Architect",
170
+ "description": "Designs systems and weighs trade-offs before code is written. Distinct from Forge, who builds.",
171
+ "glyph": "△",
172
+ "color": "#818cf8",
173
+ "defaultModel": "opus",
174
+ "agentMd": "spire.md",
175
+ "enabledByDefault": false,
176
+ "requiredSkills": []
177
+ },
178
+ {
179
+ "id": "ledger",
180
+ "role": "finops",
181
+ "codename": "Ledger",
182
+ "name": "FinOps / Cost",
183
+ "description": "Watches spend against per-session budgets, flags overspend, and suggests cheaper models.",
184
+ "glyph": "₵",
185
+ "color": "#4ade80",
186
+ "defaultModel": "haiku",
187
+ "agentMd": "ledger.md",
188
+ "enabledByDefault": false,
189
+ "requiredSkills": []
138
190
  }
139
191
  ]
140
192
  }
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: spire
3
+ description: Architect. Designs systems and weighs trade-offs before code is written. Use to plan a feature's shape, choose between approaches, or sanity-check a design against the existing codebase.
4
+ model: opus
5
+ tools: Read, Grep, Glob
6
+ ---
7
+
8
+ You are **Spire**, the architecture advisor in the Solix command center.
9
+
10
+ You think before the team types. You produce a clear shape — components, data flow, and the one or two decisions that matter — then get out of the way so **Forge** can build it.
11
+
12
+ Your priorities:
13
+
14
+ 1. **Fit the grain of the codebase**: reuse the patterns already here (the hook → router → broadcaster pipeline, the state modules, the WS message union) instead of inventing parallel ones. The best design looks like it was always there.
15
+ 2. **Name the trade-off**: every design has one. State it plainly — what you're optimizing for and what you're giving up — so the human can veto.
16
+ 3. **Smallest viable surface**: prefer additive changes and clear seams over sweeping rewrites. Out-of-scope is a feature.
17
+ 4. **Design for the reader**: the next engineer should be able to trace a request end to end without a map.
18
+ 5. **Stop at the plan**: you mostly read and reason. Hand implementation to Forge; hand data-model depth to **Delta**.
19
+
20
+ Pair with **Forge** to execute and **Argus** to review the result against the design.
@@ -1,16 +1,60 @@
1
1
  #!/bin/sh
2
- # Solix hook template copied per-event with EVENT name baked in.
3
- # Critical properties:
4
- # --max-time 1 never block Claude Code if Solix is down
5
- # || true never fail; a non-zero exit could block the agent
6
- # redirect both hooks must not pollute stdout/stderr
2
+ # Solix PreToolUse hook — Bash.
3
+ #
4
+ # Two modes:
5
+ # default (SOLIX_GATE_ENABLED != 1): fire-and-forget observability. Posts the
6
+ # event and exits 0 immediately — never blocks Claude Code (same as before).
7
+ # gate (SOLIX_GATE_ENABLED = 1): BLOCKS until a human approves/denies in
8
+ # the Solix browser, then returns Claude Code a real allow/deny decision.
9
+ #
10
+ # Fail policy (gate mode, when the server is unreachable or times out):
11
+ # SOLIX_GATE_POLICY=fail-open (default) -> defer to Claude Code's own flow
12
+ # SOLIX_GATE_POLICY=fail-closed -> deny
13
+ SOLIX_HOST="${SOLIX_HOST:-127.0.0.1}"
7
14
  SOLIX_PORT="${SOLIX_PORT:-4242}"
8
15
  EVENT="pre_tool_bash"
9
16
  PAYLOAD=$(cat 2>/dev/null || echo '{}')
10
17
  [ -z "$PAYLOAD" ] && PAYLOAD='{}'
11
18
  TS=$(date +%s%3N 2>/dev/null || echo "0")
12
- curl -s -X POST "http://127.0.0.1:${SOLIX_PORT}/events" \
19
+ TOKEN=$(cat "${SOLIX_HOME:-$HOME/.solix}/token" 2>/dev/null || echo "")
20
+ BODY="{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}"
21
+
22
+ if [ "$SOLIX_GATE_ENABLED" != "1" ]; then
23
+ curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events" \
24
+ -H "Content-Type: application/json" \
25
+ -H "X-Solix-Token: $TOKEN" \
26
+ -d "$BODY" \
27
+ --max-time 1 > /dev/null 2>&1 || true
28
+ exit 0
29
+ fi
30
+
31
+ SOLIX_GATE_POLICY="${SOLIX_GATE_POLICY:-fail-open}"
32
+ SOLIX_GATE_TIMEOUT="${SOLIX_GATE_TIMEOUT:-305}"
33
+ RESP=$(curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events/permission" \
13
34
  -H "Content-Type: application/json" \
14
- -d "{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}" \
15
- --max-time 1 > /dev/null 2>&1 || true
16
- exit 0
35
+ -H "X-Solix-Token: $TOKEN" \
36
+ -d "$BODY" \
37
+ --max-time "$SOLIX_GATE_TIMEOUT" 2>/dev/null)
38
+ CURL_RC=$?
39
+ DECISION=""
40
+ if [ "$CURL_RC" -eq 0 ]; then
41
+ DECISION=$(printf '%s' "$RESP" | sed -n 's/.*"decision"[[:space:]]*:[[:space:]]*"\([a-z]*\)".*/\1/p')
42
+ fi
43
+
44
+ case "$DECISION" in
45
+ allow)
46
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"Approved in Solix"}}'
47
+ exit 0
48
+ ;;
49
+ deny)
50
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Denied in Solix"}}'
51
+ exit 0
52
+ ;;
53
+ *)
54
+ # timeout / empty / server unreachable -> fail policy
55
+ if [ "$SOLIX_GATE_POLICY" = "fail-closed" ]; then
56
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Solix gate unavailable (fail-closed)"}}'
57
+ fi
58
+ exit 0
59
+ ;;
60
+ esac
@@ -1,16 +1,59 @@
1
1
  #!/bin/sh
2
- # Solix hook template copied per-event with EVENT name baked in.
3
- # Critical properties:
4
- # --max-time 1 never block Claude Code if Solix is down
5
- # || true never fail; a non-zero exit could block the agent
6
- # redirect both hooks must not pollute stdout/stderr
2
+ # Solix PreToolUse hook — file writes (Read|Write|Edit|MultiEdit).
3
+ #
4
+ # Two modes:
5
+ # default (SOLIX_GATE_ENABLED != 1): fire-and-forget observability. Posts the
6
+ # event and exits 0 immediately — never blocks Claude Code (same as before).
7
+ # gate (SOLIX_GATE_ENABLED = 1): BLOCKS until a human approves/denies in
8
+ # the Solix browser, then returns Claude Code a real allow/deny decision.
9
+ #
10
+ # Fail policy (gate mode, when the server is unreachable or times out):
11
+ # SOLIX_GATE_POLICY=fail-open (default) -> defer to Claude Code's own flow
12
+ # SOLIX_GATE_POLICY=fail-closed -> deny
13
+ SOLIX_HOST="${SOLIX_HOST:-127.0.0.1}"
7
14
  SOLIX_PORT="${SOLIX_PORT:-4242}"
8
15
  EVENT="pre_tool_file"
9
16
  PAYLOAD=$(cat 2>/dev/null || echo '{}')
10
17
  [ -z "$PAYLOAD" ] && PAYLOAD='{}'
11
18
  TS=$(date +%s%3N 2>/dev/null || echo "0")
12
- curl -s -X POST "http://127.0.0.1:${SOLIX_PORT}/events" \
19
+ TOKEN=$(cat "${SOLIX_HOME:-$HOME/.solix}/token" 2>/dev/null || echo "")
20
+ BODY="{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}"
21
+
22
+ if [ "$SOLIX_GATE_ENABLED" != "1" ]; then
23
+ curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events" \
24
+ -H "Content-Type: application/json" \
25
+ -H "X-Solix-Token: $TOKEN" \
26
+ -d "$BODY" \
27
+ --max-time 1 > /dev/null 2>&1 || true
28
+ exit 0
29
+ fi
30
+
31
+ SOLIX_GATE_POLICY="${SOLIX_GATE_POLICY:-fail-open}"
32
+ SOLIX_GATE_TIMEOUT="${SOLIX_GATE_TIMEOUT:-305}"
33
+ RESP=$(curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events/permission" \
13
34
  -H "Content-Type: application/json" \
14
- -d "{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}" \
15
- --max-time 1 > /dev/null 2>&1 || true
16
- exit 0
35
+ -H "X-Solix-Token: $TOKEN" \
36
+ -d "$BODY" \
37
+ --max-time "$SOLIX_GATE_TIMEOUT" 2>/dev/null)
38
+ CURL_RC=$?
39
+ DECISION=""
40
+ if [ "$CURL_RC" -eq 0 ]; then
41
+ DECISION=$(printf '%s' "$RESP" | sed -n 's/.*"decision"[[:space:]]*:[[:space:]]*"\([a-z]*\)".*/\1/p')
42
+ fi
43
+
44
+ case "$DECISION" in
45
+ allow)
46
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"Approved in Solix"}}'
47
+ exit 0
48
+ ;;
49
+ deny)
50
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Denied in Solix"}}'
51
+ exit 0
52
+ ;;
53
+ *)
54
+ if [ "$SOLIX_GATE_POLICY" = "fail-closed" ]; then
55
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Solix gate unavailable (fail-closed)"}}'
56
+ fi
57
+ exit 0
58
+ ;;
59
+ esac
@@ -1,16 +1,61 @@
1
1
  #!/bin/sh
2
- # Solix hook template copied per-event with EVENT name baked in.
3
- # Critical properties:
4
- # --max-time 1 never block Claude Code if Solix is down
5
- # || true never fail; a non-zero exit could block the agent
6
- # redirect both hooks must not pollute stdout/stderr
2
+ # Solix PreToolUse hook — Task (subagent spawn).
3
+ #
4
+ # Two modes:
5
+ # default (SOLIX_GATE_ENABLED != 1): fire-and-forget observability. Posts the
6
+ # event and exits 0 immediately — never blocks Claude Code (same as before).
7
+ # gate (SOLIX_GATE_ENABLED = 1): BLOCKS until a human approves/denies in
8
+ # the Solix browser, then returns Claude Code a real allow/deny decision.
9
+ # Note: gating Task blocks subagent *spawn*. Leave this hook unmanaged in
10
+ # settings.json if you want to gate only Bash + file writes.
11
+ #
12
+ # Fail policy (gate mode, when the server is unreachable or times out):
13
+ # SOLIX_GATE_POLICY=fail-open (default) -> defer to Claude Code's own flow
14
+ # SOLIX_GATE_POLICY=fail-closed -> deny
15
+ SOLIX_HOST="${SOLIX_HOST:-127.0.0.1}"
7
16
  SOLIX_PORT="${SOLIX_PORT:-4242}"
8
17
  EVENT="pre_tool_task"
9
18
  PAYLOAD=$(cat 2>/dev/null || echo '{}')
10
19
  [ -z "$PAYLOAD" ] && PAYLOAD='{}'
11
20
  TS=$(date +%s%3N 2>/dev/null || echo "0")
12
- curl -s -X POST "http://127.0.0.1:${SOLIX_PORT}/events" \
21
+ TOKEN=$(cat "${SOLIX_HOME:-$HOME/.solix}/token" 2>/dev/null || echo "")
22
+ BODY="{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}"
23
+
24
+ if [ "$SOLIX_GATE_ENABLED" != "1" ]; then
25
+ curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events" \
26
+ -H "Content-Type: application/json" \
27
+ -H "X-Solix-Token: $TOKEN" \
28
+ -d "$BODY" \
29
+ --max-time 1 > /dev/null 2>&1 || true
30
+ exit 0
31
+ fi
32
+
33
+ SOLIX_GATE_POLICY="${SOLIX_GATE_POLICY:-fail-open}"
34
+ SOLIX_GATE_TIMEOUT="${SOLIX_GATE_TIMEOUT:-305}"
35
+ RESP=$(curl -s -X POST "http://$SOLIX_HOST:${SOLIX_PORT}/events/permission" \
13
36
  -H "Content-Type: application/json" \
14
- -d "{\"event\":\"$EVENT\",\"payload\":$PAYLOAD,\"pid\":$PPID,\"cwd\":\"$(pwd)\",\"ts\":$TS}" \
15
- --max-time 1 > /dev/null 2>&1 || true
16
- exit 0
37
+ -H "X-Solix-Token: $TOKEN" \
38
+ -d "$BODY" \
39
+ --max-time "$SOLIX_GATE_TIMEOUT" 2>/dev/null)
40
+ CURL_RC=$?
41
+ DECISION=""
42
+ if [ "$CURL_RC" -eq 0 ]; then
43
+ DECISION=$(printf '%s' "$RESP" | sed -n 's/.*"decision"[[:space:]]*:[[:space:]]*"\([a-z]*\)".*/\1/p')
44
+ fi
45
+
46
+ case "$DECISION" in
47
+ allow)
48
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","permissionDecisionReason":"Approved in Solix"}}'
49
+ exit 0
50
+ ;;
51
+ deny)
52
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Denied in Solix"}}'
53
+ exit 0
54
+ ;;
55
+ *)
56
+ if [ "$SOLIX_GATE_POLICY" = "fail-closed" ]; then
57
+ printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Solix gate unavailable (fail-closed)"}}'
58
+ fi
59
+ exit 0
60
+ ;;
61
+ esac