arkaos 4.3.6 → 4.4.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.
- package/VERSION +1 -1
- package/bin/arka-py +22 -7
- package/config/hooks/_lib/arka_python.ps1 +31 -0
- package/config/hooks/_lib/arka_python.sh +38 -0
- package/config/hooks/post-tool-use.ps1 +8 -0
- package/config/hooks/post-tool-use.sh +11 -5
- package/config/hooks/pre-tool-use.ps1 +11 -6
- package/config/hooks/pre-tool-use.sh +11 -6
- package/config/hooks/session-start.ps1 +10 -0
- package/config/hooks/session-start.sh +5 -0
- package/config/hooks/stop.ps1 +9 -1
- package/config/hooks/stop.sh +11 -5
- package/config/hooks/user-prompt-submit.ps1 +18 -0
- package/config/hooks/user-prompt-submit.sh +11 -5
- package/core/cognition/scheduler/__pycache__/daemon.cpython-313.pyc +0 -0
- package/core/cognition/scheduler/daemon.py +7 -3
- package/core/forge/__pycache__/orchestrator.cpython-313.pyc +0 -0
- package/core/forge/orchestrator.py +2 -1
- package/core/hooks/__pycache__/_shared.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/_shared.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/stop.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/stop.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/core/hooks/_shared.py +29 -9
- package/core/hooks/stop.py +4 -3
- package/core/hooks/user_prompt_submit.py +5 -4
- package/core/knowledge/__pycache__/indexer.cpython-313.pyc +0 -0
- package/core/knowledge/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/core/knowledge/indexer.py +1 -1
- package/core/knowledge/vector_store.py +10 -3
- package/core/runtime/__pycache__/model_routing_check.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/model_routing_context.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/native_usage.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/native_usage.cpython-314.pyc +0 -0
- package/core/runtime/gateway/__pycache__/__init__.cpython-313.pyc +0 -0
- package/core/runtime/gateway/__pycache__/__main__.cpython-313.pyc +0 -0
- package/core/runtime/gateway/__pycache__/litellm_config.cpython-313.pyc +0 -0
- package/core/runtime/native_usage.py +2 -1
- package/core/shared/__pycache__/temp_paths.cpython-313.pyc +0 -0
- package/core/shared/__pycache__/temp_paths.cpython-314.pyc +0 -0
- package/core/shared/temp_paths.py +40 -0
- package/core/synapse/__pycache__/kb_cache.cpython-313.pyc +0 -0
- package/core/synapse/__pycache__/kb_cache.cpython-314.pyc +0 -0
- package/core/synapse/kb_cache.py +3 -2
- package/core/sync/__pycache__/agent_provisioner.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/ai_mcp_decider.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/content_syncer.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/descriptor_syncer.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/discovery.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/engine.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/manifest.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/mcp_optimizer.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/mcp_syncer.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/policy_loader.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/reporter.cpython-313.pyc +0 -0
- package/core/sync/__pycache__/settings_syncer.cpython-313.pyc +0 -0
- package/core/sync/agent_provisioner.py +5 -5
- package/core/sync/ai_mcp_decider.py +2 -2
- package/core/sync/content_syncer.py +14 -14
- package/core/sync/descriptor_syncer.py +2 -2
- package/core/sync/discovery.py +4 -4
- package/core/sync/engine.py +4 -4
- package/core/sync/manifest.py +1 -1
- package/core/sync/mcp_optimizer.py +5 -5
- package/core/sync/mcp_syncer.py +3 -3
- package/core/sync/policy_loader.py +1 -1
- package/core/sync/reporter.py +1 -1
- package/core/sync/settings_syncer.py +2 -2
- package/core/terminal/__pycache__/session.cpython-313.pyc +0 -0
- package/core/terminal/__pycache__/session_windows.cpython-313.pyc +0 -0
- package/core/terminal/session.py +66 -11
- package/core/terminal/session_windows.py +211 -0
- package/core/workflow/__pycache__/flow_authorization.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/flow_authorization.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/marker_cache.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/marker_cache.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/research_gate.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/research_gate.cpython-314.pyc +0 -0
- package/core/workflow/flow_authorization.py +2 -1
- package/core/workflow/flow_enforcer.py +2 -1
- package/core/workflow/marker_cache.py +2 -1
- package/core/workflow/research_gate.py +2 -1
- package/dashboard/app/pages/index.vue +6 -1
- package/installer/cli.js +5 -4
- package/installer/core-snapshot.js +53 -0
- package/installer/doctor.js +8 -3
- package/installer/index.js +29 -6
- package/installer/migrate.js +7 -4
- package/installer/update.js +13 -0
- package/package.json +1 -1
- package/pyproject.toml +2 -1
- package/scripts/__pycache__/dashboard-api.cpython-313.pyc +0 -0
- package/scripts/__pycache__/synapse-bridge.cpython-313.pyc +0 -0
- package/scripts/dashboard-api.py +69 -33
- package/scripts/knowledge-index.py +35 -2
- package/scripts/start-dashboard.ps1 +34 -14
- package/scripts/synapse-bridge.py +3 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.
|
|
1
|
+
4.4.0
|
package/bin/arka-py
CHANGED
|
@@ -30,14 +30,29 @@ done
|
|
|
30
30
|
: "${ARKA_PY:=python3}"
|
|
31
31
|
|
|
32
32
|
# ─── Make `-m core.*` resolvable regardless of cwd ────────────────────────
|
|
33
|
-
# ARKAOS_ROOT (env) wins
|
|
34
|
-
#
|
|
33
|
+
# ARKAOS_ROOT (env) wins unconditionally — an explicit operator override is
|
|
34
|
+
# honored even if wrong, so misconfiguration stays loud and debuggable.
|
|
35
|
+
# The guessed candidates are validated before winning: `.repo-path` points
|
|
36
|
+
# at an npx cache that `npm cache clean` can purge, and ~/.arkaos/core is
|
|
37
|
+
# the cognitive scheduler's minimal copy (no core/sync). A candidate only
|
|
38
|
+
# counts when it holds the full package (core/sync/__init__.py marker).
|
|
39
|
+
# Chain: .repo-path → dev checkout (bin/ -> repo root) → ~/.arkaos/lib
|
|
40
|
+
# (stable snapshot written by the installer, survives cache purges).
|
|
35
41
|
_root="${ARKAOS_ROOT:-}"
|
|
36
|
-
if [ -z "$_root" ]
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
if [ -z "$_root" ]; then
|
|
43
|
+
_repo_ptr=""
|
|
44
|
+
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
45
|
+
_repo_ptr="$(cat "$HOME/.arkaos/.repo-path" 2>/dev/null || true)"
|
|
46
|
+
fi
|
|
47
|
+
for _cand in \
|
|
48
|
+
"$_repo_ptr" \
|
|
49
|
+
"$_self/.." \
|
|
50
|
+
"$HOME/.arkaos/lib"; do
|
|
51
|
+
if [ -n "$_cand" ] && [ -f "$_cand/core/sync/__init__.py" ]; then
|
|
52
|
+
_root="$(cd "$_cand" && pwd)"
|
|
53
|
+
break
|
|
54
|
+
fi
|
|
55
|
+
done
|
|
41
56
|
fi
|
|
42
57
|
if [ -n "$_root" ] && [ -d "$_root" ]; then
|
|
43
58
|
export PYTHONPATH="${_root}${PYTHONPATH:+:$PYTHONPATH}"
|
|
@@ -40,4 +40,35 @@ function Resolve-ArkaPython {
|
|
|
40
40
|
return "python"
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
# Windows mirror of arka_resolve_root() in arka_python.sh: env override wins
|
|
44
|
+
# unconditionally; guessed candidates must contain core/sync/__init__.py
|
|
45
|
+
# (the full-package marker — `.repo-path` points at an npx cache that
|
|
46
|
+
# `npm cache clean` can purge; ~/.arkaos/lib is the installer's snapshot).
|
|
47
|
+
function Resolve-ArkaRoot {
|
|
48
|
+
if (-not [string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
49
|
+
return $env:ARKAOS_ROOT
|
|
50
|
+
}
|
|
51
|
+
$base = if ($env:USERPROFILE) { $env:USERPROFILE } elseif ($HOME) { $HOME } else { "" }
|
|
52
|
+
$repo = ""
|
|
53
|
+
$repoPathFile = Join-Path $base ".arkaos\.repo-path"
|
|
54
|
+
if ($base -and (Test-Path -LiteralPath $repoPathFile)) {
|
|
55
|
+
$repo = (Get-Content $repoPathFile -Raw).Trim()
|
|
56
|
+
}
|
|
57
|
+
if ($repo -and (Test-Path -LiteralPath (Join-Path $repo "core\sync\__init__.py"))) {
|
|
58
|
+
return $repo
|
|
59
|
+
}
|
|
60
|
+
$lib = Join-Path $base ".arkaos\lib"
|
|
61
|
+
if ($base -and (Test-Path -LiteralPath (Join-Path $lib "core\sync\__init__.py"))) {
|
|
62
|
+
return $lib
|
|
63
|
+
}
|
|
64
|
+
if ($repo -and (Test-Path -LiteralPath $repo)) {
|
|
65
|
+
return $repo
|
|
66
|
+
}
|
|
67
|
+
if ($base -and (Test-Path -LiteralPath (Join-Path $base ".arkaos"))) {
|
|
68
|
+
return (Join-Path $base ".arkaos")
|
|
69
|
+
}
|
|
70
|
+
if ($env:ARKA_OS) { return $env:ARKA_OS }
|
|
71
|
+
return (Join-Path $base ".claude\skills\arkaos")
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
$env:ARKA_PY = Resolve-ArkaPython
|
|
@@ -61,3 +61,41 @@ arka_resolve_python() {
|
|
|
61
61
|
# keep the export unconditional.
|
|
62
62
|
ARKA_PY="$(arka_resolve_python)" || true
|
|
63
63
|
export ARKA_PY
|
|
64
|
+
|
|
65
|
+
# Contract of arka_resolve_root():
|
|
66
|
+
# Echoes the ArkaOS root for `-m core.*` execution. env ARKAOS_ROOT wins
|
|
67
|
+
# unconditionally (explicit operator override stays loud and debuggable).
|
|
68
|
+
# Guessed candidates are validated on core/sync/__init__.py — the marker
|
|
69
|
+
# that distinguishes the full package from the cognitive scheduler's
|
|
70
|
+
# partial ~/.arkaos/core copy — because `.repo-path` points at an npx
|
|
71
|
+
# cache that `npm cache clean` can purge at any time. Chain:
|
|
72
|
+
# .repo-path (validated) → ~/.arkaos/lib snapshot (validated, written by
|
|
73
|
+
# the installer) → .repo-path even without core (legacy VERSION readers)
|
|
74
|
+
# → ~/.arkaos → ARKA_OS env → ~/.claude/skills/arkaos.
|
|
75
|
+
arka_resolve_root() {
|
|
76
|
+
if [ -n "${ARKAOS_ROOT:-}" ]; then
|
|
77
|
+
printf '%s\n' "$ARKAOS_ROOT"
|
|
78
|
+
return 0
|
|
79
|
+
fi
|
|
80
|
+
local repo=""
|
|
81
|
+
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
82
|
+
repo="$(cat "$HOME/.arkaos/.repo-path" 2>/dev/null || true)"
|
|
83
|
+
fi
|
|
84
|
+
if [ -n "$repo" ] && [ -f "$repo/core/sync/__init__.py" ]; then
|
|
85
|
+
printf '%s\n' "$repo"
|
|
86
|
+
return 0
|
|
87
|
+
fi
|
|
88
|
+
if [ -f "$HOME/.arkaos/lib/core/sync/__init__.py" ]; then
|
|
89
|
+
printf '%s\n' "$HOME/.arkaos/lib"
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
if [ -n "$repo" ] && [ -d "$repo" ]; then
|
|
93
|
+
printf '%s\n' "$repo"
|
|
94
|
+
return 0
|
|
95
|
+
fi
|
|
96
|
+
if [ -d "$HOME/.arkaos" ]; then
|
|
97
|
+
printf '%s\n' "$HOME/.arkaos"
|
|
98
|
+
return 0
|
|
99
|
+
fi
|
|
100
|
+
printf '%s\n' "${ARKA_OS:-$HOME/.claude/skills/arkaos}"
|
|
101
|
+
}
|
|
@@ -150,6 +150,14 @@ if ($shouldProcessGotchas -and $null -ne $payload) {
|
|
|
150
150
|
$arkaosRootPtu = (Get-Content -Raw -LiteralPath $repoPathFile -Encoding UTF8).Trim()
|
|
151
151
|
} catch { }
|
|
152
152
|
}
|
|
153
|
+
# .repo-path may point at a purged npx cache — fall through
|
|
154
|
+
# to the ~/.arkaos/lib snapshot when core is missing.
|
|
155
|
+
if (-not ($arkaosRootPtu -and (Test-Path -LiteralPath (Join-Path $arkaosRootPtu 'core\sync\__init__.py')))) {
|
|
156
|
+
$libPtu = Join-Path $env:USERPROFILE '.arkaos\lib'
|
|
157
|
+
if (Test-Path -LiteralPath (Join-Path $libPtu 'core\sync\__init__.py')) {
|
|
158
|
+
$arkaosRootPtu = $libPtu
|
|
159
|
+
}
|
|
160
|
+
}
|
|
153
161
|
}
|
|
154
162
|
if (-not $arkaosRootPtu) {
|
|
155
163
|
$arkaosRootPtu = Join-Path $env:USERPROFILE '.arkaos'
|
|
@@ -20,7 +20,17 @@
|
|
|
20
20
|
# - Hook metrics. Output: JSON to stdout. Timeout: 5s.
|
|
21
21
|
# ============================================================================
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
24
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
25
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
26
|
+
|
|
27
|
+
# ─── Resolve ARKAOS_ROOT (validated — see arka_resolve_root in _lib) ────
|
|
28
|
+
# .repo-path can point at a purged npx cache; the shared resolver falls
|
|
29
|
+
# through to the ~/.arkaos/lib snapshot instead of exporting a dead root.
|
|
30
|
+
if command -v arka_resolve_root >/dev/null 2>&1; then
|
|
31
|
+
ARKAOS_ROOT="$(arka_resolve_root)"
|
|
32
|
+
elif [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
33
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
24
34
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
25
35
|
ARKAOS_ROOT=$(cat "$HOME/.arkaos/.repo-path")
|
|
26
36
|
elif [ -d "$HOME/.arkaos" ]; then
|
|
@@ -31,10 +41,6 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
31
41
|
fi
|
|
32
42
|
export ARKAOS_ROOT
|
|
33
43
|
|
|
34
|
-
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
35
|
-
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
36
|
-
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
37
|
-
|
|
38
44
|
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
39
45
|
echo '{}'
|
|
40
46
|
exit 0
|
|
@@ -27,8 +27,17 @@ $transcriptPath = [string]$inp.transcript_path
|
|
|
27
27
|
$sessionId = [string]$inp.session_id
|
|
28
28
|
$cwd = [string]$inp.cwd
|
|
29
29
|
|
|
30
|
-
#
|
|
31
|
-
|
|
30
|
+
# Shared resolver (venv-first, yaml-verified). Mirrors _lib/arka_python.sh.
|
|
31
|
+
$arkaLib = Join-Path $PSScriptRoot "_lib\arka_python.ps1"
|
|
32
|
+
if (Test-Path -LiteralPath $arkaLib) { . $arkaLib }
|
|
33
|
+
|
|
34
|
+
# --- Resolve ARKAOS_ROOT (validated — see Resolve-ArkaRoot in _lib) ---
|
|
35
|
+
# .repo-path can point at a purged npx cache; the shared resolver falls
|
|
36
|
+
# through to the ~/.arkaos/lib snapshot instead of exporting a dead root.
|
|
37
|
+
if (Get-Command Resolve-ArkaRoot -ErrorAction SilentlyContinue) {
|
|
38
|
+
$env:ARKAOS_ROOT = Resolve-ArkaRoot
|
|
39
|
+
} elseif ([string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
40
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
32
41
|
$repoPathFile = Join-Path $HOME ".arkaos/.repo-path"
|
|
33
42
|
if (Test-Path $repoPathFile) {
|
|
34
43
|
$env:ARKAOS_ROOT = (Get-Content $repoPathFile -Raw).Trim()
|
|
@@ -38,10 +47,6 @@ if ([string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
|
38
47
|
$env:ARKAOS_ROOT = if ($env:ARKA_OS) { $env:ARKA_OS } else { Join-Path $HOME ".claude/skills/arkaos" }
|
|
39
48
|
}
|
|
40
49
|
}
|
|
41
|
-
|
|
42
|
-
# Shared resolver (venv-first, yaml-verified). Mirrors _lib/arka_python.sh.
|
|
43
|
-
$arkaLib = Join-Path $PSScriptRoot "_lib\arka_python.ps1"
|
|
44
|
-
if (Test-Path -LiteralPath $arkaLib) { . $arkaLib }
|
|
45
50
|
$pythonExe = $env:ARKA_PY
|
|
46
51
|
if (-not $pythonExe) { exit 0 }
|
|
47
52
|
|
|
@@ -22,8 +22,17 @@
|
|
|
22
22
|
# flags are honored inside the python modules. Timeout: 10s.
|
|
23
23
|
# ============================================================================
|
|
24
24
|
|
|
25
|
-
# ───
|
|
26
|
-
|
|
25
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
26
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
27
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
28
|
+
|
|
29
|
+
# ─── Resolve ARKAOS_ROOT (validated — see arka_resolve_root in _lib) ────
|
|
30
|
+
# .repo-path can point at a purged npx cache; the shared resolver falls
|
|
31
|
+
# through to the ~/.arkaos/lib snapshot instead of exporting a dead root.
|
|
32
|
+
if command -v arka_resolve_root >/dev/null 2>&1; then
|
|
33
|
+
ARKAOS_ROOT="$(arka_resolve_root)"
|
|
34
|
+
elif [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
35
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
27
36
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
28
37
|
ARKAOS_ROOT=$(cat "$HOME/.arkaos/.repo-path")
|
|
29
38
|
elif [ -d "$HOME/.arkaos" ]; then
|
|
@@ -34,10 +43,6 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
34
43
|
fi
|
|
35
44
|
export ARKAOS_ROOT
|
|
36
45
|
|
|
37
|
-
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
38
|
-
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
39
|
-
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
40
|
-
|
|
41
46
|
# ─── Degrade gracefully (fail open, same as before) ─────────────────────
|
|
42
47
|
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
43
48
|
exit 0
|
|
@@ -46,6 +46,16 @@ if (Test-Path -LiteralPath $repoPathFile) {
|
|
|
46
46
|
}
|
|
47
47
|
} catch { }
|
|
48
48
|
}
|
|
49
|
+
# .repo-path may point at a purged npx cache — the installer's snapshot
|
|
50
|
+
# keeps the drift banner alive ('2.x' is the untouched default above).
|
|
51
|
+
if ($version -eq '2.x') {
|
|
52
|
+
$libVersionFile = Join-Path $arkaosHome 'lib\VERSION'
|
|
53
|
+
if (Test-Path -LiteralPath $libVersionFile) {
|
|
54
|
+
try {
|
|
55
|
+
$version = (Get-Content -Raw -LiteralPath $libVersionFile -Encoding UTF8).Trim()
|
|
56
|
+
} catch { }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
49
59
|
|
|
50
60
|
# ─── Time greeting ─────────────────────────────────────────────────────
|
|
51
61
|
$hour = [int](Get-Date -Format 'HH')
|
|
@@ -22,6 +22,11 @@ if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
|
22
22
|
REPO=$(cat "$HOME/.arkaos/.repo-path")
|
|
23
23
|
[ -f "$REPO/VERSION" ] && VERSION=$(cat "$REPO/VERSION" | tr -d '[:space:]')
|
|
24
24
|
fi
|
|
25
|
+
# .repo-path may point at a purged npx cache — the installer's snapshot
|
|
26
|
+
# keeps the drift banner alive ("2.x" is the untouched default above).
|
|
27
|
+
if [ "$VERSION" = "2.x" ] && [ -f "$HOME/.arkaos/lib/VERSION" ]; then
|
|
28
|
+
VERSION=$(tr -d '[:space:]' < "$HOME/.arkaos/lib/VERSION")
|
|
29
|
+
fi
|
|
25
30
|
|
|
26
31
|
# ─── Static greeting (cache-friendly) ──────────────────────────────────
|
|
27
32
|
# Time-of-day branching removed: it invalidated prompt cache 3x/day without
|
package/config/hooks/stop.ps1
CHANGED
|
@@ -29,7 +29,15 @@ if ([string]::IsNullOrWhiteSpace($sessionId) -or -not (Test-Path $wfMarker)) {
|
|
|
29
29
|
exit 0
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
# Resolve ARKAOS_ROOT via the validated shared resolver: .repo-path can
|
|
33
|
+
# point at a purged npx cache; fall through to the ~/.arkaos/lib snapshot
|
|
34
|
+
# instead of exporting a dead root.
|
|
35
|
+
$arkaLibEarly = Join-Path $PSScriptRoot "_lib\arka_python.ps1"
|
|
36
|
+
if (Test-Path -LiteralPath $arkaLibEarly) { . $arkaLibEarly }
|
|
37
|
+
if (Get-Command Resolve-ArkaRoot -ErrorAction SilentlyContinue) {
|
|
38
|
+
$env:ARKAOS_ROOT = Resolve-ArkaRoot
|
|
39
|
+
} elseif ([string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
40
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
33
41
|
$repoPathFile = Join-Path $HOME ".arkaos/.repo-path"
|
|
34
42
|
if (Test-Path $repoPathFile) {
|
|
35
43
|
$env:ARKAOS_ROOT = (Get-Content $repoPathFile -Raw).Trim()
|
package/config/hooks/stop.sh
CHANGED
|
@@ -22,7 +22,17 @@
|
|
|
22
22
|
# Timeout: 5s | Always exit 0.
|
|
23
23
|
# ============================================================================
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
26
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
27
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
28
|
+
|
|
29
|
+
# ─── Resolve ARKAOS_ROOT (validated — see arka_resolve_root in _lib) ────
|
|
30
|
+
# .repo-path can point at a purged npx cache; the shared resolver falls
|
|
31
|
+
# through to the ~/.arkaos/lib snapshot instead of exporting a dead root.
|
|
32
|
+
if command -v arka_resolve_root >/dev/null 2>&1; then
|
|
33
|
+
ARKAOS_ROOT="$(arka_resolve_root)"
|
|
34
|
+
elif [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
35
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
26
36
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
27
37
|
ARKAOS_ROOT=$(cat "$HOME/.arkaos/.repo-path")
|
|
28
38
|
elif [ -d "$HOME/.arkaos" ]; then
|
|
@@ -33,10 +43,6 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
33
43
|
fi
|
|
34
44
|
export ARKAOS_ROOT
|
|
35
45
|
|
|
36
|
-
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
37
|
-
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
38
|
-
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
39
|
-
|
|
40
46
|
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
41
47
|
exit 0
|
|
42
48
|
fi
|
|
@@ -80,6 +80,14 @@ try {
|
|
|
80
80
|
$arkaosRootUps = (Get-Content -Raw -LiteralPath $repoPathFileUps -Encoding UTF8).Trim()
|
|
81
81
|
} catch { }
|
|
82
82
|
}
|
|
83
|
+
# .repo-path may point at a purged npx cache — fall through to
|
|
84
|
+
# the ~/.arkaos/lib snapshot when the core package is missing.
|
|
85
|
+
if (-not ($arkaosRootUps -and (Test-Path -LiteralPath (Join-Path $arkaosRootUps 'core\sync\__init__.py')))) {
|
|
86
|
+
$libUps = Join-Path $env:USERPROFILE '.arkaos\lib'
|
|
87
|
+
if (Test-Path -LiteralPath (Join-Path $libUps 'core\sync\__init__.py')) {
|
|
88
|
+
$arkaosRootUps = $libUps
|
|
89
|
+
}
|
|
90
|
+
}
|
|
83
91
|
}
|
|
84
92
|
if (-not $arkaosRootUps) {
|
|
85
93
|
$arkaosRootUps = Join-Path $env:USERPROFILE '.arkaos'
|
|
@@ -160,6 +168,16 @@ if ($env:ARKAOS_ROOT) {
|
|
|
160
168
|
$arkaosRoot = $null
|
|
161
169
|
}
|
|
162
170
|
}
|
|
171
|
+
# .repo-path may point at a purged npx cache — prefer the ~/.arkaos/lib
|
|
172
|
+
# snapshot over a root without the core package (env override untouched).
|
|
173
|
+
if (-not $env:ARKAOS_ROOT) {
|
|
174
|
+
if (-not ($arkaosRoot -and (Test-Path -LiteralPath (Join-Path $arkaosRoot 'core\sync\__init__.py')))) {
|
|
175
|
+
$libRoot = Join-Path $arkaosHome 'lib'
|
|
176
|
+
if (Test-Path -LiteralPath (Join-Path $libRoot 'core\sync\__init__.py')) {
|
|
177
|
+
$arkaosRoot = $libRoot
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
163
181
|
if (-not $arkaosRoot) {
|
|
164
182
|
if (Test-Path -LiteralPath $arkaosHome -PathType Container) {
|
|
165
183
|
$arkaosRoot = $arkaosHome
|
|
@@ -23,7 +23,17 @@
|
|
|
23
23
|
# Timeout: 10s | Output: JSON to stdout | Target: <100ms
|
|
24
24
|
# ============================================================================
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
27
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
28
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
29
|
+
|
|
30
|
+
# ─── Resolve ARKAOS_ROOT (validated — see arka_resolve_root in _lib) ────
|
|
31
|
+
# .repo-path can point at a purged npx cache; the shared resolver falls
|
|
32
|
+
# through to the ~/.arkaos/lib snapshot instead of exporting a dead root.
|
|
33
|
+
if command -v arka_resolve_root >/dev/null 2>&1; then
|
|
34
|
+
ARKAOS_ROOT="$(arka_resolve_root)"
|
|
35
|
+
elif [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
36
|
+
# Legacy chain (pre-snapshot _lib deployment)
|
|
27
37
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
28
38
|
ARKAOS_ROOT=$(cat "$HOME/.arkaos/.repo-path")
|
|
29
39
|
elif [ -d "$HOME/.arkaos" ]; then
|
|
@@ -34,10 +44,6 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
34
44
|
fi
|
|
35
45
|
export ARKAOS_ROOT
|
|
36
46
|
|
|
37
|
-
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
38
|
-
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
39
|
-
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
40
|
-
|
|
41
47
|
_ARKA_L0_FALLBACK='{"additionalContext": "[Constitution] NON-NEGOTIABLE: branch-isolation, obsidian-output, authority-boundaries, security-gate, context-first, solid-clean-code, spec-driven, human-writing, squad-routing, full-visibility, sequential-validation, mandatory-qa, arka-supremacy | QUALITY-GATE: marta-cqo, eduardo-copy, francisca-tech-ux | MUST: conventional-commits, test-coverage, pattern-matching, actionable-output, memory-persistence"}'
|
|
42
48
|
|
|
43
49
|
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
Binary file
|
|
@@ -275,11 +275,15 @@ class ArkaScheduler:
|
|
|
275
275
|
extra_paths = [
|
|
276
276
|
os.path.join(home, ".local", "bin"),
|
|
277
277
|
os.path.join(home, ".arkaos", "bin"),
|
|
278
|
-
"/usr/local/bin",
|
|
279
278
|
]
|
|
279
|
+
if os.name != "nt":
|
|
280
|
+
extra_paths.append("/usr/local/bin")
|
|
280
281
|
env = os.environ.copy()
|
|
281
|
-
existing = env.get("PATH", "/usr/bin:/bin")
|
|
282
|
-
|
|
282
|
+
existing = env.get("PATH", "" if os.name == "nt" else "/usr/bin:/bin")
|
|
283
|
+
# os.pathsep is ';' on Windows (where drive-letter entries contain
|
|
284
|
+
# ':') and ':' on POSIX, so the joined PATH stays valid on both.
|
|
285
|
+
parts = extra_paths + ([existing] if existing else [])
|
|
286
|
+
env["PATH"] = os.pathsep.join(parts)
|
|
283
287
|
return env
|
|
284
288
|
|
|
285
289
|
def _run_attempt(
|
|
Binary file
|
|
@@ -23,6 +23,7 @@ from enum import Enum
|
|
|
23
23
|
from pathlib import Path
|
|
24
24
|
from typing import Optional
|
|
25
25
|
|
|
26
|
+
from core.shared.temp_paths import arkaos_temp_dir
|
|
26
27
|
from core.forge.schema import (
|
|
27
28
|
ForgeContext,
|
|
28
29
|
ForgePlan,
|
|
@@ -361,7 +362,7 @@ class ForgeOrchestrator:
|
|
|
361
362
|
raise RuntimeError("No active forge plan.")
|
|
362
363
|
|
|
363
364
|
html = render_html(self._current_plan)
|
|
364
|
-
path = f"
|
|
365
|
+
path = str(arkaos_temp_dir(f"forge-{self._current_plan.id}.html"))
|
|
365
366
|
Path(path).write_text(html, encoding="utf-8")
|
|
366
367
|
return path
|
|
367
368
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/core/hooks/_shared.py
CHANGED
|
@@ -51,21 +51,41 @@ def get_str(data: dict, *keys: str) -> str:
|
|
|
51
51
|
return str(cur)
|
|
52
52
|
|
|
53
53
|
|
|
54
|
+
def _has_core_package(root: str) -> bool:
|
|
55
|
+
# core/sync/__init__.py distinguishes the full package from the
|
|
56
|
+
# cognitive scheduler's minimal core/ copy (cognition + workflow only).
|
|
57
|
+
try:
|
|
58
|
+
return (Path(root) / "core" / "sync" / "__init__.py").is_file()
|
|
59
|
+
except OSError:
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
|
|
54
63
|
def resolve_arkaos_root() -> str:
|
|
55
|
-
"""Resolve ARKAOS_ROOT with the
|
|
64
|
+
"""Resolve ARKAOS_ROOT with the hook wrappers' validated chain.
|
|
56
65
|
|
|
57
|
-
env ARKAOS_ROOT → ~/.arkaos/.repo-path
|
|
58
|
-
~/.
|
|
66
|
+
env ARKAOS_ROOT (unconditional operator override) → ~/.arkaos/.repo-path
|
|
67
|
+
(validated) → ~/.arkaos/lib stable snapshot (validated) → .repo-path
|
|
68
|
+
even without the core package (legacy VERSION readers) → ~/.arkaos →
|
|
69
|
+
ARKA_OS env → ~/.claude/skills/arkaos (portable fallback).
|
|
70
|
+
|
|
71
|
+
Mirrors arka_resolve_root() in config/hooks/_lib/arka_python.sh;
|
|
72
|
+
bin/arka-py adds one extra step (its own dev checkout) between
|
|
73
|
+
.repo-path and the snapshot.
|
|
74
|
+
|
|
75
|
+
Validation matters because .repo-path points at an npx cache that
|
|
76
|
+
`npm cache clean` can purge at any time.
|
|
59
77
|
"""
|
|
60
78
|
env_root = os.environ.get("ARKAOS_ROOT", "").strip()
|
|
61
79
|
if env_root:
|
|
62
80
|
return env_root
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
repo = repo_path()
|
|
82
|
+
if repo and _has_core_package(repo):
|
|
83
|
+
return repo
|
|
84
|
+
lib = Path.home() / ".arkaos" / "lib"
|
|
85
|
+
if _has_core_package(str(lib)):
|
|
86
|
+
return str(lib)
|
|
87
|
+
if repo and Path(repo).is_dir():
|
|
88
|
+
return repo
|
|
69
89
|
if (Path.home() / ".arkaos").is_dir():
|
|
70
90
|
return str(Path.home() / ".arkaos")
|
|
71
91
|
return os.environ.get(
|
package/core/hooks/stop.py
CHANGED
|
@@ -30,6 +30,7 @@ import re
|
|
|
30
30
|
from datetime import datetime, timezone
|
|
31
31
|
from pathlib import Path
|
|
32
32
|
|
|
33
|
+
from core.shared.temp_paths import arkaos_temp_dir
|
|
33
34
|
from core.hooks._shared import (
|
|
34
35
|
ensure_root_on_path,
|
|
35
36
|
get_str,
|
|
@@ -104,7 +105,7 @@ def _write_tmp_state(subdir: str, safe_sid: str, payload: dict) -> None:
|
|
|
104
105
|
"""Owner-only /tmp state file (umask 0o077 — PR25 v2.46.1)."""
|
|
105
106
|
prev_umask = os.umask(0o077)
|
|
106
107
|
try:
|
|
107
|
-
state_dir =
|
|
108
|
+
state_dir = arkaos_temp_dir(subdir)
|
|
108
109
|
state_dir.mkdir(parents=True, exist_ok=True)
|
|
109
110
|
(state_dir / f"{safe_sid}.json").write_text(
|
|
110
111
|
json.dumps(payload), encoding="utf-8"
|
|
@@ -220,7 +221,7 @@ def _flow_checks(
|
|
|
220
221
|
kb_reported = parse_reported_kb(last)
|
|
221
222
|
if safe_sid:
|
|
222
223
|
injected_path = (
|
|
223
|
-
|
|
224
|
+
arkaos_temp_dir("arkaos-kb-injected") / f"{safe_sid}.json"
|
|
224
225
|
)
|
|
225
226
|
if injected_path.exists():
|
|
226
227
|
injected_data = json.loads(
|
|
@@ -369,7 +370,7 @@ def main(stdin_json: dict | None = None) -> int:
|
|
|
369
370
|
_native_usage(transcript_path, session_id, raw)
|
|
370
371
|
|
|
371
372
|
# Only evaluate sessions where the classifier flagged creation intent.
|
|
372
|
-
wf_marker =
|
|
373
|
+
wf_marker = arkaos_temp_dir("arkaos-wf-required") / session_id if session_id else None
|
|
373
374
|
if wf_marker is None or not safe_session_id(session_id) or not wf_marker.is_file():
|
|
374
375
|
return 0
|
|
375
376
|
|
|
@@ -36,6 +36,7 @@ import subprocess
|
|
|
36
36
|
import time
|
|
37
37
|
from pathlib import Path
|
|
38
38
|
|
|
39
|
+
from core.shared.temp_paths import arkaos_temp_dir
|
|
39
40
|
from core.hooks._shared import (
|
|
40
41
|
ensure_root_on_path,
|
|
41
42
|
get_str,
|
|
@@ -45,7 +46,7 @@ from core.hooks._shared import (
|
|
|
45
46
|
safe_session_id,
|
|
46
47
|
)
|
|
47
48
|
|
|
48
|
-
_CACHE_DIR =
|
|
49
|
+
_CACHE_DIR = arkaos_temp_dir("arkaos-context-cache")
|
|
49
50
|
_CACHE_TTL = 300 # Constitution cache: 5 minutes
|
|
50
51
|
|
|
51
52
|
_L0_FALLBACK = (
|
|
@@ -282,7 +283,7 @@ def _kb_auto_inject(root: str, user_input: str) -> str:
|
|
|
282
283
|
project_hash = hashlib.md5(
|
|
283
284
|
root.encode(), usedforsecurity=False
|
|
284
285
|
).hexdigest()[:12]
|
|
285
|
-
cache_dir =
|
|
286
|
+
cache_dir = arkaos_temp_dir(f"arkaos-kb-{project_hash}")
|
|
286
287
|
if not cache_dir.is_dir():
|
|
287
288
|
return ""
|
|
288
289
|
try:
|
|
@@ -439,7 +440,7 @@ def _wf_mark_required(session_id: str) -> None:
|
|
|
439
440
|
if safe_session_id(session_id) is None:
|
|
440
441
|
return
|
|
441
442
|
marker_dir = Path(
|
|
442
|
-
os.environ.get("ARKA_WF_REQUIRED_DIR", "
|
|
443
|
+
os.environ.get("ARKA_WF_REQUIRED_DIR", str(arkaos_temp_dir("arkaos-wf-required")))
|
|
443
444
|
)
|
|
444
445
|
try:
|
|
445
446
|
marker_dir.mkdir(parents=True, exist_ok=True)
|
|
@@ -469,7 +470,7 @@ def _cognitive_hits(session_id: str) -> str:
|
|
|
469
470
|
|
|
470
471
|
def _one_shot_nudge(subdir: str, session_id: str) -> str:
|
|
471
472
|
"""Read + delete a /tmp/<subdir>/<session>.json nudge state file."""
|
|
472
|
-
nudge_file =
|
|
473
|
+
nudge_file = arkaos_temp_dir(subdir) / f"{session_id}.json"
|
|
473
474
|
if not nudge_file.is_file():
|
|
474
475
|
return ""
|
|
475
476
|
nudge = ""
|
|
Binary file
|
|
Binary file
|
|
@@ -347,10 +347,17 @@ class VectorStore:
|
|
|
347
347
|
for r in rows
|
|
348
348
|
]
|
|
349
349
|
|
|
350
|
-
def is_file_indexed(self, file_hash: str) -> bool:
|
|
351
|
-
"""Check if a file
|
|
350
|
+
def is_file_indexed(self, source: str, file_hash: str) -> bool:
|
|
351
|
+
"""Check if a file (identified by source path + content hash) is indexed.
|
|
352
|
+
|
|
353
|
+
The source path is part of the key so identical content in two
|
|
354
|
+
different locations (e.g. two npx cache directories) each gets
|
|
355
|
+
indexed — a hash-only check would skip every subsequent cache
|
|
356
|
+
and leave the new location unsearchable.
|
|
357
|
+
"""
|
|
352
358
|
row = self._db.execute(
|
|
353
|
-
"SELECT COUNT(*) as cnt FROM chunks WHERE file_hash = ?",
|
|
359
|
+
"SELECT COUNT(*) as cnt FROM chunks WHERE source = ? AND file_hash = ?",
|
|
360
|
+
(source, file_hash),
|
|
354
361
|
).fetchone()
|
|
355
362
|
return row["cnt"] > 0
|
|
356
363
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -33,9 +33,10 @@ from typing import Any
|
|
|
33
33
|
from core.runtime.llm_cost_telemetry import record_cost
|
|
34
34
|
from core.runtime.pricing import estimate_cost_usd
|
|
35
35
|
from core.shared.safe_session_id import safe_session_id
|
|
36
|
+
from core.shared.temp_paths import arkaos_temp_dir
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
DEFAULT_CURSOR_DIR =
|
|
39
|
+
DEFAULT_CURSOR_DIR = arkaos_temp_dir("arkaos-native-cost")
|
|
39
40
|
|
|
40
41
|
_USAGE_KEYS = (
|
|
41
42
|
"input_tokens",
|
|
Binary file
|
|
Binary file
|