@foggy-projects/deepseek-harness-plugin 0.4.0-beta.7 → 0.4.0-beta.9
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/README.md +15 -6
- package/THIRD-PARTY-RUNTIME-NOTICES.md +16 -0
- package/docs/PUBLIC-BETA-READINESS.md +53 -0
- package/docs/WINDOWS-BETA-ACCEPTANCE.md +70 -0
- package/experience/linux/README.md +5 -6
- package/experience/linux/prepare.sh +7 -9
- package/lib/atomic-json.js +41 -0
- package/lib/client.js +25 -4
- package/lib/index.js +93 -29
- package/lib/python-runtime.js +339 -0
- package/lib/remote-descriptor.js +1 -0
- package/lib/version.js +5 -0
- package/package.json +6 -3
- package/skills/foggy-deepseek-onboarding/SKILL.md +9 -3
- package/skills/foggy-deepseek-onboarding/assets/versions.json +46 -2
- package/skills/foggy-deepseek-onboarding/scripts/doctor.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/doctor.sh +1 -2
- package/skills/foggy-deepseek-onboarding/scripts/install.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/install.sh +1 -2
- package/skills/foggy-deepseek-onboarding/scripts/invoke-onboarding.ps1 +30 -0
- package/skills/foggy-deepseek-onboarding/scripts/invoke-onboarding.sh +24 -0
- package/skills/foggy-deepseek-onboarding/scripts/onboard.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/onboard.sh +1 -2
- package/skills/foggy-deepseek-onboarding/scripts/onboarding.py +59 -25
- package/skills/foggy-deepseek-onboarding/scripts/runtime-start.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/runtime-start.sh +1 -2
- package/skills/foggy-deepseek-onboarding/scripts/runtime-stop.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/runtime-stop.sh +1 -2
- package/skills/foggy-deepseek-onboarding/scripts/uninstall.ps1 +2 -2
- package/skills/foggy-deepseek-onboarding/scripts/uninstall.sh +1 -2
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
7
|
import datetime as dt
|
|
8
|
+
import errno
|
|
8
9
|
import hashlib
|
|
9
10
|
import json
|
|
10
11
|
import os
|
|
@@ -47,7 +48,7 @@ ACTIVE_PROGRESS: "ProgressReporter | None" = None
|
|
|
47
48
|
|
|
48
49
|
|
|
49
50
|
class ProgressReporter:
|
|
50
|
-
total_steps =
|
|
51
|
+
total_steps = 7
|
|
51
52
|
|
|
52
53
|
def __init__(self, path: str | None, operation_id: str | None, kind: str) -> None:
|
|
53
54
|
self.path = Path(path).expanduser() if path else None
|
|
@@ -337,11 +338,39 @@ def venv_cli(install_root: Path) -> Path:
|
|
|
337
338
|
return install_root / "venv" / ("Scripts/foggy-runtime.exe" if os.name == "nt" else "bin/foggy-runtime")
|
|
338
339
|
|
|
339
340
|
|
|
341
|
+
def replace_with_retry(source: Path, destination: Path, attempts: int = 12) -> None:
|
|
342
|
+
transient_errno = {errno.EACCES, errno.EBUSY, errno.EPERM}
|
|
343
|
+
transient_winerror = {5, 32, 33}
|
|
344
|
+
for attempt in range(attempts):
|
|
345
|
+
try:
|
|
346
|
+
os.replace(source, destination)
|
|
347
|
+
return
|
|
348
|
+
except OSError as exc:
|
|
349
|
+
transient = exc.errno in transient_errno or getattr(exc, "winerror", None) in transient_winerror
|
|
350
|
+
if not transient or attempt == attempts - 1:
|
|
351
|
+
raise
|
|
352
|
+
time.sleep(min(0.025 * (2 ** attempt), 0.4))
|
|
353
|
+
|
|
354
|
+
|
|
340
355
|
def atomic_json(path: Path, payload: dict) -> None:
|
|
341
356
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
357
|
+
handle = tempfile.NamedTemporaryFile(
|
|
358
|
+
mode="w",
|
|
359
|
+
encoding="utf-8",
|
|
360
|
+
dir=path.parent,
|
|
361
|
+
prefix=f".{path.name}.",
|
|
362
|
+
suffix=".tmp",
|
|
363
|
+
delete=False,
|
|
364
|
+
)
|
|
365
|
+
temporary = Path(handle.name)
|
|
366
|
+
try:
|
|
367
|
+
with handle:
|
|
368
|
+
json.dump(payload, handle, indent=2, ensure_ascii=False)
|
|
369
|
+
handle.flush()
|
|
370
|
+
os.fsync(handle.fileno())
|
|
371
|
+
replace_with_retry(temporary, path)
|
|
372
|
+
finally:
|
|
373
|
+
temporary.unlink(missing_ok=True)
|
|
345
374
|
|
|
346
375
|
|
|
347
376
|
def skill_tree_digest(root: Path) -> str:
|
|
@@ -996,7 +1025,7 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
996
1025
|
"workspaceMode": "dsh-session-cwd",
|
|
997
1026
|
"versions": {name: value.get("version") for name, value in components.items()},
|
|
998
1027
|
"repairComponent": repair_component,
|
|
999
|
-
"operations": ["install isolated CLI", "verify Launcher assets", "install global analysis Skill", "write install state"],
|
|
1028
|
+
"operations": ["verify private Python", "install isolated CLI", "verify Launcher assets", "install global analysis Skill", "write install state"],
|
|
1000
1029
|
"productionReady": False,
|
|
1001
1030
|
}
|
|
1002
1031
|
if args.dry_run:
|
|
@@ -1008,7 +1037,7 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1008
1037
|
getattr(args, "operation_kind", "initialize"),
|
|
1009
1038
|
)
|
|
1010
1039
|
ACTIVE_PROGRESS = progress
|
|
1011
|
-
progress.update("
|
|
1040
|
+
progress.update("python", 1, "Managed Python ready", fraction=1.0, current_file=sys.executable)
|
|
1012
1041
|
if sys.version_info < (3, 11):
|
|
1013
1042
|
raise OnboardingError(f"Python 3.11+ required, got {sys.version.split()[0]}")
|
|
1014
1043
|
install_root.mkdir(parents=True, exist_ok=True)
|
|
@@ -1020,19 +1049,19 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1020
1049
|
cli_assets = [cli_component[role] for role in ("wheel", "checksums")]
|
|
1021
1050
|
for index, asset in enumerate(cli_assets):
|
|
1022
1051
|
progress.update(
|
|
1023
|
-
"cli",
|
|
1052
|
+
"cli", 2, "Downloading and verifying CLI",
|
|
1024
1053
|
fraction=index / len(cli_assets), current_file=asset["file"],
|
|
1025
1054
|
completed_files=index, total_files=len(cli_assets),
|
|
1026
1055
|
)
|
|
1027
1056
|
verified.append(materialize(
|
|
1028
1057
|
asset, downloads / "cli" / asset["file"], cache_dirs,
|
|
1029
|
-
progress=progress, progress_phase="cli", progress_step=
|
|
1058
|
+
progress=progress, progress_phase="cli", progress_step=2,
|
|
1030
1059
|
progress_index=index, progress_total=len(cli_assets),
|
|
1031
1060
|
progress_message="Downloading and verifying CLI",
|
|
1032
1061
|
replace_corrupt=repair_component == "cli",
|
|
1033
1062
|
))
|
|
1034
1063
|
progress.update(
|
|
1035
|
-
"cli",
|
|
1064
|
+
"cli", 2, "Downloading and verifying CLI",
|
|
1036
1065
|
fraction=(index + 1) / len(cli_assets), current_file=asset["file"],
|
|
1037
1066
|
completed_files=index + 1, total_files=len(cli_assets),
|
|
1038
1067
|
)
|
|
@@ -1042,13 +1071,13 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1042
1071
|
if checksum_entries.get(wheel_asset["file"]) != wheel_asset["sha256"]:
|
|
1043
1072
|
raise OnboardingError("Pinned CLI SHA256SUMS does not match the pinned wheel hash")
|
|
1044
1073
|
if args.skip_cli_install:
|
|
1045
|
-
progress.update("cli",
|
|
1074
|
+
progress.update("cli", 2, "Using existing CLI", fraction=0.65, current_file="foggy-runtime")
|
|
1046
1075
|
cli_command = normalized(args.cli_command or shutil.which("foggy-runtime") or "")
|
|
1047
1076
|
if not cli_command.is_file():
|
|
1048
1077
|
raise OnboardingError("--skip-cli-install requires --cli-command or foggy-runtime on PATH")
|
|
1049
1078
|
cli_mode = "external"
|
|
1050
1079
|
else:
|
|
1051
|
-
progress.update("cli",
|
|
1080
|
+
progress.update("cli", 2, "Installing CLI", fraction=0.65, current_file="Python virtual environment")
|
|
1052
1081
|
python_path = venv_python(install_root)
|
|
1053
1082
|
if not python_path.is_file():
|
|
1054
1083
|
venv.EnvBuilder(with_pip=True).create(install_root / "venv")
|
|
@@ -1063,66 +1092,66 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1063
1092
|
)
|
|
1064
1093
|
cli_command = venv_cli(install_root)
|
|
1065
1094
|
cli_mode = "managed-venv"
|
|
1066
|
-
progress.update("cli",
|
|
1095
|
+
progress.update("cli", 2, "Verifying CLI version", fraction=0.9, current_file="foggy-runtime")
|
|
1067
1096
|
cli_version = command_result([str(cli_command), "--version"], check=True)
|
|
1068
1097
|
actual_cli_version = version_tuple(cli_version["stdout"])[:3]
|
|
1069
1098
|
pinned_cli_version = version_tuple(cli_component["version"])[:3]
|
|
1070
1099
|
version_matches = actual_cli_version >= pinned_cli_version if cli_mode == "external" else actual_cli_version == pinned_cli_version
|
|
1071
1100
|
if not version_matches:
|
|
1072
1101
|
raise OnboardingError(f"Unexpected CLI version: {cli_version['stdout']}")
|
|
1073
|
-
progress.update("cli",
|
|
1102
|
+
progress.update("cli", 2, "CLI ready", fraction=1.0)
|
|
1074
1103
|
|
|
1075
1104
|
launcher_dir = install_root / "launcher"
|
|
1076
1105
|
launcher_assets = components["launcher"]["assets"]
|
|
1077
1106
|
for index, asset in enumerate(launcher_assets):
|
|
1078
1107
|
progress.update(
|
|
1079
|
-
"launcher",
|
|
1108
|
+
"launcher", 3, "Downloading and verifying Launcher",
|
|
1080
1109
|
fraction=index / len(launcher_assets), current_file=asset["file"],
|
|
1081
1110
|
completed_files=index, total_files=len(launcher_assets),
|
|
1082
1111
|
)
|
|
1083
1112
|
verified.append(materialize(
|
|
1084
1113
|
asset, launcher_dir / asset["file"], cache_dirs,
|
|
1085
|
-
progress=progress, progress_phase="launcher", progress_step=
|
|
1114
|
+
progress=progress, progress_phase="launcher", progress_step=3,
|
|
1086
1115
|
progress_index=index, progress_total=len(launcher_assets),
|
|
1087
1116
|
progress_message="Downloading and verifying Launcher",
|
|
1088
1117
|
replace_corrupt=repair_component == "launcher",
|
|
1089
1118
|
))
|
|
1090
1119
|
progress.update(
|
|
1091
|
-
"launcher",
|
|
1120
|
+
"launcher", 3, "Downloading and verifying Launcher",
|
|
1092
1121
|
fraction=(index + 1) / len(launcher_assets), current_file=asset["file"],
|
|
1093
1122
|
completed_files=index + 1, total_files=len(launcher_assets),
|
|
1094
1123
|
)
|
|
1095
1124
|
if os.name != "nt":
|
|
1096
1125
|
(launcher_dir / "start-foggy-runtime.sh").chmod(0o755)
|
|
1097
|
-
progress.update("launcher",
|
|
1126
|
+
progress.update("launcher", 3, "Launcher ready", fraction=1.0)
|
|
1098
1127
|
|
|
1099
1128
|
analysis_assets = components["analysisSkill"]["assets"]
|
|
1100
1129
|
for index, asset in enumerate(analysis_assets):
|
|
1101
1130
|
progress.update(
|
|
1102
|
-
"analysis-skill",
|
|
1131
|
+
"analysis-skill", 4, "Downloading and verifying analysis Skill",
|
|
1103
1132
|
fraction=index / len(analysis_assets), current_file=asset["file"],
|
|
1104
1133
|
completed_files=index, total_files=len(analysis_assets),
|
|
1105
1134
|
)
|
|
1106
1135
|
verified.append(materialize(
|
|
1107
1136
|
asset, downloads / "skill" / asset["file"], cache_dirs,
|
|
1108
|
-
progress=progress, progress_phase="analysis-skill", progress_step=
|
|
1137
|
+
progress=progress, progress_phase="analysis-skill", progress_step=4,
|
|
1109
1138
|
progress_index=index, progress_total=len(analysis_assets),
|
|
1110
1139
|
progress_message="Downloading and verifying analysis Skill",
|
|
1111
1140
|
replace_corrupt=repair_component == "analysis-skill",
|
|
1112
1141
|
))
|
|
1113
1142
|
progress.update(
|
|
1114
|
-
"analysis-skill",
|
|
1143
|
+
"analysis-skill", 4, "Downloading and verifying analysis Skill",
|
|
1115
1144
|
fraction=(index + 1) / len(analysis_assets), current_file=asset["file"],
|
|
1116
1145
|
completed_files=index + 1, total_files=len(analysis_assets),
|
|
1117
1146
|
)
|
|
1118
1147
|
zip_asset = next(item for item in analysis_assets if item["role"] == "zip")
|
|
1119
|
-
progress.update("analysis-skill",
|
|
1148
|
+
progress.update("analysis-skill", 4, "Installing analysis Skill", fraction=0.9, current_file=zip_asset["file"])
|
|
1120
1149
|
analysis_skill = install_analysis_skill(
|
|
1121
1150
|
downloads / "skill" / zip_asset["file"], install_root, components["analysisSkill"]["version"],
|
|
1122
1151
|
zip_asset["sha256"], versions["packageVersion"], args.replace_skill or repair_component == "analysis-skill",
|
|
1123
1152
|
)
|
|
1124
|
-
progress.update("analysis-skill",
|
|
1125
|
-
progress.update("workspace-skills",
|
|
1153
|
+
progress.update("analysis-skill", 4, "Analysis Skill ready", fraction=1.0)
|
|
1154
|
+
progress.update("workspace-skills", 5, "Registering native DSH Skills", fraction=0.1)
|
|
1126
1155
|
onboarding_skill = {
|
|
1127
1156
|
"path": str(skill_root()),
|
|
1128
1157
|
"version": versions["packageVersion"],
|
|
@@ -1130,7 +1159,7 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1130
1159
|
"action": "provided-by-plugin",
|
|
1131
1160
|
"provider": "foggy-managed-skills",
|
|
1132
1161
|
}
|
|
1133
|
-
progress.update("workspace-skills",
|
|
1162
|
+
progress.update("workspace-skills", 5, "Native DSH Skills ready", fraction=1.0)
|
|
1134
1163
|
state = {
|
|
1135
1164
|
"schemaVersion": STATE_SCHEMA,
|
|
1136
1165
|
"installedAt": now_utc(),
|
|
@@ -1139,6 +1168,11 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1139
1168
|
"dataRoot": str(data_root),
|
|
1140
1169
|
"profileStore": str(profile_store),
|
|
1141
1170
|
"workspaceMode": "dsh-session-cwd",
|
|
1171
|
+
"python": {
|
|
1172
|
+
"version": components["python"]["version"],
|
|
1173
|
+
"command": sys.executable,
|
|
1174
|
+
"mode": os.environ.get("FOGGY_ONBOARDING_PYTHON_SOURCE", "managed"),
|
|
1175
|
+
},
|
|
1142
1176
|
"cli": {"version": cli_component["version"], "command": str(cli_command), "mode": cli_mode},
|
|
1143
1177
|
"launcher": {"version": components["launcher"]["version"], "path": str(launcher_dir)},
|
|
1144
1178
|
"skills": {"onboarding": onboarding_skill, "analysis": analysis_skill},
|
|
@@ -1146,7 +1180,7 @@ def install_command(args: argparse.Namespace) -> dict:
|
|
|
1146
1180
|
"securityMode": versions["defaults"]["securityMode"],
|
|
1147
1181
|
"productionReady": False,
|
|
1148
1182
|
}
|
|
1149
|
-
progress.update("state",
|
|
1183
|
+
progress.update("state", 6, "Writing install state", fraction=0.2, current_file="install-state.json")
|
|
1150
1184
|
atomic_json(install_root / "install-state.json", state)
|
|
1151
1185
|
progress.finish()
|
|
1152
1186
|
ACTIVE_PROGRESS = None
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
$ErrorActionPreference = "Stop"
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
& (Join-Path $PSScriptRoot 'invoke-onboarding.ps1') runtime-start @args
|
|
3
|
+
exit $LASTEXITCODE
|
|
4
4
|
exit $LASTEXITCODE
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
4
|
-
|
|
5
|
-
exec "$PYTHON_COMMAND" "$SCRIPT_DIR/onboarding.py" runtime-start "$@"
|
|
4
|
+
exec bash "$SCRIPT_DIR/invoke-onboarding.sh" runtime-start "$@"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
$ErrorActionPreference = "Stop"
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
& (Join-Path $PSScriptRoot 'invoke-onboarding.ps1') runtime-stop @args
|
|
3
|
+
exit $LASTEXITCODE
|
|
4
4
|
exit $LASTEXITCODE
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
4
|
-
|
|
5
|
-
exec "$PYTHON_COMMAND" "$SCRIPT_DIR/onboarding.py" runtime-stop "$@"
|
|
4
|
+
exec bash "$SCRIPT_DIR/invoke-onboarding.sh" runtime-stop "$@"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
$ErrorActionPreference = "Stop"
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
& (Join-Path $PSScriptRoot 'invoke-onboarding.ps1') uninstall @args
|
|
3
|
+
exit $LASTEXITCODE
|
|
4
4
|
exit $LASTEXITCODE
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
4
|
-
|
|
5
|
-
exec "$PYTHON_COMMAND" "$SCRIPT_DIR/onboarding.py" uninstall "$@"
|
|
4
|
+
exec bash "$SCRIPT_DIR/invoke-onboarding.sh" uninstall "$@"
|