arkaos 4.3.1 → 4.3.3

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 (48) hide show
  1. package/README.md +1 -1
  2. package/VERSION +1 -1
  3. package/arka/SKILL.md +4 -4
  4. package/arka/skills/costs/SKILL.md +1 -1
  5. package/arka/skills/fusion/SKILL.md +3 -3
  6. package/bin/arka +225 -0
  7. package/bin/arka-claude +64 -0
  8. package/bin/arka-claude.cmd +11 -0
  9. package/bin/arka-claude.ps1 +126 -0
  10. package/bin/arka-doctor +391 -0
  11. package/bin/arka-providers +261 -0
  12. package/bin/arka-py +46 -0
  13. package/bin/arka-py.cmd +9 -0
  14. package/bin/arka-py.ps1 +36 -0
  15. package/bin/arka-registry-gen +185 -0
  16. package/bin/arka-skill +300 -0
  17. package/bin/scheduler-daemon.py +48 -0
  18. package/config/claude-agents/marta-cqo.md +1 -1
  19. package/config/claude-agents/paulo-tech-lead.md +1 -1
  20. package/config/constitution.yaml +5 -5
  21. package/config/hooks/_lib/arka_python.ps1 +43 -0
  22. package/config/hooks/_lib/arka_python.sh +63 -0
  23. package/config/hooks/agent-provision.sh +8 -1
  24. package/config/hooks/cwd-changed.sh +6 -2
  25. package/config/hooks/post-tool-use-v2.sh +6 -2
  26. package/config/hooks/post-tool-use.sh +8 -17
  27. package/config/hooks/pre-tool-use.ps1 +8 -6
  28. package/config/hooks/pre-tool-use.sh +8 -17
  29. package/config/hooks/session-start.sh +23 -21
  30. package/config/hooks/stop.ps1 +7 -5
  31. package/config/hooks/stop.sh +8 -17
  32. package/config/hooks/token-hygiene.sh +5 -1
  33. package/config/hooks/user-prompt-submit-v2.sh +13 -9
  34. package/config/hooks/user-prompt-submit.sh +8 -17
  35. package/core/hooks/__pycache__/post_tool_use.cpython-312.pyc +0 -0
  36. package/core/hooks/__pycache__/pre_tool_use.cpython-312.pyc +0 -0
  37. package/core/runtime/__pycache__/cost_governor.cpython-312.pyc +0 -0
  38. package/core/runtime/__pycache__/llm_provider.cpython-312.pyc +0 -0
  39. package/core/runtime/__pycache__/openrouter_provider.cpython-312.pyc +0 -0
  40. package/core/workflow/state_reader.sh +12 -5
  41. package/departments/ops/skills/update/SKILL.md +2 -2
  42. package/departments/ops/skills/update/references/sync-engine.md +1 -1
  43. package/departments/quality/SKILL.md +1 -1
  44. package/installer/index.js +14 -0
  45. package/installer/update.js +31 -0
  46. package/package.json +6 -3
  47. package/pyproject.toml +1 -1
  48. package/scripts/seed_initial_patterns.py +1 -1
