arkaos 2.15.0 → 2.16.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 (156) hide show
  1. package/VERSION +1 -1
  2. package/arka/SKILL.md +13 -0
  3. package/arka/skills/comfyui/SKILL.md +82 -0
  4. package/arka/skills/comfyui/references/squads.md +80 -0
  5. package/arka/skills/comfyui/references/workflows.md +435 -0
  6. package/arka/skills/forge/SKILL.md +35 -599
  7. package/arka/skills/forge/references/complexity-engine.md +77 -0
  8. package/arka/skills/forge/references/critic-synthesis.md +154 -0
  9. package/arka/skills/forge/references/workflows.md +408 -0
  10. package/arka/skills/fovory/SKILL.md +91 -0
  11. package/arka/skills/fovory/references/integration.md +186 -0
  12. package/arka/skills/fovory/references/workflows.md +209 -0
  13. package/arka/skills/platform-arka/SKILL.md +121 -0
  14. package/arka/skills/platform-arka/references/workflows.md +202 -0
  15. package/arka/skills/rothbard100/SKILL.md +113 -0
  16. package/arka/skills/rothbard100/references/squad.md +111 -0
  17. package/arka/skills/rothbard100/references/workflows.md +175 -0
  18. package/config/constitution.yaml +8 -0
  19. package/config/hooks/pre-compact.sh +11 -5
  20. package/config/hooks/session-start.sh +4 -5
  21. package/config/hooks/token-hygiene.sh +120 -0
  22. package/config/hooks/user-prompt-submit.sh +28 -10
  23. package/core/agents/__pycache__/schema.cpython-313.pyc +0 -0
  24. package/core/agents/schema.py +20 -1
  25. package/core/synapse/__pycache__/layers.cpython-313.pyc +0 -0
  26. package/core/synapse/layers.py +7 -0
  27. package/core/workflow/__pycache__/schema.cpython-313.pyc +0 -0
  28. package/core/workflow/schema.py +4 -1
  29. package/departments/brand/SKILL.md +13 -0
  30. package/departments/brand/agents/brand-director.yaml +1 -0
  31. package/departments/brand/agents/brand-strategist.yaml +1 -0
  32. package/departments/brand/agents/ux-designer.yaml +1 -0
  33. package/departments/brand/agents/visual-designer.yaml +1 -0
  34. package/departments/brand/workflows/identity.yaml +1 -0
  35. package/departments/brand/workflows/naming.yaml +1 -0
  36. package/departments/community/SKILL.md +13 -0
  37. package/departments/community/agents/community-manager.yaml +1 -0
  38. package/departments/community/agents/community-strategist.yaml +1 -0
  39. package/departments/community/agents/engagement-designer.yaml +1 -0
  40. package/departments/community/workflows/setup.yaml +1 -0
  41. package/departments/content/SKILL.md +13 -0
  42. package/departments/content/agents/content-strategist.yaml +1 -0
  43. package/departments/content/agents/repurpose-distributor.yaml +1 -0
  44. package/departments/content/agents/scriptwriter.yaml +1 -0
  45. package/departments/content/agents/viral-engineer.yaml +1 -0
  46. package/departments/content/workflows/viral.yaml +1 -0
  47. package/departments/dev/SKILL.md +13 -0
  48. package/departments/dev/agents/architect.yaml +1 -0
  49. package/departments/dev/agents/backend-dev.yaml +1 -0
  50. package/departments/dev/agents/cto.yaml +1 -0
  51. package/departments/dev/agents/dba.yaml +1 -0
  52. package/departments/dev/agents/devops-eng.yaml +1 -0
  53. package/departments/dev/agents/frontend-dev.yaml +1 -0
  54. package/departments/dev/agents/qa-eng.yaml +1 -0
  55. package/departments/dev/agents/research-assistant.yaml +1 -0
  56. package/departments/dev/agents/security-eng.yaml +1 -0
  57. package/departments/dev/agents/tech-lead.yaml +1 -0
  58. package/departments/dev/skills/onboard/SKILL.md +21 -353
  59. package/departments/dev/skills/onboard/references/mcp-config.md +284 -0
  60. package/departments/dev/skills/onboard/references/stack-detection.md +83 -0
  61. package/departments/dev/workflows/debug.yaml +1 -0
  62. package/departments/dev/workflows/feature.yaml +3 -0
  63. package/departments/dev/workflows/refactor.yaml +1 -0
  64. package/departments/ecom/SKILL.md +13 -0
  65. package/departments/ecom/agents/commerce-engineer.yaml +1 -0
  66. package/departments/ecom/agents/cro-specialist.yaml +1 -0
  67. package/departments/ecom/agents/ecom-director.yaml +1 -0
  68. package/departments/ecom/agents/retention-manager.yaml +1 -0
  69. package/departments/ecom/skills/ecommerce/SKILL.md +66 -0
  70. package/departments/ecom/skills/ecommerce/references/audit-flow.md +109 -0
  71. package/departments/ecom/skills/ecommerce/references/playbooks.md +141 -0
  72. package/departments/ecom/workflows/product-page.yaml +1 -0
  73. package/departments/finance/SKILL.md +13 -0
  74. package/departments/finance/agents/cfo.yaml +1 -0
  75. package/departments/finance/agents/financial-analyst.yaml +1 -0
  76. package/departments/finance/agents/investment-strategist.yaml +1 -0
  77. package/departments/finance/workflows/cashflow.yaml +1 -0
  78. package/departments/finance/workflows/model.yaml +1 -0
  79. package/departments/kb/SKILL.md +13 -0
  80. package/departments/kb/agents/data-collector.yaml +1 -0
  81. package/departments/kb/agents/knowledge-curator.yaml +1 -0
  82. package/departments/kb/agents/knowledge-director.yaml +1 -0
  83. package/departments/kb/agents/research-analyst.yaml +1 -0
  84. package/departments/kb/skills/knowledge/SKILL.md +94 -0
  85. package/departments/kb/skills/knowledge/references/async-processing.md +89 -0
  86. package/departments/kb/skills/knowledge/references/ingestion-pipeline.md +308 -0
  87. package/departments/kb/skills/knowledge/scripts/kb-check-capabilities.sh +143 -0
  88. package/departments/kb/skills/knowledge/scripts/kb-cleanup.sh +135 -0
  89. package/departments/kb/skills/knowledge/scripts/kb-queue.sh +156 -0
  90. package/departments/kb/skills/knowledge/scripts/kb-status.sh +195 -0
  91. package/departments/kb/skills/knowledge/scripts/kb-worker.sh +217 -0
  92. package/departments/kb/workflows/learn.yaml +1 -0
  93. package/departments/landing/SKILL.md +13 -0
  94. package/departments/landing/agents/affiliate-manager.yaml +1 -0
  95. package/departments/landing/agents/conversion-strategist.yaml +1 -0
  96. package/departments/landing/agents/cro-specialist.yaml +1 -0
  97. package/departments/landing/agents/sales-copywriter.yaml +1 -0
  98. package/departments/landing/workflows/launch.yaml +1 -0
  99. package/departments/landing/workflows/offer.yaml +3 -0
  100. package/departments/leadership/SKILL.md +13 -0
  101. package/departments/leadership/agents/culture-coach.yaml +1 -0
  102. package/departments/leadership/agents/hr-specialist.yaml +1 -0
  103. package/departments/leadership/agents/leadership-director.yaml +1 -0
  104. package/departments/leadership/workflows/team-build.yaml +1 -0
  105. package/departments/marketing/SKILL.md +13 -0
  106. package/departments/marketing/agents/content-marketer.yaml +1 -0
  107. package/departments/marketing/agents/marketing-director.yaml +1 -0
  108. package/departments/marketing/agents/paid-specialist.yaml +1 -0
  109. package/departments/marketing/agents/seo-specialist.yaml +1 -0
  110. package/departments/marketing/workflows/campaign.yaml +1 -0
  111. package/departments/marketing/workflows/social.yaml +1 -0
  112. package/departments/ops/SKILL.md +13 -0
  113. package/departments/ops/agents/automation-engineer.yaml +1 -0
  114. package/departments/ops/agents/doc-writer.yaml +1 -0
  115. package/departments/ops/agents/ops-lead.yaml +1 -0
  116. package/departments/ops/skills/operations/SKILL.md +83 -0
  117. package/departments/ops/skills/operations/references/calendar-email.md +73 -0
  118. package/departments/ops/skills/operations/references/clickup-ops.md +224 -0
  119. package/departments/ops/skills/update/SKILL.md +19 -45
  120. package/departments/ops/skills/update/references/sync-engine.md +93 -0
  121. package/departments/ops/skills/update/references/workflows.md +84 -0
  122. package/departments/ops/workflows/lean-audit.yaml +1 -0
  123. package/departments/org/SKILL.md +13 -0
  124. package/departments/org/agents/coo.yaml +1 -0
  125. package/departments/org/agents/org-designer.yaml +1 -0
  126. package/departments/org/agents/people-ops.yaml +1 -0
  127. package/departments/org/workflows/design.yaml +2 -0
  128. package/departments/pm/SKILL.md +13 -0
  129. package/departments/pm/agents/pm-director.yaml +1 -0
  130. package/departments/pm/agents/product-owner.yaml +1 -0
  131. package/departments/pm/agents/scrum-master.yaml +1 -0
  132. package/departments/quality/SKILL.md +13 -0
  133. package/departments/quality/agents/copy-director.yaml +1 -0
  134. package/departments/quality/agents/cqo.yaml +1 -0
  135. package/departments/quality/agents/tech-director.yaml +1 -0
  136. package/departments/saas/SKILL.md +13 -0
  137. package/departments/saas/agents/cs-manager.yaml +1 -0
  138. package/departments/saas/agents/growth-engineer.yaml +1 -0
  139. package/departments/saas/agents/metrics-analyst.yaml +1 -0
  140. package/departments/saas/agents/saas-strategist.yaml +1 -0
  141. package/departments/saas/workflows/metrics.yaml +1 -0
  142. package/departments/saas/workflows/validate.yaml +1 -0
  143. package/departments/sales/SKILL.md +13 -0
  144. package/departments/sales/agents/sales-closer.yaml +1 -0
  145. package/departments/sales/agents/sales-director.yaml +1 -0
  146. package/departments/sales/agents/sales-ops.yaml +1 -0
  147. package/departments/sales/workflows/pipeline.yaml +1 -0
  148. package/departments/strategy/SKILL.md +13 -0
  149. package/departments/strategy/agents/business-model-designer.yaml +1 -0
  150. package/departments/strategy/agents/market-analyst.yaml +1 -0
  151. package/departments/strategy/agents/strategy-director.yaml +1 -0
  152. package/departments/strategy/workflows/analysis.yaml +1 -0
  153. package/departments/strategy/workflows/swot.yaml +1 -0
  154. package/installer/index.js +19 -0
  155. package/package.json +1 -1
  156. package/pyproject.toml +1 -1
