@deepwatch/dsh-bundle 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 oxbshw
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @deepwatch/dsh-bundle
2
+
3
+ DeepWatch's capabilities, installable into a DeepSeek Harness profile you
4
+ already run. It gives that agent senses, and an independent answer to *did that
5
+ actually work?* — without asking you to move to a different product.
6
+
7
+ The full application is [DeepWatch](https://github.com/oxbshw/watch-skill/tree/main/workspace#readme);
8
+ this package is the part of it that composes into somebody else's Harness.
9
+
10
+ ## Install
11
+
12
+ > **Not on npm yet.** Nothing exists under the `@deepwatch` scope. This package
13
+ > and its thirteen siblings are published for the first time by the
14
+ > `deepwatch-v0.1.0` release; until then the command below resolves nothing.
15
+ > To try it from a checkout, build the candidate tarballs and compose a profile
16
+ > against them — [getting started](../../../docs/getting-started.md).
17
+
18
+ ```bash
19
+ dsh plugin --profile web add @deepwatch/dsh-bundle
20
+ ```
21
+
22
+ That is the whole installation. The package declares `dsh.bundle.patch`, so DSH
23
+ reconciles it into the profile's layer stack and applies
24
+ [`cordis.patch.yml`](cordis.patch.yml) after its own layers.
25
+
26
+ For the full experience, install the engine too:
27
+
28
+ ```bash
29
+ pip install watch-skill
30
+ ```
31
+
32
+ `watch-skill` is on PyPI and the newest published version is 1.4.0 — the
33
+ release this bundle is built against. The Bridge finds the executable on
34
+ `PATH` and connects on its own.
35
+
36
+ ## Stability
37
+
38
+ `0.1.0` — a stable release. Stable means tested, documented and supported —
39
+ not 1.0. This is a pre-1.0 line, and semantic versioning gives `0.x` no
40
+ compatibility guarantee across minor versions: **a `0.MINOR` bump may change or
41
+ remove surface, and a patch will not.** Depend on it with a tilde range
42
+ (`~0.1.0`) if you want that difference enforced by your lockfile rather than by
43
+ a changelog. The usual major-version promise starts at 1.0.
44
+
45
+ ## What you get
46
+
47
+ | Tool | What it does |
48
+ |---|---|
49
+ | `watch_capabilities` | what Watch can actually do here, and what is missing |
50
+ | `watch_list_sources` | the sources Watch has indexed |
51
+ | `watch_ask_source` | ask a question about a source, answered with timestamped evidence |
52
+ | `watch_get_evidence` | resolve a citation and check whether it is still current |
53
+ | `watch_verify` | run a verification contract and return an independent verdict |
54
+
55
+ Plus a browser half that renders verification results as themselves —
56
+ `UNVERIFIED` looks like `UNVERIFIED`, and green is reserved for `VERIFIED` —
57
+ and a system-prompt section telling the agent that a tool returning without
58
+ error is not proof that anything worked.
59
+
60
+ ## Without Watch Core installed
61
+
62
+ Watch reports itself unavailable. `auto` does not substitute a mock: the
63
+ Bridge says `core_missing`, every Watch capability reads **Unavailable**, and
64
+ the install step is attached to each of them. Nothing pretends to work, and the
65
+ rest of your Workspace is unaffected.
66
+
67
+ If Watch Core is installed but fails to start, that is reported as a fault too,
68
+ with its own fix. Neither case is ever answered from the mock — a Bridge that
69
+ did that would give you a green Workspace and no indication that nothing you
70
+ ask will ever be answered.
71
+
72
+ ## Configuration
73
+
74
+ | Key | Default | Meaning |
75
+ |---|---|---|
76
+ | `transport` | `auto` | `auto` connects the engine, and reports it unavailable when it is absent or broken — it never selects the mock. `stdio` is the same transport named explicitly. `mock` is the test-only in-process backend and must be asked for by name. |
77
+ | `command` | `watch-skill` | the executable that starts Watch Core in Bridge mode |
78
+ | `args` | `[bridge]` | its arguments |
79
+ | `startupTimeoutMs` | `45000` | how long the engine has to start. Generous on purpose: a first spawn against a freshly created virtualenv pays for a cold import that a 10s backstop reported as a dead engine. |
80
+ | `requestTimeoutMs` | `30000` | deadline for a request that carries none |
81
+ | `dataDir` | *(empty)* | where this profile's engine keeps its Library, Memory, receipts and indexes. Empty leaves the engine its own `~/.watch-skill`, which two profiles on one machine would then share. `deepwatch setup` composes a directory inside the profile instead. It is a *default*: an exported `WATCHSKILL_DATA_DIR` still wins, and nothing is migrated into it. |
82
+ | `autoConnect` | `true` | connect during activation rather than on first use |
83
+
84
+ A deployment that requires the engine should pin `transport: stdio`, which
85
+ never falls back and so fails loudly when it is missing. A patch replaces the
86
+ targeted row's whole `config`, so restate every key you want to keep.
87
+
88
+ ## Uninstall
89
+
90
+ ```bash
91
+ dsh plugin --profile web remove @deepwatch/dsh-bundle
92
+ ```
93
+
94
+ The rows are purely additive, so removing the bundle leaves the host profile
95
+ exactly as it was.
96
+
97
+ ## Attribution
98
+
99
+ Built on DeepSeek Harness · Powered by Watch Skill. DeepWatch and Watch Skill are
100
+ independent projects and are not affiliated with or endorsed by DeepSeek.
@@ -0,0 +1,366 @@
1
+ # Watch for DSH — the capability bundle applied over an existing profile.
2
+ #
3
+ # This file is the whole distribution mechanism. A package declaring
4
+ # `dsh.bundle.patch` in its manifest becomes a profile layer when it is
5
+ # installed with `dsh plugin --profile <name> add @deepwatch/dsh-bundle`, and
6
+ # the rows below are appended to whatever the profile already composes.
7
+ #
8
+ # It is a patch overlay, not a tree: it is applied after the dsh-base and
9
+ # dsh-web-app layers, so it can add Watch without restating — or disturbing —
10
+ # a single upstream row. That is why this distribution needs no fork and
11
+ # carries no upstream patches.
12
+ #
13
+ # Rows are additive on purpose. Removing this bundle removes Watch and leaves
14
+ # the host profile exactly as it was.
15
+
16
+ - insert:
17
+ # The Bridge to Watch Core. Everything Watch can perceive, prove or
18
+ # remember reaches the Harness through this one service.
19
+ #
20
+ # `auto` connects the real engine when `watch-skill` is installed. It does
21
+ # not fall back to the mock, and never has an outcome other than a real
22
+ # child process: a missing engine is reported as `core_missing` and one
23
+ # that fails to start as `handshake_failed`, each carrying the step that
24
+ # fixes it, and the Workspace stays fully usable with Watch features
25
+ # disabled. The fallback did exist, and is what let a machine with no
26
+ # engine report itself connected while refusing every real request — which
27
+ # the surfaces drew as an empty result nobody could tell from "nothing
28
+ # indexed yet".
29
+ #
30
+ # `stdio` is the same transport named explicitly. `mock` is the in-process
31
+ # test backend and has to be asked for by name; everything it touches is
32
+ # flagged `isTestOnlyMock`, so no screen can present it as data. A patch
33
+ # replaces the
34
+ # targeted row's whole `config`, so an overlay must restate every key it
35
+ # wants to keep:
36
+ #
37
+ # - id: watch-core-bridge
38
+ # config:
39
+ # transport: stdio
40
+ # command: watch-skill
41
+ # args: [bridge]
42
+ # cwd: ''
43
+ # startupTimeoutMs: 45000
44
+ # requestTimeoutMs: 30000
45
+ # autoConnect: true
46
+ - id: watch-core-bridge
47
+ name: '@deepwatch/dsh-core-bridge'
48
+ config:
49
+ transport: auto
50
+ command: watch-skill
51
+ args: [bridge]
52
+ cwd: ''
53
+ # 45s, not 10s. This is the backstop for "the engine cannot answer at
54
+ # all", and 10 seconds could not tell that apart from "the engine is
55
+ # starting for the first time". A fresh `deepwatch setup` creates the
56
+ # Core virtualenv moments earlier; the first `watch-skill bridge` then
57
+ # pays for a cold Python import of thousands of files a Windows
58
+ # security scanner has never seen, and exceeded 10s on a clean machine.
59
+ #
60
+ # The product called that failure: Diagnostics reported Watch Core
61
+ # failed with `core_timeout`, the reconnect breaker opened, and the
62
+ # session never recovered — on an installation that was completely
63
+ # healthy and connected in under three seconds on its second start.
64
+ #
65
+ # A generous backstop costs nothing when the engine is well, because
66
+ # the handshake resolves as soon as it lands. It is paid only when the
67
+ # engine is genuinely dead, which is already a degraded case.
68
+ startupTimeoutMs: 45000
69
+ requestTimeoutMs: 30000
70
+ autoConnect: true
71
+
72
+ # The Host's half of the routing preflight, and the store the binding
73
+ # screens write through.
74
+ #
75
+ # A composer that refuses to submit is an affordance -- it lives in a
76
+ # browser tab and the RPC it declines to call stays callable. This is the
77
+ # other half: it reads the same stored decisions and refuses a model
78
+ # request whose route nobody in this profile chose, so a stale tab or a
79
+ # caller that skipped the screens is stopped before the provider is
80
+ # reached rather than after.
81
+ #
82
+ # It injects `llm` and nothing else. Injecting `settings` would park it on
83
+ # a deployment that composes no settings file, and a routing check that
84
+ # quietly stops running is worse than one that is not there.
85
+ #
86
+ # The `/routing` subpath, not the package root. The root re-exports the OCR
87
+ # worker and carries no `apply`; the Loader refuses a row whose module
88
+ # exports none with "invalid plugin", and takes the whole plugin tree down
89
+ # with it. `scripts/verify-bundle.mjs` now imports every row's module and
90
+ # checks for `apply`, because that failure looks exactly like a composition
91
+ # problem and is three minutes of provisioning away from being seen.
92
+ # The one place that knows who asked for a provider request, and which
93
+ # routes have actually been proved.
94
+ #
95
+ # A row of its own, ahead of everything that injects it, because there has
96
+ # to be exactly one. The routing guard used to construct it, and a Cordis
97
+ # service is reflected per scope — so the guard and the read plane read two
98
+ # different objects, and the single request allowed to prove a route was
99
+ # refused while the guard insisted nothing had asked for it. One owner,
100
+ # injected by both halves, is the fix.
101
+ - id: watch-provenance
102
+ name: '@deepwatch/dsh-technology/provenance'
103
+
104
+ # Watch, listening at the boundary every tool call already goes through.
105
+ #
106
+ # An owner evaluation ran 76 tool calls through this Host and Watch recorded
107
+ # none of them -- not a write that failed, but nothing listening: every
108
+ # Watch capability was a tool the model could choose to call, and the model
109
+ # never chose to. A product whose subject is evidence produced none, and the
110
+ # only thing resembling a verdict was a file the model wrote and then reread.
111
+ #
112
+ # `@deepseek-ai/dsh-tools` publishes the dispatch lifecycle, so this needs no
113
+ # fork and no per-tool patch. A row of its own, ahead of what injects it,
114
+ # because a Cordis service is reflected per scope and a ledger two halves
115
+ # disagree about is worse than no ledger.
116
+ - id: watch-observation
117
+ name: '@deepwatch/dsh-technology/observation'
118
+
119
+ # What one turn may spend, measured against the run that made this
120
+ # necessary: 47 model rounds, 76 tool calls, three subagents, nine minutes
121
+ # and 2.97M tokens of processed context at a 97% cache hit rate. The cache
122
+ # is why nobody stopped it -- the price signal that normally ends a runaway
123
+ # had been optimised away.
124
+ #
125
+ # Every hard limit sits well clear of that run. A budget that fires during
126
+ # ordinary work teaches people to raise it, and then it is not a budget.
127
+ - id: watch-budget
128
+ name: '@deepwatch/dsh-technology/budget'
129
+ config:
130
+ enforce: true
131
+
132
+ # The route a delegated child inherits, and the preflight that stops a
133
+ # child being created when there is not one.
134
+ #
135
+ # Upstream inherits `parent.options.provider`, which is right for a
136
+ # deployment that puts its route there. This one resolves a route per
137
+ # request from the binding a person made, so the parent has nothing in
138
+ # `options` to pass down and three subagents died on their first step with
139
+ # "has no provider/model". `agent/request` is the waterfall upstream's own
140
+ # error names for exactly this, and filling it there fixes parent and child
141
+ # with one rule.
142
+ - id: watch-delegation
143
+ name: '@deepwatch/dsh-technology/delegation'
144
+
145
+ - id: watch-routing
146
+ name: '@deepwatch/dsh-technology/routing'
147
+ config:
148
+ enforce: true
149
+
150
+ # The model-facing surface: Watch's senses and its proof step as ordinary
151
+ # Harness tools, plus the system-prompt section that tells the agent a
152
+ # tool returning without error is not a verified outcome.
153
+ #
154
+ # This row injects `watchCore`, so the Loader resolves it only after the
155
+ # Bridge exists. Removing the Bridge row leaves the agent with no Watch
156
+ # tools at all rather than with tools that fail when called.
157
+ - id: watch-tools
158
+ name: '@deepwatch/dsh-tools'
159
+ config:
160
+ queryTimeoutMs: 120000
161
+ verifyTimeoutMs: 60000
162
+ # A read is quick. The first read of a session used to hang: the
163
+ # embedding stack was imported lazily on a Bridge worker thread, where
164
+ # loading numpy's C extension deadlocks, and `watch_search_sources`
165
+ # never answered at all the first time it was asked. Core now warms
166
+ # that stack at startup on the thread that owns the server, and a
167
+ # first search in a fresh engine answers in under a second.
168
+ #
169
+ # `coldReadTimeoutMs` is the backstop for a box where that warm-up was
170
+ # skipped and the first read pays for the import itself. Deliberately
171
+ # not larger: waiting three minutes on a request that is never coming
172
+ # back is worse than reporting it.
173
+ readTimeoutMs: 30000
174
+ coldReadTimeoutMs: 60000
175
+ # Where execution receipts are journalled, beside the memory store and
176
+ # for the same reason: a record the Host makes about your workspace
177
+ # belongs in your profile, not in a process that is about to exit.
178
+ #
179
+ # Without it receipts are live-only. A room holding thirteen of them
180
+ # was restarted and the Library afterwards returned one — the receipt
181
+ # made after the restart — and Refresh could not bring the rest back,
182
+ # because Refresh re-reads what is on disk and they never were.
183
+ receiptsDirectory: .watch/receipts
184
+
185
+ # The browser half. These are `dsh.client` rows, so the modules package
186
+ # scans them into the boot graph and serves their bundles under /plugins.
187
+ #
188
+ # Every one of them registers into a slot DSH itself renders. That is not a
189
+ # stylistic preference: `slots.register` accepts any name, so a registration
190
+ # into a slot nothing renders loads cleanly, passes its tests and draws
191
+ # nothing at all. `scripts/verify-slots.mjs` checks each name against
192
+ # `inventory/dsh-slots.json`, which is extracted from the pinned packages'
193
+ # own `renderSlot` call sites.
194
+
195
+ # The product identity. It fills the same generic brand slots the official
196
+ # row fills, and claims the document title and favicon at runtime — the
197
+ # HTML shell is a built DSH artifact and is not forked.
198
+ - id: watch-brand
199
+ name: '@deepwatch/dsh-client-brand'
200
+
201
+ # The browser end of the read plane: Watch's generated Typert Remote,
202
+ # mounted into `ctx.remote`.
203
+ #
204
+ # Its own row rather than a line inside the Library, and the reason is a
205
+ # dependency cycle rather than taste. `@deepwatch/dsh-tools` is the Host
206
+ # that answers these reads, and it reads the Library's index — so tools
207
+ # depends on the Library. When the Library's browser half also mounted the
208
+ # generated contribution, the Library depended on tools in return, and no
209
+ # build order can satisfy a package that cannot compile until a file
210
+ # generated from its own dependent exists.
211
+ #
212
+ # This row must come before `watch-library`: the Library's browser half
213
+ # injects `remote.watchQuery`, so without the mount it parks rather than
214
+ # drawing a tab whose search answers from nothing.
215
+ - id: watch-client-remotes
216
+ name: '@deepwatch/dsh-client-remotes'
217
+
218
+ # Evidence: keyed tool views, plus the Compare mode.
219
+ #
220
+ # It reads what the conversation already carries and makes no Host call at
221
+ # all, which is why it can render a verdict correctly even when the Bridge
222
+ # is on its mock backend: there is no second source of truth to fall out of
223
+ # sync. Remove this row and the Watch tools still work — their results
224
+ # simply render in DSH's generic tool card.
225
+ - id: watch-client-evidence
226
+ name: '@deepwatch/dsh-client-evidence'
227
+
228
+ # The shell: the Watch mode, the sidebar section, the status strip in the
229
+ # session header, the sensory timeline and the composer panel.
230
+ - id: watch-workspace
231
+ name: '@deepwatch/dsh-workspace'
232
+
233
+ # The Live mode.
234
+ - id: watch-live
235
+ name: '@deepwatch/dsh-live'
236
+
237
+ # The Library mode.
238
+ - id: watch-library
239
+ name: '@deepwatch/dsh-library'
240
+
241
+ # The Memory mode, and the "why was this remembered?" chip.
242
+ - id: watch-client-memory
243
+ name: '@deepwatch/dsh-client-memory'
244
+
245
+ # The Technology & Capability Center: role bindings, engines, sources,
246
+ # memory, verification, diagnostics and about, added to DSH's own settings
247
+ # panel. `settings.section` is a list, so upstream's General, Models and
248
+ # Plugins sections are untouched and keep the top of the list.
249
+ - id: watch-client-settings
250
+ name: '@deepwatch/dsh-client-settings'
251
+
252
+ # Durable, correctable memory. `off` by default and deliberately so:
253
+ # durable memory about a person is not something a deployment should
254
+ # acquire because nobody changed a setting.
255
+ #
256
+ # Turn it on by restating this row's whole config with a different mode:
257
+ # 'off' nothing written, nothing recalled
258
+ # 'session_only' kept in memory only; never reaches a later session
259
+ # 'local_personal' a local ledger on disk for this profile
260
+ # 'workspace_shared' knowledge and decisions shared; personal taste is not
261
+ #
262
+ # The mode values are quoted deliberately. YAML reads a bare `off` as the
263
+ # boolean false, which would silently become an invalid mode rather than
264
+ # the one written here.
265
+ #
266
+ # The ledger is the authority and every projection — taste.md, index.md,
267
+ # log.md — is rebuilt from it, which is what makes Forget remove a memory
268
+ # rather than hide it. The ledger is not yet encrypted at rest; on Desktop
269
+ # it will move behind the OS keychain, and until then `local_personal`
270
+ # means a plain file with the profile's own permissions.
271
+ - id: watch-memory
272
+ name: '@deepwatch/dsh-memory'
273
+ config:
274
+ mode: 'off'
275
+ directory: .watch/memory
276
+ inferredThreshold: 0.8
277
+ tokenBudget: 600
278
+ writeProjections: true
279
+
280
+ # The inherited default model selection, emptied.
281
+ #
282
+ # The base layer composes `agent-default-model` with `deepseek-official` /
283
+ # `deepseek-v4-flash`, which is the right default for the Harness and the wrong
284
+ # one for this distribution. A person who had installed DeepWatch, saved an
285
+ # OpenRouter credential and never chosen a model still had that pair sitting in
286
+ # their composer as though they had picked it -- and their first prompt was
287
+ # routed to DeepSeek, which failed on a credential they had never been asked
288
+ # for and left a failed turn behind.
289
+ #
290
+ # Emptying it is a *configuration* change, not a removal. The row stays
291
+ # mounted, because `@deepseek-ai/dsh-host-apiproxy` hard-injects
292
+ # `agentDefaultModel` and disabling it would park the whole API gateway. What
293
+ # changes is that the default names no route, and upstream's own admission
294
+ # boundary refuses a turn whose provider no adapter serves -- so an
295
+ # unconfigured Chat is refused before a durable turn, a trajectory or a
296
+ # provider request exists, by the Harness's own enforcement rather than by
297
+ # anything this distribution has to intercept.
298
+ #
299
+ # DeepSeek is not removed and is not disfavoured. `llm-deepseek` stays
300
+ # composed, `deepseek-official` stays in the picker, and choosing it is one
301
+ # click. What it stops being is *chosen for you*.
302
+ #
303
+ # `name:` is deliberately absent. A patch that carries one is compared for
304
+ # equality against the target row and SKIPPED with a warning when it differs
305
+ # (vendor/include: "patch: name mismatch for %C ... skipping"), so an upstream
306
+ # rename would silently restore the DeepSeek default. Targeting the id alone
307
+ # cannot be skipped, and `tests/default-model.test.mjs` pins this row to the
308
+ # pinned baseline so a bump that changes its shape fails loudly instead.
309
+ - id: agent-default-model
310
+ config:
311
+ provider: ''
312
+ model: ''
313
+
314
+ # The dedicated DeepSeek adapter, switched off.
315
+ #
316
+ # Not because DeepSeek is unwelcome -- it stays in the catalogue and stays one
317
+ # click away -- but because it was the only provider in this distribution that
318
+ # did not have to be chosen. `llm-deepseek` registers `deepseek-official` at
319
+ # plugin load, unconditionally and with no credential, and three things follow
320
+ # from that which nothing else in the product would tolerate:
321
+ #
322
+ # - a route exists that nobody configured, so the Harness's own pre-turn
323
+ # admission check passes for it and a stale or careless client can spend a
324
+ # turn on a provider the person never set up. That is exactly how the first
325
+ # prompt in Sayed's profile reached DeepSeek;
326
+ # - `ui-settings-models` renders an "Add an API key to get started ---
327
+ # Configure the official DeepSeek provider" dialog whenever that row exists
328
+ # and holds no credential, so a fresh profile met a second first-run modal
329
+ # asking for a key to a provider it had not chosen. Its own readiness
330
+ # reports `adapter-absent` and skips the dialog when the row is gone, which
331
+ # is the supported way to answer it;
332
+ # - and it made DeepSeek a special case: every other provider is configured
333
+ # through Models & Providers, and one was configured by existing.
334
+ #
335
+ # `@earendil-works/pi-ai` carries `deepseek` in the same catalogue as the other
336
+ # thirty-six routes, and `llm-pi-ai` declares its whole installed catalogue as
337
+ # configurable from the moment it mounts -- dormant or not. So DeepSeek remains
338
+ # selectable, with the same endpoint and the same `DEEPSEEK_API_KEY`, reached
339
+ # the same way as Anthropic or OpenRouter. What it stops being is the one
340
+ # provider that configures itself.
341
+ #
342
+ # `disabled: true` on a targeted id is upstream's own mechanism, so nothing
343
+ # here is patched or forked, and removing this bundle restores the row.
344
+ - id: llm-deepseek
345
+ disabled: true
346
+
347
+ # The official brand row, switched off.
348
+ #
349
+ # This is the single entry in the parity register marked
350
+ # `intentionally_replaced`, and this is where the replacement takes effect.
351
+ # Both halves are needed, and neither alone is enough:
352
+ #
353
+ # - `renderSlot("sidebar.brand.mark", …, { fallback: <official mark> })` means
354
+ # an unfilled brand slot still draws DeepSeek's mark. Registering the Watch
355
+ # brand is what displaces the fallback.
356
+ # - `ui-brand-official` *also* registers into those slots. Left enabled, both
357
+ # marks would be drawn.
358
+ #
359
+ # `disabled: true` on a targeted id is upstream's own mechanism — the same one
360
+ # `DSH_TELEMETRY_DISABLED` uses — so nothing here is patched or forked.
361
+ #
362
+ # Attribution is not what is being removed. It moves to `sidebar.footer.action`,
363
+ # where the Watch brand plugin renders "Built on DeepSeek Harness · Extended by
364
+ # Watch Skill" together with the independence disclosure, on every screen.
365
+ - id: ui-brand-official
366
+ disabled: true
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@deepwatch/dsh-bundle",
3
+ "version": "0.1.0",
4
+ "description": "DeepWatch's capabilities, installable into an existing DeepSeek Harness profile",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Sayed Allam",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/oxbshw/watch-skill.git",
11
+ "directory": "workspace/packages/watch/bundle"
12
+ },
13
+ "homepage": "https://github.com/oxbshw/watch-skill/tree/main/workspace#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/oxbshw/watch-skill/issues"
16
+ },
17
+ "keywords": [
18
+ "deepwatch",
19
+ "deepseek-harness",
20
+ "watch-skill",
21
+ "bundle",
22
+ "plugin"
23
+ ],
24
+ "dsh": {
25
+ "bundle": {
26
+ "patch": "./cordis.patch.yml",
27
+ "variants": {
28
+ "full": "./cordis.patch.yml",
29
+ "media": "./variants/media.patch.yml",
30
+ "browser": "./variants/browser.patch.yml",
31
+ "memory": "./variants/memory.patch.yml",
32
+ "document": "./variants/document.patch.yml"
33
+ }
34
+ }
35
+ },
36
+ "files": [
37
+ "cordis.patch.yml",
38
+ "variants/*.yml",
39
+ "README.md"
40
+ ],
41
+ "sideEffects": false,
42
+ "engines": {
43
+ "node": "^22.19.0 || >=24.0.0"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "@deepwatch/dsh-client-brand": "^0.1.0",
50
+ "@deepwatch/dsh-client-evidence": "^0.1.0",
51
+ "@deepwatch/dsh-client-memory": "^0.1.0",
52
+ "@deepwatch/dsh-client-remotes": "^0.1.0",
53
+ "@deepwatch/dsh-client-settings": "^0.1.0",
54
+ "@deepwatch/dsh-core-bridge": "^0.1.0",
55
+ "@deepwatch/dsh-library": "^0.1.0",
56
+ "@deepwatch/dsh-live": "^0.1.0",
57
+ "@deepwatch/dsh-memory": "^0.1.0",
58
+ "@deepwatch/dsh-technology": "^0.1.0",
59
+ "@deepwatch/dsh-tools": "^0.1.0",
60
+ "@deepwatch/dsh-trajectory": "^0.1.0",
61
+ "@deepwatch/dsh-workspace": "^0.1.0"
62
+ }
63
+ }
@@ -0,0 +1,34 @@
1
+ # Watch Browser — observe a page, act on it, and prove what happened.
2
+ #
3
+ # Media perception plus the operator loop. This is the bundle for the case the
4
+ # product exists for: the agent clicks something, and Watch establishes whether
5
+ # the world actually changed, rather than reporting that the click succeeded.
6
+ #
7
+ # Memory is absent on purpose. Verification needs no memory, and a bundle that
8
+ # quietly acquired durable memory about a person because it was convenient is
9
+ # the failure ADR-006 exists to prevent.
10
+
11
+ - insert:
12
+ - id: watch-core-bridge
13
+ name: '@deepwatch/dsh-core-bridge'
14
+ config:
15
+ transport: auto
16
+ command: watch-skill
17
+ args: [bridge]
18
+ cwd: ''
19
+ # See cordis.patch.yml: a first cold start outruns 10s.
20
+ startupTimeoutMs: 45000
21
+ requestTimeoutMs: 30000
22
+ autoConnect: true
23
+
24
+ - id: watch-tools
25
+ name: '@deepwatch/dsh-tools'
26
+ config:
27
+ queryTimeoutMs: 120000
28
+ verifyTimeoutMs: 60000
29
+
30
+ - id: watch-client-evidence
31
+ name: '@deepwatch/dsh-client-evidence'
32
+
33
+ - id: watch-trajectory
34
+ name: '@deepwatch/dsh-trajectory'
@@ -0,0 +1,35 @@
1
+ # Watch Document — reading text off things, with the engine family behind it.
2
+ #
3
+ # OCR and document perception: the lightweight local route by default, the
4
+ # heavier engines available where the hardware and the licence allow. The
5
+ # Technology Centre row is what makes engine state truthful here — presence on
6
+ # disk is not readiness, and this bundle is the one where that distinction is
7
+ # most likely to be tested.
8
+ #
9
+ # No browser operation and no memory. A document reader that could also click
10
+ # things is a larger grant than the name implies.
11
+
12
+ - insert:
13
+ - id: watch-core-bridge
14
+ name: '@deepwatch/dsh-core-bridge'
15
+ config:
16
+ transport: auto
17
+ command: watch-skill
18
+ args: [bridge]
19
+ cwd: ''
20
+ # See cordis.patch.yml: a first cold start outruns 10s.
21
+ startupTimeoutMs: 45000
22
+ requestTimeoutMs: 30000
23
+ autoConnect: true
24
+
25
+ - id: watch-tools
26
+ name: '@deepwatch/dsh-tools'
27
+ config:
28
+ queryTimeoutMs: 120000
29
+ verifyTimeoutMs: 60000
30
+
31
+ - id: watch-technology
32
+ name: '@deepwatch/dsh-technology'
33
+
34
+ - id: watch-client-evidence
35
+ name: '@deepwatch/dsh-client-evidence'
@@ -0,0 +1,33 @@
1
+ # Watch Media — perception over recorded and live media, and nothing else.
2
+ #
3
+ # The narrowest useful bundle. It gives an agent the ability to look at a video
4
+ # or a stream and answer questions with citations, and deliberately stops
5
+ # there: no browser operation, no durable memory, no verification of world
6
+ # effects. A deployment that only ever needs "what happened in this recording"
7
+ # should not be asked to accept the rest.
8
+ #
9
+ # Every variant in this directory installs the same way as the full bundle and
10
+ # is checked by the same gate, so a narrow bundle cannot drift into referencing
11
+ # a package the workspace does not have.
12
+
13
+ - insert:
14
+ - id: watch-core-bridge
15
+ name: '@deepwatch/dsh-core-bridge'
16
+ config:
17
+ transport: auto
18
+ command: watch-skill
19
+ args: [bridge]
20
+ cwd: ''
21
+ # See cordis.patch.yml: a first cold start outruns 10s.
22
+ startupTimeoutMs: 45000
23
+ requestTimeoutMs: 30000
24
+ autoConnect: true
25
+
26
+ - id: watch-tools
27
+ name: '@deepwatch/dsh-tools'
28
+ config:
29
+ queryTimeoutMs: 120000
30
+ verifyTimeoutMs: 60000
31
+
32
+ - id: watch-client-evidence
33
+ name: '@deepwatch/dsh-client-evidence'
@@ -0,0 +1,31 @@
1
+ # Watch Memory — durable, correctable memory without perception.
2
+ #
3
+ # For a deployment that wants an agent to remember how somebody works and does
4
+ # not want it watching anything. The Bridge is still present, because memory
5
+ # projections and the Context Compiler are Watch's, but no sensory tools are
6
+ # mounted: there is nothing here that can look at a screen.
7
+ #
8
+ # `mode` is 'off' as it is everywhere else. Installing a memory bundle is not
9
+ # consent to remember things about a person; changing the mode is.
10
+
11
+ - insert:
12
+ - id: watch-core-bridge
13
+ name: '@deepwatch/dsh-core-bridge'
14
+ config:
15
+ transport: auto
16
+ command: watch-skill
17
+ args: [bridge]
18
+ cwd: ''
19
+ # See cordis.patch.yml: a first cold start outruns 10s.
20
+ startupTimeoutMs: 45000
21
+ requestTimeoutMs: 30000
22
+ autoConnect: true
23
+
24
+ - id: watch-memory
25
+ name: '@deepwatch/dsh-memory'
26
+ config:
27
+ mode: 'off'
28
+ directory: .watch/memory
29
+ inferredThreshold: 0.8
30
+ tokenBudget: 600
31
+ writeProjections: true