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/scripts/dashboard-api.py
CHANGED
|
@@ -20,6 +20,8 @@ from typing import Optional
|
|
|
20
20
|
ARKAOS_ROOT = Path(os.environ.get("ARKAOS_ROOT", Path(__file__).resolve().parent.parent))
|
|
21
21
|
sys.path.insert(0, str(ARKAOS_ROOT))
|
|
22
22
|
|
|
23
|
+
from core.shared.temp_paths import arkaos_temp_dir
|
|
24
|
+
|
|
23
25
|
from fastapi import FastAPI, Query, Request, WebSocket, WebSocketDisconnect
|
|
24
26
|
from fastapi.middleware.cors import CORSMiddleware
|
|
25
27
|
from fastapi.responses import FileResponse, JSONResponse
|
|
@@ -158,10 +160,10 @@ def overview():
|
|
|
158
160
|
|
|
159
161
|
skills_count = 0
|
|
160
162
|
try:
|
|
161
|
-
skills_count =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
)
|
|
163
|
+
skills_count = sum(
|
|
164
|
+
1 for p in (ARKAOS_ROOT / "departments").rglob("SKILL.md")
|
|
165
|
+
if "skills" in p.parts
|
|
166
|
+
)
|
|
165
167
|
except Exception:
|
|
166
168
|
skills_count = 250
|
|
167
169
|
|
|
@@ -1733,7 +1735,7 @@ def health():
|
|
|
1733
1735
|
"npx arkaos install")
|
|
1734
1736
|
|
|
1735
1737
|
try:
|
|
1736
|
-
subprocess.run([
|
|
1738
|
+
subprocess.run([sys.executable, "--version"], capture_output=True, timeout=2)
|
|
1737
1739
|
check("python", True)
|
|
1738
1740
|
except Exception:
|
|
1739
1741
|
check("python", False, "Install Python 3.11+")
|
|
@@ -2794,6 +2796,18 @@ def _current_version() -> str:
|
|
|
2794
2796
|
return "0.0.0"
|
|
2795
2797
|
|
|
2796
2798
|
|
|
2799
|
+
def _win_shim(cmd: list) -> list:
|
|
2800
|
+
"""Wrap npm/npx-style commands so Windows can execute them.
|
|
2801
|
+
|
|
2802
|
+
npm and npx are ``.cmd`` shims; ``subprocess`` (CreateProcess) cannot
|
|
2803
|
+
run them directly ("%1 is not a valid Win32 application"), so route
|
|
2804
|
+
through ``cmd /c`` on Windows. No-op on POSIX.
|
|
2805
|
+
"""
|
|
2806
|
+
if os.name == "nt":
|
|
2807
|
+
return ["cmd", "/c", *cmd]
|
|
2808
|
+
return cmd
|
|
2809
|
+
|
|
2810
|
+
|
|
2797
2811
|
def _npm_latest_version():
|
|
2798
2812
|
import subprocess
|
|
2799
2813
|
import time
|
|
@@ -2802,7 +2816,7 @@ def _npm_latest_version():
|
|
|
2802
2816
|
return _npm_latest_cache["version"]
|
|
2803
2817
|
try:
|
|
2804
2818
|
out = subprocess.run(
|
|
2805
|
-
["npm", "view", "arkaos", "version"],
|
|
2819
|
+
_win_shim(["npm", "view", "arkaos", "version"]),
|
|
2806
2820
|
capture_output=True, text=True, timeout=20,
|
|
2807
2821
|
)
|
|
2808
2822
|
latest = (out.stdout or "").strip() or None
|
|
@@ -2829,7 +2843,7 @@ def _run_core_update() -> dict:
|
|
|
2829
2843
|
import subprocess
|
|
2830
2844
|
try:
|
|
2831
2845
|
out = subprocess.run(
|
|
2832
|
-
["npx", "arkaos@latest", "update"],
|
|
2846
|
+
_win_shim(["npx", "arkaos@latest", "update"]),
|
|
2833
2847
|
capture_output=True, text=True, timeout=600,
|
|
2834
2848
|
)
|
|
2835
2849
|
tail = ((out.stdout or "") + (out.stderr or ""))[-2000:]
|
|
@@ -2994,30 +3008,49 @@ async def ws_terminal(ws: WebSocket, session_id: str, token: str = Query("")):
|
|
|
2994
3008
|
# left it. Sent before the live reader is attached, so the historical
|
|
2995
3009
|
# prefix always precedes any new output (no interleave, no dup — these
|
|
2996
3010
|
# bytes were already consumed from the kernel buffer when first read).
|
|
2997
|
-
replay = session.scrollback()
|
|
2998
|
-
if replay:
|
|
2999
|
-
try:
|
|
3000
|
-
await ws.send_bytes(replay)
|
|
3001
|
-
except Exception:
|
|
3002
|
-
await ws.close(code=1011, reason="replay failed")
|
|
3003
|
-
return
|
|
3004
|
-
|
|
3005
3011
|
loop = asyncio.get_event_loop()
|
|
3006
3012
|
output_queue: asyncio.Queue = asyncio.Queue()
|
|
3007
3013
|
|
|
3008
|
-
|
|
3014
|
+
# POSIX exposes a pollable master fd (add_reader); the Windows ConPTY
|
|
3015
|
+
# backend has none (master_fd == -1) and instead pushes output from its
|
|
3016
|
+
# own reader thread into a registered listener.
|
|
3017
|
+
use_fd_reader = getattr(session, "master_fd", -1) >= 0
|
|
3018
|
+
|
|
3019
|
+
if use_fd_reader:
|
|
3020
|
+
replay = session.scrollback()
|
|
3021
|
+
if replay:
|
|
3022
|
+
try:
|
|
3023
|
+
await ws.send_bytes(replay)
|
|
3024
|
+
except Exception:
|
|
3025
|
+
await ws.close(code=1011, reason="replay failed")
|
|
3026
|
+
return
|
|
3027
|
+
|
|
3028
|
+
def _on_readable():
|
|
3029
|
+
try:
|
|
3030
|
+
data = session.read(8192)
|
|
3031
|
+
except OSError:
|
|
3032
|
+
data = b""
|
|
3033
|
+
if data:
|
|
3034
|
+
output_queue.put_nowait(data)
|
|
3035
|
+
|
|
3009
3036
|
try:
|
|
3010
|
-
|
|
3011
|
-
except OSError:
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3037
|
+
loop.add_reader(session.master_fd, _on_readable)
|
|
3038
|
+
except (ValueError, OSError):
|
|
3039
|
+
await ws.close(code=1011, reason="pty unavailable")
|
|
3040
|
+
return
|
|
3041
|
+
else:
|
|
3042
|
+
def _emit(data: bytes):
|
|
3043
|
+
loop.call_soon_threadsafe(output_queue.put_nowait, data)
|
|
3015
3044
|
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3045
|
+
# Atomic: snapshot scrollback and start the live feed with no gap.
|
|
3046
|
+
replay = session.attach(_emit)
|
|
3047
|
+
if replay:
|
|
3048
|
+
try:
|
|
3049
|
+
await ws.send_bytes(replay)
|
|
3050
|
+
except Exception:
|
|
3051
|
+
session.set_listener(None)
|
|
3052
|
+
await ws.close(code=1011, reason="replay failed")
|
|
3053
|
+
return
|
|
3021
3054
|
|
|
3022
3055
|
async def pump_to_client():
|
|
3023
3056
|
while True:
|
|
@@ -3060,13 +3093,16 @@ async def ws_terminal(ws: WebSocket, session_id: str, token: str = Query("")):
|
|
|
3060
3093
|
pass
|
|
3061
3094
|
finally:
|
|
3062
3095
|
pump_task.cancel()
|
|
3063
|
-
# Only the still-active connection owns the
|
|
3064
|
-
# connection tearing down must not
|
|
3096
|
+
# Only the still-active connection owns the reader — a superseded
|
|
3097
|
+
# connection tearing down must not detach its replacement's reader.
|
|
3065
3098
|
if _terminal_conns.release(session_id, ws):
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3099
|
+
if use_fd_reader:
|
|
3100
|
+
try:
|
|
3101
|
+
loop.remove_reader(session.master_fd)
|
|
3102
|
+
except (ValueError, OSError):
|
|
3103
|
+
pass
|
|
3104
|
+
else:
|
|
3105
|
+
session.set_listener(None)
|
|
3070
3106
|
|
|
3071
3107
|
|
|
3072
3108
|
@app.on_event("startup")
|
|
@@ -4233,7 +4269,7 @@ def keys_delete(key_name: str):
|
|
|
4233
4269
|
|
|
4234
4270
|
@app.get("/api/metrics")
|
|
4235
4271
|
def metrics():
|
|
4236
|
-
metrics_file =
|
|
4272
|
+
metrics_file = arkaos_temp_dir("arkaos-context-cache", "hook-metrics.jsonl")
|
|
4237
4273
|
if not metrics_file.exists():
|
|
4238
4274
|
return {"entries": [], "avg_ms": 0}
|
|
4239
4275
|
entries = []
|
|
@@ -14,6 +14,12 @@ import os
|
|
|
14
14
|
import sys
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
|
|
17
|
+
# Windows consoles default to cp1252; progress lines with non-ASCII vault
|
|
18
|
+
# names would raise UnicodeEncodeError and kill the index run silently.
|
|
19
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
20
|
+
sys.stdout.reconfigure(encoding="utf-8")
|
|
21
|
+
sys.stderr.reconfigure(encoding="utf-8")
|
|
22
|
+
|
|
17
23
|
ARKAOS_ROOT = Path(os.environ.get("ARKAOS_ROOT", Path(__file__).resolve().parent.parent))
|
|
18
24
|
sys.path.insert(0, str(ARKAOS_ROOT))
|
|
19
25
|
|
|
@@ -77,13 +83,40 @@ def main() -> int:
|
|
|
77
83
|
# Index mode
|
|
78
84
|
directory = args.vault or args.dir
|
|
79
85
|
if not directory:
|
|
80
|
-
# Auto-detect vault from config
|
|
86
|
+
# Auto-detect vault from config. vault_path may be a template like
|
|
87
|
+
# "${VAULT_PATH}" — resolve it through the canonical path resolver
|
|
88
|
+
# (ARKAOS_VAULT_PATH env / profile.json vaultPath) before testing.
|
|
81
89
|
config_path = ARKAOS_ROOT / "knowledge" / "obsidian-config.json"
|
|
82
90
|
if config_path.exists():
|
|
83
|
-
config = json.loads(config_path.read_text())
|
|
91
|
+
config = json.loads(config_path.read_text(encoding="utf-8"))
|
|
84
92
|
vault = config.get("vault_path", "")
|
|
93
|
+
if vault and "${" in vault:
|
|
94
|
+
try:
|
|
95
|
+
from core.runtime.path_resolver import resolve
|
|
96
|
+
|
|
97
|
+
vault = resolve(vault)
|
|
98
|
+
except Exception:
|
|
99
|
+
vault = ""
|
|
100
|
+
if vault and Path(vault).exists():
|
|
101
|
+
directory = vault
|
|
102
|
+
if not args.json_output:
|
|
103
|
+
print(f"Vault from config: {directory}", file=sys.stderr)
|
|
104
|
+
|
|
105
|
+
if not directory:
|
|
106
|
+
# profile.json vaultPath — set by `npx arkaos install` and the
|
|
107
|
+
# authoritative answer to "where is the user's vault".
|
|
108
|
+
profile_path = Path.home() / ".arkaos" / "profile.json"
|
|
109
|
+
if profile_path.exists():
|
|
110
|
+
try:
|
|
111
|
+
vault = json.loads(
|
|
112
|
+
profile_path.read_text(encoding="utf-8")
|
|
113
|
+
).get("vaultPath", "")
|
|
114
|
+
except (json.JSONDecodeError, OSError):
|
|
115
|
+
vault = ""
|
|
85
116
|
if vault and Path(vault).exists():
|
|
86
117
|
directory = vault
|
|
118
|
+
if not args.json_output:
|
|
119
|
+
print(f"Vault from profile: {directory}", file=sys.stderr)
|
|
87
120
|
|
|
88
121
|
if not directory:
|
|
89
122
|
# Try common vault locations
|
|
@@ -30,6 +30,7 @@ $arkaosHome = Join-Path $env:USERPROFILE '.arkaos'
|
|
|
30
30
|
$pidFile = Join-Path $arkaosHome 'dashboard.pid'
|
|
31
31
|
$portFile = Join-Path $arkaosHome 'dashboard.ports'
|
|
32
32
|
$apiLog = Join-Path $arkaosHome 'api.log'
|
|
33
|
+
$apiErrLog = Join-Path $arkaosHome 'api.err.log'
|
|
33
34
|
|
|
34
35
|
$null = New-Item -ItemType Directory -Force -Path $arkaosHome -ErrorAction SilentlyContinue
|
|
35
36
|
|
|
@@ -132,7 +133,7 @@ try {
|
|
|
132
133
|
-ArgumentList @($dashboardApi, '--port', "$apiPort") `
|
|
133
134
|
-WorkingDirectory $arkaosRoot `
|
|
134
135
|
-RedirectStandardOutput $apiLog `
|
|
135
|
-
-RedirectStandardError $
|
|
136
|
+
-RedirectStandardError $apiErrLog `
|
|
136
137
|
-NoNewWindow `
|
|
137
138
|
-PassThru
|
|
138
139
|
} finally {
|
|
@@ -160,10 +161,10 @@ for ($i = 0; $i -lt 20; $i++) {
|
|
|
160
161
|
if ($apiReady) {
|
|
161
162
|
Write-Host " API: http://localhost:$apiPort" -ForegroundColor Green
|
|
162
163
|
} else {
|
|
163
|
-
Write-Host " ! API may still be starting (check log: $
|
|
164
|
-
if (Test-Path -LiteralPath $
|
|
164
|
+
Write-Host " ! API may still be starting (check log: $apiErrLog)" -ForegroundColor Yellow
|
|
165
|
+
if (Test-Path -LiteralPath $apiErrLog) {
|
|
165
166
|
try {
|
|
166
|
-
$lastError = (Get-Content -LiteralPath $
|
|
167
|
+
$lastError = (Get-Content -LiteralPath $apiErrLog -Tail 3 -ErrorAction SilentlyContinue | Select-Object -First 1)
|
|
167
168
|
if ($lastError) {
|
|
168
169
|
Write-Host " Last error: $lastError" -ForegroundColor DarkGray
|
|
169
170
|
}
|
|
@@ -180,11 +181,23 @@ $nuxtServer = Join-Path $nuxtOutput 'server\index.mjs'
|
|
|
180
181
|
|
|
181
182
|
function Start-NuxtDev {
|
|
182
183
|
param([int]$Port, [int]$ApiPort, [string]$WorkingDir)
|
|
183
|
-
#
|
|
184
|
-
#
|
|
184
|
+
# Launch node directly against the Nuxt CLI entry. The 'npx' shim is a
|
|
185
|
+
# .cmd on Windows, which Start-Process -NoNewWindow cannot exec ("%1 is
|
|
186
|
+
# not a valid Win32 application"), and wrapping it in cmd.exe yields a
|
|
187
|
+
# process tree that dies with the launcher. A direct node.exe child
|
|
188
|
+
# detaches cleanly and survives, like the API process.
|
|
185
189
|
$savedApi = $env:NUXT_PUBLIC_API_BASE
|
|
186
190
|
$env:NUXT_PUBLIC_API_BASE = "http://localhost:$ApiPort"
|
|
187
191
|
try {
|
|
192
|
+
$nuxtBin = Join-Path $WorkingDir 'node_modules\nuxt\bin\nuxt.mjs'
|
|
193
|
+
if (Test-Path -LiteralPath $nuxtBin) {
|
|
194
|
+
return Start-Process -FilePath 'node' `
|
|
195
|
+
-ArgumentList @($nuxtBin,'dev','--port',"$Port") `
|
|
196
|
+
-WorkingDirectory $WorkingDir `
|
|
197
|
+
-NoNewWindow `
|
|
198
|
+
-PassThru
|
|
199
|
+
}
|
|
200
|
+
# Fallback (non-Windows or missing local bin): the npx shim is fine.
|
|
188
201
|
return Start-Process -FilePath 'npx' `
|
|
189
202
|
-ArgumentList @('nuxt','dev','--port',"$Port") `
|
|
190
203
|
-WorkingDirectory $WorkingDir `
|
|
@@ -215,18 +228,25 @@ if (Test-Path -LiteralPath $nuxtServer) {
|
|
|
215
228
|
Write-Host " Starting UI (dev) on :$uiPort..."
|
|
216
229
|
$uiProc = Start-NuxtDev -Port $uiPort -ApiPort $apiPort -WorkingDir $dashboardDir
|
|
217
230
|
} else {
|
|
218
|
-
# Auto-install and start
|
|
219
|
-
|
|
220
|
-
|
|
231
|
+
# Auto-install and start. The dashboard pins pnpm (package.json
|
|
232
|
+
# packageManager) — npm's flat node_modules layout breaks Nuxt 4's
|
|
233
|
+
# server-entry resolution ("No entry found in rollupOptions.input"), so
|
|
234
|
+
# install with the pinned pnpm via corepack (always shipped with Node).
|
|
235
|
+
# corepack/pnpm are .cmd shims that Start-Process -NoNewWindow cannot
|
|
236
|
+
# exec directly on Windows, so route through cmd.exe.
|
|
237
|
+
Write-Host ' Installing dashboard dependencies (pnpm via corepack)...'
|
|
238
|
+
$savedPrompt = $env:COREPACK_ENABLE_DOWNLOAD_PROMPT
|
|
239
|
+
$env:COREPACK_ENABLE_DOWNLOAD_PROMPT = '0'
|
|
221
240
|
try {
|
|
222
|
-
Start-Process -FilePath $
|
|
223
|
-
-ArgumentList @('
|
|
241
|
+
Start-Process -FilePath $env:ComSpec `
|
|
242
|
+
-ArgumentList @('/c','corepack','pnpm','install') `
|
|
224
243
|
-WorkingDirectory $dashboardDir `
|
|
225
244
|
-NoNewWindow `
|
|
226
|
-
-Wait
|
|
227
|
-
-PassThru | Out-Null
|
|
245
|
+
-Wait | Out-Null
|
|
228
246
|
} catch {
|
|
229
|
-
Write-Host " ! Dashboard install failed
|
|
247
|
+
Write-Host " ! Dashboard install failed. API-only mode." -ForegroundColor Yellow
|
|
248
|
+
} finally {
|
|
249
|
+
$env:COREPACK_ENABLE_DOWNLOAD_PROMPT = $savedPrompt
|
|
230
250
|
}
|
|
231
251
|
if (Test-Path -LiteralPath $nuxtNodeModules) {
|
|
232
252
|
Write-Host " Starting UI (dev) on :$uiPort..."
|
|
@@ -24,12 +24,14 @@ from typing import Any
|
|
|
24
24
|
ARKAOS_ROOT = Path(os.environ.get("ARKAOS_ROOT", Path(__file__).resolve().parent.parent))
|
|
25
25
|
sys.path.insert(0, str(ARKAOS_ROOT))
|
|
26
26
|
|
|
27
|
+
from core.shared.temp_paths import arkaos_temp_dir # noqa: E402
|
|
28
|
+
|
|
27
29
|
# Layer tags carrying the actually-injected KB counts (ground truth for
|
|
28
30
|
# reconciling the model's self-reported `[arka:meta] kb=N`). The optional
|
|
29
31
|
# ` degraded=keyword` suffix (RAG honesty, PR-3 v4.1) must still count.
|
|
30
32
|
_KB_CONTEXT_TAG_RE = re.compile(r"\[kb-context:(\d+)[^\]]*\]")
|
|
31
33
|
_KNOWLEDGE_TAG_RE = re.compile(r"\[knowledge:(\d+) chunks?[^\]]*\]")
|
|
32
|
-
_KB_INJECTED_DIR =
|
|
34
|
+
_KB_INJECTED_DIR = arkaos_temp_dir("arkaos-kb-injected")
|
|
33
35
|
|
|
34
36
|
|
|
35
37
|
def _count_injected_kb(result: Any) -> tuple[int, int]:
|