@@ -0,0 +1,135 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # ARKA OS — KB Media Cleanup
4
+ # Removes old media directories for completed jobs.
5
+ #
6
+ # Usage: kb-cleanup.sh [--older-than 90d] [--dry-run]
7
+ # ============================================================================
8
+
9
+ ARKA_DIR="$HOME/.arka-os"
10
+ MEDIA_DIR="$ARKA_DIR/media"
11
+ JOBS_FILE="$ARKA_DIR/kb-jobs.json"
12
+ LOCK_FILE="$ARKA_DIR/kb-jobs.lock"
13
+
14
+ MAX_DAYS=90
15
+ DRY_RUN=false
16
+
17
+ # Parse args
18
+ while [ $# -gt 0 ]; do
19
+ case "$1" in
20
+ --older-than)
21
+ MAX_DAYS=$(echo "${2:-90d}" | sed 's/d$//')
22
+ shift 2
23
+ ;;
24
+ --dry-run)
25
+ DRY_RUN=true
26
+ shift
27
+ ;;
28
+ *)
29
+ shift
30
+ ;;
31
+ esac
32
+ done
33
+
34
+ CYAN='\033[0;36m'
35
+ GREEN='\033[0;32m'
36
+ YELLOW='\033[1;33m'
37
+ RED='\033[0;31m'
38
+ NC='\033[0m'
39
+
40
+ if [ ! -d "$MEDIA_DIR" ]; then
41
+ echo -e "${YELLOW}No media directory found.${NC}"
42
+ exit 0
43
+ fi
44
+
45
+ if ! command -v jq &>/dev/null; then
46
+ echo "Error: jq not found. Install with: brew install jq" >&2
47
+ exit 1
48
+ fi
49
+
50
+ echo ""
51
+ echo -e "${CYAN}═══ ARKA OS — KB Media Cleanup ═══${NC}"
52
+ echo -e " Removing completed jobs older than ${CYAN}${MAX_DAYS} days${NC}"
53
+ if $DRY_RUN; then
54
+ echo -e " ${YELLOW}DRY RUN — no files will be deleted${NC}"
55
+ fi
56
+ echo ""
57
+
58
+ CUTOFF_DATE=$(date -v-${MAX_DAYS}d +%Y-%m-%d 2>/dev/null || date -d "-${MAX_DAYS} days" +%Y-%m-%d 2>/dev/null)
59
+ if [ -z "$CUTOFF_DATE" ]; then
60
+ echo "Error: Could not calculate cutoff date" >&2
61
+ exit 1
62
+ fi
63
+
64
+ echo -e " Cutoff date: $CUTOFF_DATE"
65
+ echo ""
66
+
67
+ TOTAL_FREED=0
68
+ DIRS_REMOVED=0
69
+
70
+ # Iterate date directories
71
+ for date_dir in "$MEDIA_DIR"/*/; do
72
+ [ -d "$date_dir" ] || continue
73
+ DIR_DATE=$(basename "$date_dir")
74
+
75
+ # Check if date directory is older than cutoff
76
+ if [[ "$DIR_DATE" > "$CUTOFF_DATE" ]] || [[ "$DIR_DATE" == "$CUTOFF_DATE" ]]; then
77
+ continue
78
+ fi
79
+
80
+ # Check each job directory inside the date dir
81
+ for job_dir in "$date_dir"*/; do
82
+ [ -d "$job_dir" ] || continue
83
+ JOB_ID=$(basename "$job_dir")
84
+
85
+ # Check if this job is completed in the jobs file
86
+ if [ -f "$JOBS_FILE" ]; then
87
+ STATUS=$(jq -r --arg id "$JOB_ID" '.jobs[] | select(.id == $id) | .status // "unknown"' "$JOBS_FILE" 2>/dev/null)
88
+
89
+ # Only remove completed jobs
90
+ if [ "$STATUS" != "completed" ] && [ "$STATUS" != "unknown" ]; then
91
+ echo -e " ${YELLOW}SKIP${NC} $DIR_DATE/$JOB_ID (status: $STATUS)"
92
+ continue
93
+ fi
94
+ fi
95
+
96
+ # Calculate directory size
97
+ DIR_SIZE=$(du -sk "$job_dir" 2>/dev/null | cut -f1)
98
+ DIR_SIZE_MB=$(echo "scale=1; $DIR_SIZE / 1024" | bc 2>/dev/null || echo "$DIR_SIZE KB")
99
+
100
+ if $DRY_RUN; then
101
+ echo -e " ${YELLOW}WOULD REMOVE${NC} $DIR_DATE/$JOB_ID (${DIR_SIZE_MB}MB)"
102
+ else
103
+ rm -rf "$job_dir"
104
+ echo -e " ${GREEN}REMOVED${NC} $DIR_DATE/$JOB_ID (${DIR_SIZE_MB}MB)"
105
+
106
+ # Remove job from jobs file
107
+ if [ -f "$JOBS_FILE" ]; then
108
+ (
109
+ flock -x 200
110
+ tmp="$JOBS_FILE.tmp.$$"
111
+ jq --arg id "$JOB_ID" '.jobs = [.jobs[] | select(.id != $id)]' \
112
+ "$JOBS_FILE" > "$tmp" && mv "$tmp" "$JOBS_FILE"
113
+ ) 200>"$LOCK_FILE"
114
+ fi
115
+ fi
116
+
117
+ TOTAL_FREED=$((TOTAL_FREED + DIR_SIZE))
118
+ DIRS_REMOVED=$((DIRS_REMOVED + 1))
119
+ done
120
+
121
+ # Remove empty date directories
122
+ if ! $DRY_RUN; then
123
+ rmdir "$date_dir" 2>/dev/null || true
124
+ fi
125
+ done
126
+
127
+ # Summary
128
+ echo ""
129
+ FREED_MB=$(echo "scale=1; $TOTAL_FREED / 1024" | bc 2>/dev/null || echo "${TOTAL_FREED}KB")
130
+ if $DRY_RUN; then
131
+ echo -e "${YELLOW}DRY RUN:${NC} Would remove ${CYAN}$DIRS_REMOVED${NC} directories, freeing ~${CYAN}${FREED_MB}MB${NC}"
132
+ else
133
+ echo -e "${GREEN}Cleaned up:${NC} ${CYAN}$DIRS_REMOVED${NC} directories, freed ~${CYAN}${FREED_MB}MB${NC}"
134
+ fi
135
+ echo -e "${CYAN}══════════════════════════════════${NC}"
@@ -0,0 +1,156 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # ARKA OS — KB Queue Dispatcher
4
+ # Queues a URL for background download + transcription.
5
+ #
6
+ # Usage: kb-queue.sh <url> [--persona "Name"]
7
+ # Output: job ID (8 chars)
8
+ # ============================================================================
9
+ set -euo pipefail
10
+
11
+ URL="${1:-}"
12
+ PERSONA=""
13
+
14
+ # Parse args
15
+ shift || true
16
+ while [ $# -gt 0 ]; do
17
+ case "$1" in
18
+ --persona) PERSONA="${2:-}"; shift 2 ;;
19
+ *) shift ;;
20
+ esac
21
+ done
22
+
23
+ if [ -z "$URL" ]; then
24
+ echo "Usage: kb-queue.sh <url> [--persona \"Name\"]" >&2
25
+ exit 1
26
+ fi
27
+
28
+ ARKA_DIR="$HOME/.arka-os"
29
+ JOBS_FILE="$ARKA_DIR/kb-jobs.json"
30
+ LOCK_FILE="$ARKA_DIR/kb-jobs.lock"
31
+ CAPS_FILE="$ARKA_DIR/capabilities.json"
32
+ SCRIPTS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
+
34
+ mkdir -p "$ARKA_DIR"
35
+
36
+ # ─── Generate job ID ────────────────────────────────────────────────────────
37
+
38
+ JOB_ID=$(printf '%s%s' "$URL" "$(date +%s%N)" | md5sum 2>/dev/null || printf '%s%s' "$URL" "$(date +%s)" | md5 2>/dev/null)
39
+ JOB_ID="${JOB_ID:0:8}"
40
+
41
+ # ─── Create output directory ────────────────────────────────────────────────
42
+
43
+ DATE_DIR=$(date +%Y-%m-%d)
44
+ OUTPUT_DIR="$ARKA_DIR/media/$DATE_DIR/$JOB_ID"
45
+ mkdir -p "$OUTPUT_DIR"
46
+
47
+ # ─── Determine transcription method ─────────────────────────────────────────
48
+
49
+ TRANSCRIPTION_METHOD="none"
50
+
51
+ # Run capabilities check if file doesn't exist or is older than 1 hour
52
+ REFRESH_CAPS=false
53
+ if [ ! -f "$CAPS_FILE" ]; then
54
+ REFRESH_CAPS=true
55
+ elif [ "$(uname)" = "Darwin" ]; then
56
+ CAPS_AGE=$(( $(date +%s) - $(stat -f%m "$CAPS_FILE") ))
57
+ [ "$CAPS_AGE" -gt 3600 ] && REFRESH_CAPS=true
58
+ else
59
+ CAPS_AGE=$(( $(date +%s) - $(stat -c%Y "$CAPS_FILE") ))
60
+ [ "$CAPS_AGE" -gt 3600 ] && REFRESH_CAPS=true
61
+ fi
62
+
63
+ if $REFRESH_CAPS && [ -f "$SCRIPTS_DIR/kb-check-capabilities.sh" ]; then
64
+ bash "$SCRIPTS_DIR/kb-check-capabilities.sh" >/dev/null 2>&1
65
+ fi
66
+
67
+ # Read transcription method from capabilities
68
+ if [ -f "$CAPS_FILE" ] && command -v jq &>/dev/null; then
69
+ TRANSCRIPTION_METHOD=$(jq -r '.transcription.method // "none"' "$CAPS_FILE")
70
+ fi
71
+
72
+ # ─── Check yt-dlp is available ──────────────────────────────────────────────
73
+
74
+ if ! command -v yt-dlp &>/dev/null; then
75
+ echo "Error: yt-dlp not found. Install with: brew install yt-dlp" >&2
76
+ exit 1
77
+ fi
78
+
79
+ # ─── Initialize jobs file if needed ─────────────────────────────────────────
80
+
81
+ (
82
+ flock -x 200
83
+
84
+ if [ ! -f "$JOBS_FILE" ]; then
85
+ echo '{"jobs":[]}' > "$JOBS_FILE"
86
+ fi
87
+
88
+ # Validate JSON
89
+ if ! jq empty "$JOBS_FILE" 2>/dev/null; then
90
+ echo '{"jobs":[]}' > "$JOBS_FILE"
91
+ fi
92
+
93
+ # Add job entry
94
+ NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
95
+ tmp="$JOBS_FILE.tmp.$$"
96
+ jq --arg id "$JOB_ID" \
97
+ --arg url "$URL" \
98
+ --arg dir "$OUTPUT_DIR" \
99
+ --arg method "$TRANSCRIPTION_METHOD" \
100
+ --arg persona "$PERSONA" \
101
+ --arg now "$NOW" \
102
+ '.jobs += [{
103
+ "id": $id,
104
+ "url": $url,
105
+ "output_dir": $dir,
106
+ "transcription_method": $method,
107
+ "persona": $persona,
108
+ "status": "queued",
109
+ "title": null,
110
+ "word_count": null,
111
+ "error": null,
112
+ "pid": null,
113
+ "created_at": $now,
114
+ "updated_at": $now
115
+ }]' "$JOBS_FILE" > "$tmp" && mv "$tmp" "$JOBS_FILE"
116
+
117
+ ) 200>"$LOCK_FILE"
118
+
119
+ # ─── Launch worker in background ────────────────────────────────────────────
120
+
121
+ WORKER_SCRIPT="$SCRIPTS_DIR/kb-worker.sh"
122
+ if [ ! -f "$WORKER_SCRIPT" ]; then
123
+ echo "Error: Worker script not found: $WORKER_SCRIPT" >&2
124
+ exit 1
125
+ fi
126
+
127
+ nohup bash "$WORKER_SCRIPT" "$JOB_ID" "$URL" "$OUTPUT_DIR" "$TRANSCRIPTION_METHOD" \
128
+ > /dev/null 2>&1 &
129
+ WORKER_PID=$!
130
+
131
+ # Record PID in jobs file
132
+ (
133
+ flock -x 200
134
+ tmp="$JOBS_FILE.tmp.$$"
135
+ jq --arg id "$JOB_ID" --argjson pid "$WORKER_PID" \
136
+ '(.jobs[] | select(.id == $id)).pid = $pid' \
137
+ "$JOBS_FILE" > "$tmp" && mv "$tmp" "$JOBS_FILE"
138
+ ) 200>"$LOCK_FILE"
139
+
140
+ # ─── Output ─────────────────────────────────────────────────────────────────
141
+
142
+ if [ -t 1 ]; then
143
+ CYAN='\033[0;36m'
144
+ GREEN='\033[0;32m'
145
+ NC='\033[0m'
146
+ echo -e "${GREEN}✓${NC} Queued job ${CYAN}$JOB_ID${NC}"
147
+ echo -e " URL: $URL"
148
+ echo -e " Method: $TRANSCRIPTION_METHOD"
149
+ echo -e " Output: $OUTPUT_DIR"
150
+ echo -e " PID: $WORKER_PID"
151
+ if [ -n "$PERSONA" ]; then
152
+ echo -e " Persona: $PERSONA"
153
+ fi
154
+ else
155
+ echo "$JOB_ID"
156
+ fi
@@ -0,0 +1,195 @@
1
+ #!/bin/bash
2
+ # ============================================================================
3
+ # ARKA OS — KB Status Checker
4
+ # Shows status of queued/running/ready/completed jobs.
5
+ #
6
+ # Usage: kb-status.sh [job-id] [--json]
7
+ # ============================================================================
8
+
9
+ ARKA_DIR="$HOME/.arka-os"
10
+ JOBS_FILE="$ARKA_DIR/kb-jobs.json"
11
+ LOCK_FILE="$ARKA_DIR/kb-jobs.lock"
12
+
13
+ JOB_ID=""
14
+ JSON_MODE=false
15
+
16
+ # Parse args
17
+ while [ $# -gt 0 ]; do
18
+ case "$1" in
19
+ --json) JSON_MODE=true; shift ;;
20
+ *) JOB_ID="$1"; shift ;;
21
+ esac
22
+ done
23
+
24
+ # Colors
25
+ CYAN='\033[0;36m'
26
+ GREEN='\033[0;32m'
27
+ YELLOW='\033[1;33m'
28
+ RED='\033[0;31m'
29
+ BLUE='\033[0;34m'
30
+ NC='\033[0m'
31
+
32
+ # ─── Check jobs file exists ─────────────────────────────────────────────────
33
+
34
+ if [ ! -f "$JOBS_FILE" ]; then
35
+ if $JSON_MODE; then
36
+ echo '{"jobs":[]}'
37
+ else
38
+ echo -e "${YELLOW}No jobs found.${NC} Queue a URL with: /kb learn <url>"
39
+ fi
40
+ exit 0
41
+ fi
42
+
43
+ if ! command -v jq &>/dev/null; then
44
+ echo "Error: jq not found. Install with: brew install jq" >&2
45
+ exit 1
46
+ fi
47
+
48
+ # ─── Validate running PIDs ──────────────────────────────────────────────────
49
+
50
+ (
51
+ flock -x 200
52
+
53
+ # Check each running/downloading/transcribing job's PID
54
+ ACTIVE_IDS=$(jq -r '.jobs[] | select(.status == "downloading" or .status == "transcribing" or .status == "queued") | .id' "$JOBS_FILE" 2>/dev/null)
55
+
56
+ CHANGED=false
57
+ for id in $ACTIVE_IDS; do
58
+ PID=$(jq -r --arg id "$id" '.jobs[] | select(.id == $id) | .pid // empty' "$JOBS_FILE")
59
+ if [ -n "$PID" ] && ! kill -0 "$PID" 2>/dev/null; then
60
+ # PID is dead — mark as failed
61
+ NOW=$(date -u +%Y-%m-%dT%H:%M:%SZ)
62
+ tmp="$JOBS_FILE.tmp.$$"
63
+ jq --arg id "$id" --arg t "$NOW" \
64
+ '(.jobs[] | select(.id == $id)) |= (.status = "failed" | .error = "Worker process died unexpectedly" | .updated_at = $t)' \
65
+ "$JOBS_FILE" > "$tmp" && mv "$tmp" "$JOBS_FILE"
66
+ CHANGED=true
67
+ fi
68
+ done
69
+
70
+ ) 200>"$LOCK_FILE"
71
+
72
+ # ─── Single job detail ──────────────────────────────────────────────────────
73
+
74
+ if [ -n "$JOB_ID" ]; then
75
+ JOB=$(jq --arg id "$JOB_ID" '.jobs[] | select(.id == $id)' "$JOBS_FILE" 2>/dev/null)
76
+
77
+ if [ -z "$JOB" ] || [ "$JOB" = "null" ]; then
78
+ echo "Job not found: $JOB_ID" >&2
79
+ exit 1
80
+ fi
81
+
82
+ if $JSON_MODE; then
83
+ echo "$JOB" | jq .
84
+ exit 0
85
+ fi
86
+
87
+ STATUS=$(echo "$JOB" | jq -r '.status')
88
+ URL=$(echo "$JOB" | jq -r '.url')
89
+ TITLE=$(echo "$JOB" | jq -r '.title // "Pending..."')
90
+ DIR=$(echo "$JOB" | jq -r '.output_dir')
91
+ METHOD=$(echo "$JOB" | jq -r '.transcription_method')
92
+ PERSONA=$(echo "$JOB" | jq -r '.persona // "Not assigned"')
93
+ WORDS=$(echo "$JOB" | jq -r '.word_count // "—"')
94
+ ERROR=$(echo "$JOB" | jq -r '.error // ""')
95
+ CREATED=$(echo "$JOB" | jq -r '.created_at')
96
+ UPDATED=$(echo "$JOB" | jq -r '.updated_at')
97
+
98
+ # Status color
99
+ case "$STATUS" in
100
+ queued) STATUS_COLOR="$YELLOW" ;;
101
+ downloading) STATUS_COLOR="$BLUE" ;;
102
+ transcribing) STATUS_COLOR="$BLUE" ;;
103
+ ready) STATUS_COLOR="$GREEN" ;;
104
+ analyzing) STATUS_COLOR="$CYAN" ;;
105
+ completed) STATUS_COLOR="$GREEN" ;;
106
+ failed) STATUS_COLOR="$RED" ;;
107
+ *) STATUS_COLOR="$NC" ;;
108
+ esac
109
+
110
+ echo ""
111
+ echo -e "${CYAN}═══ Job: $JOB_ID ═══${NC}"
112
+ echo -e " Status: ${STATUS_COLOR}$STATUS${NC}"
113
+ echo -e " Title: $TITLE"
114
+ echo -e " URL: $URL"
115
+ echo -e " Method: $METHOD"
116
+ echo -e " Persona: $PERSONA"
117
+ echo -e " Words: $WORDS"
118
+ echo -e " Output: $DIR"
119
+ echo -e " Created: $CREATED"
120
+ echo -e " Updated: $UPDATED"
121
+ if [ -n "$ERROR" ]; then
122
+ echo -e " ${RED}Error: $ERROR${NC}"
123
+ fi
124
+
125
+ # Show available files
126
+ if [ -d "$DIR" ]; then
127
+ echo ""
128
+ echo -e " ${CYAN}Files:${NC}"
129
+ for f in "$DIR"/*; do
130
+ [ -f "$f" ] || continue
131
+ SIZE=$(ls -lh "$f" | awk '{print $5}')
132
+ echo -e " $(basename "$f") ($SIZE)"
133
+ done
134
+ fi
135
+
136
+ echo -e "${CYAN}══════════════════════${NC}"
137
+ exit 0
138
+ fi
139
+
140
+ # ─── Summary table ──────────────────────────────────────────────────────────
141
+
142
+ if $JSON_MODE; then
143
+ jq . "$JOBS_FILE"
144
+ exit 0
145
+ fi
146
+
147
+ TOTAL=$(jq '.jobs | length' "$JOBS_FILE")
148
+ if [ "$TOTAL" -eq 0 ]; then
149
+ echo -e "${YELLOW}No jobs found.${NC} Queue a URL with: /kb learn <url>"
150
+ exit 0
151
+ fi
152
+
153
+ echo ""
154
+ echo -e "${CYAN}═══ ARKA OS — KB Job Queue ═══${NC}"
155
+ echo ""
156
+ printf " ${CYAN}%-10s %-12s %-40s %s${NC}\n" "ID" "STATUS" "TITLE" "METHOD"
157
+ printf " %-10s %-12s %-40s %s\n" "──────────" "────────────" "────────────────────────────────────────" "──────────"
158
+
159
+ jq -r '.jobs[] | [.id, .status, (.title // "Pending..."), .transcription_method] | @tsv' "$JOBS_FILE" | while IFS=$'\t' read -r id status title method; do
160
+ # Truncate title
161
+ if [ ${#title} -gt 38 ]; then
162
+ title="${title:0:35}..."
163
+ fi
164
+
165
+ # Status color
166
+ case "$status" in
167
+ queued) SC="$YELLOW" ;;
168
+ downloading) SC="$BLUE" ;;
169
+ transcribing) SC="$BLUE" ;;
170
+ ready) SC="$GREEN" ;;
171
+ analyzing) SC="$CYAN" ;;
172
+ completed) SC="$GREEN" ;;
173
+ failed) SC="$RED" ;;
174
+ *) SC="$NC" ;;
175
+ esac
176
+
177
+ printf " %-10s ${SC}%-12s${NC} %-40s %s\n" "$id" "$status" "$title" "$method"
178
+ done
179
+
180
+ # Summary counts
181
+ QUEUED=$(jq '[.jobs[] | select(.status == "queued")] | length' "$JOBS_FILE")
182
+ ACTIVE=$(jq '[.jobs[] | select(.status == "downloading" or .status == "transcribing")] | length' "$JOBS_FILE")
183
+ READY=$(jq '[.jobs[] | select(.status == "ready")] | length' "$JOBS_FILE")
184
+ COMPLETED=$(jq '[.jobs[] | select(.status == "completed")] | length' "$JOBS_FILE")
185
+ FAILED=$(jq '[.jobs[] | select(.status == "failed")] | length' "$JOBS_FILE")
186
+
187
+ echo ""
188
+ echo -e " Queued: ${YELLOW}$QUEUED${NC} Active: ${BLUE}$ACTIVE${NC} Ready: ${GREEN}$READY${NC} Completed: ${GREEN}$COMPLETED${NC} Failed: ${RED}$FAILED${NC}"
189
+ echo ""
190
+
191
+ if [ "$READY" -gt 0 ]; then
192
+ echo -e " ${GREEN}$READY job(s) ready for processing.${NC} Run: /kb process <job-id>"
193
+ fi
194
+
195
+ echo -e "${CYAN}═══════════════════════════════${NC}"