@fotor-ai/dsh-fotor-plugin 0.6.0 → 0.6.1-test.2
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/INSTALL.md +46 -127
- package/README.md +27 -24
- package/configuration.example.yml +3 -2
- package/cordis.patch.yml +7 -15
- package/package.json +8 -2
- package/runtime/client.mjs +84 -0
- package/runtime/config.mjs +95 -0
- package/runtime/lease.mjs +25 -0
- package/runtime/lifecycle.mjs +65 -0
- package/runtime/mcp.mjs +34 -0
- package/runtime/skills.mjs +19 -0
- package/skills/fotor-connect/references/authentication.md +17 -25
- package/skills/fotor-connect/references/mcp-integration.md +1 -1
- package/skills/fotor-credits/references/authentication.md +17 -25
- package/skills/fotor-credits/references/mcp-integration.md +1 -1
- package/skills/fotor-image/references/authentication.md +17 -25
- package/skills/fotor-image/references/mcp-integration.md +1 -1
- package/skills/fotor-upload/references/authentication.md +17 -25
- package/skills/fotor-upload/references/mcp-integration.md +1 -1
- package/skills/fotor-video/references/authentication.md +17 -25
- package/skills/fotor-video/references/mcp-integration.md +1 -1
package/INSTALL.md
CHANGED
|
@@ -1,181 +1,100 @@
|
|
|
1
1
|
# Install and use Fotor with DeepSeek Harness
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DeepSeek Harness is abbreviated as `dsh` in commands and native identifiers. This guide describes automatic configuration in Fotor 0.6.1. Version 0.6.0 uses its documented manual configuration. Read the package README's version and channel, and choose a source that actually contains the target version. A candidate snapshot does not publish the npm package or change either default branch.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## 1. Check prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The current acceptance baseline is Linux DeepSeek Harness Web `0.2.1-rc.3` and stable Node `>=24.2.0 <25.0.0 || 26.x`. Earlier rc.2 results retain their original scope; the declared host range remains `>=0.2.1-rc.2 <0.3.0-0`. Node is not bundled. Check `dsh --version` and `node --version`; do not upgrade a daily installation implicitly. See the official [DeepSeek Harness repository](https://github.com/deepseek-ai/deepseek-harness) and [Node downloads](https://nodejs.org/en/download). Desktop, headless and ACP require separate acceptance.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 2. Choose one source
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
GitHub downloads the pinned **mcp-remote 0.15.2** dependency through the host package manager. npm artifacts carry its complete reviewed runtime tree. Neither path needs a separate bridge installation. Skills remain script-free; the package has no installation lifecycle hook.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
dsh --version
|
|
15
|
-
node --version
|
|
16
|
-
dsh plugin --profile web root
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Git sources additionally require Git. Follow the [host quickstart](https://deepseek-harness.github.io/deepseek-harness/en/guide/quickstart) or [Node downloads](https://nodejs.org/en/download/) for missing prerequisites. Node is not bundled. Preserve daily installations; do not upgrade them to satisfy an acceptance run.
|
|
20
|
-
|
|
21
|
-
Select one profile, working directory and Fotor-only credential directory outside the installed package. Inspect existing Fotor components before changing anything. A model-provider account is separate from Fotor OAuth. If installation uses a custom `--store-dir /absolute/path/to/store`, record it and pass that same argument on later add, update and remove commands. Retain the original profile and source as well.
|
|
22
|
-
|
|
23
|
-
**Done when:** the host and Node versions are known, the native package manager works, and the profile and external storage locations are selected.
|
|
24
|
-
|
|
25
|
-
## 2. Install one Bundle source
|
|
26
|
-
|
|
27
|
-
The package name is **`@fotor-ai/dsh-fotor-plugin`** for both sources. Installing it automatically obtains the pinned **mcp-remote 0.15.2** runtime. There is no separate bridge installation command. Git installation downloads the dependency through the host package manager; npm artifacts already carry the bridge and its complete runtime dependency tree. Installation starts neither the bridge nor OAuth.
|
|
28
|
-
|
|
29
|
-
Choose exactly one command after its channel is published:
|
|
13
|
+
Choose one source and a profile. Test channels must actually contain the requested version before use:
|
|
30
14
|
|
|
31
15
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
dsh plugin --profile
|
|
16
|
+
FOTOR_PROFILE=web
|
|
17
|
+
# GitHub default branch, after the target version is published:
|
|
18
|
+
dsh plugin --profile "$FOTOR_PROFILE" add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git" --ignore-scripts
|
|
19
|
+
# GitHub test branch:
|
|
20
|
+
dsh plugin --profile "$FOTOR_PROFILE" add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git#release/test" --ignore-scripts
|
|
21
|
+
# npm default or test channel:
|
|
22
|
+
dsh plugin --profile "$FOTOR_PROFILE" add "@fotor-ai/dsh-fotor-plugin" --ignore-scripts
|
|
23
|
+
dsh plugin --profile "$FOTOR_PROFILE" add "@fotor-ai/dsh-fotor-plugin@next" --ignore-scripts
|
|
24
|
+
# A complete local package for development:
|
|
25
|
+
dsh plugin --profile "$FOTOR_PROFILE" add /absolute/path/to/fotor-package --ignore-scripts
|
|
40
26
|
```
|
|
41
27
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
**Done when:** native installation succeeds and reports the scoped identity and expected version. Preserve a failed dependency download as a failed installation; do not continue with a missing bridge or use an unpinned `npx` workaround.
|
|
28
|
+
Run only the command for the chosen source. The Web **Plugins → Add plugin** entry accepts the same npm or GitHub source. After installation, click the host's **Enable now** button (or the Bundle switch). This selects the Bundle; its two components then activate automatically. The package cannot enable a Bundle the host has not loaded. Package name is `@fotor-ai/dsh-fotor-plugin` for both. Keep the original custom `--store-dir` argument for every later update/removal.
|
|
45
29
|
|
|
46
|
-
## 3.
|
|
47
|
-
|
|
48
|
-
Use the original profile and package-manager store. Set variables from native output and verified absolute paths:
|
|
30
|
+
## 3. Verify installation
|
|
49
31
|
|
|
50
32
|
```bash
|
|
51
|
-
FOTOR_PROFILE=web
|
|
52
|
-
dsh plugin --profile "$FOTOR_PROFILE" why @fotor-ai/dsh-fotor-plugin
|
|
53
33
|
dsh plugin --profile "$FOTOR_PROFILE" root
|
|
54
|
-
|
|
55
|
-
dsh plugin --profile "$FOTOR_PROFILE"
|
|
56
|
-
dsh plugin --profile "$FOTOR_PROFILE" why mcp-remote --json
|
|
34
|
+
dsh plugin --profile "$FOTOR_PROFILE" list --depth Infinity --json
|
|
35
|
+
dsh plugin --profile "$FOTOR_PROFILE" why @fotor-ai/dsh-fotor-plugin
|
|
57
36
|
```
|
|
58
37
|
|
|
59
|
-
|
|
38
|
+
Use the returned package root and actual dependency resolution for diagnosis, not a guessed pnpm store directory. Bundled npm dependencies can be absent from the ordinary dependency list; the installed package carries `node_modules/mcp-remote/package.json` and its `dist/client.js` and `dist/proxy.js`. Git installations use package-manager-owned links. Verify the bridge is 0.15.2.
|
|
60
39
|
|
|
61
|
-
|
|
62
|
-
- **npm artifact:** after verifying `bundleDependencies` names mcp-remote, resolve the bundled directory below. The native dependency list may omit bundled packages; an empty list alone is not a missing bridge.
|
|
40
|
+
Installation success is the expected version/source and complete files. It does not prove MCP connection. Never read the bridge's token files to diagnose installation.
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
# npm artifact only, after inspecting its manifest.
|
|
66
|
-
FOTOR_BRIDGE="$(realpath "$FOTOR_INSTALLED/node_modules/mcp-remote")"
|
|
67
|
-
```
|
|
42
|
+
## 4. Load the Bundle and resolve configuration
|
|
68
43
|
|
|
69
|
-
|
|
44
|
+
New installations require **no manual path configuration**. Start the chosen profile or allow the running Web host to load the Bundle:
|
|
70
45
|
|
|
71
46
|
```bash
|
|
72
|
-
|
|
73
|
-
cat "$FOTOR_INSTALLED/package.json"
|
|
74
|
-
cat "$FOTOR_BRIDGE/package.json"
|
|
75
|
-
test -f "$FOTOR_BRIDGE/dist/client.js"
|
|
76
|
-
test -f "$FOTOR_BRIDGE/dist/proxy.js"
|
|
47
|
+
dsh --profile "$FOTOR_PROFILE"
|
|
77
48
|
```
|
|
78
49
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
**Done when:** the scoped package/version, bridge 0.15.2, both bridge entrypoints and all selected absolute paths are verified. A `why` result alone does not establish file completeness or the Git commit.
|
|
50
|
+
The package declares both adapters enabled. A saved explicit disabled override still wins. Skills are resolved relative to the installed Fotor package; Node comes from the running Web host; the bridge is resolved from the package's dependencies. Only this package's skill root is scanned.
|
|
82
51
|
|
|
83
|
-
|
|
52
|
+
The adapter creates complete native `command`, `args`, `env` and `cwd` values in memory. Credentials default to `<active-profile-directory>/fotor/mcp-auth`, outside the installation. The default callback is loopback port 3335. A conflicting listener produces a diagnosis; stop the conflicting task or configure an unused port without changing an existing authorization's parameters casually.
|
|
84
53
|
|
|
85
|
-
|
|
54
|
+
Optional MCP settings include `endpoint` (production Fotor by default; a loopback service is for isolated acceptance), `callbackPort`, and existing native stdio fields. A supplied `args` array is complete, not an append. Explicit `env.MCP_REMOTE_CONFIG_DIR` is preserved. The [full legacy configuration example](configuration.example.yml) remains available for advanced overrides; it is never auto-applied. Overrides replace the complete `config` object, not a deep merge.
|
|
86
55
|
|
|
87
|
-
|
|
88
|
-
| --- | --- |
|
|
89
|
-
| Profile | The native profile selected for installation; keep it for updates/removal |
|
|
90
|
-
| Skill directory | Actual `FOTOR_INSTALLED` plus `/skills`; re-resolve after updates |
|
|
91
|
-
| Node command | Absolute executable for the selected supported Node version |
|
|
92
|
-
| Proxy/client entry | Actual `FOTOR_BRIDGE` plus `/dist/proxy.js` or `/dist/client.js`; re-resolve after updates |
|
|
93
|
-
| Home and agents home | Actual host locations; dedicated directories during acceptance |
|
|
94
|
-
| Working directory | Selected existing absolute workspace |
|
|
95
|
-
| `MCP_REMOTE_CONFIG_DIR` | Fotor-only external directory, separate from model credentials; retain across updates and source changes |
|
|
96
|
-
| Callback | One available port; example `3335`, host copied unchanged from `configuration.example.yml`; identical for client and proxy |
|
|
97
|
-
| Endpoint/resource | Both `https://mcp.fotor.com/mcp`; retain production and OAuth security parameters |
|
|
56
|
+
## 5. Verify skills and existing overrides
|
|
98
57
|
|
|
99
|
-
|
|
58
|
+
For ordinary use, verify the native skill menu/provider discovers the actual Fotor skills and their own `references` directories. A green component indicator without discovered entries is insufficient. Read known references through native `read`; the Shell sandbox may hide an otherwise readable host path.
|
|
100
59
|
|
|
101
|
-
|
|
60
|
+
Old complete configuration is accepted. If an old skill or bridge path no longer exists, preserve the record and remove only the obsolete override using native profile configuration to adopt automatic resolution, or supply the corrected path. Do not edit package caches, reset unrelated settings or clear credentials. Resolve duplicate Fotor providers/services before enabling another copy.
|
|
102
61
|
|
|
103
|
-
|
|
62
|
+
<a id="6-authorize-then-enable-the-connection"></a>
|
|
104
63
|
|
|
105
|
-
|
|
64
|
+
## 6. Authorize and verify the connection
|
|
106
65
|
|
|
107
|
-
|
|
108
|
-
dsh --profile "$FOTOR_PROFILE" --patch /absolute/path/to/fotor.local.yml
|
|
109
|
-
```
|
|
66
|
+
In 0.6.1 this sequence is managed automatically after host activation. The independent bridge client reuses authorization or opens the daily browser. Complete login/consent there. It must connect and discover tools, then exit with its callback listener closed before the proxy starts. Model account login remains a separate user action.
|
|
110
67
|
|
|
111
|
-
|
|
68
|
+
Connection diagnostics are `preparing`, `waiting-authorization`, `connected`, `failed` or `stopped`. The adapter being active is not a connected MCP. Authorization waits at most ten minutes and can be cancelled by disabling the MCP component. Failure does not loop through browser prompts; deliberately disable/enable to retry. Use the [authentication guide](skills/fotor-connect/references/authentication.md) for bounded recovery and browser handling.
|
|
112
69
|
|
|
113
|
-
|
|
70
|
+
Once connected, ask for a read-only model query. Website access is a separate request; preserve browser login and open each original handoff once. Never infer website login from MCP success.
|
|
114
71
|
|
|
115
|
-
|
|
72
|
+
## 7. Use, update, or remove Fotor
|
|
116
73
|
|
|
117
|
-
|
|
74
|
+
Examples: “Use Fotor's existing connection to list image models”; “Connect to the Fotor website”; or explicitly choose `/fotor-connect`. Media requests follow their own skill and credit notice rules.
|
|
118
75
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
Read [this package's authentication guide](skills/fotor-connect/references/authentication.md) before connecting. Confirm the opener targets the user's daily ordinary browser, preserve its login state, and keep the proxy stopped while the independent authorization client runs.
|
|
76
|
+
For the recorded Git source:
|
|
122
77
|
|
|
123
78
|
```bash
|
|
124
|
-
|
|
79
|
+
dsh plugin --profile "$FOTOR_PROFILE" update @fotor-ai/dsh-fotor-plugin --ignore-scripts
|
|
125
80
|
```
|
|
126
81
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
The bridge owns OAuth; this is not native remote OAuth in DeepSeek Harness. Model login, package installation, skills, Fotor authorization and website login are separate steps.
|
|
130
|
-
|
|
131
|
-
**Done when:** authorization-client discovery completes, that client/listener exits, and the enabled native stdio connection discovers actual Fotor tools.
|
|
132
|
-
|
|
133
|
-
## 7. Use, update or remove Fotor
|
|
134
|
-
|
|
135
|
-
Example requests:
|
|
136
|
-
|
|
137
|
-
- MCP-only: “Connect only to Fotor MCP and list image models. Do not open the website.”
|
|
138
|
-
- Website: “Connect to Fotor and introduce its capabilities.” Prepare the daily browser before requesting the one-use handoff; report website success only after user confirmation.
|
|
139
|
-
- Explicit skill: select `/fotor-image` and describe a task. Every successful `submit_*_task` may consume credits; preserve the existing authorization and retry rules.
|
|
140
|
-
|
|
141
|
-
Stop Fotor components and record their source, profile, store and external configuration before updating. Choose one command for the recorded source. For npm, replace `<target-version>` with an explicitly published and approved version, such as the exact version in the selected release notes:
|
|
82
|
+
For npm, select an explicitly published target:
|
|
142
83
|
|
|
143
84
|
```bash
|
|
144
|
-
# Recorded Git source only.
|
|
145
|
-
dsh plugin --profile "$FOTOR_PROFILE" update @fotor-ai/dsh-fotor-plugin --ignore-scripts
|
|
146
|
-
# Recorded npm source: select an exact published target, not a moving tag.
|
|
147
85
|
dsh plugin --profile "$FOTOR_PROFILE" update "@fotor-ai/dsh-fotor-plugin@<target-version>" --ignore-scripts
|
|
148
|
-
dsh plugin --profile "$FOTOR_PROFILE" why @fotor-ai/dsh-fotor-plugin
|
|
149
86
|
```
|
|
150
87
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
Keep the package manager's release-age policy. If it blocks a newly published version, report the target and wait, or obtain separate approval for an exception limited to that exact version and isolated profile. The earlier test.2 approval does not cover later versions. Do not disable the policy globally, clear metadata caches or reinstall to manufacture an update pass.
|
|
154
|
-
|
|
155
|
-
**Done when:** the installed version and source match the selected target, files and managed bridge are complete, and a new process discovers one copy of each skill at the re-resolved paths. A zero exit code alone is insufficient. Update complete configuration rows if paths moved; preserve the external credential store, model settings and security parameters. Record a failed native update separately from any later reinstall.
|
|
88
|
+
During historical 0.6.0-test.2 acceptance, immediate `@next` updates retained 0.6.0-test.1; exact-version updates passed. Neither `@latest` success nor success after 24 hours is established. Keep release-age protection; an acceptance-only exception needs separate approval for the exact target version. Do not treat reinstall or cache clearing as a successful upgrade. Verify installed version/files and restart the host so its module generation and paths are refreshed. Preserve the profile and custom store.
|
|
156
89
|
|
|
157
|
-
|
|
90
|
+
Before upgrading 0.6.0, record the native source, profile, store, enabled state and explicit configuration without reading token files. With no overrides, 0.6.1 resolves paths when the host loads the Bundle. Existing complete configuration and explicit disabled settings remain authoritative: upgrading does not reopen a component the user disabled. Preserve valid custom paths and connection parameters; use native configuration only to correct or remove an obsolete path override. An npm version selector is not a Git-source update; source changes use the deliberate remove/add procedure below.
|
|
158
91
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
dsh plugin --profile "$FOTOR_PROFILE" remove fotor --config.ignore-scripts=true
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
For GitHub/npm switching or scoped-package removal, use:
|
|
92
|
+
For removal:
|
|
166
93
|
|
|
167
94
|
```bash
|
|
168
95
|
dsh plugin --profile "$FOTOR_PROFILE" remove @fotor-ai/dsh-fotor-plugin --config.ignore-scripts=true
|
|
169
96
|
```
|
|
170
97
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
### Troubleshooting
|
|
174
|
-
|
|
175
|
-
- Missing bridge: inspect native install/download results and this package's dependency tree; finish installation before connecting.
|
|
176
|
-
- Changed installation path: re-query the native root/dependency paths and replace complete override rows.
|
|
177
|
-
- pnpm store mismatch: use the original profile/store; do not edit caches or move package-manager links manually.
|
|
178
|
-
- Duplicate skills/components: inspect selected sources and override rows before enabling either component.
|
|
179
|
-
- Authorization failure: follow the authentication guide's single-client bounded recovery sequence. Installation or restart success does not prove recovery from rejected credentials.
|
|
98
|
+
Stop the components first. Removal stops their processes but leaves credentials and explicit user configuration. Source switching uses deliberate removal/addition in the same profile/store; keep one source and one component pair. For the older unscoped `fotor` identity, remove that exact name before adding the scoped package. Keep old external bridge directories unless separately authorized to remove them.
|
|
180
99
|
|
|
181
|
-
|
|
100
|
+
Uninstall does not revoke server-side consent. Reinstalling in the same profile and credential directory can reuse accepted authorization; enabling still establishes a new connection. Verify that connection with an actual read-only query. A different `DSH_HOME`, profile, explicit `MCP_REMOTE_CONFIG_DIR` or connection parameters can select a different cache, and expired or rejected authorization can require new consent. Automatic configuration never migrates or copies tokens. Isolated acceptance cleanup may remove only that task's temporary state after all owned processes stop.
|
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Fotor for DeepSeek Harness
|
|
2
2
|
|
|
3
|
-
> Requires stable Node 24.2.0 or later within 24.x, or stable Node 26.x.
|
|
3
|
+
> Requires stable Node 24.2.0 or later within 24.x, or stable Node 26.x. Current acceptance uses Linux DeepSeek Harness Web 0.2.1-rc.3. Earlier rc.2 results retain their original scope. Use the release's recorded results for the exact tested host, runtime and installation route.
|
|
4
4
|
|
|
5
5
|
<p align="center"><img src="assets/logo.svg" width="72" alt="Fotor logo" /></p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
<img src="https://img.shields.io/static/v1?label=version&message=0.6.
|
|
9
|
-
<img src="https://img.shields.io/static/v1?label=channel&message=
|
|
8
|
+
<img src="https://img.shields.io/static/v1?label=version&message=0.6.1-test.2&color=087f8c&style=flat-square" alt="Version" />
|
|
9
|
+
<img src="https://img.shields.io/static/v1?label=channel&message=test&color=a56800&style=flat-square" alt="Release channel" />
|
|
10
10
|
<a href="LICENSE"><img src="https://img.shields.io/static/v1?label=license&message=Apache-2.0&color=57606a&style=flat-square" alt="Apache-2.0 license" /></a>
|
|
11
11
|
</p>
|
|
12
12
|
<p align="center">
|
|
@@ -18,12 +18,12 @@ Use Fotor's shared skills with DeepSeek Harness Web and an automatically install
|
|
|
18
18
|
| Field | Value |
|
|
19
19
|
| --- | --- |
|
|
20
20
|
| Bundle | `@fotor-ai/dsh-fotor-plugin` |
|
|
21
|
-
| Version | `0.6.
|
|
22
|
-
| Release channel | `
|
|
21
|
+
| Version | `0.6.1-test.2` |
|
|
22
|
+
| Release channel | `test` |
|
|
23
23
|
| Service environment | `production` |
|
|
24
24
|
| MCP endpoint | `https://mcp.fotor.com/mcp` |
|
|
25
25
|
| Declared host range | `>=0.2.1-rc.2 <0.3.0-0` |
|
|
26
|
-
| Host baseline | Linux DeepSeek Harness Web 0.2.1-rc.
|
|
26
|
+
| Host baseline | Linux DeepSeek Harness Web 0.2.1-rc.3 |
|
|
27
27
|
| Bridge | mcp-remote 0.15.2 |
|
|
28
28
|
| Node range | `>=24.2.0 <25.0.0 \|\| 26.x`, stable versions |
|
|
29
29
|
| License | Apache-2.0 |
|
|
@@ -32,7 +32,7 @@ Use Fotor's shared skills with DeepSeek Harness Web and an automatically install
|
|
|
32
32
|
|
|
33
33
|
Package checks cover files, references, and configuration. Verify installation, MCP authorization and calls, website login, credit links, uploads, and media execution separately in the selected host and environment. A release or model query does not establish successful website login or completed media results.
|
|
34
34
|
|
|
35
|
-
The Bundle
|
|
35
|
+
The Bundle supplies two small native Host adapters that configure the host-owned components automatically. The bridge is acquired by the package manager and owns OAuth. npm artifacts carry its full runtime dependency tree; Git installs download the dependency. Complete support requires real controlled reauthorization recovery as well as installation, calls, website access and restart reuse; consult the evidence for the installed release. Media execution and expiry-driven refresh are not established by static checks.
|
|
36
36
|
|
|
37
37
|
<a id="dsh"></a>
|
|
38
38
|
|
|
@@ -44,27 +44,27 @@ DeepSeek Harness is abbreviated as `dsh` in commands and native identifiers.
|
|
|
44
44
|
|
|
45
45
|
### DeepSeek Harness installation
|
|
46
46
|
|
|
47
|
-
####
|
|
47
|
+
#### Test release
|
|
48
48
|
|
|
49
|
-
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile.
|
|
49
|
+
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile. Select Web **Enable now** or load the CLI profile; both components then configure automatically unless explicit user settings disable them.
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
dsh plugin --profile web add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git" --ignore-scripts
|
|
52
|
+
dsh plugin --profile web add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git#release/test" --ignore-scripts
|
|
53
53
|
```
|
|
54
54
|
|
|
55
55
|
This is the standalone root Bundle for [https://github.com/fotor-ai/dsh-fotor-plugin](https://github.com/fotor-ai/dsh-fotor-plugin). Use its root Git source only after the selected channel contains this version. The [multi-platform repository](https://github.com/fotor-ai/fotor-agent-plugins) documents this external source; it no longer distributes new DeepSeek Harness packages. Existing subdirectory installations require a one-way native source migration.
|
|
56
56
|
|
|
57
|
-
The Bundle identity is `@fotor-ai/dsh-fotor-plugin`. After the corresponding npm channel is published, its alternative is `dsh plugin --profile web add "@fotor-ai/dsh-fotor-plugin" --ignore-scripts` (production) or `dsh plugin --profile web add "@fotor-ai/dsh-fotor-plugin@next" --ignore-scripts` (test). Verify the resolved version and select one source only. Bare-name npm installation follows `latest
|
|
57
|
+
The Bundle identity is `@fotor-ai/dsh-fotor-plugin`. After the corresponding npm channel is published, its alternative is `dsh plugin --profile web add "@fotor-ai/dsh-fotor-plugin" --ignore-scripts` (production) or `dsh plugin --profile web add "@fotor-ai/dsh-fotor-plugin@next" --ignore-scripts` (test). Verify the resolved version and select one source only. Bare-name npm installation follows `latest`.
|
|
58
58
|
|
|
59
|
-
Installation automatically obtains **mcp-remote 0.15.2**. Git sources download it through the host package manager; npm artifacts carry its complete locked runtime tree. Fotor skills remain script-free. No installation hook
|
|
59
|
+
Installation automatically obtains **mcp-remote 0.15.2**. Git sources download it through the host package manager; npm artifacts carry its complete locked runtime tree. Fotor skills remain script-free. No installation hook runs code; host activation starts connection and may open browser consent. Node is not bundled.
|
|
60
60
|
|
|
61
61
|
Follow the [complete installation guide](INSTALL.md):
|
|
62
62
|
|
|
63
|
-
1. Check Linux DeepSeek Harness Web `0.2.1-rc.
|
|
63
|
+
1. Check Linux DeepSeek Harness Web `0.2.1-rc.3` and stable Node **24.2.0 or later within 24.x, or 26.x**.
|
|
64
64
|
2. Install one source with lifecycle scripts disabled.
|
|
65
|
-
3.
|
|
66
|
-
4.
|
|
67
|
-
5.
|
|
65
|
+
3. In Web, click **Enable now** after installation; in CLI, start the selected profile. Both enabled-by-default adapters resolve their paths automatically.
|
|
66
|
+
4. Complete browser consent when required; existing valid authorization is reused.
|
|
67
|
+
5. Verify actual skill and tool discovery. Configure the model account separately; website access is a separate request.
|
|
68
68
|
|
|
69
69
|
The declared host range is `>=0.2.1-rc.2 <0.3.0-0`; matching versions are not automatically verified. Desktop, headless and ACP require separate acceptance.
|
|
70
70
|
|
|
@@ -72,9 +72,9 @@ The declared host range is `>=0.2.1-rc.2 <0.3.0-0`; matching versions are not au
|
|
|
72
72
|
|
|
73
73
|
### DeepSeek Harness configuration and connection
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
The native adapters resolve skills, Node and the pinned bridge at activation. Existing explicit overrides and disabled states take precedence. The [full configuration example](configuration.example.yml) is optional and never auto-applied. Overrides replace complete `config` objects. Keep default skill roots and native MCP reconnect disabled.
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
Credentials remain outside the installation, in the configured `MCP_REMOTE_CONFIG_DIR` or the active profile's dedicated Fotor directory. Follow [authentication instructions](skills/fotor-connect/references/authentication.md). The adapter runs client discovery, closes that client and its callback, then starts the native MCP proxy. User consent remains required; disabling MCP cancels its connection task.
|
|
78
78
|
|
|
79
79
|
Use the user's confirmed daily ordinary browser. MCP-only requests do not request website links; website requests prepare the browser, open the original handoff once through native permission controls, and wait for actual page confirmation. An existing login is not a first-login result.
|
|
80
80
|
|
|
@@ -95,7 +95,7 @@ For a recorded npm source, replace `<target-version>` with the approved, publish
|
|
|
95
95
|
dsh plugin --profile web update "@fotor-ai/dsh-fotor-plugin@<target-version>" --ignore-scripts
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
During historical 0.6.0-test.2 acceptance, immediate `@next` updates retained 0.6.0-test.1; exact-version native updates passed. An unqualified update can also retain the saved version. Neither `@latest` update success nor eventual success after 24 hours is established. Use the [maintenance procedure](INSTALL.md#7-use-update-or-remove-fotor); keep release-age protection and request separate approval for any exact-version exception. Never apply an npm selector to a Git source as an ordinary update.
|
|
99
99
|
|
|
100
100
|
Verify the source, version, files and actual skill/bridge directories in a new process. Preserve profile/store, credentials and connection parameters. If installation used a custom `--store-dir`, pass that same argument to updates and removal. A zero exit code with the old version is not an upgrade; cache clearing or reinstall does not turn it into a pass.
|
|
101
101
|
|
|
@@ -105,7 +105,7 @@ Verify the source, version, files and actual skill/bridge directories in a new p
|
|
|
105
105
|
|
|
106
106
|
#### Production release
|
|
107
107
|
|
|
108
|
-
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile.
|
|
108
|
+
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile. Select Web **Enable now** or load the CLI profile; both components then configure automatically unless explicit user settings disable them. Record the old source and scope, remove only this Fotor Bundle through native controls, then add the selected source. Preserve the external credential directory and valid overrides; verify automatically resolved paths when enabling the new package.
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
111
|
dsh plugin --profile web add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git" --ignore-scripts
|
|
@@ -113,16 +113,18 @@ dsh plugin --profile web add "git+https://github.com/fotor-ai/dsh-fotor-plugin.g
|
|
|
113
113
|
|
|
114
114
|
#### Test release
|
|
115
115
|
|
|
116
|
-
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile.
|
|
116
|
+
First verify that the selected revision contains the DeepSeek Harness Bundle. Install this scoped package and its pinned bridge dependency to the chosen profile. Select Web **Enable now** or load the CLI profile; both components then configure automatically unless explicit user settings disable them. Record the old source and scope, remove only this Fotor Bundle through native controls, then add the selected source. Preserve the external credential directory and valid overrides; verify automatically resolved paths when enabling the new package.
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
119
|
dsh plugin --profile web add "git+https://github.com/fotor-ai/dsh-fotor-plugin.git#release/test" --ignore-scripts
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
Legacy `fotor` and scoped packages are different identities. Stop Fotor components
|
|
122
|
+
Legacy `fotor` and scoped packages are different identities. Stop Fotor components and record old source/profile/store/paths and explicit overrides, then remove the old Bundle with `dsh plugin --profile web remove fotor --config.ignore-scripts=true`. Add one scoped source. Version 0.6.1 resolves its runtime paths automatically unless explicit overrides apply; preserve valid values and correct or remove only obsolete path overrides through native configuration. Preserve disabled settings, model settings, the external credential directory, callback/security parameters and daily browser state; do not automatically remove the old external bridge.
|
|
123
123
|
|
|
124
124
|
GitHub/npm switching uses the same explicit remove/add sequence, with `@fotor-ai/dsh-fotor-plugin` as the removal target. Keep one installed source and one component pair. Ordinary update does not rename packages or switch sources. See [maintenance](INSTALL.md#7-use-update-or-remove-fotor).
|
|
125
125
|
|
|
126
|
+
Uninstall retains external credentials but does not revoke server consent. Same-profile reinstall can reuse accepted authorization; enabling still establishes a new connection that requires actual discovery/query verification. Expired or rejected credentials may need new consent. Reinstall is not evidence of a successful native upgrade.
|
|
127
|
+
|
|
126
128
|
|
|
127
129
|
## Workflows
|
|
128
130
|
|
|
@@ -130,10 +132,11 @@ Start with [connection and model discovery](skills/fotor-connect/references/mcp-
|
|
|
130
132
|
|
|
131
133
|
## Bundle contents
|
|
132
134
|
|
|
133
|
-
- `package.json` and `cordis.patch.yml`: the
|
|
134
|
-
- `configuration.example.yml`: complete
|
|
135
|
+
- `package.json` and `cordis.patch.yml`: the Bundle and two enabled-by-default adapters.
|
|
136
|
+
- `configuration.example.yml`: optional complete legacy override; never auto-applied.
|
|
135
137
|
- `INSTALL.md`: self-contained setup and migration guide.
|
|
136
138
|
- `package-lock.json`: reviewed npm release-build input in Git snapshots; not a host-level Git dependency lock.
|
|
139
|
+
- `runtime/`: automatic configuration and cancellable connection ownership; no installation hooks.
|
|
137
140
|
- npm artifacts additionally contain the pinned third-party runtime; Fotor skills remain script-free.
|
|
138
141
|
- `.github/`: Git snapshot publication tooling, excluded from installed packages.
|
|
139
142
|
- `skills/`, including each skill's `references/`: shared workflows and DeepSeek Harness bridge/browser guidance.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
#
|
|
2
|
-
#
|
|
1
|
+
# Optional legacy full override. New installations need no path configuration.
|
|
2
|
+
# Copy outside the package only when intentionally overriding automatic values.
|
|
3
|
+
# The adapter runs its client with the same connection arguments before the proxy.
|
|
3
4
|
# Overrides replace the complete config object; fields are not deep-merged.
|
|
4
5
|
- id: fotor-skills
|
|
5
6
|
disabled: false
|
package/cordis.patch.yml
CHANGED
|
@@ -1,18 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Host activation resolves local paths; package installation has no lifecycle hook.
|
|
2
2
|
- insert:
|
|
3
3
|
- id: fotor-skills
|
|
4
|
-
name: '@
|
|
5
|
-
disabled:
|
|
6
|
-
config:
|
|
7
|
-
providerName: fotor
|
|
8
|
-
includeDefaultRoots: false
|
|
9
|
-
customSkillDirs: []
|
|
4
|
+
name: '@fotor-ai/dsh-fotor-plugin/skills'
|
|
5
|
+
disabled: false
|
|
6
|
+
config: {}
|
|
10
7
|
- id: fotor-mcp
|
|
11
|
-
name: '@
|
|
12
|
-
disabled:
|
|
13
|
-
config:
|
|
14
|
-
serverName: fotor
|
|
15
|
-
transport: stdio
|
|
16
|
-
failOnStartupError: false
|
|
17
|
-
reconnect:
|
|
18
|
-
enabled: false
|
|
8
|
+
name: '@fotor-ai/dsh-fotor-plugin/mcp'
|
|
9
|
+
disabled: false
|
|
10
|
+
config: {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fotor-ai/dsh-fotor-plugin",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1-test.2",
|
|
4
4
|
"description": "Connect to Fotor's production MCP service.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Fotor"
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"skills",
|
|
21
21
|
"assets",
|
|
22
22
|
"README.md",
|
|
23
|
-
"LICENSE"
|
|
23
|
+
"LICENSE",
|
|
24
|
+
"runtime"
|
|
24
25
|
],
|
|
25
26
|
"dsh": {
|
|
26
27
|
"bundle": {
|
|
@@ -30,6 +31,11 @@
|
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"mcp-remote": "0.15.2"
|
|
32
33
|
},
|
|
34
|
+
"type": "module",
|
|
35
|
+
"exports": {
|
|
36
|
+
"./skills": "./runtime/skills.mjs",
|
|
37
|
+
"./mcp": "./runtime/mcp.mjs"
|
|
38
|
+
},
|
|
33
39
|
"bundleDependencies": [
|
|
34
40
|
"mcp-remote"
|
|
35
41
|
],
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Bound the pinned bridge CLI without exposing its OAuth output or token files. */
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { createServer } from 'node:net';
|
|
4
|
+
import { childEnvironment } from './config.mjs';
|
|
5
|
+
|
|
6
|
+
export function toolsDiscovered(text) {
|
|
7
|
+
const marker = text.indexOf('Tools:');
|
|
8
|
+
if (marker < 0) return false;
|
|
9
|
+
const start = text.indexOf('{', marker);
|
|
10
|
+
if (start < 0) return false;
|
|
11
|
+
let depth = 0, quoted = false, escaped = false;
|
|
12
|
+
for (let index = start; index < text.length; index++) {
|
|
13
|
+
const char = text[index];
|
|
14
|
+
if (quoted) {
|
|
15
|
+
if (escaped) escaped = false;
|
|
16
|
+
else if (char === '\\') escaped = true;
|
|
17
|
+
else if (char === '"') quoted = false;
|
|
18
|
+
} else if (char === '"') quoted = true;
|
|
19
|
+
else if (char === '{') depth++;
|
|
20
|
+
else if (char === '}' && --depth === 0) {
|
|
21
|
+
try { const value = JSON.parse(text.slice(start, index + 1)); return Array.isArray(value.tools) && value.tools.every(tool => typeof tool.name === 'string'); }
|
|
22
|
+
catch { return false; }
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
export async function checkCallbackPort(args) {
|
|
28
|
+
if (!/^\d+$/.test(args[2] ?? '')) return;
|
|
29
|
+
const port = Number(args[2]);
|
|
30
|
+
const hostIndex = args.indexOf('--host');
|
|
31
|
+
const host = hostIndex < 0 ? 'localhost' : args[hostIndex + 1];
|
|
32
|
+
await new Promise((resolve, reject) => {
|
|
33
|
+
const probe = createServer(socket => socket.destroy());
|
|
34
|
+
probe.once('error', () => reject(new Error('Fotor callback port is unavailable; stop the conflicting task before retrying')));
|
|
35
|
+
probe.listen({port, host, exclusive:true}, () => probe.close(resolve));
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export function authorize(connection, { signal, status, automaticMs = 90000, humanMs = 600000, spawnProcess = spawn } = {}) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
if (signal.aborted) return reject(new Error('Fotor connection cancelled'));
|
|
41
|
+
const config = connection.native;
|
|
42
|
+
const child = spawnProcess(config.command, [connection.client, ...config.args.slice(1)], {
|
|
43
|
+
cwd: config.cwd, env: childEnvironment(config.env), stdio: ['pipe', 'pipe', 'pipe'], shell: false,
|
|
44
|
+
});
|
|
45
|
+
let output = '', waiting = false, waited = false, failure, killTimer;
|
|
46
|
+
let started = Date.now(), remaining = automaticMs;
|
|
47
|
+
const finish = error => { failure ??= error; child.kill('SIGTERM'); killTimer ??= setTimeout(() => child.kill('SIGKILL'), 1500); };
|
|
48
|
+
const aborted = () => finish(new Error('Fotor connection cancelled'));
|
|
49
|
+
signal.addEventListener('abort', aborted, { once: true });
|
|
50
|
+
let timer = setTimeout(() => finish(new Error('Fotor automatic connection budget exceeded')), remaining);
|
|
51
|
+
const receive = chunk => {
|
|
52
|
+
output += chunk.toString('utf8');
|
|
53
|
+
if (Buffer.byteLength(output) > 1024 * 1024) return finish(new Error('Fotor bridge output exceeded its bound'));
|
|
54
|
+
if (/EADDRINUSE|address already in use/i.test(output)) return finish(new Error('Fotor callback port is already in use; stop the conflicting task or preserve and adjust its explicit configuration'));
|
|
55
|
+
if (/Could not open a browser automatically/.test(output)) return finish(new Error('Fotor browser unavailable; configure the ordinary browser before retrying'));
|
|
56
|
+
if (!waited && /Please authorize this client by visiting:|Authentication required\. Waiting for authorization/.test(output)) {
|
|
57
|
+
remaining = Math.max(1, remaining - (Date.now() - started));
|
|
58
|
+
clearTimeout(timer); waiting = true; waited = true;
|
|
59
|
+
status('waiting-authorization');
|
|
60
|
+
timer = setTimeout(() => finish(new Error('Fotor authorization wait expired')), humanMs);
|
|
61
|
+
}
|
|
62
|
+
if (waiting && /Connected successfully!/.test(output)) {
|
|
63
|
+
waiting = false; started = Date.now(); clearTimeout(timer);
|
|
64
|
+
timer = setTimeout(() => finish(new Error('Fotor automatic connection budget exceeded')), remaining);
|
|
65
|
+
status('preparing');
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
child.stdout.on('data', receive); child.stderr.on('data', receive);
|
|
69
|
+
child.on('error', () => { failure = new Error('Fotor authorization client could not start'); });
|
|
70
|
+
child.on('close', code => {
|
|
71
|
+
clearTimeout(timer); clearTimeout(killTimer); signal.removeEventListener('abort', aborted);
|
|
72
|
+
const discovered = toolsDiscovered(output);
|
|
73
|
+
const connected = /Connected successfully!/.test(output);
|
|
74
|
+
const transient = !waited && /EAI_AGAIN|ENOTFOUND|ECONNRESET|ETIMEDOUT|ECONNREFUSED/.test(output);
|
|
75
|
+
output = '';
|
|
76
|
+
if (failure) reject(failure);
|
|
77
|
+
else if (code === 0 && connected && discovered) resolve({ automaticMsUsed: automaticMs - remaining + (waiting ? 0 : Date.now() - started) });
|
|
78
|
+
else {
|
|
79
|
+
const error = new Error(waited ? 'Fotor authorization did not complete; disable and enable MCP to try again' : 'Fotor client did not connect and discover tools');
|
|
80
|
+
error.transient = transient; reject(error);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|