@foggy-projects/deepseek-harness-plugin 0.4.0-beta.10
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/LICENSE +201 -0
- package/README.md +81 -0
- package/THIRD-PARTY-RUNTIME-NOTICES.md +16 -0
- package/cordis.patch.yml +6 -0
- package/docs/PUBLIC-BETA-READINESS.md +57 -0
- package/docs/WINDOWS-BETA-ACCEPTANCE.md +75 -0
- package/experience/linux/README.md +53 -0
- package/experience/linux/prepare.sh +188 -0
- package/lib/atomic-json.js +41 -0
- package/lib/client.js +453 -0
- package/lib/index.js +467 -0
- package/lib/python-runtime.js +339 -0
- package/lib/remote-descriptor.js +30 -0
- package/lib/remote.js +8 -0
- package/lib/skill-provider.js +111 -0
- package/lib/typert.js +9 -0
- package/lib/version.js +20 -0
- package/package.json +63 -0
- package/skills/foggy-deepseek-onboarding/SKILL.md +137 -0
- package/skills/foggy-deepseek-onboarding/assets/connection.schema.json +50 -0
- package/skills/foggy-deepseek-onboarding/assets/datasource.example.json +13 -0
- package/skills/foggy-deepseek-onboarding/assets/env.example +14 -0
- package/skills/foggy-deepseek-onboarding/assets/onboarding-state.schema.json +42 -0
- package/skills/foggy-deepseek-onboarding/assets/semantic-plan.example.json +8 -0
- package/skills/foggy-deepseek-onboarding/assets/semantic-plan.schema.json +21 -0
- package/skills/foggy-deepseek-onboarding/assets/versions.json +137 -0
- package/skills/foggy-deepseek-onboarding/references/onboarding-workflow.md +156 -0
- package/skills/foggy-deepseek-onboarding/scripts/doctor.ps1 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/doctor.sh +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/install.ps1 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/install.sh +4 -0
- 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 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/onboard.sh +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/onboarding.py +3027 -0
- package/skills/foggy-deepseek-onboarding/scripts/runtime-start.ps1 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/runtime-start.sh +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/runtime-stop.ps1 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/runtime-stop.sh +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/uninstall.ps1 +4 -0
- package/skills/foggy-deepseek-onboarding/scripts/uninstall.sh +4 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
DSH_VERSION="0.1.2-rc.1"
|
|
5
|
+
PNPM_VERSION="11.7.0"
|
|
6
|
+
PLUGIN_VERSION="0.4.0-beta.10"
|
|
7
|
+
PLUGIN_REF="v${PLUGIN_VERSION}"
|
|
8
|
+
PLUGIN_REPOSITORY="https://github.com/foggy-projects/foggy-deepseek-harness-plugin.git"
|
|
9
|
+
|
|
10
|
+
experience_root="${HOME}/.local/share/foggy-deepseek-harness-experience"
|
|
11
|
+
project_root="${HOME}/foggy-deepseek-experience-workspace"
|
|
12
|
+
dry_run=0
|
|
13
|
+
|
|
14
|
+
usage() {
|
|
15
|
+
cat <<'EOF'
|
|
16
|
+
Usage: prepare.sh [options]
|
|
17
|
+
|
|
18
|
+
Options:
|
|
19
|
+
--experience-root PATH DSH and plugin installation root under the Linux-native filesystem
|
|
20
|
+
--project-root PATH Workspace that receives Foggy Skills and onboarding artifacts
|
|
21
|
+
--dry-run Validate prerequisites and print the plan without changing files
|
|
22
|
+
-h, --help Show this help
|
|
23
|
+
EOF
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
while [[ $# -gt 0 ]]; do
|
|
27
|
+
case "$1" in
|
|
28
|
+
--experience-root)
|
|
29
|
+
[[ $# -ge 2 ]] || { echo "--experience-root requires a value" >&2; exit 2; }
|
|
30
|
+
experience_root="$2"
|
|
31
|
+
shift 2
|
|
32
|
+
;;
|
|
33
|
+
--project-root)
|
|
34
|
+
[[ $# -ge 2 ]] || { echo "--project-root requires a value" >&2; exit 2; }
|
|
35
|
+
project_root="$2"
|
|
36
|
+
shift 2
|
|
37
|
+
;;
|
|
38
|
+
--dry-run)
|
|
39
|
+
dry_run=1
|
|
40
|
+
shift
|
|
41
|
+
;;
|
|
42
|
+
-h|--help)
|
|
43
|
+
usage
|
|
44
|
+
exit 0
|
|
45
|
+
;;
|
|
46
|
+
*)
|
|
47
|
+
echo "Unknown option: $1" >&2
|
|
48
|
+
usage >&2
|
|
49
|
+
exit 2
|
|
50
|
+
;;
|
|
51
|
+
esac
|
|
52
|
+
done
|
|
53
|
+
|
|
54
|
+
fail() {
|
|
55
|
+
echo "Foggy Linux experience preflight failed: $*" >&2
|
|
56
|
+
exit 1
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
require_command() {
|
|
60
|
+
command -v "$1" >/dev/null 2>&1 || fail "required command not found: $1"
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
[[ "$(uname -s)" == "Linux" ]] || fail "this entry supports Linux and WSL2 only"
|
|
64
|
+
case "$(uname -m)" in
|
|
65
|
+
x86_64|amd64|aarch64|arm64) ;;
|
|
66
|
+
*) fail "supported architectures are x86_64 and arm64; detected $(uname -m)" ;;
|
|
67
|
+
esac
|
|
68
|
+
|
|
69
|
+
require_command node
|
|
70
|
+
require_command npm
|
|
71
|
+
require_command java
|
|
72
|
+
require_command git
|
|
73
|
+
require_command df
|
|
74
|
+
require_command tar
|
|
75
|
+
|
|
76
|
+
node -e 'const [major, minor] = process.versions.node.split(".").map(Number); if (!((major === 22 && minor >= 19) || major >= 24)) process.exit(1)' \
|
|
77
|
+
|| fail "Node ^22.19.0 or >=24 required; detected $(node --version 2>/dev/null || echo unknown)"
|
|
78
|
+
|
|
79
|
+
java_major="$(java -version 2>&1 | awk -F'[\".]' '/version/ { print $2; exit }')"
|
|
80
|
+
[[ "$java_major" =~ ^[0-9]+$ ]] || fail "could not detect Java version"
|
|
81
|
+
(( java_major >= 17 )) || fail "Java 17+ required; detected major version $java_major"
|
|
82
|
+
|
|
83
|
+
case "$experience_root" in
|
|
84
|
+
/*) ;;
|
|
85
|
+
*) fail "--experience-root must be an absolute path" ;;
|
|
86
|
+
esac
|
|
87
|
+
case "$project_root" in
|
|
88
|
+
/*) ;;
|
|
89
|
+
*) fail "--project-root must be an absolute path" ;;
|
|
90
|
+
esac
|
|
91
|
+
|
|
92
|
+
if grep -qi microsoft /proc/version 2>/dev/null; then
|
|
93
|
+
case "$experience_root" in
|
|
94
|
+
/mnt/*) fail "WSL2 experience root must be on the Linux-native filesystem, not under /mnt/" ;;
|
|
95
|
+
esac
|
|
96
|
+
case "$project_root" in
|
|
97
|
+
/mnt/*) fail "WSL2 project root must be on the Linux-native filesystem, not under /mnt/" ;;
|
|
98
|
+
esac
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
available_kib="$(df -Pk "$HOME" | awk 'NR==2 { print $4 }')"
|
|
102
|
+
[[ "$available_kib" =~ ^[0-9]+$ ]] || fail "could not determine free disk space"
|
|
103
|
+
(( available_kib >= 4 * 1024 * 1024 )) || fail "at least 4 GiB free disk space is required"
|
|
104
|
+
|
|
105
|
+
memory_kib="$(awk '/^MemTotal:/ { print $2; exit }' /proc/meminfo)"
|
|
106
|
+
[[ "$memory_kib" =~ ^[0-9]+$ ]] || fail "could not determine available memory"
|
|
107
|
+
(( memory_kib >= 2 * 1024 * 1024 )) || fail "at least 2 GiB memory is required"
|
|
108
|
+
if (( memory_kib < 4 * 1024 * 1024 )); then
|
|
109
|
+
echo "Warning: less than 4 GiB memory detected; DSH and the Java Runtime may start slowly." >&2
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
if [[ -d "$experience_root" ]] && [[ -n "$(find "$experience_root" -mindepth 1 -maxdepth 1 -print -quit)" ]]; then
|
|
113
|
+
fail "experience root is not empty: $experience_root"
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
cat <<EOF
|
|
117
|
+
Foggy Linux experience plan
|
|
118
|
+
DSH: $DSH_VERSION
|
|
119
|
+
pnpm: $PNPM_VERSION
|
|
120
|
+
Foggy Bundle: $PLUGIN_VERSION
|
|
121
|
+
Python: private managed 3.12.13 (downloaded during Foggy initialization)
|
|
122
|
+
Experience root: $experience_root
|
|
123
|
+
Project root: $project_root
|
|
124
|
+
Filesystem: Linux-native
|
|
125
|
+
Model secrets: not configured
|
|
126
|
+
EOF
|
|
127
|
+
|
|
128
|
+
if [[ "$dry_run" == "1" ]]; then
|
|
129
|
+
echo "Dry run passed; no files were changed."
|
|
130
|
+
exit 0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
pnpm_prefix="$experience_root/pnpm"
|
|
134
|
+
dsh_install="$experience_root/dsh-install"
|
|
135
|
+
dsh_home="$experience_root/dsh-home"
|
|
136
|
+
dsh_agents_home="$experience_root/dsh-agents-home"
|
|
137
|
+
plugin_source="$experience_root/plugin-source"
|
|
138
|
+
packages_dir="$experience_root/packages"
|
|
139
|
+
dsh_command="$dsh_install/node_modules/.bin/dsh"
|
|
140
|
+
|
|
141
|
+
mkdir -p "$experience_root" "$project_root" "$pnpm_prefix" "$dsh_install" "$dsh_home" "$dsh_agents_home/skills" "$packages_dir"
|
|
142
|
+
chmod 700 "$experience_root" "$dsh_home" "$dsh_agents_home"
|
|
143
|
+
|
|
144
|
+
npm install --prefix "$pnpm_prefix" --no-audit --no-fund "pnpm@$PNPM_VERSION"
|
|
145
|
+
pnpm_command="$pnpm_prefix/node_modules/.bin/pnpm"
|
|
146
|
+
|
|
147
|
+
printf '%s\n' 'onlyBuiltDependencies:' ' - sharp' > "$dsh_install/pnpm-workspace.yaml"
|
|
148
|
+
"$pnpm_command" add --dir "$dsh_install" --save-exact "@deepseek-ai/dsh@$DSH_VERSION"
|
|
149
|
+
|
|
150
|
+
git clone --depth 1 --branch "$PLUGIN_REF" "$PLUGIN_REPOSITORY" "$plugin_source"
|
|
151
|
+
(
|
|
152
|
+
cd "$plugin_source"
|
|
153
|
+
npm pack --pack-destination "$packages_dir"
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
plugin_package="$packages_dir/foggy-projects-deepseek-harness-plugin-$PLUGIN_VERSION.tgz"
|
|
157
|
+
[[ -f "$plugin_package" ]] || fail "packed Foggy Bundle not found: $plugin_package"
|
|
158
|
+
|
|
159
|
+
(
|
|
160
|
+
cd "$project_root"
|
|
161
|
+
DSH_HOME="$dsh_home" DSH_AGENTS_HOME="$dsh_agents_home" \
|
|
162
|
+
"$dsh_command" plugin --profile web add --workspace-root "$plugin_package"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
run_script="$experience_root/run.sh"
|
|
166
|
+
{
|
|
167
|
+
printf '%s\n' '#!/usr/bin/env bash' 'set -euo pipefail'
|
|
168
|
+
printf 'export DSH_HOME=%q\n' "$dsh_home"
|
|
169
|
+
printf 'export DSH_AGENTS_HOME=%q\n' "$dsh_agents_home"
|
|
170
|
+
printf 'export FOGGY_PROJECT_ROOT=%q\n' "$project_root"
|
|
171
|
+
printf 'cd %q\n' "$project_root"
|
|
172
|
+
printf 'exec %q web\n' "$dsh_command"
|
|
173
|
+
} > "$run_script"
|
|
174
|
+
chmod 700 "$run_script"
|
|
175
|
+
|
|
176
|
+
state_file="$experience_root/experience.env"
|
|
177
|
+
{
|
|
178
|
+
printf 'DSH_VERSION=%q\n' "$DSH_VERSION"
|
|
179
|
+
printf 'PLUGIN_VERSION=%q\n' "$PLUGIN_VERSION"
|
|
180
|
+
printf 'DSH_COMMAND=%q\n' "$dsh_command"
|
|
181
|
+
printf 'DSH_HOME=%q\n' "$dsh_home"
|
|
182
|
+
printf 'DSH_AGENTS_HOME=%q\n' "$dsh_agents_home"
|
|
183
|
+
printf 'FOGGY_PROJECT_ROOT=%q\n' "$project_root"
|
|
184
|
+
} > "$state_file"
|
|
185
|
+
chmod 600 "$state_file"
|
|
186
|
+
|
|
187
|
+
echo "Experience prepared. DeepSeek Harness and Foggy have not been started."
|
|
188
|
+
echo "Run: $run_script"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto'
|
|
2
|
+
import { mkdir, rename, rm, writeFile } from 'node:fs/promises'
|
|
3
|
+
import { dirname } from 'node:path'
|
|
4
|
+
|
|
5
|
+
const TRANSIENT_REPLACE_CODES = new Set(['EACCES', 'EBUSY', 'EPERM'])
|
|
6
|
+
const TRANSIENT_WINERRORS = new Set([5, 32, 33])
|
|
7
|
+
|
|
8
|
+
function wait(milliseconds) {
|
|
9
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function transientReplaceError(error) {
|
|
13
|
+
return TRANSIENT_REPLACE_CODES.has(error?.code) || TRANSIENT_WINERRORS.has(error?.winerror)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function replaceWithRetry(source, destination, {
|
|
17
|
+
replace = rename,
|
|
18
|
+
sleep = wait,
|
|
19
|
+
attempts = 12,
|
|
20
|
+
} = {}) {
|
|
21
|
+
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
|
22
|
+
try {
|
|
23
|
+
await replace(source, destination)
|
|
24
|
+
return
|
|
25
|
+
} catch (error) {
|
|
26
|
+
if (!transientReplaceError(error) || attempt === attempts - 1) throw error
|
|
27
|
+
await sleep(Math.min(25 * (2 ** attempt), 400))
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function writeJsonAtomic(path, payload, options = {}) {
|
|
33
|
+
await mkdir(dirname(path), { recursive: true })
|
|
34
|
+
const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`
|
|
35
|
+
try {
|
|
36
|
+
await writeFile(temporary, `${JSON.stringify(payload, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
|
|
37
|
+
await replaceWithRetry(temporary, path, options)
|
|
38
|
+
} finally {
|
|
39
|
+
await rm(temporary, { force: true })
|
|
40
|
+
}
|
|
41
|
+
}
|