package/bin/arka-py ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================================
3
+ # ArkaOS — Python entrypoint for agents and scripts.
4
+ #
5
+ # Resolves the ArkaOS interpreter (venv-first, via the shared resolver) and
6
+ # execs it, so callers never depend on the ambient `python` having ArkaOS
7
+ # deps (pyyaml, pydantic, ...). This is what SKILL.md commands invoke instead
8
+ # of a bare `python -m core...` — the failure mode that broke `/arka update`
9
+ # when the session's `python` had no yaml.
10
+ #
11
+ # Usage: arka-py -m core.sync.update_orchestrator ...
12
+ # arka-py path/to/script.py ...
13
+ # arka-py -c "import core; ..."
14
+ # ============================================================================
15
+ set -euo pipefail
16
+
17
+ # ─── Source the shared resolver, from the repo or the installed location ──
18
+ _self="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
19
+ for _lib in \
20
+ "$_self/../config/hooks/_lib/arka_python.sh" \
21
+ "$HOME/.arkaos/config/hooks/_lib/arka_python.sh"; do
22
+ if [ -f "$_lib" ]; then
23
+ # shellcheck source=/dev/null
24
+ # The resolver's ARKA_PY assignment is `|| true`-guarded internally, so
25
+ # sourcing never aborts under `set -e` even when it falls back.
26
+ . "$_lib"
27
+ break
28
+ fi
29
+ done
30
+ : "${ARKA_PY:=python3}"
31
+
32
+ # ─── Make `-m core.*` resolvable regardless of cwd ────────────────────────
33
+ # ARKAOS_ROOT (env) wins; else the installed repo pointer; else the repo this
34
+ # shim lives in (dev checkout: bin/ -> repo root).
35
+ _root="${ARKAOS_ROOT:-}"
36
+ if [ -z "$_root" ] && [ -f "$HOME/.arkaos/.repo-path" ]; then
37
+ _root="$(cat "$HOME/.arkaos/.repo-path" 2>/dev/null || true)"
38
+ fi
39
+ if [ -z "$_root" ] && [ -f "$_self/../core/hooks/__init__.py" ]; then
40
+ _root="$(cd "$_self/.." && pwd)"
41
+ fi
42
+ if [ -n "$_root" ] && [ -d "$_root" ]; then
43
+ export PYTHONPATH="${_root}${PYTHONPATH:+:$PYTHONPATH}"
44
+ fi
45
+
46
+ exec "$ARKA_PY" "$@"
@@ -0,0 +1,9 @@
1
+ @echo off
2
+ REM ==========================================================================
3
+ REM ArkaOS - Python entrypoint (cmd shim)
4
+ REM
5
+ REM Dispatches to bin\arka-py.ps1, forwarding all arguments, so `arka-py ...`
6
+ REM works from cmd.exe, PowerShell, and Windows Terminal alike.
7
+ REM ==========================================================================
8
+ powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "%~dp0arka-py.ps1" %*
9
+ exit /b %ERRORLEVEL%
@@ -0,0 +1,36 @@
1
+ # ============================================================================
2
+ # ArkaOS - Python entrypoint (Windows / PowerShell 5.1+)
3
+ #
4
+ # Port of bin/arka-py. Resolves the ArkaOS interpreter (venv-first, via the
5
+ # shared PowerShell resolver) and execs it, so SKILL.md commands never run a
6
+ # bare `python` that lacks ArkaOS deps (pyyaml, ...).
7
+ #
8
+ # Usage: arka-py -m core.sync.update_orchestrator ...
9
+ # Normally invoked through its .cmd shim (bin/arka-py.cmd).
10
+ # ============================================================================
11
+ $ErrorActionPreference = "Stop"
12
+
13
+ # ─── Source the shared resolver, from the repo or the installed location ──
14
+ $self = if ($PSScriptRoot) { $PSScriptRoot } else { Split-Path -Parent $MyInvocation.MyCommand.Path }
15
+ $libs = @(
16
+ (Join-Path $self "..\config\hooks\_lib\arka_python.ps1"),
17
+ (Join-Path (if ($env:USERPROFILE) { $env:USERPROFILE } else { $HOME }) ".arkaos\config\hooks\_lib\arka_python.ps1")
18
+ )
19
+ foreach ($lib in $libs) {
20
+ if (Test-Path -LiteralPath $lib) { . $lib; break }
21
+ }
22
+ if (-not $env:ARKA_PY) { $env:ARKA_PY = "python" }
23
+
24
+ # ─── Make `-m core.*` resolvable regardless of cwd ────────────────────────
25
+ $root = $env:ARKAOS_ROOT
26
+ if (-not $root) {
27
+ $rp = Join-Path (if ($env:USERPROFILE) { $env:USERPROFILE } else { $HOME }) ".arkaos\.repo-path"
28
+ if (Test-Path -LiteralPath $rp) { $root = (Get-Content -LiteralPath $rp -Raw).Trim() }
29
+ }
30
+ if ($root -and (Test-Path -LiteralPath $root)) {
31
+ $sep = [IO.Path]::PathSeparator
32
+ $env:PYTHONPATH = if ($env:PYTHONPATH) { "$root$sep$env:PYTHONPATH" } else { $root }
33
+ }
34
+
35
+ & $env:ARKA_PY @args
36
+ exit $LASTEXITCODE
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================================
3
+ # ARKA OS — Commands Registry Generator
4
+ # Scans SKILL.md files + keyword data to generate commands-registry.json
5
+ # Usage: bash bin/arka-registry-gen
6
+ # ============================================================================
7
+ set -e
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
10
+ REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
11
+ KEYWORDS_FILE="$REPO_DIR/knowledge/commands-keywords.json"
12
+ OUTPUT_FILE="$REPO_DIR/knowledge/commands-registry.json"
13
+ ARKA_OS="${ARKA_OS:-$HOME/.claude/skills/arka}"
14
+ TEMP_COMMANDS=$(mktemp)
15
+ trap 'rm -f "$TEMP_COMMANDS"' EXIT
16
+
17
+ # Require jq
18
+ command -v jq &>/dev/null || { echo "Error: jq is required. Install: brew install jq"; exit 1; }
19
+
20
+ # ─── Helper: Map department directory name to command prefix ───────────────
21
+ dept_prefix_for() {
22
+ case "$1" in
23
+ dev) echo "dev" ;;
24
+ marketing) echo "mkt" ;;
25
+ ecommerce) echo "ecom" ;;
26
+ finance) echo "fin" ;;
27
+ operations) echo "ops" ;;
28
+ strategy) echo "strat" ;;
29
+ knowledge) echo "kb" ;;
30
+ brand) echo "brand" ;;
31
+ *) echo "$1" ;;
32
+ esac
33
+ }
34
+
35
+ # ─── Helper: Detect metadata for a command ─────────────────────────────────
36
+ get_metadata() {
37
+ local command="$1"
38
+ local rw="false" mc="false" tier=2
39
+
40
+ case "$command" in
41
+ "/dev feature"*|"/dev api"*|"/dev debug"*|"/dev refactor"*|"/dev db"*)
42
+ rw="true"; mc="true"; tier=1 ;;
43
+ "/dev scaffold"*|"/dev deploy"*|"/dev test"*)
44
+ mc="true" ;;
45
+ "/dev security-audit"*)
46
+ tier=1 ;;
47
+ esac
48
+ echo "$rw $mc $tier"
49
+ }
50
+
51
+ # ─── Helper: Extract commands from a SKILL.md file ────────────────────────
52
+ # Parses markdown tables: | `/<prefix> <command> [args]` | description |
53
+ extract_commands() {
54
+ local file="$1"
55
+ local department="$2"
56
+ local source="${3:-builtin}"
57
+
58
+ [ -f "$file" ] || return 0
59
+
60
+ # Extract lead agent from frontmatter
61
+ local lead_agent=""
62
+ lead_agent=$(sed -n '/^---$/,/^---$/{ /^name:/s/.*: *//p; }' "$file" 2>/dev/null | head -1 | xargs 2>/dev/null || echo "")
63
+
64
+ # Parse command table rows
65
+ # Match: | `/<word> <word>...` | description |
66
+ # The backtick-wrapped command must START with / immediately after the backtick
67
+ grep -E '^\| *`/[a-z]' "$file" 2>/dev/null | while IFS= read -r line; do
68
+ # Extract command from backticks
69
+ local command
70
+ command=$(echo "$line" | sed -n 's/.*`\(\/[^`]*\)`.*/\1/p' | xargs 2>/dev/null)
71
+ [ -z "$command" ] && continue
72
+
73
+ # Extract description (second column)
74
+ local description
75
+ description=$(echo "$line" | sed 's/^[^|]*|[^|]*| *//' | sed 's/ *|.*//' | sed 's/^ *//;s/ *$//' | sed 's/^— *//;s/^- *//')
76
+ [ -z "$description" ] && continue
77
+ # Skip if description looks like a separator
78
+ echo "$description" | grep -qE '^[-]+$' && continue
79
+
80
+ # Generate command ID: /dev feature <desc> -> dev-feature
81
+ local id
82
+ id=$(echo "$command" | sed 's/ *<[^>]*>//g' | sed 's/ *\[.*//g' | sed 's/^\/\([^ ]*\) *\(.*\)/\1-\2/' | sed 's/-$//' | sed 's/ /-/g')
83
+ [ -z "$id" ] && continue
84
+
85
+ # Get metadata
86
+ local meta
87
+ meta=$(get_metadata "$command")
88
+ local rw mc tier
89
+ rw=$(echo "$meta" | cut -d' ' -f1)
90
+ mc=$(echo "$meta" | cut -d' ' -f2)
91
+ tier=$(echo "$meta" | cut -d' ' -f3)
92
+
93
+ # Output JSON line
94
+ jq -nc \
95
+ --arg id "$id" \
96
+ --arg command "$command" \
97
+ --arg department "$department" \
98
+ --arg description "$description" \
99
+ --arg lead_agent "$lead_agent" \
100
+ --argjson tier "$tier" \
101
+ --argjson requires_branch "$rw" \
102
+ --argjson modifies_code "$mc" \
103
+ --arg source "$source" \
104
+ '{id:$id,command:$command,department:$department,description:$description,lead_agent:$lead_agent,tier:$tier,requires_branch:$requires_branch,modifies_code:$modifies_code,keywords:[],examples:[],source:$source}'
105
+ done
106
+ }
107
+
108
+ # ─── Collect commands from all SKILL.md files ─────────────────────────────
109
+
110
+ # Main orchestrator
111
+ extract_commands "$REPO_DIR/arka/SKILL.md" "arka" >> "$TEMP_COMMANDS"
112
+
113
+ # Department SKILL.md files
114
+ for dept_dir in "$REPO_DIR"/departments/*/; do
115
+ [ -d "$dept_dir" ] || continue
116
+ dept_name=$(basename "$dept_dir")
117
+ dept_prefix=$(dept_prefix_for "$dept_name")
118
+
119
+ # Main department skill
120
+ [ -f "${dept_dir}SKILL.md" ] && extract_commands "${dept_dir}SKILL.md" "$dept_prefix" >> "$TEMP_COMMANDS"
121
+
122
+ # Sub-skills
123
+ for sub_skill in "${dept_dir}skills"/*/SKILL.md; do
124
+ [ -f "$sub_skill" ] || continue
125
+ extract_commands "$sub_skill" "$dept_prefix" >> "$TEMP_COMMANDS"
126
+ done
127
+ done
128
+
129
+ # External skills
130
+ for ext_skill in "$HOME/.claude/skills"/arka-ext-*/SKILL.md; do
131
+ [ -f "$ext_skill" ] || continue
132
+ ext_name=$(basename "$(dirname "$ext_skill")" | sed 's/^arka-ext-//')
133
+ extract_commands "$ext_skill" "$ext_name" "external" >> "$TEMP_COMMANDS"
134
+ done
135
+
136
+ # Pro skills
137
+ for pro_skill in "$HOME/.claude/skills"/arka-pro-*/SKILL.md; do
138
+ [ -f "$pro_skill" ] || continue
139
+ pro_name=$(basename "$(dirname "$pro_skill")" | sed 's/^arka-pro-//')
140
+ extract_commands "$pro_skill" "$pro_name" "pro" >> "$TEMP_COMMANDS"
141
+ done
142
+
143
+ # ─── Build commands array from temp file ───────────────────────────────────
144
+ if [ -s "$TEMP_COMMANDS" ]; then
145
+ COMMANDS_JSON=$(jq -s '.' "$TEMP_COMMANDS")
146
+ else
147
+ COMMANDS_JSON="[]"
148
+ fi
149
+
150
+ # ─── Deduplicate by command ID (keep first occurrence) ─────────────────────
151
+ COMMANDS_JSON=$(echo "$COMMANDS_JSON" | jq '[group_by(.id) | .[] | .[0]]')
152
+
153
+ # ─── Merge keywords and examples from seed data ───────────────────────────
154
+ if [ -f "$KEYWORDS_FILE" ]; then
155
+ COMMANDS_JSON=$(jq --slurpfile kw "$KEYWORDS_FILE" '
156
+ [.[] | . as $cmd |
157
+ if $kw[0][$cmd.id] then
158
+ .keywords = ($kw[0][$cmd.id].keywords // []) |
159
+ .examples = ($kw[0][$cmd.id].examples // [])
160
+ else . end
161
+ ]
162
+ ' <<< "$COMMANDS_JSON")
163
+ fi
164
+
165
+ # ─── Build final registry ─────────────────────────────────────────────────
166
+ TOTAL=$(echo "$COMMANDS_JSON" | jq 'length')
167
+ NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
168
+
169
+ jq -n \
170
+ --arg version "1.0.0" \
171
+ --arg generated "$NOW" \
172
+ --argjson total "$TOTAL" \
173
+ --arg generator "bin/arka-registry-gen" \
174
+ --argjson commands "$COMMANDS_JSON" \
175
+ '{
176
+ _meta: {
177
+ version: $version,
178
+ generated: $generated,
179
+ total_commands: $total,
180
+ generator: $generator
181
+ },
182
+ commands: $commands
183
+ }' > "$OUTPUT_FILE"
184
+
185
+ echo "Registry generated: $OUTPUT_FILE ($TOTAL commands)"
package/bin/arka-skill ADDED
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env bash
2
+ # ============================================================================
3
+ # ARKA OS — External Skill Manager
4
+ # Install, list, remove, and update external skills.
5
+ # ============================================================================
6
+ set -e
7
+
8
+ CYAN='\033[0;36m'
9
+ GREEN='\033[0;32m'
10
+ YELLOW='\033[1;33m'
11
+ RED='\033[0;31m'
12
+ NC='\033[0m'
13
+
14
+ ARKA_OS="${ARKA_OS:-$HOME/.claude/skills/arka}"
15
+ EXT_DIR="$HOME/.arka-os/ext-skills"
16
+ EXT_REGISTRY="$HOME/.arka-os/ext-registry.json"
17
+ SKILLS_DIR="$HOME/.claude/skills"
18
+ AGENTS_DIR="$HOME/.claude/agents"
19
+
20
+ mkdir -p "$EXT_DIR" "$SKILLS_DIR" "$AGENTS_DIR"
21
+
22
+ # Ensure ext-registry exists
23
+ if [ ! -f "$EXT_REGISTRY" ]; then
24
+ echo '{"_meta":{"format_version":1},"skills":{}}' | jq '.' > "$EXT_REGISTRY"
25
+ fi
26
+
27
+ usage() {
28
+ echo -e "${CYAN}ARKA OS — External Skill Manager${NC}"
29
+ echo ""
30
+ echo "Usage: arka skill <command> [args]"
31
+ echo ""
32
+ echo "Commands:"
33
+ echo " install <github-url> Install an external skill"
34
+ echo " list List installed external skills"
35
+ echo " remove <name> Remove an external skill"
36
+ echo " update <name> Update an external skill"
37
+ echo " create <name> Scaffold a new skill from template"
38
+ echo ""
39
+ }
40
+
41
+ # Version comparison (semver >=)
42
+ version_gte() {
43
+ # $1 = current version, $2 = required version (e.g., ">=0.2.0")
44
+ local required="${2#>=}"
45
+ [ "$(printf '%s\n' "$required" "$1" | sort -V | head -1)" = "$required" ]
46
+ }
47
+
48
+ cmd_install() {
49
+ local url="$1"
50
+ if [ -z "$url" ]; then
51
+ echo -e "${RED}Error: GitHub URL required.${NC}"
52
+ echo "Usage: arka skill install <github-url>"
53
+ exit 1
54
+ fi
55
+
56
+ # Derive name from URL
57
+ local name
58
+ name=$(basename "$url" .git)
59
+
60
+ echo -e "${CYAN}Installing external skill: ${name}${NC}"
61
+ echo ""
62
+
63
+ # Step 1: Clone
64
+ local clone_dir="$EXT_DIR/$name"
65
+ if [ -d "$clone_dir" ]; then
66
+ echo -e "${YELLOW}Skill already installed. Use 'arka skill update $name' instead.${NC}"
67
+ exit 1
68
+ fi
69
+
70
+ git clone "$url" "$clone_dir"
71
+
72
+ # Step 2: Validate
73
+ if [ ! -f "$clone_dir/SKILL.md" ]; then
74
+ echo -e "${RED}Error: SKILL.md not found. Not a valid ARKA OS skill.${NC}"
75
+ rm -rf "$clone_dir"
76
+ exit 1
77
+ fi
78
+ if [ ! -f "$clone_dir/arka-skill.json" ]; then
79
+ echo -e "${RED}Error: arka-skill.json not found. Not a valid ARKA OS skill.${NC}"
80
+ rm -rf "$clone_dir"
81
+ exit 1
82
+ fi
83
+
84
+ # Step 3: Read metadata
85
+ local skill_version skill_desc skill_author requires_arka
86
+ skill_version=$(jq -r '.version' "$clone_dir/arka-skill.json")
87
+ skill_desc=$(jq -r '.description' "$clone_dir/arka-skill.json")
88
+ skill_author=$(jq -r '.author' "$clone_dir/arka-skill.json")
89
+ requires_arka=$(jq -r '.requires_arka_version // ""' "$clone_dir/arka-skill.json")
90
+
91
+ # Step 4: Check version compatibility
92
+ if [ -n "$requires_arka" ] && [ -f "$ARKA_OS/VERSION" ]; then
93
+ local current_version
94
+ current_version=$(cat "$ARKA_OS/VERSION" | tr -d '[:space:]')
95
+ if ! version_gte "$current_version" "$requires_arka"; then
96
+ echo -e "${RED}Error: Skill requires ARKA OS $requires_arka, but you have v$current_version${NC}"
97
+ rm -rf "$clone_dir"
98
+ exit 1
99
+ fi
100
+ fi
101
+
102
+ # Step 5: Install SKILL.md
103
+ local skill_install_dir="$SKILLS_DIR/arka-ext-$name"
104
+ mkdir -p "$skill_install_dir"
105
+ cp "$clone_dir/SKILL.md" "$skill_install_dir/SKILL.md"
106
+ echo -e " ${GREEN}✓${NC} Skill: $name"
107
+
108
+ # Step 6: Install agents (if any)
109
+ local agent_count=0
110
+ if [ -d "$clone_dir/agents" ]; then
111
+ for agent_file in "$clone_dir"/agents/*.md; do
112
+ if [ -f "$agent_file" ]; then
113
+ local agent_base
114
+ agent_base=$(basename "$agent_file" .md)
115
+ cp "$agent_file" "$AGENTS_DIR/arka-ext-${name}-${agent_base}.md"
116
+ echo -e " ${GREEN}✓${NC} Agent: $agent_base"
117
+ agent_count=$((agent_count + 1))
118
+ fi
119
+ done
120
+ fi
121
+
122
+ # Step 7: Merge external MCPs (if any)
123
+ if [ -f "$clone_dir/mcps/registry-ext.json" ] && [ -f "$ARKA_OS/mcps/registry.json" ]; then
124
+ # Merge without overwriting built-in MCPs
125
+ local temp_registry
126
+ temp_registry=$(mktemp)
127
+ jq -s '
128
+ .[0] as $base |
129
+ .[1].mcpServers as $ext |
130
+ $base | .mcpServers += ($ext // {} | to_entries | map(select(.key as $k | $base.mcpServers[$k] == null)) | from_entries)
131
+ ' "$ARKA_OS/mcps/registry.json" "$clone_dir/mcps/registry-ext.json" > "$temp_registry"
132
+ cp "$temp_registry" "$ARKA_OS/mcps/registry.json"
133
+ rm "$temp_registry"
134
+ echo -e " ${GREEN}✓${NC} External MCPs merged"
135
+ fi
136
+
137
+ # Step 8: Register in ext-registry
138
+ jq --arg name "$name" --arg version "$skill_version" --arg desc "$skill_desc" \
139
+ --arg author "$skill_author" --arg url "$url" --arg date "$(date +%Y-%m-%d)" \
140
+ '.skills[$name] = {"version": $version, "description": $desc, "author": $author, "url": $url, "installed": $date}' \
141
+ "$EXT_REGISTRY" > "${EXT_REGISTRY}.tmp" && mv "${EXT_REGISTRY}.tmp" "$EXT_REGISTRY"
142
+
143
+ # Step 9: Report
144
+ echo ""
145
+ echo -e "${GREEN}═══ Skill Installed ═══${NC}"
146
+ echo -e " Name: ${CYAN}$name${NC} v$skill_version"
147
+ echo -e " Author: ${CYAN}$skill_author${NC}"
148
+ echo -e " Desc: $skill_desc"
149
+ echo -e " Agents: ${CYAN}$agent_count${NC}"
150
+ echo -e "${GREEN}═══════════════════════${NC}"
151
+ }
152
+
153
+ cmd_list() {
154
+ echo -e "${CYAN}ARKA OS — External Skills${NC}"
155
+ echo ""
156
+
157
+ local count
158
+ count=$(jq '.skills | length' "$EXT_REGISTRY" 2>/dev/null || echo "0")
159
+
160
+ if [ "$count" = "0" ]; then
161
+ echo " No external skills installed."
162
+ echo ""
163
+ echo " Install one: arka skill install <github-url>"
164
+ return
165
+ fi
166
+
167
+ jq -r '.skills | to_entries[] | " \(.key)\tv\(.value.version)\t\(.value.description)"' "$EXT_REGISTRY" | column -t -s $'\t'
168
+ echo ""
169
+ echo -e " Total: ${CYAN}$count${NC} skill(s)"
170
+ }
171
+
172
+ cmd_remove() {
173
+ local name="$1"
174
+ if [ -z "$name" ]; then
175
+ echo -e "${RED}Error: Skill name required.${NC}"
176
+ echo "Usage: arka skill remove <name>"
177
+ exit 1
178
+ fi
179
+
180
+ echo -e "${CYAN}Removing external skill: ${name}${NC}"
181
+
182
+ # Remove cloned source
183
+ [ -d "$EXT_DIR/$name" ] && rm -rf "$EXT_DIR/$name" && echo -e " ${GREEN}✓${NC} Removed source"
184
+
185
+ # Remove installed skill
186
+ [ -d "$SKILLS_DIR/arka-ext-$name" ] && rm -rf "$SKILLS_DIR/arka-ext-$name" && echo -e " ${GREEN}✓${NC} Removed skill"
187
+
188
+ # Remove installed agents
189
+ for agent in "$AGENTS_DIR"/arka-ext-${name}-*.md; do
190
+ [ -f "$agent" ] && rm "$agent" && echo -e " ${GREEN}✓${NC} Removed $(basename "$agent")"
191
+ done
192
+
193
+ # Remove from registry
194
+ jq --arg name "$name" 'del(.skills[$name])' "$EXT_REGISTRY" > "${EXT_REGISTRY}.tmp" && mv "${EXT_REGISTRY}.tmp" "$EXT_REGISTRY"
195
+ echo -e " ${GREEN}✓${NC} Removed from registry"
196
+
197
+ echo -e "${GREEN}Skill '$name' removed.${NC}"
198
+ }
199
+
200
+ cmd_update() {
201
+ local name="$1"
202
+ if [ -z "$name" ]; then
203
+ echo -e "${RED}Error: Skill name required.${NC}"
204
+ echo "Usage: arka skill update <name>"
205
+ exit 1
206
+ fi
207
+
208
+ local clone_dir="$EXT_DIR/$name"
209
+ if [ ! -d "$clone_dir/.git" ]; then
210
+ echo -e "${RED}Error: Skill '$name' not found.${NC}"
211
+ exit 1
212
+ fi
213
+
214
+ echo -e "${CYAN}Updating external skill: ${name}${NC}"
215
+
216
+ # Pull latest
217
+ cd "$clone_dir" && git pull --ff-only
218
+
219
+ # Re-install SKILL.md
220
+ local skill_install_dir="$SKILLS_DIR/arka-ext-$name"
221
+ mkdir -p "$skill_install_dir"
222
+ cp "$clone_dir/SKILL.md" "$skill_install_dir/SKILL.md"
223
+ echo -e " ${GREEN}✓${NC} Skill updated"
224
+
225
+ # Re-install agents
226
+ if [ -d "$clone_dir/agents" ]; then
227
+ for agent_file in "$clone_dir"/agents/*.md; do
228
+ if [ -f "$agent_file" ]; then
229
+ local agent_base
230
+ agent_base=$(basename "$agent_file" .md)
231
+ cp "$agent_file" "$AGENTS_DIR/arka-ext-${name}-${agent_base}.md"
232
+ echo -e " ${GREEN}✓${NC} Agent: $agent_base"
233
+ fi
234
+ done
235
+ fi
236
+
237
+ # Update registry version
238
+ local skill_version
239
+ skill_version=$(jq -r '.version' "$clone_dir/arka-skill.json" 2>/dev/null || echo "unknown")
240
+ jq --arg name "$name" --arg version "$skill_version" \
241
+ '.skills[$name].version = $version' \
242
+ "$EXT_REGISTRY" > "${EXT_REGISTRY}.tmp" && mv "${EXT_REGISTRY}.tmp" "$EXT_REGISTRY"
243
+
244
+ echo -e "${GREEN}Skill '$name' updated to v$skill_version.${NC}"
245
+ }
246
+
247
+ cmd_create() {
248
+ local name="$1"
249
+ if [ -z "$name" ]; then
250
+ echo -e "${RED}Error: Skill name required.${NC}"
251
+ echo "Usage: arka skill create <name>"
252
+ exit 1
253
+ fi
254
+
255
+ local template_dir="$ARKA_OS/skill-template"
256
+ local target_dir="./$name"
257
+
258
+ if [ -d "$target_dir" ]; then
259
+ echo -e "${RED}Error: Directory '$name' already exists.${NC}"
260
+ exit 1
261
+ fi
262
+
263
+ echo -e "${CYAN}Creating new skill: ${name}${NC}"
264
+
265
+ mkdir -p "$target_dir/agents" "$target_dir/mcps"
266
+
267
+ # Copy and process templates
268
+ if [ -f "$template_dir/SKILL.md.template" ]; then
269
+ sed "s/{{SKILL_NAME}}/$name/g" "$template_dir/SKILL.md.template" > "$target_dir/SKILL.md"
270
+ fi
271
+
272
+ if [ -f "$template_dir/arka-skill.json.template" ]; then
273
+ sed "s/{{SKILL_NAME}}/$name/g" "$template_dir/arka-skill.json.template" > "$target_dir/arka-skill.json"
274
+ fi
275
+
276
+ if [ -f "$template_dir/README.md.template" ]; then
277
+ sed "s/{{SKILL_NAME}}/$name/g" "$template_dir/README.md.template" > "$target_dir/README.md"
278
+ fi
279
+
280
+ echo -e " ${GREEN}✓${NC} Created $target_dir/"
281
+ echo -e " ${GREEN}✓${NC} SKILL.md"
282
+ echo -e " ${GREEN}✓${NC} arka-skill.json"
283
+ echo -e " ${GREEN}✓${NC} README.md"
284
+ echo ""
285
+ echo -e "Next steps:"
286
+ echo -e " 1. Edit ${CYAN}$target_dir/SKILL.md${NC} with your skill definition"
287
+ echo -e " 2. Edit ${CYAN}$target_dir/arka-skill.json${NC} with metadata"
288
+ echo -e " 3. Add agents to ${CYAN}$target_dir/agents/${NC} (optional)"
289
+ echo -e " 4. Push to GitHub and install with: ${CYAN}arka skill install <url>${NC}"
290
+ }
291
+
292
+ # Main routing
293
+ case "${1:-}" in
294
+ install) shift; cmd_install "$@" ;;
295
+ list) cmd_list ;;
296
+ remove) shift; cmd_remove "$@" ;;
297
+ update) shift; cmd_update "$@" ;;
298
+ create) shift; cmd_create "$@" ;;
299
+ *) usage ;;
300
+ esac
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env python3
2
+ """ArkaOS Scheduler Daemon — entry point for launchd/systemd/schtasks.
3
+
4
+ Runs in a loop, checking every 60 seconds whether any scheduled cognitive
5
+ task (Dreaming, Research) should execute at the current time.
6
+ """
7
+
8
+ import sys
9
+ import time
10
+ from pathlib import Path
11
+
12
+ # Ensure ArkaOS core is importable
13
+ ARKAOS_ROOT = Path(__file__).resolve().parent.parent
14
+ if str(ARKAOS_ROOT) not in sys.path:
15
+ sys.path.insert(0, str(ARKAOS_ROOT))
16
+
17
+ from core.cognition.scheduler.daemon import ArkaScheduler # noqa: E402
18
+
19
+ HOME = Path.home()
20
+ CONFIG_PATH = str(HOME / ".arkaos" / "schedules.yaml")
21
+ LOG_DIR = str(HOME / ".arkaos" / "logs")
22
+ LOCK_PATH = str(HOME / ".arkaos" / "scheduler.lock")
23
+
24
+
25
+ def main() -> None:
26
+ scheduler = ArkaScheduler(
27
+ config_path=CONFIG_PATH,
28
+ log_dir=LOG_DIR,
29
+ lock_path=LOCK_PATH,
30
+ )
31
+
32
+ if not scheduler.acquire_lock():
33
+ print("Another scheduler instance is already running. Exiting.")
34
+ sys.exit(1)
35
+
36
+ print(f"ArkaOS Scheduler started — {len(scheduler.schedules)} tasks loaded")
37
+ try:
38
+ while True:
39
+ scheduler.run_once()
40
+ time.sleep(60)
41
+ except KeyboardInterrupt:
42
+ print("Scheduler stopped.")
43
+ finally:
44
+ scheduler.release_lock()
45
+
46
+
47
+ if __name__ == "__main__":
48
+ main()
@@ -23,7 +23,7 @@ evidence, not from model size.
23
23
  ## Review Rubric (evidence interpretation, not role-play)
24
24
 
25
25
  1. Run the engine first — no verdict without a report:
26
- `python -m core.governance.evidence_checks <project_dir> [--changed-files ...] [--test-command '...'] --json`
26
+ `~/.arkaos/bin/arka-py -m core.governance.evidence_checks <project_dir> [--changed-files ...] [--test-command '...'] --json`
27
27
  2. Dispatch Eduardo (spellcheck + changed copy) and Francisca
28
28
  (lint/typecheck/tests/coverage/security-grep) with the report and the
29
29
  structured output schema `QG_VERDICT_JSON_SCHEMA` from
@@ -24,7 +24,7 @@ not cut corners to look fast.
24
24
  dispatch with `[arka:dispatch] paulo -> <specialist>`.
25
25
  3. Evidence over narration: a task is done when its tests RAN and exited 0
26
26
  on record — never when a subagent says it is done. Run
27
- `python -m core.governance.evidence_checks <project_dir> --json` before
27
+ `~/.arkaos/bin/arka-py -m core.governance.evidence_checks <project_dir> --json` before
28
28
  claiming completion.
29
29
  4. Submit to the Quality Gate (marta-cqo) with the evidence report; expect
30
30
  a structured `QGVerdict` back. REJECTED means loop, not negotiate.